Skip to content

Commit 368b1d9

Browse files
viviendavem330
authored andcommitted
net: dsa: mv88e6xxx: extend fid mask
The driver currently manages one FID per port (or bridge group), with a mask of DSA_MAX_PORTS bits, where 0 means that the FID is in use. The Marvell 88E6xxx switches support up to 4094 FIDs (from 1 to 0xfff; FID 0 means that multiple address databases are not being used). This patch changes the fid_mask for an fid_bitmap of 4096 bits. >From now on, FIDs 1 to num_ports are reserved for non-bridged ports and bridge groups (a bridge group gets the FID of its first member). The remaining bits will be reserved for VLAN entries. Signed-off-by: Vivien Didelot <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 55045dd commit 368b1d9

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

drivers/net/dsa/mv88e6xxx.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
10911091
ps->bridge_mask[fid] = br_port_mask;
10921092

10931093
if (fid != ps->fid[port]) {
1094-
ps->fid_mask |= 1 << ps->fid[port];
1094+
clear_bit(ps->fid[port], ps->fid_bitmap);
10951095
ps->fid[port] = fid;
10961096
ret = _mv88e6xxx_update_bridge_config(ds, fid);
10971097
}
@@ -1125,16 +1125,24 @@ int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
11251125

11261126
mutex_lock(&ps->smi_mutex);
11271127

1128-
newfid = __ffs(ps->fid_mask);
1128+
newfid = find_next_zero_bit(ps->fid_bitmap, VLAN_N_VID, 1);
1129+
if (unlikely(newfid > ps->num_ports)) {
1130+
netdev_err(ds->ports[port], "all first %d FIDs are used\n",
1131+
ps->num_ports);
1132+
ret = -ENOSPC;
1133+
goto unlock;
1134+
}
1135+
11291136
ps->fid[port] = newfid;
1130-
ps->fid_mask &= ~(1 << newfid);
1137+
set_bit(newfid, ps->fid_bitmap);
11311138
ps->bridge_mask[fid] &= ~(1 << port);
11321139
ps->bridge_mask[newfid] = 1 << port;
11331140

11341141
ret = _mv88e6xxx_update_bridge_config(ds, fid);
11351142
if (!ret)
11361143
ret = _mv88e6xxx_update_bridge_config(ds, newfid);
11371144

1145+
unlock:
11381146
mutex_unlock(&ps->smi_mutex);
11391147

11401148
return ret;
@@ -1552,9 +1560,9 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
15521560
* ports, and allow each of the 'real' ports to only talk to
15531561
* the upstream port.
15541562
*/
1555-
fid = __ffs(ps->fid_mask);
1563+
fid = port + 1;
15561564
ps->fid[port] = fid;
1557-
ps->fid_mask &= ~(1 << fid);
1565+
set_bit(fid, ps->fid_bitmap);
15581566

15591567
if (!dsa_is_cpu_port(ds, port))
15601568
ps->bridge_mask[fid] = 1 << port;
@@ -1853,8 +1861,6 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds)
18531861

18541862
ps->id = REG_READ(REG_PORT(0), PORT_SWITCH_ID) & 0xfff0;
18551863

1856-
ps->fid_mask = (1 << DSA_MAX_PORTS) - 1;
1857-
18581864
INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
18591865

18601866
name = kasprintf(GFP_KERNEL, "dsa%d", ds->index);

drivers/net/dsa/mv88e6xxx.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#ifndef __MV88E6XXX_H
1212
#define __MV88E6XXX_H
1313

14+
#include <linux/if_vlan.h>
15+
1416
#ifndef UINT64_MAX
1517
#define UINT64_MAX (u64)(~((u64)0))
1618
#endif
@@ -347,9 +349,9 @@ struct mv88e6xxx_priv_state {
347349

348350
/* hw bridging */
349351

350-
u32 fid_mask;
351-
u8 fid[DSA_MAX_PORTS];
352-
u16 bridge_mask[DSA_MAX_PORTS];
352+
DECLARE_BITMAP(fid_bitmap, VLAN_N_VID); /* FIDs 1 to 4095 available */
353+
u16 fid[DSA_MAX_PORTS]; /* per (non-bridged) port FID */
354+
u16 bridge_mask[DSA_MAX_PORTS]; /* br groups (indexed by FID) */
353355

354356
unsigned long port_state_update_mask;
355357
u8 port_state[DSA_MAX_PORTS];

0 commit comments

Comments
 (0)