1 From 2e5bd96eea86a246b4de3bf756f7a11b43e6187d Mon Sep 17 00:00:00 2001
2 From: Christian Marangi <ansuelsmth@gmail.com>
3 Date: Wed, 27 Jul 2022 13:35:19 +0200
4 Subject: [PATCH 10/14] net: dsa: qca8k: move port FDB/MDB function to common
7 The same port FDB/MDB function are used by drivers based on qca8k family
8 switch. Move them to common code to make them accessible also by other
10 Also drop bulk read/write functions and make them static
12 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
13 Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
14 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
16 drivers/net/dsa/qca/qca8k-8xxx.c | 306 -----------------------------
17 drivers/net/dsa/qca/qca8k-common.c | 297 +++++++++++++++++++++++++++-
18 drivers/net/dsa/qca/qca8k.h | 25 ++-
19 3 files changed, 317 insertions(+), 311 deletions(-)
21 --- a/drivers/net/dsa/qca/qca8k-8xxx.c
22 +++ b/drivers/net/dsa/qca/qca8k-8xxx.c
23 @@ -442,217 +442,6 @@ static struct regmap_config qca8k_regmap
27 -qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
32 - /* load the ARL table into an array */
33 - ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
38 - fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
40 - fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]);
41 - /* portmask - 54:48 */
42 - fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]);
44 - fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]);
45 - fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]);
46 - fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]);
47 - fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]);
48 - fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]);
49 - fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]);
55 -qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac,
61 - reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
63 - reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging);
64 - /* portmask - 54:48 */
65 - reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask);
67 - reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]);
68 - reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]);
69 - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]);
70 - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]);
71 - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]);
72 - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
74 - /* load the array into the ARL table */
75 - qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
79 -qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port)
84 - /* Set the command and FDB index */
85 - reg = QCA8K_ATU_FUNC_BUSY;
88 - reg |= QCA8K_ATU_FUNC_PORT_EN;
89 - reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port);
92 - /* Write the function register triggering the table access */
93 - ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
97 - /* wait for completion */
98 - ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
102 - /* Check for table full violation when adding an entry */
103 - if (cmd == QCA8K_FDB_LOAD) {
104 - ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®);
107 - if (reg & QCA8K_ATU_FUNC_FULL)
115 -qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port)
119 - qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
120 - ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
124 - return qca8k_fdb_read(priv, fdb);
128 -qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask,
133 - mutex_lock(&priv->reg_mutex);
134 - qca8k_fdb_write(priv, vid, port_mask, mac, aging);
135 - ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
136 - mutex_unlock(&priv->reg_mutex);
142 -qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid)
146 - mutex_lock(&priv->reg_mutex);
147 - qca8k_fdb_write(priv, vid, port_mask, mac, 0);
148 - ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
149 - mutex_unlock(&priv->reg_mutex);
155 -qca8k_fdb_flush(struct qca8k_priv *priv)
157 - mutex_lock(&priv->reg_mutex);
158 - qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1);
159 - mutex_unlock(&priv->reg_mutex);
163 -qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
164 - const u8 *mac, u16 vid)
166 - struct qca8k_fdb fdb = { 0 };
169 - mutex_lock(&priv->reg_mutex);
171 - qca8k_fdb_write(priv, vid, 0, mac, 0);
172 - ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
176 - ret = qca8k_fdb_read(priv, &fdb);
180 - /* Rule exist. Delete first */
182 - ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
187 - /* Add port to fdb portmask */
188 - fdb.port_mask |= port_mask;
190 - qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
191 - ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
194 - mutex_unlock(&priv->reg_mutex);
199 -qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
200 - const u8 *mac, u16 vid)
202 - struct qca8k_fdb fdb = { 0 };
205 - mutex_lock(&priv->reg_mutex);
207 - qca8k_fdb_write(priv, vid, 0, mac, 0);
208 - ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
212 - /* Rule doesn't exist. Why delete? */
218 - ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
222 - /* Only port in the rule is this port. Don't re insert */
223 - if (fdb.port_mask == port_mask)
226 - /* Remove port from port mask */
227 - fdb.port_mask &= ~port_mask;
229 - qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
230 - ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
233 - mutex_unlock(&priv->reg_mutex);
238 qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
241 @@ -2048,97 +1837,6 @@ exit:
246 -qca8k_port_fast_age(struct dsa_switch *ds, int port)
248 - struct qca8k_priv *priv = ds->priv;
250 - mutex_lock(&priv->reg_mutex);
251 - qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
252 - mutex_unlock(&priv->reg_mutex);
256 -qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
257 - u16 port_mask, u16 vid)
259 - /* Set the vid to the port vlan id if no vid is set */
261 - vid = QCA8K_PORT_VID_DEF;
263 - return qca8k_fdb_add(priv, addr, port_mask, vid,
264 - QCA8K_ATU_STATUS_STATIC);
268 -qca8k_port_fdb_add(struct dsa_switch *ds, int port,
269 - const unsigned char *addr, u16 vid)
271 - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
272 - u16 port_mask = BIT(port);
274 - return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
278 -qca8k_port_fdb_del(struct dsa_switch *ds, int port,
279 - const unsigned char *addr, u16 vid)
281 - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
282 - u16 port_mask = BIT(port);
285 - vid = QCA8K_PORT_VID_DEF;
287 - return qca8k_fdb_del(priv, addr, port_mask, vid);
291 -qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
292 - dsa_fdb_dump_cb_t *cb, void *data)
294 - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
295 - struct qca8k_fdb _fdb = { 0 };
296 - int cnt = QCA8K_NUM_FDB_RECORDS;
300 - mutex_lock(&priv->reg_mutex);
301 - while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
304 - is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
305 - ret = cb(_fdb.mac, _fdb.vid, is_static, data);
309 - mutex_unlock(&priv->reg_mutex);
315 -qca8k_port_mdb_add(struct dsa_switch *ds, int port,
316 - const struct switchdev_obj_port_mdb *mdb)
318 - struct qca8k_priv *priv = ds->priv;
319 - const u8 *addr = mdb->addr;
320 - u16 vid = mdb->vid;
322 - return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
326 -qca8k_port_mdb_del(struct dsa_switch *ds, int port,
327 - const struct switchdev_obj_port_mdb *mdb)
329 - struct qca8k_priv *priv = ds->priv;
330 - const u8 *addr = mdb->addr;
331 - u16 vid = mdb->vid;
333 - return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
337 qca8k_port_mirror_add(struct dsa_switch *ds, int port,
338 struct dsa_mall_mirror_tc_entry *mirror,
339 --- a/drivers/net/dsa/qca/qca8k-common.c
340 +++ b/drivers/net/dsa/qca/qca8k-common.c
341 @@ -103,7 +103,7 @@ const struct regmap_access_table qca8k_r
344 /* TODO: remove these extra ops when we can support regmap bulk read/write */
345 -int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
346 +static int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
348 int i, count = len / sizeof(u32), ret;
350 @@ -121,7 +121,7 @@ int qca8k_bulk_read(struct qca8k_priv *p
353 /* TODO: remove these extra ops when we can support regmap bulk read/write */
354 -int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
355 +static int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
357 int i, count = len / sizeof(u32), ret;
359 @@ -149,6 +149,211 @@ int qca8k_busy_wait(struct qca8k_priv *p
360 QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
363 +static int qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
368 + /* load the ARL table into an array */
369 + ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
374 + fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
375 + /* aging - 67:64 */
376 + fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]);
377 + /* portmask - 54:48 */
378 + fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]);
380 + fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]);
381 + fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]);
382 + fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]);
383 + fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]);
384 + fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]);
385 + fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]);
390 +static void qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask,
391 + const u8 *mac, u8 aging)
393 + u32 reg[3] = { 0 };
396 + reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
397 + /* aging - 67:64 */
398 + reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging);
399 + /* portmask - 54:48 */
400 + reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask);
402 + reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]);
403 + reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]);
404 + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]);
405 + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]);
406 + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]);
407 + reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
409 + /* load the array into the ARL table */
410 + qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
413 +static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd,
419 + /* Set the command and FDB index */
420 + reg = QCA8K_ATU_FUNC_BUSY;
423 + reg |= QCA8K_ATU_FUNC_PORT_EN;
424 + reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port);
427 + /* Write the function register triggering the table access */
428 + ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
432 + /* wait for completion */
433 + ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
437 + /* Check for table full violation when adding an entry */
438 + if (cmd == QCA8K_FDB_LOAD) {
439 + ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®);
442 + if (reg & QCA8K_ATU_FUNC_FULL)
449 +static int qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb,
454 + qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
455 + ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
459 + return qca8k_fdb_read(priv, fdb);
462 +static int qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac,
463 + u16 port_mask, u16 vid, u8 aging)
467 + mutex_lock(&priv->reg_mutex);
468 + qca8k_fdb_write(priv, vid, port_mask, mac, aging);
469 + ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
470 + mutex_unlock(&priv->reg_mutex);
475 +static int qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac,
476 + u16 port_mask, u16 vid)
480 + mutex_lock(&priv->reg_mutex);
481 + qca8k_fdb_write(priv, vid, port_mask, mac, 0);
482 + ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
483 + mutex_unlock(&priv->reg_mutex);
488 +void qca8k_fdb_flush(struct qca8k_priv *priv)
490 + mutex_lock(&priv->reg_mutex);
491 + qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1);
492 + mutex_unlock(&priv->reg_mutex);
495 +static int qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
496 + const u8 *mac, u16 vid)
498 + struct qca8k_fdb fdb = { 0 };
501 + mutex_lock(&priv->reg_mutex);
503 + qca8k_fdb_write(priv, vid, 0, mac, 0);
504 + ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
508 + ret = qca8k_fdb_read(priv, &fdb);
512 + /* Rule exist. Delete first */
514 + ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
519 + /* Add port to fdb portmask */
520 + fdb.port_mask |= port_mask;
522 + qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
523 + ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
526 + mutex_unlock(&priv->reg_mutex);
530 +static int qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
531 + const u8 *mac, u16 vid)
533 + struct qca8k_fdb fdb = { 0 };
536 + mutex_lock(&priv->reg_mutex);
538 + qca8k_fdb_write(priv, vid, 0, mac, 0);
539 + ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
543 + /* Rule doesn't exist. Why delete? */
549 + ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
553 + /* Only port in the rule is this port. Don't re insert */
554 + if (fdb.port_mask == port_mask)
557 + /* Remove port from port mask */
558 + fdb.port_mask &= ~port_mask;
560 + qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
561 + ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
564 + mutex_unlock(&priv->reg_mutex);
568 int qca8k_mib_init(struct qca8k_priv *priv)
571 @@ -368,6 +573,15 @@ void qca8k_port_bridge_leave(struct dsa_
572 QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
575 +void qca8k_port_fast_age(struct dsa_switch *ds, int port)
577 + struct qca8k_priv *priv = ds->priv;
579 + mutex_lock(&priv->reg_mutex);
580 + qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
581 + mutex_unlock(&priv->reg_mutex);
584 int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
586 struct qca8k_priv *priv = ds->priv;
587 @@ -452,3 +666,78 @@ int qca8k_port_max_mtu(struct dsa_switch
589 return QCA8K_MAX_MTU;
592 +int qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
593 + u16 port_mask, u16 vid)
595 + /* Set the vid to the port vlan id if no vid is set */
597 + vid = QCA8K_PORT_VID_DEF;
599 + return qca8k_fdb_add(priv, addr, port_mask, vid,
600 + QCA8K_ATU_STATUS_STATIC);
603 +int qca8k_port_fdb_add(struct dsa_switch *ds, int port,
604 + const unsigned char *addr, u16 vid)
606 + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
607 + u16 port_mask = BIT(port);
609 + return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
612 +int qca8k_port_fdb_del(struct dsa_switch *ds, int port,
613 + const unsigned char *addr, u16 vid)
615 + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
616 + u16 port_mask = BIT(port);
619 + vid = QCA8K_PORT_VID_DEF;
621 + return qca8k_fdb_del(priv, addr, port_mask, vid);
624 +int qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
625 + dsa_fdb_dump_cb_t *cb, void *data)
627 + struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
628 + struct qca8k_fdb _fdb = { 0 };
629 + int cnt = QCA8K_NUM_FDB_RECORDS;
633 + mutex_lock(&priv->reg_mutex);
634 + while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
637 + is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
638 + ret = cb(_fdb.mac, _fdb.vid, is_static, data);
642 + mutex_unlock(&priv->reg_mutex);
647 +int qca8k_port_mdb_add(struct dsa_switch *ds, int port,
648 + const struct switchdev_obj_port_mdb *mdb)
650 + struct qca8k_priv *priv = ds->priv;
651 + const u8 *addr = mdb->addr;
652 + u16 vid = mdb->vid;
654 + return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
657 +int qca8k_port_mdb_del(struct dsa_switch *ds, int port,
658 + const struct switchdev_obj_port_mdb *mdb)
660 + struct qca8k_priv *priv = ds->priv;
661 + const u8 *addr = mdb->addr;
662 + u16 vid = mdb->vid;
664 + return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
666 --- a/drivers/net/dsa/qca/qca8k.h
667 +++ b/drivers/net/dsa/qca/qca8k.h
668 @@ -430,11 +430,9 @@ int qca8k_read(struct qca8k_priv *priv,
669 int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val);
670 int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val);
672 -int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
673 -int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
675 /* Common ops function */
676 int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask);
677 +void qca8k_fdb_flush(struct qca8k_priv *priv);
679 /* Common ethtool stats function */
680 void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data);
681 @@ -463,6 +461,23 @@ int qca8k_port_change_mtu(struct dsa_swi
682 int qca8k_port_max_mtu(struct dsa_switch *ds, int port);
684 /* Common fast age function */
685 +void qca8k_port_fast_age(struct dsa_switch *ds, int port);
686 int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs);
688 +/* Common FDB function */
689 +int qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
690 + u16 port_mask, u16 vid);
691 +int qca8k_port_fdb_add(struct dsa_switch *ds, int port,
692 + const unsigned char *addr, u16 vid);
693 +int qca8k_port_fdb_del(struct dsa_switch *ds, int port,
694 + const unsigned char *addr, u16 vid);
695 +int qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
696 + dsa_fdb_dump_cb_t *cb, void *data);
698 +/* Common MDB function */
699 +int qca8k_port_mdb_add(struct dsa_switch *ds, int port,
700 + const struct switchdev_obj_port_mdb *mdb);
701 +int qca8k_port_mdb_del(struct dsa_switch *ds, int port,
702 + const struct switchdev_obj_port_mdb *mdb);
704 #endif /* __QCA8K_H */