Merge tag 'libnvdimm-for-5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm...
[linux-2.6-microblaze.git] / drivers / scsi / lpfc / lpfc_els.c
index f1c1faa..fc077cb 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.     *
  * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -242,6 +242,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
                icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
                if (elscmd == ELS_CMD_FLOGI)
                        icmd->ulpTimeout = FF_DEF_RATOV * 2;
+               else if (elscmd == ELS_CMD_LOGO)
+                       icmd->ulpTimeout = phba->fc_ratov;
                else
                        icmd->ulpTimeout = phba->fc_ratov * 2;
        } else {
@@ -313,20 +315,20 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
                /* Xmit ELS command <elsCmd> to remote NPORT <did> */
                lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
                                 "0116 Xmit ELS command x%x to remote "
-                                "NPORT x%x I/O tag: x%x, port state:x%x"
-                                " fc_flag:x%x\n",
+                                "NPORT x%x I/O tag: x%x, port state:x%x "
+                                "rpi x%x fc_flag:x%x\n",
                                 elscmd, did, elsiocb->iotag,
-                                vport->port_state,
+                                vport->port_state, ndlp->nlp_rpi,
                                 vport->fc_flag);
        } else {
                /* Xmit ELS response <elsCmd> to remote NPORT <did> */
                lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
                                 "0117 Xmit ELS response x%x to remote "
                                 "NPORT x%x I/O tag: x%x, size: x%x "
-                                "port_state x%x fc_flag x%x\n",
+                                "port_state x%x  rpi x%x fc_flag x%x\n",
                                 elscmd, ndlp->nlp_DID, elsiocb->iotag,
                                 cmdSize, vport->port_state,
-                                vport->fc_flag);
+                                ndlp->nlp_rpi, vport->fc_flag);
        }
        return elsiocb;
 
@@ -413,7 +415,7 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
        /* increment the reference count on ndlp to hold reference
         * for the callback routine.
         */
-       mbox->context2 = lpfc_nlp_get(ndlp);
+       mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
 
        rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
        if (rc == MBX_NOT_FINISHED) {
@@ -428,7 +430,7 @@ fail_issue_reg_login:
         * for the failed mbox command.
         */
        lpfc_nlp_put(ndlp);
-       mp = (struct lpfc_dmabuf *) mbox->context1;
+       mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
        lpfc_mbuf_free(phba, mp->virt, mp->phys);
        kfree(mp);
 fail_free_mbox:
@@ -502,7 +504,7 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
 
        mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi;
        mboxq->vport = vport;
-       mboxq->context1 = dmabuf;
+       mboxq->ctx_buf = dmabuf;
        rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
        if (rc == MBX_NOT_FINISHED) {
                rc = -ENXIO;
@@ -1055,9 +1057,9 @@ stop_rr_fcf_flogi:
                        goto flogifail;
 
                lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
-                                "0150 FLOGI failure Status:x%x/x%x TMO:x%x\n",
+                                "0150 FLOGI failure Status:x%x/x%x xri x%x TMO:x%x\n",
                                 irsp->ulpStatus, irsp->un.ulpWord[4],
-                                irsp->ulpTimeout);
+                                cmdiocb->sli4_xritag, irsp->ulpTimeout);
 
                /* FLOGI failed, so there is no fabric */
                spin_lock_irq(shost->host_lock);
@@ -1111,7 +1113,8 @@ stop_rr_fcf_flogi:
        /* FLOGI completes successfully */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
                         "0101 FLOGI completes successfully, I/O tag:x%x, "
-                        "Data: x%x x%x x%x x%x x%x x%x\n", cmdiocb->iotag,
+                        "xri x%x Data: x%x x%x x%x x%x x%x %x\n",
+                        cmdiocb->iotag, cmdiocb->sli4_xritag,
                         irsp->un.ulpWord[4], sp->cmn.e_d_tov,
                         sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution,
                         vport->port_state, vport->fc_flag);
@@ -1155,6 +1158,7 @@ stop_rr_fcf_flogi:
                        phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
                        phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
                        spin_unlock_irq(&phba->hbalock);
+                       phba->fcf.fcf_redisc_attempted = 0; /* reset */
                        goto out;
                }
                if (!rc) {
@@ -1169,6 +1173,7 @@ stop_rr_fcf_flogi:
                        phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
                        phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
                        spin_unlock_irq(&phba->hbalock);
+                       phba->fcf.fcf_redisc_attempted = 0; /* reset */
                        goto out;
                }
        }
@@ -1229,9 +1234,10 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        struct serv_parm *sp;
        IOCB_t *icmd;
        struct lpfc_iocbq *elsiocb;
+       struct lpfc_iocbq defer_flogi_acc;
        uint8_t *pcmd;
        uint16_t cmdsize;
-       uint32_t tmo;
+       uint32_t tmo, did;
        int rc;
 
        cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
