[SCSI] lpfc 8.3.9: SLI enhancments to support new hardware.

- Add support for the INTF (Interface) PCI register.
- Add support for greater than 2 page SGLs.
- Add support for up to 32 bit BDE lengths.
- Implement the Port Capabilities Mailbox command.
- Stop checking the Minor Code in the EQE structure.

Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
James Smart 2010-02-12 14:42:03 -05:00 committed by James Bottomley
parent ecfd03c6a9
commit 28baac7492
7 changed files with 451 additions and 100 deletions

View File

@ -49,6 +49,9 @@ void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *,
void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
void lpfc_supported_pages(struct lpfcMboxq *);
void lpfc_sli4_params(struct lpfcMboxq *);
int lpfc_pc_sli4_params_get(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 *);

View File

@ -52,29 +52,35 @@ struct dma_address {
uint32_t addr_hi;
};
#define LPFC_SLIREV_CONF_WORD 0x58
struct lpfc_sli_intf {
uint32_t word0;
#define lpfc_sli_intf_iftype_MASK 0x00000007
#define lpfc_sli_intf_iftype_SHIFT 0
#define lpfc_sli_intf_iftype_WORD word0
#define lpfc_sli_intf_rev_MASK 0x0000000f
#define lpfc_sli_intf_rev_SHIFT 4
#define lpfc_sli_intf_rev_WORD word0
#define LPFC_SLIREV_CONF_SLI4 4
#define lpfc_sli_intf_family_MASK 0x000000ff
#define lpfc_sli_intf_family_SHIFT 8
#define lpfc_sli_intf_family_WORD word0
#define lpfc_sli_intf_feat1_MASK 0x000000ff
#define lpfc_sli_intf_feat1_SHIFT 16
#define lpfc_sli_intf_feat1_WORD word0
#define lpfc_sli_intf_feat2_MASK 0x0000001f
#define lpfc_sli_intf_feat2_SHIFT 24
#define lpfc_sli_intf_feat2_WORD word0
#define lpfc_sli_intf_valid_MASK 0x00000007
#define lpfc_sli_intf_valid_SHIFT 29
#define lpfc_sli_intf_valid_WORD word0
#define lpfc_sli_intf_valid_SHIFT 29
#define lpfc_sli_intf_valid_MASK 0x00000007
#define lpfc_sli_intf_valid_WORD word0
#define LPFC_SLI_INTF_VALID 6
#define lpfc_sli_intf_featurelevel2_SHIFT 24
#define lpfc_sli_intf_featurelevel2_MASK 0x0000001F
#define lpfc_sli_intf_featurelevel2_WORD word0
#define lpfc_sli_intf_featurelevel1_SHIFT 16
#define lpfc_sli_intf_featurelevel1_MASK 0x000000FF
#define lpfc_sli_intf_featurelevel1_WORD word0
#define LPFC_SLI_INTF_FEATURELEVEL1_1 1
#define LPFC_SLI_INTF_FEATURELEVEL1_2 2
#define lpfc_sli_intf_sli_family_SHIFT 8
#define lpfc_sli_intf_sli_family_MASK 0x000000FF
#define lpfc_sli_intf_sli_family_WORD word0
#define LPFC_SLI_INTF_FAMILY_BE2 0
#define LPFC_SLI_INTF_FAMILY_BE3 1
#define lpfc_sli_intf_slirev_SHIFT 4
#define lpfc_sli_intf_slirev_MASK 0x0000000F
#define lpfc_sli_intf_slirev_WORD word0
#define LPFC_SLI_INTF_REV_SLI3 3
#define LPFC_SLI_INTF_REV_SLI4 4
#define lpfc_sli_intf_if_type_SHIFT 0
#define lpfc_sli_intf_if_type_MASK 0x00000007
#define lpfc_sli_intf_if_type_WORD word0
#define LPFC_SLI_INTF_IF_TYPE_0 0
#define LPFC_SLI_INTF_IF_TYPE_1 1
};
#define LPFC_SLI4_MBX_EMBED true
@ -157,6 +163,9 @@ struct lpfc_sli_intf {
#define LPFC_FP_DEF_IMAX 10000
#define LPFC_SP_DEF_IMAX 10000
/* PORT_CAPABILITIES constants. */
#define LPFC_MAX_SUPPORTED_PAGES 8
struct ulp_bde64 {
union ULP_BDE_TUS {
uint32_t w;
@ -512,7 +521,7 @@ struct lpfc_register {
#define LPFC_UERR_STATUS_LO 0x00A0
#define LPFC_UE_MASK_HI 0x00AC
#define LPFC_UE_MASK_LO 0x00A8
#define LPFC_SCRATCHPAD 0x0058
#define LPFC_SLI_INTF 0x0058
/* BAR0 Registers */
#define LPFC_HST_STATE 0x00AC
@ -572,19 +581,6 @@ struct lpfc_register {
#define LPFC_POST_STAGE_ARMFW_READY 0xC000
#define LPFC_POST_STAGE_ARMFW_UE 0xF000
#define lpfc_scratchpad_slirev_SHIFT 4
#define lpfc_scratchpad_slirev_MASK 0xF
#define lpfc_scratchpad_slirev_WORD word0
#define lpfc_scratchpad_chiptype_SHIFT 8
#define lpfc_scratchpad_chiptype_MASK 0xFF
#define lpfc_scratchpad_chiptype_WORD word0
#define lpfc_scratchpad_featurelevel1_SHIFT 16
#define lpfc_scratchpad_featurelevel1_MASK 0xFF
#define lpfc_scratchpad_featurelevel1_WORD word0
#define lpfc_scratchpad_featurelevel2_SHIFT 24
#define lpfc_scratchpad_featurelevel2_MASK 0xFF
#define lpfc_scratchpad_featurelevel2_WORD word0
/* BAR1 Registers */
#define LPFC_IMR_MASK_ALL 0xFFFFFFFF
#define LPFC_ISCR_CLEAR_ALL 0xFFFFFFFF
@ -1146,10 +1142,7 @@ struct sli4_sge { /* SLI-4 */
this flag !! */
#define lpfc_sli4_sge_last_MASK 0x00000001
#define lpfc_sli4_sge_last_WORD word2
uint32_t word3;
#define lpfc_sli4_sge_len_SHIFT 0
#define lpfc_sli4_sge_len_MASK 0x0001FFFF
#define lpfc_sli4_sge_len_WORD word3
uint32_t sge_len;
};
struct fcf_record {
@ -1844,6 +1837,177 @@ struct lpfc_mbx_request_features {
#define lpfc_mbx_rq_ftr_rsp_ifip_WORD word3
};
struct lpfc_mbx_supp_pages {
uint32_t word1;
#define qs_SHIFT 0
#define qs_MASK 0x00000001
#define qs_WORD word1
#define wr_SHIFT 1
#define wr_MASK 0x00000001
#define wr_WORD word1
#define pf_SHIFT 8
#define pf_MASK 0x000000ff
#define pf_WORD word1
#define cpn_SHIFT 16
#define cpn_MASK 0x000000ff
#define cpn_WORD word1
uint32_t word2;
#define list_offset_SHIFT 0
#define list_offset_MASK 0x000000ff
#define list_offset_WORD word2
#define next_offset_SHIFT 8
#define next_offset_MASK 0x000000ff
#define next_offset_WORD word2
#define elem_cnt_SHIFT 16
#define elem_cnt_MASK 0x000000ff
#define elem_cnt_WORD word2
uint32_t word3;
#define pn_0_SHIFT 24
#define pn_0_MASK 0x000000ff
#define pn_0_WORD word3
#define pn_1_SHIFT 16
#define pn_1_MASK 0x000000ff
#define pn_1_WORD word3
#define pn_2_SHIFT 8
#define pn_2_MASK 0x000000ff
#define pn_2_WORD word3
#define pn_3_SHIFT 0
#define pn_3_MASK 0x000000ff
#define pn_3_WORD word3
uint32_t word4;
#define pn_4_SHIFT 24
#define pn_4_MASK 0x000000ff
#define pn_4_WORD word4
#define pn_5_SHIFT 16
#define pn_5_MASK 0x000000ff
#define pn_5_WORD word4
#define pn_6_SHIFT 8
#define pn_6_MASK 0x000000ff
#define pn_6_WORD word4
#define pn_7_SHIFT 0
#define pn_7_MASK 0x000000ff
#define pn_7_WORD word4
uint32_t rsvd[27];
#define LPFC_SUPP_PAGES 0
#define LPFC_BLOCK_GUARD_PROFILES 1
#define LPFC_SLI4_PARAMETERS 2
};
struct lpfc_mbx_sli4_params {
uint32_t word1;
#define qs_SHIFT 0
#define qs_MASK 0x00000001
#define qs_WORD word1
#define wr_SHIFT 1
#define wr_MASK 0x00000001
#define wr_WORD word1
#define pf_SHIFT 8
#define pf_MASK 0x000000ff
#define pf_WORD word1
#define cpn_SHIFT 16
#define cpn_MASK 0x000000ff
#define cpn_WORD word1
uint32_t word2;
#define if_type_SHIFT 0
#define if_type_MASK 0x00000007
#define if_type_WORD word2
#define sli_rev_SHIFT 4
#define sli_rev_MASK 0x0000000f
#define sli_rev_WORD word2
#define sli_family_SHIFT 8
#define sli_family_MASK 0x000000ff
#define sli_family_WORD word2
#define featurelevel_1_SHIFT 16
#define featurelevel_1_MASK 0x000000ff
#define featurelevel_1_WORD word2
#define featurelevel_2_SHIFT 24
#define featurelevel_2_MASK 0x0000001f
#define featurelevel_2_WORD word2
uint32_t word3;
#define fcoe_SHIFT 0
#define fcoe_MASK 0x00000001
#define fcoe_WORD word3
#define fc_SHIFT 1
#define fc_MASK 0x00000001
#define fc_WORD word3
#define nic_SHIFT 2
#define nic_MASK 0x00000001
#define nic_WORD word3
#define iscsi_SHIFT 3
#define iscsi_MASK 0x00000001
#define iscsi_WORD word3
#define rdma_SHIFT 4
#define rdma_MASK 0x00000001
#define rdma_WORD word3
uint32_t sge_supp_len;
uint32_t word5;
#define if_page_sz_SHIFT 0
#define if_page_sz_MASK 0x0000ffff
#define if_page_sz_WORD word5
#define loopbk_scope_SHIFT 24
#define loopbk_scope_MASK 0x0000000f
#define loopbk_scope_WORD word5
#define rq_db_window_SHIFT 28
#define rq_db_window_MASK 0x0000000f
#define rq_db_window_WORD word5
uint32_t word6;
#define eq_pages_SHIFT 0
#define eq_pages_MASK 0x0000000f
#define eq_pages_WORD word6
#define eqe_size_SHIFT 8
#define eqe_size_MASK 0x000000ff
#define eqe_size_WORD word6
uint32_t word7;
#define cq_pages_SHIFT 0
#define cq_pages_MASK 0x0000000f
#define cq_pages_WORD word7
#define cqe_size_SHIFT 8
#define cqe_size_MASK 0x000000ff
#define cqe_size_WORD word7
uint32_t word8;
#define mq_pages_SHIFT 0
#define mq_pages_MASK 0x0000000f
#define mq_pages_WORD word8
#define mqe_size_SHIFT 8
#define mqe_size_MASK 0x000000ff
#define mqe_size_WORD word8
#define mq_elem_cnt_SHIFT 16
#define mq_elem_cnt_MASK 0x000000ff
#define mq_elem_cnt_WORD word8
uint32_t word9;
#define wq_pages_SHIFT 0
#define wq_pages_MASK 0x0000ffff
#define wq_pages_WORD word9
#define wqe_size_SHIFT 8
#define wqe_size_MASK 0x000000ff
#define wqe_size_WORD word9
uint32_t word10;
#define rq_pages_SHIFT 0
#define rq_pages_MASK 0x0000ffff
#define rq_pages_WORD word10
#define rqe_size_SHIFT 8
#define rqe_size_MASK 0x000000ff
#define rqe_size_WORD word10
uint32_t word11;
#define hdr_pages_SHIFT 0
#define hdr_pages_MASK 0x0000000f
#define hdr_pages_WORD word11
#define hdr_size_SHIFT 8
#define hdr_size_MASK 0x0000000f
#define hdr_size_WORD word11
#define hdr_pp_align_SHIFT 16
#define hdr_pp_align_MASK 0x0000ffff
#define hdr_pp_align_WORD word11
uint32_t word12;
#define sgl_pages_SHIFT 0
#define sgl_pages_MASK 0x0000000f
#define sgl_pages_WORD word12
#define sgl_pp_align_SHIFT 16
#define sgl_pp_align_MASK 0x0000ffff
#define sgl_pp_align_WORD word12
uint32_t rsvd_13_63[51];
};
/* Mailbox Completion Queue Error Messages */
#define MB_CQE_STATUS_SUCCESS 0x0
#define MB_CQE_STATUS_INSUFFICIENT_PRIVILEGES 0x1
@ -1894,6 +2058,8 @@ struct lpfc_mqe {
struct lpfc_mbx_request_features req_ftrs;
struct lpfc_mbx_post_hdr_tmpl hdr_tmpl;
struct lpfc_mbx_query_fw_cfg query_fw_cfg;
struct lpfc_mbx_supp_pages supp_pages;
struct lpfc_mbx_sli4_params sli4_params;
struct lpfc_mbx_nop nop;
} un;
};

View File

@ -2443,7 +2443,8 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
shost->this_id = -1;
shost->max_cmd_len = 16;
if (phba->sli_rev == LPFC_SLI_REV4) {
shost->dma_boundary = LPFC_SLI4_MAX_SEGMENT_SIZE;
shost->dma_boundary =
phba->sli4_hba.pc_sli4_params.sge_supp_len;
shost->sg_tablesize = phba->cfg_sg_seg_cnt;
}
@ -3621,8 +3622,10 @@ static int
lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
{
struct lpfc_sli *psli;
int rc;
int i, hbq_count;
LPFC_MBOXQ_t *mboxq;
int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size;
uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0};
struct lpfc_mqe *mqe;
/* Before proceed, wait for POST done and device ready */
rc = lpfc_sli4_post_status_check(phba);
@ -3680,31 +3683,26 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
* used to create the sg_dma_buf_pool must be dynamically calculated.
* 2 segments are added since the IOCB needs a command and response bde.
* To insure that the scsi sgl does not cross a 4k page boundary only
* sgl sizes of 1k, 2k, 4k, and 8k are supported.
* Table of sgl sizes and seg_cnt:
* sgl size, sg_seg_cnt total seg
* 1k 50 52
* 2k 114 116
* 4k 242 244
* 8k 498 500
* cmd(32) + rsp(160) + (52 * sizeof(sli4_sge)) = 1024
* cmd(32) + rsp(160) + (116 * sizeof(sli4_sge)) = 2048
* cmd(32) + rsp(160) + (244 * sizeof(sli4_sge)) = 4096
* cmd(32) + rsp(160) + (500 * sizeof(sli4_sge)) = 8192
* sgl sizes of must be a power of 2.
*/
if (phba->cfg_sg_seg_cnt <= LPFC_DEFAULT_SG_SEG_CNT)
phba->cfg_sg_seg_cnt = 50;
else if (phba->cfg_sg_seg_cnt <= 114)
phba->cfg_sg_seg_cnt = 114;
else if (phba->cfg_sg_seg_cnt <= 242)
phba->cfg_sg_seg_cnt = 242;
buf_size = (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp) +
((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge)));
/* Feature Level 1 hardware is limited to 2 pages */
if ((bf_get(lpfc_sli_intf_featurelevel1, &phba->sli4_hba.sli_intf) ==
LPFC_SLI_INTF_FEATURELEVEL1_1))
max_buf_size = LPFC_SLI4_FL1_MAX_BUF_SIZE;
else
phba->cfg_sg_seg_cnt = 498;
phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd)
+ sizeof(struct fcp_rsp);
phba->cfg_sg_dma_buf_size +=
((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge));
max_buf_size = LPFC_SLI4_MAX_BUF_SIZE;
for (dma_buf_size = LPFC_SLI4_MIN_BUF_SIZE;
dma_buf_size < max_buf_size && buf_size > dma_buf_size;
dma_buf_size = dma_buf_size << 1)
;
if (dma_buf_size == max_buf_size)
phba->cfg_sg_seg_cnt = (dma_buf_size -
sizeof(struct fcp_cmnd) - sizeof(struct fcp_rsp) -
(2 * sizeof(struct sli4_sge))) /
sizeof(struct sli4_sge);
phba->cfg_sg_dma_buf_size = dma_buf_size;
/* Initialize buffer queue management fields */
hbq_count = lpfc_sli_hbq_count();
@ -3822,6 +3820,43 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
goto out_free_fcp_eq_hdl;
}
mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
GFP_KERNEL);
if (!mboxq) {
rc = -ENOMEM;
goto out_free_fcp_eq_hdl;
}
/* Get the Supported Pages. It is always available. */
lpfc_supported_pages(mboxq);
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
if (unlikely(rc)) {
rc = -EIO;
mempool_free(mboxq, phba->mbox_mem_pool);
goto out_free_fcp_eq_hdl;
}
mqe = &mboxq->u.mqe;
memcpy(&pn_page[0], ((uint8_t *)&mqe->un.supp_pages.word3),
LPFC_MAX_SUPPORTED_PAGES);
for (i = 0; i < LPFC_MAX_SUPPORTED_PAGES; i++) {
switch (pn_page[i]) {
case LPFC_SLI4_PARAMETERS:
phba->sli4_hba.pc_sli4_params.supported = 1;
break;
default:
break;
}
}
/* Read the port's SLI4 Parameters capabilities if supported. */
if (phba->sli4_hba.pc_sli4_params.supported)
rc = lpfc_pc_sli4_params_get(phba, mboxq);
mempool_free(mboxq, phba->mbox_mem_pool);
if (rc) {
rc = -EIO;
goto out_free_fcp_eq_hdl;
}
return rc;
out_free_fcp_eq_hdl:
@ -4825,7 +4860,7 @@ lpfc_sli_pci_mem_unset(struct lpfc_hba *phba)
int
lpfc_sli4_post_status_check(struct lpfc_hba *phba)
{
struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg, scratchpad;
struct lpfc_register sta_reg, uerrlo_reg, uerrhi_reg;
int i, port_error = -ENODEV;
if (!phba->sli4_hba.STAregaddr)
@ -4861,14 +4896,21 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
bf_get(lpfc_hst_state_port_status, &sta_reg));
/* Log device information */
scratchpad.word0 = readl(phba->sli4_hba.SCRATCHPADregaddr);
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"2534 Device Info: ChipType=0x%x, SliRev=0x%x, "
"FeatureL1=0x%x, FeatureL2=0x%x\n",
bf_get(lpfc_scratchpad_chiptype, &scratchpad),
bf_get(lpfc_scratchpad_slirev, &scratchpad),
bf_get(lpfc_scratchpad_featurelevel1, &scratchpad),
bf_get(lpfc_scratchpad_featurelevel2, &scratchpad));
phba->sli4_hba.sli_intf.word0 = readl(phba->sli4_hba.SLIINTFregaddr);
if (bf_get(lpfc_sli_intf_valid,
&phba->sli4_hba.sli_intf) == LPFC_SLI_INTF_VALID) {
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"2534 Device Info: ChipType=0x%x, SliRev=0x%x, "
"FeatureL1=0x%x, FeatureL2=0x%x\n",
bf_get(lpfc_sli_intf_sli_family,
&phba->sli4_hba.sli_intf),
bf_get(lpfc_sli_intf_slirev,
&phba->sli4_hba.sli_intf),
bf_get(lpfc_sli_intf_featurelevel1,
&phba->sli4_hba.sli_intf),
bf_get(lpfc_sli_intf_featurelevel2,
&phba->sli4_hba.sli_intf));
}
phba->sli4_hba.ue_mask_lo = readl(phba->sli4_hba.UEMASKLOregaddr);
phba->sli4_hba.ue_mask_hi = readl(phba->sli4_hba.UEMASKHIregaddr);
/* With uncoverable error, log the error message and return error */
@ -4907,8 +4949,8 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba)
LPFC_UE_MASK_LO;
phba->sli4_hba.UEMASKHIregaddr = phba->sli4_hba.conf_regs_memmap_p +
LPFC_UE_MASK_HI;
phba->sli4_hba.SCRATCHPADregaddr = phba->sli4_hba.conf_regs_memmap_p +
LPFC_SCRATCHPAD;
phba->sli4_hba.SLIINTFregaddr = phba->sli4_hba.conf_regs_memmap_p +
LPFC_SLI_INTF;
}
/**
@ -6981,6 +7023,73 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
phba->pport->work_port_events = 0;
}
/**
* lpfc_pc_sli4_params_get - Get the SLI4_PARAMS port capabilities.
* @phba: Pointer to HBA context object.
* @mboxq: Pointer to the mailboxq memory for the mailbox command response.
*
* This function is called in the SLI4 code path to read the port's
* sli4 capabilities.
*
* This function may be be called from any context that can block-wait
* for the completion. The expectation is that this routine is called
* typically from probe_one or from the online routine.
**/
int
lpfc_pc_sli4_params_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
{
int rc;
struct lpfc_mqe *mqe;
struct lpfc_pc_sli4_params *sli4_params;
uint32_t mbox_tmo;
rc = 0;
mqe = &mboxq->u.mqe;
/* Read the port's SLI4 Parameters port capabilities */
lpfc_sli4_params(mboxq);
if (!phba->sli4_hba.intr_enable)
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
else {
mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_PORT_CAPABILITIES);
rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
}
if (unlikely(rc))
return 1;
sli4_params = &phba->sli4_hba.pc_sli4_params;
sli4_params->if_type = bf_get(if_type, &mqe->un.sli4_params);
sli4_params->sli_rev = bf_get(sli_rev, &mqe->un.sli4_params);
sli4_params->sli_family = bf_get(sli_family, &mqe->un.sli4_params);
sli4_params->featurelevel_1 = bf_get(featurelevel_1,
&mqe->un.sli4_params);
sli4_params->featurelevel_2 = bf_get(featurelevel_2,
&mqe->un.sli4_params);
sli4_params->proto_types = mqe->un.sli4_params.word3;
sli4_params->sge_supp_len = mqe->un.sli4_params.sge_supp_len;
sli4_params->if_page_sz = bf_get(if_page_sz, &mqe->un.sli4_params);
sli4_params->rq_db_window = bf_get(rq_db_window, &mqe->un.sli4_params);
sli4_params->loopbk_scope = bf_get(loopbk_scope, &mqe->un.sli4_params);
sli4_params->eq_pages_max = bf_get(eq_pages, &mqe->un.sli4_params);
sli4_params->eqe_size = bf_get(eqe_size, &mqe->un.sli4_params);
sli4_params->cq_pages_max = bf_get(cq_pages, &mqe->un.sli4_params);
sli4_params->cqe_size = bf_get(cqe_size, &mqe->un.sli4_params);
sli4_params->mq_pages_max = bf_get(mq_pages, &mqe->un.sli4_params);
sli4_params->mqe_size = bf_get(mqe_size, &mqe->un.sli4_params);
sli4_params->mq_elem_cnt = bf_get(mq_elem_cnt, &mqe->un.sli4_params);
sli4_params->wq_pages_max = bf_get(wq_pages, &mqe->un.sli4_params);
sli4_params->wqe_size = bf_get(wqe_size, &mqe->un.sli4_params);
sli4_params->rq_pages_max = bf_get(rq_pages, &mqe->un.sli4_params);
sli4_params->rqe_size = bf_get(rqe_size, &mqe->un.sli4_params);
sli4_params->hdr_pages_max = bf_get(hdr_pages, &mqe->un.sli4_params);
sli4_params->hdr_size = bf_get(hdr_size, &mqe->un.sli4_params);
sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params);
sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params);
sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params);
return rc;
}
/**
* lpfc_pci_probe_one_s3 - PCI probe func to reg SLI-3 device to PCI subsystem.
* @pdev: pointer to PCI device
@ -8053,11 +8162,11 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
int rc;
struct lpfc_sli_intf intf;
if (pci_read_config_dword(pdev, LPFC_SLIREV_CONF_WORD, &intf.word0))
if (pci_read_config_dword(pdev, LPFC_SLI_INTF, &intf.word0))
return -ENODEV;
if ((bf_get(lpfc_sli_intf_valid, &intf) == LPFC_SLI_INTF_VALID) &&
(bf_get(lpfc_sli_intf_rev, &intf) == LPFC_SLIREV_CONF_SLI4))
(bf_get(lpfc_sli_intf_slirev, &intf) == LPFC_SLI_INTF_REV_SLI4))
rc = lpfc_pci_probe_one_s4(pdev, pid);
else
rc = lpfc_pci_probe_one_s3(pdev, pid);

View File

@ -2052,3 +2052,41 @@ lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp)
bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI);
resume_rpi->event_tag = ndlp->phba->fc_eventTag;
}
/**
* lpfc_supported_pages - Initialize the PORT_CAPABILITIES supported pages
* mailbox command.
* @mbox: pointer to lpfc mbox command to initialize.
*
* The PORT_CAPABILITIES supported pages mailbox command is issued to
* retrieve the particular feature pages supported by the port.
**/
void
lpfc_supported_pages(struct lpfcMboxq *mbox)
{
struct lpfc_mbx_supp_pages *supp_pages;
memset(mbox, 0, sizeof(*mbox));
supp_pages = &mbox->u.mqe.un.supp_pages;
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES);
bf_set(cpn, supp_pages, LPFC_SUPP_PAGES);
}
/**
* lpfc_sli4_params - Initialize the PORT_CAPABILITIES SLI4 Params
* mailbox command.
* @mbox: pointer to lpfc mbox command to initialize.
*
* The PORT_CAPABILITIES SLI4 parameters mailbox command is issued to
* retrieve the particular SLI4 features supported by the port.
**/
void
lpfc_sli4_params(struct lpfcMboxq *mbox)
{
struct lpfc_mbx_sli4_params *sli4_params;
memset(mbox, 0, sizeof(*mbox));
sli4_params = &mbox->u.mqe.un.sli4_params;
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES);
bf_set(cpn, sli4_params, LPFC_SLI4_PARAMETERS);
}

