diff options
17 files changed, 635 insertions, 302 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 631ea0ac1cd8..4afdef0cc175 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -38,8 +38,8 @@ | |||
38 | 38 | ||
39 | #define _QLCNIC_LINUX_MAJOR 5 | 39 | #define _QLCNIC_LINUX_MAJOR 5 |
40 | #define _QLCNIC_LINUX_MINOR 3 | 40 | #define _QLCNIC_LINUX_MINOR 3 |
41 | #define _QLCNIC_LINUX_SUBVERSION 52 | 41 | #define _QLCNIC_LINUX_SUBVERSION 53 |
42 | #define QLCNIC_LINUX_VERSIONID "5.3.52" | 42 | #define QLCNIC_LINUX_VERSIONID "5.3.53" |
43 | #define QLCNIC_DRV_IDC_VER 0x01 | 43 | #define QLCNIC_DRV_IDC_VER 0x01 |
44 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ | 44 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ |
45 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) | 45 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) |
@@ -115,6 +115,10 @@ enum qlcnic_queue_type { | |||
115 | #define QLCNIC_VNIC_MODE 0xFF | 115 | #define QLCNIC_VNIC_MODE 0xFF |
116 | #define QLCNIC_DEFAULT_MODE 0x0 | 116 | #define QLCNIC_DEFAULT_MODE 0x0 |
117 | 117 | ||
118 | /* Virtual NIC function count */ | ||
119 | #define QLC_DEFAULT_VNIC_COUNT 8 | ||
120 | #define QLC_84XX_VNIC_COUNT 16 | ||
121 | |||
118 | /* | 122 | /* |
119 | * Following are the states of the Phantom. Phantom will set them and | 123 | * Following are the states of the Phantom. Phantom will set them and |
120 | * Host will read to check if the fields are correct. | 124 | * Host will read to check if the fields are correct. |
@@ -374,7 +378,7 @@ struct qlcnic_rx_buffer { | |||
374 | 378 | ||
375 | #define QLCNIC_INTR_DEFAULT 0x04 | 379 | #define QLCNIC_INTR_DEFAULT 0x04 |
376 | #define QLCNIC_CONFIG_INTR_COALESCE 3 | 380 | #define QLCNIC_CONFIG_INTR_COALESCE 3 |
377 | #define QLCNIC_DEV_INFO_SIZE 1 | 381 | #define QLCNIC_DEV_INFO_SIZE 2 |
378 | 382 | ||
379 | struct qlcnic_nic_intr_coalesce { | 383 | struct qlcnic_nic_intr_coalesce { |
380 | u8 type; | 384 | u8 type; |
@@ -462,8 +466,10 @@ struct qlcnic_hardware_context { | |||
462 | u16 max_rx_ques; | 466 | u16 max_rx_ques; |
463 | u16 max_mtu; | 467 | u16 max_mtu; |
464 | u32 msg_enable; | 468 | u32 msg_enable; |
465 | u16 act_pci_func; | 469 | u16 total_nic_func; |
466 | u16 max_pci_func; | 470 | u16 max_pci_func; |
471 | u32 max_vnic_func; | ||
472 | u32 total_pci_func; | ||
467 | 473 | ||
468 | u32 capabilities; | 474 | u32 capabilities; |
469 | u32 extra_capability[3]; | 475 | u32 extra_capability[3]; |
@@ -788,9 +794,10 @@ struct qlcnic_cardrsp_tx_ctx { | |||
788 | #define QLCNIC_MAC_VLAN_ADD 3 | 794 | #define QLCNIC_MAC_VLAN_ADD 3 |
789 | #define QLCNIC_MAC_VLAN_DEL 4 | 795 | #define QLCNIC_MAC_VLAN_DEL 4 |
790 | 796 | ||
791 | struct qlcnic_mac_list_s { | 797 | struct qlcnic_mac_vlan_list { |
792 | struct list_head list; | 798 | struct list_head list; |
793 | uint8_t mac_addr[ETH_ALEN+2]; | 799 | uint8_t mac_addr[ETH_ALEN+2]; |
800 | u16 vlan_id; | ||
794 | }; | 801 | }; |
795 | 802 | ||
796 | /* MAC Learn */ | 803 | /* MAC Learn */ |
@@ -856,7 +863,7 @@ struct qlcnic_mac_list_s { | |||
856 | #define QLCNIC_FW_CAP2_HW_LRO_IPV6 BIT_3 | 863 | #define QLCNIC_FW_CAP2_HW_LRO_IPV6 BIT_3 |
857 | #define QLCNIC_FW_CAPABILITY_SET_DRV_VER BIT_5 | 864 | #define QLCNIC_FW_CAPABILITY_SET_DRV_VER BIT_5 |
858 | #define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7 | 865 | #define QLCNIC_FW_CAPABILITY_2_BEACON BIT_7 |
859 | #define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_8 | 866 | #define QLCNIC_FW_CAPABILITY_2_PER_PORT_ESWITCH_CFG BIT_9 |
860 | 867 | ||
861 | /* module types */ | 868 | /* module types */ |
862 | #define LINKEVENT_MODULE_NOT_PRESENT 1 | 869 | #define LINKEVENT_MODULE_NOT_PRESENT 1 |
@@ -1637,7 +1644,9 @@ int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); | |||
1637 | void qlcnic_set_netdev_features(struct qlcnic_adapter *, | 1644 | void qlcnic_set_netdev_features(struct qlcnic_adapter *, |
1638 | struct qlcnic_esw_func_cfg *); | 1645 | struct qlcnic_esw_func_cfg *); |
1639 | void qlcnic_sriov_vf_schedule_multi(struct net_device *); | 1646 | void qlcnic_sriov_vf_schedule_multi(struct net_device *); |
1640 | void qlcnic_vf_add_mc_list(struct net_device *, u16); | 1647 | int qlcnic_is_valid_nic_func(struct qlcnic_adapter *, u8); |
1648 | int qlcnic_get_pci_func_type(struct qlcnic_adapter *, u16, u16 *, u16 *, | ||
1649 | u16 *); | ||
1641 | 1650 | ||
1642 | /* | 1651 | /* |
1643 | * QLOGIC Board information | 1652 | * QLOGIC Board information |
@@ -2136,4 +2145,26 @@ static inline bool qlcnic_sriov_vf_check(struct qlcnic_adapter *adapter) | |||
2136 | 2145 | ||
2137 | return status; | 2146 | return status; |
2138 | } | 2147 | } |
2148 | |||
2149 | static inline bool qlcnic_83xx_pf_check(struct qlcnic_adapter *adapter) | ||
2150 | { | ||
2151 | unsigned short device = adapter->pdev->device; | ||
2152 | |||
2153 | return (device == PCI_DEVICE_ID_QLOGIC_QLE834X) ? true : false; | ||
2154 | } | ||
2155 | |||
2156 | static inline bool qlcnic_83xx_vf_check(struct qlcnic_adapter *adapter) | ||
2157 | { | ||
2158 | unsigned short device = adapter->pdev->device; | ||
2159 | |||
2160 | return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false; | ||
2161 | } | ||
2162 | |||
2163 | static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter) | ||
2164 | { | ||
2165 | if (qlcnic_84xx_check(adapter)) | ||
2166 | return QLC_84XX_VNIC_COUNT; | ||
2167 | else | ||
2168 | return QLC_DEFAULT_VNIC_COUNT; | ||
2169 | } | ||
2139 | #endif /* __QLCNIC_H_ */ | 2170 | #endif /* __QLCNIC_H_ */ |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index b1cb0ffb15c7..76a80a3b16c1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #define RSS_HASHTYPE_IP_TCP 0x3 | 16 | #define RSS_HASHTYPE_IP_TCP 0x3 |
17 | #define QLC_83XX_FW_MBX_CMD 0 | 17 | #define QLC_83XX_FW_MBX_CMD 0 |
18 | #define QLC_SKIP_INACTIVE_PCI_REGS 7 | ||
18 | 19 | ||
19 | static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { | 20 | static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { |
20 | {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1}, | 21 | {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1}, |
@@ -34,7 +35,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { | |||
34 | {QLCNIC_CMD_READ_MAX_MTU, 4, 2}, | 35 | {QLCNIC_CMD_READ_MAX_MTU, 4, 2}, |
35 | {QLCNIC_CMD_READ_MAX_LRO, 4, 2}, | 36 | {QLCNIC_CMD_READ_MAX_LRO, 4, 2}, |
36 | {QLCNIC_CMD_MAC_ADDRESS, 4, 3}, | 37 | {QLCNIC_CMD_MAC_ADDRESS, 4, 3}, |
37 | {QLCNIC_CMD_GET_PCI_INFO, 1, 66}, | 38 | {QLCNIC_CMD_GET_PCI_INFO, 1, 129}, |
38 | {QLCNIC_CMD_GET_NIC_INFO, 2, 19}, | 39 | {QLCNIC_CMD_GET_NIC_INFO, 2, 19}, |
39 | {QLCNIC_CMD_SET_NIC_INFO, 32, 1}, | 40 | {QLCNIC_CMD_SET_NIC_INFO, 32, 1}, |
40 | {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3}, | 41 | {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3}, |
@@ -68,7 +69,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { | |||
68 | {QLCNIC_CMD_CONFIG_VPORT, 4, 4}, | 69 | {QLCNIC_CMD_CONFIG_VPORT, 4, 4}, |
69 | {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1}, | 70 | {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1}, |
70 | {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2}, | 71 | {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2}, |
71 | {QLCNIC_CMD_DCB_QUERY_PARAM, 2, 50}, | 72 | {QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50}, |
72 | }; | 73 | }; |
73 | 74 | ||
74 | const u32 qlcnic_83xx_ext_reg_tbl[] = { | 75 | const u32 qlcnic_83xx_ext_reg_tbl[] = { |
@@ -289,6 +290,7 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter) | |||
289 | if (qlcnic_sriov_vf_check(adapter)) | 290 | if (qlcnic_sriov_vf_check(adapter)) |
290 | return -EINVAL; | 291 | return -EINVAL; |
291 | num_msix = 1; | 292 | num_msix = 1; |
293 | adapter->drv_tx_rings = QLCNIC_SINGLE_RING; | ||
292 | } | 294 | } |
293 | /* setup interrupt mapping table for fw */ | 295 | /* setup interrupt mapping table for fw */ |
294 | ahw->intr_tbl = vzalloc(num_msix * | 296 | ahw->intr_tbl = vzalloc(num_msix * |
@@ -636,7 +638,7 @@ int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter) | |||
636 | void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter) | 638 | void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter) |
637 | { | 639 | { |
638 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 640 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
639 | u16 act_pci_fn = ahw->act_pci_func; | 641 | u16 act_pci_fn = ahw->total_nic_func; |
640 | u16 count; | 642 | u16 count; |
641 | 643 | ||
642 | ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT; | 644 | ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT; |
@@ -1518,8 +1520,7 @@ int qlcnic_83xx_set_led(struct net_device *netdev, | |||
1518 | return err; | 1520 | return err; |
1519 | } | 1521 | } |
1520 | 1522 | ||
1521 | void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter, | 1523 | void qlcnic_83xx_initialize_nic(struct qlcnic_adapter *adapter, int enable) |
1522 | int enable) | ||
1523 | { | 1524 | { |
1524 | struct qlcnic_cmd_args cmd; | 1525 | struct qlcnic_cmd_args cmd; |
1525 | int status; | 1526 | int status; |
@@ -1527,21 +1528,21 @@ void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter, | |||
1527 | if (qlcnic_sriov_vf_check(adapter)) | 1528 | if (qlcnic_sriov_vf_check(adapter)) |
1528 | return; | 1529 | return; |
1529 | 1530 | ||
1530 | if (enable) { | 1531 | if (enable) |
1531 | status = qlcnic_alloc_mbx_args(&cmd, adapter, | 1532 | status = qlcnic_alloc_mbx_args(&cmd, adapter, |
1532 | QLCNIC_CMD_INIT_NIC_FUNC); | 1533 | QLCNIC_CMD_INIT_NIC_FUNC); |
1533 | if (status) | 1534 | else |
1534 | return; | ||
1535 | |||
1536 | cmd.req.arg[1] = BIT_0 | BIT_31; | ||
1537 | } else { | ||
1538 | status = qlcnic_alloc_mbx_args(&cmd, adapter, | 1535 | status = qlcnic_alloc_mbx_args(&cmd, adapter, |
1539 | QLCNIC_CMD_STOP_NIC_FUNC); | 1536 | QLCNIC_CMD_STOP_NIC_FUNC); |
1540 | if (status) | ||
1541 | return; | ||
1542 | 1537 | ||
1543 | cmd.req.arg[1] = BIT_0 | BIT_31; | 1538 | if (status) |
1544 | } | 1539 | return; |
1540 | |||
1541 | cmd.req.arg[1] = QLC_REGISTER_LB_IDC | QLC_INIT_FW_RESOURCES; | ||
1542 | |||
1543 | if (adapter->dcb) | ||
1544 | cmd.req.arg[1] |= QLC_REGISTER_DCB_AEN; | ||
1545 | |||
1545 | status = qlcnic_issue_cmd(adapter, &cmd); | 1546 | status = qlcnic_issue_cmd(adapter, &cmd); |
1546 | if (status) | 1547 | if (status) |
1547 | dev_err(&adapter->pdev->dev, | 1548 | dev_err(&adapter->pdev->dev, |
@@ -1637,7 +1638,7 @@ int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) | |||
1637 | 1638 | ||
1638 | cmd->type = QLC_83XX_MBX_CMD_NO_WAIT; | 1639 | cmd->type = QLC_83XX_MBX_CMD_NO_WAIT; |
1639 | qlcnic_83xx_set_interface_id_promisc(adapter, &temp); | 1640 | qlcnic_83xx_set_interface_id_promisc(adapter, &temp); |
1640 | cmd->req.arg[1] = (mode ? 1 : 0) | temp; | 1641 | cmd->req.arg[1] = mode | temp; |
1641 | err = qlcnic_issue_cmd(adapter, cmd); | 1642 | err = qlcnic_issue_cmd(adapter, cmd); |
1642 | if (!err) | 1643 | if (!err) |
1643 | return err; | 1644 | return err; |
@@ -2293,11 +2294,37 @@ out: | |||
2293 | return err; | 2294 | return err; |
2294 | } | 2295 | } |
2295 | 2296 | ||
2297 | int qlcnic_get_pci_func_type(struct qlcnic_adapter *adapter, u16 type, | ||
2298 | u16 *nic, u16 *fcoe, u16 *iscsi) | ||
2299 | { | ||
2300 | struct device *dev = &adapter->pdev->dev; | ||
2301 | int err = 0; | ||
2302 | |||
2303 | switch (type) { | ||
2304 | case QLCNIC_TYPE_NIC: | ||
2305 | (*nic)++; | ||
2306 | break; | ||
2307 | case QLCNIC_TYPE_FCOE: | ||
2308 | (*fcoe)++; | ||
2309 | break; | ||
2310 | case QLCNIC_TYPE_ISCSI: | ||
2311 | (*iscsi)++; | ||
2312 | break; | ||
2313 | default: | ||
2314 | dev_err(dev, "%s: Unknown PCI type[%x]\n", | ||
2315 | __func__, type); | ||
2316 | err = -EIO; | ||
2317 | } | ||
2318 | |||
2319 | return err; | ||
2320 | } | ||
2321 | |||
2296 | int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter, | 2322 | int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter, |
2297 | struct qlcnic_pci_info *pci_info) | 2323 | struct qlcnic_pci_info *pci_info) |
2298 | { | 2324 | { |
2299 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 2325 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
2300 | struct device *dev = &adapter->pdev->dev; | 2326 | struct device *dev = &adapter->pdev->dev; |
2327 | u16 nic = 0, fcoe = 0, iscsi = 0; | ||
2301 | struct qlcnic_cmd_args cmd; | 2328 | struct qlcnic_cmd_args cmd; |
2302 | int i, err = 0, j = 0; | 2329 | int i, err = 0, j = 0; |
2303 | u32 temp; | 2330 | u32 temp; |
@@ -2308,16 +2335,20 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter, | |||
2308 | 2335 | ||
2309 | err = qlcnic_issue_cmd(adapter, &cmd); | 2336 | err = qlcnic_issue_cmd(adapter, &cmd); |
2310 | 2337 | ||
2311 | ahw->act_pci_func = 0; | 2338 | ahw->total_nic_func = 0; |
2312 | if (err == QLCNIC_RCODE_SUCCESS) { | 2339 | if (err == QLCNIC_RCODE_SUCCESS) { |
2313 | ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF; | 2340 | ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF; |
2314 | for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) { | 2341 | for (i = 2, j = 0; j < ahw->max_vnic_func; j++, pci_info++) { |
2315 | pci_info->id = cmd.rsp.arg[i] & 0xFFFF; | 2342 | pci_info->id = cmd.rsp.arg[i] & 0xFFFF; |
2316 | pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16; | 2343 | pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16; |
2317 | i++; | 2344 | i++; |
2345 | if (!pci_info->active) { | ||
2346 | i += QLC_SKIP_INACTIVE_PCI_REGS; | ||
2347 | continue; | ||
2348 | } | ||
2318 | pci_info->type = cmd.rsp.arg[i] & 0xFFFF; | 2349 | pci_info->type = cmd.rsp.arg[i] & 0xFFFF; |
2319 | if (pci_info->type == QLCNIC_TYPE_NIC) | 2350 | err = qlcnic_get_pci_func_type(adapter, pci_info->type, |
2320 | ahw->act_pci_func++; | 2351 | &nic, &fcoe, &iscsi); |
2321 | temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16; | 2352 | temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16; |
2322 | pci_info->default_port = temp; | 2353 | pci_info->default_port = temp; |
2323 | i++; | 2354 | i++; |
@@ -2335,6 +2366,13 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter, | |||
2335 | err = -EIO; | 2366 | err = -EIO; |
2336 | } | 2367 | } |
2337 | 2368 | ||
2369 | ahw->total_nic_func = nic; | ||
2370 | ahw->total_pci_func = nic + fcoe + iscsi; | ||
2371 | if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) { | ||
2372 | dev_err(dev, "%s: Invalid function count: total nic func[%x], total pci func[%x]\n", | ||
2373 | __func__, ahw->total_nic_func, ahw->total_pci_func); | ||
2374 | err = -EIO; | ||
2375 | } | ||
2338 | qlcnic_free_mbx_args(&cmd); | 2376 | qlcnic_free_mbx_args(&cmd); |
2339 | 2377 | ||
2340 | return err; | 2378 | return err; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 4cae6caa6bfa..7288f7399bc1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | |||
@@ -324,6 +324,11 @@ struct qlc_83xx_idc { | |||
324 | char **name; | 324 | char **name; |
325 | }; | 325 | }; |
326 | 326 | ||
327 | enum qlcnic_vlan_operations { | ||
328 | QLC_VLAN_ADD = 0, | ||
329 | QLC_VLAN_DELETE | ||
330 | }; | ||
331 | |||
327 | /* Device States */ | 332 | /* Device States */ |
328 | enum qlcnic_83xx_states { | 333 | enum qlcnic_83xx_states { |
329 | QLC_83XX_IDC_DEV_UNKNOWN, | 334 | QLC_83XX_IDC_DEV_UNKNOWN, |
@@ -518,6 +523,11 @@ enum qlc_83xx_ext_regs { | |||
518 | QLC_83XX_ASIC_TEMP, | 523 | QLC_83XX_ASIC_TEMP, |
519 | }; | 524 | }; |
520 | 525 | ||
526 | /* Initialize/Stop NIC command bit definitions */ | ||
527 | #define QLC_REGISTER_DCB_AEN BIT_1 | ||
528 | #define QLC_REGISTER_LB_IDC BIT_0 | ||
529 | #define QLC_INIT_FW_RESOURCES BIT_31 | ||
530 | |||
521 | /* 83xx funcitons */ | 531 | /* 83xx funcitons */ |
522 | int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *); | 532 | int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *); |
523 | int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *, struct qlcnic_cmd_args *); | 533 | int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *, struct qlcnic_cmd_args *); |
@@ -542,7 +552,7 @@ int qlcnic_83xx_config_intr_coalesce(struct qlcnic_adapter *); | |||
542 | void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *, u64 *, u16); | 552 | void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *, u64 *, u16); |
543 | int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *); | 553 | int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *); |
544 | int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); | 554 | int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); |
545 | void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *, int); | 555 | void qlcnic_83xx_initialize_nic(struct qlcnic_adapter *, int); |
546 | 556 | ||
547 | int qlcnic_83xx_napi_add(struct qlcnic_adapter *, struct net_device *); | 557 | int qlcnic_83xx_napi_add(struct qlcnic_adapter *, struct net_device *); |
548 | void qlcnic_83xx_napi_del(struct qlcnic_adapter *); | 558 | void qlcnic_83xx_napi_del(struct qlcnic_adapter *); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 89208e5b25d6..70767c137c7a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -614,8 +614,7 @@ int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter) | |||
614 | qlcnic_83xx_reinit_mbx_work(adapter->ahw->mailbox); | 614 | qlcnic_83xx_reinit_mbx_work(adapter->ahw->mailbox); |
615 | qlcnic_83xx_enable_mbx_interrupt(adapter); | 615 | qlcnic_83xx_enable_mbx_interrupt(adapter); |
616 | 616 | ||
617 | /* register for NIC IDC AEN Events */ | 617 | qlcnic_83xx_initialize_nic(adapter, 1); |
618 | qlcnic_83xx_register_nic_idc_func(adapter, 1); | ||
619 | 618 | ||
620 | err = qlcnic_sriov_pf_reinit(adapter); | 619 | err = qlcnic_sriov_pf_reinit(adapter); |
621 | if (err) | 620 | if (err) |
@@ -2198,7 +2197,6 @@ static void qlcnic_83xx_init_rings(struct qlcnic_adapter *adapter) | |||
2198 | int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) | 2197 | int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) |
2199 | { | 2198 | { |
2200 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 2199 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
2201 | struct qlcnic_dcb *dcb; | ||
2202 | int err = 0; | 2200 | int err = 0; |
2203 | 2201 | ||
2204 | ahw->msix_supported = !!qlcnic_use_msi_x; | 2202 | ahw->msix_supported = !!qlcnic_use_msi_x; |
@@ -2250,8 +2248,7 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) | |||
2250 | 2248 | ||
2251 | INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work); | 2249 | INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work); |
2252 | 2250 | ||
2253 | /* register for NIC IDC AEN Events */ | 2251 | qlcnic_83xx_initialize_nic(adapter, 1); |
2254 | qlcnic_83xx_register_nic_idc_func(adapter, 1); | ||
2255 | 2252 | ||
2256 | /* Configure default, SR-IOV or Virtual NIC mode of operation */ | 2253 | /* Configure default, SR-IOV or Virtual NIC mode of operation */ |
2257 | err = qlcnic_83xx_configure_opmode(adapter); | 2254 | err = qlcnic_83xx_configure_opmode(adapter); |
@@ -2264,11 +2261,6 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) | |||
2264 | if (err) | 2261 | if (err) |
2265 | goto disable_mbx_intr; | 2262 | goto disable_mbx_intr; |
2266 | 2263 | ||
2267 | dcb = adapter->dcb; | ||
2268 | |||
2269 | if (dcb && qlcnic_dcb_attach(dcb)) | ||
2270 | qlcnic_clear_dcb_ops(dcb); | ||
2271 | |||
2272 | /* Periodically monitor device status */ | 2264 | /* Periodically monitor device status */ |
2273 | qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work); | 2265 | qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work); |
2274 | return 0; | 2266 | return 0; |
@@ -2299,7 +2291,7 @@ void qlcnic_83xx_aer_stop_poll_work(struct qlcnic_adapter *adapter) | |||
2299 | qlcnic_83xx_disable_vnic_mode(adapter, 1); | 2291 | qlcnic_83xx_disable_vnic_mode(adapter, 1); |
2300 | 2292 | ||
2301 | qlcnic_83xx_idc_detach_driver(adapter); | 2293 | qlcnic_83xx_idc_detach_driver(adapter); |
2302 | qlcnic_83xx_register_nic_idc_func(adapter, 0); | 2294 | qlcnic_83xx_initialize_nic(adapter, 0); |
2303 | 2295 | ||
2304 | cancel_delayed_work_sync(&adapter->idc_aen_work); | 2296 | cancel_delayed_work_sync(&adapter->idc_aen_work); |
2305 | } | 2297 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c index 734d28602ac3..474320a5f0c1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c | |||
@@ -107,7 +107,7 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter) | |||
107 | 107 | ||
108 | npar = adapter->npars; | 108 | npar = adapter->npars; |
109 | 109 | ||
110 | for (i = 0; i < ahw->act_pci_func; i++, npar++) { | 110 | for (i = 0; i < ahw->total_nic_func; i++, npar++) { |
111 | dev_info(dev, "id:%d active:%d type:%d port:%d min_bw:%d max_bw:%d mac_addr:%pM\n", | 111 | dev_info(dev, "id:%d active:%d type:%d port:%d min_bw:%d max_bw:%d mac_addr:%pM\n", |
112 | npar->pci_func, npar->active, npar->type, | 112 | npar->pci_func, npar->active, npar->type, |
113 | npar->phy_port, npar->min_bw, npar->max_bw, | 113 | npar->phy_port, npar->min_bw, npar->max_bw, |
@@ -115,7 +115,7 @@ static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter) | |||
115 | } | 115 | } |
116 | 116 | ||
117 | dev_info(dev, "Max functions = %d, active functions = %d\n", | 117 | dev_info(dev, "Max functions = %d, active functions = %d\n", |
118 | ahw->max_pci_func, ahw->act_pci_func); | 118 | ahw->max_pci_func, ahw->total_nic_func); |
119 | 119 | ||
120 | if (qlcnic_83xx_set_vnic_opmode(adapter)) | 120 | if (qlcnic_83xx_set_vnic_opmode(adapter)) |
121 | return err; | 121 | return err; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index 859cb161fc63..64dcbf33d8f0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | |||
@@ -91,18 +91,6 @@ void qlcnic_free_mbx_args(struct qlcnic_cmd_args *cmd) | |||
91 | cmd->rsp.arg = NULL; | 91 | cmd->rsp.arg = NULL; |
92 | } | 92 | } |
93 | 93 | ||
94 | static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) | ||
95 | { | ||
96 | int i; | ||
97 | |||
98 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { | ||
99 | if (adapter->npars[i].pci_func == pci_func) | ||
100 | return i; | ||
101 | } | ||
102 | |||
103 | return -1; | ||
104 | } | ||
105 | |||
106 | static u32 | 94 | static u32 |
107 | qlcnic_poll_rsp(struct qlcnic_adapter *adapter) | 95 | qlcnic_poll_rsp(struct qlcnic_adapter *adapter) |
108 | { | 96 | { |
@@ -966,13 +954,15 @@ out_free_dma: | |||
966 | int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter, | 954 | int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter, |
967 | struct qlcnic_pci_info *pci_info) | 955 | struct qlcnic_pci_info *pci_info) |
968 | { | 956 | { |
969 | int err = 0, i; | 957 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
958 | size_t npar_size = sizeof(struct qlcnic_pci_info_le); | ||
959 | size_t pci_size = npar_size * ahw->max_vnic_func; | ||
960 | u16 nic = 0, fcoe = 0, iscsi = 0; | ||
961 | struct qlcnic_pci_info_le *npar; | ||
970 | struct qlcnic_cmd_args cmd; | 962 | struct qlcnic_cmd_args cmd; |
971 | dma_addr_t pci_info_dma_t; | 963 | dma_addr_t pci_info_dma_t; |
972 | struct qlcnic_pci_info_le *npar; | ||
973 | void *pci_info_addr; | 964 | void *pci_info_addr; |
974 | size_t npar_size = sizeof(struct qlcnic_pci_info_le); | 965 | int err = 0, i; |
975 | size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC; | ||
976 | 966 | ||
977 | pci_info_addr = dma_zalloc_coherent(&adapter->pdev->dev, pci_size, | 967 | pci_info_addr = dma_zalloc_coherent(&adapter->pdev->dev, pci_size, |
978 | &pci_info_dma_t, GFP_KERNEL); | 968 | &pci_info_dma_t, GFP_KERNEL); |
@@ -989,14 +979,16 @@ int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter, | |||
989 | cmd.req.arg[3] = pci_size; | 979 | cmd.req.arg[3] = pci_size; |
990 | err = qlcnic_issue_cmd(adapter, &cmd); | 980 | err = qlcnic_issue_cmd(adapter, &cmd); |
991 | 981 | ||
992 | adapter->ahw->act_pci_func = 0; | 982 | ahw->total_nic_func = 0; |
993 | if (err == QLCNIC_RCODE_SUCCESS) { | 983 | if (err == QLCNIC_RCODE_SUCCESS) { |
994 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) { | 984 | for (i = 0; i < ahw->max_vnic_func; i++, npar++, pci_info++) { |
995 | pci_info->id = le16_to_cpu(npar->id); | 985 | pci_info->id = le16_to_cpu(npar->id); |
996 | pci_info->active = le16_to_cpu(npar->active); | 986 | pci_info->active = le16_to_cpu(npar->active); |
987 | if (!pci_info->active) | ||
988 | continue; | ||
997 | pci_info->type = le16_to_cpu(npar->type); | 989 | pci_info->type = le16_to_cpu(npar->type); |
998 | if (pci_info->type == QLCNIC_TYPE_NIC) | 990 | err = qlcnic_get_pci_func_type(adapter, pci_info->type, |
999 | adapter->ahw->act_pci_func++; | 991 | &nic, &fcoe, &iscsi); |
1000 | pci_info->default_port = | 992 | pci_info->default_port = |
1001 | le16_to_cpu(npar->default_port); | 993 | le16_to_cpu(npar->default_port); |
1002 | pci_info->tx_min_bw = | 994 | pci_info->tx_min_bw = |
@@ -1011,6 +1003,14 @@ int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter, | |||
1011 | err = -EIO; | 1003 | err = -EIO; |
1012 | } | 1004 | } |
1013 | 1005 | ||
1006 | ahw->total_nic_func = nic; | ||
1007 | ahw->total_pci_func = nic + fcoe + iscsi; | ||
1008 | if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) { | ||
1009 | dev_err(&adapter->pdev->dev, | ||
1010 | "%s: Invalid function count: total nic func[%x], total pci func[%x]\n", | ||
1011 | __func__, ahw->total_nic_func, ahw->total_pci_func); | ||
1012 | err = -EIO; | ||
1013 | } | ||
1014 | qlcnic_free_mbx_args(&cmd); | 1014 | qlcnic_free_mbx_args(&cmd); |
1015 | out_free_dma: | 1015 | out_free_dma: |
1016 | dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr, | 1016 | dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr, |
@@ -1203,7 +1203,7 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, | |||
1203 | esw_stats->numbytes = QLCNIC_STATS_NOT_AVAIL; | 1203 | esw_stats->numbytes = QLCNIC_STATS_NOT_AVAIL; |
1204 | esw_stats->context_id = eswitch; | 1204 | esw_stats->context_id = eswitch; |
1205 | 1205 | ||
1206 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { | 1206 | for (i = 0; i < adapter->ahw->total_nic_func; i++) { |
1207 | if (adapter->npars[i].phy_port != eswitch) | 1207 | if (adapter->npars[i].phy_port != eswitch) |
1208 | continue; | 1208 | continue; |
1209 | 1209 | ||
@@ -1236,15 +1236,16 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, | |||
1236 | int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, | 1236 | int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, |
1237 | const u8 port, const u8 rx_tx) | 1237 | const u8 port, const u8 rx_tx) |
1238 | { | 1238 | { |
1239 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
1240 | struct qlcnic_cmd_args cmd; | ||
1239 | int err; | 1241 | int err; |
1240 | u32 arg1; | 1242 | u32 arg1; |
1241 | struct qlcnic_cmd_args cmd; | ||
1242 | 1243 | ||
1243 | if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) | 1244 | if (ahw->op_mode != QLCNIC_MGMT_FUNC) |
1244 | return -EIO; | 1245 | return -EIO; |
1245 | 1246 | ||
1246 | if (func_esw == QLCNIC_STATS_PORT) { | 1247 | if (func_esw == QLCNIC_STATS_PORT) { |
1247 | if (port >= QLCNIC_MAX_PCI_FUNC) | 1248 | if (port >= ahw->max_vnic_func) |
1248 | goto err_ret; | 1249 | goto err_ret; |
1249 | } else if (func_esw == QLCNIC_STATS_ESWITCH) { | 1250 | } else if (func_esw == QLCNIC_STATS_ESWITCH) { |
1250 | if (port >= QLCNIC_NIU_MAX_XG_PORTS) | 1251 | if (port >= QLCNIC_NIU_MAX_XG_PORTS) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c index 86bca7c14f99..77f1bce432d2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #define QLC_DCB_GET_MAP(V) (1 << V) | 16 | #define QLC_DCB_GET_MAP(V) (1 << V) |
17 | 17 | ||
18 | #define QLC_DCB_AEN_BIT 0x2 | ||
19 | #define QLC_DCB_FW_VER 0x2 | 18 | #define QLC_DCB_FW_VER 0x2 |
20 | #define QLC_DCB_MAX_TC 0x8 | 19 | #define QLC_DCB_MAX_TC 0x8 |
21 | #define QLC_DCB_MAX_APP 0x8 | 20 | #define QLC_DCB_MAX_APP 0x8 |
@@ -71,7 +70,6 @@ static void qlcnic_82xx_dcb_aen_handler(struct qlcnic_dcb *, void *); | |||
71 | static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *); | 70 | static int qlcnic_83xx_dcb_get_hw_capability(struct qlcnic_dcb *); |
72 | static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8); | 71 | static int qlcnic_83xx_dcb_query_cee_param(struct qlcnic_dcb *, char *, u8); |
73 | static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *); | 72 | static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *); |
74 | static int qlcnic_83xx_dcb_register_aen(struct qlcnic_dcb *, bool); | ||
75 | static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *, void *); | 73 | static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *, void *); |
76 | 74 | ||
77 | struct qlcnic_dcb_capability { | 75 | struct qlcnic_dcb_capability { |
@@ -179,7 +177,6 @@ static struct qlcnic_dcb_ops qlcnic_83xx_dcb_ops = { | |||
179 | .get_hw_capability = qlcnic_83xx_dcb_get_hw_capability, | 177 | .get_hw_capability = qlcnic_83xx_dcb_get_hw_capability, |
180 | .query_cee_param = qlcnic_83xx_dcb_query_cee_param, | 178 | .query_cee_param = qlcnic_83xx_dcb_query_cee_param, |
181 | .get_cee_cfg = qlcnic_83xx_dcb_get_cee_cfg, | 179 | .get_cee_cfg = qlcnic_83xx_dcb_get_cee_cfg, |
182 | .register_aen = qlcnic_83xx_dcb_register_aen, | ||
183 | .aen_handler = qlcnic_83xx_dcb_aen_handler, | 180 | .aen_handler = qlcnic_83xx_dcb_aen_handler, |
184 | }; | 181 | }; |
185 | 182 | ||
@@ -260,6 +257,9 @@ int qlcnic_register_dcb(struct qlcnic_adapter *adapter) | |||
260 | { | 257 | { |
261 | struct qlcnic_dcb *dcb; | 258 | struct qlcnic_dcb *dcb; |
262 | 259 | ||
260 | if (qlcnic_sriov_vf_check(adapter)) | ||
261 | return 0; | ||
262 | |||
263 | dcb = kzalloc(sizeof(struct qlcnic_dcb), GFP_ATOMIC); | 263 | dcb = kzalloc(sizeof(struct qlcnic_dcb), GFP_ATOMIC); |
264 | if (!dcb) | 264 | if (!dcb) |
265 | return -ENOMEM; | 265 | return -ENOMEM; |
@@ -280,7 +280,6 @@ static void __qlcnic_dcb_free(struct qlcnic_dcb *dcb) | |||
280 | return; | 280 | return; |
281 | 281 | ||
282 | adapter = dcb->adapter; | 282 | adapter = dcb->adapter; |
283 | qlcnic_dcb_register_aen(dcb, 0); | ||
284 | 283 | ||
285 | while (test_bit(QLCNIC_DCB_AEN_MODE, &dcb->state)) | 284 | while (test_bit(QLCNIC_DCB_AEN_MODE, &dcb->state)) |
286 | usleep_range(10000, 11000); | 285 | usleep_range(10000, 11000); |
@@ -304,7 +303,6 @@ static void __qlcnic_dcb_get_info(struct qlcnic_dcb *dcb) | |||
304 | { | 303 | { |
305 | qlcnic_dcb_get_hw_capability(dcb); | 304 | qlcnic_dcb_get_hw_capability(dcb); |
306 | qlcnic_dcb_get_cee_cfg(dcb); | 305 | qlcnic_dcb_get_cee_cfg(dcb); |
307 | qlcnic_dcb_register_aen(dcb, 1); | ||
308 | } | 306 | } |
309 | 307 | ||
310 | static int __qlcnic_dcb_attach(struct qlcnic_dcb *dcb) | 308 | static int __qlcnic_dcb_attach(struct qlcnic_dcb *dcb) |
@@ -642,29 +640,6 @@ static int qlcnic_83xx_dcb_get_cee_cfg(struct qlcnic_dcb *dcb) | |||
642 | return err; | 640 | return err; |
643 | } | 641 | } |
644 | 642 | ||
645 | static int qlcnic_83xx_dcb_register_aen(struct qlcnic_dcb *dcb, bool flag) | ||
646 | { | ||
647 | u8 val = (flag ? QLCNIC_CMD_INIT_NIC_FUNC : QLCNIC_CMD_STOP_NIC_FUNC); | ||
648 | struct qlcnic_adapter *adapter = dcb->adapter; | ||
649 | struct qlcnic_cmd_args cmd; | ||
650 | int err; | ||
651 | |||
652 | err = qlcnic_alloc_mbx_args(&cmd, adapter, val); | ||
653 | if (err) | ||
654 | return err; | ||
655 | |||
656 | cmd.req.arg[1] = QLC_DCB_AEN_BIT; | ||
657 | |||
658 | err = qlcnic_issue_cmd(adapter, &cmd); | ||
659 | if (err) | ||
660 | dev_err(&adapter->pdev->dev, "Failed to %s DCBX AEN, err %d\n", | ||
661 | (flag ? "register" : "unregister"), err); | ||
662 | |||
663 | qlcnic_free_mbx_args(&cmd); | ||
664 | |||
665 | return err; | ||
666 | } | ||
667 | |||
668 | static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data) | 643 | static void qlcnic_83xx_dcb_aen_handler(struct qlcnic_dcb *dcb, void *data) |
669 | { | 644 | { |
670 | u32 *val = data; | 645 | u32 *val = data; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h index c04ae0cdc108..3cf4a10fbe1e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h | |||
@@ -25,7 +25,6 @@ struct qlcnic_dcb_ops { | |||
25 | int (*get_hw_capability) (struct qlcnic_dcb *); | 25 | int (*get_hw_capability) (struct qlcnic_dcb *); |
26 | int (*query_cee_param) (struct qlcnic_dcb *, char *, u8); | 26 | int (*query_cee_param) (struct qlcnic_dcb *, char *, u8); |
27 | void (*init_dcbnl_ops) (struct qlcnic_dcb *); | 27 | void (*init_dcbnl_ops) (struct qlcnic_dcb *); |
28 | int (*register_aen) (struct qlcnic_dcb *, bool); | ||
29 | void (*aen_handler) (struct qlcnic_dcb *, void *); | 28 | void (*aen_handler) (struct qlcnic_dcb *, void *); |
30 | int (*get_cee_cfg) (struct qlcnic_dcb *); | 29 | int (*get_cee_cfg) (struct qlcnic_dcb *); |
31 | void (*get_info) (struct qlcnic_dcb *); | 30 | void (*get_info) (struct qlcnic_dcb *); |
@@ -103,13 +102,6 @@ static inline int qlcnic_dcb_get_cee_cfg(struct qlcnic_dcb *dcb) | |||
103 | return 0; | 102 | return 0; |
104 | } | 103 | } |
105 | 104 | ||
106 | static inline void | ||
107 | qlcnic_dcb_register_aen(struct qlcnic_dcb *dcb, u8 flag) | ||
108 | { | ||
109 | if (dcb && dcb->ops->register_aen) | ||
110 | dcb->ops->register_aen(dcb, flag); | ||
111 | } | ||
112 | |||
113 | static inline void qlcnic_dcb_aen_handler(struct qlcnic_dcb *dcb, void *msg) | 105 | static inline void qlcnic_dcb_aen_handler(struct qlcnic_dcb *dcb, void *msg) |
114 | { | 106 | { |
115 | if (dcb && dcb->ops->aen_handler) | 107 | if (dcb && dcb->ops->aen_handler) |
@@ -121,4 +113,10 @@ static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_dcb *dcb) | |||
121 | if (dcb && dcb->ops->init_dcbnl_ops) | 113 | if (dcb && dcb->ops->init_dcbnl_ops) |
122 | dcb->ops->init_dcbnl_ops(dcb); | 114 | dcb->ops->init_dcbnl_ops(dcb); |
123 | } | 115 | } |
116 | |||
117 | static inline void qlcnic_dcb_enable(struct qlcnic_dcb *dcb) | ||
118 | { | ||
119 | if (dcb && qlcnic_dcb_attach(dcb)) | ||
120 | qlcnic_clear_dcb_ops(dcb); | ||
121 | } | ||
124 | #endif | 122 | #endif |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index b36c02fafcfd..022401f80065 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | |||
@@ -221,7 +221,7 @@ static const u32 ext_diag_registers[] = { | |||
221 | -1 | 221 | -1 |
222 | }; | 222 | }; |
223 | 223 | ||
224 | #define QLCNIC_MGMT_API_VERSION 2 | 224 | #define QLCNIC_MGMT_API_VERSION 3 |
225 | #define QLCNIC_ETHTOOL_REGS_VER 4 | 225 | #define QLCNIC_ETHTOOL_REGS_VER 4 |
226 | 226 | ||
227 | static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter) | 227 | static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter) |
@@ -519,6 +519,9 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) | |||
519 | regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff)); | 519 | regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff)); |
520 | regs_buff[1] = QLCNIC_MGMT_API_VERSION; | 520 | regs_buff[1] = QLCNIC_MGMT_API_VERSION; |
521 | 521 | ||
522 | if (adapter->ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY) | ||
523 | regs_buff[2] = adapter->ahw->max_vnic_func; | ||
524 | |||
522 | if (qlcnic_82xx_check(adapter)) | 525 | if (qlcnic_82xx_check(adapter)) |
523 | i = qlcnic_82xx_get_registers(adapter, regs_buff); | 526 | i = qlcnic_82xx_get_registers(adapter, regs_buff); |
524 | else | 527 | else |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h index d262211b03b3..34e467b239a1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h | |||
@@ -698,7 +698,6 @@ struct qlcnic_legacy_intr_set { | |||
698 | }; | 698 | }; |
699 | 699 | ||
700 | #define QLCNIC_MSIX_BASE 0x132110 | 700 | #define QLCNIC_MSIX_BASE 0x132110 |
701 | #define QLCNIC_MAX_PCI_FUNC 8 | ||
702 | #define QLCNIC_MAX_VLAN_FILTERS 64 | 701 | #define QLCNIC_MAX_VLAN_FILTERS 64 |
703 | 702 | ||
704 | #define FLASH_ROM_WINDOW 0x42110030 | 703 | #define FLASH_ROM_WINDOW 0x42110030 |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 6f7f60c09f07..3fe971c59b8c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | |||
@@ -455,13 +455,13 @@ int qlcnic_82xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, | |||
455 | 455 | ||
456 | int qlcnic_nic_del_mac(struct qlcnic_adapter *adapter, const u8 *addr) | 456 | int qlcnic_nic_del_mac(struct qlcnic_adapter *adapter, const u8 *addr) |
457 | { | 457 | { |
458 | struct qlcnic_mac_vlan_list *cur; | ||
458 | struct list_head *head; | 459 | struct list_head *head; |
459 | struct qlcnic_mac_list_s *cur; | ||
460 | int err = -EINVAL; | 460 | int err = -EINVAL; |
461 | 461 | ||
462 | /* Delete MAC from the existing list */ | 462 | /* Delete MAC from the existing list */ |
463 | list_for_each(head, &adapter->mac_list) { | 463 | list_for_each(head, &adapter->mac_list) { |
464 | cur = list_entry(head, struct qlcnic_mac_list_s, list); | 464 | cur = list_entry(head, struct qlcnic_mac_vlan_list, list); |
465 | if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) { | 465 | if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) { |
466 | err = qlcnic_sre_macaddr_change(adapter, cur->mac_addr, | 466 | err = qlcnic_sre_macaddr_change(adapter, cur->mac_addr, |
467 | 0, QLCNIC_MAC_DEL); | 467 | 0, QLCNIC_MAC_DEL); |
@@ -477,17 +477,18 @@ int qlcnic_nic_del_mac(struct qlcnic_adapter *adapter, const u8 *addr) | |||
477 | 477 | ||
478 | int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan) | 478 | int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan) |
479 | { | 479 | { |
480 | struct qlcnic_mac_vlan_list *cur; | ||
480 | struct list_head *head; | 481 | struct list_head *head; |
481 | struct qlcnic_mac_list_s *cur; | ||
482 | 482 | ||
483 | /* look up if already exists */ | 483 | /* look up if already exists */ |
484 | list_for_each(head, &adapter->mac_list) { | 484 | list_for_each(head, &adapter->mac_list) { |
485 | cur = list_entry(head, struct qlcnic_mac_list_s, list); | 485 | cur = list_entry(head, struct qlcnic_mac_vlan_list, list); |
486 | if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) | 486 | if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0 && |
487 | cur->vlan_id == vlan) | ||
487 | return 0; | 488 | return 0; |
488 | } | 489 | } |
489 | 490 | ||
490 | cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC); | 491 | cur = kzalloc(sizeof(*cur), GFP_ATOMIC); |
491 | if (cur == NULL) | 492 | if (cur == NULL) |
492 | return -ENOMEM; | 493 | return -ENOMEM; |
493 | 494 | ||
@@ -499,6 +500,7 @@ int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan) | |||
499 | return -EIO; | 500 | return -EIO; |
500 | } | 501 | } |
501 | 502 | ||
503 | cur->vlan_id = vlan; | ||
502 | list_add_tail(&cur->list, &adapter->mac_list); | 504 | list_add_tail(&cur->list, &adapter->mac_list); |
503 | return 0; | 505 | return 0; |
504 | } | 506 | } |
@@ -516,8 +518,7 @@ void __qlcnic_set_multi(struct net_device *netdev, u16 vlan) | |||
516 | if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) | 518 | if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) |
517 | return; | 519 | return; |
518 | 520 | ||
519 | if (!qlcnic_sriov_vf_check(adapter)) | 521 | qlcnic_nic_add_mac(adapter, adapter->mac_addr, vlan); |
520 | qlcnic_nic_add_mac(adapter, adapter->mac_addr, vlan); | ||
521 | qlcnic_nic_add_mac(adapter, bcast_addr, vlan); | 522 | qlcnic_nic_add_mac(adapter, bcast_addr, vlan); |
522 | 523 | ||
523 | if (netdev->flags & IFF_PROMISC) { | 524 | if (netdev->flags & IFF_PROMISC) { |
@@ -526,15 +527,11 @@ void __qlcnic_set_multi(struct net_device *netdev, u16 vlan) | |||
526 | } else if ((netdev->flags & IFF_ALLMULTI) || | 527 | } else if ((netdev->flags & IFF_ALLMULTI) || |
527 | (netdev_mc_count(netdev) > ahw->max_mc_count)) { | 528 | (netdev_mc_count(netdev) > ahw->max_mc_count)) { |
528 | mode = VPORT_MISS_MODE_ACCEPT_MULTI; | 529 | mode = VPORT_MISS_MODE_ACCEPT_MULTI; |
529 | } else if (!netdev_mc_empty(netdev) && | 530 | } else if (!netdev_mc_empty(netdev)) { |
530 | !qlcnic_sriov_vf_check(adapter)) { | ||
531 | netdev_for_each_mc_addr(ha, netdev) | 531 | netdev_for_each_mc_addr(ha, netdev) |
532 | qlcnic_nic_add_mac(adapter, ha->addr, vlan); | 532 | qlcnic_nic_add_mac(adapter, ha->addr, vlan); |
533 | } | 533 | } |
534 | 534 | ||
535 | if (qlcnic_sriov_vf_check(adapter)) | ||
536 | qlcnic_vf_add_mc_list(netdev, vlan); | ||
537 | |||
538 | /* configure unicast MAC address, if there is not sufficient space | 535 | /* configure unicast MAC address, if there is not sufficient space |
539 | * to store all the unicast addresses then enable promiscuous mode | 536 | * to store all the unicast addresses then enable promiscuous mode |
540 | */ | 537 | */ |
@@ -545,14 +542,12 @@ void __qlcnic_set_multi(struct net_device *netdev, u16 vlan) | |||
545 | qlcnic_nic_add_mac(adapter, ha->addr, vlan); | 542 | qlcnic_nic_add_mac(adapter, ha->addr, vlan); |
546 | } | 543 | } |
547 | 544 | ||
548 | if (!qlcnic_sriov_vf_check(adapter)) { | 545 | if (mode == VPORT_MISS_MODE_ACCEPT_ALL && |
549 | if (mode == VPORT_MISS_MODE_ACCEPT_ALL && | 546 | !adapter->fdb_mac_learn) { |
550 | !adapter->fdb_mac_learn) { | 547 | qlcnic_alloc_lb_filters_mem(adapter); |
551 | qlcnic_alloc_lb_filters_mem(adapter); | 548 | adapter->drv_mac_learn = 1; |
552 | adapter->drv_mac_learn = true; | 549 | } else { |
553 | } else { | 550 | adapter->drv_mac_learn = 0; |
554 | adapter->drv_mac_learn = false; | ||
555 | } | ||
556 | } | 551 | } |
557 | 552 | ||
558 | qlcnic_nic_set_promisc(adapter, mode); | 553 | qlcnic_nic_set_promisc(adapter, mode); |
@@ -561,16 +556,17 @@ void __qlcnic_set_multi(struct net_device *netdev, u16 vlan) | |||
561 | void qlcnic_set_multi(struct net_device *netdev) | 556 | void qlcnic_set_multi(struct net_device *netdev) |
562 | { | 557 | { |
563 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 558 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
559 | struct qlcnic_mac_vlan_list *cur; | ||
564 | struct netdev_hw_addr *ha; | 560 | struct netdev_hw_addr *ha; |
565 | struct qlcnic_mac_list_s *cur; | 561 | size_t temp; |
566 | 562 | ||
567 | if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) | 563 | if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) |
568 | return; | 564 | return; |
569 | if (qlcnic_sriov_vf_check(adapter)) { | 565 | if (qlcnic_sriov_vf_check(adapter)) { |
570 | if (!netdev_mc_empty(netdev)) { | 566 | if (!netdev_mc_empty(netdev)) { |
571 | netdev_for_each_mc_addr(ha, netdev) { | 567 | netdev_for_each_mc_addr(ha, netdev) { |
572 | cur = kzalloc(sizeof(struct qlcnic_mac_list_s), | 568 | temp = sizeof(struct qlcnic_mac_vlan_list); |
573 | GFP_ATOMIC); | 569 | cur = kzalloc(temp, GFP_ATOMIC); |
574 | if (cur == NULL) | 570 | if (cur == NULL) |
575 | break; | 571 | break; |
576 | memcpy(cur->mac_addr, | 572 | memcpy(cur->mac_addr, |
@@ -605,11 +601,11 @@ int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) | |||
605 | 601 | ||
606 | void qlcnic_82xx_free_mac_list(struct qlcnic_adapter *adapter) | 602 | void qlcnic_82xx_free_mac_list(struct qlcnic_adapter *adapter) |
607 | { | 603 | { |
608 | struct qlcnic_mac_list_s *cur; | ||
609 | struct list_head *head = &adapter->mac_list; | 604 | struct list_head *head = &adapter->mac_list; |
605 | struct qlcnic_mac_vlan_list *cur; | ||
610 | 606 | ||
611 | while (!list_empty(head)) { | 607 | while (!list_empty(head)) { |
612 | cur = list_entry(head->next, struct qlcnic_mac_list_s, list); | 608 | cur = list_entry(head->next, struct qlcnic_mac_vlan_list, list); |
613 | qlcnic_sre_macaddr_change(adapter, | 609 | qlcnic_sre_macaddr_change(adapter, |
614 | cur->mac_addr, 0, QLCNIC_MAC_DEL); | 610 | cur->mac_addr, 0, QLCNIC_MAC_DEL); |
615 | list_del(&cur->list); | 611 | list_del(&cur->list); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 0149c9495347..9e1494aab4d7 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | |||
@@ -1466,8 +1466,7 @@ int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter, | |||
1466 | for (ring = 0; ring < adapter->drv_sds_rings; ring++) { | 1466 | for (ring = 0; ring < adapter->drv_sds_rings; ring++) { |
1467 | sds_ring = &recv_ctx->sds_rings[ring]; | 1467 | sds_ring = &recv_ctx->sds_rings[ring]; |
1468 | if (qlcnic_check_multi_tx(adapter) && | 1468 | if (qlcnic_check_multi_tx(adapter) && |
1469 | !adapter->ahw->diag_test && | 1469 | !adapter->ahw->diag_test) { |
1470 | (adapter->drv_tx_rings > QLCNIC_SINGLE_RING)) { | ||
1471 | netif_napi_add(netdev, &sds_ring->napi, qlcnic_rx_poll, | 1470 | netif_napi_add(netdev, &sds_ring->napi, qlcnic_rx_poll, |
1472 | NAPI_POLL_WEIGHT); | 1471 | NAPI_POLL_WEIGHT); |
1473 | } else { | 1472 | } else { |
@@ -1540,8 +1539,7 @@ void qlcnic_82xx_napi_enable(struct qlcnic_adapter *adapter) | |||
1540 | 1539 | ||
1541 | if (qlcnic_check_multi_tx(adapter) && | 1540 | if (qlcnic_check_multi_tx(adapter) && |
1542 | (adapter->flags & QLCNIC_MSIX_ENABLED) && | 1541 | (adapter->flags & QLCNIC_MSIX_ENABLED) && |
1543 | !adapter->ahw->diag_test && | 1542 | !adapter->ahw->diag_test) { |
1544 | (adapter->drv_tx_rings > QLCNIC_SINGLE_RING)) { | ||
1545 | for (ring = 0; ring < adapter->drv_tx_rings; ring++) { | 1543 | for (ring = 0; ring < adapter->drv_tx_rings; ring++) { |
1546 | tx_ring = &adapter->tx_ring[ring]; | 1544 | tx_ring = &adapter->tx_ring[ring]; |
1547 | napi_enable(&tx_ring->napi); | 1545 | napi_enable(&tx_ring->napi); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 05c1eef8df13..7bfbd428eb7f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -308,11 +308,11 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) | |||
308 | 308 | ||
309 | static void qlcnic_delete_adapter_mac(struct qlcnic_adapter *adapter) | 309 | static void qlcnic_delete_adapter_mac(struct qlcnic_adapter *adapter) |
310 | { | 310 | { |
311 | struct qlcnic_mac_list_s *cur; | 311 | struct qlcnic_mac_vlan_list *cur; |
312 | struct list_head *head; | 312 | struct list_head *head; |
313 | 313 | ||
314 | list_for_each(head, &adapter->mac_list) { | 314 | list_for_each(head, &adapter->mac_list) { |
315 | cur = list_entry(head, struct qlcnic_mac_list_s, list); | 315 | cur = list_entry(head, struct qlcnic_mac_vlan_list, list); |
316 | if (!memcmp(adapter->mac_addr, cur->mac_addr, ETH_ALEN)) { | 316 | if (!memcmp(adapter->mac_addr, cur->mac_addr, ETH_ALEN)) { |
317 | qlcnic_sre_macaddr_change(adapter, cur->mac_addr, | 317 | qlcnic_sre_macaddr_change(adapter, cur->mac_addr, |
318 | 0, QLCNIC_MAC_DEL); | 318 | 0, QLCNIC_MAC_DEL); |
@@ -646,8 +646,7 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) | |||
646 | } else { | 646 | } else { |
647 | adapter->ahw->num_msix = num_msix; | 647 | adapter->ahw->num_msix = num_msix; |
648 | if (qlcnic_check_multi_tx(adapter) && | 648 | if (qlcnic_check_multi_tx(adapter) && |
649 | !adapter->ahw->diag_test && | 649 | !adapter->ahw->diag_test) |
650 | (adapter->drv_tx_rings > 1)) | ||
651 | drv_sds_rings = num_msix - drv_tx_rings; | 650 | drv_sds_rings = num_msix - drv_tx_rings; |
652 | else | 651 | else |
653 | drv_sds_rings = num_msix; | 652 | drv_sds_rings = num_msix; |
@@ -800,25 +799,26 @@ static void qlcnic_cleanup_pci_map(struct qlcnic_hardware_context *ahw) | |||
800 | 799 | ||
801 | static int qlcnic_get_act_pci_func(struct qlcnic_adapter *adapter) | 800 | static int qlcnic_get_act_pci_func(struct qlcnic_adapter *adapter) |
802 | { | 801 | { |
802 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
803 | struct qlcnic_pci_info *pci_info; | 803 | struct qlcnic_pci_info *pci_info; |
804 | int ret; | 804 | int ret; |
805 | 805 | ||
806 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | 806 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { |
807 | switch (adapter->ahw->port_type) { | 807 | switch (ahw->port_type) { |
808 | case QLCNIC_GBE: | 808 | case QLCNIC_GBE: |
809 | adapter->ahw->act_pci_func = QLCNIC_NIU_MAX_GBE_PORTS; | 809 | ahw->total_nic_func = QLCNIC_NIU_MAX_GBE_PORTS; |
810 | break; | 810 | break; |
811 | case QLCNIC_XGBE: | 811 | case QLCNIC_XGBE: |
812 | adapter->ahw->act_pci_func = QLCNIC_NIU_MAX_XG_PORTS; | 812 | ahw->total_nic_func = QLCNIC_NIU_MAX_XG_PORTS; |
813 | break; | 813 | break; |
814 | } | 814 | } |
815 | return 0; | 815 | return 0; |
816 | } | 816 | } |
817 | 817 | ||
818 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) | 818 | if (ahw->op_mode == QLCNIC_MGMT_FUNC) |
819 | return 0; | 819 | return 0; |
820 | 820 | ||
821 | pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); | 821 | pci_info = kcalloc(ahw->max_vnic_func, sizeof(*pci_info), GFP_KERNEL); |
822 | if (!pci_info) | 822 | if (!pci_info) |
823 | return -ENOMEM; | 823 | return -ENOMEM; |
824 | 824 | ||
@@ -846,12 +846,13 @@ static bool qlcnic_port_eswitch_cfg_capability(struct qlcnic_adapter *adapter) | |||
846 | 846 | ||
847 | int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) | 847 | int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) |
848 | { | 848 | { |
849 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
849 | struct qlcnic_pci_info *pci_info; | 850 | struct qlcnic_pci_info *pci_info; |
850 | int i, id = 0, ret = 0, j = 0; | 851 | int i, id = 0, ret = 0, j = 0; |
851 | u16 act_pci_func; | 852 | u16 act_pci_func; |
852 | u8 pfn; | 853 | u8 pfn; |
853 | 854 | ||
854 | pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); | 855 | pci_info = kcalloc(ahw->max_vnic_func, sizeof(*pci_info), GFP_KERNEL); |
855 | if (!pci_info) | 856 | if (!pci_info) |
856 | return -ENOMEM; | 857 | return -ENOMEM; |
857 | 858 | ||
@@ -859,7 +860,7 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) | |||
859 | if (ret) | 860 | if (ret) |
860 | goto err_pci_info; | 861 | goto err_pci_info; |
861 | 862 | ||
862 | act_pci_func = adapter->ahw->act_pci_func; | 863 | act_pci_func = ahw->total_nic_func; |
863 | 864 | ||
864 | adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * | 865 | adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * |
865 | act_pci_func, GFP_KERNEL); | 866 | act_pci_func, GFP_KERNEL); |
@@ -875,10 +876,10 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) | |||
875 | goto err_npars; | 876 | goto err_npars; |
876 | } | 877 | } |
877 | 878 | ||
878 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 879 | for (i = 0; i < ahw->max_vnic_func; i++) { |
879 | pfn = pci_info[i].id; | 880 | pfn = pci_info[i].id; |
880 | 881 | ||
881 | if (pfn >= QLCNIC_MAX_PCI_FUNC) { | 882 | if (pfn >= ahw->max_vnic_func) { |
882 | ret = QL_STATUS_INVALID_PARAM; | 883 | ret = QL_STATUS_INVALID_PARAM; |
883 | goto err_eswitch; | 884 | goto err_eswitch; |
884 | } | 885 | } |
@@ -1345,7 +1346,7 @@ int qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) | |||
1345 | if (adapter->need_fw_reset) | 1346 | if (adapter->need_fw_reset) |
1346 | return 0; | 1347 | return 0; |
1347 | 1348 | ||
1348 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { | 1349 | for (i = 0; i < adapter->ahw->total_nic_func; i++) { |
1349 | if (!adapter->npars[i].eswitch_status) | 1350 | if (!adapter->npars[i].eswitch_status) |
1350 | continue; | 1351 | continue; |
1351 | 1352 | ||
@@ -1408,7 +1409,7 @@ int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) | |||
1408 | return 0; | 1409 | return 0; |
1409 | 1410 | ||
1410 | /* Set the NPAR config data after FW reset */ | 1411 | /* Set the NPAR config data after FW reset */ |
1411 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { | 1412 | for (i = 0; i < adapter->ahw->total_nic_func; i++) { |
1412 | npar = &adapter->npars[i]; | 1413 | npar = &adapter->npars[i]; |
1413 | pci_func = npar->pci_func; | 1414 | pci_func = npar->pci_func; |
1414 | if (!adapter->npars[i].eswitch_status) | 1415 | if (!adapter->npars[i].eswitch_status) |
@@ -2037,7 +2038,7 @@ qlcnic_reset_context(struct qlcnic_adapter *adapter) | |||
2037 | void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *adapter) | 2038 | void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *adapter) |
2038 | { | 2039 | { |
2039 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 2040 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
2040 | u16 act_pci_fn = ahw->act_pci_func; | 2041 | u16 act_pci_fn = ahw->total_nic_func; |
2041 | u16 count; | 2042 | u16 count; |
2042 | 2043 | ||
2043 | ahw->max_mc_count = QLCNIC_MAX_MC_COUNT; | 2044 | ahw->max_mc_count = QLCNIC_MAX_MC_COUNT; |
@@ -2212,7 +2213,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2212 | struct qlcnic_hardware_context *ahw; | 2213 | struct qlcnic_hardware_context *ahw; |
2213 | int err, pci_using_dac = -1; | 2214 | int err, pci_using_dac = -1; |
2214 | char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ | 2215 | char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */ |
2215 | struct qlcnic_dcb *dcb; | ||
2216 | 2216 | ||
2217 | if (pdev->is_virtfn) | 2217 | if (pdev->is_virtfn) |
2218 | return -ENODEV; | 2218 | return -ENODEV; |
@@ -2290,7 +2290,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2290 | goto err_out_free_wq; | 2290 | goto err_out_free_wq; |
2291 | 2291 | ||
2292 | adapter->dev_rst_time = jiffies; | 2292 | adapter->dev_rst_time = jiffies; |
2293 | adapter->ahw->revision_id = pdev->revision; | 2293 | ahw->revision_id = pdev->revision; |
2294 | ahw->max_vnic_func = qlcnic_get_vnic_func_count(adapter); | ||
2294 | if (qlcnic_mac_learn == FDB_MAC_LEARN) | 2295 | if (qlcnic_mac_learn == FDB_MAC_LEARN) |
2295 | adapter->fdb_mac_learn = true; | 2296 | adapter->fdb_mac_learn = true; |
2296 | else if (qlcnic_mac_learn == DRV_MAC_LEARN) | 2297 | else if (qlcnic_mac_learn == DRV_MAC_LEARN) |
@@ -2335,10 +2336,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2335 | 2336 | ||
2336 | adapter->flags |= QLCNIC_NEED_FLR; | 2337 | adapter->flags |= QLCNIC_NEED_FLR; |
2337 | 2338 | ||
2338 | dcb = adapter->dcb; | ||
2339 | |||
2340 | if (dcb && qlcnic_dcb_attach(dcb)) | ||
2341 | qlcnic_clear_dcb_ops(dcb); | ||
2342 | } else if (qlcnic_83xx_check(adapter)) { | 2339 | } else if (qlcnic_83xx_check(adapter)) { |
2343 | qlcnic_83xx_check_vf(adapter, ent); | 2340 | qlcnic_83xx_check_vf(adapter, ent); |
2344 | adapter->portnum = adapter->ahw->pci_func; | 2341 | adapter->portnum = adapter->ahw->pci_func; |
@@ -2367,6 +2364,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2367 | goto err_out_free_hw; | 2364 | goto err_out_free_hw; |
2368 | } | 2365 | } |
2369 | 2366 | ||
2367 | qlcnic_dcb_enable(adapter->dcb); | ||
2368 | |||
2370 | if (qlcnic_read_mac_addr(adapter)) | 2369 | if (qlcnic_read_mac_addr(adapter)) |
2371 | dev_warn(&pdev->dev, "failed to read mac addr\n"); | 2370 | dev_warn(&pdev->dev, "failed to read mac addr\n"); |
2372 | 2371 | ||
@@ -2500,13 +2499,11 @@ static void qlcnic_remove(struct pci_dev *pdev) | |||
2500 | qlcnic_cancel_idc_work(adapter); | 2499 | qlcnic_cancel_idc_work(adapter); |
2501 | ahw = adapter->ahw; | 2500 | ahw = adapter->ahw; |
2502 | 2501 | ||
2503 | qlcnic_dcb_free(adapter->dcb); | ||
2504 | |||
2505 | unregister_netdev(netdev); | 2502 | unregister_netdev(netdev); |
2506 | qlcnic_sriov_cleanup(adapter); | 2503 | qlcnic_sriov_cleanup(adapter); |
2507 | 2504 | ||
2508 | if (qlcnic_83xx_check(adapter)) { | 2505 | if (qlcnic_83xx_check(adapter)) { |
2509 | qlcnic_83xx_register_nic_idc_func(adapter, 0); | 2506 | qlcnic_83xx_initialize_nic(adapter, 0); |
2510 | cancel_delayed_work_sync(&adapter->idc_aen_work); | 2507 | cancel_delayed_work_sync(&adapter->idc_aen_work); |
2511 | qlcnic_83xx_free_mbx_intr(adapter); | 2508 | qlcnic_83xx_free_mbx_intr(adapter); |
2512 | qlcnic_83xx_detach_mailbox_work(adapter); | 2509 | qlcnic_83xx_detach_mailbox_work(adapter); |
@@ -2514,6 +2511,8 @@ static void qlcnic_remove(struct pci_dev *pdev) | |||
2514 | kfree(ahw->fw_info); | 2511 | kfree(ahw->fw_info); |
2515 | } | 2512 | } |
2516 | 2513 | ||
2514 | qlcnic_dcb_free(adapter->dcb); | ||
2515 | |||
2517 | qlcnic_detach(adapter); | 2516 | qlcnic_detach(adapter); |
2518 | 2517 | ||
2519 | if (adapter->npars != NULL) | 2518 | if (adapter->npars != NULL) |
@@ -2642,7 +2641,7 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) | |||
2642 | if (adapter->fhash.fmax && adapter->fhash.fhead) | 2641 | if (adapter->fhash.fmax && adapter->fhash.fhead) |
2643 | return; | 2642 | return; |
2644 | 2643 | ||
2645 | act_pci_func = adapter->ahw->act_pci_func; | 2644 | act_pci_func = adapter->ahw->total_nic_func; |
2646 | spin_lock_init(&adapter->mac_learn_lock); | 2645 | spin_lock_init(&adapter->mac_learn_lock); |
2647 | spin_lock_init(&adapter->rx_mac_learn_lock); | 2646 | spin_lock_init(&adapter->rx_mac_learn_lock); |
2648 | 2647 | ||
@@ -3725,12 +3724,6 @@ int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt, | |||
3725 | return -EINVAL; | 3724 | return -EINVAL; |
3726 | } | 3725 | } |
3727 | 3726 | ||
3728 | if (ring_cnt < 2) { | ||
3729 | netdev_err(netdev, | ||
3730 | "%s rings value should not be lower than 2\n", buf); | ||
3731 | return -EINVAL; | ||
3732 | } | ||
3733 | |||
3734 | if (!is_power_of_2(ring_cnt)) { | 3727 | if (!is_power_of_2(ring_cnt)) { |
3735 | netdev_err(netdev, "%s rings value should be a power of 2\n", | 3728 | netdev_err(netdev, "%s rings value should be a power of 2\n", |
3736 | buf); | 3729 | buf); |
@@ -3788,8 +3781,7 @@ int qlcnic_setup_rings(struct qlcnic_adapter *adapter, u8 rx_cnt, u8 tx_cnt) | |||
3788 | } | 3781 | } |
3789 | 3782 | ||
3790 | if (qlcnic_83xx_check(adapter)) { | 3783 | if (qlcnic_83xx_check(adapter)) { |
3791 | /* register for NIC IDC AEN Events */ | 3784 | qlcnic_83xx_initialize_nic(adapter, 1); |
3792 | qlcnic_83xx_register_nic_idc_func(adapter, 1); | ||
3793 | err = qlcnic_83xx_setup_mbx_intr(adapter); | 3785 | err = qlcnic_83xx_setup_mbx_intr(adapter); |
3794 | qlcnic_83xx_disable_mbx_poll(adapter); | 3786 | qlcnic_83xx_disable_mbx_poll(adapter); |
3795 | if (err) { | 3787 | if (err) { |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h index 0daf660e12a1..e14d58c59b01 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h | |||
@@ -126,8 +126,8 @@ struct qlcnic_vport { | |||
126 | u16 handle; | 126 | u16 handle; |
127 | u16 max_tx_bw; | 127 | u16 max_tx_bw; |
128 | u16 min_tx_bw; | 128 | u16 min_tx_bw; |
129 | u16 pvid; | ||
129 | u8 vlan_mode; | 130 | u8 vlan_mode; |
130 | u16 vlan; | ||
131 | u8 qos; | 131 | u8 qos; |
132 | bool spoofchk; | 132 | bool spoofchk; |
133 | u8 mac[6]; | 133 | u8 mac[6]; |
@@ -137,6 +137,8 @@ struct qlcnic_vf_info { | |||
137 | u8 pci_func; | 137 | u8 pci_func; |
138 | u16 rx_ctx_id; | 138 | u16 rx_ctx_id; |
139 | u16 tx_ctx_id; | 139 | u16 tx_ctx_id; |
140 | u16 *sriov_vlans; | ||
141 | int num_vlan; | ||
140 | unsigned long state; | 142 | unsigned long state; |
141 | struct completion ch_free_cmpl; | 143 | struct completion ch_free_cmpl; |
142 | struct work_struct trans_work; | 144 | struct work_struct trans_work; |
@@ -149,6 +151,7 @@ struct qlcnic_vf_info { | |||
149 | struct qlcnic_trans_list rcv_pend; | 151 | struct qlcnic_trans_list rcv_pend; |
150 | struct qlcnic_adapter *adapter; | 152 | struct qlcnic_adapter *adapter; |
151 | struct qlcnic_vport *vp; | 153 | struct qlcnic_vport *vp; |
154 | struct mutex vlan_list_lock; /* Lock for VLAN list */ | ||
152 | }; | 155 | }; |
153 | 156 | ||
154 | struct qlcnic_async_work_list { | 157 | struct qlcnic_async_work_list { |
@@ -197,6 +200,13 @@ int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *, | |||
197 | int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8); | 200 | int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8); |
198 | int qlcnic_sriov_vf_shutdown(struct pci_dev *); | 201 | int qlcnic_sriov_vf_shutdown(struct pci_dev *); |
199 | int qlcnic_sriov_vf_resume(struct qlcnic_adapter *); | 202 | int qlcnic_sriov_vf_resume(struct qlcnic_adapter *); |
203 | void qlcnic_sriov_free_vlans(struct qlcnic_adapter *); | ||
204 | void qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *); | ||
205 | bool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *); | ||
206 | void qlcnic_sriov_del_vlan_id(struct qlcnic_sriov *, | ||
207 | struct qlcnic_vf_info *, u16); | ||
208 | void qlcnic_sriov_add_vlan_id(struct qlcnic_sriov *, | ||
209 | struct qlcnic_vf_info *, u16); | ||
200 | 210 | ||
201 | static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter) | 211 | static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter) |
202 | { | 212 | { |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 21a4b274d2e4..bf8fca7d874f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | |||
@@ -176,6 +176,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) | |||
176 | vf->adapter = adapter; | 176 | vf->adapter = adapter; |
177 | vf->pci_func = qlcnic_sriov_virtid_fn(adapter, i); | 177 | vf->pci_func = qlcnic_sriov_virtid_fn(adapter, i); |
178 | mutex_init(&vf->send_cmd_lock); | 178 | mutex_init(&vf->send_cmd_lock); |
179 | mutex_init(&vf->vlan_list_lock); | ||
179 | INIT_LIST_HEAD(&vf->rcv_act.wait_list); | 180 | INIT_LIST_HEAD(&vf->rcv_act.wait_list); |
180 | INIT_LIST_HEAD(&vf->rcv_pend.wait_list); | 181 | INIT_LIST_HEAD(&vf->rcv_pend.wait_list); |
181 | spin_lock_init(&vf->rcv_act.lock); | 182 | spin_lock_init(&vf->rcv_act.lock); |
@@ -276,6 +277,13 @@ static void qlcnic_sriov_vf_cleanup(struct qlcnic_adapter *adapter) | |||
276 | 277 | ||
277 | void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) | 278 | void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) |
278 | { | 279 | { |
280 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; | ||
281 | |||
282 | if (!sriov) | ||
283 | return; | ||
284 | |||
285 | qlcnic_sriov_free_vlans(adapter); | ||
286 | |||
279 | if (qlcnic_sriov_pf_check(adapter)) | 287 | if (qlcnic_sriov_pf_check(adapter)) |
280 | qlcnic_sriov_pf_cleanup(adapter); | 288 | qlcnic_sriov_pf_cleanup(adapter); |
281 | 289 | ||
@@ -416,10 +424,15 @@ static int qlcnic_sriov_set_guest_vlan_mode(struct qlcnic_adapter *adapter, | |||
416 | return 0; | 424 | return 0; |
417 | 425 | ||
418 | sriov->any_vlan = cmd->rsp.arg[2] & 0xf; | 426 | sriov->any_vlan = cmd->rsp.arg[2] & 0xf; |
427 | sriov->num_allowed_vlans = cmd->rsp.arg[2] >> 16; | ||
428 | dev_info(&adapter->pdev->dev, "Number of allowed Guest VLANs = %d\n", | ||
429 | sriov->num_allowed_vlans); | ||
430 | |||
431 | qlcnic_sriov_alloc_vlans(adapter); | ||
432 | |||
419 | if (!sriov->any_vlan) | 433 | if (!sriov->any_vlan) |
420 | return 0; | 434 | return 0; |
421 | 435 | ||
422 | sriov->num_allowed_vlans = cmd->rsp.arg[2] >> 16; | ||
423 | num_vlans = sriov->num_allowed_vlans; | 436 | num_vlans = sriov->num_allowed_vlans; |
424 | sriov->allowed_vlans = kzalloc(sizeof(u16) * num_vlans, GFP_KERNEL); | 437 | sriov->allowed_vlans = kzalloc(sizeof(u16) * num_vlans, GFP_KERNEL); |
425 | if (!sriov->allowed_vlans) | 438 | if (!sriov->allowed_vlans) |
@@ -473,6 +486,8 @@ static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter) | |||
473 | if (err) | 486 | if (err) |
474 | return err; | 487 | return err; |
475 | 488 | ||
489 | ahw->max_mc_count = nic_info.max_rx_mcast_mac_filters; | ||
490 | |||
476 | err = qlcnic_get_nic_info(adapter, &nic_info, ahw->pci_func); | 491 | err = qlcnic_get_nic_info(adapter, &nic_info, ahw->pci_func); |
477 | if (err) | 492 | if (err) |
478 | return -EIO; | 493 | return -EIO; |
@@ -500,7 +515,6 @@ static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter) | |||
500 | static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter, | 515 | static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter, |
501 | int pci_using_dac) | 516 | int pci_using_dac) |
502 | { | 517 | { |
503 | struct qlcnic_dcb *dcb; | ||
504 | int err; | 518 | int err; |
505 | 519 | ||
506 | INIT_LIST_HEAD(&adapter->vf_mc_list); | 520 | INIT_LIST_HEAD(&adapter->vf_mc_list); |
@@ -538,11 +552,6 @@ static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter, | |||
538 | if (err) | 552 | if (err) |
539 | goto err_out_send_channel_term; | 553 | goto err_out_send_channel_term; |
540 | 554 | ||
541 | dcb = adapter->dcb; | ||
542 | |||
543 | if (dcb && qlcnic_dcb_attach(dcb)) | ||
544 | qlcnic_clear_dcb_ops(dcb); | ||
545 | |||
546 | err = qlcnic_setup_netdev(adapter, adapter->netdev, pci_using_dac); | 555 | err = qlcnic_setup_netdev(adapter, adapter->netdev, pci_using_dac); |
547 | if (err) | 556 | if (err) |
548 | goto err_out_send_channel_term; | 557 | goto err_out_send_channel_term; |
@@ -1447,18 +1456,27 @@ out: | |||
1447 | return ret; | 1456 | return ret; |
1448 | } | 1457 | } |
1449 | 1458 | ||
1450 | void qlcnic_vf_add_mc_list(struct net_device *netdev, u16 vlan) | 1459 | static void qlcnic_vf_add_mc_list(struct net_device *netdev) |
1451 | { | 1460 | { |
1452 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1461 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1453 | struct qlcnic_mac_list_s *cur; | 1462 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; |
1463 | struct qlcnic_mac_vlan_list *cur; | ||
1454 | struct list_head *head, tmp_list; | 1464 | struct list_head *head, tmp_list; |
1465 | struct qlcnic_vf_info *vf; | ||
1466 | u16 vlan_id; | ||
1467 | int i; | ||
1468 | |||
1469 | static const u8 bcast_addr[ETH_ALEN] = { | ||
1470 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | ||
1471 | }; | ||
1455 | 1472 | ||
1473 | vf = &adapter->ahw->sriov->vf_info[0]; | ||
1456 | INIT_LIST_HEAD(&tmp_list); | 1474 | INIT_LIST_HEAD(&tmp_list); |
1457 | head = &adapter->vf_mc_list; | 1475 | head = &adapter->vf_mc_list; |
1458 | netif_addr_lock_bh(netdev); | 1476 | netif_addr_lock_bh(netdev); |
1459 | 1477 | ||
1460 | while (!list_empty(head)) { | 1478 | while (!list_empty(head)) { |
1461 | cur = list_entry(head->next, struct qlcnic_mac_list_s, list); | 1479 | cur = list_entry(head->next, struct qlcnic_mac_vlan_list, list); |
1462 | list_move(&cur->list, &tmp_list); | 1480 | list_move(&cur->list, &tmp_list); |
1463 | } | 1481 | } |
1464 | 1482 | ||
@@ -1466,8 +1484,28 @@ void qlcnic_vf_add_mc_list(struct net_device *netdev, u16 vlan) | |||
1466 | 1484 | ||
1467 | while (!list_empty(&tmp_list)) { | 1485 | while (!list_empty(&tmp_list)) { |
1468 | cur = list_entry((&tmp_list)->next, | 1486 | cur = list_entry((&tmp_list)->next, |
1469 | struct qlcnic_mac_list_s, list); | 1487 | struct qlcnic_mac_vlan_list, list); |
1470 | qlcnic_nic_add_mac(adapter, cur->mac_addr, vlan); | 1488 | if (!qlcnic_sriov_check_any_vlan(vf)) { |
1489 | qlcnic_nic_add_mac(adapter, bcast_addr, 0); | ||
1490 | qlcnic_nic_add_mac(adapter, cur->mac_addr, 0); | ||
1491 | } else { | ||
1492 | mutex_lock(&vf->vlan_list_lock); | ||
1493 | for (i = 0; i < sriov->num_allowed_vlans; i++) { | ||
1494 | vlan_id = vf->sriov_vlans[i]; | ||
1495 | if (vlan_id) { | ||
1496 | qlcnic_nic_add_mac(adapter, bcast_addr, | ||
1497 | vlan_id); | ||
1498 | qlcnic_nic_add_mac(adapter, | ||
1499 | cur->mac_addr, | ||
1500 | vlan_id); | ||
1501 | } | ||
1502 | } | ||
1503 | mutex_unlock(&vf->vlan_list_lock); | ||
1504 | if (qlcnic_84xx_check(adapter)) { | ||
1505 | qlcnic_nic_add_mac(adapter, bcast_addr, 0); | ||
1506 | qlcnic_nic_add_mac(adapter, cur->mac_addr, 0); | ||
1507 | } | ||
1508 | } | ||
1471 | list_del(&cur->list); | 1509 | list_del(&cur->list); |
1472 | kfree(cur); | 1510 | kfree(cur); |
1473 | } | 1511 | } |
@@ -1490,13 +1528,24 @@ void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *bc) | |||
1490 | static void qlcnic_sriov_vf_set_multi(struct net_device *netdev) | 1528 | static void qlcnic_sriov_vf_set_multi(struct net_device *netdev) |
1491 | { | 1529 | { |
1492 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1530 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1493 | u16 vlan; | 1531 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
1532 | u32 mode = VPORT_MISS_MODE_DROP; | ||
1494 | 1533 | ||
1495 | if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) | 1534 | if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) |
1496 | return; | 1535 | return; |
1497 | 1536 | ||
1498 | vlan = adapter->ahw->sriov->vlan; | 1537 | if (netdev->flags & IFF_PROMISC) { |
1499 | __qlcnic_set_multi(netdev, vlan); | 1538 | if (!(adapter->flags & QLCNIC_PROMISC_DISABLED)) |
1539 | mode = VPORT_MISS_MODE_ACCEPT_ALL; | ||
1540 | } else if ((netdev->flags & IFF_ALLMULTI) || | ||
1541 | (netdev_mc_count(netdev) > ahw->max_mc_count)) { | ||
1542 | mode = VPORT_MISS_MODE_ACCEPT_MULTI; | ||
1543 | } | ||
1544 | |||
1545 | if (qlcnic_sriov_vf_check(adapter)) | ||
1546 | qlcnic_vf_add_mc_list(netdev); | ||
1547 | |||
1548 | qlcnic_nic_set_promisc(adapter, mode); | ||
1500 | } | 1549 | } |
1501 | 1550 | ||
1502 | static void qlcnic_sriov_handle_async_multi(struct work_struct *work) | 1551 | static void qlcnic_sriov_handle_async_multi(struct work_struct *work) |
@@ -1584,8 +1633,6 @@ static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter) | |||
1584 | if (err) | 1633 | if (err) |
1585 | goto err_out_term_channel; | 1634 | goto err_out_term_channel; |
1586 | 1635 | ||
1587 | qlcnic_dcb_get_info(adapter->dcb); | ||
1588 | |||
1589 | return 0; | 1636 | return 0; |
1590 | 1637 | ||
1591 | err_out_term_channel: | 1638 | err_out_term_channel: |
@@ -1833,18 +1880,60 @@ static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *adapter) | |||
1833 | cancel_delayed_work_sync(&adapter->fw_work); | 1880 | cancel_delayed_work_sync(&adapter->fw_work); |
1834 | } | 1881 | } |
1835 | 1882 | ||
1836 | static int qlcnic_sriov_validate_vlan_cfg(struct qlcnic_sriov *sriov, | 1883 | static int qlcnic_sriov_check_vlan_id(struct qlcnic_sriov *sriov, |
1884 | struct qlcnic_vf_info *vf, u16 vlan_id) | ||
1885 | { | ||
1886 | int i, err = -EINVAL; | ||
1887 | |||
1888 | if (!vf->sriov_vlans) | ||
1889 | return err; | ||
1890 | |||
1891 | mutex_lock(&vf->vlan_list_lock); | ||
1892 | |||
1893 | for (i = 0; i < sriov->num_allowed_vlans; i++) { | ||
1894 | if (vf->sriov_vlans[i] == vlan_id) { | ||
1895 | err = 0; | ||
1896 | break; | ||
1897 | } | ||
1898 | } | ||
1899 | |||
1900 | mutex_unlock(&vf->vlan_list_lock); | ||
1901 | return err; | ||
1902 | } | ||
1903 | |||
1904 | static int qlcnic_sriov_validate_num_vlans(struct qlcnic_sriov *sriov, | ||
1905 | struct qlcnic_vf_info *vf) | ||
1906 | { | ||
1907 | int err = 0; | ||
1908 | |||
1909 | mutex_lock(&vf->vlan_list_lock); | ||
1910 | |||
1911 | if (vf->num_vlan >= sriov->num_allowed_vlans) | ||
1912 | err = -EINVAL; | ||
1913 | |||
1914 | mutex_unlock(&vf->vlan_list_lock); | ||
1915 | return err; | ||
1916 | } | ||
1917 | |||
1918 | static int qlcnic_sriov_validate_vlan_cfg(struct qlcnic_adapter *adapter, | ||
1837 | u16 vid, u8 enable) | 1919 | u16 vid, u8 enable) |
1838 | { | 1920 | { |
1839 | u16 vlan = sriov->vlan; | 1921 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; |
1922 | struct qlcnic_vf_info *vf; | ||
1923 | bool vlan_exist; | ||
1840 | u8 allowed = 0; | 1924 | u8 allowed = 0; |
1841 | int i; | 1925 | int i; |
1842 | 1926 | ||
1927 | vf = &adapter->ahw->sriov->vf_info[0]; | ||
1928 | vlan_exist = qlcnic_sriov_check_any_vlan(vf); | ||
1843 | if (sriov->vlan_mode != QLC_GUEST_VLAN_MODE) | 1929 | if (sriov->vlan_mode != QLC_GUEST_VLAN_MODE) |
1844 | return -EINVAL; | 1930 | return -EINVAL; |
1845 | 1931 | ||
1846 | if (enable) { | 1932 | if (enable) { |
1847 | if (vlan) | 1933 | if (qlcnic_83xx_vf_check(adapter) && vlan_exist) |
1934 | return -EINVAL; | ||
1935 | |||
1936 | if (qlcnic_sriov_validate_num_vlans(sriov, vf)) | ||
1848 | return -EINVAL; | 1937 | return -EINVAL; |
1849 | 1938 | ||
1850 | if (sriov->any_vlan) { | 1939 | if (sriov->any_vlan) { |
@@ -1857,24 +1946,54 @@ static int qlcnic_sriov_validate_vlan_cfg(struct qlcnic_sriov *sriov, | |||
1857 | return -EINVAL; | 1946 | return -EINVAL; |
1858 | } | 1947 | } |
1859 | } else { | 1948 | } else { |
1860 | if (!vlan || vlan != vid) | 1949 | if (!vlan_exist || qlcnic_sriov_check_vlan_id(sriov, vf, vid)) |
1861 | return -EINVAL; | 1950 | return -EINVAL; |
1862 | } | 1951 | } |
1863 | 1952 | ||
1864 | return 0; | 1953 | return 0; |
1865 | } | 1954 | } |
1866 | 1955 | ||
1956 | static void qlcnic_sriov_vlan_operation(struct qlcnic_vf_info *vf, u16 vlan_id, | ||
1957 | enum qlcnic_vlan_operations opcode) | ||
1958 | { | ||
1959 | struct qlcnic_adapter *adapter = vf->adapter; | ||
1960 | struct qlcnic_sriov *sriov; | ||
1961 | |||
1962 | sriov = adapter->ahw->sriov; | ||
1963 | |||
1964 | if (!vf->sriov_vlans) | ||
1965 | return; | ||
1966 | |||
1967 | mutex_lock(&vf->vlan_list_lock); | ||
1968 | |||
1969 | switch (opcode) { | ||
1970 | case QLC_VLAN_ADD: | ||
1971 | qlcnic_sriov_add_vlan_id(sriov, vf, vlan_id); | ||
1972 | break; | ||
1973 | case QLC_VLAN_DELETE: | ||
1974 | qlcnic_sriov_del_vlan_id(sriov, vf, vlan_id); | ||
1975 | break; | ||
1976 | default: | ||
1977 | netdev_err(adapter->netdev, "Invalid VLAN operation\n"); | ||
1978 | } | ||
1979 | |||
1980 | mutex_unlock(&vf->vlan_list_lock); | ||
1981 | return; | ||
1982 | } | ||
1983 | |||
1867 | int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter, | 1984 | int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter, |
1868 | u16 vid, u8 enable) | 1985 | u16 vid, u8 enable) |
1869 | { | 1986 | { |
1870 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; | 1987 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; |
1988 | struct qlcnic_vf_info *vf; | ||
1871 | struct qlcnic_cmd_args cmd; | 1989 | struct qlcnic_cmd_args cmd; |
1872 | int ret; | 1990 | int ret; |
1873 | 1991 | ||
1874 | if (vid == 0) | 1992 | if (vid == 0) |
1875 | return 0; | 1993 | return 0; |
1876 | 1994 | ||
1877 | ret = qlcnic_sriov_validate_vlan_cfg(sriov, vid, enable); | 1995 | vf = &adapter->ahw->sriov->vf_info[0]; |
1996 | ret = qlcnic_sriov_validate_vlan_cfg(adapter, vid, enable); | ||
1878 | if (ret) | 1997 | if (ret) |
1879 | return ret; | 1998 | return ret; |
1880 | 1999 | ||
@@ -1894,11 +2013,11 @@ int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter, | |||
1894 | qlcnic_free_mac_list(adapter); | 2013 | qlcnic_free_mac_list(adapter); |
1895 | 2014 | ||
1896 | if (enable) | 2015 | if (enable) |
1897 | sriov->vlan = vid; | 2016 | qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_ADD); |
1898 | else | 2017 | else |
1899 | sriov->vlan = 0; | 2018 | qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_DELETE); |
1900 | 2019 | ||
1901 | qlcnic_sriov_vf_set_multi(adapter->netdev); | 2020 | qlcnic_set_multi(adapter->netdev); |
1902 | } | 2021 | } |
1903 | 2022 | ||
1904 | qlcnic_free_mbx_args(&cmd); | 2023 | qlcnic_free_mbx_args(&cmd); |
@@ -1908,20 +2027,18 @@ int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter, | |||
1908 | static void qlcnic_sriov_vf_free_mac_list(struct qlcnic_adapter *adapter) | 2027 | static void qlcnic_sriov_vf_free_mac_list(struct qlcnic_adapter *adapter) |
1909 | { | 2028 | { |
1910 | struct list_head *head = &adapter->mac_list; | 2029 | struct list_head *head = &adapter->mac_list; |
1911 | struct qlcnic_mac_list_s *cur; | 2030 | struct qlcnic_mac_vlan_list *cur; |
1912 | u16 vlan; | ||
1913 | |||
1914 | vlan = adapter->ahw->sriov->vlan; | ||
1915 | 2031 | ||
1916 | while (!list_empty(head)) { | 2032 | while (!list_empty(head)) { |
1917 | cur = list_entry(head->next, struct qlcnic_mac_list_s, list); | 2033 | cur = list_entry(head->next, struct qlcnic_mac_vlan_list, list); |
1918 | qlcnic_sre_macaddr_change(adapter, cur->mac_addr, | 2034 | qlcnic_sre_macaddr_change(adapter, cur->mac_addr, cur->vlan_id, |
1919 | vlan, QLCNIC_MAC_DEL); | 2035 | QLCNIC_MAC_DEL); |
1920 | list_del(&cur->list); | 2036 | list_del(&cur->list); |
1921 | kfree(cur); | 2037 | kfree(cur); |
1922 | } | 2038 | } |
1923 | } | 2039 | } |
1924 | 2040 | ||
2041 | |||
1925 | int qlcnic_sriov_vf_shutdown(struct pci_dev *pdev) | 2042 | int qlcnic_sriov_vf_shutdown(struct pci_dev *pdev) |
1926 | { | 2043 | { |
1927 | struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); | 2044 | struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); |
@@ -1972,3 +2089,70 @@ int qlcnic_sriov_vf_resume(struct qlcnic_adapter *adapter) | |||
1972 | idc->delay); | 2089 | idc->delay); |
1973 | return err; | 2090 | return err; |
1974 | } | 2091 | } |
2092 | |||
2093 | void qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *adapter) | ||
2094 | { | ||
2095 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; | ||
2096 | struct qlcnic_vf_info *vf; | ||
2097 | int i; | ||
2098 | |||
2099 | for (i = 0; i < sriov->num_vfs; i++) { | ||
2100 | vf = &sriov->vf_info[i]; | ||
2101 | vf->sriov_vlans = kcalloc(sriov->num_allowed_vlans, | ||
2102 | sizeof(*vf->sriov_vlans), GFP_KERNEL); | ||
2103 | } | ||
2104 | } | ||
2105 | |||
2106 | void qlcnic_sriov_free_vlans(struct qlcnic_adapter *adapter) | ||
2107 | { | ||
2108 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; | ||
2109 | struct qlcnic_vf_info *vf; | ||
2110 | int i; | ||
2111 | |||
2112 | for (i = 0; i < sriov->num_vfs; i++) { | ||
2113 | vf = &sriov->vf_info[i]; | ||
2114 | kfree(vf->sriov_vlans); | ||
2115 | vf->sriov_vlans = NULL; | ||
2116 | } | ||
2117 | } | ||
2118 | |||
2119 | void qlcnic_sriov_add_vlan_id(struct qlcnic_sriov *sriov, | ||
2120 | struct qlcnic_vf_info *vf, u16 vlan_id) | ||
2121 | { | ||
2122 | int i; | ||
2123 | |||
2124 | for (i = 0; i < sriov->num_allowed_vlans; i++) { | ||
2125 | if (!vf->sriov_vlans[i]) { | ||
2126 | vf->sriov_vlans[i] = vlan_id; | ||
2127 | vf->num_vlan++; | ||
2128 | return; | ||
2129 | } | ||
2130 | } | ||
2131 | } | ||
2132 | |||
2133 | void qlcnic_sriov_del_vlan_id(struct qlcnic_sriov *sriov, | ||
2134 | struct qlcnic_vf_info *vf, u16 vlan_id) | ||
2135 | { | ||
2136 | int i; | ||
2137 | |||
2138 | for (i = 0; i < sriov->num_allowed_vlans; i++) { | ||
2139 | if (vf->sriov_vlans[i] == vlan_id) { | ||
2140 | vf->sriov_vlans[i] = 0; | ||
2141 | vf->num_vlan--; | ||
2142 | return; | ||
2143 | } | ||
2144 | } | ||
2145 | } | ||
2146 | |||
2147 | bool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *vf) | ||
2148 | { | ||
2149 | bool err = false; | ||
2150 | |||
2151 | mutex_lock(&vf->vlan_list_lock); | ||
2152 | |||
2153 | if (vf->num_vlan) | ||
2154 | err = true; | ||
2155 | |||
2156 | mutex_unlock(&vf->vlan_list_lock); | ||
2157 | return err; | ||
2158 | } | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 686f460b1502..98b621fb1227 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include "qlcnic.h" | 9 | #include "qlcnic.h" |
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | 11 | ||
12 | #define QLCNIC_SRIOV_VF_MAX_MAC 1 | 12 | #define QLCNIC_SRIOV_VF_MAX_MAC 8 |
13 | #define QLC_VF_MIN_TX_RATE 100 | 13 | #define QLC_VF_MIN_TX_RATE 100 |
14 | #define QLC_VF_MAX_TX_RATE 9999 | 14 | #define QLC_VF_MAX_TX_RATE 9999 |
15 | 15 | ||
@@ -64,9 +64,10 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter, | |||
64 | { | 64 | { |
65 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; | 65 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; |
66 | struct qlcnic_resources *res = &sriov->ff_max; | 66 | struct qlcnic_resources *res = &sriov->ff_max; |
67 | u32 temp, num_vf_macs, num_vfs, max; | 67 | u16 num_macs = sriov->num_allowed_vlans + 1; |
68 | int ret = -EIO, vpid, id; | 68 | int ret = -EIO, vpid, id; |
69 | struct qlcnic_vport *vp; | 69 | struct qlcnic_vport *vp; |
70 | u32 num_vfs, max, temp; | ||
70 | 71 | ||
71 | vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func); | 72 | vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func); |
72 | if (vpid < 0) | 73 | if (vpid < 0) |
@@ -76,16 +77,21 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter, | |||
76 | max = num_vfs + 1; | 77 | max = num_vfs + 1; |
77 | info->bit_offsets = 0xffff; | 78 | info->bit_offsets = 0xffff; |
78 | info->max_tx_ques = res->num_tx_queues / max; | 79 | info->max_tx_ques = res->num_tx_queues / max; |
79 | info->max_rx_mcast_mac_filters = res->num_rx_mcast_mac_filters; | 80 | |
80 | num_vf_macs = QLCNIC_SRIOV_VF_MAX_MAC; | 81 | if (qlcnic_83xx_pf_check(adapter)) |
82 | num_macs = 1; | ||
81 | 83 | ||
82 | if (adapter->ahw->pci_func == func) { | 84 | if (adapter->ahw->pci_func == func) { |
83 | temp = res->num_rx_mcast_mac_filters - (num_vfs * num_vf_macs); | ||
84 | info->max_rx_ucast_mac_filters = temp; | ||
85 | temp = res->num_tx_mac_filters - (num_vfs * num_vf_macs); | ||
86 | info->max_tx_mac_filters = temp; | ||
87 | info->min_tx_bw = 0; | 85 | info->min_tx_bw = 0; |
88 | info->max_tx_bw = MAX_BW; | 86 | info->max_tx_bw = MAX_BW; |
87 | temp = res->num_rx_ucast_mac_filters - num_macs * num_vfs; | ||
88 | info->max_rx_ucast_mac_filters = temp; | ||
89 | temp = res->num_tx_mac_filters - num_macs * num_vfs; | ||
90 | info->max_tx_mac_filters = temp; | ||
91 | temp = num_macs * num_vfs * QLCNIC_SRIOV_VF_MAX_MAC; | ||
92 | temp = res->num_rx_mcast_mac_filters - temp; | ||
93 | info->max_rx_mcast_mac_filters = temp; | ||
94 | |||
89 | } else { | 95 | } else { |
90 | id = qlcnic_sriov_func_to_index(adapter, func); | 96 | id = qlcnic_sriov_func_to_index(adapter, func); |
91 | if (id < 0) | 97 | if (id < 0) |
@@ -93,8 +99,10 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter, | |||
93 | vp = sriov->vf_info[id].vp; | 99 | vp = sriov->vf_info[id].vp; |
94 | info->min_tx_bw = vp->min_tx_bw; | 100 | info->min_tx_bw = vp->min_tx_bw; |
95 | info->max_tx_bw = vp->max_tx_bw; | 101 | info->max_tx_bw = vp->max_tx_bw; |
96 | info->max_rx_ucast_mac_filters = num_vf_macs; | 102 | info->max_rx_ucast_mac_filters = num_macs; |
97 | info->max_tx_mac_filters = num_vf_macs; | 103 | info->max_tx_mac_filters = num_macs; |
104 | temp = num_macs * QLCNIC_SRIOV_VF_MAX_MAC; | ||
105 | info->max_rx_mcast_mac_filters = temp; | ||
98 | } | 106 | } |
99 | 107 | ||
100 | info->max_rx_ip_addr = res->num_destip / max; | 108 | info->max_rx_ip_addr = res->num_destip / max; |
@@ -132,6 +140,25 @@ static void qlcnic_sriov_pf_set_ff_max_res(struct qlcnic_adapter *adapter, | |||
132 | ff_max->max_local_ipv6_addrs = info->max_local_ipv6_addrs; | 140 | ff_max->max_local_ipv6_addrs = info->max_local_ipv6_addrs; |
133 | } | 141 | } |
134 | 142 | ||
143 | static void qlcnic_sriov_set_vf_max_vlan(struct qlcnic_adapter *adapter, | ||
144 | struct qlcnic_info *npar_info) | ||
145 | { | ||
146 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; | ||
147 | int temp, total_fn; | ||
148 | |||
149 | temp = npar_info->max_rx_mcast_mac_filters; | ||
150 | total_fn = sriov->num_vfs + 1; | ||
151 | |||
152 | temp = temp / (QLCNIC_SRIOV_VF_MAX_MAC * total_fn); | ||
153 | sriov->num_allowed_vlans = temp - 1; | ||
154 | |||
155 | if (qlcnic_83xx_pf_check(adapter)) | ||
156 | sriov->num_allowed_vlans = 1; | ||
157 | |||
158 | netdev_info(adapter->netdev, "Max Guest VLANs supported per VF = %d\n", | ||
159 | sriov->num_allowed_vlans); | ||
160 | } | ||
161 | |||
135 | static int qlcnic_sriov_get_pf_info(struct qlcnic_adapter *adapter, | 162 | static int qlcnic_sriov_get_pf_info(struct qlcnic_adapter *adapter, |
136 | struct qlcnic_info *npar_info) | 163 | struct qlcnic_info *npar_info) |
137 | { | 164 | { |
@@ -165,6 +192,7 @@ static int qlcnic_sriov_get_pf_info(struct qlcnic_adapter *adapter, | |||
165 | npar_info->max_local_ipv6_addrs = LSW(cmd.rsp.arg[8]); | 192 | npar_info->max_local_ipv6_addrs = LSW(cmd.rsp.arg[8]); |
166 | npar_info->max_remote_ipv6_addrs = MSW(cmd.rsp.arg[8]); | 193 | npar_info->max_remote_ipv6_addrs = MSW(cmd.rsp.arg[8]); |
167 | 194 | ||
195 | qlcnic_sriov_set_vf_max_vlan(adapter, npar_info); | ||
168 | qlcnic_sriov_pf_set_ff_max_res(adapter, npar_info); | 196 | qlcnic_sriov_pf_set_ff_max_res(adapter, npar_info); |
169 | dev_info(&adapter->pdev->dev, | 197 | dev_info(&adapter->pdev->dev, |
170 | "\n\ttotal_pf: %d,\n" | 198 | "\n\ttotal_pf: %d,\n" |
@@ -403,6 +431,8 @@ static int qlcnic_pci_sriov_disable(struct qlcnic_adapter *adapter) | |||
403 | 431 | ||
404 | qlcnic_sriov_pf_disable(adapter); | 432 | qlcnic_sriov_pf_disable(adapter); |
405 | 433 | ||
434 | qlcnic_sriov_free_vlans(adapter); | ||
435 | |||
406 | qlcnic_sriov_pf_cleanup(adapter); | 436 | qlcnic_sriov_pf_cleanup(adapter); |
407 | 437 | ||
408 | /* After disabling SRIOV re-init the driver in default mode | 438 | /* After disabling SRIOV re-init the driver in default mode |
@@ -511,6 +541,8 @@ static int __qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter, | |||
511 | if (err) | 541 | if (err) |
512 | goto del_flr_queue; | 542 | goto del_flr_queue; |
513 | 543 | ||
544 | qlcnic_sriov_alloc_vlans(adapter); | ||
545 | |||
514 | err = qlcnic_sriov_pf_enable(adapter, num_vfs); | 546 | err = qlcnic_sriov_pf_enable(adapter, num_vfs); |
515 | return err; | 547 | return err; |
516 | 548 | ||
@@ -608,7 +640,7 @@ static int qlcnic_sriov_set_vf_acl(struct qlcnic_adapter *adapter, u8 func) | |||
608 | 640 | ||
609 | if (vp->vlan_mode == QLC_PVID_MODE) { | 641 | if (vp->vlan_mode == QLC_PVID_MODE) { |
610 | cmd.req.arg[2] |= BIT_6; | 642 | cmd.req.arg[2] |= BIT_6; |
611 | cmd.req.arg[3] |= vp->vlan << 8; | 643 | cmd.req.arg[3] |= vp->pvid << 8; |
612 | } | 644 | } |
613 | 645 | ||
614 | err = qlcnic_issue_cmd(adapter, &cmd); | 646 | err = qlcnic_issue_cmd(adapter, &cmd); |
@@ -643,10 +675,13 @@ static int qlcnic_sriov_pf_channel_cfg_cmd(struct qlcnic_bc_trans *trans, | |||
643 | struct qlcnic_vf_info *vf = trans->vf; | 675 | struct qlcnic_vf_info *vf = trans->vf; |
644 | struct qlcnic_vport *vp = vf->vp; | 676 | struct qlcnic_vport *vp = vf->vp; |
645 | struct qlcnic_adapter *adapter; | 677 | struct qlcnic_adapter *adapter; |
678 | struct qlcnic_sriov *sriov; | ||
646 | u16 func = vf->pci_func; | 679 | u16 func = vf->pci_func; |
680 | size_t size; | ||
647 | int err; | 681 | int err; |
648 | 682 | ||
649 | adapter = vf->adapter; | 683 | adapter = vf->adapter; |
684 | sriov = adapter->ahw->sriov; | ||
650 | 685 | ||
651 | if (trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) { | 686 | if (trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) { |
652 | err = qlcnic_sriov_pf_config_vport(adapter, 1, func); | 687 | err = qlcnic_sriov_pf_config_vport(adapter, 1, func); |
@@ -656,8 +691,12 @@ static int qlcnic_sriov_pf_channel_cfg_cmd(struct qlcnic_bc_trans *trans, | |||
656 | qlcnic_sriov_pf_config_vport(adapter, 0, func); | 691 | qlcnic_sriov_pf_config_vport(adapter, 0, func); |
657 | } | 692 | } |
658 | } else { | 693 | } else { |
659 | if (vp->vlan_mode == QLC_GUEST_VLAN_MODE) | 694 | if (vp->vlan_mode == QLC_GUEST_VLAN_MODE) { |
660 | vp->vlan = 0; | 695 | size = sizeof(*vf->sriov_vlans); |
696 | size = size * sriov->num_allowed_vlans; | ||
697 | memset(vf->sriov_vlans, 0, size); | ||
698 | } | ||
699 | |||
661 | err = qlcnic_sriov_pf_config_vport(adapter, 0, func); | 700 | err = qlcnic_sriov_pf_config_vport(adapter, 0, func); |
662 | } | 701 | } |
663 | 702 | ||
@@ -679,20 +718,23 @@ err_out: | |||
679 | } | 718 | } |
680 | 719 | ||
681 | static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter, | 720 | static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter, |
682 | struct qlcnic_vport *vp, | 721 | struct qlcnic_vf_info *vf, |
683 | u16 func, u16 vlan, u8 op) | 722 | u16 vlan, u8 op) |
684 | { | 723 | { |
685 | struct qlcnic_cmd_args cmd; | 724 | struct qlcnic_cmd_args cmd; |
686 | struct qlcnic_macvlan_mbx mv; | 725 | struct qlcnic_macvlan_mbx mv; |
726 | struct qlcnic_vport *vp; | ||
687 | u8 *addr; | 727 | u8 *addr; |
688 | int err; | 728 | int err; |
689 | u32 *buf; | 729 | u32 *buf; |
690 | int vpid; | 730 | int vpid; |
691 | 731 | ||
732 | vp = vf->vp; | ||
733 | |||
692 | if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN)) | 734 | if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN)) |
693 | return -ENOMEM; | 735 | return -ENOMEM; |
694 | 736 | ||
695 | vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func); | 737 | vpid = qlcnic_sriov_pf_get_vport_handle(adapter, vf->pci_func); |
696 | if (vpid < 0) { | 738 | if (vpid < 0) { |
697 | err = -EINVAL; | 739 | err = -EINVAL; |
698 | goto out; | 740 | goto out; |
@@ -736,6 +778,35 @@ static int qlcnic_sriov_validate_create_rx_ctx(struct qlcnic_cmd_args *cmd) | |||
736 | return 0; | 778 | return 0; |
737 | } | 779 | } |
738 | 780 | ||
781 | static void qlcnic_83xx_cfg_default_mac_vlan(struct qlcnic_adapter *adapter, | ||
782 | struct qlcnic_vf_info *vf, | ||
783 | int opcode) | ||
784 | { | ||
785 | struct qlcnic_sriov *sriov; | ||
786 | u16 vlan; | ||
787 | int i; | ||
788 | |||
789 | sriov = adapter->ahw->sriov; | ||
790 | |||
791 | mutex_lock(&vf->vlan_list_lock); | ||
792 | if (vf->num_vlan) { | ||
793 | for (i = 0; i < sriov->num_allowed_vlans; i++) { | ||
794 | vlan = vf->sriov_vlans[i]; | ||
795 | if (vlan) | ||
796 | qlcnic_sriov_cfg_vf_def_mac(adapter, vf, vlan, | ||
797 | opcode); | ||
798 | } | ||
799 | } | ||
800 | mutex_unlock(&vf->vlan_list_lock); | ||
801 | |||
802 | if (vf->vp->vlan_mode != QLC_PVID_MODE) { | ||
803 | if (qlcnic_83xx_pf_check(adapter) && | ||
804 | qlcnic_sriov_check_any_vlan(vf)) | ||
805 | return; | ||
806 | qlcnic_sriov_cfg_vf_def_mac(adapter, vf, 0, opcode); | ||
807 | } | ||
808 | } | ||
809 | |||
739 | static int qlcnic_sriov_pf_create_rx_ctx_cmd(struct qlcnic_bc_trans *tran, | 810 | static int qlcnic_sriov_pf_create_rx_ctx_cmd(struct qlcnic_bc_trans *tran, |
740 | struct qlcnic_cmd_args *cmd) | 811 | struct qlcnic_cmd_args *cmd) |
741 | { | 812 | { |
@@ -743,7 +814,6 @@ static int qlcnic_sriov_pf_create_rx_ctx_cmd(struct qlcnic_bc_trans *tran, | |||
743 | struct qlcnic_adapter *adapter = vf->adapter; | 814 | struct qlcnic_adapter *adapter = vf->adapter; |
744 | struct qlcnic_rcv_mbx_out *mbx_out; | 815 | struct qlcnic_rcv_mbx_out *mbx_out; |
745 | int err; | 816 | int err; |
746 | u16 vlan; | ||
747 | 817 | ||
748 | err = qlcnic_sriov_validate_create_rx_ctx(cmd); | 818 | err = qlcnic_sriov_validate_create_rx_ctx(cmd); |
749 | if (err) { | 819 | if (err) { |
@@ -754,12 +824,10 @@ static int qlcnic_sriov_pf_create_rx_ctx_cmd(struct qlcnic_bc_trans *tran, | |||
754 | cmd->req.arg[6] = vf->vp->handle; | 824 | cmd->req.arg[6] = vf->vp->handle; |
755 | err = qlcnic_issue_cmd(adapter, cmd); | 825 | err = qlcnic_issue_cmd(adapter, cmd); |
756 | 826 | ||
757 | vlan = vf->vp->vlan; | ||
758 | if (!err) { | 827 | if (!err) { |
759 | mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd->rsp.arg[1]; | 828 | mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd->rsp.arg[1]; |
760 | vf->rx_ctx_id = mbx_out->ctx_id; | 829 | vf->rx_ctx_id = mbx_out->ctx_id; |
761 | qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func, | 830 | qlcnic_83xx_cfg_default_mac_vlan(adapter, vf, QLCNIC_MAC_ADD); |
762 | vlan, QLCNIC_MAC_ADD); | ||
763 | } else { | 831 | } else { |
764 | vf->rx_ctx_id = 0; | 832 | vf->rx_ctx_id = 0; |
765 | } | 833 | } |
@@ -843,7 +911,6 @@ static int qlcnic_sriov_pf_del_rx_ctx_cmd(struct qlcnic_bc_trans *trans, | |||
843 | struct qlcnic_vf_info *vf = trans->vf; | 911 | struct qlcnic_vf_info *vf = trans->vf; |
844 | struct qlcnic_adapter *adapter = vf->adapter; | 912 | struct qlcnic_adapter *adapter = vf->adapter; |
845 | int err; | 913 | int err; |
846 | u16 vlan; | ||
847 | 914 | ||
848 | err = qlcnic_sriov_validate_del_rx_ctx(vf, cmd); | 915 | err = qlcnic_sriov_validate_del_rx_ctx(vf, cmd); |
849 | if (err) { | 916 | if (err) { |
@@ -851,9 +918,7 @@ static int qlcnic_sriov_pf_del_rx_ctx_cmd(struct qlcnic_bc_trans *trans, | |||
851 | return err; | 918 | return err; |
852 | } | 919 | } |
853 | 920 | ||
854 | vlan = vf->vp->vlan; | 921 | qlcnic_83xx_cfg_default_mac_vlan(adapter, vf, QLCNIC_MAC_DEL); |
855 | qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func, | ||
856 | vlan, QLCNIC_MAC_DEL); | ||
857 | cmd->req.arg[1] |= vf->vp->handle << 16; | 922 | cmd->req.arg[1] |= vf->vp->handle << 16; |
858 | err = qlcnic_issue_cmd(adapter, cmd); | 923 | err = qlcnic_issue_cmd(adapter, cmd); |
859 | 924 | ||
@@ -1120,7 +1185,7 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter, | |||
1120 | cmd->req.arg[1] &= ~0x7; | 1185 | cmd->req.arg[1] &= ~0x7; |
1121 | new_op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ? | 1186 | new_op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ? |
1122 | QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL; | 1187 | QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL; |
1123 | cmd->req.arg[3] |= vp->vlan << 16; | 1188 | cmd->req.arg[3] |= vp->pvid << 16; |
1124 | cmd->req.arg[1] |= new_op; | 1189 | cmd->req.arg[1] |= new_op; |
1125 | } | 1190 | } |
1126 | 1191 | ||
@@ -1190,8 +1255,10 @@ static int qlcnic_sriov_pf_get_acl_cmd(struct qlcnic_bc_trans *trans, | |||
1190 | struct qlcnic_vport *vp = vf->vp; | 1255 | struct qlcnic_vport *vp = vf->vp; |
1191 | u8 cmd_op, mode = vp->vlan_mode; | 1256 | u8 cmd_op, mode = vp->vlan_mode; |
1192 | struct qlcnic_adapter *adapter; | 1257 | struct qlcnic_adapter *adapter; |
1258 | struct qlcnic_sriov *sriov; | ||
1193 | 1259 | ||
1194 | adapter = vf->adapter; | 1260 | adapter = vf->adapter; |
1261 | sriov = adapter->ahw->sriov; | ||
1195 | 1262 | ||
1196 | cmd_op = trans->req_hdr->cmd_op; | 1263 | cmd_op = trans->req_hdr->cmd_op; |
1197 | cmd->rsp.arg[0] |= 1 << 25; | 1264 | cmd->rsp.arg[0] |= 1 << 25; |
@@ -1205,10 +1272,10 @@ static int qlcnic_sriov_pf_get_acl_cmd(struct qlcnic_bc_trans *trans, | |||
1205 | switch (mode) { | 1272 | switch (mode) { |
1206 | case QLC_GUEST_VLAN_MODE: | 1273 | case QLC_GUEST_VLAN_MODE: |
1207 | cmd->rsp.arg[1] = mode | 1 << 8; | 1274 | cmd->rsp.arg[1] = mode | 1 << 8; |
1208 | cmd->rsp.arg[2] = 1 << 16; | 1275 | cmd->rsp.arg[2] = sriov->num_allowed_vlans << 16; |
1209 | break; | 1276 | break; |
1210 | case QLC_PVID_MODE: | 1277 | case QLC_PVID_MODE: |
1211 | cmd->rsp.arg[1] = mode | 1 << 8 | vp->vlan << 16; | 1278 | cmd->rsp.arg[1] = mode | 1 << 8 | vp->pvid << 16; |
1212 | break; | 1279 | break; |
1213 | } | 1280 | } |
1214 | 1281 | ||
@@ -1216,24 +1283,27 @@ static int qlcnic_sriov_pf_get_acl_cmd(struct qlcnic_bc_trans *trans, | |||
1216 | } | 1283 | } |
1217 | 1284 | ||
1218 | static int qlcnic_sriov_pf_del_guest_vlan(struct qlcnic_adapter *adapter, | 1285 | static int qlcnic_sriov_pf_del_guest_vlan(struct qlcnic_adapter *adapter, |
1219 | struct qlcnic_vf_info *vf) | 1286 | struct qlcnic_vf_info *vf, |
1220 | 1287 | struct qlcnic_cmd_args *cmd) | |
1221 | { | 1288 | { |
1222 | struct qlcnic_vport *vp = vf->vp; | 1289 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; |
1290 | u16 vlan; | ||
1223 | 1291 | ||
1224 | if (!vp->vlan) | 1292 | if (!qlcnic_sriov_check_any_vlan(vf)) |
1225 | return -EINVAL; | 1293 | return -EINVAL; |
1226 | 1294 | ||
1295 | vlan = cmd->req.arg[1] >> 16; | ||
1227 | if (!vf->rx_ctx_id) { | 1296 | if (!vf->rx_ctx_id) { |
1228 | vp->vlan = 0; | 1297 | qlcnic_sriov_del_vlan_id(sriov, vf, vlan); |
1229 | return 0; | 1298 | return 0; |
1230 | } | 1299 | } |
1231 | 1300 | ||
1232 | qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func, | 1301 | qlcnic_sriov_cfg_vf_def_mac(adapter, vf, vlan, QLCNIC_MAC_DEL); |
1233 | vp->vlan, QLCNIC_MAC_DEL); | 1302 | qlcnic_sriov_del_vlan_id(sriov, vf, vlan); |
1234 | vp->vlan = 0; | 1303 | |
1235 | qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func, | 1304 | if (qlcnic_83xx_pf_check(adapter)) |
1236 | 0, QLCNIC_MAC_ADD); | 1305 | qlcnic_sriov_cfg_vf_def_mac(adapter, vf, |
1306 | 0, QLCNIC_MAC_ADD); | ||
1237 | return 0; | 1307 | return 0; |
1238 | } | 1308 | } |
1239 | 1309 | ||
@@ -1241,32 +1311,37 @@ static int qlcnic_sriov_pf_add_guest_vlan(struct qlcnic_adapter *adapter, | |||
1241 | struct qlcnic_vf_info *vf, | 1311 | struct qlcnic_vf_info *vf, |
1242 | struct qlcnic_cmd_args *cmd) | 1312 | struct qlcnic_cmd_args *cmd) |
1243 | { | 1313 | { |
1244 | struct qlcnic_vport *vp = vf->vp; | 1314 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; |
1245 | int err = -EIO; | 1315 | int err = -EIO; |
1316 | u16 vlan; | ||
1246 | 1317 | ||
1247 | if (vp->vlan) | 1318 | if (qlcnic_83xx_pf_check(adapter) && qlcnic_sriov_check_any_vlan(vf)) |
1248 | return err; | 1319 | return err; |
1249 | 1320 | ||
1321 | vlan = cmd->req.arg[1] >> 16; | ||
1322 | |||
1250 | if (!vf->rx_ctx_id) { | 1323 | if (!vf->rx_ctx_id) { |
1251 | vp->vlan = cmd->req.arg[1] >> 16; | 1324 | qlcnic_sriov_add_vlan_id(sriov, vf, vlan); |
1252 | return 0; | 1325 | return 0; |
1253 | } | 1326 | } |
1254 | 1327 | ||
1255 | err = qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func, | 1328 | if (qlcnic_83xx_pf_check(adapter)) { |
1256 | 0, QLCNIC_MAC_DEL); | 1329 | err = qlcnic_sriov_cfg_vf_def_mac(adapter, vf, 0, |
1257 | if (err) | 1330 | QLCNIC_MAC_DEL); |
1258 | return err; | 1331 | if (err) |
1332 | return err; | ||
1333 | } | ||
1259 | 1334 | ||
1260 | vp->vlan = cmd->req.arg[1] >> 16; | 1335 | err = qlcnic_sriov_cfg_vf_def_mac(adapter, vf, vlan, QLCNIC_MAC_ADD); |
1261 | err = qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func, | ||
1262 | vp->vlan, QLCNIC_MAC_ADD); | ||
1263 | 1336 | ||
1264 | if (err) { | 1337 | if (err) { |
1265 | qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func, | 1338 | if (qlcnic_83xx_pf_check(adapter)) |
1266 | 0, QLCNIC_MAC_ADD); | 1339 | qlcnic_sriov_cfg_vf_def_mac(adapter, vf, 0, |
1267 | vp->vlan = 0; | 1340 | QLCNIC_MAC_ADD); |
1341 | return err; | ||
1268 | } | 1342 | } |
1269 | 1343 | ||
1344 | qlcnic_sriov_add_vlan_id(sriov, vf, vlan); | ||
1270 | return err; | 1345 | return err; |
1271 | } | 1346 | } |
1272 | 1347 | ||
@@ -1289,7 +1364,7 @@ static int qlcnic_sriov_pf_cfg_guest_vlan_cmd(struct qlcnic_bc_trans *tran, | |||
1289 | if (op) | 1364 | if (op) |
1290 | err = qlcnic_sriov_pf_add_guest_vlan(adapter, vf, cmd); | 1365 | err = qlcnic_sriov_pf_add_guest_vlan(adapter, vf, cmd); |
1291 | else | 1366 | else |
1292 | err = qlcnic_sriov_pf_del_guest_vlan(adapter, vf); | 1367 | err = qlcnic_sriov_pf_del_guest_vlan(adapter, vf, cmd); |
1293 | 1368 | ||
1294 | cmd->rsp.arg[0] |= err ? 2 << 25 : 1 << 25; | 1369 | cmd->rsp.arg[0] |= err ? 2 << 25 : 1 << 25; |
1295 | return err; | 1370 | return err; |
@@ -1299,8 +1374,6 @@ static const int qlcnic_pf_passthru_supp_cmds[] = { | |||
1299 | QLCNIC_CMD_GET_STATISTICS, | 1374 | QLCNIC_CMD_GET_STATISTICS, |
1300 | QLCNIC_CMD_GET_PORT_CONFIG, | 1375 | QLCNIC_CMD_GET_PORT_CONFIG, |
1301 | QLCNIC_CMD_GET_LINK_STATUS, | 1376 | QLCNIC_CMD_GET_LINK_STATUS, |
1302 | QLCNIC_CMD_DCB_QUERY_CAP, | ||
1303 | QLCNIC_CMD_DCB_QUERY_PARAM, | ||
1304 | QLCNIC_CMD_INIT_NIC_FUNC, | 1377 | QLCNIC_CMD_INIT_NIC_FUNC, |
1305 | QLCNIC_CMD_STOP_NIC_FUNC, | 1378 | QLCNIC_CMD_STOP_NIC_FUNC, |
1306 | }; | 1379 | }; |
@@ -1596,7 +1669,8 @@ void qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *sriov, | |||
1596 | } | 1669 | } |
1597 | 1670 | ||
1598 | if (vp->vlan_mode == QLC_GUEST_VLAN_MODE) | 1671 | if (vp->vlan_mode == QLC_GUEST_VLAN_MODE) |
1599 | vp->vlan = 0; | 1672 | memset(vf->sriov_vlans, 0, |
1673 | sizeof(*vf->sriov_vlans) * sriov->num_allowed_vlans); | ||
1600 | 1674 | ||
1601 | qlcnic_sriov_schedule_flr(sriov, vf, qlcnic_sriov_pf_process_flr); | 1675 | qlcnic_sriov_schedule_flr(sriov, vf, qlcnic_sriov_pf_process_flr); |
1602 | netdev_info(dev, "FLR received for PCI func %d\n", vf->pci_func); | 1676 | netdev_info(dev, "FLR received for PCI func %d\n", vf->pci_func); |
@@ -1766,20 +1840,22 @@ int qlcnic_sriov_set_vf_vlan(struct net_device *netdev, int vf, | |||
1766 | return -EOPNOTSUPP; | 1840 | return -EOPNOTSUPP; |
1767 | } | 1841 | } |
1768 | 1842 | ||
1843 | memset(vf_info->sriov_vlans, 0, | ||
1844 | sizeof(*vf_info->sriov_vlans) * sriov->num_allowed_vlans); | ||
1845 | |||
1769 | switch (vlan) { | 1846 | switch (vlan) { |
1770 | case 4095: | 1847 | case 4095: |
1771 | vp->vlan = 0; | ||
1772 | vp->vlan_mode = QLC_GUEST_VLAN_MODE; | 1848 | vp->vlan_mode = QLC_GUEST_VLAN_MODE; |
1773 | break; | 1849 | break; |
1774 | case 0: | 1850 | case 0: |
1775 | vp->vlan_mode = QLC_NO_VLAN_MODE; | 1851 | vp->vlan_mode = QLC_NO_VLAN_MODE; |
1776 | vp->vlan = 0; | ||
1777 | vp->qos = 0; | 1852 | vp->qos = 0; |
1778 | break; | 1853 | break; |
1779 | default: | 1854 | default: |
1780 | vp->vlan_mode = QLC_PVID_MODE; | 1855 | vp->vlan_mode = QLC_PVID_MODE; |
1781 | vp->vlan = vlan; | 1856 | qlcnic_sriov_add_vlan_id(sriov, vf_info, vlan); |
1782 | vp->qos = qos; | 1857 | vp->qos = qos; |
1858 | vp->pvid = vlan; | ||
1783 | } | 1859 | } |
1784 | 1860 | ||
1785 | netdev_info(netdev, "Setting VLAN %d, QoS %d, for VF %d\n", | 1861 | netdev_info(netdev, "Setting VLAN %d, QoS %d, for VF %d\n", |
@@ -1794,7 +1870,7 @@ static __u32 qlcnic_sriov_get_vf_vlan(struct qlcnic_adapter *adapter, | |||
1794 | 1870 | ||
1795 | switch (vp->vlan_mode) { | 1871 | switch (vp->vlan_mode) { |
1796 | case QLC_PVID_MODE: | 1872 | case QLC_PVID_MODE: |
1797 | vlan = vp->vlan; | 1873 | vlan = vp->pvid; |
1798 | break; | 1874 | break; |
1799 | case QLC_GUEST_VLAN_MODE: | 1875 | case QLC_GUEST_VLAN_MODE: |
1800 | vlan = MAX_VLAN_ID; | 1876 | vlan = MAX_VLAN_ID; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 1a9f8a400e50..b5296672c447 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -360,10 +360,28 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, | |||
360 | return size; | 360 | return size; |
361 | } | 361 | } |
362 | 362 | ||
363 | static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) | 363 | static u32 qlcnic_get_pci_func_count(struct qlcnic_adapter *adapter) |
364 | { | 364 | { |
365 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
366 | u32 count = 0; | ||
367 | |||
368 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) | ||
369 | return ahw->total_nic_func; | ||
370 | |||
371 | if (ahw->total_pci_func <= QLC_DEFAULT_VNIC_COUNT) | ||
372 | count = QLC_DEFAULT_VNIC_COUNT; | ||
373 | else | ||
374 | count = ahw->max_vnic_func; | ||
375 | |||
376 | return count; | ||
377 | } | ||
378 | |||
379 | int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) | ||
380 | { | ||
381 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
365 | int i; | 382 | int i; |
366 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { | 383 | |
384 | for (i = 0; i < pci_func_count; i++) { | ||
367 | if (adapter->npars[i].pci_func == pci_func) | 385 | if (adapter->npars[i].pci_func == pci_func) |
368 | return i; | 386 | return i; |
369 | } | 387 | } |
@@ -382,7 +400,6 @@ static int validate_pm_config(struct qlcnic_adapter *adapter, | |||
382 | src_pci_func = pm_cfg[i].pci_func; | 400 | src_pci_func = pm_cfg[i].pci_func; |
383 | dest_pci_func = pm_cfg[i].dest_npar; | 401 | dest_pci_func = pm_cfg[i].dest_npar; |
384 | src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func); | 402 | src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func); |
385 | |||
386 | if (src_index < 0) | 403 | if (src_index < 0) |
387 | return QL_STATUS_INVALID_PARAM; | 404 | return QL_STATUS_INVALID_PARAM; |
388 | 405 | ||
@@ -439,6 +456,8 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, | |||
439 | for (i = 0; i < count; i++) { | 456 | for (i = 0; i < count; i++) { |
440 | pci_func = pm_cfg[i].pci_func; | 457 | pci_func = pm_cfg[i].pci_func; |
441 | index = qlcnic_is_valid_nic_func(adapter, pci_func); | 458 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
459 | if (index < 0) | ||
460 | return QL_STATUS_INVALID_PARAM; | ||
442 | id = adapter->npars[index].phy_port; | 461 | id = adapter->npars[index].phy_port; |
443 | adapter->npars[index].enable_pm = !!pm_cfg[i].action; | 462 | adapter->npars[index].enable_pm = !!pm_cfg[i].action; |
444 | adapter->npars[index].dest_npar = id; | 463 | adapter->npars[index].dest_npar = id; |
@@ -455,17 +474,19 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, | |||
455 | { | 474 | { |
456 | struct device *dev = container_of(kobj, struct device, kobj); | 475 | struct device *dev = container_of(kobj, struct device, kobj); |
457 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 476 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
458 | struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC]; | 477 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); |
459 | int i; | 478 | struct qlcnic_pm_func_cfg *pm_cfg; |
479 | int i, pm_cfg_size; | ||
460 | u8 pci_func; | 480 | u8 pci_func; |
461 | 481 | ||
462 | if (size != sizeof(pm_cfg)) | 482 | pm_cfg_size = pci_func_count * sizeof(*pm_cfg); |
483 | if (size != pm_cfg_size) | ||
463 | return QL_STATUS_INVALID_PARAM; | 484 | return QL_STATUS_INVALID_PARAM; |
464 | 485 | ||
465 | memset(&pm_cfg, 0, | 486 | memset(buf, 0, pm_cfg_size); |
466 | sizeof(struct qlcnic_pm_func_cfg) * QLCNIC_MAX_PCI_FUNC); | 487 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; |
467 | 488 | ||
468 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 489 | for (i = 0; i < pci_func_count; i++) { |
469 | pci_func = adapter->npars[i].pci_func; | 490 | pci_func = adapter->npars[i].pci_func; |
470 | if (!adapter->npars[i].active) | 491 | if (!adapter->npars[i].active) |
471 | continue; | 492 | continue; |
@@ -477,26 +498,26 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, | |||
477 | pm_cfg[pci_func].dest_npar = 0; | 498 | pm_cfg[pci_func].dest_npar = 0; |
478 | pm_cfg[pci_func].pci_func = i; | 499 | pm_cfg[pci_func].pci_func = i; |
479 | } | 500 | } |
480 | memcpy(buf, &pm_cfg, size); | ||
481 | |||
482 | return size; | 501 | return size; |
483 | } | 502 | } |
484 | 503 | ||
485 | static int validate_esw_config(struct qlcnic_adapter *adapter, | 504 | static int validate_esw_config(struct qlcnic_adapter *adapter, |
486 | struct qlcnic_esw_func_cfg *esw_cfg, int count) | 505 | struct qlcnic_esw_func_cfg *esw_cfg, int count) |
487 | { | 506 | { |
507 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
508 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
509 | int i, ret; | ||
488 | u32 op_mode; | 510 | u32 op_mode; |
489 | u8 pci_func; | 511 | u8 pci_func; |
490 | int i, ret; | ||
491 | 512 | ||
492 | if (qlcnic_82xx_check(adapter)) | 513 | if (qlcnic_82xx_check(adapter)) |
493 | op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE); | 514 | op_mode = readl(ahw->pci_base0 + QLCNIC_DRV_OP_MODE); |
494 | else | 515 | else |
495 | op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE); | 516 | op_mode = QLCRDX(ahw, QLC_83XX_DRV_OP_MODE); |
496 | 517 | ||
497 | for (i = 0; i < count; i++) { | 518 | for (i = 0; i < count; i++) { |
498 | pci_func = esw_cfg[i].pci_func; | 519 | pci_func = esw_cfg[i].pci_func; |
499 | if (pci_func >= QLCNIC_MAX_PCI_FUNC) | 520 | if (pci_func >= pci_func_count) |
500 | return QL_STATUS_INVALID_PARAM; | 521 | return QL_STATUS_INVALID_PARAM; |
501 | 522 | ||
502 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) | 523 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) |
@@ -600,6 +621,8 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
600 | for (i = 0; i < count; i++) { | 621 | for (i = 0; i < count; i++) { |
601 | pci_func = esw_cfg[i].pci_func; | 622 | pci_func = esw_cfg[i].pci_func; |
602 | index = qlcnic_is_valid_nic_func(adapter, pci_func); | 623 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
624 | if (index < 0) | ||
625 | return QL_STATUS_INVALID_PARAM; | ||
603 | npar = &adapter->npars[index]; | 626 | npar = &adapter->npars[index]; |
604 | switch (esw_cfg[i].op_mode) { | 627 | switch (esw_cfg[i].op_mode) { |
605 | case QLCNIC_PORT_DEFAULTS: | 628 | case QLCNIC_PORT_DEFAULTS: |
@@ -629,16 +652,19 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, | |||
629 | { | 652 | { |
630 | struct device *dev = container_of(kobj, struct device, kobj); | 653 | struct device *dev = container_of(kobj, struct device, kobj); |
631 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 654 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
632 | struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; | 655 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); |
656 | struct qlcnic_esw_func_cfg *esw_cfg; | ||
657 | size_t esw_cfg_size; | ||
633 | u8 i, pci_func; | 658 | u8 i, pci_func; |
634 | 659 | ||
635 | if (size != sizeof(esw_cfg)) | 660 | esw_cfg_size = pci_func_count * sizeof(*esw_cfg); |
661 | if (size != esw_cfg_size) | ||
636 | return QL_STATUS_INVALID_PARAM; | 662 | return QL_STATUS_INVALID_PARAM; |
637 | 663 | ||
638 | memset(&esw_cfg, 0, | 664 | memset(buf, 0, esw_cfg_size); |
639 | sizeof(struct qlcnic_esw_func_cfg) * QLCNIC_MAX_PCI_FUNC); | 665 | esw_cfg = (struct qlcnic_esw_func_cfg *)buf; |
640 | 666 | ||
641 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 667 | for (i = 0; i < pci_func_count; i++) { |
642 | pci_func = adapter->npars[i].pci_func; | 668 | pci_func = adapter->npars[i].pci_func; |
643 | if (!adapter->npars[i].active) | 669 | if (!adapter->npars[i].active) |
644 | continue; | 670 | continue; |
@@ -650,9 +676,6 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, | |||
650 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) | 676 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) |
651 | return QL_STATUS_INVALID_PARAM; | 677 | return QL_STATUS_INVALID_PARAM; |
652 | } | 678 | } |
653 | |||
654 | memcpy(buf, &esw_cfg, size); | ||
655 | |||
656 | return size; | 679 | return size; |
657 | } | 680 | } |
658 | 681 | ||
@@ -711,6 +734,8 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, | |||
711 | if (ret) | 734 | if (ret) |
712 | return ret; | 735 | return ret; |
713 | index = qlcnic_is_valid_nic_func(adapter, pci_func); | 736 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
737 | if (index < 0) | ||
738 | return QL_STATUS_INVALID_PARAM; | ||
714 | adapter->npars[index].min_bw = nic_info.min_tx_bw; | 739 | adapter->npars[index].min_bw = nic_info.min_tx_bw; |
715 | adapter->npars[index].max_bw = nic_info.max_tx_bw; | 740 | adapter->npars[index].max_bw = nic_info.max_tx_bw; |
716 | } | 741 | } |
@@ -726,27 +751,28 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
726 | { | 751 | { |
727 | struct device *dev = container_of(kobj, struct device, kobj); | 752 | struct device *dev = container_of(kobj, struct device, kobj); |
728 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 753 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
754 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
755 | struct qlcnic_npar_func_cfg *np_cfg; | ||
729 | struct qlcnic_info nic_info; | 756 | struct qlcnic_info nic_info; |
730 | struct qlcnic_npar_func_cfg np_cfg[QLCNIC_MAX_PCI_FUNC]; | 757 | size_t np_cfg_size; |
731 | int i, ret; | 758 | int i, ret; |
732 | 759 | ||
733 | if (size != sizeof(np_cfg)) | 760 | np_cfg_size = pci_func_count * sizeof(*np_cfg); |
761 | if (size != np_cfg_size) | ||
734 | return QL_STATUS_INVALID_PARAM; | 762 | return QL_STATUS_INVALID_PARAM; |
735 | 763 | ||
736 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); | 764 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); |
737 | memset(&np_cfg, 0, | 765 | memset(buf, 0, np_cfg_size); |
738 | sizeof(struct qlcnic_npar_func_cfg) * QLCNIC_MAX_PCI_FUNC); | 766 | np_cfg = (struct qlcnic_npar_func_cfg *)buf; |
739 | 767 | ||
740 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 768 | for (i = 0; i < pci_func_count; i++) { |
741 | if (qlcnic_is_valid_nic_func(adapter, i) < 0) | 769 | if (qlcnic_is_valid_nic_func(adapter, i) < 0) |
742 | continue; | 770 | continue; |
743 | ret = qlcnic_get_nic_info(adapter, &nic_info, i); | 771 | ret = qlcnic_get_nic_info(adapter, &nic_info, i); |
744 | if (ret) | 772 | if (ret) |
745 | return ret; | 773 | return ret; |
746 | |||
747 | if (!adapter->npars[i].eswitch_status) | 774 | if (!adapter->npars[i].eswitch_status) |
748 | continue; | 775 | continue; |
749 | |||
750 | np_cfg[i].pci_func = i; | 776 | np_cfg[i].pci_func = i; |
751 | np_cfg[i].op_mode = (u8)nic_info.op_mode; | 777 | np_cfg[i].op_mode = (u8)nic_info.op_mode; |
752 | np_cfg[i].port_num = nic_info.phys_port; | 778 | np_cfg[i].port_num = nic_info.phys_port; |
@@ -756,8 +782,6 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
756 | np_cfg[i].max_tx_queues = nic_info.max_tx_ques; | 782 | np_cfg[i].max_tx_queues = nic_info.max_tx_ques; |
757 | np_cfg[i].max_rx_queues = nic_info.max_rx_ques; | 783 | np_cfg[i].max_rx_queues = nic_info.max_rx_ques; |
758 | } | 784 | } |
759 | |||
760 | memcpy(buf, &np_cfg, size); | ||
761 | return size; | 785 | return size; |
762 | } | 786 | } |
763 | 787 | ||
@@ -769,6 +793,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file, | |||
769 | { | 793 | { |
770 | struct device *dev = container_of(kobj, struct device, kobj); | 794 | struct device *dev = container_of(kobj, struct device, kobj); |
771 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 795 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
796 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
772 | struct qlcnic_esw_statistics port_stats; | 797 | struct qlcnic_esw_statistics port_stats; |
773 | int ret; | 798 | int ret; |
774 | 799 | ||
@@ -778,7 +803,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file, | |||
778 | if (size != sizeof(struct qlcnic_esw_statistics)) | 803 | if (size != sizeof(struct qlcnic_esw_statistics)) |
779 | return QL_STATUS_INVALID_PARAM; | 804 | return QL_STATUS_INVALID_PARAM; |
780 | 805 | ||
781 | if (offset >= QLCNIC_MAX_PCI_FUNC) | 806 | if (offset >= pci_func_count) |
782 | return QL_STATUS_INVALID_PARAM; | 807 | return QL_STATUS_INVALID_PARAM; |
783 | 808 | ||
784 | memset(&port_stats, 0, size); | 809 | memset(&port_stats, 0, size); |
@@ -869,12 +894,13 @@ static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file, | |||
869 | 894 | ||
870 | struct device *dev = container_of(kobj, struct device, kobj); | 895 | struct device *dev = container_of(kobj, struct device, kobj); |
871 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 896 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
897 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); | ||
872 | int ret; | 898 | int ret; |
873 | 899 | ||
874 | if (qlcnic_83xx_check(adapter)) | 900 | if (qlcnic_83xx_check(adapter)) |
875 | return QLC_STATUS_UNSUPPORTED_CMD; | 901 | return QLC_STATUS_UNSUPPORTED_CMD; |
876 | 902 | ||
877 | if (offset >= QLCNIC_MAX_PCI_FUNC) | 903 | if (offset >= pci_func_count) |
878 | return QL_STATUS_INVALID_PARAM; | 904 | return QL_STATUS_INVALID_PARAM; |
879 | 905 | ||
880 | ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset, | 906 | ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset, |
@@ -898,27 +924,32 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
898 | { | 924 | { |
899 | struct device *dev = container_of(kobj, struct device, kobj); | 925 | struct device *dev = container_of(kobj, struct device, kobj); |
900 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 926 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
901 | struct qlcnic_pci_func_cfg pci_cfg[QLCNIC_MAX_PCI_FUNC]; | 927 | u32 pci_func_count = qlcnic_get_pci_func_count(adapter); |
928 | struct qlcnic_pci_func_cfg *pci_cfg; | ||
902 | struct qlcnic_pci_info *pci_info; | 929 | struct qlcnic_pci_info *pci_info; |
930 | size_t pci_info_sz, pci_cfg_sz; | ||
903 | int i, ret; | 931 | int i, ret; |
904 | 932 | ||
905 | if (size != sizeof(pci_cfg)) | 933 | pci_cfg_sz = pci_func_count * sizeof(*pci_cfg); |
934 | if (size != pci_cfg_sz) | ||
906 | return QL_STATUS_INVALID_PARAM; | 935 | return QL_STATUS_INVALID_PARAM; |
907 | 936 | ||
908 | pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); | 937 | pci_info_sz = pci_func_count * sizeof(*pci_info); |
938 | pci_info = vmalloc(pci_info_sz); | ||
909 | if (!pci_info) | 939 | if (!pci_info) |
910 | return -ENOMEM; | 940 | return -ENOMEM; |
911 | 941 | ||
942 | memset(pci_info, 0, pci_info_sz); | ||
943 | memset(buf, 0, pci_cfg_sz); | ||
944 | pci_cfg = (struct qlcnic_pci_func_cfg *)buf; | ||
945 | |||
912 | ret = qlcnic_get_pci_info(adapter, pci_info); | 946 | ret = qlcnic_get_pci_info(adapter, pci_info); |
913 | if (ret) { | 947 | if (ret) { |
914 | kfree(pci_info); | 948 | vfree(pci_info); |
915 | return ret; | 949 | return ret; |
916 | } | 950 | } |
917 | 951 | ||
918 | memset(&pci_cfg, 0, | 952 | for (i = 0; i < pci_func_count; i++) { |
919 | sizeof(struct qlcnic_pci_func_cfg) * QLCNIC_MAX_PCI_FUNC); | ||
920 | |||
921 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | ||
922 | pci_cfg[i].pci_func = pci_info[i].id; | 953 | pci_cfg[i].pci_func = pci_info[i].id; |
923 | pci_cfg[i].func_type = pci_info[i].type; | 954 | pci_cfg[i].func_type = pci_info[i].type; |
924 | pci_cfg[i].port_num = pci_info[i].default_port; | 955 | pci_cfg[i].port_num = pci_info[i].default_port; |
@@ -927,8 +958,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
927 | memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); | 958 | memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); |
928 | } | 959 | } |
929 | 960 | ||
930 | memcpy(buf, &pci_cfg, size); | 961 | vfree(pci_info); |
931 | kfree(pci_info); | ||
932 | return size; | 962 | return size; |
933 | } | 963 | } |
934 | 964 | ||