blob: d8501bd959e717a09dd809963f32a3f7d4aa396e [file] [log] [blame]
James Smart128bdda2018-01-30 15:59:03 -08001/*******************************************************************
dea31012005-04-17 16:05:31 -05002 * This file is part of the Emulex Linux Device Driver for *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04003 * Fibre Channel Host Bus Adapters. *
James Smart0d041212019-01-28 11:14:41 -08004 * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term *
James Smart4ae2ebd2018-06-26 08:24:31 -07005 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
James Smart50611572016-03-31 14:12:34 -07006 * Copyright (C) 2004-2016 Emulex. All rights reserved. *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04007 * EMULEX and SLI are trademarks of Emulex. *
James Smartd080abe2017-02-12 13:52:39 -08008 * www.broadcom.com *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04009 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
dea31012005-04-17 16:05:31 -050010 * *
11 * This program is free software; you can redistribute it and/or *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -040012 * 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. *
dea31012005-04-17 16:05:31 -050022 *******************************************************************/
23
dea31012005-04-17 16:05:31 -050024#include <linux/blkdev.h>
25#include <linux/pci.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090026#include <linux/slab.h>
dea31012005-04-17 16:05:31 -050027#include <linux/interrupt.h>
28
James.Smart@Emulex.Com91886522005-08-10 15:03:09 -040029#include <scsi/scsi.h>
dea31012005-04-17 16:05:31 -050030#include <scsi/scsi_device.h>
31#include <scsi/scsi_host.h>
32#include <scsi/scsi_transport_fc.h>
James Smarta0f2d3e2017-02-12 13:52:31 -080033#include <scsi/fc/fc_fs.h>
34
James Smartda0436e2009-05-22 14:51:39 -040035#include "lpfc_hw4.h"
dea31012005-04-17 16:05:31 -050036#include "lpfc_hw.h"
37#include "lpfc_sli.h"
James Smartda0436e2009-05-22 14:51:39 -040038#include "lpfc_sli4.h"
James Smartea2151b2008-09-07 11:52:10 -040039#include "lpfc_nl.h"
dea31012005-04-17 16:05:31 -050040#include "lpfc_disc.h"
dea31012005-04-17 16:05:31 -050041#include "lpfc.h"
James Smarta0f2d3e2017-02-12 13:52:31 -080042#include "lpfc_scsi.h"
43#include "lpfc_nvme.h"
dea31012005-04-17 16:05:31 -050044#include "lpfc_logmsg.h"
45#include "lpfc_crtn.h"
James Smart92d7f7b2007-06-17 19:56:38 -050046#include "lpfc_vport.h"
James Smart858c9f62007-06-17 19:56:39 -050047#include "lpfc_debugfs.h"
dea31012005-04-17 16:05:31 -050048
49
50/* Called to verify a rcv'ed ADISC was intended for us. */
51static int
James Smart2e0fef82007-06-17 19:56:36 -050052lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
53 struct lpfc_name *nn, struct lpfc_name *pn)
dea31012005-04-17 16:05:31 -050054{
James Smart6b5151f2012-01-18 16:24:06 -050055 /* First, we MUST have a RPI registered */
56 if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED))
57 return 0;
58
dea31012005-04-17 16:05:31 -050059 /* Compare the ADISC rsp WWNN / WWPN matches our internal node
60 * table entry for that node.
61 */
James Smart2e0fef82007-06-17 19:56:36 -050062 if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)))
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -050063 return 0;
dea31012005-04-17 16:05:31 -050064
James Smart2e0fef82007-06-17 19:56:36 -050065 if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)))
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -050066 return 0;
dea31012005-04-17 16:05:31 -050067
68 /* we match, return success */
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -050069 return 1;
dea31012005-04-17 16:05:31 -050070}
71
dea31012005-04-17 16:05:31 -050072int
James Smart2e0fef82007-06-17 19:56:36 -050073lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
James Smart341af102010-01-26 23:07:37 -050074 struct serv_parm *sp, uint32_t class, int flogi)
dea31012005-04-17 16:05:31 -050075{
James Smart2e0fef82007-06-17 19:56:36 -050076 volatile struct serv_parm *hsp = &vport->fc_sparam;
James.Smart@Emulex.Com2fb70f72005-11-28 11:41:24 -050077 uint16_t hsp_value, ssp_value = 0;
dea31012005-04-17 16:05:31 -050078
James.Smart@Emulex.Com2fb70f72005-11-28 11:41:24 -050079 /*
80 * The receive data field size and buffer-to-buffer receive data field
81 * size entries are 16 bits but are represented as two 8-bit fields in
82 * the driver data structure to account for rsvd bits and other control
83 * bits. Reconstruct and compare the fields as a 16-bit values before
84 * correcting the byte values.
85 */
dea31012005-04-17 16:05:31 -050086 if (sp->cls1.classValid) {
James Smart341af102010-01-26 23:07:37 -050087 if (!flogi) {
88 hsp_value = ((hsp->cls1.rcvDataSizeMsb << 8) |
89 hsp->cls1.rcvDataSizeLsb);
90 ssp_value = ((sp->cls1.rcvDataSizeMsb << 8) |
91 sp->cls1.rcvDataSizeLsb);
92 if (!ssp_value)
93 goto bad_service_param;
94 if (ssp_value > hsp_value) {
95 sp->cls1.rcvDataSizeLsb =
96 hsp->cls1.rcvDataSizeLsb;
97 sp->cls1.rcvDataSizeMsb =
98 hsp->cls1.rcvDataSizeMsb;
99 }
James.Smart@Emulex.Com2fb70f72005-11-28 11:41:24 -0500100 }
James Smart341af102010-01-26 23:07:37 -0500101 } else if (class == CLASS1)
James Smart92d7f7b2007-06-17 19:56:38 -0500102 goto bad_service_param;
dea31012005-04-17 16:05:31 -0500103 if (sp->cls2.classValid) {
James Smart341af102010-01-26 23:07:37 -0500104 if (!flogi) {
105 hsp_value = ((hsp->cls2.rcvDataSizeMsb << 8) |
106 hsp->cls2.rcvDataSizeLsb);
107 ssp_value = ((sp->cls2.rcvDataSizeMsb << 8) |
108 sp->cls2.rcvDataSizeLsb);
109 if (!ssp_value)
110 goto bad_service_param;
111 if (ssp_value > hsp_value) {
112 sp->cls2.rcvDataSizeLsb =
113 hsp->cls2.rcvDataSizeLsb;
114 sp->cls2.rcvDataSizeMsb =
115 hsp->cls2.rcvDataSizeMsb;
116 }
James.Smart@Emulex.Com2fb70f72005-11-28 11:41:24 -0500117 }
James Smart341af102010-01-26 23:07:37 -0500118 } else if (class == CLASS2)
James Smart92d7f7b2007-06-17 19:56:38 -0500119 goto bad_service_param;
dea31012005-04-17 16:05:31 -0500120 if (sp->cls3.classValid) {
James Smart341af102010-01-26 23:07:37 -0500121 if (!flogi) {
122 hsp_value = ((hsp->cls3.rcvDataSizeMsb << 8) |
123 hsp->cls3.rcvDataSizeLsb);
124 ssp_value = ((sp->cls3.rcvDataSizeMsb << 8) |
125 sp->cls3.rcvDataSizeLsb);
126 if (!ssp_value)
127 goto bad_service_param;
128 if (ssp_value > hsp_value) {
129 sp->cls3.rcvDataSizeLsb =
130 hsp->cls3.rcvDataSizeLsb;
131 sp->cls3.rcvDataSizeMsb =
132 hsp->cls3.rcvDataSizeMsb;
133 }
James.Smart@Emulex.Com2fb70f72005-11-28 11:41:24 -0500134 }
James Smart341af102010-01-26 23:07:37 -0500135 } else if (class == CLASS3)
James Smart92d7f7b2007-06-17 19:56:38 -0500136 goto bad_service_param;
dea31012005-04-17 16:05:31 -0500137
James.Smart@Emulex.Com2fb70f72005-11-28 11:41:24 -0500138 /*
139 * Preserve the upper four bits of the MSB from the PLOGI response.
140 * These bits contain the Buffer-to-Buffer State Change Number
141 * from the target and need to be passed to the FW.
142 */
143 hsp_value = (hsp->cmn.bbRcvSizeMsb << 8) | hsp->cmn.bbRcvSizeLsb;
144 ssp_value = (sp->cmn.bbRcvSizeMsb << 8) | sp->cmn.bbRcvSizeLsb;
145 if (ssp_value > hsp_value) {
dea31012005-04-17 16:05:31 -0500146 sp->cmn.bbRcvSizeLsb = hsp->cmn.bbRcvSizeLsb;
James.Smart@Emulex.Com2fb70f72005-11-28 11:41:24 -0500147 sp->cmn.bbRcvSizeMsb = (sp->cmn.bbRcvSizeMsb & 0xF0) |
148 (hsp->cmn.bbRcvSizeMsb & 0x0F);
149 }
dea31012005-04-17 16:05:31 -0500150
dea31012005-04-17 16:05:31 -0500151 memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));
152 memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name));
James.Smart@Emulex.Com2fb70f72005-11-28 11:41:24 -0500153 return 1;
James Smart92d7f7b2007-06-17 19:56:38 -0500154bad_service_param:
James Smarte8b62012007-08-02 11:10:09 -0400155 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
156 "0207 Device %x "
157 "(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x) sent "
158 "invalid service parameters. Ignoring device.\n",
159 ndlp->nlp_DID,
160 sp->nodeName.u.wwn[0], sp->nodeName.u.wwn[1],
161 sp->nodeName.u.wwn[2], sp->nodeName.u.wwn[3],
162 sp->nodeName.u.wwn[4], sp->nodeName.u.wwn[5],
163 sp->nodeName.u.wwn[6], sp->nodeName.u.wwn[7]);
James Smart92d7f7b2007-06-17 19:56:38 -0500164 return 0;
dea31012005-04-17 16:05:31 -0500165}
166
167static void *
James Smart2e0fef82007-06-17 19:56:36 -0500168lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
James Smart92d7f7b2007-06-17 19:56:38 -0500169 struct lpfc_iocbq *rspiocb)
dea31012005-04-17 16:05:31 -0500170{
171 struct lpfc_dmabuf *pcmd, *prsp;
172 uint32_t *lp;
173 void *ptr = NULL;
174 IOCB_t *irsp;
175
176 irsp = &rspiocb->iocb;
177 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
178
179 /* For lpfc_els_abort, context2 could be zero'ed to delay
180 * freeing associated memory till after ABTS completes.
181 */
182 if (pcmd) {
183 prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf,
184 list);
185 if (prsp) {
186 lp = (uint32_t *) prsp->virt;
187 ptr = (void *)((uint8_t *)lp + sizeof(uint32_t));
188 }
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -0500189 } else {
dea31012005-04-17 16:05:31 -0500190 /* Force ulpStatus error since we are returning NULL ptr */
191 if (!(irsp->ulpStatus)) {
192 irsp->ulpStatus = IOSTAT_LOCAL_REJECT;
193 irsp->un.ulpWord[4] = IOERR_SLI_ABORTED;
194 }
195 ptr = NULL;
196 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -0500197 return ptr;
dea31012005-04-17 16:05:31 -0500198}
199
200
James Smart2a9bf3d2010-06-07 15:24:45 -0400201
dea31012005-04-17 16:05:31 -0500202/*
203 * Free resources / clean up outstanding I/Os
204 * associated with a LPFC_NODELIST entry. This
205 * routine effectively results in a "software abort".
206 */
Guilherme G. Piccoli7c9fdfb2017-05-24 18:48:51 -0300207void
James Smart2e0fef82007-06-17 19:56:36 -0500208lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
dea31012005-04-17 16:05:31 -0500209{
James Smart2a9bf3d2010-06-07 15:24:45 -0400210 LIST_HEAD(abort_list);
James Smart895427b2017-02-12 13:52:30 -0800211 struct lpfc_sli_ring *pring;
dea31012005-04-17 16:05:31 -0500212 struct lpfc_iocbq *iocb, *next_iocb;
dea31012005-04-17 16:05:31 -0500213
James Smart895427b2017-02-12 13:52:30 -0800214 pring = lpfc_phba_elsring(phba);
215
Guilherme G. Piccoli7c9fdfb2017-05-24 18:48:51 -0300216 /* In case of error recovery path, we might have a NULL pring here */
Dick Kennedy1234a6d2017-09-29 17:34:29 -0700217 if (unlikely(!pring))
Guilherme G. Piccoli7c9fdfb2017-05-24 18:48:51 -0300218 return;
219
dea31012005-04-17 16:05:31 -0500220 /* Abort outstanding I/O on NPort <nlp_DID> */
James Smarte8b62012007-08-02 11:10:09 -0400221 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_DISCOVERY,
James Smart2a9bf3d2010-06-07 15:24:45 -0400222 "2819 Abort outstanding I/O on NPort x%x "
James Smarte8b62012007-08-02 11:10:09 -0400223 "Data: x%x x%x x%x\n",
224 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
225 ndlp->nlp_rpi);
James Smart0976e1a2013-12-17 20:29:36 -0500226 /* Clean up all fabric IOs first.*/
James Smart92d7f7b2007-06-17 19:56:38 -0500227 lpfc_fabric_abort_nport(ndlp);
dea31012005-04-17 16:05:31 -0500228
James Smart0976e1a2013-12-17 20:29:36 -0500229 /*
230 * Lock the ELS ring txcmplq for SLI3/SLI4 and build a local list
231 * of all ELS IOs that need an ABTS. The IOs need to stay on the
232 * txcmplq so that the abort operation completes them successfully.
233 */
James Smart2e0fef82007-06-17 19:56:36 -0500234 spin_lock_irq(&phba->hbalock);
James Smart0976e1a2013-12-17 20:29:36 -0500235 if (phba->sli_rev == LPFC_SLI_REV4)
236 spin_lock(&pring->ring_lock);
237 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
238 /* Add to abort_list on on NDLP match. */
James Smart2a9bf3d2010-06-07 15:24:45 -0400239 if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))
240 list_add_tail(&iocb->dlist, &abort_list);
241 }
James Smart0976e1a2013-12-17 20:29:36 -0500242 if (phba->sli_rev == LPFC_SLI_REV4)
243 spin_unlock(&pring->ring_lock);
James Smart2a9bf3d2010-06-07 15:24:45 -0400244 spin_unlock_irq(&phba->hbalock);
245
James Smart0976e1a2013-12-17 20:29:36 -0500246 /* Abort the targeted IOs and remove them from the abort list. */
James Smart2a9bf3d2010-06-07 15:24:45 -0400247 list_for_each_entry_safe(iocb, next_iocb, &abort_list, dlist) {
248 spin_lock_irq(&phba->hbalock);
249 list_del_init(&iocb->dlist);
250 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
251 spin_unlock_irq(&phba->hbalock);
252 }
253
James Smart0976e1a2013-12-17 20:29:36 -0500254 INIT_LIST_HEAD(&abort_list);
255
256 /* Now process the txq */
257 spin_lock_irq(&phba->hbalock);
258 if (phba->sli_rev == LPFC_SLI_REV4)
259 spin_lock(&pring->ring_lock);
260
261 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
262 /* Check to see if iocb matches the nport we are looking for */
263 if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) {
264 list_del_init(&iocb->list);
265 list_add_tail(&iocb->list, &abort_list);
266 }
267 }
268
269 if (phba->sli_rev == LPFC_SLI_REV4)
270 spin_unlock(&pring->ring_lock);
271 spin_unlock_irq(&phba->hbalock);
272
James Smarta257bf92009-04-06 18:48:10 -0400273 /* Cancel all the IOCBs from the completions list */
James Smart0976e1a2013-12-17 20:29:36 -0500274 lpfc_sli_cancel_iocbs(phba, &abort_list,
275 IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED);
James Smart2534ba72007-04-25 09:52:20 -0400276
James Smart0d2b6b82008-06-14 22:52:47 -0400277 lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);
dea31012005-04-17 16:05:31 -0500278}
279
James Smart359e10f2019-09-21 20:58:47 -0700280/* lpfc_defer_pt2pt_acc - Complete SLI3 pt2pt processing on link up
281 * @phba: pointer to lpfc hba data structure.
282 * @link_mbox: pointer to CONFIG_LINK mailbox object
283 *
284 * This routine is only called if we are SLI3, direct connect pt2pt
285 * mode and the remote NPort issues the PLOGI after link up.
286 */
zhengbinf7cb0d02019-10-04 18:04:37 +0800287static void
James Smart359e10f2019-09-21 20:58:47 -0700288lpfc_defer_pt2pt_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *link_mbox)
289{
290 LPFC_MBOXQ_t *login_mbox;
291 MAILBOX_t *mb = &link_mbox->u.mb;
292 struct lpfc_iocbq *save_iocb;
293 struct lpfc_nodelist *ndlp;
294 int rc;
295
296 ndlp = link_mbox->ctx_ndlp;
297 login_mbox = link_mbox->context3;
298 save_iocb = login_mbox->context3;
299 link_mbox->context3 = NULL;
300 login_mbox->context3 = NULL;
301
302 /* Check for CONFIG_LINK error */
303 if (mb->mbxStatus) {
304 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
305 "4575 CONFIG_LINK fails pt2pt discovery: %x\n",
306 mb->mbxStatus);
307 mempool_free(login_mbox, phba->mbox_mem_pool);
308 mempool_free(link_mbox, phba->mbox_mem_pool);
James Smartbe0709e2019-12-18 15:57:59 -0800309 kfree(save_iocb);
James Smart359e10f2019-09-21 20:58:47 -0700310 return;
311 }
312
313 /* Now that CONFIG_LINK completed, and our SID is configured,
314 * we can now proceed with sending the PLOGI ACC.
315 */
316 rc = lpfc_els_rsp_acc(link_mbox->vport, ELS_CMD_PLOGI,
317 save_iocb, ndlp, login_mbox);
318 if (rc) {
319 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
320 "4576 PLOGI ACC fails pt2pt discovery: %x\n",
321 rc);
322 mempool_free(login_mbox, phba->mbox_mem_pool);
323 }
324
325 mempool_free(link_mbox, phba->mbox_mem_pool);
James Smartbe0709e2019-12-18 15:57:59 -0800326 kfree(save_iocb);
327}
328
329/**
330 * lpfc_defer_tgt_acc - Progress SLI4 target rcv PLOGI handler
331 * @phba: Pointer to HBA context object.
332 * @pmb: Pointer to mailbox object.
333 *
334 * This function provides the unreg rpi mailbox completion handler for a tgt.
335 * The routine frees the memory resources associated with the completed
336 * mailbox command and transmits the ELS ACC.
337 *
338 * This routine is only called if we are SLI4, acting in target
339 * mode and the remote NPort issues the PLOGI after link up.
340 **/
YueHaibingfdb827e42020-01-07 09:49:56 +0800341static void
James Smartbe0709e2019-12-18 15:57:59 -0800342lpfc_defer_acc_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
343{
344 struct lpfc_vport *vport = pmb->vport;
345 struct lpfc_nodelist *ndlp = pmb->ctx_ndlp;
346 LPFC_MBOXQ_t *mbox = pmb->context3;
347 struct lpfc_iocbq *piocb = NULL;
348 int rc;
349
350 if (mbox) {
351 pmb->context3 = NULL;
352 piocb = mbox->context3;
353 mbox->context3 = NULL;
354 }
355
356 /*
357 * Complete the unreg rpi mbx request, and update flags.
358 * This will also restart any deferred events.
359 */
360 lpfc_nlp_get(ndlp);
361 lpfc_sli4_unreg_rpi_cmpl_clr(phba, pmb);
362
363 if (!piocb) {
364 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY | LOG_ELS,
365 "4578 PLOGI ACC fail\n");
366 if (mbox)
367 mempool_free(mbox, phba->mbox_mem_pool);
368 goto out;
369 }
370
371 rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, piocb, ndlp, mbox);
372 if (rc) {
373 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY | LOG_ELS,
374 "4579 PLOGI ACC fail %x\n", rc);
375 if (mbox)
376 mempool_free(mbox, phba->mbox_mem_pool);
377 }
378 kfree(piocb);
379out:
380 lpfc_nlp_put(ndlp);
James Smart359e10f2019-09-21 20:58:47 -0700381}
382
dea31012005-04-17 16:05:31 -0500383static int
James Smart2e0fef82007-06-17 19:56:36 -0500384lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
James Smart92d7f7b2007-06-17 19:56:38 -0500385 struct lpfc_iocbq *cmdiocb)
dea31012005-04-17 16:05:31 -0500386{
James Smart2e0fef82007-06-17 19:56:36 -0500387 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
388 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -0500389 struct lpfc_dmabuf *pcmd;
James Smarted4afe72015-04-07 15:07:11 -0400390 uint64_t nlp_portwwn = 0;
dea31012005-04-17 16:05:31 -0500391 uint32_t *lp;
392 IOCB_t *icmd;
393 struct serv_parm *sp;
James Smartd6de08c2015-12-16 18:11:53 -0500394 uint32_t ed_tov;
James Smart359e10f2019-09-21 20:58:47 -0700395 LPFC_MBOXQ_t *link_mbox;
396 LPFC_MBOXQ_t *login_mbox;
397 struct lpfc_iocbq *save_iocb;
dea31012005-04-17 16:05:31 -0500398 struct ls_rjt stat;
James Smart8c258642017-02-12 13:52:36 -0800399 uint32_t vid, flag;
James Smartbe0709e2019-12-18 15:57:59 -0800400 u16 rpi;
James Smart359e10f2019-09-21 20:58:47 -0700401 int rc, defer_acc;
dea31012005-04-17 16:05:31 -0500402
403 memset(&stat, 0, sizeof (struct ls_rjt));
dea31012005-04-17 16:05:31 -0500404 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
405 lp = (uint32_t *) pcmd->virt;
406 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
James Smarta8adb832007-10-27 13:37:53 -0400407 if (wwn_to_u64(sp->portName.u.wwn) == 0) {
408 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
409 "0140 PLOGI Reject: invalid nname\n");
410 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
411 stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_PNAME;
412 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
413 NULL);
414 return 0;
415 }
416 if (wwn_to_u64(sp->nodeName.u.wwn) == 0) {
417 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
418 "0141 PLOGI Reject: invalid pname\n");
419 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
420 stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_NNAME;
421 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
422 NULL);
423 return 0;
424 }
James Smarted4afe72015-04-07 15:07:11 -0400425
426 nlp_portwwn = wwn_to_u64(ndlp->nlp_portname.u.wwn);
James Smart341af102010-01-26 23:07:37 -0500427 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0) == 0)) {
dea31012005-04-17 16:05:31 -0500428 /* Reject this request because invalid parameters */
429 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
430 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
James Smart858c9f62007-06-17 19:56:39 -0500431 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
432 NULL);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -0500433 return 0;
dea31012005-04-17 16:05:31 -0500434 }
435 icmd = &cmdiocb->iocb;
436
437 /* PLOGI chkparm OK */
James Smarte8b62012007-08-02 11:10:09 -0400438 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
James Smarte74c03c2013-04-17 20:15:19 -0400439 "0114 PLOGI chkparm OK Data: x%x x%x x%x "
440 "x%x x%x x%x\n",
James Smarte8b62012007-08-02 11:10:09 -0400441 ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag,
James Smarte74c03c2013-04-17 20:15:19 -0400442 ndlp->nlp_rpi, vport->port_state,
443 vport->fc_flag);
dea31012005-04-17 16:05:31 -0500444
James Smart3de2a652007-08-02 11:09:59 -0400445 if (vport->cfg_fcp_class == 2 && sp->cls2.classValid)
dea31012005-04-17 16:05:31 -0500446 ndlp->nlp_fcp_info |= CLASS2;
James Smarted957682007-06-17 19:56:37 -0500447 else
dea31012005-04-17 16:05:31 -0500448 ndlp->nlp_fcp_info |= CLASS3;
James Smart2e0fef82007-06-17 19:56:36 -0500449
James Smart359e10f2019-09-21 20:58:47 -0700450 defer_acc = 0;
dea31012005-04-17 16:05:31 -0500451 ndlp->nlp_class_sup = 0;
452 if (sp->cls1.classValid)
453 ndlp->nlp_class_sup |= FC_COS_CLASS1;
454 if (sp->cls2.classValid)
455 ndlp->nlp_class_sup |= FC_COS_CLASS2;
456 if (sp->cls3.classValid)
457 ndlp->nlp_class_sup |= FC_COS_CLASS3;
458 if (sp->cls4.classValid)
459 ndlp->nlp_class_sup |= FC_COS_CLASS4;
460 ndlp->nlp_maxframe =
461 ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
James Smarted4afe72015-04-07 15:07:11 -0400462 /* if already logged in, do implicit logout */
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -0500463 switch (ndlp->nlp_state) {
dea31012005-04-17 16:05:31 -0500464 case NLP_STE_NPR_NODE:
465 if (!(ndlp->nlp_flag & NLP_NPR_ADISC))
466 break;
Bart Van Asschecd05c152019-03-28 11:06:18 -0700467 /* fall through */
dea31012005-04-17 16:05:31 -0500468 case NLP_STE_REG_LOGIN_ISSUE:
469 case NLP_STE_PRLI_ISSUE:
470 case NLP_STE_UNMAPPED_NODE:
471 case NLP_STE_MAPPED_NODE:
James Smart1c5b12f2017-04-21 16:05:03 -0700472 /* For initiators, lpfc_plogi_confirm_nport skips fabric did.
473 * For target mode, execute implicit logo.
474 * Fabric nodes go into NPR.
475 */
476 if (!(ndlp->nlp_type & NLP_FABRIC) &&
477 !(phba->nvmet_support)) {
James Smarted4afe72015-04-07 15:07:11 -0400478 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
479 ndlp, NULL);
480 return 1;
481 }
482 if (nlp_portwwn != 0 &&
483 nlp_portwwn != wwn_to_u64(sp->portName.u.wwn))
484 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
485 "0143 PLOGI recv'd from DID: x%x "
486 "WWPN changed: old %llx new %llx\n",
487 ndlp->nlp_DID,
488 (unsigned long long)nlp_portwwn,
489 (unsigned long long)
490 wwn_to_u64(sp->portName.u.wwn));
491
James Smart4c2805a2020-03-31 09:50:10 -0700492 /* Notify transport of connectivity loss to trigger cleanup. */
493 if (phba->nvmet_support &&
494 ndlp->nlp_state == NLP_STE_UNMAPPED_NODE)
495 lpfc_nvmet_invalidate_host(phba, ndlp);
496
James Smarted4afe72015-04-07 15:07:11 -0400497 ndlp->nlp_prev_state = ndlp->nlp_state;
498 /* rport needs to be unregistered first */
499 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
500 break;
dea31012005-04-17 16:05:31 -0500501 }
502
James Smart9de416a2017-12-08 17:18:07 -0800503 ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
504 ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
505 ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
506 ndlp->nlp_flag &= ~NLP_FIRSTBURST;
507
James Smart359e10f2019-09-21 20:58:47 -0700508 login_mbox = NULL;
509 link_mbox = NULL;
510 save_iocb = NULL;
511
James Smart939723a2012-05-09 21:19:03 -0400512 /* Check for Nport to NPort pt2pt protocol */
James Smart92d7f7b2007-06-17 19:56:38 -0500513 if ((vport->fc_flag & FC_PT2PT) &&
514 !(vport->fc_flag & FC_PT2PT_PLOGI)) {
dea31012005-04-17 16:05:31 -0500515 /* rcv'ed PLOGI decides what our NPortId will be */
James Smart2e0fef82007-06-17 19:56:36 -0500516 vport->fc_myDID = icmd->un.rcvels.parmRo;
James Smartd6de08c2015-12-16 18:11:53 -0500517
518 ed_tov = be32_to_cpu(sp->cmn.e_d_tov);
519 if (sp->cmn.edtovResolution) {
520 /* E_D_TOV ticks are in nanoseconds */
521 ed_tov = (phba->fc_edtov + 999999) / 1000000;
dea31012005-04-17 16:05:31 -0500522 }
James Smartd6de08c2015-12-16 18:11:53 -0500523
James Smart939723a2012-05-09 21:19:03 -0400524 /*
James Smartd6de08c2015-12-16 18:11:53 -0500525 * For pt-to-pt, use the larger EDTOV
526 * RATOV = 2 * EDTOV
James Smart939723a2012-05-09 21:19:03 -0400527 */
James Smartd6de08c2015-12-16 18:11:53 -0500528 if (ed_tov > phba->fc_edtov)
529 phba->fc_edtov = ed_tov;
530 phba->fc_ratov = (2 * phba->fc_edtov) / 1000;
531
532 memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
533
534 /* Issue config_link / reg_vfi to account for updated TOV's */
535
James Smart939723a2012-05-09 21:19:03 -0400536 if (phba->sli_rev == LPFC_SLI_REV4)
537 lpfc_issue_reg_vfi(vport);
James Smartd6de08c2015-12-16 18:11:53 -0500538 else {
James Smart359e10f2019-09-21 20:58:47 -0700539 defer_acc = 1;
540 link_mbox = mempool_alloc(phba->mbox_mem_pool,
541 GFP_KERNEL);
542 if (!link_mbox)
James Smartd6de08c2015-12-16 18:11:53 -0500543 goto out;
James Smart359e10f2019-09-21 20:58:47 -0700544 lpfc_config_link(phba, link_mbox);
545 link_mbox->mbox_cmpl = lpfc_defer_pt2pt_acc;
546 link_mbox->vport = vport;
547 link_mbox->ctx_ndlp = ndlp;
548
James Smartbe0709e2019-12-18 15:57:59 -0800549 save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);
James Smart359e10f2019-09-21 20:58:47 -0700550 if (!save_iocb)
James Smartd6de08c2015-12-16 18:11:53 -0500551 goto out;
James Smart359e10f2019-09-21 20:58:47 -0700552 /* Save info from cmd IOCB used in rsp */
553 memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb,
554 sizeof(struct lpfc_iocbq));
James Smartd6de08c2015-12-16 18:11:53 -0500555 }
dea31012005-04-17 16:05:31 -0500556
James Smart2e0fef82007-06-17 19:56:36 -0500557 lpfc_can_disctmo(vport);
dea31012005-04-17 16:05:31 -0500558 }
James Smartd6de08c2015-12-16 18:11:53 -0500559
James Smart8c258642017-02-12 13:52:36 -0800560 ndlp->nlp_flag &= ~NLP_SUPPRESS_RSP;
561 if ((phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) &&
562 sp->cmn.valid_vendor_ver_level) {
563 vid = be32_to_cpu(sp->un.vv.vid);
564 flag = be32_to_cpu(sp->un.vv.flags);
565 if ((vid == LPFC_VV_EMLX_ID) && (flag & LPFC_VV_SUPPRESS_RSP))
566 ndlp->nlp_flag |= NLP_SUPPRESS_RSP;
567 }
568
James Smart359e10f2019-09-21 20:58:47 -0700569 login_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
570 if (!login_mbox)
dea31012005-04-17 16:05:31 -0500571 goto out;
572
James Smart6b5151f2012-01-18 16:24:06 -0500573 /* Registering an existing RPI behaves differently for SLI3 vs SLI4 */
James Smartbe0709e2019-12-18 15:57:59 -0800574 if (phba->nvmet_support && !defer_acc) {
575 link_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
576 if (!link_mbox)
577 goto out;
578
579 /* As unique identifiers such as iotag would be overwritten
580 * with those from the cmdiocb, allocate separate temporary
581 * storage for the copy.
582 */
583 save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);
584 if (!save_iocb)
585 goto out;
586
587 /* Unreg RPI is required for SLI4. */
588 rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
589 lpfc_unreg_login(phba, vport->vpi, rpi, link_mbox);
590 link_mbox->vport = vport;
591 link_mbox->ctx_ndlp = ndlp;
592 link_mbox->mbox_cmpl = lpfc_defer_acc_rsp;
593
594 if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
595 (!(vport->fc_flag & FC_OFFLINE_MODE)))
596 ndlp->nlp_flag |= NLP_UNREG_INP;
597
598 /* Save info from cmd IOCB used in rsp */
599 memcpy(save_iocb, cmdiocb, sizeof(*save_iocb));
600
601 /* Delay sending ACC till unreg RPI completes. */
602 defer_acc = 1;
603 } else if (phba->sli_rev == LPFC_SLI_REV4)
James Smart6b5151f2012-01-18 16:24:06 -0500604 lpfc_unreg_rpi(vport, ndlp);
605
James Smart6fb120a2009-05-22 14:52:59 -0400606 rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID,
James Smart359e10f2019-09-21 20:58:47 -0700607 (uint8_t *)sp, login_mbox, ndlp->nlp_rpi);
608 if (rc)
dea31012005-04-17 16:05:31 -0500609 goto out;
dea31012005-04-17 16:05:31 -0500610
611 /* ACC PLOGI rsp command needs to execute first,
James Smart359e10f2019-09-21 20:58:47 -0700612 * queue this login_mbox command to be processed later.
dea31012005-04-17 16:05:31 -0500613 */
James Smart359e10f2019-09-21 20:58:47 -0700614 login_mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
James Smart329f9bc2007-04-25 09:53:01 -0400615 /*
James Smart359e10f2019-09-21 20:58:47 -0700616 * login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp) deferred until mailbox
James Smart329f9bc2007-04-25 09:53:01 -0400617 * command issued in lpfc_cmpl_els_acc().
618 */
James Smart359e10f2019-09-21 20:58:47 -0700619 login_mbox->vport = vport;
James Smart2e0fef82007-06-17 19:56:36 -0500620 spin_lock_irq(shost->host_lock);
Jamie Wellnitz5024ab12006-02-28 19:25:28 -0500621 ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
James Smart2e0fef82007-06-17 19:56:36 -0500622 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -0500623
James Smart33ccf8d2006-08-17 11:57:58 -0400624 /*
625 * If there is an outstanding PLOGI issued, abort it before
626 * sending ACC rsp for received PLOGI. If pending plogi
627 * is not canceled here, the plogi will be rejected by
628 * remote port and will be retried. On a configuration with
629 * single discovery thread, this will cause a huge delay in
630 * discovery. Also this will cause multiple state machines
631 * running in parallel for this node.
James Smartfeff8b32019-10-18 14:18:20 -0700632 * This only applies to a fabric environment.
James Smart33ccf8d2006-08-17 11:57:58 -0400633 */
James Smartfeff8b32019-10-18 14:18:20 -0700634 if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) &&
635 (vport->fc_flag & FC_FABRIC)) {
James Smart33ccf8d2006-08-17 11:57:58 -0400636 /* software abort outstanding PLOGI */
James Smart07951072007-04-25 09:51:38 -0400637 lpfc_els_abort(phba, ndlp);
James Smart33ccf8d2006-08-17 11:57:58 -0400638 }
639
James Smart858c9f62007-06-17 19:56:39 -0500640 if ((vport->port_type == LPFC_NPIV_PORT &&
James Smart3de2a652007-08-02 11:09:59 -0400641 vport->cfg_restrict_login)) {
James Smart858c9f62007-06-17 19:56:39 -0500642
James Smartbe0709e2019-12-18 15:57:59 -0800643 /* no deferred ACC */
644 kfree(save_iocb);
645
James Smart858c9f62007-06-17 19:56:39 -0500646 /* In order to preserve RPIs, we want to cleanup
647 * the default RPI the firmware created to rcv
648 * this ELS request. The only way to do this is
649 * to register, then unregister the RPI.
650 */
651 spin_lock_irq(shost->host_lock);
652 ndlp->nlp_flag |= NLP_RM_DFLT_RPI;
653 spin_unlock_irq(shost->host_lock);
654 stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD;
655 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
James Smart0a8a86f2012-03-01 22:36:15 -0500656 rc = lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
James Smart359e10f2019-09-21 20:58:47 -0700657 ndlp, login_mbox);
James Smart0a8a86f2012-03-01 22:36:15 -0500658 if (rc)
James Smart359e10f2019-09-21 20:58:47 -0700659 mempool_free(login_mbox, phba->mbox_mem_pool);
James Smart858c9f62007-06-17 19:56:39 -0500660 return 1;
661 }
James Smart359e10f2019-09-21 20:58:47 -0700662 if (defer_acc) {
663 /* So the order here should be:
James Smartbe0709e2019-12-18 15:57:59 -0800664 * SLI3 pt2pt
665 * Issue CONFIG_LINK mbox
666 * CONFIG_LINK cmpl
667 * SLI4 tgt
668 * Issue UNREG RPI mbx
669 * UNREG RPI cmpl
James Smart359e10f2019-09-21 20:58:47 -0700670 * Issue PLOGI ACC
671 * PLOGI ACC cmpl
672 * Issue REG_LOGIN mbox
673 */
674
675 /* Save the REG_LOGIN mbox for and rcv IOCB copy later */
676 link_mbox->context3 = login_mbox;
677 login_mbox->context3 = save_iocb;
678
679 /* Start the ball rolling by issuing CONFIG_LINK here */
680 rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT);
681 if (rc == MBX_NOT_FINISHED)
682 goto out;
683 return 1;
684 }
685
686 rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, login_mbox);
James Smart0a8a86f2012-03-01 22:36:15 -0500687 if (rc)
James Smart359e10f2019-09-21 20:58:47 -0700688 mempool_free(login_mbox, phba->mbox_mem_pool);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -0500689 return 1;
dea31012005-04-17 16:05:31 -0500690out:
James Smart359e10f2019-09-21 20:58:47 -0700691 if (defer_acc)
692 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
James Smartbe0709e2019-12-18 15:57:59 -0800693 "4577 discovery failure: %p %p %p\n",
James Smart359e10f2019-09-21 20:58:47 -0700694 save_iocb, link_mbox, login_mbox);
James Smartbe0709e2019-12-18 15:57:59 -0800695 kfree(save_iocb);
James Smart359e10f2019-09-21 20:58:47 -0700696 if (link_mbox)
697 mempool_free(link_mbox, phba->mbox_mem_pool);
698 if (login_mbox)
699 mempool_free(login_mbox, phba->mbox_mem_pool);
700
dea31012005-04-17 16:05:31 -0500701 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
702 stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE;
James Smart858c9f62007-06-17 19:56:39 -0500703 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -0500704 return 0;
dea31012005-04-17 16:05:31 -0500705}
706
James Smart6b5151f2012-01-18 16:24:06 -0500707/**
708 * lpfc_mbx_cmpl_resume_rpi - Resume RPI completion routine
709 * @phba: pointer to lpfc hba data structure.
710 * @mboxq: pointer to mailbox object
711 *
712 * This routine is invoked to issue a completion to a rcv'ed
713 * ADISC or PDISC after the paused RPI has been resumed.
714 **/
715static void
716lpfc_mbx_cmpl_resume_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
717{
718 struct lpfc_vport *vport;
719 struct lpfc_iocbq *elsiocb;
720 struct lpfc_nodelist *ndlp;
721 uint32_t cmd;
722
James Smart3e1f0712018-11-29 16:09:29 -0800723 elsiocb = (struct lpfc_iocbq *)mboxq->ctx_buf;
724 ndlp = (struct lpfc_nodelist *)mboxq->ctx_ndlp;
James Smart6b5151f2012-01-18 16:24:06 -0500725 vport = mboxq->vport;
726 cmd = elsiocb->drvrTimeout;
727
728 if (cmd == ELS_CMD_ADISC) {
729 lpfc_els_rsp_adisc_acc(vport, elsiocb, ndlp);
730 } else {
731 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, elsiocb,
732 ndlp, NULL);
733 }
734 kfree(elsiocb);
James Smart72859902012-01-18 16:25:38 -0500735 mempool_free(mboxq, phba->mbox_mem_pool);
James Smart6b5151f2012-01-18 16:24:06 -0500736}
737
dea31012005-04-17 16:05:31 -0500738static int
James Smart2e0fef82007-06-17 19:56:36 -0500739lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
dea31012005-04-17 16:05:31 -0500740 struct lpfc_iocbq *cmdiocb)
741{
James Smart2e0fef82007-06-17 19:56:36 -0500742 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart6b5151f2012-01-18 16:24:06 -0500743 struct lpfc_iocbq *elsiocb;
dea31012005-04-17 16:05:31 -0500744 struct lpfc_dmabuf *pcmd;
James Smart2e0fef82007-06-17 19:56:36 -0500745 struct serv_parm *sp;
746 struct lpfc_name *pnn, *ppn;
dea31012005-04-17 16:05:31 -0500747 struct ls_rjt stat;
748 ADISC *ap;
749 IOCB_t *icmd;
750 uint32_t *lp;
751 uint32_t cmd;
752
753 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
754 lp = (uint32_t *) pcmd->virt;
755
756 cmd = *lp++;
757 if (cmd == ELS_CMD_ADISC) {
758 ap = (ADISC *) lp;
759 pnn = (struct lpfc_name *) & ap->nodeName;
760 ppn = (struct lpfc_name *) & ap->portName;
761 } else {
762 sp = (struct serv_parm *) lp;
763 pnn = (struct lpfc_name *) & sp->nodeName;
764 ppn = (struct lpfc_name *) & sp->portName;
765 }
766
767 icmd = &cmdiocb->iocb;
James Smart2e0fef82007-06-17 19:56:36 -0500768 if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) {
James Smart6b5151f2012-01-18 16:24:06 -0500769
770 /*
771 * As soon as we send ACC, the remote NPort can
772 * start sending us data. Thus, for SLI4 we must
773 * resume the RPI before the ACC goes out.
774 */
775 if (vport->phba->sli_rev == LPFC_SLI_REV4) {
776 elsiocb = kmalloc(sizeof(struct lpfc_iocbq),
777 GFP_KERNEL);
778 if (elsiocb) {
779
780 /* Save info from cmd IOCB used in rsp */
781 memcpy((uint8_t *)elsiocb, (uint8_t *)cmdiocb,
782 sizeof(struct lpfc_iocbq));
783
784 /* Save the ELS cmd */
785 elsiocb->drvrTimeout = cmd;
786
787 lpfc_sli4_resume_rpi(ndlp,
788 lpfc_mbx_cmpl_resume_rpi, elsiocb);
789 goto out;
790 }
791 }
792
dea31012005-04-17 16:05:31 -0500793 if (cmd == ELS_CMD_ADISC) {
James Smart2e0fef82007-06-17 19:56:36 -0500794 lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp);
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -0500795 } else {
James Smart6b5151f2012-01-18 16:24:06 -0500796 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
797 ndlp, NULL);
dea31012005-04-17 16:05:31 -0500798 }
James Smart6b5151f2012-01-18 16:24:06 -0500799out:
800 /* If we are authenticated, move to the proper state */
James Smart26d824c2019-08-14 16:56:39 -0700801 if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET))
James Smart6b5151f2012-01-18 16:24:06 -0500802 lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
803 else
804 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
805
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -0500806 return 1;
dea31012005-04-17 16:05:31 -0500807 }
808 /* Reject this request because invalid parameters */
809 stat.un.b.lsRjtRsvd0 = 0;
810 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
811 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
812 stat.un.b.vendorUnique = 0;
James Smart858c9f62007-06-17 19:56:39 -0500813 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
dea31012005-04-17 16:05:31 -0500814
dea31012005-04-17 16:05:31 -0500815 /* 1 sec timeout */
James Smart256ec0d2013-04-17 20:14:58 -0400816 mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000));
dea31012005-04-17 16:05:31 -0500817
James Smart2e0fef82007-06-17 19:56:36 -0500818 spin_lock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -0500819 ndlp->nlp_flag |= NLP_DELAY_TMO;
James Smart2e0fef82007-06-17 19:56:36 -0500820 spin_unlock_irq(shost->host_lock);
Jamie Wellnitz5024ab12006-02-28 19:25:28 -0500821 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
822 ndlp->nlp_prev_state = ndlp->nlp_state;
James Smart2e0fef82007-06-17 19:56:36 -0500823 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -0500824 return 0;
dea31012005-04-17 16:05:31 -0500825}
826
827static int
James Smart2e0fef82007-06-17 19:56:36 -0500828lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
829 struct lpfc_iocbq *cmdiocb, uint32_t els_cmd)
dea31012005-04-17 16:05:31 -0500830{
James Smart2e0fef82007-06-17 19:56:36 -0500831 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart4b40c592010-03-15 11:25:44 -0400832 struct lpfc_hba *phba = vport->phba;
833 struct lpfc_vport **vports;
834 int i, active_vlink_present = 0 ;
James Smart2e0fef82007-06-17 19:56:36 -0500835
836 /* Put ndlp in NPR state with 1 sec timeout for plogi, ACC logo */
dea31012005-04-17 16:05:31 -0500837 /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary
838 * PLOGIs during LOGO storms from a device.
839 */
James Smart2e0fef82007-06-17 19:56:36 -0500840 spin_lock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -0500841 ndlp->nlp_flag |= NLP_LOGO_ACC;
James Smart2e0fef82007-06-17 19:56:36 -0500842 spin_unlock_irq(shost->host_lock);
James Smart82d9a2a2006-04-15 11:53:05 -0400843 if (els_cmd == ELS_CMD_PRLO)
James Smart51ef4c22007-08-02 11:10:31 -0400844 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
James Smart82d9a2a2006-04-15 11:53:05 -0400845 else
James Smart51ef4c22007-08-02 11:10:31 -0400846 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
James Smart4c2805a2020-03-31 09:50:10 -0700847
848 /* Notify transport of connectivity loss to trigger cleanup. */
849 if (phba->nvmet_support &&
850 ndlp->nlp_state == NLP_STE_UNMAPPED_NODE)
851 lpfc_nvmet_invalidate_host(phba, ndlp);
852
James Smart4b40c592010-03-15 11:25:44 -0400853 if (ndlp->nlp_DID == Fabric_DID) {
854 if (vport->port_state <= LPFC_FDISC)
855 goto out;
James Smart6fb120a2009-05-22 14:52:59 -0400856 lpfc_linkdown_port(vport);
James Smart6fb120a2009-05-22 14:52:59 -0400857 spin_lock_irq(shost->host_lock);
James Smart4b40c592010-03-15 11:25:44 -0400858 vport->fc_flag |= FC_VPORT_LOGO_RCVD;
James Smart6fb120a2009-05-22 14:52:59 -0400859 spin_unlock_irq(shost->host_lock);
James Smart4b40c592010-03-15 11:25:44 -0400860 vports = lpfc_create_vport_work_array(phba);
861 if (vports) {
862 for (i = 0; i <= phba->max_vports && vports[i] != NULL;
863 i++) {
864 if ((!(vports[i]->fc_flag &
865 FC_VPORT_LOGO_RCVD)) &&
866 (vports[i]->port_state > LPFC_FDISC)) {
867 active_vlink_present = 1;
868 break;
869 }
870 }
871 lpfc_destroy_vport_work_array(phba, vports);
872 }
dea31012005-04-17 16:05:31 -0500873
James Smartcc823552015-05-21 13:55:26 -0400874 /*
875 * Don't re-instantiate if vport is marked for deletion.
876 * If we are here first then vport_delete is going to wait
877 * for discovery to complete.
878 */
879 if (!(vport->load_flag & FC_UNLOADING) &&
880 active_vlink_present) {
James Smart4b40c592010-03-15 11:25:44 -0400881 /*
882 * If there are other active VLinks present,
883 * re-instantiate the Vlink using FDISC.
884 */
James Smart256ec0d2013-04-17 20:14:58 -0400885 mod_timer(&ndlp->nlp_delayfunc,
886 jiffies + msecs_to_jiffies(1000));
James Smart4b40c592010-03-15 11:25:44 -0400887 spin_lock_irq(shost->host_lock);
888 ndlp->nlp_flag |= NLP_DELAY_TMO;
889 spin_unlock_irq(shost->host_lock);
890 ndlp->nlp_last_elscmd = ELS_CMD_FDISC;
891 vport->port_state = LPFC_FDISC;
892 } else {
893 spin_lock_irq(shost->host_lock);
894 phba->pport->fc_flag &= ~FC_LOGO_RCVD_DID_CHNG;
895 spin_unlock_irq(shost->host_lock);
896 lpfc_retry_pport_discovery(phba);
897 }
James Smart6fb120a2009-05-22 14:52:59 -0400898 } else if ((!(ndlp->nlp_type & NLP_FABRIC) &&
899 ((ndlp->nlp_type & NLP_FCP_TARGET) ||
900 !(ndlp->nlp_type & NLP_FCP_INITIATOR))) ||
901 (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
dea31012005-04-17 16:05:31 -0500902 /* Only try to re-login if this is NOT a Fabric Node */
James Smart256ec0d2013-04-17 20:14:58 -0400903 mod_timer(&ndlp->nlp_delayfunc,
904 jiffies + msecs_to_jiffies(1000 * 1));
James Smart2e0fef82007-06-17 19:56:36 -0500905 spin_lock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -0500906 ndlp->nlp_flag |= NLP_DELAY_TMO;
James Smart2e0fef82007-06-17 19:56:36 -0500907 spin_unlock_irq(shost->host_lock);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -0500908
Jamie Wellnitz5024ab12006-02-28 19:25:28 -0500909 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
dea31012005-04-17 16:05:31 -0500910 }
James Smart4b40c592010-03-15 11:25:44 -0400911out:
James Smart87af33f2007-10-27 13:37:43 -0400912 ndlp->nlp_prev_state = ndlp->nlp_state;
913 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
dea31012005-04-17 16:05:31 -0500914
James Smart2e0fef82007-06-17 19:56:36 -0500915 spin_lock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -0500916 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
James Smart2e0fef82007-06-17 19:56:36 -0500917 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -0500918 /* The driver has to wait until the ACC completes before it continues
919 * processing the LOGO. The action will resume in
920 * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an
921 * unreg_login, the driver waits so the ACC does not get aborted.
922 */
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -0500923 return 0;
dea31012005-04-17 16:05:31 -0500924}
925
James Smartb95e29b2017-12-08 17:18:05 -0800926static uint32_t
927lpfc_rcv_prli_support_check(struct lpfc_vport *vport,
928 struct lpfc_nodelist *ndlp,
929 struct lpfc_iocbq *cmdiocb)
930{
931 struct ls_rjt stat;
932 uint32_t *payload;
933 uint32_t cmd;
934
935 payload = ((struct lpfc_dmabuf *)cmdiocb->context2)->virt;
936 cmd = *payload;
937 if (vport->phba->nvmet_support) {
938 /* Must be a NVME PRLI */
939 if (cmd == ELS_CMD_PRLI)
940 goto out;
941 } else {
942 /* Initiator mode. */
943 if (!vport->nvmei_support && (cmd == ELS_CMD_NVMEPRLI))
944 goto out;
945 }
946 return 1;
947out:
948 lpfc_printf_vlog(vport, KERN_WARNING, LOG_NVME_DISC,
949 "6115 Rcv PRLI (%x) check failed: ndlp rpi %d "
950 "state x%x flags x%x\n",
951 cmd, ndlp->nlp_rpi, ndlp->nlp_state,
952 ndlp->nlp_flag);
953 memset(&stat, 0, sizeof(struct ls_rjt));
954 stat.un.b.lsRjtRsnCode = LSRJT_CMD_UNSUPPORTED;
955 stat.un.b.lsRjtRsnCodeExp = LSEXP_REQ_UNSUPPORTED;
956 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
957 ndlp, NULL);
958 return 0;
959}
960
dea31012005-04-17 16:05:31 -0500961static void
James Smart2e0fef82007-06-17 19:56:36 -0500962lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
963 struct lpfc_iocbq *cmdiocb)
dea31012005-04-17 16:05:31 -0500964{
James Smarta0f2d3e2017-02-12 13:52:31 -0800965 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -0500966 struct lpfc_dmabuf *pcmd;
967 uint32_t *lp;
968 PRLI *npr;
969 struct fc_rport *rport = ndlp->rport;
970 u32 roles;
971
972 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
973 lp = (uint32_t *) pcmd->virt;
974 npr = (PRLI *) ((uint8_t *) lp + sizeof (uint32_t));
975
James Smarta0f2d3e2017-02-12 13:52:31 -0800976 if ((npr->prliType == PRLI_FCP_TYPE) ||
977 (npr->prliType == PRLI_NVME_TYPE)) {
978 if (npr->initiatorFunc) {
979 if (npr->prliType == PRLI_FCP_TYPE)
980 ndlp->nlp_type |= NLP_FCP_INITIATOR;
981 if (npr->prliType == PRLI_NVME_TYPE)
982 ndlp->nlp_type |= NLP_NVME_INITIATOR;
983 }
James Smart3cb01c52013-07-15 18:35:04 -0400984 if (npr->targetFunc) {
James Smarta0f2d3e2017-02-12 13:52:31 -0800985 if (npr->prliType == PRLI_FCP_TYPE)
986 ndlp->nlp_type |= NLP_FCP_TARGET;
987 if (npr->prliType == PRLI_NVME_TYPE)
988 ndlp->nlp_type |= NLP_NVME_TARGET;
James Smart3cb01c52013-07-15 18:35:04 -0400989 if (npr->writeXferRdyDis)
990 ndlp->nlp_flag |= NLP_FIRSTBURST;
991 }
James Smart0d8af092019-08-14 16:57:10 -0700992 if (npr->Retry && ndlp->nlp_type &
993 (NLP_FCP_INITIATOR | NLP_FCP_TARGET))
dea31012005-04-17 16:05:31 -0500994 ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
James Smart8c258642017-02-12 13:52:36 -0800995
James Smart0d8af092019-08-14 16:57:10 -0700996 if (npr->Retry && phba->nsler &&
997 ndlp->nlp_type & (NLP_NVME_INITIATOR | NLP_NVME_TARGET))
998 ndlp->nlp_nvme_info |= NLP_NVME_NSLER;
999
1000
James Smart8c258642017-02-12 13:52:36 -08001001 /* If this driver is in nvme target mode, set the ndlp's fc4
1002 * type to NVME provided the PRLI response claims NVME FC4
1003 * type. Target mode does not issue gft_id so doesn't get
1004 * the fc4 type set until now.
1005 */
James Smart9de416a2017-12-08 17:18:07 -08001006 if (phba->nvmet_support && (npr->prliType == PRLI_NVME_TYPE)) {
James Smart8c258642017-02-12 13:52:36 -08001007 ndlp->nlp_fc4_type |= NLP_FC4_NVME;
James Smart9de416a2017-12-08 17:18:07 -08001008 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1009 }
1010 if (npr->prliType == PRLI_FCP_TYPE)
1011 ndlp->nlp_fc4_type |= NLP_FC4_FCP;
dea31012005-04-17 16:05:31 -05001012 }
1013 if (rport) {
1014 /* We need to update the rport role values */
1015 roles = FC_RPORT_ROLE_UNKNOWN;
1016 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
1017 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
1018 if (ndlp->nlp_type & NLP_FCP_TARGET)
1019 roles |= FC_RPORT_ROLE_FCP_TARGET;
James Smart858c9f62007-06-17 19:56:39 -05001020
1021 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
1022 "rport rolechg: role:x%x did:x%x flg:x%x",
1023 roles, ndlp->nlp_DID, ndlp->nlp_flag);
1024
James Smartf6e84792019-01-28 11:14:38 -08001025 if (vport->cfg_enable_fc4_type != LPFC_ENABLE_NVME)
James Smarta0f2d3e2017-02-12 13:52:31 -08001026 fc_remote_port_rolechg(rport, roles);
dea31012005-04-17 16:05:31 -05001027 }
1028}
1029
1030static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001031lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
dea31012005-04-17 16:05:31 -05001032{
James Smart2e0fef82007-06-17 19:56:36 -05001033 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart2e0fef82007-06-17 19:56:36 -05001034
James Smart40426292010-12-15 17:58:10 -05001035 if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {
James Smart30e196c2018-10-23 13:41:03 -07001036 spin_lock_irq(shost->host_lock);
James Smart51ef4c22007-08-02 11:10:31 -04001037 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
James Smart30e196c2018-10-23 13:41:03 -07001038 spin_unlock_irq(shost->host_lock);
James Smart51ef4c22007-08-02 11:10:31 -04001039 return 0;
1040 }
1041
James Smart1b32f6a2008-02-08 18:49:39 -05001042 if (!(vport->fc_flag & FC_PT2PT)) {
1043 /* Check config parameter use-adisc or FCP-2 */
Daniel Wagner0fd103c2019-10-22 09:21:12 +02001044 if (vport->cfg_use_adisc && ((vport->fc_flag & FC_RSCN_MODE) ||
James Smartffc95492010-06-07 15:23:17 -04001045 ((ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) &&
Daniel Wagner0fd103c2019-10-22 09:21:12 +02001046 (ndlp->nlp_type & NLP_FCP_TARGET)))) {
James Smart1b32f6a2008-02-08 18:49:39 -05001047 spin_lock_irq(shost->host_lock);
1048 ndlp->nlp_flag |= NLP_NPR_ADISC;
1049 spin_unlock_irq(shost->host_lock);
1050 return 1;
1051 }
James Smart92d7f7b2007-06-17 19:56:38 -05001052 }
James Smart30e196c2018-10-23 13:41:03 -07001053
1054 spin_lock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -05001055 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
James Smart30e196c2018-10-23 13:41:03 -07001056 spin_unlock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -05001057 lpfc_unreg_rpi(vport, ndlp);
1058 return 0;
dea31012005-04-17 16:05:31 -05001059}
James Smart6d368e52011-05-24 11:44:12 -04001060
James Smart78730cf2010-04-06 15:06:30 -04001061/**
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001062 * lpfc_release_rpi - Release a RPI by issuing unreg_login mailbox cmd.
James Smart78730cf2010-04-06 15:06:30 -04001063 * @phba : Pointer to lpfc_hba structure.
1064 * @vport: Pointer to lpfc_vport structure.
1065 * @rpi : rpi to be release.
1066 *
1067 * This function will send a unreg_login mailbox command to the firmware
1068 * to release a rpi.
1069 **/
Bart Van Assche3999df72019-03-28 11:06:16 -07001070static void
James Smartdea16bd2018-11-29 16:09:30 -08001071lpfc_release_rpi(struct lpfc_hba *phba, struct lpfc_vport *vport,
1072 struct lpfc_nodelist *ndlp, uint16_t rpi)
James Smart78730cf2010-04-06 15:06:30 -04001073{
1074 LPFC_MBOXQ_t *pmb;
1075 int rc;
1076
James Smartdea16bd2018-11-29 16:09:30 -08001077 /* If there is already an UNREG in progress for this ndlp,
1078 * no need to queue up another one.
1079 */
1080 if (ndlp->nlp_flag & NLP_UNREG_INP) {
1081 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1082 "1435 release_rpi SKIP UNREG x%x on "
1083 "NPort x%x deferred x%x flg x%x "
James Smart32350662019-08-14 16:57:06 -07001084 "Data: x%px\n",
James Smartdea16bd2018-11-29 16:09:30 -08001085 ndlp->nlp_rpi, ndlp->nlp_DID,
1086 ndlp->nlp_defer_did,
1087 ndlp->nlp_flag, ndlp);
1088 return;
1089 }
1090
James Smart78730cf2010-04-06 15:06:30 -04001091 pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
1092 GFP_KERNEL);
1093 if (!pmb)
1094 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
1095 "2796 mailbox memory allocation failed \n");
1096 else {
1097 lpfc_unreg_login(phba, vport->vpi, rpi, pmb);
1098 pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
James Smartdea16bd2018-11-29 16:09:30 -08001099 pmb->vport = vport;
1100 pmb->ctx_ndlp = ndlp;
1101
1102 if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
1103 (!(vport->fc_flag & FC_OFFLINE_MODE)))
1104 ndlp->nlp_flag |= NLP_UNREG_INP;
1105
1106 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1107 "1437 release_rpi UNREG x%x "
1108 "on NPort x%x flg x%x\n",
1109 ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag);
1110
James Smart78730cf2010-04-06 15:06:30 -04001111 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
1112 if (rc == MBX_NOT_FINISHED)
1113 mempool_free(pmb, phba->mbox_mem_pool);
1114 }
1115}
dea31012005-04-17 16:05:31 -05001116
1117static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001118lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1119 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001120{
James Smart78730cf2010-04-06 15:06:30 -04001121 struct lpfc_hba *phba;
1122 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
James Smart78730cf2010-04-06 15:06:30 -04001123 uint16_t rpi;
1124
1125 phba = vport->phba;
1126 /* Release the RPI if reglogin completing */
1127 if (!(phba->pport->load_flag & FC_UNLOADING) &&
1128 (evt == NLP_EVT_CMPL_REG_LOGIN) &&
1129 (!pmb->u.mb.mbxStatus)) {
James Smart78730cf2010-04-06 15:06:30 -04001130 rpi = pmb->u.mb.un.varWords[0];
James Smartdea16bd2018-11-29 16:09:30 -08001131 lpfc_release_rpi(phba, vport, ndlp, rpi);
James Smart78730cf2010-04-06 15:06:30 -04001132 }
James Smarte8b62012007-08-02 11:10:09 -04001133 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
James Smarte47c9092008-02-08 18:49:26 -05001134 "0271 Illegal State Transition: node x%x "
James Smarte8b62012007-08-02 11:10:09 -04001135 "event x%x, state x%x Data: x%x x%x\n",
1136 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
1137 ndlp->nlp_flag);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001138 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001139}
1140
James Smart87af33f2007-10-27 13:37:43 -04001141static uint32_t
1142lpfc_cmpl_plogi_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1143 void *arg, uint32_t evt)
1144{
1145 /* This transition is only legal if we previously
1146 * rcv'ed a PLOGI. Since we don't want 2 discovery threads
1147 * working on the same NPortID, do nothing for this thread
1148 * to stop it.
1149 */
1150 if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) {
1151 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
James Smarte47c9092008-02-08 18:49:26 -05001152 "0272 Illegal State Transition: node x%x "
James Smart87af33f2007-10-27 13:37:43 -04001153 "event x%x, state x%x Data: x%x x%x\n",
1154 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
1155 ndlp->nlp_flag);
1156 }
1157 return ndlp->nlp_state;
1158}
1159
dea31012005-04-17 16:05:31 -05001160/* Start of Discovery State Machine routines */
1161
1162static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001163lpfc_rcv_plogi_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1164 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001165{
1166 struct lpfc_iocbq *cmdiocb;
1167
1168 cmdiocb = (struct lpfc_iocbq *) arg;
1169
James Smart2e0fef82007-06-17 19:56:36 -05001170 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001171 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001172 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001173 return NLP_STE_FREED_NODE;
dea31012005-04-17 16:05:31 -05001174}
1175
1176static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001177lpfc_rcv_els_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1178 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001179{
James Smart2e0fef82007-06-17 19:56:36 -05001180 lpfc_issue_els_logo(vport, ndlp, 0);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001181 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001182}
1183
1184static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001185lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1186 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001187{
James Smart2e0fef82007-06-17 19:56:36 -05001188 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1189 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05001190
James Smart2e0fef82007-06-17 19:56:36 -05001191 spin_lock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05001192 ndlp->nlp_flag |= NLP_LOGO_ACC;
James Smart2e0fef82007-06-17 19:56:36 -05001193 spin_unlock_irq(shost->host_lock);
James Smart51ef4c22007-08-02 11:10:31 -04001194 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
dea31012005-04-17 16:05:31 -05001195
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001196 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001197}
1198
1199static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001200lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
dea31012005-04-17 16:05:31 -05001201 void *arg, uint32_t evt)
1202{
James Smart2e0fef82007-06-17 19:56:36 -05001203 return NLP_STE_FREED_NODE;
1204}
1205
1206static uint32_t
1207lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1208 void *arg, uint32_t evt)
1209{
James Smart2e0fef82007-06-17 19:56:36 -05001210 return NLP_STE_FREED_NODE;
1211}
1212
1213static uint32_t
James Smartdf9e1b52011-12-13 13:22:17 -05001214lpfc_device_recov_unused_node(struct lpfc_vport *vport,
1215 struct lpfc_nodelist *ndlp,
1216 void *arg, uint32_t evt)
1217{
1218 return ndlp->nlp_state;
1219}
1220
1221static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001222lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1223 void *arg, uint32_t evt)
1224{
James Smart0d2b6b82008-06-14 22:52:47 -04001225 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart2e0fef82007-06-17 19:56:36 -05001226 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05001227 struct lpfc_iocbq *cmdiocb = arg;
James Smart2e0fef82007-06-17 19:56:36 -05001228 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
1229 uint32_t *lp = (uint32_t *) pcmd->virt;
1230 struct serv_parm *sp = (struct serv_parm *) (lp + 1);
dea31012005-04-17 16:05:31 -05001231 struct ls_rjt stat;
1232 int port_cmp;
1233
dea31012005-04-17 16:05:31 -05001234 memset(&stat, 0, sizeof (struct ls_rjt));
1235
1236 /* For a PLOGI, we only accept if our portname is less
1237 * than the remote portname.
1238 */
1239 phba->fc_stat.elsLogiCol++;
James Smart2e0fef82007-06-17 19:56:36 -05001240 port_cmp = memcmp(&vport->fc_portname, &sp->portName,
James Smart92d7f7b2007-06-17 19:56:38 -05001241 sizeof(struct lpfc_name));
dea31012005-04-17 16:05:31 -05001242
1243 if (port_cmp >= 0) {
1244 /* Reject this request because the remote node will accept
1245 ours */
1246 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
1247 stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;
James Smart858c9f62007-06-17 19:56:39 -05001248 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
1249 NULL);
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05001250 } else {
James Smart0d2b6b82008-06-14 22:52:47 -04001251 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb) &&
1252 (ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
1253 (vport->num_disc_nodes)) {
1254 spin_lock_irq(shost->host_lock);
1255 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1256 spin_unlock_irq(shost->host_lock);
1257 /* Check if there are more PLOGIs to be sent */
1258 lpfc_more_plogi(vport);
1259 if (vport->num_disc_nodes == 0) {
1260 spin_lock_irq(shost->host_lock);
1261 vport->fc_flag &= ~FC_NDISC_ACTIVE;
1262 spin_unlock_irq(shost->host_lock);
1263 lpfc_can_disctmo(vport);
1264 lpfc_end_rscn(vport);
1265 }
1266 }
James Smart2e0fef82007-06-17 19:56:36 -05001267 } /* If our portname was less */
dea31012005-04-17 16:05:31 -05001268
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001269 return ndlp->nlp_state;
1270}
1271
1272static uint32_t
James Smart92d7f7b2007-06-17 19:56:38 -05001273lpfc_rcv_prli_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1274 void *arg, uint32_t evt)
1275{
1276 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1277 struct ls_rjt stat;
1278
1279 memset(&stat, 0, sizeof (struct ls_rjt));
1280 stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
1281 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
James Smart858c9f62007-06-17 19:56:39 -05001282 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
James Smart92d7f7b2007-06-17 19:56:38 -05001283 return ndlp->nlp_state;
1284}
1285
1286static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001287lpfc_rcv_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1288 void *arg, uint32_t evt)
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001289{
James Smart2e0fef82007-06-17 19:56:36 -05001290 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001291
James Smartfaa832e2018-07-31 17:23:18 -07001292 /* Retrieve RPI from LOGO IOCB. RPI is used for CMD_ABORT_XRI_CN */
1293 if (vport->phba->sli_rev == LPFC_SLI_REV3)
1294 ndlp->nlp_rpi = cmdiocb->iocb.ulpIoTag;
James Smart92d7f7b2007-06-17 19:56:38 -05001295 /* software abort outstanding PLOGI */
James Smart2e0fef82007-06-17 19:56:36 -05001296 lpfc_els_abort(vport->phba, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001297
James Smart2e0fef82007-06-17 19:56:36 -05001298 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001299 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001300}
1301
1302static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001303lpfc_rcv_els_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1304 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001305{
James Smart2e0fef82007-06-17 19:56:36 -05001306 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1307 struct lpfc_hba *phba = vport->phba;
1308 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05001309
1310 /* software abort outstanding PLOGI */
James Smart07951072007-04-25 09:51:38 -04001311 lpfc_els_abort(phba, ndlp);
dea31012005-04-17 16:05:31 -05001312
1313 if (evt == NLP_EVT_RCV_LOGO) {
James Smart51ef4c22007-08-02 11:10:31 -04001314 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05001315 } else {
James Smart2e0fef82007-06-17 19:56:36 -05001316 lpfc_issue_els_logo(vport, ndlp, 0);
dea31012005-04-17 16:05:31 -05001317 }
1318
James Smart2e0fef82007-06-17 19:56:36 -05001319 /* Put ndlp in npr state set plogi timer for 1 sec */
James Smart256ec0d2013-04-17 20:14:58 -04001320 mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000 * 1));
James Smart2e0fef82007-06-17 19:56:36 -05001321 spin_lock_irq(shost->host_lock);
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001322 ndlp->nlp_flag |= NLP_DELAY_TMO;
James Smart2e0fef82007-06-17 19:56:36 -05001323 spin_unlock_irq(shost->host_lock);
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001324 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
1325 ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05001326 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
dea31012005-04-17 16:05:31 -05001327
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001328 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001329}
1330
1331static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001332lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
1333 struct lpfc_nodelist *ndlp,
1334 void *arg,
dea31012005-04-17 16:05:31 -05001335 uint32_t evt)
1336{
James Smart2e0fef82007-06-17 19:56:36 -05001337 struct lpfc_hba *phba = vport->phba;
James Smart0ff10d42008-01-11 01:52:36 -05001338 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart2e0fef82007-06-17 19:56:36 -05001339 struct lpfc_iocbq *cmdiocb, *rspiocb;
James Smart14691152006-12-02 13:34:28 -05001340 struct lpfc_dmabuf *pcmd, *prsp, *mp;
dea31012005-04-17 16:05:31 -05001341 uint32_t *lp;
James Smart8c258642017-02-12 13:52:36 -08001342 uint32_t vid, flag;
dea31012005-04-17 16:05:31 -05001343 IOCB_t *irsp;
1344 struct serv_parm *sp;
James Smartd6de08c2015-12-16 18:11:53 -05001345 uint32_t ed_tov;
dea31012005-04-17 16:05:31 -05001346 LPFC_MBOXQ_t *mbox;
James Smartd6de08c2015-12-16 18:11:53 -05001347 int rc;
dea31012005-04-17 16:05:31 -05001348
1349 cmdiocb = (struct lpfc_iocbq *) arg;
1350 rspiocb = cmdiocb->context_un.rsp_iocb;
1351
1352 if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001353 /* Recovery from PLOGI collision logic */
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001354 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001355 }
1356
1357 irsp = &rspiocb->iocb;
1358
1359 if (irsp->ulpStatus)
1360 goto out;
1361
1362 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
1363
James Smart2e0fef82007-06-17 19:56:36 -05001364 prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
James Smarta2fc4aef2014-09-03 12:57:55 -04001365 if (!prsp)
1366 goto out;
dea31012005-04-17 16:05:31 -05001367
James Smart2e0fef82007-06-17 19:56:36 -05001368 lp = (uint32_t *) prsp->virt;
dea31012005-04-17 16:05:31 -05001369 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
James Smart58da1ff2008-04-07 10:15:56 -04001370
1371 /* Some switches have FDMI servers returning 0 for WWN */
1372 if ((ndlp->nlp_DID != FDMI_DID) &&
1373 (wwn_to_u64(sp->portName.u.wwn) == 0 ||
1374 wwn_to_u64(sp->nodeName.u.wwn) == 0)) {
James Smarta8adb832007-10-27 13:37:53 -04001375 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1376 "0142 PLOGI RSP: Invalid WWN.\n");
1377 goto out;
1378 }
James Smart341af102010-01-26 23:07:37 -05001379 if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0))
dea31012005-04-17 16:05:31 -05001380 goto out;
dea31012005-04-17 16:05:31 -05001381 /* PLOGI chkparm OK */
James Smarte8b62012007-08-02 11:10:09 -04001382 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1383 "0121 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",
1384 ndlp->nlp_DID, ndlp->nlp_state,
1385 ndlp->nlp_flag, ndlp->nlp_rpi);
James Smart3de2a652007-08-02 11:09:59 -04001386 if (vport->cfg_fcp_class == 2 && (sp->cls2.classValid))
dea31012005-04-17 16:05:31 -05001387 ndlp->nlp_fcp_info |= CLASS2;
James Smart2e0fef82007-06-17 19:56:36 -05001388 else
dea31012005-04-17 16:05:31 -05001389 ndlp->nlp_fcp_info |= CLASS3;
James Smart2e0fef82007-06-17 19:56:36 -05001390
dea31012005-04-17 16:05:31 -05001391 ndlp->nlp_class_sup = 0;
1392 if (sp->cls1.classValid)
1393 ndlp->nlp_class_sup |= FC_COS_CLASS1;
1394 if (sp->cls2.classValid)
1395 ndlp->nlp_class_sup |= FC_COS_CLASS2;
1396 if (sp->cls3.classValid)
1397 ndlp->nlp_class_sup |= FC_COS_CLASS3;
1398 if (sp->cls4.classValid)
1399 ndlp->nlp_class_sup |= FC_COS_CLASS4;
1400 ndlp->nlp_maxframe =
James Smart2e0fef82007-06-17 19:56:36 -05001401 ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
dea31012005-04-17 16:05:31 -05001402
James Smartd6de08c2015-12-16 18:11:53 -05001403 if ((vport->fc_flag & FC_PT2PT) &&
1404 (vport->fc_flag & FC_PT2PT_PLOGI)) {
1405 ed_tov = be32_to_cpu(sp->cmn.e_d_tov);
1406 if (sp->cmn.edtovResolution) {
1407 /* E_D_TOV ticks are in nanoseconds */
1408 ed_tov = (phba->fc_edtov + 999999) / 1000000;
1409 }
1410
James Smart8c258642017-02-12 13:52:36 -08001411 ndlp->nlp_flag &= ~NLP_SUPPRESS_RSP;
1412 if ((phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) &&
1413 sp->cmn.valid_vendor_ver_level) {
1414 vid = be32_to_cpu(sp->un.vv.vid);
1415 flag = be32_to_cpu(sp->un.vv.flags);
1416 if ((vid == LPFC_VV_EMLX_ID) &&
1417 (flag & LPFC_VV_SUPPRESS_RSP))
1418 ndlp->nlp_flag |= NLP_SUPPRESS_RSP;
1419 }
1420
James Smartd6de08c2015-12-16 18:11:53 -05001421 /*
1422 * Use the larger EDTOV
1423 * RATOV = 2 * EDTOV for pt-to-pt
1424 */
1425 if (ed_tov > phba->fc_edtov)
1426 phba->fc_edtov = ed_tov;
1427 phba->fc_ratov = (2 * phba->fc_edtov) / 1000;
1428
1429 memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
1430
1431 /* Issue config_link / reg_vfi to account for updated TOV's */
1432 if (phba->sli_rev == LPFC_SLI_REV4) {
1433 lpfc_issue_reg_vfi(vport);
1434 } else {
James Smart01c73bb2015-12-16 18:12:03 -05001435 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1436 if (!mbox) {
1437 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1438 "0133 PLOGI: no memory "
1439 "for config_link "
1440 "Data: x%x x%x x%x x%x\n",
1441 ndlp->nlp_DID, ndlp->nlp_state,
1442 ndlp->nlp_flag, ndlp->nlp_rpi);
1443 goto out;
1444 }
1445
James Smartd6de08c2015-12-16 18:11:53 -05001446 lpfc_config_link(phba, mbox);
1447
1448 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1449 mbox->vport = vport;
1450 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
1451 if (rc == MBX_NOT_FINISHED) {
1452 mempool_free(mbox, phba->mbox_mem_pool);
1453 goto out;
1454 }
1455 }
James Smart92d7f7b2007-06-17 19:56:38 -05001456 }
dea31012005-04-17 16:05:31 -05001457
James Smart2e0fef82007-06-17 19:56:36 -05001458 lpfc_unreg_rpi(vport, ndlp);
1459
James Smart01c73bb2015-12-16 18:12:03 -05001460 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1461 if (!mbox) {
1462 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1463 "0018 PLOGI: no memory for reg_login "
1464 "Data: x%x x%x x%x x%x\n",
1465 ndlp->nlp_DID, ndlp->nlp_state,
1466 ndlp->nlp_flag, ndlp->nlp_rpi);
1467 goto out;
1468 }
1469
James Smart6fb120a2009-05-22 14:52:59 -04001470 if (lpfc_reg_rpi(phba, vport->vpi, irsp->un.elsreq64.remoteID,
James Smart40426292010-12-15 17:58:10 -05001471 (uint8_t *) sp, mbox, ndlp->nlp_rpi) == 0) {
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05001472 switch (ndlp->nlp_DID) {
dea31012005-04-17 16:05:31 -05001473 case NameServer_DID:
James Smartde0c5b32007-04-25 09:52:27 -04001474 mbox->mbox_cmpl = lpfc_mbx_cmpl_ns_reg_login;
dea31012005-04-17 16:05:31 -05001475 break;
1476 case FDMI_DID:
James Smartde0c5b32007-04-25 09:52:27 -04001477 mbox->mbox_cmpl = lpfc_mbx_cmpl_fdmi_reg_login;
dea31012005-04-17 16:05:31 -05001478 break;
1479 default:
James Smartffc95492010-06-07 15:23:17 -04001480 ndlp->nlp_flag |= NLP_REG_LOGIN_SEND;
James Smartde0c5b32007-04-25 09:52:27 -04001481 mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
dea31012005-04-17 16:05:31 -05001482 }
James Smart3e1f0712018-11-29 16:09:29 -08001483 mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
James Smart2e0fef82007-06-17 19:56:36 -05001484 mbox->vport = vport;
James Smart0b727fe2007-10-27 13:37:25 -04001485 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
dea31012005-04-17 16:05:31 -05001486 != MBX_NOT_FINISHED) {
James Smart2e0fef82007-06-17 19:56:36 -05001487 lpfc_nlp_set_state(vport, ndlp,
1488 NLP_STE_REG_LOGIN_ISSUE);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001489 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001490 }
James Smartffc95492010-06-07 15:23:17 -04001491 if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND)
1492 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
James Smartfa4066b2008-01-11 01:53:27 -05001493 /* decrement node reference count to the failed mbox
1494 * command
1495 */
James Smart329f9bc2007-04-25 09:53:01 -04001496 lpfc_nlp_put(ndlp);
James Smart3e1f0712018-11-29 16:09:29 -08001497 mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
James Smart14691152006-12-02 13:34:28 -05001498 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1499 kfree(mp);
dea31012005-04-17 16:05:31 -05001500 mempool_free(mbox, phba->mbox_mem_pool);
James Smart92d7f7b2007-06-17 19:56:38 -05001501
James Smarte8b62012007-08-02 11:10:09 -04001502 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1503 "0134 PLOGI: cannot issue reg_login "
1504 "Data: x%x x%x x%x x%x\n",
1505 ndlp->nlp_DID, ndlp->nlp_state,
1506 ndlp->nlp_flag, ndlp->nlp_rpi);
dea31012005-04-17 16:05:31 -05001507 } else {
1508 mempool_free(mbox, phba->mbox_mem_pool);
James Smart92d7f7b2007-06-17 19:56:38 -05001509
James Smarte8b62012007-08-02 11:10:09 -04001510 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1511 "0135 PLOGI: cannot format reg_login "
1512 "Data: x%x x%x x%x x%x\n",
1513 ndlp->nlp_DID, ndlp->nlp_state,
1514 ndlp->nlp_flag, ndlp->nlp_rpi);
dea31012005-04-17 16:05:31 -05001515 }
1516
1517
James Smart92d7f7b2007-06-17 19:56:38 -05001518out:
1519 if (ndlp->nlp_DID == NameServer_DID) {
1520 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
James Smarte8b62012007-08-02 11:10:09 -04001521 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1522 "0261 Cannot Register NameServer login\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001523 }
1524
James Smart8b455cf2013-01-03 15:43:53 -05001525 /*
1526 ** In case the node reference counter does not go to zero, ensure that
1527 ** the stale state for the node is not processed.
1528 */
1529
1530 ndlp->nlp_prev_state = ndlp->nlp_state;
1531 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
James Smart0ff10d42008-01-11 01:52:36 -05001532 spin_lock_irq(shost->host_lock);
James Smarta8adb832007-10-27 13:37:53 -04001533 ndlp->nlp_flag |= NLP_DEFER_RM;
James Smart0ff10d42008-01-11 01:52:36 -05001534 spin_unlock_irq(shost->host_lock);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001535 return NLP_STE_FREED_NODE;
dea31012005-04-17 16:05:31 -05001536}
1537
1538static uint32_t
James Smart0ff10d42008-01-11 01:52:36 -05001539lpfc_cmpl_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1540 void *arg, uint32_t evt)
1541{
1542 return ndlp->nlp_state;
1543}
1544
1545static uint32_t
1546lpfc_cmpl_reglogin_plogi_issue(struct lpfc_vport *vport,
1547 struct lpfc_nodelist *ndlp, void *arg, uint32_t evt)
1548{
James Smart78730cf2010-04-06 15:06:30 -04001549 struct lpfc_hba *phba;
1550 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
1551 MAILBOX_t *mb = &pmb->u.mb;
1552 uint16_t rpi;
1553
1554 phba = vport->phba;
1555 /* Release the RPI */
1556 if (!(phba->pport->load_flag & FC_UNLOADING) &&
1557 !mb->mbxStatus) {
1558 rpi = pmb->u.mb.un.varWords[0];
James Smartdea16bd2018-11-29 16:09:30 -08001559 lpfc_release_rpi(phba, vport, ndlp, rpi);
James Smart78730cf2010-04-06 15:06:30 -04001560 }
James Smart0ff10d42008-01-11 01:52:36 -05001561 return ndlp->nlp_state;
1562}
1563
1564static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001565lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1566 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001567{
James Smart2e0fef82007-06-17 19:56:36 -05001568 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05001569
James Smart2e0fef82007-06-17 19:56:36 -05001570 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1571 spin_lock_irq(shost->host_lock);
1572 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1573 spin_unlock_irq(shost->host_lock);
1574 return ndlp->nlp_state;
1575 } else {
1576 /* software abort outstanding PLOGI */
1577 lpfc_els_abort(vport->phba, ndlp);
1578
1579 lpfc_drop_node(vport, ndlp);
James Smarta0f9b482006-04-15 11:52:56 -04001580 return NLP_STE_FREED_NODE;
1581 }
dea31012005-04-17 16:05:31 -05001582}
1583
1584static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001585lpfc_device_recov_plogi_issue(struct lpfc_vport *vport,
1586 struct lpfc_nodelist *ndlp,
1587 void *arg,
1588 uint32_t evt)
dea31012005-04-17 16:05:31 -05001589{
James Smart2e0fef82007-06-17 19:56:36 -05001590 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1591 struct lpfc_hba *phba = vport->phba;
1592
James Smart92d7f7b2007-06-17 19:56:38 -05001593 /* Don't do anything that will mess up processing of the
1594 * previous RSCN.
1595 */
1596 if (vport->fc_flag & FC_RSCN_DEFERRED)
1597 return ndlp->nlp_state;
1598
dea31012005-04-17 16:05:31 -05001599 /* software abort outstanding PLOGI */
James Smart07951072007-04-25 09:51:38 -04001600 lpfc_els_abort(phba, ndlp);
dea31012005-04-17 16:05:31 -05001601
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001602 ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05001603 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
James Smart92d7f7b2007-06-17 19:56:38 -05001604 spin_lock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04001605 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
James Smart2e0fef82007-06-17 19:56:36 -05001606 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05001607
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001608 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001609}
1610
1611static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001612lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1613 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001614{
James Smart0d2b6b82008-06-14 22:52:47 -04001615 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart2e0fef82007-06-17 19:56:36 -05001616 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05001617 struct lpfc_iocbq *cmdiocb;
1618
1619 /* software abort outstanding ADISC */
James Smart07951072007-04-25 09:51:38 -04001620 lpfc_els_abort(phba, ndlp);
dea31012005-04-17 16:05:31 -05001621
1622 cmdiocb = (struct lpfc_iocbq *) arg;
1623
James Smart0d2b6b82008-06-14 22:52:47 -04001624 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
1625 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1626 spin_lock_irq(shost->host_lock);
1627 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1628 spin_unlock_irq(shost->host_lock);
James Smart90160e02008-08-24 21:49:45 -04001629 if (vport->num_disc_nodes)
James Smart0d2b6b82008-06-14 22:52:47 -04001630 lpfc_more_adisc(vport);
James Smart0d2b6b82008-06-14 22:52:47 -04001631 }
1632 return ndlp->nlp_state;
1633 }
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001634 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05001635 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
1636 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
dea31012005-04-17 16:05:31 -05001637
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001638 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001639}
1640
1641static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001642lpfc_rcv_prli_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1643 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001644{
James Smart2e0fef82007-06-17 19:56:36 -05001645 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05001646
James Smartb95e29b2017-12-08 17:18:05 -08001647 if (lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
1648 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001649 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001650}
1651
1652static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001653lpfc_rcv_logo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1654 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001655{
James Smart2e0fef82007-06-17 19:56:36 -05001656 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05001657 struct lpfc_iocbq *cmdiocb;
1658
1659 cmdiocb = (struct lpfc_iocbq *) arg;
1660
1661 /* software abort outstanding ADISC */
James Smart07951072007-04-25 09:51:38 -04001662 lpfc_els_abort(phba, ndlp);
dea31012005-04-17 16:05:31 -05001663
James Smart2e0fef82007-06-17 19:56:36 -05001664 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001665 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001666}
1667
1668static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001669lpfc_rcv_padisc_adisc_issue(struct lpfc_vport *vport,
1670 struct lpfc_nodelist *ndlp,
1671 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001672{
1673 struct lpfc_iocbq *cmdiocb;
1674
1675 cmdiocb = (struct lpfc_iocbq *) arg;
1676
James Smart2e0fef82007-06-17 19:56:36 -05001677 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001678 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001679}
1680
1681static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001682lpfc_rcv_prlo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1683 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001684{
1685 struct lpfc_iocbq *cmdiocb;
1686
1687 cmdiocb = (struct lpfc_iocbq *) arg;
1688
1689 /* Treat like rcv logo */
James Smart2e0fef82007-06-17 19:56:36 -05001690 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001691 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001692}
1693
1694static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001695lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport,
1696 struct lpfc_nodelist *ndlp,
1697 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001698{
James Smart2e0fef82007-06-17 19:56:36 -05001699 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1700 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05001701 struct lpfc_iocbq *cmdiocb, *rspiocb;
1702 IOCB_t *irsp;
1703 ADISC *ap;
James Smart6fb120a2009-05-22 14:52:59 -04001704 int rc;
dea31012005-04-17 16:05:31 -05001705
1706 cmdiocb = (struct lpfc_iocbq *) arg;
1707 rspiocb = cmdiocb->context_un.rsp_iocb;
1708
1709 ap = (ADISC *)lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);
1710 irsp = &rspiocb->iocb;
1711
1712 if ((irsp->ulpStatus) ||
James Smart92d7f7b2007-06-17 19:56:38 -05001713 (!lpfc_check_adisc(vport, ndlp, &ap->nodeName, &ap->portName))) {
dea31012005-04-17 16:05:31 -05001714 /* 1 sec timeout */
James Smart256ec0d2013-04-17 20:14:58 -04001715 mod_timer(&ndlp->nlp_delayfunc,
1716 jiffies + msecs_to_jiffies(1000));
James Smart2e0fef82007-06-17 19:56:36 -05001717 spin_lock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05001718 ndlp->nlp_flag |= NLP_DELAY_TMO;
James Smart2e0fef82007-06-17 19:56:36 -05001719 spin_unlock_irq(shost->host_lock);
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001720 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
dea31012005-04-17 16:05:31 -05001721
James Smart2e0fef82007-06-17 19:56:36 -05001722 memset(&ndlp->nlp_nodename, 0, sizeof(struct lpfc_name));
1723 memset(&ndlp->nlp_portname, 0, sizeof(struct lpfc_name));
dea31012005-04-17 16:05:31 -05001724
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001725 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05001726 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1727 lpfc_unreg_rpi(vport, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001728 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001729 }
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001730
James Smart6fb120a2009-05-22 14:52:59 -04001731 if (phba->sli_rev == LPFC_SLI_REV4) {
James Smart6b5151f2012-01-18 16:24:06 -05001732 rc = lpfc_sli4_resume_rpi(ndlp, NULL, NULL);
James Smart6fb120a2009-05-22 14:52:59 -04001733 if (rc) {
1734 /* Stay in state and retry. */
1735 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1736 return ndlp->nlp_state;
1737 }
1738 }
1739
James.Smart@Emulex.Com25013222005-06-25 10:34:33 -04001740 if (ndlp->nlp_type & NLP_FCP_TARGET) {
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001741 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05001742 lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
James.Smart@Emulex.Com25013222005-06-25 10:34:33 -04001743 } else {
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001744 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05001745 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
James.Smart@Emulex.Com25013222005-06-25 10:34:33 -04001746 }
James Smart6fb120a2009-05-22 14:52:59 -04001747
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001748 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001749}
1750
1751static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001752lpfc_device_rm_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1753 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05001754{
James Smart2e0fef82007-06-17 19:56:36 -05001755 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05001756
James Smart2e0fef82007-06-17 19:56:36 -05001757 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1758 spin_lock_irq(shost->host_lock);
1759 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1760 spin_unlock_irq(shost->host_lock);
1761 return ndlp->nlp_state;
1762 } else {
1763 /* software abort outstanding ADISC */
1764 lpfc_els_abort(vport->phba, ndlp);
1765
1766 lpfc_drop_node(vport, ndlp);
James Smarta0f9b482006-04-15 11:52:56 -04001767 return NLP_STE_FREED_NODE;
1768 }
dea31012005-04-17 16:05:31 -05001769}
1770
1771static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001772lpfc_device_recov_adisc_issue(struct lpfc_vport *vport,
1773 struct lpfc_nodelist *ndlp,
1774 void *arg,
1775 uint32_t evt)
dea31012005-04-17 16:05:31 -05001776{
James Smart2e0fef82007-06-17 19:56:36 -05001777 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1778 struct lpfc_hba *phba = vport->phba;
1779
James Smart92d7f7b2007-06-17 19:56:38 -05001780 /* Don't do anything that will mess up processing of the
1781 * previous RSCN.
1782 */
1783 if (vport->fc_flag & FC_RSCN_DEFERRED)
1784 return ndlp->nlp_state;
1785
dea31012005-04-17 16:05:31 -05001786 /* software abort outstanding ADISC */
James Smart07951072007-04-25 09:51:38 -04001787 lpfc_els_abort(phba, ndlp);
dea31012005-04-17 16:05:31 -05001788
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001789 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05001790 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1791 spin_lock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04001792 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
James Smart2e0fef82007-06-17 19:56:36 -05001793 spin_unlock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -05001794 lpfc_disc_set_adisc(vport, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001795 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001796}
1797
1798static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001799lpfc_rcv_plogi_reglogin_issue(struct lpfc_vport *vport,
1800 struct lpfc_nodelist *ndlp,
1801 void *arg,
dea31012005-04-17 16:05:31 -05001802 uint32_t evt)
1803{
James Smart2e0fef82007-06-17 19:56:36 -05001804 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05001805
James Smart2e0fef82007-06-17 19:56:36 -05001806 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001807 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001808}
1809
1810static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001811lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport,
1812 struct lpfc_nodelist *ndlp,
1813 void *arg,
dea31012005-04-17 16:05:31 -05001814 uint32_t evt)
1815{
James Smart2e0fef82007-06-17 19:56:36 -05001816 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
James Smart8c258642017-02-12 13:52:36 -08001817 struct ls_rjt stat;
dea31012005-04-17 16:05:31 -05001818
James Smartb95e29b2017-12-08 17:18:05 -08001819 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb)) {
1820 return ndlp->nlp_state;
1821 }
James Smart8c258642017-02-12 13:52:36 -08001822 if (vport->phba->nvmet_support) {
1823 /* NVME Target mode. Handle and respond to the PRLI and
1824 * transition to UNMAPPED provided the RPI has completed
1825 * registration.
1826 */
1827 if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
1828 lpfc_rcv_prli(vport, ndlp, cmdiocb);
1829 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
James Smart8c258642017-02-12 13:52:36 -08001830 } else {
1831 /* RPI registration has not completed. Reject the PRLI
1832 * to prevent an illegal state transition when the
1833 * rpi registration does complete.
1834 */
James Smart8c258642017-02-12 13:52:36 -08001835 memset(&stat, 0, sizeof(struct ls_rjt));
James Smarte06351a2017-12-08 17:18:08 -08001836 stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
1837 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
James Smart8c258642017-02-12 13:52:36 -08001838 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
1839 ndlp, NULL);
James Smart9de416a2017-12-08 17:18:07 -08001840 return ndlp->nlp_state;
James Smart8c258642017-02-12 13:52:36 -08001841 }
1842 } else {
1843 /* Initiator mode. */
1844 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1845 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001846 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001847}
1848
1849static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001850lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
1851 struct lpfc_nodelist *ndlp,
1852 void *arg,
dea31012005-04-17 16:05:31 -05001853 uint32_t evt)
1854{
James Smart2e0fef82007-06-17 19:56:36 -05001855 struct lpfc_hba *phba = vport->phba;
1856 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
James Smart7054a602007-04-25 09:52:34 -04001857 LPFC_MBOXQ_t *mb;
1858 LPFC_MBOXQ_t *nextmb;
1859 struct lpfc_dmabuf *mp;
James Smart57178b92019-08-14 16:56:37 -07001860 struct lpfc_nodelist *ns_ndlp;
dea31012005-04-17 16:05:31 -05001861
1862 cmdiocb = (struct lpfc_iocbq *) arg;
1863
James Smart7054a602007-04-25 09:52:34 -04001864 /* cleanup any ndlp on mbox q waiting for reglogin cmpl */
1865 if ((mb = phba->sli.mbox_active)) {
James Smart04c68492009-05-22 14:52:52 -04001866 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
James Smart3e1f0712018-11-29 16:09:29 -08001867 (ndlp == (struct lpfc_nodelist *)mb->ctx_ndlp)) {
James Smartde96e9c2016-03-31 14:12:27 -07001868 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
James Smart92d7f7b2007-06-17 19:56:38 -05001869 lpfc_nlp_put(ndlp);
James Smart3e1f0712018-11-29 16:09:29 -08001870 mb->ctx_ndlp = NULL;
James Smart7054a602007-04-25 09:52:34 -04001871 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1872 }
1873 }
1874
James Smart2e0fef82007-06-17 19:56:36 -05001875 spin_lock_irq(&phba->hbalock);
James Smart7054a602007-04-25 09:52:34 -04001876 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
James Smart04c68492009-05-22 14:52:52 -04001877 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
James Smart3e1f0712018-11-29 16:09:29 -08001878 (ndlp == (struct lpfc_nodelist *)mb->ctx_ndlp)) {
1879 mp = (struct lpfc_dmabuf *)(mb->ctx_buf);
James Smart7054a602007-04-25 09:52:34 -04001880 if (mp) {
James Smart98c9ea52007-10-27 13:37:33 -04001881 __lpfc_mbuf_free(phba, mp->virt, mp->phys);
James Smart7054a602007-04-25 09:52:34 -04001882 kfree(mp);
1883 }
James Smartde96e9c2016-03-31 14:12:27 -07001884 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
James Smart92d7f7b2007-06-17 19:56:38 -05001885 lpfc_nlp_put(ndlp);
James Smart7054a602007-04-25 09:52:34 -04001886 list_del(&mb->list);
James Smart5ffc2662009-11-18 15:39:44 -05001887 phba->sli.mboxq_cnt--;
James Smart7054a602007-04-25 09:52:34 -04001888 mempool_free(mb, phba->mbox_mem_pool);
1889 }
1890 }
James Smart2e0fef82007-06-17 19:56:36 -05001891 spin_unlock_irq(&phba->hbalock);
James Smart7054a602007-04-25 09:52:34 -04001892
James Smart57178b92019-08-14 16:56:37 -07001893 /* software abort if any GID_FT is outstanding */
1894 if (vport->cfg_enable_fc4_type != LPFC_ENABLE_FCP) {
1895 ns_ndlp = lpfc_findnode_did(vport, NameServer_DID);
1896 if (ns_ndlp && NLP_CHK_NODE_ACT(ns_ndlp))
1897 lpfc_els_abort(phba, ns_ndlp);
1898 }
1899
James Smart2e0fef82007-06-17 19:56:36 -05001900 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001901 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001902}
1903
1904static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001905lpfc_rcv_padisc_reglogin_issue(struct lpfc_vport *vport,
1906 struct lpfc_nodelist *ndlp,
1907 void *arg,
dea31012005-04-17 16:05:31 -05001908 uint32_t evt)
1909{
James Smart2e0fef82007-06-17 19:56:36 -05001910 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05001911
James Smart2e0fef82007-06-17 19:56:36 -05001912 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001913 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001914}
1915
1916static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001917lpfc_rcv_prlo_reglogin_issue(struct lpfc_vport *vport,
1918 struct lpfc_nodelist *ndlp,
1919 void *arg,
dea31012005-04-17 16:05:31 -05001920 uint32_t evt)
1921{
1922 struct lpfc_iocbq *cmdiocb;
1923
1924 cmdiocb = (struct lpfc_iocbq *) arg;
James Smart51ef4c22007-08-02 11:10:31 -04001925 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001926 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001927}
1928
1929static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05001930lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
1931 struct lpfc_nodelist *ndlp,
1932 void *arg,
1933 uint32_t evt)
dea31012005-04-17 16:05:31 -05001934{
James Smart2e0fef82007-06-17 19:56:36 -05001935 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smarta0f2d3e2017-02-12 13:52:31 -08001936 struct lpfc_hba *phba = vport->phba;
James Smart2e0fef82007-06-17 19:56:36 -05001937 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
James Smart04c68492009-05-22 14:52:52 -04001938 MAILBOX_t *mb = &pmb->u.mb;
James Smart2e0fef82007-06-17 19:56:36 -05001939 uint32_t did = mb->un.varWords[1];
dea31012005-04-17 16:05:31 -05001940
dea31012005-04-17 16:05:31 -05001941 if (mb->mbxStatus) {
1942 /* RegLogin failed */
James Smarte8b62012007-08-02 11:10:09 -04001943 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
James Smart6d368e52011-05-24 11:44:12 -04001944 "0246 RegLogin failed Data: x%x x%x x%x x%x "
1945 "x%x\n",
1946 did, mb->mbxStatus, vport->port_state,
1947 mb->un.varRegLogin.vpi,
1948 mb->un.varRegLogin.rpi);
James Smartd0e56da2006-07-06 15:49:42 -04001949 /*
1950 * If RegLogin failed due to lack of HBA resources do not
1951 * retry discovery.
1952 */
1953 if (mb->mbxStatus == MBXERR_RPI_FULL) {
James Smart87af33f2007-10-27 13:37:43 -04001954 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1955 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
James Smartd0e56da2006-07-06 15:49:42 -04001956 return ndlp->nlp_state;
1957 }
1958
James Smart2e0fef82007-06-17 19:56:36 -05001959 /* Put ndlp in npr state set plogi timer for 1 sec */
James Smart256ec0d2013-04-17 20:14:58 -04001960 mod_timer(&ndlp->nlp_delayfunc,
1961 jiffies + msecs_to_jiffies(1000 * 1));
James Smart2e0fef82007-06-17 19:56:36 -05001962 spin_lock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05001963 ndlp->nlp_flag |= NLP_DELAY_TMO;
James Smart2e0fef82007-06-17 19:56:36 -05001964 spin_unlock_irq(shost->host_lock);
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001965 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
dea31012005-04-17 16:05:31 -05001966
James Smart2e0fef82007-06-17 19:56:36 -05001967 lpfc_issue_els_logo(vport, ndlp, 0);
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05001968 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05001969 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05001970 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05001971 }
1972
James Smart6d368e52011-05-24 11:44:12 -04001973 /* SLI4 ports have preallocated logical rpis. */
James Smarta0f2d3e2017-02-12 13:52:31 -08001974 if (phba->sli_rev < LPFC_SLI_REV4)
James Smart6d368e52011-05-24 11:44:12 -04001975 ndlp->nlp_rpi = mb->un.varWords[0];
1976
James Smart40426292010-12-15 17:58:10 -05001977 ndlp->nlp_flag |= NLP_RPI_REGISTERED;
dea31012005-04-17 16:05:31 -05001978
1979 /* Only if we are not a fabric nport do we issue PRLI */
James Smarta0f2d3e2017-02-12 13:52:31 -08001980 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1981 "3066 RegLogin Complete on x%x x%x x%x\n",
1982 did, ndlp->nlp_type, ndlp->nlp_fc4_type);
1983 if (!(ndlp->nlp_type & NLP_FABRIC) &&
1984 (phba->nvmet_support == 0)) {
1985 /* The driver supports FCP and NVME concurrently. If the
1986 * ndlp's nlp_fc4_type is still zero, the driver doesn't
1987 * know what PRLI to send yet. Figure that out now and
1988 * call PRLI depending on the outcome.
1989 */
1990 if (vport->fc_flag & FC_PT2PT) {
1991 /* If we are pt2pt, there is no Fabric to determine
1992 * the FC4 type of the remote nport. So if NVME
1993 * is configured try it.
1994 */
1995 ndlp->nlp_fc4_type |= NLP_FC4_FCP;
James Smartf6e84792019-01-28 11:14:38 -08001996 if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
1997 (vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
James Smarta0f2d3e2017-02-12 13:52:31 -08001998 ndlp->nlp_fc4_type |= NLP_FC4_NVME;
1999 /* We need to update the localport also */
James Smart01649562017-02-12 13:52:32 -08002000 lpfc_nvme_update_localport(vport);
James Smarta0f2d3e2017-02-12 13:52:31 -08002001 }
2002
Dick Kennedy2877cbf2017-08-23 16:55:31 -07002003 } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
2004 ndlp->nlp_fc4_type |= NLP_FC4_FCP;
2005
James Smarta0f2d3e2017-02-12 13:52:31 -08002006 } else if (ndlp->nlp_fc4_type == 0) {
James Smart7ea92eb2018-10-23 13:41:10 -07002007 /* If we are only configured for FCP, the driver
2008 * should just issue PRLI for FCP. Otherwise issue
2009 * GFT_ID to determine if remote port supports NVME.
2010 */
James Smartf6e84792019-01-28 11:14:38 -08002011 if (vport->cfg_enable_fc4_type != LPFC_ENABLE_FCP) {
Bart Van Asscheb27cbd52019-03-28 11:06:20 -07002012 lpfc_ns_cmd(vport, SLI_CTNS_GFT_ID, 0,
2013 ndlp->nlp_DID);
James Smart7ea92eb2018-10-23 13:41:10 -07002014 return ndlp->nlp_state;
2015 }
2016 ndlp->nlp_fc4_type = NLP_FC4_FCP;
James Smarta0f2d3e2017-02-12 13:52:31 -08002017 }
2018
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002019 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05002020 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
James Smart7f20c1c2019-08-14 16:56:38 -07002021 if (lpfc_issue_els_prli(vport, ndlp, 0)) {
2022 lpfc_issue_els_logo(vport, ndlp, 0);
2023 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
2024 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2025 }
dea31012005-04-17 16:05:31 -05002026 } else {
James Smart8c258642017-02-12 13:52:36 -08002027 if ((vport->fc_flag & FC_PT2PT) && phba->nvmet_support)
2028 phba->targetport->port_id = vport->fc_myDID;
2029
2030 /* Only Fabric ports should transition. NVME target
2031 * must complete PRLI.
2032 */
James Smarta0f2d3e2017-02-12 13:52:31 -08002033 if (ndlp->nlp_type & NLP_FABRIC) {
2034 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
2035 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
2036 }
dea31012005-04-17 16:05:31 -05002037 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002038 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002039}
2040
2041static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002042lpfc_device_rm_reglogin_issue(struct lpfc_vport *vport,
2043 struct lpfc_nodelist *ndlp,
2044 void *arg,
dea31012005-04-17 16:05:31 -05002045 uint32_t evt)
2046{
James Smart2e0fef82007-06-17 19:56:36 -05002047 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2048
2049 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
2050 spin_lock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04002051 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
James Smart2e0fef82007-06-17 19:56:36 -05002052 spin_unlock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04002053 return ndlp->nlp_state;
James Smart2e0fef82007-06-17 19:56:36 -05002054 } else {
2055 lpfc_drop_node(vport, ndlp);
James Smarta0f9b482006-04-15 11:52:56 -04002056 return NLP_STE_FREED_NODE;
2057 }
dea31012005-04-17 16:05:31 -05002058}
2059
2060static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002061lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport,
2062 struct lpfc_nodelist *ndlp,
2063 void *arg,
2064 uint32_t evt)
dea31012005-04-17 16:05:31 -05002065{
James Smart2e0fef82007-06-17 19:56:36 -05002066 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2067
James Smart92d7f7b2007-06-17 19:56:38 -05002068 /* Don't do anything that will mess up processing of the
2069 * previous RSCN.
2070 */
2071 if (vport->fc_flag & FC_RSCN_DEFERRED)
2072 return ndlp->nlp_state;
2073
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002074 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05002075 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2076 spin_lock_irq(shost->host_lock);
James Smarta0f2d3e2017-02-12 13:52:31 -08002077
James Smart8c258642017-02-12 13:52:36 -08002078 /* If we are a target we won't immediately transition into PRLI,
2079 * so if REG_LOGIN already completed we don't need to ignore it.
2080 */
2081 if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED) ||
2082 !vport->phba->nvmet_support)
2083 ndlp->nlp_flag |= NLP_IGNR_REG_CMPL;
2084
James Smarta0f9b482006-04-15 11:52:56 -04002085 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
James Smart2e0fef82007-06-17 19:56:36 -05002086 spin_unlock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -05002087 lpfc_disc_set_adisc(vport, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002088 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002089}
2090
2091static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002092lpfc_rcv_plogi_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2093 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002094{
2095 struct lpfc_iocbq *cmdiocb;
2096
2097 cmdiocb = (struct lpfc_iocbq *) arg;
2098
James Smart2e0fef82007-06-17 19:56:36 -05002099 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002100 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002101}
2102
2103static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002104lpfc_rcv_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2105 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002106{
James Smart2e0fef82007-06-17 19:56:36 -05002107 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002108
James Smartb95e29b2017-12-08 17:18:05 -08002109 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
2110 return ndlp->nlp_state;
James Smart2e0fef82007-06-17 19:56:36 -05002111 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002112 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002113}
2114
2115static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002116lpfc_rcv_logo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2117 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002118{
James Smart2e0fef82007-06-17 19:56:36 -05002119 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002120
2121 /* Software abort outstanding PRLI before sending acc */
James Smart2e0fef82007-06-17 19:56:36 -05002122 lpfc_els_abort(vport->phba, ndlp);
dea31012005-04-17 16:05:31 -05002123
James Smart2e0fef82007-06-17 19:56:36 -05002124 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002125 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002126}
2127
2128static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002129lpfc_rcv_padisc_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2130 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002131{
James Smart2e0fef82007-06-17 19:56:36 -05002132 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002133
James Smart2e0fef82007-06-17 19:56:36 -05002134 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002135 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002136}
2137
2138/* This routine is envoked when we rcv a PRLO request from a nport
2139 * we are logged into. We should send back a PRLO rsp setting the
2140 * appropriate bits.
2141 * NEXT STATE = PRLI_ISSUE
2142 */
2143static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002144lpfc_rcv_prlo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2145 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002146{
James Smart2e0fef82007-06-17 19:56:36 -05002147 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002148
James Smart51ef4c22007-08-02 11:10:31 -04002149 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002150 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002151}
2152
2153static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002154lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2155 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002156{
James Smart92d7f7b2007-06-17 19:56:38 -05002157 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05002158 struct lpfc_iocbq *cmdiocb, *rspiocb;
James Smart2e0fef82007-06-17 19:56:36 -05002159 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05002160 IOCB_t *irsp;
2161 PRLI *npr;
James Smarta0f2d3e2017-02-12 13:52:31 -08002162 struct lpfc_nvme_prli *nvpr;
2163 void *temp_ptr;
dea31012005-04-17 16:05:31 -05002164
2165 cmdiocb = (struct lpfc_iocbq *) arg;
2166 rspiocb = cmdiocb->context_un.rsp_iocb;
James Smarta0f2d3e2017-02-12 13:52:31 -08002167
2168 /* A solicited PRLI is either FCP or NVME. The PRLI cmd/rsp
2169 * format is different so NULL the two PRLI types so that the
2170 * driver correctly gets the correct context.
2171 */
2172 npr = NULL;
2173 nvpr = NULL;
2174 temp_ptr = lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);
2175 if (cmdiocb->iocb_flag & LPFC_PRLI_FCP_REQ)
2176 npr = (PRLI *) temp_ptr;
2177 else if (cmdiocb->iocb_flag & LPFC_PRLI_NVME_REQ)
2178 nvpr = (struct lpfc_nvme_prli *) temp_ptr;
dea31012005-04-17 16:05:31 -05002179
2180 irsp = &rspiocb->iocb;
2181 if (irsp->ulpStatus) {
James Smart858c9f62007-06-17 19:56:39 -05002182 if ((vport->port_type == LPFC_NPIV_PORT) &&
James Smart3de2a652007-08-02 11:09:59 -04002183 vport->cfg_restrict_login) {
James Smart858c9f62007-06-17 19:56:39 -05002184 goto out;
2185 }
James Smarta0f2d3e2017-02-12 13:52:31 -08002186
James Smart118c0412018-04-09 14:24:21 -07002187 /* Adjust the nlp_type accordingly if the PRLI failed */
2188 if (npr)
Dick Kennedy8db1c2b2017-08-23 16:55:36 -07002189 ndlp->nlp_fc4_type &= ~NLP_FC4_FCP;
James Smart118c0412018-04-09 14:24:21 -07002190 if (nvpr)
2191 ndlp->nlp_fc4_type &= ~NLP_FC4_NVME;
Dick Kennedy8db1c2b2017-08-23 16:55:36 -07002192
James Smart118c0412018-04-09 14:24:21 -07002193 /* We can't set the DSM state till BOTH PRLIs complete */
2194 goto out_err;
dea31012005-04-17 16:05:31 -05002195 }
2196
James Smarta0f2d3e2017-02-12 13:52:31 -08002197 if (npr && (npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
dea31012005-04-17 16:05:31 -05002198 (npr->prliType == PRLI_FCP_TYPE)) {
James Smarta0f2d3e2017-02-12 13:52:31 -08002199 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
2200 "6028 FCP NPR PRLI Cmpl Init %d Target %d\n",
2201 npr->initiatorFunc,
2202 npr->targetFunc);
dea31012005-04-17 16:05:31 -05002203 if (npr->initiatorFunc)
2204 ndlp->nlp_type |= NLP_FCP_INITIATOR;
James Smart3cb01c52013-07-15 18:35:04 -04002205 if (npr->targetFunc) {
dea31012005-04-17 16:05:31 -05002206 ndlp->nlp_type |= NLP_FCP_TARGET;
James Smart3cb01c52013-07-15 18:35:04 -04002207 if (npr->writeXferRdyDis)
2208 ndlp->nlp_flag |= NLP_FIRSTBURST;
2209 }
dea31012005-04-17 16:05:31 -05002210 if (npr->Retry)
2211 ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
James Smarta0f2d3e2017-02-12 13:52:31 -08002212
James Smarta0f2d3e2017-02-12 13:52:31 -08002213 } else if (nvpr &&
2214 (bf_get_be32(prli_acc_rsp_code, nvpr) ==
2215 PRLI_REQ_EXECUTED) &&
2216 (bf_get_be32(prli_type_code, nvpr) ==
2217 PRLI_NVME_TYPE)) {
2218
2219 /* Complete setting up the remote ndlp personality. */
2220 if (bf_get_be32(prli_init, nvpr))
2221 ndlp->nlp_type |= NLP_NVME_INITIATOR;
2222
James Smart69641622019-11-04 16:57:03 -08002223 if (phba->nsler && bf_get_be32(prli_nsler, nvpr) &&
2224 bf_get_be32(prli_conf, nvpr))
2225
James Smart0d8af092019-08-14 16:57:10 -07002226 ndlp->nlp_nvme_info |= NLP_NVME_NSLER;
2227 else
2228 ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER;
2229
James Smarta0f2d3e2017-02-12 13:52:31 -08002230 /* Target driver cannot solicit NVME FB. */
2231 if (bf_get_be32(prli_tgt, nvpr)) {
James Smartdc53a612017-05-15 15:20:50 -07002232 /* Complete the nvme target roles. The transport
2233 * needs to know if the rport is capable of
2234 * discovery in addition to its role.
2235 */
James Smarta0f2d3e2017-02-12 13:52:31 -08002236 ndlp->nlp_type |= NLP_NVME_TARGET;
James Smartdc53a612017-05-15 15:20:50 -07002237 if (bf_get_be32(prli_disc, nvpr))
2238 ndlp->nlp_type |= NLP_NVME_DISCOVERY;
James Smart07092632018-03-05 12:04:02 -08002239
2240 /*
2241 * If prli_fba is set, the Target supports FirstBurst.
2242 * If prli_fb_sz is 0, the FirstBurst size is unlimited,
2243 * otherwise it defines the actual size supported by
2244 * the NVME Target.
2245 */
James Smarta0f2d3e2017-02-12 13:52:31 -08002246 if ((bf_get_be32(prli_fba, nvpr) == 1) &&
James Smarta0f2d3e2017-02-12 13:52:31 -08002247 (phba->cfg_nvme_enable_fb) &&
2248 (!phba->nvmet_support)) {
2249 /* Both sides support FB. The target's first
2250 * burst size is a 512 byte encoded value.
2251 */
2252 ndlp->nlp_flag |= NLP_FIRSTBURST;
2253 ndlp->nvme_fb_size = bf_get_be32(prli_fb_sz,
2254 nvpr);
James Smart07092632018-03-05 12:04:02 -08002255
2256 /* Expressed in units of 512 bytes */
2257 if (ndlp->nvme_fb_size)
2258 ndlp->nvme_fb_size <<=
2259 LPFC_NVME_FB_SHIFT;
2260 else
2261 ndlp->nvme_fb_size = LPFC_NVME_MAX_FB;
James Smarta0f2d3e2017-02-12 13:52:31 -08002262 }
2263 }
2264
James Smarta0f2d3e2017-02-12 13:52:31 -08002265 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
2266 "6029 NVME PRLI Cmpl w1 x%08x "
2267 "w4 x%08x w5 x%08x flag x%x, "
2268 "fcp_info x%x nlp_type x%x\n",
2269 be32_to_cpu(nvpr->word1),
2270 be32_to_cpu(nvpr->word4),
2271 be32_to_cpu(nvpr->word5),
2272 ndlp->nlp_flag, ndlp->nlp_fcp_info,
2273 ndlp->nlp_type);
dea31012005-04-17 16:05:31 -05002274 }
James Smart92d7f7b2007-06-17 19:56:38 -05002275 if (!(ndlp->nlp_type & NLP_FCP_TARGET) &&
2276 (vport->port_type == LPFC_NPIV_PORT) &&
James Smart3de2a652007-08-02 11:09:59 -04002277 vport->cfg_restrict_login) {
James Smart858c9f62007-06-17 19:56:39 -05002278out:
James Smart92d7f7b2007-06-17 19:56:38 -05002279 spin_lock_irq(shost->host_lock);
2280 ndlp->nlp_flag |= NLP_TARGET_REMOVE;
2281 spin_unlock_irq(shost->host_lock);
2282 lpfc_issue_els_logo(vport, ndlp, 0);
2283
2284 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
James Smart87af33f2007-10-27 13:37:43 -04002285 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
James Smart92d7f7b2007-06-17 19:56:38 -05002286 return ndlp->nlp_state;
2287 }
dea31012005-04-17 16:05:31 -05002288
James Smarta0f2d3e2017-02-12 13:52:31 -08002289out_err:
2290 /* The ndlp state cannot move to MAPPED or UNMAPPED before all PRLIs
2291 * are complete.
2292 */
2293 if (ndlp->fc4_prli_sent == 0) {
2294 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
2295 if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET))
2296 lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
James Smart9de416a2017-12-08 17:18:07 -08002297 else if (ndlp->nlp_type &
2298 (NLP_FCP_INITIATOR | NLP_NVME_INITIATOR))
James Smarta0f2d3e2017-02-12 13:52:31 -08002299 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
2300 } else
2301 lpfc_printf_vlog(vport,
2302 KERN_INFO, LOG_ELS,
2303 "3067 PRLI's still outstanding "
2304 "on x%06x - count %d, Pend Node Mode "
2305 "transition...\n",
2306 ndlp->nlp_DID, ndlp->fc4_prli_sent);
2307
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002308 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002309}
2310
2311/*! lpfc_device_rm_prli_issue
James Smart92d7f7b2007-06-17 19:56:38 -05002312 *
2313 * \pre
2314 * \post
2315 * \param phba
2316 * \param ndlp
2317 * \param arg
2318 * \param evt
2319 * \return uint32_t
2320 *
2321 * \b Description:
2322 * This routine is envoked when we a request to remove a nport we are in the
2323 * process of PRLIing. We should software abort outstanding prli, unreg
2324 * login, send a logout. We will change node state to UNUSED_NODE, put it
2325 * on plogi list so it can be freed when LOGO completes.
2326 *
2327 */
2328
dea31012005-04-17 16:05:31 -05002329static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002330lpfc_device_rm_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2331 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002332{
James Smart2e0fef82007-06-17 19:56:36 -05002333 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05002334
James Smart2e0fef82007-06-17 19:56:36 -05002335 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
2336 spin_lock_irq(shost->host_lock);
2337 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
2338 spin_unlock_irq(shost->host_lock);
2339 return ndlp->nlp_state;
2340 } else {
2341 /* software abort outstanding PLOGI */
2342 lpfc_els_abort(vport->phba, ndlp);
2343
2344 lpfc_drop_node(vport, ndlp);
James Smarta0f9b482006-04-15 11:52:56 -04002345 return NLP_STE_FREED_NODE;
2346 }
dea31012005-04-17 16:05:31 -05002347}
2348
2349
2350/*! lpfc_device_recov_prli_issue
James Smart92d7f7b2007-06-17 19:56:38 -05002351 *
2352 * \pre
2353 * \post
2354 * \param phba
2355 * \param ndlp
2356 * \param arg
2357 * \param evt
2358 * \return uint32_t
2359 *
2360 * \b Description:
2361 * The routine is envoked when the state of a device is unknown, like
2362 * during a link down. We should remove the nodelist entry from the
2363 * unmapped list, issue a UNREG_LOGIN, do a software abort of the
2364 * outstanding PRLI command, then free the node entry.
2365 */
dea31012005-04-17 16:05:31 -05002366static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002367lpfc_device_recov_prli_issue(struct lpfc_vport *vport,
2368 struct lpfc_nodelist *ndlp,
2369 void *arg,
2370 uint32_t evt)
dea31012005-04-17 16:05:31 -05002371{
James Smart2e0fef82007-06-17 19:56:36 -05002372 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2373 struct lpfc_hba *phba = vport->phba;
2374
James Smart92d7f7b2007-06-17 19:56:38 -05002375 /* Don't do anything that will mess up processing of the
2376 * previous RSCN.
2377 */
2378 if (vport->fc_flag & FC_RSCN_DEFERRED)
2379 return ndlp->nlp_state;
2380
dea31012005-04-17 16:05:31 -05002381 /* software abort outstanding PRLI */
James Smart07951072007-04-25 09:51:38 -04002382 lpfc_els_abort(phba, ndlp);
dea31012005-04-17 16:05:31 -05002383
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002384 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
James Smart2e0fef82007-06-17 19:56:36 -05002385 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2386 spin_lock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04002387 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
James Smart2e0fef82007-06-17 19:56:36 -05002388 spin_unlock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -05002389 lpfc_disc_set_adisc(vport, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002390 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002391}
2392
2393static uint32_t
James Smart086a3452012-08-14 14:25:21 -04002394lpfc_rcv_plogi_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2395 void *arg, uint32_t evt)
2396{
2397 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2398 struct ls_rjt stat;
2399
2400 memset(&stat, 0, sizeof(struct ls_rjt));
2401 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2402 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2403 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2404 return ndlp->nlp_state;
2405}
2406
2407static uint32_t
2408lpfc_rcv_prli_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2409 void *arg, uint32_t evt)
2410{
2411 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2412 struct ls_rjt stat;
2413
2414 memset(&stat, 0, sizeof(struct ls_rjt));
2415 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2416 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2417 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2418 return ndlp->nlp_state;
2419}
2420
2421static uint32_t
2422lpfc_rcv_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2423 void *arg, uint32_t evt)
2424{
2425 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2426 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2427
2428 spin_lock_irq(shost->host_lock);
James Smart7c5e5182015-05-22 10:42:43 -04002429 ndlp->nlp_flag |= NLP_LOGO_ACC;
James Smart086a3452012-08-14 14:25:21 -04002430 spin_unlock_irq(shost->host_lock);
2431 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
2432 return ndlp->nlp_state;
2433}
2434
2435static uint32_t
2436lpfc_rcv_padisc_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2437 void *arg, uint32_t evt)
2438{
2439 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2440 struct ls_rjt stat;
2441
2442 memset(&stat, 0, sizeof(struct ls_rjt));
2443 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2444 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2445 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2446 return ndlp->nlp_state;
2447}
2448
2449static uint32_t
2450lpfc_rcv_prlo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2451 void *arg, uint32_t evt)
2452{
2453 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2454 struct ls_rjt stat;
2455
2456 memset(&stat, 0, sizeof(struct ls_rjt));
2457 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2458 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2459 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2460 return ndlp->nlp_state;
2461}
2462
2463static uint32_t
2464lpfc_cmpl_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2465 void *arg, uint32_t evt)
2466{
2467 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2468
2469 ndlp->nlp_prev_state = NLP_STE_LOGO_ISSUE;
2470 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2471 spin_lock_irq(shost->host_lock);
2472 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2473 spin_unlock_irq(shost->host_lock);
2474 lpfc_disc_set_adisc(vport, ndlp);
2475 return ndlp->nlp_state;
2476}
2477
2478static uint32_t
2479lpfc_device_rm_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2480 void *arg, uint32_t evt)
2481{
2482 /*
Dick Kennedyd2aa4872017-08-23 16:55:32 -07002483 * DevLoss has timed out and is calling for Device Remove.
2484 * In this case, abort the LOGO and cleanup the ndlp
James Smart086a3452012-08-14 14:25:21 -04002485 */
Dick Kennedyd2aa4872017-08-23 16:55:32 -07002486
2487 lpfc_unreg_rpi(vport, ndlp);
2488 /* software abort outstanding PLOGI */
2489 lpfc_els_abort(vport->phba, ndlp);
2490 lpfc_drop_node(vport, ndlp);
2491 return NLP_STE_FREED_NODE;
James Smart086a3452012-08-14 14:25:21 -04002492}
2493
2494static uint32_t
2495lpfc_device_recov_logo_issue(struct lpfc_vport *vport,
2496 struct lpfc_nodelist *ndlp,
2497 void *arg, uint32_t evt)
2498{
2499 /*
2500 * Device Recovery events have no meaning for a node with a LOGO
2501 * outstanding. The LOGO has to complete first and handle the
2502 * node from that point.
2503 */
2504 return ndlp->nlp_state;
2505}
2506
2507static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002508lpfc_rcv_plogi_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2509 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002510{
James Smart2e0fef82007-06-17 19:56:36 -05002511 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002512
James Smart2e0fef82007-06-17 19:56:36 -05002513 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002514 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002515}
2516
2517static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002518lpfc_rcv_prli_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2519 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002520{
James Smart2e0fef82007-06-17 19:56:36 -05002521 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002522
James Smartb95e29b2017-12-08 17:18:05 -08002523 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
2524 return ndlp->nlp_state;
2525
James Smart2e0fef82007-06-17 19:56:36 -05002526 lpfc_rcv_prli(vport, ndlp, cmdiocb);
2527 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002528 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002529}
2530
2531static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002532lpfc_rcv_logo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2533 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002534{
James Smart2e0fef82007-06-17 19:56:36 -05002535 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002536
James Smart2e0fef82007-06-17 19:56:36 -05002537 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002538 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002539}
2540
2541static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002542lpfc_rcv_padisc_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2543 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002544{
James Smart2e0fef82007-06-17 19:56:36 -05002545 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002546
James Smart2e0fef82007-06-17 19:56:36 -05002547 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002548 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002549}
2550
2551static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002552lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2553 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002554{
James Smart2e0fef82007-06-17 19:56:36 -05002555 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002556
James Smart51ef4c22007-08-02 11:10:31 -04002557 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002558 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002559}
2560
2561static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002562lpfc_device_recov_unmap_node(struct lpfc_vport *vport,
2563 struct lpfc_nodelist *ndlp,
2564 void *arg,
2565 uint32_t evt)
dea31012005-04-17 16:05:31 -05002566{
James Smart2e0fef82007-06-17 19:56:36 -05002567 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2568
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002569 ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE;
James Smart2e0fef82007-06-17 19:56:36 -05002570 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2571 spin_lock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04002572 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
James Smart01a8aed2018-09-10 10:30:41 -07002573 ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);
James Smart2e0fef82007-06-17 19:56:36 -05002574 spin_unlock_irq(shost->host_lock);
2575 lpfc_disc_set_adisc(vport, ndlp);
dea31012005-04-17 16:05:31 -05002576
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002577 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002578}
2579
2580static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002581lpfc_rcv_plogi_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2582 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002583{
James Smart2e0fef82007-06-17 19:56:36 -05002584 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002585
James Smart2e0fef82007-06-17 19:56:36 -05002586 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002587 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002588}
2589
2590static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002591lpfc_rcv_prli_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2592 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002593{
James Smart2e0fef82007-06-17 19:56:36 -05002594 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002595
James Smartb95e29b2017-12-08 17:18:05 -08002596 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
2597 return ndlp->nlp_state;
James Smart2e0fef82007-06-17 19:56:36 -05002598 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002599 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002600}
2601
2602static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002603lpfc_rcv_logo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2604 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002605{
James Smart2e0fef82007-06-17 19:56:36 -05002606 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002607
James Smart2e0fef82007-06-17 19:56:36 -05002608 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002609 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002610}
2611
2612static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002613lpfc_rcv_padisc_mapped_node(struct lpfc_vport *vport,
2614 struct lpfc_nodelist *ndlp,
2615 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002616{
James Smart2e0fef82007-06-17 19:56:36 -05002617 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002618
James Smart2e0fef82007-06-17 19:56:36 -05002619 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002620 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002621}
2622
2623static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002624lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2625 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002626{
James Smart2e0fef82007-06-17 19:56:36 -05002627 struct lpfc_hba *phba = vport->phba;
2628 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002629
2630 /* flush the target */
James Smart895427b2017-02-12 13:52:30 -08002631 lpfc_sli_abort_iocb(vport, &phba->sli.sli3_ring[LPFC_FCP_RING],
James Smart51ef4c22007-08-02 11:10:31 -04002632 ndlp->nlp_sid, 0, LPFC_CTX_TGT);
dea31012005-04-17 16:05:31 -05002633
2634 /* Treat like rcv logo */
James Smart2e0fef82007-06-17 19:56:36 -05002635 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002636 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002637}
2638
2639static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002640lpfc_device_recov_mapped_node(struct lpfc_vport *vport,
2641 struct lpfc_nodelist *ndlp,
2642 void *arg,
2643 uint32_t evt)
dea31012005-04-17 16:05:31 -05002644{
James Smart2e0fef82007-06-17 19:56:36 -05002645 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2646
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002647 ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE;
James Smart2e0fef82007-06-17 19:56:36 -05002648 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2649 spin_lock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04002650 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
James Smart01a8aed2018-09-10 10:30:41 -07002651 ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);
James Smart2e0fef82007-06-17 19:56:36 -05002652 spin_unlock_irq(shost->host_lock);
2653 lpfc_disc_set_adisc(vport, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002654 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002655}
2656
2657static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002658lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2659 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002660{
James Smart2e0fef82007-06-17 19:56:36 -05002661 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2662 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002663
2664 /* Ignore PLOGI if we have an outstanding LOGO */
James Smart0d2b6b82008-06-14 22:52:47 -04002665 if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC))
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002666 return ndlp->nlp_state;
James Smart2e0fef82007-06-17 19:56:36 -05002667 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
James Smart0d2b6b82008-06-14 22:52:47 -04002668 lpfc_cancel_retry_delay_tmo(vport, ndlp);
James Smart2e0fef82007-06-17 19:56:36 -05002669 spin_lock_irq(shost->host_lock);
James Smart0d2b6b82008-06-14 22:52:47 -04002670 ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC);
James Smart2e0fef82007-06-17 19:56:36 -05002671 spin_unlock_irq(shost->host_lock);
James Smart0d2b6b82008-06-14 22:52:47 -04002672 } else if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
2673 /* send PLOGI immediately, move to PLOGI issue state */
2674 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
2675 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2676 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2677 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
2678 }
dea31012005-04-17 16:05:31 -05002679 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002680 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002681}
2682
2683static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002684lpfc_rcv_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2685 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002686{
James Smart2e0fef82007-06-17 19:56:36 -05002687 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2688 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2689 struct ls_rjt stat;
dea31012005-04-17 16:05:31 -05002690
2691 memset(&stat, 0, sizeof (struct ls_rjt));
2692 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2693 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
James Smart858c9f62007-06-17 19:56:39 -05002694 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
dea31012005-04-17 16:05:31 -05002695
2696 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
2697 if (ndlp->nlp_flag & NLP_NPR_ADISC) {
James Smart2e0fef82007-06-17 19:56:36 -05002698 spin_lock_irq(shost->host_lock);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002699 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002700 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
James Smart2e0fef82007-06-17 19:56:36 -05002701 spin_unlock_irq(shost->host_lock);
2702 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2703 lpfc_issue_els_adisc(vport, ndlp, 0);
dea31012005-04-17 16:05:31 -05002704 } else {
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002705 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
James Smart2e0fef82007-06-17 19:56:36 -05002706 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2707 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
dea31012005-04-17 16:05:31 -05002708 }
2709 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002710 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002711}
2712
2713static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002714lpfc_rcv_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2715 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002716{
James Smart2e0fef82007-06-17 19:56:36 -05002717 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002718
James Smart2e0fef82007-06-17 19:56:36 -05002719 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002720 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002721}
2722
2723static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002724lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2725 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002726{
James Smart2e0fef82007-06-17 19:56:36 -05002727 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002728
James Smart2e0fef82007-06-17 19:56:36 -05002729 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
James Smart33ccf8d2006-08-17 11:57:58 -04002730 /*
2731 * Do not start discovery if discovery is about to start
2732 * or discovery in progress for this node. Starting discovery
2733 * here will affect the counting of discovery threads.
2734 */
James Smart2fb9bd82006-12-02 13:33:57 -05002735 if (!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
James Smart92d7f7b2007-06-17 19:56:38 -05002736 !(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
dea31012005-04-17 16:05:31 -05002737 if (ndlp->nlp_flag & NLP_NPR_ADISC) {
James Smart92d7f7b2007-06-17 19:56:38 -05002738 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002739 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
James Smart2e0fef82007-06-17 19:56:36 -05002740 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2741 lpfc_issue_els_adisc(vport, ndlp, 0);
dea31012005-04-17 16:05:31 -05002742 } else {
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002743 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
James Smart2e0fef82007-06-17 19:56:36 -05002744 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2745 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
dea31012005-04-17 16:05:31 -05002746 }
2747 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002748 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002749}
2750
2751static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002752lpfc_rcv_prlo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2753 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002754{
James Smart2e0fef82007-06-17 19:56:36 -05002755 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2756 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
dea31012005-04-17 16:05:31 -05002757
James Smart2e0fef82007-06-17 19:56:36 -05002758 spin_lock_irq(shost->host_lock);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002759 ndlp->nlp_flag |= NLP_LOGO_ACC;
James Smart2e0fef82007-06-17 19:56:36 -05002760 spin_unlock_irq(shost->host_lock);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002761
James Smart51ef4c22007-08-02 11:10:31 -04002762 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
dea31012005-04-17 16:05:31 -05002763
James Smart2e0fef82007-06-17 19:56:36 -05002764 if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) {
James Smart256ec0d2013-04-17 20:14:58 -04002765 mod_timer(&ndlp->nlp_delayfunc,
2766 jiffies + msecs_to_jiffies(1000 * 1));
James Smart2e0fef82007-06-17 19:56:36 -05002767 spin_lock_irq(shost->host_lock);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002768 ndlp->nlp_flag |= NLP_DELAY_TMO;
2769 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
James Smart2e0fef82007-06-17 19:56:36 -05002770 spin_unlock_irq(shost->host_lock);
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002771 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002772 } else {
James Smart2e0fef82007-06-17 19:56:36 -05002773 spin_lock_irq(shost->host_lock);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002774 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
James Smart2e0fef82007-06-17 19:56:36 -05002775 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05002776 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002777 return ndlp->nlp_state;
2778}
dea31012005-04-17 16:05:31 -05002779
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002780static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002781lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2782 void *arg, uint32_t evt)
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002783{
2784 struct lpfc_iocbq *cmdiocb, *rspiocb;
James Smarta0f9b482006-04-15 11:52:56 -04002785 IOCB_t *irsp;
James Smart8b455cf2013-01-03 15:43:53 -05002786 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002787
2788 cmdiocb = (struct lpfc_iocbq *) arg;
2789 rspiocb = cmdiocb->context_un.rsp_iocb;
James Smarta0f9b482006-04-15 11:52:56 -04002790
2791 irsp = &rspiocb->iocb;
2792 if (irsp->ulpStatus) {
James Smart8b455cf2013-01-03 15:43:53 -05002793 spin_lock_irq(shost->host_lock);
James Smarta8adb832007-10-27 13:37:53 -04002794 ndlp->nlp_flag |= NLP_DEFER_RM;
James Smart8b455cf2013-01-03 15:43:53 -05002795 spin_unlock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04002796 return NLP_STE_FREED_NODE;
2797 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002798 return ndlp->nlp_state;
2799}
2800
2801static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002802lpfc_cmpl_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2803 void *arg, uint32_t evt)
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002804{
2805 struct lpfc_iocbq *cmdiocb, *rspiocb;
James Smarta0f9b482006-04-15 11:52:56 -04002806 IOCB_t *irsp;
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002807
2808 cmdiocb = (struct lpfc_iocbq *) arg;
2809 rspiocb = cmdiocb->context_un.rsp_iocb;
James Smarta0f9b482006-04-15 11:52:56 -04002810
2811 irsp = &rspiocb->iocb;
2812 if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
James Smart2e0fef82007-06-17 19:56:36 -05002813 lpfc_drop_node(vport, ndlp);
James Smarta0f9b482006-04-15 11:52:56 -04002814 return NLP_STE_FREED_NODE;
2815 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002816 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002817}
2818
2819static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002820lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2821 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002822{
James Smartd7c255b2008-08-24 21:50:00 -04002823 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart086a3452012-08-14 14:25:21 -04002824
2825 /* For the fabric port just clear the fc flags. */
James Smartd7c255b2008-08-24 21:50:00 -04002826 if (ndlp->nlp_DID == Fabric_DID) {
2827 spin_lock_irq(shost->host_lock);
2828 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
2829 spin_unlock_irq(shost->host_lock);
2830 }
James Smart2e0fef82007-06-17 19:56:36 -05002831 lpfc_unreg_rpi(vport, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002832 return ndlp->nlp_state;
2833}
2834
2835static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002836lpfc_cmpl_adisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2837 void *arg, uint32_t evt)
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002838{
2839 struct lpfc_iocbq *cmdiocb, *rspiocb;
James Smarta0f9b482006-04-15 11:52:56 -04002840 IOCB_t *irsp;
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002841
2842 cmdiocb = (struct lpfc_iocbq *) arg;
2843 rspiocb = cmdiocb->context_un.rsp_iocb;
James Smarta0f9b482006-04-15 11:52:56 -04002844
2845 irsp = &rspiocb->iocb;
2846 if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
James Smart2e0fef82007-06-17 19:56:36 -05002847 lpfc_drop_node(vport, ndlp);
James Smarta0f9b482006-04-15 11:52:56 -04002848 return NLP_STE_FREED_NODE;
2849 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002850 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002851}
2852
2853static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002854lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport,
2855 struct lpfc_nodelist *ndlp,
2856 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002857{
James Smart2e0fef82007-06-17 19:56:36 -05002858 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
James Smart04c68492009-05-22 14:52:52 -04002859 MAILBOX_t *mb = &pmb->u.mb;
dea31012005-04-17 16:05:31 -05002860
James Smart04c68492009-05-22 14:52:52 -04002861 if (!mb->mbxStatus) {
James Smart6d368e52011-05-24 11:44:12 -04002862 /* SLI4 ports have preallocated logical rpis. */
2863 if (vport->phba->sli_rev < LPFC_SLI_REV4)
2864 ndlp->nlp_rpi = mb->un.varWords[0];
James Smart40426292010-12-15 17:58:10 -05002865 ndlp->nlp_flag |= NLP_RPI_REGISTERED;
James Smart4b7789b72015-12-16 18:11:55 -05002866 if (ndlp->nlp_flag & NLP_LOGO_ACC) {
2867 lpfc_unreg_rpi(vport, ndlp);
2868 }
James Smart04c68492009-05-22 14:52:52 -04002869 } else {
James Smarta0f9b482006-04-15 11:52:56 -04002870 if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
James Smart2e0fef82007-06-17 19:56:36 -05002871 lpfc_drop_node(vport, ndlp);
James Smarta0f9b482006-04-15 11:52:56 -04002872 return NLP_STE_FREED_NODE;
2873 }
2874 }
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002875 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002876}
2877
2878static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002879lpfc_device_rm_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2880 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002881{
James Smart2e0fef82007-06-17 19:56:36 -05002882 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2883
James Smarta0f9b482006-04-15 11:52:56 -04002884 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
James Smart2e0fef82007-06-17 19:56:36 -05002885 spin_lock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04002886 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
James Smart2e0fef82007-06-17 19:56:36 -05002887 spin_unlock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04002888 return ndlp->nlp_state;
2889 }
James Smart2e0fef82007-06-17 19:56:36 -05002890 lpfc_drop_node(vport, ndlp);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002891 return NLP_STE_FREED_NODE;
dea31012005-04-17 16:05:31 -05002892}
2893
2894static uint32_t
James Smart2e0fef82007-06-17 19:56:36 -05002895lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2896 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05002897{
James Smart2e0fef82007-06-17 19:56:36 -05002898 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2899
James Smart92d7f7b2007-06-17 19:56:38 -05002900 /* Don't do anything that will mess up processing of the
2901 * previous RSCN.
2902 */
2903 if (vport->fc_flag & FC_RSCN_DEFERRED)
2904 return ndlp->nlp_state;
2905
James Smarteaf15d52008-12-04 22:39:29 -05002906 lpfc_cancel_retry_delay_tmo(vport, ndlp);
James Smart2e0fef82007-06-17 19:56:36 -05002907 spin_lock_irq(shost->host_lock);
James Smarta0f9b482006-04-15 11:52:56 -04002908 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
James Smart01a8aed2018-09-10 10:30:41 -07002909 ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);
James Smart2e0fef82007-06-17 19:56:36 -05002910 spin_unlock_irq(shost->host_lock);
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002911 return ndlp->nlp_state;
dea31012005-04-17 16:05:31 -05002912}
2913
2914
2915/* This next section defines the NPort Discovery State Machine */
2916
2917/* There are 4 different double linked lists nodelist entries can reside on.
2918 * The plogi list and adisc list are used when Link Up discovery or RSCN
2919 * processing is needed. Each list holds the nodes that we will send PLOGI
2920 * or ADISC on. These lists will keep track of what nodes will be effected
2921 * by an RSCN, or a Link Up (Typically, all nodes are effected on Link Up).
2922 * The unmapped_list will contain all nodes that we have successfully logged
2923 * into at the Fibre Channel level. The mapped_list will contain all nodes
2924 * that are mapped FCP targets.
2925 */
2926/*
2927 * The bind list is a list of undiscovered (potentially non-existent) nodes
2928 * that we have saved binding information on. This information is used when
2929 * nodes transition from the unmapped to the mapped list.
2930 */
2931/* For UNUSED_NODE state, the node has just been allocated .
2932 * For PLOGI_ISSUE and REG_LOGIN_ISSUE, the node is on
2933 * the PLOGI list. For REG_LOGIN_COMPL, the node is taken off the PLOGI list
2934 * and put on the unmapped list. For ADISC processing, the node is taken off
2935 * the ADISC list and placed on either the mapped or unmapped list (depending
2936 * on its previous state). Once on the unmapped list, a PRLI is issued and the
2937 * state changed to PRLI_ISSUE. When the PRLI completion occurs, the state is
2938 * changed to UNMAPPED_NODE. If the completion indicates a mapped
2939 * node, the node is taken off the unmapped list. The binding list is checked
2940 * for a valid binding, or a binding is automatically assigned. If binding
2941 * assignment is unsuccessful, the node is left on the unmapped list. If
2942 * binding assignment is successful, the associated binding list entry (if
2943 * any) is removed, and the node is placed on the mapped list.
2944 */
2945/*
2946 * For a Link Down, all nodes on the ADISC, PLOGI, unmapped or mapped
James Smartc01f3202006-08-18 17:47:08 -04002947 * lists will receive a DEVICE_RECOVERY event. If the linkdown or devloss timers
dea31012005-04-17 16:05:31 -05002948 * expire, all effected nodes will receive a DEVICE_RM event.
2949 */
2950/*
2951 * For a Link Up or RSCN, all nodes will move from the mapped / unmapped lists
2952 * to either the ADISC or PLOGI list. After a Nameserver query or ALPA loopmap
2953 * check, additional nodes may be added or removed (via DEVICE_RM) to / from
2954 * the PLOGI or ADISC lists. Once the PLOGI and ADISC lists are populated,
2955 * we will first process the ADISC list. 32 entries are processed initially and
2956 * ADISC is initited for each one. Completions / Events for each node are
2957 * funnelled thru the state machine. As each node finishes ADISC processing, it
2958 * starts ADISC for any nodes waiting for ADISC processing. If no nodes are
2959 * waiting, and the ADISC list count is identically 0, then we are done. For
2960 * Link Up discovery, since all nodes on the PLOGI list are UNREG_LOGIN'ed, we
2961 * can issue a CLEAR_LA and reenable Link Events. Next we will process the PLOGI
2962 * list. 32 entries are processed initially and PLOGI is initited for each one.
2963 * Completions / Events for each node are funnelled thru the state machine. As
2964 * each node finishes PLOGI processing, it starts PLOGI for any nodes waiting
2965 * for PLOGI processing. If no nodes are waiting, and the PLOGI list count is
2966 * indentically 0, then we are done. We have now completed discovery / RSCN
2967 * handling. Upon completion, ALL nodes should be on either the mapped or
2968 * unmapped lists.
2969 */
2970
2971static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
James Smart2e0fef82007-06-17 19:56:36 -05002972 (struct lpfc_vport *, struct lpfc_nodelist *, void *, uint32_t) = {
dea31012005-04-17 16:05:31 -05002973 /* Action routine Event Current State */
2974 lpfc_rcv_plogi_unused_node, /* RCV_PLOGI UNUSED_NODE */
2975 lpfc_rcv_els_unused_node, /* RCV_PRLI */
2976 lpfc_rcv_logo_unused_node, /* RCV_LOGO */
2977 lpfc_rcv_els_unused_node, /* RCV_ADISC */
2978 lpfc_rcv_els_unused_node, /* RCV_PDISC */
2979 lpfc_rcv_els_unused_node, /* RCV_PRLO */
2980 lpfc_disc_illegal, /* CMPL_PLOGI */
2981 lpfc_disc_illegal, /* CMPL_PRLI */
2982 lpfc_cmpl_logo_unused_node, /* CMPL_LOGO */
2983 lpfc_disc_illegal, /* CMPL_ADISC */
2984 lpfc_disc_illegal, /* CMPL_REG_LOGIN */
2985 lpfc_device_rm_unused_node, /* DEVICE_RM */
James Smartdf9e1b52011-12-13 13:22:17 -05002986 lpfc_device_recov_unused_node, /* DEVICE_RECOVERY */
dea31012005-04-17 16:05:31 -05002987
2988 lpfc_rcv_plogi_plogi_issue, /* RCV_PLOGI PLOGI_ISSUE */
James Smart92d7f7b2007-06-17 19:56:38 -05002989 lpfc_rcv_prli_plogi_issue, /* RCV_PRLI */
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05002990 lpfc_rcv_logo_plogi_issue, /* RCV_LOGO */
dea31012005-04-17 16:05:31 -05002991 lpfc_rcv_els_plogi_issue, /* RCV_ADISC */
2992 lpfc_rcv_els_plogi_issue, /* RCV_PDISC */
2993 lpfc_rcv_els_plogi_issue, /* RCV_PRLO */
2994 lpfc_cmpl_plogi_plogi_issue, /* CMPL_PLOGI */
2995 lpfc_disc_illegal, /* CMPL_PRLI */
James Smart0ff10d42008-01-11 01:52:36 -05002996 lpfc_cmpl_logo_plogi_issue, /* CMPL_LOGO */
dea31012005-04-17 16:05:31 -05002997 lpfc_disc_illegal, /* CMPL_ADISC */
James Smart0ff10d42008-01-11 01:52:36 -05002998 lpfc_cmpl_reglogin_plogi_issue,/* CMPL_REG_LOGIN */
dea31012005-04-17 16:05:31 -05002999 lpfc_device_rm_plogi_issue, /* DEVICE_RM */
3000 lpfc_device_recov_plogi_issue, /* DEVICE_RECOVERY */
3001
3002 lpfc_rcv_plogi_adisc_issue, /* RCV_PLOGI ADISC_ISSUE */
3003 lpfc_rcv_prli_adisc_issue, /* RCV_PRLI */
3004 lpfc_rcv_logo_adisc_issue, /* RCV_LOGO */
3005 lpfc_rcv_padisc_adisc_issue, /* RCV_ADISC */
3006 lpfc_rcv_padisc_adisc_issue, /* RCV_PDISC */
3007 lpfc_rcv_prlo_adisc_issue, /* RCV_PRLO */
3008 lpfc_disc_illegal, /* CMPL_PLOGI */
3009 lpfc_disc_illegal, /* CMPL_PRLI */
3010 lpfc_disc_illegal, /* CMPL_LOGO */
3011 lpfc_cmpl_adisc_adisc_issue, /* CMPL_ADISC */
3012 lpfc_disc_illegal, /* CMPL_REG_LOGIN */
3013 lpfc_device_rm_adisc_issue, /* DEVICE_RM */
3014 lpfc_device_recov_adisc_issue, /* DEVICE_RECOVERY */
3015
3016 lpfc_rcv_plogi_reglogin_issue, /* RCV_PLOGI REG_LOGIN_ISSUE */
3017 lpfc_rcv_prli_reglogin_issue, /* RCV_PLOGI */
3018 lpfc_rcv_logo_reglogin_issue, /* RCV_LOGO */
3019 lpfc_rcv_padisc_reglogin_issue, /* RCV_ADISC */
3020 lpfc_rcv_padisc_reglogin_issue, /* RCV_PDISC */
3021 lpfc_rcv_prlo_reglogin_issue, /* RCV_PRLO */
James Smart87af33f2007-10-27 13:37:43 -04003022 lpfc_cmpl_plogi_illegal, /* CMPL_PLOGI */
dea31012005-04-17 16:05:31 -05003023 lpfc_disc_illegal, /* CMPL_PRLI */
3024 lpfc_disc_illegal, /* CMPL_LOGO */
3025 lpfc_disc_illegal, /* CMPL_ADISC */
3026 lpfc_cmpl_reglogin_reglogin_issue,/* CMPL_REG_LOGIN */
3027 lpfc_device_rm_reglogin_issue, /* DEVICE_RM */
3028 lpfc_device_recov_reglogin_issue,/* DEVICE_RECOVERY */
3029
3030 lpfc_rcv_plogi_prli_issue, /* RCV_PLOGI PRLI_ISSUE */
3031 lpfc_rcv_prli_prli_issue, /* RCV_PRLI */
3032 lpfc_rcv_logo_prli_issue, /* RCV_LOGO */
3033 lpfc_rcv_padisc_prli_issue, /* RCV_ADISC */
3034 lpfc_rcv_padisc_prli_issue, /* RCV_PDISC */
3035 lpfc_rcv_prlo_prli_issue, /* RCV_PRLO */
James Smart87af33f2007-10-27 13:37:43 -04003036 lpfc_cmpl_plogi_illegal, /* CMPL_PLOGI */
dea31012005-04-17 16:05:31 -05003037 lpfc_cmpl_prli_prli_issue, /* CMPL_PRLI */
3038 lpfc_disc_illegal, /* CMPL_LOGO */
3039 lpfc_disc_illegal, /* CMPL_ADISC */
3040 lpfc_disc_illegal, /* CMPL_REG_LOGIN */
3041 lpfc_device_rm_prli_issue, /* DEVICE_RM */
3042 lpfc_device_recov_prli_issue, /* DEVICE_RECOVERY */
3043
James Smart086a3452012-08-14 14:25:21 -04003044 lpfc_rcv_plogi_logo_issue, /* RCV_PLOGI LOGO_ISSUE */
3045 lpfc_rcv_prli_logo_issue, /* RCV_PRLI */
3046 lpfc_rcv_logo_logo_issue, /* RCV_LOGO */
3047 lpfc_rcv_padisc_logo_issue, /* RCV_ADISC */
3048 lpfc_rcv_padisc_logo_issue, /* RCV_PDISC */
3049 lpfc_rcv_prlo_logo_issue, /* RCV_PRLO */
3050 lpfc_cmpl_plogi_illegal, /* CMPL_PLOGI */
3051 lpfc_disc_illegal, /* CMPL_PRLI */
3052 lpfc_cmpl_logo_logo_issue, /* CMPL_LOGO */
3053 lpfc_disc_illegal, /* CMPL_ADISC */
3054 lpfc_disc_illegal, /* CMPL_REG_LOGIN */
3055 lpfc_device_rm_logo_issue, /* DEVICE_RM */
3056 lpfc_device_recov_logo_issue, /* DEVICE_RECOVERY */
3057
dea31012005-04-17 16:05:31 -05003058 lpfc_rcv_plogi_unmap_node, /* RCV_PLOGI UNMAPPED_NODE */
3059 lpfc_rcv_prli_unmap_node, /* RCV_PRLI */
3060 lpfc_rcv_logo_unmap_node, /* RCV_LOGO */
3061 lpfc_rcv_padisc_unmap_node, /* RCV_ADISC */
3062 lpfc_rcv_padisc_unmap_node, /* RCV_PDISC */
3063 lpfc_rcv_prlo_unmap_node, /* RCV_PRLO */
3064 lpfc_disc_illegal, /* CMPL_PLOGI */
3065 lpfc_disc_illegal, /* CMPL_PRLI */
3066 lpfc_disc_illegal, /* CMPL_LOGO */
3067 lpfc_disc_illegal, /* CMPL_ADISC */
3068 lpfc_disc_illegal, /* CMPL_REG_LOGIN */
3069 lpfc_disc_illegal, /* DEVICE_RM */
3070 lpfc_device_recov_unmap_node, /* DEVICE_RECOVERY */
3071
3072 lpfc_rcv_plogi_mapped_node, /* RCV_PLOGI MAPPED_NODE */
3073 lpfc_rcv_prli_mapped_node, /* RCV_PRLI */
3074 lpfc_rcv_logo_mapped_node, /* RCV_LOGO */
3075 lpfc_rcv_padisc_mapped_node, /* RCV_ADISC */
3076 lpfc_rcv_padisc_mapped_node, /* RCV_PDISC */
3077 lpfc_rcv_prlo_mapped_node, /* RCV_PRLO */
3078 lpfc_disc_illegal, /* CMPL_PLOGI */
3079 lpfc_disc_illegal, /* CMPL_PRLI */
3080 lpfc_disc_illegal, /* CMPL_LOGO */
3081 lpfc_disc_illegal, /* CMPL_ADISC */
3082 lpfc_disc_illegal, /* CMPL_REG_LOGIN */
3083 lpfc_disc_illegal, /* DEVICE_RM */
3084 lpfc_device_recov_mapped_node, /* DEVICE_RECOVERY */
3085
3086 lpfc_rcv_plogi_npr_node, /* RCV_PLOGI NPR_NODE */
3087 lpfc_rcv_prli_npr_node, /* RCV_PRLI */
3088 lpfc_rcv_logo_npr_node, /* RCV_LOGO */
3089 lpfc_rcv_padisc_npr_node, /* RCV_ADISC */
3090 lpfc_rcv_padisc_npr_node, /* RCV_PDISC */
3091 lpfc_rcv_prlo_npr_node, /* RCV_PRLO */
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05003092 lpfc_cmpl_plogi_npr_node, /* CMPL_PLOGI */
3093 lpfc_cmpl_prli_npr_node, /* CMPL_PRLI */
dea31012005-04-17 16:05:31 -05003094 lpfc_cmpl_logo_npr_node, /* CMPL_LOGO */
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05003095 lpfc_cmpl_adisc_npr_node, /* CMPL_ADISC */
dea31012005-04-17 16:05:31 -05003096 lpfc_cmpl_reglogin_npr_node, /* CMPL_REG_LOGIN */
3097 lpfc_device_rm_npr_node, /* DEVICE_RM */
3098 lpfc_device_recov_npr_node, /* DEVICE_RECOVERY */
3099};
3100
3101int
James Smart2e0fef82007-06-17 19:56:36 -05003102lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
3103 void *arg, uint32_t evt)
dea31012005-04-17 16:05:31 -05003104{
3105 uint32_t cur_state, rc;
James Smart2e0fef82007-06-17 19:56:36 -05003106 uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *,
dea31012005-04-17 16:05:31 -05003107 uint32_t);
James Smarte47c9092008-02-08 18:49:26 -05003108 uint32_t got_ndlp = 0;
James Smart26d824c2019-08-14 16:56:39 -07003109 uint32_t data1;
dea31012005-04-17 16:05:31 -05003110
James Smarte47c9092008-02-08 18:49:26 -05003111 if (lpfc_nlp_get(ndlp))
3112 got_ndlp = 1;
3113
dea31012005-04-17 16:05:31 -05003114 cur_state = ndlp->nlp_state;
3115
James Smart26d824c2019-08-14 16:56:39 -07003116 data1 = (((uint32_t)ndlp->nlp_fc4_type << 16) |
3117 ((uint32_t)ndlp->nlp_type));
dea31012005-04-17 16:05:31 -05003118 /* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */
James Smarte8b62012007-08-02 11:10:09 -04003119 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
3120 "0211 DSM in event x%x on NPort x%x in "
James Smartdea16bd2018-11-29 16:09:30 -08003121 "state %d rpi x%x Data: x%x x%x\n",
3122 evt, ndlp->nlp_DID, cur_state, ndlp->nlp_rpi,
James Smart26d824c2019-08-14 16:56:39 -07003123 ndlp->nlp_flag, data1);
dea31012005-04-17 16:05:31 -05003124
James Smart858c9f62007-06-17 19:56:39 -05003125 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
3126 "DSM in: evt:%d ste:%d did:x%x",
3127 evt, cur_state, ndlp->nlp_DID);
3128
dea31012005-04-17 16:05:31 -05003129 func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt];
James Smart2e0fef82007-06-17 19:56:36 -05003130 rc = (func) (vport, ndlp, arg, evt);
dea31012005-04-17 16:05:31 -05003131
3132 /* DSM out state <rc> on NPort <nlp_DID> */
James Smarte47c9092008-02-08 18:49:26 -05003133 if (got_ndlp) {
James Smart26d824c2019-08-14 16:56:39 -07003134 data1 = (((uint32_t)ndlp->nlp_fc4_type << 16) |
3135 ((uint32_t)ndlp->nlp_type));
James Smarte47c9092008-02-08 18:49:26 -05003136 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
James Smartdea16bd2018-11-29 16:09:30 -08003137 "0212 DSM out state %d on NPort x%x "
James Smart26d824c2019-08-14 16:56:39 -07003138 "rpi x%x Data: x%x x%x\n",
3139 rc, ndlp->nlp_DID, ndlp->nlp_rpi, ndlp->nlp_flag,
3140 data1);
dea31012005-04-17 16:05:31 -05003141
James Smarte47c9092008-02-08 18:49:26 -05003142 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
3143 "DSM out: ste:%d did:x%x flg:x%x",
3144 rc, ndlp->nlp_DID, ndlp->nlp_flag);
3145 /* Decrement the ndlp reference count held for this function */
3146 lpfc_nlp_put(ndlp);
3147 } else {
3148 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
James Smartd7c255b2008-08-24 21:50:00 -04003149 "0213 DSM out state %d on NPort free\n", rc);
James Smart858c9f62007-06-17 19:56:39 -05003150
James Smarte47c9092008-02-08 18:49:26 -05003151 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
3152 "DSM out: ste:%d did:x%x flg:x%x",
3153 rc, 0, 0);
3154 }
dea31012005-04-17 16:05:31 -05003155
Jamie Wellnitzc9f8735b2006-02-28 19:25:23 -05003156 return rc;
dea31012005-04-17 16:05:31 -05003157}