@@ -1303,6 +1309,35 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                phba->sli3_options, 0, 0);
 
        rc = lpfc_issue_fabric_iocb(phba, elsiocb);
+
+       phba->hba_flag |= HBA_FLOGI_ISSUED;
+
+       /* Check for a deferred FLOGI ACC condition */
+       if (phba->defer_flogi_acc_flag) {
+               did = vport->fc_myDID;
+               vport->fc_myDID = Fabric_DID;
+
+               memset(&defer_flogi_acc, 0, sizeof(struct lpfc_iocbq));
+
+               defer_flogi_acc.iocb.ulpContext = phba->defer_flogi_acc_rx_id;
+               defer_flogi_acc.iocb.unsli3.rcvsli3.ox_id =
+                                               phba->defer_flogi_acc_ox_id;
+
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                                "3354 Xmit deferred FLOGI ACC: rx_id: x%x,"
+                                " ox_id: x%x, hba_flag x%x\n",
+                                phba->defer_flogi_acc_rx_id,
+                                phba->defer_flogi_acc_ox_id, phba->hba_flag);
+
+               /* Send deferred FLOGI ACC */
+               lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, &defer_flogi_acc,
+                                ndlp, NULL);
+
+               phba->defer_flogi_acc_flag = false;
+
+               vport->fc_myDID = did;
+       }
+
        if (rc == IOCB_ERROR) {
                lpfc_els_free_iocb(phba, elsiocb);
                return 1;
@@ -1338,6 +1373,8 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
                        Fabric_DID);
 
        pring = lpfc_phba_elsring(phba);
+       if (unlikely(!pring))
+               return -EIO;
 
        /*
         * Check the txcmplq for an iocb that matches the nport the driver is
@@ -1531,7 +1568,9 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
        struct serv_parm *sp;
        uint8_t  name[sizeof(struct lpfc_name)];
        uint32_t rc, keepDID = 0, keep_nlp_flag = 0;
+       uint32_t keep_new_nlp_flag = 0;
        uint16_t keep_nlp_state;
+       u32 keep_nlp_fc4_type = 0;
        struct lpfc_nvme_rport *keep_nrport = NULL;
        int  put_node;
        int  put_rport;
@@ -1551,8 +1590,10 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
         */
        new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName);
 
+       /* return immediately if the WWPN matches ndlp */
        if (new_ndlp == ndlp && NLP_CHK_NODE_ACT(new_ndlp))
                return ndlp;
+
        if (phba->sli_rev == LPFC_SLI_REV4) {
                active_rrqs_xri_bitmap = mempool_alloc(phba->active_rrq_pool,
                                                       GFP_KERNEL);
@@ -1561,9 +1602,13 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
                               phba->cfg_rrq_xri_bitmap_sz);
        }
 
-       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
-                "3178 PLOGI confirm: ndlp %p x%x: new_ndlp %p\n",
-                ndlp, ndlp->nlp_DID, new_ndlp);
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_NODE,
+                        "3178 PLOGI confirm: ndlp x%x x%x x%x: "
+                        "new_ndlp x%x x%x x%x\n",
+                        ndlp->nlp_DID, ndlp->nlp_flag,  ndlp->nlp_fc4_type,
+                        (new_ndlp ? new_ndlp->nlp_DID : 0),
+                        (new_ndlp ? new_ndlp->nlp_flag : 0),
+                        (new_ndlp ? new_ndlp->nlp_fc4_type : 0));
 
        if (!new_ndlp) {
                rc = memcmp(&ndlp->nlp_portname, name,
@@ -1612,6 +1657,16 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
                               phba->cfg_rrq_xri_bitmap_sz);
        }
 
+       /* At this point in this routine, we know new_ndlp will be
+        * returned. however, any previous GID_FTs that were done
+        * would have updated nlp_fc4_type in ndlp, so we must ensure
+        * new_ndlp has the right value.
+        */
+       if (vport->fc_flag & FC_FABRIC) {
+               keep_nlp_fc4_type = new_ndlp->nlp_fc4_type;
+               new_ndlp->nlp_fc4_type = ndlp->nlp_fc4_type;
+       }
+
        lpfc_unreg_rpi(vport, new_ndlp);
        new_ndlp->nlp_DID = ndlp->nlp_DID;
        new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
@@ -1621,9 +1676,36 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
                       phba->cfg_rrq_xri_bitmap_sz);
 
        spin_lock_irq(shost->host_lock);
-       keep_nlp_flag = new_ndlp->nlp_flag;
+       keep_new_nlp_flag = new_ndlp->nlp_flag;
+       keep_nlp_flag = ndlp->nlp_flag;
        new_ndlp->nlp_flag = ndlp->nlp_flag;
-       ndlp->nlp_flag = keep_nlp_flag;
+
+       /* if new_ndlp had NLP_UNREG_INP set, keep it */
+       if (keep_new_nlp_flag & NLP_UNREG_INP)
+               new_ndlp->nlp_flag |= NLP_UNREG_INP;
+       else
+               new_ndlp->nlp_flag &= ~NLP_UNREG_INP;
+
+       /* if new_ndlp had NLP_RPI_REGISTERED set, keep it */
+       if (keep_new_nlp_flag & NLP_RPI_REGISTERED)
+               new_ndlp->nlp_flag |= NLP_RPI_REGISTERED;
+       else
+               new_ndlp->nlp_flag &= ~NLP_RPI_REGISTERED;
+
+       ndlp->nlp_flag = keep_new_nlp_flag;
+
+       /* if ndlp had NLP_UNREG_INP set, keep it */
+       if (keep_nlp_flag & NLP_UNREG_INP)
+               ndlp->nlp_flag |= NLP_UNREG_INP;
+       else
+               ndlp->nlp_flag &= ~NLP_UNREG_INP;
+
+       /* if ndlp had NLP_RPI_REGISTERED set, keep it */
+       if (keep_nlp_flag & NLP_RPI_REGISTERED)
+               ndlp->nlp_flag |= NLP_RPI_REGISTERED;
+       else
+               ndlp->nlp_flag &= ~NLP_RPI_REGISTERED;
+
        spin_unlock_irq(shost->host_lock);
 
        /* Set nlp_states accordingly */
@@ -1661,7 +1743,6 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
                if (ndlp->nrport) {
                        ndlp->nrport = NULL;
                        lpfc_nlp_put(ndlp);
-                       new_ndlp->nlp_fc4_type = ndlp->nlp_fc4_type;
                }
 
                /* We shall actually free the ndlp with both nlp_DID and
@@ -1674,7 +1755,10 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
                        spin_unlock_irq(&phba->ndlp_lock);
                }
 
-               /* Two ndlps cannot have the same did on the nodelist */
+               /* Two ndlps cannot have the same did on the nodelist.
+                * Note: for this case, ndlp has a NULL WWPN so setting
+                * the nlp_fc4_type isn't required.
+                */
                ndlp->nlp_DID = keepDID;
                lpfc_nlp_set_state(vport, ndlp, keep_nlp_state);
                if (phba->sli_rev == LPFC_SLI_REV4 &&
@@ -1693,8 +1777,13 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
 
                lpfc_unreg_rpi(vport, ndlp);
 
-               /* Two ndlps cannot have the same did */
+               /* Two ndlps cannot have the same did and the fc4
+                * type must be transferred because the ndlp is in
+                * flight.
+                */
                ndlp->nlp_DID = keepDID;
+               ndlp->nlp_fc4_type = keep_nlp_fc4_type;
+
                if (phba->sli_rev == LPFC_SLI_REV4 &&
                    active_rrqs_xri_bitmap)
                        memcpy(ndlp->active_rrqs_xri_bitmap,
@@ -1735,6 +1824,12 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
            active_rrqs_xri_bitmap)
                mempool_free(active_rrqs_xri_bitmap,
                             phba->active_rrq_pool);
+
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_NODE,
+                        "3173 PLOGI confirm exit: new_ndlp x%x x%x x%x\n",
+                        new_ndlp->nlp_DID, new_ndlp->nlp_flag,
+                        new_ndlp->nlp_fc4_type);
+
        return new_ndlp;
 }
 
@@ -1895,7 +1990,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
        ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
        spin_unlock_irq(shost->host_lock);
-       rc   = 0;
+       rc = 0;
 
        /* PLOGI completes to NPort <nlp_DID> */
        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
@@ -2002,8 +2097,29 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
        int ret;
 
        ndlp = lpfc_findnode_did(vport, did);
-       if (ndlp && !NLP_CHK_NODE_ACT(ndlp))
-               ndlp = NULL;
+
+       if (ndlp) {
+               /* Defer the processing of the issue PLOGI until after the
+                * outstanding UNREG_RPI mbox command completes, unless we
+                * are going offline. This logic does not apply for Fabric DIDs
+                */
+               if ((ndlp->nlp_flag & NLP_UNREG_INP) &&
+                   ((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
+                   !(vport->fc_flag & FC_OFFLINE_MODE)) {
+                       lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+                                        "4110 Issue PLOGI x%x deferred "
+                                        "on NPort x%x rpi x%x Data: %p\n",
+                                        ndlp->nlp_defer_did, ndlp->nlp_DID,
+                                        ndlp->nlp_rpi, ndlp);
+
+                       /* We can only defer 1st PLOGI */
+                       if (ndlp->nlp_defer_did == NLP_EVT_NOTHING_PENDING)
+                               ndlp->nlp_defer_did = did;
+                       return 0;
+               }
+               if (!NLP_CHK_NODE_ACT(ndlp))
+                       ndlp = NULL;
+       }
 
        /* If ndlp is not NULL, we will bump the reference count on it */
        cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
@@ -2137,7 +2253,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                else
                        lpfc_disc_state_machine(vport, ndlp, cmdiocb,
                                                NLP_EVT_CMPL_PRLI);
-       } else
+       } else {
                /* Good status, call state machine.  However, if another
                 * PRLI is outstanding, don't call the state machine
                 * because final disposition to Mapped or Unmapped is
@@ -2145,6 +2261,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                 */
                lpfc_disc_state_machine(vport, ndlp, cmdiocb,
                                        NLP_EVT_CMPL_PRLI);
+       }
 
 out:
        lpfc_els_free_iocb(phba, cmdiocb);
@@ -2203,7 +2320,7 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
        ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
        ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
-       ndlp->nlp_flag &= ~NLP_FIRSTBURST;
+       ndlp->nlp_flag &= ~(NLP_FIRSTBURST | NLP_NPR_2B_DISC);
        ndlp->nvme_fb_size = 0;
 
  send_next_prli:
@@ -2682,16 +2799,15 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                goto out;
        }
 
+       /* The LOGO will not be retried on failure.  A LOGO was
+        * issued to the remote rport and a ACC or RJT or no Answer are
+        * all acceptable.  Note the failure and move forward with
+        * discovery.  The PLOGI will retry.
+        */
        if (irsp->ulpStatus) {
-               /* Check for retry */
-               if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
-                       /* ELS command is being retried */
-                       skip_recovery = 1;
-                       goto out;
-               }
                /* LOGO failed */
                lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
-                                "2756 LOGO failure DID:%06X Status:x%x/x%x\n",
+                                "2756 LOGO failure, No Retry DID:%06X Status:x%x/x%x\n",
                                 ndlp->nlp_DID, irsp->ulpStatus,
                                 irsp->un.ulpWord[4]);
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
@@ -2711,8 +2827,8 @@ out:
                !(vport->fc_flag & FC_PT2PT_PLOGI)) {
                phba->pport->fc_myDID = 0;
 
-               if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
-                   (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
+               if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
+                   (vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
                        if (phba->nvmet_support)
                                lpfc_nvmet_update_targetport(phba);
                        else
@@ -2737,7 +2853,8 @@ out:
         * For any other port type, the rpi is unregistered as an implicit
         * LOGO.
         */
-       if ((ndlp->nlp_type & NLP_FCP_TARGET) && (skip_recovery == 0)) {
+       if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET) &&
+           skip_recovery == 0) {
                lpfc_cancel_retry_delay_tmo(vport, ndlp);
                spin_lock_irqsave(shost->host_lock, flags);
                ndlp->nlp_flag |= NLP_NPR_2B_DISC;
@@ -2770,6 +2887,8 @@ out:
  * will be stored into the context1 field of the IOCB for the completion
  * callback function to the LOGO ELS command.
  *
+ * Callers of this routine are expected to unregister the RPI first
+ *
  * Return code
  *   0 - successfully issued logo
  *   1 - failed to issue logo
@@ -2811,22 +2930,6 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                "Issue LOGO:      did:x%x",
                ndlp->nlp_DID, 0, 0);
 
-       /*
-        * If we are issuing a LOGO, we may try to recover the remote NPort
-        * by issuing a PLOGI later. Even though we issue ELS cmds by the
-        * VPI, if we have a valid RPI, and that RPI gets unreg'ed while
-        * that ELS command is in-flight, the HBA returns a IOERR_INVALID_RPI
-        * for that ELS cmd. To avoid this situation, lets get rid of the
-        * RPI right now, before any ELS cmds are sent.
-        */
-       spin_lock_irq(shost->host_lock);
-       ndlp->nlp_flag |= NLP_ISSUE_LOGO;
-       spin_unlock_irq(shost->host_lock);
-       if (lpfc_unreg_rpi(vport, ndlp)) {
-               lpfc_els_free_iocb(phba, elsiocb);
-               return 0;
-       }
-
        phba->fc_stat.elsXmitLOGO++;
        elsiocb->iocb_cmpl = lpfc_cmpl_els_logo;
        spin_lock_irq(shost->host_lock);
@@ -2834,7 +2937,6 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        ndlp->nlp_flag &= ~NLP_ISSUE_LOGO;
        spin_unlock_irq(shost->host_lock);
        rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
-
        if (rc == IOCB_ERROR) {
                spin_lock_irq(shost->host_lock);
                ndlp->nlp_flag &= ~NLP_LOGO_SND;
@@ -2842,6 +2944,11 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
                lpfc_els_free_iocb(phba, elsiocb);
                return 1;
        }
+
+       spin_lock_irq(shost->host_lock);
+       ndlp->nlp_prev_state = ndlp->nlp_state;
+       spin_unlock_irq(shost->host_lock);
+       lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
        return 0;
 }
 
@@ -3249,6 +3356,62 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
        return;
 }
 
+/**
+ * lpfc_link_reset - Issue link reset
+ * @vport: pointer to a virtual N_Port data structure.
+ *
+ * This routine performs link reset by sending INIT_LINK mailbox command.
+ * For SLI-3 adapter, link attention interrupt is enabled before issuing
+ * INIT_LINK mailbox command.
+ *
+ * Return code
+ *   0 - Link reset initiated successfully
+ *   1 - Failed to initiate link reset
+ **/
+int
+lpfc_link_reset(struct lpfc_vport *vport)
+{
+       struct lpfc_hba *phba = vport->phba;
+       LPFC_MBOXQ_t *mbox;
+       uint32_t control;
+       int rc;
+
+       lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+                        "2851 Attempt link reset\n");
+       mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (!mbox) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+                               "2852 Failed to allocate mbox memory");
+               return 1;
+       }
+
+       /* Enable Link attention interrupts */
+       if (phba->sli_rev <= LPFC_SLI_REV3) {
+               spin_lock_irq(&phba->hbalock);
+               phba->sli.sli_flag |= LPFC_PROCESS_LA;
+               control = readl(phba->HCregaddr);
+               control |= HC_LAINT_ENA;
+               writel(control, phba->HCregaddr);
+               readl(phba->HCregaddr); /* flush */
+               spin_unlock_irq(&phba->hbalock);
+       }
+
+       lpfc_init_link(phba, mbox, phba->cfg_topology,
+                      phba->cfg_link_speed);
+       mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+       mbox->vport = vport;
+       rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+       if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+                               "2853 Failed to issue INIT_LINK "
+                               "mbox command, rc:x%x\n", rc);
+               mempool_free(mbox, phba->mbox_mem_pool);
+               return 1;
+       }
+
+       return 0;
+}
+
 /**
  * lpfc_els_retry - Make retry decision on an els command iocb
  * @phba: pointer to lpfc hba data structure.
@@ -3285,6 +3448,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        int logerr = 0;
        uint32_t cmd = 0;
        uint32_t did;
+       int link_reset = 0, rc;
 
 
        /* Note: context2 may be 0 for internal driver abort
@@ -3366,7 +3530,6 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        retry = 1;
                        break;
 
-               case IOERR_SEQUENCE_TIMEOUT:
                case IOERR_INVALID_RPI:
                        if (cmd == ELS_CMD_PLOGI &&
                            did == NameServer_DID) {
@@ -3377,6 +3540,18 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        }
                        retry = 1;
                        break;
+
+               case IOERR_SEQUENCE_TIMEOUT:
+                       if (cmd == ELS_CMD_PLOGI &&
+                           did == NameServer_DID &&
+                           (cmdiocb->retry + 1) == maxretry) {
+                               /* Reset the Link */
+                               link_reset = 1;
+                               break;
+                       }
+                       retry = 1;
+                       delay = 100;
+                       break;
                }
                break;
 
@@ -3533,6 +3708,19 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                break;
        }
 
+       if (link_reset) {
+               rc = lpfc_link_reset(vport);
+               if (rc) {
+                       /* Do not give up. Retry PLOGI one more time and attempt
+                        * link reset if PLOGI fails again.
+                        */
+                       retry = 1;
+                       delay = 100;
+                       goto out_retry;
+               }
+               return 1;
+       }
+
        if (did == FDMI_DID)
                retry = 1;
 
@@ -3895,11 +4083,11 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 void
 lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
-       struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
-       struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
+       struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf);
+       struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
 
-       pmb->context1 = NULL;
-       pmb->context2 = NULL;
+       pmb->ctx_buf = NULL;
+       pmb->ctx_ndlp = NULL;
 
        lpfc_mbuf_free(phba, mp->virt, mp->phys);
        kfree(mp);
@@ -3975,7 +4163,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        /* Check to see if link went down during discovery */
        if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) {
                if (mbox) {
-                       mp = (struct lpfc_dmabuf *) mbox->context1;
+                       mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
                        if (mp) {
                                lpfc_mbuf_free(phba, mp->virt, mp->phys);
                                kfree(mp);
@@ -4019,7 +4207,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                                        "Data: x%x x%x x%x\n",
                                        ndlp->nlp_DID, ndlp->nlp_state,
                                        ndlp->nlp_rpi, ndlp->nlp_flag);
-                               mp = mbox->context1;
+                               mp = mbox->ctx_buf;
                                if (mp) {
                                        lpfc_mbuf_free(phba, mp->virt,
                                                       mp->phys);
@@ -4032,7 +4220,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        /* Increment reference count to ndlp to hold the
                         * reference to ndlp for the callback function.
                         */
-                       mbox->context2 = lpfc_nlp_get(ndlp);
+                       mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
                        mbox->vport = vport;
                        if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) {
                                mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
@@ -4086,7 +4274,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                                }
                        }
                }
