Skip to content

Commit a3ae160

Browse files
author
Paolo Abeni
committed
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/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 07445f3 + 830763b commit a3ae160

File tree

6 files changed

+148
-14
lines changed

6 files changed

+148
-14
lines changed

drivers/net/dsa/mv88e6xxx/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ mv88e6xxx-objs += port_hidden.o
1515
mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o
1616
mv88e6xxx-objs += serdes.o
1717
mv88e6xxx-objs += smi.o
18+
mv88e6xxx-objs += switchdev.o
1819
mv88e6xxx-objs += trace.o
1920

2021
# for tracing framework to find trace.h

drivers/net/dsa/mv88e6xxx/chip.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,11 +1728,11 @@ static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
17281728
return err;
17291729
}
17301730

1731-
static int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
1732-
int (*cb)(struct mv88e6xxx_chip *chip,
1733-
const struct mv88e6xxx_vtu_entry *entry,
1734-
void *priv),
1735-
void *priv)
1731+
int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
1732+
int (*cb)(struct mv88e6xxx_chip *chip,
1733+
const struct mv88e6xxx_vtu_entry *entry,
1734+
void *priv),
1735+
void *priv)
17361736
{
17371737
struct mv88e6xxx_vtu_entry entry = {
17381738
.vid = mv88e6xxx_max_vid(chip),
@@ -6526,7 +6526,7 @@ static int mv88e6xxx_port_pre_bridge_flags(struct dsa_switch *ds, int port,
65266526
const struct mv88e6xxx_ops *ops;
65276527

65286528
if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
6529-
BR_BCAST_FLOOD | BR_PORT_LOCKED))
6529+
BR_BCAST_FLOOD | BR_PORT_LOCKED | BR_PORT_MAB))
65306530
return -EINVAL;
65316531

65326532
ops = chip->info->ops;
@@ -6545,7 +6545,7 @@ static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port,
65456545
struct netlink_ext_ack *extack)
65466546
{
65476547
struct mv88e6xxx_chip *chip = ds->priv;
6548-
int err = -EOPNOTSUPP;
6548+
int err = 0;
65496549

65506550
mv88e6xxx_reg_lock(chip);
65516551

@@ -6584,6 +6584,12 @@ static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port,
65846584
goto out;
65856585
}
65866586

6587+
if (flags.mask & BR_PORT_MAB) {
6588+
bool mab = !!(flags.val & BR_PORT_MAB);
6589+
6590+
mv88e6xxx_port_set_mab(chip, port, mab);
6591+
}
6592+
65876593
if (flags.mask & BR_PORT_LOCKED) {
65886594
bool locked = !!(flags.val & BR_PORT_LOCKED);
65896595

drivers/net/dsa/mv88e6xxx/chip.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,9 @@ struct mv88e6xxx_port {
280280
unsigned int serdes_irq;
281281
char serdes_irq_name[64];
282282
struct devlink_region *region;
283+
284+
/* MacAuth Bypass control flag */
285+
bool mab;
283286
};
284287

285288
enum mv88e6xxx_region_id {
@@ -784,6 +787,12 @@ static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int po
784787
return (chip->info->invalid_port_mask & BIT(port)) != 0;
785788
}
786789

790+
static inline void mv88e6xxx_port_set_mab(struct mv88e6xxx_chip *chip,
791+
int port, bool mab)
792+
{
793+
chip->ports[port].mab = mab;
794+
}
795+
787796
int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
788797
int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
789798
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)
802811
mutex_unlock(&chip->reg_lock);
803812
}
804813

814+
int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
815+
int (*cb)(struct mv88e6xxx_chip *chip,
816+
const struct mv88e6xxx_vtu_entry *entry,
817+
void *priv),
818+
void *priv);
819+
805820
int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *bitmap);
806821

807822
#endif /* _MV88E6XXX_CHIP_H */

drivers/net/dsa/mv88e6xxx/global1_atu.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "chip.h"
1414
#include "global1.h"
15+
#include "switchdev.h"
1516
#include "trace.h"
1617

1718
/* Offset 0x01: ATU FID Register */
@@ -409,23 +410,25 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
409410

410411
err = mv88e6xxx_g1_read_atu_violation(chip);
411412
if (err)
412-
goto out;
413+
goto out_unlock;
413414

414415
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_OP, &val);
415416
if (err)
416-
goto out;
417+
goto out_unlock;
417418

418419
err = mv88e6xxx_g1_atu_fid_read(chip, &fid);
419420
if (err)
420-
goto out;
421+
goto out_unlock;
421422

422423
err = mv88e6xxx_g1_atu_data_read(chip, &entry);
423424
if (err)
424-
goto out;
425+
goto out_unlock;
425426

426427
err = mv88e6xxx_g1_atu_mac_read(chip, &entry);
427428
if (err)
428-
goto out;
429+
goto out_unlock;
430+
431+
mv88e6xxx_reg_unlock(chip);
429432

430433
spid = entry.state;
431434

@@ -441,6 +444,13 @@ static irqreturn_t mv88e6xxx_g1_atu_prob_irq_thread_fn(int irq, void *dev_id)
441444
entry.portvec, entry.mac,
442445
fid);
443446
chip->ports[spid].atu_miss_violation++;
447+
448+
if (fid != MV88E6XXX_FID_STANDALONE && chip->ports[spid].mab) {
449+
err = mv88e6xxx_handle_miss_violation(chip, spid,
450+
&entry, fid);
451+
if (err)
452+
goto out;
453+
}
444454
}
445455

446456
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)
449459
fid);
450460
chip->ports[spid].atu_full_violation++;
451461
}
452-
mv88e6xxx_reg_unlock(chip);
453462

454463
return IRQ_HANDLED;
455464

456-
out:
465+
out_unlock:
457466
mv88e6xxx_reg_unlock(chip);
458467

468+
out:
459469
dev_err(chip->dev, "ATU problem: error %d while handling interrupt\n",
460470
err);
461471
return IRQ_HANDLED;

drivers/net/dsa/mv88e6xxx/switchdev.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* switchdev.c
4+
*
5+
* Authors:
6+
* Hans J. Schultz <[email protected]>
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+
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+
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+
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+
}

drivers/net/dsa/mv88e6xxx/switchdev.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later
2+
*
3+
* switchdev.h
4+
*
5+
* Authors:
6+
* Hans J. Schultz <[email protected]>
7+
*
8+
*/
9+
10+
#ifndef _MV88E6XXX_SWITCHDEV_H_
11+
#define _MV88E6XXX_SWITCHDEV_H_
12+
13+
#include "chip.h"
14+
15+
int mv88e6xxx_handle_miss_violation(struct mv88e6xxx_chip *chip, int port,
16+
struct mv88e6xxx_atu_entry *entry,
17+
u16 fid);
18+
19+
#endif /* _MV88E6XXX_SWITCHDEV_H_ */

0 commit comments

Comments
 (0)