mirror of https://gitee.com/openkylin/linux.git
[SCSI] lpfc 8.3.24: Add resource extent support
This patch adds support for hardware that returns resource ids via extents rather than contiguous ranges. [jejb: checkpatch.pl fixes] 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:
parent
52d5244096
commit
6d368e5321
|
@ -780,6 +780,9 @@ struct lpfc_hba {
|
|||
uint16_t vpi_base;
|
||||
uint16_t vfi_base;
|
||||
unsigned long *vpi_bmask; /* vpi allocation table */
|
||||
uint16_t *vpi_ids;
|
||||
uint16_t vpi_count;
|
||||
struct list_head lpfc_vpi_blk_list;
|
||||
|
||||
/* Data structure used by fabric iocb scheduler */
|
||||
struct list_head fabric_iocb_list;
|
||||
|
|
|
@ -332,6 +332,8 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
|
|||
cmd->ulpLe = 1;
|
||||
cmd->ulpClass = CLASS3;
|
||||
cmd->ulpContext = ndlp->nlp_rpi;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
cmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
cmd->ulpOwner = OWN_CHIP;
|
||||
cmdiocbq->vport = phba->pport;
|
||||
cmdiocbq->context3 = bmp;
|
||||
|
@ -1336,6 +1338,10 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag,
|
|||
}
|
||||
|
||||
icmd->un.ulpWord[3] = ndlp->nlp_rpi;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
icmd->ulpContext =
|
||||
phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
|
||||
/* The exchange is done, mark the entry as invalid */
|
||||
phba->ct_ctx[tag].flags &= ~UNSOL_VALID;
|
||||
} else
|
||||
|
|
|
@ -55,6 +55,8 @@ void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
|
|||
void lpfc_supported_pages(struct lpfcMboxq *);
|
||||
void lpfc_pc_sli4_params(struct lpfcMboxq *);
|
||||
int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
int lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *, struct lpfcMboxq *,
|
||||
uint16_t, uint16_t, bool);
|
||||
int lpfc_get_sli4_parameters(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
|
||||
void lpfc_cleanup_rcv_buffers(struct lpfc_vport *);
|
||||
|
@ -366,6 +368,10 @@ extern void lpfc_debugfs_slow_ring_trc(struct lpfc_hba *, char *, uint32_t,
|
|||
uint32_t, uint32_t);
|
||||
extern struct lpfc_hbq_init *lpfc_hbq_defs[];
|
||||
|
||||
/* SLI4 if_type 2 externs. */
|
||||
int lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *);
|
||||
int lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *);
|
||||
|
||||
/* externs BlockGuard */
|
||||
extern char *_dump_buf_data;
|
||||
extern unsigned long _dump_buf_data_order;
|
||||
|
|
|
@ -352,6 +352,8 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
|
|||
icmd->ulpLe = 1;
|
||||
icmd->ulpClass = CLASS3;
|
||||
icmd->ulpContext = ndlp->nlp_rpi;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
|
||||
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
|
||||
/* For GEN_REQUEST64_CR, use the RPI */
|
||||
|
|
|
@ -250,7 +250,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
|
|||
icmd->un.elsreq64.myID = vport->fc_myDID;
|
||||
|
||||
/* For ELS_REQUEST64_CR, use the VPI by default */
|
||||
icmd->ulpContext = vport->vpi + phba->vpi_base;
|
||||
icmd->ulpContext = phba->vpi_ids[vport->vpi];
|
||||
icmd->ulpCt_h = 0;
|
||||
/* The CT field must be 0=INVALID_RPI for the ECHO cmd */
|
||||
if (elscmd == ELS_CMD_ECHO)
|
||||
|
@ -454,6 +454,7 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
|
|||
rc = -ENOMEM;
|
||||
goto fail_free_dmabuf;
|
||||
}
|
||||
|
||||
mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (!mboxq) {
|
||||
rc = -ENOMEM;
|
||||
|
@ -6585,6 +6586,26 @@ lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
|
|||
{
|
||||
struct lpfc_vport *vport;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
/* The physical ports are always vpi 0 - translate is unnecessary. */
|
||||
if (vpi > 0) {
|
||||
/*
|
||||
* Translate the physical vpi to the logical vpi. The
|
||||
* vport stores the logical vpi.
|
||||
*/
|
||||
for (i = 0; i < phba->max_vpi; i++) {
|
||||
if (vpi == phba->vpi_ids[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= phba->max_vpi) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
|
||||
"2936 Could not find Vport mapped "
|
||||
"to vpi %d\n", vpi);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&phba->hbalock, flags);
|
||||
list_for_each_entry(vport, &phba->port_list, listentry) {
|
||||
|
@ -6641,8 +6662,9 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
|||
vport = phba->pport;
|
||||
else
|
||||
vport = lpfc_find_vport_by_vpid(phba,
|
||||
icmd->unsli3.rcvsli3.vpi - phba->vpi_base);
|
||||
icmd->unsli3.rcvsli3.vpi);
|
||||
}
|
||||
|
||||
/* If there are no BDEs associated
|
||||
* with this IOCB, there is nothing to do.
|
||||
*/
|
||||
|
@ -7222,7 +7244,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|||
elsiocb->iocb.ulpCt_h = (SLI4_CT_VPI >> 1) & 1;
|
||||
elsiocb->iocb.ulpCt_l = SLI4_CT_VPI & 1 ;
|
||||
/* Set the ulpContext to the vpi */
|
||||
elsiocb->iocb.ulpContext = vport->vpi + phba->vpi_base;
|
||||
elsiocb->iocb.ulpContext = phba->vpi_ids[vport->vpi];
|
||||
} else {
|
||||
/* For FDISC, Let FDISC rsp set the NPortID for this VPI */
|
||||
icmd->ulpCt_h = 1;
|
||||
|
|
|
@ -881,7 +881,7 @@ lpfc_linkdown(struct lpfc_hba *phba)
|
|||
/* Clean up any firmware default rpi's */
|
||||
mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (mb) {
|
||||
lpfc_unreg_did(phba, 0xffff, 0xffffffff, mb);
|
||||
lpfc_unreg_did(phba, 0xffff, LPFC_UNREG_ALL_DFLT_RPIS, mb);
|
||||
mb->vport = vport;
|
||||
mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
if (lpfc_sli_issue_mbox(phba, mb, MBX_NOWAIT)
|
||||
|
@ -3421,7 +3421,8 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
return;
|
||||
}
|
||||
|
||||
ndlp->nlp_rpi = mb->un.varWords[0];
|
||||
if (phba->sli_rev < LPFC_SLI_REV4)
|
||||
ndlp->nlp_rpi = mb->un.varWords[0];
|
||||
ndlp->nlp_flag |= NLP_RPI_REGISTERED;
|
||||
ndlp->nlp_type |= NLP_FABRIC;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
||||
|
@ -3495,7 +3496,8 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
return;
|
||||
}
|
||||
|
||||
ndlp->nlp_rpi = mb->un.varWords[0];
|
||||
if (phba->sli_rev < LPFC_SLI_REV4)
|
||||
ndlp->nlp_rpi = mb->un.varWords[0];
|
||||
ndlp->nlp_flag |= NLP_RPI_REGISTERED;
|
||||
ndlp->nlp_type |= NLP_FABRIC;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
||||
|
@ -3582,7 +3584,6 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
|||
if (ndlp->nlp_type & NLP_FCP_INITIATOR)
|
||||
rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
|
||||
|
||||
|
||||
if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN)
|
||||
fc_remote_port_rolechg(rport, rport_ids.roles);
|
||||
|
||||
|
@ -4097,11 +4098,16 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
|||
struct lpfc_hba *phba = vport->phba;
|
||||
LPFC_MBOXQ_t *mbox;
|
||||
int rc;
|
||||
uint16_t rpi;
|
||||
|
||||
if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (mbox) {
|
||||
lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox);
|
||||
/* SLI4 ports require the physical rpi value. */
|
||||
rpi = ndlp->nlp_rpi;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
lpfc_unreg_login(phba, vport->vpi, rpi, mbox);
|
||||
mbox->vport = vport;
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
|
||||
|
@ -4170,7 +4176,8 @@ lpfc_unreg_all_rpis(struct lpfc_vport *vport)
|
|||
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (mbox) {
|
||||
lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox);
|
||||
lpfc_unreg_login(phba, vport->vpi, LPFC_UNREG_ALL_RPIS_VPORT,
|
||||
mbox);
|
||||
mbox->vport = vport;
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
mbox->context1 = NULL;
|
||||
|
@ -4194,7 +4201,8 @@ lpfc_unreg_default_rpis(struct lpfc_vport *vport)
|
|||
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (mbox) {
|
||||
lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox);
|
||||
lpfc_unreg_did(phba, vport->vpi, LPFC_UNREG_ALL_DFLT_RPIS,
|
||||
mbox);
|
||||
mbox->vport = vport;
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
mbox->context1 = NULL;
|
||||
|
@ -4644,10 +4652,7 @@ lpfc_disc_start(struct lpfc_vport *vport)
|
|||
if (num_sent)
|
||||
return;
|
||||
|
||||
/*
|
||||
* For SLI3, cmpl_reg_vpi will set port_state to READY, and
|
||||
* continue discovery.
|
||||
*/
|
||||
/* Register the VPI for SLI3, NON-NPIV only. */
|
||||
if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
|
||||
!(vport->fc_flag & FC_PT2PT) &&
|
||||
!(vport->fc_flag & FC_RSCN_MODE) &&
|
||||
|
@ -4934,7 +4939,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
|||
if (phba->sli_rev < LPFC_SLI_REV4) {
|
||||
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
|
||||
lpfc_issue_reg_vpi(phba, vport);
|
||||
else { /* NPIV Not enabled */
|
||||
else {
|
||||
lpfc_issue_clear_la(phba, vport);
|
||||
vport->port_state = LPFC_VPORT_READY;
|
||||
}
|
||||
|
@ -5060,7 +5065,8 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|||
pmb->context1 = NULL;
|
||||
pmb->context2 = NULL;
|
||||
|
||||
ndlp->nlp_rpi = mb->un.varWords[0];
|
||||
if (phba->sli_rev < LPFC_SLI_REV4)
|
||||
ndlp->nlp_rpi = mb->un.varWords[0];
|
||||
ndlp->nlp_flag |= NLP_RPI_REGISTERED;
|
||||
ndlp->nlp_type |= NLP_FABRIC;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
#define SLI3_IOCB_CMD_SIZE 128
|
||||
#define SLI3_IOCB_RSP_SIZE 64
|
||||
|
||||
#define LPFC_UNREG_ALL_RPIS_VPORT 0xffff
|
||||
#define LPFC_UNREG_ALL_DFLT_RPIS 0xffffffff
|
||||
|
||||
/* vendor ID used in SCSI netlink calls */
|
||||
#define LPFC_NL_VENDOR_ID (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX)
|
||||
|
|
|
@ -229,9 +229,26 @@ struct ulp_bde64 {
|
|||
|
||||
struct lpfc_sli4_flags {
|
||||
uint32_t word0;
|
||||
#define lpfc_fip_flag_SHIFT 0
|
||||
#define lpfc_fip_flag_MASK 0x00000001
|
||||
#define lpfc_fip_flag_WORD word0
|
||||
#define lpfc_idx_rsrc_rdy_SHIFT 0
|
||||
#define lpfc_idx_rsrc_rdy_MASK 0x00000001
|
||||
#define lpfc_idx_rsrc_rdy_WORD word0
|
||||
#define LPFC_IDX_RSRC_RDY 1
|
||||
#define lpfc_xri_rsrc_rdy_SHIFT 1
|
||||
#define lpfc_xri_rsrc_rdy_MASK 0x00000001
|
||||
#define lpfc_xri_rsrc_rdy_WORD word0
|
||||
#define LPFC_XRI_RSRC_RDY 1
|
||||
#define lpfc_rpi_rsrc_rdy_SHIFT 2
|
||||
#define lpfc_rpi_rsrc_rdy_MASK 0x00000001
|
||||
#define lpfc_rpi_rsrc_rdy_WORD word0
|
||||
#define LPFC_RPI_RSRC_RDY 1
|
||||
#define lpfc_vpi_rsrc_rdy_SHIFT 3
|
||||
#define lpfc_vpi_rsrc_rdy_MASK 0x00000001
|
||||
#define lpfc_vpi_rsrc_rdy_WORD word0
|
||||
#define LPFC_VPI_RSRC_RDY 1
|
||||
#define lpfc_vfi_rsrc_rdy_SHIFT 4
|
||||
#define lpfc_vfi_rsrc_rdy_MASK 0x00000001
|
||||
#define lpfc_vfi_rsrc_rdy_WORD word0
|
||||
#define LPFC_VFI_RSRC_RDY 1
|
||||
};
|
||||
|
||||
struct sli4_bls_rsp {
|
||||
|
@ -791,12 +808,22 @@ union lpfc_sli4_cfg_shdr {
|
|||
} response;
|
||||
};
|
||||
|
||||
/* Mailbox structures */
|
||||
/* Mailbox Header structures.
|
||||
* struct mbox_header is defined for first generation SLI4_CFG mailbox
|
||||
* calls deployed for BE-based ports.
|
||||
*
|
||||
* struct sli4_mbox_header is defined for second generation SLI4
|
||||
* ports that don't deploy the SLI4_CFG mechanism.
|
||||
*/
|
||||
struct mbox_header {
|
||||
struct lpfc_sli4_cfg_mhdr cfg_mhdr;
|
||||
union lpfc_sli4_cfg_shdr cfg_shdr;
|
||||
};
|
||||
|
||||
#define LPFC_EXTENT_LOCAL 0
|
||||
#define LPFC_TIMEOUT_DEFAULT 0
|
||||
#define LPFC_EXTENT_VERSION_DEFAULT 0
|
||||
|
||||
/* Subsystem Definitions */
|
||||
#define LPFC_MBOX_SUBSYSTEM_COMMON 0x1
|
||||
#define LPFC_MBOX_SUBSYSTEM_FCOE 0xC
|
||||
|
@ -819,6 +846,10 @@ 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_RSRC_EXTENT_INFO 0x9A
|
||||
#define LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT 0x9B
|
||||
#define LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT 0x9C
|
||||
#define LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT 0x9D
|
||||
#define LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG 0xA0
|
||||
#define LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG 0xA4
|
||||
#define LPFC_MBOX_OPCODE_WRITE_OBJECT 0xAC
|
||||
|
@ -1238,6 +1269,110 @@ struct lpfc_mbx_mq_destroy {
|
|||
} u;
|
||||
};
|
||||
|
||||
/* Start Gen 2 SLI4 Mailbox definitions: */
|
||||
|
||||
/* Define allocate-ready Gen 2 SLI4 FCoE Resource Extent Types. */
|
||||
#define LPFC_RSC_TYPE_FCOE_VFI 0x20
|
||||
#define LPFC_RSC_TYPE_FCOE_VPI 0x21
|
||||
#define LPFC_RSC_TYPE_FCOE_RPI 0x22
|
||||
#define LPFC_RSC_TYPE_FCOE_XRI 0x23
|
||||
|
||||
struct lpfc_mbx_get_rsrc_extent_info {
|
||||
struct mbox_header header;
|
||||
union {
|
||||
struct {
|
||||
uint32_t word4;
|
||||
#define lpfc_mbx_get_rsrc_extent_info_type_SHIFT 0
|
||||
#define lpfc_mbx_get_rsrc_extent_info_type_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_get_rsrc_extent_info_type_WORD word4
|
||||
} req;
|
||||
struct {
|
||||
uint32_t word4;
|
||||
#define lpfc_mbx_get_rsrc_extent_info_cnt_SHIFT 0
|
||||
#define lpfc_mbx_get_rsrc_extent_info_cnt_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_get_rsrc_extent_info_cnt_WORD word4
|
||||
#define lpfc_mbx_get_rsrc_extent_info_size_SHIFT 16
|
||||
#define lpfc_mbx_get_rsrc_extent_info_size_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_get_rsrc_extent_info_size_WORD word4
|
||||
} rsp;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct lpfc_id_range {
|
||||
uint32_t word5;
|
||||
#define lpfc_mbx_rsrc_id_word4_0_SHIFT 0
|
||||
#define lpfc_mbx_rsrc_id_word4_0_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rsrc_id_word4_0_WORD word5
|
||||
#define lpfc_mbx_rsrc_id_word4_1_SHIFT 16
|
||||
#define lpfc_mbx_rsrc_id_word4_1_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rsrc_id_word4_1_WORD word5
|
||||
};
|
||||
|
||||
/*
|
||||
* struct lpfc_mbx_alloc_rsrc_extents:
|
||||
* A mbox is generically 256 bytes long. An SLI4_CONFIG mailbox requires
|
||||
* 6 words of header + 4 words of shared subcommand header +
|
||||
* 1 words of Extent-Opcode-specific header = 11 words or 44 bytes total.
|
||||
*
|
||||
* An embedded version of SLI4_CONFIG therefore has 256 - 44 = 212 bytes
|
||||
* for extents payload.
|
||||
*
|
||||
* 212/2 (bytes per extent) = 106 extents.
|
||||
* 106/2 (extents per word) = 53 words.
|
||||
* lpfc_id_range id is statically size to 53.
|
||||
*
|
||||
* This mailbox definition is used for ALLOC or GET_ALLOCATED
|
||||
* extent ranges. For ALLOC, the type and cnt are required.
|
||||
* For GET_ALLOCATED, only the type is required.
|
||||
*/
|
||||
struct lpfc_mbx_alloc_rsrc_extents {
|
||||
struct mbox_header header;
|
||||
union {
|
||||
struct {
|
||||
uint32_t word4;
|
||||
#define lpfc_mbx_alloc_rsrc_extents_type_SHIFT 0
|
||||
#define lpfc_mbx_alloc_rsrc_extents_type_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_alloc_rsrc_extents_type_WORD word4
|
||||
#define lpfc_mbx_alloc_rsrc_extents_cnt_SHIFT 16
|
||||
#define lpfc_mbx_alloc_rsrc_extents_cnt_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_alloc_rsrc_extents_cnt_WORD word4
|
||||
} req;
|
||||
struct {
|
||||
uint32_t word4;
|
||||
#define lpfc_mbx_rsrc_cnt_SHIFT 0
|
||||
#define lpfc_mbx_rsrc_cnt_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rsrc_cnt_WORD word4
|
||||
struct lpfc_id_range id[53];
|
||||
} rsp;
|
||||
} u;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the non-embedded version of ALLOC or GET RSRC_EXTENTS. Word4 in this
|
||||
* structure shares the same SHIFT/MASK/WORD defines provided in the
|
||||
* mbx_alloc_rsrc_extents and mbx_get_alloc_rsrc_extents, word4, provided in
|
||||
* the structures defined above. This non-embedded structure provides for the
|
||||
* maximum number of extents supported by the port.
|
||||
*/
|
||||
struct lpfc_mbx_nembed_rsrc_extent {
|
||||
union lpfc_sli4_cfg_shdr cfg_shdr;
|
||||
uint32_t word4;
|
||||
struct lpfc_id_range id;
|
||||
};
|
||||
|
||||
struct lpfc_mbx_dealloc_rsrc_extents {
|
||||
struct mbox_header header;
|
||||
struct {
|
||||
uint32_t word4;
|
||||
#define lpfc_mbx_dealloc_rsrc_extents_type_SHIFT 0
|
||||
#define lpfc_mbx_dealloc_rsrc_extents_type_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_dealloc_rsrc_extents_type_WORD word4
|
||||
} req;
|
||||
|
||||
};
|
||||
|
||||
/* Start SLI4 FCoE specific mbox structures. */
|
||||
|
||||
struct lpfc_mbx_post_hdr_tmpl {
|
||||
struct mbox_header header;
|
||||
uint32_t word10;
|
||||
|
@ -1801,61 +1936,31 @@ struct lpfc_mbx_read_rev {
|
|||
|
||||
struct lpfc_mbx_read_config {
|
||||
uint32_t word1;
|
||||
#define lpfc_mbx_rd_conf_max_bbc_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_max_bbc_MASK 0x000000FF
|
||||
#define lpfc_mbx_rd_conf_max_bbc_WORD word1
|
||||
#define lpfc_mbx_rd_conf_init_bbc_SHIFT 8
|
||||
#define lpfc_mbx_rd_conf_init_bbc_MASK 0x000000FF
|
||||
#define lpfc_mbx_rd_conf_init_bbc_WORD word1
|
||||
#define lpfc_mbx_rd_conf_extnts_inuse_SHIFT 31
|
||||
#define lpfc_mbx_rd_conf_extnts_inuse_MASK 0x00000001
|
||||
#define lpfc_mbx_rd_conf_extnts_inuse_WORD word1
|
||||
uint32_t word2;
|
||||
#define lpfc_mbx_rd_conf_nport_did_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_nport_did_MASK 0x00FFFFFF
|
||||
#define lpfc_mbx_rd_conf_nport_did_WORD word2
|
||||
#define lpfc_mbx_rd_conf_topology_SHIFT 24
|
||||
#define lpfc_mbx_rd_conf_topology_MASK 0x000000FF
|
||||
#define lpfc_mbx_rd_conf_topology_WORD word2
|
||||
uint32_t word3;
|
||||
#define lpfc_mbx_rd_conf_ao_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_ao_MASK 0x00000001
|
||||
#define lpfc_mbx_rd_conf_ao_WORD word3
|
||||
#define lpfc_mbx_rd_conf_bb_scn_SHIFT 8
|
||||
#define lpfc_mbx_rd_conf_bb_scn_MASK 0x0000000F
|
||||
#define lpfc_mbx_rd_conf_bb_scn_WORD word3
|
||||
#define lpfc_mbx_rd_conf_cbb_scn_SHIFT 12
|
||||
#define lpfc_mbx_rd_conf_cbb_scn_MASK 0x0000000F
|
||||
#define lpfc_mbx_rd_conf_cbb_scn_WORD word3
|
||||
#define lpfc_mbx_rd_conf_mc_SHIFT 29
|
||||
#define lpfc_mbx_rd_conf_mc_MASK 0x00000001
|
||||
#define lpfc_mbx_rd_conf_mc_WORD word3
|
||||
uint32_t rsvd_3;
|
||||
uint32_t word4;
|
||||
#define lpfc_mbx_rd_conf_e_d_tov_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_e_d_tov_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rd_conf_e_d_tov_WORD word4
|
||||
uint32_t word5;
|
||||
#define lpfc_mbx_rd_conf_lp_tov_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_lp_tov_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rd_conf_lp_tov_WORD word5
|
||||
uint32_t rsvd_5;
|
||||
uint32_t word6;
|
||||
#define lpfc_mbx_rd_conf_r_a_tov_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_r_a_tov_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rd_conf_r_a_tov_WORD word6
|
||||
uint32_t word7;
|
||||
#define lpfc_mbx_rd_conf_r_t_tov_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_r_t_tov_MASK 0x000000FF
|
||||
#define lpfc_mbx_rd_conf_r_t_tov_WORD word7
|
||||
uint32_t word8;
|
||||
#define lpfc_mbx_rd_conf_al_tov_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_al_tov_MASK 0x0000000F
|
||||
#define lpfc_mbx_rd_conf_al_tov_WORD word8
|
||||
uint32_t rsvd_7;
|
||||
uint32_t rsvd_8;
|
||||
uint32_t word9;
|
||||
#define lpfc_mbx_rd_conf_lmt_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_lmt_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rd_conf_lmt_WORD word9
|
||||
uint32_t word10;
|
||||
#define lpfc_mbx_rd_conf_max_alpa_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_max_alpa_MASK 0x000000FF
|
||||
#define lpfc_mbx_rd_conf_max_alpa_WORD word10
|
||||
uint32_t word11_rsvd;
|
||||
uint32_t rsvd_10;
|
||||
uint32_t rsvd_11;
|
||||
uint32_t word12;
|
||||
#define lpfc_mbx_rd_conf_xri_base_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_xri_base_MASK 0x0000FFFF
|
||||
|
@ -1885,9 +1990,6 @@ struct lpfc_mbx_read_config {
|
|||
#define lpfc_mbx_rd_conf_vfi_count_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rd_conf_vfi_count_WORD word15
|
||||
uint32_t word16;
|
||||
#define lpfc_mbx_rd_conf_fcfi_base_SHIFT 0
|
||||
#define lpfc_mbx_rd_conf_fcfi_base_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rd_conf_fcfi_base_WORD word16
|
||||
#define lpfc_mbx_rd_conf_fcfi_count_SHIFT 16
|
||||
#define lpfc_mbx_rd_conf_fcfi_count_MASK 0x0000FFFF
|
||||
#define lpfc_mbx_rd_conf_fcfi_count_WORD word16
|
||||
|
@ -2197,6 +2299,12 @@ struct lpfc_sli4_parameters {
|
|||
#define cfg_fcoe_SHIFT 0
|
||||
#define cfg_fcoe_MASK 0x00000001
|
||||
#define cfg_fcoe_WORD word12
|
||||
#define cfg_ext_SHIFT 1
|
||||
#define cfg_ext_MASK 0x00000001
|
||||
#define cfg_ext_WORD word12
|
||||
#define cfg_hdrr_SHIFT 2
|
||||
#define cfg_hdrr_MASK 0x00000001
|
||||
#define cfg_hdrr_WORD word12
|
||||
#define cfg_phwq_SHIFT 15
|
||||
#define cfg_phwq_MASK 0x00000001
|
||||
#define cfg_phwq_WORD word12
|
||||
|
@ -2431,6 +2539,9 @@ struct lpfc_mqe {
|
|||
struct lpfc_mbx_cq_destroy cq_destroy;
|
||||
struct lpfc_mbx_wq_destroy wq_destroy;
|
||||
struct lpfc_mbx_rq_destroy rq_destroy;
|
||||
struct lpfc_mbx_get_rsrc_extent_info rsrc_extent_info;
|
||||
struct lpfc_mbx_alloc_rsrc_extents alloc_rsrc_extents;
|
||||
struct lpfc_mbx_dealloc_rsrc_extents dealloc_rsrc_extents;
|
||||
struct lpfc_mbx_post_sgl_pages post_sgl_pages;
|
||||
struct lpfc_mbx_nembed_cmd nembed_cmd;
|
||||
struct lpfc_mbx_read_rev read_rev;
|
||||
|
@ -2651,7 +2762,7 @@ struct lpfc_bmbx_create {
|
|||
#define SGL_ALIGN_SZ 64
|
||||
#define SGL_PAGE_SIZE 4096
|
||||
/* align SGL addr on a size boundary - adjust address up */
|
||||
#define NO_XRI ((uint16_t)-1)
|
||||
#define NO_XRI 0xffff
|
||||
|
||||
struct wqe_common {
|
||||
uint32_t word6;
|
||||
|
|
|
@ -212,7 +212,6 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
|
|||
lpfc_vpd_data = kmalloc(DMP_VPD_SIZE, GFP_KERNEL);
|
||||
if (!lpfc_vpd_data)
|
||||
goto out_free_mbox;
|
||||
|
||||
do {
|
||||
lpfc_dump_mem(phba, pmb, offset, DMP_REGION_VPD);
|
||||
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
|
||||
|
@ -603,7 +602,6 @@ lpfc_config_port_post(struct lpfc_hba *phba)
|
|||
/* Clear all pending interrupts */
|
||||
writel(0xffffffff, phba->HAregaddr);
|
||||
readl(phba->HAregaddr); /* flush */
|
||||
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
if (rc != MBX_BUSY)
|
||||
mempool_free(pmb, phba->mbox_mem_pool);
|
||||
|
@ -2690,6 +2688,7 @@ lpfc_scsi_free(struct lpfc_hba *phba)
|
|||
kfree(io);
|
||||
phba->total_iocbq_bufs--;
|
||||
}
|
||||
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3646,6 +3645,7 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba,
|
|||
lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
|
||||
"2718 Clear Virtual Link Received for VPI 0x%x"
|
||||
" tag 0x%x\n", acqe_fip->index, acqe_fip->event_tag);
|
||||
|
||||
vport = lpfc_find_vport_by_vpid(phba,
|
||||
acqe_fip->index - phba->vpi_base);
|
||||
ndlp = lpfc_sli4_perform_vport_cvl(vport);
|
||||
|
@ -4319,7 +4319,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
|
|||
spin_lock_init(&phba->sli4_hba.abts_sgl_list_lock);
|
||||
|
||||
/*
|
||||
* Initialize dirver internal slow-path work queues
|
||||
* Initialize driver internal slow-path work queues
|
||||
*/
|
||||
|
||||
/* Driver internel slow-path CQ Event pool */
|
||||
|
@ -4335,6 +4335,12 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
|
|||
/* Receive queue CQ Event work queue list */
|
||||
INIT_LIST_HEAD(&phba->sli4_hba.sp_unsol_work_queue);
|
||||
|
||||
/* Initialize extent block lists. */
|
||||
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_blk_list);
|
||||
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_xri_blk_list);
|
||||
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_vfi_blk_list);
|
||||
INIT_LIST_HEAD(&phba->lpfc_vpi_blk_list);
|
||||
|
||||
/* Initialize the driver internal SLI layer lists. */
|
||||
lpfc_sli_setup(phba);
|
||||
lpfc_sli_queue_setup(phba);
|
||||
|
@ -4409,9 +4415,19 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
|
|||
}
|
||||
/*
|
||||
* Get sli4 parameters that override parameters from Port capabilities.
|
||||
* If this call fails it is not a critical error so continue loading.
|
||||
* If this call fails, it isn't critical unless the SLI4 parameters come
|
||||
* back in conflict.
|
||||
*/
|
||||
lpfc_get_sli4_parameters(phba, mboxq);
|
||||
rc = lpfc_get_sli4_parameters(phba, mboxq);
|
||||
if (rc) {
|
||||
if (phba->sli4_hba.extents_in_use &&
|
||||
phba->sli4_hba.rpi_hdrs_in_use) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
"2999 Unsupported SLI4 Parameters "
|
||||
"Extents and RPI headers enabled.\n");
|
||||
goto out_free_bsmbx;
|
||||
}
|
||||
}
|
||||
mempool_free(mboxq, phba->mbox_mem_pool);
|
||||
/* Create all the SLI4 queues */
|
||||
rc = lpfc_sli4_queue_create(phba);
|
||||
|
@ -4436,7 +4452,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
|
|||
"1430 Failed to initialize sgl list.\n");
|
||||
goto out_free_sgl_list;
|
||||
}
|
||||
|
||||
rc = lpfc_sli4_init_rpi_hdrs(phba);
|
||||
if (rc) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||
|
@ -4555,6 +4570,9 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba)
|
|||
lpfc_sli4_cq_event_release_all(phba);
|
||||
lpfc_sli4_cq_event_pool_destroy(phba);
|
||||
|
||||
/* Release resource identifiers. */
|
||||
lpfc_sli4_dealloc_resource_identifiers(phba);
|
||||
|
||||
/* Free the bsmbx region. */
|
||||
lpfc_destroy_bootstrap_mbox(phba);
|
||||
|
||||
|
@ -4755,6 +4773,7 @@ lpfc_init_iocb_list(struct lpfc_hba *phba, int iocb_count)
|
|||
"Unloading driver.\n", __func__);
|
||||
goto out_free_iocbq;
|
||||
}
|
||||
iocbq_entry->sli4_lxritag = NO_XRI;
|
||||
iocbq_entry->sli4_xritag = NO_XRI;
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
|
@ -4852,7 +4871,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba)
|
|||
|
||||
els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||
"2400 lpfc_init_sgl_list els %d.\n",
|
||||
"2400 ELS XRI count %d.\n",
|
||||
els_xri_cnt);
|
||||
/* Initialize and populate the sglq list per host/VF. */
|
||||
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_sgl_list);
|
||||
|
@ -4885,7 +4904,6 @@ lpfc_init_sgl_list(struct lpfc_hba *phba)
|
|||
phba->sli4_hba.scsi_xri_max =
|
||||
phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt;
|
||||
phba->sli4_hba.scsi_xri_cnt = 0;
|
||||
|
||||
phba->sli4_hba.lpfc_scsi_psb_array =
|
||||
kzalloc((sizeof(struct lpfc_scsi_buf *) *
|
||||
phba->sli4_hba.scsi_xri_max), GFP_KERNEL);
|
||||
|
@ -4908,13 +4926,6 @@ lpfc_init_sgl_list(struct lpfc_hba *phba)
|
|||
goto out_free_mem;
|
||||
}
|
||||
|
||||
sglq_entry->sli4_xritag = lpfc_sli4_next_xritag(phba);
|
||||
if (sglq_entry->sli4_xritag == NO_XRI) {
|
||||
kfree(sglq_entry);
|
||||
printk(KERN_ERR "%s: failed to allocate XRI.\n"
|
||||
"Unloading driver.\n", __func__);
|
||||
goto out_free_mem;
|
||||
}
|
||||
sglq_entry->buff_type = GEN_BUFF_TYPE;
|
||||
sglq_entry->virt = lpfc_mbuf_alloc(phba, 0, &sglq_entry->phys);
|
||||
if (sglq_entry->virt == NULL) {
|
||||
|
@ -4963,24 +4974,20 @@ int
|
|||
lpfc_sli4_init_rpi_hdrs(struct lpfc_hba *phba)
|
||||
{
|
||||
int rc = 0;
|
||||
int longs;
|
||||
uint16_t rpi_count;
|
||||
struct lpfc_rpi_hdr *rpi_hdr;
|
||||
|
||||
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_hdr_list);
|
||||
|
||||
/*
|
||||
* Provision an rpi bitmask range for discovery. The total count
|
||||
* is the difference between max and base + 1.
|
||||
* If the SLI4 port supports extents, posting the rpi header isn't
|
||||
* required. Set the expected maximum count and let the actual value
|
||||
* get set when extents are fully allocated.
|
||||
*/
|
||||
rpi_count = phba->sli4_hba.max_cfg_param.rpi_base +
|
||||
phba->sli4_hba.max_cfg_param.max_rpi - 1;
|
||||
|
||||
longs = ((rpi_count) + BITS_PER_LONG - 1) / BITS_PER_LONG;
|
||||
phba->sli4_hba.rpi_bmask = kzalloc(longs * sizeof(unsigned long),
|
||||
GFP_KERNEL);
|
||||
if (!phba->sli4_hba.rpi_bmask)
|
||||
return -ENOMEM;
|
||||
if (!phba->sli4_hba.rpi_hdrs_in_use) {
|
||||
phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.max_rpi;
|
||||
return rc;
|
||||
}
|
||||
if (phba->sli4_hba.extents_in_use)
|
||||
return -EIO;
|
||||
|
||||
rpi_hdr = lpfc_sli4_create_rpi_hdr(phba);
|
||||
if (!rpi_hdr) {
|
||||
|
@ -5014,11 +5021,28 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
|
|||
struct lpfc_rpi_hdr *rpi_hdr;
|
||||
uint32_t rpi_count;
|
||||
|
||||
/*
|
||||
* If the SLI4 port supports extents, posting the rpi header isn't
|
||||
* required. Set the expected maximum count and let the actual value
|
||||
* get set when extents are fully allocated.
|
||||
*/
|
||||
if (!phba->sli4_hba.rpi_hdrs_in_use)
|
||||
return NULL;
|
||||
if (phba->sli4_hba.extents_in_use)
|
||||
return NULL;
|
||||
|
||||
/* The limit on the logical index is just the max_rpi count. */
|
||||
rpi_limit = phba->sli4_hba.max_cfg_param.rpi_base +
|
||||
phba->sli4_hba.max_cfg_param.max_rpi - 1;
|
||||
phba->sli4_hba.max_cfg_param.max_rpi - 1;
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
curr_rpi_range = phba->sli4_hba.next_rpi;
|
||||
/*
|
||||
* Establish the starting RPI in this header block. The starting
|
||||
* rpi is normalized to a zero base because the physical rpi is
|
||||
* port based.
|
||||
*/
|
||||
curr_rpi_range = phba->sli4_hba.next_rpi -
|
||||
phba->sli4_hba.max_cfg_param.rpi_base;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
||||
/*
|
||||
|
@ -5031,6 +5055,8 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
|
|||
else
|
||||
rpi_count = LPFC_RPI_HDR_COUNT;
|
||||
|
||||
if (!rpi_count)
|
||||
return NULL;
|
||||
/*
|
||||
* First allocate the protocol header region for the port. The
|
||||
* port expects a 4KB DMA-mapped memory region that is 4K aligned.
|
||||
|
@ -5063,12 +5089,14 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
|
|||
rpi_hdr->len = LPFC_HDR_TEMPLATE_SIZE;
|
||||
rpi_hdr->page_count = 1;
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
rpi_hdr->start_rpi = phba->sli4_hba.next_rpi;
|
||||
|
||||
/* The rpi_hdr stores the logical index only. */
|
||||
rpi_hdr->start_rpi = curr_rpi_range;
|
||||
list_add_tail(&rpi_hdr->list, &phba->sli4_hba.lpfc_rpi_hdr_list);
|
||||
|
||||
/*
|
||||
* The next_rpi stores the next module-64 rpi value to post
|
||||
* in any subsequent rpi memory region postings.
|
||||
* The next_rpi stores the next logical module-64 rpi value used
|
||||
* to post physical rpis in subsequent rpi postings.
|
||||
*/
|
||||
phba->sli4_hba.next_rpi += rpi_count;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
@ -5087,15 +5115,18 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
|
|||
* @phba: pointer to lpfc hba data structure.
|
||||
*
|
||||
* This routine is invoked to remove all memory resources allocated
|
||||
* to support rpis. This routine presumes the caller has released all
|
||||
* rpis consumed by fabric or port logins and is prepared to have
|
||||
* the header pages removed.
|
||||
* to support rpis for SLI4 ports not supporting extents. This routine
|
||||
* presumes the caller has released all rpis consumed by fabric or port
|
||||
* logins and is prepared to have the header pages removed.
|
||||
**/
|
||||
void
|
||||
lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *phba)
|
||||
{
|
||||
struct lpfc_rpi_hdr *rpi_hdr, *next_rpi_hdr;
|
||||
|
||||
if (!phba->sli4_hba.rpi_hdrs_in_use)
|
||||
goto exit;
|
||||
|
||||
list_for_each_entry_safe(rpi_hdr, next_rpi_hdr,
|
||||
&phba->sli4_hba.lpfc_rpi_hdr_list, list) {
|
||||
list_del(&rpi_hdr->list);
|
||||
|
@ -5104,7 +5135,9 @@ lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *phba)
|
|||
kfree(rpi_hdr->dmabuf);
|
||||
kfree(rpi_hdr);
|
||||
}
|
||||
phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.rpi_base;
|
||||
exit:
|
||||
/* There are no rpis available to the port now. */
|
||||
phba->sli4_hba.next_rpi = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5873,6 +5906,8 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
|
|||
rc = -EIO;
|
||||
} else {
|
||||
rd_config = &pmb->u.mqe.un.rd_config;
|
||||
phba->sli4_hba.extents_in_use =
|
||||
bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config);
|
||||
phba->sli4_hba.max_cfg_param.max_xri =
|
||||
bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
|
||||
phba->sli4_hba.max_cfg_param.xri_base =
|
||||
|
@ -5891,8 +5926,6 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
|
|||
bf_get(lpfc_mbx_rd_conf_vfi_base, rd_config);
|
||||
phba->sli4_hba.max_cfg_param.max_fcfi =
|
||||
bf_get(lpfc_mbx_rd_conf_fcfi_count, rd_config);
|
||||
phba->sli4_hba.max_cfg_param.fcfi_base =
|
||||
bf_get(lpfc_mbx_rd_conf_fcfi_base, rd_config);
|
||||
phba->sli4_hba.max_cfg_param.max_eq =
|
||||
bf_get(lpfc_mbx_rd_conf_eq_count, rd_config);
|
||||
phba->sli4_hba.max_cfg_param.max_rq =
|
||||
|
@ -5910,11 +5943,13 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
|
|||
(phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0;
|
||||
phba->max_vports = phba->max_vpi;
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||
"2003 cfg params XRI(B:%d M:%d), "
|
||||
"2003 cfg params Extents? %d "
|
||||
"XRI(B:%d M:%d), "
|
||||
"VPI(B:%d M:%d) "
|
||||
"VFI(B:%d M:%d) "
|
||||
"RPI(B:%d M:%d) "
|
||||
"FCFI(B:%d M:%d)\n",
|
||||
"FCFI(Count:%d)\n",
|
||||
phba->sli4_hba.extents_in_use,
|
||||
phba->sli4_hba.max_cfg_param.xri_base,
|
||||
phba->sli4_hba.max_cfg_param.max_xri,
|
||||
phba->sli4_hba.max_cfg_param.vpi_base,
|
||||
|
@ -5923,7 +5958,6 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
|
|||
phba->sli4_hba.max_cfg_param.max_vfi,
|
||||
phba->sli4_hba.max_cfg_param.rpi_base,
|
||||
phba->sli4_hba.max_cfg_param.max_rpi,
|
||||
phba->sli4_hba.max_cfg_param.fcfi_base,
|
||||
phba->sli4_hba.max_cfg_param.max_fcfi);
|
||||
}
|
||||
|
||||
|
@ -8104,6 +8138,13 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
|
|||
int length;
|
||||
struct lpfc_sli4_parameters *mbx_sli4_parameters;
|
||||
|
||||
/*
|
||||
* By default, the driver assumes the SLI4 port requires RPI
|
||||
* header postings. The SLI4_PARAM response will correct this
|
||||
* assumption.
|
||||
*/
|
||||
phba->sli4_hba.rpi_hdrs_in_use = 1;
|
||||
|
||||
/* Read the port's SLI4 Config Parameters */
|
||||
length = (sizeof(struct lpfc_mbx_get_sli4_parameters) -
|
||||
sizeof(struct lpfc_sli4_cfg_mhdr));
|
||||
|
@ -8140,6 +8181,8 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
|
|||
mbx_sli4_parameters);
|
||||
sli4_params->sgl_pp_align = bf_get(cfg_sgl_pp_align,
|
||||
mbx_sli4_parameters);
|
||||
phba->sli4_hba.extents_in_use = bf_get(cfg_ext, mbx_sli4_parameters);
|
||||
phba->sli4_hba.rpi_hdrs_in_use = bf_get(cfg_hdrr, mbx_sli4_parameters);
|
||||
|
||||
/* Make sure that sge_supp_len can be handled by the driver */
|
||||
if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE)
|
||||
|
|
|
@ -610,7 +610,8 @@ lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
|
|||
mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
|
||||
mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
|
||||
mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
|
||||
mb->un.varRdSparm.vpi = vpi + phba->vpi_base;
|
||||
if (phba->sli_rev >= LPFC_SLI_REV3)
|
||||
mb->un.varRdSparm.vpi = phba->vpi_ids[vpi];
|
||||
|
||||
/* save address for completion */
|
||||
pmb->context1 = mp;
|
||||
|
@ -643,9 +644,10 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
|
|||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
|
||||
mb->un.varUnregDID.did = did;
|
||||
if (vpi != 0xffff)
|
||||
vpi += phba->vpi_base;
|
||||
mb->un.varUnregDID.vpi = vpi;
|
||||
if ((vpi != 0xffff) &&
|
||||
(phba->sli_rev == LPFC_SLI_REV4))
|
||||
mb->un.varUnregDID.vpi = phba->vpi_ids[vpi];
|
||||
|
||||
mb->mbxCommand = MBX_UNREG_D_ID;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
|
@ -738,12 +740,10 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
|
|||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
|
||||
mb->un.varRegLogin.rpi = 0;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||
mb->un.varRegLogin.rpi = rpi;
|
||||
if (mb->un.varRegLogin.rpi == LPFC_RPI_ALLOC_ERROR)
|
||||
return 1;
|
||||
}
|
||||
mb->un.varRegLogin.vpi = vpi + phba->vpi_base;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
mb->un.varRegLogin.rpi = phba->sli4_hba.rpi_ids[rpi];
|
||||
if (phba->sli_rev >= LPFC_SLI_REV3)
|
||||
mb->un.varRegLogin.vpi = phba->vpi_ids[vpi];
|
||||
mb->un.varRegLogin.did = did;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
/* Get a buffer to hold NPorts Service Parameters */
|
||||
|
@ -757,7 +757,7 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
|
|||
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
|
||||
"0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, "
|
||||
"rpi x%x\n", vpi, did, rpi);
|
||||
return (1);
|
||||
return 1;
|
||||
}
|
||||
INIT_LIST_HEAD(&mp->list);
|
||||
sparam = mp->virt;
|
||||
|
@ -773,7 +773,7 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
|
|||
mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
|
||||
mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -789,6 +789,9 @@ lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
|
|||
*
|
||||
* This routine prepares the mailbox command for unregistering remote port
|
||||
* login.
|
||||
*
|
||||
* For SLI4 ports, the rpi passed to this function must be the physical
|
||||
* rpi value, not the logical index.
|
||||
**/
|
||||
void
|
||||
lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
|
||||
|
@ -799,9 +802,10 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
|
|||
mb = &pmb->u.mb;
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
|
||||
mb->un.varUnregLogin.rpi = (uint16_t) rpi;
|
||||
mb->un.varUnregLogin.rpi = rpi;
|
||||
mb->un.varUnregLogin.rsvd1 = 0;
|
||||
mb->un.varUnregLogin.vpi = vpi + phba->vpi_base;
|
||||
if (phba->sli_rev >= LPFC_SLI_REV3)
|
||||
mb->un.varUnregLogin.vpi = phba->vpi_ids[vpi];
|
||||
|
||||
mb->mbxCommand = MBX_UNREG_LOGIN;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
|
@ -825,9 +829,16 @@ lpfc_sli4_unreg_all_rpis(struct lpfc_vport *vport)
|
|||
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (mbox) {
|
||||
lpfc_unreg_login(phba, vport->vpi,
|
||||
vport->vpi + phba->vpi_base, mbox);
|
||||
mbox->u.mb.un.varUnregLogin.rsvd1 = 0x4000 ;
|
||||
/*
|
||||
* For SLI4 functions, the rpi field is overloaded for
|
||||
* the vport context unreg all. This routine passes
|
||||
* 0 for the rpi field in lpfc_unreg_login for compatibility
|
||||
* with SLI3 and then overrides the rpi field with the
|
||||
* expected value for SLI4.
|
||||
*/
|
||||
lpfc_unreg_login(phba, vport->vpi, phba->vpi_ids[vport->vpi],
|
||||
mbox);
|
||||
mbox->u.mb.un.varUnregLogin.rsvd1 = 0x4000;
|
||||
mbox->vport = vport;
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
mbox->context1 = NULL;
|
||||
|
@ -865,9 +876,13 @@ lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb)
|
|||
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
||||
!(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI))
|
||||
mb->un.varRegVpi.upd = 1;
|
||||
mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base;
|
||||
|
||||
mb->un.varRegVpi.vpi = phba->vpi_ids[vport->vpi];
|
||||
mb->un.varRegVpi.sid = vport->fc_myDID;
|
||||
mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
mb->un.varRegVpi.vfi = phba->sli4_hba.vfi_ids[vport->vfi];
|
||||
else
|
||||
mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
|
||||
memcpy(mb->un.varRegVpi.wwn, &vport->fc_portname,
|
||||
sizeof(struct lpfc_name));
|
||||
mb->un.varRegVpi.wwn[0] = cpu_to_le32(mb->un.varRegVpi.wwn[0]);
|
||||
|
@ -901,10 +916,10 @@ lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
|
|||
MAILBOX_t *mb = &pmb->u.mb;
|
||||
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
|
||||
|
||||
if (phba->sli_rev < LPFC_SLI_REV4)
|
||||
mb->un.varUnregVpi.vpi = vpi + phba->vpi_base;
|
||||
else
|
||||
mb->un.varUnregVpi.sli4_vpi = vpi + phba->vpi_base;
|
||||
if (phba->sli_rev == LPFC_SLI_REV3)
|
||||
mb->un.varUnregVpi.vpi = phba->vpi_ids[vpi];
|
||||
else if (phba->sli_rev >= LPFC_SLI_REV4)
|
||||
mb->un.varUnregVpi.sli4_vpi = phba->vpi_ids[vpi];
|
||||
|
||||
mb->mbxCommand = MBX_UNREG_VPI;
|
||||
mb->mbxOwner = OWN_HOST;
|
||||
|
@ -1735,12 +1750,12 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
|
|||
return length;
|
||||
}
|
||||
|
||||
/* Setup for the none-embedded mbox command */
|
||||
/* Setup for the non-embedded mbox command */
|
||||
pcount = (SLI4_PAGE_ALIGN(length))/SLI4_PAGE_SIZE;
|
||||
pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ?
|
||||
LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount;
|
||||
/* Allocate record for keeping SGE virtual addresses */
|
||||
mbox->sge_array = kmalloc(sizeof(struct lpfc_mbx_nembed_sge_virt),
|
||||
mbox->sge_array = kzalloc(sizeof(struct lpfc_mbx_nembed_sge_virt),
|
||||
GFP_KERNEL);
|
||||
if (!mbox->sge_array) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
|
||||
|
@ -1790,11 +1805,86 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
|
|||
/* The sub-header is in DMA memory, which needs endian converstion */
|
||||
if (cfg_shdr)
|
||||
lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr,
|
||||
sizeof(union lpfc_sli4_cfg_shdr));
|
||||
|
||||
sizeof(union lpfc_sli4_cfg_shdr));
|
||||
return alloc_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_mbox_rsrc_extent - Initialize the opcode resource extent.
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
* @mbox: pointer to an allocated lpfc mbox resource.
|
||||
* @exts_count: the number of extents, if required, to allocate.
|
||||
* @rsrc_type: the resource extent type.
|
||||
* @emb: true if LPFC_SLI4_MBX_EMBED. false if LPFC_SLI4_MBX_NEMBED.
|
||||
*
|
||||
* This routine completes the subcommand header for SLI4 resource extent
|
||||
* mailbox commands. It is called after lpfc_sli4_config. The caller must
|
||||
* pass an allocated mailbox and the attributes required to initialize the
|
||||
* mailbox correctly.
|
||||
*
|
||||
* Return: the actual length of the mbox command allocated.
|
||||
**/
|
||||
int
|
||||
lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
|
||||
uint16_t exts_count, uint16_t rsrc_type, bool emb)
|
||||
{
|
||||
uint8_t opcode = 0;
|
||||
struct lpfc_mbx_nembed_rsrc_extent *n_rsrc_extnt = NULL;
|
||||
void *virtaddr = NULL;
|
||||
|
||||
/* Set up SLI4 ioctl command header fields */
|
||||
if (emb == LPFC_SLI4_MBX_NEMBED) {
|
||||
/* Get the first SGE entry from the non-embedded DMA memory */
|
||||
virtaddr = mbox->sge_array->addr[0];
|
||||
if (virtaddr == NULL)
|
||||
return 1;
|
||||
n_rsrc_extnt = (struct lpfc_mbx_nembed_rsrc_extent *) virtaddr;
|
||||
}
|
||||
|
||||
/*
|
||||
* The resource type is common to all extent Opcodes and resides in the
|
||||
* same position.
|
||||
*/
|
||||
if (emb == LPFC_SLI4_MBX_EMBED)
|
||||
bf_set(lpfc_mbx_alloc_rsrc_extents_type,
|
||||
&mbox->u.mqe.un.alloc_rsrc_extents.u.req,
|
||||
rsrc_type);
|
||||
else {
|
||||
/* This is DMA data. Byteswap is required. */
|
||||
bf_set(lpfc_mbx_alloc_rsrc_extents_type,
|
||||
n_rsrc_extnt, rsrc_type);
|
||||
lpfc_sli_pcimem_bcopy(&n_rsrc_extnt->word4,
|
||||
&n_rsrc_extnt->word4,
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
|
||||
/* Complete the initialization for the particular Opcode. */
|
||||
opcode = lpfc_sli4_mbox_opcode_get(phba, mbox);
|
||||
switch (opcode) {
|
||||
case LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT:
|
||||
if (emb == LPFC_SLI4_MBX_EMBED)
|
||||
bf_set(lpfc_mbx_alloc_rsrc_extents_cnt,
|
||||
&mbox->u.mqe.un.alloc_rsrc_extents.u.req,
|
||||
exts_count);
|
||||
else
|
||||
bf_set(lpfc_mbx_alloc_rsrc_extents_cnt,
|
||||
n_rsrc_extnt, exts_count);
|
||||
break;
|
||||
case LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT:
|
||||
case LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO:
|
||||
case LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT:
|
||||
/* Initialization is complete.*/
|
||||
break;
|
||||
default:
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
|
||||
"2929 Resource Extent Opcode x%x is "
|
||||
"unsupported\n", opcode);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_mbox_opcode_get - Get the opcode from a sli4 mailbox command
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
|
@ -1939,9 +2029,12 @@ lpfc_init_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
|
|||
bf_set(lpfc_init_vfi_vr, init_vfi, 1);
|
||||
bf_set(lpfc_init_vfi_vt, init_vfi, 1);
|
||||
bf_set(lpfc_init_vfi_vp, init_vfi, 1);
|
||||
bf_set(lpfc_init_vfi_vfi, init_vfi, vport->vfi + vport->phba->vfi_base);
|
||||
bf_set(lpfc_init_vpi_vpi, init_vfi, vport->vpi + vport->phba->vpi_base);
|
||||
bf_set(lpfc_init_vfi_fcfi, init_vfi, vport->phba->fcf.fcfi);
|
||||
bf_set(lpfc_init_vfi_vfi, init_vfi,
|
||||
vport->phba->sli4_hba.vfi_ids[vport->vfi]);
|
||||
bf_set(lpfc_init_vpi_vpi, init_vfi,
|
||||
vport->phba->vpi_ids[vport->vpi]);
|
||||
bf_set(lpfc_init_vfi_fcfi, init_vfi,
|
||||
vport->phba->fcf.fcfi);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1964,9 +2057,10 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys)
|
|||
reg_vfi = &mbox->u.mqe.un.reg_vfi;
|
||||
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_VFI);
|
||||
bf_set(lpfc_reg_vfi_vp, reg_vfi, 1);
|
||||
bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base);
|
||||
bf_set(lpfc_reg_vfi_vfi, reg_vfi,
|
||||
vport->phba->sli4_hba.vfi_ids[vport->vfi]);
|
||||
bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi);
|
||||
bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base);
|
||||
bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->phba->vpi_ids[vport->vpi]);
|
||||
memcpy(reg_vfi->wwn, &vport->fc_portname, sizeof(struct lpfc_name));
|
||||
reg_vfi->wwn[0] = cpu_to_le32(reg_vfi->wwn[0]);
|
||||
reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]);
|
||||
|
@ -1997,9 +2091,9 @@ lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi)
|
|||
memset(mbox, 0, sizeof(*mbox));
|
||||
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI);
|
||||
bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi,
|
||||
vpi + phba->vpi_base);
|
||||
phba->vpi_ids[vpi]);
|
||||
bf_set(lpfc_init_vpi_vfi, &mbox->u.mqe.un.init_vpi,
|
||||
phba->pport->vfi + phba->vfi_base);
|
||||
phba->sli4_hba.vfi_ids[phba->pport->vfi]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2019,7 +2113,7 @@ lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
|
|||
memset(mbox, 0, sizeof(*mbox));
|
||||
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI);
|
||||
bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi,
|
||||
vport->vfi + vport->phba->vfi_base);
|
||||
vport->phba->sli4_hba.vfi_ids[vport->vfi]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2131,12 +2225,14 @@ lpfc_unreg_fcfi(struct lpfcMboxq *mbox, uint16_t fcfi)
|
|||
void
|
||||
lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp)
|
||||
{
|
||||
struct lpfc_hba *phba = ndlp->phba;
|
||||
struct lpfc_mbx_resume_rpi *resume_rpi;
|
||||
|
||||
memset(mbox, 0, sizeof(*mbox));
|
||||
resume_rpi = &mbox->u.mqe.un.resume_rpi;
|
||||
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI);
|
||||
bf_set(lpfc_resume_rpi_index, resume_rpi, ndlp->nlp_rpi);
|
||||
bf_set(lpfc_resume_rpi_index, resume_rpi,
|
||||
phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
|
||||
bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI);
|
||||
resume_rpi->event_tag = ndlp->phba->fc_eventTag;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,6 @@ int
|
|||
lpfc_mem_alloc(struct lpfc_hba *phba, int align)
|
||||
{
|
||||
struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
|
||||
int longs;
|
||||
int i;
|
||||
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
|
@ -138,17 +137,8 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align)
|
|||
phba->lpfc_hrb_pool = NULL;
|
||||
phba->lpfc_drb_pool = NULL;
|
||||
}
|
||||
/* vpi zero is reserved for the physical port so add 1 to max */
|
||||
longs = ((phba->max_vpi + 1) + BITS_PER_LONG - 1) / BITS_PER_LONG;
|
||||
phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), GFP_KERNEL);
|
||||
if (!phba->vpi_bmask)
|
||||
goto fail_free_dbq_pool;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_free_dbq_pool:
|
||||
pci_pool_destroy(phba->lpfc_drb_pool);
|
||||
phba->lpfc_drb_pool = NULL;
|
||||
fail_free_hrb_pool:
|
||||
pci_pool_destroy(phba->lpfc_hrb_pool);
|
||||
phba->lpfc_hrb_pool = NULL;
|
||||
|
@ -191,9 +181,6 @@ lpfc_mem_free(struct lpfc_hba *phba)
|
|||
int i;
|
||||
struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
|
||||
|
||||
/* Free VPI bitmask memory */
|
||||
kfree(phba->vpi_bmask);
|
||||
|
||||
/* Free HBQ pools */
|
||||
lpfc_sli_hbqbuf_free_all(phba);
|
||||
if (phba->lpfc_drb_pool)
|
||||
|
|
|
@ -652,6 +652,7 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
|||
lpfc_unreg_rpi(vport, ndlp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_release_rpi - Release a RPI by issuing unreg_login mailbox cmd.
|
||||
* @phba : Pointer to lpfc_hba structure.
|
||||
|
@ -1394,8 +1395,11 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
|
|||
if (mb->mbxStatus) {
|
||||
/* RegLogin failed */
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
|
||||
"0246 RegLogin failed Data: x%x x%x x%x\n",
|
||||
did, mb->mbxStatus, vport->port_state);
|
||||
"0246 RegLogin failed Data: x%x x%x x%x x%x "
|
||||
"x%x\n",
|
||||
did, mb->mbxStatus, vport->port_state,
|
||||
mb->un.varRegLogin.vpi,
|
||||
mb->un.varRegLogin.rpi);
|
||||
/*
|
||||
* If RegLogin failed due to lack of HBA resources do not
|
||||
* retry discovery.
|
||||
|
@ -1419,7 +1423,10 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
|
|||
return ndlp->nlp_state;
|
||||
}
|
||||
|
||||
ndlp->nlp_rpi = mb->un.varWords[0];
|
||||
/* SLI4 ports have preallocated logical rpis. */
|
||||
if (vport->phba->sli_rev < LPFC_SLI_REV4)
|
||||
ndlp->nlp_rpi = mb->un.varWords[0];
|
||||
|
||||
ndlp->nlp_flag |= NLP_RPI_REGISTERED;
|
||||
|
||||
/* Only if we are not a fabric nport do we issue PRLI */
|
||||
|
@ -2020,7 +2027,9 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport,
|
|||
MAILBOX_t *mb = &pmb->u.mb;
|
||||
|
||||
if (!mb->mbxStatus) {
|
||||
ndlp->nlp_rpi = mb->un.varWords[0];
|
||||
/* SLI4 ports have preallocated logical rpis. */
|
||||
if (vport->phba->sli_rev < LPFC_SLI_REV4)
|
||||
ndlp->nlp_rpi = mb->un.varWords[0];
|
||||
ndlp->nlp_flag |= NLP_RPI_REGISTERED;
|
||||
} else {
|
||||
if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
|
||||
|
|
|
@ -743,7 +743,14 @@ lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *phba)
|
|||
if (bcnt == 0)
|
||||
continue;
|
||||
/* Now, post the SCSI buffer list sgls as a block */
|
||||
status = lpfc_sli4_post_scsi_sgl_block(phba, &sblist, bcnt);
|
||||
if (!phba->sli4_hba.extents_in_use)
|
||||
status = lpfc_sli4_post_scsi_sgl_block(phba,
|
||||
&sblist,
|
||||
bcnt);
|
||||
else
|
||||
status = lpfc_sli4_post_scsi_sgl_blk_ext(phba,
|
||||
&sblist,
|
||||
bcnt);
|
||||
/* Reset SCSI buffer count for next round of posting */
|
||||
bcnt = 0;
|
||||
while (!list_empty(&sblist)) {
|
||||
|
@ -787,7 +794,7 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
|
|||
dma_addr_t pdma_phys_fcp_cmd;
|
||||
dma_addr_t pdma_phys_fcp_rsp;
|
||||
dma_addr_t pdma_phys_bpl, pdma_phys_bpl1;
|
||||
uint16_t iotag, last_xritag = NO_XRI;
|
||||
uint16_t iotag, last_xritag = NO_XRI, lxri = 0;
|
||||
int status = 0, index;
|
||||
int bcnt;
|
||||
int non_sequential_xri = 0;
|
||||
|
@ -823,13 +830,15 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
|
|||
break;
|
||||
}
|
||||
|
||||
psb->cur_iocbq.sli4_xritag = lpfc_sli4_next_xritag(phba);
|
||||
if (psb->cur_iocbq.sli4_xritag == NO_XRI) {
|
||||
lxri = lpfc_sli4_next_xritag(phba);
|
||||
if (lxri == NO_XRI) {
|
||||
pci_pool_free(phba->lpfc_scsi_dma_buf_pool,
|
||||
psb->data, psb->dma_handle);
|
||||
kfree(psb);
|
||||
break;
|
||||
}
|
||||
psb->cur_iocbq.sli4_lxritag = lxri;
|
||||
psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri];
|
||||
if (last_xritag != NO_XRI
|
||||
&& psb->cur_iocbq.sli4_xritag != (last_xritag+1)) {
|
||||
non_sequential_xri = 1;
|
||||
|
@ -916,7 +925,21 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
|
|||
}
|
||||
}
|
||||
if (bcnt) {
|
||||
status = lpfc_sli4_post_scsi_sgl_block(phba, &sblist, bcnt);
|
||||
if (!phba->sli4_hba.extents_in_use)
|
||||
status = lpfc_sli4_post_scsi_sgl_block(phba,
|
||||
&sblist,
|
||||
bcnt);
|
||||
else
|
||||
status = lpfc_sli4_post_scsi_sgl_blk_ext(phba,
|
||||
&sblist,
|
||||
bcnt);
|
||||
|
||||
if (status) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
|
||||
"3021 SCSI SGL post error %d\n",
|
||||
status);
|
||||
bcnt = 0;
|
||||
}
|
||||
/* Reset SCSI buffer count for next round of posting */
|
||||
while (!list_empty(&sblist)) {
|
||||
list_remove_head(&sblist, psb, struct lpfc_scsi_buf,
|
||||
|
@ -2797,6 +2820,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
|
|||
* of the scsi_cmnd request_buffer
|
||||
*/
|
||||
piocbq->iocb.ulpContext = pnode->nlp_rpi;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
piocbq->iocb.ulpContext =
|
||||
phba->sli4_hba.rpi_ids[pnode->nlp_rpi];
|
||||
if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE)
|
||||
piocbq->iocb.ulpFCP2Rcvy = 1;
|
||||
else
|
||||
|
@ -2810,7 +2836,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
|
|||
}
|
||||
|
||||
/**
|
||||
* lpfc_scsi_prep_task_mgmt_cmnd - Convert SLI3 scsi TM cmd to FCP info unit
|
||||
* lpfc_scsi_prep_task_mgmt_cmd - Convert SLI3 scsi TM cmd to FCP info unit
|
||||
* @vport: The virtual port for which this call is being executed.
|
||||
* @lpfc_cmd: Pointer to lpfc_scsi_buf data structure.
|
||||
* @lun: Logical unit number.
|
||||
|
@ -2854,6 +2880,10 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
|
|||
lpfc_fcpcmd_to_iocb(piocb->unsli3.fcp_ext.icd, fcp_cmnd);
|
||||
piocb->ulpCommand = CMD_FCP_ICMND64_CR;
|
||||
piocb->ulpContext = ndlp->nlp_rpi;
|
||||
if (vport->phba->sli_rev == LPFC_SLI_REV4) {
|
||||
piocb->ulpContext =
|
||||
vport->phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
|
||||
}
|
||||
if (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) {
|
||||
piocb->ulpFCP2Rcvy = 1;
|
||||
}
|
||||
|
@ -3408,9 +3438,10 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
|
|||
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
|
||||
"0702 Issue %s to TGT %d LUN %d "
|
||||
"rpi x%x nlp_flag x%x\n",
|
||||
"rpi x%x nlp_flag x%x Data: x%x x%x\n",
|
||||
lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id,
|
||||
pnode->nlp_rpi, pnode->nlp_flag);
|
||||
pnode->nlp_rpi, pnode->nlp_flag, iocbq->sli4_xritag,
|
||||
iocbq->iocb_flag);
|
||||
|
||||
status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING,
|
||||
iocbq, iocbqrsp, lpfc_cmd->timeout);
|
||||
|
@ -3422,10 +3453,12 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
|
|||
ret = FAILED;
|
||||
lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
|
||||
"0727 TMF %s to TGT %d LUN %d failed (%d, %d)\n",
|
||||
"0727 TMF %s to TGT %d LUN %d failed (%d, %d) "
|
||||
"iocb_flag x%x\n",
|
||||
lpfc_taskmgmt_name(task_mgmt_cmd),
|
||||
tgt_id, lun_id, iocbqrsp->iocb.ulpStatus,
|
||||
iocbqrsp->iocb.un.ulpWord[4]);
|
||||
iocbqrsp->iocb.un.ulpWord[4],
|
||||
iocbq->iocb_flag);
|
||||
} else if (status == IOCB_BUSY)
|
||||
ret = FAILED;
|
||||
else
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -52,6 +52,7 @@ struct lpfc_iocbq {
|
|||
struct list_head clist;
|
||||
struct list_head dlist;
|
||||
uint16_t iotag; /* pre-assigned IO tag */
|
||||
uint16_t sli4_lxritag; /* logical pre-assigned XRI. */
|
||||
uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */
|
||||
struct lpfc_cq_event cq_event;
|
||||
|
||||
|
|
|
@ -310,7 +310,6 @@ struct lpfc_max_cfg_param {
|
|||
uint16_t vfi_base;
|
||||
uint16_t vfi_used;
|
||||
uint16_t max_fcfi;
|
||||
uint16_t fcfi_base;
|
||||
uint16_t fcfi_used;
|
||||
uint16_t max_eq;
|
||||
uint16_t max_rq;
|
||||
|
@ -449,10 +448,13 @@ struct lpfc_sli4_hba {
|
|||
uint32_t intr_enable;
|
||||
struct lpfc_bmbx bmbx;
|
||||
struct lpfc_max_cfg_param max_cfg_param;
|
||||
uint16_t extents_in_use; /* must allocate resource extents. */
|
||||
uint16_t rpi_hdrs_in_use; /* must post rpi hdrs if set. */
|
||||
uint16_t next_xri; /* last_xri - max_cfg_param.xri_base = used */
|
||||
uint16_t next_rpi;
|
||||
uint16_t scsi_xri_max;
|
||||
uint16_t scsi_xri_cnt;
|
||||
uint16_t scsi_xri_start;
|
||||
struct list_head lpfc_free_sgl_list;
|
||||
struct list_head lpfc_sgl_list;
|
||||
struct lpfc_sglq **lpfc_els_sgl_array;
|
||||
|
@ -463,7 +465,17 @@ struct lpfc_sli4_hba {
|
|||
struct lpfc_sglq **lpfc_sglq_active_list;
|
||||
struct list_head lpfc_rpi_hdr_list;
|
||||
unsigned long *rpi_bmask;
|
||||
uint16_t *rpi_ids;
|
||||
uint16_t rpi_count;
|
||||
struct list_head lpfc_rpi_blk_list;
|
||||
unsigned long *xri_bmask;
|
||||
uint16_t *xri_ids;
|
||||
uint16_t xri_count;
|
||||
struct list_head lpfc_xri_blk_list;
|
||||
unsigned long *vfi_bmask;
|
||||
uint16_t *vfi_ids;
|
||||
uint16_t vfi_count;
|
||||
struct list_head lpfc_vfi_blk_list;
|
||||
struct lpfc_sli4_flags sli4_flags;
|
||||
struct list_head sp_queue_event;
|
||||
struct list_head sp_cqe_event_pool;
|
||||
|
@ -496,6 +508,7 @@ struct lpfc_sglq {
|
|||
enum lpfc_sgl_state state;
|
||||
struct lpfc_nodelist *ndlp; /* ndlp associated with IO */
|
||||
uint16_t iotag; /* pre-assigned IO tag */
|
||||
uint16_t sli4_lxritag; /* logical pre-assigned xri. */
|
||||
uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */
|
||||
struct sli4_sge *sgl; /* pre-assigned SGL */
|
||||
void *virt; /* virtual address. */
|
||||
|
@ -510,6 +523,13 @@ struct lpfc_rpi_hdr {
|
|||
uint32_t start_rpi;
|
||||
};
|
||||
|
||||
struct lpfc_rsrc_blks {
|
||||
struct list_head list;
|
||||
uint16_t rsrc_start;
|
||||
uint16_t rsrc_size;
|
||||
uint16_t rsrc_used;
|
||||
};
|
||||
|
||||
/*
|
||||
* SLI4 specific function prototypes
|
||||
*/
|
||||
|
@ -549,8 +569,11 @@ int lpfc_sli4_post_sgl(struct lpfc_hba *, dma_addr_t, dma_addr_t, uint16_t);
|
|||
int lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *);
|
||||
uint16_t lpfc_sli4_next_xritag(struct lpfc_hba *);
|
||||
int lpfc_sli4_post_async_mbox(struct lpfc_hba *);
|
||||
int lpfc_sli4_post_sgl_list(struct lpfc_hba *phba);
|
||||
int lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba);
|
||||
int lpfc_sli4_post_els_sgl_list_ext(struct lpfc_hba *phba);
|
||||
int lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *, struct list_head *, int);
|
||||
int lpfc_sli4_post_scsi_sgl_blk_ext(struct lpfc_hba *, struct list_head *,
|
||||
int);
|
||||
struct lpfc_cq_event *__lpfc_sli4_cq_event_alloc(struct lpfc_hba *);
|
||||
struct lpfc_cq_event *lpfc_sli4_cq_event_alloc(struct lpfc_hba *);
|
||||
void __lpfc_sli4_cq_event_release(struct lpfc_hba *, struct lpfc_cq_event *);
|
||||
|
|
|
@ -83,7 +83,7 @@ inline void lpfc_vport_set_state(struct lpfc_vport *vport,
|
|||
static int
|
||||
lpfc_alloc_vpi(struct lpfc_hba *phba)
|
||||
{
|
||||
int vpi;
|
||||
unsigned long vpi;
|
||||
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
/* Start at bit 1 because vpi zero is reserved for the physical port */
|
||||
|
|
Loading…
Reference in New Issue