scsi: lpfc: NVME Target: Receive buffer updates
NVME Target: Receive buffer updates Allocates buffer pools and configures adapter interfaces to handle receive buffer (asynchronous FCP CMD ius, first burst data) from the adapter. Splits by protocol, etc. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
f358dd0ca2
commit
2d7dbc4c27
|
@ -770,8 +770,11 @@ struct lpfc_hba {
|
|||
uint32_t cfg_suppress_rsp;
|
||||
uint32_t cfg_nvme_oas;
|
||||
uint32_t cfg_nvme_io_channel;
|
||||
uint32_t cfg_nvmet_mrq;
|
||||
uint32_t cfg_nvmet_mrq_post;
|
||||
uint32_t cfg_enable_nvmet;
|
||||
uint32_t cfg_nvme_enable_fb;
|
||||
uint32_t cfg_nvmet_fb_size;
|
||||
uint32_t cfg_total_seg_cnt;
|
||||
uint32_t cfg_sg_seg_cnt;
|
||||
uint32_t cfg_sg_dma_buf_size;
|
||||
|
|
|
@ -58,6 +58,10 @@
|
|||
#define LPFC_MIN_DEVLOSS_TMO 1
|
||||
#define LPFC_MAX_DEVLOSS_TMO 255
|
||||
|
||||
#define LPFC_DEF_MRQ_POST 256
|
||||
#define LPFC_MIN_MRQ_POST 32
|
||||
#define LPFC_MAX_MRQ_POST 512
|
||||
|
||||
/*
|
||||
* Write key size should be multiple of 4. If write key is changed
|
||||
* make sure that library write key is also changed.
|
||||
|
@ -3281,6 +3285,24 @@ static DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
|
|||
LPFC_ATTR_R(suppress_rsp, 1, 0, 1,
|
||||
"Enable suppress rsp feature is firmware supports it");
|
||||
|
||||
/*
|
||||
* lpfc_nvmet_mrq: Specify number of RQ pairs for processing NVMET cmds
|
||||
* lpfc_nvmet_mrq = 1 use a single RQ pair
|
||||
* lpfc_nvmet_mrq >= 2 use specified RQ pairs for MRQ
|
||||
*
|
||||
*/
|
||||
LPFC_ATTR_R(nvmet_mrq,
|
||||
1, 1, 16,
|
||||
"Specify number of RQ pairs for processing NVMET cmds");
|
||||
|
||||
/*
|
||||
* lpfc_nvmet_mrq_post: Specify number buffers to post on every MRQ
|
||||
*
|
||||
*/
|
||||
LPFC_ATTR_R(nvmet_mrq_post, LPFC_DEF_MRQ_POST,
|
||||
LPFC_MIN_MRQ_POST, LPFC_MAX_MRQ_POST,
|
||||
"Specify number of buffers to post on every MRQ");
|
||||
|
||||
/*
|
||||
* lpfc_enable_fc4_type: Defines what FC4 types are supported.
|
||||
* Supported Values: 1 - register just FCP
|
||||
|
@ -4657,13 +4679,28 @@ LPFC_VPORT_ATTR_RW(first_burst_size, 0, 0, 65536,
|
|||
"First burst size for Targets that support first burst");
|
||||
|
||||
/*
|
||||
* lpfc_nvme_enable_fb: Enable NVME first burst on I and T functions.
|
||||
* For the Initiator (I), enabling this parameter means that an NVME
|
||||
* PRLI response with FBA enabled and an FB_SIZE set to a nonzero value
|
||||
* will be processed by the initiator for subsequent NVME FCP IO.
|
||||
* lpfc_nvmet_fb_size: NVME Target mode supported first burst size.
|
||||
* When the driver is configured as an NVME target, this value is
|
||||
* communicated to the NVME initiator in the PRLI response. It is
|
||||
* used only when the lpfc_nvme_enable_fb and lpfc_nvmet_support
|
||||
* parameters are set and the target is sending the PRLI RSP.
|
||||
* Parameter supported on physical port only - no NPIV support.
|
||||
* Value range is [0,1]. Default value is 0 (disabled).
|
||||
* Value range is [0,65536]. Default value is 0.
|
||||
*/
|
||||
LPFC_ATTR_RW(nvmet_fb_size, 0, 0, 65536,
|
||||
"NVME Target mode first burst size in 512B increments.");
|
||||
|
||||
/*
|
||||
* lpfc_nvme_enable_fb: Enable NVME first burst on I and T functions.
|
||||
* For the Initiator (I), enabling this parameter means that an NVMET
|
||||
* PRLI response with FBA enabled and an FB_SIZE set to a nonzero value will be
|
||||
* processed by the initiator for subsequent NVME FCP IO. For the target
|
||||
* function (T), enabling this parameter qualifies the lpfc_nvmet_fb_size
|
||||
* driver parameter as the target function's first burst size returned to the
|
||||
* initiator in the target's NVME PRLI response. Parameter supported on physical
|
||||
* port only - no NPIV support.
|
||||
* Value range is [0,1]. Default value is 0 (disabled).
|
||||
*/
|
||||
LPFC_ATTR_RW(nvme_enable_fb, 0, 0, 1,
|
||||
"Enable First Burst feature on I and T functions.");
|
||||
|
||||
|
@ -5099,7 +5136,10 @@ struct device_attribute *lpfc_hba_attrs[] = {
|
|||
&dev_attr_lpfc_fcp_io_channel,
|
||||
&dev_attr_lpfc_suppress_rsp,
|
||||
&dev_attr_lpfc_nvme_io_channel,
|
||||
&dev_attr_lpfc_nvmet_mrq,
|
||||
&dev_attr_lpfc_nvmet_mrq_post,
|
||||
&dev_attr_lpfc_nvme_enable_fb,
|
||||
&dev_attr_lpfc_nvmet_fb_size,
|
||||
&dev_attr_lpfc_enable_bg,
|
||||
&dev_attr_lpfc_soft_wwnn,
|
||||
&dev_attr_lpfc_soft_wwpn,
|
||||
|
@ -6136,9 +6176,12 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
|
|||
lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp);
|
||||
|
||||
lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type);
|
||||
lpfc_nvmet_mrq_init(phba, lpfc_nvmet_mrq);
|
||||
lpfc_nvmet_mrq_post_init(phba, lpfc_nvmet_mrq_post);
|
||||
|
||||
/* Initialize first burst. Target vs Initiator are different. */
|
||||
lpfc_nvme_enable_fb_init(phba, lpfc_nvme_enable_fb);
|
||||
lpfc_nvmet_fb_size_init(phba, lpfc_nvmet_fb_size);
|
||||
lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel);
|
||||
lpfc_nvme_io_channel_init(phba, lpfc_nvme_io_channel);
|
||||
|
||||
|
@ -6205,9 +6248,35 @@ lpfc_nvme_mod_param_dep(struct lpfc_hba *phba)
|
|||
phba->nvmet_support) {
|
||||
phba->cfg_enable_fc4_type &= ~LPFC_ENABLE_FCP;
|
||||
phba->cfg_fcp_io_channel = 0;
|
||||
} else
|
||||
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
|
||||
"6013 %s x%x fb_size x%x, fb_max x%x\n",
|
||||
"NVME Target PRLI ACC enable_fb ",
|
||||
phba->cfg_nvme_enable_fb,
|
||||
phba->cfg_nvmet_fb_size,
|
||||
LPFC_NVMET_FB_SZ_MAX);
|
||||
|
||||
if (phba->cfg_nvme_enable_fb == 0)
|
||||
phba->cfg_nvmet_fb_size = 0;
|
||||
else {
|
||||
if (phba->cfg_nvmet_fb_size > LPFC_NVMET_FB_SZ_MAX)
|
||||
phba->cfg_nvmet_fb_size = LPFC_NVMET_FB_SZ_MAX;
|
||||
}
|
||||
|
||||
/* Adjust lpfc_nvmet_mrq to avoid running out of WQE slots */
|
||||
if (phba->cfg_nvmet_mrq > phba->cfg_nvme_io_channel) {
|
||||
phba->cfg_nvmet_mrq = phba->cfg_nvme_io_channel;
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC,
|
||||
"6018 Adjust lpfc_nvmet_mrq to %d\n",
|
||||
phba->cfg_nvmet_mrq);
|
||||
}
|
||||
} else {
|
||||
/* Not NVME Target mode. Turn off Target parameters. */
|
||||
phba->nvmet_support = 0;
|
||||
phba->cfg_nvmet_mrq = 0;
|
||||
phba->cfg_nvmet_mrq_post = 0;
|
||||
phba->cfg_nvmet_fb_size = 0;
|
||||
}
|
||||
|
||||
if (phba->cfg_fcp_io_channel > phba->cfg_nvme_io_channel)
|
||||
phba->io_channel_irqs = phba->cfg_fcp_io_channel;
|
||||
|
|
|
@ -229,6 +229,7 @@ void lpfc_reg_vfi(struct lpfcMboxq *, struct lpfc_vport *, dma_addr_t);
|
|||
void lpfc_init_vpi(struct lpfc_hba *, struct lpfcMboxq *, uint16_t);
|
||||
void lpfc_unreg_vfi(struct lpfcMboxq *, struct lpfc_vport *);
|
||||
void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *);
|
||||
void lpfc_reg_fcfi_mrq(struct lpfc_hba *phba, struct lpfcMboxq *mbox, int mode);
|
||||
void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t);
|
||||
void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *);
|
||||
int lpfc_check_pending_fcoe_event(struct lpfc_hba *, uint8_t);
|
||||
|
|
|
@ -2837,7 +2837,7 @@ __lpfc_idiag_print_rqpair(struct lpfc_queue *qp, struct lpfc_queue *datqp,
|
|||
|
||||
static int
|
||||
lpfc_idiag_cqs_for_eq(struct lpfc_hba *phba, char *pbuffer,
|
||||
int *len, int max_cnt, int eq_id)
|
||||
int *len, int max_cnt, int eqidx, int eq_id)
|
||||
{
|
||||
struct lpfc_queue *qp;
|
||||
int qidx, rc;
|
||||
|
@ -2880,6 +2880,27 @@ lpfc_idiag_cqs_for_eq(struct lpfc_hba *phba, char *pbuffer,
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (phba->cfg_nvmet_mrq > eqidx) {
|
||||
/* NVMET CQset */
|
||||
qp = phba->sli4_hba.nvmet_cqset[eqidx];
|
||||
*len = __lpfc_idiag_print_cq(qp, "NVMET CQset", pbuffer, *len);
|
||||
|
||||
/* Reset max counter */
|
||||
qp->CQ_max_cqe = 0;
|
||||
|
||||
if (*len >= max_cnt)
|
||||
return 1;
|
||||
|
||||
/* RQ header */
|
||||
qp = phba->sli4_hba.nvmet_mrq_hdr[eqidx];
|
||||
*len = __lpfc_idiag_print_rqpair(qp,
|
||||
phba->sli4_hba.nvmet_mrq_data[eqidx],
|
||||
"NVMET MRQ", pbuffer, *len);
|
||||
|
||||
if (*len >= max_cnt)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2977,7 +2998,7 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
|
|||
|
||||
/* will dump both fcp and nvme cqs/wqs for the eq */
|
||||
rc = lpfc_idiag_cqs_for_eq(phba, pbuffer, &len,
|
||||
max_cnt, qp->queue_id);
|
||||
max_cnt, x, qp->queue_id);
|
||||
if (rc)
|
||||
goto too_big;
|
||||
|
||||
|
|
|
@ -962,6 +962,7 @@ struct mbox_header {
|
|||
#define LPFC_MBOX_OPCODE_FCOE_DELETE_FCF 0x0A
|
||||
#define LPFC_MBOX_OPCODE_FCOE_POST_HDR_TEMPLATE 0x0B
|
||||
#define LPFC_MBOX_OPCODE_FCOE_REDISCOVER_FCF 0x10
|
||||
#define LPFC_MBOX_OPCODE_FCOE_CQ_CREATE_SET 0x1D
|
||||
#define LPFC_MBOX_OPCODE_FCOE_SET_FCLINK_SETTINGS 0x21
|
||||
#define LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_STATE 0x22
|
||||
#define LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_LOOPBACK 0x23
|
||||
|
@ -1143,6 +1144,116 @@ struct lpfc_mbx_cq_create {
|
|||
} u;
|
||||
};
|
||||
|
||||
struct lpfc_mbx_cq_create_set {
|
||||
union lpfc_sli4_cfg_shdr cfg_shdr;
|
||||
union {
|
||||
struct {
|
||||
uint32_t word0;
|
||||
#define lpfc_mbx_cq_create_set_page_size_SHIFT 16 /* Version 2 Only */
|
||||
#define lpfc_mbx_cq_create_set_page_size_MASK 0x000000FF
|
||||
#define lpfc_mbx_cq_create_set_page_size_WORD word0
|
||||
#define lpfc_mbx_cq_create_set_num_pages_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_num_pages_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_num_pages_WORD word0
|
||||
uint32_t word1;
|
||||
#define lpfc_mbx_cq_create_set_evt_SHIFT 31
|
||||
#define lpfc_mbx_cq_create_set_evt_MASK 0x00000001
|
||||
#define lpfc_mbx_cq_create_set_evt_WORD word1
|
||||
#define lpfc_mbx_cq_create_set_valid_SHIFT 29
|
||||
#define lpfc_mbx_cq_create_set_valid_MASK 0x00000001
|
||||
#define lpfc_mbx_cq_create_set_valid_WORD word1
|
||||
#define lpfc_mbx_cq_create_set_cqe_cnt_SHIFT 27
|
||||
#define lpfc_mbx_cq_create_set_cqe_cnt_MASK 0x00000003
|
||||
#define lpfc_mbx_cq_create_set_cqe_cnt_WORD word1
|
||||
#define lpfc_mbx_cq_create_set_cqe_size_SHIFT 25
|
||||
#define lpfc_mbx_cq_create_set_cqe_size_MASK 0x00000003
|
||||
#define lpfc_mbx_cq_create_set_cqe_size_WORD word1
|
||||
#define lpfc_mbx_cq_create_set_auto_SHIFT 15
|
||||
#define lpfc_mbx_cq_create_set_auto_MASK 0x0000001
|
||||
#define lpfc_mbx_cq_create_set_auto_WORD word1
|
||||
#define lpfc_mbx_cq_create_set_nodelay_SHIFT 14
|
||||
#define lpfc_mbx_cq_create_set_nodelay_MASK 0x00000001
|
||||
#define lpfc_mbx_cq_create_set_nodelay_WORD word1
|
||||
#define lpfc_mbx_cq_create_set_clswm_SHIFT 12
|
||||
#define lpfc_mbx_cq_create_set_clswm_MASK 0x00000003
|
||||
#define lpfc_mbx_cq_create_set_clswm_WORD word1
|
||||
uint32_t word2;
|
||||
#define lpfc_mbx_cq_create_set_arm_SHIFT 31
|
||||
#define lpfc_mbx_cq_create_set_arm_MASK 0x00000001
|
||||
#define lpfc_mbx_cq_create_set_arm_WORD word2
|
||||
#define lpfc_mbx_cq_create_set_num_cq_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_num_cq_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_num_cq_WORD word2
|
||||
uint32_t word3;
|
||||
#define lpfc_mbx_cq_create_set_eq_id1_SHIFT 16
|
||||
#define lpfc_mbx_cq_create_set_eq_id1_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id1_WORD word3
|
||||
#define lpfc_mbx_cq_create_set_eq_id0_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_eq_id0_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id0_WORD word3
|
||||
uint32_t word4;
|
||||
#define lpfc_mbx_cq_create_set_eq_id3_SHIFT 16
|
||||
#define lpfc_mbx_cq_create_set_eq_id3_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id3_WORD word4
|
||||
#define lpfc_mbx_cq_create_set_eq_id2_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_eq_id2_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id2_WORD word4
|
||||
uint32_t word5;
|
||||
#define lpfc_mbx_cq_create_set_eq_id5_SHIFT 16
|
||||
#define lpfc_mbx_cq_create_set_eq_id5_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id5_WORD word5
|
||||
#define lpfc_mbx_cq_create_set_eq_id4_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_eq_id4_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id4_WORD word5
|
||||
uint32_t word6;
|
||||
#define lpfc_mbx_cq_create_set_eq_id7_SHIFT 16
|
||||
#define lpfc_mbx_cq_create_set_eq_id7_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id7_WORD word6
|
||||
#define lpfc_mbx_cq_create_set_eq_id6_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_eq_id6_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id6_WORD word6
|
||||
uint32_t word7;
|
||||
#define lpfc_mbx_cq_create_set_eq_id9_SHIFT 16
|
||||
#define lpfc_mbx_cq_create_set_eq_id9_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id9_WORD word7
|
||||
#define lpfc_mbx_cq_create_set_eq_id8_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_eq_id8_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id8_WORD word7
|
||||
uint32_t word8;
|
||||
#define lpfc_mbx_cq_create_set_eq_id11_SHIFT 16
|
||||
#define lpfc_mbx_cq_create_set_eq_id11_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id11_WORD word8
|
||||
#define lpfc_mbx_cq_create_set_eq_id10_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_eq_id10_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id10_WORD word8
|
||||
uint32_t word9;
|
||||
#define lpfc_mbx_cq_create_set_eq_id13_SHIFT 16
|
||||
#define lpfc_mbx_cq_create_set_eq_id13_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id13_WORD word9
|
||||
#define lpfc_mbx_cq_create_set_eq_id12_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_eq_id12_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id12_WORD word9
|
||||
uint32_t word10;
|
||||
#define lpfc_mbx_cq_create_set_eq_id15_SHIFT 16
|
||||
#define lpfc_mbx_cq_create_set_eq_id15_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id15_WORD word10
|
||||
#define lpfc_mbx_cq_create_set_eq_id14_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_eq_id14_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_eq_id14_WORD word10
|
||||
struct dma_address page[1];
|
||||
} request;
|
||||
struct {
|
||||
uint32_t word0;
|
||||
#define lpfc_mbx_cq_create_set_num_alloc_SHIFT 16
|
||||
#define lpfc_mbx_cq_create_set_num_alloc_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_num_alloc_WORD word0
|
||||
#define lpfc_mbx_cq_create_set_base_id_SHIFT 0
|
||||
#define lpfc_mbx_cq_create_set_base_id_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_cq_create_set_base_id_WORD word0
|
||||
} response;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct lpfc_mbx_cq_destroy {
|
||||
struct mbox_header header;
|
||||
union {
|
||||
|
@ -1252,10 +1363,10 @@ struct rq_context {
|
|||
#define LPFC_RQ_RING_SIZE_1024 10 /* 1024 entries */
|
||||
#define LPFC_RQ_RING_SIZE_2048 11 /* 2048 entries */
|
||||
#define LPFC_RQ_RING_SIZE_4096 12 /* 4096 entries */
|
||||
#define lpfc_rq_context_rqe_count_1_SHIFT 16 /* Version 1 Only */
|
||||
#define lpfc_rq_context_rqe_count_1_SHIFT 16 /* Version 1-2 Only */
|
||||
#define lpfc_rq_context_rqe_count_1_MASK 0x0000FFFF
|
||||
#define lpfc_rq_context_rqe_count_1_WORD word0
|
||||
#define lpfc_rq_context_rqe_size_SHIFT 8 /* Version 1 Only */
|
||||
#define lpfc_rq_context_rqe_size_SHIFT 8 /* Version 1-2 Only */
|
||||
#define lpfc_rq_context_rqe_size_MASK 0x0000000F
|
||||
#define lpfc_rq_context_rqe_size_WORD word0
|
||||
#define LPFC_RQE_SIZE_8 2
|
||||
|
@ -1267,7 +1378,13 @@ struct rq_context {
|
|||
#define lpfc_rq_context_page_size_MASK 0x000000FF
|
||||
#define lpfc_rq_context_page_size_WORD word0
|
||||
#define LPFC_RQ_PAGE_SIZE_4096 0x1
|
||||
uint32_t reserved1;
|
||||
uint32_t word1;
|
||||
#define lpfc_rq_context_data_size_SHIFT 16 /* Version 2 Only */
|
||||
#define lpfc_rq_context_data_size_MASK 0x0000FFFF
|
||||
#define lpfc_rq_context_data_size_WORD word1
|
||||
#define lpfc_rq_context_hdr_size_SHIFT 0 /* Version 2 Only */
|
||||
#define lpfc_rq_context_hdr_size_MASK 0x0000FFFF
|
||||
#define lpfc_rq_context_hdr_size_WORD word1
|
||||
uint32_t word2;
|
||||
#define lpfc_rq_context_cq_id_SHIFT 16
|
||||
#define lpfc_rq_context_cq_id_MASK 0x000003FF
|
||||
|
@ -1275,6 +1392,9 @@ struct rq_context {
|
|||
#define lpfc_rq_context_buf_size_SHIFT 0
|
||||
#define lpfc_rq_context_buf_size_MASK 0x0000FFFF
|
||||
#define lpfc_rq_context_buf_size_WORD word2
|
||||
#define lpfc_rq_context_base_cq_SHIFT 0 /* Version 2 Only */
|
||||
#define lpfc_rq_context_base_cq_MASK 0x0000FFFF
|
||||
#define lpfc_rq_context_base_cq_WORD word2
|
||||
uint32_t buffer_size; /* Version 1 Only */
|
||||
};
|
||||
|
||||
|
@ -1296,10 +1416,65 @@ struct lpfc_mbx_rq_create {
|
|||
#define lpfc_mbx_rq_create_ulp_num_MASK 0x000000FF
|
||||
#define lpfc_mbx_rq_create_ulp_num_WORD word0
|
||||
struct rq_context context;
|
||||
struct dma_address page[LPFC_MAX_WQ_PAGE];
|
||||
struct dma_address page[LPFC_MAX_RQ_PAGE];
|
||||
} request;
|
||||
struct {
|
||||
uint32_t word0;
|
||||
#define lpfc_mbx_rq_create_q_cnt_v2_SHIFT 16
|
||||
#define lpfc_mbx_rq_create_q_cnt_v2_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rq_create_q_cnt_v2_WORD word0
|
||||
#define lpfc_mbx_rq_create_q_id_SHIFT 0
|
||||
#define lpfc_mbx_rq_create_q_id_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rq_create_q_id_WORD word0
|
||||
uint32_t doorbell_offset;
|
||||
uint32_t word2;
|
||||
#define lpfc_mbx_rq_create_bar_set_SHIFT 0
|
||||
#define lpfc_mbx_rq_create_bar_set_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rq_create_bar_set_WORD word2
|
||||
#define lpfc_mbx_rq_create_db_format_SHIFT 16
|
||||
#define lpfc_mbx_rq_create_db_format_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rq_create_db_format_WORD word2
|
||||
} response;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct lpfc_mbx_rq_create_v2 {
|
||||
union lpfc_sli4_cfg_shdr cfg_shdr;
|
||||
union {
|
||||
struct {
|
||||
uint32_t word0;
|
||||
#define lpfc_mbx_rq_create_num_pages_SHIFT 0
|
||||
#define lpfc_mbx_rq_create_num_pages_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rq_create_num_pages_WORD word0
|
||||
#define lpfc_mbx_rq_create_rq_cnt_SHIFT 16
|
||||
#define lpfc_mbx_rq_create_rq_cnt_MASK 0x000000FF
|
||||
#define lpfc_mbx_rq_create_rq_cnt_WORD word0
|
||||
#define lpfc_mbx_rq_create_dua_SHIFT 16
|
||||
#define lpfc_mbx_rq_create_dua_MASK 0x00000001
|
||||
#define lpfc_mbx_rq_create_dua_WORD word0
|
||||
#define lpfc_mbx_rq_create_bqu_SHIFT 17
|
||||
#define lpfc_mbx_rq_create_bqu_MASK 0x00000001
|
||||
#define lpfc_mbx_rq_create_bqu_WORD word0
|
||||
#define lpfc_mbx_rq_create_ulp_num_SHIFT 24
|
||||
#define lpfc_mbx_rq_create_ulp_num_MASK 0x000000FF
|
||||
#define lpfc_mbx_rq_create_ulp_num_WORD word0
|
||||
#define lpfc_mbx_rq_create_dim_SHIFT 29
|
||||
#define lpfc_mbx_rq_create_dim_MASK 0x00000001
|
||||
#define lpfc_mbx_rq_create_dim_WORD word0
|
||||
#define lpfc_mbx_rq_create_dfd_SHIFT 30
|
||||
#define lpfc_mbx_rq_create_dfd_MASK 0x00000001
|
||||
#define lpfc_mbx_rq_create_dfd_WORD word0
|
||||
#define lpfc_mbx_rq_create_dnb_SHIFT 31
|
||||
#define lpfc_mbx_rq_create_dnb_MASK 0x00000001
|
||||
#define lpfc_mbx_rq_create_dnb_WORD word0
|
||||
struct rq_context context;
|
||||
struct dma_address page[1];
|
||||
} request;
|
||||
struct {
|
||||
uint32_t word0;
|
||||
#define lpfc_mbx_rq_create_q_cnt_v2_SHIFT 16
|
||||
#define lpfc_mbx_rq_create_q_cnt_v2_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rq_create_q_cnt_v2_WORD word0
|
||||
#define lpfc_mbx_rq_create_q_id_SHIFT 0
|
||||
#define lpfc_mbx_rq_create_q_id_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rq_create_q_id_WORD word0
|
||||
|
@ -2213,6 +2388,160 @@ struct lpfc_mbx_reg_fcfi {
|
|||
#define lpfc_reg_fcfi_vlan_tag_WORD word8
|
||||
};
|
||||
|
||||
struct lpfc_mbx_reg_fcfi_mrq {
|
||||
uint32_t word1;
|
||||
#define lpfc_reg_fcfi_mrq_info_index_SHIFT 0
|
||||
#define lpfc_reg_fcfi_mrq_info_index_MASK 0x0000FFFF
|
||||
#define lpfc_reg_fcfi_mrq_info_index_WORD word1
|
||||
#define lpfc_reg_fcfi_mrq_fcfi_SHIFT 16
|
||||
#define lpfc_reg_fcfi_mrq_fcfi_MASK 0x0000FFFF
|
||||
#define lpfc_reg_fcfi_mrq_fcfi_WORD word1
|
||||
uint32_t word2;
|
||||
#define lpfc_reg_fcfi_mrq_rq_id1_SHIFT 0
|
||||
#define lpfc_reg_fcfi_mrq_rq_id1_MASK 0x0000FFFF
|
||||
#define lpfc_reg_fcfi_mrq_rq_id1_WORD word2
|
||||
#define lpfc_reg_fcfi_mrq_rq_id0_SHIFT 16
|
||||
#define lpfc_reg_fcfi_mrq_rq_id0_MASK 0x0000FFFF
|
||||
#define lpfc_reg_fcfi_mrq_rq_id0_WORD word2
|
||||
uint32_t word3;
|
||||
#define lpfc_reg_fcfi_mrq_rq_id3_SHIFT 0
|
||||
#define lpfc_reg_fcfi_mrq_rq_id3_MASK 0x0000FFFF
|
||||
#define lpfc_reg_fcfi_mrq_rq_id3_WORD word3
|
||||
#define lpfc_reg_fcfi_mrq_rq_id2_SHIFT 16
|
||||
#define lpfc_reg_fcfi_mrq_rq_id2_MASK 0x0000FFFF
|
||||
#define lpfc_reg_fcfi_mrq_rq_id2_WORD word3
|
||||
uint32_t word4;
|
||||
#define lpfc_reg_fcfi_mrq_type_match0_SHIFT 24
|
||||
#define lpfc_reg_fcfi_mrq_type_match0_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_type_match0_WORD word4
|
||||
#define lpfc_reg_fcfi_mrq_type_mask0_SHIFT 16
|
||||
#define lpfc_reg_fcfi_mrq_type_mask0_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_type_mask0_WORD word4
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match0_SHIFT 8
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match0_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match0_WORD word4
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask0_SHIFT 0
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask0_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask0_WORD word4
|
||||
uint32_t word5;
|
||||
#define lpfc_reg_fcfi_mrq_type_match1_SHIFT 24
|
||||
#define lpfc_reg_fcfi_mrq_type_match1_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_type_match1_WORD word5
|
||||
#define lpfc_reg_fcfi_mrq_type_mask1_SHIFT 16
|
||||
#define lpfc_reg_fcfi_mrq_type_mask1_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_type_mask1_WORD word5
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match1_SHIFT 8
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match1_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match1_WORD word5
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask1_SHIFT 0
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask1_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask1_WORD word5
|
||||
uint32_t word6;
|
||||
#define lpfc_reg_fcfi_mrq_type_match2_SHIFT 24
|
||||
#define lpfc_reg_fcfi_mrq_type_match2_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_type_match2_WORD word6
|
||||
#define lpfc_reg_fcfi_mrq_type_mask2_SHIFT 16
|
||||
#define lpfc_reg_fcfi_mrq_type_mask2_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_type_mask2_WORD word6
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match2_SHIFT 8
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match2_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match2_WORD word6
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask2_SHIFT 0
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask2_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask2_WORD word6
|
||||
uint32_t word7;
|
||||
#define lpfc_reg_fcfi_mrq_type_match3_SHIFT 24
|
||||
#define lpfc_reg_fcfi_mrq_type_match3_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_type_match3_WORD word7
|
||||
#define lpfc_reg_fcfi_mrq_type_mask3_SHIFT 16
|
||||
#define lpfc_reg_fcfi_mrq_type_mask3_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_type_mask3_WORD word7
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match3_SHIFT 8
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match3_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_rctl_match3_WORD word7
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask3_SHIFT 0
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask3_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_rctl_mask3_WORD word7
|
||||
uint32_t word8;
|
||||
#define lpfc_reg_fcfi_mrq_ptc7_SHIFT 31
|
||||
#define lpfc_reg_fcfi_mrq_ptc7_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_ptc7_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_ptc6_SHIFT 30
|
||||
#define lpfc_reg_fcfi_mrq_ptc6_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_ptc6_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_ptc5_SHIFT 29
|
||||
#define lpfc_reg_fcfi_mrq_ptc5_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_ptc5_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_ptc4_SHIFT 28
|
||||
#define lpfc_reg_fcfi_mrq_ptc4_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_ptc4_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_ptc3_SHIFT 27
|
||||
#define lpfc_reg_fcfi_mrq_ptc3_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_ptc3_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_ptc2_SHIFT 26
|
||||
#define lpfc_reg_fcfi_mrq_ptc2_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_ptc2_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_ptc1_SHIFT 25
|
||||
#define lpfc_reg_fcfi_mrq_ptc1_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_ptc1_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_ptc0_SHIFT 24
|
||||
#define lpfc_reg_fcfi_mrq_ptc0_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_ptc0_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_pt7_SHIFT 23
|
||||
#define lpfc_reg_fcfi_mrq_pt7_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_pt7_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_pt6_SHIFT 22
|
||||
#define lpfc_reg_fcfi_mrq_pt6_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_pt6_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_pt5_SHIFT 21
|
||||
#define lpfc_reg_fcfi_mrq_pt5_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_pt5_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_pt4_SHIFT 20
|
||||
#define lpfc_reg_fcfi_mrq_pt4_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_pt4_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_pt3_SHIFT 19
|
||||
#define lpfc_reg_fcfi_mrq_pt3_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_pt3_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_pt2_SHIFT 18
|
||||
#define lpfc_reg_fcfi_mrq_pt2_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_pt2_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_pt1_SHIFT 17
|
||||
#define lpfc_reg_fcfi_mrq_pt1_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_pt1_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_pt0_SHIFT 16
|
||||
#define lpfc_reg_fcfi_mrq_pt0_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_pt0_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_xmv_SHIFT 15
|
||||
#define lpfc_reg_fcfi_mrq_xmv_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_xmv_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_mode_SHIFT 13
|
||||
#define lpfc_reg_fcfi_mrq_mode_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_mode_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_vv_SHIFT 12
|
||||
#define lpfc_reg_fcfi_mrq_vv_MASK 0x00000001
|
||||
#define lpfc_reg_fcfi_mrq_vv_WORD word8
|
||||
#define lpfc_reg_fcfi_mrq_vlan_tag_SHIFT 0
|
||||
#define lpfc_reg_fcfi_mrq_vlan_tag_MASK 0x00000FFF
|
||||
#define lpfc_reg_fcfi_mrq_vlan_tag_WORD word8
|
||||
uint32_t word9;
|
||||
#define lpfc_reg_fcfi_mrq_policy_SHIFT 12
|
||||
#define lpfc_reg_fcfi_mrq_policy_MASK 0x0000000F
|
||||
#define lpfc_reg_fcfi_mrq_policy_WORD word9
|
||||
#define lpfc_reg_fcfi_mrq_filter_SHIFT 8
|
||||
#define lpfc_reg_fcfi_mrq_filter_MASK 0x0000000F
|
||||
#define lpfc_reg_fcfi_mrq_filter_WORD word9
|
||||
#define lpfc_reg_fcfi_mrq_npairs_SHIFT 0
|
||||
#define lpfc_reg_fcfi_mrq_npairs_MASK 0x000000FF
|
||||
#define lpfc_reg_fcfi_mrq_npairs_WORD word9
|
||||
uint32_t word10;
|
||||
uint32_t word11;
|
||||
uint32_t word12;
|
||||
uint32_t word13;
|
||||
uint32_t word14;
|
||||
uint32_t word15;
|
||||
uint32_t word16;
|
||||
};
|
||||
|
||||
struct lpfc_mbx_unreg_fcfi {
|
||||
uint32_t word1_rsv;
|
||||
uint32_t word2;
|
||||
|
@ -2392,6 +2721,9 @@ struct lpfc_mbx_request_features {
|
|||
#define lpfc_mbx_rq_ftr_rq_perfh_SHIFT 11
|
||||
#define lpfc_mbx_rq_ftr_rq_perfh_MASK 0x00000001
|
||||
#define lpfc_mbx_rq_ftr_rq_perfh_WORD word2
|
||||
#define lpfc_mbx_rq_ftr_rq_mrqp_SHIFT 16
|
||||
#define lpfc_mbx_rq_ftr_rq_mrqp_MASK 0x00000001
|
||||
#define lpfc_mbx_rq_ftr_rq_mrqp_WORD word2
|
||||
uint32_t word3;
|
||||
#define lpfc_mbx_rq_ftr_rsp_iaab_SHIFT 0
|
||||
#define lpfc_mbx_rq_ftr_rsp_iaab_MASK 0x00000001
|
||||
|
@ -2420,6 +2752,9 @@ struct lpfc_mbx_request_features {
|
|||
#define lpfc_mbx_rq_ftr_rsp_perfh_SHIFT 11
|
||||
#define lpfc_mbx_rq_ftr_rsp_perfh_MASK 0x00000001
|
||||
#define lpfc_mbx_rq_ftr_rsp_perfh_WORD word3
|
||||
#define lpfc_mbx_rq_ftr_rsp_mrqp_SHIFT 16
|
||||
#define lpfc_mbx_rq_ftr_rsp_mrqp_MASK 0x00000001
|
||||
#define lpfc_mbx_rq_ftr_rsp_mrqp_WORD word3
|
||||
};
|
||||
|
||||
struct lpfc_mbx_supp_pages {
|
||||
|
@ -3312,14 +3647,17 @@ struct lpfc_mqe {
|
|||
struct lpfc_mbx_del_fcf_tbl_entry del_fcf_entry;
|
||||
struct lpfc_mbx_redisc_fcf_tbl redisc_fcf_tbl;
|
||||
struct lpfc_mbx_reg_fcfi reg_fcfi;
|
||||
struct lpfc_mbx_reg_fcfi_mrq reg_fcfi_mrq;
|
||||
struct lpfc_mbx_unreg_fcfi unreg_fcfi;
|
||||
struct lpfc_mbx_mq_create mq_create;
|
||||
struct lpfc_mbx_mq_create_ext mq_create_ext;
|
||||
struct lpfc_mbx_eq_create eq_create;
|
||||
struct lpfc_mbx_modify_eq_delay eq_delay;
|
||||
struct lpfc_mbx_cq_create cq_create;
|
||||
struct lpfc_mbx_cq_create_set cq_create_set;
|
||||
struct lpfc_mbx_wq_create wq_create;
|
||||
struct lpfc_mbx_rq_create rq_create;
|
||||
struct lpfc_mbx_rq_create_v2 rq_create_v2;
|
||||
struct lpfc_mbx_mq_destroy mq_destroy;
|
||||
struct lpfc_mbx_eq_destroy eq_destroy;
|
||||
struct lpfc_mbx_cq_destroy cq_destroy;
|
||||
|
@ -3972,6 +4310,7 @@ struct lpfc_nvme_prli {
|
|||
#define prli_fb_sz_SHIFT 0
|
||||
#define prli_fb_sz_MASK 0x0000ffff
|
||||
#define prli_fb_sz_WORD word5
|
||||
#define LPFC_NVMET_FB_SZ_MAX 65536 /* Driver target mode only. */
|
||||
};
|
||||
|
||||
struct create_xri_wqe {
|
||||
|
|
|
@ -3354,8 +3354,15 @@ lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba)
|
|||
* update on pci function's nvmet xri-sgl list
|
||||
*/
|
||||
els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);
|
||||
nvmet_xri_cnt = 0;
|
||||
nvmet_xri_cnt = phba->cfg_nvmet_mrq * phba->cfg_nvmet_mrq_post;
|
||||
tot_cnt = phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt;
|
||||
if (nvmet_xri_cnt > tot_cnt) {
|
||||
phba->cfg_nvmet_mrq_post = tot_cnt / phba->cfg_nvmet_mrq;
|
||||
nvmet_xri_cnt = phba->cfg_nvmet_mrq * phba->cfg_nvmet_mrq_post;
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||
"6301 NVMET post-sgl count changed to %d\n",
|
||||
phba->cfg_nvmet_mrq_post);
|
||||
}
|
||||
|
||||
if (nvmet_xri_cnt > phba->sli4_hba.nvmet_xri_cnt) {
|
||||
/* els xri-sgl expanded */
|
||||
|
@ -7674,11 +7681,13 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba)
|
|||
phba->cfg_fcp_io_channel = io_channel;
|
||||
if (phba->cfg_nvme_io_channel > io_channel)
|
||||
phba->cfg_nvme_io_channel = io_channel;
|
||||
if (phba->cfg_nvme_io_channel < phba->cfg_nvmet_mrq)
|
||||
phba->cfg_nvmet_mrq = phba->cfg_nvme_io_channel;
|
||||
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"2574 IO channels: irqs %d fcp %d nvme %d\n",
|
||||
"2574 IO channels: irqs %d fcp %d nvme %d MRQ: %d\n",
|
||||
phba->io_channel_irqs, phba->cfg_fcp_io_channel,
|
||||
phba->cfg_nvme_io_channel);
|
||||
phba->cfg_nvme_io_channel, phba->cfg_nvmet_mrq);
|
||||
|
||||
/* Get EQ depth from module parameter, fake the default for now */
|
||||
phba->sli4_hba.eq_esize = LPFC_EQE_SIZE_4B;
|
||||
|
@ -7768,7 +7777,7 @@ int
|
|||
lpfc_sli4_queue_create(struct lpfc_hba *phba)
|
||||
{
|
||||
struct lpfc_queue *qdesc;
|
||||
int idx, io_channel;
|
||||
int idx, io_channel, max;
|
||||
|
||||
/*
|
||||
* Create HBA Record arrays.
|
||||
|
@ -7845,7 +7854,6 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
|
|||
goto out_error;
|
||||
}
|
||||
|
||||
|
||||
phba->sli4_hba.nvme_wq = kcalloc(phba->cfg_nvme_io_channel,
|
||||
sizeof(struct lpfc_queue *),
|
||||
GFP_KERNEL);
|
||||
|
@ -7870,6 +7878,39 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
|
|||
"fast-path CQ map\n");
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
if (phba->nvmet_support) {
|
||||
phba->sli4_hba.nvmet_cqset = kcalloc(
|
||||
phba->cfg_nvmet_mrq,
|
||||
sizeof(struct lpfc_queue *),
|
||||
GFP_KERNEL);
|
||||
if (!phba->sli4_hba.nvmet_cqset) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"3121 Fail allocate memory for "
|
||||
"fast-path CQ set array\n");
|
||||
goto out_error;
|
||||
}
|
||||
phba->sli4_hba.nvmet_mrq_hdr = kcalloc(
|
||||
phba->cfg_nvmet_mrq,
|
||||
sizeof(struct lpfc_queue *),
|
||||
GFP_KERNEL);
|
||||
if (!phba->sli4_hba.nvmet_mrq_hdr) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"3122 Fail allocate memory for "
|
||||
"fast-path RQ set hdr array\n");
|
||||
goto out_error;
|
||||
}
|
||||
phba->sli4_hba.nvmet_mrq_data = kcalloc(
|
||||
phba->cfg_nvmet_mrq,
|
||||
sizeof(struct lpfc_queue *),
|
||||
GFP_KERNEL);
|
||||
if (!phba->sli4_hba.nvmet_mrq_data) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"3124 Fail allocate memory for "
|
||||
"fast-path RQ set data array\n");
|
||||
goto out_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_wq_list);
|
||||
|
@ -7897,6 +7938,30 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
|
|||
if (lpfc_alloc_nvme_wq_cq(phba, idx))
|
||||
goto out_error;
|
||||
|
||||
/* allocate MRQ CQs */
|
||||
max = phba->cfg_nvme_io_channel;
|
||||
if (max < phba->cfg_nvmet_mrq)
|
||||
max = phba->cfg_nvmet_mrq;
|
||||
|
||||
for (idx = 0; idx < max; idx++)
|
||||
if (lpfc_alloc_nvme_wq_cq(phba, idx))
|
||||
goto out_error;
|
||||
|
||||
if (phba->nvmet_support) {
|
||||
for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) {
|
||||
qdesc = lpfc_sli4_queue_alloc(phba,
|
||||
phba->sli4_hba.cq_esize,
|
||||
phba->sli4_hba.cq_ecount);
|
||||
if (!qdesc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"3142 Failed allocate NVME "
|
||||
"CQ Set (%d)\n", idx);
|
||||
goto out_error;
|
||||
}
|
||||
phba->sli4_hba.nvmet_cqset[idx] = qdesc;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create Slow Path Completion Queues (CQs)
|
||||
*/
|
||||
|
@ -7999,6 +8064,44 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
|
|||
}
|
||||
phba->sli4_hba.dat_rq = qdesc;
|
||||
|
||||
if (phba->nvmet_support) {
|
||||
for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) {
|
||||
/* Create NVMET Receive Queue for header */
|
||||
qdesc = lpfc_sli4_queue_alloc(phba,
|
||||
phba->sli4_hba.rq_esize,
|
||||
phba->sli4_hba.rq_ecount);
|
||||
if (!qdesc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"3146 Failed allocate "
|
||||
"receive HRQ\n");
|
||||
goto out_error;
|
||||
}
|
||||
phba->sli4_hba.nvmet_mrq_hdr[idx] = qdesc;
|
||||
|
||||
/* Only needed for header of RQ pair */
|
||||
qdesc->rqbp = kzalloc(sizeof(struct lpfc_rqb),
|
||||
GFP_KERNEL);
|
||||
if (qdesc->rqbp == NULL) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"6131 Failed allocate "
|
||||
"Header RQBP\n");
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
/* Create NVMET Receive Queue for data */
|
||||
qdesc = lpfc_sli4_queue_alloc(phba,
|
||||
phba->sli4_hba.rq_esize,
|
||||
phba->sli4_hba.rq_ecount);
|
||||
if (!qdesc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"3156 Failed allocate "
|
||||
"receive DRQ\n");
|
||||
goto out_error;
|
||||
}
|
||||
phba->sli4_hba.nvmet_mrq_data[idx] = qdesc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the Queues needed for Flash Optimized Fabric operations */
|
||||
if (phba->cfg_fof)
|
||||
lpfc_fof_queue_create(phba);
|
||||
|
@ -8085,6 +8188,14 @@ lpfc_sli4_queue_destroy(struct lpfc_hba *phba)
|
|||
/* Release NVME CQ mapping array */
|
||||
lpfc_sli4_release_queue_map(&phba->sli4_hba.nvme_cq_map);
|
||||
|
||||
lpfc_sli4_release_queues(&phba->sli4_hba.nvmet_cqset,
|
||||
phba->cfg_nvmet_mrq);
|
||||
|
||||
lpfc_sli4_release_queues(&phba->sli4_hba.nvmet_mrq_hdr,
|
||||
phba->cfg_nvmet_mrq);
|
||||
lpfc_sli4_release_queues(&phba->sli4_hba.nvmet_mrq_data,
|
||||
phba->cfg_nvmet_mrq);
|
||||
|
||||
/* Release mailbox command work queue */
|
||||
__lpfc_sli4_release_queue(&phba->sli4_hba.mbx_wq);
|
||||
|
||||
|
@ -8422,6 +8533,44 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
|
|||
(uint32_t)rc);
|
||||
goto out_destroy;
|
||||
}
|
||||
if (phba->nvmet_support) {
|
||||
if (!phba->sli4_hba.nvmet_cqset) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"3165 Fast-path NVME CQ Set "
|
||||
"array not allocated\n");
|
||||
rc = -ENOMEM;
|
||||
goto out_destroy;
|
||||
}
|
||||
if (phba->cfg_nvmet_mrq > 1) {
|
||||
rc = lpfc_cq_create_set(phba,
|
||||
phba->sli4_hba.nvmet_cqset,
|
||||
phba->sli4_hba.hba_eq,
|
||||
LPFC_WCQ, LPFC_NVMET);
|
||||
if (rc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"3164 Failed setup of NVME CQ "
|
||||
"Set, rc = 0x%x\n",
|
||||
(uint32_t)rc);
|
||||
goto out_destroy;
|
||||
}
|
||||
} else {
|
||||
/* Set up NVMET Receive Complete Queue */
|
||||
rc = lpfc_cq_create(phba, phba->sli4_hba.nvmet_cqset[0],
|
||||
phba->sli4_hba.hba_eq[0],
|
||||
LPFC_WCQ, LPFC_NVMET);
|
||||
if (rc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"6089 Failed setup NVMET CQ: "
|
||||
"rc = 0x%x\n", (uint32_t)rc);
|
||||
goto out_destroy;
|
||||
}
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
"6090 NVMET CQ setup: cq-id=%d, "
|
||||
"parent eq-id=%d\n",
|
||||
phba->sli4_hba.nvmet_cqset[0]->queue_id,
|
||||
phba->sli4_hba.hba_eq[0]->queue_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up slow-path ELS WQ/CQ */
|
||||
if (!phba->sli4_hba.els_cq || !phba->sli4_hba.els_wq) {
|
||||
|
@ -8473,6 +8622,58 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
|
|||
phba->sli4_hba.nvmels_cq->queue_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create NVMET Receive Queue (RQ)
|
||||
*/
|
||||
if (phba->nvmet_support) {
|
||||
if ((!phba->sli4_hba.nvmet_cqset) ||
|
||||
(!phba->sli4_hba.nvmet_mrq_hdr) ||
|
||||
(!phba->sli4_hba.nvmet_mrq_data)) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"6130 MRQ CQ Queues not "
|
||||
"allocated\n");
|
||||
rc = -ENOMEM;
|
||||
goto out_destroy;
|
||||
}
|
||||
if (phba->cfg_nvmet_mrq > 1) {
|
||||
rc = lpfc_mrq_create(phba,
|
||||
phba->sli4_hba.nvmet_mrq_hdr,
|
||||
phba->sli4_hba.nvmet_mrq_data,
|
||||
phba->sli4_hba.nvmet_cqset,
|
||||
LPFC_NVMET);
|
||||
if (rc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"6098 Failed setup of NVMET "
|
||||
"MRQ: rc = 0x%x\n",
|
||||
(uint32_t)rc);
|
||||
goto out_destroy;
|
||||
}
|
||||
|
||||
} else {
|
||||
rc = lpfc_rq_create(phba,
|
||||
phba->sli4_hba.nvmet_mrq_hdr[0],
|
||||
phba->sli4_hba.nvmet_mrq_data[0],
|
||||
phba->sli4_hba.nvmet_cqset[0],
|
||||
LPFC_NVMET);
|
||||
if (rc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"6057 Failed setup of NVMET "
|
||||
"Receive Queue: rc = 0x%x\n",
|
||||
(uint32_t)rc);
|
||||
goto out_destroy;
|
||||
}
|
||||
|
||||
lpfc_printf_log(
|
||||
phba, KERN_INFO, LOG_INIT,
|
||||
"6099 NVMET RQ setup: hdr-rq-id=%d, "
|
||||
"dat-rq-id=%d parent cq-id=%d\n",
|
||||
phba->sli4_hba.nvmet_mrq_hdr[0]->queue_id,
|
||||
phba->sli4_hba.nvmet_mrq_data[0]->queue_id,
|
||||
phba->sli4_hba.nvmet_cqset[0]->queue_id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!phba->sli4_hba.hdr_rq || !phba->sli4_hba.dat_rq) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"0540 Receive Queue not allocated\n");
|
||||
|
@ -8589,6 +8790,21 @@ lpfc_sli4_queue_unset(struct lpfc_hba *phba)
|
|||
for (qidx = 0; qidx < phba->cfg_nvme_io_channel; qidx++)
|
||||
lpfc_cq_destroy(phba, phba->sli4_hba.nvme_cq[qidx]);
|
||||
|
||||
/* Unset NVMET MRQ queue */
|
||||
if (phba->sli4_hba.nvmet_mrq_hdr) {
|
||||
for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++)
|
||||
lpfc_rq_destroy(phba,
|
||||
phba->sli4_hba.nvmet_mrq_hdr[qidx],
|
||||
phba->sli4_hba.nvmet_mrq_data[qidx]);
|
||||
}
|
||||
|
||||
/* Unset NVMET CQ Set complete queue */
|
||||
if (phba->sli4_hba.nvmet_cqset) {
|
||||
for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++)
|
||||
lpfc_cq_destroy(phba,
|
||||
phba->sli4_hba.nvmet_cqset[qidx]);
|
||||
}
|
||||
|
||||
/* Unset FCP response complete queue */
|
||||
if (phba->sli4_hba.fcp_cq)
|
||||
for (qidx = 0; qidx < phba->cfg_fcp_io_channel; qidx++)
|
||||
|
@ -9935,6 +10151,7 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
|
|||
!phba->nvme_support) {
|
||||
phba->nvme_support = 0;
|
||||
phba->nvmet_support = 0;
|
||||
phba->cfg_nvmet_mrq = 0;
|
||||
phba->cfg_nvme_io_channel = 0;
|
||||
phba->io_channel_irqs = phba->cfg_fcp_io_channel;
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_NVME,
|
||||
|
@ -10875,12 +11092,14 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
|
|||
if (phba->intr_type != MSIX) {
|
||||
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP)
|
||||
phba->cfg_fcp_io_channel = 1;
|
||||
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
|
||||
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
|
||||
phba->cfg_nvme_io_channel = 1;
|
||||
if (phba->nvmet_support)
|
||||
phba->cfg_nvmet_mrq = 1;
|
||||
}
|
||||
phba->io_channel_irqs = 1;
|
||||
}
|
||||
|
||||
|
||||
/* Set up SLI-4 HBA */
|
||||
if (lpfc_sli4_hba_setup(phba)) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
|
|
|
@ -2081,6 +2081,9 @@ lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)
|
|||
if (phba->max_vpi && phba->cfg_enable_npiv)
|
||||
bf_set(lpfc_mbx_rq_ftr_rq_npiv, &mboxq->u.mqe.un.req_ftrs, 1);
|
||||
|
||||
if (phba->nvmet_support)
|
||||
bf_set(lpfc_mbx_rq_ftr_rq_mrqp, &mboxq->u.mqe.un.req_ftrs, 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2448,6 +2451,26 @@ lpfc_reg_fcfi(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
|
|||
/* addr mode is bit wise inverted value of fcf addr_mode */
|
||||
bf_set(lpfc_reg_fcfi_mam, reg_fcfi,
|
||||
(~phba->fcf.addr_mode) & 0x3);
|
||||
} else {
|
||||
/* This is ONLY for NVMET MRQ == 1 */
|
||||
if (phba->cfg_nvmet_mrq != 1)
|
||||
return;
|
||||
|
||||
bf_set(lpfc_reg_fcfi_rq_id0, reg_fcfi,
|
||||
phba->sli4_hba.nvmet_mrq_hdr[0]->queue_id);
|
||||
/* Match type FCP - rq_id0 */
|
||||
bf_set(lpfc_reg_fcfi_type_match0, reg_fcfi, FC_TYPE_FCP);
|
||||
bf_set(lpfc_reg_fcfi_type_mask0, reg_fcfi, 0xff);
|
||||
bf_set(lpfc_reg_fcfi_rctl_match0, reg_fcfi,
|
||||
FC_RCTL_DD_UNSOL_CMD);
|
||||
|
||||
bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi,
|
||||
phba->sli4_hba.hdr_rq->queue_id);
|
||||
/* Match everything else - rq_id1 */
|
||||
bf_set(lpfc_reg_fcfi_type_match1, reg_fcfi, 0);
|
||||
bf_set(lpfc_reg_fcfi_type_mask1, reg_fcfi, 0);
|
||||
bf_set(lpfc_reg_fcfi_rctl_match1, reg_fcfi, 0);
|
||||
bf_set(lpfc_reg_fcfi_rctl_mask1, reg_fcfi, 0);
|
||||
}
|
||||
bf_set(lpfc_reg_fcfi_rq_id2, reg_fcfi, REG_FCF_INVALID_QID);
|
||||
bf_set(lpfc_reg_fcfi_rq_id3, reg_fcfi, REG_FCF_INVALID_QID);
|
||||
|
@ -2460,6 +2483,70 @@ lpfc_reg_fcfi(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_reg_fcfi_mrq - Initialize the REG_FCFI_MRQ mailbox command
|
||||
* @phba: pointer to the hba structure containing the FCF index and RQ ID.
|
||||
* @mbox: pointer to lpfc mbox command to initialize.
|
||||
* @mode: 0 to register FCFI, 1 to register MRQs
|
||||
*
|
||||
* The REG_FCFI_MRQ mailbox command supports Fibre Channel Forwarders (FCFs).
|
||||
* The SLI Host uses the command to activate an FCF after it has acquired FCF
|
||||
* information via a READ_FCF mailbox command. This mailbox command also is used
|
||||
* to indicate where received unsolicited frames from this FCF will be sent. By
|
||||
* default this routine will set up the FCF to forward all unsolicited frames
|
||||
* the the RQ ID passed in the @phba. This can be overridden by the caller for
|
||||
* more complicated setups.
|
||||
**/
|
||||
void
|
||||
lpfc_reg_fcfi_mrq(struct lpfc_hba *phba, struct lpfcMboxq *mbox, int mode)
|
||||
{
|
||||
struct lpfc_mbx_reg_fcfi_mrq *reg_fcfi;
|
||||
|
||||
/* This is ONLY for MRQ */
|
||||
if (phba->cfg_nvmet_mrq <= 1)
|
||||
return;
|
||||
|
||||
memset(mbox, 0, sizeof(*mbox));
|
||||
reg_fcfi = &mbox->u.mqe.un.reg_fcfi_mrq;
|
||||
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_FCFI_MRQ);
|
||||
if (mode == 0) {
|
||||
bf_set(lpfc_reg_fcfi_mrq_info_index, reg_fcfi,
|
||||
phba->fcf.current_rec.fcf_indx);
|
||||
if (phba->fcf.current_rec.vlan_id != LPFC_FCOE_NULL_VID) {
|
||||
bf_set(lpfc_reg_fcfi_mrq_vv, reg_fcfi, 1);
|
||||
bf_set(lpfc_reg_fcfi_mrq_vlan_tag, reg_fcfi,
|
||||
phba->fcf.current_rec.vlan_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bf_set(lpfc_reg_fcfi_mrq_rq_id0, reg_fcfi,
|
||||
phba->sli4_hba.nvmet_mrq_hdr[0]->queue_id);
|
||||
/* Match NVME frames of type FCP (protocol NVME) - rq_id0 */
|
||||
bf_set(lpfc_reg_fcfi_mrq_type_match0, reg_fcfi, FC_TYPE_FCP);
|
||||
bf_set(lpfc_reg_fcfi_mrq_type_mask0, reg_fcfi, 0xff);
|
||||
bf_set(lpfc_reg_fcfi_mrq_rctl_match0, reg_fcfi, FC_RCTL_DD_UNSOL_CMD);
|
||||
bf_set(lpfc_reg_fcfi_mrq_rctl_mask0, reg_fcfi, 0xff);
|
||||
bf_set(lpfc_reg_fcfi_mrq_ptc0, reg_fcfi, 1);
|
||||
bf_set(lpfc_reg_fcfi_mrq_pt0, reg_fcfi, 1);
|
||||
|
||||
bf_set(lpfc_reg_fcfi_mrq_policy, reg_fcfi, 3); /* NVME connection id */
|
||||
bf_set(lpfc_reg_fcfi_mrq_mode, reg_fcfi, 1);
|
||||
bf_set(lpfc_reg_fcfi_mrq_filter, reg_fcfi, 1); /* rq_id0 */
|
||||
bf_set(lpfc_reg_fcfi_mrq_npairs, reg_fcfi, phba->cfg_nvmet_mrq);
|
||||
|
||||
bf_set(lpfc_reg_fcfi_mrq_rq_id1, reg_fcfi,
|
||||
phba->sli4_hba.hdr_rq->queue_id);
|
||||
/* Match everything - rq_id1 */
|
||||
bf_set(lpfc_reg_fcfi_mrq_type_match1, reg_fcfi, 0);
|
||||
bf_set(lpfc_reg_fcfi_mrq_type_mask1, reg_fcfi, 0);
|
||||
bf_set(lpfc_reg_fcfi_mrq_rctl_match1, reg_fcfi, 0);
|
||||
bf_set(lpfc_reg_fcfi_mrq_rctl_mask1, reg_fcfi, 0);
|
||||
|
||||
bf_set(lpfc_reg_fcfi_mrq_rq_id2, reg_fcfi, REG_FCF_INVALID_QID);
|
||||
bf_set(lpfc_reg_fcfi_mrq_rq_id3, reg_fcfi, REG_FCF_INVALID_QID);
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_unreg_fcfi - Initialize the UNREG_FCFI mailbox command
|
||||
* @mbox: pointer to lpfc mbox command to initialize.
|
||||
|
|
|
@ -2027,6 +2027,29 @@ lpfc_sli_hbqbuf_get(struct list_head *rb_list)
|
|||
return container_of(d_buf, struct hbq_dmabuf, dbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli_rqbuf_get - Remove the first dma buffer off of an RQ list
|
||||
* @phba: Pointer to HBA context object.
|
||||
* @hbqno: HBQ number.
|
||||
*
|
||||
* This function removes the first RQ buffer on an RQ buffer list and returns a
|
||||
* pointer to that buffer. If it finds no buffers on the list it returns NULL.
|
||||
**/
|
||||
static struct rqb_dmabuf *
|
||||
lpfc_sli_rqbuf_get(struct lpfc_hba *phba, struct lpfc_queue *hrq)
|
||||
{
|
||||
struct lpfc_dmabuf *h_buf;
|
||||
struct lpfc_rqb *rqbp;
|
||||
|
||||
rqbp = hrq->rqbp;
|
||||
list_remove_head(&rqbp->rqb_buffer_list, h_buf,
|
||||
struct lpfc_dmabuf, list);
|
||||
if (!h_buf)
|
||||
return NULL;
|
||||
rqbp->buffer_count--;
|
||||
return container_of(h_buf, struct rqb_dmabuf, hbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli_hbqbuf_find - Find the hbq buffer associated with a tag
|
||||
* @phba: Pointer to HBA context object.
|
||||
|
@ -5271,6 +5294,14 @@ lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba)
|
|||
lpfc_sli4_eq_release(phba->sli4_hba.hba_eq[qidx],
|
||||
LPFC_QUEUE_REARM);
|
||||
|
||||
if (phba->nvmet_support) {
|
||||
for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++) {
|
||||
lpfc_sli4_cq_release(
|
||||
phba->sli4_hba.nvmet_cqset[qidx],
|
||||
LPFC_QUEUE_REARM);
|
||||
}
|
||||
}
|
||||
|
||||
if (phba->cfg_fof)
|
||||
lpfc_sli4_eq_release(phba->sli4_hba.fof_eq, LPFC_QUEUE_REARM);
|
||||
}
|
||||
|
@ -6485,7 +6516,7 @@ lpfc_set_host_data(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
|
|||
int
|
||||
lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
||||
{
|
||||
int rc;
|
||||
int rc, i;
|
||||
LPFC_MBOXQ_t *mboxq;
|
||||
struct lpfc_mqe *mqe;
|
||||
uint8_t *vpd;
|
||||
|
@ -6494,6 +6525,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
|||
struct Scsi_Host *shost = lpfc_shost_from_vport(phba->pport);
|
||||
struct lpfc_vport *vport = phba->pport;
|
||||
struct lpfc_dmabuf *mp;
|
||||
struct lpfc_rqb *rqbp;
|
||||
|
||||
/* Perform a PCI function reset to start from clean */
|
||||
rc = lpfc_pci_function_reset(phba);
|
||||
|
@ -6856,6 +6888,29 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
|||
}
|
||||
}
|
||||
|
||||
if (phba->nvmet_support && phba->cfg_nvmet_mrq) {
|
||||
|
||||
/* Post initial buffers to all RQs created */
|
||||
for (i = 0; i < phba->cfg_nvmet_mrq; i++) {
|
||||
rqbp = phba->sli4_hba.nvmet_mrq_hdr[i]->rqbp;
|
||||
INIT_LIST_HEAD(&rqbp->rqb_buffer_list);
|
||||
rqbp->rqb_alloc_buffer = lpfc_sli4_nvmet_alloc;
|
||||
rqbp->rqb_free_buffer = lpfc_sli4_nvmet_free;
|
||||
rqbp->entry_count = 256;
|
||||
rqbp->buffer_count = 0;
|
||||
|
||||
/* Divide by 4 and round down to multiple of 16 */
|
||||
rc = (phba->cfg_nvmet_mrq_post >> 2) & 0xfff8;
|
||||
phba->sli4_hba.nvmet_mrq_hdr[i]->entry_repost = rc;
|
||||
phba->sli4_hba.nvmet_mrq_data[i]->entry_repost = rc;
|
||||
|
||||
lpfc_post_rq_buffer(
|
||||
phba, phba->sli4_hba.nvmet_mrq_hdr[i],
|
||||
phba->sli4_hba.nvmet_mrq_data[i],
|
||||
phba->cfg_nvmet_mrq_post);
|
||||
}
|
||||
}
|
||||
|
||||
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) {
|
||||
/* register the allocated scsi sgl pool to the port */
|
||||
rc = lpfc_sli4_repost_scsi_sgl_list(phba);
|
||||
|
@ -6898,7 +6953,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
|||
lpfc_sli4_node_prep(phba);
|
||||
|
||||
if (!(phba->hba_flag & HBA_FCOE_MODE)) {
|
||||
if (phba->nvmet_support == 0) {
|
||||
if ((phba->nvmet_support == 0) || (phba->cfg_nvmet_mrq == 1)) {
|
||||
/*
|
||||
* The FC Port needs to register FCFI (index 0)
|
||||
*/
|
||||
|
@ -6910,6 +6965,26 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
|||
rc = 0;
|
||||
phba->fcf.fcfi = bf_get(lpfc_reg_fcfi_fcfi,
|
||||
&mboxq->u.mqe.un.reg_fcfi);
|
||||
} else {
|
||||
/* We are a NVME Target mode with MRQ > 1 */
|
||||
|
||||
/* First register the FCFI */
|
||||
lpfc_reg_fcfi_mrq(phba, mboxq, 0);
|
||||
mboxq->vport = phba->pport;
|
||||
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
|
||||
if (rc != MBX_SUCCESS)
|
||||
goto out_unset_queue;
|
||||
rc = 0;
|
||||
phba->fcf.fcfi = bf_get(lpfc_reg_fcfi_mrq_fcfi,
|
||||
&mboxq->u.mqe.un.reg_fcfi_mrq);
|
||||
|
||||
/* Next register the MRQs */
|
||||
lpfc_reg_fcfi_mrq(phba, mboxq, 1);
|
||||
mboxq->vport = phba->pport;
|
||||
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
|
||||
if (rc != MBX_SUCCESS)
|
||||
goto out_unset_queue;
|
||||
rc = 0;
|
||||
}
|
||||
/* Check if the port is configured to be disabled */
|
||||
lpfc_sli_read_link_ste(phba);
|
||||
|
@ -12987,6 +13062,101 @@ lpfc_sli4_fp_handle_rel_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
|
|||
"miss-matched qid: wcqe-qid=x%x\n", hba_wqid);
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_nvmet_handle_rcqe - Process a receive-queue completion queue entry
|
||||
* @phba: Pointer to HBA context object.
|
||||
* @rcqe: Pointer to receive-queue completion queue entry.
|
||||
*
|
||||
* This routine process a receive-queue completion queue entry.
|
||||
*
|
||||
* Return: true if work posted to worker thread, otherwise false.
|
||||
**/
|
||||
static bool
|
||||
lpfc_sli4_nvmet_handle_rcqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
|
||||
struct lpfc_rcqe *rcqe)
|
||||
{
|
||||
bool workposted = false;
|
||||
struct lpfc_queue *hrq;
|
||||
struct lpfc_queue *drq;
|
||||
struct rqb_dmabuf *dma_buf;
|
||||
struct fc_frame_header *fc_hdr;
|
||||
uint32_t status, rq_id;
|
||||
unsigned long iflags;
|
||||
uint32_t fctl, idx;
|
||||
|
||||
if ((phba->nvmet_support == 0) ||
|
||||
(phba->sli4_hba.nvmet_cqset == NULL))
|
||||
return workposted;
|
||||
|
||||
idx = cq->queue_id - phba->sli4_hba.nvmet_cqset[0]->queue_id;
|
||||
hrq = phba->sli4_hba.nvmet_mrq_hdr[idx];
|
||||
drq = phba->sli4_hba.nvmet_mrq_data[idx];
|
||||
|
||||
/* sanity check on queue memory */
|
||||
if (unlikely(!hrq) || unlikely(!drq))
|
||||
return workposted;
|
||||
|
||||
if (bf_get(lpfc_cqe_code, rcqe) == CQE_CODE_RECEIVE_V1)
|
||||
rq_id = bf_get(lpfc_rcqe_rq_id_v1, rcqe);
|
||||
else
|
||||
rq_id = bf_get(lpfc_rcqe_rq_id, rcqe);
|
||||
|
||||
if ((phba->nvmet_support == 0) ||
|
||||
(rq_id != hrq->queue_id))
|
||||
return workposted;
|
||||
|
||||
status = bf_get(lpfc_rcqe_status, rcqe);
|
||||
switch (status) {
|
||||
case FC_STATUS_RQ_BUF_LEN_EXCEEDED:
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"6126 Receive Frame Truncated!!\n");
|
||||
hrq->RQ_buf_trunc++;
|
||||
break;
|
||||
case FC_STATUS_RQ_SUCCESS:
|
||||
lpfc_sli4_rq_release(hrq, drq);
|
||||
spin_lock_irqsave(&phba->hbalock, iflags);
|
||||
dma_buf = lpfc_sli_rqbuf_get(phba, hrq);
|
||||
if (!dma_buf) {
|
||||
hrq->RQ_no_buf_found++;
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
goto out;
|
||||
}
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
hrq->RQ_rcv_buf++;
|
||||
fc_hdr = (struct fc_frame_header *)dma_buf->hbuf.virt;
|
||||
|
||||
/* Just some basic sanity checks on FCP Command frame */
|
||||
fctl = (fc_hdr->fh_f_ctl[0] << 16 |
|
||||
fc_hdr->fh_f_ctl[1] << 8 |
|
||||
fc_hdr->fh_f_ctl[2]);
|
||||
if (((fctl &
|
||||
(FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT)) !=
|
||||
(FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT)) ||
|
||||
(fc_hdr->fh_seq_cnt != 0)) /* 0 byte swapped is still 0 */
|
||||
goto drop;
|
||||
|
||||
if (fc_hdr->fh_type == FC_TYPE_FCP) {
|
||||
dma_buf->bytes_recv = bf_get(lpfc_rcqe_length, rcqe);
|
||||
/* todo: tgt: forward cmd iu to transport */
|
||||
return false;
|
||||
}
|
||||
drop:
|
||||
lpfc_in_buf_free(phba, &dma_buf->dbuf);
|
||||
break;
|
||||
case FC_STATUS_INSUFF_BUF_NEED_BUF:
|
||||
case FC_STATUS_INSUFF_BUF_FRM_DISC:
|
||||
hrq->RQ_no_posted_buf++;
|
||||
/* Post more buffers if possible */
|
||||
spin_lock_irqsave(&phba->hbalock, iflags);
|
||||
phba->hba_flag |= HBA_POST_RECEIVE_BUFFER;
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
workposted = true;
|
||||
break;
|
||||
}
|
||||
out:
|
||||
return workposted;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_fp_handle_cqe - Process fast-path work queue completion entry
|
||||
* @cq: Pointer to the completion queue.
|
||||
|
@ -13035,6 +13205,10 @@ lpfc_sli4_fp_handle_cqe(struct lpfc_hba *phba, struct lpfc_queue *cq,
|
|||
case CQE_CODE_RECEIVE_V1:
|
||||
case CQE_CODE_RECEIVE:
|
||||
phba->last_completion_time = jiffies;
|
||||
if (cq->subtype == LPFC_NVMET) {
|
||||
workposted = lpfc_sli4_nvmet_handle_rcqe(
|
||||
phba, cq, (struct lpfc_rcqe *)&wcqe);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
|
@ -13064,7 +13238,7 @@ lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
|
|||
struct lpfc_queue *cq = NULL;
|
||||
struct lpfc_cqe *cqe;
|
||||
bool workposted = false;
|
||||
uint16_t cqid;
|
||||
uint16_t cqid, id;
|
||||
int ecount = 0;
|
||||
|
||||
if (unlikely(bf_get_le32(lpfc_eqe_major_code, eqe) != 0)) {
|
||||
|
@ -13079,6 +13253,15 @@ lpfc_sli4_hba_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
|
|||
/* Get the reference to the corresponding CQ */
|
||||
cqid = bf_get_le32(lpfc_eqe_resource_id, eqe);
|
||||
|
||||
if (phba->cfg_nvmet_mrq && phba->sli4_hba.nvmet_cqset) {
|
||||
id = phba->sli4_hba.nvmet_cqset[0]->queue_id;
|
||||
if ((cqid >= id) && (cqid < (id + phba->cfg_nvmet_mrq))) {
|
||||
/* Process NVMET unsol rcv */
|
||||
cq = phba->sli4_hba.nvmet_cqset[cqid - id];
|
||||
goto process_cq;
|
||||
}
|
||||
}
|
||||
|
||||
if (phba->sli4_hba.nvme_cq_map &&
|
||||
(cqid == phba->sli4_hba.nvme_cq_map[qidx])) {
|
||||
/* Process NVME / NVMET command completion */
|
||||
|
@ -13962,6 +14145,234 @@ out:
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_cq_create_set - Create a set of Completion Queues on the HBA for MRQ
|
||||
* @phba: HBA structure that indicates port to create a queue on.
|
||||
* @cqp: The queue structure array to use to create the completion queues.
|
||||
* @eqp: The event queue array to bind these completion queues to.
|
||||
*
|
||||
* This function creates a set of completion queue, s to support MRQ
|
||||
* as detailed in @cqp, on a port,
|
||||
* described by @phba by sending a CREATE_CQ_SET mailbox command to the HBA.
|
||||
*
|
||||
* The @phba struct is used to send mailbox command to HBA. The @cq struct
|
||||
* is used to get the entry count and entry size that are necessary to
|
||||
* determine the number of pages to allocate and use for this queue. The @eq
|
||||
* is used to indicate which event queue to bind this completion queue to. This
|
||||
* function will send the CREATE_CQ_SET mailbox command to the HBA to setup the
|
||||
* completion queue. This function is asynchronous and will wait for the mailbox
|
||||
* command to finish before continuing.
|
||||
*
|
||||
* On success this function will return a zero. If unable to allocate enough
|
||||
* memory this function will return -ENOMEM. If the queue create mailbox command
|
||||
* fails this function will return -ENXIO.
|
||||
**/
|
||||
int
|
||||
lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
|
||||
struct lpfc_queue **eqp, uint32_t type, uint32_t subtype)
|
||||
{
|
||||
struct lpfc_queue *cq;
|
||||
struct lpfc_queue *eq;
|
||||
struct lpfc_mbx_cq_create_set *cq_set;
|
||||
struct lpfc_dmabuf *dmabuf;
|
||||
LPFC_MBOXQ_t *mbox;
|
||||
int rc, length, alloclen, status = 0;
|
||||
int cnt, idx, numcq, page_idx = 0;
|
||||
uint32_t shdr_status, shdr_add_status;
|
||||
union lpfc_sli4_cfg_shdr *shdr;
|
||||
uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz;
|
||||
|
||||
/* sanity check on queue memory */
|
||||
numcq = phba->cfg_nvmet_mrq;
|
||||
if (!cqp || !eqp || !numcq)
|
||||
return -ENODEV;
|
||||
if (!phba->sli4_hba.pc_sli4_params.supported)
|
||||
hw_page_size = SLI4_PAGE_SIZE;
|
||||
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (!mbox)
|
||||
return -ENOMEM;
|
||||
|
||||
length = sizeof(struct lpfc_mbx_cq_create_set);
|
||||
length += ((numcq * cqp[0]->page_count) *
|
||||
sizeof(struct dma_address));
|
||||
alloclen = lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
|
||||
LPFC_MBOX_OPCODE_FCOE_CQ_CREATE_SET, length,
|
||||
LPFC_SLI4_MBX_NEMBED);
|
||||
if (alloclen < length) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"3098 Allocated DMA memory size (%d) is "
|
||||
"less than the requested DMA memory size "
|
||||
"(%d)\n", alloclen, length);
|
||||
status = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
cq_set = mbox->sge_array->addr[0];
|
||||
shdr = (union lpfc_sli4_cfg_shdr *)&cq_set->cfg_shdr;
|
||||
bf_set(lpfc_mbox_hdr_version, &shdr->request, 0);
|
||||
|
||||
for (idx = 0; idx < numcq; idx++) {
|
||||
cq = cqp[idx];
|
||||
eq = eqp[idx];
|
||||
if (!cq || !eq) {
|
||||
status = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (idx) {
|
||||
case 0:
|
||||
bf_set(lpfc_mbx_cq_create_set_page_size,
|
||||
&cq_set->u.request,
|
||||
(hw_page_size / SLI4_PAGE_SIZE));
|
||||
bf_set(lpfc_mbx_cq_create_set_num_pages,
|
||||
&cq_set->u.request, cq->page_count);
|
||||
bf_set(lpfc_mbx_cq_create_set_evt,
|
||||
&cq_set->u.request, 1);
|
||||
bf_set(lpfc_mbx_cq_create_set_valid,
|
||||
&cq_set->u.request, 1);
|
||||
bf_set(lpfc_mbx_cq_create_set_cqe_size,
|
||||
&cq_set->u.request, 0);
|
||||
bf_set(lpfc_mbx_cq_create_set_num_cq,
|
||||
&cq_set->u.request, numcq);
|
||||
switch (cq->entry_count) {
|
||||
default:
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"3118 Bad CQ count. (%d)\n",
|
||||
cq->entry_count);
|
||||
if (cq->entry_count < 256) {
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
/* otherwise default to smallest (drop thru) */
|
||||
case 256:
|
||||
bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
|
||||
&cq_set->u.request, LPFC_CQ_CNT_256);
|
||||
break;
|
||||
case 512:
|
||||
bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
|
||||
&cq_set->u.request, LPFC_CQ_CNT_512);
|
||||
break;
|
||||
case 1024:
|
||||
bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
|
||||
&cq_set->u.request, LPFC_CQ_CNT_1024);
|
||||
break;
|
||||
}
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id0,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 1:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id1,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 2:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id2,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 3:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id3,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 4:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id4,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 5:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id5,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 6:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id6,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 7:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id7,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 8:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id8,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 9:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id9,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 10:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id10,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 11:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id11,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 12:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id12,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 13:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id13,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 14:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id14,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
case 15:
|
||||
bf_set(lpfc_mbx_cq_create_set_eq_id15,
|
||||
&cq_set->u.request, eq->queue_id);
|
||||
break;
|
||||
}
|
||||
|
||||
/* link the cq onto the parent eq child list */
|
||||
list_add_tail(&cq->list, &eq->child_list);
|
||||
/* Set up completion queue's type and subtype */
|
||||
cq->type = type;
|
||||
cq->subtype = subtype;
|
||||
cq->assoc_qid = eq->queue_id;
|
||||
cq->host_index = 0;
|
||||
cq->hba_index = 0;
|
||||
|
||||
rc = 0;
|
||||
list_for_each_entry(dmabuf, &cq->page_list, list) {
|
||||
memset(dmabuf->virt, 0, hw_page_size);
|
||||
cnt = page_idx + dmabuf->buffer_tag;
|
||||
cq_set->u.request.page[cnt].addr_lo =
|
||||
putPaddrLow(dmabuf->phys);
|
||||
cq_set->u.request.page[cnt].addr_hi =
|
||||
putPaddrHigh(dmabuf->phys);
|
||||
rc++;
|
||||
}
|
||||
page_idx += rc;
|
||||
}
|
||||
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
|
||||
|
||||
/* The IOCTL status is embedded in the mailbox subheader. */
|
||||
shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
|
||||
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
|
||||
if (shdr_status || shdr_add_status || rc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"3119 CQ_CREATE_SET mailbox failed with "
|
||||
"status x%x add_status x%x, mbx status x%x\n",
|
||||
shdr_status, shdr_add_status, rc);
|
||||
status = -ENXIO;
|
||||
goto out;
|
||||
}
|
||||
rc = bf_get(lpfc_mbx_cq_create_set_base_id, &cq_set->u.response);
|
||||
if (rc == 0xFFFF) {
|
||||
status = -ENXIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < numcq; idx++) {
|
||||
cq = cqp[idx];
|
||||
cq->queue_id = rc + idx;
|
||||
}
|
||||
|
||||
out:
|
||||
lpfc_sli4_mbox_cmd_free(phba, mbox);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_mq_create_fb_init - Send MCC_CREATE without async events registration
|
||||
* @phba: HBA structure that indicates port to create a queue on.
|
||||
|
@ -14692,6 +15103,197 @@ out:
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_mrq_create - Create MRQ Receive Queues on the HBA
|
||||
* @phba: HBA structure that indicates port to create a queue on.
|
||||
* @hrqp: The queue structure array to use to create the header receive queues.
|
||||
* @drqp: The queue structure array to use to create the data receive queues.
|
||||
* @cqp: The completion queue array to bind these receive queues to.
|
||||
*
|
||||
* This function creates a receive buffer queue pair , as detailed in @hrq and
|
||||
* @drq, on a port, described by @phba by sending a RQ_CREATE mailbox command
|
||||
* to the HBA.
|
||||
*
|
||||
* The @phba struct is used to send mailbox command to HBA. The @drq and @hrq
|
||||
* struct is used to get the entry count that is necessary to determine the
|
||||
* number of pages to use for this queue. The @cq is used to indicate which
|
||||
* completion queue to bind received buffers that are posted to these queues to.
|
||||
* This function will send the RQ_CREATE mailbox command to the HBA to setup the
|
||||
* receive queue pair. This function is asynchronous and will wait for the
|
||||
* mailbox command to finish before continuing.
|
||||
*
|
||||
* On success this function will return a zero. If unable to allocate enough
|
||||
* memory this function will return -ENOMEM. If the queue create mailbox command
|
||||
* fails this function will return -ENXIO.
|
||||
**/
|
||||
int
|
||||
lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
|
||||
struct lpfc_queue **drqp, struct lpfc_queue **cqp,
|
||||
uint32_t subtype)
|
||||
{
|
||||
struct lpfc_queue *hrq, *drq, *cq;
|
||||
struct lpfc_mbx_rq_create_v2 *rq_create;
|
||||
struct lpfc_dmabuf *dmabuf;
|
||||
LPFC_MBOXQ_t *mbox;
|
||||
int rc, length, alloclen, status = 0;
|
||||
int cnt, idx, numrq, page_idx = 0;
|
||||
uint32_t shdr_status, shdr_add_status;
|
||||
union lpfc_sli4_cfg_shdr *shdr;
|
||||
uint32_t hw_page_size = phba->sli4_hba.pc_sli4_params.if_page_sz;
|
||||
|
||||
numrq = phba->cfg_nvmet_mrq;
|
||||
/* sanity check on array memory */
|
||||
if (!hrqp || !drqp || !cqp || !numrq)
|
||||
return -ENODEV;
|
||||
if (!phba->sli4_hba.pc_sli4_params.supported)
|
||||
hw_page_size = SLI4_PAGE_SIZE;
|
||||
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (!mbox)
|
||||
return -ENOMEM;
|
||||
|
||||
length = sizeof(struct lpfc_mbx_rq_create_v2);
|
||||
length += ((2 * numrq * hrqp[0]->page_count) *
|
||||
sizeof(struct dma_address));
|
||||
|
||||
alloclen = lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
|
||||
LPFC_MBOX_OPCODE_FCOE_RQ_CREATE, length,
|
||||
LPFC_SLI4_MBX_NEMBED);
|
||||
if (alloclen < length) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"3099 Allocated DMA memory size (%d) is "
|
||||
"less than the requested DMA memory size "
|
||||
"(%d)\n", alloclen, length);
|
||||
status = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
rq_create = mbox->sge_array->addr[0];
|
||||
shdr = (union lpfc_sli4_cfg_shdr *)&rq_create->cfg_shdr;
|
||||
|
||||
bf_set(lpfc_mbox_hdr_version, &shdr->request, LPFC_Q_CREATE_VERSION_2);
|
||||
cnt = 0;
|
||||
|
||||
for (idx = 0; idx < numrq; idx++) {
|
||||
hrq = hrqp[idx];
|
||||
drq = drqp[idx];
|
||||
cq = cqp[idx];
|
||||
|
||||
if (hrq->entry_count != drq->entry_count) {
|
||||
status = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* sanity check on queue memory */
|
||||
if (!hrq || !drq || !cq) {
|
||||
status = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (idx == 0) {
|
||||
bf_set(lpfc_mbx_rq_create_num_pages,
|
||||
&rq_create->u.request,
|
||||
hrq->page_count);
|
||||
bf_set(lpfc_mbx_rq_create_rq_cnt,
|
||||
&rq_create->u.request, (numrq * 2));
|
||||
bf_set(lpfc_mbx_rq_create_dnb, &rq_create->u.request,
|
||||
1);
|
||||
bf_set(lpfc_rq_context_base_cq,
|
||||
&rq_create->u.request.context,
|
||||
cq->queue_id);
|
||||
bf_set(lpfc_rq_context_data_size,
|
||||
&rq_create->u.request.context,
|
||||
LPFC_DATA_BUF_SIZE);
|
||||
bf_set(lpfc_rq_context_hdr_size,
|
||||
&rq_create->u.request.context,
|
||||
LPFC_HDR_BUF_SIZE);
|
||||
bf_set(lpfc_rq_context_rqe_count_1,
|
||||
&rq_create->u.request.context,
|
||||
hrq->entry_count);
|
||||
bf_set(lpfc_rq_context_rqe_size,
|
||||
&rq_create->u.request.context,
|
||||
LPFC_RQE_SIZE_8);
|
||||
bf_set(lpfc_rq_context_page_size,
|
||||
&rq_create->u.request.context,
|
||||
(PAGE_SIZE/SLI4_PAGE_SIZE));
|
||||
}
|
||||
rc = 0;
|
||||
list_for_each_entry(dmabuf, &hrq->page_list, list) {
|
||||
memset(dmabuf->virt, 0, hw_page_size);
|
||||
cnt = page_idx + dmabuf->buffer_tag;
|
||||
rq_create->u.request.page[cnt].addr_lo =
|
||||
putPaddrLow(dmabuf->phys);
|
||||
rq_create->u.request.page[cnt].addr_hi =
|
||||
putPaddrHigh(dmabuf->phys);
|
||||
rc++;
|
||||
}
|
||||
page_idx += rc;
|
||||
|
||||
rc = 0;
|
||||
list_for_each_entry(dmabuf, &drq->page_list, list) {
|
||||
memset(dmabuf->virt, 0, hw_page_size);
|
||||
cnt = page_idx + dmabuf->buffer_tag;
|
||||
rq_create->u.request.page[cnt].addr_lo =
|
||||
putPaddrLow(dmabuf->phys);
|
||||
rq_create->u.request.page[cnt].addr_hi =
|
||||
putPaddrHigh(dmabuf->phys);
|
||||
rc++;
|
||||
}
|
||||
page_idx += rc;
|
||||
|
||||
hrq->db_format = LPFC_DB_RING_FORMAT;
|
||||
hrq->db_regaddr = phba->sli4_hba.RQDBregaddr;
|
||||
hrq->type = LPFC_HRQ;
|
||||
hrq->assoc_qid = cq->queue_id;
|
||||
hrq->subtype = subtype;
|
||||
hrq->host_index = 0;
|
||||
hrq->hba_index = 0;
|
||||
|
||||
drq->db_format = LPFC_DB_RING_FORMAT;
|
||||
drq->db_regaddr = phba->sli4_hba.RQDBregaddr;
|
||||
drq->type = LPFC_DRQ;
|
||||
drq->assoc_qid = cq->queue_id;
|
||||
drq->subtype = subtype;
|
||||
drq->host_index = 0;
|
||||
drq->hba_index = 0;
|
||||
|
||||
list_add_tail(&hrq->list, &cq->child_list);
|
||||
list_add_tail(&drq->list, &cq->child_list);
|
||||
}
|
||||
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
|
||||
/* The IOCTL status is embedded in the mailbox subheader. */
|
||||
shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
|
||||
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
|
||||
if (shdr_status || shdr_add_status || rc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"3120 RQ_CREATE mailbox failed with "
|
||||
"status x%x add_status x%x, mbx status x%x\n",
|
||||
shdr_status, shdr_add_status, rc);
|
||||
status = -ENXIO;
|
||||
goto out;
|
||||
}
|
||||
rc = bf_get(lpfc_mbx_rq_create_q_id, &rq_create->u.response);
|
||||
if (rc == 0xFFFF) {
|
||||
status = -ENXIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Initialize all RQs with associated queue id */
|
||||
for (idx = 0; idx < numrq; idx++) {
|
||||
hrq = hrqp[idx];
|
||||
hrq->queue_id = rc + (2 * idx);
|
||||
drq = drqp[idx];
|
||||
drq->queue_id = rc + (2 * idx) + 1;
|
||||
}
|
||||
|
||||
out:
|
||||
lpfc_sli4_mbox_cmd_free(phba, mbox);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_eq_destroy - Destroy an event Queue on the HBA
|
||||
* @eq: The queue structure associated with the queue to destroy.
|
||||
|
|
|
@ -550,6 +550,9 @@ struct lpfc_sli4_hba {
|
|||
struct lpfc_queue **hba_eq; /* Event queues for HBA */
|
||||
struct lpfc_queue **fcp_cq; /* Fast-path FCP compl queue */
|
||||
struct lpfc_queue **nvme_cq; /* Fast-path NVME compl queue */
|
||||
struct lpfc_queue **nvmet_cqset; /* Fast-path NVMET CQ Set queues */
|
||||
struct lpfc_queue **nvmet_mrq_hdr; /* Fast-path NVMET hdr MRQs */
|
||||
struct lpfc_queue **nvmet_mrq_data; /* Fast-path NVMET data MRQs */
|
||||
struct lpfc_queue **fcp_wq; /* Fast-path FCP work queue */
|
||||
struct lpfc_queue **nvme_wq; /* Fast-path NVME work queue */
|
||||
uint16_t *fcp_cq_map;
|
||||
|
@ -655,6 +658,8 @@ struct lpfc_sli4_hba {
|
|||
uint16_t num_online_cpu;
|
||||
uint16_t num_present_cpu;
|
||||
uint16_t curr_disp_cpu;
|
||||
|
||||
uint16_t nvmet_mrq_post_idx;
|
||||
};
|
||||
|
||||
enum lpfc_sge_type {
|
||||
|
@ -742,12 +747,18 @@ int lpfc_eq_create(struct lpfc_hba *, struct lpfc_queue *, uint32_t);
|
|||
int lpfc_modify_hba_eq_delay(struct lpfc_hba *phba, uint32_t startq);
|
||||
int lpfc_cq_create(struct lpfc_hba *, struct lpfc_queue *,
|
||||
struct lpfc_queue *, uint32_t, uint32_t);
|
||||
int lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
|
||||
struct lpfc_queue **eqp, uint32_t type,
|
||||
uint32_t subtype);
|
||||
int32_t lpfc_mq_create(struct lpfc_hba *, struct lpfc_queue *,
|
||||
struct lpfc_queue *, uint32_t);
|
||||
int lpfc_wq_create(struct lpfc_hba *, struct lpfc_queue *,
|
||||
struct lpfc_queue *, uint32_t);
|
||||
int lpfc_rq_create(struct lpfc_hba *, struct lpfc_queue *,
|
||||
struct lpfc_queue *, struct lpfc_queue *, uint32_t);
|
||||
int lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp,
|
||||
struct lpfc_queue **drqp, struct lpfc_queue **cqp,
|
||||
uint32_t subtype);
|
||||
void lpfc_rq_adjust_repost(struct lpfc_hba *, struct lpfc_queue *, int);
|
||||
int lpfc_eq_destroy(struct lpfc_hba *, struct lpfc_queue *);
|
||||
int lpfc_cq_destroy(struct lpfc_hba *, struct lpfc_queue *);
|
||||
|
|
Loading…
Reference in New Issue