diff options
| author | Dmitry Torokhov <[email protected]> | 2023-05-01 15:20:08 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-05-01 15:20:08 -0700 | 
| commit | 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e (patch) | |
| tree | d57f3a63479a07b4e0cece029886e76e04feb984 /drivers/net/dsa/mv88e6xxx/switchdev.c | |
| parent | 5dc63e56a9cf8df0b59c234a505a1653f1bdf885 (diff) | |
| parent | 53bea86b5712c7491bb3dae12e271666df0a308c (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.4 merge window.
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		<[email protected]> + * + */ + +#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; +}  |