diff options
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c')
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index d132765f92a..247a9f9b7bd 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[], 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 @@ -341,6 +341,12 @@ static const struct net_device_ops qlcnic_netdev_ops = { #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = qlcnic_poll_controller, #endif +#ifdef CONFIG_QLCNIC_SRIOV + .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 }; static const struct net_device_ops qlcnic_netdev_failed_ops = { @@ -399,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) @@ -895,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; } @@ -913,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); @@ -1710,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 | @@ -1731,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; @@ -2112,6 +2151,7 @@ static int __qlcnic_shutdown(struct pci_dev *pdev) if (netif_running(netdev)) qlcnic_down(adapter, netdev); + qlcnic_sriov_cleanup(adapter); if (qlcnic_82xx_check(adapter)) qlcnic_clr_all_drv_state(adapter, 0); @@ -3266,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); @@ -3281,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"); |