| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- // 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;
- }
|