]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/scsi/lpfc/lpfc_els.c
[SCSI] initialize shost_data to zero
[net-next-2.6.git] / drivers / scsi / lpfc / lpfc_els.c
CommitLineData
dea3101e
JB
1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for *
c44ce173 3 * Fibre Channel Host Bus Adapters. *
9413afff 4 * Copyright (C) 2004-2007 Emulex. All rights reserved. *
c44ce173 5 * EMULEX and SLI are trademarks of Emulex. *
dea3101e 6 * www.emulex.com *
c44ce173 7 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
dea3101e
JB
8 * *
9 * This program is free software; you can redistribute it and/or *
c44ce173
JSEC
10 * modify it under the terms of version 2 of the GNU General *
11 * Public License as published by the Free Software Foundation. *
12 * This program is distributed in the hope that it will be useful. *
13 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
14 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
15 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
16 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
17 * TO BE LEGALLY INVALID. See the GNU General Public License for *
18 * more details, a copy of which can be found in the file COPYING *
19 * included with this package. *
dea3101e
JB
20 *******************************************************************/
21
dea3101e
JB
22#include <linux/blkdev.h>
23#include <linux/pci.h>
24#include <linux/interrupt.h>
25
91886523 26#include <scsi/scsi.h>
dea3101e
JB
27#include <scsi/scsi_device.h>
28#include <scsi/scsi_host.h>
29#include <scsi/scsi_transport_fc.h>
30
31#include "lpfc_hw.h"
32#include "lpfc_sli.h"
33#include "lpfc_disc.h"
34#include "lpfc_scsi.h"
35#include "lpfc.h"
36#include "lpfc_logmsg.h"
37#include "lpfc_crtn.h"
92d7f7b0 38#include "lpfc_vport.h"
858c9f6c 39#include "lpfc_debugfs.h"
dea3101e
JB
40
41static int lpfc_els_retry(struct lpfc_hba *, struct lpfc_iocbq *,
42 struct lpfc_iocbq *);
92d7f7b0
JS
43static void lpfc_cmpl_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *,
44 struct lpfc_iocbq *);
45
dea3101e
JB
46static int lpfc_max_els_tries = 3;
47
858c9f6c 48int
2e0fef85 49lpfc_els_chk_latt(struct lpfc_vport *vport)
dea3101e 50{
2e0fef85
JS
51 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
52 struct lpfc_hba *phba = vport->phba;
dea3101e 53 uint32_t ha_copy;
dea3101e 54
2e0fef85
JS
55 if (vport->port_state >= LPFC_VPORT_READY ||
56 phba->link_state == LPFC_LINK_DOWN)
dea3101e
JB
57 return 0;
58
59 /* Read the HBA Host Attention Register */
dea3101e 60 ha_copy = readl(phba->HAregaddr);
dea3101e
JB
61
62 if (!(ha_copy & HA_LATT))
63 return 0;
64
65 /* Pending Link Event during Discovery */
92d7f7b0
JS
66 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
67 "%d (%d):0237 Pending Link Event during "
dea3101e 68 "Discovery: State x%x\n",
92d7f7b0 69 phba->brd_no, vport->vpi, phba->pport->port_state);
dea3101e
JB
70
71 /* CLEAR_LA should re-enable link attention events and
72 * we should then imediately take a LATT event. The
73 * LATT processing should call lpfc_linkdown() which
74 * will cleanup any left over in-progress discovery
75 * events.
76 */
2e0fef85
JS
77 spin_lock_irq(shost->host_lock);
78 vport->fc_flag |= FC_ABORT_DISCOVERY;
79 spin_unlock_irq(shost->host_lock);
dea3101e 80
92d7f7b0 81 if (phba->link_state != LPFC_CLEAR_LA)
ed957684 82 lpfc_issue_clear_la(phba, vport);
dea3101e 83
c9f8735b 84 return 1;
dea3101e
JB
85}
86
87static struct lpfc_iocbq *
2e0fef85
JS
88lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
89 uint16_t cmdSize, uint8_t retry,
90 struct lpfc_nodelist *ndlp, uint32_t did,
91 uint32_t elscmd)
dea3101e 92{
2e0fef85 93 struct lpfc_hba *phba = vport->phba;
0bd4ca25 94 struct lpfc_iocbq *elsiocb;
dea3101e
JB
95 struct lpfc_dmabuf *pcmd, *prsp, *pbuflist;
96 struct ulp_bde64 *bpl;
97 IOCB_t *icmd;
98
dea3101e 99
2e0fef85
JS
100 if (!lpfc_is_link_up(phba))
101 return NULL;
dea3101e 102
dea3101e 103 /* Allocate buffer for command iocb */
0bd4ca25 104 elsiocb = lpfc_sli_get_iocbq(phba);
dea3101e
JB
105
106 if (elsiocb == NULL)
107 return NULL;
dea3101e
JB
108 icmd = &elsiocb->iocb;
109
110 /* fill in BDEs for command */
111 /* Allocate buffer for command payload */
92d7f7b0 112 if (((pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
dea3101e
JB
113 ((pcmd->virt = lpfc_mbuf_alloc(phba,
114 MEM_PRI, &(pcmd->phys))) == 0)) {
c9475cb0 115 kfree(pcmd);
dea3101e 116
604a3e30 117 lpfc_sli_release_iocbq(phba, elsiocb);
dea3101e
JB
118 return NULL;
119 }
120
121 INIT_LIST_HEAD(&pcmd->list);
122
123 /* Allocate buffer for response payload */
124 if (expectRsp) {
92d7f7b0 125 prsp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
dea3101e
JB
126 if (prsp)
127 prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
128 &prsp->phys);
129 if (prsp == 0 || prsp->virt == 0) {
c9475cb0 130 kfree(prsp);
dea3101e
JB
131 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
132 kfree(pcmd);
604a3e30 133 lpfc_sli_release_iocbq(phba, elsiocb);
dea3101e
JB
134 return NULL;
135 }
136 INIT_LIST_HEAD(&prsp->list);
137 } else {
138 prsp = NULL;
139 }
140
141 /* Allocate buffer for Buffer ptr list */
92d7f7b0 142 pbuflist = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
dea3101e 143 if (pbuflist)
ed957684
JS
144 pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
145 &pbuflist->phys);
dea3101e 146 if (pbuflist == 0 || pbuflist->virt == 0) {
604a3e30 147 lpfc_sli_release_iocbq(phba, elsiocb);
dea3101e
JB
148 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
149 lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
150 kfree(pcmd);
151 kfree(prsp);
c9475cb0 152 kfree(pbuflist);
dea3101e
JB
153 return NULL;
154 }
155
156 INIT_LIST_HEAD(&pbuflist->list);
157
158 icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
159 icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
160 icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL;
2e0fef85 161 icmd->un.elsreq64.remoteID = did; /* DID */
dea3101e 162 if (expectRsp) {
92d7f7b0 163 icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
dea3101e 164 icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
2680eeaa 165 icmd->ulpTimeout = phba->fc_ratov * 2;
dea3101e 166 } else {
92d7f7b0 167 icmd->un.elsreq64.bdl.bdeSize = sizeof(struct ulp_bde64);
dea3101e
JB
168 icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX;
169 }
dea3101e
JB
170 icmd->ulpBdeCount = 1;
171 icmd->ulpLe = 1;
172 icmd->ulpClass = CLASS3;
173
92d7f7b0
JS
174 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
175 icmd->un.elsreq64.myID = vport->fc_myDID;
176
177 /* For ELS_REQUEST64_CR, use the VPI by default */
178 icmd->ulpContext = vport->vpi;
179 icmd->ulpCt_h = 0;
180 icmd->ulpCt_l = 1;
181 }
182
dea3101e
JB
183 bpl = (struct ulp_bde64 *) pbuflist->virt;
184 bpl->addrLow = le32_to_cpu(putPaddrLow(pcmd->phys));
185 bpl->addrHigh = le32_to_cpu(putPaddrHigh(pcmd->phys));
186 bpl->tus.f.bdeSize = cmdSize;
187 bpl->tus.f.bdeFlags = 0;
188 bpl->tus.w = le32_to_cpu(bpl->tus.w);
189
190 if (expectRsp) {
191 bpl++;
192 bpl->addrLow = le32_to_cpu(putPaddrLow(prsp->phys));
193 bpl->addrHigh = le32_to_cpu(putPaddrHigh(prsp->phys));
194 bpl->tus.f.bdeSize = FCELSSIZE;
195 bpl->tus.f.bdeFlags = BUFF_USE_RCV;
196 bpl->tus.w = le32_to_cpu(bpl->tus.w);
197 }
198
199 /* Save for completion so we can release these resources */
92d7f7b0
JS
200 if (elscmd != ELS_CMD_LS_RJT)
201 elsiocb->context1 = lpfc_nlp_get(ndlp);
329f9bc7
JS
202 elsiocb->context2 = pcmd;
203 elsiocb->context3 = pbuflist;
dea3101e 204 elsiocb->retry = retry;
2e0fef85 205 elsiocb->vport = vport;
dea3101e
JB
206 elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT;
207
208 if (prsp) {
209 list_add(&prsp->list, &pcmd->list);
210 }
211
212 if (expectRsp) {
213 /* Xmit ELS command <elsCmd> to remote NPORT <did> */
214 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 215 "%d (%d):0116 Xmit ELS command x%x to remote "
2e0fef85 216 "NPORT x%x I/O tag: x%x, port state: x%x\n",
92d7f7b0 217 phba->brd_no, vport->vpi, elscmd, did,
2e0fef85 218 elsiocb->iotag, vport->port_state);
dea3101e
JB
219 } else {
220 /* Xmit ELS response <elsCmd> to remote NPORT <did> */
221 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 222 "%d (%d):0117 Xmit ELS response x%x to remote "
1dcb58e5 223 "NPORT x%x I/O tag: x%x, size: x%x\n",
92d7f7b0 224 phba->brd_no, vport->vpi, elscmd,
1dcb58e5 225 ndlp->nlp_DID, elsiocb->iotag, cmdSize);
dea3101e
JB
226 }
227
c9f8735b 228 return elsiocb;
dea3101e
JB
229}
230
231
232static int
92d7f7b0 233lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
dea3101e 234{
2e0fef85 235 struct lpfc_hba *phba = vport->phba;
dea3101e 236 LPFC_MBOXQ_t *mbox;
14691150 237 struct lpfc_dmabuf *mp;
92d7f7b0
JS
238 struct lpfc_nodelist *ndlp;
239 struct serv_parm *sp;
dea3101e
JB
240 int rc;
241
92d7f7b0
JS
242 sp = &phba->fc_fabparam;
243 ndlp = lpfc_findnode_did(vport, Fabric_DID);
244 if (!ndlp)
245 goto fail;
246
247 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
248 if (!mbox)
249 goto fail;
250
251 vport->port_state = LPFC_FABRIC_CFG_LINK;
252 lpfc_config_link(phba, mbox);
253 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
254 mbox->vport = vport;
255
256 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB);
257 if (rc == MBX_NOT_FINISHED)
258 goto fail_free_mbox;
259
260 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
261 if (!mbox)
262 goto fail;
263 rc = lpfc_reg_login(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox,
264 0);
265 if (rc)
266 goto fail_free_mbox;
267
268 mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login;
269 mbox->vport = vport;
270 mbox->context2 = lpfc_nlp_get(ndlp);
271
272 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB);
273 if (rc == MBX_NOT_FINISHED)
274 goto fail_issue_reg_login;
275
276 return 0;
277
278fail_issue_reg_login:
279 lpfc_nlp_put(ndlp);
280 mp = (struct lpfc_dmabuf *) mbox->context1;
281 lpfc_mbuf_free(phba, mp->virt, mp->phys);
282 kfree(mp);
283fail_free_mbox:
284 mempool_free(mbox, phba->mbox_mem_pool);
285
286fail:
287 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
288 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
289 "%d (%d):0249 Cannot issue Register Fabric login\n",
290 phba->brd_no, vport->vpi);
291 return -ENXIO;
292}
293
294static int
295lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
296 struct serv_parm *sp, IOCB_t *irsp)
297{
298 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
299 struct lpfc_hba *phba = vport->phba;
300 struct lpfc_nodelist *np;
301 struct lpfc_nodelist *next_np;
302
2e0fef85
JS
303 spin_lock_irq(shost->host_lock);
304 vport->fc_flag |= FC_FABRIC;
305 spin_unlock_irq(shost->host_lock);
dea3101e
JB
306
307 phba->fc_edtov = be32_to_cpu(sp->cmn.e_d_tov);
308 if (sp->cmn.edtovResolution) /* E_D_TOV ticks are in nanoseconds */
309 phba->fc_edtov = (phba->fc_edtov + 999999) / 1000000;
310
311 phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
312
313 if (phba->fc_topology == TOPOLOGY_LOOP) {
2e0fef85
JS
314 spin_lock_irq(shost->host_lock);
315 vport->fc_flag |= FC_PUBLIC_LOOP;
316 spin_unlock_irq(shost->host_lock);
dea3101e
JB
317 } else {
318 /*
319 * If we are a N-port connected to a Fabric, fixup sparam's so
320 * logins to devices on remote loops work.
321 */
2e0fef85 322 vport->fc_sparam.cmn.altBbCredit = 1;
dea3101e
JB
323 }
324
2e0fef85 325 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
dea3101e 326 memcpy(&ndlp->nlp_portname, &sp->portName, sizeof(struct lpfc_name));
92d7f7b0 327 memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof(struct lpfc_name));
dea3101e
JB
328 ndlp->nlp_class_sup = 0;
329 if (sp->cls1.classValid)
330 ndlp->nlp_class_sup |= FC_COS_CLASS1;
331 if (sp->cls2.classValid)
332 ndlp->nlp_class_sup |= FC_COS_CLASS2;
333 if (sp->cls3.classValid)
334 ndlp->nlp_class_sup |= FC_COS_CLASS3;
335 if (sp->cls4.classValid)
336 ndlp->nlp_class_sup |= FC_COS_CLASS4;
337 ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
338 sp->cmn.bbRcvSizeLsb;
339 memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
340
92d7f7b0
JS
341 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
342 if (sp->cmn.response_multiple_NPort) {
343 lpfc_printf_log(phba, KERN_WARNING, LOG_ELS | LOG_VPORT,
344 "%d:1816 FLOGI NPIV supported, "
345 "response data 0x%x\n",
346 phba->brd_no,
347 sp->cmn.response_multiple_NPort);
348 phba->link_flag |= LS_NPIV_FAB_SUPPORTED;
dea3101e 349
92d7f7b0
JS
350 } else {
351 /* Because we asked f/w for NPIV it still expects us
352 to call reg_vnpid atleast for the physcial host */
353 lpfc_printf_log(phba, KERN_WARNING, LOG_ELS | LOG_VPORT,
354 "%d:1817 Fabric does not support NPIV "
355 "- configuring single port mode.\n",
356 phba->brd_no);
92d7f7b0
JS
357 phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
358 }
359 }
dea3101e 360
92d7f7b0
JS
361 if ((vport->fc_prevDID != vport->fc_myDID) &&
362 !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
dea3101e 363
92d7f7b0
JS
364 /* If our NportID changed, we need to ensure all
365 * remaining NPORTs get unreg_login'ed.
366 */
367 list_for_each_entry_safe(np, next_np,
368 &vport->fc_nodes, nlp_listp) {
369 if ((np->nlp_state != NLP_STE_NPR_NODE) ||
370 !(np->nlp_flag & NLP_NPR_ADISC))
371 continue;
372 spin_lock_irq(shost->host_lock);
373 np->nlp_flag &= ~NLP_NPR_ADISC;
374 spin_unlock_irq(shost->host_lock);
375 lpfc_unreg_rpi(vport, np);
376 }
377 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
378 lpfc_mbx_unreg_vpi(vport);
379 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
380 }
381 }
dea3101e 382
92d7f7b0
JS
383 ndlp->nlp_sid = irsp->un.ulpWord[4] & Mask_DID;
384 lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE);
dea3101e 385
92d7f7b0
JS
386 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED &&
387 vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) {
388 lpfc_register_new_vport(phba, vport, ndlp);
389 return 0;
390 }
391 lpfc_issue_fabric_reglogin(vport);
dea3101e 392 return 0;
dea3101e
JB
393}
394
395/*
396 * We FLOGIed into an NPort, initiate pt2pt protocol
397 */
398static int
2e0fef85
JS
399lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
400 struct serv_parm *sp)
dea3101e 401{
2e0fef85
JS
402 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
403 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
404 LPFC_MBOXQ_t *mbox;
405 int rc;
406
2e0fef85
JS
407 spin_lock_irq(shost->host_lock);
408 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
409 spin_unlock_irq(shost->host_lock);
dea3101e
JB
410
411 phba->fc_edtov = FF_DEF_EDTOV;
412 phba->fc_ratov = FF_DEF_RATOV;
2e0fef85 413 rc = memcmp(&vport->fc_portname, &sp->portName,
92d7f7b0 414 sizeof(vport->fc_portname));
dea3101e
JB
415 if (rc >= 0) {
416 /* This side will initiate the PLOGI */
2e0fef85
JS
417 spin_lock_irq(shost->host_lock);
418 vport->fc_flag |= FC_PT2PT_PLOGI;
419 spin_unlock_irq(shost->host_lock);
dea3101e
JB
420
421 /*
422 * N_Port ID cannot be 0, set our to LocalID the other
423 * side will be RemoteID.
424 */
425
426 /* not equal */
427 if (rc)
2e0fef85 428 vport->fc_myDID = PT2PT_LocalID;
dea3101e
JB
429
430 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
431 if (!mbox)
432 goto fail;
433
434 lpfc_config_link(phba, mbox);
435
436 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
ed957684 437 mbox->vport = vport;
dea3101e 438 rc = lpfc_sli_issue_mbox(phba, mbox,
92d7f7b0 439 MBX_NOWAIT | MBX_STOP_IOCB);
dea3101e
JB
440 if (rc == MBX_NOT_FINISHED) {
441 mempool_free(mbox, phba->mbox_mem_pool);
442 goto fail;
443 }
329f9bc7 444 lpfc_nlp_put(ndlp);
dea3101e 445
2e0fef85 446 ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID);
dea3101e
JB
447 if (!ndlp) {
448 /*
449 * Cannot find existing Fabric ndlp, so allocate a
450 * new one
451 */
452 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
453 if (!ndlp)
454 goto fail;
455
2e0fef85 456 lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID);
dea3101e
JB
457 }
458
459 memcpy(&ndlp->nlp_portname, &sp->portName,
2e0fef85 460 sizeof(struct lpfc_name));
dea3101e 461 memcpy(&ndlp->nlp_nodename, &sp->nodeName,
2e0fef85
JS
462 sizeof(struct lpfc_name));
463 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
464 spin_lock_irq(shost->host_lock);
dea3101e 465 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2e0fef85 466 spin_unlock_irq(shost->host_lock);
dea3101e
JB
467 } else {
468 /* This side will wait for the PLOGI */
329f9bc7 469 lpfc_nlp_put(ndlp);
dea3101e
JB
470 }
471
2e0fef85
JS
472 spin_lock_irq(shost->host_lock);
473 vport->fc_flag |= FC_PT2PT;
474 spin_unlock_irq(shost->host_lock);
dea3101e
JB
475
476 /* Start discovery - this should just do CLEAR_LA */
2e0fef85 477 lpfc_disc_start(vport);
dea3101e 478 return 0;
92d7f7b0 479fail:
dea3101e
JB
480 return -ENXIO;
481}
482
483static void
329f9bc7
JS
484lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
485 struct lpfc_iocbq *rspiocb)
dea3101e 486{
2e0fef85
JS
487 struct lpfc_vport *vport = cmdiocb->vport;
488 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e
JB
489 IOCB_t *irsp = &rspiocb->iocb;
490 struct lpfc_nodelist *ndlp = cmdiocb->context1;
491 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
492 struct serv_parm *sp;
493 int rc;
494
495 /* Check to see if link went down during discovery */
2e0fef85 496 if (lpfc_els_chk_latt(vport)) {
329f9bc7 497 lpfc_nlp_put(ndlp);
dea3101e
JB
498 goto out;
499 }
500
858c9f6c
JS
501 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
502 "FLOGI cmpl: status:x%x/x%x state:x%x",
503 irsp->ulpStatus, irsp->un.ulpWord[4],
504 vport->port_state);
505
dea3101e
JB
506 if (irsp->ulpStatus) {
507 /* Check for retry */
2e0fef85 508 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
dea3101e 509 goto out;
2e0fef85 510
dea3101e 511 /* FLOGI failed, so there is no fabric */
2e0fef85
JS
512 spin_lock_irq(shost->host_lock);
513 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
514 spin_unlock_irq(shost->host_lock);
dea3101e 515
329f9bc7 516 /* If private loop, then allow max outstanding els to be
dea3101e
JB
517 * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no
518 * alpa map would take too long otherwise.
519 */
520 if (phba->alpa_map[0] == 0) {
329f9bc7 521 phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
dea3101e
JB
522 }
523
524 /* FLOGI failure */
92d7f7b0
JS
525 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
526 "%d (%d):0100 FLOGI failure Data: x%x x%x "
527 "x%x\n",
528 phba->brd_no, vport->vpi,
c9f8735b
JW
529 irsp->ulpStatus, irsp->un.ulpWord[4],
530 irsp->ulpTimeout);
dea3101e
JB
531 goto flogifail;
532 }
533
534 /*
535 * The FLogI succeeded. Sync the data for the CPU before
536 * accessing it.
537 */
538 prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
539
540 sp = prsp->virt + sizeof(uint32_t);
541
542 /* FLOGI completes successfully */
543 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 544 "%d (%d):0101 FLOGI completes sucessfully "
dea3101e 545 "Data: x%x x%x x%x x%x\n",
92d7f7b0 546 phba->brd_no, vport->vpi,
dea3101e
JB
547 irsp->un.ulpWord[4], sp->cmn.e_d_tov,
548 sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution);
549
2e0fef85 550 if (vport->port_state == LPFC_FLOGI) {
dea3101e
JB
551 /*
552 * If Common Service Parameters indicate Nport
553 * we are point to point, if Fport we are Fabric.
554 */
555 if (sp->cmn.fPort)
2e0fef85 556 rc = lpfc_cmpl_els_flogi_fabric(vport, ndlp, sp, irsp);
dea3101e 557 else
2e0fef85 558 rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
dea3101e
JB
559
560 if (!rc)
561 goto out;
562 }
563
564flogifail:
329f9bc7 565 lpfc_nlp_put(ndlp);
dea3101e 566
858c9f6c 567 if (!lpfc_error_lost_link(irsp)) {
dea3101e 568 /* FLOGI failed, so just use loop map to make discovery list */
2e0fef85 569 lpfc_disc_list_loopmap(vport);
dea3101e
JB
570
571 /* Start discovery */
2e0fef85 572 lpfc_disc_start(vport);
dea3101e
JB
573 }
574
575out:
576 lpfc_els_free_iocb(phba, cmdiocb);
577}
578
579static int
2e0fef85 580lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
dea3101e
JB
581 uint8_t retry)
582{
2e0fef85 583 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
584 struct serv_parm *sp;
585 IOCB_t *icmd;
586 struct lpfc_iocbq *elsiocb;
587 struct lpfc_sli_ring *pring;
588 uint8_t *pcmd;
589 uint16_t cmdsize;
590 uint32_t tmo;
591 int rc;
592
593 pring = &phba->sli.ring[LPFC_ELS_RING];
594
92d7f7b0 595 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
2e0fef85
JS
596 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
597 ndlp->nlp_DID, ELS_CMD_FLOGI);
92d7f7b0 598
488d1469 599 if (!elsiocb)
c9f8735b 600 return 1;
dea3101e
JB
601
602 icmd = &elsiocb->iocb;
603 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
604
605 /* For FLOGI request, remainder of payload is service parameters */
606 *((uint32_t *) (pcmd)) = ELS_CMD_FLOGI;
92d7f7b0
JS
607 pcmd += sizeof(uint32_t);
608 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
dea3101e
JB
609 sp = (struct serv_parm *) pcmd;
610
611 /* Setup CSPs accordingly for Fabric */
612 sp->cmn.e_d_tov = 0;
613 sp->cmn.w2.r_a_tov = 0;
614 sp->cls1.classValid = 0;
615 sp->cls2.seqDelivery = 1;
616 sp->cls3.seqDelivery = 1;
617 if (sp->cmn.fcphLow < FC_PH3)
618 sp->cmn.fcphLow = FC_PH3;
619 if (sp->cmn.fcphHigh < FC_PH3)
620 sp->cmn.fcphHigh = FC_PH3;
621
92d7f7b0
JS
622 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
623 sp->cmn.request_multiple_Nport = 1;
624
625 /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */
626 icmd->ulpCt_h = 1;
627 icmd->ulpCt_l = 0;
628 }
629
858c9f6c
JS
630 if (phba->fc_topology != TOPOLOGY_LOOP) {
631 icmd->un.elsreq64.myID = 0;
632 icmd->un.elsreq64.fl = 1;
633 }
634
dea3101e
JB
635 tmo = phba->fc_ratov;
636 phba->fc_ratov = LPFC_DISC_FLOGI_TMO;
2e0fef85 637 lpfc_set_disctmo(vport);
dea3101e
JB
638 phba->fc_ratov = tmo;
639
640 phba->fc_stat.elsXmitFLOGI++;
641 elsiocb->iocb_cmpl = lpfc_cmpl_els_flogi;
858c9f6c
JS
642
643 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
644 "Issue FLOGI: opt:x%x",
645 phba->sli3_options, 0, 0);
646
92d7f7b0 647 rc = lpfc_issue_fabric_iocb(phba, elsiocb);
dea3101e
JB
648 if (rc == IOCB_ERROR) {
649 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 650 return 1;
dea3101e 651 }
c9f8735b 652 return 0;
dea3101e
JB
653}
654
655int
2e0fef85 656lpfc_els_abort_flogi(struct lpfc_hba *phba)
dea3101e
JB
657{
658 struct lpfc_sli_ring *pring;
659 struct lpfc_iocbq *iocb, *next_iocb;
660 struct lpfc_nodelist *ndlp;
661 IOCB_t *icmd;
662
663 /* Abort outstanding I/O on NPort <nlp_DID> */
664 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
665 "%d:0201 Abort outstanding I/O on NPort x%x\n",
666 phba->brd_no, Fabric_DID);
667
668 pring = &phba->sli.ring[LPFC_ELS_RING];
669
670 /*
671 * Check the txcmplq for an iocb that matches the nport the driver is
672 * searching for.
673 */
2e0fef85 674 spin_lock_irq(&phba->hbalock);
dea3101e
JB
675 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
676 icmd = &iocb->iocb;
2e0fef85
JS
677 if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
678 icmd->un.elsreq64.bdl.ulpIoTag32) {
dea3101e 679 ndlp = (struct lpfc_nodelist *)(iocb->context1);
92d7f7b0 680 if (ndlp && (ndlp->nlp_DID == Fabric_DID)) {
07951076 681 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
92d7f7b0 682 }
dea3101e
JB
683 }
684 }
2e0fef85 685 spin_unlock_irq(&phba->hbalock);
dea3101e
JB
686
687 return 0;
688}
689
690int
2e0fef85 691lpfc_initial_flogi(struct lpfc_vport *vport)
dea3101e 692{
2e0fef85 693 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
694 struct lpfc_nodelist *ndlp;
695
c9f8735b 696 /* First look for the Fabric ndlp */
2e0fef85 697 ndlp = lpfc_findnode_did(vport, Fabric_DID);
c9f8735b 698 if (!ndlp) {
dea3101e 699 /* Cannot find existing Fabric ndlp, so allocate a new one */
c9f8735b
JW
700 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
701 if (!ndlp)
702 return 0;
2e0fef85 703 lpfc_nlp_init(vport, ndlp, Fabric_DID);
c9f8735b 704 } else {
2e0fef85 705 lpfc_dequeue_node(vport, ndlp);
dea3101e 706 }
2e0fef85 707 if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
329f9bc7 708 lpfc_nlp_put(ndlp);
dea3101e 709 }
c9f8735b 710 return 1;
dea3101e
JB
711}
712
92d7f7b0
JS
713int
714lpfc_initial_fdisc(struct lpfc_vport *vport)
715{
716 struct lpfc_hba *phba = vport->phba;
717 struct lpfc_nodelist *ndlp;
718
719 /* First look for the Fabric ndlp */
720 ndlp = lpfc_findnode_did(vport, Fabric_DID);
721 if (!ndlp) {
722 /* Cannot find existing Fabric ndlp, so allocate a new one */
723 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
724 if (!ndlp)
725 return 0;
726 lpfc_nlp_init(vport, ndlp, Fabric_DID);
727 } else {
728 lpfc_dequeue_node(vport, ndlp);
729 }
730 if (lpfc_issue_els_fdisc(vport, ndlp, 0)) {
731 lpfc_nlp_put(ndlp);
732 }
733 return 1;
734}
dea3101e 735static void
2e0fef85 736lpfc_more_plogi(struct lpfc_vport *vport)
dea3101e
JB
737{
738 int sentplogi;
2e0fef85 739 struct lpfc_hba *phba = vport->phba;
dea3101e 740
2e0fef85
JS
741 if (vport->num_disc_nodes)
742 vport->num_disc_nodes--;
dea3101e
JB
743
744 /* Continue discovery with <num_disc_nodes> PLOGIs to go */
745 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
92d7f7b0 746 "%d (%d):0232 Continue discovery with %d PLOGIs to go "
dea3101e 747 "Data: x%x x%x x%x\n",
92d7f7b0 748 phba->brd_no, vport->vpi, vport->num_disc_nodes,
2e0fef85 749 vport->fc_plogi_cnt, vport->fc_flag, vport->port_state);
dea3101e
JB
750
751 /* Check to see if there are more PLOGIs to be sent */
2e0fef85
JS
752 if (vport->fc_flag & FC_NLP_MORE)
753 /* go thru NPR nodes and issue any remaining ELS PLOGIs */
754 sentplogi = lpfc_els_disc_plogi(vport);
755
dea3101e
JB
756 return;
757}
758
488d1469 759static struct lpfc_nodelist *
92d7f7b0 760lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
488d1469
JS
761 struct lpfc_nodelist *ndlp)
762{
2e0fef85 763 struct lpfc_vport *vport = ndlp->vport;
488d1469 764 struct lpfc_nodelist *new_ndlp;
488d1469 765 struct serv_parm *sp;
92d7f7b0 766 uint8_t name[sizeof(struct lpfc_name)];
488d1469
JS
767 uint32_t rc;
768
2fb9bd8b
JS
769 /* Fabric nodes can have the same WWPN so we don't bother searching
770 * by WWPN. Just return the ndlp that was given to us.
771 */
772 if (ndlp->nlp_type & NLP_FABRIC)
773 return ndlp;
774
92d7f7b0 775 sp = (struct serv_parm *) ((uint8_t *) prsp + sizeof(uint32_t));
685f0bf7 776 memset(name, 0, sizeof(struct lpfc_name));
488d1469 777
685f0bf7 778 /* Now we find out if the NPort we are logging into, matches the WWPN
488d1469
JS
779 * we have for that ndlp. If not, we have some work to do.
780 */
2e0fef85 781 new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName);
488d1469 782
92795650 783 if (new_ndlp == ndlp)
488d1469 784 return ndlp;
488d1469
JS
785
786 if (!new_ndlp) {
2e0fef85
JS
787 rc = memcmp(&ndlp->nlp_portname, name,
788 sizeof(struct lpfc_name));
92795650
JS
789 if (!rc)
790 return ndlp;
488d1469
JS
791 new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
792 if (!new_ndlp)
793 return ndlp;
794
2e0fef85 795 lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
488d1469
JS
796 }
797
2e0fef85 798 lpfc_unreg_rpi(vport, new_ndlp);
488d1469 799 new_ndlp->nlp_DID = ndlp->nlp_DID;
92795650 800 new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
2e0fef85 801 lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state);
488d1469 802
2e0fef85 803 /* Move this back to NPR state */
de0c5b32 804 if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0)
2e0fef85 805 lpfc_drop_node(vport, ndlp);
92795650 806 else {
2e0fef85 807 lpfc_unreg_rpi(vport, ndlp);
92795650 808 ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
2e0fef85 809 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
92795650 810 }
488d1469
JS
811 return new_ndlp;
812}
813
dea3101e 814static void
2e0fef85
JS
815lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
816 struct lpfc_iocbq *rspiocb)
dea3101e 817{
2e0fef85
JS
818 struct lpfc_vport *vport = cmdiocb->vport;
819 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 820 IOCB_t *irsp;
dea3101e 821 struct lpfc_nodelist *ndlp;
92795650 822 struct lpfc_dmabuf *prsp;
dea3101e
JB
823 int disc, rc, did, type;
824
dea3101e
JB
825 /* we pass cmdiocb to state machine which needs rspiocb as well */
826 cmdiocb->context_un.rsp_iocb = rspiocb;
827
828 irsp = &rspiocb->iocb;
858c9f6c
JS
829 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
830 "PLOGI cmpl: status:x%x/x%x did:x%x",
831 irsp->ulpStatus, irsp->un.ulpWord[4],
832 irsp->un.elsreq64.remoteID);
833
2e0fef85 834 ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
ed957684 835 if (!ndlp) {
92d7f7b0
JS
836 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
837 "%d (%d):0136 PLOGI completes to NPort x%x "
838 "with no ndlp. Data: x%x x%x x%x\n",
839 phba->brd_no, vport->vpi, irsp->un.elsreq64.remoteID,
840 irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpIoTag);
488d1469 841 goto out;
ed957684 842 }
dea3101e
JB
843
844 /* Since ndlp can be freed in the disc state machine, note if this node
845 * is being used during discovery.
846 */
2e0fef85 847 spin_lock_irq(shost->host_lock);
dea3101e 848 disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
488d1469 849 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
2e0fef85 850 spin_unlock_irq(shost->host_lock);
dea3101e
JB
851 rc = 0;
852
853 /* PLOGI completes to NPort <nlp_DID> */
854 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 855 "%d (%d):0102 PLOGI completes to NPort x%x "
c9f8735b 856 "Data: x%x x%x x%x x%x x%x\n",
92d7f7b0
JS
857 phba->brd_no, vport->vpi, ndlp->nlp_DID,
858 irsp->ulpStatus, irsp->un.ulpWord[4],
859 irsp->ulpTimeout, disc, vport->num_disc_nodes);
dea3101e
JB
860
861 /* Check to see if link went down during discovery */
2e0fef85
JS
862 if (lpfc_els_chk_latt(vport)) {
863 spin_lock_irq(shost->host_lock);
dea3101e 864 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2e0fef85 865 spin_unlock_irq(shost->host_lock);
dea3101e
JB
866 goto out;
867 }
868
869 /* ndlp could be freed in DSM, save these values now */
870 type = ndlp->nlp_type;
871 did = ndlp->nlp_DID;
872
873 if (irsp->ulpStatus) {
874 /* Check for retry */
875 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
876 /* ELS command is being retried */
877 if (disc) {
2e0fef85 878 spin_lock_irq(shost->host_lock);
dea3101e 879 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2e0fef85 880 spin_unlock_irq(shost->host_lock);
dea3101e
JB
881 }
882 goto out;
883 }
884
885 /* PLOGI failed */
92d7f7b0
JS
886 if (ndlp->nlp_DID == NameServer_DID) {
887 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
888 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
889 "%d (%d):0250 Nameserver login error: "
890 "0x%x / 0x%x\n",
891 phba->brd_no, vport->vpi,
892 irsp->ulpStatus, irsp->un.ulpWord[4]);
893 }
894
dea3101e 895 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
858c9f6c 896 if (lpfc_error_lost_link(irsp)) {
c9f8735b 897 rc = NLP_STE_FREED_NODE;
2fe165b6 898 } else {
2e0fef85 899 rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
92d7f7b0 900 NLP_EVT_CMPL_PLOGI);
dea3101e
JB
901 }
902 } else {
903 /* Good status, call state machine */
92795650 904 prsp = list_entry(((struct lpfc_dmabuf *)
92d7f7b0
JS
905 cmdiocb->context2)->list.next,
906 struct lpfc_dmabuf, list);
907 ndlp = lpfc_plogi_confirm_nport(phba, prsp->virt, ndlp);
2e0fef85 908 rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
92d7f7b0 909 NLP_EVT_CMPL_PLOGI);
dea3101e
JB
910 }
911
2e0fef85 912 if (disc && vport->num_disc_nodes) {
dea3101e 913 /* Check to see if there are more PLOGIs to be sent */
2e0fef85 914 lpfc_more_plogi(vport);
dea3101e 915
2e0fef85
JS
916 if (vport->num_disc_nodes == 0) {
917 spin_lock_irq(shost->host_lock);
918 vport->fc_flag &= ~FC_NDISC_ACTIVE;
919 spin_unlock_irq(shost->host_lock);
dea3101e 920
2e0fef85
JS
921 lpfc_can_disctmo(vport);
922 if (vport->fc_flag & FC_RSCN_MODE) {
10d4e957
JS
923 /*
924 * Check to see if more RSCNs came in while
925 * we were processing this one.
926 */
2e0fef85
JS
927 if ((vport->fc_rscn_id_cnt == 0) &&
928 (!(vport->fc_flag & FC_RSCN_DISCOVERY))) {
929 spin_lock_irq(shost->host_lock);
930 vport->fc_flag &= ~FC_RSCN_MODE;
931 spin_unlock_irq(shost->host_lock);
10d4e957 932 } else {
2e0fef85 933 lpfc_els_handle_rscn(vport);
10d4e957 934 }
dea3101e
JB
935 }
936 }
937 }
938
939out:
940 lpfc_els_free_iocb(phba, cmdiocb);
941 return;
942}
943
944int
2e0fef85 945lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
dea3101e 946{
2e0fef85 947 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
948 struct serv_parm *sp;
949 IOCB_t *icmd;
950 struct lpfc_iocbq *elsiocb;
951 struct lpfc_sli_ring *pring;
952 struct lpfc_sli *psli;
953 uint8_t *pcmd;
954 uint16_t cmdsize;
92d7f7b0 955 int ret;
dea3101e
JB
956
957 psli = &phba->sli;
958 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
959
92d7f7b0 960 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
2e0fef85
JS
961 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, NULL, did,
962 ELS_CMD_PLOGI);
c9f8735b
JW
963 if (!elsiocb)
964 return 1;
dea3101e
JB
965
966 icmd = &elsiocb->iocb;
967 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
968
969 /* For PLOGI request, remainder of payload is service parameters */
970 *((uint32_t *) (pcmd)) = ELS_CMD_PLOGI;
92d7f7b0
JS
971 pcmd += sizeof(uint32_t);
972 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
dea3101e
JB
973 sp = (struct serv_parm *) pcmd;
974
975 if (sp->cmn.fcphLow < FC_PH_4_3)
976 sp->cmn.fcphLow = FC_PH_4_3;
977
978 if (sp->cmn.fcphHigh < FC_PH3)
979 sp->cmn.fcphHigh = FC_PH3;
980
858c9f6c
JS
981 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
982 "Issue PLOGI: did:x%x",
983 did, 0, 0);
984
dea3101e
JB
985 phba->fc_stat.elsXmitPLOGI++;
986 elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi;
92d7f7b0
JS
987 ret = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
988
989 if (ret == IOCB_ERROR) {
dea3101e 990 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 991 return 1;
dea3101e 992 }
c9f8735b 993 return 0;
dea3101e
JB
994}
995
996static void
2e0fef85
JS
997lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
998 struct lpfc_iocbq *rspiocb)
dea3101e 999{
2e0fef85
JS
1000 struct lpfc_vport *vport = cmdiocb->vport;
1001 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e
JB
1002 IOCB_t *irsp;
1003 struct lpfc_sli *psli;
1004 struct lpfc_nodelist *ndlp;
1005
1006 psli = &phba->sli;
1007 /* we pass cmdiocb to state machine which needs rspiocb as well */
1008 cmdiocb->context_un.rsp_iocb = rspiocb;
1009
1010 irsp = &(rspiocb->iocb);
1011 ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2e0fef85 1012 spin_lock_irq(shost->host_lock);
dea3101e 1013 ndlp->nlp_flag &= ~NLP_PRLI_SND;
2e0fef85 1014 spin_unlock_irq(shost->host_lock);
dea3101e 1015
858c9f6c
JS
1016 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1017 "PRLI cmpl: status:x%x/x%x did:x%x",
1018 irsp->ulpStatus, irsp->un.ulpWord[4],
1019 ndlp->nlp_DID);
1020
dea3101e
JB
1021 /* PRLI completes to NPort <nlp_DID> */
1022 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 1023 "%d (%d):0103 PRLI completes to NPort x%x "
c9f8735b 1024 "Data: x%x x%x x%x x%x\n",
92d7f7b0
JS
1025 phba->brd_no, vport->vpi, ndlp->nlp_DID,
1026 irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout,
2e0fef85 1027 vport->num_disc_nodes);
dea3101e 1028
2e0fef85 1029 vport->fc_prli_sent--;
dea3101e 1030 /* Check to see if link went down during discovery */
2e0fef85 1031 if (lpfc_els_chk_latt(vport))
dea3101e
JB
1032 goto out;
1033
1034 if (irsp->ulpStatus) {
1035 /* Check for retry */
1036 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
1037 /* ELS command is being retried */
1038 goto out;
1039 }
1040 /* PRLI failed */
1041 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
858c9f6c 1042 if (lpfc_error_lost_link(irsp)) {
dea3101e 1043 goto out;
2fe165b6 1044 } else {
2e0fef85 1045 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
92d7f7b0 1046 NLP_EVT_CMPL_PRLI);
dea3101e
JB
1047 }
1048 } else {
1049 /* Good status, call state machine */
2e0fef85 1050 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
92d7f7b0 1051 NLP_EVT_CMPL_PRLI);
dea3101e
JB
1052 }
1053
1054out:
1055 lpfc_els_free_iocb(phba, cmdiocb);
1056 return;
1057}
1058
1059int
2e0fef85 1060lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
dea3101e
JB
1061 uint8_t retry)
1062{
2e0fef85
JS
1063 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1064 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
1065 PRLI *npr;
1066 IOCB_t *icmd;
1067 struct lpfc_iocbq *elsiocb;
1068 struct lpfc_sli_ring *pring;
1069 struct lpfc_sli *psli;
1070 uint8_t *pcmd;
1071 uint16_t cmdsize;
1072
1073 psli = &phba->sli;
1074 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
1075
92d7f7b0 1076 cmdsize = (sizeof(uint32_t) + sizeof(PRLI));
2e0fef85
JS
1077 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1078 ndlp->nlp_DID, ELS_CMD_PRLI);
488d1469 1079 if (!elsiocb)
c9f8735b 1080 return 1;
dea3101e
JB
1081
1082 icmd = &elsiocb->iocb;
1083 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1084
1085 /* For PRLI request, remainder of payload is service parameters */
92d7f7b0 1086 memset(pcmd, 0, (sizeof(PRLI) + sizeof(uint32_t)));
dea3101e 1087 *((uint32_t *) (pcmd)) = ELS_CMD_PRLI;
92d7f7b0 1088 pcmd += sizeof(uint32_t);
dea3101e
JB
1089
1090 /* For PRLI, remainder of payload is PRLI parameter page */
1091 npr = (PRLI *) pcmd;
1092 /*
1093 * If our firmware version is 3.20 or later,
1094 * set the following bits for FC-TAPE support.
1095 */
1096 if (phba->vpd.rev.feaLevelHigh >= 0x02) {
1097 npr->ConfmComplAllowed = 1;
1098 npr->Retry = 1;
1099 npr->TaskRetryIdReq = 1;
1100 }
1101 npr->estabImagePair = 1;
1102 npr->readXferRdyDis = 1;
1103
1104 /* For FCP support */
1105 npr->prliType = PRLI_FCP_TYPE;
1106 npr->initiatorFunc = 1;
1107
858c9f6c
JS
1108 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1109 "Issue PRLI: did:x%x",
1110 ndlp->nlp_DID, 0, 0);
1111
dea3101e
JB
1112 phba->fc_stat.elsXmitPRLI++;
1113 elsiocb->iocb_cmpl = lpfc_cmpl_els_prli;
2e0fef85 1114 spin_lock_irq(shost->host_lock);
dea3101e 1115 ndlp->nlp_flag |= NLP_PRLI_SND;
2e0fef85 1116 spin_unlock_irq(shost->host_lock);
dea3101e 1117 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2e0fef85 1118 spin_lock_irq(shost->host_lock);
dea3101e 1119 ndlp->nlp_flag &= ~NLP_PRLI_SND;
2e0fef85 1120 spin_unlock_irq(shost->host_lock);
dea3101e 1121 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 1122 return 1;
dea3101e 1123 }
2e0fef85 1124 vport->fc_prli_sent++;
c9f8735b 1125 return 0;
dea3101e
JB
1126}
1127
1128static void
2e0fef85 1129lpfc_more_adisc(struct lpfc_vport *vport)
dea3101e
JB
1130{
1131 int sentadisc;
2e0fef85 1132 struct lpfc_hba *phba = vport->phba;
dea3101e 1133
2e0fef85
JS
1134 if (vport->num_disc_nodes)
1135 vport->num_disc_nodes--;
dea3101e
JB
1136
1137 /* Continue discovery with <num_disc_nodes> ADISCs to go */
1138 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
92d7f7b0 1139 "%d (%d):0210 Continue discovery with %d ADISCs to go "
dea3101e 1140 "Data: x%x x%x x%x\n",
92d7f7b0 1141 phba->brd_no, vport->vpi, vport->num_disc_nodes,
2e0fef85 1142 vport->fc_adisc_cnt, vport->fc_flag, vport->port_state);
dea3101e
JB
1143
1144 /* Check to see if there are more ADISCs to be sent */
2e0fef85
JS
1145 if (vport->fc_flag & FC_NLP_MORE) {
1146 lpfc_set_disctmo(vport);
1147 /* go thru NPR nodes and issue any remaining ELS ADISCs */
1148 sentadisc = lpfc_els_disc_adisc(vport);
dea3101e
JB
1149 }
1150 return;
1151}
1152
1153static void
2e0fef85 1154lpfc_rscn_disc(struct lpfc_vport *vport)
dea3101e 1155{
2e0fef85
JS
1156 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1157
858c9f6c
JS
1158 lpfc_can_disctmo(vport);
1159
dea3101e 1160 /* RSCN discovery */
2e0fef85
JS
1161 /* go thru NPR nodes and issue ELS PLOGIs */
1162 if (vport->fc_npr_cnt)
1163 if (lpfc_els_disc_plogi(vport))
dea3101e 1164 return;
2e0fef85
JS
1165
1166 if (vport->fc_flag & FC_RSCN_MODE) {
dea3101e
JB
1167 /* Check to see if more RSCNs came in while we were
1168 * processing this one.
1169 */
2e0fef85
JS
1170 if ((vport->fc_rscn_id_cnt == 0) &&
1171 (!(vport->fc_flag & FC_RSCN_DISCOVERY))) {
1172 spin_lock_irq(shost->host_lock);
1173 vport->fc_flag &= ~FC_RSCN_MODE;
1174 spin_unlock_irq(shost->host_lock);
dea3101e 1175 } else {
2e0fef85 1176 lpfc_els_handle_rscn(vport);
dea3101e
JB
1177 }
1178 }
1179}
1180
1181static void
2e0fef85
JS
1182lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1183 struct lpfc_iocbq *rspiocb)
dea3101e 1184{
2e0fef85
JS
1185 struct lpfc_vport *vport = cmdiocb->vport;
1186 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 1187 IOCB_t *irsp;
dea3101e 1188 struct lpfc_nodelist *ndlp;
2e0fef85 1189 int disc;
dea3101e
JB
1190
1191 /* we pass cmdiocb to state machine which needs rspiocb as well */
1192 cmdiocb->context_un.rsp_iocb = rspiocb;
1193
1194 irsp = &(rspiocb->iocb);
1195 ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
dea3101e 1196
858c9f6c
JS
1197 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1198 "ADISC cmpl: status:x%x/x%x did:x%x",
1199 irsp->ulpStatus, irsp->un.ulpWord[4],
1200 ndlp->nlp_DID);
1201
dea3101e
JB
1202 /* Since ndlp can be freed in the disc state machine, note if this node
1203 * is being used during discovery.
1204 */
2e0fef85 1205 spin_lock_irq(shost->host_lock);
dea3101e 1206 disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
c9f8735b 1207 ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC);
2e0fef85 1208 spin_unlock_irq(shost->host_lock);
dea3101e
JB
1209
1210 /* ADISC completes to NPort <nlp_DID> */
1211 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 1212 "%d (%d):0104 ADISC completes to NPort x%x "
c9f8735b 1213 "Data: x%x x%x x%x x%x x%x\n",
92d7f7b0
JS
1214 phba->brd_no, vport->vpi, ndlp->nlp_DID,
1215 irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout,
1216 disc, vport->num_disc_nodes);
dea3101e
JB
1217
1218 /* Check to see if link went down during discovery */
2e0fef85
JS
1219 if (lpfc_els_chk_latt(vport)) {
1220 spin_lock_irq(shost->host_lock);
dea3101e 1221 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2e0fef85 1222 spin_unlock_irq(shost->host_lock);
dea3101e
JB
1223 goto out;
1224 }
1225
1226 if (irsp->ulpStatus) {
1227 /* Check for retry */
1228 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
1229 /* ELS command is being retried */
1230 if (disc) {
2e0fef85 1231 spin_lock_irq(shost->host_lock);
dea3101e 1232 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2e0fef85
JS
1233 spin_unlock_irq(shost->host_lock);
1234 lpfc_set_disctmo(vport);
dea3101e
JB
1235 }
1236 goto out;
1237 }
1238 /* ADISC failed */
1239 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
858c9f6c 1240 if (!lpfc_error_lost_link(irsp)) {
2e0fef85 1241 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
858c9f6c 1242 NLP_EVT_CMPL_ADISC);
dea3101e
JB
1243 }
1244 } else {
1245 /* Good status, call state machine */
2e0fef85 1246 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
dea3101e
JB
1247 NLP_EVT_CMPL_ADISC);
1248 }
1249
2e0fef85 1250 if (disc && vport->num_disc_nodes) {
dea3101e 1251 /* Check to see if there are more ADISCs to be sent */
2e0fef85 1252 lpfc_more_adisc(vport);
dea3101e
JB
1253
1254 /* Check to see if we are done with ADISC authentication */
2e0fef85 1255 if (vport->num_disc_nodes == 0) {
92d7f7b0
JS
1256 /* If we get here, there is nothing left to ADISC */
1257 /*
1258 * For NPIV, cmpl_reg_vpi will set port_state to READY,
1259 * and continue discovery.
1260 */
1261 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
1262 !(vport->fc_flag & FC_RSCN_MODE)) {
1263 lpfc_issue_reg_vpi(phba, vport);
1264 goto out;
1265 }
1266 /*
1267 * For SLI2, we need to set port_state to READY
1268 * and continue discovery.
1269 */
1270 if (vport->port_state < LPFC_VPORT_READY) {
1271 /* If we get here, there is nothing to ADISC */
ed957684 1272 if (vport->port_type == LPFC_PHYSICAL_PORT)
2e0fef85 1273 lpfc_issue_clear_la(phba, vport);
92d7f7b0
JS
1274
1275 if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
1276 vport->num_disc_nodes = 0;
1277 /* go thru NPR list, issue ELS PLOGIs */
1278 if (vport->fc_npr_cnt)
1279 lpfc_els_disc_plogi(vport);
1280
1281 if (!vport->num_disc_nodes) {
1282 spin_lock_irq(shost->host_lock);
1283 vport->fc_flag &=
1284 ~FC_NDISC_ACTIVE;
1285 spin_unlock_irq(
1286 shost->host_lock);
1287 lpfc_can_disctmo(vport);
1288 }
1289 }
1290 vport->port_state = LPFC_VPORT_READY;
dea3101e 1291 } else {
2e0fef85 1292 lpfc_rscn_disc(vport);
dea3101e
JB
1293 }
1294 }
1295 }
dea3101e
JB
1296out:
1297 lpfc_els_free_iocb(phba, cmdiocb);
1298 return;
1299}
1300
1301int
2e0fef85 1302lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
dea3101e
JB
1303 uint8_t retry)
1304{
2e0fef85
JS
1305 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1306 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
1307 ADISC *ap;
1308 IOCB_t *icmd;
1309 struct lpfc_iocbq *elsiocb;
2e0fef85
JS
1310 struct lpfc_sli *psli = &phba->sli;
1311 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
dea3101e
JB
1312 uint8_t *pcmd;
1313 uint16_t cmdsize;
1314
92d7f7b0 1315 cmdsize = (sizeof(uint32_t) + sizeof(ADISC));
2e0fef85
JS
1316 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1317 ndlp->nlp_DID, ELS_CMD_ADISC);
488d1469 1318 if (!elsiocb)
c9f8735b 1319 return 1;
dea3101e
JB
1320
1321 icmd = &elsiocb->iocb;
1322 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1323
1324 /* For ADISC request, remainder of payload is service parameters */
1325 *((uint32_t *) (pcmd)) = ELS_CMD_ADISC;
92d7f7b0 1326 pcmd += sizeof(uint32_t);
dea3101e
JB
1327
1328 /* Fill in ADISC payload */
1329 ap = (ADISC *) pcmd;
1330 ap->hardAL_PA = phba->fc_pref_ALPA;
92d7f7b0
JS
1331 memcpy(&ap->portName, &vport->fc_portname, sizeof(struct lpfc_name));
1332 memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
2e0fef85 1333 ap->DID = be32_to_cpu(vport->fc_myDID);
dea3101e 1334
858c9f6c
JS
1335 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1336 "Issue ADISC: did:x%x",
1337 ndlp->nlp_DID, 0, 0);
1338
dea3101e
JB
1339 phba->fc_stat.elsXmitADISC++;
1340 elsiocb->iocb_cmpl = lpfc_cmpl_els_adisc;
2e0fef85 1341 spin_lock_irq(shost->host_lock);
dea3101e 1342 ndlp->nlp_flag |= NLP_ADISC_SND;
2e0fef85 1343 spin_unlock_irq(shost->host_lock);
dea3101e 1344 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2e0fef85 1345 spin_lock_irq(shost->host_lock);
dea3101e 1346 ndlp->nlp_flag &= ~NLP_ADISC_SND;
2e0fef85 1347 spin_unlock_irq(shost->host_lock);
dea3101e 1348 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 1349 return 1;
dea3101e 1350 }
c9f8735b 1351 return 0;
dea3101e
JB
1352}
1353
1354static void
2e0fef85
JS
1355lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1356 struct lpfc_iocbq *rspiocb)
dea3101e 1357{
2e0fef85
JS
1358 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
1359 struct lpfc_vport *vport = ndlp->vport;
1360 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e
JB
1361 IOCB_t *irsp;
1362 struct lpfc_sli *psli;
dea3101e
JB
1363
1364 psli = &phba->sli;
1365 /* we pass cmdiocb to state machine which needs rspiocb as well */
1366 cmdiocb->context_un.rsp_iocb = rspiocb;
1367
1368 irsp = &(rspiocb->iocb);
2e0fef85 1369 spin_lock_irq(shost->host_lock);
dea3101e 1370 ndlp->nlp_flag &= ~NLP_LOGO_SND;
2e0fef85 1371 spin_unlock_irq(shost->host_lock);
dea3101e 1372
858c9f6c
JS
1373 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1374 "LOGO cmpl: status:x%x/x%x did:x%x",
1375 irsp->ulpStatus, irsp->un.ulpWord[4],
1376 ndlp->nlp_DID);
1377
dea3101e
JB
1378 /* LOGO completes to NPort <nlp_DID> */
1379 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 1380 "%d (%d):0105 LOGO completes to NPort x%x "
c9f8735b 1381 "Data: x%x x%x x%x x%x\n",
92d7f7b0
JS
1382 phba->brd_no, vport->vpi, ndlp->nlp_DID,
1383 irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout,
2e0fef85 1384 vport->num_disc_nodes);
dea3101e
JB
1385
1386 /* Check to see if link went down during discovery */
2e0fef85 1387 if (lpfc_els_chk_latt(vport))
dea3101e
JB
1388 goto out;
1389
92d7f7b0
JS
1390 if (ndlp->nlp_flag & NLP_TARGET_REMOVE) {
1391 /* NLP_EVT_DEVICE_RM should unregister the RPI
1392 * which should abort all outstanding IOs.
1393 */
1394 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1395 NLP_EVT_DEVICE_RM);
1396 goto out;
1397 }
1398
dea3101e
JB
1399 if (irsp->ulpStatus) {
1400 /* Check for retry */
2e0fef85 1401 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
dea3101e
JB
1402 /* ELS command is being retried */
1403 goto out;
dea3101e
JB
1404 /* LOGO failed */
1405 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
858c9f6c 1406 if (lpfc_error_lost_link(irsp))
dea3101e 1407 goto out;
858c9f6c 1408 else
2e0fef85 1409 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
92d7f7b0 1410 NLP_EVT_CMPL_LOGO);
dea3101e 1411 } else {
5024ab17
JW
1412 /* Good status, call state machine.
1413 * This will unregister the rpi if needed.
1414 */
2e0fef85 1415 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
92d7f7b0 1416 NLP_EVT_CMPL_LOGO);
dea3101e
JB
1417 }
1418
1419out:
1420 lpfc_els_free_iocb(phba, cmdiocb);
1421 return;
1422}
1423
1424int
2e0fef85 1425lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
dea3101e
JB
1426 uint8_t retry)
1427{
2e0fef85
JS
1428 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1429 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
1430 IOCB_t *icmd;
1431 struct lpfc_iocbq *elsiocb;
1432 struct lpfc_sli_ring *pring;
1433 struct lpfc_sli *psli;
1434 uint8_t *pcmd;
1435 uint16_t cmdsize;
92d7f7b0 1436 int rc;
dea3101e
JB
1437
1438 psli = &phba->sli;
1439 pring = &psli->ring[LPFC_ELS_RING];
1440
92d7f7b0 1441 cmdsize = (2 * sizeof(uint32_t)) + sizeof(struct lpfc_name);
2e0fef85
JS
1442 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1443 ndlp->nlp_DID, ELS_CMD_LOGO);
488d1469 1444 if (!elsiocb)
c9f8735b 1445 return 1;
dea3101e
JB
1446
1447 icmd = &elsiocb->iocb;
1448 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1449 *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
92d7f7b0 1450 pcmd += sizeof(uint32_t);
dea3101e
JB
1451
1452 /* Fill in LOGO payload */
2e0fef85 1453 *((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID);
92d7f7b0
JS
1454 pcmd += sizeof(uint32_t);
1455 memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name));
dea3101e 1456
858c9f6c
JS
1457 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1458 "Issue LOGO: did:x%x",
1459 ndlp->nlp_DID, 0, 0);
1460
dea3101e
JB
1461 phba->fc_stat.elsXmitLOGO++;
1462 elsiocb->iocb_cmpl = lpfc_cmpl_els_logo;
2e0fef85 1463 spin_lock_irq(shost->host_lock);
dea3101e 1464 ndlp->nlp_flag |= NLP_LOGO_SND;
2e0fef85 1465 spin_unlock_irq(shost->host_lock);
92d7f7b0
JS
1466 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
1467
1468 if (rc == IOCB_ERROR) {
2e0fef85 1469 spin_lock_irq(shost->host_lock);
dea3101e 1470 ndlp->nlp_flag &= ~NLP_LOGO_SND;
2e0fef85 1471 spin_unlock_irq(shost->host_lock);
dea3101e 1472 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 1473 return 1;
dea3101e 1474 }
c9f8735b 1475 return 0;
dea3101e
JB
1476}
1477
1478static void
2e0fef85
JS
1479lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1480 struct lpfc_iocbq *rspiocb)
dea3101e 1481{
2e0fef85 1482 struct lpfc_vport *vport = cmdiocb->vport;
dea3101e
JB
1483 IOCB_t *irsp;
1484
1485 irsp = &rspiocb->iocb;
1486
858c9f6c
JS
1487 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1488 "ELS cmd cmpl: status:x%x/x%x did:x%x",
1489 irsp->ulpStatus, irsp->un.ulpWord[4],
1490 irsp->un.elsreq64.remoteID);
1491
dea3101e 1492 /* ELS cmd tag <ulpIoTag> completes */
92d7f7b0
JS
1493 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
1494 "%d (%d):0106 ELS cmd tag x%x completes Data: x%x x%x "
1495 "x%x\n",
1496 phba->brd_no, vport->vpi,
c9f8735b
JW
1497 irsp->ulpIoTag, irsp->ulpStatus,
1498 irsp->un.ulpWord[4], irsp->ulpTimeout);
dea3101e
JB
1499
1500 /* Check to see if link went down during discovery */
2e0fef85 1501 lpfc_els_chk_latt(vport);
dea3101e
JB
1502 lpfc_els_free_iocb(phba, cmdiocb);
1503 return;
1504}
1505
1506int
2e0fef85 1507lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
dea3101e 1508{
2e0fef85 1509 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
1510 IOCB_t *icmd;
1511 struct lpfc_iocbq *elsiocb;
1512 struct lpfc_sli_ring *pring;
1513 struct lpfc_sli *psli;
1514 uint8_t *pcmd;
1515 uint16_t cmdsize;
1516 struct lpfc_nodelist *ndlp;
1517
1518 psli = &phba->sli;
1519 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
92d7f7b0 1520 cmdsize = (sizeof(uint32_t) + sizeof(SCR));
c9f8735b
JW
1521 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
1522 if (!ndlp)
1523 return 1;
dea3101e 1524
2e0fef85
JS
1525 lpfc_nlp_init(vport, ndlp, nportid);
1526
1527 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1528 ndlp->nlp_DID, ELS_CMD_SCR);
dea3101e 1529
488d1469 1530 if (!elsiocb) {
329f9bc7 1531 lpfc_nlp_put(ndlp);
c9f8735b 1532 return 1;
dea3101e
JB
1533 }
1534
1535 icmd = &elsiocb->iocb;
1536 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1537
1538 *((uint32_t *) (pcmd)) = ELS_CMD_SCR;
92d7f7b0 1539 pcmd += sizeof(uint32_t);
dea3101e
JB
1540
1541 /* For SCR, remainder of payload is SCR parameter page */
92d7f7b0 1542 memset(pcmd, 0, sizeof(SCR));
dea3101e
JB
1543 ((SCR *) pcmd)->Function = SCR_FUNC_FULL;
1544
858c9f6c
JS
1545 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1546 "Issue SCR: did:x%x",
1547 ndlp->nlp_DID, 0, 0);
1548
dea3101e
JB
1549 phba->fc_stat.elsXmitSCR++;
1550 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
dea3101e 1551 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
329f9bc7 1552 lpfc_nlp_put(ndlp);
dea3101e 1553 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 1554 return 1;
dea3101e 1555 }
329f9bc7 1556 lpfc_nlp_put(ndlp);
c9f8735b 1557 return 0;
dea3101e
JB
1558}
1559
1560static int
2e0fef85 1561lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
dea3101e 1562{
2e0fef85 1563 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
1564 IOCB_t *icmd;
1565 struct lpfc_iocbq *elsiocb;
1566 struct lpfc_sli_ring *pring;
1567 struct lpfc_sli *psli;
1568 FARP *fp;
1569 uint8_t *pcmd;
1570 uint32_t *lp;
1571 uint16_t cmdsize;
1572 struct lpfc_nodelist *ondlp;
1573 struct lpfc_nodelist *ndlp;
1574
1575 psli = &phba->sli;
1576 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
92d7f7b0 1577 cmdsize = (sizeof(uint32_t) + sizeof(FARP));
c9f8735b
JW
1578 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
1579 if (!ndlp)
1580 return 1;
dea3101e 1581
2e0fef85
JS
1582 lpfc_nlp_init(vport, ndlp, nportid);
1583
1584 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1585 ndlp->nlp_DID, ELS_CMD_RNID);
488d1469 1586 if (!elsiocb) {
329f9bc7 1587 lpfc_nlp_put(ndlp);
c9f8735b 1588 return 1;
dea3101e
JB
1589 }
1590
1591 icmd = &elsiocb->iocb;
1592 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1593
1594 *((uint32_t *) (pcmd)) = ELS_CMD_FARPR;
92d7f7b0 1595 pcmd += sizeof(uint32_t);
dea3101e
JB
1596
1597 /* Fill in FARPR payload */
1598 fp = (FARP *) (pcmd);
92d7f7b0 1599 memset(fp, 0, sizeof(FARP));
dea3101e
JB
1600 lp = (uint32_t *) pcmd;
1601 *lp++ = be32_to_cpu(nportid);
2e0fef85 1602 *lp++ = be32_to_cpu(vport->fc_myDID);
dea3101e
JB
1603 fp->Rflags = 0;
1604 fp->Mflags = (FARP_MATCH_PORT | FARP_MATCH_NODE);
1605
92d7f7b0
JS
1606 memcpy(&fp->RportName, &vport->fc_portname, sizeof(struct lpfc_name));
1607 memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
2e0fef85
JS
1608 ondlp = lpfc_findnode_did(vport, nportid);
1609 if (ondlp) {
dea3101e 1610 memcpy(&fp->OportName, &ondlp->nlp_portname,
92d7f7b0 1611 sizeof(struct lpfc_name));
dea3101e 1612 memcpy(&fp->OnodeName, &ondlp->nlp_nodename,
92d7f7b0 1613 sizeof(struct lpfc_name));
dea3101e
JB
1614 }
1615
858c9f6c
JS
1616 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1617 "Issue FARPR: did:x%x",
1618 ndlp->nlp_DID, 0, 0);
1619
dea3101e
JB
1620 phba->fc_stat.elsXmitFARPR++;
1621 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
dea3101e 1622 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
329f9bc7 1623 lpfc_nlp_put(ndlp);
dea3101e 1624 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 1625 return 1;
dea3101e 1626 }
329f9bc7 1627 lpfc_nlp_put(ndlp);
c9f8735b 1628 return 0;
dea3101e
JB
1629}
1630
ed957684
JS
1631static void
1632lpfc_end_rscn(struct lpfc_vport *vport)
1633{
1634 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1635
1636 if (vport->fc_flag & FC_RSCN_MODE) {
1637 /*
1638 * Check to see if more RSCNs came in while we were
1639 * processing this one.
1640 */
1641 if (vport->fc_rscn_id_cnt ||
1642 (vport->fc_flag & FC_RSCN_DISCOVERY) != 0)
1643 lpfc_els_handle_rscn(vport);
1644 else {
1645 spin_lock_irq(shost->host_lock);
1646 vport->fc_flag &= ~FC_RSCN_MODE;
1647 spin_unlock_irq(shost->host_lock);
1648 }
1649 }
1650}
1651
fdcebe28 1652void
2e0fef85 1653lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
fdcebe28 1654{
2e0fef85
JS
1655 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1656
1657 spin_lock_irq(shost->host_lock);
fdcebe28 1658 nlp->nlp_flag &= ~NLP_DELAY_TMO;
2e0fef85 1659 spin_unlock_irq(shost->host_lock);
fdcebe28
JS
1660 del_timer_sync(&nlp->nlp_delayfunc);
1661 nlp->nlp_last_elscmd = 0;
1662
1663 if (!list_empty(&nlp->els_retry_evt.evt_listp))
1664 list_del_init(&nlp->els_retry_evt.evt_listp);
1665
1666 if (nlp->nlp_flag & NLP_NPR_2B_DISC) {
2e0fef85 1667 spin_lock_irq(shost->host_lock);
fdcebe28 1668 nlp->nlp_flag &= ~NLP_NPR_2B_DISC;
2e0fef85
JS
1669 spin_unlock_irq(shost->host_lock);
1670 if (vport->num_disc_nodes) {
fdcebe28
JS
1671 /* Check to see if there are more
1672 * PLOGIs to be sent
1673 */
2e0fef85
JS
1674 lpfc_more_plogi(vport);
1675
1676 if (vport->num_disc_nodes == 0) {
1677 spin_lock_irq(shost->host_lock);
1678 vport->fc_flag &= ~FC_NDISC_ACTIVE;
1679 spin_unlock_irq(shost->host_lock);
1680 lpfc_can_disctmo(vport);
ed957684 1681 lpfc_end_rscn(vport);
fdcebe28
JS
1682 }
1683 }
1684 }
1685 return;
1686}
1687
dea3101e
JB
1688void
1689lpfc_els_retry_delay(unsigned long ptr)
1690{
2e0fef85
JS
1691 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) ptr;
1692 struct lpfc_vport *vport = ndlp->vport;
2e0fef85 1693 struct lpfc_hba *phba = vport->phba;
92d7f7b0 1694 unsigned long flags;
2e0fef85 1695 struct lpfc_work_evt *evtp = &ndlp->els_retry_evt;
dea3101e 1696
2e0fef85
JS
1697 ndlp = (struct lpfc_nodelist *) ptr;
1698 phba = ndlp->vport->phba;
dea3101e
JB
1699 evtp = &ndlp->els_retry_evt;
1700
92d7f7b0 1701 spin_lock_irqsave(&phba->hbalock, flags);
dea3101e 1702 if (!list_empty(&evtp->evt_listp)) {
92d7f7b0 1703 spin_unlock_irqrestore(&phba->hbalock, flags);
dea3101e
JB
1704 return;
1705 }
1706
1707 evtp->evt_arg1 = ndlp;
1708 evtp->evt = LPFC_EVT_ELS_RETRY;
1709 list_add_tail(&evtp->evt_listp, &phba->work_list);
1710 if (phba->work_wait)
92d7f7b0 1711 lpfc_worker_wake_up(phba);
dea3101e 1712
92d7f7b0 1713 spin_unlock_irqrestore(&phba->hbalock, flags);
dea3101e
JB
1714 return;
1715}
1716
1717void
1718lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
1719{
2e0fef85
JS
1720 struct lpfc_vport *vport = ndlp->vport;
1721 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1722 uint32_t cmd, did, retry;
dea3101e 1723
2e0fef85 1724 spin_lock_irq(shost->host_lock);
5024ab17
JW
1725 did = ndlp->nlp_DID;
1726 cmd = ndlp->nlp_last_elscmd;
1727 ndlp->nlp_last_elscmd = 0;
dea3101e
JB
1728
1729 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
2e0fef85 1730 spin_unlock_irq(shost->host_lock);
dea3101e
JB
1731 return;
1732 }
1733
1734 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
2e0fef85 1735 spin_unlock_irq(shost->host_lock);
1a169689
JS
1736 /*
1737 * If a discovery event readded nlp_delayfunc after timer
1738 * firing and before processing the timer, cancel the
1739 * nlp_delayfunc.
1740 */
1741 del_timer_sync(&ndlp->nlp_delayfunc);
dea3101e
JB
1742 retry = ndlp->nlp_retry;
1743
1744 switch (cmd) {
1745 case ELS_CMD_FLOGI:
2e0fef85 1746 lpfc_issue_els_flogi(vport, ndlp, retry);
dea3101e
JB
1747 break;
1748 case ELS_CMD_PLOGI:
2e0fef85 1749 if (!lpfc_issue_els_plogi(vport, ndlp->nlp_DID, retry)) {
5024ab17 1750 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 1751 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
6ad42535 1752 }
dea3101e
JB
1753 break;
1754 case ELS_CMD_ADISC:
2e0fef85 1755 if (!lpfc_issue_els_adisc(vport, ndlp, retry)) {
5024ab17 1756 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 1757 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
6ad42535 1758 }
dea3101e
JB
1759 break;
1760 case ELS_CMD_PRLI:
2e0fef85 1761 if (!lpfc_issue_els_prli(vport, ndlp, retry)) {
5024ab17 1762 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 1763 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
6ad42535 1764 }
dea3101e
JB
1765 break;
1766 case ELS_CMD_LOGO:
2e0fef85 1767 if (!lpfc_issue_els_logo(vport, ndlp, retry)) {
5024ab17 1768 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 1769 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
6ad42535 1770 }
dea3101e 1771 break;
92d7f7b0
JS
1772 case ELS_CMD_FDISC:
1773 lpfc_issue_els_fdisc(vport, ndlp, retry);
1774 break;
dea3101e
JB
1775 }
1776 return;
1777}
1778
1779static int
2e0fef85
JS
1780lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1781 struct lpfc_iocbq *rspiocb)
dea3101e 1782{
2e0fef85
JS
1783 struct lpfc_vport *vport = cmdiocb->vport;
1784 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1785 IOCB_t *irsp = &rspiocb->iocb;
1786 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
1787 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
dea3101e
JB
1788 uint32_t *elscmd;
1789 struct ls_rjt stat;
2e0fef85
JS
1790 int retry = 0, maxretry = lpfc_max_els_tries, delay = 0;
1791 uint32_t cmd = 0;
488d1469 1792 uint32_t did;
dea3101e 1793
488d1469 1794
dea3101e
JB
1795 /* Note: context2 may be 0 for internal driver abort
1796 * of delays ELS command.
1797 */
1798
1799 if (pcmd && pcmd->virt) {
1800 elscmd = (uint32_t *) (pcmd->virt);
1801 cmd = *elscmd++;
1802 }
1803
329f9bc7 1804 if (ndlp)
488d1469
JS
1805 did = ndlp->nlp_DID;
1806 else {
1807 /* We should only hit this case for retrying PLOGI */
1808 did = irsp->un.elsreq64.remoteID;
2e0fef85 1809 ndlp = lpfc_findnode_did(vport, did);
488d1469
JS
1810 if (!ndlp && (cmd != ELS_CMD_PLOGI))
1811 return 1;
1812 }
1813
858c9f6c
JS
1814 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1815 "Retry ELS: wd7:x%x wd4:x%x did:x%x",
1816 *(((uint32_t *) irsp) + 7), irsp->un.ulpWord[4], ndlp->nlp_DID);
1817
dea3101e
JB
1818 switch (irsp->ulpStatus) {
1819 case IOSTAT_FCP_RSP_ERROR:
1820 case IOSTAT_REMOTE_STOP:
1821 break;
1822
1823 case IOSTAT_LOCAL_REJECT:
1824 switch ((irsp->un.ulpWord[4] & 0xff)) {
1825 case IOERR_LOOP_OPEN_FAILURE:
2e0fef85 1826 if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0)
92d7f7b0 1827 delay = 1000;
dea3101e
JB
1828 retry = 1;
1829 break;
1830
92d7f7b0
JS
1831 case IOERR_ILLEGAL_COMMAND:
1832 if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) &&
1833 (cmd == ELS_CMD_FDISC)) {
1834 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
1835 "%d (%d):0124 FDISC failed (3/6) retrying...\n",
1836 phba->brd_no, vport->vpi);
1837 lpfc_mbx_unreg_vpi(vport);
1838 retry = 1;
1839 /* Always retry for this case */
1840 cmdiocb->retry = 0;
1841 }
1842 break;
1843
dea3101e 1844 case IOERR_NO_RESOURCES:
858c9f6c
JS
1845 retry = 1;
1846 if (cmdiocb->retry > 100)
1847 delay = 100;
1848 maxretry = 250;
1849 break;
1850
1851 case IOERR_ILLEGAL_FRAME:
92d7f7b0 1852 delay = 100;
dea3101e
JB
1853 retry = 1;
1854 break;
1855
858c9f6c 1856 case IOERR_SEQUENCE_TIMEOUT:
dea3101e
JB
1857 case IOERR_INVALID_RPI:
1858 retry = 1;
1859 break;
1860 }
1861 break;
1862
1863 case IOSTAT_NPORT_RJT:
1864 case IOSTAT_FABRIC_RJT:
1865 if (irsp->un.ulpWord[4] & RJT_UNAVAIL_TEMP) {
1866 retry = 1;
1867 break;
1868 }
1869 break;
1870
1871 case IOSTAT_NPORT_BSY:
1872 case IOSTAT_FABRIC_BSY:
1873 retry = 1;
1874 break;
1875
1876 case IOSTAT_LS_RJT:
1877 stat.un.lsRjtError = be32_to_cpu(irsp->un.ulpWord[4]);
1878 /* Added for Vendor specifc support
1879 * Just keep retrying for these Rsn / Exp codes
1880 */
1881 switch (stat.un.b.lsRjtRsnCode) {
1882 case LSRJT_UNABLE_TPC:
1883 if (stat.un.b.lsRjtRsnCodeExp ==
1884 LSEXP_CMD_IN_PROGRESS) {
1885 if (cmd == ELS_CMD_PLOGI) {
92d7f7b0 1886 delay = 1000;
dea3101e
JB
1887 maxretry = 48;
1888 }
1889 retry = 1;
1890 break;
1891 }
1892 if (cmd == ELS_CMD_PLOGI) {
92d7f7b0 1893 delay = 1000;
dea3101e
JB
1894 maxretry = lpfc_max_els_tries + 1;
1895 retry = 1;
1896 break;
1897 }
92d7f7b0
JS
1898 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
1899 (cmd == ELS_CMD_FDISC) &&
1900 (stat.un.b.lsRjtRsnCodeExp == LSEXP_OUT_OF_RESOURCE)){
1901 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
1902 "%d (%d):0125 FDISC Failed (x%x)."
1903 " Fabric out of resources\n",
1904 phba->brd_no, vport->vpi, stat.un.lsRjtError);
1905 lpfc_vport_set_state(vport,
1906 FC_VPORT_NO_FABRIC_RSCS);
1907 }
dea3101e
JB
1908 break;
1909
1910 case LSRJT_LOGICAL_BSY:
858c9f6c
JS
1911 if ((cmd == ELS_CMD_PLOGI) ||
1912 (cmd == ELS_CMD_PRLI)) {
92d7f7b0 1913 delay = 1000;
dea3101e 1914 maxretry = 48;
92d7f7b0
JS
1915 } else if (cmd == ELS_CMD_FDISC) {
1916 /* Always retry for this case */
1917 cmdiocb->retry = 0;
dea3101e
JB
1918 }
1919 retry = 1;
1920 break;
92d7f7b0
JS
1921
1922 case LSRJT_LOGICAL_ERR:
1923 case LSRJT_PROTOCOL_ERR:
1924 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
1925 (cmd == ELS_CMD_FDISC) &&
1926 ((stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_PNAME) ||
1927 (stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_NPORT_ID))
1928 ) {
1929 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
1930 "%d (%d):0123 FDISC Failed (x%x)."
1931 " Fabric Detected Bad WWN\n",
1932 phba->brd_no, vport->vpi, stat.un.lsRjtError);
1933 lpfc_vport_set_state(vport,
1934 FC_VPORT_FABRIC_REJ_WWN);
1935 }
1936 break;
dea3101e
JB
1937 }
1938 break;
1939
1940 case IOSTAT_INTERMED_RSP:
1941 case IOSTAT_BA_RJT:
1942 break;
1943
1944 default:
1945 break;
1946 }
1947
488d1469 1948 if (did == FDMI_DID)
dea3101e 1949 retry = 1;
dea3101e
JB
1950
1951 if ((++cmdiocb->retry) >= maxretry) {
1952 phba->fc_stat.elsRetryExceeded++;
1953 retry = 0;
1954 }
1955
ed957684
JS
1956 if ((vport->load_flag & FC_UNLOADING) != 0)
1957 retry = 0;
1958
dea3101e
JB
1959 if (retry) {
1960
1961 /* Retry ELS command <elsCmd> to remote NPORT <did> */
1962 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 1963 "%d (%d):0107 Retry ELS command x%x to remote "
dea3101e 1964 "NPORT x%x Data: x%x x%x\n",
92d7f7b0 1965 phba->brd_no, vport->vpi,
488d1469 1966 cmd, did, cmdiocb->retry, delay);
dea3101e 1967
858c9f6c
JS
1968 if (((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) &&
1969 ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
1970 ((irsp->un.ulpWord[4] & 0xff) != IOERR_NO_RESOURCES))) {
1971 /* Don't reset timer for no resources */
1972
dea3101e 1973 /* If discovery / RSCN timer is running, reset it */
2e0fef85 1974 if (timer_pending(&vport->fc_disctmo) ||
92d7f7b0 1975 (vport->fc_flag & FC_RSCN_MODE))
2e0fef85 1976 lpfc_set_disctmo(vport);
dea3101e
JB
1977 }
1978
1979 phba->fc_stat.elsXmitRetry++;
488d1469 1980 if (ndlp && delay) {
dea3101e
JB
1981 phba->fc_stat.elsDelayRetry++;
1982 ndlp->nlp_retry = cmdiocb->retry;
1983
92d7f7b0
JS
1984 /* delay is specified in milliseconds */
1985 mod_timer(&ndlp->nlp_delayfunc,
1986 jiffies + msecs_to_jiffies(delay));
2e0fef85 1987 spin_lock_irq(shost->host_lock);
dea3101e 1988 ndlp->nlp_flag |= NLP_DELAY_TMO;
2e0fef85 1989 spin_unlock_irq(shost->host_lock);
dea3101e 1990
5024ab17 1991 ndlp->nlp_prev_state = ndlp->nlp_state;
858c9f6c
JS
1992 if (cmd == ELS_CMD_PRLI)
1993 lpfc_nlp_set_state(vport, ndlp,
1994 NLP_STE_REG_LOGIN_ISSUE);
1995 else
1996 lpfc_nlp_set_state(vport, ndlp,
1997 NLP_STE_NPR_NODE);
dea3101e
JB
1998 ndlp->nlp_last_elscmd = cmd;
1999
c9f8735b 2000 return 1;
dea3101e
JB
2001 }
2002 switch (cmd) {
2003 case ELS_CMD_FLOGI:
2e0fef85 2004 lpfc_issue_els_flogi(vport, ndlp, cmdiocb->retry);
c9f8735b 2005 return 1;
92d7f7b0
JS
2006 case ELS_CMD_FDISC:
2007 lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry);
2008 return 1;
dea3101e 2009 case ELS_CMD_PLOGI:
488d1469
JS
2010 if (ndlp) {
2011 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 2012 lpfc_nlp_set_state(vport, ndlp,
de0c5b32 2013 NLP_STE_PLOGI_ISSUE);
488d1469 2014 }
2e0fef85 2015 lpfc_issue_els_plogi(vport, did, cmdiocb->retry);
c9f8735b 2016 return 1;
dea3101e 2017 case ELS_CMD_ADISC:
5024ab17 2018 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
2019 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2020 lpfc_issue_els_adisc(vport, ndlp, cmdiocb->retry);
c9f8735b 2021 return 1;
dea3101e 2022 case ELS_CMD_PRLI:
5024ab17 2023 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
2024 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
2025 lpfc_issue_els_prli(vport, ndlp, cmdiocb->retry);
c9f8735b 2026 return 1;
dea3101e 2027 case ELS_CMD_LOGO:
5024ab17 2028 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
2029 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2030 lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry);
c9f8735b 2031 return 1;
dea3101e
JB
2032 }
2033 }
2034
2035 /* No retry ELS command <elsCmd> to remote NPORT <did> */
2036 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0
JS
2037 "%d (%d):0108 No retry ELS command x%x to remote "
2038 "NPORT x%x Data: x%x\n",
2039 phba->brd_no, vport->vpi,
488d1469 2040 cmd, did, cmdiocb->retry);
dea3101e 2041
c9f8735b 2042 return 0;
dea3101e
JB
2043}
2044
2045int
329f9bc7 2046lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
dea3101e
JB
2047{
2048 struct lpfc_dmabuf *buf_ptr, *buf_ptr1;
2049
329f9bc7
JS
2050 if (elsiocb->context1) {
2051 lpfc_nlp_put(elsiocb->context1);
2052 elsiocb->context1 = NULL;
2053 }
dea3101e
JB
2054 /* context2 = cmd, context2->next = rsp, context3 = bpl */
2055 if (elsiocb->context2) {
2056 buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2;
2057 /* Free the response before processing the command. */
2058 if (!list_empty(&buf_ptr1->list)) {
2059 list_remove_head(&buf_ptr1->list, buf_ptr,
2060 struct lpfc_dmabuf,
2061 list);
2062 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
2063 kfree(buf_ptr);
2064 }
2065 lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys);
2066 kfree(buf_ptr1);
2067 }
2068
2069 if (elsiocb->context3) {
2070 buf_ptr = (struct lpfc_dmabuf *) elsiocb->context3;
2071 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
2072 kfree(buf_ptr);
2073 }
604a3e30 2074 lpfc_sli_release_iocbq(phba, elsiocb);
dea3101e
JB
2075 return 0;
2076}
2077
2078static void
2e0fef85
JS
2079lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2080 struct lpfc_iocbq *rspiocb)
dea3101e 2081{
2e0fef85
JS
2082 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2083 struct lpfc_vport *vport = cmdiocb->vport;
858c9f6c
JS
2084 IOCB_t *irsp;
2085
2086 irsp = &rspiocb->iocb;
2087 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2088 "ACC LOGO cmpl: status:x%x/x%x did:x%x",
2089 irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID);
dea3101e
JB
2090
2091 /* ACC to LOGO completes to NPort <nlp_DID> */
2092 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 2093 "%d (%d):0109 ACC to LOGO completes to NPort x%x "
dea3101e 2094 "Data: x%x x%x x%x\n",
92d7f7b0
JS
2095 phba->brd_no, vport->vpi, ndlp->nlp_DID,
2096 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
dea3101e 2097
dea3101e
JB
2098 switch (ndlp->nlp_state) {
2099 case NLP_STE_UNUSED_NODE: /* node is just allocated */
2e0fef85 2100 lpfc_drop_node(vport, ndlp);
dea3101e
JB
2101 break;
2102 case NLP_STE_NPR_NODE: /* NPort Recovery mode */
2e0fef85 2103 lpfc_unreg_rpi(vport, ndlp);
dea3101e
JB
2104 break;
2105 default:
2106 break;
2107 }
2108 lpfc_els_free_iocb(phba, cmdiocb);
2109 return;
2110}
2111
858c9f6c
JS
2112void
2113lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2114{
2115 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
2116 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
2117
2118 pmb->context1 = NULL;
2119 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2120 kfree(mp);
2121 mempool_free(pmb, phba->mbox_mem_pool);
2122 lpfc_nlp_put(ndlp);
2123 return;
2124}
2125
dea3101e 2126static void
858c9f6c 2127lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
329f9bc7 2128 struct lpfc_iocbq *rspiocb)
dea3101e 2129{
2e0fef85
JS
2130 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2131 struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL;
2132 struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
33ccf8d1 2133 IOCB_t *irsp;
dea3101e 2134 LPFC_MBOXQ_t *mbox = NULL;
2e0fef85 2135 struct lpfc_dmabuf *mp = NULL;
dea3101e 2136
33ccf8d1
JS
2137 irsp = &rspiocb->iocb;
2138
dea3101e
JB
2139 if (cmdiocb->context_un.mbox)
2140 mbox = cmdiocb->context_un.mbox;
2141
dea3101e 2142 /* Check to see if link went down during discovery */
2e0fef85 2143 if (!ndlp || lpfc_els_chk_latt(vport)) {
dea3101e 2144 if (mbox) {
14691150
JS
2145 mp = (struct lpfc_dmabuf *) mbox->context1;
2146 if (mp) {
2147 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2148 kfree(mp);
2149 }
329f9bc7 2150 mempool_free(mbox, phba->mbox_mem_pool);
dea3101e
JB
2151 }
2152 goto out;
2153 }
2154
858c9f6c
JS
2155 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2156 "ACC cmpl: status:x%x/x%x did:x%x",
2157 irsp->ulpStatus, irsp->un.ulpWord[4],
2158 irsp->un.rcvels.remoteID);
2159
dea3101e
JB
2160 /* ELS response tag <ulpIoTag> completes */
2161 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 2162 "%d (%d):0110 ELS response tag x%x completes "
c9f8735b 2163 "Data: x%x x%x x%x x%x x%x x%x x%x\n",
92d7f7b0 2164 phba->brd_no, vport->vpi,
dea3101e 2165 cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus,
c9f8735b 2166 rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout,
2e0fef85 2167 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
c9f8735b 2168 ndlp->nlp_rpi);
dea3101e
JB
2169
2170 if (mbox) {
2171 if ((rspiocb->iocb.ulpStatus == 0)
2172 && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) {
2e0fef85 2173 lpfc_unreg_rpi(vport, ndlp);
329f9bc7 2174 mbox->context2 = lpfc_nlp_get(ndlp);
2e0fef85 2175 mbox->vport = vport;
858c9f6c
JS
2176 if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) {
2177 mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
2178 mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
2179 }
2180 else {
2181 mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
2182 ndlp->nlp_prev_state = ndlp->nlp_state;
2183 lpfc_nlp_set_state(vport, ndlp,
2e0fef85 2184 NLP_STE_REG_LOGIN_ISSUE);
858c9f6c 2185 }
dea3101e
JB
2186 if (lpfc_sli_issue_mbox(phba, mbox,
2187 (MBX_NOWAIT | MBX_STOP_IOCB))
2188 != MBX_NOT_FINISHED) {
2189 goto out;
2190 }
329f9bc7 2191 lpfc_nlp_put(ndlp);
dea3101e
JB
2192 /* NOTE: we should have messages for unsuccessful
2193 reglogin */
dea3101e 2194 } else {
858c9f6c
JS
2195 /* Do not drop node for lpfc_els_abort'ed ELS cmds */
2196 if (!lpfc_error_lost_link(irsp) &&
2197 ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
2198 lpfc_drop_node(vport, ndlp);
2199 ndlp = NULL;
dea3101e
JB
2200 }
2201 }
14691150
JS
2202 mp = (struct lpfc_dmabuf *) mbox->context1;
2203 if (mp) {
2204 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2205 kfree(mp);
2206 }
2207 mempool_free(mbox, phba->mbox_mem_pool);
dea3101e
JB
2208 }
2209out:
2210 if (ndlp) {
2e0fef85 2211 spin_lock_irq(shost->host_lock);
858c9f6c 2212 ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI);
2e0fef85 2213 spin_unlock_irq(shost->host_lock);
dea3101e
JB
2214 }
2215 lpfc_els_free_iocb(phba, cmdiocb);
2216 return;
2217}
2218
2219int
2e0fef85
JS
2220lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
2221 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
2222 LPFC_MBOXQ_t *mbox, uint8_t newnode)
dea3101e 2223{
2e0fef85
JS
2224 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2225 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
2226 IOCB_t *icmd;
2227 IOCB_t *oldcmd;
2228 struct lpfc_iocbq *elsiocb;
2229 struct lpfc_sli_ring *pring;
2230 struct lpfc_sli *psli;
2231 uint8_t *pcmd;
2232 uint16_t cmdsize;
2233 int rc;
82d9a2a2 2234 ELS_PKT *els_pkt_ptr;
dea3101e
JB
2235
2236 psli = &phba->sli;
2237 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
2238 oldcmd = &oldiocb->iocb;
2239
2240 switch (flag) {
2241 case ELS_CMD_ACC:
92d7f7b0 2242 cmdsize = sizeof(uint32_t);
2e0fef85
JS
2243 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
2244 ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
488d1469 2245 if (!elsiocb) {
2e0fef85 2246 spin_lock_irq(shost->host_lock);
5024ab17 2247 ndlp->nlp_flag &= ~NLP_LOGO_ACC;
2e0fef85 2248 spin_unlock_irq(shost->host_lock);
c9f8735b 2249 return 1;
dea3101e 2250 }
2e0fef85 2251
dea3101e
JB
2252 icmd = &elsiocb->iocb;
2253 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2254 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2255 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
92d7f7b0 2256 pcmd += sizeof(uint32_t);
858c9f6c
JS
2257
2258 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2259 "Issue ACC: did:x%x flg:x%x",
2260 ndlp->nlp_DID, ndlp->nlp_flag, 0);
dea3101e
JB
2261 break;
2262 case ELS_CMD_PLOGI:
92d7f7b0 2263 cmdsize = (sizeof(struct serv_parm) + sizeof(uint32_t));
2e0fef85
JS
2264 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
2265 ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
488d1469 2266 if (!elsiocb)
c9f8735b 2267 return 1;
488d1469 2268
dea3101e
JB
2269 icmd = &elsiocb->iocb;
2270 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2271 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2272
2273 if (mbox)
2274 elsiocb->context_un.mbox = mbox;
2275
2276 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
92d7f7b0
JS
2277 pcmd += sizeof(uint32_t);
2278 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
858c9f6c
JS
2279
2280 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2281 "Issue ACC PLOGI: did:x%x flg:x%x",
2282 ndlp->nlp_DID, ndlp->nlp_flag, 0);
dea3101e 2283 break;
82d9a2a2 2284 case ELS_CMD_PRLO:
92d7f7b0 2285 cmdsize = sizeof(uint32_t) + sizeof(PRLO);
2e0fef85 2286 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
82d9a2a2
JS
2287 ndlp, ndlp->nlp_DID, ELS_CMD_PRLO);
2288 if (!elsiocb)
2289 return 1;
2290
2291 icmd = &elsiocb->iocb;
2292 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2293 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2294
2295 memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt,
92d7f7b0 2296 sizeof(uint32_t) + sizeof(PRLO));
82d9a2a2
JS
2297 *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC;
2298 els_pkt_ptr = (ELS_PKT *) pcmd;
2299 els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
858c9f6c
JS
2300
2301 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2302 "Issue ACC PRLO: did:x%x flg:x%x",
2303 ndlp->nlp_DID, ndlp->nlp_flag, 0);
82d9a2a2 2304 break;
dea3101e 2305 default:
c9f8735b 2306 return 1;
dea3101e
JB
2307 }
2308
329f9bc7
JS
2309 if (newnode) {
2310 lpfc_nlp_put(ndlp);
dea3101e 2311 elsiocb->context1 = NULL;
329f9bc7 2312 }
dea3101e
JB
2313
2314 /* Xmit ELS ACC response tag <ulpIoTag> */
2315 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 2316 "%d (%d):0128 Xmit ELS ACC response tag x%x, XRI: x%x, "
1dcb58e5 2317 "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n",
92d7f7b0 2318 phba->brd_no, vport->vpi, elsiocb->iotag,
dea3101e
JB
2319 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2320 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2321
2322 if (ndlp->nlp_flag & NLP_LOGO_ACC) {
2e0fef85 2323 spin_lock_irq(shost->host_lock);
c9f8735b 2324 ndlp->nlp_flag &= ~NLP_LOGO_ACC;
2e0fef85 2325 spin_unlock_irq(shost->host_lock);
dea3101e
JB
2326 elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc;
2327 } else {
858c9f6c 2328 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
dea3101e
JB
2329 }
2330
2331 phba->fc_stat.elsXmitACC++;
dea3101e 2332 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e
JB
2333 if (rc == IOCB_ERROR) {
2334 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 2335 return 1;
dea3101e 2336 }
c9f8735b 2337 return 0;
dea3101e
JB
2338}
2339
2340int
2e0fef85 2341lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
858c9f6c
JS
2342 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
2343 LPFC_MBOXQ_t *mbox)
dea3101e 2344{
2e0fef85 2345 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
2346 IOCB_t *icmd;
2347 IOCB_t *oldcmd;
2348 struct lpfc_iocbq *elsiocb;
2349 struct lpfc_sli_ring *pring;
2350 struct lpfc_sli *psli;
2351 uint8_t *pcmd;
2352 uint16_t cmdsize;
2353 int rc;
2354
2355 psli = &phba->sli;
2356 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
2357
92d7f7b0 2358 cmdsize = 2 * sizeof(uint32_t);
2e0fef85
JS
2359 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
2360 ndlp->nlp_DID, ELS_CMD_LS_RJT);
488d1469 2361 if (!elsiocb)
c9f8735b 2362 return 1;
dea3101e
JB
2363
2364 icmd = &elsiocb->iocb;
2365 oldcmd = &oldiocb->iocb;
2366 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2367 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2368
2369 *((uint32_t *) (pcmd)) = ELS_CMD_LS_RJT;
92d7f7b0 2370 pcmd += sizeof(uint32_t);
dea3101e
JB
2371 *((uint32_t *) (pcmd)) = rejectError;
2372
858c9f6c
JS
2373 if (mbox) {
2374 elsiocb->context_un.mbox = mbox;
2375 elsiocb->context1 = lpfc_nlp_get(ndlp);
2376 }
2377
dea3101e
JB
2378 /* Xmit ELS RJT <err> response tag <ulpIoTag> */
2379 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0
JS
2380 "%d (%d):0129 Xmit ELS RJT x%x response tag x%x "
2381 "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
2382 "rpi x%x\n",
2383 phba->brd_no, vport->vpi, rejectError, elsiocb->iotag,
dea3101e
JB
2384 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2385 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2386
858c9f6c
JS
2387 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2388 "Issue LS_RJT: did:x%x flg:x%x err:x%x",
2389 ndlp->nlp_DID, ndlp->nlp_flag, rejectError);
2390
dea3101e 2391 phba->fc_stat.elsXmitLSRJT++;
858c9f6c 2392 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
dea3101e 2393 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e
JB
2394 if (rc == IOCB_ERROR) {
2395 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 2396 return 1;
dea3101e 2397 }
c9f8735b 2398 return 0;
dea3101e
JB
2399}
2400
2401int
2e0fef85
JS
2402lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
2403 struct lpfc_nodelist *ndlp)
dea3101e 2404{
2e0fef85
JS
2405 struct lpfc_hba *phba = vport->phba;
2406 struct lpfc_sli *psli = &phba->sli;
2407 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
dea3101e 2408 ADISC *ap;
2e0fef85 2409 IOCB_t *icmd, *oldcmd;
dea3101e 2410 struct lpfc_iocbq *elsiocb;
dea3101e
JB
2411 uint8_t *pcmd;
2412 uint16_t cmdsize;
2413 int rc;
2414
92d7f7b0 2415 cmdsize = sizeof(uint32_t) + sizeof(ADISC);
2e0fef85
JS
2416 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
2417 ndlp->nlp_DID, ELS_CMD_ACC);
488d1469 2418 if (!elsiocb)
c9f8735b 2419 return 1;
dea3101e 2420
5b8bd0c9
JS
2421 icmd = &elsiocb->iocb;
2422 oldcmd = &oldiocb->iocb;
2423 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2424
dea3101e
JB
2425 /* Xmit ADISC ACC response tag <ulpIoTag> */
2426 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 2427 "%d (%d):0130 Xmit ADISC ACC response iotag x%x xri: "
5b8bd0c9 2428 "x%x, did x%x, nlp_flag x%x, nlp_state x%x rpi x%x\n",
92d7f7b0 2429 phba->brd_no, vport->vpi, elsiocb->iotag,
dea3101e
JB
2430 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2431 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2432
dea3101e
JB
2433 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2434
2435 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
92d7f7b0 2436 pcmd += sizeof(uint32_t);
dea3101e
JB
2437
2438 ap = (ADISC *) (pcmd);
2439 ap->hardAL_PA = phba->fc_pref_ALPA;
92d7f7b0
JS
2440 memcpy(&ap->portName, &vport->fc_portname, sizeof(struct lpfc_name));
2441 memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
2e0fef85 2442 ap->DID = be32_to_cpu(vport->fc_myDID);
dea3101e 2443
858c9f6c
JS
2444 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2445 "Issue ACC ADISC: did:x%x flg:x%x",
2446 ndlp->nlp_DID, ndlp->nlp_flag, 0);
2447
dea3101e 2448 phba->fc_stat.elsXmitACC++;
858c9f6c 2449 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
dea3101e 2450 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e
JB
2451 if (rc == IOCB_ERROR) {
2452 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 2453 return 1;
dea3101e 2454 }
c9f8735b 2455 return 0;
dea3101e
JB
2456}
2457
2458int
2e0fef85 2459lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
5b8bd0c9 2460 struct lpfc_nodelist *ndlp)
dea3101e 2461{
2e0fef85 2462 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
2463 PRLI *npr;
2464 lpfc_vpd_t *vpd;
2465 IOCB_t *icmd;
2466 IOCB_t *oldcmd;
2467 struct lpfc_iocbq *elsiocb;
2468 struct lpfc_sli_ring *pring;
2469 struct lpfc_sli *psli;
2470 uint8_t *pcmd;
2471 uint16_t cmdsize;
2472 int rc;
2473
2474 psli = &phba->sli;
2475 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
2476
92d7f7b0 2477 cmdsize = sizeof(uint32_t) + sizeof(PRLI);
2e0fef85 2478 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
92d7f7b0 2479 ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)));
c9f8735b
JW
2480 if (!elsiocb)
2481 return 1;
dea3101e 2482
5b8bd0c9
JS
2483 icmd = &elsiocb->iocb;
2484 oldcmd = &oldiocb->iocb;
2485 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2486
dea3101e
JB
2487 /* Xmit PRLI ACC response tag <ulpIoTag> */
2488 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 2489 "%d (%d):0131 Xmit PRLI ACC response tag x%x xri x%x, "
5b8bd0c9 2490 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
92d7f7b0 2491 phba->brd_no, vport->vpi, elsiocb->iotag,
dea3101e
JB
2492 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2493 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2494
dea3101e
JB
2495 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2496
2497 *((uint32_t *) (pcmd)) = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK));
92d7f7b0 2498 pcmd += sizeof(uint32_t);
dea3101e
JB
2499
2500 /* For PRLI, remainder of payload is PRLI parameter page */
92d7f7b0 2501 memset(pcmd, 0, sizeof(PRLI));
dea3101e
JB
2502
2503 npr = (PRLI *) pcmd;
2504 vpd = &phba->vpd;
2505 /*
2506 * If our firmware version is 3.20 or later,
2507 * set the following bits for FC-TAPE support.
2508 */
2509 if (vpd->rev.feaLevelHigh >= 0x02) {
2510 npr->ConfmComplAllowed = 1;
2511 npr->Retry = 1;
2512 npr->TaskRetryIdReq = 1;
2513 }
2514
2515 npr->acceptRspCode = PRLI_REQ_EXECUTED;
2516 npr->estabImagePair = 1;
2517 npr->readXferRdyDis = 1;
2518 npr->ConfmComplAllowed = 1;
2519
2520 npr->prliType = PRLI_FCP_TYPE;
2521 npr->initiatorFunc = 1;
2522
858c9f6c
JS
2523 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2524 "Issue ACC PRLI: did:x%x flg:x%x",
2525 ndlp->nlp_DID, ndlp->nlp_flag, 0);
2526
dea3101e 2527 phba->fc_stat.elsXmitACC++;
858c9f6c 2528 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
dea3101e 2529
dea3101e 2530 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e
JB
2531 if (rc == IOCB_ERROR) {
2532 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 2533 return 1;
dea3101e 2534 }
c9f8735b 2535 return 0;
dea3101e
JB
2536}
2537
2538static int
2e0fef85 2539lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
329f9bc7 2540 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
dea3101e 2541{
2e0fef85 2542 struct lpfc_hba *phba = vport->phba;
dea3101e 2543 RNID *rn;
2e0fef85 2544 IOCB_t *icmd, *oldcmd;
dea3101e
JB
2545 struct lpfc_iocbq *elsiocb;
2546 struct lpfc_sli_ring *pring;
2547 struct lpfc_sli *psli;
2548 uint8_t *pcmd;
2549 uint16_t cmdsize;
2550 int rc;
2551
2552 psli = &phba->sli;
2553 pring = &psli->ring[LPFC_ELS_RING];
2554
92d7f7b0
JS
2555 cmdsize = sizeof(uint32_t) + sizeof(uint32_t)
2556 + (2 * sizeof(struct lpfc_name));
dea3101e 2557 if (format)
92d7f7b0 2558 cmdsize += sizeof(RNID_TOP_DISC);
dea3101e 2559
2e0fef85
JS
2560 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
2561 ndlp->nlp_DID, ELS_CMD_ACC);
488d1469 2562 if (!elsiocb)
c9f8735b 2563 return 1;
dea3101e 2564
5b8bd0c9
JS
2565 icmd = &elsiocb->iocb;
2566 oldcmd = &oldiocb->iocb;
2567 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2568
dea3101e
JB
2569 /* Xmit RNID ACC response tag <ulpIoTag> */
2570 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0 2571 "%d (%d):0132 Xmit RNID ACC response tag x%x "
5b8bd0c9 2572 "xri x%x\n",
92d7f7b0 2573 phba->brd_no, vport->vpi, elsiocb->iotag,
dea3101e
JB
2574 elsiocb->iocb.ulpContext);
2575
dea3101e
JB
2576 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2577
2578 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
92d7f7b0 2579 pcmd += sizeof(uint32_t);
dea3101e 2580
92d7f7b0 2581 memset(pcmd, 0, sizeof(RNID));
dea3101e
JB
2582 rn = (RNID *) (pcmd);
2583 rn->Format = format;
92d7f7b0
JS
2584 rn->CommonLen = (2 * sizeof(struct lpfc_name));
2585 memcpy(&rn->portName, &vport->fc_portname, sizeof(struct lpfc_name));
2586 memcpy(&rn->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
dea3101e
JB
2587 switch (format) {
2588 case 0:
2589 rn->SpecificLen = 0;
2590 break;
2591 case RNID_TOPOLOGY_DISC:
92d7f7b0 2592 rn->SpecificLen = sizeof(RNID_TOP_DISC);
dea3101e 2593 memcpy(&rn->un.topologyDisc.portName,
92d7f7b0 2594 &vport->fc_portname, sizeof(struct lpfc_name));
dea3101e
JB
2595 rn->un.topologyDisc.unitType = RNID_HBA;
2596 rn->un.topologyDisc.physPort = 0;
2597 rn->un.topologyDisc.attachedNodes = 0;
2598 break;
2599 default:
2600 rn->CommonLen = 0;
2601 rn->SpecificLen = 0;
2602 break;
2603 }
2604
858c9f6c
JS
2605 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2606 "Issue ACC RNID: did:x%x flg:x%x",
2607 ndlp->nlp_DID, ndlp->nlp_flag, 0);
2608
dea3101e 2609 phba->fc_stat.elsXmitACC++;
858c9f6c 2610 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
329f9bc7 2611 lpfc_nlp_put(ndlp);
dea3101e
JB
2612 elsiocb->context1 = NULL; /* Don't need ndlp for cmpl,
2613 * it could be freed */
2614
dea3101e 2615 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e
JB
2616 if (rc == IOCB_ERROR) {
2617 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 2618 return 1;
dea3101e 2619 }
c9f8735b 2620 return 0;
dea3101e
JB
2621}
2622
2623int
2e0fef85 2624lpfc_els_disc_adisc(struct lpfc_vport *vport)
dea3101e 2625{
2e0fef85 2626 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 2627 struct lpfc_nodelist *ndlp, *next_ndlp;
2e0fef85 2628 int sentadisc = 0;
dea3101e 2629
685f0bf7 2630 /* go thru NPR nodes and issue any remaining ELS ADISCs */
2e0fef85 2631 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
685f0bf7
JS
2632 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
2633 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
2634 (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) {
2e0fef85 2635 spin_lock_irq(shost->host_lock);
685f0bf7 2636 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2e0fef85 2637 spin_unlock_irq(shost->host_lock);
685f0bf7 2638 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
2639 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2640 lpfc_issue_els_adisc(vport, ndlp, 0);
685f0bf7 2641 sentadisc++;
2e0fef85
JS
2642 vport->num_disc_nodes++;
2643 if (vport->num_disc_nodes >=
2644 vport->phba->cfg_discovery_threads) {
2645 spin_lock_irq(shost->host_lock);
2646 vport->fc_flag |= FC_NLP_MORE;
2647 spin_unlock_irq(shost->host_lock);
685f0bf7 2648 break;
dea3101e
JB
2649 }
2650 }
2651 }
2652 if (sentadisc == 0) {
2e0fef85
JS
2653 spin_lock_irq(shost->host_lock);
2654 vport->fc_flag &= ~FC_NLP_MORE;
2655 spin_unlock_irq(shost->host_lock);
dea3101e 2656 }
2fe165b6 2657 return sentadisc;
dea3101e
JB
2658}
2659
2660int
2e0fef85 2661lpfc_els_disc_plogi(struct lpfc_vport *vport)
dea3101e 2662{
2e0fef85 2663 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 2664 struct lpfc_nodelist *ndlp, *next_ndlp;
2e0fef85 2665 int sentplogi = 0;
dea3101e 2666
2e0fef85
JS
2667 /* go thru NPR nodes and issue any remaining ELS PLOGIs */
2668 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
685f0bf7
JS
2669 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
2670 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
2671 (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 &&
2672 (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) {
2673 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
2674 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2675 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
685f0bf7 2676 sentplogi++;
2e0fef85
JS
2677 vport->num_disc_nodes++;
2678 if (vport->num_disc_nodes >=
2679 vport->phba->cfg_discovery_threads) {
2680 spin_lock_irq(shost->host_lock);
2681 vport->fc_flag |= FC_NLP_MORE;
2682 spin_unlock_irq(shost->host_lock);
685f0bf7 2683 break;
dea3101e
JB
2684 }
2685 }
2686 }
2687 if (sentplogi == 0) {
2e0fef85
JS
2688 spin_lock_irq(shost->host_lock);
2689 vport->fc_flag &= ~FC_NLP_MORE;
2690 spin_unlock_irq(shost->host_lock);
dea3101e 2691 }
2fe165b6 2692 return sentplogi;
dea3101e
JB
2693}
2694
92d7f7b0 2695void
2e0fef85 2696lpfc_els_flush_rscn(struct lpfc_vport *vport)
dea3101e 2697{
2e0fef85
JS
2698 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2699 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
2700 int i;
2701
2e0fef85 2702 for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
92d7f7b0 2703 lpfc_in_buf_free(phba, vport->fc_rscn_id_list[i]);
2e0fef85 2704 vport->fc_rscn_id_list[i] = NULL;
dea3101e 2705 }
2e0fef85
JS
2706 spin_lock_irq(shost->host_lock);
2707 vport->fc_rscn_id_cnt = 0;
2708 vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY);
2709 spin_unlock_irq(shost->host_lock);
2710 lpfc_can_disctmo(vport);
dea3101e
JB
2711}
2712
2713int
2e0fef85 2714lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
dea3101e
JB
2715{
2716 D_ID ns_did;
2717 D_ID rscn_did;
dea3101e 2718 uint32_t *lp;
92d7f7b0 2719 uint32_t payload_len, i;
2e0fef85 2720 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
2721
2722 ns_did.un.word = did;
dea3101e
JB
2723
2724 /* Never match fabric nodes for RSCNs */
2725 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
2e0fef85 2726 return 0;
dea3101e
JB
2727
2728 /* If we are doing a FULL RSCN rediscovery, match everything */
2e0fef85 2729 if (vport->fc_flag & FC_RSCN_DISCOVERY)
c9f8735b 2730 return did;
dea3101e 2731
2e0fef85 2732 for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
92d7f7b0
JS
2733 lp = vport->fc_rscn_id_list[i]->virt;
2734 payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK);
2735 payload_len -= sizeof(uint32_t); /* take off word 0 */
dea3101e 2736 while (payload_len) {
92d7f7b0
JS
2737 rscn_did.un.word = be32_to_cpu(*lp++);
2738 payload_len -= sizeof(uint32_t);
dea3101e
JB
2739 switch (rscn_did.un.b.resv) {
2740 case 0: /* Single N_Port ID effected */
2e0fef85 2741 if (ns_did.un.word == rscn_did.un.word)
92d7f7b0 2742 return did;
dea3101e
JB
2743 break;
2744 case 1: /* Whole N_Port Area effected */
2745 if ((ns_did.un.b.domain == rscn_did.un.b.domain)
2746 && (ns_did.un.b.area == rscn_did.un.b.area))
92d7f7b0 2747 return did;
dea3101e
JB
2748 break;
2749 case 2: /* Whole N_Port Domain effected */
2750 if (ns_did.un.b.domain == rscn_did.un.b.domain)
92d7f7b0 2751 return did;
dea3101e
JB
2752 break;
2753 default:
2e0fef85 2754 /* Unknown Identifier in RSCN node */
dea3101e 2755 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
92d7f7b0
JS
2756 "%d (%d):0217 Unknown "
2757 "Identifier in RSCN payload "
2758 "Data: x%x\n",
2759 phba->brd_no, vport->vpi,
2760 rscn_did.un.word);
2761 case 3: /* Whole Fabric effected */
2762 return did;
dea3101e
JB
2763 }
2764 }
92d7f7b0
JS
2765 }
2766 return 0;
dea3101e
JB
2767}
2768
2769static int
2e0fef85 2770lpfc_rscn_recovery_check(struct lpfc_vport *vport)
dea3101e 2771{
685f0bf7 2772 struct lpfc_nodelist *ndlp = NULL;
dea3101e
JB
2773
2774 /* Look at all nodes effected by pending RSCNs and move
685f0bf7 2775 * them to NPR state.
dea3101e 2776 */
dea3101e 2777
2e0fef85 2778 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
685f0bf7 2779 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE ||
2e0fef85 2780 lpfc_rscn_payload_check(vport, ndlp->nlp_DID) == 0)
685f0bf7 2781 continue;
dea3101e 2782
2e0fef85 2783 lpfc_disc_state_machine(vport, ndlp, NULL,
92d7f7b0 2784 NLP_EVT_DEVICE_RECOVERY);
5024ab17 2785
685f0bf7
JS
2786 /*
2787 * Make sure NLP_DELAY_TMO is NOT running after a device
2788 * recovery event.
2789 */
2790 if (ndlp->nlp_flag & NLP_DELAY_TMO)
2e0fef85 2791 lpfc_cancel_retry_delay_tmo(vport, ndlp);
dea3101e 2792 }
685f0bf7 2793
c9f8735b 2794 return 0;
dea3101e
JB
2795}
2796
2797static int
2e0fef85
JS
2798lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2799 struct lpfc_nodelist *ndlp, uint8_t newnode)
dea3101e 2800{
2e0fef85
JS
2801 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2802 struct lpfc_hba *phba = vport->phba;
dea3101e 2803 struct lpfc_dmabuf *pcmd;
92d7f7b0
JS
2804 struct lpfc_vport *next_vport;
2805 uint32_t *lp, *datap;
dea3101e 2806 IOCB_t *icmd;
92d7f7b0
JS
2807 uint32_t payload_len, length, nportid, *cmd;
2808 int rscn_cnt = vport->fc_rscn_id_cnt;
2809 int rscn_id = 0, hba_id = 0;
d2873e4c 2810 int i;
dea3101e
JB
2811
2812 icmd = &cmdiocb->iocb;
2813 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
2814 lp = (uint32_t *) pcmd->virt;
2815
92d7f7b0
JS
2816 payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK);
2817 payload_len -= sizeof(uint32_t); /* take off word 0 */
dea3101e
JB
2818
2819 /* RSCN received */
ed957684 2820 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
92d7f7b0
JS
2821 "%d (%d):0214 RSCN received Data: x%x x%x x%x x%x\n",
2822 phba->brd_no, vport->vpi, vport->fc_flag, payload_len,
2823 *lp, rscn_cnt);
dea3101e 2824
d2873e4c 2825 for (i = 0; i < payload_len/sizeof(uint32_t); i++)
2e0fef85 2826 fc_host_post_event(shost, fc_get_event_number(),
d2873e4c
JS
2827 FCH_EVT_RSCN, lp[i]);
2828
dea3101e
JB
2829 /* If we are about to begin discovery, just ACC the RSCN.
2830 * Discovery processing will satisfy it.
2831 */
2e0fef85 2832 if (vport->port_state <= LPFC_NS_QRY) {
858c9f6c
JS
2833 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
2834 "RCV RSCN ignore: did:x%x/ste:x%x flg:x%x",
2835 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
2836
2e0fef85 2837 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
92d7f7b0 2838 newnode);
c9f8735b 2839 return 0;
dea3101e
JB
2840 }
2841
92d7f7b0
JS
2842 /* If this RSCN just contains NPortIDs for other vports on this HBA,
2843 * just ACC and ignore it.
2844 */
2845 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
2846 !(phba->cfg_peer_port_login)) {
2847 i = payload_len;
2848 datap = lp;
2849 while (i > 0) {
2850 nportid = *datap++;
2851 nportid = ((be32_to_cpu(nportid)) & Mask_DID);
2852 i -= sizeof(uint32_t);
2853 rscn_id++;
2854 list_for_each_entry(next_vport, &phba->port_list,
2855 listentry) {
2856 if (nportid == next_vport->fc_myDID) {
2857 hba_id++;
2858 break;
2859 }
2860 }
2861 }
2862 if (rscn_id == hba_id) {
2863 /* ALL NPortIDs in RSCN are on HBA */
2864 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
2865 "%d (%d):0214 Ignore RSCN Data: x%x x%x x%x x%x\n",
2866 phba->brd_no, vport->vpi, vport->fc_flag, payload_len,
2867 *lp, rscn_cnt);
858c9f6c
JS
2868
2869 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
2870 "RCV RSCN vport: did:x%x/ste:x%x flg:x%x",
2871 ndlp->nlp_DID, vport->port_state,
2872 ndlp->nlp_flag);
2873
92d7f7b0
JS
2874 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb,
2875 ndlp, NULL, newnode);
2876 return 0;
2877 }
2878 }
2879
dea3101e
JB
2880 /* If we are already processing an RSCN, save the received
2881 * RSCN payload buffer, cmdiocb->context2 to process later.
2882 */
2e0fef85 2883 if (vport->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) {
858c9f6c
JS
2884 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
2885 "RCV RSCN defer: did:x%x/ste:x%x flg:x%x",
2886 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
2887
92d7f7b0
JS
2888 vport->fc_flag |= FC_RSCN_DEFERRED;
2889 if ((rscn_cnt < FC_MAX_HOLD_RSCN) &&
2e0fef85
JS
2890 !(vport->fc_flag & FC_RSCN_DISCOVERY)) {
2891 spin_lock_irq(shost->host_lock);
2892 vport->fc_flag |= FC_RSCN_MODE;
2893 spin_unlock_irq(shost->host_lock);
92d7f7b0
JS
2894 if (rscn_cnt) {
2895 cmd = vport->fc_rscn_id_list[rscn_cnt-1]->virt;
2896 length = be32_to_cpu(*cmd & ~ELS_CMD_MASK);
2897 }
2898 if ((rscn_cnt) &&
2899 (payload_len + length <= LPFC_BPL_SIZE)) {
2900 *cmd &= ELS_CMD_MASK;
2901 *cmd |= be32_to_cpu(payload_len + length);
2902 memcpy(((uint8_t *)cmd) + length, lp,
2903 payload_len);
2904 } else {
2905 vport->fc_rscn_id_list[rscn_cnt] = pcmd;
2906 vport->fc_rscn_id_cnt++;
2907 /* If we zero, cmdiocb->context2, the calling
2908 * routine will not try to free it.
2909 */
2910 cmdiocb->context2 = NULL;
2911 }
dea3101e
JB
2912
2913 /* Deferred RSCN */
2914 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
92d7f7b0 2915 "%d (%d):0235 Deferred RSCN "
dea3101e 2916 "Data: x%x x%x x%x\n",
92d7f7b0
JS
2917 phba->brd_no, vport->vpi,
2918 vport->fc_rscn_id_cnt, vport->fc_flag,
2e0fef85 2919 vport->port_state);
dea3101e 2920 } else {
2e0fef85
JS
2921 spin_lock_irq(shost->host_lock);
2922 vport->fc_flag |= FC_RSCN_DISCOVERY;
2923 spin_unlock_irq(shost->host_lock);
dea3101e
JB
2924 /* ReDiscovery RSCN */
2925 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
92d7f7b0 2926 "%d (%d):0234 ReDiscovery RSCN "
dea3101e 2927 "Data: x%x x%x x%x\n",
92d7f7b0
JS
2928 phba->brd_no, vport->vpi,
2929 vport->fc_rscn_id_cnt, vport->fc_flag,
2e0fef85 2930 vport->port_state);
dea3101e
JB
2931 }
2932 /* Send back ACC */
2e0fef85 2933 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
dea3101e
JB
2934 newnode);
2935
2936 /* send RECOVERY event for ALL nodes that match RSCN payload */
2e0fef85 2937 lpfc_rscn_recovery_check(vport);
92d7f7b0 2938 vport->fc_flag &= ~FC_RSCN_DEFERRED;
c9f8735b 2939 return 0;
dea3101e
JB
2940 }
2941
858c9f6c
JS
2942 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
2943 "RCV RSCN: did:x%x/ste:x%x flg:x%x",
2944 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
2945
2e0fef85
JS
2946 spin_lock_irq(shost->host_lock);
2947 vport->fc_flag |= FC_RSCN_MODE;
2948 spin_unlock_irq(shost->host_lock);
2949 vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd;
dea3101e
JB
2950 /*
2951 * If we zero, cmdiocb->context2, the calling routine will
2952 * not try to free it.
2953 */
2954 cmdiocb->context2 = NULL;
2955
2e0fef85 2956 lpfc_set_disctmo(vport);
dea3101e
JB
2957
2958 /* Send back ACC */
2e0fef85 2959 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode);
dea3101e
JB
2960
2961 /* send RECOVERY event for ALL nodes that match RSCN payload */
2e0fef85 2962 lpfc_rscn_recovery_check(vport);
dea3101e 2963
2e0fef85 2964 return lpfc_els_handle_rscn(vport);
dea3101e
JB
2965}
2966
2967int
2e0fef85 2968lpfc_els_handle_rscn(struct lpfc_vport *vport)
dea3101e
JB
2969{
2970 struct lpfc_nodelist *ndlp;
2e0fef85 2971 struct lpfc_hba *phba = vport->phba;
dea3101e 2972
92d7f7b0
JS
2973 /* Ignore RSCN if the port is being torn down. */
2974 if (vport->load_flag & FC_UNLOADING) {
2975 lpfc_els_flush_rscn(vport);
2976 return 0;
2977 }
2978
dea3101e 2979 /* Start timer for RSCN processing */
2e0fef85 2980 lpfc_set_disctmo(vport);
dea3101e
JB
2981
2982 /* RSCN processed */
ed957684 2983 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
92d7f7b0
JS
2984 "%d (%d):0215 RSCN processed Data: x%x x%x x%x x%x\n",
2985 phba->brd_no, vport->vpi,
2e0fef85
JS
2986 vport->fc_flag, 0, vport->fc_rscn_id_cnt,
2987 vport->port_state);
dea3101e
JB
2988
2989 /* To process RSCN, first compare RSCN data with NameServer */
2e0fef85
JS
2990 vport->fc_ns_retry = 0;
2991 ndlp = lpfc_findnode_did(vport, NameServer_DID);
685f0bf7 2992 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
dea3101e 2993 /* Good ndlp, issue CT Request to NameServer */
92d7f7b0 2994 if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, 0) == 0)
dea3101e
JB
2995 /* Wait for NameServer query cmpl before we can
2996 continue */
c9f8735b 2997 return 1;
dea3101e
JB
2998 } else {
2999 /* If login to NameServer does not exist, issue one */
3000 /* Good status, issue PLOGI to NameServer */
2e0fef85
JS
3001 ndlp = lpfc_findnode_did(vport, NameServer_DID);
3002 if (ndlp)
dea3101e
JB
3003 /* Wait for NameServer login cmpl before we can
3004 continue */
c9f8735b 3005 return 1;
2e0fef85 3006
c9f8735b
JW
3007 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
3008 if (!ndlp) {
2e0fef85 3009 lpfc_els_flush_rscn(vport);
c9f8735b 3010 return 0;
dea3101e 3011 } else {
2e0fef85 3012 lpfc_nlp_init(vport, ndlp, NameServer_DID);
dea3101e 3013 ndlp->nlp_type |= NLP_FABRIC;
5024ab17 3014 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
3015 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
3016 lpfc_issue_els_plogi(vport, NameServer_DID, 0);
dea3101e
JB
3017 /* Wait for NameServer login cmpl before we can
3018 continue */
c9f8735b 3019 return 1;
dea3101e
JB
3020 }
3021 }
3022
2e0fef85 3023 lpfc_els_flush_rscn(vport);
c9f8735b 3024 return 0;
dea3101e
JB
3025}
3026
3027static int
2e0fef85
JS
3028lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3029 struct lpfc_nodelist *ndlp, uint8_t newnode)
dea3101e 3030{
2e0fef85
JS
3031 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3032 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
3033 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3034 uint32_t *lp = (uint32_t *) pcmd->virt;
3035 IOCB_t *icmd = &cmdiocb->iocb;
3036 struct serv_parm *sp;
3037 LPFC_MBOXQ_t *mbox;
3038 struct ls_rjt stat;
3039 uint32_t cmd, did;
3040 int rc;
3041
3042 cmd = *lp++;
3043 sp = (struct serv_parm *) lp;
3044
3045 /* FLOGI received */
3046
2e0fef85 3047 lpfc_set_disctmo(vport);
dea3101e
JB
3048
3049 if (phba->fc_topology == TOPOLOGY_LOOP) {
3050 /* We should never receive a FLOGI in loop mode, ignore it */
3051 did = icmd->un.elsreq64.remoteID;
3052
3053 /* An FLOGI ELS command <elsCmd> was received from DID <did> in
3054 Loop Mode */
3055 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
92d7f7b0
JS
3056 "%d (%d):0113 An FLOGI ELS command x%x was "
3057 "received from DID x%x in Loop Mode\n",
3058 phba->brd_no, vport->vpi, cmd, did);
c9f8735b 3059 return 1;
dea3101e
JB
3060 }
3061
3062 did = Fabric_DID;
3063
2e0fef85 3064 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3))) {
dea3101e
JB
3065 /* For a FLOGI we accept, then if our portname is greater
3066 * then the remote portname we initiate Nport login.
3067 */
3068
2e0fef85 3069 rc = memcmp(&vport->fc_portname, &sp->portName,
92d7f7b0 3070 sizeof(struct lpfc_name));
dea3101e
JB
3071
3072 if (!rc) {
2e0fef85
JS
3073 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
3074 if (!mbox)
c9f8735b 3075 return 1;
2e0fef85 3076
dea3101e
JB
3077 lpfc_linkdown(phba);
3078 lpfc_init_link(phba, mbox,
3079 phba->cfg_topology,
3080 phba->cfg_link_speed);
3081 mbox->mb.un.varInitLnk.lipsr_AL_PA = 0;
3082 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
ed957684 3083 mbox->vport = vport;
dea3101e
JB
3084 rc = lpfc_sli_issue_mbox
3085 (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB));
5b8bd0c9 3086 lpfc_set_loopback_flag(phba);
dea3101e 3087 if (rc == MBX_NOT_FINISHED) {
329f9bc7 3088 mempool_free(mbox, phba->mbox_mem_pool);
dea3101e 3089 }
c9f8735b 3090 return 1;
2fe165b6 3091 } else if (rc > 0) { /* greater than */
2e0fef85
JS
3092 spin_lock_irq(shost->host_lock);
3093 vport->fc_flag |= FC_PT2PT_PLOGI;
3094 spin_unlock_irq(shost->host_lock);
dea3101e 3095 }
2e0fef85
JS
3096 spin_lock_irq(shost->host_lock);
3097 vport->fc_flag |= FC_PT2PT;
3098 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
3099 spin_unlock_irq(shost->host_lock);
dea3101e
JB
3100 } else {
3101 /* Reject this request because invalid parameters */
3102 stat.un.b.lsRjtRsvd0 = 0;
3103 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
3104 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
3105 stat.un.b.vendorUnique = 0;
858c9f6c
JS
3106 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
3107 NULL);
c9f8735b 3108 return 1;
dea3101e
JB
3109 }
3110
3111 /* Send back ACC */
2e0fef85 3112 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode);
dea3101e 3113
c9f8735b 3114 return 0;
dea3101e
JB
3115}
3116
3117static int
2e0fef85
JS
3118lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3119 struct lpfc_nodelist *ndlp)
dea3101e
JB
3120{
3121 struct lpfc_dmabuf *pcmd;
3122 uint32_t *lp;
3123 IOCB_t *icmd;
3124 RNID *rn;
3125 struct ls_rjt stat;
3126 uint32_t cmd, did;
3127
3128 icmd = &cmdiocb->iocb;
3129 did = icmd->un.elsreq64.remoteID;
3130 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3131 lp = (uint32_t *) pcmd->virt;
3132
3133 cmd = *lp++;
3134 rn = (RNID *) lp;
3135
3136 /* RNID received */
3137
3138 switch (rn->Format) {
3139 case 0:
3140 case RNID_TOPOLOGY_DISC:
3141 /* Send back ACC */
2e0fef85 3142 lpfc_els_rsp_rnid_acc(vport, rn->Format, cmdiocb, ndlp);
dea3101e
JB
3143 break;
3144 default:
3145 /* Reject this request because format not supported */
3146 stat.un.b.lsRjtRsvd0 = 0;
3147 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
3148 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
3149 stat.un.b.vendorUnique = 0;
858c9f6c
JS
3150 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
3151 NULL);
dea3101e 3152 }
c9f8735b 3153 return 0;
dea3101e
JB
3154}
3155
3156static int
2e0fef85
JS
3157lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3158 struct lpfc_nodelist *ndlp)
7bb3b137
JW
3159{
3160 struct ls_rjt stat;
3161
3162 /* For now, unconditionally reject this command */
3163 stat.un.b.lsRjtRsvd0 = 0;
3164 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
3165 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
3166 stat.un.b.vendorUnique = 0;
858c9f6c 3167 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
7bb3b137
JW
3168 return 0;
3169}
3170
082c0266 3171static void
329f9bc7 3172lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
7bb3b137 3173{
2e0fef85
JS
3174 struct lpfc_sli *psli = &phba->sli;
3175 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
7bb3b137
JW
3176 MAILBOX_t *mb;
3177 IOCB_t *icmd;
3178 RPS_RSP *rps_rsp;
3179 uint8_t *pcmd;
3180 struct lpfc_iocbq *elsiocb;
3181 struct lpfc_nodelist *ndlp;
3182 uint16_t xri, status;
3183 uint32_t cmdsize;
3184
7bb3b137
JW
3185 mb = &pmb->mb;
3186
3187 ndlp = (struct lpfc_nodelist *) pmb->context2;
3188 xri = (uint16_t) ((unsigned long)(pmb->context1));
041976fb
RD
3189 pmb->context1 = NULL;
3190 pmb->context2 = NULL;
7bb3b137
JW
3191
3192 if (mb->mbxStatus) {
329f9bc7 3193 mempool_free(pmb, phba->mbox_mem_pool);
7bb3b137
JW
3194 return;
3195 }
3196
3197 cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t);
329f9bc7 3198 mempool_free(pmb, phba->mbox_mem_pool);
2e0fef85
JS
3199 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
3200 lpfc_max_els_tries, ndlp,
3201 ndlp->nlp_DID, ELS_CMD_ACC);
329f9bc7 3202 lpfc_nlp_put(ndlp);
c9f8735b 3203 if (!elsiocb)
7bb3b137 3204 return;
7bb3b137
JW
3205
3206 icmd = &elsiocb->iocb;
3207 icmd->ulpContext = xri;
3208
3209 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3210 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
92d7f7b0 3211 pcmd += sizeof(uint32_t); /* Skip past command */
7bb3b137
JW
3212 rps_rsp = (RPS_RSP *)pcmd;
3213
3214 if (phba->fc_topology != TOPOLOGY_LOOP)
3215 status = 0x10;
3216 else
3217 status = 0x8;
2e0fef85 3218 if (phba->pport->fc_flag & FC_FABRIC)
7bb3b137
JW
3219 status |= 0x4;
3220
3221 rps_rsp->rsvd1 = 0;
3222 rps_rsp->portStatus = be16_to_cpu(status);
3223 rps_rsp->linkFailureCnt = be32_to_cpu(mb->un.varRdLnk.linkFailureCnt);
3224 rps_rsp->lossSyncCnt = be32_to_cpu(mb->un.varRdLnk.lossSyncCnt);
3225 rps_rsp->lossSignalCnt = be32_to_cpu(mb->un.varRdLnk.lossSignalCnt);
3226 rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt);
3227 rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord);
3228 rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt);
3229
3230 /* Xmit ELS RPS ACC response tag <ulpIoTag> */
3231 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0
JS
3232 "%d (%d):0118 Xmit ELS RPS ACC response tag x%x "
3233 "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
3234 "rpi x%x\n",
3235 phba->brd_no, ndlp->vport->vpi, elsiocb->iotag,
7bb3b137
JW
3236 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
3237 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
3238
858c9f6c 3239 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
7bb3b137 3240 phba->fc_stat.elsXmitACC++;
ed957684 3241 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR)
7bb3b137 3242 lpfc_els_free_iocb(phba, elsiocb);
7bb3b137
JW
3243 return;
3244}
3245
3246static int
2e0fef85
JS
3247lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3248 struct lpfc_nodelist *ndlp)
dea3101e 3249{
2e0fef85 3250 struct lpfc_hba *phba = vport->phba;
dea3101e 3251 uint32_t *lp;
7bb3b137
JW
3252 uint8_t flag;
3253 LPFC_MBOXQ_t *mbox;
3254 struct lpfc_dmabuf *pcmd;
3255 RPS *rps;
3256 struct ls_rjt stat;
3257
2fe165b6
JW
3258 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
3259 (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
7bb3b137
JW
3260 stat.un.b.lsRjtRsvd0 = 0;
3261 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
3262 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
3263 stat.un.b.vendorUnique = 0;
858c9f6c
JS
3264 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
3265 NULL);
7bb3b137
JW
3266 }
3267
3268 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3269 lp = (uint32_t *) pcmd->virt;
3270 flag = (be32_to_cpu(*lp++) & 0xf);
3271 rps = (RPS *) lp;
3272
3273 if ((flag == 0) ||
3274 ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) ||
2e0fef85 3275 ((flag == 2) && (memcmp(&rps->un.portName, &vport->fc_portname,
92d7f7b0 3276 sizeof(struct lpfc_name)) == 0))) {
2e0fef85 3277
92d7f7b0
JS
3278 printk("Fix me....\n");
3279 dump_stack();
2e0fef85
JS
3280 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
3281 if (mbox) {
7bb3b137
JW
3282 lpfc_read_lnk_stat(phba, mbox);
3283 mbox->context1 =
92d7f7b0 3284 (void *)((unsigned long) cmdiocb->iocb.ulpContext);
329f9bc7 3285 mbox->context2 = lpfc_nlp_get(ndlp);
92d7f7b0 3286 mbox->vport = vport;
7bb3b137
JW
3287 mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
3288 if (lpfc_sli_issue_mbox (phba, mbox,
2e0fef85 3289 (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED)
7bb3b137
JW
3290 /* Mbox completion will send ELS Response */
3291 return 0;
2e0fef85 3292
329f9bc7 3293 lpfc_nlp_put(ndlp);
7bb3b137
JW
3294 mempool_free(mbox, phba->mbox_mem_pool);
3295 }
3296 }
3297 stat.un.b.lsRjtRsvd0 = 0;
3298 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
3299 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
3300 stat.un.b.vendorUnique = 0;
858c9f6c 3301 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
7bb3b137
JW
3302 return 0;
3303}
3304
082c0266 3305static int
2e0fef85
JS
3306lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
3307 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
7bb3b137 3308{
2e0fef85
JS
3309 struct lpfc_hba *phba = vport->phba;
3310 IOCB_t *icmd, *oldcmd;
7bb3b137
JW
3311 RPL_RSP rpl_rsp;
3312 struct lpfc_iocbq *elsiocb;
2e0fef85
JS
3313 struct lpfc_sli *psli = &phba->sli;
3314 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
7bb3b137 3315 uint8_t *pcmd;
dea3101e 3316
2e0fef85
JS
3317 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
3318 ndlp->nlp_DID, ELS_CMD_ACC);
7bb3b137 3319
488d1469 3320 if (!elsiocb)
7bb3b137 3321 return 1;
488d1469 3322
7bb3b137
JW
3323 icmd = &elsiocb->iocb;
3324 oldcmd = &oldiocb->iocb;
3325 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
3326
3327 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3328 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
92d7f7b0 3329 pcmd += sizeof(uint16_t);
7bb3b137
JW
3330 *((uint16_t *)(pcmd)) = be16_to_cpu(cmdsize);
3331 pcmd += sizeof(uint16_t);
3332
3333 /* Setup the RPL ACC payload */
3334 rpl_rsp.listLen = be32_to_cpu(1);
3335 rpl_rsp.index = 0;
3336 rpl_rsp.port_num_blk.portNum = 0;
2e0fef85
JS
3337 rpl_rsp.port_num_blk.portID = be32_to_cpu(vport->fc_myDID);
3338 memcpy(&rpl_rsp.port_num_blk.portName, &vport->fc_portname,
7bb3b137
JW
3339 sizeof(struct lpfc_name));
3340
3341 memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t));
3342
3343
3344 /* Xmit ELS RPL ACC response tag <ulpIoTag> */
3345 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0
JS
3346 "%d (%d):0120 Xmit ELS RPL ACC response tag x%x "
3347 "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
3348 "rpi x%x\n",
3349 phba->brd_no, vport->vpi, elsiocb->iotag,
7bb3b137
JW
3350 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
3351 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
3352
858c9f6c 3353 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
7bb3b137
JW
3354
3355 phba->fc_stat.elsXmitACC++;
3356 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
3357 lpfc_els_free_iocb(phba, elsiocb);
3358 return 1;
3359 }
3360 return 0;
3361}
3362
3363static int
2e0fef85
JS
3364lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3365 struct lpfc_nodelist *ndlp)
7bb3b137
JW
3366{
3367 struct lpfc_dmabuf *pcmd;
3368 uint32_t *lp;
3369 uint32_t maxsize;
3370 uint16_t cmdsize;
3371 RPL *rpl;
3372 struct ls_rjt stat;
3373
2fe165b6
JW
3374 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
3375 (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
7bb3b137
JW
3376 stat.un.b.lsRjtRsvd0 = 0;
3377 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
3378 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
3379 stat.un.b.vendorUnique = 0;
858c9f6c
JS
3380 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
3381 NULL);
7bb3b137
JW
3382 }
3383
dea3101e
JB
3384 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3385 lp = (uint32_t *) pcmd->virt;
7bb3b137 3386 rpl = (RPL *) (lp + 1);
dea3101e 3387
7bb3b137 3388 maxsize = be32_to_cpu(rpl->maxsize);
dea3101e 3389
7bb3b137
JW
3390 /* We support only one port */
3391 if ((rpl->index == 0) &&
3392 ((maxsize == 0) ||
3393 ((maxsize * sizeof(uint32_t)) >= sizeof(RPL_RSP)))) {
3394 cmdsize = sizeof(uint32_t) + sizeof(RPL_RSP);
2fe165b6 3395 } else {
7bb3b137
JW
3396 cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t);
3397 }
2e0fef85 3398 lpfc_els_rsp_rpl_acc(vport, cmdsize, cmdiocb, ndlp);
dea3101e
JB
3399
3400 return 0;
3401}
3402
3403static int
2e0fef85
JS
3404lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3405 struct lpfc_nodelist *ndlp)
dea3101e 3406{
2e0fef85 3407 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
3408 struct lpfc_dmabuf *pcmd;
3409 uint32_t *lp;
3410 IOCB_t *icmd;
3411 FARP *fp;
3412 uint32_t cmd, cnt, did;
3413
3414 icmd = &cmdiocb->iocb;
3415 did = icmd->un.elsreq64.remoteID;
3416 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3417 lp = (uint32_t *) pcmd->virt;
3418
3419 cmd = *lp++;
3420 fp = (FARP *) lp;
3421
3422 /* FARP-REQ received from DID <did> */
ed957684 3423 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0
JS
3424 "%d (%d):0601 FARP-REQ received from DID x%x\n",
3425 phba->brd_no, vport->vpi, did);
dea3101e
JB
3426
3427 /* We will only support match on WWPN or WWNN */
3428 if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) {
c9f8735b 3429 return 0;
dea3101e
JB
3430 }
3431
3432 cnt = 0;
3433 /* If this FARP command is searching for my portname */
3434 if (fp->Mflags & FARP_MATCH_PORT) {
2e0fef85 3435 if (memcmp(&fp->RportName, &vport->fc_portname,
92d7f7b0 3436 sizeof(struct lpfc_name)) == 0)
dea3101e
JB
3437 cnt = 1;
3438 }
3439
3440 /* If this FARP command is searching for my nodename */
3441 if (fp->Mflags & FARP_MATCH_NODE) {
2e0fef85 3442 if (memcmp(&fp->RnodeName, &vport->fc_nodename,
92d7f7b0 3443 sizeof(struct lpfc_name)) == 0)
dea3101e
JB
3444 cnt = 1;
3445 }
3446
3447 if (cnt) {
3448 if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
3449 (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) {
3450 /* Log back into the node before sending the FARP. */
3451 if (fp->Rflags & FARP_REQUEST_PLOGI) {
5024ab17 3452 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 3453 lpfc_nlp_set_state(vport, ndlp,
de0c5b32 3454 NLP_STE_PLOGI_ISSUE);
2e0fef85 3455 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
dea3101e
JB
3456 }
3457
3458 /* Send a FARP response to that node */
2e0fef85
JS
3459 if (fp->Rflags & FARP_REQUEST_FARPR)
3460 lpfc_issue_els_farpr(vport, did, 0);
dea3101e
JB
3461 }
3462 }
c9f8735b 3463 return 0;
dea3101e
JB
3464}
3465
3466static int
2e0fef85
JS
3467lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3468 struct lpfc_nodelist *ndlp)
dea3101e
JB
3469{
3470 struct lpfc_dmabuf *pcmd;
3471 uint32_t *lp;
3472 IOCB_t *icmd;
3473 uint32_t cmd, did;
2e0fef85 3474 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
3475
3476 icmd = &cmdiocb->iocb;
3477 did = icmd->un.elsreq64.remoteID;
3478 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3479 lp = (uint32_t *) pcmd->virt;
3480
3481 cmd = *lp++;
3482 /* FARP-RSP received from DID <did> */
ed957684 3483 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0
JS
3484 "%d (%d):0600 FARP-RSP received from DID x%x\n",
3485 phba->brd_no, vport->vpi, did);
dea3101e 3486 /* ACCEPT the Farp resp request */
2e0fef85 3487 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
dea3101e
JB
3488
3489 return 0;
3490}
3491
3492static int
2e0fef85
JS
3493lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3494 struct lpfc_nodelist *fan_ndlp)
dea3101e
JB
3495{
3496 struct lpfc_dmabuf *pcmd;
3497 uint32_t *lp;
3498 IOCB_t *icmd;
dea3101e 3499 uint32_t cmd, did;
5024ab17
JW
3500 FAN *fp;
3501 struct lpfc_nodelist *ndlp, *next_ndlp;
2e0fef85 3502 struct lpfc_hba *phba = vport->phba;
5024ab17
JW
3503
3504 /* FAN received */
ed957684 3505 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0
JS
3506 "%d (%d):0265 FAN received\n",
3507 phba->brd_no, vport->vpi);
dea3101e
JB
3508
3509 icmd = &cmdiocb->iocb;
3510 did = icmd->un.elsreq64.remoteID;
5024ab17
JW
3511 pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
3512 lp = (uint32_t *)pcmd->virt;
dea3101e
JB
3513
3514 cmd = *lp++;
92d7f7b0 3515 fp = (FAN *) lp;
dea3101e 3516
5024ab17 3517 /* FAN received; Fan does not have a reply sequence */
dea3101e 3518
2e0fef85 3519 if (phba->pport->port_state == LPFC_LOCAL_CFG_LINK) {
5024ab17
JW
3520 if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName,
3521 sizeof(struct lpfc_name)) != 0) ||
3522 (memcmp(&phba->fc_fabparam.portName, &fp->FportName,
3523 sizeof(struct lpfc_name)) != 0)) {
3524 /*
3525 * This node has switched fabrics. FLOGI is required
3526 * Clean up the old rpi's
dea3101e 3527 */
5024ab17
JW
3528
3529 list_for_each_entry_safe(ndlp, next_ndlp,
2e0fef85 3530 &vport->fc_nodes, nlp_listp) {
685f0bf7
JS
3531 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
3532 continue;
5024ab17
JW
3533 if (ndlp->nlp_type & NLP_FABRIC) {
3534 /*
3535 * Clean up old Fabric, Nameserver and
3536 * other NLP_FABRIC logins
3537 */
2e0fef85 3538 lpfc_drop_node(vport, ndlp);
2fe165b6 3539 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
5024ab17
JW
3540 /* Fail outstanding I/O now since this
3541 * device is marked for PLOGI
3542 */
2e0fef85 3543 lpfc_unreg_rpi(vport, ndlp);
5024ab17
JW
3544 }
3545 }
3546
2e0fef85
JS
3547 vport->port_state = LPFC_FLOGI;
3548 lpfc_set_disctmo(vport);
3549 lpfc_initial_flogi(vport);
c9f8735b 3550 return 0;
dea3101e 3551 }
5024ab17
JW
3552 /* Discovery not needed,
3553 * move the nodes to their original state.
3554 */
2e0fef85 3555 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
685f0bf7
JS
3556 nlp_listp) {
3557 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
3558 continue;
dea3101e 3559
5024ab17
JW
3560 switch (ndlp->nlp_prev_state) {
3561 case NLP_STE_UNMAPPED_NODE:
3562 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2e0fef85 3563 lpfc_nlp_set_state(vport, ndlp,
de0c5b32 3564 NLP_STE_UNMAPPED_NODE);
5024ab17
JW
3565 break;
3566
3567 case NLP_STE_MAPPED_NODE:
3568 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2e0fef85 3569 lpfc_nlp_set_state(vport, ndlp,
de0c5b32 3570 NLP_STE_MAPPED_NODE);
5024ab17
JW
3571 break;
3572
3573 default:
3574 break;
3575 }
3576 }
3577
3578 /* Start discovery - this should just do CLEAR_LA */
2e0fef85 3579 lpfc_disc_start(vport);
dea3101e 3580 }
c9f8735b 3581 return 0;
dea3101e
JB
3582}
3583
3584void
3585lpfc_els_timeout(unsigned long ptr)
3586{
2e0fef85
JS
3587 struct lpfc_vport *vport = (struct lpfc_vport *) ptr;
3588 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
3589 unsigned long iflag;
3590
2e0fef85
JS
3591 spin_lock_irqsave(&vport->work_port_lock, iflag);
3592 if ((vport->work_port_events & WORKER_ELS_TMO) == 0) {
3593 vport->work_port_events |= WORKER_ELS_TMO;
92d7f7b0
JS
3594 spin_unlock_irqrestore(&vport->work_port_lock, iflag);
3595
3596 spin_lock_irqsave(&phba->hbalock, iflag);
dea3101e 3597 if (phba->work_wait)
92d7f7b0
JS
3598 lpfc_worker_wake_up(phba);
3599 spin_unlock_irqrestore(&phba->hbalock, iflag);
dea3101e 3600 }
92d7f7b0
JS
3601 else
3602 spin_unlock_irqrestore(&vport->work_port_lock, iflag);
dea3101e
JB
3603 return;
3604}
3605
3606void
2e0fef85 3607lpfc_els_timeout_handler(struct lpfc_vport *vport)
dea3101e 3608{
2e0fef85 3609 struct lpfc_hba *phba = vport->phba;
dea3101e
JB
3610 struct lpfc_sli_ring *pring;
3611 struct lpfc_iocbq *tmp_iocb, *piocb;
3612 IOCB_t *cmd = NULL;
3613 struct lpfc_dmabuf *pcmd;
2e0fef85 3614 uint32_t els_command = 0;
dea3101e 3615 uint32_t timeout;
2e0fef85 3616 uint32_t remote_ID = 0xffffffff;
dea3101e 3617
dea3101e 3618 /* If the timer is already canceled do nothing */
2e0fef85 3619 if ((vport->work_port_events & WORKER_ELS_TMO) == 0) {
dea3101e
JB
3620 return;
3621 }
2e0fef85 3622 spin_lock_irq(&phba->hbalock);
dea3101e
JB
3623 timeout = (uint32_t)(phba->fc_ratov << 1);
3624
3625 pring = &phba->sli.ring[LPFC_ELS_RING];
dea3101e
JB
3626
3627 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
3628 cmd = &piocb->iocb;
3629
2e0fef85
JS
3630 if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 ||
3631 piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
3632 piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
dea3101e 3633 continue;
2e0fef85
JS
3634
3635 if (piocb->vport != vport)
3636 continue;
3637
dea3101e 3638 pcmd = (struct lpfc_dmabuf *) piocb->context2;
2e0fef85
JS
3639 if (pcmd)
3640 els_command = *(uint32_t *) (pcmd->virt);
dea3101e 3641
92d7f7b0
JS
3642 if (els_command == ELS_CMD_FARP ||
3643 els_command == ELS_CMD_FARPR ||
3644 els_command == ELS_CMD_FDISC)
3645 continue;
3646
3647 if (vport != piocb->vport)
dea3101e 3648 continue;
dea3101e
JB
3649
3650 if (piocb->drvrTimeout > 0) {
92d7f7b0 3651 if (piocb->drvrTimeout >= timeout)
dea3101e 3652 piocb->drvrTimeout -= timeout;
92d7f7b0 3653 else
dea3101e 3654 piocb->drvrTimeout = 0;
dea3101e
JB
3655 continue;
3656 }
3657
2e0fef85
JS
3658 remote_ID = 0xffffffff;
3659 if (cmd->ulpCommand != CMD_GEN_REQUEST64_CR)
dea3101e 3660 remote_ID = cmd->un.elsreq64.remoteID;
2e0fef85
JS
3661 else {
3662 struct lpfc_nodelist *ndlp;
3663 ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext);
3664 if (ndlp)
3665 remote_ID = ndlp->nlp_DID;
dea3101e
JB
3666 }
3667
92d7f7b0
JS
3668 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
3669 "%d (%d):0127 ELS timeout Data: x%x x%x x%x "
3670 "x%x\n",
3671 phba->brd_no, vport->vpi, els_command,
dea3101e
JB
3672 remote_ID, cmd->ulpCommand, cmd->ulpIoTag);
3673
07951076 3674 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
dea3101e 3675 }
2e0fef85 3676 spin_unlock_irq(&phba->hbalock);
5a0e326d 3677
2e0fef85
JS
3678 if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt)
3679 mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout);
dea3101e
JB
3680}
3681
3682void
2e0fef85 3683lpfc_els_flush_cmd(struct lpfc_vport *vport)
dea3101e 3684{
2534ba75 3685 LIST_HEAD(completions);
2e0fef85 3686 struct lpfc_hba *phba = vport->phba;
329f9bc7 3687 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
dea3101e
JB
3688 struct lpfc_iocbq *tmp_iocb, *piocb;
3689 IOCB_t *cmd = NULL;
92d7f7b0
JS
3690
3691 lpfc_fabric_abort_vport(vport);
dea3101e 3692
2e0fef85 3693 spin_lock_irq(&phba->hbalock);
dea3101e
JB
3694 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
3695 cmd = &piocb->iocb;
3696
3697 if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
3698 continue;
3699 }
3700
3701 /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */
329f9bc7
JS
3702 if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN ||
3703 cmd->ulpCommand == CMD_QUE_RING_BUF64_CN ||
3704 cmd->ulpCommand == CMD_CLOSE_XRI_CN ||
3705 cmd->ulpCommand == CMD_ABORT_XRI_CN)
dea3101e 3706 continue;
dea3101e 3707
2e0fef85
JS
3708 if (piocb->vport != vport)
3709 continue;
3710
2534ba75 3711 list_move_tail(&piocb->list, &completions);
1dcb58e5 3712 pring->txq_cnt--;
dea3101e
JB
3713 }
3714
3715 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
dea3101e
JB
3716 if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
3717 continue;
3718 }
dea3101e 3719
2e0fef85
JS
3720 if (piocb->vport != vport)
3721 continue;
3722
07951076 3723 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
dea3101e 3724 }
2e0fef85 3725 spin_unlock_irq(&phba->hbalock);
2534ba75 3726
2e0fef85 3727 while (!list_empty(&completions)) {
2534ba75
JS
3728 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
3729 cmd = &piocb->iocb;
92d7f7b0 3730 list_del_init(&piocb->list);
2534ba75 3731
2e0fef85
JS
3732 if (!piocb->iocb_cmpl)
3733 lpfc_sli_release_iocbq(phba, piocb);
3734 else {
2534ba75
JS
3735 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
3736 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
3737 (piocb->iocb_cmpl) (phba, piocb, piocb);
2e0fef85 3738 }
2534ba75
JS
3739 }
3740
dea3101e
JB
3741 return;
3742}
3743
ed957684
JS
3744static void
3745lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
92d7f7b0 3746 struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb)
dea3101e 3747{
dea3101e 3748 struct lpfc_nodelist *ndlp;
dea3101e 3749 struct ls_rjt stat;
92d7f7b0 3750 uint32_t *payload;
2e0fef85 3751 uint32_t cmd, did, newnode, rjt_err = 0;
ed957684 3752 IOCB_t *icmd = &elsiocb->iocb;
dea3101e 3753
92d7f7b0 3754 if (vport == NULL || elsiocb->context2 == NULL)
dea3101e 3755 goto dropit;
2e0fef85 3756
dea3101e 3757 newnode = 0;
92d7f7b0
JS
3758 payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt;
3759 cmd = *payload;
ed957684
JS
3760 if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0)
3761 lpfc_post_buffer(phba, pring, 1, 1);
dea3101e 3762
858c9f6c
JS
3763 did = icmd->un.rcvels.remoteID;
3764 if (icmd->ulpStatus) {
3765 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3766 "RCV Unsol ELS: status:x%x/x%x did:x%x",
3767 icmd->ulpStatus, icmd->un.ulpWord[4], did);
dea3101e 3768 goto dropit;
858c9f6c 3769 }
dea3101e
JB
3770
3771 /* Check to see if link went down during discovery */
ed957684 3772 if (lpfc_els_chk_latt(vport))
dea3101e 3773 goto dropit;
dea3101e 3774
92d7f7b0
JS
3775 /* Ignore traffic recevied during vport shutdown. */
3776 if (vport->load_flag & FC_UNLOADING)
3777 goto dropit;
3778
2e0fef85 3779 ndlp = lpfc_findnode_did(vport, did);
c9f8735b 3780 if (!ndlp) {
dea3101e 3781 /* Cannot find existing Fabric ndlp, so allocate a new one */
c9f8735b 3782 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
ed957684 3783 if (!ndlp)
dea3101e 3784 goto dropit;
dea3101e 3785
2e0fef85 3786 lpfc_nlp_init(vport, ndlp, did);
dea3101e
JB
3787 newnode = 1;
3788 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) {
3789 ndlp->nlp_type |= NLP_FABRIC;
3790 }
2e0fef85 3791 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
dea3101e
JB
3792 }
3793
3794 phba->fc_stat.elsRcvFrame++;
329f9bc7
JS
3795 if (elsiocb->context1)
3796 lpfc_nlp_put(elsiocb->context1);
3797 elsiocb->context1 = lpfc_nlp_get(ndlp);
2e0fef85 3798 elsiocb->vport = vport;
dea3101e
JB
3799
3800 if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) {
3801 cmd &= ELS_CMD_MASK;
3802 }
3803 /* ELS command <elsCmd> received from NPORT <did> */
3804 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
92d7f7b0
JS
3805 "%d (%d):0112 ELS command x%x received from NPORT x%x "
3806 "Data: x%x\n", phba->brd_no, vport->vpi, cmd, did,
ed957684 3807 vport->port_state);
dea3101e
JB
3808
3809 switch (cmd) {
3810 case ELS_CMD_PLOGI:
858c9f6c
JS
3811 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3812 "RCV PLOGI: did:x%x/ste:x%x flg:x%x",
3813 did, vport->port_state, ndlp->nlp_flag);
3814
dea3101e 3815 phba->fc_stat.elsRcvPLOGI++;
858c9f6c
JS
3816 ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp);
3817
3818 if (vport->port_state < LPFC_DISC_AUTH) {
3819 rjt_err = LSRJT_UNABLE_TPC;
dea3101e
JB
3820 break;
3821 }
2e0fef85
JS
3822 lpfc_disc_state_machine(vport, ndlp, elsiocb,
3823 NLP_EVT_RCV_PLOGI);
858c9f6c 3824
dea3101e
JB
3825 break;
3826 case ELS_CMD_FLOGI:
858c9f6c
JS
3827 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3828 "RCV FLOGI: did:x%x/ste:x%x flg:x%x",
3829 did, vport->port_state, ndlp->nlp_flag);
3830
dea3101e 3831 phba->fc_stat.elsRcvFLOGI++;
2e0fef85 3832 lpfc_els_rcv_flogi(vport, elsiocb, ndlp, newnode);
de0c5b32 3833 if (newnode)
2e0fef85 3834 lpfc_drop_node(vport, ndlp);
dea3101e
JB
3835 break;
3836 case ELS_CMD_LOGO:
858c9f6c
JS
3837 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3838 "RCV LOGO: did:x%x/ste:x%x flg:x%x",
3839 did, vport->port_state, ndlp->nlp_flag);
3840
dea3101e 3841 phba->fc_stat.elsRcvLOGO++;
2e0fef85 3842 if (vport->port_state < LPFC_DISC_AUTH) {
858c9f6c 3843 rjt_err = LSRJT_UNABLE_TPC;
dea3101e
JB
3844 break;
3845 }
2e0fef85 3846 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO);
dea3101e
JB
3847 break;
3848 case ELS_CMD_PRLO:
858c9f6c
JS
3849 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3850 "RCV PRLO: did:x%x/ste:x%x flg:x%x",
3851 did, vport->port_state, ndlp->nlp_flag);
3852
dea3101e 3853 phba->fc_stat.elsRcvPRLO++;
2e0fef85 3854 if (vport->port_state < LPFC_DISC_AUTH) {
858c9f6c 3855 rjt_err = LSRJT_UNABLE_TPC;
dea3101e
JB
3856 break;
3857 }
2e0fef85 3858 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO);
dea3101e
JB
3859 break;
3860 case ELS_CMD_RSCN:
3861 phba->fc_stat.elsRcvRSCN++;
2e0fef85 3862 lpfc_els_rcv_rscn(vport, elsiocb, ndlp, newnode);
de0c5b32 3863 if (newnode)
2e0fef85 3864 lpfc_drop_node(vport, ndlp);
dea3101e
JB
3865 break;
3866 case ELS_CMD_ADISC:
858c9f6c
JS
3867 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3868 "RCV ADISC: did:x%x/ste:x%x flg:x%x",
3869 did, vport->port_state, ndlp->nlp_flag);
3870
dea3101e 3871 phba->fc_stat.elsRcvADISC++;
2e0fef85 3872 if (vport->port_state < LPFC_DISC_AUTH) {
858c9f6c 3873 rjt_err = LSRJT_UNABLE_TPC;
dea3101e
JB
3874 break;
3875 }
2e0fef85
JS
3876 lpfc_disc_state_machine(vport, ndlp, elsiocb,
3877 NLP_EVT_RCV_ADISC);
dea3101e
JB
3878 break;
3879 case ELS_CMD_PDISC:
858c9f6c
JS
3880 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3881 "RCV PDISC: did:x%x/ste:x%x flg:x%x",
3882 did, vport->port_state, ndlp->nlp_flag);
3883
dea3101e 3884 phba->fc_stat.elsRcvPDISC++;
2e0fef85 3885 if (vport->port_state < LPFC_DISC_AUTH) {
858c9f6c 3886 rjt_err = LSRJT_UNABLE_TPC;
dea3101e
JB
3887 break;
3888 }
2e0fef85
JS
3889 lpfc_disc_state_machine(vport, ndlp, elsiocb,
3890 NLP_EVT_RCV_PDISC);
dea3101e
JB
3891 break;
3892 case ELS_CMD_FARPR:
858c9f6c
JS
3893 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3894 "RCV FARPR: did:x%x/ste:x%x flg:x%x",
3895 did, vport->port_state, ndlp->nlp_flag);
3896
dea3101e 3897 phba->fc_stat.elsRcvFARPR++;
2e0fef85 3898 lpfc_els_rcv_farpr(vport, elsiocb, ndlp);
dea3101e
JB
3899 break;
3900 case ELS_CMD_FARP:
858c9f6c
JS
3901 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3902 "RCV FARP: did:x%x/ste:x%x flg:x%x",
3903 did, vport->port_state, ndlp->nlp_flag);
3904
dea3101e 3905 phba->fc_stat.elsRcvFARP++;
2e0fef85 3906 lpfc_els_rcv_farp(vport, elsiocb, ndlp);
dea3101e
JB
3907 break;
3908 case ELS_CMD_FAN:
858c9f6c
JS
3909 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3910 "RCV FAN: did:x%x/ste:x%x flg:x%x",
3911 did, vport->port_state, ndlp->nlp_flag);
3912
dea3101e 3913 phba->fc_stat.elsRcvFAN++;
2e0fef85 3914 lpfc_els_rcv_fan(vport, elsiocb, ndlp);
dea3101e 3915 break;
dea3101e 3916 case ELS_CMD_PRLI:
858c9f6c
JS
3917 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3918 "RCV PRLI: did:x%x/ste:x%x flg:x%x",
3919 did, vport->port_state, ndlp->nlp_flag);
3920
dea3101e 3921 phba->fc_stat.elsRcvPRLI++;
2e0fef85 3922 if (vport->port_state < LPFC_DISC_AUTH) {
858c9f6c 3923 rjt_err = LSRJT_UNABLE_TPC;
dea3101e
JB
3924 break;
3925 }
2e0fef85 3926 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI);
dea3101e 3927 break;
7bb3b137 3928 case ELS_CMD_LIRR:
858c9f6c
JS
3929 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3930 "RCV LIRR: did:x%x/ste:x%x flg:x%x",
3931 did, vport->port_state, ndlp->nlp_flag);
3932
7bb3b137 3933 phba->fc_stat.elsRcvLIRR++;
2e0fef85 3934 lpfc_els_rcv_lirr(vport, elsiocb, ndlp);
de0c5b32 3935 if (newnode)
2e0fef85 3936 lpfc_drop_node(vport, ndlp);
7bb3b137
JW
3937 break;
3938 case ELS_CMD_RPS:
858c9f6c
JS
3939 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3940 "RCV RPS: did:x%x/ste:x%x flg:x%x",
3941 did, vport->port_state, ndlp->nlp_flag);
3942
7bb3b137 3943 phba->fc_stat.elsRcvRPS++;
2e0fef85 3944 lpfc_els_rcv_rps(vport, elsiocb, ndlp);
de0c5b32 3945 if (newnode)
2e0fef85 3946 lpfc_drop_node(vport, ndlp);
7bb3b137
JW
3947 break;
3948 case ELS_CMD_RPL:
858c9f6c
JS
3949 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3950 "RCV RPL: did:x%x/ste:x%x flg:x%x",
3951 did, vport->port_state, ndlp->nlp_flag);
3952
7bb3b137 3953 phba->fc_stat.elsRcvRPL++;
2e0fef85 3954 lpfc_els_rcv_rpl(vport, elsiocb, ndlp);
de0c5b32 3955 if (newnode)
2e0fef85 3956 lpfc_drop_node(vport, ndlp);
7bb3b137 3957 break;
dea3101e 3958 case ELS_CMD_RNID:
858c9f6c
JS
3959 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3960 "RCV RNID: did:x%x/ste:x%x flg:x%x",
3961 did, vport->port_state, ndlp->nlp_flag);
3962
dea3101e 3963 phba->fc_stat.elsRcvRNID++;
2e0fef85 3964 lpfc_els_rcv_rnid(vport, elsiocb, ndlp);
de0c5b32 3965 if (newnode)
2e0fef85 3966 lpfc_drop_node(vport, ndlp);
dea3101e
JB
3967 break;
3968 default:
858c9f6c
JS
3969 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3970 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x",
3971 cmd, did, vport->port_state);
3972
dea3101e 3973 /* Unsupported ELS command, reject */
858c9f6c 3974 rjt_err = LSRJT_INVALID_CMD;
dea3101e
JB
3975
3976 /* Unknown ELS command <elsCmd> received from NPORT <did> */
3977 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
92d7f7b0 3978 "%d (%d):0115 Unknown ELS command x%x "
ed957684 3979 "received from NPORT x%x\n",
92d7f7b0 3980 phba->brd_no, vport->vpi, cmd, did);
de0c5b32 3981 if (newnode)
2e0fef85 3982 lpfc_drop_node(vport, ndlp);
dea3101e
JB
3983 break;
3984 }
3985
3986 /* check if need to LS_RJT received ELS cmd */
3987 if (rjt_err) {
92d7f7b0 3988 memset(&stat, 0, sizeof(stat));
858c9f6c 3989 stat.un.b.lsRjtRsnCode = rjt_err;
1f679caf 3990 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
858c9f6c
JS
3991 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp,
3992 NULL);
92d7f7b0
JS
3993 if (newnode)
3994 lpfc_drop_node(vport, ndlp);
dea3101e
JB
3995 }
3996
ed957684
JS
3997 return;
3998
3999dropit:
4000 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
92d7f7b0 4001 "%d (%d):0111 Dropping received ELS cmd "
ed957684 4002 "Data: x%x x%x x%x\n",
92d7f7b0 4003 phba->brd_no, vport ? vport->vpi : 0xffff,
ed957684
JS
4004 icmd->ulpStatus, icmd->un.ulpWord[4],
4005 icmd->ulpTimeout);
4006 phba->fc_stat.elsRcvDrop++;
4007}
4008
92d7f7b0
JS
4009static struct lpfc_vport *
4010lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
4011{
4012 struct lpfc_vport *vport;
4013
4014 list_for_each_entry(vport, &phba->port_list, listentry) {
4015 if (vport->vpi == vpi)
4016 return vport;
4017 }
4018 return NULL;
4019}
ed957684
JS
4020
4021void
4022lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
4023 struct lpfc_iocbq *elsiocb)
4024{
4025 struct lpfc_vport *vport = phba->pport;
ed957684 4026 IOCB_t *icmd = &elsiocb->iocb;
ed957684 4027 dma_addr_t paddr;
92d7f7b0
JS
4028 struct lpfc_dmabuf *bdeBuf1 = elsiocb->context2;
4029 struct lpfc_dmabuf *bdeBuf2 = elsiocb->context3;
4030
4031 elsiocb->context2 = NULL;
4032 elsiocb->context3 = NULL;
ed957684 4033
92d7f7b0
JS
4034 if (icmd->ulpStatus == IOSTAT_NEED_BUFFER) {
4035 lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
4036 } else if (icmd->ulpStatus == IOSTAT_LOCAL_REJECT &&
4037 (icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING) {
ed957684
JS
4038 phba->fc_stat.NoRcvBuf++;
4039 /* Not enough posted buffers; Try posting more buffers */
92d7f7b0 4040 if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
ed957684
JS
4041 lpfc_post_buffer(phba, pring, 0, 1);
4042 return;
4043 }
4044
92d7f7b0
JS
4045 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
4046 (icmd->ulpCommand == CMD_IOCB_RCV_ELS64_CX ||
4047 icmd->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
4048 if (icmd->unsli3.rcvsli3.vpi == 0xffff)
4049 vport = phba->pport;
4050 else {
4051 uint16_t vpi = icmd->unsli3.rcvsli3.vpi;
4052 vport = lpfc_find_vport_by_vpid(phba, vpi);
4053 }
4054 }
4055 /* If there are no BDEs associated
4056 * with this IOCB, there is nothing to do.
4057 */
ed957684
JS
4058 if (icmd->ulpBdeCount == 0)
4059 return;
4060
92d7f7b0
JS
4061 /* type of ELS cmd is first 32bit word
4062 * in packet
4063 */
ed957684 4064 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
92d7f7b0 4065 elsiocb->context2 = bdeBuf1;
ed957684
JS
4066 } else {
4067 paddr = getPaddr(icmd->un.cont64[0].addrHigh,
4068 icmd->un.cont64[0].addrLow);
92d7f7b0
JS
4069 elsiocb->context2 = lpfc_sli_ringpostbuf_get(phba, pring,
4070 paddr);
ed957684
JS
4071 }
4072
92d7f7b0
JS
4073 lpfc_els_unsol_buffer(phba, pring, vport, elsiocb);
4074 /*
4075 * The different unsolicited event handlers would tell us
4076 * if they are done with "mp" by setting context2 to NULL.
4077 */
329f9bc7
JS
4078 lpfc_nlp_put(elsiocb->context1);
4079 elsiocb->context1 = NULL;
dea3101e 4080 if (elsiocb->context2) {
92d7f7b0
JS
4081 lpfc_in_buf_free(phba, (struct lpfc_dmabuf *)elsiocb->context2);
4082 elsiocb->context2 = NULL;
dea3101e 4083 }
ed957684
JS
4084
4085 /* RCV_ELS64_CX provide for 2 BDEs - process 2nd if included */
92d7f7b0 4086 if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) &&
ed957684 4087 icmd->ulpBdeCount == 2) {
92d7f7b0
JS
4088 elsiocb->context2 = bdeBuf2;
4089 lpfc_els_unsol_buffer(phba, pring, vport, elsiocb);
ed957684
JS
4090 /* free mp if we are done with it */
4091 if (elsiocb->context2) {
92d7f7b0
JS
4092 lpfc_in_buf_free(phba, elsiocb->context2);
4093 elsiocb->context2 = NULL;
4094 }
4095 }
4096}
4097
4098void
4099lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
4100{
4101 struct lpfc_nodelist *ndlp, *ndlp_fdmi;
4102
4103 ndlp = lpfc_findnode_did(vport, NameServer_DID);
4104 if (!ndlp) {
4105 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
4106 if (!ndlp) {
4107 if (phba->fc_topology == TOPOLOGY_LOOP) {
4108 lpfc_disc_start(vport);
4109 return;
4110 }
4111 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4112 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
4113 "%d (%d):0251 NameServer login: no memory\n",
4114 phba->brd_no, vport->vpi);
4115 return;
4116 }
4117 lpfc_nlp_init(vport, ndlp, NameServer_DID);
4118 ndlp->nlp_type |= NLP_FABRIC;
4119 }
4120
4121 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
4122
4123 if (lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0)) {
4124 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4125 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
4126 "%d (%d):0252 Cannot issue NameServer login\n",
4127 phba->brd_no, vport->vpi);
4128 return;
4129 }
4130
4131 if (phba->cfg_fdmi_on) {
4132 ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
4133 GFP_KERNEL);
4134 if (ndlp_fdmi) {
4135 lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
4136 ndlp_fdmi->nlp_type |= NLP_FABRIC;
4137 ndlp_fdmi->nlp_state =
4138 NLP_STE_PLOGI_ISSUE;
4139 lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID,
4140 0);
4141 }
4142 }
4143 return;
4144}
4145
4146static void
4147lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
4148{
4149 struct lpfc_vport *vport = pmb->vport;
4150 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
4151 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
4152 MAILBOX_t *mb = &pmb->mb;
4153
4154 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
4155 lpfc_nlp_put(ndlp);
4156
4157 if (mb->mbxStatus) {
4158 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
4159 "%d (%d):0915 Register VPI failed: 0x%x\n",
4160 phba->brd_no, vport->vpi, mb->mbxStatus);
4161
4162 switch (mb->mbxStatus) {
4163 case 0x11: /* unsupported feature */
4164 case 0x9603: /* max_vpi exceeded */
4165 /* giving up on vport registration */
4166 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4167 spin_lock_irq(shost->host_lock);
4168 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
4169 spin_unlock_irq(shost->host_lock);
4170 lpfc_can_disctmo(vport);
4171 break;
4172 default:
4173 /* Try to recover from this error */
4174 lpfc_mbx_unreg_vpi(vport);
4175 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
4176 lpfc_initial_fdisc(vport);
4177 break;
4178 }
4179
4180 } else {
4181 if (vport == phba->pport)
4182 lpfc_issue_fabric_reglogin(vport);
4183 else
4184 lpfc_do_scr_ns_plogi(phba, vport);
4185 }
4186 mempool_free(pmb, phba->mbox_mem_pool);
4187 return;
4188}
4189
4190void
4191lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
4192 struct lpfc_nodelist *ndlp)
4193{
4194 LPFC_MBOXQ_t *mbox;
4195
4196 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
4197 if (mbox) {
4198 lpfc_reg_vpi(phba, vport->vpi, vport->fc_myDID, mbox);
4199 mbox->vport = vport;
4200 mbox->context2 = lpfc_nlp_get(ndlp);
4201 mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport;
4202 if (lpfc_sli_issue_mbox(phba, mbox,
4203 MBX_NOWAIT | MBX_STOP_IOCB)
4204 == MBX_NOT_FINISHED) {
4205 mempool_free(mbox, phba->mbox_mem_pool);
4206 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
4207
4208 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4209
4210 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
4211 "%d (%d):0253 Register VPI: Cannot send mbox\n",
4212 phba->brd_no, vport->vpi);
4213 }
4214 } else {
4215 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4216
4217 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
4218 "%d (%d):0254 Register VPI: no memory\n",
4219 phba->brd_no, vport->vpi);
4220
4221 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
4222 lpfc_nlp_put(ndlp);
4223 }
4224}
4225
4226static void
4227lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
4228 struct lpfc_iocbq *rspiocb)
4229{
4230 struct lpfc_vport *vport = cmdiocb->vport;
4231 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
4232 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
4233 struct lpfc_nodelist *np;
4234 struct lpfc_nodelist *next_np;
4235 IOCB_t *irsp = &rspiocb->iocb;
4236 struct lpfc_iocbq *piocb;
4237
4238 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
4239 "%d (%d):0123 FDISC completes. x%x/x%x prevDID: x%x\n",
4240 phba->brd_no, vport->vpi,
4241 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID);
4242
4243 /* Since all FDISCs are being single threaded, we
4244 * must reset the discovery timer for ALL vports
4245 * waiting to send FDISC when one completes.
4246 */
4247 list_for_each_entry(piocb, &phba->fabric_iocb_list, list) {
4248 lpfc_set_disctmo(piocb->vport);
4249 }
4250
858c9f6c
JS
4251 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
4252 "FDISC cmpl: status:x%x/x%x prevdid:x%x",
4253 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID);
4254
92d7f7b0
JS
4255 if (irsp->ulpStatus) {
4256 /* Check for retry */
4257 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
4258 goto out;
4259
4260 /* FDISC failed */
4261 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
4262 "%d (%d):0124 FDISC failed. (%d/%d)\n",
4263 phba->brd_no, vport->vpi,
4264 irsp->ulpStatus, irsp->un.ulpWord[4]);
858c9f6c 4265
92d7f7b0
JS
4266 if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
4267 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4268
4269 lpfc_nlp_put(ndlp);
4270 /* giving up on FDISC. Cancel discovery timer */
4271 lpfc_can_disctmo(vport);
4272 } else {
4273 spin_lock_irq(shost->host_lock);
4274 vport->fc_flag |= FC_FABRIC;
4275 if (vport->phba->fc_topology == TOPOLOGY_LOOP)
4276 vport->fc_flag |= FC_PUBLIC_LOOP;
4277 spin_unlock_irq(shost->host_lock);
4278
4279 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
4280 lpfc_vport_set_state(vport, FC_VPORT_ACTIVE);
4281 if ((vport->fc_prevDID != vport->fc_myDID) &&
4282 !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
4283 /* If our NportID changed, we need to ensure all
4284 * remaining NPORTs get unreg_login'ed so we can
4285 * issue unreg_vpi.
4286 */
4287 list_for_each_entry_safe(np, next_np,
4288 &vport->fc_nodes, nlp_listp) {
4289 if (np->nlp_state != NLP_STE_NPR_NODE
4290 || !(np->nlp_flag & NLP_NPR_ADISC))
4291 continue;
4292 spin_lock_irq(shost->host_lock);
4293 np->nlp_flag &= ~NLP_NPR_ADISC;
4294 spin_unlock_irq(shost->host_lock);
4295 lpfc_unreg_rpi(vport, np);
4296 }
4297 lpfc_mbx_unreg_vpi(vport);
4298 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
4299 }
4300
4301 if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
4302 lpfc_register_new_vport(phba, vport, ndlp);
4303 else
4304 lpfc_do_scr_ns_plogi(phba, vport);
4305
4306 lpfc_nlp_put(ndlp); /* Free Fabric ndlp for vports */
4307 }
4308
4309out:
4310 lpfc_els_free_iocb(phba, cmdiocb);
4311}
4312
4313int
4314lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
4315 uint8_t retry)
4316{
4317 struct lpfc_hba *phba = vport->phba;
4318 IOCB_t *icmd;
4319 struct lpfc_iocbq *elsiocb;
4320 struct serv_parm *sp;
4321 uint8_t *pcmd;
4322 uint16_t cmdsize;
4323 int did = ndlp->nlp_DID;
4324 int rc;
92d7f7b0
JS
4325
4326 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
4327 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
4328 ELS_CMD_FDISC);
4329 if (!elsiocb) {
92d7f7b0
JS
4330 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4331
4332 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
4333 "%d (%d):0255 Issue FDISC: no IOCB\n",
4334 phba->brd_no, vport->vpi);
4335 return 1;
4336 }
4337
4338 icmd = &elsiocb->iocb;
4339 icmd->un.elsreq64.myID = 0;
4340 icmd->un.elsreq64.fl = 1;
4341
4342 /* For FDISC, Let FDISC rsp set the NPortID for this VPI */
4343 icmd->ulpCt_h = 1;
4344 icmd->ulpCt_l = 0;
4345
4346 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4347 *((uint32_t *) (pcmd)) = ELS_CMD_FDISC;
4348 pcmd += sizeof(uint32_t); /* CSP Word 1 */
4349 memcpy(pcmd, &vport->phba->pport->fc_sparam, sizeof(struct serv_parm));
4350 sp = (struct serv_parm *) pcmd;
4351 /* Setup CSPs accordingly for Fabric */
4352 sp->cmn.e_d_tov = 0;
4353 sp->cmn.w2.r_a_tov = 0;
4354 sp->cls1.classValid = 0;
4355 sp->cls2.seqDelivery = 1;
4356 sp->cls3.seqDelivery = 1;
4357
4358 pcmd += sizeof(uint32_t); /* CSP Word 2 */
4359 pcmd += sizeof(uint32_t); /* CSP Word 3 */
4360 pcmd += sizeof(uint32_t); /* CSP Word 4 */
4361 pcmd += sizeof(uint32_t); /* Port Name */
4362 memcpy(pcmd, &vport->fc_portname, 8);
4363 pcmd += sizeof(uint32_t); /* Node Name */
4364 pcmd += sizeof(uint32_t); /* Node Name */
4365 memcpy(pcmd, &vport->fc_nodename, 8);
4366
4367 lpfc_set_disctmo(vport);
4368
4369 phba->fc_stat.elsXmitFDISC++;
4370 elsiocb->iocb_cmpl = lpfc_cmpl_els_fdisc;
4371
858c9f6c
JS
4372 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
4373 "Issue FDISC: did:x%x",
4374 did, 0, 0);
4375
92d7f7b0
JS
4376 rc = lpfc_issue_fabric_iocb(phba, elsiocb);
4377 if (rc == IOCB_ERROR) {
4378 lpfc_els_free_iocb(phba, elsiocb);
92d7f7b0
JS
4379 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4380
4381 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
4382 "%d (%d):0256 Issue FDISC: Cannot send IOCB\n",
4383 phba->brd_no, vport->vpi);
4384
4385 return 1;
4386 }
4387 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
4388 vport->port_state = LPFC_FDISC;
4389 return 0;
4390}
4391
4392static void
4393lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
4394 struct lpfc_iocbq *rspiocb)
4395{
4396 struct lpfc_vport *vport = cmdiocb->vport;
858c9f6c
JS
4397 IOCB_t *irsp;
4398
4399 irsp = &rspiocb->iocb;
4400 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
4401 "LOGO npiv cmpl: status:x%x/x%x did:x%x",
4402 irsp->ulpStatus, irsp->un.ulpWord[4], irsp->un.rcvels.remoteID);
92d7f7b0
JS
4403
4404 lpfc_els_free_iocb(phba, cmdiocb);
4405 vport->unreg_vpi_cmpl = VPORT_ERROR;
4406}
4407
4408int
4409lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
4410{
4411 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
4412 struct lpfc_hba *phba = vport->phba;
4413 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
4414 IOCB_t *icmd;
4415 struct lpfc_iocbq *elsiocb;
4416 uint8_t *pcmd;
4417 uint16_t cmdsize;
4418
4419 cmdsize = 2 * sizeof(uint32_t) + sizeof(struct lpfc_name);
4420 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, 0, ndlp, ndlp->nlp_DID,
4421 ELS_CMD_LOGO);
4422 if (!elsiocb)
4423 return 1;
4424
4425 icmd = &elsiocb->iocb;
4426 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4427 *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
4428 pcmd += sizeof(uint32_t);
4429
4430 /* Fill in LOGO payload */
4431 *((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID);
4432 pcmd += sizeof(uint32_t);
4433 memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name));
4434
858c9f6c
JS
4435 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
4436 "Issue LOGO npiv did:x%x flg:x%x",
4437 ndlp->nlp_DID, ndlp->nlp_flag, 0);
4438
92d7f7b0
JS
4439 elsiocb->iocb_cmpl = lpfc_cmpl_els_npiv_logo;
4440 spin_lock_irq(shost->host_lock);
4441 ndlp->nlp_flag |= NLP_LOGO_SND;
4442 spin_unlock_irq(shost->host_lock);
4443 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
4444 spin_lock_irq(shost->host_lock);
4445 ndlp->nlp_flag &= ~NLP_LOGO_SND;
4446 spin_unlock_irq(shost->host_lock);
4447 lpfc_els_free_iocb(phba, elsiocb);
4448 return 1;
4449 }
4450 return 0;
4451}
4452
4453void
4454lpfc_fabric_block_timeout(unsigned long ptr)
4455{
4456 struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
4457 unsigned long iflags;
4458 uint32_t tmo_posted;
4459 spin_lock_irqsave(&phba->pport->work_port_lock, iflags);
4460 tmo_posted = phba->pport->work_port_events & WORKER_FABRIC_BLOCK_TMO;
4461 if (!tmo_posted)
4462 phba->pport->work_port_events |= WORKER_FABRIC_BLOCK_TMO;
4463 spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags);
4464
4465 if (!tmo_posted) {
4466 spin_lock_irqsave(&phba->hbalock, iflags);
4467 if (phba->work_wait)
4468 lpfc_worker_wake_up(phba);
4469 spin_unlock_irqrestore(&phba->hbalock, iflags);
4470 }
4471}
4472
4473static void
4474lpfc_resume_fabric_iocbs(struct lpfc_hba *phba)
4475{
4476 struct lpfc_iocbq *iocb;
4477 unsigned long iflags;
4478 int ret;
4479 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
4480 IOCB_t *cmd;
4481
4482repeat:
4483 iocb = NULL;
4484 spin_lock_irqsave(&phba->hbalock, iflags);
4485 /* Post any pending iocb to the SLI layer */
4486 if (atomic_read(&phba->fabric_iocb_count) == 0) {
4487 list_remove_head(&phba->fabric_iocb_list, iocb, typeof(*iocb),
4488 list);
4489 if (iocb)
4490 atomic_inc(&phba->fabric_iocb_count);
4491 }
4492 spin_unlock_irqrestore(&phba->hbalock, iflags);
4493 if (iocb) {
4494 iocb->fabric_iocb_cmpl = iocb->iocb_cmpl;
4495 iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb;
4496 iocb->iocb_flag |= LPFC_IO_FABRIC;
4497
858c9f6c
JS
4498 lpfc_debugfs_disc_trc(iocb->vport, LPFC_DISC_TRC_ELS_CMD,
4499 "Fabric sched1: ste:x%x",
4500 iocb->vport->port_state, 0, 0);
4501
92d7f7b0
JS
4502 ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0);
4503
4504 if (ret == IOCB_ERROR) {
4505 iocb->iocb_cmpl = iocb->fabric_iocb_cmpl;
4506 iocb->fabric_iocb_cmpl = NULL;
4507 iocb->iocb_flag &= ~LPFC_IO_FABRIC;
4508 cmd = &iocb->iocb;
4509 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
4510 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
4511 iocb->iocb_cmpl(phba, iocb, iocb);
4512
4513 atomic_dec(&phba->fabric_iocb_count);
4514 goto repeat;
4515 }
4516 }
4517
4518 return;
4519}
4520
4521void
4522lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba)
4523{
4524 clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
4525
4526 lpfc_resume_fabric_iocbs(phba);
4527 return;
4528}
4529
4530static void
4531lpfc_block_fabric_iocbs(struct lpfc_hba *phba)
4532{
4533 int blocked;
4534
4535 blocked = test_and_set_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
4536 /* Start a timer to unblock fabric
4537 * iocbs after 100ms
4538 */
4539 if (!blocked)
4540 mod_timer(&phba->fabric_block_timer, jiffies + HZ/10 );
4541
4542 return;
4543}
4544
4545static void
4546lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
4547 struct lpfc_iocbq *rspiocb)
4548{
4549 struct ls_rjt stat;
4550
4551 if ((cmdiocb->iocb_flag & LPFC_IO_FABRIC) != LPFC_IO_FABRIC)
4552 BUG();
4553
4554 switch (rspiocb->iocb.ulpStatus) {
4555 case IOSTAT_NPORT_RJT:
4556 case IOSTAT_FABRIC_RJT:
4557 if (rspiocb->iocb.un.ulpWord[4] & RJT_UNAVAIL_TEMP) {
4558 lpfc_block_fabric_iocbs(phba);
ed957684 4559 }
92d7f7b0
JS
4560 break;
4561
4562 case IOSTAT_NPORT_BSY:
4563 case IOSTAT_FABRIC_BSY:
4564 lpfc_block_fabric_iocbs(phba);
4565 break;
4566
4567 case IOSTAT_LS_RJT:
4568 stat.un.lsRjtError =
4569 be32_to_cpu(rspiocb->iocb.un.ulpWord[4]);
4570 if ((stat.un.b.lsRjtRsnCode == LSRJT_UNABLE_TPC) ||
4571 (stat.un.b.lsRjtRsnCode == LSRJT_LOGICAL_BSY))
4572 lpfc_block_fabric_iocbs(phba);
4573 break;
4574 }
4575
4576 if (atomic_read(&phba->fabric_iocb_count) == 0)
4577 BUG();
4578
4579 cmdiocb->iocb_cmpl = cmdiocb->fabric_iocb_cmpl;
4580 cmdiocb->fabric_iocb_cmpl = NULL;
4581 cmdiocb->iocb_flag &= ~LPFC_IO_FABRIC;
4582 cmdiocb->iocb_cmpl(phba, cmdiocb, rspiocb);
4583
4584 atomic_dec(&phba->fabric_iocb_count);
4585 if (!test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags)) {
4586 /* Post any pending iocbs to HBA */
4587 lpfc_resume_fabric_iocbs(phba);
4588 }
4589}
4590
4591int
4592lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb)
4593{
4594 unsigned long iflags;
4595 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
4596 int ready;
4597 int ret;
4598
4599 if (atomic_read(&phba->fabric_iocb_count) > 1)
4600 BUG();
4601
4602 spin_lock_irqsave(&phba->hbalock, iflags);
4603 ready = atomic_read(&phba->fabric_iocb_count) == 0 &&
4604 !test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
4605
4606 spin_unlock_irqrestore(&phba->hbalock, iflags);
4607 if (ready) {
4608 iocb->fabric_iocb_cmpl = iocb->iocb_cmpl;
4609 iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb;
4610 iocb->iocb_flag |= LPFC_IO_FABRIC;
4611
858c9f6c
JS
4612 lpfc_debugfs_disc_trc(iocb->vport, LPFC_DISC_TRC_ELS_CMD,
4613 "Fabric sched2: ste:x%x",
4614 iocb->vport->port_state, 0, 0);
4615
92d7f7b0
JS
4616 atomic_inc(&phba->fabric_iocb_count);
4617 ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0);
4618
4619 if (ret == IOCB_ERROR) {
4620 iocb->iocb_cmpl = iocb->fabric_iocb_cmpl;
4621 iocb->fabric_iocb_cmpl = NULL;
4622 iocb->iocb_flag &= ~LPFC_IO_FABRIC;
4623 atomic_dec(&phba->fabric_iocb_count);
4624 }
4625 } else {
4626 spin_lock_irqsave(&phba->hbalock, iflags);
4627 list_add_tail(&iocb->list, &phba->fabric_iocb_list);
4628 spin_unlock_irqrestore(&phba->hbalock, iflags);
4629 ret = IOCB_SUCCESS;
4630 }
4631 return ret;
4632}
4633
4634
4635void lpfc_fabric_abort_vport(struct lpfc_vport *vport)
4636{
4637 LIST_HEAD(completions);
4638 struct lpfc_hba *phba = vport->phba;
4639 struct lpfc_iocbq *tmp_iocb, *piocb;
4640 IOCB_t *cmd;
4641
4642 spin_lock_irq(&phba->hbalock);
4643 list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
4644 list) {
4645
4646 if (piocb->vport != vport)
4647 continue;
4648
4649 list_move_tail(&piocb->list, &completions);
4650 }
4651 spin_unlock_irq(&phba->hbalock);
4652
4653 while (!list_empty(&completions)) {
4654 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
4655 list_del_init(&piocb->list);
4656
4657 cmd = &piocb->iocb;
4658 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
4659 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
4660 (piocb->iocb_cmpl) (phba, piocb, piocb);
4661 }
4662}
4663
4664void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp)
4665{
4666 LIST_HEAD(completions);
4667 struct lpfc_hba *phba = ndlp->vport->phba;
4668 struct lpfc_iocbq *tmp_iocb, *piocb;
4669 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
4670 IOCB_t *cmd;
4671
4672 spin_lock_irq(&phba->hbalock);
4673 list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
4674 list) {
4675 if ((lpfc_check_sli_ndlp(phba, pring, piocb, ndlp))) {
4676
4677 list_move_tail(&piocb->list, &completions);
ed957684 4678 }
dea3101e 4679 }
92d7f7b0
JS
4680 spin_unlock_irq(&phba->hbalock);
4681
4682 while (!list_empty(&completions)) {
4683 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
4684 list_del_init(&piocb->list);
4685
4686 cmd = &piocb->iocb;
4687 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
4688 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
4689 (piocb->iocb_cmpl) (phba, piocb, piocb);
4690 }
4691}
4692
4693void lpfc_fabric_abort_hba(struct lpfc_hba *phba)
4694{
4695 LIST_HEAD(completions);
4696 struct lpfc_iocbq *piocb;
4697 IOCB_t *cmd;
4698
4699 spin_lock_irq(&phba->hbalock);
4700 list_splice_init(&phba->fabric_iocb_list, &completions);
4701 spin_unlock_irq(&phba->hbalock);
4702
4703 while (!list_empty(&completions)) {
4704 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
4705 list_del_init(&piocb->list);
4706
4707 cmd = &piocb->iocb;
4708 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
4709 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
4710 (piocb->iocb_cmpl) (phba, piocb, piocb);
4711 }
dea3101e 4712}
92d7f7b0
JS
4713
4714
4715void lpfc_fabric_abort_flogi(struct lpfc_hba *phba)
4716{
4717 LIST_HEAD(completions);
4718 struct lpfc_iocbq *tmp_iocb, *piocb;
4719 IOCB_t *cmd;
4720 struct lpfc_nodelist *ndlp;
4721
4722 spin_lock_irq(&phba->hbalock);
4723 list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
4724 list) {
4725
4726 cmd = &piocb->iocb;
4727 ndlp = (struct lpfc_nodelist *) piocb->context1;
4728 if (cmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
4729 ndlp != NULL &&
4730 ndlp->nlp_DID == Fabric_DID)
4731 list_move_tail(&piocb->list, &completions);
4732 }
4733 spin_unlock_irq(&phba->hbalock);
4734
4735 while (!list_empty(&completions)) {
4736 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
4737 list_del_init(&piocb->list);
4738
4739 cmd = &piocb->iocb;
4740 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
4741 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
4742 (piocb->iocb_cmpl) (phba, piocb, piocb);
4743 }
4744}
4745
4746