aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAjit Khaparde <ajit.khaparde@emulex.com>2012-03-18 02:23:21 -0400
committerDavid S. Miller <davem@davemloft.net>2012-03-19 16:52:17 -0400
commitfbc13f018c0043146f8eccc7d6a6c0e66339e2d5 (patch)
tree6b4a162c091dbd8f0757c68a07cecd314779a239
parent4762f6cec4455f3bbe4ca82c100fe5d85d3c02a2 (diff)
be2net: Program secondary UC MAC address into MAC filter
Signed-off-by: Ajit Khaparde <ajit.khaparde@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h6
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c53
2 files changed, 53 insertions, 6 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index cabe1b892722..03fc3dbe3872 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -309,6 +309,8 @@ struct be_vf_cfg {
309 309
310#define BE_FLAGS_LINK_STATUS_INIT 1 310#define BE_FLAGS_LINK_STATUS_INIT 1
311#define BE_FLAGS_WORKER_SCHEDULED (1 << 3) 311#define BE_FLAGS_WORKER_SCHEDULED (1 << 3)
312#define BE_UC_PMAC_COUNT 30
313#define BE_VF_UC_PMAC_COUNT 2
312 314
313struct be_adapter { 315struct be_adapter {
314 struct pci_dev *pdev; 316 struct pci_dev *pdev;
@@ -361,7 +363,7 @@ struct be_adapter {
361 /* Ethtool knobs and info */ 363 /* Ethtool knobs and info */
362 char fw_ver[FW_VER_LEN]; 364 char fw_ver[FW_VER_LEN];
363 int if_handle; /* Used to configure filtering */ 365 int if_handle; /* Used to configure filtering */
364 u32 pmac_id; /* MAC addr handle used by BE card */ 366 u32 *pmac_id; /* MAC addr handle used by BE card */
365 u32 beacon_state; /* for set_phys_id */ 367 u32 beacon_state; /* for set_phys_id */
366 368
367 bool eeh_err; 369 bool eeh_err;
@@ -391,6 +393,8 @@ struct be_adapter {
391 u16 pvid; 393 u16 pvid;
392 u8 wol_cap; 394 u8 wol_cap;
393 bool wol; 395 bool wol;
396 u32 max_pmac_cnt; /* Max secondary UC MACs programmable */
397 u32 uc_macs; /* Count of secondary UC MAC programmed */
394}; 398};
395 399
396#define be_physfn(adapter) (!adapter->is_virtfn) 400#define be_physfn(adapter) (!adapter->is_virtfn)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 050e3ebd4fb3..b4348b8ee529 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -235,7 +235,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
235 struct sockaddr *addr = p; 235 struct sockaddr *addr = p;
236 int status = 0; 236 int status = 0;
237 u8 current_mac[ETH_ALEN]; 237 u8 current_mac[ETH_ALEN];
238 u32 pmac_id = adapter->pmac_id; 238 u32 pmac_id = adapter->pmac_id[0];
239 239
240 if (!is_valid_ether_addr(addr->sa_data)) 240 if (!is_valid_ether_addr(addr->sa_data))
241 return -EADDRNOTAVAIL; 241 return -EADDRNOTAVAIL;
@@ -248,7 +248,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
248 248
249 if (memcmp(addr->sa_data, current_mac, ETH_ALEN)) { 249 if (memcmp(addr->sa_data, current_mac, ETH_ALEN)) {
250 status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, 250 status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
251 adapter->if_handle, &adapter->pmac_id, 0); 251 adapter->if_handle, &adapter->pmac_id[0], 0);
252 if (status) 252 if (status)
253 goto err; 253 goto err;
254 254
@@ -885,6 +885,29 @@ static void be_set_rx_mode(struct net_device *netdev)
885 goto done; 885 goto done;
886 } 886 }
887 887
888 if (netdev_uc_count(netdev) != adapter->uc_macs) {
889 struct netdev_hw_addr *ha;
890 int i = 1; /* First slot is claimed by the Primary MAC */
891
892 for (; adapter->uc_macs > 0; adapter->uc_macs--, i++) {
893 be_cmd_pmac_del(adapter, adapter->if_handle,
894 adapter->pmac_id[i], 0);
895 }
896
897 if (netdev_uc_count(netdev) > adapter->max_pmac_cnt) {
898 be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
899 adapter->promiscuous = true;
900 goto done;
901 }
902
903 netdev_for_each_uc_addr(ha, adapter->netdev) {
904 adapter->uc_macs++; /* First slot is for Primary MAC */
905 be_cmd_pmac_add(adapter, (u8 *)ha->addr,
906 adapter->if_handle,
907 &adapter->pmac_id[adapter->uc_macs], 0);
908 }
909 }
910
888 be_cmd_rx_filter(adapter, IFF_MULTICAST, ON); 911 be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
889done: 912done:
890 return; 913 return;
@@ -2458,6 +2481,8 @@ static void be_vf_clear(struct be_adapter *adapter)
2458 2481
2459static int be_clear(struct be_adapter *adapter) 2482static int be_clear(struct be_adapter *adapter)
2460{ 2483{
2484 int i = 1;
2485
2461 if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) { 2486 if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
2462 cancel_delayed_work_sync(&adapter->work); 2487 cancel_delayed_work_sync(&adapter->work);
2463 adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED; 2488 adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
@@ -2466,6 +2491,10 @@ static int be_clear(struct be_adapter *adapter)
2466 if (sriov_enabled(adapter)) 2491 if (sriov_enabled(adapter))
2467 be_vf_clear(adapter); 2492 be_vf_clear(adapter);
2468 2493
2494 for (; adapter->uc_macs > 0; adapter->uc_macs--, i++)
2495 be_cmd_pmac_del(adapter, adapter->if_handle,
2496 adapter->pmac_id[i], 0);
2497
2469 be_cmd_if_destroy(adapter, adapter->if_handle, 0); 2498 be_cmd_if_destroy(adapter, adapter->if_handle, 0);
2470 2499
2471 be_mcc_queues_destroy(adapter); 2500 be_mcc_queues_destroy(adapter);
@@ -2477,6 +2506,7 @@ static int be_clear(struct be_adapter *adapter)
2477 be_cmd_fw_clean(adapter); 2506 be_cmd_fw_clean(adapter);
2478 2507
2479 be_msix_disable(adapter); 2508 be_msix_disable(adapter);
2509 kfree(adapter->pmac_id);
2480 return 0; 2510 return 0;
2481} 2511}
2482 2512
@@ -2552,10 +2582,10 @@ static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac)
2552 false, adapter->if_handle, pmac_id); 2582 false, adapter->if_handle, pmac_id);
2553 2583
2554 if (!status) 2584 if (!status)
2555 adapter->pmac_id = pmac_id; 2585 adapter->pmac_id[0] = pmac_id;
2556 } else { 2586 } else {
2557 status = be_cmd_pmac_add(adapter, mac, 2587 status = be_cmd_pmac_add(adapter, mac,
2558 adapter->if_handle, &adapter->pmac_id, 0); 2588 adapter->if_handle, &adapter->pmac_id[0], 0);
2559 } 2589 }
2560do_none: 2590do_none:
2561 return status; 2591 return status;
@@ -2610,7 +2640,7 @@ static int be_setup(struct be_adapter *adapter)
2610 } 2640 }
2611 status = be_cmd_if_create(adapter, cap_flags, en_flags, 2641 status = be_cmd_if_create(adapter, cap_flags, en_flags,
2612 netdev->dev_addr, &adapter->if_handle, 2642 netdev->dev_addr, &adapter->if_handle,
2613 &adapter->pmac_id, 0); 2643 &adapter->pmac_id[0], 0);
2614 if (status != 0) 2644 if (status != 0)
2615 goto err; 2645 goto err;
2616 2646
@@ -3059,6 +3089,8 @@ static void be_netdev_init(struct net_device *netdev)
3059 netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | 3089 netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
3060 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; 3090 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
3061 3091
3092 netdev->priv_flags |= IFF_UNICAST_FLT;
3093
3062 netdev->flags |= IFF_MULTICAST; 3094 netdev->flags |= IFF_MULTICAST;
3063 3095
3064 netif_set_gso_max_size(netdev, 65535); 3096 netif_set_gso_max_size(netdev, 65535);
@@ -3264,6 +3296,17 @@ static int be_get_config(struct be_adapter *adapter)
3264 else 3296 else
3265 adapter->max_vlans = BE_NUM_VLANS_SUPPORTED; 3297 adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
3266 3298
3299 if (be_physfn(adapter))
3300 adapter->max_pmac_cnt = BE_UC_PMAC_COUNT;
3301 else
3302 adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT;
3303
3304 /* primary mac needs 1 pmac entry */
3305 adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1,
3306 sizeof(u32), GFP_KERNEL);
3307 if (!adapter->pmac_id)
3308 return -ENOMEM;
3309
3267 status = be_cmd_get_cntl_attributes(adapter); 3310 status = be_cmd_get_cntl_attributes(adapter);
3268 if (status) 3311 if (status)
3269 return status; 3312 return status;