Skip to content

Commit ebe60f3

Browse files
bwhacksgregkh
authored andcommitted
r6040: Fix multicast filter some more
[ Upstream commit e226930 ] This code has been broken forever, but in several different and creative ways. So far as I can work out, the R6040 MAC filter has 4 exact-match entries, the first of which the driver uses for its assigned unicast address, plus a 64-entry hash-based filter for multicast addresses (maybe unicast as well?). The original version of this code would write the first 4 multicast addresses as exact-match entries from offset 1 (bug coolya#1: there is no entry 4 so this could write to some PHY registers). It would fill the remainder of the exact-match entries with the broadcast address (bug coolya#2: this would overwrite the last used entry). If more than 4 multicast addresses were configured, it would set up the hash table, write some random crap to the MAC control register (bug coolya#3) and finally walk off the end of the list when filling the exact-match entries (bug coolya#4). All of this seems to be pointless, since it sets the promiscuous bit when the interface is made promiscuous or if >4 multicast addresses are enabled, and never clears it (bug coolya#5, masking bug coolya#2). The recent(ish) changes to the multicast list fixed bug coolya#4, but completely removed the limit on iteration over the exact-match entries (bug coolya#6). Bug coolya#4 was reported as <https://bugzilla.kernel.org/show_bug.cgi?id=15355> and more recently as <http://bugs.debian.org/600155>. Florian Fainelli attempted to fix these in commit 3bcf822, but that actually dealt with bugs coolya#1-3, bug coolya#4 having been fixed in mainline at that point. That commit fixes the most important current bug coolya#6. Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
1 parent 2556c3e commit ebe60f3

1 file changed

Lines changed: 12 additions & 10 deletions

File tree

drivers/net/r6040.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -988,16 +988,18 @@ static void r6040_multicast_list(struct net_device *dev)
988988
/* Multicast Address 1~4 case */
989989
i = 0;
990990
netdev_for_each_mc_addr(ha, dev) {
991-
if (i < MCAST_MAX) {
992-
adrp = (u16 *) ha->addr;
993-
iowrite16(adrp[0], ioaddr + MID_1L + 8 * i);
994-
iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
995-
iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
996-
} else {
997-
iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
998-
iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
999-
iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
1000-
}
991+
if (i >= MCAST_MAX)
992+
break;
993+
adrp = (u16 *) ha->addr;
994+
iowrite16(adrp[0], ioaddr + MID_1L + 8 * i);
995+
iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
996+
iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
997+
i++;
998+
}
999+
while (i < MCAST_MAX) {
1000+
iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
1001+
iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
1002+
iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
10011003
i++;
10021004
}
10031005
}

0 commit comments

Comments
 (0)