aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb4vf/cxgb4vf_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cxgb4vf/cxgb4vf_main.c')
-rw-r--r--drivers/net/cxgb4vf/cxgb4vf_main.c73
1 files changed, 45 insertions, 28 deletions
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index 9246d2fa6cf9..f54af48edb93 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -814,40 +814,48 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev)
814} 814}
815 815
816/* 816/*
817 * Collect up to maxaddrs worth of a netdevice's unicast addresses into an 817 * Collect up to maxaddrs worth of a netdevice's unicast addresses, starting
818 * array of addrss pointers and return the number collected. 818 * at a specified offset within the list, into an array of addrss pointers and
819 * return the number collected.
819 */ 820 */
820static inline int collect_netdev_uc_list_addrs(const struct net_device *dev, 821static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev,
821 const u8 **addr, 822 const u8 **addr,
822 unsigned int maxaddrs) 823 unsigned int offset,
824 unsigned int maxaddrs)
823{ 825{
826 unsigned int index = 0;
824 unsigned int naddr = 0; 827 unsigned int naddr = 0;
825 const struct netdev_hw_addr *ha; 828 const struct netdev_hw_addr *ha;
826 829
827 for_each_dev_addr(dev, ha) { 830 for_each_dev_addr(dev, ha)
828 addr[naddr++] = ha->addr; 831 if (index++ >= offset) {
829 if (naddr >= maxaddrs) 832 addr[naddr++] = ha->addr;
830 break; 833 if (naddr >= maxaddrs)
831 } 834 break;
835 }
832 return naddr; 836 return naddr;
833} 837}
834 838
835/* 839/*
836 * Collect up to maxaddrs worth of a netdevice's multicast addresses into an 840 * Collect up to maxaddrs worth of a netdevice's multicast addresses, starting
837 * array of addrss pointers and return the number collected. 841 * at a specified offset within the list, into an array of addrss pointers and
842 * return the number collected.
838 */ 843 */
839static inline int collect_netdev_mc_list_addrs(const struct net_device *dev, 844static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev,
840 const u8 **addr, 845 const u8 **addr,
841 unsigned int maxaddrs) 846 unsigned int offset,
847 unsigned int maxaddrs)
842{ 848{
849 unsigned int index = 0;
843 unsigned int naddr = 0; 850 unsigned int naddr = 0;
844 const struct netdev_hw_addr *ha; 851 const struct netdev_hw_addr *ha;
845 852
846 netdev_for_each_mc_addr(ha, dev) { 853 netdev_for_each_mc_addr(ha, dev)
847 addr[naddr++] = ha->addr; 854 if (index++ >= offset) {
848 if (naddr >= maxaddrs) 855 addr[naddr++] = ha->addr;
849 break; 856 if (naddr >= maxaddrs)
850 } 857 break;
858 }
851 return naddr; 859 return naddr;
852} 860}
853 861
@@ -860,16 +868,20 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
860 u64 mhash = 0; 868 u64 mhash = 0;
861 u64 uhash = 0; 869 u64 uhash = 0;
862 bool free = true; 870 bool free = true;
863 u16 filt_idx[7]; 871 unsigned int offset, naddr;
864 const u8 *addr[7]; 872 const u8 *addr[7];
865 int ret, naddr = 0; 873 int ret;
866 const struct port_info *pi = netdev_priv(dev); 874 const struct port_info *pi = netdev_priv(dev);
867 875
868 /* first do the secondary unicast addresses */ 876 /* first do the secondary unicast addresses */
869 naddr = collect_netdev_uc_list_addrs(dev, addr, ARRAY_SIZE(addr)); 877 for (offset = 0; ; offset += naddr) {
870 if (naddr > 0) { 878 naddr = collect_netdev_uc_list_addrs(dev, addr, offset,
879 ARRAY_SIZE(addr));
880 if (naddr == 0)
881 break;
882
871 ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, 883 ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
872 naddr, addr, filt_idx, &uhash, sleep); 884 naddr, addr, NULL, &uhash, sleep);
873 if (ret < 0) 885 if (ret < 0)
874 return ret; 886 return ret;
875 887
@@ -877,12 +889,17 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
877 } 889 }
878 890
879 /* next set up the multicast addresses */ 891 /* next set up the multicast addresses */
880 naddr = collect_netdev_mc_list_addrs(dev, addr, ARRAY_SIZE(addr)); 892 for (offset = 0; ; offset += naddr) {
881 if (naddr > 0) { 893 naddr = collect_netdev_mc_list_addrs(dev, addr, offset,
894 ARRAY_SIZE(addr));
895 if (naddr == 0)
896 break;
897
882 ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, 898 ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
883 naddr, addr, filt_idx, &mhash, sleep); 899 naddr, addr, NULL, &mhash, sleep);
884 if (ret < 0) 900 if (ret < 0)
885 return ret; 901 return ret;
902 free = false;
886 } 903 }
887 904
888 return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0, 905 return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0,