brintos

brintos / linux-shallow public Read only

0
0
Text · 94.1 KiB · 4574716 Raw
3186 lines · c
1/*******************************************************************2 * This file is part of the Emulex Linux Device Driver for         *3 * Fibre Channel Host Bus Adapters.                                *4 * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *5 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.     *6 * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *7 * EMULEX and SLI are trademarks of Emulex.                        *8 * www.broadcom.com                                                *9 * Portions Copyright (C) 2004-2005 Christoph Hellwig              *10 *                                                                 *11 * This program is free software; you can redistribute it and/or   *12 * modify it under the terms of version 2 of the GNU General       *13 * Public License as published by the Free Software Foundation.    *14 * This program is distributed in the hope that it will be useful. *15 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *16 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *17 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *18 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *19 * TO BE LEGALLY INVALID.  See the GNU General Public License for  *20 * more details, a copy of which can be found in the file COPYING  *21 * included with this package.                                     *22 *******************************************************************/23 24#include <linux/blkdev.h>25#include <linux/pci.h>26#include <linux/slab.h>27#include <linux/interrupt.h>28 29#include <scsi/scsi.h>30#include <scsi/scsi_device.h>31#include <scsi/scsi_host.h>32#include <scsi/scsi_transport_fc.h>33#include <scsi/fc/fc_fs.h>34 35#include "lpfc_hw4.h"36#include "lpfc_hw.h"37#include "lpfc_sli.h"38#include "lpfc_sli4.h"39#include "lpfc_nl.h"40#include "lpfc_disc.h"41#include "lpfc.h"42#include "lpfc_scsi.h"43#include "lpfc_nvme.h"44#include "lpfc_logmsg.h"45#include "lpfc_crtn.h"46#include "lpfc_vport.h"47#include "lpfc_debugfs.h"48 49 50/* Called to clear RSCN discovery flags when driver is unloading. */51static bool52lpfc_check_unload_and_clr_rscn(unsigned long *fc_flag)53{54	/* If unloading, then clear the FC_RSCN_DEFERRED flag */55	if (test_bit(FC_UNLOADING, fc_flag)) {56		clear_bit(FC_RSCN_DEFERRED, fc_flag);57		return false;58	}59	return test_bit(FC_RSCN_DEFERRED, fc_flag);60}61 62/* Called to verify a rcv'ed ADISC was intended for us. */63static int64lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,65		 struct lpfc_name *nn, struct lpfc_name *pn)66{67	/* First, we MUST have a RPI registered */68	if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED))69		return 0;70 71	/* Compare the ADISC rsp WWNN / WWPN matches our internal node72	 * table entry for that node.73	 */74	if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)))75		return 0;76 77	if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)))78		return 0;79 80	/* we match, return success */81	return 1;82}83 84int85lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,86		 struct serv_parm *sp, uint32_t class, int flogi)87{88	volatile struct serv_parm *hsp = &vport->fc_sparam;89	uint16_t hsp_value, ssp_value = 0;90 91	/*92	 * The receive data field size and buffer-to-buffer receive data field93	 * size entries are 16 bits but are represented as two 8-bit fields in94	 * the driver data structure to account for rsvd bits and other control95	 * bits.  Reconstruct and compare the fields as a 16-bit values before96	 * correcting the byte values.97	 */98	if (sp->cls1.classValid) {99		if (!flogi) {100			hsp_value = ((hsp->cls1.rcvDataSizeMsb << 8) |101				     hsp->cls1.rcvDataSizeLsb);102			ssp_value = ((sp->cls1.rcvDataSizeMsb << 8) |103				     sp->cls1.rcvDataSizeLsb);104			if (!ssp_value)105				goto bad_service_param;106			if (ssp_value > hsp_value) {107				sp->cls1.rcvDataSizeLsb =108					hsp->cls1.rcvDataSizeLsb;109				sp->cls1.rcvDataSizeMsb =110					hsp->cls1.rcvDataSizeMsb;111			}112		}113	} else if (class == CLASS1)114		goto bad_service_param;115	if (sp->cls2.classValid) {116		if (!flogi) {117			hsp_value = ((hsp->cls2.rcvDataSizeMsb << 8) |118				     hsp->cls2.rcvDataSizeLsb);119			ssp_value = ((sp->cls2.rcvDataSizeMsb << 8) |120				     sp->cls2.rcvDataSizeLsb);121			if (!ssp_value)122				goto bad_service_param;123			if (ssp_value > hsp_value) {124				sp->cls2.rcvDataSizeLsb =125					hsp->cls2.rcvDataSizeLsb;126				sp->cls2.rcvDataSizeMsb =127					hsp->cls2.rcvDataSizeMsb;128			}129		}130	} else if (class == CLASS2)131		goto bad_service_param;132	if (sp->cls3.classValid) {133		if (!flogi) {134			hsp_value = ((hsp->cls3.rcvDataSizeMsb << 8) |135				     hsp->cls3.rcvDataSizeLsb);136			ssp_value = ((sp->cls3.rcvDataSizeMsb << 8) |137				     sp->cls3.rcvDataSizeLsb);138			if (!ssp_value)139				goto bad_service_param;140			if (ssp_value > hsp_value) {141				sp->cls3.rcvDataSizeLsb =142					hsp->cls3.rcvDataSizeLsb;143				sp->cls3.rcvDataSizeMsb =144					hsp->cls3.rcvDataSizeMsb;145			}146		}147	} else if (class == CLASS3)148		goto bad_service_param;149 150	/*151	 * Preserve the upper four bits of the MSB from the PLOGI response.152	 * These bits contain the Buffer-to-Buffer State Change Number153	 * from the target and need to be passed to the FW.154	 */155	hsp_value = (hsp->cmn.bbRcvSizeMsb << 8) | hsp->cmn.bbRcvSizeLsb;156	ssp_value = (sp->cmn.bbRcvSizeMsb << 8) | sp->cmn.bbRcvSizeLsb;157	if (ssp_value > hsp_value) {158		sp->cmn.bbRcvSizeLsb = hsp->cmn.bbRcvSizeLsb;159		sp->cmn.bbRcvSizeMsb = (sp->cmn.bbRcvSizeMsb & 0xF0) |160				       (hsp->cmn.bbRcvSizeMsb & 0x0F);161	}162 163	memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));164	memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name));165	return 1;166bad_service_param:167	lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,168			 "0207 Device %x "169			 "(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x) sent "170			 "invalid service parameters.  Ignoring device.\n",171			 ndlp->nlp_DID,172			 sp->nodeName.u.wwn[0], sp->nodeName.u.wwn[1],173			 sp->nodeName.u.wwn[2], sp->nodeName.u.wwn[3],174			 sp->nodeName.u.wwn[4], sp->nodeName.u.wwn[5],175			 sp->nodeName.u.wwn[6], sp->nodeName.u.wwn[7]);176	return 0;177}178 179static void *180lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,181			struct lpfc_iocbq *rspiocb)182{183	struct lpfc_dmabuf *pcmd, *prsp;184	uint32_t *lp;185	void     *ptr = NULL;186	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);187 188	pcmd = cmdiocb->cmd_dmabuf;189 190	/* For lpfc_els_abort, cmd_dmabuf could be zero'ed to delay191	 * freeing associated memory till after ABTS completes.192	 */193	if (pcmd) {194		prsp =  list_get_first(&pcmd->list, struct lpfc_dmabuf,195				       list);196		if (prsp) {197			lp = (uint32_t *) prsp->virt;198			ptr = (void *)((uint8_t *)lp + sizeof(uint32_t));199		}200	} else {201		/* Force ulp_status error since we are returning NULL ptr */202		if (!(ulp_status)) {203			if (phba->sli_rev == LPFC_SLI_REV4) {204				bf_set(lpfc_wcqe_c_status, &rspiocb->wcqe_cmpl,205				       IOSTAT_LOCAL_REJECT);206				rspiocb->wcqe_cmpl.parameter = IOERR_SLI_ABORTED;207			} else {208				rspiocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT;209				rspiocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED;210			}211		}212		ptr = NULL;213	}214	return ptr;215}216 217 218 219/*220 * Free resources / clean up outstanding I/Os221 * associated with a LPFC_NODELIST entry. This222 * routine effectively results in a "software abort".223 */224void225lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)226{227	LIST_HEAD(abort_list);228	LIST_HEAD(drv_cmpl_list);229	struct lpfc_sli_ring *pring;230	struct lpfc_iocbq *iocb, *next_iocb;231	int retval = 0;232 233	pring = lpfc_phba_elsring(phba);234 235	/* In case of error recovery path, we might have a NULL pring here */236	if (unlikely(!pring))237		return;238 239	/* Abort outstanding I/O on NPort <nlp_DID> */240	lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_DISCOVERY,241			 "2819 Abort outstanding I/O on NPort x%x "242			 "Data: x%x x%x x%x\n",243			 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,244			 ndlp->nlp_rpi);245	/* Clean up all fabric IOs first.*/246	lpfc_fabric_abort_nport(ndlp);247 248	/*249	 * Lock the ELS ring txcmplq for SLI3/SLI4 and build a local list250	 * of all ELS IOs that need an ABTS.  The IOs need to stay on the251	 * txcmplq so that the abort operation completes them successfully.252	 */253	spin_lock_irq(&phba->hbalock);254	if (phba->sli_rev == LPFC_SLI_REV4)255		spin_lock(&pring->ring_lock);256	list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {257	/* Add to abort_list on on NDLP match. */258		if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))259			list_add_tail(&iocb->dlist, &abort_list);260	}261	if (phba->sli_rev == LPFC_SLI_REV4)262		spin_unlock(&pring->ring_lock);263	spin_unlock_irq(&phba->hbalock);264 265	/* Abort the targeted IOs and remove them from the abort list. */266	list_for_each_entry_safe(iocb, next_iocb, &abort_list, dlist) {267		spin_lock_irq(&phba->hbalock);268		list_del_init(&iocb->dlist);269		retval = lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);270		spin_unlock_irq(&phba->hbalock);271 272		if (retval && test_bit(FC_UNLOADING, &phba->pport->load_flag)) {273			list_del_init(&iocb->list);274			list_add_tail(&iocb->list, &drv_cmpl_list);275		}276	}277 278	lpfc_sli_cancel_iocbs(phba, &drv_cmpl_list, IOSTAT_LOCAL_REJECT,279			      IOERR_SLI_ABORTED);280 281	/* Make sure HBA is alive */282	lpfc_issue_hb_tmo(phba);283 284	INIT_LIST_HEAD(&abort_list);285 286	/* Now process the txq */287	spin_lock_irq(&phba->hbalock);288	if (phba->sli_rev == LPFC_SLI_REV4)289		spin_lock(&pring->ring_lock);290 291	list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {292		/* Check to see if iocb matches the nport we are looking for */293		if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) {294			list_del_init(&iocb->list);295			list_add_tail(&iocb->list, &abort_list);296		}297	}298 299	if (phba->sli_rev == LPFC_SLI_REV4)300		spin_unlock(&pring->ring_lock);301	spin_unlock_irq(&phba->hbalock);302 303	/* Cancel all the IOCBs from the completions list */304	lpfc_sli_cancel_iocbs(phba, &abort_list,305			      IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED);306 307	lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);308}309 310/* lpfc_defer_plogi_acc - Issue PLOGI ACC after reg_login completes311 * @phba: pointer to lpfc hba data structure.312 * @login_mbox: pointer to REG_RPI mailbox object313 *314 * The ACC for a rcv'ed PLOGI is deferred until AFTER the REG_RPI completes315 */316static void317lpfc_defer_plogi_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *login_mbox)318{319	struct lpfc_iocbq *save_iocb;320	struct lpfc_nodelist *ndlp;321	MAILBOX_t *mb = &login_mbox->u.mb;322 323	int rc;324 325	ndlp = login_mbox->ctx_ndlp;326	save_iocb = login_mbox->ctx_u.save_iocb;327 328	if (mb->mbxStatus == MBX_SUCCESS) {329		/* Now that REG_RPI completed successfully,330		 * we can now proceed with sending the PLOGI ACC.331		 */332		rc = lpfc_els_rsp_acc(login_mbox->vport, ELS_CMD_PLOGI,333				      save_iocb, ndlp, NULL);334		if (rc) {335			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,336					"4576 PLOGI ACC fails pt2pt discovery: "337					"DID %x Data: %x\n", ndlp->nlp_DID, rc);338		}339	}340 341	/* Now process the REG_RPI cmpl */342	lpfc_mbx_cmpl_reg_login(phba, login_mbox);343	ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN;344	kfree(save_iocb);345}346 347static int348lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,349	       struct lpfc_iocbq *cmdiocb)350{351	struct lpfc_hba    *phba = vport->phba;352	struct lpfc_dmabuf *pcmd;353	uint64_t nlp_portwwn = 0;354	uint32_t *lp;355	union lpfc_wqe128 *wqe;356	IOCB_t *icmd;357	struct serv_parm *sp;358	uint32_t ed_tov;359	LPFC_MBOXQ_t *link_mbox;360	LPFC_MBOXQ_t *login_mbox;361	struct lpfc_iocbq *save_iocb;362	struct ls_rjt stat;363	uint32_t vid, flag;364	int rc;365	u32 remote_did;366 367	memset(&stat, 0, sizeof (struct ls_rjt));368	pcmd = cmdiocb->cmd_dmabuf;369	lp = (uint32_t *) pcmd->virt;370	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));371	if (wwn_to_u64(sp->portName.u.wwn) == 0) {372		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,373				 "0140 PLOGI Reject: invalid pname\n");374		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;375		stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_PNAME;376		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,377			NULL);378		return 0;379	}380	if (wwn_to_u64(sp->nodeName.u.wwn) == 0) {381		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,382				 "0141 PLOGI Reject: invalid nname\n");383		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;384		stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_NNAME;385		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,386			NULL);387		return 0;388	}389 390	nlp_portwwn = wwn_to_u64(ndlp->nlp_portname.u.wwn);391	if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0) == 0)) {392		/* Reject this request because invalid parameters */393		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;394		stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;395		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,396			NULL);397		return 0;398	}399 400	if (phba->sli_rev == LPFC_SLI_REV4)401		wqe = &cmdiocb->wqe;402	else403		icmd = &cmdiocb->iocb;404 405	/* PLOGI chkparm OK */406	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,407			 "0114 PLOGI chkparm OK Data: x%x x%x x%x "408			 "x%x x%x x%lx\n",409			 ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag,410			 ndlp->nlp_rpi, vport->port_state,411			 vport->fc_flag);412 413	if (vport->cfg_fcp_class == 2 && sp->cls2.classValid)414		ndlp->nlp_fcp_info |= CLASS2;415	else416		ndlp->nlp_fcp_info |= CLASS3;417 418	ndlp->nlp_class_sup = 0;419	if (sp->cls1.classValid)420		ndlp->nlp_class_sup |= FC_COS_CLASS1;421	if (sp->cls2.classValid)422		ndlp->nlp_class_sup |= FC_COS_CLASS2;423	if (sp->cls3.classValid)424		ndlp->nlp_class_sup |= FC_COS_CLASS3;425	if (sp->cls4.classValid)426		ndlp->nlp_class_sup |= FC_COS_CLASS4;427	ndlp->nlp_maxframe =428		((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;429	/* if already logged in, do implicit logout */430	switch (ndlp->nlp_state) {431	case  NLP_STE_NPR_NODE:432		if (!(ndlp->nlp_flag & NLP_NPR_ADISC))433			break;434		fallthrough;435	case  NLP_STE_REG_LOGIN_ISSUE:436	case  NLP_STE_PRLI_ISSUE:437	case  NLP_STE_UNMAPPED_NODE:438	case  NLP_STE_MAPPED_NODE:439		/* For initiators, lpfc_plogi_confirm_nport skips fabric did.440		 * For target mode, execute implicit logo.441		 * Fabric nodes go into NPR.442		 */443		if (!(ndlp->nlp_type & NLP_FABRIC) &&444		    !(phba->nvmet_support)) {445			/* Clear ndlp info, since follow up PRLI may have446			 * updated ndlp information447			 */448			ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);449			ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);450			ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;451			ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER;452			ndlp->nlp_flag &= ~NLP_FIRSTBURST;453 454			lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,455					 ndlp, NULL);456			return 1;457		}458		if (nlp_portwwn != 0 &&459		    nlp_portwwn != wwn_to_u64(sp->portName.u.wwn))460			lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,461					 "0143 PLOGI recv'd from DID: x%x "462					 "WWPN changed: old %llx new %llx\n",463					 ndlp->nlp_DID,464					 (unsigned long long)nlp_portwwn,465					 (unsigned long long)466					 wwn_to_u64(sp->portName.u.wwn));467 468		/* Notify transport of connectivity loss to trigger cleanup. */469		if (phba->nvmet_support &&470		    ndlp->nlp_state == NLP_STE_UNMAPPED_NODE)471			lpfc_nvmet_invalidate_host(phba, ndlp);472 473		ndlp->nlp_prev_state = ndlp->nlp_state;474		/* rport needs to be unregistered first */475		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);476		break;477	}478 479	ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);480	ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);481	ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;482	ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER;483	ndlp->nlp_flag &= ~NLP_FIRSTBURST;484 485	login_mbox = NULL;486	link_mbox = NULL;487	save_iocb = NULL;488 489	/* Check for Nport to NPort pt2pt protocol */490	if (test_bit(FC_PT2PT, &vport->fc_flag) &&491	    !test_bit(FC_PT2PT_PLOGI, &vport->fc_flag)) {492		/* rcv'ed PLOGI decides what our NPortId will be */493		if (phba->sli_rev == LPFC_SLI_REV4) {494			vport->fc_myDID = bf_get(els_rsp64_sid,495						 &cmdiocb->wqe.xmit_els_rsp);496		} else {497			vport->fc_myDID = icmd->un.rcvels.parmRo;498		}499 500		/* If there is an outstanding FLOGI, abort it now.501		 * The remote NPort is not going to ACC our FLOGI502		 * if its already issuing a PLOGI for pt2pt mode.503		 * This indicates our FLOGI was dropped; however, we504		 * must have ACCed the remote NPorts FLOGI to us505		 * to make it here.506		 */507		if (test_bit(HBA_FLOGI_OUTSTANDING, &phba->hba_flag))508			lpfc_els_abort_flogi(phba);509 510		ed_tov = be32_to_cpu(sp->cmn.e_d_tov);511		if (sp->cmn.edtovResolution) {512			/* E_D_TOV ticks are in nanoseconds */513			ed_tov = (phba->fc_edtov + 999999) / 1000000;514		}515 516		/*517		 * For pt-to-pt, use the larger EDTOV518		 * RATOV = 2 * EDTOV519		 */520		if (ed_tov > phba->fc_edtov)521			phba->fc_edtov = ed_tov;522		phba->fc_ratov = (2 * phba->fc_edtov) / 1000;523 524		memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));525 526		/* Issue CONFIG_LINK for SLI3 or REG_VFI for SLI4,527		 * to account for updated TOV's / parameters528		 */529		if (phba->sli_rev == LPFC_SLI_REV4)530			lpfc_issue_reg_vfi(vport);531		else {532			link_mbox = mempool_alloc(phba->mbox_mem_pool,533						  GFP_KERNEL);534			if (!link_mbox)535				goto out;536			lpfc_config_link(phba, link_mbox);537			link_mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;538			link_mbox->vport = vport;539 540			/* The default completion handling for CONFIG_LINK541			 * does not require the ndlp so no reference is needed.542			 */543			link_mbox->ctx_ndlp = ndlp;544 545			rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT);546			if (rc == MBX_NOT_FINISHED) {547				mempool_free(link_mbox, phba->mbox_mem_pool);548				goto out;549			}550		}551 552		lpfc_can_disctmo(vport);553	}554 555	ndlp->nlp_flag &= ~NLP_SUPPRESS_RSP;556	if ((phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) &&557	    sp->cmn.valid_vendor_ver_level) {558		vid = be32_to_cpu(sp->un.vv.vid);559		flag = be32_to_cpu(sp->un.vv.flags);560		if ((vid == LPFC_VV_EMLX_ID) && (flag & LPFC_VV_SUPPRESS_RSP))561			ndlp->nlp_flag |= NLP_SUPPRESS_RSP;562	}563 564	login_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);565	if (!login_mbox)566		goto out;567 568	save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);569	if (!save_iocb)570		goto out;571 572	/* Save info from cmd IOCB to be used in rsp after all mbox completes */573	memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb,574	       sizeof(struct lpfc_iocbq));575 576	/* Registering an existing RPI behaves differently for SLI3 vs SLI4 */577	if (phba->sli_rev == LPFC_SLI_REV4)578		lpfc_unreg_rpi(vport, ndlp);579 580	/* Issue REG_LOGIN first, before ACCing the PLOGI, thus we will581	 * always be deferring the ACC.582	 */583	if (phba->sli_rev == LPFC_SLI_REV4)584		remote_did = bf_get(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest);585	else586		remote_did = icmd->un.rcvels.remoteID;587	rc = lpfc_reg_rpi(phba, vport->vpi, remote_did,588			    (uint8_t *)sp, login_mbox, ndlp->nlp_rpi);589	if (rc)590		goto out;591 592	login_mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;593	login_mbox->vport = vport;594 595	/*596	 * If there is an outstanding PLOGI issued, abort it before597	 * sending ACC rsp for received PLOGI. If pending plogi598	 * is not canceled here, the plogi will be rejected by599	 * remote port and will be retried. On a configuration with600	 * single discovery thread, this will cause a huge delay in601	 * discovery. Also this will cause multiple state machines602	 * running in parallel for this node.603	 * This only applies to a fabric environment.604	 */605	if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) &&606	    test_bit(FC_FABRIC, &vport->fc_flag)) {607		/* software abort outstanding PLOGI */608		lpfc_els_abort(phba, ndlp);609	}610 611	if ((vport->port_type == LPFC_NPIV_PORT &&612	     vport->cfg_restrict_login)) {613 614		/* no deferred ACC */615		kfree(save_iocb);616 617		/* This is an NPIV SLI4 instance that does not need to register618		 * a default RPI.619		 */620		if (phba->sli_rev == LPFC_SLI_REV4) {621			lpfc_mbox_rsrc_cleanup(phba, login_mbox,622					       MBOX_THD_UNLOCKED);623			login_mbox = NULL;624		} else {625			/* In order to preserve RPIs, we want to cleanup626			 * the default RPI the firmware created to rcv627			 * this ELS request. The only way to do this is628			 * to register, then unregister the RPI.629			 */630			spin_lock_irq(&ndlp->lock);631			ndlp->nlp_flag |= (NLP_RM_DFLT_RPI | NLP_ACC_REGLOGIN |632					   NLP_RCV_PLOGI);633			spin_unlock_irq(&ndlp->lock);634		}635 636		stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD;637		stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;638		rc = lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,639					 ndlp, login_mbox);640		if (rc && login_mbox)641			lpfc_mbox_rsrc_cleanup(phba, login_mbox,642					       MBOX_THD_UNLOCKED);643		return 1;644	}645 646	/* So the order here should be:647	 * SLI3 pt2pt648	 *   Issue CONFIG_LINK mbox649	 *   CONFIG_LINK cmpl650	 * SLI4 pt2pt651	 *   Issue REG_VFI mbox652	 *   REG_VFI cmpl653	 * SLI4654	 *   Issue UNREG RPI mbx655	 *   UNREG RPI cmpl656	 * Issue REG_RPI mbox657	 * REG RPI cmpl658	 * Issue PLOGI ACC659	 * PLOGI ACC cmpl660	 */661	login_mbox->mbox_cmpl = lpfc_defer_plogi_acc;662	login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp);663	if (!login_mbox->ctx_ndlp)664		goto out;665 666	login_mbox->ctx_u.save_iocb = save_iocb; /* For PLOGI ACC */667 668	spin_lock_irq(&ndlp->lock);669	ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);670	spin_unlock_irq(&ndlp->lock);671 672	/* Start the ball rolling by issuing REG_LOGIN here */673	rc = lpfc_sli_issue_mbox(phba, login_mbox, MBX_NOWAIT);674	if (rc == MBX_NOT_FINISHED) {675		lpfc_nlp_put(ndlp);676		goto out;677	}678	lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE);679 680	return 1;681out:682	kfree(save_iocb);683	if (login_mbox)684		mempool_free(login_mbox, phba->mbox_mem_pool);685 686	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;687	stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE;688	lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);689	return 0;690}691 692/**693 * lpfc_mbx_cmpl_resume_rpi - Resume RPI completion routine694 * @phba: pointer to lpfc hba data structure.695 * @mboxq: pointer to mailbox object696 *697 * This routine is invoked to issue a completion to a rcv'ed698 * ADISC or PDISC after the paused RPI has been resumed.699 **/700static void701lpfc_mbx_cmpl_resume_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)702{703	struct lpfc_vport *vport;704	struct lpfc_iocbq *elsiocb;705	struct lpfc_nodelist *ndlp;706	uint32_t cmd;707 708	elsiocb = mboxq->ctx_u.save_iocb;709	ndlp = mboxq->ctx_ndlp;710	vport = mboxq->vport;711	cmd = elsiocb->drvrTimeout;712 713	if (cmd == ELS_CMD_ADISC) {714		lpfc_els_rsp_adisc_acc(vport, elsiocb, ndlp);715	} else {716		lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, elsiocb,717			ndlp, NULL);718	}719 720	/* This nlp_put pairs with lpfc_sli4_resume_rpi */721	lpfc_nlp_put(ndlp);722 723	kfree(elsiocb);724	mempool_free(mboxq, phba->mbox_mem_pool);725}726 727static int728lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,729		struct lpfc_iocbq *cmdiocb)730{731	struct lpfc_hba *phba = vport->phba;732	struct lpfc_iocbq  *elsiocb;733	struct lpfc_dmabuf *pcmd;734	struct serv_parm   *sp;735	struct lpfc_name   *pnn, *ppn;736	struct ls_rjt stat;737	ADISC *ap;738	uint32_t *lp;739	uint32_t cmd;740 741	pcmd = cmdiocb->cmd_dmabuf;742	lp = (uint32_t *) pcmd->virt;743 744	cmd = *lp++;745	if (cmd == ELS_CMD_ADISC) {746		ap = (ADISC *) lp;747		pnn = (struct lpfc_name *) & ap->nodeName;748		ppn = (struct lpfc_name *) & ap->portName;749	} else {750		sp = (struct serv_parm *) lp;751		pnn = (struct lpfc_name *) & sp->nodeName;752		ppn = (struct lpfc_name *) & sp->portName;753	}754 755	if (get_job_ulpstatus(phba, cmdiocb) == 0 &&756	    lpfc_check_adisc(vport, ndlp, pnn, ppn)) {757 758		/*759		 * As soon as  we send ACC, the remote NPort can760		 * start sending us data. Thus, for SLI4 we must761		 * resume the RPI before the ACC goes out.762		 */763		if (vport->phba->sli_rev == LPFC_SLI_REV4) {764			elsiocb = kmalloc(sizeof(struct lpfc_iocbq),765				GFP_KERNEL);766			if (elsiocb) {767				/* Save info from cmd IOCB used in rsp */768				memcpy((uint8_t *)elsiocb, (uint8_t *)cmdiocb,769					sizeof(struct lpfc_iocbq));770 771				/* Save the ELS cmd */772				elsiocb->drvrTimeout = cmd;773 774				if (lpfc_sli4_resume_rpi(ndlp,775						lpfc_mbx_cmpl_resume_rpi,776						elsiocb))777					kfree(elsiocb);778				goto out;779			}780		}781 782		if (cmd == ELS_CMD_ADISC) {783			lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp);784		} else {785			lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,786				ndlp, NULL);787		}788out:789		/* If we are authenticated, move to the proper state.790		 * It is possible an ADISC arrived and the remote nport791		 * is already in MAPPED or UNMAPPED state.  Catch this792		 * condition and don't set the nlp_state again because793		 * it causes an unnecessary transport unregister/register.794		 *795		 * Nodes marked for ADISC will move MAPPED or UNMAPPED state796		 * after issuing ADISC797		 */798		if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) {799			if ((ndlp->nlp_state != NLP_STE_MAPPED_NODE) &&800			    !(ndlp->nlp_flag & NLP_NPR_ADISC))801				lpfc_nlp_set_state(vport, ndlp,802						   NLP_STE_MAPPED_NODE);803		}804 805		return 1;806	}807	/* Reject this request because invalid parameters */808	stat.un.b.lsRjtRsvd0 = 0;809	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;810	stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;811	stat.un.b.vendorUnique = 0;812	lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);813 814	/* 1 sec timeout */815	mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000));816 817	spin_lock_irq(&ndlp->lock);818	ndlp->nlp_flag |= NLP_DELAY_TMO;819	spin_unlock_irq(&ndlp->lock);820	ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;821	ndlp->nlp_prev_state = ndlp->nlp_state;822	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);823	return 0;824}825 826static int827lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,828	      struct lpfc_iocbq *cmdiocb, uint32_t els_cmd)829{830	struct lpfc_hba    *phba = vport->phba;831	struct lpfc_vport **vports;832	int i, active_vlink_present = 0 ;833 834	/* Put ndlp in NPR state with 1 sec timeout for plogi, ACC logo */835	/* Only call LOGO ACC for first LOGO, this avoids sending unnecessary836	 * PLOGIs during LOGO storms from a device.837	 */838	spin_lock_irq(&ndlp->lock);839	ndlp->nlp_flag |= NLP_LOGO_ACC;840	spin_unlock_irq(&ndlp->lock);841	if (els_cmd == ELS_CMD_PRLO)842		lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);843	else844		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);845 846	/* This clause allows the initiator to ACC the LOGO back to the847	 * Fabric Domain Controller.  It does deliberately skip all other848	 * steps because some fabrics send RDP requests after logging out849	 * from the initiator.850	 */851	if (ndlp->nlp_type & NLP_FABRIC &&852	    ((ndlp->nlp_DID & WELL_KNOWN_DID_MASK) != WELL_KNOWN_DID_MASK))853		return 0;854 855	/* Notify transport of connectivity loss to trigger cleanup. */856	if (phba->nvmet_support &&857	    ndlp->nlp_state == NLP_STE_UNMAPPED_NODE)858		lpfc_nvmet_invalidate_host(phba, ndlp);859 860	if (ndlp->nlp_DID == Fabric_DID) {861		if (vport->port_state <= LPFC_FDISC ||862		    test_bit(FC_PT2PT, &vport->fc_flag))863			goto out;864		lpfc_linkdown_port(vport);865		set_bit(FC_VPORT_LOGO_RCVD, &vport->fc_flag);866		vports = lpfc_create_vport_work_array(phba);867		if (vports) {868			for (i = 0; i <= phba->max_vports && vports[i] != NULL;869					i++) {870				if (!test_bit(FC_VPORT_LOGO_RCVD,871					      &vports[i]->fc_flag) &&872				    vports[i]->port_state > LPFC_FDISC) {873					active_vlink_present = 1;874					break;875				}876			}877			lpfc_destroy_vport_work_array(phba, vports);878		}879 880		/*881		 * Don't re-instantiate if vport is marked for deletion.882		 * If we are here first then vport_delete is going to wait883		 * for discovery to complete.884		 */885		if (!test_bit(FC_UNLOADING, &vport->load_flag) &&886		    active_vlink_present) {887			/*888			 * If there are other active VLinks present,889			 * re-instantiate the Vlink using FDISC.890			 */891			mod_timer(&ndlp->nlp_delayfunc,892				  jiffies + msecs_to_jiffies(1000));893			spin_lock_irq(&ndlp->lock);894			ndlp->nlp_flag |= NLP_DELAY_TMO;895			spin_unlock_irq(&ndlp->lock);896			ndlp->nlp_last_elscmd = ELS_CMD_FDISC;897			vport->port_state = LPFC_FDISC;898		} else {899			clear_bit(FC_LOGO_RCVD_DID_CHNG, &phba->pport->fc_flag);900			lpfc_retry_pport_discovery(phba);901		}902	} else {903		lpfc_printf_vlog(vport, KERN_INFO,904				 LOG_NODE | LOG_ELS | LOG_DISCOVERY,905				 "3203 LOGO recover nport x%06x state x%x "906				 "ntype x%x fc_flag x%lx\n",907				 ndlp->nlp_DID, ndlp->nlp_state,908				 ndlp->nlp_type, vport->fc_flag);909 910		/* Special cases for rports that recover post LOGO. */911		if ((!(ndlp->nlp_type == NLP_FABRIC) &&912		     (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET) ||913		      test_bit(FC_PT2PT, &vport->fc_flag))) ||914		    (ndlp->nlp_state >= NLP_STE_ADISC_ISSUE ||915		     ndlp->nlp_state <= NLP_STE_PRLI_ISSUE)) {916			mod_timer(&ndlp->nlp_delayfunc,917				  jiffies + msecs_to_jiffies(1000 * 1));918			spin_lock_irq(&ndlp->lock);919			ndlp->nlp_flag |= NLP_DELAY_TMO;920			spin_unlock_irq(&ndlp->lock);921			ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;922			lpfc_printf_vlog(vport, KERN_INFO,923					 LOG_NODE | LOG_ELS | LOG_DISCOVERY,924					 "3204 Start nlpdelay on DID x%06x "925					 "nflag x%x lastels x%x ref cnt %u",926					 ndlp->nlp_DID, ndlp->nlp_flag,927					 ndlp->nlp_last_elscmd,928					 kref_read(&ndlp->kref));929		}930	}931out:932	/* Unregister from backend, could have been skipped due to ADISC */933	lpfc_nlp_unreg_node(vport, ndlp);934 935	ndlp->nlp_prev_state = ndlp->nlp_state;936	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);937 938	spin_lock_irq(&ndlp->lock);939	ndlp->nlp_flag &= ~NLP_NPR_ADISC;940	spin_unlock_irq(&ndlp->lock);941	/* The driver has to wait until the ACC completes before it continues942	 * processing the LOGO.  The action will resume in943	 * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an944	 * unreg_login, the driver waits so the ACC does not get aborted.945	 */946	return 0;947}948 949static uint32_t950lpfc_rcv_prli_support_check(struct lpfc_vport *vport,951			    struct lpfc_nodelist *ndlp,952			    struct lpfc_iocbq *cmdiocb)953{954	struct ls_rjt stat;955	uint32_t *payload;956	uint32_t cmd;957	PRLI *npr;958 959	payload = cmdiocb->cmd_dmabuf->virt;960	cmd = *payload;961	npr = (PRLI *)((uint8_t *)payload + sizeof(uint32_t));962 963	if (vport->phba->nvmet_support) {964		/* Must be a NVME PRLI */965		if (cmd == ELS_CMD_PRLI)966			goto out;967	} else {968		/* Initiator mode. */969		if (!vport->nvmei_support && (cmd == ELS_CMD_NVMEPRLI))970			goto out;971 972		/* NPIV ports will RJT initiator only functions */973		if (vport->port_type == LPFC_NPIV_PORT &&974		    npr->initiatorFunc && !npr->targetFunc)975			goto out;976	}977	return 1;978out:979	lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY,980			 "6115 Rcv PRLI (%x) check failed: ndlp rpi %d "981			 "state x%x flags x%x port_type: x%x "982			 "npr->initfcn: x%x npr->tgtfcn: x%x\n",983			 cmd, ndlp->nlp_rpi, ndlp->nlp_state,984			 ndlp->nlp_flag, vport->port_type,985			 npr->initiatorFunc, npr->targetFunc);986	memset(&stat, 0, sizeof(struct ls_rjt));987	stat.un.b.lsRjtRsnCode = LSRJT_CMD_UNSUPPORTED;988	stat.un.b.lsRjtRsnCodeExp = LSEXP_REQ_UNSUPPORTED;989	lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,990			    ndlp, NULL);991	return 0;992}993 994static void995lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,996	      struct lpfc_iocbq *cmdiocb)997{998	struct lpfc_hba  *phba = vport->phba;999	struct lpfc_dmabuf *pcmd;1000	uint32_t *lp;1001	PRLI *npr;1002	struct fc_rport *rport = ndlp->rport;1003	u32 roles;1004 1005	pcmd = cmdiocb->cmd_dmabuf;1006	lp = (uint32_t *)pcmd->virt;1007	npr = (PRLI *)((uint8_t *)lp + sizeof(uint32_t));1008 1009	if ((npr->prliType == PRLI_FCP_TYPE) ||1010	    (npr->prliType == PRLI_NVME_TYPE)) {1011		if (npr->initiatorFunc) {1012			if (npr->prliType == PRLI_FCP_TYPE)1013				ndlp->nlp_type |= NLP_FCP_INITIATOR;1014			if (npr->prliType == PRLI_NVME_TYPE)1015				ndlp->nlp_type |= NLP_NVME_INITIATOR;1016		}1017		if (npr->targetFunc) {1018			if (npr->prliType == PRLI_FCP_TYPE)1019				ndlp->nlp_type |= NLP_FCP_TARGET;1020			if (npr->prliType == PRLI_NVME_TYPE)1021				ndlp->nlp_type |= NLP_NVME_TARGET;1022			if (npr->writeXferRdyDis)1023				ndlp->nlp_flag |= NLP_FIRSTBURST;1024		}1025		if (npr->Retry && ndlp->nlp_type &1026					(NLP_FCP_INITIATOR | NLP_FCP_TARGET))1027			ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;1028 1029		if (npr->Retry && phba->nsler &&1030		    ndlp->nlp_type & (NLP_NVME_INITIATOR | NLP_NVME_TARGET))1031			ndlp->nlp_nvme_info |= NLP_NVME_NSLER;1032 1033 1034		/* If this driver is in nvme target mode, set the ndlp's fc41035		 * type to NVME provided the PRLI response claims NVME FC41036		 * type.  Target mode does not issue gft_id so doesn't get1037		 * the fc4 type set until now.1038		 */1039		if (phba->nvmet_support && (npr->prliType == PRLI_NVME_TYPE)) {1040			ndlp->nlp_fc4_type |= NLP_FC4_NVME;1041			lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);1042		}1043 1044		/* Fabric Controllers send FCP PRLI as an initiator but should1045		 * not get recognized as FCP type and registered with transport.1046		 */1047		if (npr->prliType == PRLI_FCP_TYPE &&1048		    !(ndlp->nlp_type & NLP_FABRIC))1049			ndlp->nlp_fc4_type |= NLP_FC4_FCP;1050	}1051	if (rport) {1052		/* We need to update the rport role values */1053		roles = FC_RPORT_ROLE_UNKNOWN;1054		if (ndlp->nlp_type & NLP_FCP_INITIATOR)1055			roles |= FC_RPORT_ROLE_FCP_INITIATOR;1056		if (ndlp->nlp_type & NLP_FCP_TARGET)1057			roles |= FC_RPORT_ROLE_FCP_TARGET;1058 1059		lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,1060			"rport rolechg:   role:x%x did:x%x flg:x%x",1061			roles, ndlp->nlp_DID, ndlp->nlp_flag);1062 1063		if (vport->cfg_enable_fc4_type != LPFC_ENABLE_NVME)1064			fc_remote_port_rolechg(rport, roles);1065	}1066}1067 1068static uint32_t1069lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)1070{1071	if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {1072		spin_lock_irq(&ndlp->lock);1073		ndlp->nlp_flag &= ~NLP_NPR_ADISC;1074		spin_unlock_irq(&ndlp->lock);1075		return 0;1076	}1077 1078	if (!test_bit(FC_PT2PT, &vport->fc_flag)) {1079		/* Check config parameter use-adisc or FCP-2 */1080		if (vport->cfg_use_adisc &&1081		    (test_bit(FC_RSCN_MODE, &vport->fc_flag) ||1082		    ((ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) &&1083		     (ndlp->nlp_type & NLP_FCP_TARGET)))) {1084			spin_lock_irq(&ndlp->lock);1085			ndlp->nlp_flag |= NLP_NPR_ADISC;1086			spin_unlock_irq(&ndlp->lock);1087			return 1;1088		}1089	}1090 1091	spin_lock_irq(&ndlp->lock);1092	ndlp->nlp_flag &= ~NLP_NPR_ADISC;1093	spin_unlock_irq(&ndlp->lock);1094	lpfc_unreg_rpi(vport, ndlp);1095	return 0;1096}1097 1098/**1099 * lpfc_release_rpi - Release a RPI by issuing unreg_login mailbox cmd.1100 * @phba : Pointer to lpfc_hba structure.1101 * @vport: Pointer to lpfc_vport structure.1102 * @ndlp: Pointer to lpfc_nodelist structure.1103 * @rpi  : rpi to be release.1104 *1105 * This function will send a unreg_login mailbox command to the firmware1106 * to release a rpi.1107 **/1108static void1109lpfc_release_rpi(struct lpfc_hba *phba, struct lpfc_vport *vport,1110		 struct lpfc_nodelist *ndlp, uint16_t rpi)1111{1112	LPFC_MBOXQ_t *pmb;1113	int rc;1114 1115	/* If there is already an UNREG in progress for this ndlp,1116	 * no need to queue up another one.1117	 */1118	if (ndlp->nlp_flag & NLP_UNREG_INP) {1119		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1120				 "1435 release_rpi SKIP UNREG x%x on "1121				 "NPort x%x deferred x%x  flg x%x "1122				 "Data: x%px\n",1123				 ndlp->nlp_rpi, ndlp->nlp_DID,1124				 ndlp->nlp_defer_did,1125				 ndlp->nlp_flag, ndlp);1126		return;1127	}1128 1129	pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,1130			GFP_KERNEL);1131	if (!pmb)1132		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1133				 "2796 mailbox memory allocation failed \n");1134	else {1135		lpfc_unreg_login(phba, vport->vpi, rpi, pmb);1136		pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;1137		pmb->vport = vport;1138		pmb->ctx_ndlp = lpfc_nlp_get(ndlp);1139		if (!pmb->ctx_ndlp) {1140			mempool_free(pmb, phba->mbox_mem_pool);1141			return;1142		}1143 1144		if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&1145		    (!test_bit(FC_OFFLINE_MODE, &vport->fc_flag)))1146			ndlp->nlp_flag |= NLP_UNREG_INP;1147 1148		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1149				 "1437 release_rpi UNREG x%x "1150				 "on NPort x%x flg x%x\n",1151				 ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag);1152 1153		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);1154		if (rc == MBX_NOT_FINISHED) {1155			lpfc_nlp_put(ndlp);1156			mempool_free(pmb, phba->mbox_mem_pool);1157		}1158	}1159}1160 1161static uint32_t1162lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1163		  void *arg, uint32_t evt)1164{1165	struct lpfc_hba *phba;1166	LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;1167	uint16_t rpi;1168 1169	phba = vport->phba;1170	/* Release the RPI if reglogin completing */1171	if (!test_bit(FC_UNLOADING, &phba->pport->load_flag) &&1172	    evt == NLP_EVT_CMPL_REG_LOGIN && !pmb->u.mb.mbxStatus) {1173		rpi = pmb->u.mb.un.varWords[0];1174		lpfc_release_rpi(phba, vport, ndlp, rpi);1175	}1176	lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1177			 "0271 Illegal State Transition: node x%x "1178			 "event x%x, state x%x Data: x%x x%x\n",1179			 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,1180			 ndlp->nlp_flag);1181	return ndlp->nlp_state;1182}1183 1184static uint32_t1185lpfc_cmpl_plogi_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1186		  void *arg, uint32_t evt)1187{1188	/* This transition is only legal if we previously1189	 * rcv'ed a PLOGI. Since we don't want 2 discovery threads1190	 * working on the same NPortID, do nothing for this thread1191	 * to stop it.1192	 */1193	if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) {1194		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1195				 "0272 Illegal State Transition: node x%x "1196				 "event x%x, state x%x Data: x%x x%x\n",1197				  ndlp->nlp_DID, evt, ndlp->nlp_state,1198				  ndlp->nlp_rpi, ndlp->nlp_flag);1199	}1200	return ndlp->nlp_state;1201}1202 1203/* Start of Discovery State Machine routines */1204 1205static uint32_t1206lpfc_rcv_plogi_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1207			   void *arg, uint32_t evt)1208{1209	struct lpfc_iocbq *cmdiocb;1210 1211	cmdiocb = (struct lpfc_iocbq *) arg;1212 1213	if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {1214		return ndlp->nlp_state;1215	}1216	return NLP_STE_FREED_NODE;1217}1218 1219static uint32_t1220lpfc_rcv_els_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1221			 void *arg, uint32_t evt)1222{1223	lpfc_issue_els_logo(vport, ndlp, 0);1224	return ndlp->nlp_state;1225}1226 1227static uint32_t1228lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1229			  void *arg, uint32_t evt)1230{1231	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;1232 1233	spin_lock_irq(&ndlp->lock);1234	ndlp->nlp_flag |= NLP_LOGO_ACC;1235	spin_unlock_irq(&ndlp->lock);1236	lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);1237 1238	return ndlp->nlp_state;1239}1240 1241static uint32_t1242lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1243			   void *arg, uint32_t evt)1244{1245	return NLP_STE_FREED_NODE;1246}1247 1248static uint32_t1249lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1250			   void *arg, uint32_t evt)1251{1252	return NLP_STE_FREED_NODE;1253}1254 1255static uint32_t1256lpfc_device_recov_unused_node(struct lpfc_vport *vport,1257			struct lpfc_nodelist *ndlp,1258			   void *arg, uint32_t evt)1259{1260	return ndlp->nlp_state;1261}1262 1263static uint32_t1264lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1265			   void *arg, uint32_t evt)1266{1267	struct lpfc_hba   *phba = vport->phba;1268	struct lpfc_iocbq *cmdiocb = arg;1269	struct lpfc_dmabuf *pcmd = cmdiocb->cmd_dmabuf;1270	uint32_t *lp = (uint32_t *) pcmd->virt;1271	struct serv_parm *sp = (struct serv_parm *) (lp + 1);1272	struct ls_rjt stat;1273	int port_cmp;1274 1275	memset(&stat, 0, sizeof (struct ls_rjt));1276 1277	/* For a PLOGI, we only accept if our portname is less1278	 * than the remote portname.1279	 */1280	phba->fc_stat.elsLogiCol++;1281	port_cmp = memcmp(&vport->fc_portname, &sp->portName,1282			  sizeof(struct lpfc_name));1283 1284	if (port_cmp >= 0) {1285		/* Reject this request because the remote node will accept1286		   ours */1287		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;1288		stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;1289		lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,1290			NULL);1291	} else {1292		if (lpfc_rcv_plogi(vport, ndlp, cmdiocb) &&1293		    (ndlp->nlp_flag & NLP_NPR_2B_DISC) &&1294		    (vport->num_disc_nodes)) {1295			spin_lock_irq(&ndlp->lock);1296			ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;1297			spin_unlock_irq(&ndlp->lock);1298			/* Check if there are more PLOGIs to be sent */1299			lpfc_more_plogi(vport);1300			if (vport->num_disc_nodes == 0) {1301				clear_bit(FC_NDISC_ACTIVE, &vport->fc_flag);1302				lpfc_can_disctmo(vport);1303				lpfc_end_rscn(vport);1304			}1305		}1306	} /* If our portname was less */1307 1308	return ndlp->nlp_state;1309}1310 1311static uint32_t1312lpfc_rcv_prli_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1313			  void *arg, uint32_t evt)1314{1315	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;1316	struct ls_rjt     stat;1317 1318	memset(&stat, 0, sizeof (struct ls_rjt));1319	stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;1320	stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;1321	lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);1322	return ndlp->nlp_state;1323}1324 1325static uint32_t1326lpfc_rcv_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1327			  void *arg, uint32_t evt)1328{1329	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;1330 1331	/* Retrieve RPI from LOGO IOCB. RPI is used for CMD_ABORT_XRI_CN */1332	if (vport->phba->sli_rev == LPFC_SLI_REV3)1333		ndlp->nlp_rpi = cmdiocb->iocb.ulpIoTag;1334				/* software abort outstanding PLOGI */1335	lpfc_els_abort(vport->phba, ndlp);1336 1337	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);1338	return ndlp->nlp_state;1339}1340 1341static uint32_t1342lpfc_rcv_els_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1343			 void *arg, uint32_t evt)1344{1345	struct lpfc_hba   *phba = vport->phba;1346	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;1347 1348	/* software abort outstanding PLOGI */1349	lpfc_els_abort(phba, ndlp);1350 1351	if (evt == NLP_EVT_RCV_LOGO) {1352		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);1353	} else {1354		lpfc_issue_els_logo(vport, ndlp, 0);1355	}1356 1357	/* Put ndlp in npr state set plogi timer for 1 sec */1358	mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000 * 1));1359	spin_lock_irq(&ndlp->lock);1360	ndlp->nlp_flag |= NLP_DELAY_TMO;1361	spin_unlock_irq(&ndlp->lock);1362	ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;1363	ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;1364	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);1365 1366	return ndlp->nlp_state;1367}1368 1369static uint32_t1370lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,1371			    struct lpfc_nodelist *ndlp,1372			    void *arg,1373			    uint32_t evt)1374{1375	struct lpfc_hba    *phba = vport->phba;1376	struct lpfc_iocbq  *cmdiocb, *rspiocb;1377	struct lpfc_dmabuf *pcmd, *prsp;1378	uint32_t *lp;1379	uint32_t vid, flag;1380	struct serv_parm *sp;1381	uint32_t ed_tov;1382	LPFC_MBOXQ_t *mbox;1383	int rc;1384	u32 ulp_status;1385	u32 did;1386 1387	cmdiocb = (struct lpfc_iocbq *) arg;1388	rspiocb = cmdiocb->rsp_iocb;1389 1390	ulp_status = get_job_ulpstatus(phba, rspiocb);1391 1392	if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {1393		/* Recovery from PLOGI collision logic */1394		return ndlp->nlp_state;1395	}1396 1397	if (ulp_status)1398		goto out;1399 1400	pcmd = cmdiocb->cmd_dmabuf;1401 1402	prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);1403	if (!prsp)1404		goto out;1405 1406	lp = (uint32_t *) prsp->virt;1407	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));1408 1409	/* Some switches have FDMI servers returning 0 for WWN */1410	if ((ndlp->nlp_DID != FDMI_DID) &&1411		(wwn_to_u64(sp->portName.u.wwn) == 0 ||1412		wwn_to_u64(sp->nodeName.u.wwn) == 0)) {1413		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1414				 "0142 PLOGI RSP: Invalid WWN.\n");1415		goto out;1416	}1417	if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0))1418		goto out;1419	/* PLOGI chkparm OK */1420	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,1421			 "0121 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",1422			 ndlp->nlp_DID, ndlp->nlp_state,1423			 ndlp->nlp_flag, ndlp->nlp_rpi);1424	if (vport->cfg_fcp_class == 2 && (sp->cls2.classValid))1425		ndlp->nlp_fcp_info |= CLASS2;1426	else1427		ndlp->nlp_fcp_info |= CLASS3;1428 1429	ndlp->nlp_class_sup = 0;1430	if (sp->cls1.classValid)1431		ndlp->nlp_class_sup |= FC_COS_CLASS1;1432	if (sp->cls2.classValid)1433		ndlp->nlp_class_sup |= FC_COS_CLASS2;1434	if (sp->cls3.classValid)1435		ndlp->nlp_class_sup |= FC_COS_CLASS3;1436	if (sp->cls4.classValid)1437		ndlp->nlp_class_sup |= FC_COS_CLASS4;1438	ndlp->nlp_maxframe =1439		((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;1440 1441	if (test_bit(FC_PT2PT, &vport->fc_flag) &&1442	    test_bit(FC_PT2PT_PLOGI, &vport->fc_flag)) {1443		ed_tov = be32_to_cpu(sp->cmn.e_d_tov);1444		if (sp->cmn.edtovResolution) {1445			/* E_D_TOV ticks are in nanoseconds */1446			ed_tov = (phba->fc_edtov + 999999) / 1000000;1447		}1448 1449		ndlp->nlp_flag &= ~NLP_SUPPRESS_RSP;1450		if ((phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) &&1451		    sp->cmn.valid_vendor_ver_level) {1452			vid = be32_to_cpu(sp->un.vv.vid);1453			flag = be32_to_cpu(sp->un.vv.flags);1454			if ((vid == LPFC_VV_EMLX_ID) &&1455			    (flag & LPFC_VV_SUPPRESS_RSP))1456				ndlp->nlp_flag |= NLP_SUPPRESS_RSP;1457		}1458 1459		/*1460		 * Use the larger EDTOV1461		 * RATOV = 2 * EDTOV for pt-to-pt1462		 */1463		if (ed_tov > phba->fc_edtov)1464			phba->fc_edtov = ed_tov;1465		phba->fc_ratov = (2 * phba->fc_edtov) / 1000;1466 1467		memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));1468 1469		/* Issue config_link / reg_vfi to account for updated TOV's */1470		if (phba->sli_rev == LPFC_SLI_REV4) {1471			lpfc_issue_reg_vfi(vport);1472		} else {1473			mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);1474			if (!mbox) {1475				lpfc_printf_vlog(vport, KERN_ERR,1476						 LOG_TRACE_EVENT,1477						 "0133 PLOGI: no memory "1478						 "for config_link "1479						 "Data: x%x x%x x%x x%x\n",1480						 ndlp->nlp_DID, ndlp->nlp_state,1481						 ndlp->nlp_flag, ndlp->nlp_rpi);1482				goto out;1483			}1484 1485			lpfc_config_link(phba, mbox);1486 1487			mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;1488			mbox->vport = vport;1489			rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);1490			if (rc == MBX_NOT_FINISHED) {1491				mempool_free(mbox, phba->mbox_mem_pool);1492				goto out;1493			}1494		}1495	}1496 1497	lpfc_unreg_rpi(vport, ndlp);1498 1499	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);1500	if (!mbox) {1501		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1502				 "0018 PLOGI: no memory for reg_login "1503				 "Data: x%x x%x x%x x%x\n",1504				 ndlp->nlp_DID, ndlp->nlp_state,1505				 ndlp->nlp_flag, ndlp->nlp_rpi);1506		goto out;1507	}1508 1509	did = get_job_els_rsp64_did(phba, cmdiocb);1510 1511	if (lpfc_reg_rpi(phba, vport->vpi, did,1512			 (uint8_t *) sp, mbox, ndlp->nlp_rpi) == 0) {1513		switch (ndlp->nlp_DID) {1514		case NameServer_DID:1515			mbox->mbox_cmpl = lpfc_mbx_cmpl_ns_reg_login;1516			/* Fabric Controller Node needs these parameters. */1517			memcpy(&ndlp->fc_sparam, sp, sizeof(struct serv_parm));1518			break;1519		case FDMI_DID:1520			mbox->mbox_cmpl = lpfc_mbx_cmpl_fdmi_reg_login;1521			break;1522		default:1523			ndlp->nlp_flag |= NLP_REG_LOGIN_SEND;1524			mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;1525		}1526 1527		mbox->ctx_ndlp = lpfc_nlp_get(ndlp);1528		if (!mbox->ctx_ndlp)1529			goto out;1530 1531		mbox->vport = vport;1532		if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)1533		    != MBX_NOT_FINISHED) {1534			lpfc_nlp_set_state(vport, ndlp,1535					   NLP_STE_REG_LOGIN_ISSUE);1536			return ndlp->nlp_state;1537		}1538		if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND)1539			ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;1540		/* decrement node reference count to the failed mbox1541		 * command1542		 */1543		lpfc_nlp_put(ndlp);1544		lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);1545		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1546				 "0134 PLOGI: cannot issue reg_login "1547				 "Data: x%x x%x x%x x%x\n",1548				 ndlp->nlp_DID, ndlp->nlp_state,1549				 ndlp->nlp_flag, ndlp->nlp_rpi);1550	} else {1551		mempool_free(mbox, phba->mbox_mem_pool);1552 1553		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1554				 "0135 PLOGI: cannot format reg_login "1555				 "Data: x%x x%x x%x x%x\n",1556				 ndlp->nlp_DID, ndlp->nlp_state,1557				 ndlp->nlp_flag, ndlp->nlp_rpi);1558	}1559 1560 1561out:1562	if (ndlp->nlp_DID == NameServer_DID) {1563		lpfc_vport_set_state(vport, FC_VPORT_FAILED);1564		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1565				 "0261 Cannot Register NameServer login\n");1566	}1567 1568	/*1569	** In case the node reference counter does not go to zero, ensure that1570	** the stale state for the node is not processed.1571	*/1572 1573	ndlp->nlp_prev_state = ndlp->nlp_state;1574	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);1575	return NLP_STE_FREED_NODE;1576}1577 1578static uint32_t1579lpfc_cmpl_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1580			   void *arg, uint32_t evt)1581{1582	return ndlp->nlp_state;1583}1584 1585static uint32_t1586lpfc_cmpl_reglogin_plogi_issue(struct lpfc_vport *vport,1587	struct lpfc_nodelist *ndlp, void *arg, uint32_t evt)1588{1589	struct lpfc_hba *phba;1590	LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;1591	MAILBOX_t *mb = &pmb->u.mb;1592	uint16_t rpi;1593 1594	phba = vport->phba;1595	/* Release the RPI */1596	if (!test_bit(FC_UNLOADING, &phba->pport->load_flag) &&1597	    !mb->mbxStatus) {1598		rpi = pmb->u.mb.un.varWords[0];1599		lpfc_release_rpi(phba, vport, ndlp, rpi);1600	}1601	return ndlp->nlp_state;1602}1603 1604static uint32_t1605lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1606			   void *arg, uint32_t evt)1607{1608	if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {1609		spin_lock_irq(&ndlp->lock);1610		ndlp->nlp_flag |= NLP_NODEV_REMOVE;1611		spin_unlock_irq(&ndlp->lock);1612		return ndlp->nlp_state;1613	} else {1614		/* software abort outstanding PLOGI */1615		lpfc_els_abort(vport->phba, ndlp);1616 1617		lpfc_drop_node(vport, ndlp);1618		return NLP_STE_FREED_NODE;1619	}1620}1621 1622static uint32_t1623lpfc_device_recov_plogi_issue(struct lpfc_vport *vport,1624			      struct lpfc_nodelist *ndlp,1625			      void *arg,1626			      uint32_t evt)1627{1628	struct lpfc_hba  *phba = vport->phba;1629 1630	/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */1631	if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))1632		return ndlp->nlp_state;1633 1634	/* software abort outstanding PLOGI */1635	lpfc_els_abort(phba, ndlp);1636 1637	ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;1638	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);1639	spin_lock_irq(&ndlp->lock);1640	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);1641	spin_unlock_irq(&ndlp->lock);1642 1643	return ndlp->nlp_state;1644}1645 1646static uint32_t1647lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1648			   void *arg, uint32_t evt)1649{1650	struct lpfc_hba   *phba = vport->phba;1651	struct lpfc_iocbq *cmdiocb;1652 1653	/* software abort outstanding ADISC */1654	lpfc_els_abort(phba, ndlp);1655 1656	cmdiocb = (struct lpfc_iocbq *) arg;1657 1658	if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {1659		if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {1660			spin_lock_irq(&ndlp->lock);1661			ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;1662			spin_unlock_irq(&ndlp->lock);1663			if (vport->num_disc_nodes)1664				lpfc_more_adisc(vport);1665		}1666		return ndlp->nlp_state;1667	}1668	ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;1669	lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);1670	lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);1671 1672	return ndlp->nlp_state;1673}1674 1675static uint32_t1676lpfc_rcv_prli_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1677			  void *arg, uint32_t evt)1678{1679	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;1680 1681	if (lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))1682		lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);1683	return ndlp->nlp_state;1684}1685 1686static uint32_t1687lpfc_rcv_logo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1688			  void *arg, uint32_t evt)1689{1690	struct lpfc_hba *phba = vport->phba;1691	struct lpfc_iocbq *cmdiocb;1692 1693	cmdiocb = (struct lpfc_iocbq *) arg;1694 1695	/* software abort outstanding ADISC */1696	lpfc_els_abort(phba, ndlp);1697 1698	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);1699	return ndlp->nlp_state;1700}1701 1702static uint32_t1703lpfc_rcv_padisc_adisc_issue(struct lpfc_vport *vport,1704			    struct lpfc_nodelist *ndlp,1705			    void *arg, uint32_t evt)1706{1707	struct lpfc_iocbq *cmdiocb;1708 1709	cmdiocb = (struct lpfc_iocbq *) arg;1710 1711	lpfc_rcv_padisc(vport, ndlp, cmdiocb);1712	return ndlp->nlp_state;1713}1714 1715static uint32_t1716lpfc_rcv_prlo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1717			  void *arg, uint32_t evt)1718{1719	struct lpfc_iocbq *cmdiocb;1720 1721	cmdiocb = (struct lpfc_iocbq *) arg;1722 1723	/* Treat like rcv logo */1724	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);1725	return ndlp->nlp_state;1726}1727 1728static uint32_t1729lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport,1730			    struct lpfc_nodelist *ndlp,1731			    void *arg, uint32_t evt)1732{1733	struct lpfc_hba   *phba = vport->phba;1734	struct lpfc_iocbq *cmdiocb, *rspiocb;1735	ADISC *ap;1736	int rc;1737	u32 ulp_status;1738 1739	cmdiocb = (struct lpfc_iocbq *) arg;1740	rspiocb = cmdiocb->rsp_iocb;1741 1742	ulp_status = get_job_ulpstatus(phba, rspiocb);1743 1744	ap = (ADISC *)lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);1745 1746	if ((ulp_status) ||1747	    (!lpfc_check_adisc(vport, ndlp, &ap->nodeName, &ap->portName))) {1748		/* 1 sec timeout */1749		mod_timer(&ndlp->nlp_delayfunc,1750			  jiffies + msecs_to_jiffies(1000));1751		spin_lock_irq(&ndlp->lock);1752		ndlp->nlp_flag |= NLP_DELAY_TMO;1753		spin_unlock_irq(&ndlp->lock);1754		ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;1755 1756		ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;1757		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);1758		lpfc_unreg_rpi(vport, ndlp);1759		return ndlp->nlp_state;1760	}1761 1762	if (phba->sli_rev == LPFC_SLI_REV4) {1763		rc = lpfc_sli4_resume_rpi(ndlp, NULL, NULL);1764		if (rc) {1765			/* Stay in state and retry. */1766			ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;1767			return ndlp->nlp_state;1768		}1769	}1770 1771	if (ndlp->nlp_type & NLP_FCP_TARGET)1772		ndlp->nlp_fc4_type |= NLP_FC4_FCP;1773 1774	if (ndlp->nlp_type & NLP_NVME_TARGET)1775		ndlp->nlp_fc4_type |= NLP_FC4_NVME;1776 1777	if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) {1778		ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;1779		lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);1780	} else {1781		ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;1782		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);1783	}1784 1785	return ndlp->nlp_state;1786}1787 1788static uint32_t1789lpfc_device_rm_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,1790			   void *arg, uint32_t evt)1791{1792	if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {1793		spin_lock_irq(&ndlp->lock);1794		ndlp->nlp_flag |= NLP_NODEV_REMOVE;1795		spin_unlock_irq(&ndlp->lock);1796		return ndlp->nlp_state;1797	} else {1798		/* software abort outstanding ADISC */1799		lpfc_els_abort(vport->phba, ndlp);1800 1801		lpfc_drop_node(vport, ndlp);1802		return NLP_STE_FREED_NODE;1803	}1804}1805 1806static uint32_t1807lpfc_device_recov_adisc_issue(struct lpfc_vport *vport,1808			      struct lpfc_nodelist *ndlp,1809			      void *arg,1810			      uint32_t evt)1811{1812	struct lpfc_hba  *phba = vport->phba;1813 1814	/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */1815	if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))1816		return ndlp->nlp_state;1817 1818	/* software abort outstanding ADISC */1819	lpfc_els_abort(phba, ndlp);1820 1821	ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;1822	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);1823	spin_lock_irq(&ndlp->lock);1824	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);1825	spin_unlock_irq(&ndlp->lock);1826	lpfc_disc_set_adisc(vport, ndlp);1827	return ndlp->nlp_state;1828}1829 1830static uint32_t1831lpfc_rcv_plogi_reglogin_issue(struct lpfc_vport *vport,1832			      struct lpfc_nodelist *ndlp,1833			      void *arg,1834			      uint32_t evt)1835{1836	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;1837 1838	lpfc_rcv_plogi(vport, ndlp, cmdiocb);1839	return ndlp->nlp_state;1840}1841 1842static uint32_t1843lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport,1844			     struct lpfc_nodelist *ndlp,1845			     void *arg,1846			     uint32_t evt)1847{1848	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;1849	struct ls_rjt     stat;1850 1851	if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb)) {1852		return ndlp->nlp_state;1853	}1854	if (vport->phba->nvmet_support) {1855		/* NVME Target mode.  Handle and respond to the PRLI and1856		 * transition to UNMAPPED provided the RPI has completed1857		 * registration.1858		 */1859		if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {1860			lpfc_rcv_prli(vport, ndlp, cmdiocb);1861			lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);1862		} else {1863			/* RPI registration has not completed. Reject the PRLI1864			 * to prevent an illegal state transition when the1865			 * rpi registration does complete.1866			 */1867			memset(&stat, 0, sizeof(struct ls_rjt));1868			stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;1869			stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;1870			lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,1871					    ndlp, NULL);1872			return ndlp->nlp_state;1873		}1874	} else {1875		/* Initiator mode. */1876		lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);1877	}1878	return ndlp->nlp_state;1879}1880 1881static uint32_t1882lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,1883			     struct lpfc_nodelist *ndlp,1884			     void *arg,1885			     uint32_t evt)1886{1887	struct lpfc_hba   *phba = vport->phba;1888	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;1889	LPFC_MBOXQ_t	  *mb;1890	LPFC_MBOXQ_t	  *nextmb;1891 1892	cmdiocb = (struct lpfc_iocbq *) arg;1893 1894	/* cleanup any ndlp on mbox q waiting for reglogin cmpl */1895	if ((mb = phba->sli.mbox_active)) {1896		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&1897		   (ndlp == mb->ctx_ndlp)) {1898			ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;1899			lpfc_nlp_put(ndlp);1900			mb->ctx_ndlp = NULL;1901			mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;1902		}1903	}1904 1905	spin_lock_irq(&phba->hbalock);1906	list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {1907		if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&1908		   (ndlp == mb->ctx_ndlp)) {1909			ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;1910			lpfc_nlp_put(ndlp);1911			list_del(&mb->list);1912			phba->sli.mboxq_cnt--;1913			lpfc_mbox_rsrc_cleanup(phba, mb, MBOX_THD_LOCKED);1914		}1915	}1916	spin_unlock_irq(&phba->hbalock);1917 1918	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);1919	return ndlp->nlp_state;1920}1921 1922static uint32_t1923lpfc_rcv_padisc_reglogin_issue(struct lpfc_vport *vport,1924			       struct lpfc_nodelist *ndlp,1925			       void *arg,1926			       uint32_t evt)1927{1928	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;1929 1930	lpfc_rcv_padisc(vport, ndlp, cmdiocb);1931	return ndlp->nlp_state;1932}1933 1934static uint32_t1935lpfc_rcv_prlo_reglogin_issue(struct lpfc_vport *vport,1936			     struct lpfc_nodelist *ndlp,1937			     void *arg,1938			     uint32_t evt)1939{1940	struct lpfc_iocbq *cmdiocb;1941 1942	cmdiocb = (struct lpfc_iocbq *) arg;1943	lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);1944	return ndlp->nlp_state;1945}1946 1947static uint32_t1948lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,1949				  struct lpfc_nodelist *ndlp,1950				  void *arg,1951				  uint32_t evt)1952{1953	struct lpfc_hba *phba = vport->phba;1954	LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;1955	MAILBOX_t *mb = &pmb->u.mb;1956	uint32_t did  = mb->un.varWords[1];1957 1958	if (mb->mbxStatus) {1959		/* RegLogin failed */1960		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1961				 "0246 RegLogin failed Data: x%x x%x x%x x%x "1962				 "x%x\n",1963				 did, mb->mbxStatus, vport->port_state,1964				 mb->un.varRegLogin.vpi,1965				 mb->un.varRegLogin.rpi);1966		/*1967		 * If RegLogin failed due to lack of HBA resources do not1968		 * retry discovery.1969		 */1970		if (mb->mbxStatus == MBXERR_RPI_FULL) {1971			ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;1972			lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);1973			return ndlp->nlp_state;1974		}1975 1976		/* Put ndlp in npr state set plogi timer for 1 sec */1977		mod_timer(&ndlp->nlp_delayfunc,1978			  jiffies + msecs_to_jiffies(1000 * 1));1979		spin_lock_irq(&ndlp->lock);1980		ndlp->nlp_flag |= NLP_DELAY_TMO;1981		spin_unlock_irq(&ndlp->lock);1982		ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;1983 1984		lpfc_issue_els_logo(vport, ndlp, 0);1985		return ndlp->nlp_state;1986	}1987 1988	/* SLI4 ports have preallocated logical rpis. */1989	if (phba->sli_rev < LPFC_SLI_REV4)1990		ndlp->nlp_rpi = mb->un.varWords[0];1991 1992	ndlp->nlp_flag |= NLP_RPI_REGISTERED;1993 1994	/* Only if we are not a fabric nport do we issue PRLI */1995	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1996			 "3066 RegLogin Complete on x%x x%x x%x\n",1997			 did, ndlp->nlp_type, ndlp->nlp_fc4_type);1998	if (!(ndlp->nlp_type & NLP_FABRIC) &&1999	    (phba->nvmet_support == 0)) {2000		/* The driver supports FCP and NVME concurrently.  If the2001		 * ndlp's nlp_fc4_type is still zero, the driver doesn't2002		 * know what PRLI to send yet.  Figure that out now and2003		 * call PRLI depending on the outcome.2004		 */2005		if (test_bit(FC_PT2PT, &vport->fc_flag)) {2006			/* If we are pt2pt, there is no Fabric to determine2007			 * the FC4 type of the remote nport. So if NVME2008			 * is configured try it.2009			 */2010			ndlp->nlp_fc4_type |= NLP_FC4_FCP;2011			if ((!test_bit(FC_PT2PT_NO_NVME, &vport->fc_flag)) &&2012			    (vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH ||2013			    vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {2014				ndlp->nlp_fc4_type |= NLP_FC4_NVME;2015				/* We need to update the localport also */2016				lpfc_nvme_update_localport(vport);2017			}2018 2019		} else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {2020			ndlp->nlp_fc4_type |= NLP_FC4_FCP;2021 2022		} else if (ndlp->nlp_fc4_type == 0) {2023			/* If we are only configured for FCP, the driver2024			 * should just issue PRLI for FCP. Otherwise issue2025			 * GFT_ID to determine if remote port supports NVME.2026			 */2027			if (vport->cfg_enable_fc4_type != LPFC_ENABLE_FCP) {2028				lpfc_ns_cmd(vport, SLI_CTNS_GFT_ID, 0,2029					    ndlp->nlp_DID);2030				return ndlp->nlp_state;2031			}2032			ndlp->nlp_fc4_type = NLP_FC4_FCP;2033		}2034 2035		ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;2036		lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);2037		if (lpfc_issue_els_prli(vport, ndlp, 0)) {2038			lpfc_issue_els_logo(vport, ndlp, 0);2039			ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;2040			lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);2041		}2042	} else {2043		if (test_bit(FC_PT2PT, &vport->fc_flag) && phba->nvmet_support)2044			phba->targetport->port_id = vport->fc_myDID;2045 2046		/* Only Fabric ports should transition. NVME target2047		 * must complete PRLI.2048		 */2049		if (ndlp->nlp_type & NLP_FABRIC) {2050			ndlp->nlp_fc4_type &= ~NLP_FC4_FCP;2051			ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;2052			lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);2053		}2054	}2055	return ndlp->nlp_state;2056}2057 2058static uint32_t2059lpfc_device_rm_reglogin_issue(struct lpfc_vport *vport,2060			      struct lpfc_nodelist *ndlp,2061			      void *arg,2062			      uint32_t evt)2063{2064	if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {2065		spin_lock_irq(&ndlp->lock);2066		ndlp->nlp_flag |= NLP_NODEV_REMOVE;2067		spin_unlock_irq(&ndlp->lock);2068		return ndlp->nlp_state;2069	} else {2070		lpfc_drop_node(vport, ndlp);2071		return NLP_STE_FREED_NODE;2072	}2073}2074 2075static uint32_t2076lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport,2077				 struct lpfc_nodelist *ndlp,2078				 void *arg,2079				 uint32_t evt)2080{2081	/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */2082	if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))2083		return ndlp->nlp_state;2084 2085	ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;2086	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);2087	spin_lock_irq(&ndlp->lock);2088 2089	/* If we are a target we won't immediately transition into PRLI,2090	 * so if REG_LOGIN already completed we don't need to ignore it.2091	 */2092	if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED) ||2093	    !vport->phba->nvmet_support)2094		ndlp->nlp_flag |= NLP_IGNR_REG_CMPL;2095 2096	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);2097	spin_unlock_irq(&ndlp->lock);2098	lpfc_disc_set_adisc(vport, ndlp);2099	return ndlp->nlp_state;2100}2101 2102static uint32_t2103lpfc_rcv_plogi_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2104			  void *arg, uint32_t evt)2105{2106	struct lpfc_iocbq *cmdiocb;2107 2108	cmdiocb = (struct lpfc_iocbq *) arg;2109 2110	lpfc_rcv_plogi(vport, ndlp, cmdiocb);2111	return ndlp->nlp_state;2112}2113 2114static uint32_t2115lpfc_rcv_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2116			 void *arg, uint32_t evt)2117{2118	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2119 2120	if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))2121		return ndlp->nlp_state;2122	lpfc_rcv_prli(vport, ndlp, cmdiocb);2123	lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);2124	return ndlp->nlp_state;2125}2126 2127static uint32_t2128lpfc_rcv_logo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2129			 void *arg, uint32_t evt)2130{2131	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2132 2133	/* Software abort outstanding PRLI before sending acc */2134	lpfc_els_abort(vport->phba, ndlp);2135 2136	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);2137	return ndlp->nlp_state;2138}2139 2140static uint32_t2141lpfc_rcv_padisc_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2142			   void *arg, uint32_t evt)2143{2144	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2145 2146	lpfc_rcv_padisc(vport, ndlp, cmdiocb);2147	return ndlp->nlp_state;2148}2149 2150/* This routine is envoked when we rcv a PRLO request from a nport2151 * we are logged into.  We should send back a PRLO rsp setting the2152 * appropriate bits.2153 * NEXT STATE = PRLI_ISSUE2154 */2155static uint32_t2156lpfc_rcv_prlo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2157			 void *arg, uint32_t evt)2158{2159	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2160 2161	lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);2162	return ndlp->nlp_state;2163}2164 2165static uint32_t2166lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2167			  void *arg, uint32_t evt)2168{2169	struct lpfc_iocbq *cmdiocb, *rspiocb;2170	struct lpfc_hba   *phba = vport->phba;2171	PRLI *npr;2172	struct lpfc_nvme_prli *nvpr;2173	void *temp_ptr;2174	u32 ulp_status;2175	bool acc_imode_sps = false;2176 2177	cmdiocb = (struct lpfc_iocbq *) arg;2178	rspiocb = cmdiocb->rsp_iocb;2179 2180	ulp_status = get_job_ulpstatus(phba, rspiocb);2181 2182	/* A solicited PRLI is either FCP or NVME.  The PRLI cmd/rsp2183	 * format is different so NULL the two PRLI types so that the2184	 * driver correctly gets the correct context.2185	 */2186	npr = NULL;2187	nvpr = NULL;2188	temp_ptr = lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);2189	if (cmdiocb->cmd_flag & LPFC_PRLI_FCP_REQ)2190		npr = (PRLI *) temp_ptr;2191	else if (cmdiocb->cmd_flag & LPFC_PRLI_NVME_REQ)2192		nvpr = (struct lpfc_nvme_prli *) temp_ptr;2193 2194	if (ulp_status) {2195		if ((vport->port_type == LPFC_NPIV_PORT) &&2196		    vport->cfg_restrict_login) {2197			goto out;2198		}2199 2200		/* Adjust the nlp_type accordingly if the PRLI failed */2201		if (npr)2202			ndlp->nlp_fc4_type &= ~NLP_FC4_FCP;2203		if (nvpr)2204			ndlp->nlp_fc4_type &= ~NLP_FC4_NVME;2205 2206		/* We can't set the DSM state till BOTH PRLIs complete */2207		goto out_err;2208	}2209 2210	if (npr && npr->prliType == PRLI_FCP_TYPE) {2211		lpfc_printf_vlog(vport, KERN_INFO,2212				 LOG_ELS | LOG_NODE | LOG_DISCOVERY,2213				 "6028 FCP NPR PRLI Cmpl Init %d Target %d "2214				 "EIP %d AccCode x%x\n",2215				 npr->initiatorFunc, npr->targetFunc,2216				 npr->estabImagePair, npr->acceptRspCode);2217 2218		if (npr->acceptRspCode == PRLI_INV_SRV_PARM) {2219			/* Strict initiators don't establish an image pair. */2220			if (npr->initiatorFunc && !npr->targetFunc &&2221			    !npr->estabImagePair)2222				acc_imode_sps = true;2223		}2224 2225		if (npr->acceptRspCode == PRLI_REQ_EXECUTED || acc_imode_sps) {2226			if (npr->initiatorFunc)2227				ndlp->nlp_type |= NLP_FCP_INITIATOR;2228			if (npr->targetFunc) {2229				ndlp->nlp_type |= NLP_FCP_TARGET;2230				if (npr->writeXferRdyDis)2231					ndlp->nlp_flag |= NLP_FIRSTBURST;2232			}2233			if (npr->Retry)2234				ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;2235		}2236	} else if (nvpr &&2237		   (bf_get_be32(prli_acc_rsp_code, nvpr) ==2238		    PRLI_REQ_EXECUTED) &&2239		   (bf_get_be32(prli_type_code, nvpr) ==2240		    PRLI_NVME_TYPE)) {2241 2242		/* Complete setting up the remote ndlp personality. */2243		if (bf_get_be32(prli_init, nvpr))2244			ndlp->nlp_type |= NLP_NVME_INITIATOR;2245 2246		if (phba->nsler && bf_get_be32(prli_nsler, nvpr) &&2247		    bf_get_be32(prli_conf, nvpr))2248 2249			ndlp->nlp_nvme_info |= NLP_NVME_NSLER;2250		else2251			ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER;2252 2253		/* Target driver cannot solicit NVME FB. */2254		if (bf_get_be32(prli_tgt, nvpr)) {2255			/* Complete the nvme target roles.  The transport2256			 * needs to know if the rport is capable of2257			 * discovery in addition to its role.2258			 */2259			ndlp->nlp_type |= NLP_NVME_TARGET;2260			if (bf_get_be32(prli_disc, nvpr))2261				ndlp->nlp_type |= NLP_NVME_DISCOVERY;2262 2263			/*2264			 * If prli_fba is set, the Target supports FirstBurst.2265			 * If prli_fb_sz is 0, the FirstBurst size is unlimited,2266			 * otherwise it defines the actual size supported by2267			 * the NVME Target.2268			 */2269			if ((bf_get_be32(prli_fba, nvpr) == 1) &&2270			    (phba->cfg_nvme_enable_fb) &&2271			    (!phba->nvmet_support)) {2272				/* Both sides support FB. The target's first2273				 * burst size is a 512 byte encoded value.2274				 */2275				ndlp->nlp_flag |= NLP_FIRSTBURST;2276				ndlp->nvme_fb_size = bf_get_be32(prli_fb_sz,2277								 nvpr);2278 2279				/* Expressed in units of 512 bytes */2280				if (ndlp->nvme_fb_size)2281					ndlp->nvme_fb_size <<=2282						LPFC_NVME_FB_SHIFT;2283				else2284					ndlp->nvme_fb_size = LPFC_NVME_MAX_FB;2285			}2286		}2287 2288		lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,2289				 "6029 NVME PRLI Cmpl w1 x%08x "2290				 "w4 x%08x w5 x%08x flag x%x, "2291				 "fcp_info x%x nlp_type x%x\n",2292				 be32_to_cpu(nvpr->word1),2293				 be32_to_cpu(nvpr->word4),2294				 be32_to_cpu(nvpr->word5),2295				 ndlp->nlp_flag, ndlp->nlp_fcp_info,2296				 ndlp->nlp_type);2297	}2298	if (!(ndlp->nlp_type & NLP_FCP_TARGET) &&2299	    (vport->port_type == LPFC_NPIV_PORT) &&2300	     vport->cfg_restrict_login) {2301out:2302		spin_lock_irq(&ndlp->lock);2303		ndlp->nlp_flag |= NLP_TARGET_REMOVE;2304		spin_unlock_irq(&ndlp->lock);2305		lpfc_issue_els_logo(vport, ndlp, 0);2306 2307		ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;2308		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);2309		return ndlp->nlp_state;2310	}2311 2312out_err:2313	/* The ndlp state cannot move to MAPPED or UNMAPPED before all PRLIs2314	 * are complete.2315	 */2316	if (ndlp->fc4_prli_sent == 0) {2317		ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;2318		if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET))2319			lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);2320		else if (ndlp->nlp_type &2321			 (NLP_FCP_INITIATOR | NLP_NVME_INITIATOR))2322			lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);2323	} else2324		lpfc_printf_vlog(vport,2325				 KERN_INFO, LOG_ELS,2326				 "3067 PRLI's still outstanding "2327				 "on x%06x - count %d, Pend Node Mode "2328				 "transition...\n",2329				 ndlp->nlp_DID, ndlp->fc4_prli_sent);2330 2331	return ndlp->nlp_state;2332}2333 2334/*! lpfc_device_rm_prli_issue2335 *2336 * \pre2337 * \post2338 * \param   phba2339 * \param   ndlp2340 * \param   arg2341 * \param   evt2342 * \return  uint32_t2343 *2344 * \b Description:2345 *    This routine is envoked when we a request to remove a nport we are in the2346 *    process of PRLIing. We should software abort outstanding prli, unreg2347 *    login, send a logout. We will change node state to UNUSED_NODE, put it2348 *    on plogi list so it can be freed when LOGO completes.2349 *2350 */2351 2352static uint32_t2353lpfc_device_rm_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2354			  void *arg, uint32_t evt)2355{2356	if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {2357		spin_lock_irq(&ndlp->lock);2358		ndlp->nlp_flag |= NLP_NODEV_REMOVE;2359		spin_unlock_irq(&ndlp->lock);2360		return ndlp->nlp_state;2361	} else {2362		/* software abort outstanding PLOGI */2363		lpfc_els_abort(vport->phba, ndlp);2364 2365		lpfc_drop_node(vport, ndlp);2366		return NLP_STE_FREED_NODE;2367	}2368}2369 2370 2371/*! lpfc_device_recov_prli_issue2372 *2373 * \pre2374 * \post2375 * \param   phba2376 * \param   ndlp2377 * \param   arg2378 * \param   evt2379 * \return  uint32_t2380 *2381 * \b Description:2382 *    The routine is envoked when the state of a device is unknown, like2383 *    during a link down. We should remove the nodelist entry from the2384 *    unmapped list, issue a UNREG_LOGIN, do a software abort of the2385 *    outstanding PRLI command, then free the node entry.2386 */2387static uint32_t2388lpfc_device_recov_prli_issue(struct lpfc_vport *vport,2389			     struct lpfc_nodelist *ndlp,2390			     void *arg,2391			     uint32_t evt)2392{2393	struct lpfc_hba  *phba = vport->phba;2394 2395	/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */2396	if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))2397		return ndlp->nlp_state;2398 2399	/* software abort outstanding PRLI */2400	lpfc_els_abort(phba, ndlp);2401 2402	ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;2403	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);2404	spin_lock_irq(&ndlp->lock);2405	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);2406	spin_unlock_irq(&ndlp->lock);2407	lpfc_disc_set_adisc(vport, ndlp);2408	return ndlp->nlp_state;2409}2410 2411static uint32_t2412lpfc_rcv_plogi_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2413			  void *arg, uint32_t evt)2414{2415	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;2416	struct ls_rjt     stat;2417 2418	memset(&stat, 0, sizeof(struct ls_rjt));2419	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;2420	stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;2421	lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);2422	return ndlp->nlp_state;2423}2424 2425static uint32_t2426lpfc_rcv_prli_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2427			 void *arg, uint32_t evt)2428{2429	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;2430	struct ls_rjt     stat;2431 2432	memset(&stat, 0, sizeof(struct ls_rjt));2433	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;2434	stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;2435	lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);2436	return ndlp->nlp_state;2437}2438 2439static uint32_t2440lpfc_rcv_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2441			 void *arg, uint32_t evt)2442{2443	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;2444 2445	spin_lock_irq(&ndlp->lock);2446	ndlp->nlp_flag |= NLP_LOGO_ACC;2447	spin_unlock_irq(&ndlp->lock);2448	lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);2449	return ndlp->nlp_state;2450}2451 2452static uint32_t2453lpfc_rcv_padisc_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2454			   void *arg, uint32_t evt)2455{2456	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;2457	struct ls_rjt     stat;2458 2459	memset(&stat, 0, sizeof(struct ls_rjt));2460	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;2461	stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;2462	lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);2463	return ndlp->nlp_state;2464}2465 2466static uint32_t2467lpfc_rcv_prlo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2468			 void *arg, uint32_t evt)2469{2470	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;2471	struct ls_rjt     stat;2472 2473	memset(&stat, 0, sizeof(struct ls_rjt));2474	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;2475	stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;2476	lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);2477	return ndlp->nlp_state;2478}2479 2480static uint32_t2481lpfc_cmpl_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2482			  void *arg, uint32_t evt)2483{2484	ndlp->nlp_prev_state = NLP_STE_LOGO_ISSUE;2485	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);2486	spin_lock_irq(&ndlp->lock);2487	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);2488	spin_unlock_irq(&ndlp->lock);2489	lpfc_disc_set_adisc(vport, ndlp);2490	return ndlp->nlp_state;2491}2492 2493static uint32_t2494lpfc_device_rm_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2495			  void *arg, uint32_t evt)2496{2497	/*2498	 * DevLoss has timed out and is calling for Device Remove.2499	 * In this case, abort the LOGO and cleanup the ndlp2500	 */2501 2502	lpfc_unreg_rpi(vport, ndlp);2503	/* software abort outstanding PLOGI */2504	lpfc_els_abort(vport->phba, ndlp);2505	lpfc_drop_node(vport, ndlp);2506	return NLP_STE_FREED_NODE;2507}2508 2509static uint32_t2510lpfc_device_recov_logo_issue(struct lpfc_vport *vport,2511			     struct lpfc_nodelist *ndlp,2512			     void *arg, uint32_t evt)2513{2514	/*2515	 * Device Recovery events have no meaning for a node with a LOGO2516	 * outstanding.  The LOGO has to complete first and handle the2517	 * node from that point.2518	 */2519	return ndlp->nlp_state;2520}2521 2522static uint32_t2523lpfc_rcv_plogi_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2524			  void *arg, uint32_t evt)2525{2526	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2527 2528	lpfc_rcv_plogi(vport, ndlp, cmdiocb);2529	return ndlp->nlp_state;2530}2531 2532static uint32_t2533lpfc_rcv_prli_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2534			 void *arg, uint32_t evt)2535{2536	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2537 2538	if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))2539		return ndlp->nlp_state;2540 2541	lpfc_rcv_prli(vport, ndlp, cmdiocb);2542	lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);2543	return ndlp->nlp_state;2544}2545 2546static uint32_t2547lpfc_rcv_logo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2548			 void *arg, uint32_t evt)2549{2550	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2551 2552	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);2553	return ndlp->nlp_state;2554}2555 2556static uint32_t2557lpfc_rcv_padisc_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2558			   void *arg, uint32_t evt)2559{2560	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2561 2562	lpfc_rcv_padisc(vport, ndlp, cmdiocb);2563	return ndlp->nlp_state;2564}2565 2566static uint32_t2567lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2568			 void *arg, uint32_t evt)2569{2570	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2571 2572	lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);2573	return ndlp->nlp_state;2574}2575 2576static uint32_t2577lpfc_device_rm_unmap_node(struct lpfc_vport *vport,2578			  struct lpfc_nodelist *ndlp,2579			  void *arg,2580			  uint32_t evt)2581{2582	lpfc_drop_node(vport, ndlp);2583	return NLP_STE_FREED_NODE;2584}2585 2586static uint32_t2587lpfc_device_recov_unmap_node(struct lpfc_vport *vport,2588			     struct lpfc_nodelist *ndlp,2589			     void *arg,2590			     uint32_t evt)2591{2592	ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE;2593	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);2594	spin_lock_irq(&ndlp->lock);2595	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);2596	ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);2597	spin_unlock_irq(&ndlp->lock);2598	lpfc_disc_set_adisc(vport, ndlp);2599 2600	return ndlp->nlp_state;2601}2602 2603static uint32_t2604lpfc_rcv_plogi_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2605			   void *arg, uint32_t evt)2606{2607	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2608 2609	lpfc_rcv_plogi(vport, ndlp, cmdiocb);2610	return ndlp->nlp_state;2611}2612 2613static uint32_t2614lpfc_rcv_prli_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2615			  void *arg, uint32_t evt)2616{2617	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2618 2619	if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))2620		return ndlp->nlp_state;2621	lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);2622	return ndlp->nlp_state;2623}2624 2625static uint32_t2626lpfc_rcv_logo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2627			  void *arg, uint32_t evt)2628{2629	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2630 2631	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);2632	return ndlp->nlp_state;2633}2634 2635static uint32_t2636lpfc_rcv_padisc_mapped_node(struct lpfc_vport *vport,2637			    struct lpfc_nodelist *ndlp,2638			    void *arg, uint32_t evt)2639{2640	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2641 2642	lpfc_rcv_padisc(vport, ndlp, cmdiocb);2643	return ndlp->nlp_state;2644}2645 2646static uint32_t2647lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2648			  void *arg, uint32_t evt)2649{2650	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2651 2652	/* flush the target */2653	lpfc_sli_abort_iocb(vport, ndlp->nlp_sid, 0, LPFC_CTX_TGT);2654 2655	/* Send PRLO_ACC */2656	spin_lock_irq(&ndlp->lock);2657	ndlp->nlp_flag |= NLP_LOGO_ACC;2658	spin_unlock_irq(&ndlp->lock);2659	lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);2660 2661	/* Save ELS_CMD_PRLO as the last elscmd and then set to NPR.2662	 * lpfc_cmpl_els_logo_acc is expected to restart discovery.2663	 */2664	ndlp->nlp_last_elscmd = ELS_CMD_PRLO;2665	ndlp->nlp_prev_state = ndlp->nlp_state;2666 2667	lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE | LOG_ELS | LOG_DISCOVERY,2668			 "3422 DID x%06x nflag x%x lastels x%x ref cnt %u\n",2669			 ndlp->nlp_DID, ndlp->nlp_flag,2670			 ndlp->nlp_last_elscmd,2671			 kref_read(&ndlp->kref));2672 2673	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);2674 2675	return ndlp->nlp_state;2676}2677 2678static uint32_t2679lpfc_device_recov_mapped_node(struct lpfc_vport *vport,2680			      struct lpfc_nodelist *ndlp,2681			      void *arg,2682			      uint32_t evt)2683{2684	lpfc_disc_set_adisc(vport, ndlp);2685 2686	ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE;2687	lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);2688	spin_lock_irq(&ndlp->lock);2689	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);2690	ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);2691	spin_unlock_irq(&ndlp->lock);2692	return ndlp->nlp_state;2693}2694 2695static uint32_t2696lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2697			void *arg, uint32_t evt)2698{2699	struct lpfc_iocbq *cmdiocb  = (struct lpfc_iocbq *) arg;2700 2701	/* Ignore PLOGI if we have an outstanding LOGO */2702	if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC))2703		return ndlp->nlp_state;2704	if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {2705		lpfc_cancel_retry_delay_tmo(vport, ndlp);2706		spin_lock_irq(&ndlp->lock);2707		ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC);2708		spin_unlock_irq(&ndlp->lock);2709	} else if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {2710		/* send PLOGI immediately, move to PLOGI issue state */2711		if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {2712			ndlp->nlp_prev_state = NLP_STE_NPR_NODE;2713			lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);2714			lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);2715		}2716	}2717	return ndlp->nlp_state;2718}2719 2720static uint32_t2721lpfc_rcv_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2722		       void *arg, uint32_t evt)2723{2724	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2725	struct ls_rjt     stat;2726 2727	memset(&stat, 0, sizeof (struct ls_rjt));2728	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;2729	stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;2730	lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);2731 2732	if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {2733		/*2734		 * ADISC nodes will be handled in regular discovery path after2735		 * receiving response from NS.2736		 *2737		 * For other nodes, Send PLOGI to trigger an implicit LOGO.2738		 */2739		if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {2740			ndlp->nlp_prev_state = NLP_STE_NPR_NODE;2741			lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);2742			lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);2743		}2744	}2745	return ndlp->nlp_state;2746}2747 2748static uint32_t2749lpfc_rcv_logo_npr_node(struct lpfc_vport *vport,  struct lpfc_nodelist *ndlp,2750		       void *arg, uint32_t evt)2751{2752	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2753 2754	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);2755	return ndlp->nlp_state;2756}2757 2758static uint32_t2759lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2760			 void *arg, uint32_t evt)2761{2762	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2763 2764	lpfc_rcv_padisc(vport, ndlp, cmdiocb);2765	/*2766	 * Do not start discovery if discovery is about to start2767	 * or discovery in progress for this node. Starting discovery2768	 * here will affect the counting of discovery threads.2769	 */2770	if (!(ndlp->nlp_flag & NLP_DELAY_TMO) &&2771	    !(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {2772		/*2773		 * ADISC nodes will be handled in regular discovery path after2774		 * receiving response from NS.2775		 *2776		 * For other nodes, Send PLOGI to trigger an implicit LOGO.2777		 */2778		if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {2779			ndlp->nlp_prev_state = NLP_STE_NPR_NODE;2780			lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);2781			lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);2782		}2783	}2784	return ndlp->nlp_state;2785}2786 2787static uint32_t2788lpfc_rcv_prlo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2789		       void *arg, uint32_t evt)2790{2791	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;2792 2793	spin_lock_irq(&ndlp->lock);2794	ndlp->nlp_flag |= NLP_LOGO_ACC;2795	spin_unlock_irq(&ndlp->lock);2796 2797	lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);2798 2799	if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) {2800		mod_timer(&ndlp->nlp_delayfunc,2801			  jiffies + msecs_to_jiffies(1000 * 1));2802		spin_lock_irq(&ndlp->lock);2803		ndlp->nlp_flag |= NLP_DELAY_TMO;2804		ndlp->nlp_flag &= ~NLP_NPR_ADISC;2805		spin_unlock_irq(&ndlp->lock);2806		ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;2807	} else {2808		spin_lock_irq(&ndlp->lock);2809		ndlp->nlp_flag &= ~NLP_NPR_ADISC;2810		spin_unlock_irq(&ndlp->lock);2811	}2812	return ndlp->nlp_state;2813}2814 2815static uint32_t2816lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2817			 void *arg, uint32_t evt)2818{2819	struct lpfc_hba *phba = vport->phba;2820	struct lpfc_iocbq *cmdiocb, *rspiocb;2821	u32 ulp_status;2822 2823	cmdiocb = (struct lpfc_iocbq *) arg;2824	rspiocb = cmdiocb->rsp_iocb;2825 2826	ulp_status = get_job_ulpstatus(phba, rspiocb);2827 2828	if (ulp_status)2829		return NLP_STE_FREED_NODE;2830 2831	return ndlp->nlp_state;2832}2833 2834static uint32_t2835lpfc_cmpl_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2836			void *arg, uint32_t evt)2837{2838	struct lpfc_hba *phba = vport->phba;2839	struct lpfc_iocbq *cmdiocb, *rspiocb;2840	u32 ulp_status;2841 2842	cmdiocb = (struct lpfc_iocbq *) arg;2843	rspiocb = cmdiocb->rsp_iocb;2844 2845	ulp_status = get_job_ulpstatus(phba, rspiocb);2846 2847	if (ulp_status && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {2848		lpfc_drop_node(vport, ndlp);2849		return NLP_STE_FREED_NODE;2850	}2851	return ndlp->nlp_state;2852}2853 2854static uint32_t2855lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2856			void *arg, uint32_t evt)2857{2858	/* For the fabric port just clear the fc flags. */2859	if (ndlp->nlp_DID == Fabric_DID) {2860		clear_bit(FC_FABRIC, &vport->fc_flag);2861		clear_bit(FC_PUBLIC_LOOP, &vport->fc_flag);2862	}2863	lpfc_unreg_rpi(vport, ndlp);2864	return ndlp->nlp_state;2865}2866 2867static uint32_t2868lpfc_cmpl_adisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2869			 void *arg, uint32_t evt)2870{2871	struct lpfc_hba *phba = vport->phba;2872	struct lpfc_iocbq *cmdiocb, *rspiocb;2873	u32 ulp_status;2874 2875	cmdiocb = (struct lpfc_iocbq *) arg;2876	rspiocb = cmdiocb->rsp_iocb;2877 2878	ulp_status = get_job_ulpstatus(phba, rspiocb);2879 2880	if (ulp_status && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {2881		lpfc_drop_node(vport, ndlp);2882		return NLP_STE_FREED_NODE;2883	}2884	return ndlp->nlp_state;2885}2886 2887static uint32_t2888lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport,2889			    struct lpfc_nodelist *ndlp,2890			    void *arg, uint32_t evt)2891{2892	LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;2893	MAILBOX_t    *mb = &pmb->u.mb;2894 2895	if (!mb->mbxStatus) {2896		/* SLI4 ports have preallocated logical rpis. */2897		if (vport->phba->sli_rev < LPFC_SLI_REV4)2898			ndlp->nlp_rpi = mb->un.varWords[0];2899		ndlp->nlp_flag |= NLP_RPI_REGISTERED;2900		if (ndlp->nlp_flag & NLP_LOGO_ACC) {2901			lpfc_unreg_rpi(vport, ndlp);2902		}2903	} else {2904		if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {2905			lpfc_drop_node(vport, ndlp);2906			return NLP_STE_FREED_NODE;2907		}2908	}2909	return ndlp->nlp_state;2910}2911 2912static uint32_t2913lpfc_device_rm_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2914			void *arg, uint32_t evt)2915{2916	if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {2917		spin_lock_irq(&ndlp->lock);2918		ndlp->nlp_flag |= NLP_NODEV_REMOVE;2919		spin_unlock_irq(&ndlp->lock);2920		return ndlp->nlp_state;2921	}2922	lpfc_drop_node(vport, ndlp);2923	return NLP_STE_FREED_NODE;2924}2925 2926static uint32_t2927lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,2928			   void *arg, uint32_t evt)2929{2930	/* Don't do anything that disrupts the RSCN unless lpfc is unloading. */2931	if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag))2932		return ndlp->nlp_state;2933 2934	lpfc_cancel_retry_delay_tmo(vport, ndlp);2935	spin_lock_irq(&ndlp->lock);2936	ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);2937	ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);2938	spin_unlock_irq(&ndlp->lock);2939	return ndlp->nlp_state;2940}2941 2942 2943/* This next section defines the NPort Discovery State Machine */2944 2945/* There are 4 different double linked lists nodelist entries can reside on.2946 * The plogi list and adisc list are used when Link Up discovery or RSCN2947 * processing is needed. Each list holds the nodes that we will send PLOGI2948 * or ADISC on. These lists will keep track of what nodes will be effected2949 * by an RSCN, or a Link Up (Typically, all nodes are effected on Link Up).2950 * The unmapped_list will contain all nodes that we have successfully logged2951 * into at the Fibre Channel level. The mapped_list will contain all nodes2952 * that are mapped FCP targets.2953 */2954/*2955 * The bind list is a list of undiscovered (potentially non-existent) nodes2956 * that we have saved binding information on. This information is used when2957 * nodes transition from the unmapped to the mapped list.2958 */2959/* For UNUSED_NODE state, the node has just been allocated .2960 * For PLOGI_ISSUE and REG_LOGIN_ISSUE, the node is on2961 * the PLOGI list. For REG_LOGIN_COMPL, the node is taken off the PLOGI list2962 * and put on the unmapped list. For ADISC processing, the node is taken off2963 * the ADISC list and placed on either the mapped or unmapped list (depending2964 * on its previous state). Once on the unmapped list, a PRLI is issued and the2965 * state changed to PRLI_ISSUE. When the PRLI completion occurs, the state is2966 * changed to UNMAPPED_NODE. If the completion indicates a mapped2967 * node, the node is taken off the unmapped list. The binding list is checked2968 * for a valid binding, or a binding is automatically assigned. If binding2969 * assignment is unsuccessful, the node is left on the unmapped list. If2970 * binding assignment is successful, the associated binding list entry (if2971 * any) is removed, and the node is placed on the mapped list.2972 */2973/*2974 * For a Link Down, all nodes on the ADISC, PLOGI, unmapped or mapped2975 * lists will receive a DEVICE_RECOVERY event. If the linkdown or devloss timers2976 * expire, all effected nodes will receive a DEVICE_RM event.2977 */2978/*2979 * For a Link Up or RSCN, all nodes will move from the mapped / unmapped lists2980 * to either the ADISC or PLOGI list.  After a Nameserver query or ALPA loopmap2981 * check, additional nodes may be added or removed (via DEVICE_RM) to / from2982 * the PLOGI or ADISC lists. Once the PLOGI and ADISC lists are populated,2983 * we will first process the ADISC list.  32 entries are processed initially and2984 * ADISC is initited for each one.  Completions / Events for each node are2985 * funnelled thru the state machine.  As each node finishes ADISC processing, it2986 * starts ADISC for any nodes waiting for ADISC processing. If no nodes are2987 * waiting, and the ADISC list count is identically 0, then we are done. For2988 * Link Up discovery, since all nodes on the PLOGI list are UNREG_LOGIN'ed, we2989 * can issue a CLEAR_LA and reenable Link Events. Next we will process the PLOGI2990 * list.  32 entries are processed initially and PLOGI is initited for each one.2991 * Completions / Events for each node are funnelled thru the state machine.  As2992 * each node finishes PLOGI processing, it starts PLOGI for any nodes waiting2993 * for PLOGI processing. If no nodes are waiting, and the PLOGI list count is2994 * indentically 0, then we are done. We have now completed discovery / RSCN2995 * handling. Upon completion, ALL nodes should be on either the mapped or2996 * unmapped lists.2997 */2998 2999static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])3000     (struct lpfc_vport *, struct lpfc_nodelist *, void *, uint32_t) = {3001	/* Action routine                  Event       Current State  */3002	lpfc_rcv_plogi_unused_node,	/* RCV_PLOGI   UNUSED_NODE    */3003	lpfc_rcv_els_unused_node,	/* RCV_PRLI        */3004	lpfc_rcv_logo_unused_node,	/* RCV_LOGO        */3005	lpfc_rcv_els_unused_node,	/* RCV_ADISC       */3006	lpfc_rcv_els_unused_node,	/* RCV_PDISC       */3007	lpfc_rcv_els_unused_node,	/* RCV_PRLO        */3008	lpfc_disc_illegal,		/* CMPL_PLOGI      */3009	lpfc_disc_illegal,		/* CMPL_PRLI       */3010	lpfc_cmpl_logo_unused_node,	/* CMPL_LOGO       */3011	lpfc_disc_illegal,		/* CMPL_ADISC      */3012	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */3013	lpfc_device_rm_unused_node,	/* DEVICE_RM       */3014	lpfc_device_recov_unused_node,	/* DEVICE_RECOVERY */3015 3016	lpfc_rcv_plogi_plogi_issue,	/* RCV_PLOGI   PLOGI_ISSUE    */3017	lpfc_rcv_prli_plogi_issue,	/* RCV_PRLI        */3018	lpfc_rcv_logo_plogi_issue,	/* RCV_LOGO        */3019	lpfc_rcv_els_plogi_issue,	/* RCV_ADISC       */3020	lpfc_rcv_els_plogi_issue,	/* RCV_PDISC       */3021	lpfc_rcv_els_plogi_issue,	/* RCV_PRLO        */3022	lpfc_cmpl_plogi_plogi_issue,	/* CMPL_PLOGI      */3023	lpfc_disc_illegal,		/* CMPL_PRLI       */3024	lpfc_cmpl_logo_plogi_issue,	/* CMPL_LOGO       */3025	lpfc_disc_illegal,		/* CMPL_ADISC      */3026	lpfc_cmpl_reglogin_plogi_issue,/* CMPL_REG_LOGIN  */3027	lpfc_device_rm_plogi_issue,	/* DEVICE_RM       */3028	lpfc_device_recov_plogi_issue,	/* DEVICE_RECOVERY */3029 3030	lpfc_rcv_plogi_adisc_issue,	/* RCV_PLOGI   ADISC_ISSUE    */3031	lpfc_rcv_prli_adisc_issue,	/* RCV_PRLI        */3032	lpfc_rcv_logo_adisc_issue,	/* RCV_LOGO        */3033	lpfc_rcv_padisc_adisc_issue,	/* RCV_ADISC       */3034	lpfc_rcv_padisc_adisc_issue,	/* RCV_PDISC       */3035	lpfc_rcv_prlo_adisc_issue,	/* RCV_PRLO        */3036	lpfc_disc_illegal,		/* CMPL_PLOGI      */3037	lpfc_disc_illegal,		/* CMPL_PRLI       */3038	lpfc_disc_illegal,		/* CMPL_LOGO       */3039	lpfc_cmpl_adisc_adisc_issue,	/* CMPL_ADISC      */3040	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */3041	lpfc_device_rm_adisc_issue,	/* DEVICE_RM       */3042	lpfc_device_recov_adisc_issue,	/* DEVICE_RECOVERY */3043 3044	lpfc_rcv_plogi_reglogin_issue,	/* RCV_PLOGI  REG_LOGIN_ISSUE */3045	lpfc_rcv_prli_reglogin_issue,	/* RCV_PLOGI       */3046	lpfc_rcv_logo_reglogin_issue,	/* RCV_LOGO        */3047	lpfc_rcv_padisc_reglogin_issue,	/* RCV_ADISC       */3048	lpfc_rcv_padisc_reglogin_issue,	/* RCV_PDISC       */3049	lpfc_rcv_prlo_reglogin_issue,	/* RCV_PRLO        */3050	lpfc_cmpl_plogi_illegal,	/* CMPL_PLOGI      */3051	lpfc_disc_illegal,		/* CMPL_PRLI       */3052	lpfc_disc_illegal,		/* CMPL_LOGO       */3053	lpfc_disc_illegal,		/* CMPL_ADISC      */3054	lpfc_cmpl_reglogin_reglogin_issue,/* CMPL_REG_LOGIN  */3055	lpfc_device_rm_reglogin_issue,	/* DEVICE_RM       */3056	lpfc_device_recov_reglogin_issue,/* DEVICE_RECOVERY */3057 3058	lpfc_rcv_plogi_prli_issue,	/* RCV_PLOGI   PRLI_ISSUE     */3059	lpfc_rcv_prli_prli_issue,	/* RCV_PRLI        */3060	lpfc_rcv_logo_prli_issue,	/* RCV_LOGO        */3061	lpfc_rcv_padisc_prli_issue,	/* RCV_ADISC       */3062	lpfc_rcv_padisc_prli_issue,	/* RCV_PDISC       */3063	lpfc_rcv_prlo_prli_issue,	/* RCV_PRLO        */3064	lpfc_cmpl_plogi_illegal,	/* CMPL_PLOGI      */3065	lpfc_cmpl_prli_prli_issue,	/* CMPL_PRLI       */3066	lpfc_disc_illegal,		/* CMPL_LOGO       */3067	lpfc_disc_illegal,		/* CMPL_ADISC      */3068	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */3069	lpfc_device_rm_prli_issue,	/* DEVICE_RM       */3070	lpfc_device_recov_prli_issue,	/* DEVICE_RECOVERY */3071 3072	lpfc_rcv_plogi_logo_issue,	/* RCV_PLOGI   LOGO_ISSUE     */3073	lpfc_rcv_prli_logo_issue,	/* RCV_PRLI        */3074	lpfc_rcv_logo_logo_issue,	/* RCV_LOGO        */3075	lpfc_rcv_padisc_logo_issue,	/* RCV_ADISC       */3076	lpfc_rcv_padisc_logo_issue,	/* RCV_PDISC       */3077	lpfc_rcv_prlo_logo_issue,	/* RCV_PRLO        */3078	lpfc_cmpl_plogi_illegal,	/* CMPL_PLOGI      */3079	lpfc_disc_illegal,		/* CMPL_PRLI       */3080	lpfc_cmpl_logo_logo_issue,	/* CMPL_LOGO       */3081	lpfc_disc_illegal,		/* CMPL_ADISC      */3082	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */3083	lpfc_device_rm_logo_issue,	/* DEVICE_RM       */3084	lpfc_device_recov_logo_issue,	/* DEVICE_RECOVERY */3085 3086	lpfc_rcv_plogi_unmap_node,	/* RCV_PLOGI   UNMAPPED_NODE  */3087	lpfc_rcv_prli_unmap_node,	/* RCV_PRLI        */3088	lpfc_rcv_logo_unmap_node,	/* RCV_LOGO        */3089	lpfc_rcv_padisc_unmap_node,	/* RCV_ADISC       */3090	lpfc_rcv_padisc_unmap_node,	/* RCV_PDISC       */3091	lpfc_rcv_prlo_unmap_node,	/* RCV_PRLO        */3092	lpfc_disc_illegal,		/* CMPL_PLOGI      */3093	lpfc_disc_illegal,		/* CMPL_PRLI       */3094	lpfc_disc_illegal,		/* CMPL_LOGO       */3095	lpfc_disc_illegal,		/* CMPL_ADISC      */3096	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */3097	lpfc_device_rm_unmap_node,	/* DEVICE_RM       */3098	lpfc_device_recov_unmap_node,	/* DEVICE_RECOVERY */3099 3100	lpfc_rcv_plogi_mapped_node,	/* RCV_PLOGI   MAPPED_NODE    */3101	lpfc_rcv_prli_mapped_node,	/* RCV_PRLI        */3102	lpfc_rcv_logo_mapped_node,	/* RCV_LOGO        */3103	lpfc_rcv_padisc_mapped_node,	/* RCV_ADISC       */3104	lpfc_rcv_padisc_mapped_node,	/* RCV_PDISC       */3105	lpfc_rcv_prlo_mapped_node,	/* RCV_PRLO        */3106	lpfc_disc_illegal,		/* CMPL_PLOGI      */3107	lpfc_disc_illegal,		/* CMPL_PRLI       */3108	lpfc_disc_illegal,		/* CMPL_LOGO       */3109	lpfc_disc_illegal,		/* CMPL_ADISC      */3110	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */3111	lpfc_disc_illegal,		/* DEVICE_RM       */3112	lpfc_device_recov_mapped_node,	/* DEVICE_RECOVERY */3113 3114	lpfc_rcv_plogi_npr_node,        /* RCV_PLOGI   NPR_NODE    */3115	lpfc_rcv_prli_npr_node,         /* RCV_PRLI        */3116	lpfc_rcv_logo_npr_node,         /* RCV_LOGO        */3117	lpfc_rcv_padisc_npr_node,       /* RCV_ADISC       */3118	lpfc_rcv_padisc_npr_node,       /* RCV_PDISC       */3119	lpfc_rcv_prlo_npr_node,         /* RCV_PRLO        */3120	lpfc_cmpl_plogi_npr_node,	/* CMPL_PLOGI      */3121	lpfc_cmpl_prli_npr_node,	/* CMPL_PRLI       */3122	lpfc_cmpl_logo_npr_node,        /* CMPL_LOGO       */3123	lpfc_cmpl_adisc_npr_node,       /* CMPL_ADISC      */3124	lpfc_cmpl_reglogin_npr_node,    /* CMPL_REG_LOGIN  */3125	lpfc_device_rm_npr_node,        /* DEVICE_RM       */3126	lpfc_device_recov_npr_node,     /* DEVICE_RECOVERY */3127};3128 3129int3130lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,3131			void *arg, uint32_t evt)3132{3133	uint32_t cur_state, rc;3134	uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *,3135			 uint32_t);3136	uint32_t got_ndlp = 0;3137	uint32_t data1;3138 3139	if (lpfc_nlp_get(ndlp))3140		got_ndlp = 1;3141 3142	cur_state = ndlp->nlp_state;3143 3144	data1 = (((uint32_t)ndlp->nlp_fc4_type << 16) |3145		((uint32_t)ndlp->nlp_type));3146	/* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */3147	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,3148			 "0211 DSM in event x%x on NPort x%x in "3149			 "state %d rpi x%x Data: x%x x%x\n",3150			 evt, ndlp->nlp_DID, cur_state, ndlp->nlp_rpi,3151			 ndlp->nlp_flag, data1);3152 3153	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,3154		 "DSM in:          evt:%d ste:%d did:x%x",3155		evt, cur_state, ndlp->nlp_DID);3156 3157	func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt];3158	rc = (func) (vport, ndlp, arg, evt);3159 3160	/* DSM out state <rc> on NPort <nlp_DID> */3161	if (got_ndlp) {3162		data1 = (((uint32_t)ndlp->nlp_fc4_type << 16) |3163			((uint32_t)ndlp->nlp_type));3164		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,3165			 "0212 DSM out state %d on NPort x%x "3166			 "rpi x%x Data: x%x x%x\n",3167			 rc, ndlp->nlp_DID, ndlp->nlp_rpi, ndlp->nlp_flag,3168			 data1);3169 3170		lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,3171			"DSM out:         ste:%d did:x%x flg:x%x",3172			rc, ndlp->nlp_DID, ndlp->nlp_flag);3173		/* Decrement the ndlp reference count held for this function */3174		lpfc_nlp_put(ndlp);3175	} else {3176		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,3177			"0213 DSM out state %d on NPort free\n", rc);3178 3179		lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,3180			"DSM out:         ste:%d did:x%x flg:x%x",3181			rc, 0, 0);3182	}3183 3184	return rc;3185}3186