-               mp = (struct lpfc_dmabuf *) mbox->context1;
+               mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
                if (mp) {
                        lpfc_mbuf_free(phba, mp->virt, mp->phys);
                        kfree(mp);
@@ -4272,14 +4460,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
        default:
                return 1;
        }
-       /* Xmit ELS ACC response tag <ulpIoTag> */
-       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
-                        "0128 Xmit ELS ACC response tag x%x, XRI: x%x, "
-                        "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x "
-                        "fc_flag x%x\n",
-                        elsiocb->iotag, elsiocb->iocb.ulpContext,
-                        ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
-                        ndlp->nlp_rpi, vport->fc_flag);
        if (ndlp->nlp_flag & NLP_LOGO_ACC) {
                spin_lock_irq(shost->host_lock);
                if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED ||
@@ -4448,6 +4628,15 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
                lpfc_els_free_iocb(phba, elsiocb);
                return 1;
        }
+
+       /* Xmit ELS ACC response tag <ulpIoTag> */
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                        "0128 Xmit ELS ACC response Status: x%x, IoTag: x%x, "
+                        "XRI: x%x, DID: x%x, nlp_flag: x%x nlp_state: x%x "
+                        "RPI: x%x, fc_flag x%x\n",
+                        rc, elsiocb->iotag, elsiocb->sli4_xritag,
+                        ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+                        ndlp->nlp_rpi, vport->fc_flag);
        return 0;
 }
 
@@ -5281,6 +5470,8 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba)
 
        desc->info.port_speed.speed = cpu_to_be16(rdp_speed);
 
+       if (phba->lmt & LMT_128Gb)
+               rdp_cap |= RDP_PS_128GB;
        if (phba->lmt & LMT_64Gb)
                rdp_cap |= RDP_PS_64GB;
        if (phba->lmt & LMT_32Gb)
@@ -5499,7 +5690,7 @@ lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context)
                goto prep_mbox_fail;
        mbox->vport = rdp_context->ndlp->vport;
        mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a0;
-       mbox->context2 = (struct lpfc_rdp_context *) rdp_context;
+       mbox->ctx_ndlp = (struct lpfc_rdp_context *)rdp_context;
        rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
        if (rc == MBX_NOT_FINISHED)
                goto issue_mbox_fail;
