Skip to content

Commit d5812a8

Browse files
committed
Merge branch 'net-dsa-b53-Various-ARL-fixes'
Florian Fainelli says: ==================== net: dsa: b53: Various ARL fixes This patch series fixes a number of short comings in the existing b53 driver ARL management logic in particular: - we were not looking up the {MAC,VID} tuples against their VID, despite having VLANs enabled - the MDB entries (multicast) would lose their validity as soon as a single port in the vector would leave the entry - the ARL was currently under utilized because we would always place new entries in bin index #1, instead of using all possible bins available, thus reducing the ARL effective size by 50% or 75% depending on the switch generation - it was possible to overwrite the ARL entries because no proper space verification was done This patch series addresses all of these issues. Changes in v2: - added a new patch to correctly flip invidual VLAN learning vs. shared VLAN learning depending on the global VLAN state - added Andrew's R-b tags for patches which did not change - corrected some verbosity and minor issues in patch #4 to match caller expectations, also avoid a variable length DECLARE_BITMAP() call ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 87f78f2 + 64fec94 commit d5812a8

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed

drivers/net/dsa/b53/b53_common.c

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,10 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op)
14741474
reg |= ARLTBL_RW;
14751475
else
14761476
reg &= ~ARLTBL_RW;
1477+
if (dev->vlan_enabled)
1478+
reg &= ~ARLTBL_IVL_SVL_SELECT;
1479+
else
1480+
reg |= ARLTBL_IVL_SVL_SELECT;
14771481
b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_RW_CTRL, reg);
14781482

14791483
return b53_arl_op_wait(dev);
@@ -1483,13 +1487,16 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,
14831487
u16 vid, struct b53_arl_entry *ent, u8 *idx,
14841488
bool is_valid)
14851489
{
1490+
DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
14861491
unsigned int i;
14871492
int ret;
14881493

14891494
ret = b53_arl_op_wait(dev);
14901495
if (ret)
14911496
return ret;
14921497

1498+
bitmap_zero(free_bins, dev->num_arl_entries);
1499+
14931500
/* Read the bins */
14941501
for (i = 0; i < dev->num_arl_entries; i++) {
14951502
u64 mac_vid;
@@ -1501,13 +1508,24 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,
15011508
B53_ARLTBL_DATA_ENTRY(i), &fwd_entry);
15021509
b53_arl_to_entry(ent, mac_vid, fwd_entry);
15031510

1504-
if (!(fwd_entry & ARLTBL_VALID))
1511+
if (!(fwd_entry & ARLTBL_VALID)) {
1512+
set_bit(i, free_bins);
15051513
continue;
1514+
}
15061515
if ((mac_vid & ARLTBL_MAC_MASK) != mac)
15071516
continue;
1517+
if (dev->vlan_enabled &&
1518+
((mac_vid >> ARLTBL_VID_S) & ARLTBL_VID_MASK) != vid)
1519+
continue;
15081520
*idx = i;
1521+
return 0;
15091522
}
15101523

1524+
if (bitmap_weight(free_bins, dev->num_arl_entries) == 0)
1525+
return -ENOSPC;
1526+
1527+
*idx = find_first_bit(free_bins, dev->num_arl_entries);
1528+
15111529
return -ENOENT;
15121530
}
15131531

@@ -1537,10 +1555,21 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
15371555
if (op)
15381556
return ret;
15391557

1540-
/* We could not find a matching MAC, so reset to a new entry */
1541-
if (ret) {
1558+
switch (ret) {
1559+
case -ENOSPC:
1560+
dev_dbg(dev->dev, "{%pM,%.4d} no space left in ARL\n",
1561+
addr, vid);
1562+
return is_valid ? ret : 0;
1563+
case -ENOENT:
1564+
/* We could not find a matching MAC, so reset to a new entry */
1565+
dev_dbg(dev->dev, "{%pM,%.4d} not found, using idx: %d\n",
1566+
addr, vid, idx);
15421567
fwd_entry = 0;
1543-
idx = 1;
1568+
break;
1569+
default:
1570+
dev_dbg(dev->dev, "{%pM,%.4d} found, using idx: %d\n",
1571+
addr, vid, idx);
1572+
break;
15441573
}
15451574

15461575
/* For multicast address, the port is a bitmask and the validity
@@ -1558,7 +1587,6 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
15581587
ent.is_valid = !!(ent.port);
15591588
}
15601589

1561-
ent.is_valid = is_valid;
15621590
ent.vid = vid;
15631591
ent.is_static = true;
15641592
ent.is_age = false;

drivers/net/dsa/b53/b53_regs.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@
292292
/* ARL Table Read/Write Register (8 bit) */
293293
#define B53_ARLTBL_RW_CTRL 0x00
294294
#define ARLTBL_RW BIT(0)
295+
#define ARLTBL_IVL_SVL_SELECT BIT(6)
295296
#define ARLTBL_START_DONE BIT(7)
296297

297298
/* MAC Address Index Register (48 bit) */
@@ -304,7 +305,7 @@
304305
*
305306
* BCM5325 and BCM5365 share most definitions below
306307
*/
307-
#define B53_ARLTBL_MAC_VID_ENTRY(n) (0x10 * (n))
308+
#define B53_ARLTBL_MAC_VID_ENTRY(n) ((0x10 * (n)) + 0x10)
308309
#define ARLTBL_MAC_MASK 0xffffffffffffULL
309310
#define ARLTBL_VID_S 48
310311
#define ARLTBL_VID_MASK_25 0xff
@@ -316,13 +317,16 @@
316317
#define ARLTBL_VALID_25 BIT(63)
317318

318319
/* ARL Table Data Entry N Registers (32 bit) */
319-
#define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x08)
320+
#define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x18)
320321
#define ARLTBL_DATA_PORT_ID_MASK 0x1ff
321322
#define ARLTBL_TC(tc) ((3 & tc) << 11)
322323
#define ARLTBL_AGE BIT(14)
323324
#define ARLTBL_STATIC BIT(15)
324325
#define ARLTBL_VALID BIT(16)
325326

327+
/* Maximum number of bin entries in the ARL for all switches */
328+
#define B53_ARLTBL_MAX_BIN_ENTRIES 4
329+
326330
/* ARL Search Control Register (8 bit) */
327331
#define B53_ARL_SRCH_CTL 0x50
328332
#define B53_ARL_SRCH_CTL_25 0x20

0 commit comments

Comments
 (0)