Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / qlogic / qlcnic / qlcnic_main.c
index b3ab7a3386e388401bd8ddc772982aa7a5b28ec9..247a9f9b7bdc1139abeb6a5f92046b142ba3fea5 100644 (file)
@@ -290,7 +290,7 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
                return err;
 
        if (is_unicast_ether_addr(addr))
-               err = qlcnic_nic_add_mac(adapter, addr);
+               err = qlcnic_nic_add_mac(adapter, addr, 0);
        else if (is_multicast_ether_addr(addr))
                err = dev_mc_add_excl(netdev, addr);
        else
@@ -345,6 +345,7 @@ static const struct net_device_ops qlcnic_netdev_ops = {
        .ndo_set_vf_mac         = qlcnic_sriov_set_vf_mac,
        .ndo_set_vf_tx_rate     = qlcnic_sriov_set_vf_tx_rate,
        .ndo_get_vf_config      = qlcnic_sriov_get_vf_config,
+       .ndo_set_vf_vlan        = qlcnic_sriov_set_vf_vlan,
 #endif
 };
 
@@ -404,6 +405,7 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = {
        .config_promisc_mode            = qlcnic_82xx_nic_set_promisc,
        .change_l2_filter               = qlcnic_82xx_change_filter,
        .get_board_info                 = qlcnic_82xx_get_board_info,
+       .free_mac_list                  = qlcnic_82xx_free_mac_list,
 };
 
 int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
@@ -900,16 +902,31 @@ void qlcnic_set_vlan_config(struct qlcnic_adapter *adapter,
        else
                adapter->flags |= QLCNIC_TAGGING_ENABLED;
 
-       if (esw_cfg->vlan_id)
-               adapter->pvid = esw_cfg->vlan_id;
-       else
-               adapter->pvid = 0;
+       if (esw_cfg->vlan_id) {
+               adapter->rx_pvid = esw_cfg->vlan_id;
+               adapter->tx_pvid = esw_cfg->vlan_id;
+       } else {
+               adapter->rx_pvid = 0;
+               adapter->tx_pvid = 0;
+       }
 }
 
 static int
 qlcnic_vlan_rx_add(struct net_device *netdev, __be16 proto, u16 vid)
 {
        struct qlcnic_adapter *adapter = netdev_priv(netdev);
+       int err;
+
+       if (qlcnic_sriov_vf_check(adapter)) {
+               err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 1);
+               if (err) {
+                       netdev_err(netdev,
+                                  "Cannot add VLAN filter for VLAN id %d, err=%d",
+                                  vid, err);
+                       return err;
+               }
+       }
+
        set_bit(vid, adapter->vlans);
        return 0;
 }
@@ -918,6 +935,17 @@ static int
 qlcnic_vlan_rx_del(struct net_device *netdev, __be16 proto, u16 vid)
 {
        struct qlcnic_adapter *adapter = netdev_priv(netdev);
+       int err;
+
+       if (qlcnic_sriov_vf_check(adapter)) {
+               err = qlcnic_sriov_cfg_vf_guest_vlan(adapter, vid, 0);
+               if (err) {
+                       netdev_err(netdev,
+                                  "Cannot delete VLAN filter for VLAN id %d, err=%d",
+                                  vid, err);
+                       return err;
+               }
+       }
 
        qlcnic_restore_indev_addr(netdev, NETDEV_DOWN);
        clear_bit(vid, adapter->vlans);
@@ -1715,7 +1743,10 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
 
        qlcnic_change_mtu(netdev, netdev->mtu);
 
-       SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops);
+       if (qlcnic_sriov_vf_check(adapter))
+               SET_ETHTOOL_OPS(netdev, &qlcnic_sriov_vf_ethtool_ops);
+       else
+               SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops);
 
        netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
                             NETIF_F_IPV6_CSUM | NETIF_F_GRO |
@@ -1736,6 +1767,9 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
        if (qlcnic_vlan_tx_check(adapter))
                netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX);
 
+       if (qlcnic_sriov_vf_check(adapter))
+               netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+
        if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
                netdev->features |= NETIF_F_LRO;
 
@@ -3272,8 +3306,10 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data, size_t len)
 
        qlcnic_detach(adapter);
 
-       if (qlcnic_83xx_check(adapter))
+       if (qlcnic_83xx_check(adapter)) {
                qlcnic_83xx_free_mbx_intr(adapter);
+               qlcnic_83xx_enable_mbx_poll(adapter);
+       }
 
        qlcnic_teardown_intr(adapter);
        err = qlcnic_setup_intr(adapter, data);
@@ -3287,6 +3323,7 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data, size_t len)
                /* register for NIC IDC AEN Events */
                qlcnic_83xx_register_nic_idc_func(adapter, 1);
                err = qlcnic_83xx_setup_mbx_intr(adapter);
+               qlcnic_83xx_disable_mbx_poll(adapter);
                if (err) {
                        dev_err(&adapter->pdev->dev,
                                "failed to setup mbx interrupt\n");