@@ -5542,7 +5733,7 @@ lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
        struct ls_rjt stat;
 
        if (phba->sli_rev < LPFC_SLI_REV4 ||
-           bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+           bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
                                                LPFC_SLI_INTF_IF_TYPE_2) {
                rjt_err = LSRJT_UNABLE_TPC;
                rjt_expl = LSEXP_REQ_UNSUPPORTED;
@@ -5624,10 +5815,10 @@ lpfc_els_lcb_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        int rc;
 
        mb = &pmb->u.mb;
-       lcb_context = (struct lpfc_lcb_context *)pmb->context1;
+       lcb_context = (struct lpfc_lcb_context *)pmb->ctx_ndlp;
        ndlp = lcb_context->ndlp;
-       pmb->context1 = NULL;
-       pmb->context2 = NULL;
+       pmb->ctx_ndlp = NULL;
+       pmb->ctx_buf = NULL;
 
        shdr = (union lpfc_sli4_cfg_shdr *)
                        &pmb->u.mqe.un.beacon_config.header.cfg_shdr;
@@ -5701,6 +5892,9 @@ error:
        stat = (struct ls_rjt *)(pcmd + sizeof(uint32_t));
        stat->un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
 
+       if (shdr_add_status == ADD_STATUS_OPERATION_ALREADY_ACTIVE)
+               stat->un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;
+
        elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
        phba->fc_stat.elsXmitLSRJT++;
        rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
@@ -5731,7 +5925,7 @@ lpfc_sli4_set_beacon(struct lpfc_vport *vport,
        lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
                         LPFC_MBOX_OPCODE_SET_BEACON_CONFIG, len,
                         LPFC_SLI4_MBX_EMBED);
-       mbox->context1 = (void *)lcb_context;
+       mbox->ctx_ndlp = (void *)lcb_context;
        mbox->vport = phba->pport;
        mbox->mbox_cmpl = lpfc_els_lcb_rsp;
        bf_set(lpfc_mbx_set_beacon_port_num, &mbox->u.mqe.un.beacon_config,
@@ -6011,6 +6205,19 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
                if (vport->phba->nvmet_support)
                        continue;
 
+               /* If we are in the process of doing discovery on this
+                * NPort, let it continue on its own.
+                */
+               switch (ndlp->nlp_state) {
+               case  NLP_STE_PLOGI_ISSUE:
+               case  NLP_STE_ADISC_ISSUE:
+               case  NLP_STE_REG_LOGIN_ISSUE:
+               case  NLP_STE_PRLI_ISSUE:
+               case  NLP_STE_LOGO_ISSUE:
+                       continue;
+               }
+
+
                lpfc_disc_state_machine(vport, ndlp, NULL,
                                        NLP_EVT_DEVICE_RECOVERY);
                lpfc_cancel_retry_delay_tmo(vport, ndlp);
@@ -6272,6 +6479,7 @@ int
 lpfc_els_handle_rscn(struct lpfc_vport *vport)
 {
        struct lpfc_nodelist *ndlp;
+       struct lpfc_hba  *phba = vport->phba;
 
        /* Ignore RSCN if the port is being torn down. */
        if (vport->load_flag & FC_UNLOADING) {
@@ -6300,8 +6508,15 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport)
                 * flush the RSCN.  Otherwise, the outstanding requests
                 * need to complete.
                 */
-               if (lpfc_issue_gidft(vport) > 0)
+               if (phba->cfg_ns_query == LPFC_NS_QUERY_GID_FT) {
+                       if (lpfc_issue_gidft(vport) > 0)
+                               return 1;
+               } else if (phba->cfg_ns_query == LPFC_NS_QUERY_GID_PT) {
+                       if (lpfc_issue_gidpt(vport) > 0)
+                               return 1;
+               } else {
                        return 1;
+               }
        } else {
                /* Nameserver login in question.  Revalidate. */
                if (ndlp) {
@@ -6455,6 +6670,11 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
        port_state = vport->port_state;
        vport->fc_flag |= FC_PT2PT;
        vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+
+       /* Acking an unsol FLOGI.  Count 1 for link bounce
+        * work-around.
+        */
+       vport->rcv_flogi_cnt++;
        spin_unlock_irq(shost->host_lock);
        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
                         "3311 Rcv Flogi PS x%x new PS x%x "
@@ -6472,6 +6692,25 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
 
        memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
 
+       /* Defer ACC response until AFTER we issue a FLOGI */
+       if (!(phba->hba_flag & HBA_FLOGI_ISSUED)) {
+               phba->defer_flogi_acc_rx_id = cmdiocb->iocb.ulpContext;
+               phba->defer_flogi_acc_ox_id =
+                                       cmdiocb->iocb.unsli3.rcvsli3.ox_id;
+
+               vport->fc_myDID = did;
+
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+                                "3344 Deferring FLOGI ACC: rx_id: x%x,"
+                                " ox_id: x%x, hba_flag x%x\n",
+                                phba->defer_flogi_acc_rx_id,
+                                phba->defer_flogi_acc_ox_id, phba->hba_flag);
+
+               phba->defer_flogi_acc_flag = true;
+
+               return 0;
+       }
+
        /* Send back ACC */
        lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, cmdiocb, ndlp, NULL);
 
@@ -6644,11 +6883,11 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 
        mb = &pmb->u.mb;
 
-       ndlp = (struct lpfc_nodelist *) pmb->context2;
-       rxid = (uint16_t) ((unsigned long)(pmb->context1) & 0xffff);
-       oxid = (uint16_t) (((unsigned long)(pmb->context1) >> 16) & 0xffff);
-       pmb->context1 = NULL;
-       pmb->context2 = NULL;
+       ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
+       rxid = (uint16_t)((unsigned long)(pmb->ctx_buf) & 0xffff);
+       oxid = (uint16_t)(((unsigned long)(pmb->ctx_buf) >> 16) & 0xffff);
+       pmb->ctx_buf = NULL;
+       pmb->ctx_ndlp = NULL;
 
        if (mb->mbxStatus) {
                mempool_free(pmb, phba->mbox_mem_pool);
@@ -6732,11 +6971,11 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 
        mb = &pmb->u.mb;
 
-       ndlp = (struct lpfc_nodelist *) pmb->context2;
-       rxid = (uint16_t) ((unsigned long)(pmb->context1) & 0xffff);
-       oxid = (uint16_t) (((unsigned long)(pmb->context1) >> 16) & 0xffff);
-       pmb->context1 = NULL;
-       pmb->context2 = NULL;
+       ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
+       rxid = (uint16_t)((unsigned long)(pmb->ctx_buf) & 0xffff);
+       oxid = (uint16_t)(((unsigned long)(pmb->ctx_buf) >> 16) & 0xffff);
+       pmb->ctx_ndlp = NULL;
+       pmb->ctx_buf = NULL;
 
        if (mb->mbxStatus) {
                mempool_free(pmb, phba->mbox_mem_pool);
@@ -6827,10 +7066,10 @@ lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
        mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
        if (mbox) {
                lpfc_read_lnk_stat(phba, mbox);
-               mbox->context1 = (void *)((unsigned long)
+               mbox->ctx_buf = (void *)((unsigned long)
                        ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) |
                        cmdiocb->iocb.ulpContext)); /* rx_id */
-               mbox->context2 = lpfc_nlp_get(ndlp);
+               mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
                mbox->vport = vport;
                mbox->mbox_cmpl = lpfc_els_rsp_rls_acc;
                if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
@@ -6990,10 +7229,10 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
                mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
                if (mbox) {
                        lpfc_read_lnk_stat(phba, mbox);
-                       mbox->context1 = (void *)((unsigned long)
+                       mbox->ctx_buf = (void *)((unsigned long)
                                ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) |
                                cmdiocb->iocb.ulpContext)); /* rx_id */
-                       mbox->context2 = lpfc_nlp_get(ndlp);
+                       mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
                        mbox->vport = vport;
                        mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
                        if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
@@ -7852,8 +8091,9 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        struct ls_rjt stat;
        uint32_t *payload;
        uint32_t cmd, did, newnode;
-       uint8_t rjt_exp, rjt_err = 0;
+       uint8_t rjt_exp, rjt_err = 0, init_link = 0;
        IOCB_t *icmd = &elsiocb->iocb;
+       LPFC_MBOXQ_t *mbox;
 
        if (!vport || !(elsiocb->context2))
                goto dropit;
@@ -7940,9 +8180,10 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                        cmd, did, vport->port_state, vport->fc_flag,
                        vport->fc_myDID, vport->fc_prevDID);
 
-       /* reject till our FLOGI completes */
+       /* reject till our FLOGI completes or PLOGI assigned DID via PT2PT */
        if ((vport->port_state < LPFC_FABRIC_CFG_LINK) &&
-           (cmd != ELS_CMD_FLOGI)) {
+           (cmd != ELS_CMD_FLOGI) &&
+           !((cmd == ELS_CMD_PLOGI) && (vport->fc_flag & FC_PT2PT))) {
                rjt_err = LSRJT_LOGICAL_BSY;
                rjt_exp = LSEXP_NOTHING_MORE;
                goto lsrjt;
@@ -8002,6 +8243,19 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                        did, vport->port_state, ndlp->nlp_flag);
 
                phba->fc_stat.elsRcvFLOGI++;
+
+               /* If the driver believes fabric discovery is done and is ready,
+                * bounce the link.  There is some descrepancy.
+                */
+               if (vport->port_state >= LPFC_LOCAL_CFG_LINK &&
+                   vport->fc_flag & FC_PT2PT &&
+                   vport->rcv_flogi_cnt >= 1) {
+                       rjt_err = LSRJT_LOGICAL_BSY;
+                       rjt_exp = LSEXP_NOTHING_MORE;
+                       init_link++;
+                       goto lsrjt;
+               }
+
                lpfc_els_rcv_flogi(vport, elsiocb, ndlp);
                if (newnode)
                        lpfc_nlp_put(ndlp);
@@ -8230,6 +8484,27 @@ lsrjt:
 
        lpfc_nlp_put(elsiocb->context1);
        elsiocb->context1 = NULL;
+
+       /* Special case.  Driver received an unsolicited command that
+        * unsupportable given the driver's current state.  Reset the
+        * link and start over.
+        */
+       if (init_link) {
+               mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+               if (!mbox)
+                       return;
+               lpfc_linkdown(phba);
+               lpfc_init_link(phba, mbox,
+                              phba->cfg_topology,
+                              phba->cfg_link_speed);
+               mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
+               mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+               mbox->vport = vport;
+               if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) ==
+                   MBX_NOT_FINISHED)
+                       mempool_free(mbox, phba->mbox_mem_pool);
+       }
+
        return;
 
 dropit:
@@ -8453,7 +8728,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 {
        struct lpfc_vport *vport = pmb->vport;
        struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
-       struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
+       struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
        MAILBOX_t *mb = &pmb->u.mb;
        int rc;
 
@@ -8571,7 +8846,7 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
        if (mbox) {
                lpfc_reg_vpi(vport, mbox);
                mbox->vport = vport;
-               mbox->context2 = lpfc_nlp_get(ndlp);
+               mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
                mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport;
                if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
                    == MBX_NOT_FINISHED) {
@@ -9505,7 +9780,8 @@ lpfc_sli_abts_recover_port(struct lpfc_vport *vport,
                                "rport in state 0x%x\n", ndlp->nlp_state);
                return;
        }
-       lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+       lpfc_printf_log(phba, KERN_ERR,
+                       LOG_ELS | LOG_FCP_ERROR | LOG_NVME_IOERR,
                        "3094 Start rport recovery on shost id 0x%x "
                        "fc_id 0x%06x vpi 0x%x rpi 0x%x state 0x%x "
                        "flags 0x%x\n",
@@ -9518,8 +9794,8 @@ lpfc_sli_abts_recover_port(struct lpfc_vport *vport,
         */
        spin_lock_irqsave(shost->host_lock, flags);
        ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
+       ndlp->nlp_flag |= NLP_ISSUE_LOGO;
        spin_unlock_irqrestore(shost->host_lock, flags);
-       lpfc_issue_els_logo(vport, ndlp, 0);
-       lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
+       lpfc_unreg_rpi(vport, ndlp);
 }