diff options
author | Sathya Perla <sathya.perla@emulex.com> | 2011-10-23 22:45:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-10-24 18:40:14 -0400 |
commit | f9449ab76805a2f0e739f5e85a6d9e32d089f1b2 (patch) | |
tree | 859c82352adf2a5347f03aa46c090aebcc2e738d /drivers/net/ethernet/emulex/benet/be_main.c | |
parent | a54769f51b9495f8313224fea670ab6fe720f4b1 (diff) |
be2net: refactor VF setup/teardown code into be_vf_setup/clear()
Currently the code for VF setup/teardown done by a PF (if_create,
mac_add_config, link_status_query etc) is scattered; this patch
refactors this code into be_vf_setup() and be_vf_clear(). The
if_create/if_destroy/mac_addr_query cmds are now called after the MCCQ
is created; so these cmds are now modified to use the MCCQ instead of
MBOX.
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex/benet/be_main.c')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 229 |
1 files changed, 105 insertions, 124 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index d05b6bb5ae81..d32e3787beb4 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -2069,7 +2069,7 @@ done: | |||
2069 | return; | 2069 | return; |
2070 | } | 2070 | } |
2071 | 2071 | ||
2072 | static void be_sriov_enable(struct be_adapter *adapter) | 2072 | static int be_sriov_enable(struct be_adapter *adapter) |
2073 | { | 2073 | { |
2074 | be_check_sriov_fn_type(adapter); | 2074 | be_check_sriov_fn_type(adapter); |
2075 | #ifdef CONFIG_PCI_IOV | 2075 | #ifdef CONFIG_PCI_IOV |
@@ -2091,8 +2091,17 @@ static void be_sriov_enable(struct be_adapter *adapter) | |||
2091 | 2091 | ||
2092 | status = pci_enable_sriov(adapter->pdev, num_vfs); | 2092 | status = pci_enable_sriov(adapter->pdev, num_vfs); |
2093 | adapter->sriov_enabled = status ? false : true; | 2093 | adapter->sriov_enabled = status ? false : true; |
2094 | |||
2095 | if (adapter->sriov_enabled) { | ||
2096 | adapter->vf_cfg = kcalloc(num_vfs, | ||
2097 | sizeof(struct be_vf_cfg), | ||
2098 | GFP_KERNEL); | ||
2099 | if (!adapter->vf_cfg) | ||
2100 | return -ENOMEM; | ||
2101 | } | ||
2094 | } | 2102 | } |
2095 | #endif | 2103 | #endif |
2104 | return 0; | ||
2096 | } | 2105 | } |
2097 | 2106 | ||
2098 | static void be_sriov_disable(struct be_adapter *adapter) | 2107 | static void be_sriov_disable(struct be_adapter *adapter) |
@@ -2100,6 +2109,7 @@ static void be_sriov_disable(struct be_adapter *adapter) | |||
2100 | #ifdef CONFIG_PCI_IOV | 2109 | #ifdef CONFIG_PCI_IOV |
2101 | if (adapter->sriov_enabled) { | 2110 | if (adapter->sriov_enabled) { |
2102 | pci_disable_sriov(adapter->pdev); | 2111 | pci_disable_sriov(adapter->pdev); |
2112 | kfree(adapter->vf_cfg); | ||
2103 | adapter->sriov_enabled = false; | 2113 | adapter->sriov_enabled = false; |
2104 | } | 2114 | } |
2105 | #endif | 2115 | #endif |
@@ -2405,7 +2415,7 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) | |||
2405 | */ | 2415 | */ |
2406 | static inline int be_vf_eth_addr_config(struct be_adapter *adapter) | 2416 | static inline int be_vf_eth_addr_config(struct be_adapter *adapter) |
2407 | { | 2417 | { |
2408 | u32 vf = 0; | 2418 | u32 vf; |
2409 | int status = 0; | 2419 | int status = 0; |
2410 | u8 mac[ETH_ALEN]; | 2420 | u8 mac[ETH_ALEN]; |
2411 | 2421 | ||
@@ -2427,7 +2437,7 @@ static inline int be_vf_eth_addr_config(struct be_adapter *adapter) | |||
2427 | return status; | 2437 | return status; |
2428 | } | 2438 | } |
2429 | 2439 | ||
2430 | static inline void be_vf_eth_addr_rem(struct be_adapter *adapter) | 2440 | static void be_vf_clear(struct be_adapter *adapter) |
2431 | { | 2441 | { |
2432 | u32 vf; | 2442 | u32 vf; |
2433 | 2443 | ||
@@ -2437,29 +2447,25 @@ static inline void be_vf_eth_addr_rem(struct be_adapter *adapter) | |||
2437 | adapter->vf_cfg[vf].vf_if_handle, | 2447 | adapter->vf_cfg[vf].vf_if_handle, |
2438 | adapter->vf_cfg[vf].vf_pmac_id, vf + 1); | 2448 | adapter->vf_cfg[vf].vf_pmac_id, vf + 1); |
2439 | } | 2449 | } |
2450 | |||
2451 | for (vf = 0; vf < num_vfs; vf++) | ||
2452 | if (adapter->vf_cfg[vf].vf_if_handle) | ||
2453 | be_cmd_if_destroy(adapter, | ||
2454 | adapter->vf_cfg[vf].vf_if_handle, vf + 1); | ||
2440 | } | 2455 | } |
2441 | 2456 | ||
2442 | static int be_clear(struct be_adapter *adapter) | 2457 | static int be_clear(struct be_adapter *adapter) |
2443 | { | 2458 | { |
2444 | int vf; | ||
2445 | |||
2446 | if (be_physfn(adapter) && adapter->sriov_enabled) | 2459 | if (be_physfn(adapter) && adapter->sriov_enabled) |
2447 | be_vf_eth_addr_rem(adapter); | 2460 | be_vf_clear(adapter); |
2461 | |||
2462 | be_cmd_if_destroy(adapter, adapter->if_handle, 0); | ||
2448 | 2463 | ||
2449 | be_mcc_queues_destroy(adapter); | 2464 | be_mcc_queues_destroy(adapter); |
2450 | be_rx_queues_destroy(adapter); | 2465 | be_rx_queues_destroy(adapter); |
2451 | be_tx_queues_destroy(adapter); | 2466 | be_tx_queues_destroy(adapter); |
2452 | adapter->eq_next_idx = 0; | 2467 | adapter->eq_next_idx = 0; |
2453 | 2468 | ||
2454 | if (be_physfn(adapter) && adapter->sriov_enabled) | ||
2455 | for (vf = 0; vf < num_vfs; vf++) | ||
2456 | if (adapter->vf_cfg[vf].vf_if_handle) | ||
2457 | be_cmd_if_destroy(adapter, | ||
2458 | adapter->vf_cfg[vf].vf_if_handle, | ||
2459 | vf + 1); | ||
2460 | |||
2461 | be_cmd_if_destroy(adapter, adapter->if_handle, 0); | ||
2462 | |||
2463 | adapter->be3_native = false; | 2469 | adapter->be3_native = false; |
2464 | adapter->promiscuous = false; | 2470 | adapter->promiscuous = false; |
2465 | 2471 | ||
@@ -2468,83 +2474,99 @@ static int be_clear(struct be_adapter *adapter) | |||
2468 | return 0; | 2474 | return 0; |
2469 | } | 2475 | } |
2470 | 2476 | ||
2477 | static int be_vf_setup(struct be_adapter *adapter) | ||
2478 | { | ||
2479 | u32 cap_flags, en_flags, vf; | ||
2480 | u16 lnk_speed; | ||
2481 | int status; | ||
2482 | |||
2483 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST; | ||
2484 | for (vf = 0; vf < num_vfs; vf++) { | ||
2485 | status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL, | ||
2486 | &adapter->vf_cfg[vf].vf_if_handle, | ||
2487 | NULL, vf+1); | ||
2488 | if (status) | ||
2489 | goto err; | ||
2490 | adapter->vf_cfg[vf].vf_pmac_id = BE_INVALID_PMAC_ID; | ||
2491 | } | ||
2492 | |||
2493 | if (!lancer_chip(adapter)) { | ||
2494 | status = be_vf_eth_addr_config(adapter); | ||
2495 | if (status) | ||
2496 | goto err; | ||
2497 | } | ||
2498 | |||
2499 | for (vf = 0; vf < num_vfs; vf++) { | ||
2500 | status = be_cmd_link_status_query(adapter, NULL, &lnk_speed, | ||
2501 | vf + 1); | ||
2502 | if (status) | ||
2503 | goto err; | ||
2504 | adapter->vf_cfg[vf].vf_tx_rate = lnk_speed * 10; | ||
2505 | } | ||
2506 | return 0; | ||
2507 | err: | ||
2508 | return status; | ||
2509 | } | ||
2510 | |||
2471 | static int be_setup(struct be_adapter *adapter) | 2511 | static int be_setup(struct be_adapter *adapter) |
2472 | { | 2512 | { |
2473 | struct net_device *netdev = adapter->netdev; | 2513 | struct net_device *netdev = adapter->netdev; |
2474 | u32 cap_flags, en_flags, vf = 0; | 2514 | u32 cap_flags, en_flags; |
2475 | u32 tx_fc, rx_fc; | 2515 | u32 tx_fc, rx_fc; |
2476 | int status; | 2516 | int status; |
2477 | u8 mac[ETH_ALEN]; | 2517 | u8 mac[ETH_ALEN]; |
2478 | 2518 | ||
2479 | be_cmd_req_native_mode(adapter); | 2519 | /* Allow all priorities by default. A GRP5 evt may modify this */ |
2480 | 2520 | adapter->vlan_prio_bmap = 0xff; | |
2481 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | | 2521 | adapter->link_speed = -1; |
2482 | BE_IF_FLAGS_BROADCAST | | ||
2483 | BE_IF_FLAGS_MULTICAST; | ||
2484 | 2522 | ||
2485 | if (be_physfn(adapter)) { | 2523 | be_cmd_req_native_mode(adapter); |
2486 | cap_flags |= BE_IF_FLAGS_MCAST_PROMISCUOUS | | ||
2487 | BE_IF_FLAGS_PROMISCUOUS | | ||
2488 | BE_IF_FLAGS_PASS_L3L4_ERRORS; | ||
2489 | en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS; | ||
2490 | |||
2491 | if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) { | ||
2492 | cap_flags |= BE_IF_FLAGS_RSS; | ||
2493 | en_flags |= BE_IF_FLAGS_RSS; | ||
2494 | } | ||
2495 | } | ||
2496 | 2524 | ||
2497 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | 2525 | status = be_tx_queues_create(adapter); |
2498 | netdev->dev_addr, false/* pmac_invalid */, | ||
2499 | &adapter->if_handle, &adapter->pmac_id, 0); | ||
2500 | if (status != 0) | 2526 | if (status != 0) |
2501 | goto err; | 2527 | goto err; |
2502 | 2528 | ||
2503 | if (be_physfn(adapter)) { | 2529 | status = be_rx_queues_create(adapter); |
2504 | if (adapter->sriov_enabled) { | ||
2505 | while (vf < num_vfs) { | ||
2506 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | | ||
2507 | BE_IF_FLAGS_BROADCAST; | ||
2508 | status = be_cmd_if_create(adapter, cap_flags, | ||
2509 | en_flags, mac, true, | ||
2510 | &adapter->vf_cfg[vf].vf_if_handle, | ||
2511 | NULL, vf+1); | ||
2512 | if (status) { | ||
2513 | dev_err(&adapter->pdev->dev, | ||
2514 | "Interface Create failed for VF %d\n", | ||
2515 | vf); | ||
2516 | goto err; | ||
2517 | } | ||
2518 | adapter->vf_cfg[vf].vf_pmac_id = | ||
2519 | BE_INVALID_PMAC_ID; | ||
2520 | vf++; | ||
2521 | } | ||
2522 | } | ||
2523 | } else { | ||
2524 | status = be_cmd_mac_addr_query(adapter, mac, | ||
2525 | MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); | ||
2526 | if (!status) { | ||
2527 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | ||
2528 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | ||
2529 | } | ||
2530 | } | ||
2531 | |||
2532 | status = be_tx_queues_create(adapter); | ||
2533 | if (status != 0) | 2530 | if (status != 0) |
2534 | goto err; | 2531 | goto err; |
2535 | 2532 | ||
2536 | status = be_rx_queues_create(adapter); | 2533 | status = be_mcc_queues_create(adapter); |
2537 | if (status != 0) | 2534 | if (status != 0) |
2538 | goto err; | 2535 | goto err; |
2539 | 2536 | ||
2540 | /* Allow all priorities by default. A GRP5 evt may modify this */ | 2537 | memset(mac, 0, ETH_ALEN); |
2541 | adapter->vlan_prio_bmap = 0xff; | 2538 | status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK, |
2539 | true /*permanent */, 0); | ||
2540 | if (status) | ||
2541 | return status; | ||
2542 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | ||
2543 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | ||
2542 | 2544 | ||
2543 | status = be_mcc_queues_create(adapter); | 2545 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | |
2546 | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS; | ||
2547 | cap_flags = en_flags | BE_IF_FLAGS_MCAST_PROMISCUOUS | | ||
2548 | BE_IF_FLAGS_PROMISCUOUS; | ||
2549 | if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) { | ||
2550 | cap_flags |= BE_IF_FLAGS_RSS; | ||
2551 | en_flags |= BE_IF_FLAGS_RSS; | ||
2552 | } | ||
2553 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | ||
2554 | netdev->dev_addr, &adapter->if_handle, | ||
2555 | &adapter->pmac_id, 0); | ||
2544 | if (status != 0) | 2556 | if (status != 0) |
2545 | goto err; | 2557 | goto err; |
2546 | 2558 | ||
2547 | adapter->link_speed = -1; | 2559 | /* For BEx, the VF's permanent mac queried from card is incorrect. |
2560 | * Query the mac configued by the PF using if_handle | ||
2561 | */ | ||
2562 | if (!be_physfn(adapter) && !lancer_chip(adapter)) { | ||
2563 | status = be_cmd_mac_addr_query(adapter, mac, | ||
2564 | MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); | ||
2565 | if (!status) { | ||
2566 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | ||
2567 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | ||
2568 | } | ||
2569 | } | ||
2548 | 2570 | ||
2549 | be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL); | 2571 | be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL); |
2550 | 2572 | ||
@@ -2565,8 +2587,14 @@ static int be_setup(struct be_adapter *adapter) | |||
2565 | } | 2587 | } |
2566 | 2588 | ||
2567 | pcie_set_readrq(adapter->pdev, 4096); | 2589 | pcie_set_readrq(adapter->pdev, 4096); |
2568 | return 0; | ||
2569 | 2590 | ||
2591 | if (be_physfn(adapter) && adapter->sriov_enabled) { | ||
2592 | status = be_vf_setup(adapter); | ||
2593 | if (status) | ||
2594 | goto err; | ||
2595 | } | ||
2596 | |||
2597 | return 0; | ||
2570 | err: | 2598 | err: |
2571 | be_clear(adapter); | 2599 | be_clear(adapter); |
2572 | return status; | 2600 | return status; |
@@ -3123,7 +3151,6 @@ static void __devexit be_remove(struct pci_dev *pdev) | |||
3123 | 3151 | ||
3124 | be_ctrl_cleanup(adapter); | 3152 | be_ctrl_cleanup(adapter); |
3125 | 3153 | ||
3126 | kfree(adapter->vf_cfg); | ||
3127 | be_sriov_disable(adapter); | 3154 | be_sriov_disable(adapter); |
3128 | 3155 | ||
3129 | be_msix_disable(adapter); | 3156 | be_msix_disable(adapter); |
@@ -3138,30 +3165,12 @@ static void __devexit be_remove(struct pci_dev *pdev) | |||
3138 | static int be_get_config(struct be_adapter *adapter) | 3165 | static int be_get_config(struct be_adapter *adapter) |
3139 | { | 3166 | { |
3140 | int status; | 3167 | int status; |
3141 | u8 mac[ETH_ALEN]; | ||
3142 | 3168 | ||
3143 | status = be_cmd_query_fw_cfg(adapter, &adapter->port_num, | 3169 | status = be_cmd_query_fw_cfg(adapter, &adapter->port_num, |
3144 | &adapter->function_mode, &adapter->function_caps); | 3170 | &adapter->function_mode, &adapter->function_caps); |
3145 | if (status) | 3171 | if (status) |
3146 | return status; | 3172 | return status; |
3147 | 3173 | ||
3148 | memset(mac, 0, ETH_ALEN); | ||
3149 | |||
3150 | /* A default permanent address is given to each VF for Lancer*/ | ||
3151 | if (be_physfn(adapter) || lancer_chip(adapter)) { | ||
3152 | status = be_cmd_mac_addr_query(adapter, mac, | ||
3153 | MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0); | ||
3154 | |||
3155 | if (status) | ||
3156 | return status; | ||
3157 | |||
3158 | if (!is_valid_ether_addr(mac)) | ||
3159 | return -EADDRNOTAVAIL; | ||
3160 | |||
3161 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | ||
3162 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | ||
3163 | } | ||
3164 | |||
3165 | if (adapter->function_mode & 0x400) | 3174 | if (adapter->function_mode & 0x400) |
3166 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4; | 3175 | adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4; |
3167 | else | 3176 | else |
@@ -3310,18 +3319,13 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
3310 | } | 3319 | } |
3311 | } | 3320 | } |
3312 | 3321 | ||
3313 | be_sriov_enable(adapter); | 3322 | status = be_sriov_enable(adapter); |
3314 | if (adapter->sriov_enabled) { | 3323 | if (status) |
3315 | adapter->vf_cfg = kcalloc(num_vfs, | 3324 | goto free_netdev; |
3316 | sizeof(struct be_vf_cfg), GFP_KERNEL); | ||
3317 | |||
3318 | if (!adapter->vf_cfg) | ||
3319 | goto free_netdev; | ||
3320 | } | ||
3321 | 3325 | ||
3322 | status = be_ctrl_init(adapter); | 3326 | status = be_ctrl_init(adapter); |
3323 | if (status) | 3327 | if (status) |
3324 | goto free_vf_cfg; | 3328 | goto disable_sriov; |
3325 | 3329 | ||
3326 | if (lancer_chip(adapter)) { | 3330 | if (lancer_chip(adapter)) { |
3327 | status = lancer_test_and_set_rdy_state(adapter); | 3331 | status = lancer_test_and_set_rdy_state(adapter); |
@@ -3375,33 +3379,11 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
3375 | if (status != 0) | 3379 | if (status != 0) |
3376 | goto unsetup; | 3380 | goto unsetup; |
3377 | 3381 | ||
3378 | if (be_physfn(adapter) && adapter->sriov_enabled) { | ||
3379 | u8 mac_speed; | ||
3380 | u16 vf, lnk_speed; | ||
3381 | |||
3382 | if (!lancer_chip(adapter)) { | ||
3383 | status = be_vf_eth_addr_config(adapter); | ||
3384 | if (status) | ||
3385 | goto unreg_netdev; | ||
3386 | } | ||
3387 | |||
3388 | for (vf = 0; vf < num_vfs; vf++) { | ||
3389 | status = be_cmd_link_status_query(adapter, &mac_speed, | ||
3390 | &lnk_speed, vf + 1); | ||
3391 | if (!status) | ||
3392 | adapter->vf_cfg[vf].vf_tx_rate = lnk_speed * 10; | ||
3393 | else | ||
3394 | goto unreg_netdev; | ||
3395 | } | ||
3396 | } | ||
3397 | |||
3398 | dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); | 3382 | dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); |
3399 | 3383 | ||
3400 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); | 3384 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); |
3401 | return 0; | 3385 | return 0; |
3402 | 3386 | ||
3403 | unreg_netdev: | ||
3404 | unregister_netdev(netdev); | ||
3405 | unsetup: | 3387 | unsetup: |
3406 | be_clear(adapter); | 3388 | be_clear(adapter); |
3407 | msix_disable: | 3389 | msix_disable: |
@@ -3410,10 +3392,9 @@ stats_clean: | |||
3410 | be_stats_cleanup(adapter); | 3392 | be_stats_cleanup(adapter); |
3411 | ctrl_clean: | 3393 | ctrl_clean: |
3412 | be_ctrl_cleanup(adapter); | 3394 | be_ctrl_cleanup(adapter); |
3413 | free_vf_cfg: | 3395 | disable_sriov: |
3414 | kfree(adapter->vf_cfg); | ||
3415 | free_netdev: | ||
3416 | be_sriov_disable(adapter); | 3396 | be_sriov_disable(adapter); |
3397 | free_netdev: | ||
3417 | free_netdev(netdev); | 3398 | free_netdev(netdev); |
3418 | pci_set_drvdata(pdev, NULL); | 3399 | pci_set_drvdata(pdev, NULL); |
3419 | rel_reg: | 3400 | rel_reg: |