1 --- a/drivers/net/r6040.c
2 +++ b/drivers/net/r6040.c
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 @@ -928,78 +930,96 @@ static void r6040_multicast_list(struct
14 struct r6040_private *lp = netdev_priv(dev);
15 void __iomem *ioaddr = lp->base;
19 struct dev_mc_list *dmi = dev->mc_list;
22 + u16 hash_table[4] = { 0 };
24 + spin_lock_irqsave(&lp->lock, flags);
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);
33 - /* Promiscous Mode */
34 - spin_lock_irqsave(&lp->lock, flags);
36 /* Clear AMCP & PROM bits */
37 - reg = ioread16(ioaddr) & ~0x0120;
38 + lp->mcr0 = ioread16(ioaddr + MCR0) & ~(PROMISC | HASH_EN);
40 + /* Promiscuous mode */
41 if (dev->flags & IFF_PROMISC) {
44 + lp->mcr0 |= PROMISC;
46 - /* Too many multicast addresses
47 - * accept all traffic */
48 - else if ((dev->mc_count > MCAST_MAX)
49 - || (dev->flags & IFF_ALLMULTI))
52 - iowrite16(reg, ioaddr);
53 - spin_unlock_irqrestore(&lp->lock, flags);
55 - /* Build the hash table */
56 - if (dev->mc_count > MCAST_MAX) {
59 + /* Enable multicast hash table function to
60 + * receive all multicast packets. */
61 + else if (dev->flags & IFF_ALLMULTI) {
62 + lp->mcr0 |= HASH_EN;
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);
70 for (i = 0; i < 4; i++)
72 + hash_table[i] = 0xffff;
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) {
81 + while (i < dev->mc_count) {
82 + u16 *adrp = (u16 *)dmi->dmi_addr;
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);
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);
97 + /* Otherwise, Enable multicast hash table function. */
103 + lp->mcr0 |= HASH_EN;
105 - crc = ether_crc_le(6, addrs);
106 + for (i = 0; i < MCAST_MAX ; i++) {
107 + iowrite16(0, ioaddr + MID_1L + 8 * i);
108 + iowrite16(0, ioaddr + MID_1M + 8 * i);
109 + iowrite16(0, ioaddr + MID_1H + 8 * i);
112 + /* Build multicast hash table */
113 + for (i = 0; i < dev->mc_count; i++) {
114 + u8 *addrs = dmi->dmi_addr;
117 + crc = ether_crc(ETH_ALEN, addrs);
119 - hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
120 + hash_table[crc >> 4] |= 1 << (crc & 0xf);
122 - /* Write the index of the hash table */
123 - for (i = 0; i < 4; i++)
124 - iowrite16(hash_table[i] << 14, ioaddr + MCR1);
125 - /* Fill the MAC hash tables with their values */
126 - iowrite16(hash_table[0], ioaddr + MAR0);
127 - iowrite16(hash_table[1], ioaddr + MAR1);
128 - iowrite16(hash_table[2], ioaddr + MAR2);
129 - iowrite16(hash_table[3], ioaddr + MAR3);
131 - /* Multicast Address 1~4 case */
132 - for (i = 0, dmi; (i < dev->mc_count) && (i < MCAST_MAX); i++) {
133 - adrp = (u16 *)dmi->dmi_addr;
134 - iowrite16(adrp[0], ioaddr + MID_1L + 8*i);
135 - iowrite16(adrp[1], ioaddr + MID_1M + 8*i);
136 - iowrite16(adrp[2], ioaddr + MID_1H + 8*i);
139 - for (i = dev->mc_count; i < MCAST_MAX; i++) {
140 - iowrite16(0xffff, ioaddr + MID_0L + 8*i);
141 - iowrite16(0xffff, ioaddr + MID_0M + 8*i);
142 - iowrite16(0xffff, ioaddr + MID_0H + 8*i);
144 + iowrite16(lp->mcr0, ioaddr + MCR0);
146 + /* Fill the MAC hash tables with their values */
147 + if (lp->mcr0 && HASH_EN) {
148 + iowrite16(hash_table[0], ioaddr + MAR0);
149 + iowrite16(hash_table[1], ioaddr + MAR1);
150 + iowrite16(hash_table[2], ioaddr + MAR2);
151 + iowrite16(hash_table[3], ioaddr + MAR3);
154 + spin_unlock_irqrestore(&lp->lock, flags);
157 static void netdev_get_drvinfo(struct net_device *dev,