|
@@ -3965,6 +3965,36 @@ static void vxge_io_resume(struct pci_dev *pdev)
|
|
|
netif_device_attach(netdev);
|
|
|
}
|
|
|
|
|
|
+static inline u32 vxge_get_num_vfs(u64 function_mode)
|
|
|
+{
|
|
|
+ u32 num_functions = 0;
|
|
|
+
|
|
|
+ switch (function_mode) {
|
|
|
+ case VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION:
|
|
|
+ case VXGE_HW_FUNCTION_MODE_SRIOV_8:
|
|
|
+ num_functions = 8;
|
|
|
+ break;
|
|
|
+ case VXGE_HW_FUNCTION_MODE_SINGLE_FUNCTION:
|
|
|
+ num_functions = 1;
|
|
|
+ break;
|
|
|
+ case VXGE_HW_FUNCTION_MODE_SRIOV:
|
|
|
+ case VXGE_HW_FUNCTION_MODE_MRIOV:
|
|
|
+ case VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION_17:
|
|
|
+ num_functions = 17;
|
|
|
+ break;
|
|
|
+ case VXGE_HW_FUNCTION_MODE_SRIOV_4:
|
|
|
+ num_functions = 4;
|
|
|
+ break;
|
|
|
+ case VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION_2:
|
|
|
+ num_functions = 2;
|
|
|
+ break;
|
|
|
+ case VXGE_HW_FUNCTION_MODE_MRIOV_8:
|
|
|
+ num_functions = 8; /* TODO */
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return num_functions;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* vxge_probe
|
|
|
* @pdev : structure containing the PCI related information of the device.
|
|
@@ -3992,14 +4022,19 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
|
|
|
u8 *macaddr;
|
|
|
struct vxge_mac_addrs *entry;
|
|
|
static int bus = -1, device = -1;
|
|
|
+ u32 host_type;
|
|
|
u8 new_device = 0;
|
|
|
+ enum vxge_hw_status is_privileged;
|
|
|
+ u32 function_mode;
|
|
|
+ u32 num_vfs = 0;
|
|
|
|
|
|
vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
|
|
|
attr.pdev = pdev;
|
|
|
|
|
|
- if (bus != pdev->bus->number)
|
|
|
- new_device = 1;
|
|
|
- if (device != PCI_SLOT(pdev->devfn))
|
|
|
+ /* In SRIOV-17 mode, functions of the same adapter
|
|
|
+ * can be deployed on different buses */
|
|
|
+ if ((!pdev->is_virtfn) && ((bus != pdev->bus->number) ||
|
|
|
+ (device != PCI_SLOT(pdev->devfn))))
|
|
|
new_device = 1;
|
|
|
|
|
|
bus = pdev->bus->number;
|
|
@@ -4133,6 +4168,11 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
|
|
|
"%s:%d Vpath mask = %llx", __func__, __LINE__,
|
|
|
(unsigned long long)vpath_mask);
|
|
|
|
|
|
+ function_mode = ll_config.device_hw_info.function_mode;
|
|
|
+ host_type = ll_config.device_hw_info.host_type;
|
|
|
+ is_privileged = __vxge_hw_device_is_privilaged(host_type,
|
|
|
+ ll_config.device_hw_info.func_id);
|
|
|
+
|
|
|
/* Check how many vpaths are available */
|
|
|
for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
|
|
|
if (!((vpath_mask) & vxge_mBIT(i)))
|
|
@@ -4140,14 +4180,18 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
|
|
|
max_vpath_supported++;
|
|
|
}
|
|
|
|
|
|
+ if (new_device)
|
|
|
+ num_vfs = vxge_get_num_vfs(function_mode) - 1;
|
|
|
+
|
|
|
/* Enable SRIOV mode, if firmware has SRIOV support and if it is a PF */
|
|
|
- if ((VXGE_HW_FUNCTION_MODE_SRIOV ==
|
|
|
- ll_config.device_hw_info.function_mode) &&
|
|
|
- (max_config_dev > 1) && (pdev->is_physfn)) {
|
|
|
- ret = pci_enable_sriov(pdev, max_config_dev - 1);
|
|
|
- if (ret)
|
|
|
- vxge_debug_ll_config(VXGE_ERR,
|
|
|
- "Failed to enable SRIOV: %d\n", ret);
|
|
|
+ if (is_sriov(function_mode) && (max_config_dev > 1) &&
|
|
|
+ (ll_config.intr_type != INTA) &&
|
|
|
+ (is_privileged == VXGE_HW_OK)) {
|
|
|
+ ret = pci_enable_sriov(pdev, ((max_config_dev - 1) < num_vfs)
|
|
|
+ ? (max_config_dev - 1) : num_vfs);
|
|
|
+ if (ret)
|
|
|
+ vxge_debug_ll_config(VXGE_ERR,
|
|
|
+ "Failed in enabling SRIOV mode: %d\n", ret);
|
|
|
}
|
|
|
|
|
|
/*
|