1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * switchdev.c 4 * 5 * Authors: 6 * Hans J. Schultz <netdev@kapio-technology.com> 7 * 8 */ 9 10 #include <net/switchdev.h> 11 #include "chip.h" 12 #include "global1.h" 13 #include "switchdev.h" 14 15 struct mv88e6xxx_fid_search_ctx { 16 u16 fid_search; 17 u16 vid_found; 18 }; 19 20 static int __mv88e6xxx_find_vid(struct mv88e6xxx_chip *chip, 21 const struct mv88e6xxx_vtu_entry *entry, 22 void *priv) 23 { 24 struct mv88e6xxx_fid_search_ctx *ctx = priv; 25 26 if (ctx->fid_search == entry->fid) { 27 ctx->vid_found = entry->vid; 28 return 1; 29 } 30 31 return 0; 32 } 33 34 static int mv88e6xxx_find_vid(struct mv88e6xxx_chip *chip, u16 fid, u16 *vid) 35 { 36 struct mv88e6xxx_fid_search_ctx ctx; 37 int err; 38 39 ctx.fid_search = fid; 40 mv88e6xxx_reg_lock(chip); 41 err = mv88e6xxx_vtu_walk(chip, __mv88e6xxx_find_vid, &ctx); 42 mv88e6xxx_reg_unlock(chip); 43 if (err < 0) 44 return err; 45 if (err == 1) 46 *vid = ctx.vid_found; 47 else 48 return -ENOENT; 49 50 return 0; 51 } 52 53 int mv88e6xxx_handle_miss_violation(struct mv88e6xxx_chip *chip, int port, 54 struct mv88e6xxx_atu_entry *entry, u16 fid) 55 { 56 struct switchdev_notifier_fdb_info info = { 57 .addr = entry->mac, 58 .locked = true, 59 }; 60 struct net_device *brport; 61 struct dsa_port *dp; 62 u16 vid; 63 int err; 64 65 err = mv88e6xxx_find_vid(chip, fid, &vid); 66 if (err) 67 return err; 68 69 info.vid = vid; 70 dp = dsa_to_port(chip->ds, port); 71 72 rtnl_lock(); 73 brport = dsa_port_to_bridge_port(dp); 74 if (!brport) { 75 rtnl_unlock(); 76 return -ENODEV; 77 } 78 err = call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE, 79 brport, &info.info, NULL); 80 rtnl_unlock(); 81 82 return err; 83 } 84