diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 63 |
1 files changed, 19 insertions, 44 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 112d24c6c9ce..27a70a52f3c9 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -78,12 +78,9 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter, struct ixgbe_hw *hw = &adapter->hw; int i; - adapter->flags |= IXGBE_FLAG_SRIOV_ENABLED; - /* Enable VMDq flag so device will be set in VM mode */ - adapter->flags |= IXGBE_FLAG_VMDQ_ENABLED; - if (!adapter->ring_feature[RING_F_VMDQ].limit) - adapter->ring_feature[RING_F_VMDQ].limit = 1; + adapter->flags |= IXGBE_FLAG_SRIOV_ENABLED | + IXGBE_FLAG_VMDQ_ENABLED; /* Allocate memory for per VF control structures */ adapter->vfinfo = kcalloc(num_vfs, sizeof(struct vf_data_storage), @@ -227,9 +224,6 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsigned int max_vfs) int ixgbe_disable_sriov(struct ixgbe_adapter *adapter) { unsigned int num_vfs = adapter->num_vfs, vf; - struct ixgbe_hw *hw = &adapter->hw; - u32 gpie; - u32 vmdctl; int rss; /* set num VFs to 0 to prevent access to vfinfo */ @@ -271,18 +265,6 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter) pci_disable_sriov(adapter->pdev); #endif - /* turn off device IOV mode */ - IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, 0); - gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); - gpie &= ~IXGBE_GPIE_VTMODE_MASK; - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); - - /* set default pool back to 0 */ - vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL); - vmdctl &= ~IXGBE_VT_CTL_POOL_MASK; - IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl); - IXGBE_WRITE_FLUSH(hw); - /* Disable VMDq flag so device will be set in VM mode */ if (adapter->ring_feature[RING_F_VMDQ].limit == 1) { adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED; @@ -305,10 +287,9 @@ static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs) { #ifdef CONFIG_PCI_IOV struct ixgbe_adapter *adapter = pci_get_drvdata(dev); - int err = 0; - u8 num_tc; - int i; int pre_existing_vfs = pci_num_vf(dev); + int err = 0, num_rx_pools, i, limit; + u8 num_tc; if (pre_existing_vfs && pre_existing_vfs != num_vfs) err = ixgbe_disable_sriov(adapter); @@ -330,23 +311,15 @@ static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs) * than we have available pools. The PCI bus driver already checks for * other values out of range. */ - num_tc = netdev_get_num_tc(adapter->netdev); - - if (num_tc > 4) { - if ((num_vfs + adapter->num_rx_pools) > IXGBE_MAX_VFS_8TC) { - e_dev_err("Currently the device is configured with %d TCs, Creating more than %d VFs is not allowed\n", num_tc, IXGBE_MAX_VFS_8TC); - return -EPERM; - } - } else if ((num_tc > 1) && (num_tc <= 4)) { - if ((num_vfs + adapter->num_rx_pools) > IXGBE_MAX_VFS_4TC) { - e_dev_err("Currently the device is configured with %d TCs, Creating more than %d VFs is not allowed\n", num_tc, IXGBE_MAX_VFS_4TC); - return -EPERM; - } - } else { - if ((num_vfs + adapter->num_rx_pools) > IXGBE_MAX_VFS_1TC) { - e_dev_err("Currently the device is configured with %d TCs, Creating more than %d VFs is not allowed\n", num_tc, IXGBE_MAX_VFS_1TC); - return -EPERM; - } + num_tc = adapter->hw_tcs; + num_rx_pools = adapter->num_rx_pools; + limit = (num_tc > 4) ? IXGBE_MAX_VFS_8TC : + (num_tc > 1) ? IXGBE_MAX_VFS_4TC : IXGBE_MAX_VFS_1TC; + + if (num_vfs > (limit - num_rx_pools)) { + e_dev_err("Currently configured with %d TCs, and %d offloaded macvlans. Creating more than %d VFs is not allowed\n", + num_tc, num_rx_pools - 1, limit - num_rx_pools); + return -EPERM; } err = __ixgbe_enable_sriov(adapter, num_vfs); @@ -378,13 +351,15 @@ static int ixgbe_pci_sriov_disable(struct pci_dev *dev) int err; #ifdef CONFIG_PCI_IOV u32 current_flags = adapter->flags; + int prev_num_vf = pci_num_vf(dev); #endif err = ixgbe_disable_sriov(adapter); /* Only reinit if no error and state changed */ #ifdef CONFIG_PCI_IOV - if (!err && current_flags != adapter->flags) + if (!err && (current_flags != adapter->flags || + prev_num_vf != pci_num_vf(dev))) ixgbe_sriov_reinit(adapter); #endif @@ -738,7 +713,7 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) { struct ixgbe_hw *hw = &adapter->hw; struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; - u8 num_tcs = netdev_get_num_tc(adapter->netdev); + u8 num_tcs = adapter->hw_tcs; /* remove VLAN filters beloning to this VF */ ixgbe_clear_vf_vlans(adapter, vf); @@ -946,7 +921,7 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter, { u32 add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT; u32 vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK); - u8 tcs = netdev_get_num_tc(adapter->netdev); + u8 tcs = adapter->hw_tcs; if (adapter->vfinfo[vf].pf_vlan || tcs) { e_warn(drv, @@ -1034,7 +1009,7 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter, struct net_device *dev = adapter->netdev; struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; unsigned int default_tc = 0; - u8 num_tcs = netdev_get_num_tc(dev); + u8 num_tcs = adapter->hw_tcs; /* verify the PF is supporting the correct APIs */ switch (adapter->vfinfo[vf].vf_api) { |