diff options
author | Casey Leedom <leedom@chelsio.com> | 2010-11-24 07:23:57 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-11-28 14:40:58 -0500 |
commit | 42eb59d3a80ff83b4cacb92dcc44b22da7d4969b (patch) | |
tree | c053c48b34d4a9c17badc50967c9cd3b5eaee34b /drivers/net/cxgb4vf/cxgb4vf_main.c | |
parent | bcc70bb3aeae7c3d035881d41055685f08a2b745 (diff) |
cxgb4vf: fix setting unicast/multicast addresses ...
We were truncating the number of unicast and multicast MAC addresses
supported. Additionally, we were incorrectly computing the MAC Address
hash (a "1 << N" where we needed a "1ULL << N").
Signed-off-by: Casey Leedom <leedom@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cxgb4vf/cxgb4vf_main.c')
-rw-r--r-- | drivers/net/cxgb4vf/cxgb4vf_main.c | 73 |
1 files changed, 45 insertions, 28 deletions
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index c3449bbc585a..d887a76cd39d 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
@@ -816,40 +816,48 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev) | |||
816 | } | 816 | } |
817 | 817 | ||
818 | /* | 818 | /* |
819 | * Collect up to maxaddrs worth of a netdevice's unicast addresses into an | 819 | * Collect up to maxaddrs worth of a netdevice's unicast addresses, starting |
820 | * array of addrss pointers and return the number collected. | 820 | * at a specified offset within the list, into an array of addrss pointers and |
821 | * return the number collected. | ||
821 | */ | 822 | */ |
822 | static inline int collect_netdev_uc_list_addrs(const struct net_device *dev, | 823 | static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev, |
823 | const u8 **addr, | 824 | const u8 **addr, |
824 | unsigned int maxaddrs) | 825 | unsigned int offset, |
826 | unsigned int maxaddrs) | ||
825 | { | 827 | { |
828 | unsigned int index = 0; | ||
826 | unsigned int naddr = 0; | 829 | unsigned int naddr = 0; |
827 | const struct netdev_hw_addr *ha; | 830 | const struct netdev_hw_addr *ha; |
828 | 831 | ||
829 | for_each_dev_addr(dev, ha) { | 832 | for_each_dev_addr(dev, ha) |
830 | addr[naddr++] = ha->addr; | 833 | if (index++ >= offset) { |
831 | if (naddr >= maxaddrs) | 834 | addr[naddr++] = ha->addr; |
832 | break; | 835 | if (naddr >= maxaddrs) |
833 | } | 836 | break; |
837 | } | ||
834 | return naddr; | 838 | return naddr; |
835 | } | 839 | } |
836 | 840 | ||
837 | /* | 841 | /* |
838 | * Collect up to maxaddrs worth of a netdevice's multicast addresses into an | 842 | * Collect up to maxaddrs worth of a netdevice's multicast addresses, starting |
839 | * array of addrss pointers and return the number collected. | 843 | * at a specified offset within the list, into an array of addrss pointers and |
844 | * return the number collected. | ||
840 | */ | 845 | */ |
841 | static inline int collect_netdev_mc_list_addrs(const struct net_device *dev, | 846 | static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev, |
842 | const u8 **addr, | 847 | const u8 **addr, |
843 | unsigned int maxaddrs) | 848 | unsigned int offset, |
849 | unsigned int maxaddrs) | ||
844 | { | 850 | { |
851 | unsigned int index = 0; | ||
845 | unsigned int naddr = 0; | 852 | unsigned int naddr = 0; |
846 | const struct netdev_hw_addr *ha; | 853 | const struct netdev_hw_addr *ha; |
847 | 854 | ||
848 | netdev_for_each_mc_addr(ha, dev) { | 855 | netdev_for_each_mc_addr(ha, dev) |
849 | addr[naddr++] = ha->addr; | 856 | if (index++ >= offset) { |
850 | if (naddr >= maxaddrs) | 857 | addr[naddr++] = ha->addr; |
851 | break; | 858 | if (naddr >= maxaddrs) |
852 | } | 859 | break; |
860 | } | ||
853 | return naddr; | 861 | return naddr; |
854 | } | 862 | } |
855 | 863 | ||
@@ -862,16 +870,20 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) | |||
862 | u64 mhash = 0; | 870 | u64 mhash = 0; |
863 | u64 uhash = 0; | 871 | u64 uhash = 0; |
864 | bool free = true; | 872 | bool free = true; |
865 | u16 filt_idx[7]; | 873 | unsigned int offset, naddr; |
866 | const u8 *addr[7]; | 874 | const u8 *addr[7]; |
867 | int ret, naddr = 0; | 875 | int ret; |
868 | const struct port_info *pi = netdev_priv(dev); | 876 | const struct port_info *pi = netdev_priv(dev); |
869 | 877 | ||
870 | /* first do the secondary unicast addresses */ | 878 | /* first do the secondary unicast addresses */ |
871 | naddr = collect_netdev_uc_list_addrs(dev, addr, ARRAY_SIZE(addr)); | 879 | for (offset = 0; ; offset += naddr) { |
872 | if (naddr > 0) { | 880 | naddr = collect_netdev_uc_list_addrs(dev, addr, offset, |
881 | ARRAY_SIZE(addr)); | ||
882 | if (naddr == 0) | ||
883 | break; | ||
884 | |||
873 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, | 885 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, |
874 | naddr, addr, filt_idx, &uhash, sleep); | 886 | naddr, addr, NULL, &uhash, sleep); |
875 | if (ret < 0) | 887 | if (ret < 0) |
876 | return ret; | 888 | return ret; |
877 | 889 | ||
@@ -879,12 +891,17 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) | |||
879 | } | 891 | } |
880 | 892 | ||
881 | /* next set up the multicast addresses */ | 893 | /* next set up the multicast addresses */ |
882 | naddr = collect_netdev_mc_list_addrs(dev, addr, ARRAY_SIZE(addr)); | 894 | for (offset = 0; ; offset += naddr) { |
883 | if (naddr > 0) { | 895 | naddr = collect_netdev_mc_list_addrs(dev, addr, offset, |
896 | ARRAY_SIZE(addr)); | ||
897 | if (naddr == 0) | ||
898 | break; | ||
899 | |||
884 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, | 900 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, |
885 | naddr, addr, filt_idx, &mhash, sleep); | 901 | naddr, addr, NULL, &mhash, sleep); |
886 | if (ret < 0) | 902 | if (ret < 0) |
887 | return ret; | 903 | return ret; |
904 | free = false; | ||
888 | } | 905 | } |
889 | 906 | ||
890 | return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0, | 907 | return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0, |