source: branches/backfire/target/linux/rdc/patches-2.6.30/015-r6040_fix_multicast.patch @ 28466

Last change on this file since 28466 was 28466, checked in by florian, 5 years ago

[rdc] fix 015-r6040_fix_multicast.patch not applying

File size: 4.4 KB
  • drivers/net/r6040.c

    a b  
    6969 
    7070/* MAC registers */ 
    7171#define MCR0            0x00    /* Control register 0 */ 
     72#define  PROMISC        0x0020  /* Promiscuous mode */ 
     73#define  HASH_EN        0x0100  /* Enable multicast hash table function */ 
    7274#define MCR1            0x04    /* Control register 1 */ 
    7375#define  MAC_RST        0x0001  /* Reset the MAC */ 
    7476#define MBCR            0x08    /* Bus control */ 
    static void r6040_multicast_list(struct 
    928930{ 
    929931        struct r6040_private *lp = netdev_priv(dev); 
    930932        void __iomem *ioaddr = lp->base; 
    931         u16 *adrp; 
    932         u16 reg; 
    933933        unsigned long flags; 
    934934        struct dev_mc_list *dmi = dev->mc_list; 
    935935        int i; 
     936        u16 *adrp; 
     937        u16 hash_table[4] = { 0 }; 
     938 
     939        spin_lock_irqsave(&lp->lock, flags); 
    936940 
    937         /* MAC Address */ 
     941        /* Keep our MAC Address */ 
    938942        adrp = (u16 *)dev->dev_addr; 
    939943        iowrite16(adrp[0], ioaddr + MID_0L); 
    940944        iowrite16(adrp[1], ioaddr + MID_0M); 
    941945        iowrite16(adrp[2], ioaddr + MID_0H); 
    942946 
    943         /* Promiscous Mode */ 
    944         spin_lock_irqsave(&lp->lock, flags); 
    945  
    946947        /* Clear AMCP & PROM bits */ 
    947         reg = ioread16(ioaddr) & ~0x0120; 
     948        lp->mcr0 = ioread16(ioaddr + MCR0) & ~(PROMISC | HASH_EN); 
     949 
     950        /* Promiscuous mode */ 
    948951        if (dev->flags & IFF_PROMISC) { 
    949                 reg |= 0x0020; 
    950                 lp->mcr0 |= 0x0020; 
     952                lp->mcr0 |= PROMISC; 
    951953        } 
    952         /* Too many multicast addresses 
    953          * accept all traffic */ 
    954         else if ((dev->mc_count > MCAST_MAX) 
    955                 || (dev->flags & IFF_ALLMULTI)) 
    956                 reg |= 0x0020; 
    957954 
    958         iowrite16(reg, ioaddr); 
    959         spin_unlock_irqrestore(&lp->lock, flags); 
    960  
    961         /* Build the hash table */ 
    962         if (dev->mc_count > MCAST_MAX) { 
    963                 u16 hash_table[4]; 
    964                 u32 crc; 
     955        /* Enable multicast hash table function to 
     956         * receive all multicast packets. */ 
     957        else if (dev->flags & IFF_ALLMULTI) { 
     958                lp->mcr0 |= HASH_EN; 
     959 
     960                for (i = 0; i < MCAST_MAX ; i++) { 
     961                        iowrite16(0, ioaddr + MID_1L + 8 * i); 
     962                        iowrite16(0, ioaddr + MID_1M + 8 * i); 
     963                        iowrite16(0, ioaddr + MID_1H + 8 * i); 
     964                } 
    965965 
    966966                for (i = 0; i < 4; i++) 
    967                         hash_table[i] = 0; 
     967                        hash_table[i] = 0xffff; 
     968        } 
    968969 
    969                 for (i = 0; i < dev->mc_count; i++) { 
    970                         char *addrs = dmi->dmi_addr; 
     970        /* Use internal multicast address registers if the number of 
     971         * multicast addresses is not greater than MCAST_MAX. */ 
     972        else if (dev->mc_count <= MCAST_MAX) { 
     973                i = 0; 
     974                while (i < dev->mc_count) { 
     975                        u16 *adrp = (u16 *)dmi->dmi_addr; 
    971976 
    972977                        dmi = dmi->next; 
     978                        iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); 
     979                        iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); 
     980                        iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); 
     981                        i++; 
     982                } 
     983                while (i < MCAST_MAX) { 
     984                        iowrite16(0, ioaddr + MID_1L + 8 * i); 
     985                        iowrite16(0, ioaddr + MID_1M + 8 * i); 
     986                        iowrite16(0, ioaddr + MID_1H + 8 * i); 
     987                        i++; 
     988                } 
     989        } 
     990        /* Otherwise, Enable multicast hash table function. */ 
     991        else { 
     992                u32 crc; 
    973993 
    974                         if (!(*addrs & 1)) 
    975                                 continue; 
     994                lp->mcr0 |= HASH_EN; 
    976995 
    977                         crc = ether_crc_le(6, addrs); 
     996                for (i = 0; i < MCAST_MAX ; i++) { 
     997                        iowrite16(0, ioaddr + MID_1L + 8 * i); 
     998                        iowrite16(0, ioaddr + MID_1M + 8 * i); 
     999                        iowrite16(0, ioaddr + MID_1H + 8 * i); 
     1000                } 
     1001 
     1002                /* Build multicast hash table */ 
     1003                for (i = 0; i < dev->mc_count; i++) { 
     1004                        u8 *addrs = dmi->dmi_addr; 
     1005                        dmi = dmi->next; 
     1006 
     1007                        crc = ether_crc(ETH_ALEN, addrs); 
    9781008                        crc >>= 26; 
    979                         hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); 
     1009                        hash_table[crc >> 4] |= 1 << (crc & 0xf); 
    9801010                } 
    981                 /* Write the index of the hash table */ 
    982                 for (i = 0; i < 4; i++) 
    983                         iowrite16(hash_table[i] << 14, ioaddr + MCR1); 
    984                 /* Fill the MAC hash tables with their values */ 
    985                 iowrite16(hash_table[0], ioaddr + MAR0); 
    986                 iowrite16(hash_table[1], ioaddr + MAR1); 
    987                 iowrite16(hash_table[2], ioaddr + MAR2); 
    988                 iowrite16(hash_table[3], ioaddr + MAR3); 
    989         } 
    990         /* Multicast Address 1~4 case */ 
    991         for (i = 0, dmi; (i < dev->mc_count) && (i < MCAST_MAX); i++) { 
    992                 adrp = (u16 *)dmi->dmi_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                 dmi = dmi->next; 
    997         } 
    998         for (i = dev->mc_count; i < MCAST_MAX; i++) { 
    999                 iowrite16(0xffff, ioaddr + MID_0L + 8*i); 
    1000                 iowrite16(0xffff, ioaddr + MID_0M + 8*i); 
    1001                 iowrite16(0xffff, ioaddr + MID_0H + 8*i); 
    10021011        } 
     1012        iowrite16(lp->mcr0, ioaddr + MCR0); 
     1013 
     1014        /* Fill the MAC hash tables with their values */ 
     1015        if (lp->mcr0 && HASH_EN) { 
     1016                iowrite16(hash_table[0], ioaddr + MAR0); 
     1017                iowrite16(hash_table[1], ioaddr + MAR1); 
     1018                iowrite16(hash_table[2], ioaddr + MAR2); 
     1019                iowrite16(hash_table[3], ioaddr + MAR3); 
     1020        } 
     1021 
     1022        spin_unlock_irqrestore(&lp->lock, flags); 
    10031023} 
    10041024 
    10051025static void netdev_get_drvinfo(struct net_device *dev, 
Note: See TracBrowser for help on using the repository browser.