[SCSI] lpfc 8.3.24: Add SR-IOV control
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <jbottomley@parallels.com>
This commit is contained in:
committed by
James Bottomley
parent
c0c1151276
commit
912e3acde6
@ -4033,6 +4033,36 @@ lpfc_reset_hba(struct lpfc_hba *phba)
|
||||
lpfc_unblock_mgmt_io(phba);
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli_probe_sriov_nr_virtfn - Enable a number of sr-iov virtual functions
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
* @nr_vfn: number of virtual functions to be enabled.
|
||||
*
|
||||
* This function enables the PCI SR-IOV virtual functions to a physical
|
||||
* function. It invokes the PCI SR-IOV api with the @nr_vfn provided to
|
||||
* enable the number of virtual functions to the physical function. As
|
||||
* not all devices support SR-IOV, the return code from the pci_enable_sriov()
|
||||
* API call does not considered as an error condition for most of the device.
|
||||
**/
|
||||
int
|
||||
lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *phba, int nr_vfn)
|
||||
{
|
||||
struct pci_dev *pdev = phba->pcidev;
|
||||
int rc;
|
||||
|
||||
rc = pci_enable_sriov(pdev, nr_vfn);
|
||||
if (rc) {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
|
||||
"2806 Failed to enable sriov on this device "
|
||||
"with vfn number nr_vf:%d, rc:%d\n",
|
||||
nr_vfn, rc);
|
||||
} else
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
|
||||
"2807 Successful enable sriov on this device "
|
||||
"with vfn number nr_vf:%d\n", nr_vfn);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli_driver_resource_setup - Setup driver internal resources for SLI3 dev.
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
@ -4048,6 +4078,7 @@ static int
|
||||
lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
|
||||
{
|
||||
struct lpfc_sli *psli;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Initialize timers used by driver
|
||||
@ -4122,6 +4153,23 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
|
||||
if (lpfc_mem_alloc(phba, BPL_ALIGN_SZ))
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Enable sr-iov virtual functions if supported and configured
|
||||
* through the module parameter.
|
||||
*/
|
||||
if (phba->cfg_sriov_nr_virtfn > 0) {
|
||||
rc = lpfc_sli_probe_sriov_nr_virtfn(phba,
|
||||
phba->cfg_sriov_nr_virtfn);
|
||||
if (rc) {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
|
||||
"2808 Requested number of SR-IOV "
|
||||
"virtual functions (%d) is not "
|
||||
"supported\n",
|
||||
phba->cfg_sriov_nr_virtfn);
|
||||
phba->cfg_sriov_nr_virtfn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4427,6 +4475,23 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
|
||||
goto out_free_fcp_eq_hdl;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable sr-iov virtual functions if supported and configured
|
||||
* through the module parameter.
|
||||
*/
|
||||
if (phba->cfg_sriov_nr_virtfn > 0) {
|
||||
rc = lpfc_sli_probe_sriov_nr_virtfn(phba,
|
||||
phba->cfg_sriov_nr_virtfn);
|
||||
if (rc) {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
|
||||
"3020 Requested number of SR-IOV "
|
||||
"virtual functions (%d) is not "
|
||||
"supported\n",
|
||||
phba->cfg_sriov_nr_virtfn);
|
||||
phba->cfg_sriov_nr_virtfn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
out_free_fcp_eq_hdl:
|
||||
@ -5780,7 +5845,12 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
|
||||
{
|
||||
LPFC_MBOXQ_t *pmb;
|
||||
struct lpfc_mbx_read_config *rd_config;
|
||||
uint32_t rc = 0;
|
||||
union lpfc_sli4_cfg_shdr *shdr;
|
||||
uint32_t shdr_status, shdr_add_status;
|
||||
struct lpfc_mbx_get_func_cfg *get_func_cfg;
|
||||
struct lpfc_rsrc_desc_fcfcoe *desc;
|
||||
uint32_t desc_count;
|
||||
int length, i, rc = 0;
|
||||
|
||||
pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (!pmb) {
|
||||
@ -5855,7 +5925,9 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
|
||||
phba->sli4_hba.max_cfg_param.fcfi_base,
|
||||
phba->sli4_hba.max_cfg_param.max_fcfi);
|
||||
}
|
||||
mempool_free(pmb, phba->mbox_mem_pool);
|
||||
|
||||
if (rc)
|
||||
goto read_cfg_out;
|
||||
|
||||
/* Reset the DFT_HBA_Q_DEPTH to the max xri */
|
||||
if (phba->cfg_hba_queue_depth >
|
||||
@ -5864,6 +5936,65 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
|
||||
phba->cfg_hba_queue_depth =
|
||||
phba->sli4_hba.max_cfg_param.max_xri -
|
||||
lpfc_sli4_get_els_iocb_cnt(phba);
|
||||
|
||||
if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
|
||||
LPFC_SLI_INTF_IF_TYPE_2)
|
||||
goto read_cfg_out;
|
||||
|
||||
/* get the pf# and vf# for SLI4 if_type 2 port */
|
||||
length = (sizeof(struct lpfc_mbx_get_func_cfg) -
|
||||
sizeof(struct lpfc_sli4_cfg_mhdr));
|
||||
lpfc_sli4_config(phba, pmb, LPFC_MBOX_SUBSYSTEM_COMMON,
|
||||
LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG,
|
||||
length, LPFC_SLI4_MBX_EMBED);
|
||||
|
||||
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
|
||||
shdr = (union lpfc_sli4_cfg_shdr *)
|
||||
&pmb->u.mqe.un.sli4_config.header.cfg_shdr;
|
||||
shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
|
||||
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
|
||||
if (rc || shdr_status || shdr_add_status) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"3026 Mailbox failed , mbxCmd x%x "
|
||||
"GET_FUNCTION_CONFIG, mbxStatus x%x\n",
|
||||
bf_get(lpfc_mqe_command, &pmb->u.mqe),
|
||||
bf_get(lpfc_mqe_status, &pmb->u.mqe));
|
||||
rc = -EIO;
|
||||
goto read_cfg_out;
|
||||
}
|
||||
|
||||
/* search for fc_fcoe resrouce descriptor */
|
||||
get_func_cfg = &pmb->u.mqe.un.get_func_cfg;
|
||||
desc_count = get_func_cfg->func_cfg.rsrc_desc_count;
|
||||
|
||||
for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) {
|
||||
desc = (struct lpfc_rsrc_desc_fcfcoe *)
|
||||
&get_func_cfg->func_cfg.desc[i];
|
||||
if (LPFC_RSRC_DESC_TYPE_FCFCOE ==
|
||||
bf_get(lpfc_rsrc_desc_pcie_type, desc)) {
|
||||
phba->sli4_hba.iov.pf_number =
|
||||
bf_get(lpfc_rsrc_desc_fcfcoe_pfnum, desc);
|
||||
phba->sli4_hba.iov.vf_number =
|
||||
bf_get(lpfc_rsrc_desc_fcfcoe_vfnum, desc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < LPFC_RSRC_DESC_MAX_NUM)
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||
"3027 GET_FUNCTION_CONFIG: pf_number:%d, "
|
||||
"vf_number:%d\n", phba->sli4_hba.iov.pf_number,
|
||||
phba->sli4_hba.iov.vf_number);
|
||||
else {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"3028 GET_FUNCTION_CONFIG: failed to find "
|
||||
"Resrouce Descriptor:x%x\n",
|
||||
LPFC_RSRC_DESC_TYPE_FCFCOE);
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
read_cfg_out:
|
||||
mempool_free(pmb, phba->mbox_mem_pool);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -7825,6 +7956,7 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
|
||||
{
|
||||
int wait_cnt = 0;
|
||||
LPFC_MBOXQ_t *mboxq;
|
||||
struct pci_dev *pdev = phba->pcidev;
|
||||
|
||||
lpfc_stop_hba_timers(phba);
|
||||
phba->sli4_hba.intr_enable = 0;
|
||||
@ -7864,6 +7996,10 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
|
||||
/* Disable PCI subsystem interrupt */
|
||||
lpfc_sli4_disable_intr(phba);
|
||||
|
||||
/* Disable SR-IOV if enabled */
|
||||
if (phba->cfg_sriov_nr_virtfn)
|
||||
pci_disable_sriov(pdev);
|
||||
|
||||
/* Stop kthread signal shall trigger work_done one more time */
|
||||
kthread_stop(phba->worker_thread);
|
||||
|
||||
@ -8243,6 +8379,10 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev)
|
||||
|
||||
lpfc_debugfs_terminate(vport);
|
||||
|
||||
/* Disable SR-IOV if enabled */
|
||||
if (phba->cfg_sriov_nr_virtfn)
|
||||
pci_disable_sriov(pdev);
|
||||
|
||||
/* Disable interrupt */
|
||||
lpfc_sli_disable_intr(phba);
|
||||
|
||||
|
Reference in New Issue
Block a user