aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h15
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c35
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h3
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c1
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c8
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c40
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h1
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c80
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c1
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c42
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c17
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 *);
1640int qlcnic_reset_npar_config(struct qlcnic_adapter *); 1644int qlcnic_reset_npar_config(struct qlcnic_adapter *);
1641int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *); 1645int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *);
1642void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16); 1646void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16);
1643int qlcnic_get_beacon_state(struct qlcnic_adapter *, u8 *);
1644int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter); 1647int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
1645int qlcnic_read_mac_addr(struct qlcnic_adapter *); 1648int qlcnic_read_mac_addr(struct qlcnic_adapter *);
1646int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); 1649int 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
1772extern struct qlcnic_nic_template qlcnic_vf_ops; 1776extern 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
2000static inline void qlcnic_get_beacon_state(struct qlcnic_adapter *adapter)
2001{
2002 adapter->ahw->hw_ops->get_beacon_state(adapter);
2003}
2004
1996static inline void qlcnic_read_phys_port_id(struct qlcnic_adapter *adapter) 2005static 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
187static struct qlcnic_nic_template qlcnic_83xx_ops = { 187static 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
1391void 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
1391int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state, 1418int 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 *);
559void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); 561void qlcnic_83xx_napi_enable(struct qlcnic_adapter *);
560void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); 562void qlcnic_83xx_napi_disable(struct qlcnic_adapter *);
561int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32); 563int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32);
564void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *);
562void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); 565void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32);
563int qlcnic_ind_rd(struct qlcnic_adapter *, u32); 566int qlcnic_ind_rd(struct qlcnic_adapter *, u32);
564int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *); 567int 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
785int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int enable) 788int 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
1533int qlcnic_get_beacon_state(struct qlcnic_adapter *adapter, u8 *h_state) 1536void 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
1548void qlcnic_82xx_get_func_no(struct qlcnic_adapter *adapter) 1566void 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);
169int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32); 169int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32);
170int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter, 170int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter,
171 struct net_device *netdev); 171 struct net_device *netdev);
172void qlcnic_82xx_get_beacon_state(struct qlcnic_adapter *);
172void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, 173void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter,
173 u64 *uaddr, u16 vlan_id); 174 u64 *uaddr, u16 vlan_id);
174void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter); 175void 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
159static inline u8 qlcnic_mac_hash(u64 mac) 159static 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
164static inline u32 qlcnic_get_ref_handle(struct qlcnic_adapter *adapter, 164static 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
551static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter) 552static 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
278void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) 278void 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
16static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8); 21static 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 */
353static 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
347static int qlcnic_sriov_pf_cfg_eswitch(struct qlcnic_adapter *adapter, 374static 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;