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 <davem@davemloft.net>
This commit is contained in:
commit
d5812a8627
@ -1474,6 +1474,10 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op)
|
||||
reg |= ARLTBL_RW;
|
||||
else
|
||||
reg &= ~ARLTBL_RW;
|
||||
if (dev->vlan_enabled)
|
||||
reg &= ~ARLTBL_IVL_SVL_SELECT;
|
||||
else
|
||||
reg |= ARLTBL_IVL_SVL_SELECT;
|
||||
b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_RW_CTRL, reg);
|
||||
|
||||
return b53_arl_op_wait(dev);
|
||||
@ -1483,6 +1487,7 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,
|
||||
u16 vid, struct b53_arl_entry *ent, u8 *idx,
|
||||
bool is_valid)
|
||||
{
|
||||
DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
@ -1490,6 +1495,8 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bitmap_zero(free_bins, dev->num_arl_entries);
|
||||
|
||||
/* Read the bins */
|
||||
for (i = 0; i < dev->num_arl_entries; i++) {
|
||||
u64 mac_vid;
|
||||
@ -1501,13 +1508,24 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,
|
||||
B53_ARLTBL_DATA_ENTRY(i), &fwd_entry);
|
||||
b53_arl_to_entry(ent, mac_vid, fwd_entry);
|
||||
|
||||
if (!(fwd_entry & ARLTBL_VALID))
|
||||
if (!(fwd_entry & ARLTBL_VALID)) {
|
||||
set_bit(i, free_bins);
|
||||
continue;
|
||||
}
|
||||
if ((mac_vid & ARLTBL_MAC_MASK) != mac)
|
||||
continue;
|
||||
if (dev->vlan_enabled &&
|
||||
((mac_vid >> ARLTBL_VID_S) & ARLTBL_VID_MASK) != vid)
|
||||
continue;
|
||||
*idx = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bitmap_weight(free_bins, dev->num_arl_entries) == 0)
|
||||
return -ENOSPC;
|
||||
|
||||
*idx = find_first_bit(free_bins, dev->num_arl_entries);
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
@ -1537,10 +1555,21 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
|
||||
if (op)
|
||||
return ret;
|
||||
|
||||
/* We could not find a matching MAC, so reset to a new entry */
|
||||
if (ret) {
|
||||
switch (ret) {
|
||||
case -ENOSPC:
|
||||
dev_dbg(dev->dev, "{%pM,%.4d} no space left in ARL\n",
|
||||
addr, vid);
|
||||
return is_valid ? ret : 0;
|
||||
case -ENOENT:
|
||||
/* We could not find a matching MAC, so reset to a new entry */
|
||||
dev_dbg(dev->dev, "{%pM,%.4d} not found, using idx: %d\n",
|
||||
addr, vid, idx);
|
||||
fwd_entry = 0;
|
||||
idx = 1;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(dev->dev, "{%pM,%.4d} found, using idx: %d\n",
|
||||
addr, vid, idx);
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
ent.is_valid = !!(ent.port);
|
||||
}
|
||||
|
||||
ent.is_valid = is_valid;
|
||||
ent.vid = vid;
|
||||
ent.is_static = true;
|
||||
ent.is_age = false;
|
||||
|
@ -292,6 +292,7 @@
|
||||
/* ARL Table Read/Write Register (8 bit) */
|
||||
#define B53_ARLTBL_RW_CTRL 0x00
|
||||
#define ARLTBL_RW BIT(0)
|
||||
#define ARLTBL_IVL_SVL_SELECT BIT(6)
|
||||
#define ARLTBL_START_DONE BIT(7)
|
||||
|
||||
/* MAC Address Index Register (48 bit) */
|
||||
@ -304,7 +305,7 @@
|
||||
*
|
||||
* BCM5325 and BCM5365 share most definitions below
|
||||
*/
|
||||
#define B53_ARLTBL_MAC_VID_ENTRY(n) (0x10 * (n))
|
||||
#define B53_ARLTBL_MAC_VID_ENTRY(n) ((0x10 * (n)) + 0x10)
|
||||
#define ARLTBL_MAC_MASK 0xffffffffffffULL
|
||||
#define ARLTBL_VID_S 48
|
||||
#define ARLTBL_VID_MASK_25 0xff
|
||||
@ -316,13 +317,16 @@
|
||||
#define ARLTBL_VALID_25 BIT(63)
|
||||
|
||||
/* ARL Table Data Entry N Registers (32 bit) */
|
||||
#define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x08)
|
||||
#define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x18)
|
||||
#define ARLTBL_DATA_PORT_ID_MASK 0x1ff
|
||||
#define ARLTBL_TC(tc) ((3 & tc) << 11)
|
||||
#define ARLTBL_AGE BIT(14)
|
||||
#define ARLTBL_STATIC BIT(15)
|
||||
#define ARLTBL_VALID BIT(16)
|
||||
|
||||
/* Maximum number of bin entries in the ARL for all switches */
|
||||
#define B53_ARLTBL_MAX_BIN_ENTRIES 4
|
||||
|
||||
/* ARL Search Control Register (8 bit) */
|
||||
#define B53_ARL_SRCH_CTL 0x50
|
||||
#define B53_ARL_SRCH_CTL_25 0x20
|
||||
|
Loading…
Reference in New Issue
Block a user