diff options
author | Florian Fainelli <florian@openwrt.org> | 2010-04-07 19:50:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-07 19:50:58 -0400 |
commit | 3bcf8229a8c49769e48d3e0bd1e20d8e003f8106 (patch) | |
tree | d963b025f673f638a7e40d7c67a7cd4cb75f866e | |
parent | 005c93b5d876edf670b4c71d8dd79dc4e845a099 (diff) |
r6040: fix r6040_multicast_list
As reported in <https://bugzilla.kernel.org/show_bug.cgi?id=15355>, r6040_
multicast_list currently crashes. This is due a wrong maximum of multicast
entries. This patch fixes the following issues with multicast:
- number of maximum entries if off-by-one (4 instead of 3)
- the writing of the hash table index is not necessary and leads to invalid
values being written into the MCR1 register, so the MAC is simply put in a non
coherent state
- when we exceed the maximum number of mutlticast address, writing the
broadcast address should be done in registers MID_1{L,M,H} instead of
MID_O{L,M,H}, otherwise we would loose the adapter's MAC address
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/r6040.c | 11 |
1 files changed, 4 insertions, 7 deletions
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 15d5373dc8f3..1247bc6b19d4 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -135,7 +135,7 @@ | |||
135 | #define RX_DESC_SIZE (RX_DCNT * sizeof(struct r6040_descriptor)) | 135 | #define RX_DESC_SIZE (RX_DCNT * sizeof(struct r6040_descriptor)) |
136 | #define TX_DESC_SIZE (TX_DCNT * sizeof(struct r6040_descriptor)) | 136 | #define TX_DESC_SIZE (TX_DCNT * sizeof(struct r6040_descriptor)) |
137 | #define MBCR_DEFAULT 0x012A /* MAC Bus Control Register */ | 137 | #define MBCR_DEFAULT 0x012A /* MAC Bus Control Register */ |
138 | #define MCAST_MAX 4 /* Max number multicast addresses to filter */ | 138 | #define MCAST_MAX 3 /* Max number multicast addresses to filter */ |
139 | 139 | ||
140 | /* Descriptor status */ | 140 | /* Descriptor status */ |
141 | #define DSC_OWNER_MAC 0x8000 /* MAC is the owner of this descriptor */ | 141 | #define DSC_OWNER_MAC 0x8000 /* MAC is the owner of this descriptor */ |
@@ -983,9 +983,6 @@ static void r6040_multicast_list(struct net_device *dev) | |||
983 | crc >>= 26; | 983 | crc >>= 26; |
984 | hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); | 984 | hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); |
985 | } | 985 | } |
986 | /* Write the index of the hash table */ | ||
987 | for (i = 0; i < 4; i++) | ||
988 | iowrite16(hash_table[i] << 14, ioaddr + MCR1); | ||
989 | /* Fill the MAC hash tables with their values */ | 986 | /* Fill the MAC hash tables with their values */ |
990 | iowrite16(hash_table[0], ioaddr + MAR0); | 987 | iowrite16(hash_table[0], ioaddr + MAR0); |
991 | iowrite16(hash_table[1], ioaddr + MAR1); | 988 | iowrite16(hash_table[1], ioaddr + MAR1); |
@@ -1001,9 +998,9 @@ static void r6040_multicast_list(struct net_device *dev) | |||
1001 | iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); | 998 | iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); |
1002 | iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); | 999 | iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); |
1003 | } else { | 1000 | } else { |
1004 | iowrite16(0xffff, ioaddr + MID_0L + 8 * i); | 1001 | iowrite16(0xffff, ioaddr + MID_1L + 8 * i); |
1005 | iowrite16(0xffff, ioaddr + MID_0M + 8 * i); | 1002 | iowrite16(0xffff, ioaddr + MID_1M + 8 * i); |
1006 | iowrite16(0xffff, ioaddr + MID_0H + 8 * i); | 1003 | iowrite16(0xffff, ioaddr + MID_1H + 8 * i); |
1007 | } | 1004 | } |
1008 | i++; | 1005 | i++; |
1009 | } | 1006 | } |