|
|
@@ -46,88 +46,96 @@
|
|
|
#include "ixgbe_sriov.h"
|
|
|
|
|
|
#ifdef CONFIG_PCI_IOV
|
|
|
-static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
|
|
|
+static inline void ixgbe_alloc_vf_macvlans(struct ixgbe_adapter *adapter,
|
|
|
+ unsigned int num_vfs)
|
|
|
{
|
|
|
struct ixgbe_hw *hw = &adapter->hw;
|
|
|
- int num_vf_macvlans, i;
|
|
|
struct vf_macvlans *mv_list;
|
|
|
-
|
|
|
- adapter->flags |= IXGBE_FLAG_SRIOV_ENABLED;
|
|
|
- e_info(probe, "SR-IOV enabled with %d VFs\n", adapter->num_vfs);
|
|
|
-
|
|
|
- /* 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->ring_feature[RING_F_VMDQ].offset = adapter->num_vfs;
|
|
|
+ int num_vf_macvlans, i;
|
|
|
|
|
|
num_vf_macvlans = hw->mac.num_rar_entries -
|
|
|
- (IXGBE_MAX_PF_MACVLANS + 1 + adapter->num_vfs);
|
|
|
+ (IXGBE_MAX_PF_MACVLANS + 1 + num_vfs);
|
|
|
+ if (!num_vf_macvlans)
|
|
|
+ return;
|
|
|
|
|
|
- adapter->mv_list = mv_list = kcalloc(num_vf_macvlans,
|
|
|
- sizeof(struct vf_macvlans),
|
|
|
- GFP_KERNEL);
|
|
|
+ mv_list = kcalloc(num_vf_macvlans, sizeof(struct vf_macvlans),
|
|
|
+ GFP_KERNEL);
|
|
|
if (mv_list) {
|
|
|
/* Initialize list of VF macvlans */
|
|
|
INIT_LIST_HEAD(&adapter->vf_mvs.l);
|
|
|
for (i = 0; i < num_vf_macvlans; i++) {
|
|
|
- mv_list->vf = -1;
|
|
|
- mv_list->free = true;
|
|
|
- list_add(&mv_list->l, &adapter->vf_mvs.l);
|
|
|
- mv_list++;
|
|
|
+ mv_list[i].vf = -1;
|
|
|
+ mv_list[i].free = true;
|
|
|
+ list_add(&mv_list[i].l, &adapter->vf_mvs.l);
|
|
|
}
|
|
|
+ adapter->mv_list = mv_list;
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
|
|
|
+ unsigned int num_vfs)
|
|
|
+{
|
|
|
+ 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;
|
|
|
+
|
|
|
+ /* Allocate memory for per VF control structures */
|
|
|
+ adapter->vfinfo = kcalloc(num_vfs, sizeof(struct vf_data_storage),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!adapter->vfinfo)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ adapter->num_vfs = num_vfs;
|
|
|
+
|
|
|
+ ixgbe_alloc_vf_macvlans(adapter, num_vfs);
|
|
|
+ adapter->ring_feature[RING_F_VMDQ].offset = num_vfs;
|
|
|
|
|
|
/* Initialize default switching mode VEB */
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
|
|
|
adapter->bridge_mode = BRIDGE_MODE_VEB;
|
|
|
|
|
|
- /* If call to enable VFs succeeded then allocate memory
|
|
|
- * for per VF control structures.
|
|
|
- */
|
|
|
- adapter->vfinfo =
|
|
|
- kcalloc(adapter->num_vfs,
|
|
|
- sizeof(struct vf_data_storage), GFP_KERNEL);
|
|
|
- if (adapter->vfinfo) {
|
|
|
- /* limit trafffic classes based on VFs enabled */
|
|
|
- if ((adapter->hw.mac.type == ixgbe_mac_82599EB) &&
|
|
|
- (adapter->num_vfs < 16)) {
|
|
|
- adapter->dcb_cfg.num_tcs.pg_tcs = MAX_TRAFFIC_CLASS;
|
|
|
- adapter->dcb_cfg.num_tcs.pfc_tcs = MAX_TRAFFIC_CLASS;
|
|
|
- } else if (adapter->num_vfs < 32) {
|
|
|
- adapter->dcb_cfg.num_tcs.pg_tcs = 4;
|
|
|
- adapter->dcb_cfg.num_tcs.pfc_tcs = 4;
|
|
|
- } else {
|
|
|
- adapter->dcb_cfg.num_tcs.pg_tcs = 1;
|
|
|
- adapter->dcb_cfg.num_tcs.pfc_tcs = 1;
|
|
|
- }
|
|
|
-
|
|
|
- /* Disable RSC when in SR-IOV mode */
|
|
|
- adapter->flags2 &= ~(IXGBE_FLAG2_RSC_CAPABLE |
|
|
|
- IXGBE_FLAG2_RSC_ENABLED);
|
|
|
+ /* limit trafffic classes based on VFs enabled */
|
|
|
+ if ((adapter->hw.mac.type == ixgbe_mac_82599EB) && (num_vfs < 16)) {
|
|
|
+ adapter->dcb_cfg.num_tcs.pg_tcs = MAX_TRAFFIC_CLASS;
|
|
|
+ adapter->dcb_cfg.num_tcs.pfc_tcs = MAX_TRAFFIC_CLASS;
|
|
|
+ } else if (num_vfs < 32) {
|
|
|
+ adapter->dcb_cfg.num_tcs.pg_tcs = 4;
|
|
|
+ adapter->dcb_cfg.num_tcs.pfc_tcs = 4;
|
|
|
+ } else {
|
|
|
+ adapter->dcb_cfg.num_tcs.pg_tcs = 1;
|
|
|
+ adapter->dcb_cfg.num_tcs.pfc_tcs = 1;
|
|
|
+ }
|
|
|
|
|
|
- for (i = 0; i < adapter->num_vfs; i++) {
|
|
|
- /* enable spoof checking for all VFs */
|
|
|
- adapter->vfinfo[i].spoofchk_enabled = true;
|
|
|
+ /* Disable RSC when in SR-IOV mode */
|
|
|
+ adapter->flags2 &= ~(IXGBE_FLAG2_RSC_CAPABLE |
|
|
|
+ IXGBE_FLAG2_RSC_ENABLED);
|
|
|
|
|
|
- /* We support VF RSS querying only for 82599 and x540
|
|
|
- * devices at the moment. These devices share RSS
|
|
|
- * indirection table and RSS hash key with PF therefore
|
|
|
- * we want to disable the querying by default.
|
|
|
- */
|
|
|
- adapter->vfinfo[i].rss_query_enabled = 0;
|
|
|
+ for (i = 0; i < num_vfs; i++) {
|
|
|
+ /* enable spoof checking for all VFs */
|
|
|
+ adapter->vfinfo[i].spoofchk_enabled = true;
|
|
|
|
|
|
- /* Untrust all VFs */
|
|
|
- adapter->vfinfo[i].trusted = false;
|
|
|
+ /* We support VF RSS querying only for 82599 and x540
|
|
|
+ * devices at the moment. These devices share RSS
|
|
|
+ * indirection table and RSS hash key with PF therefore
|
|
|
+ * we want to disable the querying by default.
|
|
|
+ */
|
|
|
+ adapter->vfinfo[i].rss_query_enabled = 0;
|
|
|
|
|
|
- /* set the default xcast mode */
|
|
|
- adapter->vfinfo[i].xcast_mode = IXGBEVF_XCAST_MODE_NONE;
|
|
|
- }
|
|
|
+ /* Untrust all VFs */
|
|
|
+ adapter->vfinfo[i].trusted = false;
|
|
|
|
|
|
- return 0;
|
|
|
+ /* set the default xcast mode */
|
|
|
+ adapter->vfinfo[i].xcast_mode = IXGBEVF_XCAST_MODE_NONE;
|
|
|
}
|
|
|
|
|
|
- return -ENOMEM;
|
|
|
+ e_info(probe, "SR-IOV enabled with %d VFs\n", num_vfs);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -165,12 +173,13 @@ static void ixgbe_get_vfs(struct ixgbe_adapter *adapter)
|
|
|
/* Note this function is called when the user wants to enable SR-IOV
|
|
|
* VFs using the now deprecated module parameter
|
|
|
*/
|
|
|
-void ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
|
|
|
+void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsigned int max_vfs)
|
|
|
{
|
|
|
int pre_existing_vfs = 0;
|
|
|
+ unsigned int num_vfs;
|
|
|
|
|
|
pre_existing_vfs = pci_num_vf(adapter->pdev);
|
|
|
- if (!pre_existing_vfs && !adapter->num_vfs)
|
|
|
+ if (!pre_existing_vfs && !max_vfs)
|
|
|
return;
|
|
|
|
|
|
/* If there are pre-existing VFs then we have to force
|
|
|
@@ -180,7 +189,7 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
|
|
|
* have been created via the new PCI SR-IOV sysfs interface.
|
|
|
*/
|
|
|
if (pre_existing_vfs) {
|
|
|
- adapter->num_vfs = pre_existing_vfs;
|
|
|
+ num_vfs = pre_existing_vfs;
|
|
|
dev_warn(&adapter->pdev->dev,
|
|
|
"Virtual Functions already enabled for this device - Please reload all VF drivers to avoid spoofed packet errors\n");
|
|
|
} else {
|
|
|
@@ -192,17 +201,16 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
|
|
|
* physical function. If the user requests greater than
|
|
|
* 63 VFs then it is an error - reset to default of zero.
|
|
|
*/
|
|
|
- adapter->num_vfs = min_t(unsigned int, adapter->num_vfs, IXGBE_MAX_VFS_DRV_LIMIT);
|
|
|
+ num_vfs = min_t(unsigned int, max_vfs, IXGBE_MAX_VFS_DRV_LIMIT);
|
|
|
|
|
|
- err = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
|
|
|
+ err = pci_enable_sriov(adapter->pdev, num_vfs);
|
|
|
if (err) {
|
|
|
e_err(probe, "Failed to enable PCI sriov: %d\n", err);
|
|
|
- adapter->num_vfs = 0;
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (!__ixgbe_enable_sriov(adapter)) {
|
|
|
+ if (!__ixgbe_enable_sriov(adapter, num_vfs)) {
|
|
|
ixgbe_get_vfs(adapter);
|
|
|
return;
|
|
|
}
|
|
|
@@ -298,6 +306,7 @@ 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);
|
|
|
|
|
|
@@ -310,23 +319,41 @@ static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
|
|
|
return err;
|
|
|
|
|
|
/* While the SR-IOV capability structure reports total VFs to be 64,
|
|
|
- * we have to limit the actual number allocated based on two factors.
|
|
|
+ * we limit the actual number allocated as below based on two factors.
|
|
|
+ * Num_TCs MAX_VFs
|
|
|
+ * 1 63
|
|
|
+ * <=4 31
|
|
|
+ * >4 15
|
|
|
* First, we reserve some transmit/receive resources for the PF.
|
|
|
* Second, VMDQ also uses the same pools that SR-IOV does. We need to
|
|
|
* account for this, so that we don't accidentally allocate more VFs
|
|
|
* than we have available pools. The PCI bus driver already checks for
|
|
|
* other values out of range.
|
|
|
*/
|
|
|
- if ((num_vfs + adapter->num_rx_pools) > IXGBE_MAX_VF_FUNCTIONS)
|
|
|
- return -EPERM;
|
|
|
+ num_tc = netdev_get_num_tc(adapter->netdev);
|
|
|
|
|
|
- adapter->num_vfs = num_vfs;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- err = __ixgbe_enable_sriov(adapter);
|
|
|
+ err = __ixgbe_enable_sriov(adapter, num_vfs);
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
- for (i = 0; i < adapter->num_vfs; i++)
|
|
|
+ for (i = 0; i < num_vfs; i++)
|
|
|
ixgbe_vf_configuration(dev, (i | 0x10000000));
|
|
|
|
|
|
/* reset before enabling SRIOV to avoid mailbox issues */
|