Skip to content

Commit 6344dbd

Browse files
ffainellidavem330
authored andcommitted
net: dsa: b53: Rework ARL bin logic
When asking the ARL to read a MAC address, we will get a number of bins returned in a single read. Out of those bins, there can essentially be 3 states: - all bins are full, we have no space left, and we can either replace an existing address or return that full condition - the MAC address was found, then we need to return its bin index and modify that one, and only that one - the MAC address was not found and we have a least one bin free, we use that bin index location then The code would unfortunately fail on all counts. Fixes: 1da6df8 ("net: dsa: b53: Implement ARL add/del/dump operations") Signed-off-by: Florian Fainelli <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c2e77a1 commit 6344dbd

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

drivers/net/dsa/b53/b53_common.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,13 +1483,16 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,
14831483
u16 vid, struct b53_arl_entry *ent, u8 *idx,
14841484
bool is_valid)
14851485
{
1486+
DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
14861487
unsigned int i;
14871488
int ret;
14881489

14891490
ret = b53_arl_op_wait(dev);
14901491
if (ret)
14911492
return ret;
14921493

1494+
bitmap_zero(free_bins, dev->num_arl_entries);
1495+
14931496
/* Read the bins */
14941497
for (i = 0; i < dev->num_arl_entries; i++) {
14951498
u64 mac_vid;
@@ -1501,16 +1504,24 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,
15011504
B53_ARLTBL_DATA_ENTRY(i), &fwd_entry);
15021505
b53_arl_to_entry(ent, mac_vid, fwd_entry);
15031506

1504-
if (!(fwd_entry & ARLTBL_VALID))
1507+
if (!(fwd_entry & ARLTBL_VALID)) {
1508+
set_bit(i, free_bins);
15051509
continue;
1510+
}
15061511
if ((mac_vid & ARLTBL_MAC_MASK) != mac)
15071512
continue;
15081513
if (dev->vlan_enabled &&
15091514
((mac_vid >> ARLTBL_VID_S) & ARLTBL_VID_MASK) != vid)
15101515
continue;
15111516
*idx = i;
1517+
return 0;
15121518
}
15131519

1520+
if (bitmap_weight(free_bins, dev->num_arl_entries) == 0)
1521+
return -ENOSPC;
1522+
1523+
*idx = find_first_bit(free_bins, dev->num_arl_entries);
1524+
15141525
return -ENOENT;
15151526
}
15161527

@@ -1540,10 +1551,21 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
15401551
if (op)
15411552
return ret;
15421553

1543-
/* We could not find a matching MAC, so reset to a new entry */
1544-
if (ret) {
1554+
switch (ret) {
1555+
case -ENOSPC:
1556+
dev_dbg(dev->dev, "{%pM,%.4d} no space left in ARL\n",
1557+
addr, vid);
1558+
return is_valid ? ret : 0;
1559+
case -ENOENT:
1560+
/* We could not find a matching MAC, so reset to a new entry */
1561+
dev_dbg(dev->dev, "{%pM,%.4d} not found, using idx: %d\n",
1562+
addr, vid, idx);
15451563
fwd_entry = 0;
1546-
idx = 1;
1564+
break;
1565+
default:
1566+
dev_dbg(dev->dev, "{%pM,%.4d} found, using idx: %d\n",
1567+
addr, vid, idx);
1568+
break;
15471569
}
15481570

15491571
/* For multicast address, the port is a bitmask and the validity

drivers/net/dsa/b53/b53_regs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,9 @@
323323
#define ARLTBL_STATIC BIT(15)
324324
#define ARLTBL_VALID BIT(16)
325325

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

0 commit comments

Comments
 (0)