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
__mv88e6xxx_find_vid(struct mv88e6xxx_chip * chip,const struct mv88e6xxx_vtu_entry * entry,void * priv)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
mv88e6xxx_find_vid(struct mv88e6xxx_chip * chip,u16 fid,u16 * vid)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
mv88e6xxx_handle_miss_violation(struct mv88e6xxx_chip * chip,int port,struct mv88e6xxx_atu_entry * entry,u16 fid)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