Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+39 -7
+33 -5
drivers/net/dsa/b53/b53_common.c
··· 1474 1474 reg |= ARLTBL_RW; 1475 1475 else 1476 1476 reg &= ~ARLTBL_RW; 1477 + if (dev->vlan_enabled) 1478 + reg &= ~ARLTBL_IVL_SVL_SELECT; 1479 + else 1480 + reg |= ARLTBL_IVL_SVL_SELECT; 1477 1481 b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_RW_CTRL, reg); 1478 1482 1479 1483 return b53_arl_op_wait(dev); ··· 1487 1483 u16 vid, struct b53_arl_entry *ent, u8 *idx, 1488 1484 bool is_valid) 1489 1485 { 1486 + DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); 1490 1487 unsigned int i; 1491 1488 int ret; 1492 1489 1493 1490 ret = b53_arl_op_wait(dev); 1494 1491 if (ret) 1495 1492 return ret; 1493 + 1494 + bitmap_zero(free_bins, dev->num_arl_entries); 1496 1495 1497 1496 /* Read the bins */ 1498 1497 for (i = 0; i < dev->num_arl_entries; i++) { ··· 1508 1501 B53_ARLTBL_DATA_ENTRY(i), &fwd_entry); 1509 1502 b53_arl_to_entry(ent, mac_vid, fwd_entry); 1510 1503 1511 - if (!(fwd_entry & ARLTBL_VALID)) 1504 + if (!(fwd_entry & ARLTBL_VALID)) { 1505 + set_bit(i, free_bins); 1512 1506 continue; 1507 + } 1513 1508 if ((mac_vid & ARLTBL_MAC_MASK) != mac) 1514 1509 continue; 1510 + if (dev->vlan_enabled && 1511 + ((mac_vid >> ARLTBL_VID_S) & ARLTBL_VID_MASK) != vid) 1512 + continue; 1515 1513 *idx = i; 1514 + return 0; 1516 1515 } 1516 + 1517 + if (bitmap_weight(free_bins, dev->num_arl_entries) == 0) 1518 + return -ENOSPC; 1519 + 1520 + *idx = find_first_bit(free_bins, dev->num_arl_entries); 1517 1521 1518 1522 return -ENOENT; 1519 1523 } ··· 1555 1537 if (op) 1556 1538 return ret; 1557 1539 1558 - /* We could not find a matching MAC, so reset to a new entry */ 1559 - if (ret) { 1540 + switch (ret) { 1541 + case -ENOSPC: 1542 + dev_dbg(dev->dev, "{%pM,%.4d} no space left in ARL\n", 1543 + addr, vid); 1544 + return is_valid ? ret : 0; 1545 + case -ENOENT: 1546 + /* We could not find a matching MAC, so reset to a new entry */ 1547 + dev_dbg(dev->dev, "{%pM,%.4d} not found, using idx: %d\n", 1548 + addr, vid, idx); 1560 1549 fwd_entry = 0; 1561 - idx = 1; 1550 + break; 1551 + default: 1552 + dev_dbg(dev->dev, "{%pM,%.4d} found, using idx: %d\n", 1553 + addr, vid, idx); 1554 + break; 1562 1555 } 1563 1556 1564 1557 /* For multicast address, the port is a bitmask and the validity ··· 1587 1558 ent.is_valid = !!(ent.port); 1588 1559 } 1589 1560 1590 - ent.is_valid = is_valid; 1591 1561 ent.vid = vid; 1592 1562 ent.is_static = true; 1593 1563 ent.is_age = false;
+6 -2
drivers/net/dsa/b53/b53_regs.h
··· 292 292 /* ARL Table Read/Write Register (8 bit) */ 293 293 #define B53_ARLTBL_RW_CTRL 0x00 294 294 #define ARLTBL_RW BIT(0) 295 + #define ARLTBL_IVL_SVL_SELECT BIT(6) 295 296 #define ARLTBL_START_DONE BIT(7) 296 297 297 298 /* MAC Address Index Register (48 bit) */ ··· 305 304 * 306 305 * BCM5325 and BCM5365 share most definitions below 307 306 */ 308 - #define B53_ARLTBL_MAC_VID_ENTRY(n) (0x10 * (n)) 307 + #define B53_ARLTBL_MAC_VID_ENTRY(n) ((0x10 * (n)) + 0x10) 309 308 #define ARLTBL_MAC_MASK 0xffffffffffffULL 310 309 #define ARLTBL_VID_S 48 311 310 #define ARLTBL_VID_MASK_25 0xff ··· 317 316 #define ARLTBL_VALID_25 BIT(63) 318 317 319 318 /* ARL Table Data Entry N Registers (32 bit) */ 320 - #define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x08) 319 + #define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x18) 321 320 #define ARLTBL_DATA_PORT_ID_MASK 0x1ff 322 321 #define ARLTBL_TC(tc) ((3 & tc) << 11) 323 322 #define ARLTBL_AGE BIT(14) 324 323 #define ARLTBL_STATIC BIT(15) 325 324 #define ARLTBL_VALID BIT(16) 325 + 326 + /* Maximum number of bin entries in the ARL for all switches */ 327 + #define B53_ARLTBL_MAX_BIN_ENTRIES 4 326 328 327 329 /* ARL Search Control Register (8 bit) */ 328 330 #define B53_ARL_SRCH_CTL 0x50