Commit fbc13f01 authored by Ajit Khaparde's avatar Ajit Khaparde Committed by David S. Miller

be2net: Program secondary UC MAC address into MAC filter

Signed-off-by: default avatarAjit Khaparde <ajit.khaparde@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4762f6ce
...@@ -309,6 +309,8 @@ struct be_vf_cfg { ...@@ -309,6 +309,8 @@ struct be_vf_cfg {
#define BE_FLAGS_LINK_STATUS_INIT 1 #define BE_FLAGS_LINK_STATUS_INIT 1
#define BE_FLAGS_WORKER_SCHEDULED (1 << 3) #define BE_FLAGS_WORKER_SCHEDULED (1 << 3)
#define BE_UC_PMAC_COUNT 30
#define BE_VF_UC_PMAC_COUNT 2
struct be_adapter { struct be_adapter {
struct pci_dev *pdev; struct pci_dev *pdev;
...@@ -361,7 +363,7 @@ struct be_adapter { ...@@ -361,7 +363,7 @@ struct be_adapter {
/* Ethtool knobs and info */ /* Ethtool knobs and info */
char fw_ver[FW_VER_LEN]; char fw_ver[FW_VER_LEN];
int if_handle; /* Used to configure filtering */ int if_handle; /* Used to configure filtering */
u32 pmac_id; /* MAC addr handle used by BE card */ u32 *pmac_id; /* MAC addr handle used by BE card */
u32 beacon_state; /* for set_phys_id */ u32 beacon_state; /* for set_phys_id */
bool eeh_err; bool eeh_err;
...@@ -391,6 +393,8 @@ struct be_adapter { ...@@ -391,6 +393,8 @@ struct be_adapter {
u16 pvid; u16 pvid;
u8 wol_cap; u8 wol_cap;
bool wol; bool wol;
u32 max_pmac_cnt; /* Max secondary UC MACs programmable */
u32 uc_macs; /* Count of secondary UC MAC programmed */
}; };
#define be_physfn(adapter) (!adapter->is_virtfn) #define be_physfn(adapter) (!adapter->is_virtfn)
......
...@@ -235,7 +235,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) ...@@ -235,7 +235,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
struct sockaddr *addr = p; struct sockaddr *addr = p;
int status = 0; int status = 0;
u8 current_mac[ETH_ALEN]; 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)) if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
...@@ -248,7 +248,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) ...@@ -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)) { if (memcmp(addr->sa_data, current_mac, ETH_ALEN)) {
status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, 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) if (status)
goto err; goto err;
...@@ -885,6 +885,29 @@ static void be_set_rx_mode(struct net_device *netdev) ...@@ -885,6 +885,29 @@ static void be_set_rx_mode(struct net_device *netdev)
goto done; 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); be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
done: done:
return; return;
...@@ -2458,6 +2481,8 @@ static void be_vf_clear(struct be_adapter *adapter) ...@@ -2458,6 +2481,8 @@ static void be_vf_clear(struct be_adapter *adapter)
static int be_clear(struct be_adapter *adapter) static int be_clear(struct be_adapter *adapter)
{ {
int i = 1;
if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) { if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
cancel_delayed_work_sync(&adapter->work); cancel_delayed_work_sync(&adapter->work);
adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED; adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
...@@ -2466,6 +2491,10 @@ static int be_clear(struct be_adapter *adapter) ...@@ -2466,6 +2491,10 @@ static int be_clear(struct be_adapter *adapter)
if (sriov_enabled(adapter)) if (sriov_enabled(adapter))
be_vf_clear(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_cmd_if_destroy(adapter, adapter->if_handle, 0);
be_mcc_queues_destroy(adapter); be_mcc_queues_destroy(adapter);
...@@ -2477,6 +2506,7 @@ static int be_clear(struct be_adapter *adapter) ...@@ -2477,6 +2506,7 @@ static int be_clear(struct be_adapter *adapter)
be_cmd_fw_clean(adapter); be_cmd_fw_clean(adapter);
be_msix_disable(adapter); be_msix_disable(adapter);
kfree(adapter->pmac_id);
return 0; return 0;
} }
...@@ -2552,10 +2582,10 @@ static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac) ...@@ -2552,10 +2582,10 @@ static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac)
false, adapter->if_handle, pmac_id); false, adapter->if_handle, pmac_id);
if (!status) if (!status)
adapter->pmac_id = pmac_id; adapter->pmac_id[0] = pmac_id;
} else { } else {
status = be_cmd_pmac_add(adapter, mac, status = be_cmd_pmac_add(adapter, mac,
adapter->if_handle, &adapter->pmac_id, 0); adapter->if_handle, &adapter->pmac_id[0], 0);
} }
do_none: do_none:
return status; return status;
...@@ -2610,7 +2640,7 @@ static int be_setup(struct be_adapter *adapter) ...@@ -2610,7 +2640,7 @@ static int be_setup(struct be_adapter *adapter)
} }
status = be_cmd_if_create(adapter, cap_flags, en_flags, status = be_cmd_if_create(adapter, cap_flags, en_flags,
netdev->dev_addr, &adapter->if_handle, netdev->dev_addr, &adapter->if_handle,
&adapter->pmac_id, 0); &adapter->pmac_id[0], 0);
if (status != 0) if (status != 0)
goto err; goto err;
...@@ -3059,6 +3089,8 @@ static void be_netdev_init(struct net_device *netdev) ...@@ -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 | netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev->priv_flags |= IFF_UNICAST_FLT;
netdev->flags |= IFF_MULTICAST; netdev->flags |= IFF_MULTICAST;
netif_set_gso_max_size(netdev, 65535); netif_set_gso_max_size(netdev, 65535);
...@@ -3264,6 +3296,17 @@ static int be_get_config(struct be_adapter *adapter) ...@@ -3264,6 +3296,17 @@ static int be_get_config(struct be_adapter *adapter)
else else
adapter->max_vlans = BE_NUM_VLANS_SUPPORTED; 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); status = be_cmd_get_cntl_attributes(adapter);
if (status) if (status)
return status; return status;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment