Commit 912e3acd authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.3.24: Add SR-IOV control

Signed-off-by: default avatarAlex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <jbottomley@parallels.com>
parent c0c11512
......@@ -660,6 +660,7 @@ struct lpfc_hba {
uint32_t cfg_hostmem_hgp;
uint32_t cfg_log_verbose;
uint32_t cfg_aer_support;
uint32_t cfg_sriov_nr_virtfn;
uint32_t cfg_iocb_cnt;
uint32_t cfg_suppress_link_up;
#define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */
......
This diff is collapsed.
......@@ -430,3 +430,5 @@ void lpfc_cleanup_wt_rrqs(struct lpfc_hba *);
void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *);
struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t,
uint32_t);
/* functions to support SR-IOV */
int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int);
......@@ -903,6 +903,8 @@ struct RRQ { /* Structure is in Big Endian format */
#define rrq_rxid_WORD rrq_exchg
};
#define LPFC_MAX_VFN_PER_PFN 255 /* Maximum VFs allowed per ARI */
#define LPFC_DEF_VFN_PER_PFN 0 /* Default VFs due to platform limitation*/
struct RTV_RSP { /* Structure is in Big Endian format */
uint32_t ratov;
......
......@@ -758,6 +758,12 @@ union lpfc_sli4_cfg_shdr {
#define lpfc_mbox_hdr_version_SHIFT 0
#define lpfc_mbox_hdr_version_MASK 0x000000FF
#define lpfc_mbox_hdr_version_WORD word9
#define lpfc_mbox_hdr_pf_num_SHIFT 16
#define lpfc_mbox_hdr_pf_num_MASK 0x000000FF
#define lpfc_mbox_hdr_pf_num_WORD word9
#define lpfc_mbox_hdr_vh_num_SHIFT 24
#define lpfc_mbox_hdr_vh_num_MASK 0x000000FF
#define lpfc_mbox_hdr_vh_num_WORD word9
#define LPFC_Q_CREATE_VERSION_2 2
#define LPFC_Q_CREATE_VERSION_1 1
#define LPFC_Q_CREATE_VERSION_0 0
......@@ -813,6 +819,8 @@ struct mbox_header {
#define LPFC_MBOX_OPCODE_QUERY_FW_CFG 0x3A
#define LPFC_MBOX_OPCODE_FUNCTION_RESET 0x3D
#define LPFC_MBOX_OPCODE_MQ_CREATE_EXT 0x5A
#define LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG 0xA0
#define LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG 0xA4
#define LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS 0xB5
/* FCoE Opcodes */
......@@ -2217,6 +2225,145 @@ struct lpfc_mbx_get_sli4_parameters {
struct lpfc_sli4_parameters sli4_parameters;
};
struct lpfc_rscr_desc_generic {
#define LPFC_RSRC_DESC_WSIZE 18
uint32_t desc[LPFC_RSRC_DESC_WSIZE];
};
struct lpfc_rsrc_desc_pcie {
uint32_t word0;
#define lpfc_rsrc_desc_pcie_type_SHIFT 0
#define lpfc_rsrc_desc_pcie_type_MASK 0x000000ff
#define lpfc_rsrc_desc_pcie_type_WORD word0
#define LPFC_RSRC_DESC_TYPE_PCIE 0x40
uint32_t word1;
#define lpfc_rsrc_desc_pcie_pfnum_SHIFT 0
#define lpfc_rsrc_desc_pcie_pfnum_MASK 0x000000ff
#define lpfc_rsrc_desc_pcie_pfnum_WORD word1
uint32_t reserved;
uint32_t word3;
#define lpfc_rsrc_desc_pcie_sriov_sta_SHIFT 0
#define lpfc_rsrc_desc_pcie_sriov_sta_MASK 0x000000ff
#define lpfc_rsrc_desc_pcie_sriov_sta_WORD word3
#define lpfc_rsrc_desc_pcie_pf_sta_SHIFT 8
#define lpfc_rsrc_desc_pcie_pf_sta_MASK 0x000000ff
#define lpfc_rsrc_desc_pcie_pf_sta_WORD word3
#define lpfc_rsrc_desc_pcie_pf_type_SHIFT 16
#define lpfc_rsrc_desc_pcie_pf_type_MASK 0x000000ff
#define lpfc_rsrc_desc_pcie_pf_type_WORD word3
uint32_t word4;
#define lpfc_rsrc_desc_pcie_nr_virtfn_SHIFT 0
#define lpfc_rsrc_desc_pcie_nr_virtfn_MASK 0x0000ffff
#define lpfc_rsrc_desc_pcie_nr_virtfn_WORD word4
};
struct lpfc_rsrc_desc_fcfcoe {
uint32_t word0;
#define lpfc_rsrc_desc_fcfcoe_type_SHIFT 0
#define lpfc_rsrc_desc_fcfcoe_type_MASK 0x000000ff
#define lpfc_rsrc_desc_fcfcoe_type_WORD word0
#define LPFC_RSRC_DESC_TYPE_FCFCOE 0x43
uint32_t word1;
#define lpfc_rsrc_desc_fcfcoe_vfnum_SHIFT 0
#define lpfc_rsrc_desc_fcfcoe_vfnum_MASK 0x000000ff
#define lpfc_rsrc_desc_fcfcoe_vfnum_WORD word1
#define lpfc_rsrc_desc_fcfcoe_pfnum_SHIFT 16
#define lpfc_rsrc_desc_fcfcoe_pfnum_MASK 0x000007ff
#define lpfc_rsrc_desc_fcfcoe_pfnum_WORD word1
uint32_t word2;
#define lpfc_rsrc_desc_fcfcoe_rpi_cnt_SHIFT 0
#define lpfc_rsrc_desc_fcfcoe_rpi_cnt_MASK 0x0000ffff
#define lpfc_rsrc_desc_fcfcoe_rpi_cnt_WORD word2
#define lpfc_rsrc_desc_fcfcoe_xri_cnt_SHIFT 16
#define lpfc_rsrc_desc_fcfcoe_xri_cnt_MASK 0x0000ffff
#define lpfc_rsrc_desc_fcfcoe_xri_cnt_WORD word2
uint32_t word3;
#define lpfc_rsrc_desc_fcfcoe_wq_cnt_SHIFT 0
#define lpfc_rsrc_desc_fcfcoe_wq_cnt_MASK 0x0000ffff
#define lpfc_rsrc_desc_fcfcoe_wq_cnt_WORD word3
#define lpfc_rsrc_desc_fcfcoe_rq_cnt_SHIFT 16
#define lpfc_rsrc_desc_fcfcoe_rq_cnt_MASK 0x0000ffff
#define lpfc_rsrc_desc_fcfcoe_rq_cnt_WORD word3
uint32_t word4;
#define lpfc_rsrc_desc_fcfcoe_cq_cnt_SHIFT 0
#define lpfc_rsrc_desc_fcfcoe_cq_cnt_MASK 0x0000ffff
#define lpfc_rsrc_desc_fcfcoe_cq_cnt_WORD word4
#define lpfc_rsrc_desc_fcfcoe_vpi_cnt_SHIFT 16
#define lpfc_rsrc_desc_fcfcoe_vpi_cnt_MASK 0x0000ffff
#define lpfc_rsrc_desc_fcfcoe_vpi_cnt_WORD word4
uint32_t word5;
#define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_SHIFT 0
#define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_MASK 0x0000ffff
#define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_WORD word5
#define lpfc_rsrc_desc_fcfcoe_vfi_cnt_SHIFT 16
#define lpfc_rsrc_desc_fcfcoe_vfi_cnt_MASK 0x0000ffff
#define lpfc_rsrc_desc_fcfcoe_vfi_cnt_WORD word5
uint32_t word6;
uint32_t word7;
uint32_t word8;
uint32_t word9;
uint32_t word10;
uint32_t word11;
uint32_t word12;
uint32_t word13;
#define lpfc_rsrc_desc_fcfcoe_lnk_nr_SHIFT 0
#define lpfc_rsrc_desc_fcfcoe_lnk_nr_MASK 0x0000003f
#define lpfc_rsrc_desc_fcfcoe_lnk_nr_WORD word13
#define lpfc_rsrc_desc_fcfcoe_lnk_tp_SHIFT 6
#define lpfc_rsrc_desc_fcfcoe_lnk_tp_MASK 0x00000003
#define lpfc_rsrc_desc_fcfcoe_lnk_tp_WORD word13
#define lpfc_rsrc_desc_fcfcoe_lmc_SHIFT 8
#define lpfc_rsrc_desc_fcfcoe_lmc_MASK 0x00000001
#define lpfc_rsrc_desc_fcfcoe_lmc_WORD word13
#define lpfc_rsrc_desc_fcfcoe_lld_SHIFT 9
#define lpfc_rsrc_desc_fcfcoe_lld_MASK 0x00000001
#define lpfc_rsrc_desc_fcfcoe_lld_WORD word13
#define lpfc_rsrc_desc_fcfcoe_eq_cnt_SHIFT 16
#define lpfc_rsrc_desc_fcfcoe_eq_cnt_MASK 0x0000ffff
#define lpfc_rsrc_desc_fcfcoe_eq_cnt_WORD word13
};
struct lpfc_func_cfg {
#define LPFC_RSRC_DESC_MAX_NUM 2
uint32_t rsrc_desc_count;
struct lpfc_rscr_desc_generic desc[LPFC_RSRC_DESC_MAX_NUM];
};
struct lpfc_mbx_get_func_cfg {
struct mbox_header header;
#define LPFC_CFG_TYPE_PERSISTENT_OVERRIDE 0x0
#define LPFC_CFG_TYPE_FACTURY_DEFAULT 0x1
#define LPFC_CFG_TYPE_CURRENT_ACTIVE 0x2
struct lpfc_func_cfg func_cfg;
};
struct lpfc_prof_cfg {
#define LPFC_RSRC_DESC_MAX_NUM 2
uint32_t rsrc_desc_count;
struct lpfc_rscr_desc_generic desc[LPFC_RSRC_DESC_MAX_NUM];
};
struct lpfc_mbx_get_prof_cfg {
struct mbox_header header;
#define LPFC_CFG_TYPE_PERSISTENT_OVERRIDE 0x0
#define LPFC_CFG_TYPE_FACTURY_DEFAULT 0x1
#define LPFC_CFG_TYPE_CURRENT_ACTIVE 0x2
union {
struct {
uint32_t word10;
#define lpfc_mbx_get_prof_cfg_prof_id_SHIFT 0
#define lpfc_mbx_get_prof_cfg_prof_id_MASK 0x000000ff
#define lpfc_mbx_get_prof_cfg_prof_id_WORD word10
#define lpfc_mbx_get_prof_cfg_prof_tp_SHIFT 8
#define lpfc_mbx_get_prof_cfg_prof_tp_MASK 0x00000003
#define lpfc_mbx_get_prof_cfg_prof_tp_WORD word10
} request;
struct {
struct lpfc_prof_cfg prof_cfg;
} response;
} u;
};
/* Mailbox Completion Queue Error Messages */
#define MB_CQE_STATUS_SUCCESS 0x0
#define MB_CQE_STATUS_INSUFFICIENT_PRIVILEGES 0x1
......@@ -2271,6 +2418,8 @@ struct lpfc_mqe {
struct lpfc_mbx_supp_pages supp_pages;
struct lpfc_mbx_pc_sli4_params sli4_params;
struct lpfc_mbx_get_sli4_parameters get_sli4_parameters;
struct lpfc_mbx_get_func_cfg get_func_cfg;
struct lpfc_mbx_get_prof_cfg get_prof_cfg;
struct lpfc_mbx_nop nop;
} un;
};
......
......@@ -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);
......
......@@ -365,6 +365,11 @@ struct lpfc_pc_sli4_params {
uint8_t rqv;
};
struct lpfc_iov {
uint32_t pf_number;
uint32_t vf_number;
};
/* SLI4 HBA data structure entries */
struct lpfc_sli4_hba {
void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for
......@@ -467,6 +472,7 @@ struct lpfc_sli4_hba {
struct list_head sp_els_xri_aborted_work_queue;
struct list_head sp_unsol_work_queue;
struct lpfc_sli4_link link_state;
struct lpfc_iov iov;
spinlock_t abts_scsi_buf_list_lock; /* list of aborted SCSI IOs */
spinlock_t abts_sgl_list_lock; /* list of aborted els IOs */
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment