diff options
author | Arun Ramadoss <arun.ramadoss@microchip.com> | 2022-06-17 14:12:53 +0530 |
---|---|---|
committer | Paolo Abeni <pabeni@redhat.com> | 2022-06-21 15:26:45 +0200 |
commit | 980c7d171d3a6e777715ca968f97090448d6ff1d (patch) | |
tree | 19e4ec75652b149b0d278effc297fdd5a29fd139 /drivers/net/dsa/microchip/ksz8795.c | |
parent | 7012033ce10e0968e6cb82709aa0ed7f2080b61e (diff) |
net: dsa: microchip: update the ksz_port_mdb_add/del
ksz_mdb_add/del in ksz_common.c is specific for the ksz8795.c file. The
ksz9477 has its separate ksz9477_port_mdb_add/del functions. This patch
moves the ksz8795 specific mdb functionality from ksz_common to ksz8795.
And this dsa_switch_ops hooks for ksz8795/ksz9477 are invoked through
the ksz_port_mdb_add/del.
Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'drivers/net/dsa/microchip/ksz8795.c')
-rw-r--r-- | drivers/net/dsa/microchip/ksz8795.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index 440779a2cca6..7ebed00777b9 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -953,6 +953,80 @@ static void ksz8_flush_dyn_mac_table(struct ksz_device *dev, int port) } } +static int ksz8_mdb_add(struct ksz_device *dev, int port, + const struct switchdev_obj_port_mdb *mdb, + struct dsa_db db) +{ + struct alu_struct alu; + int index; + int empty = 0; + + alu.port_forward = 0; + for (index = 0; index < dev->info->num_statics; index++) { + if (!dev->dev_ops->r_sta_mac_table(dev, index, &alu)) { + /* Found one already in static MAC table. */ + if (!memcmp(alu.mac, mdb->addr, ETH_ALEN) && + alu.fid == mdb->vid) + break; + /* Remember the first empty entry. */ + } else if (!empty) { + empty = index + 1; + } + } + + /* no available entry */ + if (index == dev->info->num_statics && !empty) + return -ENOSPC; + + /* add entry */ + if (index == dev->info->num_statics) { + index = empty - 1; + memset(&alu, 0, sizeof(alu)); + memcpy(alu.mac, mdb->addr, ETH_ALEN); + alu.is_static = true; + } + alu.port_forward |= BIT(port); + if (mdb->vid) { + alu.is_use_fid = true; + + /* Need a way to map VID to FID. */ + alu.fid = mdb->vid; + } + dev->dev_ops->w_sta_mac_table(dev, index, &alu); + + return 0; +} + +static int ksz8_mdb_del(struct ksz_device *dev, int port, + const struct switchdev_obj_port_mdb *mdb, + struct dsa_db db) +{ + struct alu_struct alu; + int index; + + for (index = 0; index < dev->info->num_statics; index++) { + if (!dev->dev_ops->r_sta_mac_table(dev, index, &alu)) { + /* Found one already in static MAC table. */ + if (!memcmp(alu.mac, mdb->addr, ETH_ALEN) && + alu.fid == mdb->vid) + break; + } + } + + /* no available entry */ + if (index == dev->info->num_statics) + goto exit; + + /* clear port */ + alu.port_forward &= ~BIT(port); + if (!alu.port_forward) + alu.is_static = false; + dev->dev_ops->w_sta_mac_table(dev, index, &alu); + +exit: + return 0; +} + static int ksz8_port_vlan_filtering(struct ksz_device *dev, int port, bool flag, struct netlink_ext_ack *extack) { @@ -1449,6 +1523,8 @@ static const struct ksz_dev_ops ksz8_dev_ops = { .r_mib_pkt = ksz8_r_mib_pkt, .freeze_mib = ksz8_freeze_mib, .port_init_cnt = ksz8_port_init_cnt, + .mdb_add = ksz8_mdb_add, + .mdb_del = ksz8_mdb_del, .vlan_filtering = ksz8_port_vlan_filtering, .vlan_add = ksz8_port_vlan_add, .vlan_del = ksz8_port_vlan_del, |