|
@@ -235,7 +235,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
|
|
|
struct sockaddr *addr = p;
|
|
|
int status = 0;
|
|
|
u8 current_mac[ETH_ALEN];
|
|
|
- u32 pmac_id = adapter->pmac_id;
|
|
|
+ u32 pmac_id = adapter->pmac_id[0];
|
|
|
|
|
|
if (!is_valid_ether_addr(addr->sa_data))
|
|
|
return -EADDRNOTAVAIL;
|
|
@@ -248,7 +248,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
|
|
|
|
|
|
if (memcmp(addr->sa_data, current_mac, ETH_ALEN)) {
|
|
|
status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
|
|
|
- adapter->if_handle, &adapter->pmac_id, 0);
|
|
|
+ adapter->if_handle, &adapter->pmac_id[0], 0);
|
|
|
if (status)
|
|
|
goto err;
|
|
|
|
|
@@ -885,6 +885,29 @@ static void be_set_rx_mode(struct net_device *netdev)
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
+ if (netdev_uc_count(netdev) != adapter->uc_macs) {
|
|
|
+ struct netdev_hw_addr *ha;
|
|
|
+ int i = 1; /* First slot is claimed by the Primary MAC */
|
|
|
+
|
|
|
+ for (; adapter->uc_macs > 0; adapter->uc_macs--, i++) {
|
|
|
+ be_cmd_pmac_del(adapter, adapter->if_handle,
|
|
|
+ adapter->pmac_id[i], 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (netdev_uc_count(netdev) > adapter->max_pmac_cnt) {
|
|
|
+ be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
|
|
|
+ adapter->promiscuous = true;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ netdev_for_each_uc_addr(ha, adapter->netdev) {
|
|
|
+ adapter->uc_macs++; /* First slot is for Primary MAC */
|
|
|
+ be_cmd_pmac_add(adapter, (u8 *)ha->addr,
|
|
|
+ adapter->if_handle,
|
|
|
+ &adapter->pmac_id[adapter->uc_macs], 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
|
|
|
done:
|
|
|
return;
|
|
@@ -2458,6 +2481,8 @@ static void be_vf_clear(struct be_adapter *adapter)
|
|
|
|
|
|
static int be_clear(struct be_adapter *adapter)
|
|
|
{
|
|
|
+ int i = 1;
|
|
|
+
|
|
|
if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
|
|
|
cancel_delayed_work_sync(&adapter->work);
|
|
|
adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
|
|
@@ -2466,6 +2491,10 @@ static int be_clear(struct be_adapter *adapter)
|
|
|
if (sriov_enabled(adapter))
|
|
|
be_vf_clear(adapter);
|
|
|
|
|
|
+ for (; adapter->uc_macs > 0; adapter->uc_macs--, i++)
|
|
|
+ be_cmd_pmac_del(adapter, adapter->if_handle,
|
|
|
+ adapter->pmac_id[i], 0);
|
|
|
+
|
|
|
be_cmd_if_destroy(adapter, adapter->if_handle, 0);
|
|
|
|
|
|
be_mcc_queues_destroy(adapter);
|
|
@@ -2477,6 +2506,7 @@ static int be_clear(struct be_adapter *adapter)
|
|
|
be_cmd_fw_clean(adapter);
|
|
|
|
|
|
be_msix_disable(adapter);
|
|
|
+ kfree(adapter->pmac_id);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2552,10 +2582,10 @@ static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac)
|
|
|
false, adapter->if_handle, pmac_id);
|
|
|
|
|
|
if (!status)
|
|
|
- adapter->pmac_id = pmac_id;
|
|
|
+ adapter->pmac_id[0] = pmac_id;
|
|
|
} else {
|
|
|
status = be_cmd_pmac_add(adapter, mac,
|
|
|
- adapter->if_handle, &adapter->pmac_id, 0);
|
|
|
+ adapter->if_handle, &adapter->pmac_id[0], 0);
|
|
|
}
|
|
|
do_none:
|
|
|
return status;
|
|
@@ -2610,7 +2640,7 @@ static int be_setup(struct be_adapter *adapter)
|
|
|
}
|
|
|
status = be_cmd_if_create(adapter, cap_flags, en_flags,
|
|
|
netdev->dev_addr, &adapter->if_handle,
|
|
|
- &adapter->pmac_id, 0);
|
|
|
+ &adapter->pmac_id[0], 0);
|
|
|
if (status != 0)
|
|
|
goto err;
|
|
|
|
|
@@ -3059,6 +3089,8 @@ static void be_netdev_init(struct net_device *netdev)
|
|
|
netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
|
|
|
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
|
|
|
|
|
|
+ netdev->priv_flags |= IFF_UNICAST_FLT;
|
|
|
+
|
|
|
netdev->flags |= IFF_MULTICAST;
|
|
|
|
|
|
netif_set_gso_max_size(netdev, 65535);
|
|
@@ -3264,6 +3296,17 @@ static int be_get_config(struct be_adapter *adapter)
|
|
|
else
|
|
|
adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
|
|
|
|
|
|
+ if (be_physfn(adapter))
|
|
|
+ adapter->max_pmac_cnt = BE_UC_PMAC_COUNT;
|
|
|
+ else
|
|
|
+ adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT;
|
|
|
+
|
|
|
+ /* primary mac needs 1 pmac entry */
|
|
|
+ adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1,
|
|
|
+ sizeof(u32), GFP_KERNEL);
|
|
|
+ if (!adapter->pmac_id)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
status = be_cmd_get_cntl_attributes(adapter);
|
|
|
if (status)
|
|
|
return status;
|