diff options
author | David S. Miller <davem@davemloft.net> | 2014-05-09 13:10:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-09 13:10:12 -0400 |
commit | fe6f397c433c43a4404259d6ee3f1200b9a6d97e (patch) | |
tree | cb65904068dada14f327e1c4aec60c2618a35667 | |
parent | a3ab3c13f1fe6eea92468ddd1681d41e133fe703 (diff) | |
parent | 27a4041e16b5bab07d74e82bb09d0933f7737cf6 (diff) |
Merge branch 'qlcnic-next'
Rajesh Borundia says:
====================
qlcnic: SR-IOV and FW-dump enhancements
This patch series contain following enhancements.
* SR-IOV enhancements:
- Allow SR-IOV VF's to probe in hypervisor. SR-IOV VF can be
uplinked to bridge/macvtap device with this change.
- Commands from VF are processed in process context
as it may sleep during PF-VF communication. Earlier
we use to process qlcnic_sriov_vf_set_multi function in
process context but now we process individual commands.
- As SR-IOV VF's can be uplinked to bridge/macvtap device
support mac-learning to allow communication through
embedded switch.
* FW-dump enhancement:
- Support to collect RDMEM section of firmware dump using
PEX DMA method for 82xx series adapter.
* Changes in v2:
- Removed unnecessary cast from void pointer to something
else and verified this issue in entire patch series as
per David Miller's suggestion.
Please apply this series to net-next.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 31 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 25 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c | 37 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 188 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 84 |
11 files changed, 244 insertions, 203 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 09fe9c276f1c..6cb24dc864ba 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -39,8 +39,8 @@ | |||
39 | 39 | ||
40 | #define _QLCNIC_LINUX_MAJOR 5 | 40 | #define _QLCNIC_LINUX_MAJOR 5 |
41 | #define _QLCNIC_LINUX_MINOR 3 | 41 | #define _QLCNIC_LINUX_MINOR 3 |
42 | #define _QLCNIC_LINUX_SUBVERSION 58 | 42 | #define _QLCNIC_LINUX_SUBVERSION 59 |
43 | #define QLCNIC_LINUX_VERSIONID "5.3.58" | 43 | #define QLCNIC_LINUX_VERSIONID "5.3.59" |
44 | #define QLCNIC_DRV_IDC_VER 0x01 | 44 | #define QLCNIC_DRV_IDC_VER 0x01 |
45 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ | 45 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ |
46 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) | 46 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) |
@@ -1019,6 +1019,8 @@ struct qlcnic_ipaddr { | |||
1019 | #define QLCNIC_DEL_VXLAN_PORT 0x200000 | 1019 | #define QLCNIC_DEL_VXLAN_PORT 0x200000 |
1020 | #endif | 1020 | #endif |
1021 | 1021 | ||
1022 | #define QLCNIC_VLAN_FILTERING 0x800000 | ||
1023 | |||
1022 | #define QLCNIC_IS_MSI_FAMILY(adapter) \ | 1024 | #define QLCNIC_IS_MSI_FAMILY(adapter) \ |
1023 | ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) | 1025 | ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) |
1024 | #define QLCNIC_IS_TSO_CAPABLE(adapter) \ | 1026 | #define QLCNIC_IS_TSO_CAPABLE(adapter) \ |
@@ -1693,7 +1695,7 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *); | |||
1693 | int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); | 1695 | int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); |
1694 | void qlcnic_set_netdev_features(struct qlcnic_adapter *, | 1696 | void qlcnic_set_netdev_features(struct qlcnic_adapter *, |
1695 | struct qlcnic_esw_func_cfg *); | 1697 | struct qlcnic_esw_func_cfg *); |
1696 | void qlcnic_sriov_vf_schedule_multi(struct net_device *); | 1698 | void qlcnic_sriov_vf_set_multi(struct net_device *); |
1697 | int qlcnic_is_valid_nic_func(struct qlcnic_adapter *, u8); | 1699 | int qlcnic_is_valid_nic_func(struct qlcnic_adapter *, u8); |
1698 | int qlcnic_get_pci_func_type(struct qlcnic_adapter *, u16, u16 *, u16 *, | 1700 | int qlcnic_get_pci_func_type(struct qlcnic_adapter *, u16, u16 *, u16 *, |
1699 | u16 *); | 1701 | u16 *); |
@@ -2355,6 +2357,16 @@ static inline bool qlcnic_83xx_vf_check(struct qlcnic_adapter *adapter) | |||
2355 | return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false; | 2357 | return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false; |
2356 | } | 2358 | } |
2357 | 2359 | ||
2360 | static inline bool qlcnic_sriov_check(struct qlcnic_adapter *adapter) | ||
2361 | { | ||
2362 | bool status; | ||
2363 | |||
2364 | status = (qlcnic_sriov_pf_check(adapter) || | ||
2365 | qlcnic_sriov_vf_check(adapter)) ? true : false; | ||
2366 | |||
2367 | return status; | ||
2368 | } | ||
2369 | |||
2358 | static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter) | 2370 | static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter) |
2359 | { | 2371 | { |
2360 | if (qlcnic_84xx_check(adapter)) | 2372 | if (qlcnic_84xx_check(adapter)) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 7c125d7fb547..a4a4ec0b68f8 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -3037,19 +3037,18 @@ void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter) | |||
3037 | QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK); | 3037 | QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK); |
3038 | } | 3038 | } |
3039 | 3039 | ||
3040 | int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, | 3040 | int qlcnic_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, |
3041 | u32 *data, u32 count) | 3041 | u32 *data, u32 count) |
3042 | { | 3042 | { |
3043 | int i, j, ret = 0; | 3043 | int i, j, ret = 0; |
3044 | u32 temp; | 3044 | u32 temp; |
3045 | int err = 0; | ||
3046 | 3045 | ||
3047 | /* Check alignment */ | 3046 | /* Check alignment */ |
3048 | if (addr & 0xF) | 3047 | if (addr & 0xF) |
3049 | return -EIO; | 3048 | return -EIO; |
3050 | 3049 | ||
3051 | mutex_lock(&adapter->ahw->mem_lock); | 3050 | mutex_lock(&adapter->ahw->mem_lock); |
3052 | qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_HI, 0); | 3051 | qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_HI, 0); |
3053 | 3052 | ||
3054 | for (i = 0; i < count; i++, addr += 16) { | 3053 | for (i = 0; i < count; i++, addr += 16) { |
3055 | if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET, | 3054 | if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET, |
@@ -3060,26 +3059,16 @@ int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr, | |||
3060 | return -EIO; | 3059 | return -EIO; |
3061 | } | 3060 | } |
3062 | 3061 | ||
3063 | qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_LO, addr); | 3062 | qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_LO, addr); |
3064 | qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_LO, | 3063 | qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_LO, *data++); |
3065 | *data++); | 3064 | qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_HI, *data++); |
3066 | qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_HI, | 3065 | qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_ULO, *data++); |
3067 | *data++); | 3066 | qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_UHI, *data++); |
3068 | qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_ULO, | 3067 | qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_ENABLE); |
3069 | *data++); | 3068 | qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_START); |
3070 | qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_UHI, | ||
3071 | *data++); | ||
3072 | qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL, | ||
3073 | QLCNIC_TA_WRITE_ENABLE); | ||
3074 | qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL, | ||
3075 | QLCNIC_TA_WRITE_START); | ||
3076 | 3069 | ||
3077 | for (j = 0; j < MAX_CTL_CHECK; j++) { | 3070 | for (j = 0; j < MAX_CTL_CHECK; j++) { |
3078 | temp = QLCRD32(adapter, QLCNIC_MS_CTRL, &err); | 3071 | temp = qlcnic_ind_rd(adapter, QLCNIC_MS_CTRL); |
3079 | if (err == -EIO) { | ||
3080 | mutex_unlock(&adapter->ahw->mem_lock); | ||
3081 | return err; | ||
3082 | } | ||
3083 | 3072 | ||
3084 | if ((temp & TA_CTL_BUSY) == 0) | 3073 | if ((temp & TA_CTL_BUSY) == 0) |
3085 | break; | 3074 | break; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 88d809c35633..97784d09933f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | |||
@@ -560,7 +560,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *); | |||
560 | void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); | 560 | void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); |
561 | void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); | 561 | void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); |
562 | int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32); | 562 | int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32); |
563 | void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); | 563 | int qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); |
564 | int qlcnic_ind_rd(struct qlcnic_adapter *, u32); | 564 | int qlcnic_ind_rd(struct qlcnic_adapter *, u32); |
565 | int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *); | 565 | int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *); |
566 | int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *, | 566 | int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *, |
@@ -617,7 +617,6 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *, u32); | |||
617 | int qlcnic_83xx_lock_driver(struct qlcnic_adapter *); | 617 | int qlcnic_83xx_lock_driver(struct qlcnic_adapter *); |
618 | void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *); | 618 | void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *); |
619 | int qlcnic_83xx_set_default_offload_settings(struct qlcnic_adapter *); | 619 | int qlcnic_83xx_set_default_offload_settings(struct qlcnic_adapter *); |
620 | int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32); | ||
621 | int qlcnic_83xx_idc_vnic_pf_entry(struct qlcnic_adapter *); | 620 | int qlcnic_83xx_idc_vnic_pf_entry(struct qlcnic_adapter *); |
622 | int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *, int); | 621 | int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *, int); |
623 | int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *); | 622 | int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *); |
@@ -659,4 +658,5 @@ void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *); | |||
659 | u32 qlcnic_83xx_get_cap_size(void *, int); | 658 | u32 qlcnic_83xx_get_cap_size(void *, int); |
660 | void qlcnic_83xx_set_sys_info(void *, int, u32); | 659 | void qlcnic_83xx_set_sys_info(void *, int, u32); |
661 | void qlcnic_83xx_store_cap_mask(void *, u32); | 660 | void qlcnic_83xx_store_cap_mask(void *, u32); |
661 | int qlcnic_ms_mem_write128(struct qlcnic_adapter *, u64, u32 *, u32); | ||
662 | #endif | 662 | #endif |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 34d273794e96..f33559b72528 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -1363,8 +1363,8 @@ static int qlcnic_83xx_copy_bootloader(struct qlcnic_adapter *adapter) | |||
1363 | return ret; | 1363 | return ret; |
1364 | } | 1364 | } |
1365 | /* 16 byte write to MS memory */ | 1365 | /* 16 byte write to MS memory */ |
1366 | ret = qlcnic_83xx_ms_mem_write128(adapter, dest, (u32 *)p_cache, | 1366 | ret = qlcnic_ms_mem_write128(adapter, dest, (u32 *)p_cache, |
1367 | size / 16); | 1367 | size / 16); |
1368 | if (ret) { | 1368 | if (ret) { |
1369 | vfree(p_cache); | 1369 | vfree(p_cache); |
1370 | return ret; | 1370 | return ret; |
@@ -1389,8 +1389,8 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) | |||
1389 | p_cache = (u32 *)fw->data; | 1389 | p_cache = (u32 *)fw->data; |
1390 | addr = (u64)dest; | 1390 | addr = (u64)dest; |
1391 | 1391 | ||
1392 | ret = qlcnic_83xx_ms_mem_write128(adapter, addr, | 1392 | ret = qlcnic_ms_mem_write128(adapter, addr, |
1393 | p_cache, size / 16); | 1393 | p_cache, size / 16); |
1394 | if (ret) { | 1394 | if (ret) { |
1395 | dev_err(&adapter->pdev->dev, "MS memory write failed\n"); | 1395 | dev_err(&adapter->pdev->dev, "MS memory write failed\n"); |
1396 | release_firmware(fw); | 1396 | release_firmware(fw); |
@@ -1405,8 +1405,8 @@ static int qlcnic_83xx_copy_fw_file(struct qlcnic_adapter *adapter) | |||
1405 | data[i] = fw->data[size + i]; | 1405 | data[i] = fw->data[size + i]; |
1406 | for (; i < 16; i++) | 1406 | for (; i < 16; i++) |
1407 | data[i] = 0; | 1407 | data[i] = 0; |
1408 | ret = qlcnic_83xx_ms_mem_write128(adapter, addr, | 1408 | ret = qlcnic_ms_mem_write128(adapter, addr, |
1409 | (u32 *)data, 1); | 1409 | (u32 *)data, 1); |
1410 | if (ret) { | 1410 | if (ret) { |
1411 | dev_err(&adapter->pdev->dev, | 1411 | dev_err(&adapter->pdev->dev, |
1412 | "MS memory write failed\n"); | 1412 | "MS memory write failed\n"); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 9f3adf4e70b5..c9e8574959b7 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | |||
@@ -373,12 +373,16 @@ int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr) | |||
373 | return data; | 373 | return data; |
374 | } | 374 | } |
375 | 375 | ||
376 | void qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data) | 376 | int qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data) |
377 | { | 377 | { |
378 | int ret = 0; | ||
379 | |||
378 | if (qlcnic_82xx_check(adapter)) | 380 | if (qlcnic_82xx_check(adapter)) |
379 | qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data); | 381 | qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data); |
380 | else | 382 | else |
381 | qlcnic_83xx_wrt_reg_indirect(adapter, addr, data); | 383 | ret = qlcnic_83xx_wrt_reg_indirect(adapter, addr, data); |
384 | |||
385 | return ret; | ||
382 | } | 386 | } |
383 | 387 | ||
384 | static int | 388 | static int |
@@ -567,28 +571,14 @@ static void __qlcnic_set_multi(struct net_device *netdev, u16 vlan) | |||
567 | void qlcnic_set_multi(struct net_device *netdev) | 571 | void qlcnic_set_multi(struct net_device *netdev) |
568 | { | 572 | { |
569 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 573 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
570 | struct qlcnic_mac_vlan_list *cur; | ||
571 | struct netdev_hw_addr *ha; | ||
572 | size_t temp; | ||
573 | 574 | ||
574 | if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) | 575 | if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) |
575 | return; | 576 | return; |
576 | if (qlcnic_sriov_vf_check(adapter)) { | 577 | |
577 | if (!netdev_mc_empty(netdev)) { | 578 | if (qlcnic_sriov_vf_check(adapter)) |
578 | netdev_for_each_mc_addr(ha, netdev) { | 579 | qlcnic_sriov_vf_set_multi(netdev); |
579 | temp = sizeof(struct qlcnic_mac_vlan_list); | 580 | else |
580 | cur = kzalloc(temp, GFP_ATOMIC); | 581 | __qlcnic_set_multi(netdev, 0); |
581 | if (cur == NULL) | ||
582 | break; | ||
583 | memcpy(cur->mac_addr, | ||
584 | ha->addr, ETH_ALEN); | ||
585 | list_add_tail(&cur->list, &adapter->vf_mc_list); | ||
586 | } | ||
587 | } | ||
588 | qlcnic_sriov_vf_schedule_multi(adapter->netdev); | ||
589 | return; | ||
590 | } | ||
591 | __qlcnic_set_multi(netdev, 0); | ||
592 | } | 582 | } |
593 | 583 | ||
594 | int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) | 584 | int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index deb2278b48d5..e45bf09af0c9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | |||
@@ -313,20 +313,16 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, | |||
313 | u16 vlan_id = 0; | 313 | u16 vlan_id = 0; |
314 | u8 hindex, hval; | 314 | u8 hindex, hval; |
315 | 315 | ||
316 | if (!qlcnic_sriov_pf_check(adapter)) { | 316 | if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) |
317 | if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) | 317 | return; |
318 | return; | 318 | |
319 | } else { | 319 | if (adapter->flags & QLCNIC_VLAN_FILTERING) { |
320 | if (protocol == ETH_P_8021Q) { | 320 | if (protocol == ETH_P_8021Q) { |
321 | vh = (struct vlan_ethhdr *)skb->data; | 321 | vh = (struct vlan_ethhdr *)skb->data; |
322 | vlan_id = ntohs(vh->h_vlan_TCI); | 322 | vlan_id = ntohs(vh->h_vlan_TCI); |
323 | } else if (vlan_tx_tag_present(skb)) { | 323 | } else if (vlan_tx_tag_present(skb)) { |
324 | vlan_id = vlan_tx_tag_get(skb); | 324 | vlan_id = vlan_tx_tag_get(skb); |
325 | } | 325 | } |
326 | |||
327 | if (ether_addr_equal(phdr->h_source, adapter->mac_addr) && | ||
328 | !vlan_id) | ||
329 | return; | ||
330 | } | 326 | } |
331 | 327 | ||
332 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); | 328 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 7023d358baa9..8a570fa3542b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -378,7 +378,8 @@ static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], | |||
378 | if (!adapter->fdb_mac_learn) | 378 | if (!adapter->fdb_mac_learn) |
379 | return ndo_dflt_fdb_del(ndm, tb, netdev, addr); | 379 | return ndo_dflt_fdb_del(ndm, tb, netdev, addr); |
380 | 380 | ||
381 | if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { | 381 | if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) || |
382 | qlcnic_sriov_check(adapter)) { | ||
382 | if (is_unicast_ether_addr(addr)) { | 383 | if (is_unicast_ether_addr(addr)) { |
383 | err = dev_uc_del(netdev, addr); | 384 | err = dev_uc_del(netdev, addr); |
384 | if (!err) | 385 | if (!err) |
@@ -402,7 +403,8 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], | |||
402 | if (!adapter->fdb_mac_learn) | 403 | if (!adapter->fdb_mac_learn) |
403 | return ndo_dflt_fdb_add(ndm, tb, netdev, addr, flags); | 404 | return ndo_dflt_fdb_add(ndm, tb, netdev, addr, flags); |
404 | 405 | ||
405 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | 406 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) && |
407 | !qlcnic_sriov_check(adapter)) { | ||
406 | pr_info("%s: FDB e-switch is not enabled\n", __func__); | 408 | pr_info("%s: FDB e-switch is not enabled\n", __func__); |
407 | return -EOPNOTSUPP; | 409 | return -EOPNOTSUPP; |
408 | } | 410 | } |
@@ -432,7 +434,8 @@ static int qlcnic_fdb_dump(struct sk_buff *skb, struct netlink_callback *ncb, | |||
432 | if (!adapter->fdb_mac_learn) | 434 | if (!adapter->fdb_mac_learn) |
433 | return ndo_dflt_fdb_dump(skb, ncb, netdev, idx); | 435 | return ndo_dflt_fdb_dump(skb, ncb, netdev, idx); |
434 | 436 | ||
435 | if (adapter->flags & QLCNIC_ESWITCH_ENABLED) | 437 | if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) || |
438 | qlcnic_sriov_check(adapter)) | ||
436 | idx = ndo_dflt_fdb_dump(skb, ncb, netdev, idx); | 439 | idx = ndo_dflt_fdb_dump(skb, ncb, netdev, idx); |
437 | 440 | ||
438 | return idx; | 441 | return idx; |
@@ -1917,8 +1920,6 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
1917 | if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state)) | 1920 | if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state)) |
1918 | return; | 1921 | return; |
1919 | 1922 | ||
1920 | if (qlcnic_sriov_vf_check(adapter)) | ||
1921 | qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); | ||
1922 | smp_mb(); | 1923 | smp_mb(); |
1923 | netif_carrier_off(netdev); | 1924 | netif_carrier_off(netdev); |
1924 | adapter->ahw->linkup = 0; | 1925 | adapter->ahw->linkup = 0; |
@@ -1930,6 +1931,8 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
1930 | qlcnic_delete_lb_filters(adapter); | 1931 | qlcnic_delete_lb_filters(adapter); |
1931 | 1932 | ||
1932 | qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); | 1933 | qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); |
1934 | if (qlcnic_sriov_vf_check(adapter)) | ||
1935 | qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); | ||
1933 | 1936 | ||
1934 | qlcnic_napi_disable(adapter); | 1937 | qlcnic_napi_disable(adapter); |
1935 | 1938 | ||
@@ -2398,9 +2401,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2398 | int err, pci_using_dac = -1; | 2401 | int err, pci_using_dac = -1; |
2399 | char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ | 2402 | char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ |
2400 | 2403 | ||
2401 | if (pdev->is_virtfn) | ||
2402 | return -ENODEV; | ||
2403 | |||
2404 | err = pci_enable_device(pdev); | 2404 | err = pci_enable_device(pdev); |
2405 | if (err) | 2405 | if (err) |
2406 | return err; | 2406 | return err; |
@@ -2680,9 +2680,9 @@ static void qlcnic_remove(struct pci_dev *pdev) | |||
2680 | return; | 2680 | return; |
2681 | 2681 | ||
2682 | netdev = adapter->netdev; | 2682 | netdev = adapter->netdev; |
2683 | qlcnic_sriov_pf_disable(adapter); | ||
2684 | 2683 | ||
2685 | qlcnic_cancel_idc_work(adapter); | 2684 | qlcnic_cancel_idc_work(adapter); |
2685 | qlcnic_sriov_pf_disable(adapter); | ||
2686 | ahw = adapter->ahw; | 2686 | ahw = adapter->ahw; |
2687 | 2687 | ||
2688 | unregister_netdev(netdev); | 2688 | unregister_netdev(netdev); |
@@ -2812,6 +2812,8 @@ static int qlcnic_close(struct net_device *netdev) | |||
2812 | return 0; | 2812 | return 0; |
2813 | } | 2813 | } |
2814 | 2814 | ||
2815 | #define QLCNIC_VF_LB_BUCKET_SIZE 1 | ||
2816 | |||
2815 | void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) | 2817 | void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) |
2816 | { | 2818 | { |
2817 | void *head; | 2819 | void *head; |
@@ -2827,7 +2829,10 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) | |||
2827 | spin_lock_init(&adapter->mac_learn_lock); | 2829 | spin_lock_init(&adapter->mac_learn_lock); |
2828 | spin_lock_init(&adapter->rx_mac_learn_lock); | 2830 | spin_lock_init(&adapter->rx_mac_learn_lock); |
2829 | 2831 | ||
2830 | if (qlcnic_82xx_check(adapter)) { | 2832 | if (qlcnic_sriov_vf_check(adapter)) { |
2833 | filter_size = QLCNIC_83XX_SRIOV_VF_MAX_MAC - 1; | ||
2834 | adapter->fhash.fbucket_size = QLCNIC_VF_LB_BUCKET_SIZE; | ||
2835 | } else if (qlcnic_82xx_check(adapter)) { | ||
2831 | filter_size = QLCNIC_LB_MAX_FILTERS; | 2836 | filter_size = QLCNIC_LB_MAX_FILTERS; |
2832 | adapter->fhash.fbucket_size = QLCNIC_LB_BUCKET_SIZE; | 2837 | adapter->fhash.fbucket_size = QLCNIC_LB_BUCKET_SIZE; |
2833 | } else { | 2838 | } else { |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c index 37b979b1266b..f7694da8ed5d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c | |||
@@ -238,6 +238,8 @@ void qlcnic_82xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) | |||
238 | 238 | ||
239 | hdr->drv_cap_mask = hdr->cap_mask; | 239 | hdr->drv_cap_mask = hdr->cap_mask; |
240 | fw_dump->cap_mask = hdr->cap_mask; | 240 | fw_dump->cap_mask = hdr->cap_mask; |
241 | |||
242 | fw_dump->use_pex_dma = (hdr->capabilities & BIT_0) ? true : false; | ||
241 | } | 243 | } |
242 | 244 | ||
243 | inline u32 qlcnic_82xx_get_cap_size(void *t_hdr, int index) | 245 | inline u32 qlcnic_82xx_get_cap_size(void *t_hdr, int index) |
@@ -276,6 +278,8 @@ inline void qlcnic_83xx_set_saved_state(void *t_hdr, u32 index, | |||
276 | hdr->saved_state[index] = value; | 278 | hdr->saved_state[index] = value; |
277 | } | 279 | } |
278 | 280 | ||
281 | #define QLCNIC_TEMPLATE_VERSION (0x20001) | ||
282 | |||
279 | void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) | 283 | void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) |
280 | { | 284 | { |
281 | struct qlcnic_83xx_dump_template_hdr *hdr; | 285 | struct qlcnic_83xx_dump_template_hdr *hdr; |
@@ -288,6 +292,9 @@ void qlcnic_83xx_cache_tmpl_hdr_values(struct qlcnic_fw_dump *fw_dump) | |||
288 | 292 | ||
289 | hdr->drv_cap_mask = hdr->cap_mask; | 293 | hdr->drv_cap_mask = hdr->cap_mask; |
290 | fw_dump->cap_mask = hdr->cap_mask; | 294 | fw_dump->cap_mask = hdr->cap_mask; |
295 | |||
296 | fw_dump->use_pex_dma = (fw_dump->version & 0xfffff) >= | ||
297 | QLCNIC_TEMPLATE_VERSION; | ||
291 | } | 298 | } |
292 | 299 | ||
293 | inline u32 qlcnic_83xx_get_cap_size(void *t_hdr, int index) | 300 | inline u32 qlcnic_83xx_get_cap_size(void *t_hdr, int index) |
@@ -658,29 +665,28 @@ out: | |||
658 | static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter, | 665 | static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter, |
659 | struct __mem *mem) | 666 | struct __mem *mem) |
660 | { | 667 | { |
661 | struct qlcnic_83xx_dump_template_hdr *tmpl_hdr; | ||
662 | struct device *dev = &adapter->pdev->dev; | 668 | struct device *dev = &adapter->pdev->dev; |
663 | u32 dma_no, dma_base_addr, temp_addr; | 669 | u32 dma_no, dma_base_addr, temp_addr; |
664 | int i, ret, dma_sts; | 670 | int i, ret, dma_sts; |
671 | void *tmpl_hdr; | ||
665 | 672 | ||
666 | tmpl_hdr = adapter->ahw->fw_dump.tmpl_hdr; | 673 | tmpl_hdr = adapter->ahw->fw_dump.tmpl_hdr; |
667 | dma_no = tmpl_hdr->saved_state[QLC_83XX_DMA_ENGINE_INDEX]; | 674 | dma_no = qlcnic_get_saved_state(adapter, tmpl_hdr, |
675 | QLC_83XX_DMA_ENGINE_INDEX); | ||
668 | dma_base_addr = QLC_DMA_REG_BASE_ADDR(dma_no); | 676 | dma_base_addr = QLC_DMA_REG_BASE_ADDR(dma_no); |
669 | 677 | ||
670 | temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_LOW; | 678 | temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_LOW; |
671 | ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, | 679 | ret = qlcnic_ind_wr(adapter, temp_addr, mem->desc_card_addr); |
672 | mem->desc_card_addr); | ||
673 | if (ret) | 680 | if (ret) |
674 | return ret; | 681 | return ret; |
675 | 682 | ||
676 | temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_HI; | 683 | temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_HI; |
677 | ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, 0); | 684 | ret = qlcnic_ind_wr(adapter, temp_addr, 0); |
678 | if (ret) | 685 | if (ret) |
679 | return ret; | 686 | return ret; |
680 | 687 | ||
681 | temp_addr = dma_base_addr + QLC_DMA_CMD_STATUS_CTRL; | 688 | temp_addr = dma_base_addr + QLC_DMA_CMD_STATUS_CTRL; |
682 | ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, | 689 | ret = qlcnic_ind_wr(adapter, temp_addr, mem->start_dma_cmd); |
683 | mem->start_dma_cmd); | ||
684 | if (ret) | 690 | if (ret) |
685 | return ret; | 691 | return ret; |
686 | 692 | ||
@@ -710,15 +716,16 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter, | |||
710 | struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; | 716 | struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump; |
711 | u32 temp, dma_base_addr, size = 0, read_size = 0; | 717 | u32 temp, dma_base_addr, size = 0, read_size = 0; |
712 | struct qlcnic_pex_dma_descriptor *dma_descr; | 718 | struct qlcnic_pex_dma_descriptor *dma_descr; |
713 | struct qlcnic_83xx_dump_template_hdr *tmpl_hdr; | ||
714 | struct device *dev = &adapter->pdev->dev; | 719 | struct device *dev = &adapter->pdev->dev; |
715 | dma_addr_t dma_phys_addr; | 720 | dma_addr_t dma_phys_addr; |
716 | void *dma_buffer; | 721 | void *dma_buffer; |
722 | void *tmpl_hdr; | ||
717 | 723 | ||
718 | tmpl_hdr = fw_dump->tmpl_hdr; | 724 | tmpl_hdr = fw_dump->tmpl_hdr; |
719 | 725 | ||
720 | /* Check if DMA engine is available */ | 726 | /* Check if DMA engine is available */ |
721 | temp = tmpl_hdr->saved_state[QLC_83XX_DMA_ENGINE_INDEX]; | 727 | temp = qlcnic_get_saved_state(adapter, tmpl_hdr, |
728 | QLC_83XX_DMA_ENGINE_INDEX); | ||
722 | dma_base_addr = QLC_DMA_REG_BASE_ADDR(temp); | 729 | dma_base_addr = QLC_DMA_REG_BASE_ADDR(temp); |
723 | temp = qlcnic_ind_rd(adapter, | 730 | temp = qlcnic_ind_rd(adapter, |
724 | dma_base_addr + QLC_DMA_CMD_STATUS_CTRL); | 731 | dma_base_addr + QLC_DMA_CMD_STATUS_CTRL); |
@@ -764,8 +771,8 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter, | |||
764 | 771 | ||
765 | /* Write DMA descriptor to MS memory*/ | 772 | /* Write DMA descriptor to MS memory*/ |
766 | temp = sizeof(struct qlcnic_pex_dma_descriptor) / 16; | 773 | temp = sizeof(struct qlcnic_pex_dma_descriptor) / 16; |
767 | *ret = qlcnic_83xx_ms_mem_write128(adapter, mem->desc_card_addr, | 774 | *ret = qlcnic_ms_mem_write128(adapter, mem->desc_card_addr, |
768 | (u32 *)dma_descr, temp); | 775 | (u32 *)dma_descr, temp); |
769 | if (*ret) { | 776 | if (*ret) { |
770 | dev_info(dev, "Failed to write DMA descriptor to MS memory at address 0x%x\n", | 777 | dev_info(dev, "Failed to write DMA descriptor to MS memory at address 0x%x\n", |
771 | mem->desc_card_addr); | 778 | mem->desc_card_addr); |
@@ -1141,8 +1148,6 @@ free_mem: | |||
1141 | return err; | 1148 | return err; |
1142 | } | 1149 | } |
1143 | 1150 | ||
1144 | #define QLCNIC_TEMPLATE_VERSION (0x20001) | ||
1145 | |||
1146 | int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) | 1151 | int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) |
1147 | { | 1152 | { |
1148 | struct qlcnic_hardware_context *ahw; | 1153 | struct qlcnic_hardware_context *ahw; |
@@ -1203,12 +1208,6 @@ flash_temp: | |||
1203 | "Default minidump capture mask 0x%x\n", | 1208 | "Default minidump capture mask 0x%x\n", |
1204 | fw_dump->cap_mask); | 1209 | fw_dump->cap_mask); |
1205 | 1210 | ||
1206 | if (qlcnic_83xx_check(adapter) && | ||
1207 | (fw_dump->version & 0xfffff) >= QLCNIC_TEMPLATE_VERSION) | ||
1208 | fw_dump->use_pex_dma = true; | ||
1209 | else | ||
1210 | fw_dump->use_pex_dma = false; | ||
1211 | |||
1212 | qlcnic_enable_fw_dump_state(adapter); | 1211 | qlcnic_enable_fw_dump_state(adapter); |
1213 | 1212 | ||
1214 | return 0; | 1213 | return 0; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h index 396bd1fd1d27..335b50f7bd3e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h | |||
@@ -52,6 +52,7 @@ enum qlcnic_bc_commands { | |||
52 | QLCNIC_BC_CMD_CFG_GUEST_VLAN = 0x3, | 52 | QLCNIC_BC_CMD_CFG_GUEST_VLAN = 0x3, |
53 | }; | 53 | }; |
54 | 54 | ||
55 | #define QLCNIC_83XX_SRIOV_VF_MAX_MAC 2 | ||
55 | #define QLC_BC_CMD 1 | 56 | #define QLC_BC_CMD 1 |
56 | 57 | ||
57 | struct qlcnic_trans_list { | 58 | struct qlcnic_trans_list { |
@@ -151,13 +152,14 @@ struct qlcnic_vf_info { | |||
151 | struct qlcnic_trans_list rcv_pend; | 152 | struct qlcnic_trans_list rcv_pend; |
152 | struct qlcnic_adapter *adapter; | 153 | struct qlcnic_adapter *adapter; |
153 | struct qlcnic_vport *vp; | 154 | struct qlcnic_vport *vp; |
154 | struct mutex vlan_list_lock; /* Lock for VLAN list */ | 155 | spinlock_t vlan_list_lock; /* Lock for VLAN list */ |
155 | }; | 156 | }; |
156 | 157 | ||
157 | struct qlcnic_async_work_list { | 158 | struct qlcnic_async_work_list { |
158 | struct list_head list; | 159 | struct list_head list; |
159 | struct work_struct work; | 160 | struct work_struct work; |
160 | void *ptr; | 161 | void *ptr; |
162 | struct qlcnic_cmd_args *cmd; | ||
161 | }; | 163 | }; |
162 | 164 | ||
163 | struct qlcnic_back_channel { | 165 | struct qlcnic_back_channel { |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 0638c1810d54..3b39ab2ad5e9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | |||
@@ -39,6 +39,8 @@ static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *, u8); | |||
39 | static void qlcnic_sriov_process_bc_cmd(struct work_struct *); | 39 | static void qlcnic_sriov_process_bc_cmd(struct work_struct *); |
40 | static int qlcnic_sriov_vf_shutdown(struct pci_dev *); | 40 | static int qlcnic_sriov_vf_shutdown(struct pci_dev *); |
41 | static int qlcnic_sriov_vf_resume(struct qlcnic_adapter *); | 41 | static int qlcnic_sriov_vf_resume(struct qlcnic_adapter *); |
42 | static int qlcnic_sriov_async_issue_cmd(struct qlcnic_adapter *, | ||
43 | struct qlcnic_cmd_args *); | ||
42 | 44 | ||
43 | static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = { | 45 | static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = { |
44 | .read_crb = qlcnic_83xx_read_crb, | 46 | .read_crb = qlcnic_83xx_read_crb, |
@@ -181,7 +183,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) | |||
181 | vf->adapter = adapter; | 183 | vf->adapter = adapter; |
182 | vf->pci_func = qlcnic_sriov_virtid_fn(adapter, i); | 184 | vf->pci_func = qlcnic_sriov_virtid_fn(adapter, i); |
183 | mutex_init(&vf->send_cmd_lock); | 185 | mutex_init(&vf->send_cmd_lock); |
184 | mutex_init(&vf->vlan_list_lock); | 186 | spin_lock_init(&vf->vlan_list_lock); |
185 | INIT_LIST_HEAD(&vf->rcv_act.wait_list); | 187 | INIT_LIST_HEAD(&vf->rcv_act.wait_list); |
186 | INIT_LIST_HEAD(&vf->rcv_pend.wait_list); | 188 | INIT_LIST_HEAD(&vf->rcv_pend.wait_list); |
187 | spin_lock_init(&vf->rcv_act.lock); | 189 | spin_lock_init(&vf->rcv_act.lock); |
@@ -197,8 +199,9 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) | |||
197 | goto qlcnic_destroy_async_wq; | 199 | goto qlcnic_destroy_async_wq; |
198 | } | 200 | } |
199 | sriov->vf_info[i].vp = vp; | 201 | sriov->vf_info[i].vp = vp; |
202 | vp->vlan_mode = QLC_GUEST_VLAN_MODE; | ||
200 | vp->max_tx_bw = MAX_BW; | 203 | vp->max_tx_bw = MAX_BW; |
201 | vp->spoofchk = true; | 204 | vp->spoofchk = false; |
202 | random_ether_addr(vp->mac); | 205 | random_ether_addr(vp->mac); |
203 | dev_info(&adapter->pdev->dev, | 206 | dev_info(&adapter->pdev->dev, |
204 | "MAC Address %pM is configured for VF %d\n", | 207 | "MAC Address %pM is configured for VF %d\n", |
@@ -515,6 +518,8 @@ static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter, | |||
515 | { | 518 | { |
516 | int err; | 519 | int err; |
517 | 520 | ||
521 | adapter->flags |= QLCNIC_VLAN_FILTERING; | ||
522 | adapter->ahw->total_nic_func = 1; | ||
518 | INIT_LIST_HEAD(&adapter->vf_mc_list); | 523 | INIT_LIST_HEAD(&adapter->vf_mc_list); |
519 | if (!qlcnic_use_msi_x && !!qlcnic_use_msi) | 524 | if (!qlcnic_use_msi_x && !!qlcnic_use_msi) |
520 | dev_warn(&adapter->pdev->dev, | 525 | dev_warn(&adapter->pdev->dev, |
@@ -770,6 +775,7 @@ static int qlcnic_sriov_prepare_bc_hdr(struct qlcnic_bc_trans *trans, | |||
770 | cmd->req.arg = (u32 *)trans->req_pay; | 775 | cmd->req.arg = (u32 *)trans->req_pay; |
771 | cmd->rsp.arg = (u32 *)trans->rsp_pay; | 776 | cmd->rsp.arg = (u32 *)trans->rsp_pay; |
772 | cmd_op = cmd->req.arg[0] & 0xff; | 777 | cmd_op = cmd->req.arg[0] & 0xff; |
778 | cmd->cmd_op = cmd_op; | ||
773 | remainder = (trans->rsp_pay_size) % (bc_pay_sz); | 779 | remainder = (trans->rsp_pay_size) % (bc_pay_sz); |
774 | num_frags = (trans->rsp_pay_size) / (bc_pay_sz); | 780 | num_frags = (trans->rsp_pay_size) / (bc_pay_sz); |
775 | if (remainder) | 781 | if (remainder) |
@@ -1356,7 +1362,7 @@ static int qlcnic_sriov_retry_bc_cmd(struct qlcnic_adapter *adapter, | |||
1356 | return -EIO; | 1362 | return -EIO; |
1357 | } | 1363 | } |
1358 | 1364 | ||
1359 | static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, | 1365 | static int __qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, |
1360 | struct qlcnic_cmd_args *cmd) | 1366 | struct qlcnic_cmd_args *cmd) |
1361 | { | 1367 | { |
1362 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 1368 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
@@ -1408,12 +1414,17 @@ retry: | |||
1408 | (mbx_err_code == QLCNIC_MBX_PORT_RSP_OK)) { | 1414 | (mbx_err_code == QLCNIC_MBX_PORT_RSP_OK)) { |
1409 | rsp = QLCNIC_RCODE_SUCCESS; | 1415 | rsp = QLCNIC_RCODE_SUCCESS; |
1410 | } else { | 1416 | } else { |
1411 | rsp = mbx_err_code; | 1417 | if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) { |
1412 | if (!rsp) | 1418 | rsp = QLCNIC_RCODE_SUCCESS; |
1413 | rsp = 1; | 1419 | } else { |
1414 | dev_err(dev, | 1420 | rsp = mbx_err_code; |
1415 | "MBX command 0x%x failed with err:0x%x for VF %d\n", | 1421 | if (!rsp) |
1416 | opcode, mbx_err_code, func); | 1422 | rsp = 1; |
1423 | |||
1424 | dev_err(dev, | ||
1425 | "MBX command 0x%x failed with err:0x%x for VF %d\n", | ||
1426 | opcode, mbx_err_code, func); | ||
1427 | } | ||
1417 | } | 1428 | } |
1418 | 1429 | ||
1419 | err_out: | 1430 | err_out: |
@@ -1428,6 +1439,16 @@ cleanup_transaction: | |||
1428 | return rsp; | 1439 | return rsp; |
1429 | } | 1440 | } |
1430 | 1441 | ||
1442 | |||
1443 | static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, | ||
1444 | struct qlcnic_cmd_args *cmd) | ||
1445 | { | ||
1446 | if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) | ||
1447 | return qlcnic_sriov_async_issue_cmd(adapter, cmd); | ||
1448 | else | ||
1449 | return __qlcnic_sriov_issue_cmd(adapter, cmd); | ||
1450 | } | ||
1451 | |||
1431 | static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_op) | 1452 | static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_op) |
1432 | { | 1453 | { |
1433 | struct qlcnic_cmd_args cmd; | 1454 | struct qlcnic_cmd_args cmd; |
@@ -1458,58 +1479,28 @@ out: | |||
1458 | return ret; | 1479 | return ret; |
1459 | } | 1480 | } |
1460 | 1481 | ||
1461 | static void qlcnic_vf_add_mc_list(struct net_device *netdev) | 1482 | static void qlcnic_vf_add_mc_list(struct net_device *netdev, const u8 *mac) |
1462 | { | 1483 | { |
1463 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1484 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1464 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; | 1485 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; |
1465 | struct qlcnic_mac_vlan_list *cur; | ||
1466 | struct list_head *head, tmp_list; | ||
1467 | struct qlcnic_vf_info *vf; | 1486 | struct qlcnic_vf_info *vf; |
1468 | u16 vlan_id; | 1487 | u16 vlan_id; |
1469 | int i; | 1488 | int i; |
1470 | 1489 | ||
1471 | static const u8 bcast_addr[ETH_ALEN] = { | ||
1472 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | ||
1473 | }; | ||
1474 | |||
1475 | vf = &adapter->ahw->sriov->vf_info[0]; | 1490 | vf = &adapter->ahw->sriov->vf_info[0]; |
1476 | INIT_LIST_HEAD(&tmp_list); | ||
1477 | head = &adapter->vf_mc_list; | ||
1478 | netif_addr_lock_bh(netdev); | ||
1479 | 1491 | ||
1480 | while (!list_empty(head)) { | 1492 | if (!qlcnic_sriov_check_any_vlan(vf)) { |
1481 | cur = list_entry(head->next, struct qlcnic_mac_vlan_list, list); | 1493 | qlcnic_nic_add_mac(adapter, mac, 0); |
1482 | list_move(&cur->list, &tmp_list); | 1494 | } else { |
1483 | } | 1495 | spin_lock(&vf->vlan_list_lock); |
1484 | 1496 | for (i = 0; i < sriov->num_allowed_vlans; i++) { | |
1485 | netif_addr_unlock_bh(netdev); | 1497 | vlan_id = vf->sriov_vlans[i]; |
1486 | 1498 | if (vlan_id) | |
1487 | while (!list_empty(&tmp_list)) { | 1499 | qlcnic_nic_add_mac(adapter, mac, vlan_id); |
1488 | cur = list_entry((&tmp_list)->next, | ||
1489 | struct qlcnic_mac_vlan_list, list); | ||
1490 | if (!qlcnic_sriov_check_any_vlan(vf)) { | ||
1491 | qlcnic_nic_add_mac(adapter, bcast_addr, 0); | ||
1492 | qlcnic_nic_add_mac(adapter, cur->mac_addr, 0); | ||
1493 | } else { | ||
1494 | mutex_lock(&vf->vlan_list_lock); | ||
1495 | for (i = 0; i < sriov->num_allowed_vlans; i++) { | ||
1496 | vlan_id = vf->sriov_vlans[i]; | ||
1497 | if (vlan_id) { | ||
1498 | qlcnic_nic_add_mac(adapter, bcast_addr, | ||
1499 | vlan_id); | ||
1500 | qlcnic_nic_add_mac(adapter, | ||
1501 | cur->mac_addr, | ||
1502 | vlan_id); | ||
1503 | } | ||
1504 | } | ||
1505 | mutex_unlock(&vf->vlan_list_lock); | ||
1506 | if (qlcnic_84xx_check(adapter)) { | ||
1507 | qlcnic_nic_add_mac(adapter, bcast_addr, 0); | ||
1508 | qlcnic_nic_add_mac(adapter, cur->mac_addr, 0); | ||
1509 | } | ||
1510 | } | 1500 | } |
1511 | list_del(&cur->list); | 1501 | spin_unlock(&vf->vlan_list_lock); |
1512 | kfree(cur); | 1502 | if (qlcnic_84xx_check(adapter)) |
1503 | qlcnic_nic_add_mac(adapter, mac, 0); | ||
1513 | } | 1504 | } |
1514 | } | 1505 | } |
1515 | 1506 | ||
@@ -1518,6 +1509,7 @@ void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *bc) | |||
1518 | struct list_head *head = &bc->async_list; | 1509 | struct list_head *head = &bc->async_list; |
1519 | struct qlcnic_async_work_list *entry; | 1510 | struct qlcnic_async_work_list *entry; |
1520 | 1511 | ||
1512 | flush_workqueue(bc->bc_async_wq); | ||
1521 | while (!list_empty(head)) { | 1513 | while (!list_empty(head)) { |
1522 | entry = list_entry(head->next, struct qlcnic_async_work_list, | 1514 | entry = list_entry(head->next, struct qlcnic_async_work_list, |
1523 | list); | 1515 | list); |
@@ -1527,10 +1519,14 @@ void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *bc) | |||
1527 | } | 1519 | } |
1528 | } | 1520 | } |
1529 | 1521 | ||
1530 | static void qlcnic_sriov_vf_set_multi(struct net_device *netdev) | 1522 | void qlcnic_sriov_vf_set_multi(struct net_device *netdev) |
1531 | { | 1523 | { |
1532 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1524 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1533 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 1525 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
1526 | static const u8 bcast_addr[ETH_ALEN] = { | ||
1527 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | ||
1528 | }; | ||
1529 | struct netdev_hw_addr *ha; | ||
1534 | u32 mode = VPORT_MISS_MODE_DROP; | 1530 | u32 mode = VPORT_MISS_MODE_DROP; |
1535 | 1531 | ||
1536 | if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) | 1532 | if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) |
@@ -1542,23 +1538,49 @@ static void qlcnic_sriov_vf_set_multi(struct net_device *netdev) | |||
1542 | } else if ((netdev->flags & IFF_ALLMULTI) || | 1538 | } else if ((netdev->flags & IFF_ALLMULTI) || |
1543 | (netdev_mc_count(netdev) > ahw->max_mc_count)) { | 1539 | (netdev_mc_count(netdev) > ahw->max_mc_count)) { |
1544 | mode = VPORT_MISS_MODE_ACCEPT_MULTI; | 1540 | mode = VPORT_MISS_MODE_ACCEPT_MULTI; |
1541 | } else { | ||
1542 | qlcnic_vf_add_mc_list(netdev, bcast_addr); | ||
1543 | if (!netdev_mc_empty(netdev)) { | ||
1544 | netdev_for_each_mc_addr(ha, netdev) | ||
1545 | qlcnic_vf_add_mc_list(netdev, ha->addr); | ||
1546 | } | ||
1545 | } | 1547 | } |
1546 | 1548 | ||
1547 | if (qlcnic_sriov_vf_check(adapter)) | 1549 | /* configure unicast MAC address, if there is not sufficient space |
1548 | qlcnic_vf_add_mc_list(netdev); | 1550 | * to store all the unicast addresses then enable promiscuous mode |
1551 | */ | ||
1552 | if (netdev_uc_count(netdev) > ahw->max_uc_count) { | ||
1553 | mode = VPORT_MISS_MODE_ACCEPT_ALL; | ||
1554 | } else if (!netdev_uc_empty(netdev)) { | ||
1555 | netdev_for_each_uc_addr(ha, netdev) | ||
1556 | qlcnic_vf_add_mc_list(netdev, ha->addr); | ||
1557 | } | ||
1558 | |||
1559 | if (adapter->pdev->is_virtfn) { | ||
1560 | if (mode == VPORT_MISS_MODE_ACCEPT_ALL && | ||
1561 | !adapter->fdb_mac_learn) { | ||
1562 | qlcnic_alloc_lb_filters_mem(adapter); | ||
1563 | adapter->drv_mac_learn = 1; | ||
1564 | adapter->rx_mac_learn = true; | ||
1565 | } else { | ||
1566 | adapter->drv_mac_learn = 0; | ||
1567 | adapter->rx_mac_learn = false; | ||
1568 | } | ||
1569 | } | ||
1549 | 1570 | ||
1550 | qlcnic_nic_set_promisc(adapter, mode); | 1571 | qlcnic_nic_set_promisc(adapter, mode); |
1551 | } | 1572 | } |
1552 | 1573 | ||
1553 | static void qlcnic_sriov_handle_async_multi(struct work_struct *work) | 1574 | static void qlcnic_sriov_handle_async_issue_cmd(struct work_struct *work) |
1554 | { | 1575 | { |
1555 | struct qlcnic_async_work_list *entry; | 1576 | struct qlcnic_async_work_list *entry; |
1556 | struct net_device *netdev; | 1577 | struct qlcnic_adapter *adapter; |
1578 | struct qlcnic_cmd_args *cmd; | ||
1557 | 1579 | ||
1558 | entry = container_of(work, struct qlcnic_async_work_list, work); | 1580 | entry = container_of(work, struct qlcnic_async_work_list, work); |
1559 | netdev = (struct net_device *)entry->ptr; | 1581 | adapter = entry->ptr; |
1560 | 1582 | cmd = entry->cmd; | |
1561 | qlcnic_sriov_vf_set_multi(netdev); | 1583 | __qlcnic_sriov_issue_cmd(adapter, cmd); |
1562 | return; | 1584 | return; |
1563 | } | 1585 | } |
1564 | 1586 | ||
@@ -1588,8 +1610,9 @@ qlcnic_sriov_get_free_node_async_work(struct qlcnic_back_channel *bc) | |||
1588 | return entry; | 1610 | return entry; |
1589 | } | 1611 | } |
1590 | 1612 | ||
1591 | static void qlcnic_sriov_schedule_bc_async_work(struct qlcnic_back_channel *bc, | 1613 | static void qlcnic_sriov_schedule_async_cmd(struct qlcnic_back_channel *bc, |
1592 | work_func_t func, void *data) | 1614 | work_func_t func, void *data, |
1615 | struct qlcnic_cmd_args *cmd) | ||
1593 | { | 1616 | { |
1594 | struct qlcnic_async_work_list *entry = NULL; | 1617 | struct qlcnic_async_work_list *entry = NULL; |
1595 | 1618 | ||
@@ -1598,21 +1621,23 @@ static void qlcnic_sriov_schedule_bc_async_work(struct qlcnic_back_channel *bc, | |||
1598 | return; | 1621 | return; |
1599 | 1622 | ||
1600 | entry->ptr = data; | 1623 | entry->ptr = data; |
1624 | entry->cmd = cmd; | ||
1601 | INIT_WORK(&entry->work, func); | 1625 | INIT_WORK(&entry->work, func); |
1602 | queue_work(bc->bc_async_wq, &entry->work); | 1626 | queue_work(bc->bc_async_wq, &entry->work); |
1603 | } | 1627 | } |
1604 | 1628 | ||
1605 | void qlcnic_sriov_vf_schedule_multi(struct net_device *netdev) | 1629 | static int qlcnic_sriov_async_issue_cmd(struct qlcnic_adapter *adapter, |
1630 | struct qlcnic_cmd_args *cmd) | ||
1606 | { | 1631 | { |
1607 | 1632 | ||
1608 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | ||
1609 | struct qlcnic_back_channel *bc = &adapter->ahw->sriov->bc; | 1633 | struct qlcnic_back_channel *bc = &adapter->ahw->sriov->bc; |
1610 | 1634 | ||
1611 | if (adapter->need_fw_reset) | 1635 | if (adapter->need_fw_reset) |
1612 | return; | 1636 | return -EIO; |
1613 | 1637 | ||
1614 | qlcnic_sriov_schedule_bc_async_work(bc, qlcnic_sriov_handle_async_multi, | 1638 | qlcnic_sriov_schedule_async_cmd(bc, qlcnic_sriov_handle_async_issue_cmd, |
1615 | netdev); | 1639 | adapter, cmd); |
1640 | return 0; | ||
1616 | } | 1641 | } |
1617 | 1642 | ||
1618 | static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter) | 1643 | static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter) |
@@ -1836,6 +1861,12 @@ static int qlcnic_sriov_vf_idc_unknown_state(struct qlcnic_adapter *adapter) | |||
1836 | return 0; | 1861 | return 0; |
1837 | } | 1862 | } |
1838 | 1863 | ||
1864 | static void qlcnic_sriov_vf_periodic_tasks(struct qlcnic_adapter *adapter) | ||
1865 | { | ||
1866 | if (adapter->fhash.fnum) | ||
1867 | qlcnic_prune_lb_filters(adapter); | ||
1868 | } | ||
1869 | |||
1839 | static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *work) | 1870 | static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *work) |
1840 | { | 1871 | { |
1841 | struct qlcnic_adapter *adapter; | 1872 | struct qlcnic_adapter *adapter; |
@@ -1867,6 +1898,8 @@ static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *work) | |||
1867 | } | 1898 | } |
1868 | 1899 | ||
1869 | idc->prev_state = idc->curr_state; | 1900 | idc->prev_state = idc->curr_state; |
1901 | qlcnic_sriov_vf_periodic_tasks(adapter); | ||
1902 | |||
1870 | if (!ret && test_bit(QLC_83XX_MODULE_LOADED, &idc->status)) | 1903 | if (!ret && test_bit(QLC_83XX_MODULE_LOADED, &idc->status)) |
1871 | qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state, | 1904 | qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state, |
1872 | idc->delay); | 1905 | idc->delay); |
@@ -1890,7 +1923,7 @@ static int qlcnic_sriov_check_vlan_id(struct qlcnic_sriov *sriov, | |||
1890 | if (!vf->sriov_vlans) | 1923 | if (!vf->sriov_vlans) |
1891 | return err; | 1924 | return err; |
1892 | 1925 | ||
1893 | mutex_lock(&vf->vlan_list_lock); | 1926 | spin_lock_bh(&vf->vlan_list_lock); |
1894 | 1927 | ||
1895 | for (i = 0; i < sriov->num_allowed_vlans; i++) { | 1928 | for (i = 0; i < sriov->num_allowed_vlans; i++) { |
1896 | if (vf->sriov_vlans[i] == vlan_id) { | 1929 | if (vf->sriov_vlans[i] == vlan_id) { |
@@ -1899,7 +1932,7 @@ static int qlcnic_sriov_check_vlan_id(struct qlcnic_sriov *sriov, | |||
1899 | } | 1932 | } |
1900 | } | 1933 | } |
1901 | 1934 | ||
1902 | mutex_unlock(&vf->vlan_list_lock); | 1935 | spin_unlock_bh(&vf->vlan_list_lock); |
1903 | return err; | 1936 | return err; |
1904 | } | 1937 | } |
1905 | 1938 | ||
@@ -1908,12 +1941,12 @@ static int qlcnic_sriov_validate_num_vlans(struct qlcnic_sriov *sriov, | |||
1908 | { | 1941 | { |
1909 | int err = 0; | 1942 | int err = 0; |
1910 | 1943 | ||
1911 | mutex_lock(&vf->vlan_list_lock); | 1944 | spin_lock_bh(&vf->vlan_list_lock); |
1912 | 1945 | ||
1913 | if (vf->num_vlan >= sriov->num_allowed_vlans) | 1946 | if (vf->num_vlan >= sriov->num_allowed_vlans) |
1914 | err = -EINVAL; | 1947 | err = -EINVAL; |
1915 | 1948 | ||
1916 | mutex_unlock(&vf->vlan_list_lock); | 1949 | spin_unlock_bh(&vf->vlan_list_lock); |
1917 | return err; | 1950 | return err; |
1918 | } | 1951 | } |
1919 | 1952 | ||
@@ -1966,7 +1999,7 @@ static void qlcnic_sriov_vlan_operation(struct qlcnic_vf_info *vf, u16 vlan_id, | |||
1966 | if (!vf->sriov_vlans) | 1999 | if (!vf->sriov_vlans) |
1967 | return; | 2000 | return; |
1968 | 2001 | ||
1969 | mutex_lock(&vf->vlan_list_lock); | 2002 | spin_lock_bh(&vf->vlan_list_lock); |
1970 | 2003 | ||
1971 | switch (opcode) { | 2004 | switch (opcode) { |
1972 | case QLC_VLAN_ADD: | 2005 | case QLC_VLAN_ADD: |
@@ -1979,7 +2012,7 @@ static void qlcnic_sriov_vlan_operation(struct qlcnic_vf_info *vf, u16 vlan_id, | |||
1979 | netdev_err(adapter->netdev, "Invalid VLAN operation\n"); | 2012 | netdev_err(adapter->netdev, "Invalid VLAN operation\n"); |
1980 | } | 2013 | } |
1981 | 2014 | ||
1982 | mutex_unlock(&vf->vlan_list_lock); | 2015 | spin_unlock_bh(&vf->vlan_list_lock); |
1983 | return; | 2016 | return; |
1984 | } | 2017 | } |
1985 | 2018 | ||
@@ -1987,6 +2020,7 @@ int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter, | |||
1987 | u16 vid, u8 enable) | 2020 | u16 vid, u8 enable) |
1988 | { | 2021 | { |
1989 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; | 2022 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; |
2023 | struct net_device *netdev = adapter->netdev; | ||
1990 | struct qlcnic_vf_info *vf; | 2024 | struct qlcnic_vf_info *vf; |
1991 | struct qlcnic_cmd_args cmd; | 2025 | struct qlcnic_cmd_args cmd; |
1992 | int ret; | 2026 | int ret; |
@@ -2012,14 +2046,18 @@ int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter, | |||
2012 | dev_err(&adapter->pdev->dev, | 2046 | dev_err(&adapter->pdev->dev, |
2013 | "Failed to configure guest VLAN, err=%d\n", ret); | 2047 | "Failed to configure guest VLAN, err=%d\n", ret); |
2014 | } else { | 2048 | } else { |
2049 | netif_addr_lock_bh(netdev); | ||
2015 | qlcnic_free_mac_list(adapter); | 2050 | qlcnic_free_mac_list(adapter); |
2051 | netif_addr_unlock_bh(netdev); | ||
2016 | 2052 | ||
2017 | if (enable) | 2053 | if (enable) |
2018 | qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_ADD); | 2054 | qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_ADD); |
2019 | else | 2055 | else |
2020 | qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_DELETE); | 2056 | qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_DELETE); |
2021 | 2057 | ||
2022 | qlcnic_set_multi(adapter->netdev); | 2058 | netif_addr_lock_bh(netdev); |
2059 | qlcnic_set_multi(netdev); | ||
2060 | netif_addr_unlock_bh(netdev); | ||
2023 | } | 2061 | } |
2024 | 2062 | ||
2025 | qlcnic_free_mbx_args(&cmd); | 2063 | qlcnic_free_mbx_args(&cmd); |
@@ -2150,11 +2188,11 @@ bool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *vf) | |||
2150 | { | 2188 | { |
2151 | bool err = false; | 2189 | bool err = false; |
2152 | 2190 | ||
2153 | mutex_lock(&vf->vlan_list_lock); | 2191 | spin_lock_bh(&vf->vlan_list_lock); |
2154 | 2192 | ||
2155 | if (vf->num_vlan) | 2193 | if (vf->num_vlan) |
2156 | err = true; | 2194 | err = true; |
2157 | 2195 | ||
2158 | mutex_unlock(&vf->vlan_list_lock); | 2196 | spin_unlock_bh(&vf->vlan_list_lock); |
2159 | return err; | 2197 | return err; |
2160 | } | 2198 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index c7926ce85fec..6d2f72f114f2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | |||
@@ -84,7 +84,7 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter, | |||
84 | info->max_tx_ques = res->num_tx_queues / max; | 84 | info->max_tx_ques = res->num_tx_queues / max; |
85 | 85 | ||
86 | if (qlcnic_83xx_pf_check(adapter)) | 86 | if (qlcnic_83xx_pf_check(adapter)) |
87 | num_macs = 1; | 87 | num_macs = QLCNIC_83XX_SRIOV_VF_MAX_MAC; |
88 | 88 | ||
89 | info->max_rx_mcast_mac_filters = res->num_rx_mcast_mac_filters; | 89 | info->max_rx_mcast_mac_filters = res->num_rx_mcast_mac_filters; |
90 | 90 | ||
@@ -338,9 +338,12 @@ static int qlcnic_sriov_pf_cfg_vlan_filtering(struct qlcnic_adapter *adapter, | |||
338 | 338 | ||
339 | cmd.req.arg[1] = 0x4; | 339 | cmd.req.arg[1] = 0x4; |
340 | if (enable) { | 340 | if (enable) { |
341 | adapter->flags |= QLCNIC_VLAN_FILTERING; | ||
341 | cmd.req.arg[1] |= BIT_16; | 342 | cmd.req.arg[1] |= BIT_16; |
342 | if (qlcnic_84xx_check(adapter)) | 343 | if (qlcnic_84xx_check(adapter)) |
343 | cmd.req.arg[1] |= QLC_SRIOV_ALLOW_VLAN0; | 344 | cmd.req.arg[1] |= QLC_SRIOV_ALLOW_VLAN0; |
345 | } else { | ||
346 | adapter->flags &= ~QLCNIC_VLAN_FILTERING; | ||
344 | } | 347 | } |
345 | 348 | ||
346 | err = qlcnic_issue_cmd(adapter, &cmd); | 349 | err = qlcnic_issue_cmd(adapter, &cmd); |
@@ -472,12 +475,12 @@ static int qlcnic_pci_sriov_disable(struct qlcnic_adapter *adapter) | |||
472 | return -EPERM; | 475 | return -EPERM; |
473 | } | 476 | } |
474 | 477 | ||
478 | qlcnic_sriov_pf_disable(adapter); | ||
479 | |||
475 | rtnl_lock(); | 480 | rtnl_lock(); |
476 | if (netif_running(netdev)) | 481 | if (netif_running(netdev)) |
477 | __qlcnic_down(adapter, netdev); | 482 | __qlcnic_down(adapter, netdev); |
478 | 483 | ||
479 | qlcnic_sriov_pf_disable(adapter); | ||
480 | |||
481 | qlcnic_sriov_free_vlans(adapter); | 484 | qlcnic_sriov_free_vlans(adapter); |
482 | 485 | ||
483 | qlcnic_sriov_pf_cleanup(adapter); | 486 | qlcnic_sriov_pf_cleanup(adapter); |
@@ -596,7 +599,6 @@ static int __qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter, | |||
596 | 599 | ||
597 | qlcnic_sriov_alloc_vlans(adapter); | 600 | qlcnic_sriov_alloc_vlans(adapter); |
598 | 601 | ||
599 | err = qlcnic_sriov_pf_enable(adapter, num_vfs); | ||
600 | return err; | 602 | return err; |
601 | 603 | ||
602 | del_flr_queue: | 604 | del_flr_queue: |
@@ -627,25 +629,36 @@ static int qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter, int num_vfs) | |||
627 | __qlcnic_down(adapter, netdev); | 629 | __qlcnic_down(adapter, netdev); |
628 | 630 | ||
629 | err = __qlcnic_pci_sriov_enable(adapter, num_vfs); | 631 | err = __qlcnic_pci_sriov_enable(adapter, num_vfs); |
630 | if (err) { | 632 | if (err) |
631 | netdev_info(netdev, "Failed to enable SR-IOV on port %d\n", | 633 | goto error; |
632 | adapter->portnum); | ||
633 | 634 | ||
634 | err = -EIO; | 635 | if (netif_running(netdev)) |
635 | if (qlcnic_83xx_configure_opmode(adapter)) | 636 | __qlcnic_up(adapter, netdev); |
636 | goto error; | 637 | |
637 | } else { | 638 | rtnl_unlock(); |
639 | err = qlcnic_sriov_pf_enable(adapter, num_vfs); | ||
640 | if (!err) { | ||
638 | netdev_info(netdev, | 641 | netdev_info(netdev, |
639 | "SR-IOV is enabled successfully on port %d\n", | 642 | "SR-IOV is enabled successfully on port %d\n", |
640 | adapter->portnum); | 643 | adapter->portnum); |
641 | /* Return number of vfs enabled */ | 644 | /* Return number of vfs enabled */ |
642 | err = num_vfs; | 645 | return num_vfs; |
643 | } | 646 | } |
647 | |||
648 | rtnl_lock(); | ||
644 | if (netif_running(netdev)) | 649 | if (netif_running(netdev)) |
645 | __qlcnic_up(adapter, netdev); | 650 | __qlcnic_down(adapter, netdev); |
646 | 651 | ||
647 | error: | 652 | error: |
653 | if (!qlcnic_83xx_configure_opmode(adapter)) { | ||
654 | if (netif_running(netdev)) | ||
655 | __qlcnic_up(adapter, netdev); | ||
656 | } | ||
657 | |||
648 | rtnl_unlock(); | 658 | rtnl_unlock(); |
659 | netdev_info(netdev, "Failed to enable SR-IOV on port %d\n", | ||
660 | adapter->portnum); | ||
661 | |||
649 | return err; | 662 | return err; |
650 | } | 663 | } |
651 | 664 | ||
@@ -774,7 +787,7 @@ static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter, | |||
774 | struct qlcnic_vf_info *vf, | 787 | struct qlcnic_vf_info *vf, |
775 | u16 vlan, u8 op) | 788 | u16 vlan, u8 op) |
776 | { | 789 | { |
777 | struct qlcnic_cmd_args cmd; | 790 | struct qlcnic_cmd_args *cmd; |
778 | struct qlcnic_macvlan_mbx mv; | 791 | struct qlcnic_macvlan_mbx mv; |
779 | struct qlcnic_vport *vp; | 792 | struct qlcnic_vport *vp; |
780 | u8 *addr; | 793 | u8 *addr; |
@@ -784,21 +797,27 @@ static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter, | |||
784 | 797 | ||
785 | vp = vf->vp; | 798 | vp = vf->vp; |
786 | 799 | ||
787 | if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN)) | 800 | cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); |
801 | if (!cmd) | ||
788 | return -ENOMEM; | 802 | return -ENOMEM; |
789 | 803 | ||
804 | err = qlcnic_alloc_mbx_args(cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN); | ||
805 | if (err) | ||
806 | goto free_cmd; | ||
807 | |||
808 | cmd->type = QLC_83XX_MBX_CMD_NO_WAIT; | ||
790 | vpid = qlcnic_sriov_pf_get_vport_handle(adapter, vf->pci_func); | 809 | vpid = qlcnic_sriov_pf_get_vport_handle(adapter, vf->pci_func); |
791 | if (vpid < 0) { | 810 | if (vpid < 0) { |
792 | err = -EINVAL; | 811 | err = -EINVAL; |
793 | goto out; | 812 | goto free_args; |
794 | } | 813 | } |
795 | 814 | ||
796 | if (vlan) | 815 | if (vlan) |
797 | op = ((op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ? | 816 | op = ((op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ? |
798 | QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL); | 817 | QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL); |
799 | 818 | ||
800 | cmd.req.arg[1] = op | (1 << 8) | (3 << 6); | 819 | cmd->req.arg[1] = op | (1 << 8) | (3 << 6); |
801 | cmd.req.arg[1] |= ((vpid & 0xffff) << 16) | BIT_31; | 820 | cmd->req.arg[1] |= ((vpid & 0xffff) << 16) | BIT_31; |
802 | 821 | ||
803 | addr = vp->mac; | 822 | addr = vp->mac; |
804 | mv.vlan = vlan; | 823 | mv.vlan = vlan; |
@@ -808,18 +827,18 @@ static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter, | |||
808 | mv.mac_addr3 = addr[3]; | 827 | mv.mac_addr3 = addr[3]; |
809 | mv.mac_addr4 = addr[4]; | 828 | mv.mac_addr4 = addr[4]; |
810 | mv.mac_addr5 = addr[5]; | 829 | mv.mac_addr5 = addr[5]; |
811 | buf = &cmd.req.arg[2]; | 830 | buf = &cmd->req.arg[2]; |
812 | memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx)); | 831 | memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx)); |
813 | 832 | ||
814 | err = qlcnic_issue_cmd(adapter, &cmd); | 833 | err = qlcnic_issue_cmd(adapter, cmd); |
815 | 834 | ||
816 | if (err) | 835 | if (!err) |
817 | dev_err(&adapter->pdev->dev, | 836 | return err; |
818 | "MAC-VLAN %s to CAM failed, err=%d.\n", | ||
819 | ((op == 1) ? "add " : "delete "), err); | ||
820 | 837 | ||
821 | out: | 838 | free_args: |
822 | qlcnic_free_mbx_args(&cmd); | 839 | qlcnic_free_mbx_args(cmd); |
840 | free_cmd: | ||
841 | kfree(cmd); | ||
823 | return err; | 842 | return err; |
824 | } | 843 | } |
825 | 844 | ||
@@ -841,7 +860,7 @@ static void qlcnic_83xx_cfg_default_mac_vlan(struct qlcnic_adapter *adapter, | |||
841 | 860 | ||
842 | sriov = adapter->ahw->sriov; | 861 | sriov = adapter->ahw->sriov; |
843 | 862 | ||
844 | mutex_lock(&vf->vlan_list_lock); | 863 | spin_lock_bh(&vf->vlan_list_lock); |
845 | if (vf->num_vlan) { | 864 | if (vf->num_vlan) { |
846 | for (i = 0; i < sriov->num_allowed_vlans; i++) { | 865 | for (i = 0; i < sriov->num_allowed_vlans; i++) { |
847 | vlan = vf->sriov_vlans[i]; | 866 | vlan = vf->sriov_vlans[i]; |
@@ -850,7 +869,7 @@ static void qlcnic_83xx_cfg_default_mac_vlan(struct qlcnic_adapter *adapter, | |||
850 | opcode); | 869 | opcode); |
851 | } | 870 | } |
852 | } | 871 | } |
853 | mutex_unlock(&vf->vlan_list_lock); | 872 | spin_unlock_bh(&vf->vlan_list_lock); |
854 | 873 | ||
855 | if (vf->vp->vlan_mode != QLC_PVID_MODE) { | 874 | if (vf->vp->vlan_mode != QLC_PVID_MODE) { |
856 | if (qlcnic_83xx_pf_check(adapter) && | 875 | if (qlcnic_83xx_pf_check(adapter) && |
@@ -1237,7 +1256,6 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter, | |||
1237 | struct qlcnic_vf_info *vf, | 1256 | struct qlcnic_vf_info *vf, |
1238 | struct qlcnic_cmd_args *cmd) | 1257 | struct qlcnic_cmd_args *cmd) |
1239 | { | 1258 | { |
1240 | struct qlcnic_macvlan_mbx *macvlan; | ||
1241 | struct qlcnic_vport *vp = vf->vp; | 1259 | struct qlcnic_vport *vp = vf->vp; |
1242 | u8 op, new_op; | 1260 | u8 op, new_op; |
1243 | 1261 | ||
@@ -1247,14 +1265,6 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter, | |||
1247 | cmd->req.arg[1] |= (vf->vp->handle << 16); | 1265 | cmd->req.arg[1] |= (vf->vp->handle << 16); |
1248 | cmd->req.arg[1] |= BIT_31; | 1266 | cmd->req.arg[1] |= BIT_31; |
1249 | 1267 | ||
1250 | macvlan = (struct qlcnic_macvlan_mbx *)&cmd->req.arg[2]; | ||
1251 | if (!(macvlan->mac_addr0 & BIT_0)) { | ||
1252 | dev_err(&adapter->pdev->dev, | ||
1253 | "MAC address change is not allowed from VF %d", | ||
1254 | vf->pci_func); | ||
1255 | return -EINVAL; | ||
1256 | } | ||
1257 | |||
1258 | if (vp->vlan_mode == QLC_PVID_MODE) { | 1268 | if (vp->vlan_mode == QLC_PVID_MODE) { |
1259 | op = cmd->req.arg[1] & 0x7; | 1269 | op = cmd->req.arg[1] & 0x7; |
1260 | cmd->req.arg[1] &= ~0x7; | 1270 | cmd->req.arg[1] &= ~0x7; |