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