trivial: remove unnecessary semicolons
[linux-2.6-block.git] / drivers / scsi / lpfc / lpfc_ct.c
CommitLineData
dea3101e 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for *
c44ce173 3 * Fibre Channel Host Bus Adapters. *
d8e93df1 4 * Copyright (C) 2004-2009 Emulex. All rights reserved. *
c44ce173 5 * EMULEX and SLI are trademarks of Emulex. *
dea3101e 6 * www.emulex.com *
7 * *
8 * This program is free software; you can redistribute it and/or *
c44ce173
JSEC
9 * modify it under the terms of version 2 of the GNU General *
10 * Public License as published by the Free Software Foundation. *
11 * This program is distributed in the hope that it will be useful. *
12 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
13 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
14 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
15 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
16 * TO BE LEGALLY INVALID. See the GNU General Public License for *
17 * more details, a copy of which can be found in the file COPYING *
18 * included with this package. *
dea3101e 19 *******************************************************************/
20
21/*
09372820 22 * Fibre Channel SCSI LAN Device Driver CT support: FC Generic Services FC-GS
dea3101e 23 */
24
25#include <linux/blkdev.h>
26#include <linux/pci.h>
27#include <linux/interrupt.h>
28#include <linux/utsname.h>
29
91886523 30#include <scsi/scsi.h>
dea3101e 31#include <scsi/scsi_device.h>
32#include <scsi/scsi_host.h>
f888ba3c 33#include <scsi/scsi_transport_fc.h>
dea3101e 34
da0436e9 35#include "lpfc_hw4.h"
dea3101e 36#include "lpfc_hw.h"
37#include "lpfc_sli.h"
da0436e9 38#include "lpfc_sli4.h"
ea2151b4 39#include "lpfc_nl.h"
dea3101e 40#include "lpfc_disc.h"
41#include "lpfc_scsi.h"
42#include "lpfc.h"
43#include "lpfc_logmsg.h"
44#include "lpfc_crtn.h"
45#include "lpfc_version.h"
92d7f7b0 46#include "lpfc_vport.h"
858c9f6c 47#include "lpfc_debugfs.h"
dea3101e 48
49#define HBA_PORTSPEED_UNKNOWN 0 /* Unknown - transceiver
50 * incapable of reporting */
51#define HBA_PORTSPEED_1GBIT 1 /* 1 GBit/sec */
52#define HBA_PORTSPEED_2GBIT 2 /* 2 GBit/sec */
53#define HBA_PORTSPEED_4GBIT 8 /* 4 GBit/sec */
54#define HBA_PORTSPEED_8GBIT 16 /* 8 GBit/sec */
55#define HBA_PORTSPEED_10GBIT 4 /* 10 GBit/sec */
56#define HBA_PORTSPEED_NOT_NEGOTIATED 5 /* Speed not established */
57
58#define FOURBYTES 4
59
60
61static char *lpfc_release_version = LPFC_DRIVER_VERSION;
62
ed957684 63static void
9c2face6
JS
64lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
65 struct lpfc_dmabuf *mp, uint32_t size)
ed957684
JS
66{
67 if (!mp) {
9c2face6 68 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
97eab634 69 "0146 Ignoring unsolicited CT No HBQ "
9c2face6
JS
70 "status = x%x\n",
71 piocbq->iocb.ulpStatus);
ed957684 72 }
9c2face6
JS
73 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
74 "0145 Ignoring unsolicted CT HBQ Size:%d "
75 "status = x%x\n",
76 size, piocbq->iocb.ulpStatus);
ed957684
JS
77}
78
79static void
9c2face6
JS
80lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
81 struct lpfc_dmabuf *mp, uint32_t size)
ed957684 82{
9c2face6 83 lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size);
ed957684
JS
84}
85
dea3101e 86void
2e0fef85
JS
87lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
88 struct lpfc_iocbq *piocbq)
dea3101e 89{
92d7f7b0 90
ed957684 91 struct lpfc_dmabuf *mp = NULL;
dea3101e 92 IOCB_t *icmd = &piocbq->iocb;
ed957684
JS
93 int i;
94 struct lpfc_iocbq *iocbq;
95 dma_addr_t paddr;
96 uint32_t size;
9c2face6
JS
97 struct list_head head;
98 struct lpfc_dmabuf *bdeBuf;
dea3101e 99
f1c3b0fc
JS
100 lpfc_bsg_ct_unsol_event(phba, pring, piocbq);
101
92d7f7b0
JS
102 if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
103 lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
104 } else if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
105 ((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) {
dea3101e 106 /* Not enough posted buffers; Try posting more buffers */
107 phba->fc_stat.NoRcvBuf++;
92d7f7b0 108 if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
495a714c 109 lpfc_post_buffer(phba, pring, 2);
dea3101e 110 return;
111 }
112
113 /* If there are no BDEs associated with this IOCB,
114 * there is nothing to do.
115 */
116 if (icmd->ulpBdeCount == 0)
117 return;
118
ed957684 119 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
9c2face6
JS
120 INIT_LIST_HEAD(&head);
121 list_add_tail(&head, &piocbq->list);
122 list_for_each_entry(iocbq, &head, list) {
ed957684 123 icmd = &iocbq->iocb;
9c2face6 124 if (icmd->ulpBdeCount == 0)
ed957684 125 continue;
9c2face6
JS
126 bdeBuf = iocbq->context2;
127 iocbq->context2 = NULL;
ed957684 128 size = icmd->un.cont64[0].tus.f.bdeSize;
9c2face6
JS
129 lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size);
130 lpfc_in_buf_free(phba, bdeBuf);
ed957684 131 if (icmd->ulpBdeCount == 2) {
9c2face6
JS
132 bdeBuf = iocbq->context3;
133 iocbq->context3 = NULL;
134 size = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize;
135 lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf,
136 size);
137 lpfc_in_buf_free(phba, bdeBuf);
ed957684 138 }
dea3101e 139 }
9c2face6 140 list_del(&head);
ed957684 141 } else {
d7c255b2
JS
142 INIT_LIST_HEAD(&head);
143 list_add_tail(&head, &piocbq->list);
144 list_for_each_entry(iocbq, &head, list) {
ed957684 145 icmd = &iocbq->iocb;
9c2face6 146 if (icmd->ulpBdeCount == 0)
d7c255b2 147 lpfc_ct_unsol_buffer(phba, iocbq, NULL, 0);
ed957684
JS
148 for (i = 0; i < icmd->ulpBdeCount; i++) {
149 paddr = getPaddr(icmd->un.cont64[i].addrHigh,
150 icmd->un.cont64[i].addrLow);
151 mp = lpfc_sli_ringpostbuf_get(phba, pring,
152 paddr);
153 size = icmd->un.cont64[i].tus.f.bdeSize;
d7c255b2 154 lpfc_ct_unsol_buffer(phba, iocbq, mp, size);
92d7f7b0 155 lpfc_in_buf_free(phba, mp);
ed957684 156 }
495a714c 157 lpfc_post_buffer(phba, pring, i);
dea3101e 158 }
d7c255b2 159 list_del(&head);
dea3101e 160 }
dea3101e 161}
162
163static void
2e0fef85 164lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist)
dea3101e 165{
166 struct lpfc_dmabuf *mlast, *next_mlast;
167
168 list_for_each_entry_safe(mlast, next_mlast, &mlist->list, list) {
169 lpfc_mbuf_free(phba, mlast->virt, mlast->phys);
170 list_del(&mlast->list);
171 kfree(mlast);
172 }
173 lpfc_mbuf_free(phba, mlist->virt, mlist->phys);
174 kfree(mlist);
175 return;
176}
177
178static struct lpfc_dmabuf *
2e0fef85 179lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl,
dea3101e 180 uint32_t size, int *entries)
181{
182 struct lpfc_dmabuf *mlist = NULL;
183 struct lpfc_dmabuf *mp;
184 int cnt, i = 0;
185
09372820 186 /* We get chunks of FCELSSIZE */
dea3101e 187 cnt = size > FCELSSIZE ? FCELSSIZE: size;
188
189 while (size) {
190 /* Allocate buffer for rsp payload */
191 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
192 if (!mp) {
193 if (mlist)
194 lpfc_free_ct_rsp(phba, mlist);
195 return NULL;
196 }
197
198 INIT_LIST_HEAD(&mp->list);
199
92d7f7b0
JS
200 if (cmdcode == be16_to_cpu(SLI_CTNS_GID_FT) ||
201 cmdcode == be16_to_cpu(SLI_CTNS_GFF_ID))
dea3101e 202 mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
203 else
204 mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
205
206 if (!mp->virt) {
207 kfree(mp);
0b3a82d3
ES
208 if (mlist)
209 lpfc_free_ct_rsp(phba, mlist);
dea3101e 210 return NULL;
211 }
212
213 /* Queue it to a linked list */
214 if (!mlist)
215 mlist = mp;
216 else
217 list_add_tail(&mp->list, &mlist->list);
218
34b02dcd 219 bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
dea3101e 220 /* build buffer ptr list for IOCB */
92d7f7b0
JS
221 bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
222 bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
dea3101e 223 bpl->tus.f.bdeSize = (uint16_t) cnt;
224 bpl->tus.w = le32_to_cpu(bpl->tus.w);
225 bpl++;
226
227 i++;
228 size -= cnt;
229 }
230
231 *entries = i;
232 return mlist;
233}
234
858c9f6c
JS
235int
236lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb)
237{
238 struct lpfc_dmabuf *buf_ptr;
239
51ef4c26
JS
240 if (ctiocb->context_un.ndlp) {
241 lpfc_nlp_put(ctiocb->context_un.ndlp);
242 ctiocb->context_un.ndlp = NULL;
243 }
858c9f6c
JS
244 if (ctiocb->context1) {
245 buf_ptr = (struct lpfc_dmabuf *) ctiocb->context1;
246 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
247 kfree(buf_ptr);
248 ctiocb->context1 = NULL;
249 }
250 if (ctiocb->context2) {
251 lpfc_free_ct_rsp(phba, (struct lpfc_dmabuf *) ctiocb->context2);
252 ctiocb->context2 = NULL;
253 }
254
255 if (ctiocb->context3) {
256 buf_ptr = (struct lpfc_dmabuf *) ctiocb->context3;
257 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
258 kfree(buf_ptr);
259 ctiocb->context1 = NULL;
260 }
261 lpfc_sli_release_iocbq(phba, ctiocb);
262 return 0;
263}
264
dea3101e 265static int
2e0fef85 266lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
dea3101e 267 struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp,
268 void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
269 struct lpfc_iocbq *),
270 struct lpfc_nodelist *ndlp, uint32_t usr_flg, uint32_t num_entry,
92d7f7b0 271 uint32_t tmo, uint8_t retry)
dea3101e 272{
2e0fef85 273 struct lpfc_hba *phba = vport->phba;
dea3101e 274 IOCB_t *icmd;
0bd4ca25 275 struct lpfc_iocbq *geniocb;
92d7f7b0 276 int rc;
dea3101e 277
278 /* Allocate buffer for command iocb */
0bd4ca25 279 geniocb = lpfc_sli_get_iocbq(phba);
dea3101e 280
281 if (geniocb == NULL)
282 return 1;
dea3101e 283
284 icmd = &geniocb->iocb;
285 icmd->un.genreq64.bdl.ulpIoTag32 = 0;
286 icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
287 icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
34b02dcd 288 icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
dea3101e 289 icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof (struct ulp_bde64));
290
291 if (usr_flg)
292 geniocb->context3 = NULL;
293 else
294 geniocb->context3 = (uint8_t *) bmp;
295
296 /* Save for completion so we can release these resources */
297 geniocb->context1 = (uint8_t *) inp;
298 geniocb->context2 = (uint8_t *) outp;
e47c9093 299 geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
dea3101e 300
301 /* Fill in payload, bp points to frame payload */
302 icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
303
304 /* Fill in rest of iocb */
305 icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
306 icmd->un.genreq64.w5.hcsw.Dfctl = 0;
307 icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
308 icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
309
c9f8735b
JW
310 if (!tmo) {
311 /* FC spec states we need 3 * ratov for CT requests */
312 tmo = (3 * phba->fc_ratov);
313 }
dea3101e 314 icmd->ulpTimeout = tmo;
315 icmd->ulpBdeCount = 1;
316 icmd->ulpLe = 1;
317 icmd->ulpClass = CLASS3;
318 icmd->ulpContext = ndlp->nlp_rpi;
319
92d7f7b0
JS
320 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
321 /* For GEN_REQUEST64_CR, use the RPI */
322 icmd->ulpCt_h = 0;
323 icmd->ulpCt_l = 0;
324 }
325
dea3101e 326 /* Issue GEN REQ IOCB for NPORT <did> */
e8b62011
JS
327 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
328 "0119 Issue GEN REQ IOCB to NPORT x%x "
329 "Data: x%x x%x\n",
330 ndlp->nlp_DID, icmd->ulpIoTag,
331 vport->port_state);
dea3101e 332 geniocb->iocb_cmpl = cmpl;
333 geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
2e0fef85 334 geniocb->vport = vport;
92d7f7b0 335 geniocb->retry = retry;
3772a991 336 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);
92d7f7b0
JS
337
338 if (rc == IOCB_ERROR) {
604a3e30 339 lpfc_sli_release_iocbq(phba, geniocb);
dea3101e 340 return 1;
341 }
dea3101e 342
343 return 0;
344}
345
346static int
2e0fef85 347lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,
dea3101e 348 struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp,
349 void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
350 struct lpfc_iocbq *),
92d7f7b0 351 uint32_t rsp_size, uint8_t retry)
dea3101e 352{
2e0fef85 353 struct lpfc_hba *phba = vport->phba;
dea3101e 354 struct ulp_bde64 *bpl = (struct ulp_bde64 *) bmp->virt;
355 struct lpfc_dmabuf *outmp;
356 int cnt = 0, status;
357 int cmdcode = ((struct lpfc_sli_ct_request *) inmp->virt)->
358 CommandResponse.bits.CmdRsp;
359
360 bpl++; /* Skip past ct request */
361
362 /* Put buffer(s) for ct rsp in bpl */
363 outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt);
364 if (!outmp)
365 return -ENOMEM;
366
2e0fef85 367 status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0,
92d7f7b0 368 cnt+1, 0, retry);
dea3101e 369 if (status) {
370 lpfc_free_ct_rsp(phba, outmp);
371 return -ENOMEM;
372 }
373 return 0;
374}
375
549e55cd 376struct lpfc_vport *
92d7f7b0 377lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) {
92d7f7b0 378 struct lpfc_vport *vport_curr;
549e55cd 379 unsigned long flags;
92d7f7b0 380
549e55cd 381 spin_lock_irqsave(&phba->hbalock, flags);
92d7f7b0 382 list_for_each_entry(vport_curr, &phba->port_list, listentry) {
549e55cd
JS
383 if ((vport_curr->fc_myDID) && (vport_curr->fc_myDID == did)) {
384 spin_unlock_irqrestore(&phba->hbalock, flags);
92d7f7b0 385 return vport_curr;
549e55cd 386 }
92d7f7b0 387 }
549e55cd 388 spin_unlock_irqrestore(&phba->hbalock, flags);
92d7f7b0
JS
389 return NULL;
390}
391
dea3101e 392static int
2e0fef85 393lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
dea3101e 394{
2e0fef85 395 struct lpfc_hba *phba = vport->phba;
dea3101e 396 struct lpfc_sli_ct_request *Response =
397 (struct lpfc_sli_ct_request *) mp->virt;
398 struct lpfc_nodelist *ndlp = NULL;
399 struct lpfc_dmabuf *mlast, *next_mp;
400 uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;
2e0fef85 401 uint32_t Did, CTentry;
dea3101e 402 int Cnt;
403 struct list_head head;
404
2e0fef85 405 lpfc_set_disctmo(vport);
92d7f7b0 406 vport->num_disc_nodes = 0;
0ff10d46 407 vport->fc_ns_retry = 0;
dea3101e 408
dea3101e 409
410 list_add_tail(&head, &mp->list);
411 list_for_each_entry_safe(mp, next_mp, &head, list) {
412 mlast = mp;
413
7054a606
JS
414 Cnt = Size > FCELSSIZE ? FCELSSIZE : Size;
415
dea3101e 416 Size -= Cnt;
417
1dcb58e5 418 if (!ctptr) {
dea3101e 419 ctptr = (uint32_t *) mlast->virt;
1dcb58e5 420 } else
dea3101e 421 Cnt -= 16; /* subtract length of CT header */
422
423 /* Loop through entire NameServer list of DIDs */
7054a606 424 while (Cnt >= sizeof (uint32_t)) {
dea3101e 425 /* Get next DID from NameServer List */
426 CTentry = *ctptr++;
427 Did = ((be32_to_cpu(CTentry)) & Mask_DID);
92d7f7b0 428
dea3101e 429 ndlp = NULL;
92d7f7b0
JS
430
431 /*
432 * Check for rscn processing or not
433 * To conserve rpi's, filter out addresses for other
434 * vports on the same physical HBAs.
435 */
436 if ((Did != vport->fc_myDID) &&
437 ((lpfc_find_vport_by_did(phba, Did) == NULL) ||
3de2a653 438 vport->cfg_peer_port_login)) {
92d7f7b0 439 if ((vport->port_type != LPFC_NPIV_PORT) ||
98c9ea5c 440 (!(vport->ct_flags & FC_CT_RFF_ID)) ||
3de2a653 441 (!vport->cfg_restrict_login)) {
92d7f7b0 442 ndlp = lpfc_setup_disc_node(vport, Did);
58da1ffb 443 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
858c9f6c
JS
444 lpfc_debugfs_disc_trc(vport,
445 LPFC_DISC_TRC_CT,
446 "Parse GID_FTrsp: "
447 "did:x%x flg:x%x x%x",
448 Did, ndlp->nlp_flag,
449 vport->fc_flag);
450
e8b62011
JS
451 lpfc_printf_vlog(vport,
452 KERN_INFO,
92d7f7b0 453 LOG_DISCOVERY,
e8b62011 454 "0238 Process "
92d7f7b0
JS
455 "x%x NameServer Rsp"
456 "Data: x%x x%x x%x\n",
e8b62011 457 Did, ndlp->nlp_flag,
92d7f7b0
JS
458 vport->fc_flag,
459 vport->fc_rscn_id_cnt);
460 } else {
858c9f6c
JS
461 lpfc_debugfs_disc_trc(vport,
462 LPFC_DISC_TRC_CT,
463 "Skip1 GID_FTrsp: "
464 "did:x%x flg:x%x cnt:%d",
465 Did, vport->fc_flag,
466 vport->fc_rscn_id_cnt);
467
e8b62011
JS
468 lpfc_printf_vlog(vport,
469 KERN_INFO,
92d7f7b0 470 LOG_DISCOVERY,
e8b62011 471 "0239 Skip x%x "
92d7f7b0
JS
472 "NameServer Rsp Data: "
473 "x%x x%x\n",
e8b62011 474 Did, vport->fc_flag,
92d7f7b0
JS
475 vport->fc_rscn_id_cnt);
476 }
477
478 } else {
479 if (!(vport->fc_flag & FC_RSCN_MODE) ||
480 (lpfc_rscn_payload_check(vport, Did))) {
858c9f6c
JS
481 lpfc_debugfs_disc_trc(vport,
482 LPFC_DISC_TRC_CT,
483 "Query GID_FTrsp: "
484 "did:x%x flg:x%x cnt:%d",
485 Did, vport->fc_flag,
486 vport->fc_rscn_id_cnt);
487
0ff10d46
JS
488 /* This NPortID was previously
489 * a FCP target, * Don't even
490 * bother to send GFF_ID.
491 */
492 ndlp = lpfc_findnode_did(vport,
493 Did);
e47c9093
JS
494 if (ndlp &&
495 NLP_CHK_NODE_ACT(ndlp)
496 && (ndlp->nlp_type &
497 NLP_FCP_TARGET))
0ff10d46
JS
498 lpfc_setup_disc_node
499 (vport, Did);
500 else if (lpfc_ns_cmd(vport,
92d7f7b0
JS
501 SLI_CTNS_GFF_ID,
502 0, Did) == 0)
503 vport->num_disc_nodes++;
504 }
505 else {
858c9f6c
JS
506 lpfc_debugfs_disc_trc(vport,
507 LPFC_DISC_TRC_CT,
508 "Skip2 GID_FTrsp: "
509 "did:x%x flg:x%x cnt:%d",
510 Did, vport->fc_flag,
511 vport->fc_rscn_id_cnt);
512
e8b62011
JS
513 lpfc_printf_vlog(vport,
514 KERN_INFO,
92d7f7b0 515 LOG_DISCOVERY,
e8b62011 516 "0245 Skip x%x "
92d7f7b0
JS
517 "NameServer Rsp Data: "
518 "x%x x%x\n",
e8b62011 519 Did, vport->fc_flag,
92d7f7b0
JS
520 vport->fc_rscn_id_cnt);
521 }
522 }
dea3101e 523 }
dea3101e 524 if (CTentry & (be32_to_cpu(SLI_CT_LAST_ENTRY)))
525 goto nsout1;
526 Cnt -= sizeof (uint32_t);
527 }
528 ctptr = NULL;
529
530 }
531
532nsout1:
533 list_del(&head);
dea3101e 534 return 0;
535}
536
dea3101e 537static void
2e0fef85
JS
538lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
539 struct lpfc_iocbq *rspiocb)
dea3101e 540{
2e0fef85 541 struct lpfc_vport *vport = cmdiocb->vport;
92d7f7b0 542 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea3101e 543 IOCB_t *irsp;
dea3101e 544 struct lpfc_dmabuf *bmp;
dea3101e 545 struct lpfc_dmabuf *outp;
dea3101e 546 struct lpfc_sli_ct_request *CTrsp;
51ef4c26 547 struct lpfc_nodelist *ndlp;
58da1ffb 548 int rc;
dea3101e 549
51ef4c26
JS
550 /* First save ndlp, before we overwrite it */
551 ndlp = cmdiocb->context_un.ndlp;
552
dea3101e 553 /* we pass cmdiocb to state machine which needs rspiocb as well */
554 cmdiocb->context_un.rsp_iocb = rspiocb;
555
dea3101e 556 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
557 bmp = (struct lpfc_dmabuf *) cmdiocb->context3;
858c9f6c
JS
558 irsp = &rspiocb->iocb;
559
560 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
561 "GID_FT cmpl: status:x%x/x%x rtry:%d",
562 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_ns_retry);
dea3101e 563
92d7f7b0 564 /* Don't bother processing response if vport is being torn down. */
eada272d
JS
565 if (vport->load_flag & FC_UNLOADING) {
566 if (vport->fc_flag & FC_RSCN_MODE)
567 lpfc_els_flush_rscn(vport);
92d7f7b0 568 goto out;
eada272d 569 }
92d7f7b0 570
58da1ffb 571 if (lpfc_els_chk_latt(vport)) {
e8b62011
JS
572 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
573 "0216 Link event during NS query\n");
eada272d
JS
574 if (vport->fc_flag & FC_RSCN_MODE)
575 lpfc_els_flush_rscn(vport);
858c9f6c
JS
576 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
577 goto out;
578 }
58da1ffb
JS
579 if (lpfc_error_lost_link(irsp)) {
580 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
581 "0226 NS query failed due to link event\n");
eada272d
JS
582 if (vport->fc_flag & FC_RSCN_MODE)
583 lpfc_els_flush_rscn(vport);
58da1ffb
JS
584 goto out;
585 }
858c9f6c 586 if (irsp->ulpStatus) {
dea3101e 587 /* Check for retry */
2e0fef85 588 if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
58da1ffb
JS
589 if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
590 irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)
858c9f6c 591 vport->fc_ns_retry++;
0ff10d46 592
58da1ffb
JS
593 /* CT command is being retried */
594 rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
92d7f7b0 595 vport->fc_ns_retry, 0);
58da1ffb
JS
596 if (rc == 0)
597 goto out;
92d7f7b0 598 }
eada272d
JS
599 if (vport->fc_flag & FC_RSCN_MODE)
600 lpfc_els_flush_rscn(vport);
92d7f7b0 601 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
e8b62011
JS
602 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
603 "0257 GID_FT Query error: 0x%x 0x%x\n",
604 irsp->ulpStatus, vport->fc_ns_retry);
dea3101e 605 } else {
606 /* Good status, continue checking */
607 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
608 if (CTrsp->CommandResponse.bits.CmdRsp ==
609 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
e8b62011
JS
610 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
611 "0208 NameServer Rsp Data: x%x\n",
612 vport->fc_flag);
2e0fef85 613 lpfc_ns_rsp(vport, outp,
dea3101e 614 (uint32_t) (irsp->un.genreq64.bdl.bdeSize));
615 } else if (CTrsp->CommandResponse.bits.CmdRsp ==
616 be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
617 /* NameServer Rsp Error */
a58cbd52
JS
618 if ((CTrsp->ReasonCode == SLI_CT_UNABLE_TO_PERFORM_REQ)
619 && (CTrsp->Explanation == SLI_CT_NO_FC4_TYPES)) {
e8b62011
JS
620 lpfc_printf_vlog(vport, KERN_INFO,
621 LOG_DISCOVERY,
622 "0269 No NameServer Entries "
a58cbd52 623 "Data: x%x x%x x%x x%x\n",
a58cbd52
JS
624 CTrsp->CommandResponse.bits.CmdRsp,
625 (uint32_t) CTrsp->ReasonCode,
626 (uint32_t) CTrsp->Explanation,
627 vport->fc_flag);
628
629 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
630 "GID_FT no entry cmd:x%x rsn:x%x exp:x%x",
631 (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
632 (uint32_t) CTrsp->ReasonCode,
633 (uint32_t) CTrsp->Explanation);
e8b62011
JS
634 } else {
635 lpfc_printf_vlog(vport, KERN_INFO,
636 LOG_DISCOVERY,
637 "0240 NameServer Rsp Error "
dea3101e 638 "Data: x%x x%x x%x x%x\n",
dea3101e 639 CTrsp->CommandResponse.bits.CmdRsp,
640 (uint32_t) CTrsp->ReasonCode,
641 (uint32_t) CTrsp->Explanation,
2e0fef85 642 vport->fc_flag);
858c9f6c 643
a58cbd52 644 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
858c9f6c
JS
645 "GID_FT rsp err1 cmd:x%x rsn:x%x exp:x%x",
646 (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
647 (uint32_t) CTrsp->ReasonCode,
648 (uint32_t) CTrsp->Explanation);
a58cbd52
JS
649 }
650
858c9f6c 651
dea3101e 652 } else {
653 /* NameServer Rsp Error */
e8b62011
JS
654 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
655 "0241 NameServer Rsp Error "
dea3101e 656 "Data: x%x x%x x%x x%x\n",
dea3101e 657 CTrsp->CommandResponse.bits.CmdRsp,
658 (uint32_t) CTrsp->ReasonCode,
659 (uint32_t) CTrsp->Explanation,
2e0fef85 660 vport->fc_flag);
858c9f6c
JS
661
662 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
663 "GID_FT rsp err2 cmd:x%x rsn:x%x exp:x%x",
664 (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
665 (uint32_t) CTrsp->ReasonCode,
666 (uint32_t) CTrsp->Explanation);
dea3101e 667 }
668 }
669 /* Link up / RSCN discovery */
92d7f7b0
JS
670 if (vport->num_disc_nodes == 0) {
671 /*
672 * The driver has cycled through all Nports in the RSCN payload.
673 * Complete the handling by cleaning up and marking the
674 * current driver state.
675 */
676 if (vport->port_state >= LPFC_DISC_AUTH) {
677 if (vport->fc_flag & FC_RSCN_MODE) {
678 lpfc_els_flush_rscn(vport);
679 spin_lock_irq(shost->host_lock);
680 vport->fc_flag |= FC_RSCN_MODE; /* RSCN still */
681 spin_unlock_irq(shost->host_lock);
682 }
683 else
684 lpfc_els_flush_rscn(vport);
685 }
686
687 lpfc_disc_start(vport);
688 }
689out:
51ef4c26 690 cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
858c9f6c 691 lpfc_ct_free_iocb(phba, cmdiocb);
92d7f7b0
JS
692 return;
693}
694
311464ec 695static void
92d7f7b0
JS
696lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
697 struct lpfc_iocbq *rspiocb)
698{
699 struct lpfc_vport *vport = cmdiocb->vport;
700 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
701 IOCB_t *irsp = &rspiocb->iocb;
92d7f7b0
JS
702 struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1;
703 struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2;
704 struct lpfc_sli_ct_request *CTrsp;
0ff10d46 705 int did, rc, retry;
92d7f7b0
JS
706 uint8_t fbits;
707 struct lpfc_nodelist *ndlp;
708
709 did = ((struct lpfc_sli_ct_request *) inp->virt)->un.gff.PortId;
710 did = be32_to_cpu(did);
711
858c9f6c
JS
712 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
713 "GFF_ID cmpl: status:x%x/x%x did:x%x",
714 irsp->ulpStatus, irsp->un.ulpWord[4], did);
715
92d7f7b0
JS
716 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
717 /* Good status, continue checking */
718 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
719 fbits = CTrsp->un.gff_acc.fbits[FCP_TYPE_FEATURE_OFFSET];
720
721 if (CTrsp->CommandResponse.bits.CmdRsp ==
722 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
723 if ((fbits & FC4_FEATURE_INIT) &&
724 !(fbits & FC4_FEATURE_TARGET)) {
e8b62011
JS
725 lpfc_printf_vlog(vport, KERN_INFO,
726 LOG_DISCOVERY,
727 "0270 Skip x%x GFF "
728 "NameServer Rsp Data: (init) "
729 "x%x x%x\n", did, fbits,
730 vport->fc_rscn_id_cnt);
92d7f7b0
JS
731 goto out;
732 }
733 }
734 }
858c9f6c 735 else {
0ff10d46
JS
736 /* Check for retry */
737 if (cmdiocb->retry < LPFC_MAX_NS_RETRY) {
738 retry = 1;
739 if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
740 switch (irsp->un.ulpWord[4]) {
741 case IOERR_NO_RESOURCES:
742 /* We don't increment the retry
743 * count for this case.
744 */
745 break;
746 case IOERR_LINK_DOWN:
747 case IOERR_SLI_ABORTED:
748 case IOERR_SLI_DOWN:
749 retry = 0;
750 break;
751 default:
752 cmdiocb->retry++;
753 }
754 }
755 else
756 cmdiocb->retry++;
757
758 if (retry) {
759 /* CT command is being retried */
760 rc = lpfc_ns_cmd(vport, SLI_CTNS_GFF_ID,
761 cmdiocb->retry, did);
762 if (rc == 0) {
763 /* success */
764 lpfc_ct_free_iocb(phba, cmdiocb);
765 return;
766 }
767 }
768 }
e8b62011
JS
769 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
770 "0267 NameServer GFF Rsp "
771 "x%x Error (%d %d) Data: x%x x%x\n",
772 did, irsp->ulpStatus, irsp->un.ulpWord[4],
7f5f3d0d 773 vport->fc_flag, vport->fc_rscn_id_cnt);
858c9f6c
JS
774 }
775
92d7f7b0
JS
776 /* This is a target port, unregistered port, or the GFF_ID failed */
777 ndlp = lpfc_setup_disc_node(vport, did);
58da1ffb 778 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
e8b62011
JS
779 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
780 "0242 Process x%x GFF "
781 "NameServer Rsp Data: x%x x%x x%x\n",
782 did, ndlp->nlp_flag, vport->fc_flag,
783 vport->fc_rscn_id_cnt);
92d7f7b0 784 } else {
e8b62011
JS
785 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
786 "0243 Skip x%x GFF "
787 "NameServer Rsp Data: x%x x%x\n", did,
788 vport->fc_flag, vport->fc_rscn_id_cnt);
92d7f7b0 789 }
dea3101e 790out:
92d7f7b0
JS
791 /* Link up / RSCN discovery */
792 if (vport->num_disc_nodes)
793 vport->num_disc_nodes--;
794 if (vport->num_disc_nodes == 0) {
795 /*
796 * The driver has cycled through all Nports in the RSCN payload.
797 * Complete the handling by cleaning up and marking the
798 * current driver state.
799 */
800 if (vport->port_state >= LPFC_DISC_AUTH) {
801 if (vport->fc_flag & FC_RSCN_MODE) {
802 lpfc_els_flush_rscn(vport);
803 spin_lock_irq(shost->host_lock);
804 vport->fc_flag |= FC_RSCN_MODE; /* RSCN still */
805 spin_unlock_irq(shost->host_lock);
806 }
807 else
808 lpfc_els_flush_rscn(vport);
809 }
810 lpfc_disc_start(vport);
811 }
858c9f6c 812 lpfc_ct_free_iocb(phba, cmdiocb);
dea3101e 813 return;
814}
815
92d7f7b0 816
dea3101e 817static void
7ee5d43e
JS
818lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
819 struct lpfc_iocbq *rspiocb)
dea3101e 820{
92d7f7b0 821 struct lpfc_vport *vport = cmdiocb->vport;
dea3101e 822 struct lpfc_dmabuf *inp;
823 struct lpfc_dmabuf *outp;
824 IOCB_t *irsp;
825 struct lpfc_sli_ct_request *CTrsp;
51ef4c26 826 struct lpfc_nodelist *ndlp;
92d7f7b0
JS
827 int cmdcode, rc;
828 uint8_t retry;
858c9f6c 829 uint32_t latt;
dea3101e 830
51ef4c26
JS
831 /* First save ndlp, before we overwrite it */
832 ndlp = cmdiocb->context_un.ndlp;
833
dea3101e 834 /* we pass cmdiocb to state machine which needs rspiocb as well */
835 cmdiocb->context_un.rsp_iocb = rspiocb;
836
837 inp = (struct lpfc_dmabuf *) cmdiocb->context1;
838 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
dea3101e 839 irsp = &rspiocb->iocb;
840
92d7f7b0
JS
841 cmdcode = be16_to_cpu(((struct lpfc_sli_ct_request *) inp->virt)->
842 CommandResponse.bits.CmdRsp);
dea3101e 843 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
844
858c9f6c
JS
845 latt = lpfc_els_chk_latt(vport);
846
847 /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
e8b62011 848 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
7ee5d43e 849 "0209 CT Request completes, latt %d, "
e8b62011
JS
850 "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n",
851 latt, irsp->ulpStatus,
852 CTrsp->CommandResponse.bits.CmdRsp,
853 cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag);
dea3101e 854
858c9f6c
JS
855 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
856 "CT cmd cmpl: status:x%x/x%x cmd:x%x",
857 irsp->ulpStatus, irsp->un.ulpWord[4], cmdcode);
858
92d7f7b0 859 if (irsp->ulpStatus) {
e8b62011
JS
860 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
861 "0268 NS cmd %x Error (%d %d)\n",
862 cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]);
858c9f6c 863
92d7f7b0
JS
864 if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
865 ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) ||
866 (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED)))
867 goto out;
868
869 retry = cmdiocb->retry;
870 if (retry >= LPFC_MAX_NS_RETRY)
871 goto out;
872
873 retry++;
e8b62011 874 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
d7c255b2 875 "0250 Retrying NS cmd %x\n", cmdcode);
92d7f7b0
JS
876 rc = lpfc_ns_cmd(vport, cmdcode, retry, 0);
877 if (rc == 0)
878 goto out;
879 }
880
881out:
51ef4c26 882 cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
858c9f6c 883 lpfc_ct_free_iocb(phba, cmdiocb);
dea3101e 884 return;
885}
886
7ee5d43e
JS
887static void
888lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
889 struct lpfc_iocbq *rspiocb)
890{
891 IOCB_t *irsp = &rspiocb->iocb;
892 struct lpfc_vport *vport = cmdiocb->vport;
893
98c9ea5c
JS
894 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
895 struct lpfc_dmabuf *outp;
896 struct lpfc_sli_ct_request *CTrsp;
897
898 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
899 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
900 if (CTrsp->CommandResponse.bits.CmdRsp ==
901 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
902 vport->ct_flags |= FC_CT_RFT_ID;
903 }
7ee5d43e
JS
904 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
905 return;
906}
907
dea3101e 908static void
2e0fef85
JS
909lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
910 struct lpfc_iocbq *rspiocb)
dea3101e 911{
7ee5d43e
JS
912 IOCB_t *irsp = &rspiocb->iocb;
913 struct lpfc_vport *vport = cmdiocb->vport;
914
98c9ea5c
JS
915 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
916 struct lpfc_dmabuf *outp;
917 struct lpfc_sli_ct_request *CTrsp;
918
919 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
920 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
921 if (CTrsp->CommandResponse.bits.CmdRsp ==
922 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
923 vport->ct_flags |= FC_CT_RNN_ID;
924 }
7ee5d43e 925 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
dea3101e 926 return;
927}
928
92d7f7b0
JS
929static void
930lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
931 struct lpfc_iocbq *rspiocb)
932{
7ee5d43e
JS
933 IOCB_t *irsp = &rspiocb->iocb;
934 struct lpfc_vport *vport = cmdiocb->vport;
935
98c9ea5c
JS
936 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
937 struct lpfc_dmabuf *outp;
938 struct lpfc_sli_ct_request *CTrsp;
939
940 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
941 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
942 if (CTrsp->CommandResponse.bits.CmdRsp ==
943 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
944 vport->ct_flags |= FC_CT_RSPN_ID;
945 }
7ee5d43e 946 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
92d7f7b0
JS
947 return;
948}
949
dea3101e 950static void
2e0fef85
JS
951lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
952 struct lpfc_iocbq *rspiocb)
dea3101e 953{
7ee5d43e
JS
954 IOCB_t *irsp = &rspiocb->iocb;
955 struct lpfc_vport *vport = cmdiocb->vport;
956
98c9ea5c
JS
957 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
958 struct lpfc_dmabuf *outp;
959 struct lpfc_sli_ct_request *CTrsp;
960
961 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
962 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
963 if (CTrsp->CommandResponse.bits.CmdRsp ==
964 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
965 vport->ct_flags |= FC_CT_RSNN_NN;
966 }
7ee5d43e
JS
967 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
968 return;
969}
970
971static void
972lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
973 struct lpfc_iocbq *rspiocb)
974{
975 struct lpfc_vport *vport = cmdiocb->vport;
976
977 /* even if it fails we will act as though it succeeded. */
978 vport->ct_flags = 0;
979 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
dea3101e 980 return;
981}
982
2fb9bd8b 983static void
92d7f7b0
JS
984lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
985 struct lpfc_iocbq *rspiocb)
2fb9bd8b 986{
92d7f7b0
JS
987 IOCB_t *irsp = &rspiocb->iocb;
988 struct lpfc_vport *vport = cmdiocb->vport;
989
98c9ea5c
JS
990 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
991 struct lpfc_dmabuf *outp;
992 struct lpfc_sli_ct_request *CTrsp;
993
994 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
995 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
996 if (CTrsp->CommandResponse.bits.CmdRsp ==
997 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
998 vport->ct_flags |= FC_CT_RFF_ID;
999 }
7ee5d43e 1000 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
2fb9bd8b
JS
1001 return;
1002}
1003
495a714c 1004int
92d7f7b0
JS
1005lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
1006 size_t size)
1007{
1008 int n;
1009 uint8_t *wwn = vport->phba->wwpn;
1010
1011 n = snprintf(symbol, size,
1012 "Emulex PPN-%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1013 wwn[0], wwn[1], wwn[2], wwn[3],
1014 wwn[4], wwn[5], wwn[6], wwn[7]);
1015
1016 if (vport->port_type == LPFC_PHYSICAL_PORT)
1017 return n;
1018
1019 if (n < size)
1020 n += snprintf(symbol + n, size - n, " VPort-%d", vport->vpi);
1021
eada272d
JS
1022 if (n < size &&
1023 strlen(vport->fc_vport->symbolic_name))
1024 n += snprintf(symbol + n, size - n, " VName-%s",
1025 vport->fc_vport->symbolic_name);
92d7f7b0
JS
1026 return n;
1027}
1028
1029int
1030lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,
1031 size_t size)
dea3101e 1032{
1033 char fwrev[16];
92d7f7b0 1034 int n;
dea3101e 1035
92d7f7b0 1036 lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
dea3101e 1037
92d7f7b0
JS
1038 n = snprintf(symbol, size, "Emulex %s FV%s DV%s",
1039 vport->phba->ModelName, fwrev, lpfc_release_version);
1040 return n;
dea3101e 1041}
1042
1043/*
1044 * lpfc_ns_cmd
1045 * Description:
1046 * Issue Cmd to NameServer
1047 * SLI_CTNS_GID_FT
1048 * LI_CTNS_RFT_ID
1049 */
1050int
92d7f7b0
JS
1051lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1052 uint8_t retry, uint32_t context)
dea3101e 1053{
92d7f7b0 1054 struct lpfc_nodelist * ndlp;
2e0fef85 1055 struct lpfc_hba *phba = vport->phba;
dea3101e 1056 struct lpfc_dmabuf *mp, *bmp;
1057 struct lpfc_sli_ct_request *CtReq;
1058 struct ulp_bde64 *bpl;
1059 void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
1060 struct lpfc_iocbq *) = NULL;
1061 uint32_t rsp_size = 1024;
92d7f7b0 1062 size_t size;
858c9f6c 1063 int rc = 0;
92d7f7b0
JS
1064
1065 ndlp = lpfc_findnode_did(vport, NameServer_DID);
e47c9093
JS
1066 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)
1067 || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) {
858c9f6c
JS
1068 rc=1;
1069 goto ns_cmd_exit;
1070 }
dea3101e 1071
1072 /* fill in BDEs for command */
1073 /* Allocate buffer for command payload */
1074 mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
858c9f6c
JS
1075 if (!mp) {
1076 rc=2;
dea3101e 1077 goto ns_cmd_exit;
858c9f6c 1078 }
dea3101e 1079
1080 INIT_LIST_HEAD(&mp->list);
1081 mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
858c9f6c
JS
1082 if (!mp->virt) {
1083 rc=3;
dea3101e 1084 goto ns_cmd_free_mp;
858c9f6c 1085 }
dea3101e 1086
1087 /* Allocate buffer for Buffer ptr list */
1088 bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
858c9f6c
JS
1089 if (!bmp) {
1090 rc=4;
dea3101e 1091 goto ns_cmd_free_mpvirt;
858c9f6c 1092 }
dea3101e 1093
1094 INIT_LIST_HEAD(&bmp->list);
1095 bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(bmp->phys));
858c9f6c
JS
1096 if (!bmp->virt) {
1097 rc=5;
dea3101e 1098 goto ns_cmd_free_bmp;
858c9f6c 1099 }
dea3101e 1100
1101 /* NameServer Req */
e8b62011
JS
1102 lpfc_printf_vlog(vport, KERN_INFO ,LOG_DISCOVERY,
1103 "0236 NameServer Req Data: x%x x%x x%x\n",
1104 cmdcode, vport->fc_flag, vport->fc_rscn_id_cnt);
dea3101e 1105
1106 bpl = (struct ulp_bde64 *) bmp->virt;
1107 memset(bpl, 0, sizeof(struct ulp_bde64));
92d7f7b0
JS
1108 bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
1109 bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
dea3101e 1110 bpl->tus.f.bdeFlags = 0;
1111 if (cmdcode == SLI_CTNS_GID_FT)
1112 bpl->tus.f.bdeSize = GID_REQUEST_SZ;
92d7f7b0
JS
1113 else if (cmdcode == SLI_CTNS_GFF_ID)
1114 bpl->tus.f.bdeSize = GFF_REQUEST_SZ;
dea3101e 1115 else if (cmdcode == SLI_CTNS_RFT_ID)
1116 bpl->tus.f.bdeSize = RFT_REQUEST_SZ;
1117 else if (cmdcode == SLI_CTNS_RNN_ID)
1118 bpl->tus.f.bdeSize = RNN_REQUEST_SZ;
92d7f7b0
JS
1119 else if (cmdcode == SLI_CTNS_RSPN_ID)
1120 bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
dea3101e 1121 else if (cmdcode == SLI_CTNS_RSNN_NN)
1122 bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
7ee5d43e
JS
1123 else if (cmdcode == SLI_CTNS_DA_ID)
1124 bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
2fb9bd8b
JS
1125 else if (cmdcode == SLI_CTNS_RFF_ID)
1126 bpl->tus.f.bdeSize = RFF_REQUEST_SZ;
dea3101e 1127 else
1128 bpl->tus.f.bdeSize = 0;
1129 bpl->tus.w = le32_to_cpu(bpl->tus.w);
1130
1131 CtReq = (struct lpfc_sli_ct_request *) mp->virt;
1132 memset(CtReq, 0, sizeof (struct lpfc_sli_ct_request));
1133 CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
1134 CtReq->RevisionId.bits.InId = 0;
1135 CtReq->FsType = SLI_CT_DIRECTORY_SERVICE;
1136 CtReq->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER;
1137 CtReq->CommandResponse.bits.Size = 0;
1138 switch (cmdcode) {
1139 case SLI_CTNS_GID_FT:
1140 CtReq->CommandResponse.bits.CmdRsp =
1141 be16_to_cpu(SLI_CTNS_GID_FT);
1142 CtReq->un.gid.Fc4Type = SLI_CTPT_FCP;
92d7f7b0 1143 if (vport->port_state < LPFC_NS_QRY)
2e0fef85
JS
1144 vport->port_state = LPFC_NS_QRY;
1145 lpfc_set_disctmo(vport);
dea3101e 1146 cmpl = lpfc_cmpl_ct_cmd_gid_ft;
1147 rsp_size = FC_MAX_NS_RSP;
1148 break;
1149
92d7f7b0
JS
1150 case SLI_CTNS_GFF_ID:
1151 CtReq->CommandResponse.bits.CmdRsp =
1152 be16_to_cpu(SLI_CTNS_GFF_ID);
09372820 1153 CtReq->un.gff.PortId = cpu_to_be32(context);
92d7f7b0
JS
1154 cmpl = lpfc_cmpl_ct_cmd_gff_id;
1155 break;
1156
dea3101e 1157 case SLI_CTNS_RFT_ID:
7ee5d43e 1158 vport->ct_flags &= ~FC_CT_RFT_ID;
dea3101e 1159 CtReq->CommandResponse.bits.CmdRsp =
1160 be16_to_cpu(SLI_CTNS_RFT_ID);
09372820 1161 CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID);
dea3101e 1162 CtReq->un.rft.fcpReg = 1;
1163 cmpl = lpfc_cmpl_ct_cmd_rft_id;
1164 break;
1165
1166 case SLI_CTNS_RNN_ID:
7ee5d43e 1167 vport->ct_flags &= ~FC_CT_RNN_ID;
dea3101e 1168 CtReq->CommandResponse.bits.CmdRsp =
1169 be16_to_cpu(SLI_CTNS_RNN_ID);
09372820 1170 CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID);
2e0fef85 1171 memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename,
dea3101e 1172 sizeof (struct lpfc_name));
1173 cmpl = lpfc_cmpl_ct_cmd_rnn_id;
1174 break;
1175
92d7f7b0 1176 case SLI_CTNS_RSPN_ID:
7ee5d43e 1177 vport->ct_flags &= ~FC_CT_RSPN_ID;
92d7f7b0
JS
1178 CtReq->CommandResponse.bits.CmdRsp =
1179 be16_to_cpu(SLI_CTNS_RSPN_ID);
09372820 1180 CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID);
92d7f7b0
JS
1181 size = sizeof(CtReq->un.rspn.symbname);
1182 CtReq->un.rspn.len =
1183 lpfc_vport_symbolic_port_name(vport,
1184 CtReq->un.rspn.symbname, size);
1185 cmpl = lpfc_cmpl_ct_cmd_rspn_id;
1186 break;
dea3101e 1187 case SLI_CTNS_RSNN_NN:
7ee5d43e 1188 vport->ct_flags &= ~FC_CT_RSNN_NN;
dea3101e 1189 CtReq->CommandResponse.bits.CmdRsp =
1190 be16_to_cpu(SLI_CTNS_RSNN_NN);
2e0fef85 1191 memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename,
dea3101e 1192 sizeof (struct lpfc_name));
92d7f7b0
JS
1193 size = sizeof(CtReq->un.rsnn.symbname);
1194 CtReq->un.rsnn.len =
1195 lpfc_vport_symbolic_node_name(vport,
1196 CtReq->un.rsnn.symbname, size);
dea3101e 1197 cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
1198 break;
7ee5d43e
JS
1199 case SLI_CTNS_DA_ID:
1200 /* Implement DA_ID Nameserver request */
1201 CtReq->CommandResponse.bits.CmdRsp =
1202 be16_to_cpu(SLI_CTNS_DA_ID);
09372820 1203 CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID);
7ee5d43e
JS
1204 cmpl = lpfc_cmpl_ct_cmd_da_id;
1205 break;
92d7f7b0 1206 case SLI_CTNS_RFF_ID:
7ee5d43e 1207 vport->ct_flags &= ~FC_CT_RFF_ID;
92d7f7b0
JS
1208 CtReq->CommandResponse.bits.CmdRsp =
1209 be16_to_cpu(SLI_CTNS_RFF_ID);
a419aef8 1210 CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);
92d7f7b0
JS
1211 CtReq->un.rff.fbits = FC4_FEATURE_INIT;
1212 CtReq->un.rff.type_code = FC_FCP_DATA;
1213 cmpl = lpfc_cmpl_ct_cmd_rff_id;
1214 break;
dea3101e 1215 }
e47c9093
JS
1216 /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
1217 * to hold ndlp reference for the corresponding callback function.
1218 */
858c9f6c 1219 if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) {
dea3101e 1220 /* On success, The cmpl function will free the buffers */
858c9f6c
JS
1221 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
1222 "Issue CT cmd: cmd:x%x did:x%x",
1223 cmdcode, ndlp->nlp_DID, 0);
dea3101e 1224 return 0;
858c9f6c 1225 }
858c9f6c 1226 rc=6;
e47c9093
JS
1227
1228 /* Decrement ndlp reference count to release ndlp reference held
1229 * for the failed command's callback function.
1230 */
51ef4c26 1231 lpfc_nlp_put(ndlp);
e47c9093 1232
dea3101e 1233 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
1234ns_cmd_free_bmp:
1235 kfree(bmp);
1236ns_cmd_free_mpvirt:
1237 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1238ns_cmd_free_mp:
1239 kfree(mp);
1240ns_cmd_exit:
e8b62011
JS
1241 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
1242 "0266 Issue NameServer Req x%x err %d Data: x%x x%x\n",
1243 cmdcode, rc, vport->fc_flag, vport->fc_rscn_id_cnt);
dea3101e 1244 return 1;
1245}
1246
1247static void
2e0fef85
JS
1248lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1249 struct lpfc_iocbq * rspiocb)
dea3101e 1250{
dea3101e 1251 struct lpfc_dmabuf *inp = cmdiocb->context1;
1252 struct lpfc_dmabuf *outp = cmdiocb->context2;
1253 struct lpfc_sli_ct_request *CTrsp = outp->virt;
1254 struct lpfc_sli_ct_request *CTcmd = inp->virt;
1255 struct lpfc_nodelist *ndlp;
1256 uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
1257 uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
2e0fef85 1258 struct lpfc_vport *vport = cmdiocb->vport;
858c9f6c
JS
1259 IOCB_t *irsp = &rspiocb->iocb;
1260 uint32_t latt;
1261
1262 latt = lpfc_els_chk_latt(vport);
1263
1264 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
1265 "FDMI cmpl: status:x%x/x%x latt:%d",
1266 irsp->ulpStatus, irsp->un.ulpWord[4], latt);
1267
1268 if (latt || irsp->ulpStatus) {
e8b62011
JS
1269 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1270 "0229 FDMI cmd %04x failed, latt = %d "
1271 "ulpStatus: x%x, rid x%x\n",
1272 be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus,
1273 irsp->un.ulpWord[4]);
858c9f6c
JS
1274 lpfc_ct_free_iocb(phba, cmdiocb);
1275 return;
1276 }
dea3101e 1277
2e0fef85 1278 ndlp = lpfc_findnode_did(vport, FDMI_DID);
e47c9093
JS
1279 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
1280 goto fail_out;
1281
dea3101e 1282 if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
1283 /* FDMI rsp failed */
e8b62011
JS
1284 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1285 "0220 FDMI rsp failed Data: x%x\n",
1286 be16_to_cpu(fdmi_cmd));
dea3101e 1287 }
1288
1289 switch (be16_to_cpu(fdmi_cmd)) {
1290 case SLI_MGMT_RHBA:
2e0fef85 1291 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA);
dea3101e 1292 break;
1293
1294 case SLI_MGMT_RPA:
1295 break;
1296
1297 case SLI_MGMT_DHBA:
2e0fef85 1298 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT);
dea3101e 1299 break;
1300
1301 case SLI_MGMT_DPRT:
2e0fef85 1302 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA);
dea3101e 1303 break;
1304 }
e47c9093
JS
1305
1306fail_out:
858c9f6c 1307 lpfc_ct_free_iocb(phba, cmdiocb);
dea3101e 1308 return;
1309}
2e0fef85 1310
dea3101e 1311int
2e0fef85 1312lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
dea3101e 1313{
2e0fef85 1314 struct lpfc_hba *phba = vport->phba;
dea3101e 1315 struct lpfc_dmabuf *mp, *bmp;
1316 struct lpfc_sli_ct_request *CtReq;
1317 struct ulp_bde64 *bpl;
1318 uint32_t size;
1319 REG_HBA *rh;
1320 PORT_ENTRY *pe;
1321 REG_PORT_ATTRIBUTE *pab;
1322 ATTRIBUTE_BLOCK *ab;
1323 ATTRIBUTE_ENTRY *ae;
1324 void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
1325 struct lpfc_iocbq *);
1326
1327
1328 /* fill in BDEs for command */
1329 /* Allocate buffer for command payload */
1330 mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
1331 if (!mp)
1332 goto fdmi_cmd_exit;
1333
1334 mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
1335 if (!mp->virt)
1336 goto fdmi_cmd_free_mp;
1337
1338 /* Allocate buffer for Buffer ptr list */
1339 bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
1340 if (!bmp)
1341 goto fdmi_cmd_free_mpvirt;
1342
1343 bmp->virt = lpfc_mbuf_alloc(phba, 0, &(bmp->phys));
1344 if (!bmp->virt)
1345 goto fdmi_cmd_free_bmp;
1346
1347 INIT_LIST_HEAD(&mp->list);
1348 INIT_LIST_HEAD(&bmp->list);
1349
1350 /* FDMI request */
e8b62011
JS
1351 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1352 "0218 FDMI Request Data: x%x x%x x%x\n",
1353 vport->fc_flag, vport->port_state, cmdcode);
dea3101e 1354 CtReq = (struct lpfc_sli_ct_request *) mp->virt;
1355
1356 memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
1357 CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
1358 CtReq->RevisionId.bits.InId = 0;
1359
1360 CtReq->FsType = SLI_CT_MANAGEMENT_SERVICE;
1361 CtReq->FsSubType = SLI_CT_FDMI_Subtypes;
1362 size = 0;
1363
1364 switch (cmdcode) {
1365 case SLI_MGMT_RHBA:
1366 {
1367 lpfc_vpd_t *vp = &phba->vpd;
1368 uint32_t i, j, incr;
1369 int len;
1370
1371 CtReq->CommandResponse.bits.CmdRsp =
1372 be16_to_cpu(SLI_MGMT_RHBA);
1373 CtReq->CommandResponse.bits.Size = 0;
1374 rh = (REG_HBA *) & CtReq->un.PortID;
2e0fef85 1375 memcpy(&rh->hi.PortName, &vport->fc_sparam.portName,
dea3101e 1376 sizeof (struct lpfc_name));
1377 /* One entry (port) per adapter */
1378 rh->rpl.EntryCnt = be32_to_cpu(1);
2e0fef85 1379 memcpy(&rh->rpl.pe, &vport->fc_sparam.portName,
dea3101e 1380 sizeof (struct lpfc_name));
1381
1382 /* point to the HBA attribute block */
1383 size = 2 * sizeof (struct lpfc_name) + FOURBYTES;
1384 ab = (ATTRIBUTE_BLOCK *) ((uint8_t *) rh + size);
1385 ab->EntryCnt = 0;
1386
1387 /* Point to the beginning of the first HBA attribute
1388 entry */
1389 /* #1 HBA attribute entry */
1390 size += FOURBYTES;
1391 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1392 ae->ad.bits.AttrType = be16_to_cpu(NODE_NAME);
1393 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES
1394 + sizeof (struct lpfc_name));
2e0fef85 1395 memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName,
dea3101e 1396 sizeof (struct lpfc_name));
1397 ab->EntryCnt++;
1398 size += FOURBYTES + sizeof (struct lpfc_name);
1399
1400 /* #2 HBA attribute entry */
1401 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1402 ae->ad.bits.AttrType = be16_to_cpu(MANUFACTURER);
1403 strcpy(ae->un.Manufacturer, "Emulex Corporation");
1404 len = strlen(ae->un.Manufacturer);
1405 len += (len & 3) ? (4 - (len & 3)) : 4;
1406 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
1407 ab->EntryCnt++;
1408 size += FOURBYTES + len;
1409
1410 /* #3 HBA attribute entry */
1411 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1412 ae->ad.bits.AttrType = be16_to_cpu(SERIAL_NUMBER);
1413 strcpy(ae->un.SerialNumber, phba->SerialNumber);
1414 len = strlen(ae->un.SerialNumber);
1415 len += (len & 3) ? (4 - (len & 3)) : 4;
1416 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
1417 ab->EntryCnt++;
1418 size += FOURBYTES + len;
1419
1420 /* #4 HBA attribute entry */
1421 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1422 ae->ad.bits.AttrType = be16_to_cpu(MODEL);
1423 strcpy(ae->un.Model, phba->ModelName);
1424 len = strlen(ae->un.Model);
1425 len += (len & 3) ? (4 - (len & 3)) : 4;
1426 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
1427 ab->EntryCnt++;
1428 size += FOURBYTES + len;
1429
1430 /* #5 HBA attribute entry */
1431 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1432 ae->ad.bits.AttrType = be16_to_cpu(MODEL_DESCRIPTION);
1433 strcpy(ae->un.ModelDescription, phba->ModelDesc);
1434 len = strlen(ae->un.ModelDescription);
1435 len += (len & 3) ? (4 - (len & 3)) : 4;
1436 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
1437 ab->EntryCnt++;
1438 size += FOURBYTES + len;
1439
1440 /* #6 HBA attribute entry */
1441 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1442 ae->ad.bits.AttrType = be16_to_cpu(HARDWARE_VERSION);
1443 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 8);
1444 /* Convert JEDEC ID to ascii for hardware version */
1445 incr = vp->rev.biuRev;
1446 for (i = 0; i < 8; i++) {
1447 j = (incr & 0xf);
1448 if (j <= 9)
1449 ae->un.HardwareVersion[7 - i] =
1450 (char)((uint8_t) 0x30 +
1451 (uint8_t) j);
1452 else
1453 ae->un.HardwareVersion[7 - i] =
1454 (char)((uint8_t) 0x61 +
1455 (uint8_t) (j - 10));
1456 incr = (incr >> 4);
1457 }
1458 ab->EntryCnt++;
1459 size += FOURBYTES + 8;
1460
1461 /* #7 HBA attribute entry */
1462 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1463 ae->ad.bits.AttrType = be16_to_cpu(DRIVER_VERSION);
1464 strcpy(ae->un.DriverVersion, lpfc_release_version);
1465 len = strlen(ae->un.DriverVersion);
1466 len += (len & 3) ? (4 - (len & 3)) : 4;
1467 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
1468 ab->EntryCnt++;
1469 size += FOURBYTES + len;
1470
1471 /* #8 HBA attribute entry */
1472 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1473 ae->ad.bits.AttrType = be16_to_cpu(OPTION_ROM_VERSION);
1474 strcpy(ae->un.OptionROMVersion, phba->OptionROMVersion);
1475 len = strlen(ae->un.OptionROMVersion);
1476 len += (len & 3) ? (4 - (len & 3)) : 4;
1477 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
1478 ab->EntryCnt++;
1479 size += FOURBYTES + len;
1480
1481 /* #9 HBA attribute entry */
1482 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1483 ae->ad.bits.AttrType = be16_to_cpu(FIRMWARE_VERSION);
1484 lpfc_decode_firmware_rev(phba, ae->un.FirmwareVersion,
1485 1);
1486 len = strlen(ae->un.FirmwareVersion);
1487 len += (len & 3) ? (4 - (len & 3)) : 4;
1488 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
1489 ab->EntryCnt++;
1490 size += FOURBYTES + len;
1491
1492 /* #10 HBA attribute entry */
1493 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1494 ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION);
1495 sprintf(ae->un.OsNameVersion, "%s %s %s",
2fb9bd8b
JS
1496 init_utsname()->sysname,
1497 init_utsname()->release,
96b644bd 1498 init_utsname()->version);
dea3101e 1499 len = strlen(ae->un.OsNameVersion);
1500 len += (len & 3) ? (4 - (len & 3)) : 4;
1501 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
1502 ab->EntryCnt++;
1503 size += FOURBYTES + len;
1504
1505 /* #11 HBA attribute entry */
1506 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size);
1507 ae->ad.bits.AttrType = be16_to_cpu(MAX_CT_PAYLOAD_LEN);
1508 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
1509 ae->un.MaxCTPayloadLen = (65 * 4096);
1510 ab->EntryCnt++;
1511 size += FOURBYTES + 4;
1512
1513 ab->EntryCnt = be32_to_cpu(ab->EntryCnt);
1514 /* Total size */
1515 size = GID_REQUEST_SZ - 4 + size;
1516 }
1517 break;
1518
1519 case SLI_MGMT_RPA:
1520 {
1521 lpfc_vpd_t *vp;
1522 struct serv_parm *hsp;
1523 int len;
1524
1525 vp = &phba->vpd;
1526
1527 CtReq->CommandResponse.bits.CmdRsp =
1528 be16_to_cpu(SLI_MGMT_RPA);
1529 CtReq->CommandResponse.bits.Size = 0;
1530 pab = (REG_PORT_ATTRIBUTE *) & CtReq->un.PortID;
1531 size = sizeof (struct lpfc_name) + FOURBYTES;
1532 memcpy((uint8_t *) & pab->PortName,
2e0fef85 1533 (uint8_t *) & vport->fc_sparam.portName,
dea3101e 1534 sizeof (struct lpfc_name));
1535 pab->ab.EntryCnt = 0;
1536
1537 /* #1 Port attribute entry */
1538 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
1539 ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_FC4_TYPES);
1540 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 32);
1541 ae->un.SupportFC4Types[2] = 1;
1542 ae->un.SupportFC4Types[7] = 1;
1543 pab->ab.EntryCnt++;
1544 size += FOURBYTES + 32;
1545
1546 /* #2 Port attribute entry */
1547 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
1548 ae->ad.bits.AttrType = be16_to_cpu(SUPPORTED_SPEED);
1549 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
74b72a59
JW
1550
1551 ae->un.SupportSpeed = 0;
1552 if (phba->lmt & LMT_10Gb)
dea3101e 1553 ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT;
74b72a59
JW
1554 if (phba->lmt & LMT_8Gb)
1555 ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT;
1556 if (phba->lmt & LMT_4Gb)
1557 ae->un.SupportSpeed |= HBA_PORTSPEED_4GBIT;
1558 if (phba->lmt & LMT_2Gb)
1559 ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT;
1560 if (phba->lmt & LMT_1Gb)
1561 ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT;
1562
dea3101e 1563 pab->ab.EntryCnt++;
1564 size += FOURBYTES + 4;
1565
1566 /* #3 Port attribute entry */
1567 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
1568 ae->ad.bits.AttrType = be16_to_cpu(PORT_SPEED);
1569 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
1570 switch(phba->fc_linkspeed) {
1571 case LA_1GHZ_LINK:
1572 ae->un.PortSpeed = HBA_PORTSPEED_1GBIT;
1573 break;
1574 case LA_2GHZ_LINK:
1575 ae->un.PortSpeed = HBA_PORTSPEED_2GBIT;
1576 break;
1577 case LA_4GHZ_LINK:
1578 ae->un.PortSpeed = HBA_PORTSPEED_4GBIT;
1579 break;
b87eab38
JS
1580 case LA_8GHZ_LINK:
1581 ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
1582 break;
f4b4c68f
JS
1583 case LA_10GHZ_LINK:
1584 ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
1585 break;
dea3101e 1586 default:
1587 ae->un.PortSpeed =
1588 HBA_PORTSPEED_UNKNOWN;
1589 break;
1590 }
1591 pab->ab.EntryCnt++;
1592 size += FOURBYTES + 4;
1593
1594 /* #4 Port attribute entry */
1595 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
1596 ae->ad.bits.AttrType = be16_to_cpu(MAX_FRAME_SIZE);
1597 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4);
2e0fef85 1598 hsp = (struct serv_parm *) & vport->fc_sparam;
dea3101e 1599 ae->un.MaxFrameSize =
1600 (((uint32_t) hsp->cmn.
1601 bbRcvSizeMsb) << 8) | (uint32_t) hsp->cmn.
1602 bbRcvSizeLsb;
1603 pab->ab.EntryCnt++;
1604 size += FOURBYTES + 4;
1605
1606 /* #5 Port attribute entry */
1607 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size);
1608 ae->ad.bits.AttrType = be16_to_cpu(OS_DEVICE_NAME);
1609 strcpy((char *)ae->un.OsDeviceName, LPFC_DRIVER_NAME);
1610 len = strlen((char *)ae->un.OsDeviceName);
1611 len += (len & 3) ? (4 - (len & 3)) : 4;
1612 ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + len);
1613 pab->ab.EntryCnt++;
1614 size += FOURBYTES + len;
1615
3de2a653 1616 if (vport->cfg_fdmi_on == 2) {
dea3101e 1617 /* #6 Port attribute entry */
1618 ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab +
1619 size);
1620 ae->ad.bits.AttrType = be16_to_cpu(HOST_NAME);
1621 sprintf(ae->un.HostName, "%s",
96b644bd 1622 init_utsname()->nodename);
dea3101e 1623 len = strlen(ae->un.HostName);
1624 len += (len & 3) ? (4 - (len & 3)) : 4;
1625 ae->ad.bits.AttrLen =
1626 be16_to_cpu(FOURBYTES + len);
1627 pab->ab.EntryCnt++;
1628 size += FOURBYTES + len;
1629 }
1630
1631 pab->ab.EntryCnt = be32_to_cpu(pab->ab.EntryCnt);
1632 /* Total size */
1633 size = GID_REQUEST_SZ - 4 + size;
1634 }
1635 break;
1636
1637 case SLI_MGMT_DHBA:
1638 CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_MGMT_DHBA);
1639 CtReq->CommandResponse.bits.Size = 0;
1640 pe = (PORT_ENTRY *) & CtReq->un.PortID;
1641 memcpy((uint8_t *) & pe->PortName,
2e0fef85 1642 (uint8_t *) & vport->fc_sparam.portName,
dea3101e 1643 sizeof (struct lpfc_name));
1644 size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name);
1645 break;
1646
1647 case SLI_MGMT_DPRT:
1648 CtReq->CommandResponse.bits.CmdRsp = be16_to_cpu(SLI_MGMT_DPRT);
1649 CtReq->CommandResponse.bits.Size = 0;
1650 pe = (PORT_ENTRY *) & CtReq->un.PortID;
1651 memcpy((uint8_t *) & pe->PortName,
2e0fef85 1652 (uint8_t *) & vport->fc_sparam.portName,
dea3101e 1653 sizeof (struct lpfc_name));
1654 size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name);
1655 break;
1656 }
1657
1658 bpl = (struct ulp_bde64 *) bmp->virt;
92d7f7b0
JS
1659 bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
1660 bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
dea3101e 1661 bpl->tus.f.bdeFlags = 0;
1662 bpl->tus.f.bdeSize = size;
1663 bpl->tus.w = le32_to_cpu(bpl->tus.w);
1664
1665 cmpl = lpfc_cmpl_ct_cmd_fdmi;
1666
e47c9093
JS
1667 /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
1668 * to hold ndlp reference for the corresponding callback function.
1669 */
92d7f7b0 1670 if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0))
dea3101e 1671 return 0;
1672
e47c9093
JS
1673 /* Decrement ndlp reference count to release ndlp reference held
1674 * for the failed command's callback function.
1675 */
51ef4c26 1676 lpfc_nlp_put(ndlp);
e47c9093 1677
dea3101e 1678 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
1679fdmi_cmd_free_bmp:
1680 kfree(bmp);
1681fdmi_cmd_free_mpvirt:
1682 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1683fdmi_cmd_free_mp:
1684 kfree(mp);
1685fdmi_cmd_exit:
1686 /* Issue FDMI request failed */
e8b62011
JS
1687 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1688 "0244 Issue FDMI request failed Data: x%x\n",
1689 cmdcode);
dea3101e 1690 return 1;
1691}
1692
1693void
1694lpfc_fdmi_tmo(unsigned long ptr)
1695{
2e0fef85
JS
1696 struct lpfc_vport *vport = (struct lpfc_vport *)ptr;
1697 struct lpfc_hba *phba = vport->phba;
5e9d9b82 1698 uint32_t tmo_posted;
dea3101e 1699 unsigned long iflag;
1700
2e0fef85 1701 spin_lock_irqsave(&vport->work_port_lock, iflag);
5e9d9b82
JS
1702 tmo_posted = vport->work_port_events & WORKER_FDMI_TMO;
1703 if (!tmo_posted)
2e0fef85 1704 vport->work_port_events |= WORKER_FDMI_TMO;
5e9d9b82 1705 spin_unlock_irqrestore(&vport->work_port_lock, iflag);
92d7f7b0 1706
5e9d9b82
JS
1707 if (!tmo_posted)
1708 lpfc_worker_wake_up(phba);
1709 return;
dea3101e 1710}
1711
1712void
2e0fef85 1713lpfc_fdmi_timeout_handler(struct lpfc_vport *vport)
dea3101e 1714{
1715 struct lpfc_nodelist *ndlp;
1716
2e0fef85 1717 ndlp = lpfc_findnode_did(vport, FDMI_DID);
e47c9093 1718 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
2e0fef85
JS
1719 if (init_utsname()->nodename[0] != '\0')
1720 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
1721 else
1722 mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
dea3101e 1723 }
dea3101e 1724 return;
1725}
1726
dea3101e 1727void
2e0fef85 1728lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
dea3101e 1729{
1730 struct lpfc_sli *psli = &phba->sli;
1731 lpfc_vpd_t *vp = &phba->vpd;
1732 uint32_t b1, b2, b3, b4, i, rev;
1733 char c;
1734 uint32_t *ptr, str[4];
1735 uint8_t *fwname;
1736
f1126688
JS
1737 if (phba->sli_rev == LPFC_SLI_REV4)
1738 sprintf(fwrevision, "%s", vp->rev.opFwName);
1739 else if (vp->rev.rBit) {
f4b4c68f 1740 if (psli->sli_flag & LPFC_SLI_ACTIVE)
dea3101e 1741 rev = vp->rev.sli2FwRev;
1742 else
1743 rev = vp->rev.sli1FwRev;
1744
1745 b1 = (rev & 0x0000f000) >> 12;
1746 b2 = (rev & 0x00000f00) >> 8;
1747 b3 = (rev & 0x000000c0) >> 6;
1748 b4 = (rev & 0x00000030) >> 4;
1749
1750 switch (b4) {
1751 case 0:
1752 c = 'N';
1753 break;
1754 case 1:
1755 c = 'A';
1756 break;
1757 case 2:
1758 c = 'B';
1759 break;
1760 default:
1761 c = 0;
1762 break;
1763 }
1764 b4 = (rev & 0x0000000f);
1765
f4b4c68f 1766 if (psli->sli_flag & LPFC_SLI_ACTIVE)
dea3101e 1767 fwname = vp->rev.sli2FwName;
1768 else
1769 fwname = vp->rev.sli1FwName;
1770
1771 for (i = 0; i < 16; i++)
1772 if (fwname[i] == 0x20)
1773 fwname[i] = 0;
1774
1775 ptr = (uint32_t*)fwname;
1776
1777 for (i = 0; i < 3; i++)
1778 str[i] = be32_to_cpu(*ptr++);
1779
1780 if (c == 0) {
1781 if (flag)
1782 sprintf(fwrevision, "%d.%d%d (%s)",
1783 b1, b2, b3, (char *)str);
1784 else
1785 sprintf(fwrevision, "%d.%d%d", b1,
1786 b2, b3);
1787 } else {
1788 if (flag)
1789 sprintf(fwrevision, "%d.%d%d%c%d (%s)",
1790 b1, b2, b3, c,
1791 b4, (char *)str);
1792 else
1793 sprintf(fwrevision, "%d.%d%d%c%d",
1794 b1, b2, b3, c, b4);
1795 }
1796 } else {
1797 rev = vp->rev.smFwRev;
1798
1799 b1 = (rev & 0xff000000) >> 24;
1800 b2 = (rev & 0x00f00000) >> 20;
1801 b3 = (rev & 0x000f0000) >> 16;
1802 c = (rev & 0x0000ff00) >> 8;
1803 b4 = (rev & 0x000000ff);
1804
1805 if (flag)
1806 sprintf(fwrevision, "%d.%d%d%c%d ", b1,
1807 b2, b3, c, b4);
1808 else
1809 sprintf(fwrevision, "%d.%d%d%c%d ", b1,
1810 b2, b3, c, b4);
1811 }
1812 return;
1813}