diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 776077ec1a23..01c2e2d83e76 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -400,41 +400,50 @@ static void dwmac4_set_filter(struct mac_device_info *hw, struct net_device *dev) { void __iomem *ioaddr = (void __iomem *)dev->base_addr; - unsigned int value = 0; + int numhashregs = (hw->multicast_filter_bins >> 5); + int mcbitslog2 = hw->mcast_bits_log2; + unsigned int value; + int i; + value = readl(ioaddr + GMAC_PACKET_FILTER); + value &= ~GMAC_PACKET_FILTER_HMC; + value &= ~GMAC_PACKET_FILTER_HPF; + value &= ~GMAC_PACKET_FILTER_PCF; + value &= ~GMAC_PACKET_FILTER_PM; + value &= ~GMAC_PACKET_FILTER_PR; if (dev->flags & IFF_PROMISC) { value = GMAC_PACKET_FILTER_PR | GMAC_PACKET_FILTER_PCF; } else if ((dev->flags & IFF_ALLMULTI) || - (netdev_mc_count(dev) > HASH_TABLE_SIZE)) { + (netdev_mc_count(dev) > hw->multicast_filter_bins)) { /* Pass all multi */ - value = GMAC_PACKET_FILTER_PM; - /* Set the 64 bits of the HASH tab. To be updated if taller - * hash table is used - */ - writel(0xffffffff, ioaddr + GMAC_HASH_TAB_0_31); - writel(0xffffffff, ioaddr + GMAC_HASH_TAB_32_63); + value |= GMAC_PACKET_FILTER_PM; + /* Set all the bits of the HASH tab */ + for (i = 0; i < numhashregs; i++) + writel(0xffffffff, ioaddr + GMAC_HASH_TAB(i)); } else if (!netdev_mc_empty(dev)) { - u32 mc_filter[2]; struct netdev_hw_addr *ha; + u32 mc_filter[8]; /* Hash filter for multicast */ - value = GMAC_PACKET_FILTER_HMC; + value |= GMAC_PACKET_FILTER_HMC; memset(mc_filter, 0, sizeof(mc_filter)); netdev_for_each_mc_addr(ha, dev) { - /* The upper 6 bits of the calculated CRC are used to - * index the content of the Hash Table Reg 0 and 1. + /* The upper n bits of the calculated CRC are used to + * index the contents of the hash table. The number of + * bits used depends on the hardware configuration + * selected at core configuration time. */ - int bit_nr = - (bitrev32(~crc32_le(~0, ha->addr, 6)) >> 26); - /* The most significant bit determines the register - * to use while the other 5 bits determines the bit - * within the selected register + int bit_nr = bitrev32(~crc32_le(~0, ha->addr, + ETH_ALEN)) >> (32 - mcbitslog2); + /* The most significant bit determines the register to + * use (H/L) while the other 5 bits determine the bit + * within the register. */ - mc_filter[bit_nr >> 5] |= (1 << (bit_nr & 0x1F)); + mc_filter[bit_nr >> 5] |= (1 << (bit_nr & 0x1f)); } - writel(mc_filter[0], ioaddr + GMAC_HASH_TAB_0_31); - writel(mc_filter[1], ioaddr + GMAC_HASH_TAB_32_63); + for (i = 0; i < numhashregs; i++) + writel(mc_filter[i], ioaddr + GMAC_HASH_TAB(i)); } value |= GMAC_PACKET_FILTER_HPF; |