Skip to content

Commit

Permalink
Merge branch 'mv88e6xxx-add-mab-offload-support'
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paolo Abeni committed Jan 10, 2023
2 parents 07445f3 + 830763b commit a3ae160
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 14 deletions.
1 change: 1 addition & 0 deletions drivers/net/dsa/mv88e6xxx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 13 additions & 7 deletions drivers/net/dsa/mv88e6xxx/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -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);

Expand Down
15 changes: 15 additions & 0 deletions drivers/net/dsa/mv88e6xxx/chip.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand All @@ -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 */
24 changes: 17 additions & 7 deletions drivers/net/dsa/mv88e6xxx/global1_atu.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "chip.h"
#include "global1.h"
#include "switchdev.h"
#include "trace.h"

/* Offset 0x01: ATU FID Register */
Expand Down Expand Up @@ -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;

Expand All @@ -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) {
Expand All @@ -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;
Expand Down
83 changes: 83 additions & 0 deletions drivers/net/dsa/mv88e6xxx/switchdev.c
Original file line number Diff line number Diff line change
@@ -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;
}
19 changes: 19 additions & 0 deletions drivers/net/dsa/mv88e6xxx/switchdev.h
Original file line number Diff line number Diff line change
@@ -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_ */

0 comments on commit a3ae160

Please sign in to comment.