[SCSI] lpfc 8.3.19: Add SLI4 FC Discovery support

Add SLI4 FC Discovery support

- Replace READ_LA and READ_LA64 with READ_TOPOLOGY mailbox command.
- Converted the old READ_LA structure to use bf_set/get instead of bit fields.
- Rename HBA_FCOE_SUPPORT flag to HBA_FCOE_MODE. Flag now indicates function
  is running as SLI-4 FC or FCoE port. Make sure flag reset each time
  READ_REV completed as it can dynamically change.
- Removed BDE union in the READ_TOPOLOGY mailbox command and added a define to
  define the ALPA MAP SIZE. Added FC Code for async events.
- Added code to support new 16G link speed.
- Define new set of values to keep track of valid user settable link speeds.
- Used new link speed definitions to define link speed max and bitmap.
- Redefined FDMI Port sppeds to be hax values and added the 16G value.
- Added new CQE trailer code for FC Events.
- Add lpfc_issue_init_vfi and lpfc_init_vfi_cmpl routines.
- Replace many calls to the initial_flogi routine with lpfc_issue_init_vfi.
- Add vp and vpi fields to the INIT_VFI mailbox command.
- Addapt lpfc_hba_init_link routine for SLI4 use.
- Use lpfc_hba_init_link call from lpfc_sli4_hba_setup.
- Add a check for FC mode to register the FCFI before init link.
- Convert lpfc_sli4_init_vpi to be called without a vpi (get it from vport).

Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
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-11-20 23:11:48 -05:00
committed by James Bottomley
parent 085c647c33
commit 76a95d75ed
14 changed files with 516 additions and 382 deletions

View File

