diff options
author | Paolo Abeni <pabeni@redhat.com> | 2023-01-10 11:58:41 +0100 |
---|---|---|
committer | Paolo Abeni <pabeni@redhat.com> | 2023-01-10 11:58:42 +0100 |
commit | a3ae16030a0320229df10cedfeff1f80df26ee76 (patch) | |
tree | 83e12848caf711d096f3c149413b9675ad21160a /drivers/net/dsa/mv88e6xxx/switchdev.c | |
parent | 07445f3c7ca1cfe490353be52bda91d9e6745ef4 (diff) | |
parent | 830763b9672036178288f3a09e963646f1d3cafa (diff) |
Merge branch 'mv88e6xxx-add-mab-offload-support'
Hans J. Schultz says:
====================
mv88e6xxx: Add MAB offload support
This patch-set adds MAB [1] offload support in mv88e6xxx.
Patch #1: Correct default return value for mv88e6xxx_port_bridge_flags.
Patch #2: Shorten the locked section in
mv88e6xxx_g1_atu_prob_irq_thread_fn().
Patch #3: The MAB implementation for mv88e6xxx.
[1] https://git.kernel.org/netdev/net-next/c/4bf24ad09bc0
====================
Link: https://lore.kernel.org/r/20230108094849.1789162-1-netdev@kapio-technology.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/switchdev.c')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/switchdev.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/switchdev.c b/drivers/net/dsa/mv88e6xxx/switchdev.c new file mode 100644 index 000000000000..4c346a884fb2 --- /dev/null +++ b/drivers/net/dsa/mv88e6xxx/switchdev.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * switchdev.c + * + * Authors: + * Hans J. Schultz <netdev@kapio-technology.com> + * + */ + +#include <net/switchdev.h> +#include "chip.h" +#include "global1.h" +#include "switchdev.h" + +struct mv88e6xxx_fid_search_ctx { + u16 fid_search; + u16 vid_found; +}; + +static int __mv88e6xxx_find_vid(struct mv88e6xxx_chip *chip, + const struct mv88e6xxx_vtu_entry *entry, + void *priv) +{ + struct mv88e6xxx_fid_search_ctx *ctx = priv; + + if (ctx->fid_search == entry->fid) { + ctx->vid_found = entry->vid; + return 1; + } + + return 0; +} + +static int mv88e6xxx_find_vid(struct mv88e6xxx_chip *chip, u16 fid, u16 *vid) +{ + struct mv88e6xxx_fid_search_ctx ctx; + int err; + + ctx.fid_search = fid; + mv88e6xxx_reg_lock(chip); + err = mv88e6xxx_vtu_walk(chip, __mv88e6xxx_find_vid, &ctx); + mv88e6xxx_reg_unlock(chip); + if (err < 0) + return err; + if (err == 1) + *vid = ctx.vid_found; + else + return -ENOENT; + + return 0; +} + +int mv88e6xxx_handle_miss_violation(struct mv88e6xxx_chip *chip, int port, + struct mv88e6xxx_atu_entry *entry, u16 fid) +{ + struct switchdev_notifier_fdb_info info = { + .addr = entry->mac, + .locked = true, + }; + struct net_device *brport; + struct dsa_port *dp; + u16 vid; + int err; + + err = mv88e6xxx_find_vid(chip, fid, &vid); + if (err) + return err; + + info.vid = vid; + dp = dsa_to_port(chip->ds, port); + + rtnl_lock(); + brport = dsa_port_to_bridge_port(dp); + if (!brport) { + rtnl_unlock(); + return -ENODEV; + } + err = call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE, + brport, &info.info, NULL); + rtnl_unlock(); + + return err; +} |