xref: /linux/drivers/scsi/lpfc/lpfc_nportdisc.c (revision 858259cf7d1c443c836a2022b78cb281f0a9b95e)
1 /*******************************************************************
2  * This file is part of the Emulex Linux Device Driver for         *
3  * Fibre Channel Host Bus Adapters.                                *
4  * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
5  * EMULEX and SLI are trademarks of Emulex.                        *
6  * www.emulex.com                                                  *
7  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
8  *                                                                 *
9  * This program is free software; you can redistribute it and/or   *
10  * modify it under the terms of version 2 of the GNU General       *
11  * Public License as published by the Free Software Foundation.    *
12  * This program is distributed in the hope that it will be useful. *
13  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
14  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
15  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
16  * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
17  * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
18  * more details, a copy of which can be found in the file COPYING  *
19  * included with this package.                                     *
20  *******************************************************************/
21 
22 #include <linux/blkdev.h>
23 #include <linux/pci.h>
24 #include <linux/interrupt.h>
25 
26 #include <scsi/scsi.h>
27 #include <scsi/scsi_device.h>
28 #include <scsi/scsi_host.h>
29 #include <scsi/scsi_transport_fc.h>
30 
31 #include "lpfc_hw.h"
32 #include "lpfc_sli.h"
33 #include "lpfc_disc.h"
34 #include "lpfc_scsi.h"
35 #include "lpfc.h"
36 #include "lpfc_logmsg.h"
37 #include "lpfc_crtn.h"
38 
39 
40 /* Called to verify a rcv'ed ADISC was intended for us. */
41 static int
42 lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
43 		 struct lpfc_name * nn, struct lpfc_name * pn)
44 {
45 	/* Compare the ADISC rsp WWNN / WWPN matches our internal node
46 	 * table entry for that node.
47 	 */
48 	if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0)
49 		return (0);
50 
51 	if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0)
52 		return (0);
53 
54 	/* we match, return success */
55 	return (1);
56 }
57 
58 
59 int
60 lpfc_check_sparm(struct lpfc_hba * phba,
61 		 struct lpfc_nodelist * ndlp, struct serv_parm * sp,
62 		 uint32_t class)
63 {
64 	volatile struct serv_parm *hsp = &phba->fc_sparam;
65 	/* First check for supported version */
66 
67 	/* Next check for class validity */
68 	if (sp->cls1.classValid) {
69 
70 		if (sp->cls1.rcvDataSizeMsb > hsp->cls1.rcvDataSizeMsb)
71 			sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
72 		if (sp->cls1.rcvDataSizeLsb > hsp->cls1.rcvDataSizeLsb)
73 			sp->cls1.rcvDataSizeLsb = hsp->cls1.rcvDataSizeLsb;
74 	} else if (class == CLASS1) {
75 		return (0);
76 	}
77 
78 	if (sp->cls2.classValid) {
79 
80 		if (sp->cls2.rcvDataSizeMsb > hsp->cls2.rcvDataSizeMsb)
81 			sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
82 		if (sp->cls2.rcvDataSizeLsb > hsp->cls2.rcvDataSizeLsb)
83 			sp->cls2.rcvDataSizeLsb = hsp->cls2.rcvDataSizeLsb;
84 	} else if (class == CLASS2) {
85 		return (0);
86 	}
87 
88 	if (sp->cls3.classValid) {
89 
90 		if (sp->cls3.rcvDataSizeMsb > hsp->cls3.rcvDataSizeMsb)
91 			sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
92 		if (sp->cls3.rcvDataSizeLsb > hsp->cls3.rcvDataSizeLsb)
93 			sp->cls3.rcvDataSizeLsb = hsp->cls3.rcvDataSizeLsb;
94 	} else if (class == CLASS3) {
95 		return (0);
96 	}
97 
98 	if (sp->cmn.bbRcvSizeMsb > hsp->cmn.bbRcvSizeMsb)
99 		sp->cmn.bbRcvSizeMsb = hsp->cmn.bbRcvSizeMsb;
100 	if (sp->cmn.bbRcvSizeLsb > hsp->cmn.bbRcvSizeLsb)
101 		sp->cmn.bbRcvSizeLsb = hsp->cmn.bbRcvSizeLsb;
102 
103 	/* If check is good, copy wwpn wwnn into ndlp */
104 	memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));
105 	memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name));
106 	return (1);
107 }
108 
109 static void *
110 lpfc_check_elscmpl_iocb(struct lpfc_hba * phba,
111 		      struct lpfc_iocbq *cmdiocb,
112 		      struct lpfc_iocbq *rspiocb)
113 {
114 	struct lpfc_dmabuf *pcmd, *prsp;
115 	uint32_t *lp;
116 	void     *ptr = NULL;
117 	IOCB_t   *irsp;
118 
119 	irsp = &rspiocb->iocb;
120 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
121 
122 	/* For lpfc_els_abort, context2 could be zero'ed to delay
123 	 * freeing associated memory till after ABTS completes.
124 	 */
125 	if (pcmd) {
126 		prsp =  list_get_first(&pcmd->list, struct lpfc_dmabuf,
127 				       list);
128 		if (prsp) {
129 			lp = (uint32_t *) prsp->virt;
130 			ptr = (void *)((uint8_t *)lp + sizeof(uint32_t));
131 		}
132 	}
133 	else {
134 		/* Force ulpStatus error since we are returning NULL ptr */
135 		if (!(irsp->ulpStatus)) {
136 			irsp->ulpStatus = IOSTAT_LOCAL_REJECT;
137 			irsp->un.ulpWord[4] = IOERR_SLI_ABORTED;
138 		}
139 		ptr = NULL;
140 	}
141 	return (ptr);
142 }
143 
144 
145 /*
146  * Free resources / clean up outstanding I/Os
147  * associated with a LPFC_NODELIST entry. This
148  * routine effectively results in a "software abort".
149  */
150 int
151 lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
152 	int send_abts)
153 {
154 	struct lpfc_sli *psli;
155 	struct lpfc_sli_ring *pring;
156 	struct lpfc_iocbq *iocb, *next_iocb;
157 	IOCB_t *icmd;
158 	int    found = 0;
159 
160 	/* Abort outstanding I/O on NPort <nlp_DID> */
161 	lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
162 			"%d:0201 Abort outstanding I/O on NPort x%x "
163 			"Data: x%x x%x x%x\n",
164 			phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
165 			ndlp->nlp_state, ndlp->nlp_rpi);
166 
167 	psli = &phba->sli;
168 	pring = &psli->ring[LPFC_ELS_RING];
169 
170 	/* First check the txq */
171 	do {
172 		found = 0;
173 		spin_lock_irq(phba->host->host_lock);
174 		list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
175 			/* Check to see if iocb matches the nport we are looking
176 			   for */
177 			if ((lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))) {
178 				found = 1;
179 				/* It matches, so deque and call compl with an
180 				   error */
181 				list_del(&iocb->list);
182 				pring->txq_cnt--;
183 				if (iocb->iocb_cmpl) {
184 					icmd = &iocb->iocb;
185 					icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
186 					icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
187 					spin_unlock_irq(phba->host->host_lock);
188 					(iocb->iocb_cmpl) (phba, iocb, iocb);
189 					spin_lock_irq(phba->host->host_lock);
190 				} else
191 					lpfc_sli_release_iocbq(phba, iocb);
192 				break;
193 			}
194 		}
195 		spin_unlock_irq(phba->host->host_lock);
196 	} while (found);
197 
198 	/* Everything on txcmplq will be returned by firmware
199 	 * with a no rpi / linkdown / abort error.  For ring 0,
200 	 * ELS discovery, we want to get rid of it right here.
201 	 */
202 	/* Next check the txcmplq */
203 	do {
204 		found = 0;
205 		spin_lock_irq(phba->host->host_lock);
206 		list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq,
207 					 list) {
208 			/* Check to see if iocb matches the nport we are looking
209 			   for */
210 			if ((lpfc_check_sli_ndlp (phba, pring, iocb, ndlp))) {
211 				found = 1;
212 				/* It matches, so deque and call compl with an
213 				   error */
214 				list_del(&iocb->list);
215 				pring->txcmplq_cnt--;
216 
217 				icmd = &iocb->iocb;
218 				/* If the driver is completing an ELS
219 				 * command early, flush it out of the firmware.
220 				 */
221 				if (send_abts &&
222 				   (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) &&
223 				   (icmd->un.elsreq64.bdl.ulpIoTag32)) {
224 					lpfc_sli_issue_abort_iotag32(phba,
225 							     pring, iocb);
226 				}
227 				if (iocb->iocb_cmpl) {
228 					icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
229 					icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
230 					spin_unlock_irq(phba->host->host_lock);
231 					(iocb->iocb_cmpl) (phba, iocb, iocb);
232 					spin_lock_irq(phba->host->host_lock);
233 				} else
234 					lpfc_sli_release_iocbq(phba, iocb);
235 				break;
236 			}
237 		}
238 		spin_unlock_irq(phba->host->host_lock);
239 	} while(found);
240 
241 	/* If we are delaying issuing an ELS command, cancel it */
242 	if (ndlp->nlp_flag & NLP_DELAY_TMO) {
243 		ndlp->nlp_flag &= ~NLP_DELAY_TMO;
244 		del_timer_sync(&ndlp->nlp_delayfunc);
245 		if (!list_empty(&ndlp->els_retry_evt.evt_listp))
246 			list_del_init(&ndlp->els_retry_evt.evt_listp);
247 	}
248 	return (0);
249 }
250 
251 static int
252 lpfc_rcv_plogi(struct lpfc_hba * phba,
253 		      struct lpfc_nodelist * ndlp,
254 		      struct lpfc_iocbq *cmdiocb)
255 {
256 	struct lpfc_dmabuf *pcmd;
257 	uint32_t *lp;
258 	IOCB_t *icmd;
259 	struct serv_parm *sp;
260 	LPFC_MBOXQ_t *mbox;
261 	struct ls_rjt stat;
262 	int rc;
263 
264 	memset(&stat, 0, sizeof (struct ls_rjt));
265 	if (phba->hba_state <= LPFC_FLOGI) {
266 		/* Before responding to PLOGI, check for pt2pt mode.
267 		 * If we are pt2pt, with an outstanding FLOGI, abort
268 		 * the FLOGI and resend it first.
269 		 */
270 		if (phba->fc_flag & FC_PT2PT) {
271 			lpfc_els_abort_flogi(phba);
272 		        if (!(phba->fc_flag & FC_PT2PT_PLOGI)) {
273 				/* If the other side is supposed to initiate
274 				 * the PLOGI anyway, just ACC it now and
275 				 * move on with discovery.
276 				 */
277 				phba->fc_edtov = FF_DEF_EDTOV;
278 				phba->fc_ratov = FF_DEF_RATOV;
279 				/* Start discovery - this should just do
280 				   CLEAR_LA */
281 				lpfc_disc_start(phba);
282 			}
283 			else {
284 				lpfc_initial_flogi(phba);
285 			}
286 		}
287 		else {
288 			stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
289 			stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
290 			lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb,
291 					    ndlp);
292 			return 0;
293 		}
294 	}
295 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
296 	lp = (uint32_t *) pcmd->virt;
297 	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
298 	if ((lpfc_check_sparm(phba, ndlp, sp, CLASS3) == 0)) {
299 		/* Reject this request because invalid parameters */
300 		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
301 		stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
302 		lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
303 		return (0);
304 	}
305 	icmd = &cmdiocb->iocb;
306 
307 	/* PLOGI chkparm OK */
308 	lpfc_printf_log(phba,
309 			KERN_INFO,
310 			LOG_ELS,
311 			"%d:0114 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",
312 			phba->brd_no,
313 			ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag,
314 			ndlp->nlp_rpi);
315 
316 	if ((phba->cfg_fcp_class == 2) &&
317 	    (sp->cls2.classValid)) {
318 		ndlp->nlp_fcp_info |= CLASS2;
319 	} else {
320 		ndlp->nlp_fcp_info |= CLASS3;
321 	}
322 	ndlp->nlp_class_sup = 0;
323 	if (sp->cls1.classValid)
324 		ndlp->nlp_class_sup |= FC_COS_CLASS1;
325 	if (sp->cls2.classValid)
326 		ndlp->nlp_class_sup |= FC_COS_CLASS2;
327 	if (sp->cls3.classValid)
328 		ndlp->nlp_class_sup |= FC_COS_CLASS3;
329 	if (sp->cls4.classValid)
330 		ndlp->nlp_class_sup |= FC_COS_CLASS4;
331 	ndlp->nlp_maxframe =
332 		((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
333 
334 	/* no need to reg_login if we are already in one of these states */
335 	switch(ndlp->nlp_state) {
336 	case  NLP_STE_NPR_NODE:
337 		if (!(ndlp->nlp_flag & NLP_NPR_ADISC))
338 			break;
339 	case  NLP_STE_REG_LOGIN_ISSUE:
340 	case  NLP_STE_PRLI_ISSUE:
341 	case  NLP_STE_UNMAPPED_NODE:
342 	case  NLP_STE_MAPPED_NODE:
343 		lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0);
344 		return (1);
345 	}
346 
347 	if ((phba->fc_flag & FC_PT2PT)
348 	    && !(phba->fc_flag & FC_PT2PT_PLOGI)) {
349 		/* rcv'ed PLOGI decides what our NPortId will be */
350 		phba->fc_myDID = icmd->un.rcvels.parmRo;
351 		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
352 		if (mbox == NULL)
353 			goto out;
354 		lpfc_config_link(phba, mbox);
355 		mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
356 		rc = lpfc_sli_issue_mbox
357 			(phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB));
358 		if (rc == MBX_NOT_FINISHED) {
359 			mempool_free( mbox, phba->mbox_mem_pool);
360 			goto out;
361 		}
362 
363 		lpfc_can_disctmo(phba);
364 	}
365 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
366 	if (mbox == NULL)
367 		goto out;
368 
369 	if (lpfc_reg_login(phba, icmd->un.rcvels.remoteID,
370 			   (uint8_t *) sp, mbox, 0)) {
371 		mempool_free( mbox, phba->mbox_mem_pool);
372 		goto out;
373 	}
374 
375 	/* ACC PLOGI rsp command needs to execute first,
376 	 * queue this mbox command to be processed later.
377 	 */
378 	mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
379 	mbox->context2  = ndlp;
380 	ndlp->nlp_flag |= NLP_ACC_REGLOGIN;
381 
382 	/* If there is an outstanding PLOGI issued, abort it before
383 	 * sending ACC rsp to PLOGI recieved.
384 	 */
385 	if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) {
386 		/* software abort outstanding PLOGI */
387 		lpfc_els_abort(phba, ndlp, 1);
388 	}
389 	ndlp->nlp_flag |= NLP_RCV_PLOGI;
390 	lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0);
391 	return (1);
392 
393 out:
394 	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
395 	stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE;
396 	lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
397 	return (0);
398 }
399 
400 static int
401 lpfc_rcv_padisc(struct lpfc_hba * phba,
402 		struct lpfc_nodelist * ndlp,
403 		struct lpfc_iocbq *cmdiocb)
404 {
405 	struct lpfc_dmabuf *pcmd;
406 	struct serv_parm *sp;
407 	struct lpfc_name *pnn, *ppn;
408 	struct ls_rjt stat;
409 	ADISC *ap;
410 	IOCB_t *icmd;
411 	uint32_t *lp;
412 	uint32_t cmd;
413 
414 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
415 	lp = (uint32_t *) pcmd->virt;
416 
417 	cmd = *lp++;
418 	if (cmd == ELS_CMD_ADISC) {
419 		ap = (ADISC *) lp;
420 		pnn = (struct lpfc_name *) & ap->nodeName;
421 		ppn = (struct lpfc_name *) & ap->portName;
422 	} else {
423 		sp = (struct serv_parm *) lp;
424 		pnn = (struct lpfc_name *) & sp->nodeName;
425 		ppn = (struct lpfc_name *) & sp->portName;
426 	}
427 
428 	icmd = &cmdiocb->iocb;
429 	if ((icmd->ulpStatus == 0) &&
430 	    (lpfc_check_adisc(phba, ndlp, pnn, ppn))) {
431 		if (cmd == ELS_CMD_ADISC) {
432 			lpfc_els_rsp_adisc_acc(phba, cmdiocb, ndlp);
433 		}
434 		else {
435 			lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp,
436 				NULL, 0);
437 		}
438 		return (1);
439 	}
440 	/* Reject this request because invalid parameters */
441 	stat.un.b.lsRjtRsvd0 = 0;
442 	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
443 	stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
444 	stat.un.b.vendorUnique = 0;
445 	lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
446 
447 	ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI;
448 	/* 1 sec timeout */
449 	mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
450 
451 	spin_lock_irq(phba->host->host_lock);
452 	ndlp->nlp_flag |= NLP_DELAY_TMO;
453 	spin_unlock_irq(phba->host->host_lock);
454 	ndlp->nlp_state = NLP_STE_NPR_NODE;
455 	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
456 	return (0);
457 }
458 
459 static int
460 lpfc_rcv_logo(struct lpfc_hba * phba,
461 		      struct lpfc_nodelist * ndlp,
462 		      struct lpfc_iocbq *cmdiocb)
463 {
464 	/* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */
465 	/* Only call LOGO ACC for first LOGO, this avoids sending unnecessary
466 	 * PLOGIs during LOGO storms from a device.
467 	 */
468 	ndlp->nlp_flag |= NLP_LOGO_ACC;
469 	lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
470 
471 	if (!(ndlp->nlp_type & NLP_FABRIC)) {
472 		/* Only try to re-login if this is NOT a Fabric Node */
473 		ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI;
474 		mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
475 		spin_lock_irq(phba->host->host_lock);
476 		ndlp->nlp_flag |= NLP_DELAY_TMO;
477 		spin_unlock_irq(phba->host->host_lock);
478 	}
479 
480 	ndlp->nlp_state = NLP_STE_NPR_NODE;
481 	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
482 
483 	ndlp->nlp_flag &= ~NLP_NPR_ADISC;
484 	/* The driver has to wait until the ACC completes before it continues
485 	 * processing the LOGO.  The action will resume in
486 	 * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an
487 	 * unreg_login, the driver waits so the ACC does not get aborted.
488 	 */
489 	return (0);
490 }
491 
492 static void
493 lpfc_rcv_prli(struct lpfc_hba * phba,
494 		      struct lpfc_nodelist * ndlp,
495 		      struct lpfc_iocbq *cmdiocb)
496 {
497 	struct lpfc_dmabuf *pcmd;
498 	uint32_t *lp;
499 	PRLI *npr;
500 	struct fc_rport *rport = ndlp->rport;
501 	u32 roles;
502 
503 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
504 	lp = (uint32_t *) pcmd->virt;
505 	npr = (PRLI *) ((uint8_t *) lp + sizeof (uint32_t));
506 
507 	ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
508 	ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
509 	if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
510 	    (npr->prliType == PRLI_FCP_TYPE)) {
511 		if (npr->initiatorFunc)
512 			ndlp->nlp_type |= NLP_FCP_INITIATOR;
513 		if (npr->targetFunc)
514 			ndlp->nlp_type |= NLP_FCP_TARGET;
515 		if (npr->Retry)
516 			ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
517 	}
518 	if (rport) {
519 		/* We need to update the rport role values */
520 		roles = FC_RPORT_ROLE_UNKNOWN;
521 		if (ndlp->nlp_type & NLP_FCP_INITIATOR)
522 			roles |= FC_RPORT_ROLE_FCP_INITIATOR;
523 		if (ndlp->nlp_type & NLP_FCP_TARGET)
524 			roles |= FC_RPORT_ROLE_FCP_TARGET;
525 		fc_remote_port_rolechg(rport, roles);
526 	}
527 }
528 
529 static uint32_t
530 lpfc_disc_set_adisc(struct lpfc_hba * phba,
531 		      struct lpfc_nodelist * ndlp)
532 {
533 	/* Check config parameter use-adisc or FCP-2 */
534 	if ((phba->cfg_use_adisc == 0) &&
535 		!(phba->fc_flag & FC_RSCN_MODE)) {
536 		if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE))
537 			return (0);
538 	}
539 	spin_lock_irq(phba->host->host_lock);
540 	ndlp->nlp_flag |= NLP_NPR_ADISC;
541 	spin_unlock_irq(phba->host->host_lock);
542 	return (1);
543 }
544 
545 static uint32_t
546 lpfc_disc_noop(struct lpfc_hba * phba,
547 		struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
548 {
549 	/* This routine does nothing, just return the current state */
550 	return (ndlp->nlp_state);
551 }
552 
553 static uint32_t
554 lpfc_disc_illegal(struct lpfc_hba * phba,
555 		   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
556 {
557 	lpfc_printf_log(phba,
558 			KERN_ERR,
559 			LOG_DISCOVERY,
560 			"%d:0253 Illegal State Transition: node x%x event x%x, "
561 			"state x%x Data: x%x x%x\n",
562 			phba->brd_no,
563 			ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
564 			ndlp->nlp_flag);
565 	return (ndlp->nlp_state);
566 }
567 
568 /* Start of Discovery State Machine routines */
569 
570 static uint32_t
571 lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba,
572 			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
573 {
574 	struct lpfc_iocbq *cmdiocb;
575 
576 	cmdiocb = (struct lpfc_iocbq *) arg;
577 
578 	if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
579 		ndlp->nlp_state = NLP_STE_UNUSED_NODE;
580 		lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
581 		return (ndlp->nlp_state);
582 	}
583 	lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
584 	return (NLP_STE_FREED_NODE);
585 }
586 
587 static uint32_t
588 lpfc_rcv_els_unused_node(struct lpfc_hba * phba,
589 			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
590 {
591 	lpfc_issue_els_logo(phba, ndlp, 0);
592 	lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
593 	return (ndlp->nlp_state);
594 }
595 
596 static uint32_t
597 lpfc_rcv_logo_unused_node(struct lpfc_hba * phba,
598 			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
599 {
600 	struct lpfc_iocbq     *cmdiocb;
601 
602 	cmdiocb = (struct lpfc_iocbq *) arg;
603 
604 	spin_lock_irq(phba->host->host_lock);
605 	ndlp->nlp_flag |= NLP_LOGO_ACC;
606 	spin_unlock_irq(phba->host->host_lock);
607 	lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
608 	lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
609 
610 	return (ndlp->nlp_state);
611 }
612 
613 static uint32_t
614 lpfc_cmpl_logo_unused_node(struct lpfc_hba * phba,
615 			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
616 {
617 	lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
618 	return (NLP_STE_FREED_NODE);
619 }
620 
621 static uint32_t
622 lpfc_device_rm_unused_node(struct lpfc_hba * phba,
623 			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
624 {
625 	lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
626 	return (NLP_STE_FREED_NODE);
627 }
628 
629 static uint32_t
630 lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
631 			   void *arg, uint32_t evt)
632 {
633 	struct lpfc_iocbq *cmdiocb = arg;
634 	struct lpfc_dmabuf *pcmd;
635 	struct serv_parm *sp;
636 	uint32_t *lp;
637 	struct ls_rjt stat;
638 	int port_cmp;
639 
640 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
641 	lp = (uint32_t *) pcmd->virt;
642 	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
643 
644 	memset(&stat, 0, sizeof (struct ls_rjt));
645 
646 	/* For a PLOGI, we only accept if our portname is less
647 	 * than the remote portname.
648 	 */
649 	phba->fc_stat.elsLogiCol++;
650 	port_cmp = memcmp(&phba->fc_portname, &sp->portName,
651 			  sizeof (struct lpfc_name));
652 
653 	if (port_cmp >= 0) {
654 		/* Reject this request because the remote node will accept
655 		   ours */
656 		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
657 		stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;
658 		lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
659 	}
660 	else {
661 		lpfc_rcv_plogi(phba, ndlp, cmdiocb);
662 	} /* if our portname was less */
663 
664 	return (ndlp->nlp_state);
665 }
666 
667 static uint32_t
668 lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba,
669 			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
670 {
671 	struct lpfc_iocbq     *cmdiocb;
672 
673 	cmdiocb = (struct lpfc_iocbq *) arg;
674 
675 	/* software abort outstanding PLOGI */
676 	lpfc_els_abort(phba, ndlp, 1);
677 	mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
678 	spin_lock_irq(phba->host->host_lock);
679 	ndlp->nlp_flag |= NLP_DELAY_TMO;
680 	spin_unlock_irq(phba->host->host_lock);
681 
682 	if (evt == NLP_EVT_RCV_LOGO) {
683 		lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
684 	}
685 	else {
686 		lpfc_issue_els_logo(phba, ndlp, 0);
687 	}
688 
689 	/* Put ndlp in npr list set plogi timer for 1 sec */
690 	ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI;
691 	ndlp->nlp_state = NLP_STE_NPR_NODE;
692 	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
693 
694 	return (ndlp->nlp_state);
695 }
696 
697 static uint32_t
698 lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
699 			    struct lpfc_nodelist * ndlp, void *arg,
700 			    uint32_t evt)
701 {
702 	struct lpfc_iocbq *cmdiocb, *rspiocb;
703 	struct lpfc_dmabuf *pcmd, *prsp;
704 	uint32_t *lp;
705 	IOCB_t *irsp;
706 	struct serv_parm *sp;
707 	LPFC_MBOXQ_t *mbox;
708 
709 	cmdiocb = (struct lpfc_iocbq *) arg;
710 	rspiocb = cmdiocb->context_un.rsp_iocb;
711 
712 	if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
713 		return (ndlp->nlp_state);
714 	}
715 
716 	irsp = &rspiocb->iocb;
717 
718 	if (irsp->ulpStatus)
719 		goto out;
720 
721 	pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
722 
723 	prsp = list_get_first(&pcmd->list,
724 			      struct lpfc_dmabuf,
725 			      list);
726 	lp = (uint32_t *) prsp->virt;
727 
728 	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
729 	if (!lpfc_check_sparm(phba, ndlp, sp, CLASS3))
730 		goto out;
731 
732 	/* PLOGI chkparm OK */
733 	lpfc_printf_log(phba,
734 			KERN_INFO,
735 			LOG_ELS,
736 			"%d:0121 PLOGI chkparm OK "
737 			"Data: x%x x%x x%x x%x\n",
738 			phba->brd_no,
739 			ndlp->nlp_DID, ndlp->nlp_state,
740 			ndlp->nlp_flag, ndlp->nlp_rpi);
741 
742 	if ((phba->cfg_fcp_class == 2) &&
743 	    (sp->cls2.classValid)) {
744 		ndlp->nlp_fcp_info |= CLASS2;
745 	} else {
746 		ndlp->nlp_fcp_info |= CLASS3;
747 	}
748 	ndlp->nlp_class_sup = 0;
749 	if (sp->cls1.classValid)
750 		ndlp->nlp_class_sup |= FC_COS_CLASS1;
751 	if (sp->cls2.classValid)
752 		ndlp->nlp_class_sup |= FC_COS_CLASS2;
753 	if (sp->cls3.classValid)
754 		ndlp->nlp_class_sup |= FC_COS_CLASS3;
755 	if (sp->cls4.classValid)
756 		ndlp->nlp_class_sup |= FC_COS_CLASS4;
757 	ndlp->nlp_maxframe =
758 		((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
759 		sp->cmn.bbRcvSizeLsb;
760 
761 	if (!(mbox = mempool_alloc(phba->mbox_mem_pool,
762 				   GFP_KERNEL)))
763 		goto out;
764 
765 	lpfc_unreg_rpi(phba, ndlp);
766 	if (lpfc_reg_login
767 	    (phba, irsp->un.elsreq64.remoteID,
768 	     (uint8_t *) sp, mbox, 0) == 0) {
769 		/* set_slim mailbox command needs to
770 		 * execute first, queue this command to
771 		 * be processed later.
772 		 */
773 		switch(ndlp->nlp_DID) {
774 		case NameServer_DID:
775 			mbox->mbox_cmpl =
776 				lpfc_mbx_cmpl_ns_reg_login;
777 			break;
778 		case FDMI_DID:
779 			mbox->mbox_cmpl =
780 				lpfc_mbx_cmpl_fdmi_reg_login;
781 			break;
782 		default:
783 			mbox->mbox_cmpl =
784 				lpfc_mbx_cmpl_reg_login;
785 		}
786 		mbox->context2 = ndlp;
787 		if (lpfc_sli_issue_mbox(phba, mbox,
788 					(MBX_NOWAIT | MBX_STOP_IOCB))
789 		    != MBX_NOT_FINISHED) {
790 			ndlp->nlp_state =
791 				NLP_STE_REG_LOGIN_ISSUE;
792 			lpfc_nlp_list(phba, ndlp,
793 				      NLP_REGLOGIN_LIST);
794 			return (ndlp->nlp_state);
795 		}
796 		mempool_free(mbox, phba->mbox_mem_pool);
797 	} else {
798 		mempool_free(mbox, phba->mbox_mem_pool);
799 	}
800 
801 
802  out:
803 	/* Free this node since the driver cannot login or has the wrong
804 	   sparm */
805 	lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
806 	return (NLP_STE_FREED_NODE);
807 }
808 
809 static uint32_t
810 lpfc_device_rm_plogi_issue(struct lpfc_hba * phba,
811 			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
812 {
813 	/* software abort outstanding PLOGI */
814 	lpfc_els_abort(phba, ndlp, 1);
815 
816 	lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
817 	return (NLP_STE_FREED_NODE);
818 }
819 
820 static uint32_t
821 lpfc_device_recov_plogi_issue(struct lpfc_hba * phba,
822 			    struct lpfc_nodelist * ndlp, void *arg,
823 			    uint32_t evt)
824 {
825 	/* software abort outstanding PLOGI */
826 	lpfc_els_abort(phba, ndlp, 1);
827 
828 	ndlp->nlp_state = NLP_STE_NPR_NODE;
829 	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
830 	spin_lock_irq(phba->host->host_lock);
831 	ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
832 	spin_unlock_irq(phba->host->host_lock);
833 
834 	return (ndlp->nlp_state);
835 }
836 
837 static uint32_t
838 lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba,
839 			    struct lpfc_nodelist * ndlp, void *arg,
840 			    uint32_t evt)
841 {
842 	struct lpfc_iocbq *cmdiocb;
843 
844 	/* software abort outstanding ADISC */
845 	lpfc_els_abort(phba, ndlp, 1);
846 
847 	cmdiocb = (struct lpfc_iocbq *) arg;
848 
849 	if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
850 		return (ndlp->nlp_state);
851 	}
852 	ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
853 	lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
854 	lpfc_issue_els_plogi(phba, ndlp, 0);
855 
856 	return (ndlp->nlp_state);
857 }
858 
859 static uint32_t
860 lpfc_rcv_prli_adisc_issue(struct lpfc_hba * phba,
861 			    struct lpfc_nodelist * ndlp, void *arg,
862 			    uint32_t evt)
863 {
864 	struct lpfc_iocbq *cmdiocb;
865 
866 	cmdiocb = (struct lpfc_iocbq *) arg;
867 
868 	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
869 	return (ndlp->nlp_state);
870 }
871 
872 static uint32_t
873 lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba,
874 			    struct lpfc_nodelist * ndlp, void *arg,
875 			    uint32_t evt)
876 {
877 	struct lpfc_iocbq *cmdiocb;
878 
879 	cmdiocb = (struct lpfc_iocbq *) arg;
880 
881 	/* software abort outstanding ADISC */
882 	lpfc_els_abort(phba, ndlp, 0);
883 
884 	lpfc_rcv_logo(phba, ndlp, cmdiocb);
885 	return (ndlp->nlp_state);
886 }
887 
888 static uint32_t
889 lpfc_rcv_padisc_adisc_issue(struct lpfc_hba * phba,
890 			    struct lpfc_nodelist * ndlp, void *arg,
891 			    uint32_t evt)
892 {
893 	struct lpfc_iocbq *cmdiocb;
894 
895 	cmdiocb = (struct lpfc_iocbq *) arg;
896 
897 	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
898 	return (ndlp->nlp_state);
899 }
900 
901 static uint32_t
902 lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba,
903 			    struct lpfc_nodelist * ndlp, void *arg,
904 			    uint32_t evt)
905 {
906 	struct lpfc_iocbq *cmdiocb;
907 
908 	cmdiocb = (struct lpfc_iocbq *) arg;
909 
910 	/* Treat like rcv logo */
911 	lpfc_rcv_logo(phba, ndlp, cmdiocb);
912 	return (ndlp->nlp_state);
913 }
914 
915 static uint32_t
916 lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba,
917 			    struct lpfc_nodelist * ndlp, void *arg,
918 			    uint32_t evt)
919 {
920 	struct lpfc_iocbq *cmdiocb, *rspiocb;
921 	IOCB_t *irsp;
922 	ADISC *ap;
923 
924 	cmdiocb = (struct lpfc_iocbq *) arg;
925 	rspiocb = cmdiocb->context_un.rsp_iocb;
926 
927 	ap = (ADISC *)lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);
928 	irsp = &rspiocb->iocb;
929 
930 	if ((irsp->ulpStatus) ||
931 		(!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) {
932 		ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI;
933 		/* 1 sec timeout */
934 		mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
935 		spin_lock_irq(phba->host->host_lock);
936 		ndlp->nlp_flag |= NLP_DELAY_TMO;
937 		spin_unlock_irq(phba->host->host_lock);
938 
939 		memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name));
940 		memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name));
941 
942 		ndlp->nlp_state = NLP_STE_NPR_NODE;
943 		lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
944 		lpfc_unreg_rpi(phba, ndlp);
945 		return (ndlp->nlp_state);
946 	}
947 	if (ndlp->nlp_type & NLP_FCP_TARGET) {
948 		ndlp->nlp_state = NLP_STE_MAPPED_NODE;
949 		lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST);
950 	} else {
951 		ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
952 		lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
953 	}
954 	return (ndlp->nlp_state);
955 }
956 
957 static uint32_t
958 lpfc_device_rm_adisc_issue(struct lpfc_hba * phba,
959 			    struct lpfc_nodelist * ndlp, void *arg,
960 			    uint32_t evt)
961 {
962 	/* software abort outstanding ADISC */
963 	lpfc_els_abort(phba, ndlp, 1);
964 
965 	lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
966 	return (NLP_STE_FREED_NODE);
967 }
968 
969 static uint32_t
970 lpfc_device_recov_adisc_issue(struct lpfc_hba * phba,
971 			    struct lpfc_nodelist * ndlp, void *arg,
972 			    uint32_t evt)
973 {
974 	/* software abort outstanding ADISC */
975 	lpfc_els_abort(phba, ndlp, 1);
976 
977 	ndlp->nlp_state = NLP_STE_NPR_NODE;
978 	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
979 	spin_lock_irq(phba->host->host_lock);
980 	ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
981 	spin_unlock_irq(phba->host->host_lock);
982 
983 	lpfc_disc_set_adisc(phba, ndlp);
984 	return (ndlp->nlp_state);
985 }
986 
987 static uint32_t
988 lpfc_rcv_plogi_reglogin_issue(struct lpfc_hba * phba,
989 			      struct lpfc_nodelist * ndlp, void *arg,
990 			      uint32_t evt)
991 {
992 	struct lpfc_iocbq *cmdiocb;
993 
994 	cmdiocb = (struct lpfc_iocbq *) arg;
995 
996 	lpfc_rcv_plogi(phba, ndlp, cmdiocb);
997 	return (ndlp->nlp_state);
998 }
999 
1000 static uint32_t
1001 lpfc_rcv_prli_reglogin_issue(struct lpfc_hba * phba,
1002 			     struct lpfc_nodelist * ndlp, void *arg,
1003 			     uint32_t evt)
1004 {
1005 	struct lpfc_iocbq *cmdiocb;
1006 
1007 	cmdiocb = (struct lpfc_iocbq *) arg;
1008 
1009 	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
1010 	return (ndlp->nlp_state);
1011 }
1012 
1013 static uint32_t
1014 lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba,
1015 			     struct lpfc_nodelist * ndlp, void *arg,
1016 			     uint32_t evt)
1017 {
1018 	struct lpfc_iocbq *cmdiocb;
1019 
1020 	cmdiocb = (struct lpfc_iocbq *) arg;
1021 
1022 	lpfc_rcv_logo(phba, ndlp, cmdiocb);
1023 	return (ndlp->nlp_state);
1024 }
1025 
1026 static uint32_t
1027 lpfc_rcv_padisc_reglogin_issue(struct lpfc_hba * phba,
1028 			       struct lpfc_nodelist * ndlp, void *arg,
1029 			       uint32_t evt)
1030 {
1031 	struct lpfc_iocbq *cmdiocb;
1032 
1033 	cmdiocb = (struct lpfc_iocbq *) arg;
1034 
1035 	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
1036 	return (ndlp->nlp_state);
1037 }
1038 
1039 static uint32_t
1040 lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba,
1041 			     struct lpfc_nodelist * ndlp, void *arg,
1042 			     uint32_t evt)
1043 {
1044 	struct lpfc_iocbq *cmdiocb;
1045 
1046 	cmdiocb = (struct lpfc_iocbq *) arg;
1047 	lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
1048 	return (ndlp->nlp_state);
1049 }
1050 
1051 static uint32_t
1052 lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
1053 				  struct lpfc_nodelist * ndlp,
1054 				  void *arg, uint32_t evt)
1055 {
1056 	LPFC_MBOXQ_t *pmb;
1057 	MAILBOX_t *mb;
1058 	uint32_t did;
1059 
1060 	pmb = (LPFC_MBOXQ_t *) arg;
1061 	mb = &pmb->mb;
1062 	did = mb->un.varWords[1];
1063 	if (mb->mbxStatus) {
1064 		/* RegLogin failed */
1065 		lpfc_printf_log(phba,
1066 				KERN_ERR,
1067 				LOG_DISCOVERY,
1068 				"%d:0246 RegLogin failed Data: x%x x%x x%x\n",
1069 				phba->brd_no,
1070 				did, mb->mbxStatus, phba->hba_state);
1071 
1072 		mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
1073 		spin_lock_irq(phba->host->host_lock);
1074 		ndlp->nlp_flag |= NLP_DELAY_TMO;
1075 		spin_unlock_irq(phba->host->host_lock);
1076 
1077 		lpfc_issue_els_logo(phba, ndlp, 0);
1078 		/* Put ndlp in npr list set plogi timer for 1 sec */
1079 		ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI;
1080 		ndlp->nlp_state = NLP_STE_NPR_NODE;
1081 		lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
1082 		return (ndlp->nlp_state);
1083 	}
1084 
1085 	ndlp->nlp_rpi = mb->un.varWords[0];
1086 
1087 	/* Only if we are not a fabric nport do we issue PRLI */
1088 	if (!(ndlp->nlp_type & NLP_FABRIC)) {
1089 		ndlp->nlp_state = NLP_STE_PRLI_ISSUE;
1090 		lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST);
1091 		lpfc_issue_els_prli(phba, ndlp, 0);
1092 	} else {
1093 		ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
1094 		lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
1095 	}
1096 	return (ndlp->nlp_state);
1097 }
1098 
1099 static uint32_t
1100 lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba,
1101 			      struct lpfc_nodelist * ndlp, void *arg,
1102 			      uint32_t evt)
1103 {
1104 	lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
1105 	return (NLP_STE_FREED_NODE);
1106 }
1107 
1108 static uint32_t
1109 lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba,
1110 			       struct lpfc_nodelist * ndlp, void *arg,
1111 			       uint32_t evt)
1112 {
1113 	ndlp->nlp_state = NLP_STE_NPR_NODE;
1114 	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
1115 	spin_lock_irq(phba->host->host_lock);
1116 	ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1117 	spin_unlock_irq(phba->host->host_lock);
1118 	return (ndlp->nlp_state);
1119 }
1120 
1121 static uint32_t
1122 lpfc_rcv_plogi_prli_issue(struct lpfc_hba * phba,
1123 			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1124 {
1125 	struct lpfc_iocbq *cmdiocb;
1126 
1127 	cmdiocb = (struct lpfc_iocbq *) arg;
1128 
1129 	lpfc_rcv_plogi(phba, ndlp, cmdiocb);
1130 	return (ndlp->nlp_state);
1131 }
1132 
1133 static uint32_t
1134 lpfc_rcv_prli_prli_issue(struct lpfc_hba * phba,
1135 			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1136 {
1137 	struct lpfc_iocbq *cmdiocb;
1138 
1139 	cmdiocb = (struct lpfc_iocbq *) arg;
1140 
1141 	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
1142 	return (ndlp->nlp_state);
1143 }
1144 
1145 static uint32_t
1146 lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba,
1147 			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1148 {
1149 	struct lpfc_iocbq *cmdiocb;
1150 
1151 	cmdiocb = (struct lpfc_iocbq *) arg;
1152 
1153 	/* Software abort outstanding PRLI before sending acc */
1154 	lpfc_els_abort(phba, ndlp, 1);
1155 
1156 	lpfc_rcv_logo(phba, ndlp, cmdiocb);
1157 	return (ndlp->nlp_state);
1158 }
1159 
1160 static uint32_t
1161 lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba,
1162 			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1163 {
1164 	struct lpfc_iocbq *cmdiocb;
1165 
1166 	cmdiocb = (struct lpfc_iocbq *) arg;
1167 
1168 	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
1169 	return (ndlp->nlp_state);
1170 }
1171 
1172 /* This routine is envoked when we rcv a PRLO request from a nport
1173  * we are logged into.  We should send back a PRLO rsp setting the
1174  * appropriate bits.
1175  * NEXT STATE = PRLI_ISSUE
1176  */
1177 static uint32_t
1178 lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba,
1179 			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1180 {
1181 	struct lpfc_iocbq *cmdiocb;
1182 
1183 	cmdiocb = (struct lpfc_iocbq *) arg;
1184 	lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
1185 	return (ndlp->nlp_state);
1186 }
1187 
1188 static uint32_t
1189 lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba,
1190 			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1191 {
1192 	struct lpfc_iocbq *cmdiocb, *rspiocb;
1193 	IOCB_t *irsp;
1194 	PRLI *npr;
1195 
1196 	cmdiocb = (struct lpfc_iocbq *) arg;
1197 	rspiocb = cmdiocb->context_un.rsp_iocb;
1198 	npr = (PRLI *)lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);
1199 
1200 	irsp = &rspiocb->iocb;
1201 	if (irsp->ulpStatus) {
1202 		ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
1203 		lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
1204 		return (ndlp->nlp_state);
1205 	}
1206 
1207 	/* Check out PRLI rsp */
1208 	ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
1209 	ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
1210 	if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
1211 	    (npr->prliType == PRLI_FCP_TYPE)) {
1212 		if (npr->initiatorFunc)
1213 			ndlp->nlp_type |= NLP_FCP_INITIATOR;
1214 		if (npr->targetFunc)
1215 			ndlp->nlp_type |= NLP_FCP_TARGET;
1216 		if (npr->Retry)
1217 			ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
1218 	}
1219 
1220 	ndlp->nlp_state = NLP_STE_MAPPED_NODE;
1221 	lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST);
1222 	return (ndlp->nlp_state);
1223 }
1224 
1225 /*! lpfc_device_rm_prli_issue
1226   *
1227   * \pre
1228   * \post
1229   * \param   phba
1230   * \param   ndlp
1231   * \param   arg
1232   * \param   evt
1233   * \return  uint32_t
1234   *
1235   * \b Description:
1236   *    This routine is envoked when we a request to remove a nport we are in the
1237   *    process of PRLIing. We should software abort outstanding prli, unreg
1238   *    login, send a logout. We will change node state to UNUSED_NODE, put it
1239   *    on plogi list so it can be freed when LOGO completes.
1240   *
1241   */
1242 static uint32_t
1243 lpfc_device_rm_prli_issue(struct lpfc_hba * phba,
1244 			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1245 {
1246 	/* software abort outstanding PRLI */
1247 	lpfc_els_abort(phba, ndlp, 1);
1248 
1249 	lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
1250 	return (NLP_STE_FREED_NODE);
1251 }
1252 
1253 
1254 /*! lpfc_device_recov_prli_issue
1255   *
1256   * \pre
1257   * \post
1258   * \param   phba
1259   * \param   ndlp
1260   * \param   arg
1261   * \param   evt
1262   * \return  uint32_t
1263   *
1264   * \b Description:
1265   *    The routine is envoked when the state of a device is unknown, like
1266   *    during a link down. We should remove the nodelist entry from the
1267   *    unmapped list, issue a UNREG_LOGIN, do a software abort of the
1268   *    outstanding PRLI command, then free the node entry.
1269   */
1270 static uint32_t
1271 lpfc_device_recov_prli_issue(struct lpfc_hba * phba,
1272 			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1273 {
1274 	/* software abort outstanding PRLI */
1275 	lpfc_els_abort(phba, ndlp, 1);
1276 
1277 	ndlp->nlp_state = NLP_STE_NPR_NODE;
1278 	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
1279 	spin_lock_irq(phba->host->host_lock);
1280 	ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1281 	spin_unlock_irq(phba->host->host_lock);
1282 	return (ndlp->nlp_state);
1283 }
1284 
1285 static uint32_t
1286 lpfc_rcv_plogi_unmap_node(struct lpfc_hba * phba,
1287 			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1288 {
1289 	struct lpfc_iocbq *cmdiocb;
1290 
1291 	cmdiocb = (struct lpfc_iocbq *) arg;
1292 
1293 	lpfc_rcv_plogi(phba, ndlp, cmdiocb);
1294 	return (ndlp->nlp_state);
1295 }
1296 
1297 static uint32_t
1298 lpfc_rcv_prli_unmap_node(struct lpfc_hba * phba,
1299 			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1300 {
1301 	struct lpfc_iocbq *cmdiocb;
1302 
1303 	cmdiocb = (struct lpfc_iocbq *) arg;
1304 
1305 	lpfc_rcv_prli(phba, ndlp, cmdiocb);
1306 	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
1307 	return (ndlp->nlp_state);
1308 }
1309 
1310 static uint32_t
1311 lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba,
1312 			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1313 {
1314 	struct lpfc_iocbq *cmdiocb;
1315 
1316 	cmdiocb = (struct lpfc_iocbq *) arg;
1317 
1318 	lpfc_rcv_logo(phba, ndlp, cmdiocb);
1319 	return (ndlp->nlp_state);
1320 }
1321 
1322 static uint32_t
1323 lpfc_rcv_padisc_unmap_node(struct lpfc_hba * phba,
1324 			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1325 {
1326 	struct lpfc_iocbq *cmdiocb;
1327 
1328 	cmdiocb = (struct lpfc_iocbq *) arg;
1329 
1330 	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
1331 	return (ndlp->nlp_state);
1332 }
1333 
1334 static uint32_t
1335 lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba,
1336 			 struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1337 {
1338 	struct lpfc_iocbq *cmdiocb;
1339 
1340 	cmdiocb = (struct lpfc_iocbq *) arg;
1341 
1342 	/* Treat like rcv logo */
1343 	lpfc_rcv_logo(phba, ndlp, cmdiocb);
1344 	return (ndlp->nlp_state);
1345 }
1346 
1347 static uint32_t
1348 lpfc_device_recov_unmap_node(struct lpfc_hba * phba,
1349 			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1350 {
1351 	ndlp->nlp_state = NLP_STE_NPR_NODE;
1352 	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
1353 	ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1354 	lpfc_disc_set_adisc(phba, ndlp);
1355 
1356 	return (ndlp->nlp_state);
1357 }
1358 
1359 static uint32_t
1360 lpfc_rcv_plogi_mapped_node(struct lpfc_hba * phba,
1361 			   struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1362 {
1363 	struct lpfc_iocbq *cmdiocb;
1364 
1365 	cmdiocb = (struct lpfc_iocbq *) arg;
1366 
1367 	lpfc_rcv_plogi(phba, ndlp, cmdiocb);
1368 	return (ndlp->nlp_state);
1369 }
1370 
1371 static uint32_t
1372 lpfc_rcv_prli_mapped_node(struct lpfc_hba * phba,
1373 			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1374 {
1375 	struct lpfc_iocbq *cmdiocb;
1376 
1377 	cmdiocb = (struct lpfc_iocbq *) arg;
1378 
1379 	lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
1380 	return (ndlp->nlp_state);
1381 }
1382 
1383 static uint32_t
1384 lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba,
1385 			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1386 {
1387 	struct lpfc_iocbq *cmdiocb;
1388 
1389 	cmdiocb = (struct lpfc_iocbq *) arg;
1390 
1391 	lpfc_rcv_logo(phba, ndlp, cmdiocb);
1392 	return (ndlp->nlp_state);
1393 }
1394 
1395 static uint32_t
1396 lpfc_rcv_padisc_mapped_node(struct lpfc_hba * phba,
1397 			    struct lpfc_nodelist * ndlp, void *arg,
1398 			    uint32_t evt)
1399 {
1400 	struct lpfc_iocbq *cmdiocb;
1401 
1402 	cmdiocb = (struct lpfc_iocbq *) arg;
1403 
1404 	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
1405 	return (ndlp->nlp_state);
1406 }
1407 
1408 static uint32_t
1409 lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba,
1410 			  struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1411 {
1412 	struct lpfc_iocbq *cmdiocb;
1413 
1414 	cmdiocb = (struct lpfc_iocbq *) arg;
1415 
1416 	/* flush the target */
1417 	spin_lock_irq(phba->host->host_lock);
1418 	lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
1419 			       ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
1420 	spin_unlock_irq(phba->host->host_lock);
1421 
1422 	/* Treat like rcv logo */
1423 	lpfc_rcv_logo(phba, ndlp, cmdiocb);
1424 	return (ndlp->nlp_state);
1425 }
1426 
1427 static uint32_t
1428 lpfc_device_recov_mapped_node(struct lpfc_hba * phba,
1429 			    struct lpfc_nodelist * ndlp, void *arg,
1430 			    uint32_t evt)
1431 {
1432 	ndlp->nlp_state = NLP_STE_NPR_NODE;
1433 	lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
1434 	spin_lock_irq(phba->host->host_lock);
1435 	ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1436 	spin_unlock_irq(phba->host->host_lock);
1437 	lpfc_disc_set_adisc(phba, ndlp);
1438 	return (ndlp->nlp_state);
1439 }
1440 
1441 static uint32_t
1442 lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba,
1443 			    struct lpfc_nodelist * ndlp, void *arg,
1444 			    uint32_t evt)
1445 {
1446 	struct lpfc_iocbq *cmdiocb;
1447 
1448 	cmdiocb = (struct lpfc_iocbq *) arg;
1449 
1450 	/* Ignore PLOGI if we have an outstanding LOGO */
1451 	if (ndlp->nlp_flag & NLP_LOGO_SND) {
1452 		return (ndlp->nlp_state);
1453 	}
1454 
1455 	if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
1456 		spin_lock_irq(phba->host->host_lock);
1457 		ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC);
1458 		spin_unlock_irq(phba->host->host_lock);
1459 		return (ndlp->nlp_state);
1460 	}
1461 
1462 	/* send PLOGI immediately, move to PLOGI issue state */
1463 	if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
1464 			ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
1465 			lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
1466 			lpfc_issue_els_plogi(phba, ndlp, 0);
1467 	}
1468 	return (ndlp->nlp_state);
1469 }
1470 
1471 static uint32_t
1472 lpfc_rcv_prli_npr_node(struct lpfc_hba * phba,
1473 			    struct lpfc_nodelist * ndlp, void *arg,
1474 			    uint32_t evt)
1475 {
1476 	struct lpfc_iocbq     *cmdiocb;
1477 	struct ls_rjt          stat;
1478 
1479 	cmdiocb = (struct lpfc_iocbq *) arg;
1480 
1481 	memset(&stat, 0, sizeof (struct ls_rjt));
1482 	stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
1483 	stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
1484 	lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
1485 
1486 	if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
1487 		if (ndlp->nlp_flag & NLP_NPR_ADISC) {
1488 			ndlp->nlp_state = NLP_STE_ADISC_ISSUE;
1489 			lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST);
1490 			lpfc_issue_els_adisc(phba, ndlp, 0);
1491 		} else {
1492 			ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
1493 			lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
1494 			lpfc_issue_els_plogi(phba, ndlp, 0);
1495 		}
1496 	}
1497 	return (ndlp->nlp_state);
1498 }
1499 
1500 static uint32_t
1501 lpfc_rcv_logo_npr_node(struct lpfc_hba * phba,
1502 			    struct lpfc_nodelist * ndlp, void *arg,
1503 			    uint32_t evt)
1504 {
1505 	struct lpfc_iocbq     *cmdiocb;
1506 
1507 	cmdiocb = (struct lpfc_iocbq *) arg;
1508 
1509 	lpfc_rcv_logo(phba, ndlp, cmdiocb);
1510 	return (ndlp->nlp_state);
1511 }
1512 
1513 static uint32_t
1514 lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba,
1515 			    struct lpfc_nodelist * ndlp, void *arg,
1516 			    uint32_t evt)
1517 {
1518 	struct lpfc_iocbq     *cmdiocb;
1519 
1520 	cmdiocb = (struct lpfc_iocbq *) arg;
1521 
1522 	lpfc_rcv_padisc(phba, ndlp, cmdiocb);
1523 
1524 	if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
1525 		if (ndlp->nlp_flag & NLP_NPR_ADISC) {
1526 			ndlp->nlp_state = NLP_STE_ADISC_ISSUE;
1527 			lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST);
1528 			lpfc_issue_els_adisc(phba, ndlp, 0);
1529 		} else {
1530 			ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
1531 			lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
1532 			lpfc_issue_els_plogi(phba, ndlp, 0);
1533 		}
1534 	}
1535 	return (ndlp->nlp_state);
1536 }
1537 
1538 static uint32_t
1539 lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba,
1540 			    struct lpfc_nodelist * ndlp, void *arg,
1541 			    uint32_t evt)
1542 {
1543 	struct lpfc_iocbq     *cmdiocb;
1544 
1545 	cmdiocb = (struct lpfc_iocbq *) arg;
1546 
1547 	lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
1548 
1549 	if (ndlp->nlp_flag & NLP_DELAY_TMO) {
1550 		if (ndlp->nlp_last_elscmd == (unsigned long)ELS_CMD_PLOGI) {
1551 			return (ndlp->nlp_state);
1552 		} else {
1553 			spin_lock_irq(phba->host->host_lock);
1554 			ndlp->nlp_flag &= ~NLP_DELAY_TMO;
1555 			spin_unlock_irq(phba->host->host_lock);
1556 			del_timer_sync(&ndlp->nlp_delayfunc);
1557 			if (!list_empty(&ndlp->els_retry_evt.evt_listp))
1558 				list_del_init(&ndlp->els_retry_evt.evt_listp);
1559 		}
1560 	}
1561 
1562 	ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
1563 	lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
1564 	lpfc_issue_els_plogi(phba, ndlp, 0);
1565 	return (ndlp->nlp_state);
1566 }
1567 
1568 static uint32_t
1569 lpfc_cmpl_logo_npr_node(struct lpfc_hba * phba,
1570 		struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1571 {
1572 	lpfc_unreg_rpi(phba, ndlp);
1573 	/* This routine does nothing, just return the current state */
1574 	return (ndlp->nlp_state);
1575 }
1576 
1577 static uint32_t
1578 lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba,
1579 			    struct lpfc_nodelist * ndlp, void *arg,
1580 			    uint32_t evt)
1581 {
1582 	LPFC_MBOXQ_t *pmb;
1583 	MAILBOX_t *mb;
1584 
1585 	pmb = (LPFC_MBOXQ_t *) arg;
1586 	mb = &pmb->mb;
1587 
1588 	ndlp->nlp_rpi = mb->un.varWords[0];
1589 
1590 	return (ndlp->nlp_state);
1591 }
1592 
1593 static uint32_t
1594 lpfc_device_rm_npr_node(struct lpfc_hba * phba,
1595 			    struct lpfc_nodelist * ndlp, void *arg,
1596 			    uint32_t evt)
1597 {
1598 	lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
1599 	return (NLP_STE_FREED_NODE);
1600 }
1601 
1602 static uint32_t
1603 lpfc_device_recov_npr_node(struct lpfc_hba * phba,
1604 			    struct lpfc_nodelist * ndlp, void *arg,
1605 			    uint32_t evt)
1606 {
1607 	spin_lock_irq(phba->host->host_lock);
1608 	ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1609 	spin_unlock_irq(phba->host->host_lock);
1610 	return (ndlp->nlp_state);
1611 }
1612 
1613 
1614 /* This next section defines the NPort Discovery State Machine */
1615 
1616 /* There are 4 different double linked lists nodelist entries can reside on.
1617  * The plogi list and adisc list are used when Link Up discovery or RSCN
1618  * processing is needed. Each list holds the nodes that we will send PLOGI
1619  * or ADISC on. These lists will keep track of what nodes will be effected
1620  * by an RSCN, or a Link Up (Typically, all nodes are effected on Link Up).
1621  * The unmapped_list will contain all nodes that we have successfully logged
1622  * into at the Fibre Channel level. The mapped_list will contain all nodes
1623  * that are mapped FCP targets.
1624  */
1625 /*
1626  * The bind list is a list of undiscovered (potentially non-existent) nodes
1627  * that we have saved binding information on. This information is used when
1628  * nodes transition from the unmapped to the mapped list.
1629  */
1630 /* For UNUSED_NODE state, the node has just been allocated .
1631  * For PLOGI_ISSUE and REG_LOGIN_ISSUE, the node is on
1632  * the PLOGI list. For REG_LOGIN_COMPL, the node is taken off the PLOGI list
1633  * and put on the unmapped list. For ADISC processing, the node is taken off
1634  * the ADISC list and placed on either the mapped or unmapped list (depending
1635  * on its previous state). Once on the unmapped list, a PRLI is issued and the
1636  * state changed to PRLI_ISSUE. When the PRLI completion occurs, the state is
1637  * changed to UNMAPPED_NODE. If the completion indicates a mapped
1638  * node, the node is taken off the unmapped list. The binding list is checked
1639  * for a valid binding, or a binding is automatically assigned. If binding
1640  * assignment is unsuccessful, the node is left on the unmapped list. If
1641  * binding assignment is successful, the associated binding list entry (if
1642  * any) is removed, and the node is placed on the mapped list.
1643  */
1644 /*
1645  * For a Link Down, all nodes on the ADISC, PLOGI, unmapped or mapped
1646  * lists will receive a DEVICE_RECOVERY event. If the linkdown or nodev timers
1647  * expire, all effected nodes will receive a DEVICE_RM event.
1648  */
1649 /*
1650  * For a Link Up or RSCN, all nodes will move from the mapped / unmapped lists
1651  * to either the ADISC or PLOGI list.  After a Nameserver query or ALPA loopmap
1652  * check, additional nodes may be added or removed (via DEVICE_RM) to / from
1653  * the PLOGI or ADISC lists. Once the PLOGI and ADISC lists are populated,
1654  * we will first process the ADISC list.  32 entries are processed initially and
1655  * ADISC is initited for each one.  Completions / Events for each node are
1656  * funnelled thru the state machine.  As each node finishes ADISC processing, it
1657  * starts ADISC for any nodes waiting for ADISC processing. If no nodes are
1658  * waiting, and the ADISC list count is identically 0, then we are done. For
1659  * Link Up discovery, since all nodes on the PLOGI list are UNREG_LOGIN'ed, we
1660  * can issue a CLEAR_LA and reenable Link Events. Next we will process the PLOGI
1661  * list.  32 entries are processed initially and PLOGI is initited for each one.
1662  * Completions / Events for each node are funnelled thru the state machine.  As
1663  * each node finishes PLOGI processing, it starts PLOGI for any nodes waiting
1664  * for PLOGI processing. If no nodes are waiting, and the PLOGI list count is
1665  * indentically 0, then we are done. We have now completed discovery / RSCN
1666  * handling. Upon completion, ALL nodes should be on either the mapped or
1667  * unmapped lists.
1668  */
1669 
1670 static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
1671      (struct lpfc_hba *, struct lpfc_nodelist *, void *, uint32_t) = {
1672 	/* Action routine                  Event       Current State  */
1673 	lpfc_rcv_plogi_unused_node,	/* RCV_PLOGI   UNUSED_NODE    */
1674 	lpfc_rcv_els_unused_node,	/* RCV_PRLI        */
1675 	lpfc_rcv_logo_unused_node,	/* RCV_LOGO        */
1676 	lpfc_rcv_els_unused_node,	/* RCV_ADISC       */
1677 	lpfc_rcv_els_unused_node,	/* RCV_PDISC       */
1678 	lpfc_rcv_els_unused_node,	/* RCV_PRLO        */
1679 	lpfc_disc_illegal,		/* CMPL_PLOGI      */
1680 	lpfc_disc_illegal,		/* CMPL_PRLI       */
1681 	lpfc_cmpl_logo_unused_node,	/* CMPL_LOGO       */
1682 	lpfc_disc_illegal,		/* CMPL_ADISC      */
1683 	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */
1684 	lpfc_device_rm_unused_node,	/* DEVICE_RM       */
1685 	lpfc_disc_illegal,		/* DEVICE_RECOVERY */
1686 
1687 	lpfc_rcv_plogi_plogi_issue,	/* RCV_PLOGI   PLOGI_ISSUE    */
1688 	lpfc_rcv_els_plogi_issue,	/* RCV_PRLI        */
1689 	lpfc_rcv_els_plogi_issue,	/* RCV_LOGO        */
1690 	lpfc_rcv_els_plogi_issue,	/* RCV_ADISC       */
1691 	lpfc_rcv_els_plogi_issue,	/* RCV_PDISC       */
1692 	lpfc_rcv_els_plogi_issue,	/* RCV_PRLO        */
1693 	lpfc_cmpl_plogi_plogi_issue,	/* CMPL_PLOGI      */
1694 	lpfc_disc_illegal,		/* CMPL_PRLI       */
1695 	lpfc_disc_illegal,		/* CMPL_LOGO       */
1696 	lpfc_disc_illegal,		/* CMPL_ADISC      */
1697 	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */
1698 	lpfc_device_rm_plogi_issue,	/* DEVICE_RM       */
1699 	lpfc_device_recov_plogi_issue,	/* DEVICE_RECOVERY */
1700 
1701 	lpfc_rcv_plogi_adisc_issue,	/* RCV_PLOGI   ADISC_ISSUE    */
1702 	lpfc_rcv_prli_adisc_issue,	/* RCV_PRLI        */
1703 	lpfc_rcv_logo_adisc_issue,	/* RCV_LOGO        */
1704 	lpfc_rcv_padisc_adisc_issue,	/* RCV_ADISC       */
1705 	lpfc_rcv_padisc_adisc_issue,	/* RCV_PDISC       */
1706 	lpfc_rcv_prlo_adisc_issue,	/* RCV_PRLO        */
1707 	lpfc_disc_illegal,		/* CMPL_PLOGI      */
1708 	lpfc_disc_illegal,		/* CMPL_PRLI       */
1709 	lpfc_disc_illegal,		/* CMPL_LOGO       */
1710 	lpfc_cmpl_adisc_adisc_issue,	/* CMPL_ADISC      */
1711 	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */
1712 	lpfc_device_rm_adisc_issue,	/* DEVICE_RM       */
1713 	lpfc_device_recov_adisc_issue,	/* DEVICE_RECOVERY */
1714 
1715 	lpfc_rcv_plogi_reglogin_issue,	/* RCV_PLOGI  REG_LOGIN_ISSUE */
1716 	lpfc_rcv_prli_reglogin_issue,	/* RCV_PLOGI       */
1717 	lpfc_rcv_logo_reglogin_issue,	/* RCV_LOGO        */
1718 	lpfc_rcv_padisc_reglogin_issue,	/* RCV_ADISC       */
1719 	lpfc_rcv_padisc_reglogin_issue,	/* RCV_PDISC       */
1720 	lpfc_rcv_prlo_reglogin_issue,	/* RCV_PRLO        */
1721 	lpfc_disc_illegal,		/* CMPL_PLOGI      */
1722 	lpfc_disc_illegal,		/* CMPL_PRLI       */
1723 	lpfc_disc_illegal,		/* CMPL_LOGO       */
1724 	lpfc_disc_illegal,		/* CMPL_ADISC      */
1725 	lpfc_cmpl_reglogin_reglogin_issue,/* CMPL_REG_LOGIN  */
1726 	lpfc_device_rm_reglogin_issue,	/* DEVICE_RM       */
1727 	lpfc_device_recov_reglogin_issue,/* DEVICE_RECOVERY */
1728 
1729 	lpfc_rcv_plogi_prli_issue,	/* RCV_PLOGI   PRLI_ISSUE     */
1730 	lpfc_rcv_prli_prli_issue,	/* RCV_PRLI        */
1731 	lpfc_rcv_logo_prli_issue,	/* RCV_LOGO        */
1732 	lpfc_rcv_padisc_prli_issue,	/* RCV_ADISC       */
1733 	lpfc_rcv_padisc_prli_issue,	/* RCV_PDISC       */
1734 	lpfc_rcv_prlo_prli_issue,	/* RCV_PRLO        */
1735 	lpfc_disc_illegal,		/* CMPL_PLOGI      */
1736 	lpfc_cmpl_prli_prli_issue,	/* CMPL_PRLI       */
1737 	lpfc_disc_illegal,		/* CMPL_LOGO       */
1738 	lpfc_disc_illegal,		/* CMPL_ADISC      */
1739 	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */
1740 	lpfc_device_rm_prli_issue,	/* DEVICE_RM       */
1741 	lpfc_device_recov_prli_issue,	/* DEVICE_RECOVERY */
1742 
1743 	lpfc_rcv_plogi_unmap_node,	/* RCV_PLOGI   UNMAPPED_NODE  */
1744 	lpfc_rcv_prli_unmap_node,	/* RCV_PRLI        */
1745 	lpfc_rcv_logo_unmap_node,	/* RCV_LOGO        */
1746 	lpfc_rcv_padisc_unmap_node,	/* RCV_ADISC       */
1747 	lpfc_rcv_padisc_unmap_node,	/* RCV_PDISC       */
1748 	lpfc_rcv_prlo_unmap_node,	/* RCV_PRLO        */
1749 	lpfc_disc_illegal,		/* CMPL_PLOGI      */
1750 	lpfc_disc_illegal,		/* CMPL_PRLI       */
1751 	lpfc_disc_illegal,		/* CMPL_LOGO       */
1752 	lpfc_disc_illegal,		/* CMPL_ADISC      */
1753 	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */
1754 	lpfc_disc_illegal,		/* DEVICE_RM       */
1755 	lpfc_device_recov_unmap_node,	/* DEVICE_RECOVERY */
1756 
1757 	lpfc_rcv_plogi_mapped_node,	/* RCV_PLOGI   MAPPED_NODE    */
1758 	lpfc_rcv_prli_mapped_node,	/* RCV_PRLI        */
1759 	lpfc_rcv_logo_mapped_node,	/* RCV_LOGO        */
1760 	lpfc_rcv_padisc_mapped_node,	/* RCV_ADISC       */
1761 	lpfc_rcv_padisc_mapped_node,	/* RCV_PDISC       */
1762 	lpfc_rcv_prlo_mapped_node,	/* RCV_PRLO        */
1763 	lpfc_disc_illegal,		/* CMPL_PLOGI      */
1764 	lpfc_disc_illegal,		/* CMPL_PRLI       */
1765 	lpfc_disc_illegal,		/* CMPL_LOGO       */
1766 	lpfc_disc_illegal,		/* CMPL_ADISC      */
1767 	lpfc_disc_illegal,		/* CMPL_REG_LOGIN  */
1768 	lpfc_disc_illegal,		/* DEVICE_RM       */
1769 	lpfc_device_recov_mapped_node,	/* DEVICE_RECOVERY */
1770 
1771 	lpfc_rcv_plogi_npr_node,        /* RCV_PLOGI   NPR_NODE    */
1772 	lpfc_rcv_prli_npr_node,         /* RCV_PRLI        */
1773 	lpfc_rcv_logo_npr_node,         /* RCV_LOGO        */
1774 	lpfc_rcv_padisc_npr_node,       /* RCV_ADISC       */
1775 	lpfc_rcv_padisc_npr_node,       /* RCV_PDISC       */
1776 	lpfc_rcv_prlo_npr_node,         /* RCV_PRLO        */
1777 	lpfc_disc_noop,			/* CMPL_PLOGI      */
1778 	lpfc_disc_noop,			/* CMPL_PRLI       */
1779 	lpfc_cmpl_logo_npr_node,        /* CMPL_LOGO       */
1780 	lpfc_disc_noop,			/* CMPL_ADISC      */
1781 	lpfc_cmpl_reglogin_npr_node,    /* CMPL_REG_LOGIN  */
1782 	lpfc_device_rm_npr_node,        /* DEVICE_RM       */
1783 	lpfc_device_recov_npr_node,     /* DEVICE_RECOVERY */
1784 };
1785 
1786 int
1787 lpfc_disc_state_machine(struct lpfc_hba * phba,
1788 			struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
1789 {
1790 	uint32_t cur_state, rc;
1791 	uint32_t(*func) (struct lpfc_hba *, struct lpfc_nodelist *, void *,
1792 			 uint32_t);
1793 
1794 	ndlp->nlp_disc_refcnt++;
1795 	cur_state = ndlp->nlp_state;
1796 
1797 	/* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */
1798 	lpfc_printf_log(phba,
1799 			KERN_INFO,
1800 			LOG_DISCOVERY,
1801 			"%d:0211 DSM in event x%x on NPort x%x in state %d "
1802 			"Data: x%x\n",
1803 			phba->brd_no,
1804 			evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag);
1805 
1806 	func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt];
1807 	rc = (func) (phba, ndlp, arg, evt);
1808 
1809 	/* DSM out state <rc> on NPort <nlp_DID> */
1810 	lpfc_printf_log(phba,
1811 		       KERN_INFO,
1812 		       LOG_DISCOVERY,
1813 		       "%d:0212 DSM out state %d on NPort x%x Data: x%x\n",
1814 		       phba->brd_no,
1815 		       rc, ndlp->nlp_DID, ndlp->nlp_flag);
1816 
1817 	ndlp->nlp_disc_refcnt--;
1818 
1819 	/* Check to see if ndlp removal is deferred */
1820 	if ((ndlp->nlp_disc_refcnt == 0)
1821 	    && (ndlp->nlp_flag & NLP_DELAY_REMOVE)) {
1822 		spin_lock_irq(phba->host->host_lock);
1823 		ndlp->nlp_flag &= ~NLP_DELAY_REMOVE;
1824 		spin_unlock_irq(phba->host->host_lock);
1825 		lpfc_nlp_remove(phba, ndlp);
1826 		return (NLP_STE_FREED_NODE);
1827 	}
1828 	if (rc == NLP_STE_FREED_NODE)
1829 		return (NLP_STE_FREED_NODE);
1830 	ndlp->nlp_state = rc;
1831 	return (rc);
1832 }
1833