Merge branch 'mv88e6xxx-add-mab-offload-support'
Hans J. Schultz says: ==================== mv88e6xxx: Add MAB offload support This patch-set adds MAB [1] offload support in mv88e6xxx. Patch #1: Correct default return value for mv88e6xxx_port_bridge_flags. Patch #2: Shorten the locked section in mv88e6xxx_g1_atu_prob_irq_thread_fn(). Patch #3: The MAB implementation for mv88e6xxx. [1] https://git.kernel.org/netdev/net-next/c/4bf24ad09bc0 ==================== Link: https://lore.kernel.org/r/20230108094849.1789162-1-netdev@kapio-technology.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
a3ae16030a
|
@ -15,6 +15,7 @@ mv88e6xxx-objs += port_hidden.o
|
|||
mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o
|
||||
mv88e6xxx-objs += serdes.o
|
||||
mv88e6xxx-objs += smi.o
|
||||
mv88e6xxx-objs += switchdev.o
|
||||
mv88e6xxx-objs += trace.o
|
||||
|
||||
# for tracing framework to find trace.h
|
||||
|
|
|
@ -1728,11 +1728,11 @@ static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
|
||||
int (*cb)(struct mv88e6xxx_chip *chip,
|
||||
const struct mv88e6xxx_vtu_entry *entry,
|
||||
void *priv),
|
||||
void *priv)
|
||||
int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
|
||||
int (*cb)(struct mv88e6xxx_chip *chip,
|
||||
const struct mv88e6xxx_vtu_entry *entry,
|
||||
void *priv),
|
||||
void *priv)
|
||||
{
|
||||
struct mv88e6xxx_vtu_entry entry = {
|
||||
.vid = mv88e6xxx_max_vid(chip),
|
||||
|
@ -6526,7 +6526,7 @@ static int mv88e6xxx_port_pre_bridge_flags(struct dsa_switch *ds, int port,
|
|||
const struct mv88e6xxx_ops *ops;
|
||||
|
||||
if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
|
||||
BR_BCAST_FLOOD | BR_PORT_LOCKED))
|
||||
BR_BCAST_FLOOD | BR_PORT_LOCKED | BR_PORT_MAB))
|
||||
return -EINVAL;
|
||||
|
||||
ops = chip->info->ops;
|
||||
|
@ -6545,7 +6545,7 @@ static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port,
|
|||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
int err = -EOPNOTSUPP;
|
||||
int err = 0;
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
|
||||
|
@ -6584,6 +6584,12 @@ static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (flags.mask & BR_PORT_MAB) {
|
||||
bool mab = !!(flags.val & BR_PORT_MAB);
|
||||
|
||||
mv88e6xxx_port_set_mab(chip, port, mab);
|
||||
}
|
||||
|
||||
if (flags.mask & BR_PORT_LOCKED) {
|
||||
bool locked = !!(flags.val & BR_PORT_LOCKED);
|
||||
|
||||
|
|
|
@ -280,6 +280,9 @@ struct mv88e6xxx_port {
|
|||
unsigned int serdes_irq;
|
||||
char serdes_irq_name[64];
|
||||
struct devlink_region *region;
|
||||
|
||||
/* MacAuth Bypass control flag */
|
||||
bool mab;
|
||||
};
|
||||
|
||||
enum mv88e6xxx_region_id {
|
||||
|
@ -784,6 +787,12 @@ static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int po
|
|||
return (chip->info->invalid_port_mask & BIT(port)) != 0;
|
||||
}
|
||||
|
||||
static inline void mv88e6xxx_port_set_mab(struct mv88e6xxx_chip *chip,
|
||||
int port, bool mab)
|
||||
{
|
||||
chip->ports[port].mab = mab;
|
||||
}
|
||||
|
||||
int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
|
||||
int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
|
||||
int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
|
||||
|
@ -802,6 +811,12 @@ static inline void mv88e6xxx_reg_unlock(struct mv88e6xxx_chip *chip)
|
|||
mutex_unlock(&chip->reg_lock);
|
||||
}
|
||||
|
||||
int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
|
||||
int (*cb)(struct mv88e6xxx_chip *chip,
|
||||
const struct mv88e6xxx_vtu_entry *entry,
|
||||
void *priv),
|
||||
void *priv);
|
||||
|
||||
int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *bitmap);
|
||||
|
||||
#endif /* _MV88E6XXX_CHIP_H */
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "chip.h"
|
||||
#include "global1.h"
|
||||
#include "switchdev.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* Offset 0x01: ATU FID Register */
|
||||
|
@ -409,23 +410,25 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
|
|||
|
||||
err = mv88e6xxx_g1_read_atu_violation(chip);
|
||||
if (err)
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
|
||||
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_OP, &val);
|
||||
if (err)
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
|
||||
err = mv88e6xxx_g1_atu_fid_read(chip, &fid);
|
||||
if (err)
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
|
||||
err = mv88e6xxx_g1_atu_data_read(chip, &entry);
|
||||
if (err)
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
|
||||
err = mv88e6xxx_g1_atu_mac_read(chip, &entry);
|
||||
if (err)
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
||||
spid = entry.state;
|
||||
|
||||
|
@ -441,6 +444,13 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
|
|||
entry.portvec, entry.mac,
|
||||
fid);
|
||||
chip->ports[spid].atu_miss_violation++;
|
||||
|
||||
if (fid != MV88E6XXX_FID_STANDALONE && chip->ports[spid].mab) {
|
||||
err = mv88e6xxx_handle_miss_violation(chip, spid,
|
||||
&entry, fid);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) {
|
||||
|
@ -449,13 +459,13 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
|
|||
fid);
|
||||
chip->ports[spid].atu_full_violation++;
|
||||
}
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
out:
|
||||
out_unlock:
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
||||
out:
|
||||
dev_err(chip->dev, "ATU problem: error %d while handling interrupt\n",
|
||||
err);
|
||||
return IRQ_HANDLED;
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
// 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;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* switchdev.h
|
||||
*
|
||||
* Authors:
|
||||
* Hans J. Schultz <netdev@kapio-technology.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MV88E6XXX_SWITCHDEV_H_
|
||||
#define _MV88E6XXX_SWITCHDEV_H_
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
int mv88e6xxx_handle_miss_violation(struct mv88e6xxx_chip *chip, int port,
|
||||
struct mv88e6xxx_atu_entry *entry,
|
||||
u16 fid);
|
||||
|
||||
#endif /* _MV88E6XXX_SWITCHDEV_H_ */
|
Loading…
Reference in New Issue