Commit 9589b062 authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.3.23: Miscellaneous fixes

Miscellaneous fixes

- Do not limit RPI Count to a minimum of 64
- Fix FCFI incorrect on received unsolicited frames.
- Save the FCFI returned in the REG_FCFI mailbox command if it was successful.
- Fixed Vports not sending FDISC after lips.
- Align based on the SLI4_PAGE_SIZE.
- Fixed double byte swap on received RRQ.
- Fixed mask size for the wq_id mask from 0x7F to 0x7FFF.
- Clear FC_FABRIC flag when NPIV LOGO completes (and add a log message).
- Modified driver to skip round robin only when ulpStatus==LOCAL_REJECT
  and word4=SEQUENCE_TIMEOUT to prevent FLOGI to disconnected FCF.
- Don't add rport if driver unloading
Signed-off-by: default avatarAlex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 86a80846
...@@ -670,6 +670,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -670,6 +670,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
* Driver needs to re-reg VPI in order for f/w * Driver needs to re-reg VPI in order for f/w
* to update the MAC address. * to update the MAC address.
*/ */
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
lpfc_register_new_vport(phba, vport, ndlp); lpfc_register_new_vport(phba, vport, ndlp);
return 0; return 0;
} }
...@@ -869,8 +870,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -869,8 +870,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
*/ */
if ((phba->hba_flag & HBA_FIP_SUPPORT) && if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
(phba->fcf.fcf_flag & FCF_DISCOVERY) && (phba->fcf.fcf_flag & FCF_DISCOVERY) &&
(irsp->ulpStatus != IOSTAT_LOCAL_REJECT) && !((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
(irsp->un.ulpWord[4] != IOERR_SLI_ABORTED)) { (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))) {
lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS, lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
"2611 FLOGI failed on FCF (x%x), " "2611 FLOGI failed on FCF (x%x), "
"status:x%x/x%x, tmo:x%x, perform " "status:x%x/x%x, tmo:x%x, perform "
...@@ -4107,13 +4108,13 @@ lpfc_els_clear_rrq(struct lpfc_vport *vport, ...@@ -4107,13 +4108,13 @@ lpfc_els_clear_rrq(struct lpfc_vport *vport,
pcmd += sizeof(uint32_t); pcmd += sizeof(uint32_t);
rrq = (struct RRQ *)pcmd; rrq = (struct RRQ *)pcmd;
rrq->rrq_exchg = be32_to_cpu(rrq->rrq_exchg); rrq->rrq_exchg = be32_to_cpu(rrq->rrq_exchg);
rxid = be16_to_cpu(bf_get(rrq_rxid, rrq)); rxid = bf_get(rrq_rxid, rrq);
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x" "2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x"
" x%x x%x\n", " x%x x%x\n",
be32_to_cpu(bf_get(rrq_did, rrq)), be32_to_cpu(bf_get(rrq_did, rrq)),
be16_to_cpu(bf_get(rrq_oxid, rrq)), bf_get(rrq_oxid, rrq),
rxid, rxid,
iocb->iotag, iocb->iocb.ulpContext); iocb->iotag, iocb->iocb.ulpContext);
...@@ -4121,7 +4122,7 @@ lpfc_els_clear_rrq(struct lpfc_vport *vport, ...@@ -4121,7 +4122,7 @@ lpfc_els_clear_rrq(struct lpfc_vport *vport,
"Clear RRQ: did:x%x flg:x%x exchg:x%.08x", "Clear RRQ: did:x%x flg:x%x exchg:x%.08x",
ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg); ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg);
if (vport->fc_myDID == be32_to_cpu(bf_get(rrq_did, rrq))) if (vport->fc_myDID == be32_to_cpu(bf_get(rrq_did, rrq)))
xri = be16_to_cpu(bf_get(rrq_oxid, rrq)); xri = bf_get(rrq_oxid, rrq);
else else
xri = rxid; xri = rxid;
prrq = lpfc_get_active_rrq(vport, xri, ndlp->nlp_DID); prrq = lpfc_get_active_rrq(vport, xri, ndlp->nlp_DID);
...@@ -7290,8 +7291,9 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -7290,8 +7291,9 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_vport *vport = cmdiocb->vport; struct lpfc_vport *vport = cmdiocb->vport;
IOCB_t *irsp; IOCB_t *irsp;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
ndlp = (struct lpfc_nodelist *)cmdiocb->context1; struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
ndlp = (struct lpfc_nodelist *)cmdiocb->context1;
irsp = &rspiocb->iocb; irsp = &rspiocb->iocb;
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
"LOGO npiv cmpl: status:x%x/x%x did:x%x", "LOGO npiv cmpl: status:x%x/x%x did:x%x",
...@@ -7302,6 +7304,19 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -7302,6 +7304,19 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* Trigger the release of the ndlp after logo */ /* Trigger the release of the ndlp after logo */
lpfc_nlp_put(ndlp); lpfc_nlp_put(ndlp);
/* NPIV LOGO completes to NPort <nlp_DID> */
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"2928 NPIV LOGO completes to NPort x%x "
"Data: x%x x%x x%x x%x\n",
ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
irsp->ulpTimeout, vport->num_disc_nodes);
if (irsp->ulpStatus == IOSTAT_SUCCESS) {
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~FC_FABRIC;
spin_unlock_irq(shost->host_lock);
}
} }
/** /**
......
/******************************************************************* /*******************************************************************
* This file is part of the Emulex Linux Device Driver for * * This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. * * Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2009 Emulex. All rights reserved. * * Copyright (C) 2004-2011 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. * * EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com * * www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig * * Portions Copyright (C) 2004-2005 Christoph Hellwig *
...@@ -3569,6 +3569,10 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) ...@@ -3569,6 +3569,10 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
"rport add: did:x%x flg:x%x type x%x", "rport add: did:x%x flg:x%x type x%x",
ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
/* Don't add the remote port if unloading. */
if (vport->load_flag & FC_UNLOADING)
return;
ndlp->rport = rport = fc_remote_port_add(shost, 0, &rport_ids); ndlp->rport = rport = fc_remote_port_add(shost, 0, &rport_ids);
if (!rport || !get_device(&rport->dev)) { if (!rport || !get_device(&rport->dev)) {
dev_printk(KERN_WARNING, &phba->pcidev->dev, dev_printk(KERN_WARNING, &phba->pcidev->dev,
......
...@@ -2108,6 +2108,8 @@ struct lpfc_mbx_pc_sli4_params { ...@@ -2108,6 +2108,8 @@ struct lpfc_mbx_pc_sli4_params {
#define sgl_pp_align_WORD word12 #define sgl_pp_align_WORD word12
uint32_t rsvd_13_63[51]; uint32_t rsvd_13_63[51];
}; };
#define SLI4_PAGE_ALIGN(addr) (((addr)+((SLI4_PAGE_SIZE)-1)) \
&(~((SLI4_PAGE_SIZE)-1)))
struct lpfc_sli4_parameters { struct lpfc_sli4_parameters {
uint32_t word0; uint32_t word0;
...@@ -2524,7 +2526,7 @@ struct wqe_common { ...@@ -2524,7 +2526,7 @@ struct wqe_common {
#define wqe_wqes_WORD word10 #define wqe_wqes_WORD word10
/* Note that this field overlaps above fields */ /* Note that this field overlaps above fields */
#define wqe_wqid_SHIFT 1 #define wqe_wqid_SHIFT 1
#define wqe_wqid_MASK 0x0000007f #define wqe_wqid_MASK 0x00007fff
#define wqe_wqid_WORD word10 #define wqe_wqid_WORD word10
#define wqe_pri_SHIFT 16 #define wqe_pri_SHIFT 16
#define wqe_pri_MASK 0x00000007 #define wqe_pri_MASK 0x00000007
......
...@@ -4906,6 +4906,7 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) ...@@ -4906,6 +4906,7 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
uint16_t rpi_limit, curr_rpi_range; uint16_t rpi_limit, curr_rpi_range;
struct lpfc_dmabuf *dmabuf; struct lpfc_dmabuf *dmabuf;
struct lpfc_rpi_hdr *rpi_hdr; struct lpfc_rpi_hdr *rpi_hdr;
uint32_t rpi_count;
rpi_limit = phba->sli4_hba.max_cfg_param.rpi_base + 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;
...@@ -4920,7 +4921,9 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) ...@@ -4920,7 +4921,9 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
* and to allow the full max_rpi range per port. * and to allow the full max_rpi range per port.
*/ */
if ((curr_rpi_range + (LPFC_RPI_HDR_COUNT - 1)) > rpi_limit) if ((curr_rpi_range + (LPFC_RPI_HDR_COUNT - 1)) > rpi_limit)
return NULL; rpi_count = rpi_limit - curr_rpi_range;
else
rpi_count = LPFC_RPI_HDR_COUNT;
/* /*
* First allocate the protocol header region for the port. The * First allocate the protocol header region for the port. The
...@@ -4961,7 +4964,7 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) ...@@ -4961,7 +4964,7 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba)
* The next_rpi stores the next module-64 rpi value to post * The next_rpi stores the next module-64 rpi value to post
* in any subsequent rpi memory region postings. * in any subsequent rpi memory region postings.
*/ */
phba->sli4_hba.next_rpi += LPFC_RPI_HDR_COUNT; phba->sli4_hba.next_rpi += rpi_count;
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
return rpi_hdr; return rpi_hdr;
......
...@@ -1736,7 +1736,7 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox, ...@@ -1736,7 +1736,7 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
} }
/* Setup for the none-embedded mbox command */ /* Setup for the none-embedded mbox command */
pcount = (PAGE_ALIGN(length))/SLI4_PAGE_SIZE; pcount = (SLI4_PAGE_ALIGN(length))/SLI4_PAGE_SIZE;
pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ? pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ?
LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount; LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount;
/* Allocate record for keeping SGE virtual addresses */ /* Allocate record for keeping SGE virtual addresses */
......
...@@ -5018,10 +5018,11 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) ...@@ -5018,10 +5018,11 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
lpfc_reg_fcfi(phba, mboxq); lpfc_reg_fcfi(phba, mboxq);
mboxq->vport = phba->pport; mboxq->vport = phba->pport;
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
if (rc == MBX_SUCCESS) if (rc != MBX_SUCCESS)
rc = 0;
else
goto out_unset_queue; goto out_unset_queue;
rc = 0;
phba->fcf.fcfi = bf_get(lpfc_reg_fcfi_fcfi,
&mboxq->u.mqe.un.reg_fcfi);
} }
/* /*
* The port is ready, set the host's link state to LINK_DOWN * The port is ready, set the host's link state to LINK_DOWN
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment