Root/target/linux/rdc/patches-2.6.32/015-r6040_fix_multicast.patch

1--- a/drivers/net/r6040.c
2+++ b/drivers/net/r6040.c
3@@ -70,6 +70,8 @@
4 
5 /* MAC registers */
6 #define MCR0 0x00 /* Control register 0 */
7+#define PROMISC 0x0020 /* Promiscuous mode */
8+#define HASH_EN 0x0100 /* Enable multicast hash table function */
9 #define MCR1 0x04 /* Control register 1 */
10 #define MAC_RST 0x0001 /* Reset the MAC */
11 #define MBCR 0x08 /* Bus control */
12@@ -837,76 +839,96 @@
13 {
14     struct r6040_private *lp = netdev_priv(dev);
15     void __iomem *ioaddr = lp->base;
16- u16 *adrp;
17- u16 reg;
18     unsigned long flags;
19     struct dev_mc_list *dmi = dev->mc_list;
20     int i;
21+ u16 *adrp;
22+ u16 hash_table[4] = { 0 };
23+
24+ spin_lock_irqsave(&lp->lock, flags);
25 
26- /* MAC Address */
27+ /* Keep our MAC Address */
28     adrp = (u16 *)dev->dev_addr;
29     iowrite16(adrp[0], ioaddr + MID_0L);
30     iowrite16(adrp[1], ioaddr + MID_0M);
31     iowrite16(adrp[2], ioaddr + MID_0H);
32 
33- /* Promiscous Mode */
34- spin_lock_irqsave(&lp->lock, flags);
35-
36     /* Clear AMCP & PROM bits */
37- reg = ioread16(ioaddr) & ~0x0120;
38+ lp->mcr0 = ioread16(ioaddr + MCR0) & ~(PROMISC | HASH_EN);
39+
40+ /* Promiscuous mode */
41     if (dev->flags & IFF_PROMISC) {
42- reg |= 0x0020;
43- lp->mcr0 |= 0x0020;
44+ lp->mcr0 |= PROMISC;
45     }
46- /* Too many multicast addresses
47- * accept all traffic */
48- else if ((dev->mc_count > MCAST_MAX)
49- || (dev->flags & IFF_ALLMULTI))
50- reg |= 0x0020;
51 
52- iowrite16(reg, ioaddr);
53- spin_unlock_irqrestore(&lp->lock, flags);
54-
55- /* Build the hash table */
56- if (dev->mc_count > MCAST_MAX) {
57- u16 hash_table[4];
58- u32 crc;
59+ /* Enable multicast hash table function to
60+ * receive all multicast packets. */
61+ else if (dev->flags & IFF_ALLMULTI) {
62+ lp->mcr0 |= HASH_EN;
63+
64+ for (i = 0; i < MCAST_MAX ; i++) {
65+ iowrite16(0, ioaddr + MID_1L + 8 * i);
66+ iowrite16(0, ioaddr + MID_1M + 8 * i);
67+ iowrite16(0, ioaddr + MID_1H + 8 * i);
68+ }
69 
70         for (i = 0; i < 4; i++)
71- hash_table[i] = 0;
72+ hash_table[i] = 0xffff;
73+ }
74 
75- for (i = 0; i < dev->mc_count; i++) {
76- char *addrs = dmi->dmi_addr;
77+ /* Use internal multicast address registers if the number of
78+ * multicast addresses is not greater than MCAST_MAX. */
79+ else if (dev->mc_count <= MCAST_MAX) {
80+ i = 0;
81+ while (i < dev->mc_count) {
82+ u16 *adrp = (u16 *)dmi->dmi_addr;
83 
84             dmi = dmi->next;
85+ iowrite16(adrp[0], ioaddr + MID_1L + 8 * i);
86+ iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
87+ iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
88+ i++;
89+ }
90+ while (i < MCAST_MAX) {
91+ iowrite16(0, ioaddr + MID_1L + 8 * i);
92+ iowrite16(0, ioaddr + MID_1M + 8 * i);
93+ iowrite16(0, ioaddr + MID_1H + 8 * i);
94+ i++;
95+ }
96+ }
97+ /* Otherwise, Enable multicast hash table function. */
98+ else {
99+ u32 crc;
100+
101+ lp->mcr0 |= HASH_EN;
102 
103- if (!(*addrs & 1))
104- continue;
105+ for (i = 0; i < MCAST_MAX ; i++) {
106+ iowrite16(0, ioaddr + MID_1L + 8 * i);
107+ iowrite16(0, ioaddr + MID_1M + 8 * i);
108+ iowrite16(0, ioaddr + MID_1H + 8 * i);
109+ }
110+
111+ /* Build multicast hash table */
112+ for (i = 0; i < dev->mc_count; i++) {
113+ u8 *addrs = dmi->dmi_addr;
114+ dmi = dmi->next;
115 
116- crc = ether_crc_le(6, addrs);
117+ crc = ether_crc(ETH_ALEN, addrs);
118             crc >>= 26;
119- hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
120+ hash_table[crc >> 4] |= 1 << (crc & 0xf);
121         }
122- /* Fill the MAC hash tables with their values */
123+ }
124+ iowrite16(lp->mcr0, ioaddr + MCR0);
125+
126+ /* Fill the MAC hash tables with their values */
127+ if (lp->mcr0 && HASH_EN) {
128         iowrite16(hash_table[0], ioaddr + MAR0);
129         iowrite16(hash_table[1], ioaddr + MAR1);
130         iowrite16(hash_table[2], ioaddr + MAR2);
131         iowrite16(hash_table[3], ioaddr + MAR3);
132     }
133- /* Multicast Address 1~4 case */
134- dmi = dev->mc_list;
135- for (i = 0, dmi; (i < dev->mc_count) && (i < MCAST_MAX); i++) {
136- adrp = (u16 *)dmi->dmi_addr;
137- iowrite16(adrp[0], ioaddr + MID_1L + 8*i);
138- iowrite16(adrp[1], ioaddr + MID_1M + 8*i);
139- iowrite16(adrp[2], ioaddr + MID_1H + 8*i);
140- dmi = dmi->next;
141- }
142- for (i = dev->mc_count; i < MCAST_MAX; i++) {
143- iowrite16(0xffff, ioaddr + MID_1L + 8*i);
144- iowrite16(0xffff, ioaddr + MID_1M + 8*i);
145- iowrite16(0xffff, ioaddr + MID_1H + 8*i);
146- }
147+
148+ spin_unlock_irqrestore(&lp->lock, flags);
149 }
150 
151 static void netdev_get_drvinfo(struct net_device *dev,
152

Archive Download this file



interactive