|
@@ -816,40 +816,48 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev)
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * Collect up to maxaddrs worth of a netdevice's unicast addresses into an
|
|
|
|
- * array of addrss pointers and return the number collected.
|
|
|
|
|
|
+ * Collect up to maxaddrs worth of a netdevice's unicast addresses, starting
|
|
|
|
+ * at a specified offset within the list, into an array of addrss pointers and
|
|
|
|
+ * return the number collected.
|
|
*/
|
|
*/
|
|
-static inline int collect_netdev_uc_list_addrs(const struct net_device *dev,
|
|
|
|
- const u8 **addr,
|
|
|
|
- unsigned int maxaddrs)
|
|
|
|
|
|
+static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev,
|
|
|
|
+ const u8 **addr,
|
|
|
|
+ unsigned int offset,
|
|
|
|
+ unsigned int maxaddrs)
|
|
{
|
|
{
|
|
|
|
+ unsigned int index = 0;
|
|
unsigned int naddr = 0;
|
|
unsigned int naddr = 0;
|
|
const struct netdev_hw_addr *ha;
|
|
const struct netdev_hw_addr *ha;
|
|
|
|
|
|
- for_each_dev_addr(dev, ha) {
|
|
|
|
- addr[naddr++] = ha->addr;
|
|
|
|
- if (naddr >= maxaddrs)
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ for_each_dev_addr(dev, ha)
|
|
|
|
+ if (index++ >= offset) {
|
|
|
|
+ addr[naddr++] = ha->addr;
|
|
|
|
+ if (naddr >= maxaddrs)
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
return naddr;
|
|
return naddr;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * Collect up to maxaddrs worth of a netdevice's multicast addresses into an
|
|
|
|
- * array of addrss pointers and return the number collected.
|
|
|
|
|
|
+ * Collect up to maxaddrs worth of a netdevice's multicast addresses, starting
|
|
|
|
+ * at a specified offset within the list, into an array of addrss pointers and
|
|
|
|
+ * return the number collected.
|
|
*/
|
|
*/
|
|
-static inline int collect_netdev_mc_list_addrs(const struct net_device *dev,
|
|
|
|
- const u8 **addr,
|
|
|
|
- unsigned int maxaddrs)
|
|
|
|
|
|
+static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev,
|
|
|
|
+ const u8 **addr,
|
|
|
|
+ unsigned int offset,
|
|
|
|
+ unsigned int maxaddrs)
|
|
{
|
|
{
|
|
|
|
+ unsigned int index = 0;
|
|
unsigned int naddr = 0;
|
|
unsigned int naddr = 0;
|
|
const struct netdev_hw_addr *ha;
|
|
const struct netdev_hw_addr *ha;
|
|
|
|
|
|
- netdev_for_each_mc_addr(ha, dev) {
|
|
|
|
- addr[naddr++] = ha->addr;
|
|
|
|
- if (naddr >= maxaddrs)
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ netdev_for_each_mc_addr(ha, dev)
|
|
|
|
+ if (index++ >= offset) {
|
|
|
|
+ addr[naddr++] = ha->addr;
|
|
|
|
+ if (naddr >= maxaddrs)
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
return naddr;
|
|
return naddr;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -862,16 +870,20 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
|
|
u64 mhash = 0;
|
|
u64 mhash = 0;
|
|
u64 uhash = 0;
|
|
u64 uhash = 0;
|
|
bool free = true;
|
|
bool free = true;
|
|
- u16 filt_idx[7];
|
|
|
|
|
|
+ unsigned int offset, naddr;
|
|
const u8 *addr[7];
|
|
const u8 *addr[7];
|
|
- int ret, naddr = 0;
|
|
|
|
|
|
+ int ret;
|
|
const struct port_info *pi = netdev_priv(dev);
|
|
const struct port_info *pi = netdev_priv(dev);
|
|
|
|
|
|
/* first do the secondary unicast addresses */
|
|
/* first do the secondary unicast addresses */
|
|
- naddr = collect_netdev_uc_list_addrs(dev, addr, ARRAY_SIZE(addr));
|
|
|
|
- if (naddr > 0) {
|
|
|
|
|
|
+ for (offset = 0; ; offset += naddr) {
|
|
|
|
+ naddr = collect_netdev_uc_list_addrs(dev, addr, offset,
|
|
|
|
+ ARRAY_SIZE(addr));
|
|
|
|
+ if (naddr == 0)
|
|
|
|
+ break;
|
|
|
|
+
|
|
ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
|
|
ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
|
|
- naddr, addr, filt_idx, &uhash, sleep);
|
|
|
|
|
|
+ naddr, addr, NULL, &uhash, sleep);
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
return ret;
|
|
return ret;
|
|
|
|
|
|
@@ -879,12 +891,17 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
|
|
}
|
|
}
|
|
|
|
|
|
/* next set up the multicast addresses */
|
|
/* next set up the multicast addresses */
|
|
- naddr = collect_netdev_mc_list_addrs(dev, addr, ARRAY_SIZE(addr));
|
|
|
|
- if (naddr > 0) {
|
|
|
|
|
|
+ for (offset = 0; ; offset += naddr) {
|
|
|
|
+ naddr = collect_netdev_mc_list_addrs(dev, addr, offset,
|
|
|
|
+ ARRAY_SIZE(addr));
|
|
|
|
+ if (naddr == 0)
|
|
|
|
+ break;
|
|
|
|
+
|
|
ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
|
|
ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
|
|
- naddr, addr, filt_idx, &mhash, sleep);
|
|
|
|
|
|
+ naddr, addr, NULL, &mhash, sleep);
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
return ret;
|
|
return ret;
|
|
|
|
+ free = false;
|
|
}
|
|
}
|
|
|
|
|
|
return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0,
|
|
return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0,
|