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