aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorRajesh Borundia <rajesh.borundia@qlogic.com>2013-04-19 03:01:12 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-19 16:14:40 -0400
commit91b7282b613d4da65e8b4c87d521156cdc64c169 (patch)
tree1b412de7cd339ab96922cd9e427572bf123c8ff0 /drivers/net
parent4000e7a78d12d71e37fcd2366c73fcb02e97fffb (diff)
qlcnic: Support VLAN id config.
o Add support for VLAN id configuration per VF using iproute2 tool. o VLAN id's 1-4094 are treated as PVID by the PF and Guest VLAN tagging is not allowed by default. o PVID is disabled when the VLAN id is set to 0 o Guest VLAN tagging is allowed when the VLAN id is set to 4095. o Only one Guest VLAN id is supported. o VLAN id can be changed only when the VF driver is not loaded. Signed-off-by: Manish Chopra <manish.chopra@qlogic.com> Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com> Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h17
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c5
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c18
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c8
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c41
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h18
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c171
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c243
8 files changed, 492 insertions, 29 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 2b13bd0495ea..7dc7e02d00aa 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -979,7 +979,8 @@ struct qlcnic_adapter {
979 u8 reset_ctx_cnt; 979 u8 reset_ctx_cnt;
980 980
981 u16 is_up; 981 u16 is_up;
982 u16 pvid; 982 u16 rx_pvid;
983 u16 tx_pvid;
983 984
984 u32 irq; 985 u32 irq;
985 u32 heartbeat; 986 u32 heartbeat;
@@ -1445,10 +1446,10 @@ void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
1445 struct qlcnic_host_rds_ring *rds_ring, u8 ring_id); 1446 struct qlcnic_host_rds_ring *rds_ring, u8 ring_id);
1446int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max); 1447int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max);
1447void qlcnic_set_multi(struct net_device *netdev); 1448void qlcnic_set_multi(struct net_device *netdev);
1448void __qlcnic_set_multi(struct net_device *netdev); 1449void __qlcnic_set_multi(struct net_device *, u16);
1449int qlcnic_nic_add_mac(struct qlcnic_adapter *, const u8 *); 1450int qlcnic_nic_add_mac(struct qlcnic_adapter *, const u8 *, u16);
1450int qlcnic_nic_del_mac(struct qlcnic_adapter *, const u8 *); 1451int qlcnic_nic_del_mac(struct qlcnic_adapter *, const u8 *);
1451void qlcnic_free_mac_list(struct qlcnic_adapter *adapter); 1452void qlcnic_82xx_free_mac_list(struct qlcnic_adapter *adapter);
1452 1453
1453int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu); 1454int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu);
1454int qlcnic_fw_cmd_set_drv_version(struct qlcnic_adapter *); 1455int qlcnic_fw_cmd_set_drv_version(struct qlcnic_adapter *);
@@ -1530,7 +1531,7 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
1530int qlcnic_read_mac_addr(struct qlcnic_adapter *); 1531int qlcnic_read_mac_addr(struct qlcnic_adapter *);
1531int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); 1532int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
1532void qlcnic_sriov_vf_schedule_multi(struct net_device *); 1533void qlcnic_sriov_vf_schedule_multi(struct net_device *);
1533void qlcnic_vf_add_mc_list(struct net_device *); 1534void qlcnic_vf_add_mc_list(struct net_device *, u16);
1534 1535
1535/* 1536/*
1536 * QLOGIC Board information 1537 * QLOGIC Board information
@@ -1606,6 +1607,7 @@ struct qlcnic_hardware_ops {
1606 int (*config_promisc_mode) (struct qlcnic_adapter *, u32); 1607 int (*config_promisc_mode) (struct qlcnic_adapter *, u32);
1607 void (*change_l2_filter) (struct qlcnic_adapter *, u64 *, u16); 1608 void (*change_l2_filter) (struct qlcnic_adapter *, u64 *, u16);
1608 int (*get_board_info) (struct qlcnic_adapter *); 1609 int (*get_board_info) (struct qlcnic_adapter *);
1610 void (*free_mac_list) (struct qlcnic_adapter *);
1609}; 1611};
1610 1612
1611extern struct qlcnic_nic_template qlcnic_vf_ops; 1613extern struct qlcnic_nic_template qlcnic_vf_ops;
@@ -1815,6 +1817,11 @@ static inline int qlcnic_get_board_info(struct qlcnic_adapter *adapter)
1815 return adapter->ahw->hw_ops->get_board_info(adapter); 1817 return adapter->ahw->hw_ops->get_board_info(adapter);
1816} 1818}
1817 1819
1820static inline void qlcnic_free_mac_list(struct qlcnic_adapter *adapter)
1821{
1822 return adapter->ahw->hw_ops->free_mac_list(adapter);
1823}
1824
1818static inline void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter, 1825static inline void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter,
1819 u32 key) 1826 u32 key)
1820{ 1827{
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 4035e82167a8..3a4b5723b94e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -172,6 +172,7 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
172 .config_promisc_mode = qlcnic_83xx_nic_set_promisc, 172 .config_promisc_mode = qlcnic_83xx_nic_set_promisc,
173 .change_l2_filter = qlcnic_83xx_change_l2_filter, 173 .change_l2_filter = qlcnic_83xx_change_l2_filter,
174 .get_board_info = qlcnic_83xx_get_port_info, 174 .get_board_info = qlcnic_83xx_get_port_info,
175 .free_mac_list = qlcnic_82xx_free_mac_list,
175}; 176};
176 177
177static struct qlcnic_nic_template qlcnic_83xx_ops = { 178static struct qlcnic_nic_template qlcnic_83xx_ops = {
@@ -1797,6 +1798,10 @@ int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
1797 if (err) 1798 if (err)
1798 return err; 1799 return err;
1799 1800
1801 if (vlan_id)
1802 op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
1803 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL;
1804
1800 cmd.req.arg[1] = op | (1 << 8); 1805 cmd.req.arg[1] = op | (1 << 8);
1801 qlcnic_83xx_set_interface_id_macaddr(adapter, &temp); 1806 qlcnic_83xx_set_interface_id_macaddr(adapter, &temp);
1802 cmd.req.arg[1] |= temp; 1807 cmd.req.arg[1] |= temp;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index c3cbfaea97c3..6a6512ba9f38 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -468,7 +468,7 @@ int qlcnic_nic_del_mac(struct qlcnic_adapter *adapter, const u8 *addr)
468 return err; 468 return err;
469} 469}
470 470
471int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr) 471int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan)
472{ 472{
473 struct list_head *head; 473 struct list_head *head;
474 struct qlcnic_mac_list_s *cur; 474 struct qlcnic_mac_list_s *cur;
@@ -487,7 +487,7 @@ int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr)
487 memcpy(cur->mac_addr, addr, ETH_ALEN); 487 memcpy(cur->mac_addr, addr, ETH_ALEN);
488 488
489 if (qlcnic_sre_macaddr_change(adapter, 489 if (qlcnic_sre_macaddr_change(adapter,
490 cur->mac_addr, 0, QLCNIC_MAC_ADD)) { 490 cur->mac_addr, vlan, QLCNIC_MAC_ADD)) {
491 kfree(cur); 491 kfree(cur);
492 return -EIO; 492 return -EIO;
493 } 493 }
@@ -496,7 +496,7 @@ int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr)
496 return 0; 496 return 0;
497} 497}
498 498
499void __qlcnic_set_multi(struct net_device *netdev) 499void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
500{ 500{
501 struct qlcnic_adapter *adapter = netdev_priv(netdev); 501 struct qlcnic_adapter *adapter = netdev_priv(netdev);
502 struct netdev_hw_addr *ha; 502 struct netdev_hw_addr *ha;
@@ -509,8 +509,8 @@ void __qlcnic_set_multi(struct net_device *netdev)
509 return; 509 return;
510 510
511 if (!qlcnic_sriov_vf_check(adapter)) 511 if (!qlcnic_sriov_vf_check(adapter))
512 qlcnic_nic_add_mac(adapter, adapter->mac_addr); 512 qlcnic_nic_add_mac(adapter, adapter->mac_addr, vlan);
513 qlcnic_nic_add_mac(adapter, bcast_addr); 513 qlcnic_nic_add_mac(adapter, bcast_addr, vlan);
514 514
515 if (netdev->flags & IFF_PROMISC) { 515 if (netdev->flags & IFF_PROMISC) {
516 if (!(adapter->flags & QLCNIC_PROMISC_DISABLED)) 516 if (!(adapter->flags & QLCNIC_PROMISC_DISABLED))
@@ -526,12 +526,12 @@ void __qlcnic_set_multi(struct net_device *netdev)
526 526
527 if (!netdev_mc_empty(netdev) && !qlcnic_sriov_vf_check(adapter)) { 527 if (!netdev_mc_empty(netdev) && !qlcnic_sriov_vf_check(adapter)) {
528 netdev_for_each_mc_addr(ha, netdev) { 528 netdev_for_each_mc_addr(ha, netdev) {
529 qlcnic_nic_add_mac(adapter, ha->addr); 529 qlcnic_nic_add_mac(adapter, ha->addr, vlan);
530 } 530 }
531 } 531 }
532 532
533 if (qlcnic_sriov_vf_check(adapter)) 533 if (qlcnic_sriov_vf_check(adapter))
534 qlcnic_vf_add_mc_list(netdev); 534 qlcnic_vf_add_mc_list(netdev, vlan);
535 535
536send_fw_cmd: 536send_fw_cmd:
537 if (!qlcnic_sriov_vf_check(adapter)) { 537 if (!qlcnic_sriov_vf_check(adapter)) {
@@ -570,7 +570,7 @@ void qlcnic_set_multi(struct net_device *netdev)
570 qlcnic_sriov_vf_schedule_multi(adapter->netdev); 570 qlcnic_sriov_vf_schedule_multi(adapter->netdev);
571 return; 571 return;
572 } 572 }
573 __qlcnic_set_multi(netdev); 573 __qlcnic_set_multi(netdev, 0);
574} 574}
575 575
576int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) 576int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
@@ -592,7 +592,7 @@ int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
592 (struct cmd_desc_type0 *)&req, 1); 592 (struct cmd_desc_type0 *)&req, 1);
593} 593}
594 594
595void qlcnic_free_mac_list(struct qlcnic_adapter *adapter) 595void qlcnic_82xx_free_mac_list(struct qlcnic_adapter *adapter)
596{ 596{
597 struct qlcnic_mac_list_s *cur; 597 struct qlcnic_mac_list_s *cur;
598 struct list_head *head = &adapter->mac_list; 598 struct list_head *head = &adapter->mac_list;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index f3fe31e8f6bd..356859b9f21c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -344,14 +344,14 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
344 flags = FLAGS_VLAN_OOB; 344 flags = FLAGS_VLAN_OOB;
345 vlan_tci = vlan_tx_tag_get(skb); 345 vlan_tci = vlan_tx_tag_get(skb);
346 } 346 }
347 if (unlikely(adapter->pvid)) { 347 if (unlikely(adapter->tx_pvid)) {
348 if (vlan_tci && !(adapter->flags & QLCNIC_TAGGING_ENABLED)) 348 if (vlan_tci && !(adapter->flags & QLCNIC_TAGGING_ENABLED))
349 return -EIO; 349 return -EIO;
350 if (vlan_tci && (adapter->flags & QLCNIC_TAGGING_ENABLED)) 350 if (vlan_tci && (adapter->flags & QLCNIC_TAGGING_ENABLED))
351 goto set_flags; 351 goto set_flags;
352 352
353 flags = FLAGS_VLAN_OOB; 353 flags = FLAGS_VLAN_OOB;
354 vlan_tci = adapter->pvid; 354 vlan_tci = adapter->tx_pvid;
355 } 355 }
356set_flags: 356set_flags:
357 qlcnic_set_tx_vlan_tci(first_desc, vlan_tci); 357 qlcnic_set_tx_vlan_tci(first_desc, vlan_tci);
@@ -980,10 +980,10 @@ static inline int qlcnic_check_rx_tagging(struct qlcnic_adapter *adapter,
980 memmove(skb->data + VLAN_HLEN, eth_hdr, ETH_ALEN * 2); 980 memmove(skb->data + VLAN_HLEN, eth_hdr, ETH_ALEN * 2);
981 skb_pull(skb, VLAN_HLEN); 981 skb_pull(skb, VLAN_HLEN);
982 } 982 }
983 if (!adapter->pvid) 983 if (!adapter->rx_pvid)
984 return 0; 984 return 0;
985 985
986 if (*vlan_tag == adapter->pvid) { 986 if (*vlan_tag == adapter->rx_pvid) {
987 /* Outer vlan tag. Packet should follow non-vlan path */ 987 /* Outer vlan tag. Packet should follow non-vlan path */
988 *vlan_tag = 0xffff; 988 *vlan_tag = 0xffff;
989 return 0; 989 return 0;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index b3ab7a3386e3..9890aa8abdcd 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -290,7 +290,7 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
290 return err; 290 return err;
291 291
292 if (is_unicast_ether_addr(addr)) 292 if (is_unicast_ether_addr(addr))
293 err = qlcnic_nic_add_mac(adapter, addr); 293 err = qlcnic_nic_add_mac(adapter, addr, 0);
294 else if (is_multicast_ether_addr(addr)) 294 else if (is_multicast_ether_addr(addr))
295 err = dev_mc_add_excl(netdev, addr); 295 err = dev_mc_add_excl(netdev, addr);
296 else 296 else
@@ -345,6 +345,7 @@ static const struct net_device_ops qlcnic_netdev_ops = {
345 .ndo_set_vf_mac = qlcnic_sriov_set_vf_mac, 345 .ndo_set_vf_mac = qlcnic_sriov_set_vf_mac,
346 .ndo_set_vf_tx_rate = qlcnic_sriov_set_vf_tx_rate, 346 .ndo_set_vf_tx_rate = qlcnic_sriov_set_vf_tx_rate,
347 .ndo_get_vf_config = qlcnic_sriov_get_vf_config, 347 .ndo_get_vf_config = qlcnic_sriov_get_vf_config,
348 .ndo_set_vf_vlan = qlcnic_sriov_set_vf_vlan,
348#endif 349#endif
349}; 350};
350 351
@@ -404,6 +405,7 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = {
404 .config_promisc_mode = qlcnic_82xx_nic_set_promisc, 405 .config_promisc_mode = qlcnic_82xx_nic_set_promisc,
405 .change_l2_filter = qlcnic_82xx_change_filter, 406 .change_l2_filter = qlcnic_82xx_change_filter,
406 .get_board_info = qlcnic_82xx_get_board_info, 407 .get_board_info = qlcnic_82xx_get_board_info,
408 .free_mac_list = qlcnic_82xx_free_mac_list,
407}; 409};
408 410
409int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) 411int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
@@ -900,16 +902,31 @@ void qlcnic_set_vlan_config(struct qlcnic_adapter *adapter,
900 else 902 else
901 adapter->flags |= QLCNIC_TAGGING_ENABLED; 903 adapter->flags |= QLCNIC_TAGGING_ENABLED;
902 904
903 if (esw_cfg->vlan_id) 905 if (esw_cfg->vlan_id) {
904 adapter->pvid = esw_cfg->vlan_id; 906 adapter->rx_pvid = esw_cfg->vlan_id;
905 else 907 adapter->tx_pvid = esw_cfg->vlan_id;
906 adapter->pvid = 0; 908 } else {
909 adapter->rx_pvid = 0;
910 adapter->tx_pvid = 0;
911 }
907} 912}
908 913
909static int 914static int
910qlcnic_vlan_rx_add(struct net_device *netdev, __be16 proto, u16 vid) 915qlcnic_vlan_rx_add(struct net_device *netdev, __be16 proto, u16 vid)
911{ 916{
912 struct qlcnic_adapter *adapter = netdev_priv(netdev); 917 struct qlcnic_adapter *adapter = netdev_priv(netdev);
918 int err;
919
920 if (qlcnic_sriov_vf_check(adapter)) {
921 err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 1);
922 if (err) {
923 netdev_err(netdev,
924 "Cannot add VLAN filter for VLAN id %d, err=%d",
925 vid, err);
926 return err;
927 }
928 }
929
913 set_bit(vid, adapter->vlans); 930 set_bit(vid, adapter->vlans);
914 return 0; 931 return 0;
915} 932}
@@ -918,6 +935,17 @@ static int
918qlcnic_vlan_rx_del(struct net_device *netdev, __be16 proto, u16 vid) 935qlcnic_vlan_rx_del(struct net_device *netdev, __be16 proto, u16 vid)
919{ 936{
920 struct qlcnic_adapter *adapter = netdev_priv(netdev); 937 struct qlcnic_adapter *adapter = netdev_priv(netdev);
938 int err;
939
940 if (qlcnic_sriov_vf_check(adapter)) {
941 err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 0);
942 if (err) {
943 netdev_err(netdev,
944 "Cannot delete VLAN filter for VLAN id %d, err=%d",
945 vid, err);
946 return err;
947 }
948 }
921 949
922 qlcnic_restore_indev_addr(netdev, NETDEV_DOWN); 950 qlcnic_restore_indev_addr(netdev, NETDEV_DOWN);
923 clear_bit(vid, adapter->vlans); 951 clear_bit(vid, adapter->vlans);
@@ -1736,6 +1764,9 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
1736 if (qlcnic_vlan_tx_check(adapter)) 1764 if (qlcnic_vlan_tx_check(adapter))
1737 netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX); 1765 netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX);
1738 1766
1767 if (qlcnic_sriov_vf_check(adapter))
1768 netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
1769
1739 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) 1770 if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
1740 netdev->features |= NETIF_F_LRO; 1771 netdev->features |= NETIF_F_LRO;
1741 1772
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
index 5f73d42d6689..d85fbb57c25b 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
@@ -48,6 +48,8 @@ struct qlcnic_bc_hdr {
48enum qlcnic_bc_commands { 48enum qlcnic_bc_commands {
49 QLCNIC_BC_CMD_CHANNEL_INIT = 0x0, 49 QLCNIC_BC_CMD_CHANNEL_INIT = 0x0,
50 QLCNIC_BC_CMD_CHANNEL_TERM = 0x1, 50 QLCNIC_BC_CMD_CHANNEL_TERM = 0x1,
51 QLCNIC_BC_CMD_GET_ACL = 0x2,
52 QLCNIC_BC_CMD_CFG_GUEST_VLAN = 0x3,
51}; 53};
52 54
53#define QLC_BC_CMD 1 55#define QLC_BC_CMD 1
@@ -95,6 +97,12 @@ enum qlcnic_vf_state {
95 QLC_BC_VF_SOFT_FLR, 97 QLC_BC_VF_SOFT_FLR,
96}; 98};
97 99
100enum qlcnic_vlan_mode {
101 QLC_NO_VLAN_MODE = 0,
102 QLC_PVID_MODE,
103 QLC_GUEST_VLAN_MODE,
104};
105
98struct qlcnic_resources { 106struct qlcnic_resources {
99 u16 num_tx_mac_filters; 107 u16 num_tx_mac_filters;
100 u16 num_rx_ucast_mac_filters; 108 u16 num_rx_ucast_mac_filters;
@@ -118,6 +126,9 @@ struct qlcnic_vport {
118 u16 handle; 126 u16 handle;
119 u16 max_tx_bw; 127 u16 max_tx_bw;
120 u16 min_tx_bw; 128 u16 min_tx_bw;
129 u8 vlan_mode;
130 u16 vlan;
131 u8 qos;
121 u8 mac[6]; 132 u8 mac[6];
122}; 133};
123 134
@@ -156,6 +167,11 @@ struct qlcnic_back_channel {
156struct qlcnic_sriov { 167struct qlcnic_sriov {
157 u16 vp_handle; 168 u16 vp_handle;
158 u8 num_vfs; 169 u8 num_vfs;
170 u8 any_vlan;
171 u8 vlan_mode;
172 u16 num_allowed_vlans;
173 u16 *allowed_vlans;
174 u16 vlan;
159 struct qlcnic_resources ff_max; 175 struct qlcnic_resources ff_max;
160 struct qlcnic_back_channel bc; 176 struct qlcnic_back_channel bc;
161 struct qlcnic_vf_info *vf_info; 177 struct qlcnic_vf_info *vf_info;
@@ -177,6 +193,7 @@ int __qlcnic_sriov_add_act_list(struct qlcnic_sriov *, struct qlcnic_vf_info *,
177 struct qlcnic_bc_trans *); 193 struct qlcnic_bc_trans *);
178int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *, 194int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *,
179 struct qlcnic_info *, u16); 195 struct qlcnic_info *, u16);
196int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8);
180 197
181static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter) 198static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter)
182{ 199{
@@ -207,6 +224,7 @@ int qlcnic_sriov_set_vf_mac(struct net_device *, int, u8 *);
207int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int); 224int qlcnic_sriov_set_vf_tx_rate(struct net_device *, int, int);
208int qlcnic_sriov_get_vf_config(struct net_device *, int , 225int qlcnic_sriov_get_vf_config(struct net_device *, int ,
209 struct ifla_vf_info *); 226 struct ifla_vf_info *);
227int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8);
210#else 228#else
211static inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {} 229static inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {}
212static inline void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter) {} 230static inline void qlcnic_sriov_pf_cleanup(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 b00cba96a82a..d5b626dad16b 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -28,6 +28,8 @@
28#define QLC_83XX_VF_RESET_FAIL_THRESH 8 28#define QLC_83XX_VF_RESET_FAIL_THRESH 8
29#define QLC_BC_CMD_MAX_RETRY_CNT 5 29#define QLC_BC_CMD_MAX_RETRY_CNT 5
30 30
31static void qlcnic_sriov_vf_free_mac_list(struct qlcnic_adapter *);
32static int qlcnic_sriov_alloc_bc_mbx_args(struct qlcnic_cmd_args *, u32);
31static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *); 33static void qlcnic_sriov_vf_poll_dev_state(struct work_struct *);
32static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *); 34static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *);
33static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *); 35static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *);
@@ -64,6 +66,7 @@ static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = {
64 .config_promisc_mode = qlcnic_83xx_nic_set_promisc, 66 .config_promisc_mode = qlcnic_83xx_nic_set_promisc,
65 .change_l2_filter = qlcnic_83xx_change_l2_filter, 67 .change_l2_filter = qlcnic_83xx_change_l2_filter,
66 .get_board_info = qlcnic_83xx_get_port_info, 68 .get_board_info = qlcnic_83xx_get_port_info,
69 .free_mac_list = qlcnic_sriov_vf_free_mac_list,
67}; 70};
68 71
69static struct qlcnic_nic_template qlcnic_sriov_vf_ops = { 72static struct qlcnic_nic_template qlcnic_sriov_vf_ops = {
@@ -79,6 +82,8 @@ static struct qlcnic_nic_template qlcnic_sriov_vf_ops = {
79static const struct qlcnic_mailbox_metadata qlcnic_sriov_bc_mbx_tbl[] = { 82static const struct qlcnic_mailbox_metadata qlcnic_sriov_bc_mbx_tbl[] = {
80 {QLCNIC_BC_CMD_CHANNEL_INIT, 2, 2}, 83 {QLCNIC_BC_CMD_CHANNEL_INIT, 2, 2},
81 {QLCNIC_BC_CMD_CHANNEL_TERM, 2, 2}, 84 {QLCNIC_BC_CMD_CHANNEL_TERM, 2, 2},
85 {QLCNIC_BC_CMD_GET_ACL, 3, 14},
86 {QLCNIC_BC_CMD_CFG_GUEST_VLAN, 2, 2},
82}; 87};
83 88
84static inline bool qlcnic_sriov_bc_msg_check(u32 val) 89static inline bool qlcnic_sriov_bc_msg_check(u32 val)
@@ -446,6 +451,71 @@ int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *adapter,
446 return err; 451 return err;
447} 452}
448 453
454static int qlcnic_sriov_set_pvid_mode(struct qlcnic_adapter *adapter,
455 struct qlcnic_cmd_args *cmd)
456{
457 adapter->rx_pvid = (cmd->rsp.arg[1] >> 16) & 0xffff;
458 adapter->flags &= ~QLCNIC_TAGGING_ENABLED;
459 return 0;
460}
461
462static int qlcnic_sriov_set_guest_vlan_mode(struct qlcnic_adapter *adapter,
463 struct qlcnic_cmd_args *cmd)
464{
465 struct qlcnic_sriov *sriov = adapter->ahw->sriov;
466 int i, num_vlans;
467 u16 *vlans;
468
469 if (sriov->allowed_vlans)
470 return 0;
471
472 sriov->any_vlan = cmd->rsp.arg[2] & 0xf;
473 if (!sriov->any_vlan)
474 return 0;
475
476 sriov->num_allowed_vlans = cmd->rsp.arg[2] >> 16;
477 num_vlans = sriov->num_allowed_vlans;
478 sriov->allowed_vlans = kzalloc(sizeof(u16) * num_vlans, GFP_KERNEL);
479 if (!sriov->allowed_vlans)
480 return -ENOMEM;
481
482 vlans = (u16 *)&cmd->rsp.arg[3];
483 for (i = 0; i < num_vlans; i++)
484 sriov->allowed_vlans[i] = vlans[i];
485
486 return 0;
487}
488
489static int qlcnic_sriov_get_vf_acl(struct qlcnic_adapter *adapter)
490{
491 struct qlcnic_sriov *sriov = adapter->ahw->sriov;
492 struct qlcnic_cmd_args cmd;
493 int ret;
494
495 ret = qlcnic_sriov_alloc_bc_mbx_args(&cmd, QLCNIC_BC_CMD_GET_ACL);
496 if (ret)
497 return ret;
498
499 ret = qlcnic_issue_cmd(adapter, &cmd);
500 if (ret) {
501 dev_err(&adapter->pdev->dev, "Failed to get ACL, err=%d\n",
502 ret);
503 } else {
504 sriov->vlan_mode = cmd.rsp.arg[1] & 0x3;
505 switch (sriov->vlan_mode) {
506 case QLC_GUEST_VLAN_MODE:
507 ret = qlcnic_sriov_set_guest_vlan_mode(adapter, &cmd);
508 break;
509 case QLC_PVID_MODE:
510 ret = qlcnic_sriov_set_pvid_mode(adapter, &cmd);
511 break;
512 }
513 }
514
515 qlcnic_free_mbx_args(&cmd);
516 return ret;
517}
518
449static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter) 519static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter)
450{ 520{
451 struct qlcnic_info nic_info; 521 struct qlcnic_info nic_info;
@@ -460,6 +530,10 @@ static int qlcnic_sriov_vf_init_driver(struct qlcnic_adapter *adapter)
460 if (err) 530 if (err)
461 return -EIO; 531 return -EIO;
462 532
533 err = qlcnic_sriov_get_vf_acl(adapter);
534 if (err)
535 return err;
536
463 if (qlcnic_83xx_get_port_info(adapter)) 537 if (qlcnic_83xx_get_port_info(adapter))
464 return -EIO; 538 return -EIO;
465 539
@@ -1411,7 +1485,7 @@ out:
1411 return ret; 1485 return ret;
1412} 1486}
1413 1487
1414void qlcnic_vf_add_mc_list(struct net_device *netdev) 1488void qlcnic_vf_add_mc_list(struct net_device *netdev, u16 vlan)
1415{ 1489{
1416 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1490 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1417 struct qlcnic_mac_list_s *cur; 1491 struct qlcnic_mac_list_s *cur;
@@ -1431,7 +1505,7 @@ void qlcnic_vf_add_mc_list(struct net_device *netdev)
1431 while (!list_empty(&tmp_list)) { 1505 while (!list_empty(&tmp_list)) {
1432 cur = list_entry((&tmp_list)->next, 1506 cur = list_entry((&tmp_list)->next,
1433 struct qlcnic_mac_list_s, list); 1507 struct qlcnic_mac_list_s, list);
1434 qlcnic_nic_add_mac(adapter, cur->mac_addr); 1508 qlcnic_nic_add_mac(adapter, cur->mac_addr, vlan);
1435 list_del(&cur->list); 1509 list_del(&cur->list);
1436 kfree(cur); 1510 kfree(cur);
1437 } 1511 }
@@ -1454,11 +1528,13 @@ void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *bc)
1454static void qlcnic_sriov_vf_set_multi(struct net_device *netdev) 1528static void qlcnic_sriov_vf_set_multi(struct net_device *netdev)
1455{ 1529{
1456 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1530 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1531 u16 vlan;
1457 1532
1458 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) 1533 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
1459 return; 1534 return;
1460 1535
1461 __qlcnic_set_multi(netdev); 1536 vlan = adapter->ahw->sriov->vlan;
1537 __qlcnic_set_multi(netdev, vlan);
1462} 1538}
1463 1539
1464static void qlcnic_sriov_handle_async_multi(struct work_struct *work) 1540static void qlcnic_sriov_handle_async_multi(struct work_struct *work)
@@ -1787,3 +1863,92 @@ static void qlcnic_sriov_vf_cancel_fw_work(struct qlcnic_adapter *adapter)
1787 clear_bit(__QLCNIC_RESETTING, &adapter->state); 1863 clear_bit(__QLCNIC_RESETTING, &adapter->state);
1788 cancel_delayed_work_sync(&adapter->fw_work); 1864 cancel_delayed_work_sync(&adapter->fw_work);
1789} 1865}
1866
1867static int qlcnic_sriov_validate_vlan_cfg(struct qlcnic_sriov *sriov,
1868 u16 vid, u8 enable)
1869{
1870 u16 vlan = sriov->vlan;
1871 u8 allowed = 0;
1872 int i;
1873
1874 if (sriov->vlan_mode != QLC_GUEST_VLAN_MODE)
1875 return -EINVAL;
1876
1877 if (enable) {
1878 if (vlan)
1879 return -EINVAL;
1880
1881 if (sriov->any_vlan) {
1882 for (i = 0; i < sriov->num_allowed_vlans; i++) {
1883 if (sriov->allowed_vlans[i] == vid)
1884 allowed = 1;
1885 }
1886
1887 if (!allowed)
1888 return -EINVAL;
1889 }
1890 } else {
1891 if (!vlan || vlan != vid)
1892 return -EINVAL;
1893 }
1894
1895 return 0;
1896}
1897
1898int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter,
1899 u16 vid, u8 enable)
1900{
1901 struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1902 struct qlcnic_cmd_args cmd;
1903 int ret;
1904
1905 if (vid == 0)
1906 return 0;
1907
1908 ret = qlcnic_sriov_validate_vlan_cfg(sriov, vid, enable);
1909 if (ret)
1910 return ret;
1911
1912 ret = qlcnic_sriov_alloc_bc_mbx_args(&cmd,
1913 QLCNIC_BC_CMD_CFG_GUEST_VLAN);
1914 if (ret)
1915 return ret;
1916
1917 cmd.req.arg[1] = (enable & 1) | vid << 16;
1918
1919 qlcnic_sriov_cleanup_async_list(&sriov->bc);
1920 ret = qlcnic_issue_cmd(adapter, &cmd);
1921 if (ret) {
1922 dev_err(&adapter->pdev->dev,
1923 "Failed to configure guest VLAN, err=%d\n", ret);
1924 } else {
1925 qlcnic_free_mac_list(adapter);
1926
1927 if (enable)
1928 sriov->vlan = vid;
1929 else
1930 sriov->vlan = 0;
1931
1932 qlcnic_sriov_vf_set_multi(adapter->netdev);
1933 }
1934
1935 qlcnic_free_mbx_args(&cmd);
1936 return ret;
1937}
1938
1939static void qlcnic_sriov_vf_free_mac_list(struct qlcnic_adapter *adapter)
1940{
1941 struct list_head *head = &adapter->mac_list;
1942 struct qlcnic_mac_list_s *cur;
1943 u16 vlan;
1944
1945 vlan = adapter->ahw->sriov->vlan;
1946
1947 while (!list_empty(head)) {
1948 cur = list_entry(head->next, struct qlcnic_mac_list_s, list);
1949 qlcnic_sre_macaddr_change(adapter, cur->mac_addr,
1950 vlan, QLCNIC_MAC_DEL);
1951 list_del(&cur->list);
1952 kfree(cur);
1953 }
1954}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
index 59d385b7ccd7..c81be2da119b 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
@@ -286,6 +286,29 @@ out:
286 return ret; 286 return ret;
287} 287}
288 288
289static int qlcnic_sriov_pf_cfg_vlan_filtering(struct qlcnic_adapter *adapter,
290 u8 enable)
291{
292 struct qlcnic_cmd_args cmd;
293 int err;
294
295 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
296 if (err)
297 return err;
298
299 cmd.req.arg[1] = 0x4;
300 if (enable)
301 cmd.req.arg[1] |= BIT_16;
302
303 err = qlcnic_issue_cmd(adapter, &cmd);
304 if (err)
305 dev_err(&adapter->pdev->dev,
306 "Failed to configure VLAN filtering, err=%d\n", err);
307
308 qlcnic_free_mbx_args(&cmd);
309 return err;
310}
311
289static int qlcnic_sriov_pf_cfg_eswitch(struct qlcnic_adapter *adapter, 312static int qlcnic_sriov_pf_cfg_eswitch(struct qlcnic_adapter *adapter,
290 u8 func, u8 enable) 313 u8 func, u8 enable)
291{ 314{
@@ -350,6 +373,7 @@ void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter)
350 qlcnic_sriov_cfg_bc_intr(adapter, 0); 373 qlcnic_sriov_cfg_bc_intr(adapter, 0);
351 qlcnic_sriov_pf_config_vport(adapter, 0, func); 374 qlcnic_sriov_pf_config_vport(adapter, 0, func);
352 qlcnic_sriov_pf_cfg_eswitch(adapter, func, 0); 375 qlcnic_sriov_pf_cfg_eswitch(adapter, func, 0);
376 qlcnic_sriov_pf_cfg_vlan_filtering(adapter, 0);
353 __qlcnic_sriov_cleanup(adapter); 377 __qlcnic_sriov_cleanup(adapter);
354 adapter->ahw->op_mode = QLCNIC_MGMT_FUNC; 378 adapter->ahw->op_mode = QLCNIC_MGMT_FUNC;
355 clear_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state); 379 clear_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
@@ -402,10 +426,14 @@ static int qlcnic_sriov_pf_init(struct qlcnic_adapter *adapter)
402 if (!qlcnic_sriov_enable_check(adapter)) 426 if (!qlcnic_sriov_enable_check(adapter))
403 return 0; 427 return 0;
404 428
405 err = qlcnic_sriov_pf_cfg_eswitch(adapter, func, 1); 429 err = qlcnic_sriov_pf_cfg_vlan_filtering(adapter, 1);
406 if (err) 430 if (err)
407 return err; 431 return err;
408 432
433 err = qlcnic_sriov_pf_cfg_eswitch(adapter, func, 1);
434 if (err)
435 goto disable_vlan_filtering;
436
409 err = qlcnic_sriov_pf_config_vport(adapter, 1, func); 437 err = qlcnic_sriov_pf_config_vport(adapter, 1, func);
410 if (err) 438 if (err)
411 goto disable_eswitch; 439 goto disable_eswitch;
@@ -439,6 +467,9 @@ delete_vport:
439disable_eswitch: 467disable_eswitch:
440 qlcnic_sriov_pf_cfg_eswitch(adapter, func, 0); 468 qlcnic_sriov_pf_cfg_eswitch(adapter, func, 0);
441 469
470disable_vlan_filtering:
471 qlcnic_sriov_pf_cfg_vlan_filtering(adapter, 0);
472
442 return err; 473 return err;
443} 474}
444 475
@@ -544,6 +575,36 @@ int qlcnic_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
544 return err; 575 return err;
545} 576}
546 577
578static int qlcnic_sriov_set_vf_acl(struct qlcnic_adapter *adapter, u8 func)
579{
580 struct qlcnic_cmd_args cmd;
581 struct qlcnic_vport *vp;
582 int err, id;
583
584 id = qlcnic_sriov_func_to_index(adapter, func);
585 if (id < 0)
586 return id;
587
588 vp = adapter->ahw->sriov->vf_info[id].vp;
589 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
590 if (err)
591 return err;
592
593 cmd.req.arg[1] = 0x3 | func << 16;
594 if (vp->vlan_mode == QLC_PVID_MODE) {
595 cmd.req.arg[2] |= BIT_6;
596 cmd.req.arg[3] |= vp->vlan << 8;
597 }
598
599 err = qlcnic_issue_cmd(adapter, &cmd);
600 if (err)
601 dev_err(&adapter->pdev->dev, "Failed to set ACL, err=%d\n",
602 err);
603
604 qlcnic_free_mbx_args(&cmd);
605 return err;
606}
607
547static int qlcnic_sriov_set_vf_vport_info(struct qlcnic_adapter *adapter, 608static int qlcnic_sriov_set_vf_vport_info(struct qlcnic_adapter *adapter,
548 u16 func) 609 u16 func)
549{ 610{
@@ -554,6 +615,10 @@ static int qlcnic_sriov_set_vf_vport_info(struct qlcnic_adapter *adapter,
554 if (err) 615 if (err)
555 return -EIO; 616 return -EIO;
556 617
618 err = qlcnic_sriov_set_vf_acl(adapter, func);
619 if (err)
620 return err;
621
557 return 0; 622 return 0;
558} 623}
559 624
@@ -661,6 +726,7 @@ static int qlcnic_sriov_pf_create_rx_ctx_cmd(struct qlcnic_bc_trans *tran,
661 struct qlcnic_adapter *adapter = vf->adapter; 726 struct qlcnic_adapter *adapter = vf->adapter;
662 struct qlcnic_rcv_mbx_out *mbx_out; 727 struct qlcnic_rcv_mbx_out *mbx_out;
663 int err; 728 int err;
729 u16 vlan;
664 730
665 err = qlcnic_sriov_validate_create_rx_ctx(cmd); 731 err = qlcnic_sriov_validate_create_rx_ctx(cmd);
666 if (err) { 732 if (err) {
@@ -671,11 +737,12 @@ static int qlcnic_sriov_pf_create_rx_ctx_cmd(struct qlcnic_bc_trans *tran,
671 cmd->req.arg[6] = vf->vp->handle; 737 cmd->req.arg[6] = vf->vp->handle;
672 err = qlcnic_issue_cmd(adapter, cmd); 738 err = qlcnic_issue_cmd(adapter, cmd);
673 739
740 vlan = vf->vp->vlan;
674 if (!err) { 741 if (!err) {
675 mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd->rsp.arg[1]; 742 mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd->rsp.arg[1];
676 vf->rx_ctx_id = mbx_out->ctx_id; 743 vf->rx_ctx_id = mbx_out->ctx_id;
677 qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func, 744 qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func,
678 0, QLCNIC_MAC_ADD); 745 vlan, QLCNIC_MAC_ADD);
679 } else { 746 } else {
680 vf->rx_ctx_id = 0; 747 vf->rx_ctx_id = 0;
681 } 748 }
@@ -759,6 +826,7 @@ static int qlcnic_sriov_pf_del_rx_ctx_cmd(struct qlcnic_bc_trans *trans,
759 struct qlcnic_vf_info *vf = trans->vf; 826 struct qlcnic_vf_info *vf = trans->vf;
760 struct qlcnic_adapter *adapter = vf->adapter; 827 struct qlcnic_adapter *adapter = vf->adapter;
761 int err; 828 int err;
829 u16 vlan;
762 830
763 err = qlcnic_sriov_validate_del_rx_ctx(vf, cmd); 831 err = qlcnic_sriov_validate_del_rx_ctx(vf, cmd);
764 if (err) { 832 if (err) {
@@ -766,8 +834,9 @@ static int qlcnic_sriov_pf_del_rx_ctx_cmd(struct qlcnic_bc_trans *trans,
766 return err; 834 return err;
767 } 835 }
768 836
837 vlan = vf->vp->vlan;
769 qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func, 838 qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func,
770 0, QLCNIC_MAC_DEL); 839 vlan, QLCNIC_MAC_DEL);
771 cmd->req.arg[1] |= vf->vp->handle << 16; 840 cmd->req.arg[1] |= vf->vp->handle << 16;
772 err = qlcnic_issue_cmd(adapter, cmd); 841 err = qlcnic_issue_cmd(adapter, cmd);
773 842
@@ -1012,6 +1081,8 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter,
1012 struct qlcnic_cmd_args *cmd) 1081 struct qlcnic_cmd_args *cmd)
1013{ 1082{
1014 struct qlcnic_macvlan_mbx *macvlan; 1083 struct qlcnic_macvlan_mbx *macvlan;
1084 struct qlcnic_vport *vp = vf->vp;
1085 u8 op, new_op;
1015 1086
1016 if (!(cmd->req.arg[1] & BIT_8)) 1087 if (!(cmd->req.arg[1] & BIT_8))
1017 return -EINVAL; 1088 return -EINVAL;
@@ -1027,6 +1098,15 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter,
1027 return -EINVAL; 1098 return -EINVAL;
1028 } 1099 }
1029 1100
1101 if (vp->vlan_mode == QLC_PVID_MODE) {
1102 op = cmd->req.arg[1] & 0x7;
1103 cmd->req.arg[1] &= ~0x7;
1104 new_op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
1105 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL;
1106 cmd->req.arg[3] |= vp->vlan << 16;
1107 cmd->req.arg[1] |= new_op;
1108 }
1109
1030 return 0; 1110 return 0;
1031} 1111}
1032 1112
@@ -1089,6 +1169,109 @@ static int qlcnic_sriov_pf_cfg_promisc_cmd(struct qlcnic_bc_trans *trans,
1089 return err; 1169 return err;
1090} 1170}
1091 1171
1172static int qlcnic_sriov_pf_get_acl_cmd(struct qlcnic_bc_trans *trans,
1173 struct qlcnic_cmd_args *cmd)
1174{
1175 struct qlcnic_vf_info *vf = trans->vf;
1176 struct qlcnic_vport *vp = vf->vp;
1177 u8 cmd_op, mode = vp->vlan_mode;
1178
1179 cmd_op = trans->req_hdr->cmd_op;
1180 cmd->rsp.arg[0] = (cmd_op & 0xffff) | 14 << 16 | 1 << 25;
1181
1182 switch (mode) {
1183 case QLC_GUEST_VLAN_MODE:
1184 cmd->rsp.arg[1] = mode | 1 << 8;
1185 cmd->rsp.arg[2] = 1 << 16;
1186 break;
1187 case QLC_PVID_MODE:
1188 cmd->rsp.arg[1] = mode | 1 << 8 | vp->vlan << 16;
1189 break;
1190 }
1191
1192 return 0;
1193}
1194
1195static int qlcnic_sriov_pf_del_guest_vlan(struct qlcnic_adapter *adapter,
1196 struct qlcnic_vf_info *vf)
1197
1198{
1199 struct qlcnic_vport *vp = vf->vp;
1200
1201 if (!vp->vlan)
1202 return -EINVAL;
1203
1204 if (!vf->rx_ctx_id) {
1205 vp->vlan = 0;
1206 return 0;
1207 }
1208
1209 qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func,
1210 vp->vlan, QLCNIC_MAC_DEL);
1211 vp->vlan = 0;
1212 qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func,
1213 0, QLCNIC_MAC_ADD);
1214 return 0;
1215}
1216
1217static int qlcnic_sriov_pf_add_guest_vlan(struct qlcnic_adapter *adapter,
1218 struct qlcnic_vf_info *vf,
1219 struct qlcnic_cmd_args *cmd)
1220{
1221 struct qlcnic_vport *vp = vf->vp;
1222 int err = -EIO;
1223
1224 if (vp->vlan)
1225 return err;
1226
1227 if (!vf->rx_ctx_id) {
1228 vp->vlan = cmd->req.arg[1] >> 16;
1229 return 0;
1230 }
1231
1232 err = qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func,
1233 0, QLCNIC_MAC_DEL);
1234 if (err)
1235 return err;
1236
1237 vp->vlan = cmd->req.arg[1] >> 16;
1238 err = qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func,
1239 vp->vlan, QLCNIC_MAC_ADD);
1240
1241 if (err) {
1242 qlcnic_sriov_cfg_vf_def_mac(adapter, vp, vf->pci_func,
1243 0, QLCNIC_MAC_ADD);
1244 vp->vlan = 0;
1245 }
1246
1247 return err;
1248}
1249
1250static int qlcnic_sriov_pf_cfg_guest_vlan_cmd(struct qlcnic_bc_trans *tran,
1251 struct qlcnic_cmd_args *cmd)
1252{
1253 struct qlcnic_vf_info *vf = tran->vf;
1254 struct qlcnic_adapter *adapter = vf->adapter;
1255 struct qlcnic_vport *vp = vf->vp;
1256 int err = -EIO;
1257 u8 op;
1258
1259 if (vp->vlan_mode != QLC_GUEST_VLAN_MODE) {
1260 cmd->rsp.arg[0] |= 2 << 25;
1261 return err;
1262 }
1263
1264 op = cmd->req.arg[1] & 0xf;
1265
1266 if (op)
1267 err = qlcnic_sriov_pf_add_guest_vlan(adapter, vf, cmd);
1268 else
1269 err = qlcnic_sriov_pf_del_guest_vlan(adapter, vf);
1270
1271 cmd->rsp.arg[0] |= err ? 2 << 25 : 1 << 25;
1272 return err;
1273}
1274
1092static const int qlcnic_pf_passthru_supp_cmds[] = { 1275static const int qlcnic_pf_passthru_supp_cmds[] = {
1093 QLCNIC_CMD_GET_STATISTICS, 1276 QLCNIC_CMD_GET_STATISTICS,
1094 QLCNIC_CMD_GET_PORT_CONFIG, 1277 QLCNIC_CMD_GET_PORT_CONFIG,
@@ -1098,6 +1281,8 @@ static const int qlcnic_pf_passthru_supp_cmds[] = {
1098static const struct qlcnic_sriov_cmd_handler qlcnic_pf_bc_cmd_hdlr[] = { 1281static const struct qlcnic_sriov_cmd_handler qlcnic_pf_bc_cmd_hdlr[] = {
1099 [QLCNIC_BC_CMD_CHANNEL_INIT] = {&qlcnic_sriov_pf_channel_cfg_cmd}, 1282 [QLCNIC_BC_CMD_CHANNEL_INIT] = {&qlcnic_sriov_pf_channel_cfg_cmd},
1100 [QLCNIC_BC_CMD_CHANNEL_TERM] = {&qlcnic_sriov_pf_channel_cfg_cmd}, 1283 [QLCNIC_BC_CMD_CHANNEL_TERM] = {&qlcnic_sriov_pf_channel_cfg_cmd},
1284 [QLCNIC_BC_CMD_GET_ACL] = {&qlcnic_sriov_pf_get_acl_cmd},
1285 [QLCNIC_BC_CMD_CFG_GUEST_VLAN] = {&qlcnic_sriov_pf_cfg_guest_vlan_cmd},
1101}; 1286};
1102 1287
1103static const struct qlcnic_sriov_fw_cmd_handler qlcnic_pf_fw_cmd_hdlr[] = { 1288static const struct qlcnic_sriov_fw_cmd_handler qlcnic_pf_fw_cmd_hdlr[] = {
@@ -1518,6 +1703,56 @@ int qlcnic_sriov_set_vf_tx_rate(struct net_device *netdev, int vf, int tx_rate)
1518 return 0; 1703 return 0;
1519} 1704}
1520 1705
1706int qlcnic_sriov_set_vf_vlan(struct net_device *netdev, int vf,
1707 u16 vlan, u8 qos)
1708{
1709 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1710 struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1711 struct qlcnic_vf_info *vf_info;
1712 struct qlcnic_vport *vp;
1713
1714 if (!qlcnic_sriov_pf_check(adapter))
1715 return -EOPNOTSUPP;
1716
1717 if (vf >= sriov->num_vfs || qos > 7)
1718 return -EINVAL;
1719
1720 if (vlan > MAX_VLAN_ID) {
1721 netdev_err(netdev,
1722 "Invalid VLAN ID, allowed range is [0 - %d]\n",
1723 MAX_VLAN_ID);
1724 return -EINVAL;
1725 }
1726
1727 vf_info = &sriov->vf_info[vf];
1728 vp = vf_info->vp;
1729 if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) {
1730 netdev_err(netdev,
1731 "VLAN change failed for VF %d, as VF driver is loaded. Please unload VF driver and retry the operation\n",
1732 vf);
1733 return -EOPNOTSUPP;
1734 }
1735
1736 switch (vlan) {
1737 case 4095:
1738 vp->vlan_mode = QLC_GUEST_VLAN_MODE;
1739 break;
1740 case 0:
1741 vp->vlan_mode = QLC_NO_VLAN_MODE;
1742 vp->vlan = 0;
1743 vp->qos = 0;
1744 break;
1745 default:
1746 vp->vlan_mode = QLC_PVID_MODE;
1747 vp->vlan = vlan;
1748 vp->qos = qos;
1749 }
1750
1751 netdev_info(netdev, "Setting VLAN %d, QoS %d, for VF %d\n",
1752 vlan, qos, vf);
1753 return 0;
1754}
1755
1521int qlcnic_sriov_get_vf_config(struct net_device *netdev, 1756int qlcnic_sriov_get_vf_config(struct net_device *netdev,
1522 int vf, struct ifla_vf_info *ivi) 1757 int vf, struct ifla_vf_info *ivi)
1523{ 1758{
@@ -1533,6 +1768,8 @@ int qlcnic_sriov_get_vf_config(struct net_device *netdev,
1533 1768
1534 vp = sriov->vf_info[vf].vp; 1769 vp = sriov->vf_info[vf].vp;
1535 memcpy(&ivi->mac, vp->mac, ETH_ALEN); 1770 memcpy(&ivi->mac, vp->mac, ETH_ALEN);
1771 ivi->vlan = vp->vlan;
1772 ivi->qos = vp->qos;
1536 if (vp->max_tx_bw == MAX_BW) 1773 if (vp->max_tx_bw == MAX_BW)
1537 ivi->tx_rate = 0; 1774 ivi->tx_rate = 0;
1538 else 1775 else