aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAidan Williams <aidan@nicta.com.au>2008-01-30 03:52:23 -0500
committerDavid S. Miller <davem@davemloft.net>2008-02-03 07:28:47 -0500
commit775919bc23880f250ca1029a6420187ee4bb5b26 (patch)
tree1dc0ce2d7f978ea912cea8bfcc2c540f682b308e /drivers/net
parent7cc8f38188133e0c278b9f207d63c2c2b4d98236 (diff)
EMAC driver: bf537 MAC multicast hash filtering patch
The bf537 Ethernet MAC driver in the 2007R1.1-RC3 kernel (and the current kernel) do not implement multicast hash filtering. This is a performance problem if you have lots of multicast on your network. This patch plugs the right bits into the multicast hash registers. Signed-off-by: Aidan Williams <aidan@nicta.com.au> Signed-off-by: Bryan Wu <bryan.wu@analog.com> Signed-off-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bfin_mac.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index ee398196ea80..c6586cdb8b95 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -11,6 +11,7 @@
11 * Description: 11 * Description:
12 * 12 *
13 * Modified: 13 * Modified:
14 * 2006-12-19 Aidan Williams, multicast hash support
14 * Copyright 2004-2006 Analog Devices Inc. 15 * Copyright 2004-2006 Analog Devices Inc.
15 * 16 *
16 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 17 * Bugs: Enter bugs at http://blackfin.uclinux.org/
@@ -800,6 +801,39 @@ static void bf537mac_timeout(struct net_device *dev)
800 netif_wake_queue(dev); 801 netif_wake_queue(dev);
801} 802}
802 803
804static void bf537mac_multicast_hash(struct net_device *dev)
805{
806 u32 emac_hashhi, emac_hashlo;
807 struct dev_mc_list *dmi = dev->mc_list;
808 char *addrs;
809 int i;
810 u32 crc;
811
812 emac_hashhi = emac_hashlo = 0;
813
814 for (i = 0; i < dev->mc_count; i++) {
815 addrs = dmi->dmi_addr;
816 dmi = dmi->next;
817
818 /* skip non-multicast addresses */
819 if (!(*addrs & 1))
820 continue;
821
822 crc = ether_crc(ETH_ALEN, addrs);
823 crc >>= 26;
824
825 if (crc & 0x20)
826 emac_hashhi |= 1 << (crc & 0x1f);
827 else
828 emac_hashlo |= 1 << (crc & 0x1f);
829 }
830
831 bfin_write_EMAC_HASHHI(emac_hashhi);
832 bfin_write_EMAC_HASHLO(emac_hashlo);
833
834 return;
835}
836
803/* 837/*
804 * This routine will, depending on the values passed to it, 838 * This routine will, depending on the values passed to it,
805 * either make it accept multicast packets, go into 839 * either make it accept multicast packets, go into
@@ -815,11 +849,17 @@ static void bf537mac_set_multicast_list(struct net_device *dev)
815 sysctl = bfin_read_EMAC_OPMODE(); 849 sysctl = bfin_read_EMAC_OPMODE();
816 sysctl |= RAF; 850 sysctl |= RAF;
817 bfin_write_EMAC_OPMODE(sysctl); 851 bfin_write_EMAC_OPMODE(sysctl);
818 } else if (dev->flags & IFF_ALLMULTI || dev->mc_count) { 852 } else if (dev->flags & IFF_ALLMULTI) {
819 /* accept all multicast */ 853 /* accept all multicast */
820 sysctl = bfin_read_EMAC_OPMODE(); 854 sysctl = bfin_read_EMAC_OPMODE();
821 sysctl |= PAM; 855 sysctl |= PAM;
822 bfin_write_EMAC_OPMODE(sysctl); 856 bfin_write_EMAC_OPMODE(sysctl);
857 } else if (dev->mc_count) {
858 /* set up multicast hash table */
859 sysctl = bfin_read_EMAC_OPMODE();
860 sysctl |= HM;
861 bfin_write_EMAC_OPMODE(sysctl);
862 bf537mac_multicast_hash(dev);
823 } else { 863 } else {
824 /* clear promisc or multicast mode */ 864 /* clear promisc or multicast mode */
825 sysctl = bfin_read_EMAC_OPMODE(); 865 sysctl = bfin_read_EMAC_OPMODE();