View File

@ -798,19 +798,17 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
*/
sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd));
sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_cmd));
bf_set(lpfc_sli4_sge_len, sgl, sizeof(struct fcp_cmnd));
bf_set(lpfc_sli4_sge_last, sgl, 0);
sgl->word2 = cpu_to_le32(sgl->word2);
sgl->word3 = cpu_to_le32(sgl->word3);
sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd));
sgl++;
/* Setup the physical region for the FCP RSP */
sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_rsp));
sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_rsp));
bf_set(lpfc_sli4_sge_len, sgl, sizeof(struct fcp_rsp));
bf_set(lpfc_sli4_sge_last, sgl, 1);
sgl->word2 = cpu_to_le32(sgl->word2);
sgl->word3 = cpu_to_le32(sgl->word3);
sgl->sge_len = cpu_to_le32(sizeof(struct fcp_rsp));
/*
* Since the IOCB for the FCP I/O is built into this
@ -1872,7 +1870,6 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
scsi_for_each_sg(scsi_cmnd, sgel, nseg, num_bde) {
physaddr = sg_dma_address(sgel);
dma_len = sg_dma_len(sgel);
bf_set(lpfc_sli4_sge_len, sgl, sg_dma_len(sgel));
sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr));
sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr));
if ((num_bde + 1) == nseg)
@ -1881,7 +1878,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
bf_set(lpfc_sli4_sge_last, sgl, 0);
bf_set(lpfc_sli4_sge_offset, sgl, dma_offset);
sgl->word2 = cpu_to_le32(sgl->word2);
sgl->word3 = cpu_to_le32(sgl->word3);
sgl->sge_len = cpu_to_le32(dma_len);
dma_offset += dma_len;
sgl++;
}

View File

@ -5739,19 +5739,19 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
for (i = 0; i < numBdes; i++) {
/* Should already be byte swapped. */
sgl->addr_hi = bpl->addrHigh;
sgl->addr_lo = bpl->addrLow;
/* swap the size field back to the cpu so we
* can assign it to the sgl.
*/
bde.tus.w = le32_to_cpu(bpl->tus.w);
bf_set(lpfc_sli4_sge_len, sgl, bde.tus.f.bdeSize);
sgl->addr_hi = bpl->addrHigh;
sgl->addr_lo = bpl->addrLow;
if ((i+1) == numBdes)
bf_set(lpfc_sli4_sge_last, sgl, 1);
else
bf_set(lpfc_sli4_sge_last, sgl, 0);
sgl->word2 = cpu_to_le32(sgl->word2);
sgl->word3 = cpu_to_le32(sgl->word3);
/* swap the size field back to the cpu so we
* can assign it to the sgl.
*/
bde.tus.w = le32_to_cpu(bpl->tus.w);
sgl->sge_len = cpu_to_le32(bde.tus.f.bdeSize);
bpl++;
sgl++;
}
@ -5764,11 +5764,10 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
cpu_to_le32(icmd->un.genreq64.bdl.addrHigh);
sgl->addr_lo =
cpu_to_le32(icmd->un.genreq64.bdl.addrLow);
bf_set(lpfc_sli4_sge_len, sgl,
icmd->un.genreq64.bdl.bdeSize);
bf_set(lpfc_sli4_sge_last, sgl, 1);
sgl->word2 = cpu_to_le32(sgl->word2);
sgl->word3 = cpu_to_le32(sgl->word3);
sgl->sge_len =
cpu_to_le32(icmd->un.genreq64.bdl.bdeSize);
}
return sglq->sli4_xritag;
}
@ -8934,8 +8933,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe)
int ecount = 0;
uint16_t cqid;
if (bf_get(lpfc_eqe_major_code, eqe) != 0 ||
bf_get(lpfc_eqe_minor_code, eqe) != 0) {
if (bf_get(lpfc_eqe_major_code, eqe) != 0) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"0359 Not a valid slow-path completion "
"event: majorcode=x%x, minorcode=x%x\n",
@ -9167,8 +9165,7 @@ lpfc_sli4_fp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
uint16_t cqid;
int ecount = 0;
if (unlikely(bf_get(lpfc_eqe_major_code, eqe) != 0) ||
unlikely(bf_get(lpfc_eqe_minor_code, eqe) != 0)) {
if (unlikely(bf_get(lpfc_eqe_major_code, eqe) != 0)) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
"0366 Not a valid fast-path completion "
"event: majorcode=x%x, minorcode=x%x\n",

View File

@ -264,7 +264,10 @@ struct lpfc_bmbx {
#define SLI4_CT_VFI 2
#define SLI4_CT_FCFI 3
#define LPFC_SLI4_MAX_SEGMENT_SIZE 0x10000
#define LPFC_SLI4_FL1_MAX_SEGMENT_SIZE 0x10000
#define LPFC_SLI4_FL1_MAX_BUF_SIZE 0X2000
#define LPFC_SLI4_MIN_BUF_SIZE 0x400
#define LPFC_SLI4_MAX_BUF_SIZE 0x20000
/*
* SLI4 specific data structures
@ -298,6 +301,42 @@ struct lpfc_fcp_eq_hdl {
struct lpfc_hba *phba;
};
/* Port Capabilities for SLI4 Parameters */
struct lpfc_pc_sli4_params {
uint32_t supported;
uint32_t if_type;
uint32_t sli_rev;
uint32_t sli_family;
uint32_t featurelevel_1;
uint32_t featurelevel_2;
uint32_t proto_types;
#define LPFC_SLI4_PROTO_FCOE 0x0000001
#define LPFC_SLI4_PROTO_FC 0x0000002
#define LPFC_SLI4_PROTO_NIC 0x0000004
#define LPFC_SLI4_PROTO_ISCSI 0x0000008
#define LPFC_SLI4_PROTO_RDMA 0x0000010
uint32_t sge_supp_len;
uint32_t if_page_sz;
uint32_t rq_db_window;
uint32_t loopbk_scope;
uint32_t eq_pages_max;
uint32_t eqe_size;
uint32_t cq_pages_max;
uint32_t cqe_size;
uint32_t mq_pages_max;
uint32_t mqe_size;
uint32_t mq_elem_cnt;
uint32_t wq_pages_max;
uint32_t wqe_size;
uint32_t rq_pages_max;
uint32_t rqe_size;
uint32_t hdr_pages_max;
uint32_t hdr_size;
uint32_t hdr_pp_align;
uint32_t sgl_pages_max;
uint32_t sgl_pp_align;
};
/* SLI4 HBA data structure entries */
struct lpfc_sli4_hba {
void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for
@ -311,7 +350,7 @@ struct lpfc_sli4_hba {
void __iomem *UERRHIregaddr; /* Address to UERR_STATUS_HI register */
void __iomem *UEMASKLOregaddr; /* Address to UE_MASK_LO register */
void __iomem *UEMASKHIregaddr; /* Address to UE_MASK_HI register */
void __iomem *SCRATCHPADregaddr; /* Address to scratchpad register */
void __iomem *SLIINTFregaddr; /* Address to SLI_INTF register */
/* BAR1 FCoE function CSR register memory map */
void __iomem *STAregaddr; /* Address to HST_STATE register */
void __iomem *ISRregaddr; /* Address to HST_ISR register */
@ -326,6 +365,8 @@ struct lpfc_sli4_hba {
uint32_t ue_mask_lo;
uint32_t ue_mask_hi;
struct lpfc_register sli_intf;
struct lpfc_pc_sli4_params pc_sli4_params;
struct msix_entry *msix_entries;
uint32_t cfg_eqn;
struct lpfc_fcp_eq_hdl *fcp_eq_hdl; /* FCP per-WQ handle */