@ -446,23 +446,25 @@ lpfc_config_port_post(struct lpfc_hba *phba)
/* Get the default values for Model Name and Description */
lpfc_get_hba_model_desc(phba, phba->ModelName, phba->ModelDesc);
if ((phba->cfg_link_speed > LINK_SPEED_10G)
|| ((phba->cfg_link_speed == LINK_SPEED_1G)
if ((phba->cfg_link_speed > LPFC_USER_LINK_SPEED_16G)
|| ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_1G)
&& !(phba->lmt & LMT_1Gb))
|| ((phba->cfg_link_speed == LINK_SPEED_2G)
|| ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_2G)
&& !(phba->lmt & LMT_2Gb))
|| ((phba->cfg_link_speed == LINK_SPEED_4G)
|| ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_4G)
&& !(phba->lmt & LMT_4Gb))
|| ((phba->cfg_link_speed == LINK_SPEED_8G)
|| ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_8G)
&& !(phba->lmt & LMT_8Gb))
|| ((phba->cfg_link_speed == LINK_SPEED_10G)
&& !(phba->lmt & LMT_10Gb))) {
|| ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_10G)
&& !(phba->lmt & LMT_10Gb))
|| ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G)
&& !(phba->lmt & LMT_16Gb))) {
/* Reset link speed to auto */
lpfc_printf_log(phba, KERN_WARNING, LOG_LINK_EVENT,
"1302 Invalid speed for this board: "
"Reset link speed to auto: x%x\n",
phba->cfg_link_speed);
phba->cfg_link_speed = LINK_SPEED_AUTO;
phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
}
phba->link_state = LPFC_LINK_DOWN;
@ -648,22 +650,23 @@ lpfc_hba_init_link(struct lpfc_hba *phba, uint32_t flag)
mb = &pmb->u.mb;
pmb->vport = vport;
lpfc_init_link(phba, pmb, phba->cfg_topology,
phba->cfg_link_speed);
lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
lpfc_set_loopback_flag(phba);
rc = lpfc_sli_issue_mbox(phba, pmb, flag);
if (rc != MBX_SUCCESS) {
if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0498 Adapter failed to init, mbxCmd x%x "
"INIT_LINK, mbxStatus x%x\n",
mb->mbxCommand, mb->mbxStatus);
/* Clear all interrupt enable conditions */
writel(0, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */
/* Clear all pending interrupts */
writel(0xffffffff, phba->HAregaddr);
readl(phba->HAregaddr); /* flush */
if (phba->sli_rev <= LPFC_SLI_REV3) {
/* Clear all interrupt enable conditions */
writel(0, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */
/* Clear all pending interrupts */
writel(0xffffffff, phba->HAregaddr);
readl(phba->HAregaddr); /* flush */
}
phba->link_state = LPFC_HBA_ERROR;
if (rc != MBX_BUSY || flag == MBX_POLL)
mempool_free(pmb, phba->mbox_mem_pool);
@ -1459,8 +1462,8 @@ lpfc_handle_latt(struct lpfc_hba *phba)
lpfc_els_flush_all_cmd(phba);
psli->slistat.link_event++;
lpfc_read_la(phba, pmb, mp);
pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la;
lpfc_read_topology(phba, pmb, mp);
pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
pmb->vport = vport;
/* Block ELS IOCBs until we have processed this mbox command */
phba->sli.ring[LPFC_ELS_RING].flag |= LPFC_STOP_IOCB_EVENT;
@ -3059,20 +3062,20 @@ lpfc_sli4_parse_latt_type(struct lpfc_hba *phba,
switch (bf_get(lpfc_acqe_link_status, acqe_link)) {
case LPFC_ASYNC_LINK_STATUS_DOWN:
case LPFC_ASYNC_LINK_STATUS_LOGICAL_DOWN:
att_type = AT_LINK_DOWN;
att_type = LPFC_ATT_LINK_DOWN;
break;
case LPFC_ASYNC_LINK_STATUS_UP:
/* Ignore physical link up events - wait for logical link up */
att_type = AT_RESERVED;
att_type = LPFC_ATT_RESERVED;
break;
case LPFC_ASYNC_LINK_STATUS_LOGICAL_UP:
att_type = AT_LINK_UP;
att_type = LPFC_ATT_LINK_UP;
break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0399 Invalid link attention type: x%x\n",
bf_get(lpfc_acqe_link_status, acqe_link));
att_type = AT_RESERVED;
att_type = LPFC_ATT_RESERVED;
break;
}
return att_type;
@ -3096,32 +3099,28 @@ lpfc_sli4_parse_latt_link_speed(struct lpfc_hba *phba,
switch (bf_get(lpfc_acqe_link_speed, acqe_link)) {
case LPFC_ASYNC_LINK_SPEED_ZERO:
link_speed = LA_UNKNW_LINK;
break;
case LPFC_ASYNC_LINK_SPEED_10MBPS:
link_speed = LA_UNKNW_LINK;
break;
case LPFC_ASYNC_LINK_SPEED_100MBPS:
link_speed = LA_UNKNW_LINK;
link_speed = LPFC_LINK_SPEED_UNKNOWN;
break;
case LPFC_ASYNC_LINK_SPEED_1GBPS:
link_speed = LA_1GHZ_LINK;
link_speed = LPFC_LINK_SPEED_1GHZ;
break;
case LPFC_ASYNC_LINK_SPEED_10GBPS:
link_speed = LA_10GHZ_LINK;
link_speed = LPFC_LINK_SPEED_10GHZ;
break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0483 Invalid link-attention link speed: x%x\n",
bf_get(lpfc_acqe_link_speed, acqe_link));
link_speed = LA_UNKNW_LINK;
link_speed = LPFC_LINK_SPEED_UNKNOWN;
break;
}
return link_speed;
}
/**
* lpfc_sli4_async_link_evt - Process the asynchronous link event
* lpfc_sli4_async_link_evt - Process the asynchronous FC or FCoE link event
* @phba: pointer to lpfc hba data structure.
* @acqe_link: pointer to the async link completion queue entry.
*
@ -3134,11 +3133,12 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
struct lpfc_dmabuf *mp;
LPFC_MBOXQ_t *pmb;
MAILBOX_t *mb;
READ_LA_VAR *la;
struct lpfc_mbx_read_top *la;
uint8_t att_type;
int rc;
att_type = lpfc_sli4_parse_latt_type(phba, acqe_link);
if (att_type != AT_LINK_DOWN && att_type != AT_LINK_UP)
if (att_type != LPFC_ATT_LINK_DOWN && att_type != LPFC_ATT_LINK_UP)
return;
phba->fcoe_eventtag = acqe_link->event_tag;
pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@ -3169,28 +3169,11 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
/* Update link event statistics */
phba->sli.slistat.link_event++;
/* Create pseudo lpfc_handle_latt mailbox command from link ACQE */
lpfc_read_la(phba, pmb, mp);
/* Create lpfc_handle_latt mailbox command from link ACQE */
lpfc_read_topology(phba, pmb, mp);
pmb->mbox_cmpl = lpfc_mbx_cmpl_read_topology;
pmb->vport = phba->pport;
/* Parse and translate status field */
mb = &pmb->u.mb;
mb->mbxStatus = lpfc_sli4_parse_latt_fault(phba, acqe_link);
/* Parse and translate link attention fields */
la = (READ_LA_VAR *) &pmb->u.mb.un.varReadLA;
la->eventTag = acqe_link->event_tag;
la->attType = att_type;
la->UlnkSpeed = lpfc_sli4_parse_latt_link_speed(phba, acqe_link);
/* Fake the the following irrelvant fields */
la->topology = TOPOLOGY_PT_PT;
la->granted_AL_PA = 0;
la->il = 0;
la->pb = 0;
la->fa = 0;
la->mm = 0;
/* Keep the link status for extra SLI4 state machine reference */
phba->sli4_hba.link_state.speed =
bf_get(lpfc_acqe_link_speed, acqe_link);
@ -3204,9 +3187,42 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
bf_get(lpfc_acqe_link_fault, acqe_link);
phba->sli4_hba.link_state.logical_speed =
bf_get(lpfc_acqe_qos_link_speed, acqe_link);
/*
* For FC Mode: issue the READ_TOPOLOGY mailbox command to fetch
* topology info. Note: Optional for non FC-AL ports.
*/
if (!(phba->hba_flag & HBA_FCOE_MODE)) {
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED)
goto out_free_dmabuf;
return;
}
/*
* For FCoE Mode: fill in all the topology information we need and call
* the READ_TOPOLOGY completion routine to continue without actually
* sending the READ_TOPOLOGY mailbox command to the port.
*/
/* Parse and translate status field */
mb = &pmb->u.mb;
mb->mbxStatus = lpfc_sli4_parse_latt_fault(phba, acqe_link);
/* Parse and translate link attention fields */
la = (struct lpfc_mbx_read_top *) &pmb->u.mb.un.varReadTop;
la->eventTag = acqe_link->event_tag;
bf_set(lpfc_mbx_read_top_att_type, la, att_type);
bf_set(lpfc_mbx_read_top_link_spd, la,
lpfc_sli4_parse_latt_link_speed(phba, acqe_link));
/* Fake the the following irrelvant fields */
bf_set(lpfc_mbx_read_top_topology, la, LPFC_TOPOLOGY_PT_PT);
bf_set(lpfc_mbx_read_top_alpa_granted, la, 0);
bf_set(lpfc_mbx_read_top_il, la, 0);
bf_set(lpfc_mbx_read_top_pb, la, 0);
bf_set(lpfc_mbx_read_top_fa, la, 0);
bf_set(lpfc_mbx_read_top_mm, la, 0);
/* Invoke the lpfc_handle_latt mailbox command callback function */
lpfc_mbx_cmpl_read_la(phba, pmb);
lpfc_mbx_cmpl_read_topology(phba, pmb);
return;
@ -3295,15 +3311,15 @@ lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba)
}
/**
* lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event
* lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event
* @phba: pointer to lpfc hba data structure.
* @acqe_link: pointer to the async fcoe completion queue entry.
*
* This routine is to handle the SLI4 asynchronous fcoe event.
**/
static void
lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
struct lpfc_acqe_fcoe *acqe_fcoe)
lpfc_sli4_async_fip_evt(struct lpfc_hba *phba,
struct lpfc_acqe_fcoe *acqe_fcoe)
{
uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe);
int rc;
@ -3605,12 +3621,13 @@ void lpfc_sli4_async_event_proc(struct lpfc_hba *phba)
/* Process the asynchronous event */
switch (bf_get(lpfc_trailer_code, &cq_event->cqe.mcqe_cmpl)) {
case LPFC_TRAILER_CODE_LINK:
case LPFC_TRAILER_CODE_FC:
lpfc_sli4_async_link_evt(phba,
&cq_event->cqe.acqe_link);
break;
case LPFC_TRAILER_CODE_FCOE:
lpfc_sli4_async_fcoe_evt(phba,
&cq_event->cqe.acqe_fcoe);
lpfc_sli4_async_fip_evt(phba,
&cq_event->cqe.acqe_fcoe);
break;
case LPFC_TRAILER_CODE_DCBX:
lpfc_sli4_async_dcbx_evt(phba,