diff options
author | Ajit Khaparde <ajit.khaparde@emulex.com> | 2012-03-18 02:23:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-03-19 16:52:17 -0400 |
commit | fbc13f018c0043146f8eccc7d6a6c0e66339e2d5 (patch) | |
tree | 6b4a162c091dbd8f0757c68a07cecd314779a239 | |
parent | 4762f6cec4455f3bbe4ca82c100fe5d85d3c02a2 (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.h | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 53 |
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 | ||
313 | struct be_adapter { | 315 | struct 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); |
889 | done: | 912 | done: |
890 | return; | 913 | return; |
@@ -2458,6 +2481,8 @@ static void be_vf_clear(struct be_adapter *adapter) | |||
2458 | 2481 | ||
2459 | static int be_clear(struct be_adapter *adapter) | 2482 | static 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 | } |
2560 | do_none: | 2590 | do_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; |