diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 15 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 35 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 40 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 80 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 42 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 17 |
12 files changed, 184 insertions, 63 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 8d7aa4ceac90..25e1492ad528 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 53 | 41 | #define _QLCNIC_LINUX_SUBVERSION 54 |
42 | #define QLCNIC_LINUX_VERSIONID "5.3.53" | 42 | #define QLCNIC_LINUX_VERSIONID "5.3.54" |
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)) |
@@ -970,6 +970,9 @@ struct qlcnic_ipaddr { | |||
970 | #define QLCNIC_BEACON_EANBLE 0xC | 970 | #define QLCNIC_BEACON_EANBLE 0xC |
971 | #define QLCNIC_BEACON_DISABLE 0xD | 971 | #define QLCNIC_BEACON_DISABLE 0xD |
972 | 972 | ||
973 | #define QLCNIC_BEACON_ON 2 | ||
974 | #define QLCNIC_BEACON_OFF 0 | ||
975 | |||
973 | #define QLCNIC_MSIX_TBL_SPACE 8192 | 976 | #define QLCNIC_MSIX_TBL_SPACE 8192 |
974 | #define QLCNIC_PCI_REG_MSIX_TBL 0x44 | 977 | #define QLCNIC_PCI_REG_MSIX_TBL 0x44 |
975 | #define QLCNIC_MSIX_TBL_PGSIZE 4096 | 978 | #define QLCNIC_MSIX_TBL_PGSIZE 4096 |
@@ -1079,6 +1082,7 @@ struct qlcnic_adapter { | |||
1079 | u64 dev_rst_time; | 1082 | u64 dev_rst_time; |
1080 | bool drv_mac_learn; | 1083 | bool drv_mac_learn; |
1081 | bool fdb_mac_learn; | 1084 | bool fdb_mac_learn; |
1085 | u8 rx_mac_learn; | ||
1082 | unsigned long vlans[BITS_TO_LONGS(VLAN_N_VID)]; | 1086 | unsigned long vlans[BITS_TO_LONGS(VLAN_N_VID)]; |
1083 | u8 flash_mfg_id; | 1087 | u8 flash_mfg_id; |
1084 | struct qlcnic_npar_info *npars; | 1088 | struct qlcnic_npar_info *npars; |
@@ -1640,7 +1644,6 @@ int qlcnic_set_default_offload_settings(struct qlcnic_adapter *); | |||
1640 | int qlcnic_reset_npar_config(struct qlcnic_adapter *); | 1644 | int qlcnic_reset_npar_config(struct qlcnic_adapter *); |
1641 | int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *); | 1645 | int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *); |
1642 | void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16); | 1646 | void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16); |
1643 | int qlcnic_get_beacon_state(struct qlcnic_adapter *, u8 *); | ||
1644 | int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); | 1647 | int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); |
1645 | int qlcnic_read_mac_addr(struct qlcnic_adapter *); | 1648 | int qlcnic_read_mac_addr(struct qlcnic_adapter *); |
1646 | int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); | 1649 | int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); |
@@ -1767,6 +1770,7 @@ struct qlcnic_hardware_ops { | |||
1767 | pci_channel_state_t); | 1770 | pci_channel_state_t); |
1768 | pci_ers_result_t (*io_slot_reset) (struct pci_dev *); | 1771 | pci_ers_result_t (*io_slot_reset) (struct pci_dev *); |
1769 | void (*io_resume) (struct pci_dev *); | 1772 | void (*io_resume) (struct pci_dev *); |
1773 | void (*get_beacon_state)(struct qlcnic_adapter *); | ||
1770 | }; | 1774 | }; |
1771 | 1775 | ||
1772 | extern struct qlcnic_nic_template qlcnic_vf_ops; | 1776 | extern struct qlcnic_nic_template qlcnic_vf_ops; |
@@ -1993,6 +1997,11 @@ static inline void qlcnic_set_mac_filter_count(struct qlcnic_adapter *adapter) | |||
1993 | adapter->ahw->hw_ops->set_mac_filter_count(adapter); | 1997 | adapter->ahw->hw_ops->set_mac_filter_count(adapter); |
1994 | } | 1998 | } |
1995 | 1999 | ||
2000 | static inline void qlcnic_get_beacon_state(struct qlcnic_adapter *adapter) | ||
2001 | { | ||
2002 | adapter->ahw->hw_ops->get_beacon_state(adapter); | ||
2003 | } | ||
2004 | |||
1996 | static inline void qlcnic_read_phys_port_id(struct qlcnic_adapter *adapter) | 2005 | static inline void qlcnic_read_phys_port_id(struct qlcnic_adapter *adapter) |
1997 | { | 2006 | { |
1998 | if (adapter->ahw->hw_ops->read_phys_port_id) | 2007 | if (adapter->ahw->hw_ops->read_phys_port_id) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 03eb2ad9611a..a684d28e37af 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -181,7 +181,7 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = { | |||
181 | .io_error_detected = qlcnic_83xx_io_error_detected, | 181 | .io_error_detected = qlcnic_83xx_io_error_detected, |
182 | .io_slot_reset = qlcnic_83xx_io_slot_reset, | 182 | .io_slot_reset = qlcnic_83xx_io_slot_reset, |
183 | .io_resume = qlcnic_83xx_io_resume, | 183 | .io_resume = qlcnic_83xx_io_resume, |
184 | 184 | .get_beacon_state = qlcnic_83xx_get_beacon_state, | |
185 | }; | 185 | }; |
186 | 186 | ||
187 | static struct qlcnic_nic_template qlcnic_83xx_ops = { | 187 | static struct qlcnic_nic_template qlcnic_83xx_ops = { |
@@ -1388,6 +1388,33 @@ out: | |||
1388 | netif_device_attach(netdev); | 1388 | netif_device_attach(netdev); |
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *adapter) | ||
1392 | { | ||
1393 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
1394 | struct qlcnic_cmd_args cmd; | ||
1395 | u8 beacon_state; | ||
1396 | int err = 0; | ||
1397 | |||
1398 | err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LED_CONFIG); | ||
1399 | if (!err) { | ||
1400 | err = qlcnic_issue_cmd(adapter, &cmd); | ||
1401 | if (!err) { | ||
1402 | beacon_state = cmd.rsp.arg[4]; | ||
1403 | if (beacon_state == QLCNIC_BEACON_DISABLE) | ||
1404 | ahw->beacon_state = QLC_83XX_BEACON_OFF; | ||
1405 | else if (beacon_state == QLC_83XX_ENABLE_BEACON) | ||
1406 | ahw->beacon_state = QLC_83XX_BEACON_ON; | ||
1407 | } | ||
1408 | } else { | ||
1409 | netdev_err(adapter->netdev, "Get beacon state failed, err=%d\n", | ||
1410 | err); | ||
1411 | } | ||
1412 | |||
1413 | qlcnic_free_mbx_args(&cmd); | ||
1414 | |||
1415 | return; | ||
1416 | } | ||
1417 | |||
1391 | int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state, | 1418 | int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state, |
1392 | u32 beacon) | 1419 | u32 beacon) |
1393 | { | 1420 | { |
@@ -1591,7 +1618,9 @@ static void qlcnic_83xx_set_interface_id_promisc(struct qlcnic_adapter *adapter, | |||
1591 | u32 *interface_id) | 1618 | u32 *interface_id) |
1592 | { | 1619 | { |
1593 | if (qlcnic_sriov_pf_check(adapter)) { | 1620 | if (qlcnic_sriov_pf_check(adapter)) { |
1621 | qlcnic_alloc_lb_filters_mem(adapter); | ||
1594 | qlcnic_pf_set_interface_id_promisc(adapter, interface_id); | 1622 | qlcnic_pf_set_interface_id_promisc(adapter, interface_id); |
1623 | adapter->rx_mac_learn = 1; | ||
1595 | } else { | 1624 | } else { |
1596 | if (!qlcnic_sriov_vf_check(adapter)) | 1625 | if (!qlcnic_sriov_vf_check(adapter)) |
1597 | *interface_id = adapter->recv_ctx->context_id << 16; | 1626 | *interface_id = adapter->recv_ctx->context_id << 16; |
@@ -1618,6 +1647,10 @@ int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) | |||
1618 | 1647 | ||
1619 | cmd->type = QLC_83XX_MBX_CMD_NO_WAIT; | 1648 | cmd->type = QLC_83XX_MBX_CMD_NO_WAIT; |
1620 | qlcnic_83xx_set_interface_id_promisc(adapter, &temp); | 1649 | qlcnic_83xx_set_interface_id_promisc(adapter, &temp); |
1650 | |||
1651 | if (qlcnic_84xx_check(adapter) && qlcnic_sriov_pf_check(adapter)) | ||
1652 | mode = VPORT_MISS_MODE_ACCEPT_ALL; | ||
1653 | |||
1621 | cmd->req.arg[1] = mode | temp; | 1654 | cmd->req.arg[1] = mode | temp; |
1622 | err = qlcnic_issue_cmd(adapter, cmd); | 1655 | err = qlcnic_issue_cmd(adapter, cmd); |
1623 | if (!err) | 1656 | if (!err) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 34d291168b79..4643b159df86 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | |||
@@ -381,6 +381,8 @@ enum qlcnic_83xx_states { | |||
381 | 381 | ||
382 | /* LED configuration settings */ | 382 | /* LED configuration settings */ |
383 | #define QLC_83XX_ENABLE_BEACON 0xe | 383 | #define QLC_83XX_ENABLE_BEACON 0xe |
384 | #define QLC_83XX_BEACON_ON 1 | ||
385 | #define QLC_83XX_BEACON_OFF 0 | ||
384 | #define QLC_83XX_LED_RATE 0xff | 386 | #define QLC_83XX_LED_RATE 0xff |
385 | #define QLC_83XX_LED_ACT (1 << 10) | 387 | #define QLC_83XX_LED_ACT (1 << 10) |
386 | #define QLC_83XX_LED_MOD (0 << 13) | 388 | #define QLC_83XX_LED_MOD (0 << 13) |
@@ -559,6 +561,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *); | |||
559 | void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); | 561 | void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); |
560 | void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); | 562 | void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); |
561 | int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32); | 563 | int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32); |
564 | void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *); | ||
562 | void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); | 565 | void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); |
563 | int qlcnic_ind_rd(struct qlcnic_adapter *, u32); | 566 | int qlcnic_ind_rd(struct qlcnic_adapter *, u32); |
564 | int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *); | 567 | int qlcnic_83xx_create_rx_ctx(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 22ae884728b8..abe3924c61c5 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -2214,6 +2214,7 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) | |||
2214 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 2214 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
2215 | int err = 0; | 2215 | int err = 0; |
2216 | 2216 | ||
2217 | adapter->rx_mac_learn = 0; | ||
2217 | ahw->msix_supported = !!qlcnic_use_msi_x; | 2218 | ahw->msix_supported = !!qlcnic_use_msi_x; |
2218 | 2219 | ||
2219 | qlcnic_83xx_init_rings(adapter); | 2220 | qlcnic_83xx_init_rings(adapter); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c index 474320a5f0c1..23c4fd10e505 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c | |||
@@ -224,10 +224,14 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter) | |||
224 | return -EIO; | 224 | return -EIO; |
225 | } | 225 | } |
226 | 226 | ||
227 | if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY) | 227 | if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY) { |
228 | adapter->flags |= QLCNIC_ESWITCH_ENABLED; | 228 | adapter->flags |= QLCNIC_ESWITCH_ENABLED; |
229 | else | 229 | if (adapter->drv_mac_learn) |
230 | adapter->rx_mac_learn = 1; | ||
231 | } else { | ||
230 | adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; | 232 | adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; |
233 | adapter->rx_mac_learn = 0; | ||
234 | } | ||
231 | 235 | ||
232 | ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER; | 236 | ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER; |
233 | ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO; | 237 | ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index a9a149b82375..6ca5e57da3da 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | |||
@@ -546,8 +546,11 @@ void __qlcnic_set_multi(struct net_device *netdev, u16 vlan) | |||
546 | !adapter->fdb_mac_learn) { | 546 | !adapter->fdb_mac_learn) { |
547 | qlcnic_alloc_lb_filters_mem(adapter); | 547 | qlcnic_alloc_lb_filters_mem(adapter); |
548 | adapter->drv_mac_learn = 1; | 548 | adapter->drv_mac_learn = 1; |
549 | if (adapter->flags & QLCNIC_ESWITCH_ENABLED) | ||
550 | adapter->rx_mac_learn = 1; | ||
549 | } else { | 551 | } else { |
550 | adapter->drv_mac_learn = 0; | 552 | adapter->drv_mac_learn = 0; |
553 | adapter->rx_mac_learn = 0; | ||
551 | } | 554 | } |
552 | 555 | ||
553 | qlcnic_nic_set_promisc(adapter, mode); | 556 | qlcnic_nic_set_promisc(adapter, mode); |
@@ -779,8 +782,8 @@ void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter) | |||
779 | "Could not send interrupt coalescing parameters\n"); | 782 | "Could not send interrupt coalescing parameters\n"); |
780 | } | 783 | } |
781 | 784 | ||
782 | #define QLCNIC_ENABLE_IPV4_LRO 1 | 785 | #define QLCNIC_ENABLE_IPV4_LRO BIT_0 |
783 | #define QLCNIC_ENABLE_IPV6_LRO 2 | 786 | #define QLCNIC_ENABLE_IPV6_LRO (BIT_1 | BIT_9) |
784 | 787 | ||
785 | int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int enable) | 788 | int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int enable) |
786 | { | 789 | { |
@@ -1530,19 +1533,34 @@ int qlcnic_82xx_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) | |||
1530 | return rv; | 1533 | return rv; |
1531 | } | 1534 | } |
1532 | 1535 | ||
1533 | int qlcnic_get_beacon_state(struct qlcnic_adapter *adapter, u8 *h_state) | 1536 | void qlcnic_82xx_get_beacon_state(struct qlcnic_adapter *adapter) |
1534 | { | 1537 | { |
1538 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
1535 | struct qlcnic_cmd_args cmd; | 1539 | struct qlcnic_cmd_args cmd; |
1536 | int err; | 1540 | u8 beacon_state; |
1541 | int err = 0; | ||
1537 | 1542 | ||
1538 | err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LED_STATUS); | 1543 | if (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_2_BEACON) { |
1539 | if (!err) { | 1544 | err = qlcnic_alloc_mbx_args(&cmd, adapter, |
1540 | err = qlcnic_issue_cmd(adapter, &cmd); | 1545 | QLCNIC_CMD_GET_LED_STATUS); |
1541 | if (!err) | 1546 | if (!err) { |
1542 | *h_state = cmd.rsp.arg[1]; | 1547 | err = qlcnic_issue_cmd(adapter, &cmd); |
1548 | if (err) { | ||
1549 | netdev_err(adapter->netdev, | ||
1550 | "Failed to get current beacon state, err=%d\n", | ||
1551 | err); | ||
1552 | } else { | ||
1553 | beacon_state = cmd.rsp.arg[1]; | ||
1554 | if (beacon_state == QLCNIC_BEACON_DISABLE) | ||
1555 | ahw->beacon_state = QLCNIC_BEACON_OFF; | ||
1556 | else if (beacon_state == QLCNIC_BEACON_EANBLE) | ||
1557 | ahw->beacon_state = QLCNIC_BEACON_ON; | ||
1558 | } | ||
1559 | } | ||
1560 | qlcnic_free_mbx_args(&cmd); | ||
1543 | } | 1561 | } |
1544 | qlcnic_free_mbx_args(&cmd); | 1562 | |
1545 | return err; | 1563 | return; |
1546 | } | 1564 | } |
1547 | 1565 | ||
1548 | void qlcnic_82xx_get_func_no(struct qlcnic_adapter *adapter) | 1566 | void qlcnic_82xx_get_func_no(struct qlcnic_adapter *adapter) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h index 13303e7d1ed7..0e739aed1bc6 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h | |||
@@ -169,6 +169,7 @@ int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int); | |||
169 | int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32); | 169 | int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32); |
170 | int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter, | 170 | int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter, |
171 | struct net_device *netdev); | 171 | struct net_device *netdev); |
172 | void qlcnic_82xx_get_beacon_state(struct qlcnic_adapter *); | ||
172 | void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, | 173 | void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, |
173 | u64 *uaddr, u16 vlan_id); | 174 | u64 *uaddr, u16 vlan_id); |
174 | void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter); | 175 | void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 6373f6022486..cbe4a30abd79 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | |||
@@ -156,9 +156,9 @@ static inline void qlcnic_83xx_disable_tx_intr(struct qlcnic_adapter *adapter, | |||
156 | writel(1, tx_ring->crb_intr_mask); | 156 | writel(1, tx_ring->crb_intr_mask); |
157 | } | 157 | } |
158 | 158 | ||
159 | static inline u8 qlcnic_mac_hash(u64 mac) | 159 | static inline u8 qlcnic_mac_hash(u64 mac, u16 vlan) |
160 | { | 160 | { |
161 | return (u8)((mac & 0xff) ^ ((mac >> 40) & 0xff)); | 161 | return (u8)((mac & 0xff) ^ ((mac >> 40) & 0xff) ^ (vlan & 0xff)); |
162 | } | 162 | } |
163 | 163 | ||
164 | static inline u32 qlcnic_get_ref_handle(struct qlcnic_adapter *adapter, | 164 | static inline u32 qlcnic_get_ref_handle(struct qlcnic_adapter *adapter, |
@@ -221,8 +221,11 @@ void qlcnic_add_lb_filter(struct qlcnic_adapter *adapter, struct sk_buff *skb, | |||
221 | u8 hindex, op; | 221 | u8 hindex, op; |
222 | int ret; | 222 | int ret; |
223 | 223 | ||
224 | if (!qlcnic_sriov_pf_check(adapter) || (vlan_id == 0xffff)) | ||
225 | vlan_id = 0; | ||
226 | |||
224 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); | 227 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); |
225 | hindex = qlcnic_mac_hash(src_addr) & | 228 | hindex = qlcnic_mac_hash(src_addr, vlan_id) & |
226 | (adapter->fhash.fbucket_size - 1); | 229 | (adapter->fhash.fbucket_size - 1); |
227 | 230 | ||
228 | if (loopback_pkt) { | 231 | if (loopback_pkt) { |
@@ -322,27 +325,43 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, | |||
322 | struct cmd_desc_type0 *first_desc, | 325 | struct cmd_desc_type0 *first_desc, |
323 | struct sk_buff *skb) | 326 | struct sk_buff *skb) |
324 | { | 327 | { |
328 | struct vlan_ethhdr *vh = (struct vlan_ethhdr *)(skb->data); | ||
329 | struct ethhdr *phdr = (struct ethhdr *)(skb->data); | ||
330 | struct net_device *netdev = adapter->netdev; | ||
331 | u16 protocol = ntohs(skb->protocol); | ||
325 | struct qlcnic_filter *fil, *tmp_fil; | 332 | struct qlcnic_filter *fil, *tmp_fil; |
326 | struct hlist_node *n; | ||
327 | struct hlist_head *head; | 333 | struct hlist_head *head; |
328 | struct net_device *netdev = adapter->netdev; | 334 | struct hlist_node *n; |
329 | struct ethhdr *phdr = (struct ethhdr *)(skb->data); | ||
330 | u64 src_addr = 0; | 335 | u64 src_addr = 0; |
331 | u16 vlan_id = 0; | 336 | u16 vlan_id = 0; |
332 | u8 hindex; | 337 | u8 hindex, hval; |
333 | 338 | ||
334 | if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) | 339 | if (!qlcnic_sriov_pf_check(adapter)) { |
335 | return; | 340 | if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) |
341 | return; | ||
342 | } else { | ||
343 | if (protocol == ETH_P_8021Q) { | ||
344 | vh = (struct vlan_ethhdr *)skb->data; | ||
345 | vlan_id = ntohs(vh->h_vlan_TCI); | ||
346 | } else if (vlan_tx_tag_present(skb)) { | ||
347 | vlan_id = vlan_tx_tag_get(skb); | ||
348 | } | ||
349 | |||
350 | if (ether_addr_equal(phdr->h_source, adapter->mac_addr) && | ||
351 | !vlan_id) | ||
352 | return; | ||
353 | } | ||
336 | 354 | ||
337 | if (adapter->fhash.fnum >= adapter->fhash.fmax) { | 355 | if (adapter->fhash.fnum >= adapter->fhash.fmax) { |
338 | adapter->stats.mac_filter_limit_overrun++; | 356 | adapter->stats.mac_filter_limit_overrun++; |
339 | netdev_info(netdev, "Can not add more than %d mac addresses\n", | 357 | netdev_info(netdev, "Can not add more than %d mac-vlan filters, configured %d\n", |
340 | adapter->fhash.fmax); | 358 | adapter->fhash.fmax, adapter->fhash.fnum); |
341 | return; | 359 | return; |
342 | } | 360 | } |
343 | 361 | ||
344 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); | 362 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); |
345 | hindex = qlcnic_mac_hash(src_addr) & (adapter->fhash.fbucket_size - 1); | 363 | hval = qlcnic_mac_hash(src_addr, vlan_id); |
364 | hindex = hval & (adapter->fhash.fbucket_size - 1); | ||
346 | head = &(adapter->fhash.fhead[hindex]); | 365 | head = &(adapter->fhash.fhead[hindex]); |
347 | 366 | ||
348 | hlist_for_each_entry_safe(tmp_fil, n, head, fnode) { | 367 | hlist_for_each_entry_safe(tmp_fil, n, head, fnode) { |
@@ -1599,7 +1618,8 @@ qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, | |||
1599 | struct sk_buff *skb; | 1618 | struct sk_buff *skb; |
1600 | struct qlcnic_host_rds_ring *rds_ring; | 1619 | struct qlcnic_host_rds_ring *rds_ring; |
1601 | int index, length, cksum, is_lb_pkt; | 1620 | int index, length, cksum, is_lb_pkt; |
1602 | u16 vid = 0xffff, t_vid; | 1621 | u16 vid = 0xffff; |
1622 | int err; | ||
1603 | 1623 | ||
1604 | if (unlikely(ring >= adapter->max_rds_rings)) | 1624 | if (unlikely(ring >= adapter->max_rds_rings)) |
1605 | return NULL; | 1625 | return NULL; |
@@ -1617,19 +1637,19 @@ qlcnic_83xx_process_rcv(struct qlcnic_adapter *adapter, | |||
1617 | if (!skb) | 1637 | if (!skb) |
1618 | return buffer; | 1638 | return buffer; |
1619 | 1639 | ||
1620 | if (adapter->drv_mac_learn && | ||
1621 | (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | ||
1622 | t_vid = 0; | ||
1623 | is_lb_pkt = qlcnic_83xx_is_lb_pkt(sts_data[1], 0); | ||
1624 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid); | ||
1625 | } | ||
1626 | |||
1627 | if (length > rds_ring->skb_size) | 1640 | if (length > rds_ring->skb_size) |
1628 | skb_put(skb, rds_ring->skb_size); | 1641 | skb_put(skb, rds_ring->skb_size); |
1629 | else | 1642 | else |
1630 | skb_put(skb, length); | 1643 | skb_put(skb, length); |
1631 | 1644 | ||
1632 | if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) { | 1645 | err = qlcnic_check_rx_tagging(adapter, skb, &vid); |
1646 | |||
1647 | if (adapter->rx_mac_learn) { | ||
1648 | is_lb_pkt = qlcnic_83xx_is_lb_pkt(sts_data[1], 0); | ||
1649 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, vid); | ||
1650 | } | ||
1651 | |||
1652 | if (unlikely(err)) { | ||
1633 | adapter->stats.rxdropped++; | 1653 | adapter->stats.rxdropped++; |
1634 | dev_kfree_skb(skb); | 1654 | dev_kfree_skb(skb); |
1635 | return buffer; | 1655 | return buffer; |
@@ -1664,7 +1684,8 @@ qlcnic_83xx_process_lro(struct qlcnic_adapter *adapter, | |||
1664 | int l2_hdr_offset, l4_hdr_offset; | 1684 | int l2_hdr_offset, l4_hdr_offset; |
1665 | int index, is_lb_pkt; | 1685 | int index, is_lb_pkt; |
1666 | u16 lro_length, length, data_offset, gso_size; | 1686 | u16 lro_length, length, data_offset, gso_size; |
1667 | u16 vid = 0xffff, t_vid; | 1687 | u16 vid = 0xffff; |
1688 | int err; | ||
1668 | 1689 | ||
1669 | if (unlikely(ring > adapter->max_rds_rings)) | 1690 | if (unlikely(ring > adapter->max_rds_rings)) |
1670 | return NULL; | 1691 | return NULL; |
@@ -1686,12 +1707,6 @@ qlcnic_83xx_process_lro(struct qlcnic_adapter *adapter, | |||
1686 | if (!skb) | 1707 | if (!skb) |
1687 | return buffer; | 1708 | return buffer; |
1688 | 1709 | ||
1689 | if (adapter->drv_mac_learn && | ||
1690 | (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | ||
1691 | t_vid = 0; | ||
1692 | is_lb_pkt = qlcnic_83xx_is_lb_pkt(sts_data[1], 1); | ||
1693 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid); | ||
1694 | } | ||
1695 | if (qlcnic_83xx_is_tstamp(sts_data[1])) | 1710 | if (qlcnic_83xx_is_tstamp(sts_data[1])) |
1696 | data_offset = l4_hdr_offset + QLCNIC_TCP_TS_HDR_SIZE; | 1711 | data_offset = l4_hdr_offset + QLCNIC_TCP_TS_HDR_SIZE; |
1697 | else | 1712 | else |
@@ -1700,7 +1715,14 @@ qlcnic_83xx_process_lro(struct qlcnic_adapter *adapter, | |||
1700 | skb_put(skb, lro_length + data_offset); | 1715 | skb_put(skb, lro_length + data_offset); |
1701 | skb_pull(skb, l2_hdr_offset); | 1716 | skb_pull(skb, l2_hdr_offset); |
1702 | 1717 | ||
1703 | if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) { | 1718 | err = qlcnic_check_rx_tagging(adapter, skb, &vid); |
1719 | |||
1720 | if (adapter->rx_mac_learn) { | ||
1721 | is_lb_pkt = qlcnic_83xx_is_lb_pkt(sts_data[1], 1); | ||
1722 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, vid); | ||
1723 | } | ||
1724 | |||
1725 | if (unlikely(err)) { | ||
1704 | adapter->stats.rxdropped++; | 1726 | adapter->stats.rxdropped++; |
1705 | dev_kfree_skb(skb); | 1727 | dev_kfree_skb(skb); |
1706 | return buffer; | 1728 | return buffer; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index eeec83a0e664..a57dfe4ad40e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -546,6 +546,7 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = { | |||
546 | .io_error_detected = qlcnic_82xx_io_error_detected, | 546 | .io_error_detected = qlcnic_82xx_io_error_detected, |
547 | .io_slot_reset = qlcnic_82xx_io_slot_reset, | 547 | .io_slot_reset = qlcnic_82xx_io_slot_reset, |
548 | .io_resume = qlcnic_82xx_io_resume, | 548 | .io_resume = qlcnic_82xx_io_resume, |
549 | .get_beacon_state = qlcnic_82xx_get_beacon_state, | ||
549 | }; | 550 | }; |
550 | 551 | ||
551 | static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter) | 552 | static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index bf8fca7d874f..f998fdcd7551 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | |||
@@ -277,9 +277,7 @@ static void qlcnic_sriov_vf_cleanup(struct qlcnic_adapter *adapter) | |||
277 | 277 | ||
278 | void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) | 278 | void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) |
279 | { | 279 | { |
280 | struct qlcnic_sriov *sriov = adapter->ahw->sriov; | 280 | if (!test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state)) |
281 | |||
282 | if (!sriov) | ||
283 | return; | 281 | return; |
284 | 282 | ||
285 | qlcnic_sriov_free_vlans(adapter); | 283 | qlcnic_sriov_free_vlans(adapter); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index d14d9a139eef..09acf15c3a56 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | |||
@@ -9,9 +9,14 @@ | |||
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 8 | 12 | #define QLCNIC_SRIOV_VF_MAX_MAC 7 |
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 | #define QLC_MAC_OPCODE_MASK 0x7 | ||
16 | #define QLC_MAC_STAR_ADD 6 | ||
17 | #define QLC_MAC_STAR_DEL 7 | ||
18 | #define QLC_VF_FLOOD_BIT BIT_16 | ||
19 | #define QLC_FLOOD_MODE 0x5 | ||
15 | 20 | ||
16 | static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8); | 21 | static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8); |
17 | 22 | ||
@@ -344,6 +349,28 @@ static int qlcnic_sriov_pf_cfg_vlan_filtering(struct qlcnic_adapter *adapter, | |||
344 | return err; | 349 | return err; |
345 | } | 350 | } |
346 | 351 | ||
352 | /* On configuring VF flood bit, PFD will receive traffic from all VFs */ | ||
353 | static int qlcnic_sriov_pf_cfg_flood(struct qlcnic_adapter *adapter) | ||
354 | { | ||
355 | struct qlcnic_cmd_args cmd; | ||
356 | int err; | ||
357 | |||
358 | err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO); | ||
359 | if (err) | ||
360 | return err; | ||
361 | |||
362 | cmd.req.arg[1] = QLC_FLOOD_MODE | QLC_VF_FLOOD_BIT; | ||
363 | |||
364 | err = qlcnic_issue_cmd(adapter, &cmd); | ||
365 | if (err) | ||
366 | dev_err(&adapter->pdev->dev, | ||
367 | "Failed to configure VF Flood bit on PF, err=%d\n", | ||
368 | err); | ||
369 | |||
370 | qlcnic_free_mbx_args(&cmd); | ||
371 | return err; | ||
372 | } | ||
373 | |||
347 | static int qlcnic_sriov_pf_cfg_eswitch(struct qlcnic_adapter *adapter, | 374 | static int qlcnic_sriov_pf_cfg_eswitch(struct qlcnic_adapter *adapter, |
348 | u8 func, u8 enable) | 375 | u8 func, u8 enable) |
349 | { | 376 | { |
@@ -471,6 +498,12 @@ static int qlcnic_sriov_pf_init(struct qlcnic_adapter *adapter) | |||
471 | if (err) | 498 | if (err) |
472 | return err; | 499 | return err; |
473 | 500 | ||
501 | if (qlcnic_84xx_check(adapter)) { | ||
502 | err = qlcnic_sriov_pf_cfg_flood(adapter); | ||
503 | if (err) | ||
504 | goto disable_vlan_filtering; | ||
505 | } | ||
506 | |||
474 | err = qlcnic_sriov_pf_cfg_eswitch(adapter, func, 1); | 507 | err = qlcnic_sriov_pf_cfg_eswitch(adapter, func, 1); |
475 | if (err) | 508 | if (err) |
476 | goto disable_vlan_filtering; | 509 | goto disable_vlan_filtering; |
@@ -1173,6 +1206,13 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter, | |||
1173 | struct qlcnic_vport *vp = vf->vp; | 1206 | struct qlcnic_vport *vp = vf->vp; |
1174 | u8 op, new_op; | 1207 | u8 op, new_op; |
1175 | 1208 | ||
1209 | if (((cmd->req.arg[1] & QLC_MAC_OPCODE_MASK) == QLC_MAC_STAR_ADD) || | ||
1210 | ((cmd->req.arg[1] & QLC_MAC_OPCODE_MASK) == QLC_MAC_STAR_DEL)) { | ||
1211 | netdev_err(adapter->netdev, "MAC + any VLAN filter not allowed from VF %d\n", | ||
1212 | vf->pci_func); | ||
1213 | return -EINVAL; | ||
1214 | } | ||
1215 | |||
1176 | if (!(cmd->req.arg[1] & BIT_8)) | 1216 | if (!(cmd->req.arg[1] & BIT_8)) |
1177 | return -EINVAL; | 1217 | return -EINVAL; |
1178 | 1218 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index c9b704deae93..1c8552f682d6 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -126,6 +126,8 @@ static int qlcnic_83xx_store_beacon(struct qlcnic_adapter *adapter, | |||
126 | if (kstrtoul(buf, 2, &h_beacon)) | 126 | if (kstrtoul(buf, 2, &h_beacon)) |
127 | return -EINVAL; | 127 | return -EINVAL; |
128 | 128 | ||
129 | qlcnic_get_beacon_state(adapter); | ||
130 | |||
129 | if (ahw->beacon_state == h_beacon) | 131 | if (ahw->beacon_state == h_beacon) |
130 | return len; | 132 | return len; |
131 | 133 | ||
@@ -157,7 +159,7 @@ static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter, | |||
157 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 159 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
158 | int err, drv_sds_rings = adapter->drv_sds_rings; | 160 | int err, drv_sds_rings = adapter->drv_sds_rings; |
159 | u16 beacon; | 161 | u16 beacon; |
160 | u8 h_beacon_state, b_state, b_rate; | 162 | u8 b_state, b_rate; |
161 | 163 | ||
162 | if (len != sizeof(u16)) | 164 | if (len != sizeof(u16)) |
163 | return QL_STATUS_INVALID_PARAM; | 165 | return QL_STATUS_INVALID_PARAM; |
@@ -167,18 +169,7 @@ static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter, | |||
167 | if (err) | 169 | if (err) |
168 | return err; | 170 | return err; |
169 | 171 | ||
170 | if (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_2_BEACON) { | 172 | qlcnic_get_beacon_state(adapter); |
171 | err = qlcnic_get_beacon_state(adapter, &h_beacon_state); | ||
172 | if (err) { | ||
173 | netdev_err(adapter->netdev, | ||
174 | "Failed to get current beacon state\n"); | ||
175 | } else { | ||
176 | if (h_beacon_state == QLCNIC_BEACON_DISABLE) | ||
177 | ahw->beacon_state = 0; | ||
178 | else if (h_beacon_state == QLCNIC_BEACON_EANBLE) | ||
179 | ahw->beacon_state = 2; | ||
180 | } | ||
181 | } | ||
182 | 173 | ||
183 | if (ahw->beacon_state == b_state) | 174 | if (ahw->beacon_state == b_state) |
184 | return len; | 175 | return len; |