[SCSI] lpfc: NPIV: add SLI-3 interface
[deliverable/linux.git] / drivers / scsi / lpfc / lpfc_els.c
CommitLineData
dea3101e 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 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 20 *******************************************************************/
21
dea3101e 22#include <linux/blkdev.h>
23#include <linux/pci.h>
24#include <linux/interrupt.h>
25
91886523 26#include <scsi/scsi.h>
dea3101e 27#include <scsi/scsi_device.h>
28#include <scsi/scsi_host.h>
29#include <scsi/scsi_transport_fc.h>
30
31#include "lpfc_hw.h"
32#include "lpfc_sli.h"
33#include "lpfc_disc.h"
34#include "lpfc_scsi.h"
35#include "lpfc.h"
36#include "lpfc_logmsg.h"
37#include "lpfc_crtn.h"
38
39static int lpfc_els_retry(struct lpfc_hba *, struct lpfc_iocbq *,
40 struct lpfc_iocbq *);
41static int lpfc_max_els_tries = 3;
42
43static int
2e0fef85 44lpfc_els_chk_latt(struct lpfc_vport *vport)
dea3101e 45{
2e0fef85
JS
46 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
47 struct lpfc_hba *phba = vport->phba;
dea3101e 48 uint32_t ha_copy;
dea3101e 49
2e0fef85
JS
50 if (vport->port_state >= LPFC_VPORT_READY ||
51 phba->link_state == LPFC_LINK_DOWN)
dea3101e 52 return 0;
53
54 /* Read the HBA Host Attention Register */
dea3101e 55 ha_copy = readl(phba->HAregaddr);
dea3101e 56
57 if (!(ha_copy & HA_LATT))
58 return 0;
59
60 /* Pending Link Event during Discovery */
61 lpfc_printf_log(phba, KERN_WARNING, LOG_DISCOVERY,
62 "%d:0237 Pending Link Event during "
63 "Discovery: State x%x\n",
2e0fef85 64 phba->brd_no, phba->pport->port_state);
dea3101e 65
66 /* CLEAR_LA should re-enable link attention events and
67 * we should then imediately take a LATT event. The
68 * LATT processing should call lpfc_linkdown() which
69 * will cleanup any left over in-progress discovery
70 * events.
71 */
2e0fef85
JS
72 spin_lock_irq(shost->host_lock);
73 vport->fc_flag |= FC_ABORT_DISCOVERY;
74 spin_unlock_irq(shost->host_lock);
dea3101e 75
2e0fef85 76 if (phba->link_state != LPFC_CLEAR_LA) {
ed957684 77 lpfc_issue_clear_la(phba, vport);
dea3101e 78 }
79
c9f8735b 80 return 1;
dea3101e 81
82}
83
84static struct lpfc_iocbq *
2e0fef85
JS
85lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
86 uint16_t cmdSize, uint8_t retry,
87 struct lpfc_nodelist *ndlp, uint32_t did,
88 uint32_t elscmd)
dea3101e 89{
2e0fef85 90 struct lpfc_hba *phba = vport->phba;
0bd4ca25 91 struct lpfc_iocbq *elsiocb;
dea3101e 92 struct lpfc_dmabuf *pcmd, *prsp, *pbuflist;
93 struct ulp_bde64 *bpl;
94 IOCB_t *icmd;
95
dea3101e 96
2e0fef85
JS
97 if (!lpfc_is_link_up(phba))
98 return NULL;
dea3101e 99
dea3101e 100 /* Allocate buffer for command iocb */
0bd4ca25 101 elsiocb = lpfc_sli_get_iocbq(phba);
dea3101e 102
103 if (elsiocb == NULL)
104 return NULL;
dea3101e 105 icmd = &elsiocb->iocb;
106
107 /* fill in BDEs for command */
108 /* Allocate buffer for command payload */
109 if (((pcmd = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
110 ((pcmd->virt = lpfc_mbuf_alloc(phba,
111 MEM_PRI, &(pcmd->phys))) == 0)) {
c9475cb0 112 kfree(pcmd);
dea3101e 113
604a3e30 114 lpfc_sli_release_iocbq(phba, elsiocb);
dea3101e 115 return NULL;
116 }
117
118 INIT_LIST_HEAD(&pcmd->list);
119
120 /* Allocate buffer for response payload */
121 if (expectRsp) {
122 prsp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
123 if (prsp)
124 prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
125 &prsp->phys);
126 if (prsp == 0 || prsp->virt == 0) {
c9475cb0 127 kfree(prsp);
dea3101e 128 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
129 kfree(pcmd);
604a3e30 130 lpfc_sli_release_iocbq(phba, elsiocb);
dea3101e 131 return NULL;
132 }
133 INIT_LIST_HEAD(&prsp->list);
134 } else {
135 prsp = NULL;
136 }
137
138 /* Allocate buffer for Buffer ptr list */
139 pbuflist = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
140 if (pbuflist)
ed957684
JS
141 pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
142 &pbuflist->phys);
dea3101e 143 if (pbuflist == 0 || pbuflist->virt == 0) {
604a3e30 144 lpfc_sli_release_iocbq(phba, elsiocb);
dea3101e 145 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
146 lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
147 kfree(pcmd);
148 kfree(prsp);
c9475cb0 149 kfree(pbuflist);
dea3101e 150 return NULL;
151 }
152
153 INIT_LIST_HEAD(&pbuflist->list);
154
155 icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
156 icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
157 icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL;
2e0fef85 158 icmd->un.elsreq64.remoteID = did; /* DID */
dea3101e 159 if (expectRsp) {
160 icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64));
dea3101e 161 icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
2680eeaa 162 icmd->ulpTimeout = phba->fc_ratov * 2;
dea3101e 163 } else {
164 icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64);
165 icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX;
166 }
167
168 icmd->ulpBdeCount = 1;
169 icmd->ulpLe = 1;
170 icmd->ulpClass = CLASS3;
171
172 bpl = (struct ulp_bde64 *) pbuflist->virt;
173 bpl->addrLow = le32_to_cpu(putPaddrLow(pcmd->phys));
174 bpl->addrHigh = le32_to_cpu(putPaddrHigh(pcmd->phys));
175 bpl->tus.f.bdeSize = cmdSize;
176 bpl->tus.f.bdeFlags = 0;
177 bpl->tus.w = le32_to_cpu(bpl->tus.w);
178
179 if (expectRsp) {
180 bpl++;
181 bpl->addrLow = le32_to_cpu(putPaddrLow(prsp->phys));
182 bpl->addrHigh = le32_to_cpu(putPaddrHigh(prsp->phys));
183 bpl->tus.f.bdeSize = FCELSSIZE;
184 bpl->tus.f.bdeFlags = BUFF_USE_RCV;
185 bpl->tus.w = le32_to_cpu(bpl->tus.w);
186 }
187
188 /* Save for completion so we can release these resources */
329f9bc7
JS
189 elsiocb->context1 = lpfc_nlp_get(ndlp);
190 elsiocb->context2 = pcmd;
191 elsiocb->context3 = pbuflist;
dea3101e 192 elsiocb->retry = retry;
2e0fef85 193 elsiocb->vport = vport;
dea3101e 194 elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT;
195
196 if (prsp) {
197 list_add(&prsp->list, &pcmd->list);
198 }
199
200 if (expectRsp) {
201 /* Xmit ELS command <elsCmd> to remote NPORT <did> */
202 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
203 "%d:0116 Xmit ELS command x%x to remote "
2e0fef85
JS
204 "NPORT x%x I/O tag: x%x, port state: x%x\n",
205 phba->brd_no, elscmd, did,
206 elsiocb->iotag, vport->port_state);
dea3101e 207 } else {
208 /* Xmit ELS response <elsCmd> to remote NPORT <did> */
209 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
210 "%d:0117 Xmit ELS response x%x to remote "
1dcb58e5 211 "NPORT x%x I/O tag: x%x, size: x%x\n",
dea3101e 212 phba->brd_no, elscmd,
1dcb58e5 213 ndlp->nlp_DID, elsiocb->iotag, cmdSize);
dea3101e 214 }
215
c9f8735b 216 return elsiocb;
dea3101e 217}
218
219
220static int
2e0fef85
JS
221lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
222 struct serv_parm *sp, IOCB_t *irsp)
dea3101e 223{
2e0fef85
JS
224 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
225 struct lpfc_hba *phba = vport->phba;
dea3101e 226 LPFC_MBOXQ_t *mbox;
14691150 227 struct lpfc_dmabuf *mp;
dea3101e 228 int rc;
229
2e0fef85
JS
230 spin_lock_irq(shost->host_lock);
231 vport->fc_flag |= FC_FABRIC;
232 spin_unlock_irq(shost->host_lock);
dea3101e 233
234 phba->fc_edtov = be32_to_cpu(sp->cmn.e_d_tov);
235 if (sp->cmn.edtovResolution) /* E_D_TOV ticks are in nanoseconds */
236 phba->fc_edtov = (phba->fc_edtov + 999999) / 1000000;
237
238 phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
239
240 if (phba->fc_topology == TOPOLOGY_LOOP) {
2e0fef85
JS
241 spin_lock_irq(shost->host_lock);
242 vport->fc_flag |= FC_PUBLIC_LOOP;
243 spin_unlock_irq(shost->host_lock);
dea3101e 244 } else {
245 /*
246 * If we are a N-port connected to a Fabric, fixup sparam's so
247 * logins to devices on remote loops work.
248 */
2e0fef85 249 vport->fc_sparam.cmn.altBbCredit = 1;
dea3101e 250 }
251
2e0fef85 252 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
dea3101e 253 memcpy(&ndlp->nlp_portname, &sp->portName, sizeof(struct lpfc_name));
254 memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));
255 ndlp->nlp_class_sup = 0;
256 if (sp->cls1.classValid)
257 ndlp->nlp_class_sup |= FC_COS_CLASS1;
258 if (sp->cls2.classValid)
259 ndlp->nlp_class_sup |= FC_COS_CLASS2;
260 if (sp->cls3.classValid)
261 ndlp->nlp_class_sup |= FC_COS_CLASS3;
262 if (sp->cls4.classValid)
263 ndlp->nlp_class_sup |= FC_COS_CLASS4;
264 ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
265 sp->cmn.bbRcvSizeLsb;
266 memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
267
2e0fef85
JS
268 ndlp->nlp_sid = irsp->un.ulpWord[4] & Mask_DID;
269
dea3101e 270 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
271 if (!mbox)
272 goto fail;
273
2e0fef85 274 vport->port_state = LPFC_FABRIC_CFG_LINK;
dea3101e 275 lpfc_config_link(phba, mbox);
276 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
ed957684 277 mbox->vport = vport;
dea3101e 278
279 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB);
280 if (rc == MBX_NOT_FINISHED)
281 goto fail_free_mbox;
282
283 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
284 if (!mbox)
285 goto fail;
2e0fef85
JS
286 rc = lpfc_reg_login(phba, Fabric_DID, (uint8_t *) sp, mbox, 0);
287 if (rc)
dea3101e 288 goto fail_free_mbox;
289
dea3101e 290 mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login;
2e0fef85 291 mbox->vport = vport;
329f9bc7 292 mbox->context2 = lpfc_nlp_get(ndlp);
dea3101e 293
294 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB);
295 if (rc == MBX_NOT_FINISHED)
14691150 296 goto fail_issue_reg_login;
dea3101e 297
298 return 0;
299
14691150 300 fail_issue_reg_login:
329f9bc7 301 lpfc_nlp_put(ndlp);
14691150
JS
302 mp = (struct lpfc_dmabuf *) mbox->context1;
303 lpfc_mbuf_free(phba, mp->virt, mp->phys);
304 kfree(mp);
dea3101e 305 fail_free_mbox:
306 mempool_free(mbox, phba->mbox_mem_pool);
307 fail:
308 return -ENXIO;
309}
310
311/*
312 * We FLOGIed into an NPort, initiate pt2pt protocol
313 */
314static int
2e0fef85
JS
315lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
316 struct serv_parm *sp)
dea3101e 317{
2e0fef85
JS
318 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
319 struct lpfc_hba *phba = vport->phba;
dea3101e 320 LPFC_MBOXQ_t *mbox;
321 int rc;
322
2e0fef85
JS
323 spin_lock_irq(shost->host_lock);
324 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
325 spin_unlock_irq(shost->host_lock);
dea3101e 326
327 phba->fc_edtov = FF_DEF_EDTOV;
328 phba->fc_ratov = FF_DEF_RATOV;
2e0fef85 329 rc = memcmp(&vport->fc_portname, &sp->portName,
dea3101e 330 sizeof(struct lpfc_name));
331 if (rc >= 0) {
332 /* This side will initiate the PLOGI */
2e0fef85
JS
333 spin_lock_irq(shost->host_lock);
334 vport->fc_flag |= FC_PT2PT_PLOGI;
335 spin_unlock_irq(shost->host_lock);
dea3101e 336
337 /*
338 * N_Port ID cannot be 0, set our to LocalID the other
339 * side will be RemoteID.
340 */
341
342 /* not equal */
343 if (rc)
2e0fef85 344 vport->fc_myDID = PT2PT_LocalID;
dea3101e 345
346 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
347 if (!mbox)
348 goto fail;
349
350 lpfc_config_link(phba, mbox);
351
352 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
ed957684 353 mbox->vport = vport;
dea3101e 354 rc = lpfc_sli_issue_mbox(phba, mbox,
355 MBX_NOWAIT | MBX_STOP_IOCB);
356 if (rc == MBX_NOT_FINISHED) {
357 mempool_free(mbox, phba->mbox_mem_pool);
358 goto fail;
359 }
329f9bc7 360 lpfc_nlp_put(ndlp);
dea3101e 361
2e0fef85 362 ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID);
dea3101e 363 if (!ndlp) {
364 /*
365 * Cannot find existing Fabric ndlp, so allocate a
366 * new one
367 */
368 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
369 if (!ndlp)
370 goto fail;
371
2e0fef85 372 lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID);
dea3101e 373 }
374
375 memcpy(&ndlp->nlp_portname, &sp->portName,
2e0fef85 376 sizeof(struct lpfc_name));
dea3101e 377 memcpy(&ndlp->nlp_nodename, &sp->nodeName,
2e0fef85
JS
378 sizeof(struct lpfc_name));
379 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
380 spin_lock_irq(shost->host_lock);
dea3101e 381 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2e0fef85 382 spin_unlock_irq(shost->host_lock);
dea3101e 383 } else {
384 /* This side will wait for the PLOGI */
329f9bc7 385 lpfc_nlp_put(ndlp);
dea3101e 386 }
387
2e0fef85
JS
388 spin_lock_irq(shost->host_lock);
389 vport->fc_flag |= FC_PT2PT;
390 spin_unlock_irq(shost->host_lock);
dea3101e 391
392 /* Start discovery - this should just do CLEAR_LA */
2e0fef85 393 lpfc_disc_start(vport);
dea3101e 394 return 0;
395 fail:
396 return -ENXIO;
397}
398
399static void
329f9bc7
JS
400lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
401 struct lpfc_iocbq *rspiocb)
dea3101e 402{
2e0fef85
JS
403 struct lpfc_vport *vport = cmdiocb->vport;
404 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 405 IOCB_t *irsp = &rspiocb->iocb;
406 struct lpfc_nodelist *ndlp = cmdiocb->context1;
407 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
408 struct serv_parm *sp;
409 int rc;
410
411 /* Check to see if link went down during discovery */
2e0fef85 412 if (lpfc_els_chk_latt(vport)) {
329f9bc7 413 lpfc_nlp_put(ndlp);
dea3101e 414 goto out;
415 }
416
417 if (irsp->ulpStatus) {
418 /* Check for retry */
2e0fef85 419 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
dea3101e 420 goto out;
2e0fef85 421
dea3101e 422 /* FLOGI failed, so there is no fabric */
2e0fef85
JS
423 spin_lock_irq(shost->host_lock);
424 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
425 spin_unlock_irq(shost->host_lock);
dea3101e 426
329f9bc7 427 /* If private loop, then allow max outstanding els to be
dea3101e 428 * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no
429 * alpa map would take too long otherwise.
430 */
431 if (phba->alpa_map[0] == 0) {
329f9bc7 432 phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
dea3101e 433 }
434
435 /* FLOGI failure */
436 lpfc_printf_log(phba,
437 KERN_INFO,
438 LOG_ELS,
c9f8735b 439 "%d:0100 FLOGI failure Data: x%x x%x x%x\n",
dea3101e 440 phba->brd_no,
c9f8735b
JW
441 irsp->ulpStatus, irsp->un.ulpWord[4],
442 irsp->ulpTimeout);
dea3101e 443 goto flogifail;
444 }
445
446 /*
447 * The FLogI succeeded. Sync the data for the CPU before
448 * accessing it.
449 */
450 prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
451
452 sp = prsp->virt + sizeof(uint32_t);
453
454 /* FLOGI completes successfully */
455 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
456 "%d:0101 FLOGI completes sucessfully "
457 "Data: x%x x%x x%x x%x\n",
458 phba->brd_no,
459 irsp->un.ulpWord[4], sp->cmn.e_d_tov,
460 sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution);
461
2e0fef85 462 if (vport->port_state == LPFC_FLOGI) {
dea3101e 463 /*
464 * If Common Service Parameters indicate Nport
465 * we are point to point, if Fport we are Fabric.
466 */
467 if (sp->cmn.fPort)
2e0fef85 468 rc = lpfc_cmpl_els_flogi_fabric(vport, ndlp, sp, irsp);
dea3101e 469 else
2e0fef85 470 rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
dea3101e 471
472 if (!rc)
473 goto out;
474 }
475
476flogifail:
329f9bc7 477 lpfc_nlp_put(ndlp);
dea3101e 478
479 if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
480 (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED &&
481 irsp->un.ulpWord[4] != IOERR_SLI_DOWN)) {
482 /* FLOGI failed, so just use loop map to make discovery list */
2e0fef85 483 lpfc_disc_list_loopmap(vport);
dea3101e 484
485 /* Start discovery */
2e0fef85 486 lpfc_disc_start(vport);
dea3101e 487 }
488
489out:
490 lpfc_els_free_iocb(phba, cmdiocb);
491}
492
493static int
2e0fef85 494lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
dea3101e 495 uint8_t retry)
496{
2e0fef85 497 struct lpfc_hba *phba = vport->phba;
dea3101e 498 struct serv_parm *sp;
499 IOCB_t *icmd;
500 struct lpfc_iocbq *elsiocb;
501 struct lpfc_sli_ring *pring;
502 uint8_t *pcmd;
503 uint16_t cmdsize;
504 uint32_t tmo;
505 int rc;
506
507 pring = &phba->sli.ring[LPFC_ELS_RING];
508
509 cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm));
2e0fef85
JS
510 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
511 ndlp->nlp_DID, ELS_CMD_FLOGI);
488d1469 512 if (!elsiocb)
c9f8735b 513 return 1;
dea3101e 514
515 icmd = &elsiocb->iocb;
516 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
517
518 /* For FLOGI request, remainder of payload is service parameters */
519 *((uint32_t *) (pcmd)) = ELS_CMD_FLOGI;
520 pcmd += sizeof (uint32_t);
2e0fef85 521 memcpy(pcmd, &vport->fc_sparam, sizeof (struct serv_parm));
dea3101e 522 sp = (struct serv_parm *) pcmd;
523
524 /* Setup CSPs accordingly for Fabric */
525 sp->cmn.e_d_tov = 0;
526 sp->cmn.w2.r_a_tov = 0;
527 sp->cls1.classValid = 0;
528 sp->cls2.seqDelivery = 1;
529 sp->cls3.seqDelivery = 1;
530 if (sp->cmn.fcphLow < FC_PH3)
531 sp->cmn.fcphLow = FC_PH3;
532 if (sp->cmn.fcphHigh < FC_PH3)
533 sp->cmn.fcphHigh = FC_PH3;
534
535 tmo = phba->fc_ratov;
536 phba->fc_ratov = LPFC_DISC_FLOGI_TMO;
2e0fef85 537 lpfc_set_disctmo(vport);
dea3101e 538 phba->fc_ratov = tmo;
539
540 phba->fc_stat.elsXmitFLOGI++;
541 elsiocb->iocb_cmpl = lpfc_cmpl_els_flogi;
dea3101e 542 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e 543 if (rc == IOCB_ERROR) {
544 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 545 return 1;
dea3101e 546 }
c9f8735b 547 return 0;
dea3101e 548}
549
550int
2e0fef85 551lpfc_els_abort_flogi(struct lpfc_hba *phba)
dea3101e 552{
553 struct lpfc_sli_ring *pring;
554 struct lpfc_iocbq *iocb, *next_iocb;
555 struct lpfc_nodelist *ndlp;
556 IOCB_t *icmd;
557
558 /* Abort outstanding I/O on NPort <nlp_DID> */
559 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
560 "%d:0201 Abort outstanding I/O on NPort x%x\n",
561 phba->brd_no, Fabric_DID);
562
563 pring = &phba->sli.ring[LPFC_ELS_RING];
564
565 /*
566 * Check the txcmplq for an iocb that matches the nport the driver is
567 * searching for.
568 */
2e0fef85 569 spin_lock_irq(&phba->hbalock);
dea3101e 570 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
571 icmd = &iocb->iocb;
2e0fef85
JS
572 if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
573 icmd->un.elsreq64.bdl.ulpIoTag32) {
dea3101e 574 ndlp = (struct lpfc_nodelist *)(iocb->context1);
07951076
JS
575 if (ndlp && (ndlp->nlp_DID == Fabric_DID))
576 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
dea3101e 577 }
578 }
2e0fef85 579 spin_unlock_irq(&phba->hbalock);
dea3101e 580
581 return 0;
582}
583
584int
2e0fef85 585lpfc_initial_flogi(struct lpfc_vport *vport)
dea3101e 586{
2e0fef85 587 struct lpfc_hba *phba = vport->phba;
dea3101e 588 struct lpfc_nodelist *ndlp;
589
c9f8735b 590 /* First look for the Fabric ndlp */
2e0fef85 591 ndlp = lpfc_findnode_did(vport, Fabric_DID);
c9f8735b 592 if (!ndlp) {
dea3101e 593 /* Cannot find existing Fabric ndlp, so allocate a new one */
c9f8735b
JW
594 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
595 if (!ndlp)
596 return 0;
2e0fef85 597 lpfc_nlp_init(vport, ndlp, Fabric_DID);
c9f8735b 598 } else {
2e0fef85 599 lpfc_dequeue_node(vport, ndlp);
dea3101e 600 }
2e0fef85 601 if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
329f9bc7 602 lpfc_nlp_put(ndlp);
dea3101e 603 }
c9f8735b 604 return 1;
dea3101e 605}
606
607static void
2e0fef85 608lpfc_more_plogi(struct lpfc_vport *vport)
dea3101e 609{
610 int sentplogi;
2e0fef85 611 struct lpfc_hba *phba = vport->phba;
dea3101e 612
2e0fef85
JS
613 if (vport->num_disc_nodes)
614 vport->num_disc_nodes--;
dea3101e 615
616 /* Continue discovery with <num_disc_nodes> PLOGIs to go */
617 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
618 "%d:0232 Continue discovery with %d PLOGIs to go "
619 "Data: x%x x%x x%x\n",
2e0fef85
JS
620 phba->brd_no, vport->num_disc_nodes,
621 vport->fc_plogi_cnt, vport->fc_flag, vport->port_state);
dea3101e 622
623 /* Check to see if there are more PLOGIs to be sent */
2e0fef85
JS
624 if (vport->fc_flag & FC_NLP_MORE)
625 /* go thru NPR nodes and issue any remaining ELS PLOGIs */
626 sentplogi = lpfc_els_disc_plogi(vport);
627
dea3101e 628 return;
629}
630
488d1469 631static struct lpfc_nodelist *
685f0bf7 632lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp,
488d1469
JS
633 struct lpfc_nodelist *ndlp)
634{
2e0fef85 635 struct lpfc_vport *vport = ndlp->vport;
488d1469 636 struct lpfc_nodelist *new_ndlp;
488d1469
JS
637 uint32_t *lp;
638 struct serv_parm *sp;
639 uint8_t name[sizeof (struct lpfc_name)];
640 uint32_t rc;
641
2fb9bd8b
JS
642 /* Fabric nodes can have the same WWPN so we don't bother searching
643 * by WWPN. Just return the ndlp that was given to us.
644 */
645 if (ndlp->nlp_type & NLP_FABRIC)
646 return ndlp;
647
488d1469
JS
648 lp = (uint32_t *) prsp->virt;
649 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
685f0bf7 650 memset(name, 0, sizeof(struct lpfc_name));
488d1469 651
685f0bf7 652 /* Now we find out if the NPort we are logging into, matches the WWPN
488d1469
JS
653 * we have for that ndlp. If not, we have some work to do.
654 */
2e0fef85 655 new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName);
488d1469 656
92795650 657 if (new_ndlp == ndlp)
488d1469 658 return ndlp;
488d1469
JS
659
660 if (!new_ndlp) {
2e0fef85
JS
661 rc = memcmp(&ndlp->nlp_portname, name,
662 sizeof(struct lpfc_name));
92795650
JS
663 if (!rc)
664 return ndlp;
488d1469
JS
665 new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
666 if (!new_ndlp)
667 return ndlp;
668
2e0fef85 669 lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
488d1469
JS
670 }
671
2e0fef85 672 lpfc_unreg_rpi(vport, new_ndlp);
488d1469 673 new_ndlp->nlp_DID = ndlp->nlp_DID;
92795650 674 new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
2e0fef85 675 lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state);
488d1469 676
2e0fef85 677 /* Move this back to NPR state */
de0c5b32 678 if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0)
2e0fef85 679 lpfc_drop_node(vport, ndlp);
92795650 680 else {
2e0fef85 681 lpfc_unreg_rpi(vport, ndlp);
92795650 682 ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
2e0fef85 683 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
92795650 684 }
488d1469
JS
685 return new_ndlp;
686}
687
dea3101e 688static void
2e0fef85
JS
689lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
690 struct lpfc_iocbq *rspiocb)
dea3101e 691{
2e0fef85
JS
692 struct lpfc_vport *vport = cmdiocb->vport;
693 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 694 IOCB_t *irsp;
dea3101e 695 struct lpfc_nodelist *ndlp;
92795650 696 struct lpfc_dmabuf *prsp;
dea3101e 697 int disc, rc, did, type;
698
dea3101e 699 /* we pass cmdiocb to state machine which needs rspiocb as well */
700 cmdiocb->context_un.rsp_iocb = rspiocb;
701
702 irsp = &rspiocb->iocb;
2e0fef85 703 ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
ed957684
JS
704
705 if (!ndlp) {
488d1469 706 goto out;
ed957684 707 }
dea3101e 708
709 /* Since ndlp can be freed in the disc state machine, note if this node
710 * is being used during discovery.
711 */
2e0fef85 712 spin_lock_irq(shost->host_lock);
dea3101e 713 disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
488d1469 714 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
2e0fef85 715 spin_unlock_irq(shost->host_lock);
dea3101e 716 rc = 0;
717
718 /* PLOGI completes to NPort <nlp_DID> */
719 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
720 "%d:0102 PLOGI completes to NPort x%x "
c9f8735b 721 "Data: x%x x%x x%x x%x x%x\n",
dea3101e 722 phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
c9f8735b 723 irsp->un.ulpWord[4], irsp->ulpTimeout, disc,
2e0fef85 724 vport->num_disc_nodes);
dea3101e 725
726 /* Check to see if link went down during discovery */
2e0fef85
JS
727 if (lpfc_els_chk_latt(vport)) {
728 spin_lock_irq(shost->host_lock);
dea3101e 729 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2e0fef85 730 spin_unlock_irq(shost->host_lock);
dea3101e 731 goto out;
732 }
733
734 /* ndlp could be freed in DSM, save these values now */
735 type = ndlp->nlp_type;
736 did = ndlp->nlp_DID;
737
738 if (irsp->ulpStatus) {
739 /* Check for retry */
740 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
741 /* ELS command is being retried */
742 if (disc) {
2e0fef85 743 spin_lock_irq(shost->host_lock);
dea3101e 744 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2e0fef85 745 spin_unlock_irq(shost->host_lock);
dea3101e 746 }
747 goto out;
748 }
749
750 /* PLOGI failed */
751 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
752 if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
753 ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
6281bfe0 754 (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
dea3101e 755 (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
c9f8735b 756 rc = NLP_STE_FREED_NODE;
2fe165b6 757 } else {
2e0fef85 758 rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
dea3101e 759 NLP_EVT_CMPL_PLOGI);
760 }
761 } else {
762 /* Good status, call state machine */
92795650
JS
763 prsp = list_entry(((struct lpfc_dmabuf *)
764 cmdiocb->context2)->list.next,
765 struct lpfc_dmabuf, list);
766 ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp);
2e0fef85 767 rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
dea3101e 768 NLP_EVT_CMPL_PLOGI);
769 }
770
2e0fef85 771 if (disc && vport->num_disc_nodes) {
dea3101e 772 /* Check to see if there are more PLOGIs to be sent */
2e0fef85 773 lpfc_more_plogi(vport);
dea3101e 774
2e0fef85
JS
775 if (vport->num_disc_nodes == 0) {
776 spin_lock_irq(shost->host_lock);
777 vport->fc_flag &= ~FC_NDISC_ACTIVE;
778 spin_unlock_irq(shost->host_lock);
dea3101e 779
2e0fef85
JS
780 lpfc_can_disctmo(vport);
781 if (vport->fc_flag & FC_RSCN_MODE) {
10d4e957
JS
782 /*
783 * Check to see if more RSCNs came in while
784 * we were processing this one.
785 */
2e0fef85
JS
786 if ((vport->fc_rscn_id_cnt == 0) &&
787 (!(vport->fc_flag & FC_RSCN_DISCOVERY))) {
788 spin_lock_irq(shost->host_lock);
789 vport->fc_flag &= ~FC_RSCN_MODE;
790 spin_unlock_irq(shost->host_lock);
10d4e957 791 } else {
2e0fef85 792 lpfc_els_handle_rscn(vport);
10d4e957 793 }
dea3101e 794 }
795 }
796 }
797
798out:
799 lpfc_els_free_iocb(phba, cmdiocb);
800 return;
801}
802
803int
2e0fef85 804lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
dea3101e 805{
2e0fef85 806 struct lpfc_hba *phba = vport->phba;
dea3101e 807 struct serv_parm *sp;
808 IOCB_t *icmd;
809 struct lpfc_iocbq *elsiocb;
810 struct lpfc_sli_ring *pring;
811 struct lpfc_sli *psli;
812 uint8_t *pcmd;
813 uint16_t cmdsize;
814
815 psli = &phba->sli;
816 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
817
818 cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm));
2e0fef85
JS
819 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, NULL, did,
820 ELS_CMD_PLOGI);
c9f8735b
JW
821 if (!elsiocb)
822 return 1;
dea3101e 823
824 icmd = &elsiocb->iocb;
825 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
826
827 /* For PLOGI request, remainder of payload is service parameters */
828 *((uint32_t *) (pcmd)) = ELS_CMD_PLOGI;
829 pcmd += sizeof (uint32_t);
2e0fef85 830 memcpy(pcmd, &vport->fc_sparam, sizeof (struct serv_parm));
dea3101e 831 sp = (struct serv_parm *) pcmd;
832
833 if (sp->cmn.fcphLow < FC_PH_4_3)
834 sp->cmn.fcphLow = FC_PH_4_3;
835
836 if (sp->cmn.fcphHigh < FC_PH3)
837 sp->cmn.fcphHigh = FC_PH3;
838
839 phba->fc_stat.elsXmitPLOGI++;
840 elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi;
dea3101e 841 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
dea3101e 842 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 843 return 1;
dea3101e 844 }
c9f8735b 845 return 0;
dea3101e 846}
847
848static void
2e0fef85
JS
849lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
850 struct lpfc_iocbq *rspiocb)
dea3101e 851{
2e0fef85
JS
852 struct lpfc_vport *vport = cmdiocb->vport;
853 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 854 IOCB_t *irsp;
855 struct lpfc_sli *psli;
856 struct lpfc_nodelist *ndlp;
857
858 psli = &phba->sli;
859 /* we pass cmdiocb to state machine which needs rspiocb as well */
860 cmdiocb->context_un.rsp_iocb = rspiocb;
861
862 irsp = &(rspiocb->iocb);
863 ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2e0fef85 864 spin_lock_irq(shost->host_lock);
dea3101e 865 ndlp->nlp_flag &= ~NLP_PRLI_SND;
2e0fef85 866 spin_unlock_irq(shost->host_lock);
dea3101e 867
868 /* PRLI completes to NPort <nlp_DID> */
869 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
870 "%d:0103 PRLI completes to NPort x%x "
c9f8735b 871 "Data: x%x x%x x%x x%x\n",
dea3101e 872 phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
c9f8735b 873 irsp->un.ulpWord[4], irsp->ulpTimeout,
2e0fef85 874 vport->num_disc_nodes);
dea3101e 875
2e0fef85 876 vport->fc_prli_sent--;
dea3101e 877 /* Check to see if link went down during discovery */
2e0fef85 878 if (lpfc_els_chk_latt(vport))
dea3101e 879 goto out;
880
881 if (irsp->ulpStatus) {
882 /* Check for retry */
883 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
884 /* ELS command is being retried */
885 goto out;
886 }
887 /* PRLI failed */
888 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
889 if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
890 ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
6281bfe0 891 (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
dea3101e 892 (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
893 goto out;
2fe165b6 894 } else {
2e0fef85 895 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
dea3101e 896 NLP_EVT_CMPL_PRLI);
897 }
898 } else {
899 /* Good status, call state machine */
2e0fef85
JS
900 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
901 NLP_EVT_CMPL_PRLI);
dea3101e 902 }
903
904out:
905 lpfc_els_free_iocb(phba, cmdiocb);
906 return;
907}
908
909int
2e0fef85 910lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
dea3101e 911 uint8_t retry)
912{
2e0fef85
JS
913 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
914 struct lpfc_hba *phba = vport->phba;
dea3101e 915 PRLI *npr;
916 IOCB_t *icmd;
917 struct lpfc_iocbq *elsiocb;
918 struct lpfc_sli_ring *pring;
919 struct lpfc_sli *psli;
920 uint8_t *pcmd;
921 uint16_t cmdsize;
922
923 psli = &phba->sli;
924 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
925
926 cmdsize = (sizeof (uint32_t) + sizeof (PRLI));
2e0fef85
JS
927 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
928 ndlp->nlp_DID, ELS_CMD_PRLI);
488d1469 929 if (!elsiocb)
c9f8735b 930 return 1;
dea3101e 931
932 icmd = &elsiocb->iocb;
933 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
934
935 /* For PRLI request, remainder of payload is service parameters */
936 memset(pcmd, 0, (sizeof (PRLI) + sizeof (uint32_t)));
937 *((uint32_t *) (pcmd)) = ELS_CMD_PRLI;
938 pcmd += sizeof (uint32_t);
939
940 /* For PRLI, remainder of payload is PRLI parameter page */
941 npr = (PRLI *) pcmd;
942 /*
943 * If our firmware version is 3.20 or later,
944 * set the following bits for FC-TAPE support.
945 */
946 if (phba->vpd.rev.feaLevelHigh >= 0x02) {
947 npr->ConfmComplAllowed = 1;
948 npr->Retry = 1;
949 npr->TaskRetryIdReq = 1;
950 }
951 npr->estabImagePair = 1;
952 npr->readXferRdyDis = 1;
953
954 /* For FCP support */
955 npr->prliType = PRLI_FCP_TYPE;
956 npr->initiatorFunc = 1;
957
958 phba->fc_stat.elsXmitPRLI++;
959 elsiocb->iocb_cmpl = lpfc_cmpl_els_prli;
2e0fef85 960 spin_lock_irq(shost->host_lock);
dea3101e 961 ndlp->nlp_flag |= NLP_PRLI_SND;
2e0fef85 962 spin_unlock_irq(shost->host_lock);
dea3101e 963 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2e0fef85 964 spin_lock_irq(shost->host_lock);
dea3101e 965 ndlp->nlp_flag &= ~NLP_PRLI_SND;
2e0fef85 966 spin_unlock_irq(shost->host_lock);
dea3101e 967 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 968 return 1;
dea3101e 969 }
2e0fef85 970 vport->fc_prli_sent++;
c9f8735b 971 return 0;
dea3101e 972}
973
974static void
2e0fef85 975lpfc_more_adisc(struct lpfc_vport *vport)
dea3101e 976{
977 int sentadisc;
2e0fef85 978 struct lpfc_hba *phba = vport->phba;
dea3101e 979
2e0fef85
JS
980 if (vport->num_disc_nodes)
981 vport->num_disc_nodes--;
dea3101e 982
983 /* Continue discovery with <num_disc_nodes> ADISCs to go */
984 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
985 "%d:0210 Continue discovery with %d ADISCs to go "
986 "Data: x%x x%x x%x\n",
2e0fef85
JS
987 phba->brd_no, vport->num_disc_nodes,
988 vport->fc_adisc_cnt, vport->fc_flag, vport->port_state);
dea3101e 989
990 /* Check to see if there are more ADISCs to be sent */
2e0fef85
JS
991 if (vport->fc_flag & FC_NLP_MORE) {
992 lpfc_set_disctmo(vport);
993 /* go thru NPR nodes and issue any remaining ELS ADISCs */
994 sentadisc = lpfc_els_disc_adisc(vport);
dea3101e 995 }
996 return;
997}
998
999static void
2e0fef85 1000lpfc_rscn_disc(struct lpfc_vport *vport)
dea3101e 1001{
2e0fef85
JS
1002 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1003
dea3101e 1004 /* RSCN discovery */
2e0fef85
JS
1005 /* go thru NPR nodes and issue ELS PLOGIs */
1006 if (vport->fc_npr_cnt)
1007 if (lpfc_els_disc_plogi(vport))
dea3101e 1008 return;
2e0fef85
JS
1009
1010 if (vport->fc_flag & FC_RSCN_MODE) {
dea3101e 1011 /* Check to see if more RSCNs came in while we were
1012 * processing this one.
1013 */
2e0fef85
JS
1014 if ((vport->fc_rscn_id_cnt == 0) &&
1015 (!(vport->fc_flag & FC_RSCN_DISCOVERY))) {
1016 spin_lock_irq(shost->host_lock);
1017 vport->fc_flag &= ~FC_RSCN_MODE;
1018 spin_unlock_irq(shost->host_lock);
dea3101e 1019 } else {
2e0fef85 1020 lpfc_els_handle_rscn(vport);
dea3101e 1021 }
1022 }
1023}
1024
1025static void
2e0fef85
JS
1026lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1027 struct lpfc_iocbq *rspiocb)
dea3101e 1028{
2e0fef85
JS
1029 struct lpfc_vport *vport = cmdiocb->vport;
1030 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 1031 IOCB_t *irsp;
dea3101e 1032 struct lpfc_nodelist *ndlp;
2e0fef85 1033 int disc;
dea3101e 1034
1035 /* we pass cmdiocb to state machine which needs rspiocb as well */
1036 cmdiocb->context_un.rsp_iocb = rspiocb;
1037
1038 irsp = &(rspiocb->iocb);
1039 ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
dea3101e 1040
1041 /* Since ndlp can be freed in the disc state machine, note if this node
1042 * is being used during discovery.
1043 */
2e0fef85 1044 spin_lock_irq(shost->host_lock);
dea3101e 1045 disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
c9f8735b 1046 ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC);
2e0fef85 1047 spin_unlock_irq(shost->host_lock);
dea3101e 1048
1049 /* ADISC completes to NPort <nlp_DID> */
1050 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
1051 "%d:0104 ADISC completes to NPort x%x "
c9f8735b 1052 "Data: x%x x%x x%x x%x x%x\n",
dea3101e 1053 phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
c9f8735b 1054 irsp->un.ulpWord[4], irsp->ulpTimeout, disc,
2e0fef85 1055 vport->num_disc_nodes);
dea3101e 1056
1057 /* Check to see if link went down during discovery */
2e0fef85
JS
1058 if (lpfc_els_chk_latt(vport)) {
1059 spin_lock_irq(shost->host_lock);
dea3101e 1060 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2e0fef85 1061 spin_unlock_irq(shost->host_lock);
dea3101e 1062 goto out;
1063 }
1064
1065 if (irsp->ulpStatus) {
1066 /* Check for retry */
1067 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
1068 /* ELS command is being retried */
1069 if (disc) {
2e0fef85 1070 spin_lock_irq(shost->host_lock);
dea3101e 1071 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2e0fef85
JS
1072 spin_unlock_irq(shost->host_lock);
1073 lpfc_set_disctmo(vport);
dea3101e 1074 }
1075 goto out;
1076 }
1077 /* ADISC failed */
1078 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
c9f8735b
JW
1079 if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
1080 ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) &&
1081 (irsp->un.ulpWord[4] != IOERR_LINK_DOWN) &&
1082 (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) {
2e0fef85 1083 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
dea3101e 1084 NLP_EVT_CMPL_ADISC);
1085 }
1086 } else {
1087 /* Good status, call state machine */
2e0fef85 1088 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
dea3101e 1089 NLP_EVT_CMPL_ADISC);
1090 }
1091
2e0fef85 1092 if (disc && vport->num_disc_nodes) {
dea3101e 1093 /* Check to see if there are more ADISCs to be sent */
2e0fef85 1094 lpfc_more_adisc(vport);
dea3101e 1095
1096 /* Check to see if we are done with ADISC authentication */
2e0fef85
JS
1097 if (vport->num_disc_nodes == 0) {
1098 lpfc_can_disctmo(vport);
dea3101e 1099 /* If we get here, there is nothing left to wait for */
2e0fef85
JS
1100 if (vport->port_state < LPFC_VPORT_READY &&
1101 phba->link_state != LPFC_CLEAR_LA) {
ed957684 1102 if (vport->port_type == LPFC_PHYSICAL_PORT)
2e0fef85 1103 lpfc_issue_clear_la(phba, vport);
dea3101e 1104 } else {
2e0fef85 1105 lpfc_rscn_disc(vport);
dea3101e 1106 }
1107 }
1108 }
dea3101e 1109out:
1110 lpfc_els_free_iocb(phba, cmdiocb);
1111 return;
1112}
1113
1114int
2e0fef85 1115lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
dea3101e 1116 uint8_t retry)
1117{
2e0fef85
JS
1118 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1119 struct lpfc_hba *phba = vport->phba;
dea3101e 1120 ADISC *ap;
1121 IOCB_t *icmd;
1122 struct lpfc_iocbq *elsiocb;
2e0fef85
JS
1123 struct lpfc_sli *psli = &phba->sli;
1124 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
dea3101e 1125 uint8_t *pcmd;
1126 uint16_t cmdsize;
1127
dea3101e 1128 cmdsize = (sizeof (uint32_t) + sizeof (ADISC));
2e0fef85
JS
1129 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1130 ndlp->nlp_DID, ELS_CMD_ADISC);
488d1469 1131 if (!elsiocb)
c9f8735b 1132 return 1;
dea3101e 1133
1134 icmd = &elsiocb->iocb;
1135 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1136
1137 /* For ADISC request, remainder of payload is service parameters */
1138 *((uint32_t *) (pcmd)) = ELS_CMD_ADISC;
1139 pcmd += sizeof (uint32_t);
1140
1141 /* Fill in ADISC payload */
1142 ap = (ADISC *) pcmd;
1143 ap->hardAL_PA = phba->fc_pref_ALPA;
2e0fef85
JS
1144 memcpy(&ap->portName, &vport->fc_portname, sizeof (struct lpfc_name));
1145 memcpy(&ap->nodeName, &vport->fc_nodename, sizeof (struct lpfc_name));
1146 ap->DID = be32_to_cpu(vport->fc_myDID);
dea3101e 1147
1148 phba->fc_stat.elsXmitADISC++;
1149 elsiocb->iocb_cmpl = lpfc_cmpl_els_adisc;
2e0fef85 1150 spin_lock_irq(shost->host_lock);
dea3101e 1151 ndlp->nlp_flag |= NLP_ADISC_SND;
2e0fef85 1152 spin_unlock_irq(shost->host_lock);
dea3101e 1153 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2e0fef85 1154 spin_lock_irq(shost->host_lock);
dea3101e 1155 ndlp->nlp_flag &= ~NLP_ADISC_SND;
2e0fef85 1156 spin_unlock_irq(shost->host_lock);
dea3101e 1157 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 1158 return 1;
dea3101e 1159 }
c9f8735b 1160 return 0;
dea3101e 1161}
1162
1163static void
2e0fef85
JS
1164lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1165 struct lpfc_iocbq *rspiocb)
dea3101e 1166{
2e0fef85
JS
1167 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
1168 struct lpfc_vport *vport = ndlp->vport;
1169 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 1170 IOCB_t *irsp;
1171 struct lpfc_sli *psli;
dea3101e 1172
1173 psli = &phba->sli;
1174 /* we pass cmdiocb to state machine which needs rspiocb as well */
1175 cmdiocb->context_un.rsp_iocb = rspiocb;
1176
1177 irsp = &(rspiocb->iocb);
2e0fef85 1178 spin_lock_irq(shost->host_lock);
dea3101e 1179 ndlp->nlp_flag &= ~NLP_LOGO_SND;
2e0fef85 1180 spin_unlock_irq(shost->host_lock);
dea3101e 1181
1182 /* LOGO completes to NPort <nlp_DID> */
1183 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
1184 "%d:0105 LOGO completes to NPort x%x "
c9f8735b 1185 "Data: x%x x%x x%x x%x\n",
dea3101e 1186 phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
c9f8735b 1187 irsp->un.ulpWord[4], irsp->ulpTimeout,
2e0fef85 1188 vport->num_disc_nodes);
dea3101e 1189
1190 /* Check to see if link went down during discovery */
2e0fef85 1191 if (lpfc_els_chk_latt(vport))
dea3101e 1192 goto out;
1193
1194 if (irsp->ulpStatus) {
1195 /* Check for retry */
2e0fef85 1196 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
dea3101e 1197 /* ELS command is being retried */
1198 goto out;
dea3101e 1199 /* LOGO failed */
1200 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
1201 if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
1202 ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
6281bfe0 1203 (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
dea3101e 1204 (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
1205 goto out;
2fe165b6 1206 } else {
2e0fef85 1207 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
dea3101e 1208 NLP_EVT_CMPL_LOGO);
1209 }
1210 } else {
5024ab17
JW
1211 /* Good status, call state machine.
1212 * This will unregister the rpi if needed.
1213 */
2e0fef85
JS
1214 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1215 NLP_EVT_CMPL_LOGO);
dea3101e 1216 }
1217
1218out:
1219 lpfc_els_free_iocb(phba, cmdiocb);
1220 return;
1221}
1222
1223int
2e0fef85 1224lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
dea3101e 1225 uint8_t retry)
1226{
2e0fef85
JS
1227 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1228 struct lpfc_hba *phba = vport->phba;
dea3101e 1229 IOCB_t *icmd;
1230 struct lpfc_iocbq *elsiocb;
1231 struct lpfc_sli_ring *pring;
1232 struct lpfc_sli *psli;
1233 uint8_t *pcmd;
1234 uint16_t cmdsize;
1235
1236 psli = &phba->sli;
1237 pring = &psli->ring[LPFC_ELS_RING];
1238
10d4e957 1239 cmdsize = (2 * sizeof (uint32_t)) + sizeof (struct lpfc_name);
2e0fef85
JS
1240 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1241 ndlp->nlp_DID, ELS_CMD_LOGO);
488d1469 1242 if (!elsiocb)
c9f8735b 1243 return 1;
dea3101e 1244
1245 icmd = &elsiocb->iocb;
1246 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1247 *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
1248 pcmd += sizeof (uint32_t);
1249
1250 /* Fill in LOGO payload */
2e0fef85 1251 *((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID);
dea3101e 1252 pcmd += sizeof (uint32_t);
2e0fef85 1253 memcpy(pcmd, &vport->fc_portname, sizeof (struct lpfc_name));
dea3101e 1254
1255 phba->fc_stat.elsXmitLOGO++;
1256 elsiocb->iocb_cmpl = lpfc_cmpl_els_logo;
2e0fef85 1257 spin_lock_irq(shost->host_lock);
dea3101e 1258 ndlp->nlp_flag |= NLP_LOGO_SND;
2e0fef85 1259 spin_unlock_irq(shost->host_lock);
dea3101e 1260 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2e0fef85 1261 spin_lock_irq(shost->host_lock);
dea3101e 1262 ndlp->nlp_flag &= ~NLP_LOGO_SND;
2e0fef85 1263 spin_unlock_irq(shost->host_lock);
dea3101e 1264 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 1265 return 1;
dea3101e 1266 }
c9f8735b 1267 return 0;
dea3101e 1268}
1269
1270static void
2e0fef85
JS
1271lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1272 struct lpfc_iocbq *rspiocb)
dea3101e 1273{
2e0fef85 1274 struct lpfc_vport *vport = cmdiocb->vport;
dea3101e 1275 IOCB_t *irsp;
1276
1277 irsp = &rspiocb->iocb;
1278
1279 /* ELS cmd tag <ulpIoTag> completes */
1280 lpfc_printf_log(phba,
1281 KERN_INFO,
1282 LOG_ELS,
c9f8735b 1283 "%d:0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n",
dea3101e 1284 phba->brd_no,
c9f8735b
JW
1285 irsp->ulpIoTag, irsp->ulpStatus,
1286 irsp->un.ulpWord[4], irsp->ulpTimeout);
dea3101e 1287
1288 /* Check to see if link went down during discovery */
2e0fef85 1289 lpfc_els_chk_latt(vport);
dea3101e 1290 lpfc_els_free_iocb(phba, cmdiocb);
1291 return;
1292}
1293
1294int
2e0fef85 1295lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
dea3101e 1296{
2e0fef85 1297 struct lpfc_hba *phba = vport->phba;
dea3101e 1298 IOCB_t *icmd;
1299 struct lpfc_iocbq *elsiocb;
1300 struct lpfc_sli_ring *pring;
1301 struct lpfc_sli *psli;
1302 uint8_t *pcmd;
1303 uint16_t cmdsize;
1304 struct lpfc_nodelist *ndlp;
1305
1306 psli = &phba->sli;
1307 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
1308 cmdsize = (sizeof (uint32_t) + sizeof (SCR));
c9f8735b
JW
1309 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
1310 if (!ndlp)
1311 return 1;
dea3101e 1312
2e0fef85
JS
1313 lpfc_nlp_init(vport, ndlp, nportid);
1314
1315 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1316 ndlp->nlp_DID, ELS_CMD_SCR);
dea3101e 1317
488d1469 1318 if (!elsiocb) {
329f9bc7 1319 lpfc_nlp_put(ndlp);
c9f8735b 1320 return 1;
dea3101e 1321 }
1322
1323 icmd = &elsiocb->iocb;
1324 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1325
1326 *((uint32_t *) (pcmd)) = ELS_CMD_SCR;
1327 pcmd += sizeof (uint32_t);
1328
1329 /* For SCR, remainder of payload is SCR parameter page */
1330 memset(pcmd, 0, sizeof (SCR));
1331 ((SCR *) pcmd)->Function = SCR_FUNC_FULL;
1332
1333 phba->fc_stat.elsXmitSCR++;
1334 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
dea3101e 1335 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
329f9bc7 1336 lpfc_nlp_put(ndlp);
dea3101e 1337 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 1338 return 1;
dea3101e 1339 }
329f9bc7 1340 lpfc_nlp_put(ndlp);
c9f8735b 1341 return 0;
dea3101e 1342}
1343
1344static int
2e0fef85 1345lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
dea3101e 1346{
2e0fef85 1347 struct lpfc_hba *phba = vport->phba;
dea3101e 1348 IOCB_t *icmd;
1349 struct lpfc_iocbq *elsiocb;
1350 struct lpfc_sli_ring *pring;
1351 struct lpfc_sli *psli;
1352 FARP *fp;
1353 uint8_t *pcmd;
1354 uint32_t *lp;
1355 uint16_t cmdsize;
1356 struct lpfc_nodelist *ondlp;
1357 struct lpfc_nodelist *ndlp;
1358
1359 psli = &phba->sli;
1360 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
1361 cmdsize = (sizeof (uint32_t) + sizeof (FARP));
c9f8735b
JW
1362 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
1363 if (!ndlp)
1364 return 1;
dea3101e 1365
2e0fef85
JS
1366 lpfc_nlp_init(vport, ndlp, nportid);
1367
1368 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1369 ndlp->nlp_DID, ELS_CMD_RNID);
488d1469 1370 if (!elsiocb) {
329f9bc7 1371 lpfc_nlp_put(ndlp);
c9f8735b 1372 return 1;
dea3101e 1373 }
1374
1375 icmd = &elsiocb->iocb;
1376 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1377
1378 *((uint32_t *) (pcmd)) = ELS_CMD_FARPR;
1379 pcmd += sizeof (uint32_t);
1380
1381 /* Fill in FARPR payload */
1382 fp = (FARP *) (pcmd);
1383 memset(fp, 0, sizeof (FARP));
1384 lp = (uint32_t *) pcmd;
1385 *lp++ = be32_to_cpu(nportid);
2e0fef85 1386 *lp++ = be32_to_cpu(vport->fc_myDID);
dea3101e 1387 fp->Rflags = 0;
1388 fp->Mflags = (FARP_MATCH_PORT | FARP_MATCH_NODE);
1389
2e0fef85
JS
1390 memcpy(&fp->RportName, &vport->fc_portname, sizeof (struct lpfc_name));
1391 memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof (struct lpfc_name));
1392 ondlp = lpfc_findnode_did(vport, nportid);
1393 if (ondlp) {
dea3101e 1394 memcpy(&fp->OportName, &ondlp->nlp_portname,
1395 sizeof (struct lpfc_name));
1396 memcpy(&fp->OnodeName, &ondlp->nlp_nodename,
1397 sizeof (struct lpfc_name));
1398 }
1399
1400 phba->fc_stat.elsXmitFARPR++;
1401 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
dea3101e 1402 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
329f9bc7 1403 lpfc_nlp_put(ndlp);
dea3101e 1404 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 1405 return 1;
dea3101e 1406 }
329f9bc7 1407 lpfc_nlp_put(ndlp);
c9f8735b 1408 return 0;
dea3101e 1409}
1410
ed957684
JS
1411static void
1412lpfc_end_rscn(struct lpfc_vport *vport)
1413{
1414 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1415
1416 if (vport->fc_flag & FC_RSCN_MODE) {
1417 /*
1418 * Check to see if more RSCNs came in while we were
1419 * processing this one.
1420 */
1421 if (vport->fc_rscn_id_cnt ||
1422 (vport->fc_flag & FC_RSCN_DISCOVERY) != 0)
1423 lpfc_els_handle_rscn(vport);
1424 else {
1425 spin_lock_irq(shost->host_lock);
1426 vport->fc_flag &= ~FC_RSCN_MODE;
1427 spin_unlock_irq(shost->host_lock);
1428 }
1429 }
1430}
1431
fdcebe28 1432void
2e0fef85 1433lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
fdcebe28 1434{
2e0fef85
JS
1435 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1436
1437 spin_lock_irq(shost->host_lock);
fdcebe28 1438 nlp->nlp_flag &= ~NLP_DELAY_TMO;
2e0fef85 1439 spin_unlock_irq(shost->host_lock);
fdcebe28
JS
1440 del_timer_sync(&nlp->nlp_delayfunc);
1441 nlp->nlp_last_elscmd = 0;
1442
1443 if (!list_empty(&nlp->els_retry_evt.evt_listp))
1444 list_del_init(&nlp->els_retry_evt.evt_listp);
1445
1446 if (nlp->nlp_flag & NLP_NPR_2B_DISC) {
2e0fef85 1447 spin_lock_irq(shost->host_lock);
fdcebe28 1448 nlp->nlp_flag &= ~NLP_NPR_2B_DISC;
2e0fef85
JS
1449 spin_unlock_irq(shost->host_lock);
1450 if (vport->num_disc_nodes) {
fdcebe28
JS
1451 /* Check to see if there are more
1452 * PLOGIs to be sent
1453 */
2e0fef85
JS
1454 lpfc_more_plogi(vport);
1455
1456 if (vport->num_disc_nodes == 0) {
1457 spin_lock_irq(shost->host_lock);
1458 vport->fc_flag &= ~FC_NDISC_ACTIVE;
1459 spin_unlock_irq(shost->host_lock);
1460 lpfc_can_disctmo(vport);
ed957684 1461 lpfc_end_rscn(vport);
fdcebe28
JS
1462 }
1463 }
1464 }
1465 return;
1466}
1467
dea3101e 1468void
1469lpfc_els_retry_delay(unsigned long ptr)
1470{
2e0fef85
JS
1471 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) ptr;
1472 struct lpfc_vport *vport = ndlp->vport;
1473 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1474 struct lpfc_hba *phba = vport->phba;
dea3101e 1475 unsigned long iflag;
2e0fef85 1476 struct lpfc_work_evt *evtp = &ndlp->els_retry_evt;
dea3101e 1477
2e0fef85
JS
1478 ndlp = (struct lpfc_nodelist *) ptr;
1479 phba = ndlp->vport->phba;
dea3101e 1480 evtp = &ndlp->els_retry_evt;
1481
2e0fef85 1482 spin_lock_irqsave(shost->host_lock, iflag);
dea3101e 1483 if (!list_empty(&evtp->evt_listp)) {
2e0fef85 1484 spin_unlock_irqrestore(shost->host_lock, iflag);
dea3101e 1485 return;
1486 }
1487
1488 evtp->evt_arg1 = ndlp;
1489 evtp->evt = LPFC_EVT_ELS_RETRY;
1490 list_add_tail(&evtp->evt_listp, &phba->work_list);
1491 if (phba->work_wait)
1492 wake_up(phba->work_wait);
1493
2e0fef85 1494 spin_unlock_irqrestore(shost->host_lock, iflag);
dea3101e 1495 return;
1496}
1497
1498void
1499lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
1500{
2e0fef85
JS
1501 struct lpfc_vport *vport = ndlp->vport;
1502 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1503 uint32_t cmd, did, retry;
dea3101e 1504
2e0fef85 1505 spin_lock_irq(shost->host_lock);
5024ab17
JW
1506 did = ndlp->nlp_DID;
1507 cmd = ndlp->nlp_last_elscmd;
1508 ndlp->nlp_last_elscmd = 0;
dea3101e 1509
1510 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
2e0fef85 1511 spin_unlock_irq(shost->host_lock);
dea3101e 1512 return;
1513 }
1514
1515 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
2e0fef85 1516 spin_unlock_irq(shost->host_lock);
1a169689
JS
1517 /*
1518 * If a discovery event readded nlp_delayfunc after timer
1519 * firing and before processing the timer, cancel the
1520 * nlp_delayfunc.
1521 */
1522 del_timer_sync(&ndlp->nlp_delayfunc);
dea3101e 1523 retry = ndlp->nlp_retry;
1524
1525 switch (cmd) {
1526 case ELS_CMD_FLOGI:
2e0fef85 1527 lpfc_issue_els_flogi(vport, ndlp, retry);
dea3101e 1528 break;
1529 case ELS_CMD_PLOGI:
2e0fef85 1530 if (!lpfc_issue_els_plogi(vport, ndlp->nlp_DID, retry)) {
5024ab17 1531 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 1532 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
6ad42535 1533 }
dea3101e 1534 break;
1535 case ELS_CMD_ADISC:
2e0fef85 1536 if (!lpfc_issue_els_adisc(vport, ndlp, retry)) {
5024ab17 1537 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 1538 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
6ad42535 1539 }
dea3101e 1540 break;
1541 case ELS_CMD_PRLI:
2e0fef85 1542 if (!lpfc_issue_els_prli(vport, ndlp, retry)) {
5024ab17 1543 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 1544 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
6ad42535 1545 }
dea3101e 1546 break;
1547 case ELS_CMD_LOGO:
2e0fef85 1548 if (!lpfc_issue_els_logo(vport, ndlp, retry)) {
5024ab17 1549 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 1550 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
6ad42535 1551 }
dea3101e 1552 break;
1553 }
1554 return;
1555}
1556
1557static int
2e0fef85
JS
1558lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1559 struct lpfc_iocbq *rspiocb)
dea3101e 1560{
2e0fef85
JS
1561 struct lpfc_vport *vport = cmdiocb->vport;
1562 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1563 IOCB_t *irsp = &rspiocb->iocb;
1564 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
1565 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
dea3101e 1566 uint32_t *elscmd;
1567 struct ls_rjt stat;
2e0fef85
JS
1568 int retry = 0, maxretry = lpfc_max_els_tries, delay = 0;
1569 uint32_t cmd = 0;
488d1469 1570 uint32_t did;
dea3101e 1571
488d1469 1572
dea3101e 1573 /* Note: context2 may be 0 for internal driver abort
1574 * of delays ELS command.
1575 */
1576
1577 if (pcmd && pcmd->virt) {
1578 elscmd = (uint32_t *) (pcmd->virt);
1579 cmd = *elscmd++;
1580 }
1581
329f9bc7 1582 if (ndlp)
488d1469
JS
1583 did = ndlp->nlp_DID;
1584 else {
1585 /* We should only hit this case for retrying PLOGI */
1586 did = irsp->un.elsreq64.remoteID;
2e0fef85 1587 ndlp = lpfc_findnode_did(vport, did);
488d1469
JS
1588 if (!ndlp && (cmd != ELS_CMD_PLOGI))
1589 return 1;
1590 }
1591
dea3101e 1592 switch (irsp->ulpStatus) {
1593 case IOSTAT_FCP_RSP_ERROR:
1594 case IOSTAT_REMOTE_STOP:
1595 break;
1596
1597 case IOSTAT_LOCAL_REJECT:
1598 switch ((irsp->un.ulpWord[4] & 0xff)) {
1599 case IOERR_LOOP_OPEN_FAILURE:
2e0fef85 1600 if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0)
dea3101e 1601 delay = 1;
dea3101e 1602 retry = 1;
1603 break;
1604
1605 case IOERR_SEQUENCE_TIMEOUT:
1606 retry = 1;
dea3101e 1607 break;
1608
1609 case IOERR_NO_RESOURCES:
2e0fef85 1610 if (cmd == ELS_CMD_PLOGI)
dea3101e 1611 delay = 1;
dea3101e 1612 retry = 1;
1613 break;
1614
1615 case IOERR_INVALID_RPI:
1616 retry = 1;
1617 break;
1618 }
1619 break;
1620
1621 case IOSTAT_NPORT_RJT:
1622 case IOSTAT_FABRIC_RJT:
1623 if (irsp->un.ulpWord[4] & RJT_UNAVAIL_TEMP) {
1624 retry = 1;
1625 break;
1626 }
1627 break;
1628
1629 case IOSTAT_NPORT_BSY:
1630 case IOSTAT_FABRIC_BSY:
1631 retry = 1;
1632 break;
1633
1634 case IOSTAT_LS_RJT:
1635 stat.un.lsRjtError = be32_to_cpu(irsp->un.ulpWord[4]);
1636 /* Added for Vendor specifc support
1637 * Just keep retrying for these Rsn / Exp codes
1638 */
1639 switch (stat.un.b.lsRjtRsnCode) {
1640 case LSRJT_UNABLE_TPC:
1641 if (stat.un.b.lsRjtRsnCodeExp ==
1642 LSEXP_CMD_IN_PROGRESS) {
1643 if (cmd == ELS_CMD_PLOGI) {
1644 delay = 1;
1645 maxretry = 48;
1646 }
1647 retry = 1;
1648 break;
1649 }
1650 if (cmd == ELS_CMD_PLOGI) {
1651 delay = 1;
1652 maxretry = lpfc_max_els_tries + 1;
1653 retry = 1;
1654 break;
1655 }
1656 break;
1657
1658 case LSRJT_LOGICAL_BSY:
1659 if (cmd == ELS_CMD_PLOGI) {
1660 delay = 1;
1661 maxretry = 48;
1662 }
1663 retry = 1;
1664 break;
1665 }
1666 break;
1667
1668 case IOSTAT_INTERMED_RSP:
1669 case IOSTAT_BA_RJT:
1670 break;
1671
1672 default:
1673 break;
1674 }
1675
488d1469 1676 if (did == FDMI_DID)
dea3101e 1677 retry = 1;
dea3101e 1678
1679 if ((++cmdiocb->retry) >= maxretry) {
1680 phba->fc_stat.elsRetryExceeded++;
1681 retry = 0;
1682 }
1683
ed957684
JS
1684 if ((vport->load_flag & FC_UNLOADING) != 0)
1685 retry = 0;
1686
dea3101e 1687 if (retry) {
1688
1689 /* Retry ELS command <elsCmd> to remote NPORT <did> */
1690 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
1691 "%d:0107 Retry ELS command x%x to remote "
1692 "NPORT x%x Data: x%x x%x\n",
1693 phba->brd_no,
488d1469 1694 cmd, did, cmdiocb->retry, delay);
dea3101e 1695
1696 if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) {
1697 /* If discovery / RSCN timer is running, reset it */
2e0fef85
JS
1698 if (timer_pending(&vport->fc_disctmo) ||
1699 (vport->fc_flag & FC_RSCN_MODE))
1700 lpfc_set_disctmo(vport);
dea3101e 1701 }
1702
1703 phba->fc_stat.elsXmitRetry++;
488d1469 1704 if (ndlp && delay) {
dea3101e 1705 phba->fc_stat.elsDelayRetry++;
1706 ndlp->nlp_retry = cmdiocb->retry;
1707
1708 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
2e0fef85 1709 spin_lock_irq(shost->host_lock);
dea3101e 1710 ndlp->nlp_flag |= NLP_DELAY_TMO;
2e0fef85 1711 spin_unlock_irq(shost->host_lock);
dea3101e 1712
5024ab17 1713 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 1714 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
dea3101e 1715 ndlp->nlp_last_elscmd = cmd;
1716
c9f8735b 1717 return 1;
dea3101e 1718 }
1719 switch (cmd) {
1720 case ELS_CMD_FLOGI:
2e0fef85 1721 lpfc_issue_els_flogi(vport, ndlp, cmdiocb->retry);
c9f8735b 1722 return 1;
dea3101e 1723 case ELS_CMD_PLOGI:
488d1469
JS
1724 if (ndlp) {
1725 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 1726 lpfc_nlp_set_state(vport, ndlp,
de0c5b32 1727 NLP_STE_PLOGI_ISSUE);
488d1469 1728 }
2e0fef85 1729 lpfc_issue_els_plogi(vport, did, cmdiocb->retry);
c9f8735b 1730 return 1;
dea3101e 1731 case ELS_CMD_ADISC:
5024ab17 1732 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
1733 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
1734 lpfc_issue_els_adisc(vport, ndlp, cmdiocb->retry);
c9f8735b 1735 return 1;
dea3101e 1736 case ELS_CMD_PRLI:
5024ab17 1737 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
1738 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
1739 lpfc_issue_els_prli(vport, ndlp, cmdiocb->retry);
c9f8735b 1740 return 1;
dea3101e 1741 case ELS_CMD_LOGO:
5024ab17 1742 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
1743 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1744 lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry);
c9f8735b 1745 return 1;
dea3101e 1746 }
1747 }
1748
1749 /* No retry ELS command <elsCmd> to remote NPORT <did> */
1750 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
1751 "%d:0108 No retry ELS command x%x to remote NPORT x%x "
488d1469 1752 "Data: x%x\n",
dea3101e 1753 phba->brd_no,
488d1469 1754 cmd, did, cmdiocb->retry);
dea3101e 1755
c9f8735b 1756 return 0;
dea3101e 1757}
1758
1759int
329f9bc7 1760lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
dea3101e 1761{
1762 struct lpfc_dmabuf *buf_ptr, *buf_ptr1;
1763
329f9bc7
JS
1764 if (elsiocb->context1) {
1765 lpfc_nlp_put(elsiocb->context1);
1766 elsiocb->context1 = NULL;
1767 }
dea3101e 1768 /* context2 = cmd, context2->next = rsp, context3 = bpl */
1769 if (elsiocb->context2) {
1770 buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2;
1771 /* Free the response before processing the command. */
1772 if (!list_empty(&buf_ptr1->list)) {
1773 list_remove_head(&buf_ptr1->list, buf_ptr,
1774 struct lpfc_dmabuf,
1775 list);
1776 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
1777 kfree(buf_ptr);
1778 }
1779 lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys);
1780 kfree(buf_ptr1);
1781 }
1782
1783 if (elsiocb->context3) {
1784 buf_ptr = (struct lpfc_dmabuf *) elsiocb->context3;
1785 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
1786 kfree(buf_ptr);
1787 }
604a3e30 1788 lpfc_sli_release_iocbq(phba, elsiocb);
dea3101e 1789 return 0;
1790}
1791
1792static void
2e0fef85
JS
1793lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1794 struct lpfc_iocbq *rspiocb)
dea3101e 1795{
2e0fef85
JS
1796 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
1797 struct lpfc_vport *vport = cmdiocb->vport;
dea3101e 1798
1799 /* ACC to LOGO completes to NPort <nlp_DID> */
1800 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
1801 "%d:0109 ACC to LOGO completes to NPort x%x "
1802 "Data: x%x x%x x%x\n",
1803 phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
1804 ndlp->nlp_state, ndlp->nlp_rpi);
1805
dea3101e 1806 switch (ndlp->nlp_state) {
1807 case NLP_STE_UNUSED_NODE: /* node is just allocated */
2e0fef85 1808 lpfc_drop_node(vport, ndlp);
dea3101e 1809 break;
1810 case NLP_STE_NPR_NODE: /* NPort Recovery mode */
2e0fef85 1811 lpfc_unreg_rpi(vport, ndlp);
dea3101e 1812 break;
1813 default:
1814 break;
1815 }
1816 lpfc_els_free_iocb(phba, cmdiocb);
1817 return;
1818}
1819
1820static void
329f9bc7
JS
1821lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1822 struct lpfc_iocbq *rspiocb)
dea3101e 1823{
2e0fef85
JS
1824 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
1825 struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL;
1826 struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
33ccf8d1 1827 IOCB_t *irsp;
dea3101e 1828 LPFC_MBOXQ_t *mbox = NULL;
2e0fef85 1829 struct lpfc_dmabuf *mp = NULL;
dea3101e 1830
33ccf8d1
JS
1831 irsp = &rspiocb->iocb;
1832
dea3101e 1833 if (cmdiocb->context_un.mbox)
1834 mbox = cmdiocb->context_un.mbox;
1835
dea3101e 1836 /* Check to see if link went down during discovery */
2e0fef85 1837 if (!ndlp || lpfc_els_chk_latt(vport)) {
dea3101e 1838 if (mbox) {
14691150
JS
1839 mp = (struct lpfc_dmabuf *) mbox->context1;
1840 if (mp) {
1841 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1842 kfree(mp);
1843 }
329f9bc7 1844 mempool_free(mbox, phba->mbox_mem_pool);
dea3101e 1845 }
1846 goto out;
1847 }
1848
1849 /* ELS response tag <ulpIoTag> completes */
1850 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
1851 "%d:0110 ELS response tag x%x completes "
c9f8735b 1852 "Data: x%x x%x x%x x%x x%x x%x x%x\n",
dea3101e 1853 phba->brd_no,
1854 cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus,
c9f8735b 1855 rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout,
2e0fef85 1856 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
c9f8735b 1857 ndlp->nlp_rpi);
dea3101e 1858
1859 if (mbox) {
1860 if ((rspiocb->iocb.ulpStatus == 0)
1861 && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) {
2e0fef85 1862 lpfc_unreg_rpi(vport, ndlp);
dea3101e 1863 mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
329f9bc7 1864 mbox->context2 = lpfc_nlp_get(ndlp);
2e0fef85 1865 mbox->vport = vport;
5024ab17 1866 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
1867 lpfc_nlp_set_state(vport, ndlp,
1868 NLP_STE_REG_LOGIN_ISSUE);
dea3101e 1869 if (lpfc_sli_issue_mbox(phba, mbox,
1870 (MBX_NOWAIT | MBX_STOP_IOCB))
1871 != MBX_NOT_FINISHED) {
1872 goto out;
1873 }
329f9bc7 1874 lpfc_nlp_put(ndlp);
dea3101e 1875 /* NOTE: we should have messages for unsuccessful
1876 reglogin */
dea3101e 1877 } else {
33ccf8d1
JS
1878 /* Do not call NO_LIST for lpfc_els_abort'ed ELS cmds */
1879 if (!((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
1880 ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
1881 (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
1882 (irsp->un.ulpWord[4] == IOERR_SLI_DOWN)))) {
1883 if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
2e0fef85 1884 lpfc_drop_node(vport, ndlp);
33ccf8d1
JS
1885 ndlp = NULL;
1886 }
dea3101e 1887 }
1888 }
14691150
JS
1889 mp = (struct lpfc_dmabuf *) mbox->context1;
1890 if (mp) {
1891 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1892 kfree(mp);
1893 }
1894 mempool_free(mbox, phba->mbox_mem_pool);
dea3101e 1895 }
1896out:
1897 if (ndlp) {
2e0fef85 1898 spin_lock_irq(shost->host_lock);
dea3101e 1899 ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN;
2e0fef85 1900 spin_unlock_irq(shost->host_lock);
dea3101e 1901 }
1902 lpfc_els_free_iocb(phba, cmdiocb);
1903 return;
1904}
1905
1906int
2e0fef85
JS
1907lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
1908 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
1909 LPFC_MBOXQ_t *mbox, uint8_t newnode)
dea3101e 1910{
2e0fef85
JS
1911 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1912 struct lpfc_hba *phba = vport->phba;
dea3101e 1913 IOCB_t *icmd;
1914 IOCB_t *oldcmd;
1915 struct lpfc_iocbq *elsiocb;
1916 struct lpfc_sli_ring *pring;
1917 struct lpfc_sli *psli;
1918 uint8_t *pcmd;
1919 uint16_t cmdsize;
1920 int rc;
82d9a2a2 1921 ELS_PKT *els_pkt_ptr;
dea3101e 1922
1923 psli = &phba->sli;
1924 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
1925 oldcmd = &oldiocb->iocb;
1926
1927 switch (flag) {
1928 case ELS_CMD_ACC:
1929 cmdsize = sizeof (uint32_t);
2e0fef85
JS
1930 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
1931 ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
488d1469 1932 if (!elsiocb) {
2e0fef85 1933 spin_lock_irq(shost->host_lock);
5024ab17 1934 ndlp->nlp_flag &= ~NLP_LOGO_ACC;
2e0fef85 1935 spin_unlock_irq(shost->host_lock);
c9f8735b 1936 return 1;
dea3101e 1937 }
2e0fef85 1938
dea3101e 1939 icmd = &elsiocb->iocb;
1940 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
1941 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1942 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
1943 pcmd += sizeof (uint32_t);
1944 break;
1945 case ELS_CMD_PLOGI:
1946 cmdsize = (sizeof (struct serv_parm) + sizeof (uint32_t));
2e0fef85
JS
1947 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
1948 ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
488d1469 1949 if (!elsiocb)
c9f8735b 1950 return 1;
488d1469 1951
dea3101e 1952 icmd = &elsiocb->iocb;
1953 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
1954 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1955
1956 if (mbox)
1957 elsiocb->context_un.mbox = mbox;
1958
1959 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
1960 pcmd += sizeof (uint32_t);
2e0fef85 1961 memcpy(pcmd, &vport->fc_sparam, sizeof (struct serv_parm));
dea3101e 1962 break;
82d9a2a2
JS
1963 case ELS_CMD_PRLO:
1964 cmdsize = sizeof (uint32_t) + sizeof (PRLO);
2e0fef85 1965 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
82d9a2a2
JS
1966 ndlp, ndlp->nlp_DID, ELS_CMD_PRLO);
1967 if (!elsiocb)
1968 return 1;
1969
1970 icmd = &elsiocb->iocb;
1971 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
1972 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1973
1974 memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt,
1975 sizeof (uint32_t) + sizeof (PRLO));
1976 *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC;
1977 els_pkt_ptr = (ELS_PKT *) pcmd;
1978 els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
1979 break;
dea3101e 1980 default:
c9f8735b 1981 return 1;
dea3101e 1982 }
1983
329f9bc7
JS
1984 if (newnode) {
1985 lpfc_nlp_put(ndlp);
dea3101e 1986 elsiocb->context1 = NULL;
329f9bc7 1987 }
dea3101e 1988
1989 /* Xmit ELS ACC response tag <ulpIoTag> */
1990 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
1dcb58e5
JS
1991 "%d:0128 Xmit ELS ACC response tag x%x, XRI: x%x, "
1992 "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n",
1993 phba->brd_no, elsiocb->iotag,
dea3101e 1994 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
1995 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
1996
1997 if (ndlp->nlp_flag & NLP_LOGO_ACC) {
2e0fef85 1998 spin_lock_irq(shost->host_lock);
c9f8735b 1999 ndlp->nlp_flag &= ~NLP_LOGO_ACC;
2e0fef85 2000 spin_unlock_irq(shost->host_lock);
dea3101e 2001 elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc;
2002 } else {
2003 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
2004 }
2005
2006 phba->fc_stat.elsXmitACC++;
dea3101e 2007 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e 2008 if (rc == IOCB_ERROR) {
2009 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 2010 return 1;
dea3101e 2011 }
c9f8735b 2012 return 0;
dea3101e 2013}
2014
2015int
2e0fef85
JS
2016lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
2017 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
dea3101e 2018{
2e0fef85 2019 struct lpfc_hba *phba = vport->phba;
dea3101e 2020 IOCB_t *icmd;
2021 IOCB_t *oldcmd;
2022 struct lpfc_iocbq *elsiocb;
2023 struct lpfc_sli_ring *pring;
2024 struct lpfc_sli *psli;
2025 uint8_t *pcmd;
2026 uint16_t cmdsize;
2027 int rc;
2028
2029 psli = &phba->sli;
2030 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
2031
2032 cmdsize = 2 * sizeof (uint32_t);
2e0fef85
JS
2033 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
2034 ndlp->nlp_DID, ELS_CMD_LS_RJT);
488d1469 2035 if (!elsiocb)
c9f8735b 2036 return 1;
dea3101e 2037
2038 icmd = &elsiocb->iocb;
2039 oldcmd = &oldiocb->iocb;
2040 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2041 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2042
2043 *((uint32_t *) (pcmd)) = ELS_CMD_LS_RJT;
2044 pcmd += sizeof (uint32_t);
2045 *((uint32_t *) (pcmd)) = rejectError;
2046
2047 /* Xmit ELS RJT <err> response tag <ulpIoTag> */
2048 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
5b8bd0c9
JS
2049 "%d:0129 Xmit ELS RJT x%x response tag x%x xri x%x, "
2050 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
2051 phba->brd_no, rejectError, elsiocb->iotag,
dea3101e 2052 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2053 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2054
2055 phba->fc_stat.elsXmitLSRJT++;
2056 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
dea3101e 2057 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e 2058 if (rc == IOCB_ERROR) {
2059 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 2060 return 1;
dea3101e 2061 }
c9f8735b 2062 return 0;
dea3101e 2063}
2064
2065int
2e0fef85
JS
2066lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
2067 struct lpfc_nodelist *ndlp)
dea3101e 2068{
2e0fef85
JS
2069 struct lpfc_hba *phba = vport->phba;
2070 struct lpfc_sli *psli = &phba->sli;
2071 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
dea3101e 2072 ADISC *ap;
2e0fef85 2073 IOCB_t *icmd, *oldcmd;
dea3101e 2074 struct lpfc_iocbq *elsiocb;
dea3101e 2075 uint8_t *pcmd;
2076 uint16_t cmdsize;
2077 int rc;
2078
dea3101e 2079 cmdsize = sizeof (uint32_t) + sizeof (ADISC);
2e0fef85
JS
2080 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
2081 ndlp->nlp_DID, ELS_CMD_ACC);
488d1469 2082 if (!elsiocb)
c9f8735b 2083 return 1;
dea3101e 2084
5b8bd0c9
JS
2085 icmd = &elsiocb->iocb;
2086 oldcmd = &oldiocb->iocb;
2087 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2088
dea3101e 2089 /* Xmit ADISC ACC response tag <ulpIoTag> */
2090 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
5b8bd0c9
JS
2091 "%d:0130 Xmit ADISC ACC response iotag x%x xri: "
2092 "x%x, did x%x, nlp_flag x%x, nlp_state x%x rpi x%x\n",
2093 phba->brd_no, elsiocb->iotag,
dea3101e 2094 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2095 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2096
dea3101e 2097 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2098
2099 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
2100 pcmd += sizeof (uint32_t);
2101
2102 ap = (ADISC *) (pcmd);
2103 ap->hardAL_PA = phba->fc_pref_ALPA;
2e0fef85
JS
2104 memcpy(&ap->portName, &vport->fc_portname, sizeof (struct lpfc_name));
2105 memcpy(&ap->nodeName, &vport->fc_nodename, sizeof (struct lpfc_name));
2106 ap->DID = be32_to_cpu(vport->fc_myDID);
dea3101e 2107
2108 phba->fc_stat.elsXmitACC++;
2109 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
dea3101e 2110 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e 2111 if (rc == IOCB_ERROR) {
2112 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 2113 return 1;
dea3101e 2114 }
c9f8735b 2115 return 0;
dea3101e 2116}
2117
2118int
2e0fef85 2119lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
5b8bd0c9 2120 struct lpfc_nodelist *ndlp)
dea3101e 2121{
2e0fef85 2122 struct lpfc_hba *phba = vport->phba;
dea3101e 2123 PRLI *npr;
2124 lpfc_vpd_t *vpd;
2125 IOCB_t *icmd;
2126 IOCB_t *oldcmd;
2127 struct lpfc_iocbq *elsiocb;
2128 struct lpfc_sli_ring *pring;
2129 struct lpfc_sli *psli;
2130 uint8_t *pcmd;
2131 uint16_t cmdsize;
2132 int rc;
2133
2134 psli = &phba->sli;
2135 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
2136
2137 cmdsize = sizeof (uint32_t) + sizeof (PRLI);
2e0fef85 2138 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
ed957684 2139 ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)));
c9f8735b
JW
2140 if (!elsiocb)
2141 return 1;
dea3101e 2142
5b8bd0c9
JS
2143 icmd = &elsiocb->iocb;
2144 oldcmd = &oldiocb->iocb;
2145 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2146
dea3101e 2147 /* Xmit PRLI ACC response tag <ulpIoTag> */
2148 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
5b8bd0c9
JS
2149 "%d:0131 Xmit PRLI ACC response tag x%x xri x%x, "
2150 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
2151 phba->brd_no, elsiocb->iotag,
dea3101e 2152 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2153 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2154
dea3101e 2155 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2156
2157 *((uint32_t *) (pcmd)) = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK));
2158 pcmd += sizeof (uint32_t);
2159
2160 /* For PRLI, remainder of payload is PRLI parameter page */
2161 memset(pcmd, 0, sizeof (PRLI));
2162
2163 npr = (PRLI *) pcmd;
2164 vpd = &phba->vpd;
2165 /*
2166 * If our firmware version is 3.20 or later,
2167 * set the following bits for FC-TAPE support.
2168 */
2169 if (vpd->rev.feaLevelHigh >= 0x02) {
2170 npr->ConfmComplAllowed = 1;
2171 npr->Retry = 1;
2172 npr->TaskRetryIdReq = 1;
2173 }
2174
2175 npr->acceptRspCode = PRLI_REQ_EXECUTED;
2176 npr->estabImagePair = 1;
2177 npr->readXferRdyDis = 1;
2178 npr->ConfmComplAllowed = 1;
2179
2180 npr->prliType = PRLI_FCP_TYPE;
2181 npr->initiatorFunc = 1;
2182
2183 phba->fc_stat.elsXmitACC++;
2184 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
2185
dea3101e 2186 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e 2187 if (rc == IOCB_ERROR) {
2188 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 2189 return 1;
dea3101e 2190 }
c9f8735b 2191 return 0;
dea3101e 2192}
2193
2194static int
2e0fef85 2195lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
329f9bc7 2196 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
dea3101e 2197{
2e0fef85 2198 struct lpfc_hba *phba = vport->phba;
dea3101e 2199 RNID *rn;
2e0fef85 2200 IOCB_t *icmd, *oldcmd;
dea3101e 2201 struct lpfc_iocbq *elsiocb;
2202 struct lpfc_sli_ring *pring;
2203 struct lpfc_sli *psli;
2204 uint8_t *pcmd;
2205 uint16_t cmdsize;
2206 int rc;
2207
2208 psli = &phba->sli;
2209 pring = &psli->ring[LPFC_ELS_RING];
2210
2211 cmdsize = sizeof (uint32_t) + sizeof (uint32_t)
2212 + (2 * sizeof (struct lpfc_name));
2213 if (format)
2214 cmdsize += sizeof (RNID_TOP_DISC);
2215
2e0fef85
JS
2216 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
2217 ndlp->nlp_DID, ELS_CMD_ACC);
488d1469 2218 if (!elsiocb)
c9f8735b 2219 return 1;
dea3101e 2220
5b8bd0c9
JS
2221 icmd = &elsiocb->iocb;
2222 oldcmd = &oldiocb->iocb;
2223 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2224
dea3101e 2225 /* Xmit RNID ACC response tag <ulpIoTag> */
2226 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
2227 "%d:0132 Xmit RNID ACC response tag x%x "
5b8bd0c9
JS
2228 "xri x%x\n",
2229 phba->brd_no, elsiocb->iotag,
dea3101e 2230 elsiocb->iocb.ulpContext);
2231
dea3101e 2232 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2233
2234 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
2235 pcmd += sizeof (uint32_t);
2236
2237 memset(pcmd, 0, sizeof (RNID));
2238 rn = (RNID *) (pcmd);
2239 rn->Format = format;
2240 rn->CommonLen = (2 * sizeof (struct lpfc_name));
2e0fef85
JS
2241 memcpy(&rn->portName, &vport->fc_portname, sizeof (struct lpfc_name));
2242 memcpy(&rn->nodeName, &vport->fc_nodename, sizeof (struct lpfc_name));
dea3101e 2243 switch (format) {
2244 case 0:
2245 rn->SpecificLen = 0;
2246 break;
2247 case RNID_TOPOLOGY_DISC:
2248 rn->SpecificLen = sizeof (RNID_TOP_DISC);
2249 memcpy(&rn->un.topologyDisc.portName,
2e0fef85 2250 &vport->fc_portname, sizeof (struct lpfc_name));
dea3101e 2251 rn->un.topologyDisc.unitType = RNID_HBA;
2252 rn->un.topologyDisc.physPort = 0;
2253 rn->un.topologyDisc.attachedNodes = 0;
2254 break;
2255 default:
2256 rn->CommonLen = 0;
2257 rn->SpecificLen = 0;
2258 break;
2259 }
2260
2261 phba->fc_stat.elsXmitACC++;
2262 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
329f9bc7 2263 lpfc_nlp_put(ndlp);
dea3101e 2264 elsiocb->context1 = NULL; /* Don't need ndlp for cmpl,
2265 * it could be freed */
2266
dea3101e 2267 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
dea3101e 2268 if (rc == IOCB_ERROR) {
2269 lpfc_els_free_iocb(phba, elsiocb);
c9f8735b 2270 return 1;
dea3101e 2271 }
c9f8735b 2272 return 0;
dea3101e 2273}
2274
2275int
2e0fef85 2276lpfc_els_disc_adisc(struct lpfc_vport *vport)
dea3101e 2277{
2e0fef85 2278 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 2279 struct lpfc_nodelist *ndlp, *next_ndlp;
2e0fef85 2280 int sentadisc = 0;
dea3101e 2281
685f0bf7 2282 /* go thru NPR nodes and issue any remaining ELS ADISCs */
2e0fef85 2283 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
685f0bf7
JS
2284 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
2285 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
2286 (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) {
2e0fef85 2287 spin_lock_irq(shost->host_lock);
685f0bf7 2288 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2e0fef85 2289 spin_unlock_irq(shost->host_lock);
685f0bf7 2290 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
2291 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2292 lpfc_issue_els_adisc(vport, ndlp, 0);
685f0bf7 2293 sentadisc++;
2e0fef85
JS
2294 vport->num_disc_nodes++;
2295 if (vport->num_disc_nodes >=
2296 vport->phba->cfg_discovery_threads) {
2297 spin_lock_irq(shost->host_lock);
2298 vport->fc_flag |= FC_NLP_MORE;
2299 spin_unlock_irq(shost->host_lock);
685f0bf7 2300 break;
dea3101e 2301 }
2302 }
2303 }
2304 if (sentadisc == 0) {
2e0fef85
JS
2305 spin_lock_irq(shost->host_lock);
2306 vport->fc_flag &= ~FC_NLP_MORE;
2307 spin_unlock_irq(shost->host_lock);
dea3101e 2308 }
2fe165b6 2309 return sentadisc;
dea3101e 2310}
2311
2312int
2e0fef85 2313lpfc_els_disc_plogi(struct lpfc_vport *vport)
dea3101e 2314{
2e0fef85 2315 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 2316 struct lpfc_nodelist *ndlp, *next_ndlp;
2e0fef85 2317 int sentplogi = 0;
dea3101e 2318
2e0fef85
JS
2319 /* go thru NPR nodes and issue any remaining ELS PLOGIs */
2320 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
685f0bf7
JS
2321 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
2322 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
2323 (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 &&
2324 (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) {
2325 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
2326 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2327 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
685f0bf7 2328 sentplogi++;
2e0fef85
JS
2329 vport->num_disc_nodes++;
2330 if (vport->num_disc_nodes >=
2331 vport->phba->cfg_discovery_threads) {
2332 spin_lock_irq(shost->host_lock);
2333 vport->fc_flag |= FC_NLP_MORE;
2334 spin_unlock_irq(shost->host_lock);
685f0bf7 2335 break;
dea3101e 2336 }
2337 }
2338 }
2339 if (sentplogi == 0) {
2e0fef85
JS
2340 spin_lock_irq(shost->host_lock);
2341 vport->fc_flag &= ~FC_NLP_MORE;
2342 spin_unlock_irq(shost->host_lock);
dea3101e 2343 }
2fe165b6 2344 return sentplogi;
dea3101e 2345}
2346
2347int
2e0fef85 2348lpfc_els_flush_rscn(struct lpfc_vport *vport)
dea3101e 2349{
2e0fef85
JS
2350 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2351 struct lpfc_hba *phba = vport->phba;
dea3101e 2352 struct lpfc_dmabuf *mp;
2353 int i;
2354
2e0fef85
JS
2355 for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
2356 mp = vport->fc_rscn_id_list[i];
ed957684
JS
2357 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
2358 lpfc_sli_hbqbuf_free(phba, mp->virt, mp->phys);
2359 else {
2360 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2361 kfree(mp);
2362 }
2e0fef85 2363 vport->fc_rscn_id_list[i] = NULL;
dea3101e 2364 }
2e0fef85
JS
2365 spin_lock_irq(shost->host_lock);
2366 vport->fc_rscn_id_cnt = 0;
2367 vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY);
2368 spin_unlock_irq(shost->host_lock);
2369 lpfc_can_disctmo(vport);
c9f8735b 2370 return 0;
dea3101e 2371}
2372
2373int
2e0fef85 2374lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
dea3101e 2375{
2376 D_ID ns_did;
2377 D_ID rscn_did;
2378 struct lpfc_dmabuf *mp;
2379 uint32_t *lp;
2380 uint32_t payload_len, cmd, i, match;
2e0fef85 2381 struct lpfc_hba *phba = vport->phba;
dea3101e 2382
2383 ns_did.un.word = did;
2384 match = 0;
2385
2386 /* Never match fabric nodes for RSCNs */
2387 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
2e0fef85 2388 return 0;
dea3101e 2389
2390 /* If we are doing a FULL RSCN rediscovery, match everything */
2e0fef85 2391 if (vport->fc_flag & FC_RSCN_DISCOVERY)
c9f8735b 2392 return did;
dea3101e 2393
2e0fef85
JS
2394 for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
2395 mp = vport->fc_rscn_id_list[i];
dea3101e 2396 lp = (uint32_t *) mp->virt;
2397 cmd = *lp++;
2398 payload_len = be32_to_cpu(cmd) & 0xffff; /* payload length */
2399 payload_len -= sizeof (uint32_t); /* take off word 0 */
2400 while (payload_len) {
2401 rscn_did.un.word = *lp++;
2402 rscn_did.un.word = be32_to_cpu(rscn_did.un.word);
2403 payload_len -= sizeof (uint32_t);
2404 switch (rscn_did.un.b.resv) {
2405 case 0: /* Single N_Port ID effected */
2e0fef85 2406 if (ns_did.un.word == rscn_did.un.word)
dea3101e 2407 match = did;
dea3101e 2408 break;
2409 case 1: /* Whole N_Port Area effected */
2410 if ((ns_did.un.b.domain == rscn_did.un.b.domain)
2411 && (ns_did.un.b.area == rscn_did.un.b.area))
dea3101e 2412 match = did;
dea3101e 2413 break;
2414 case 2: /* Whole N_Port Domain effected */
2415 if (ns_did.un.b.domain == rscn_did.un.b.domain)
dea3101e 2416 match = did;
dea3101e 2417 break;
2418 case 3: /* Whole Fabric effected */
2419 match = did;
2420 break;
2421 default:
2e0fef85 2422 /* Unknown Identifier in RSCN node */
dea3101e 2423 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
2424 "%d:0217 Unknown Identifier in "
2425 "RSCN payload Data: x%x\n",
2426 phba->brd_no, rscn_did.un.word);
2427 break;
2428 }
2e0fef85 2429 if (match)
dea3101e 2430 break;
2431 }
2432 }
c9f8735b 2433 return match;
dea3101e 2434}
2435
2436static int
2e0fef85 2437lpfc_rscn_recovery_check(struct lpfc_vport *vport)
dea3101e 2438{
685f0bf7 2439 struct lpfc_nodelist *ndlp = NULL;
dea3101e 2440
2441 /* Look at all nodes effected by pending RSCNs and move
685f0bf7 2442 * them to NPR state.
dea3101e 2443 */
dea3101e 2444
2e0fef85 2445 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
685f0bf7 2446 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE ||
2e0fef85 2447 lpfc_rscn_payload_check(vport, ndlp->nlp_DID) == 0)
685f0bf7 2448 continue;
dea3101e 2449
2e0fef85 2450 lpfc_disc_state_machine(vport, ndlp, NULL,
dea3101e 2451 NLP_EVT_DEVICE_RECOVERY);
5024ab17 2452
685f0bf7
JS
2453 /*
2454 * Make sure NLP_DELAY_TMO is NOT running after a device
2455 * recovery event.
2456 */
2457 if (ndlp->nlp_flag & NLP_DELAY_TMO)
2e0fef85 2458 lpfc_cancel_retry_delay_tmo(vport, ndlp);
dea3101e 2459 }
685f0bf7 2460
c9f8735b 2461 return 0;
dea3101e 2462}
2463
2464static int
2e0fef85
JS
2465lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2466 struct lpfc_nodelist *ndlp, uint8_t newnode)
dea3101e 2467{
2e0fef85
JS
2468 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2469 struct lpfc_hba *phba = vport->phba;
dea3101e 2470 struct lpfc_dmabuf *pcmd;
2471 uint32_t *lp;
2472 IOCB_t *icmd;
2473 uint32_t payload_len, cmd;
d2873e4c 2474 int i;
dea3101e 2475
2476 icmd = &cmdiocb->iocb;
2477 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
2478 lp = (uint32_t *) pcmd->virt;
2479
2480 cmd = *lp++;
2481 payload_len = be32_to_cpu(cmd) & 0xffff; /* payload length */
2482 payload_len -= sizeof (uint32_t); /* take off word 0 */
2483 cmd &= ELS_CMD_MASK;
2484
2485 /* RSCN received */
ed957684 2486 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
dea3101e 2487 "%d:0214 RSCN received Data: x%x x%x x%x x%x\n",
2e0fef85
JS
2488 phba->brd_no, vport->fc_flag, payload_len, *lp,
2489 vport->fc_rscn_id_cnt);
dea3101e 2490
d2873e4c 2491 for (i = 0; i < payload_len/sizeof(uint32_t); i++)
2e0fef85 2492 fc_host_post_event(shost, fc_get_event_number(),
d2873e4c
JS
2493 FCH_EVT_RSCN, lp[i]);
2494
dea3101e 2495 /* If we are about to begin discovery, just ACC the RSCN.
2496 * Discovery processing will satisfy it.
2497 */
2e0fef85
JS
2498 if (vport->port_state <= LPFC_NS_QRY) {
2499 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
dea3101e 2500 newnode);
c9f8735b 2501 return 0;
dea3101e 2502 }
2503
2504 /* If we are already processing an RSCN, save the received
2505 * RSCN payload buffer, cmdiocb->context2 to process later.
2506 */
2e0fef85
JS
2507 if (vport->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) {
2508 if ((vport->fc_rscn_id_cnt < FC_MAX_HOLD_RSCN) &&
2509 !(vport->fc_flag & FC_RSCN_DISCOVERY)) {
2510 spin_lock_irq(shost->host_lock);
2511 vport->fc_flag |= FC_RSCN_MODE;
2512 spin_unlock_irq(shost->host_lock);
2513 vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd;
dea3101e 2514
2515 /* If we zero, cmdiocb->context2, the calling
2516 * routine will not try to free it.
2517 */
2518 cmdiocb->context2 = NULL;
2519
2520 /* Deferred RSCN */
2521 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
2522 "%d:0235 Deferred RSCN "
2523 "Data: x%x x%x x%x\n",
2e0fef85
JS
2524 phba->brd_no, vport->fc_rscn_id_cnt,
2525 vport->fc_flag,
2526 vport->port_state);
dea3101e 2527 } else {
2e0fef85
JS
2528 spin_lock_irq(shost->host_lock);
2529 vport->fc_flag |= FC_RSCN_DISCOVERY;
2530 spin_unlock_irq(shost->host_lock);
dea3101e 2531 /* ReDiscovery RSCN */
2532 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
2533 "%d:0234 ReDiscovery RSCN "
2534 "Data: x%x x%x x%x\n",
2e0fef85
JS
2535 phba->brd_no, vport->fc_rscn_id_cnt,
2536 vport->fc_flag,
2537 vport->port_state);
dea3101e 2538 }
2539 /* Send back ACC */
2e0fef85 2540 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
dea3101e 2541 newnode);
2542
2543 /* send RECOVERY event for ALL nodes that match RSCN payload */
2e0fef85 2544 lpfc_rscn_recovery_check(vport);
c9f8735b 2545 return 0;
dea3101e 2546 }
2547
2e0fef85
JS
2548 spin_lock_irq(shost->host_lock);
2549 vport->fc_flag |= FC_RSCN_MODE;
2550 spin_unlock_irq(shost->host_lock);
2551 vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd;
dea3101e 2552 /*
2553 * If we zero, cmdiocb->context2, the calling routine will
2554 * not try to free it.
2555 */
2556 cmdiocb->context2 = NULL;
2557
2e0fef85 2558 lpfc_set_disctmo(vport);
dea3101e 2559
2560 /* Send back ACC */
2e0fef85 2561 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode);
dea3101e 2562
2563 /* send RECOVERY event for ALL nodes that match RSCN payload */
2e0fef85 2564 lpfc_rscn_recovery_check(vport);
dea3101e 2565
2e0fef85 2566 return lpfc_els_handle_rscn(vport);
dea3101e 2567}
2568
2569int
2e0fef85 2570lpfc_els_handle_rscn(struct lpfc_vport *vport)
dea3101e 2571{
2572 struct lpfc_nodelist *ndlp;
2e0fef85 2573 struct lpfc_hba *phba = vport->phba;
dea3101e 2574
2575 /* Start timer for RSCN processing */
2e0fef85 2576 lpfc_set_disctmo(vport);
dea3101e 2577
2578 /* RSCN processed */
ed957684 2579 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
dea3101e 2580 "%d:0215 RSCN processed Data: x%x x%x x%x x%x\n",
2581 phba->brd_no,
2e0fef85
JS
2582 vport->fc_flag, 0, vport->fc_rscn_id_cnt,
2583 vport->port_state);
dea3101e 2584
2585 /* To process RSCN, first compare RSCN data with NameServer */
2e0fef85
JS
2586 vport->fc_ns_retry = 0;
2587 ndlp = lpfc_findnode_did(vport, NameServer_DID);
685f0bf7 2588 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
dea3101e 2589 /* Good ndlp, issue CT Request to NameServer */
2e0fef85 2590 if (lpfc_ns_cmd(vport, ndlp, SLI_CTNS_GID_FT) == 0)
dea3101e 2591 /* Wait for NameServer query cmpl before we can
2592 continue */
c9f8735b 2593 return 1;
dea3101e 2594 } else {
2595 /* If login to NameServer does not exist, issue one */
2596 /* Good status, issue PLOGI to NameServer */
2e0fef85
JS
2597 ndlp = lpfc_findnode_did(vport, NameServer_DID);
2598 if (ndlp)
dea3101e 2599 /* Wait for NameServer login cmpl before we can
2600 continue */
c9f8735b 2601 return 1;
2e0fef85 2602
c9f8735b
JW
2603 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
2604 if (!ndlp) {
2e0fef85 2605 lpfc_els_flush_rscn(vport);
c9f8735b 2606 return 0;
dea3101e 2607 } else {
2e0fef85 2608 lpfc_nlp_init(vport, ndlp, NameServer_DID);
dea3101e 2609 ndlp->nlp_type |= NLP_FABRIC;
5024ab17 2610 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85
JS
2611 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2612 lpfc_issue_els_plogi(vport, NameServer_DID, 0);
dea3101e 2613 /* Wait for NameServer login cmpl before we can
2614 continue */
c9f8735b 2615 return 1;
dea3101e 2616 }
2617 }
2618
2e0fef85 2619 lpfc_els_flush_rscn(vport);
c9f8735b 2620 return 0;
dea3101e 2621}
2622
2623static int
2e0fef85
JS
2624lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2625 struct lpfc_nodelist *ndlp, uint8_t newnode)
dea3101e 2626{
2e0fef85
JS
2627 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2628 struct lpfc_hba *phba = vport->phba;
dea3101e 2629 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
2630 uint32_t *lp = (uint32_t *) pcmd->virt;
2631 IOCB_t *icmd = &cmdiocb->iocb;
2632 struct serv_parm *sp;
2633 LPFC_MBOXQ_t *mbox;
2634 struct ls_rjt stat;
2635 uint32_t cmd, did;
2636 int rc;
2637
2638 cmd = *lp++;
2639 sp = (struct serv_parm *) lp;
2640
2641 /* FLOGI received */
2642
2e0fef85 2643 lpfc_set_disctmo(vport);
dea3101e 2644
2645 if (phba->fc_topology == TOPOLOGY_LOOP) {
2646 /* We should never receive a FLOGI in loop mode, ignore it */
2647 did = icmd->un.elsreq64.remoteID;
2648
2649 /* An FLOGI ELS command <elsCmd> was received from DID <did> in
2650 Loop Mode */
2651 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
2652 "%d:0113 An FLOGI ELS command x%x was received "
2653 "from DID x%x in Loop Mode\n",
2654 phba->brd_no, cmd, did);
c9f8735b 2655 return 1;
dea3101e 2656 }
2657
2658 did = Fabric_DID;
2659
2e0fef85 2660 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3))) {
dea3101e 2661 /* For a FLOGI we accept, then if our portname is greater
2662 * then the remote portname we initiate Nport login.
2663 */
2664
2e0fef85 2665 rc = memcmp(&vport->fc_portname, &sp->portName,
dea3101e 2666 sizeof (struct lpfc_name));
2667
2668 if (!rc) {
2e0fef85
JS
2669 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2670 if (!mbox)
c9f8735b 2671 return 1;
2e0fef85 2672
dea3101e 2673 lpfc_linkdown(phba);
2674 lpfc_init_link(phba, mbox,
2675 phba->cfg_topology,
2676 phba->cfg_link_speed);
2677 mbox->mb.un.varInitLnk.lipsr_AL_PA = 0;
2678 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
ed957684 2679 mbox->vport = vport;
dea3101e 2680 rc = lpfc_sli_issue_mbox
2681 (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB));
5b8bd0c9 2682 lpfc_set_loopback_flag(phba);
dea3101e 2683 if (rc == MBX_NOT_FINISHED) {
329f9bc7 2684 mempool_free(mbox, phba->mbox_mem_pool);
dea3101e 2685 }
c9f8735b 2686 return 1;
2fe165b6 2687 } else if (rc > 0) { /* greater than */
2e0fef85
JS
2688 spin_lock_irq(shost->host_lock);
2689 vport->fc_flag |= FC_PT2PT_PLOGI;
2690 spin_unlock_irq(shost->host_lock);
dea3101e 2691 }
2e0fef85
JS
2692 spin_lock_irq(shost->host_lock);
2693 vport->fc_flag |= FC_PT2PT;
2694 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
2695 spin_unlock_irq(shost->host_lock);
dea3101e 2696 } else {
2697 /* Reject this request because invalid parameters */
2698 stat.un.b.lsRjtRsvd0 = 0;
2699 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2700 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
2701 stat.un.b.vendorUnique = 0;
2e0fef85 2702 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
c9f8735b 2703 return 1;
dea3101e 2704 }
2705
2706 /* Send back ACC */
2e0fef85 2707 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode);
dea3101e 2708
c9f8735b 2709 return 0;
dea3101e 2710}
2711
2712static int
2e0fef85
JS
2713lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2714 struct lpfc_nodelist *ndlp)
dea3101e 2715{
2716 struct lpfc_dmabuf *pcmd;
2717 uint32_t *lp;
2718 IOCB_t *icmd;
2719 RNID *rn;
2720 struct ls_rjt stat;
2721 uint32_t cmd, did;
2722
2723 icmd = &cmdiocb->iocb;
2724 did = icmd->un.elsreq64.remoteID;
2725 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
2726 lp = (uint32_t *) pcmd->virt;
2727
2728 cmd = *lp++;
2729 rn = (RNID *) lp;
2730
2731 /* RNID received */
2732
2733 switch (rn->Format) {
2734 case 0:
2735 case RNID_TOPOLOGY_DISC:
2736 /* Send back ACC */
2e0fef85 2737 lpfc_els_rsp_rnid_acc(vport, rn->Format, cmdiocb, ndlp);
dea3101e 2738 break;
2739 default:
2740 /* Reject this request because format not supported */
2741 stat.un.b.lsRjtRsvd0 = 0;
2742 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2743 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
2744 stat.un.b.vendorUnique = 0;
2e0fef85 2745 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
dea3101e 2746 }
c9f8735b 2747 return 0;
dea3101e 2748}
2749
2750static int
2e0fef85
JS
2751lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2752 struct lpfc_nodelist *ndlp)
7bb3b137
JW
2753{
2754 struct ls_rjt stat;
2755
2756 /* For now, unconditionally reject this command */
2757 stat.un.b.lsRjtRsvd0 = 0;
2758 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2759 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
2760 stat.un.b.vendorUnique = 0;
2e0fef85 2761 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
7bb3b137
JW
2762 return 0;
2763}
2764
082c0266 2765static void
329f9bc7 2766lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
7bb3b137 2767{
2e0fef85
JS
2768 struct lpfc_sli *psli = &phba->sli;
2769 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
7bb3b137
JW
2770 MAILBOX_t *mb;
2771 IOCB_t *icmd;
2772 RPS_RSP *rps_rsp;
2773 uint8_t *pcmd;
2774 struct lpfc_iocbq *elsiocb;
2775 struct lpfc_nodelist *ndlp;
2776 uint16_t xri, status;
2777 uint32_t cmdsize;
2778
7bb3b137
JW
2779 mb = &pmb->mb;
2780
2781 ndlp = (struct lpfc_nodelist *) pmb->context2;
2782 xri = (uint16_t) ((unsigned long)(pmb->context1));
041976fb
RD
2783 pmb->context1 = NULL;
2784 pmb->context2 = NULL;
7bb3b137
JW
2785
2786 if (mb->mbxStatus) {
329f9bc7 2787 mempool_free(pmb, phba->mbox_mem_pool);
7bb3b137
JW
2788 return;
2789 }
2790
2791 cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t);
329f9bc7 2792 mempool_free(pmb, phba->mbox_mem_pool);
2e0fef85
JS
2793 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
2794 lpfc_max_els_tries, ndlp,
2795 ndlp->nlp_DID, ELS_CMD_ACC);
329f9bc7 2796 lpfc_nlp_put(ndlp);
c9f8735b 2797 if (!elsiocb)
7bb3b137 2798 return;
7bb3b137
JW
2799
2800 icmd = &elsiocb->iocb;
2801 icmd->ulpContext = xri;
2802
2803 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2804 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
2805 pcmd += sizeof (uint32_t); /* Skip past command */
2806 rps_rsp = (RPS_RSP *)pcmd;
2807
2808 if (phba->fc_topology != TOPOLOGY_LOOP)
2809 status = 0x10;
2810 else
2811 status = 0x8;
2e0fef85 2812 if (phba->pport->fc_flag & FC_FABRIC)
7bb3b137
JW
2813 status |= 0x4;
2814
2815 rps_rsp->rsvd1 = 0;
2816 rps_rsp->portStatus = be16_to_cpu(status);
2817 rps_rsp->linkFailureCnt = be32_to_cpu(mb->un.varRdLnk.linkFailureCnt);
2818 rps_rsp->lossSyncCnt = be32_to_cpu(mb->un.varRdLnk.lossSyncCnt);
2819 rps_rsp->lossSignalCnt = be32_to_cpu(mb->un.varRdLnk.lossSignalCnt);
2820 rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt);
2821 rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord);
2822 rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt);
2823
2824 /* Xmit ELS RPS ACC response tag <ulpIoTag> */
2825 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
5b8bd0c9
JS
2826 "%d:0118 Xmit ELS RPS ACC response tag x%x xri x%x, "
2827 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
2828 phba->brd_no, elsiocb->iotag,
7bb3b137
JW
2829 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2830 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2831
2832 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
2833 phba->fc_stat.elsXmitACC++;
ed957684 2834 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR)
7bb3b137 2835 lpfc_els_free_iocb(phba, elsiocb);
7bb3b137
JW
2836 return;
2837}
2838
2839static int
2e0fef85
JS
2840lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2841 struct lpfc_nodelist *ndlp)
dea3101e 2842{
2e0fef85 2843 struct lpfc_hba *phba = vport->phba;
dea3101e 2844 uint32_t *lp;
7bb3b137
JW
2845 uint8_t flag;
2846 LPFC_MBOXQ_t *mbox;
2847 struct lpfc_dmabuf *pcmd;
2848 RPS *rps;
2849 struct ls_rjt stat;
2850
2fe165b6
JW
2851 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
2852 (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
7bb3b137
JW
2853 stat.un.b.lsRjtRsvd0 = 0;
2854 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2855 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
2856 stat.un.b.vendorUnique = 0;
2e0fef85 2857 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
7bb3b137
JW
2858 }
2859
2860 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
2861 lp = (uint32_t *) pcmd->virt;
2862 flag = (be32_to_cpu(*lp++) & 0xf);
2863 rps = (RPS *) lp;
2864
2865 if ((flag == 0) ||
2866 ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) ||
2e0fef85 2867 ((flag == 2) && (memcmp(&rps->un.portName, &vport->fc_portname,
7bb3b137 2868 sizeof (struct lpfc_name)) == 0))) {
2e0fef85
JS
2869
2870 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
2871 if (mbox) {
7bb3b137
JW
2872 lpfc_read_lnk_stat(phba, mbox);
2873 mbox->context1 =
2874 (void *)((unsigned long)cmdiocb->iocb.ulpContext);
329f9bc7 2875 mbox->context2 = lpfc_nlp_get(ndlp);
7bb3b137
JW
2876 mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
2877 if (lpfc_sli_issue_mbox (phba, mbox,
2e0fef85 2878 (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED)
7bb3b137
JW
2879 /* Mbox completion will send ELS Response */
2880 return 0;
2e0fef85 2881
329f9bc7 2882 lpfc_nlp_put(ndlp);
7bb3b137
JW
2883 mempool_free(mbox, phba->mbox_mem_pool);
2884 }
2885 }
2886 stat.un.b.lsRjtRsvd0 = 0;
2887 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2888 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
2889 stat.un.b.vendorUnique = 0;
2e0fef85 2890 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
7bb3b137
JW
2891 return 0;
2892}
2893
082c0266 2894static int
2e0fef85
JS
2895lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
2896 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
7bb3b137 2897{
2e0fef85
JS
2898 struct lpfc_hba *phba = vport->phba;
2899 IOCB_t *icmd, *oldcmd;
7bb3b137
JW
2900 RPL_RSP rpl_rsp;
2901 struct lpfc_iocbq *elsiocb;
2e0fef85
JS
2902 struct lpfc_sli *psli = &phba->sli;
2903 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
7bb3b137 2904 uint8_t *pcmd;
dea3101e 2905
2e0fef85
JS
2906 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
2907 ndlp->nlp_DID, ELS_CMD_ACC);
7bb3b137 2908
488d1469 2909 if (!elsiocb)
7bb3b137 2910 return 1;
488d1469 2911
7bb3b137
JW
2912 icmd = &elsiocb->iocb;
2913 oldcmd = &oldiocb->iocb;
2914 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2915
2916 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2917 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
2918 pcmd += sizeof (uint16_t);
2919 *((uint16_t *)(pcmd)) = be16_to_cpu(cmdsize);
2920 pcmd += sizeof(uint16_t);
2921
2922 /* Setup the RPL ACC payload */
2923 rpl_rsp.listLen = be32_to_cpu(1);
2924 rpl_rsp.index = 0;
2925 rpl_rsp.port_num_blk.portNum = 0;
2e0fef85
JS
2926 rpl_rsp.port_num_blk.portID = be32_to_cpu(vport->fc_myDID);
2927 memcpy(&rpl_rsp.port_num_blk.portName, &vport->fc_portname,
7bb3b137
JW
2928 sizeof(struct lpfc_name));
2929
2930 memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t));
2931
2932
2933 /* Xmit ELS RPL ACC response tag <ulpIoTag> */
2934 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
5b8bd0c9
JS
2935 "%d:0120 Xmit ELS RPL ACC response tag x%x xri x%x, "
2936 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
2937 phba->brd_no, elsiocb->iotag,
7bb3b137
JW
2938 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2939 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2940
2941 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
2942
2943 phba->fc_stat.elsXmitACC++;
2944 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2945 lpfc_els_free_iocb(phba, elsiocb);
2946 return 1;
2947 }
2948 return 0;
2949}
2950
2951static int
2e0fef85
JS
2952lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2953 struct lpfc_nodelist *ndlp)
7bb3b137
JW
2954{
2955 struct lpfc_dmabuf *pcmd;
2956 uint32_t *lp;
2957 uint32_t maxsize;
2958 uint16_t cmdsize;
2959 RPL *rpl;
2960 struct ls_rjt stat;
2961
2fe165b6
JW
2962 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
2963 (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
7bb3b137
JW
2964 stat.un.b.lsRjtRsvd0 = 0;
2965 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2966 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
2967 stat.un.b.vendorUnique = 0;
2e0fef85 2968 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp);
7bb3b137
JW
2969 }
2970
dea3101e 2971 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
2972 lp = (uint32_t *) pcmd->virt;
7bb3b137 2973 rpl = (RPL *) (lp + 1);
dea3101e 2974
7bb3b137 2975 maxsize = be32_to_cpu(rpl->maxsize);
dea3101e 2976
7bb3b137
JW
2977 /* We support only one port */
2978 if ((rpl->index == 0) &&
2979 ((maxsize == 0) ||
2980 ((maxsize * sizeof(uint32_t)) >= sizeof(RPL_RSP)))) {
2981 cmdsize = sizeof(uint32_t) + sizeof(RPL_RSP);
2fe165b6 2982 } else {
7bb3b137
JW
2983 cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t);
2984 }
2e0fef85 2985 lpfc_els_rsp_rpl_acc(vport, cmdsize, cmdiocb, ndlp);
dea3101e 2986
2987 return 0;
2988}
2989
2990static int
2e0fef85
JS
2991lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
2992 struct lpfc_nodelist *ndlp)
dea3101e 2993{
2e0fef85 2994 struct lpfc_hba *phba = vport->phba;
dea3101e 2995 struct lpfc_dmabuf *pcmd;
2996 uint32_t *lp;
2997 IOCB_t *icmd;
2998 FARP *fp;
2999 uint32_t cmd, cnt, did;
3000
3001 icmd = &cmdiocb->iocb;
3002 did = icmd->un.elsreq64.remoteID;
3003 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3004 lp = (uint32_t *) pcmd->virt;
3005
3006 cmd = *lp++;
3007 fp = (FARP *) lp;
3008
3009 /* FARP-REQ received from DID <did> */
ed957684 3010 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
dea3101e 3011 "%d:0601 FARP-REQ received from DID x%x\n",
3012 phba->brd_no, did);
3013
3014 /* We will only support match on WWPN or WWNN */
3015 if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) {
c9f8735b 3016 return 0;
dea3101e 3017 }
3018
3019 cnt = 0;
3020 /* If this FARP command is searching for my portname */
3021 if (fp->Mflags & FARP_MATCH_PORT) {
2e0fef85 3022 if (memcmp(&fp->RportName, &vport->fc_portname,
dea3101e 3023 sizeof (struct lpfc_name)) == 0)
3024 cnt = 1;
3025 }
3026
3027 /* If this FARP command is searching for my nodename */
3028 if (fp->Mflags & FARP_MATCH_NODE) {
2e0fef85 3029 if (memcmp(&fp->RnodeName, &vport->fc_nodename,
dea3101e 3030 sizeof (struct lpfc_name)) == 0)
3031 cnt = 1;
3032 }
3033
3034 if (cnt) {
3035 if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
3036 (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) {
3037 /* Log back into the node before sending the FARP. */
3038 if (fp->Rflags & FARP_REQUEST_PLOGI) {
5024ab17 3039 ndlp->nlp_prev_state = ndlp->nlp_state;
2e0fef85 3040 lpfc_nlp_set_state(vport, ndlp,
de0c5b32 3041 NLP_STE_PLOGI_ISSUE);
2e0fef85 3042 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
dea3101e 3043 }
3044
3045 /* Send a FARP response to that node */
2e0fef85
JS
3046 if (fp->Rflags & FARP_REQUEST_FARPR)
3047 lpfc_issue_els_farpr(vport, did, 0);
dea3101e 3048 }
3049 }
c9f8735b 3050 return 0;
dea3101e 3051}
3052
3053static int
2e0fef85
JS
3054lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3055 struct lpfc_nodelist *ndlp)
dea3101e 3056{
3057 struct lpfc_dmabuf *pcmd;
3058 uint32_t *lp;
3059 IOCB_t *icmd;
3060 uint32_t cmd, did;
2e0fef85 3061 struct lpfc_hba *phba = vport->phba;
dea3101e 3062
3063 icmd = &cmdiocb->iocb;
3064 did = icmd->un.elsreq64.remoteID;
3065 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3066 lp = (uint32_t *) pcmd->virt;
3067
3068 cmd = *lp++;
3069 /* FARP-RSP received from DID <did> */
ed957684 3070 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
dea3101e 3071 "%d:0600 FARP-RSP received from DID x%x\n",
3072 phba->brd_no, did);
dea3101e 3073 /* ACCEPT the Farp resp request */
2e0fef85 3074 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
dea3101e 3075
3076 return 0;
3077}
3078
3079static int
2e0fef85
JS
3080lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3081 struct lpfc_nodelist *fan_ndlp)
dea3101e 3082{
3083 struct lpfc_dmabuf *pcmd;
3084 uint32_t *lp;
3085 IOCB_t *icmd;
dea3101e 3086 uint32_t cmd, did;
5024ab17
JW
3087 FAN *fp;
3088 struct lpfc_nodelist *ndlp, *next_ndlp;
2e0fef85 3089 struct lpfc_hba *phba = vport->phba;
5024ab17
JW
3090
3091 /* FAN received */
ed957684
JS
3092 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
3093 "%d:0265 FAN received\n",
3094 phba->brd_no);
dea3101e 3095
3096 icmd = &cmdiocb->iocb;
3097 did = icmd->un.elsreq64.remoteID;
5024ab17
JW
3098 pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
3099 lp = (uint32_t *)pcmd->virt;
dea3101e 3100
3101 cmd = *lp++;
5024ab17 3102 fp = (FAN *)lp;
dea3101e 3103
5024ab17 3104 /* FAN received; Fan does not have a reply sequence */
dea3101e 3105
2e0fef85 3106 if (phba->pport->port_state == LPFC_LOCAL_CFG_LINK) {
5024ab17
JW
3107 if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName,
3108 sizeof(struct lpfc_name)) != 0) ||
3109 (memcmp(&phba->fc_fabparam.portName, &fp->FportName,
3110 sizeof(struct lpfc_name)) != 0)) {
3111 /*
3112 * This node has switched fabrics. FLOGI is required
3113 * Clean up the old rpi's
dea3101e 3114 */
5024ab17
JW
3115
3116 list_for_each_entry_safe(ndlp, next_ndlp,
2e0fef85 3117 &vport->fc_nodes, nlp_listp) {
685f0bf7
JS
3118 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
3119 continue;
5024ab17
JW
3120 if (ndlp->nlp_type & NLP_FABRIC) {
3121 /*
3122 * Clean up old Fabric, Nameserver and
3123 * other NLP_FABRIC logins
3124 */
2e0fef85 3125 lpfc_drop_node(vport, ndlp);
2fe165b6 3126 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
5024ab17
JW
3127 /* Fail outstanding I/O now since this
3128 * device is marked for PLOGI
3129 */
2e0fef85 3130 lpfc_unreg_rpi(vport, ndlp);
5024ab17
JW
3131 }
3132 }
3133
2e0fef85
JS
3134 vport->port_state = LPFC_FLOGI;
3135 lpfc_set_disctmo(vport);
3136 lpfc_initial_flogi(vport);
c9f8735b 3137 return 0;
dea3101e 3138 }
5024ab17
JW
3139 /* Discovery not needed,
3140 * move the nodes to their original state.
3141 */
2e0fef85 3142 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
685f0bf7
JS
3143 nlp_listp) {
3144 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
3145 continue;
dea3101e 3146
5024ab17
JW
3147 switch (ndlp->nlp_prev_state) {
3148 case NLP_STE_UNMAPPED_NODE:
3149 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2e0fef85 3150 lpfc_nlp_set_state(vport, ndlp,
de0c5b32 3151 NLP_STE_UNMAPPED_NODE);
5024ab17
JW
3152 break;
3153
3154 case NLP_STE_MAPPED_NODE:
3155 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2e0fef85 3156 lpfc_nlp_set_state(vport, ndlp,
de0c5b32 3157 NLP_STE_MAPPED_NODE);
5024ab17
JW
3158 break;
3159
3160 default:
3161 break;
3162 }
3163 }
3164
3165 /* Start discovery - this should just do CLEAR_LA */
2e0fef85 3166 lpfc_disc_start(vport);
dea3101e 3167 }
c9f8735b 3168 return 0;
dea3101e 3169}
3170
3171void
3172lpfc_els_timeout(unsigned long ptr)
3173{
2e0fef85
JS
3174 struct lpfc_vport *vport = (struct lpfc_vport *) ptr;
3175 struct lpfc_hba *phba = vport->phba;
dea3101e 3176 unsigned long iflag;
3177
2e0fef85
JS
3178 spin_lock_irqsave(&vport->work_port_lock, iflag);
3179 if ((vport->work_port_events & WORKER_ELS_TMO) == 0) {
3180 vport->work_port_events |= WORKER_ELS_TMO;
dea3101e 3181 if (phba->work_wait)
3182 wake_up(phba->work_wait);
3183 }
2e0fef85 3184 spin_unlock_irqrestore(&vport->work_port_lock, iflag);
dea3101e 3185 return;
3186}
3187
3188void
2e0fef85 3189lpfc_els_timeout_handler(struct lpfc_vport *vport)
dea3101e 3190{
2e0fef85 3191 struct lpfc_hba *phba = vport->phba;
dea3101e 3192 struct lpfc_sli_ring *pring;
3193 struct lpfc_iocbq *tmp_iocb, *piocb;
3194 IOCB_t *cmd = NULL;
3195 struct lpfc_dmabuf *pcmd;
2e0fef85 3196 uint32_t els_command = 0;
dea3101e 3197 uint32_t timeout;
2e0fef85 3198 uint32_t remote_ID = 0xffffffff;
dea3101e 3199
dea3101e 3200 /* If the timer is already canceled do nothing */
2e0fef85 3201 if ((vport->work_port_events & WORKER_ELS_TMO) == 0) {
dea3101e 3202 return;
3203 }
2e0fef85 3204 spin_lock_irq(&phba->hbalock);
dea3101e 3205 timeout = (uint32_t)(phba->fc_ratov << 1);
3206
3207 pring = &phba->sli.ring[LPFC_ELS_RING];
dea3101e 3208
3209 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
3210 cmd = &piocb->iocb;
3211
2e0fef85
JS
3212 if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 ||
3213 piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
3214 piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
dea3101e 3215 continue;
2e0fef85
JS
3216
3217 if (piocb->vport != vport)
3218 continue;
3219
dea3101e 3220 pcmd = (struct lpfc_dmabuf *) piocb->context2;
2e0fef85
JS
3221 if (pcmd)
3222 els_command = *(uint32_t *) (pcmd->virt);
dea3101e 3223
3224 if ((els_command == ELS_CMD_FARP)
3225 || (els_command == ELS_CMD_FARPR)) {
3226 continue;
3227 }
3228
3229 if (piocb->drvrTimeout > 0) {
3230 if (piocb->drvrTimeout >= timeout) {
3231 piocb->drvrTimeout -= timeout;
3232 } else {
3233 piocb->drvrTimeout = 0;
3234 }
3235 continue;
3236 }
3237
2e0fef85
JS
3238 remote_ID = 0xffffffff;
3239 if (cmd->ulpCommand != CMD_GEN_REQUEST64_CR)
dea3101e 3240 remote_ID = cmd->un.elsreq64.remoteID;
2e0fef85
JS
3241 else {
3242 struct lpfc_nodelist *ndlp;
3243 ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext);
3244 if (ndlp)
3245 remote_ID = ndlp->nlp_DID;
dea3101e 3246 }
3247
3248 lpfc_printf_log(phba,
3249 KERN_ERR,
3250 LOG_ELS,
3251 "%d:0127 ELS timeout Data: x%x x%x x%x x%x\n",
3252 phba->brd_no, els_command,
3253 remote_ID, cmd->ulpCommand, cmd->ulpIoTag);
3254
07951076 3255 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
dea3101e 3256 }
2e0fef85 3257 spin_unlock_irq(&phba->hbalock);
5a0e326d 3258
2e0fef85
JS
3259 if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt)
3260 mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout);
dea3101e 3261}
3262
3263void
2e0fef85 3264lpfc_els_flush_cmd(struct lpfc_vport *vport)
dea3101e 3265{
2534ba75 3266 LIST_HEAD(completions);
2e0fef85 3267 struct lpfc_hba *phba = vport->phba;
329f9bc7 3268 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
dea3101e 3269 struct lpfc_iocbq *tmp_iocb, *piocb;
3270 IOCB_t *cmd = NULL;
dea3101e 3271
2e0fef85 3272 spin_lock_irq(&phba->hbalock);
dea3101e 3273 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
3274 cmd = &piocb->iocb;
3275
3276 if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
3277 continue;
3278 }
3279
3280 /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */
329f9bc7
JS
3281 if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN ||
3282 cmd->ulpCommand == CMD_QUE_RING_BUF64_CN ||
3283 cmd->ulpCommand == CMD_CLOSE_XRI_CN ||
3284 cmd->ulpCommand == CMD_ABORT_XRI_CN)
dea3101e 3285 continue;
dea3101e 3286
2e0fef85
JS
3287 if (piocb->vport != vport)
3288 continue;
3289
2534ba75 3290 list_move_tail(&piocb->list, &completions);
1dcb58e5 3291 pring->txq_cnt--;
dea3101e 3292 }
3293
3294 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
dea3101e 3295 if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
3296 continue;
3297 }
dea3101e 3298
2e0fef85
JS
3299 if (piocb->vport != vport)
3300 continue;
3301
07951076 3302 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
dea3101e 3303 }
2e0fef85 3304 spin_unlock_irq(&phba->hbalock);
2534ba75 3305
2e0fef85 3306 while (!list_empty(&completions)) {
2534ba75
JS
3307 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
3308 cmd = &piocb->iocb;
3309 list_del(&piocb->list);
3310
2e0fef85
JS
3311 if (!piocb->iocb_cmpl)
3312 lpfc_sli_release_iocbq(phba, piocb);
3313 else {
2534ba75
JS
3314 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
3315 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
3316 (piocb->iocb_cmpl) (phba, piocb, piocb);
2e0fef85 3317 }
2534ba75
JS
3318 }
3319
dea3101e 3320 return;
3321}
3322
ed957684
JS
3323static void
3324lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3325 struct lpfc_vport *vport, struct lpfc_dmabuf *mp,
3326 struct lpfc_iocbq *elsiocb)
dea3101e 3327{
dea3101e 3328 struct lpfc_nodelist *ndlp;
dea3101e 3329 struct ls_rjt stat;
ed957684 3330 uint32_t *lp;
2e0fef85 3331 uint32_t cmd, did, newnode, rjt_err = 0;
ed957684 3332 IOCB_t *icmd = &elsiocb->iocb;
dea3101e 3333
ed957684 3334 if (!vport || !mp)
dea3101e 3335 goto dropit;
2e0fef85 3336
dea3101e 3337 newnode = 0;
3338 lp = (uint32_t *) mp->virt;
3339 cmd = *lp++;
ed957684
JS
3340 if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0)
3341 lpfc_post_buffer(phba, pring, 1, 1);
dea3101e 3342
ed957684 3343 if (icmd->ulpStatus)
dea3101e 3344 goto dropit;
dea3101e 3345
3346 /* Check to see if link went down during discovery */
ed957684 3347 if (lpfc_els_chk_latt(vport))
dea3101e 3348 goto dropit;
dea3101e 3349
3350 did = icmd->un.rcvels.remoteID;
2e0fef85 3351 ndlp = lpfc_findnode_did(vport, did);
c9f8735b 3352 if (!ndlp) {
dea3101e 3353 /* Cannot find existing Fabric ndlp, so allocate a new one */
c9f8735b 3354 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
ed957684 3355 if (!ndlp)
dea3101e 3356 goto dropit;
dea3101e 3357
2e0fef85 3358 lpfc_nlp_init(vport, ndlp, did);
dea3101e 3359 newnode = 1;
3360 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) {
3361 ndlp->nlp_type |= NLP_FABRIC;
3362 }
2e0fef85 3363 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
dea3101e 3364 }
3365
3366 phba->fc_stat.elsRcvFrame++;
329f9bc7
JS
3367 if (elsiocb->context1)
3368 lpfc_nlp_put(elsiocb->context1);
3369 elsiocb->context1 = lpfc_nlp_get(ndlp);
dea3101e 3370 elsiocb->context2 = mp;
2e0fef85 3371 elsiocb->vport = vport;
dea3101e 3372
3373 if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) {
3374 cmd &= ELS_CMD_MASK;
3375 }
3376 /* ELS command <elsCmd> received from NPORT <did> */
3377 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
3378 "%d:0112 ELS command x%x received from NPORT x%x "
2e0fef85 3379 "Data: x%x\n", phba->brd_no, cmd, did,
ed957684 3380 vport->port_state);
dea3101e 3381
3382 switch (cmd) {
3383 case ELS_CMD_PLOGI:
3384 phba->fc_stat.elsRcvPLOGI++;
2e0fef85 3385 if (vport->port_state < LPFC_DISC_AUTH) {
1f679caf 3386 rjt_err = 1;
dea3101e 3387 break;
3388 }
92795650 3389 ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp);
2e0fef85
JS
3390 lpfc_disc_state_machine(vport, ndlp, elsiocb,
3391 NLP_EVT_RCV_PLOGI);
dea3101e 3392 break;
3393 case ELS_CMD_FLOGI:
3394 phba->fc_stat.elsRcvFLOGI++;
2e0fef85 3395 lpfc_els_rcv_flogi(vport, elsiocb, ndlp, newnode);
de0c5b32 3396 if (newnode)
2e0fef85 3397 lpfc_drop_node(vport, ndlp);
dea3101e 3398 break;
3399 case ELS_CMD_LOGO:
3400 phba->fc_stat.elsRcvLOGO++;
2e0fef85 3401 if (vport->port_state < LPFC_DISC_AUTH) {
1f679caf 3402 rjt_err = 1;
dea3101e 3403 break;
3404 }
2e0fef85 3405 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO);
dea3101e 3406 break;
3407 case ELS_CMD_PRLO:
3408 phba->fc_stat.elsRcvPRLO++;
2e0fef85 3409 if (vport->port_state < LPFC_DISC_AUTH) {
1f679caf 3410 rjt_err = 1;
dea3101e 3411 break;
3412 }
2e0fef85 3413 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO);
dea3101e 3414 break;
3415 case ELS_CMD_RSCN:
3416 phba->fc_stat.elsRcvRSCN++;
2e0fef85 3417 lpfc_els_rcv_rscn(vport, elsiocb, ndlp, newnode);
de0c5b32 3418 if (newnode)
2e0fef85 3419 lpfc_drop_node(vport, ndlp);
dea3101e 3420 break;
3421 case ELS_CMD_ADISC:
3422 phba->fc_stat.elsRcvADISC++;
2e0fef85 3423 if (vport->port_state < LPFC_DISC_AUTH) {
1f679caf 3424 rjt_err = 1;
dea3101e 3425 break;
3426 }
2e0fef85
JS
3427 lpfc_disc_state_machine(vport, ndlp, elsiocb,
3428 NLP_EVT_RCV_ADISC);
dea3101e 3429 break;
3430 case ELS_CMD_PDISC:
3431 phba->fc_stat.elsRcvPDISC++;
2e0fef85 3432 if (vport->port_state < LPFC_DISC_AUTH) {
1f679caf 3433 rjt_err = 1;
dea3101e 3434 break;
3435 }
2e0fef85
JS
3436 lpfc_disc_state_machine(vport, ndlp, elsiocb,
3437 NLP_EVT_RCV_PDISC);
dea3101e 3438 break;
3439 case ELS_CMD_FARPR:
3440 phba->fc_stat.elsRcvFARPR++;
2e0fef85 3441 lpfc_els_rcv_farpr(vport, elsiocb, ndlp);
dea3101e 3442 break;
3443 case ELS_CMD_FARP:
3444 phba->fc_stat.elsRcvFARP++;
2e0fef85 3445 lpfc_els_rcv_farp(vport, elsiocb, ndlp);
dea3101e 3446 break;
3447 case ELS_CMD_FAN:
3448 phba->fc_stat.elsRcvFAN++;
2e0fef85 3449 lpfc_els_rcv_fan(vport, elsiocb, ndlp);
dea3101e 3450 break;
dea3101e 3451 case ELS_CMD_PRLI:
3452 phba->fc_stat.elsRcvPRLI++;
2e0fef85 3453 if (vport->port_state < LPFC_DISC_AUTH) {
1f679caf 3454 rjt_err = 1;
dea3101e 3455 break;
3456 }
2e0fef85 3457 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI);
dea3101e 3458 break;
7bb3b137
JW
3459 case ELS_CMD_LIRR:
3460 phba->fc_stat.elsRcvLIRR++;
2e0fef85 3461 lpfc_els_rcv_lirr(vport, elsiocb, ndlp);
de0c5b32 3462 if (newnode)
2e0fef85 3463 lpfc_drop_node(vport, ndlp);
7bb3b137
JW
3464 break;
3465 case ELS_CMD_RPS:
3466 phba->fc_stat.elsRcvRPS++;
2e0fef85 3467 lpfc_els_rcv_rps(vport, elsiocb, ndlp);
de0c5b32 3468 if (newnode)
2e0fef85 3469 lpfc_drop_node(vport, ndlp);
7bb3b137
JW
3470 break;
3471 case ELS_CMD_RPL:
3472 phba->fc_stat.elsRcvRPL++;
2e0fef85 3473 lpfc_els_rcv_rpl(vport, elsiocb, ndlp);
de0c5b32 3474 if (newnode)
2e0fef85 3475 lpfc_drop_node(vport, ndlp);
7bb3b137 3476 break;
dea3101e 3477 case ELS_CMD_RNID:
3478 phba->fc_stat.elsRcvRNID++;
2e0fef85 3479 lpfc_els_rcv_rnid(vport, elsiocb, ndlp);
de0c5b32 3480 if (newnode)
2e0fef85 3481 lpfc_drop_node(vport, ndlp);
dea3101e 3482 break;
3483 default:
3484 /* Unsupported ELS command, reject */
1f679caf 3485 rjt_err = 1;
dea3101e 3486
3487 /* Unknown ELS command <elsCmd> received from NPORT <did> */
3488 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
ed957684
JS
3489 "%d:0115 Unknown ELS command x%x "
3490 "received from NPORT x%x\n",
3491 phba->brd_no, cmd, did);
de0c5b32 3492 if (newnode)
2e0fef85 3493 lpfc_drop_node(vport, ndlp);
dea3101e 3494 break;
3495 }
3496
3497 /* check if need to LS_RJT received ELS cmd */
3498 if (rjt_err) {
3499 stat.un.b.lsRjtRsvd0 = 0;
3500 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
1f679caf 3501 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
dea3101e 3502 stat.un.b.vendorUnique = 0;
2e0fef85 3503 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp);
dea3101e 3504 }
3505
ed957684
JS
3506 return;
3507
3508dropit:
3509 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
3510 "%d:0111 Dropping received ELS cmd "
3511 "Data: x%x x%x x%x\n",
3512 phba->brd_no,
3513 icmd->ulpStatus, icmd->un.ulpWord[4],
3514 icmd->ulpTimeout);
3515 phba->fc_stat.elsRcvDrop++;
3516}
3517
3518
3519void
3520lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3521 struct lpfc_iocbq *elsiocb)
3522{
3523 struct lpfc_vport *vport = phba->pport;
3524 struct lpfc_dmabuf *mp = NULL;
3525 IOCB_t *icmd = &elsiocb->iocb;
3526 struct hbq_dmabuf *sp = NULL;
3527 dma_addr_t paddr;
3528
3529 if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
3530 ((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) {
3531 phba->fc_stat.NoRcvBuf++;
3532 /* Not enough posted buffers; Try posting more buffers */
3533 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
3534 lpfc_sli_hbqbuf_fill_hbq(phba);
3535 else
3536 lpfc_post_buffer(phba, pring, 0, 1);
3537 return;
3538 }
3539
3540 /* If there are no BDEs associated with this IOCB,
3541 * there is nothing to do.
3542 */
3543 if (icmd->ulpBdeCount == 0)
3544 return;
3545
3546 /* type of ELS cmd is first 32bit word in packet */
3547 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
3548 paddr = getPaddr(icmd->un.cont64[0].addrHigh,
3549 icmd->un.cont64[0].addrLow);
3550 sp = lpfc_sli_hbqbuf_find(phba, icmd->un.ulpWord[3]);
3551 if (sp)
3552 phba->hbq_buff_count--;
3553 mp = sp ? &sp->dbuf : NULL;
3554 } else {
3555 paddr = getPaddr(icmd->un.cont64[0].addrHigh,
3556 icmd->un.cont64[0].addrLow);
3557 mp = lpfc_sli_ringpostbuf_get(phba, pring, paddr);
3558 }
3559
3560 lpfc_els_unsol_buffer(phba, pring, vport, mp, elsiocb);
3561
329f9bc7
JS
3562 lpfc_nlp_put(elsiocb->context1);
3563 elsiocb->context1 = NULL;
dea3101e 3564 if (elsiocb->context2) {
ed957684
JS
3565 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
3566 lpfc_sli_free_hbq(phba, sp);
3567 else {
3568 lpfc_mbuf_free(phba, mp->virt, mp->phys);
3569 kfree(mp);
3570 }
dea3101e 3571 }
ed957684
JS
3572
3573 /* RCV_ELS64_CX provide for 2 BDEs - process 2nd if included */
3574 if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) != 0 &&
3575 icmd->ulpBdeCount == 2) {
3576 sp = lpfc_sli_hbqbuf_find(phba, icmd->un.ulpWord[15]);
3577 if (sp)
3578 phba->hbq_buff_count--;
3579 mp = sp ? &sp->dbuf : NULL;
3580 lpfc_els_unsol_buffer(phba, pring, vport, mp, elsiocb);
3581 /* free mp if we are done with it */
3582 if (elsiocb->context2) {
3583 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
3584 lpfc_sli_free_hbq(phba, sp);
3585 else {
3586 lpfc_mbuf_free(phba, mp->virt, mp->phys);
3587 kfree(mp);
3588 }
3589 }
dea3101e 3590 }
dea3101e 3591}
This page took 0.414692 seconds and 5 git commands to generate.