diff options
author | David S. Miller <davem@davemloft.net> | 2014-04-14 13:43:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-04-14 13:43:58 -0400 |
commit | 14ed4a5bcbd56e87e7c56b4604f43e47162a2e54 (patch) | |
tree | 83dca5a5591e1fdb07979f76e6394262dc7d3a97 | |
parent | 677df2f4aefaf9a87f6a37cc38453515547f4bda (diff) | |
parent | 696f1943a1538bb448c5bf55a18793ad410da00b (diff) |
Merge branch 'qlcnic'
Shahed Shaikh says:
====================
qlcnic: Bug fixes
This patch series contains following bug fixes -
* Send INIT_NIC_FUNC mailbox command as first mailbox
* Fix a panic because of uninitialized delayed_work.
* Fix inconsistent calculation of max rings count.
* Fix PVID configuration issue. Driver needs to clear older
PVID before adding new one.
* Fix QLogic application/driver interface by packing vNIC information
array.
* Fix a crash when user tries to disable SR-IOV while VFs are
still assigned to VMs.
Please apply to net.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 21 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 31 |
6 files changed, 43 insertions, 29 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index b48737dcd3c5..ba20c721ee97 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -2139,8 +2139,6 @@ static int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *adapter) | |||
2139 | ahw->max_mac_filters = nic_info.max_mac_filters; | 2139 | ahw->max_mac_filters = nic_info.max_mac_filters; |
2140 | ahw->max_mtu = nic_info.max_mtu; | 2140 | ahw->max_mtu = nic_info.max_mtu; |
2141 | 2141 | ||
2142 | adapter->max_tx_rings = ahw->max_tx_ques; | ||
2143 | adapter->max_sds_rings = ahw->max_rx_ques; | ||
2144 | /* eSwitch capability indicates vNIC mode. | 2142 | /* eSwitch capability indicates vNIC mode. |
2145 | * vNIC and SRIOV are mutually exclusive operational modes. | 2143 | * vNIC and SRIOV are mutually exclusive operational modes. |
2146 | * If SR-IOV capability is detected, SR-IOV physical function | 2144 | * If SR-IOV capability is detected, SR-IOV physical function |
@@ -2161,6 +2159,7 @@ static int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *adapter) | |||
2161 | int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter) | 2159 | int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter) |
2162 | { | 2160 | { |
2163 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 2161 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
2162 | u16 max_sds_rings, max_tx_rings; | ||
2164 | int ret; | 2163 | int ret; |
2165 | 2164 | ||
2166 | ret = qlcnic_83xx_get_nic_configuration(adapter); | 2165 | ret = qlcnic_83xx_get_nic_configuration(adapter); |
@@ -2173,18 +2172,21 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter) | |||
2173 | if (qlcnic_83xx_config_vnic_opmode(adapter)) | 2172 | if (qlcnic_83xx_config_vnic_opmode(adapter)) |
2174 | return -EIO; | 2173 | return -EIO; |
2175 | 2174 | ||
2176 | adapter->max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS; | 2175 | max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS; |
2177 | adapter->max_tx_rings = QLCNIC_MAX_VNIC_TX_RINGS; | 2176 | max_tx_rings = QLCNIC_MAX_VNIC_TX_RINGS; |
2178 | } else if (ret == QLC_83XX_DEFAULT_OPMODE) { | 2177 | } else if (ret == QLC_83XX_DEFAULT_OPMODE) { |
2179 | ahw->nic_mode = QLCNIC_DEFAULT_MODE; | 2178 | ahw->nic_mode = QLCNIC_DEFAULT_MODE; |
2180 | adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver; | 2179 | adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver; |
2181 | ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry; | 2180 | ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry; |
2182 | adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS; | 2181 | max_sds_rings = QLCNIC_MAX_SDS_RINGS; |
2183 | adapter->max_tx_rings = QLCNIC_MAX_TX_RINGS; | 2182 | max_tx_rings = QLCNIC_MAX_TX_RINGS; |
2184 | } else { | 2183 | } else { |
2185 | return -EIO; | 2184 | return -EIO; |
2186 | } | 2185 | } |
2187 | 2186 | ||
2187 | adapter->max_sds_rings = min(ahw->max_rx_ques, max_sds_rings); | ||
2188 | adapter->max_tx_rings = min(ahw->max_tx_ques, max_tx_rings); | ||
2189 | |||
2188 | return 0; | 2190 | return 0; |
2189 | } | 2191 | } |
2190 | 2192 | ||
@@ -2348,15 +2350,16 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) | |||
2348 | goto disable_intr; | 2350 | goto disable_intr; |
2349 | } | 2351 | } |
2350 | 2352 | ||
2353 | INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work); | ||
2354 | |||
2351 | err = qlcnic_83xx_setup_mbx_intr(adapter); | 2355 | err = qlcnic_83xx_setup_mbx_intr(adapter); |
2352 | if (err) | 2356 | if (err) |
2353 | goto disable_mbx_intr; | 2357 | goto disable_mbx_intr; |
2354 | 2358 | ||
2355 | qlcnic_83xx_clear_function_resources(adapter); | 2359 | qlcnic_83xx_clear_function_resources(adapter); |
2356 | 2360 | qlcnic_dcb_enable(adapter->dcb); | |
2357 | INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work); | ||
2358 | |||
2359 | qlcnic_83xx_initialize_nic(adapter, 1); | 2361 | qlcnic_83xx_initialize_nic(adapter, 1); |
2362 | qlcnic_dcb_get_info(adapter->dcb); | ||
2360 | 2363 | ||
2361 | /* Configure default, SR-IOV or Virtual NIC mode of operation */ | 2364 | /* Configure default, SR-IOV or Virtual NIC mode of operation */ |
2362 | err = qlcnic_83xx_configure_opmode(adapter); | 2365 | err = qlcnic_83xx_configure_opmode(adapter); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index 64dcbf33d8f0..c1e11f5715b0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | |||
@@ -883,8 +883,6 @@ int qlcnic_82xx_get_nic_info(struct qlcnic_adapter *adapter, | |||
883 | npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques); | 883 | npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques); |
884 | npar_info->capabilities = le32_to_cpu(nic_info->capabilities); | 884 | npar_info->capabilities = le32_to_cpu(nic_info->capabilities); |
885 | npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu); | 885 | npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu); |
886 | adapter->max_tx_rings = npar_info->max_tx_ques; | ||
887 | adapter->max_sds_rings = npar_info->max_rx_ques; | ||
888 | } | 886 | } |
889 | 887 | ||
890 | qlcnic_free_mbx_args(&cmd); | 888 | qlcnic_free_mbx_args(&cmd); |
@@ -1356,6 +1354,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, | |||
1356 | arg2 &= ~BIT_3; | 1354 | arg2 &= ~BIT_3; |
1357 | break; | 1355 | break; |
1358 | case QLCNIC_ADD_VLAN: | 1356 | case QLCNIC_ADD_VLAN: |
1357 | arg1 &= ~(0x0ffff << 16); | ||
1359 | arg1 |= (BIT_2 | BIT_5); | 1358 | arg1 |= (BIT_2 | BIT_5); |
1360 | arg1 |= (esw_cfg->vlan_id << 16); | 1359 | arg1 |= (esw_cfg->vlan_id << 16); |
1361 | break; | 1360 | break; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c index 7d4f54912bad..a51fe18f09a8 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c | |||
@@ -330,8 +330,6 @@ static int __qlcnic_dcb_attach(struct qlcnic_dcb *dcb) | |||
330 | goto out_free_cfg; | 330 | goto out_free_cfg; |
331 | } | 331 | } |
332 | 332 | ||
333 | qlcnic_dcb_get_info(dcb); | ||
334 | |||
335 | return 0; | 333 | return 0; |
336 | out_free_cfg: | 334 | out_free_cfg: |
337 | kfree(dcb->cfg); | 335 | kfree(dcb->cfg); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 309d05640883..84d011ed7ec2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -2528,8 +2528,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2528 | goto err_out_free_hw; | 2528 | goto err_out_free_hw; |
2529 | } | 2529 | } |
2530 | 2530 | ||
2531 | qlcnic_dcb_enable(adapter->dcb); | ||
2532 | |||
2533 | if (qlcnic_read_mac_addr(adapter)) | 2531 | if (qlcnic_read_mac_addr(adapter)) |
2534 | dev_warn(&pdev->dev, "failed to read mac addr\n"); | 2532 | dev_warn(&pdev->dev, "failed to read mac addr\n"); |
2535 | 2533 | ||
@@ -2549,7 +2547,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2549 | "Device does not support MSI interrupts\n"); | 2547 | "Device does not support MSI interrupts\n"); |
2550 | 2548 | ||
2551 | if (qlcnic_82xx_check(adapter)) { | 2549 | if (qlcnic_82xx_check(adapter)) { |
2550 | qlcnic_dcb_enable(adapter->dcb); | ||
2551 | qlcnic_dcb_get_info(adapter->dcb); | ||
2552 | err = qlcnic_setup_intr(adapter); | 2552 | err = qlcnic_setup_intr(adapter); |
2553 | |||
2553 | if (err) { | 2554 | if (err) { |
2554 | dev_err(&pdev->dev, "Failed to setup interrupt\n"); | 2555 | dev_err(&pdev->dev, "Failed to setup interrupt\n"); |
2555 | goto err_out_disable_msi; | 2556 | goto err_out_disable_msi; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 14f748cbf0de..280137991544 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | |||
@@ -461,6 +461,16 @@ static int qlcnic_pci_sriov_disable(struct qlcnic_adapter *adapter) | |||
461 | { | 461 | { |
462 | struct net_device *netdev = adapter->netdev; | 462 | struct net_device *netdev = adapter->netdev; |
463 | 463 | ||
464 | if (pci_vfs_assigned(adapter->pdev)) { | ||
465 | netdev_err(adapter->netdev, | ||
466 | "SR-IOV VFs belonging to port %d are assigned to VMs. SR-IOV can not be disabled on this port\n", | ||
467 | adapter->portnum); | ||
468 | netdev_info(adapter->netdev, | ||
469 | "Please detach SR-IOV VFs belonging to port %d from VMs, and then try to disable SR-IOV on this port\n", | ||
470 | adapter->portnum); | ||
471 | return -EPERM; | ||
472 | } | ||
473 | |||
464 | rtnl_lock(); | 474 | rtnl_lock(); |
465 | if (netif_running(netdev)) | 475 | if (netif_running(netdev)) |
466 | __qlcnic_down(adapter, netdev); | 476 | __qlcnic_down(adapter, netdev); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 448d156c3d08..cd346e27f2e1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -354,7 +354,7 @@ int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) | |||
354 | { | 354 | { |
355 | int i; | 355 | int i; |
356 | 356 | ||
357 | for (i = 0; i < adapter->ahw->max_vnic_func; i++) { | 357 | for (i = 0; i < adapter->ahw->total_nic_func; i++) { |
358 | if (adapter->npars[i].pci_func == pci_func) | 358 | if (adapter->npars[i].pci_func == pci_func) |
359 | return i; | 359 | return i; |
360 | } | 360 | } |
@@ -720,6 +720,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
720 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 720 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
721 | struct qlcnic_npar_func_cfg *np_cfg; | 721 | struct qlcnic_npar_func_cfg *np_cfg; |
722 | struct qlcnic_info nic_info; | 722 | struct qlcnic_info nic_info; |
723 | u8 pci_func; | ||
723 | int i, ret; | 724 | int i, ret; |
724 | u32 count; | 725 | u32 count; |
725 | 726 | ||
@@ -729,26 +730,28 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
729 | 730 | ||
730 | count = size / sizeof(struct qlcnic_npar_func_cfg); | 731 | count = size / sizeof(struct qlcnic_npar_func_cfg); |
731 | for (i = 0; i < adapter->ahw->total_nic_func; i++) { | 732 | for (i = 0; i < adapter->ahw->total_nic_func; i++) { |
732 | if (qlcnic_is_valid_nic_func(adapter, i) < 0) | ||
733 | continue; | ||
734 | if (adapter->npars[i].pci_func >= count) { | 733 | if (adapter->npars[i].pci_func >= count) { |
735 | dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n", | 734 | dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n", |
736 | __func__, adapter->ahw->total_nic_func, count); | 735 | __func__, adapter->ahw->total_nic_func, count); |
737 | continue; | 736 | continue; |
738 | } | 737 | } |
739 | ret = qlcnic_get_nic_info(adapter, &nic_info, i); | ||
740 | if (ret) | ||
741 | return ret; | ||
742 | if (!adapter->npars[i].eswitch_status) | 738 | if (!adapter->npars[i].eswitch_status) |
743 | continue; | 739 | continue; |
744 | np_cfg[i].pci_func = i; | 740 | pci_func = adapter->npars[i].pci_func; |
745 | np_cfg[i].op_mode = (u8)nic_info.op_mode; | 741 | if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0) |
746 | np_cfg[i].port_num = nic_info.phys_port; | 742 | continue; |
747 | np_cfg[i].fw_capab = nic_info.capabilities; | 743 | ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func); |
748 | np_cfg[i].min_bw = nic_info.min_tx_bw; | 744 | if (ret) |
749 | np_cfg[i].max_bw = nic_info.max_tx_bw; | 745 | return ret; |
750 | np_cfg[i].max_tx_queues = nic_info.max_tx_ques; | 746 | |
751 | np_cfg[i].max_rx_queues = nic_info.max_rx_ques; | 747 | np_cfg[pci_func].pci_func = pci_func; |
748 | np_cfg[pci_func].op_mode = (u8)nic_info.op_mode; | ||
749 | np_cfg[pci_func].port_num = nic_info.phys_port; | ||
750 | np_cfg[pci_func].fw_capab = nic_info.capabilities; | ||
751 | np_cfg[pci_func].min_bw = nic_info.min_tx_bw; | ||
752 | np_cfg[pci_func].max_bw = nic_info.max_tx_bw; | ||
753 | np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques; | ||
754 | np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques; | ||
752 | } | 755 | } |
753 | return size; | 756 | return size; |
754 | } | 757 | } |