Skip to content

Commit 7888173

Browse files
committed
Merge branch 'net-xilinx-axienet-multicast-fixes-and-improvements'
Sean Anderson says: ==================== net: xilinx: axienet: Multicast fixes and improvements This series has a few small patches improving the handling of multicast addresses. In particular, it makes the driver a whole lot less spammy, and adjusts things so we aren't in promiscuous mode when we have more than four multicast addresses (a common occurance on modern systems). As the hardware has a 4-entry CAM, the ideal method would be to "pack" multiple addresses into one CAM entry. Something like: entry.address = address[0] | address[1]; entry.mask = ~(address[0] ^ address[1]); Which would make the entry match both addresses (along with some others that would need to be filtered in software). Mapping addresses to entries in an efficient way is a bit tricky. If anyone knows of an in-tree example of something like this, I'd be glad to hear about it. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 5efc962 + 749e67d commit 7888173

File tree

2 files changed

+22
-21
lines changed

2 files changed

+22
-21
lines changed

drivers/net/ethernet/xilinx/xilinx_axienet.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@
175175
#define XAE_FFE_OFFSET 0x0000070C /* Frame Filter Enable */
176176
#define XAE_AF0_OFFSET 0x00000710 /* Address Filter 0 */
177177
#define XAE_AF1_OFFSET 0x00000714 /* Address Filter 1 */
178+
#define XAE_AM0_OFFSET 0x00000750 /* Frame Filter Mask Value Bytes 3-0 */
179+
#define XAE_AM1_OFFSET 0x00000754 /* Frame Filter Mask Value Bytes 7-4 */
178180

179181
#define XAE_TX_VLAN_DATA_OFFSET 0x00004000 /* TX VLAN data table address */
180182
#define XAE_RX_VLAN_DATA_OFFSET 0x00008000 /* RX VLAN data table address */

drivers/net/ethernet/xilinx/xilinx_axienet_main.c

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -437,24 +437,27 @@ static void axienet_set_multicast_list(struct net_device *ndev)
437437
u32 reg, af0reg, af1reg;
438438
struct axienet_local *lp = netdev_priv(ndev);
439439

440-
if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) ||
441-
netdev_mc_count(ndev) > XAE_MULTICAST_CAM_TABLE_NUM) {
442-
/* We must make the kernel realize we had to move into
443-
* promiscuous mode. If it was a promiscuous mode request
444-
* the flag is already set. If not we set it.
445-
*/
446-
ndev->flags |= IFF_PROMISC;
447-
reg = axienet_ior(lp, XAE_FMI_OFFSET);
440+
reg = axienet_ior(lp, XAE_FMI_OFFSET);
441+
reg &= ~XAE_FMI_PM_MASK;
442+
if (ndev->flags & IFF_PROMISC)
448443
reg |= XAE_FMI_PM_MASK;
444+
else
445+
reg &= ~XAE_FMI_PM_MASK;
446+
axienet_iow(lp, XAE_FMI_OFFSET, reg);
447+
448+
if (ndev->flags & IFF_ALLMULTI ||
449+
netdev_mc_count(ndev) > XAE_MULTICAST_CAM_TABLE_NUM) {
450+
reg &= 0xFFFFFF00;
449451
axienet_iow(lp, XAE_FMI_OFFSET, reg);
450-
dev_info(&ndev->dev, "Promiscuous mode enabled.\n");
452+
axienet_iow(lp, XAE_AF0_OFFSET, 1); /* Multicast bit */
453+
axienet_iow(lp, XAE_AF1_OFFSET, 0);
454+
axienet_iow(lp, XAE_AM0_OFFSET, 1); /* ditto */
455+
axienet_iow(lp, XAE_AM1_OFFSET, 0);
456+
axienet_iow(lp, XAE_FFE_OFFSET, 1);
457+
i = 1;
451458
} else if (!netdev_mc_empty(ndev)) {
452459
struct netdev_hw_addr *ha;
453460

454-
reg = axienet_ior(lp, XAE_FMI_OFFSET);
455-
reg &= ~XAE_FMI_PM_MASK;
456-
axienet_iow(lp, XAE_FMI_OFFSET, reg);
457-
458461
netdev_for_each_mc_addr(ha, ndev) {
459462
if (i >= XAE_MULTICAST_CAM_TABLE_NUM)
460463
break;
@@ -467,25 +470,21 @@ static void axienet_set_multicast_list(struct net_device *ndev)
467470
af1reg = (ha->addr[4]);
468471
af1reg |= (ha->addr[5] << 8);
469472

470-
reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00;
473+
reg &= 0xFFFFFF00;
471474
reg |= i;
472475

473476
axienet_iow(lp, XAE_FMI_OFFSET, reg);
474477
axienet_iow(lp, XAE_AF0_OFFSET, af0reg);
475478
axienet_iow(lp, XAE_AF1_OFFSET, af1reg);
479+
axienet_iow(lp, XAE_AM0_OFFSET, 0xffffffff);
480+
axienet_iow(lp, XAE_AM1_OFFSET, 0x0000ffff);
476481
axienet_iow(lp, XAE_FFE_OFFSET, 1);
477482
i++;
478483
}
479-
} else {
480-
reg = axienet_ior(lp, XAE_FMI_OFFSET);
481-
reg &= ~XAE_FMI_PM_MASK;
482-
483-
axienet_iow(lp, XAE_FMI_OFFSET, reg);
484-
dev_info(&ndev->dev, "Promiscuous mode disabled.\n");
485484
}
486485

487486
for (; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) {
488-
reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00;
487+
reg &= 0xFFFFFF00;
489488
reg |= i;
490489
axienet_iow(lp, XAE_FMI_OFFSET, reg);
491490
axienet_iow(lp, XAE_FFE_OFFSET, 0);

0 commit comments

Comments
 (0)