From: Joachim Eastwood Date: Thu, 18 Oct 2012 11:01:15 +0000 (+0000) Subject: net/at91_ether: share macb_set_rx_mode with macb X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=e0da1f144abd34b3e29fe0ba871fee2c57b991c6;p=openwrt%2Fstaging%2Fblogic.git net/at91_ether: share macb_set_rx_mode with macb Signed-off-by: Joachim Eastwood --- diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index a1e0949e6449..f340d248e792 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -140,111 +140,6 @@ static int set_mac_address(struct net_device *dev, void* addr) return 0; } -static int inline hash_bit_value(int bitnr, __u8 *addr) -{ - if (addr[bitnr / 8] & (1 << (bitnr % 8))) - return 1; - return 0; -} - -/* - * The hash address register is 64 bits long and takes up two locations in the memory map. - * The least significant bits are stored in EMAC_HSL and the most significant - * bits in EMAC_HSH. - * - * The unicast hash enable and the multicast hash enable bits in the network configuration - * register enable the reception of hash matched frames. The destination address is - * reduced to a 6 bit index into the 64 bit hash register using the following hash function. - * The hash function is an exclusive or of every sixth bit of the destination address. - * hash_index[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47] - * hash_index[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46] - * hash_index[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45] - * hash_index[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44] - * hash_index[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43] - * hash_index[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42] - * da[0] represents the least significant bit of the first byte received, that is, the multicast/ - * unicast indicator, and da[47] represents the most significant bit of the last byte - * received. - * If the hash index points to a bit that is set in the hash register then the frame will be - * matched according to whether the frame is multicast or unicast. - * A multicast match will be signalled if the multicast hash enable bit is set, da[0] is 1 and - * the hash index points to a bit set in the hash register. - * A unicast match will be signalled if the unicast hash enable bit is set, da[0] is 0 and the - * hash index points to a bit set in the hash register. - * To receive all multicast frames, the hash register should be set with all ones and the - * multicast hash enable bit should be set in the network configuration register. - */ - -/* - * Return the hash index value for the specified address. - */ -static int hash_get_index(__u8 *addr) -{ - int i, j, bitval; - int hash_index = 0; - - for (j = 0; j < 6; j++) { - for (i = 0, bitval = 0; i < 8; i++) - bitval ^= hash_bit_value(i*6 + j, addr); - - hash_index |= (bitval << j); - } - - return hash_index; -} - -/* - * Add multicast addresses to the internal multicast-hash table. - */ -static void at91ether_sethashtable(struct net_device *dev) -{ - struct macb *lp = netdev_priv(dev); - struct netdev_hw_addr *ha; - unsigned long mc_filter[2]; - unsigned int bitnr; - - mc_filter[0] = mc_filter[1] = 0; - - netdev_for_each_mc_addr(ha, dev) { - bitnr = hash_get_index(ha->addr); - mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); - } - - macb_writel(lp, HRB, mc_filter[0]); - macb_writel(lp, HRT, mc_filter[1]); -} - -/* - * Enable/Disable promiscuous and multicast modes. - */ -static void at91ether_set_multicast_list(struct net_device *dev) -{ - struct macb *lp = netdev_priv(dev); - unsigned long cfg; - - cfg = macb_readl(lp, NCFGR); - - if (dev->flags & IFF_PROMISC) /* Enable promiscuous mode */ - cfg |= MACB_BIT(CAF); - else if (dev->flags & (~IFF_PROMISC)) /* Disable promiscuous mode */ - cfg &= ~MACB_BIT(CAF); - - if (dev->flags & IFF_ALLMULTI) { /* Enable all multicast mode */ - macb_writel(lp, HRT, -1); - macb_writel(lp, HRB, -1); - cfg |= MACB_BIT(NCFGR_MTI); - } else if (!netdev_mc_empty(dev)) { /* Enable specific multicasts */ - at91ether_sethashtable(dev); - cfg |= MACB_BIT(NCFGR_MTI); - } else if (dev->flags & (~IFF_ALLMULTI)) { /* Disable all multicast mode */ - macb_writel(lp, HRT, 0); - macb_writel(lp, HRB, 0); - cfg &= ~MACB_BIT(NCFGR_MTI); - } - - macb_writel(lp, NCFGR, cfg); -} - /* ................................ MAC ................................ */ /* @@ -500,7 +395,7 @@ static const struct net_device_ops at91ether_netdev_ops = { .ndo_stop = at91ether_close, .ndo_start_xmit = at91ether_start_xmit, .ndo_get_stats = at91ether_stats, - .ndo_set_rx_mode = at91ether_set_multicast_list, + .ndo_set_rx_mode = macb_set_rx_mode, .ndo_set_mac_address = set_mac_address, .ndo_do_ioctl = macb_ioctl, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 8ee6de523eda..6c84a1104aff 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -997,7 +997,7 @@ static void macb_sethashtable(struct net_device *dev) /* * Enable/Disable promiscuous and multicast modes. */ -static void macb_set_rx_mode(struct net_device *dev) +void macb_set_rx_mode(struct net_device *dev) { unsigned long cfg; struct macb *bp = netdev_priv(dev); @@ -1029,6 +1029,7 @@ static void macb_set_rx_mode(struct net_device *dev) macb_writel(bp, NCFGR, cfg); } +EXPORT_SYMBOL_GPL(macb_set_rx_mode); static int macb_open(struct net_device *dev) { diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index fd2961a4fca0..2710562e5b64 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -574,6 +574,7 @@ extern const struct ethtool_ops macb_ethtool_ops; int macb_mii_init(struct macb *bp); int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +void macb_set_rx_mode(struct net_device *dev); static inline bool macb_is_gem(struct macb *bp) {