x86/amd-iommu: Add function to complete a tlb flush
[linux/fpc-iii.git] / drivers / scsi / lpfc / lpfc_ct.c
blob9a1bd9534d744fd2e3454ea3c8ff67673324e02b
1 /*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2009 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com *
7 * *
8 * This program is free software; you can redistribute it and/or *
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. *
19 *******************************************************************/
22 * Fibre Channel SCSI LAN Device Driver CT support: FC Generic Services FC-GS
25 #include <linux/blkdev.h>
26 #include <linux/pci.h>
27 #include <linux/interrupt.h>
28 #include <linux/utsname.h>
30 #include <scsi/scsi.h>
31 #include <scsi/scsi_device.h>
32 #include <scsi/scsi_host.h>
33 #include <scsi/scsi_transport_fc.h>
35 #include "lpfc_hw4.h"
36 #include "lpfc_hw.h"
37 #include "lpfc_sli.h"
38 #include "lpfc_sli4.h"
39 #include "lpfc_nl.h"
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"
46 #include "lpfc_vport.h"
47 #include "lpfc_debugfs.h"
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 */
58 #define FOURBYTES 4
61 static char *lpfc_release_version = LPFC_DRIVER_VERSION;
63 static void
64 lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
65 struct lpfc_dmabuf *mp, uint32_t size)
67 if (!mp) {
68 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
69 "0146 Ignoring unsolicited CT No HBQ "
70 "status = x%x\n",
71 piocbq->iocb.ulpStatus);
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);
79 static void
80 lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
81 struct lpfc_dmabuf *mp, uint32_t size)
83 lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size);
86 void
87 lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
88 struct lpfc_iocbq *piocbq)
91 struct lpfc_dmabuf *mp = NULL;
92 IOCB_t *icmd = &piocbq->iocb;
93 int i;
94 struct lpfc_iocbq *iocbq;
95 dma_addr_t paddr;
96 uint32_t size;
97 struct list_head head;
98 struct lpfc_dmabuf *bdeBuf;
100 lpfc_bsg_ct_unsol_event(phba, pring, piocbq);
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)) {
106 /* Not enough posted buffers; Try posting more buffers */
107 phba->fc_stat.NoRcvBuf++;
108 if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
109 lpfc_post_buffer(phba, pring, 2);
110 return;
113 /* If there are no BDEs associated with this IOCB,
114 * there is nothing to do.
116 if (icmd->ulpBdeCount == 0)
117 return;
119 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
120 INIT_LIST_HEAD(&head);
121 list_add_tail(&head, &piocbq->list);
122 list_for_each_entry(iocbq, &head, list) {
123 icmd = &iocbq->iocb;
124 if (icmd->ulpBdeCount == 0)
125 continue;
126 bdeBuf = iocbq->context2;
127 iocbq->context2 = NULL;
128 size = icmd->un.cont64[0].tus.f.bdeSize;
129 lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size);
130 lpfc_in_buf_free(phba, bdeBuf);
131 if (icmd->ulpBdeCount == 2) {
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);
140 list_del(&head);
141 } else {
142 INIT_LIST_HEAD(&head);
143 list_add_tail(&head, &piocbq->list);
144 list_for_each_entry(iocbq, &head, list) {
145 icmd = &iocbq->iocb;
146 if (icmd->ulpBdeCount == 0)
147 lpfc_ct_unsol_buffer(phba, iocbq, NULL, 0);
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;
154 lpfc_ct_unsol_buffer(phba, iocbq, mp, size);
155 lpfc_in_buf_free(phba, mp);
157 lpfc_post_buffer(phba, pring, i);
159 list_del(&head);
163 static void
164 lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist)
166 struct lpfc_dmabuf *mlast, *next_mlast;
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);
173 lpfc_mbuf_free(phba, mlist->virt, mlist->phys);
174 kfree(mlist);
175 return;
178 static struct lpfc_dmabuf *
179 lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl,
180 uint32_t size, int *entries)
182 struct lpfc_dmabuf *mlist = NULL;
183 struct lpfc_dmabuf *mp;
184 int cnt, i = 0;
186 /* We get chunks of FCELSSIZE */
187 cnt = size > FCELSSIZE ? FCELSSIZE: size;
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;
198 INIT_LIST_HEAD(&mp->list);
200 if (cmdcode == be16_to_cpu(SLI_CTNS_GID_FT) ||
201 cmdcode == be16_to_cpu(SLI_CTNS_GFF_ID))
202 mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
203 else
204 mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
206 if (!mp->virt) {
207 kfree(mp);
208 if (mlist)
209 lpfc_free_ct_rsp(phba, mlist);
210 return NULL;
213 /* Queue it to a linked list */
214 if (!mlist)
215 mlist = mp;
216 else
217 list_add_tail(&mp->list, &mlist->list);
219 bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
220 /* build buffer ptr list for IOCB */
221 bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
222 bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
223 bpl->tus.f.bdeSize = (uint16_t) cnt;
224 bpl->tus.w = le32_to_cpu(bpl->tus.w);
225 bpl++;
227 i++;
228 size -= cnt;
231 *entries = i;
232 return mlist;
236 lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb)
238 struct lpfc_dmabuf *buf_ptr;
240 if (ctiocb->context_un.ndlp) {
241 lpfc_nlp_put(ctiocb->context_un.ndlp);
242 ctiocb->context_un.ndlp = NULL;
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;
250 if (ctiocb->context2) {
251 lpfc_free_ct_rsp(phba, (struct lpfc_dmabuf *) ctiocb->context2);
252 ctiocb->context2 = NULL;
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;
261 lpfc_sli_release_iocbq(phba, ctiocb);
262 return 0;
265 static int
266 lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
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,
271 uint32_t tmo, uint8_t retry)
273 struct lpfc_hba *phba = vport->phba;
274 IOCB_t *icmd;
275 struct lpfc_iocbq *geniocb;
276 int rc;
278 /* Allocate buffer for command iocb */
279 geniocb = lpfc_sli_get_iocbq(phba);
281 if (geniocb == NULL)
282 return 1;
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);
288 icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
289 icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof (struct ulp_bde64));
291 if (usr_flg)
292 geniocb->context3 = NULL;
293 else
294 geniocb->context3 = (uint8_t *) bmp;
296 /* Save for completion so we can release these resources */
297 geniocb->context1 = (uint8_t *) inp;
298 geniocb->context2 = (uint8_t *) outp;
299 geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
301 /* Fill in payload, bp points to frame payload */
302 icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
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;
310 if (!tmo) {
311 /* FC spec states we need 3 * ratov for CT requests */
312 tmo = (3 * phba->fc_ratov);
314 icmd->ulpTimeout = tmo;
315 icmd->ulpBdeCount = 1;
316 icmd->ulpLe = 1;
317 icmd->ulpClass = CLASS3;
318 icmd->ulpContext = ndlp->nlp_rpi;
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;
326 /* Issue GEN REQ IOCB for NPORT <did> */
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);
332 geniocb->iocb_cmpl = cmpl;
333 geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
334 geniocb->vport = vport;
335 geniocb->retry = retry;
336 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);
338 if (rc == IOCB_ERROR) {
339 lpfc_sli_release_iocbq(phba, geniocb);
340 return 1;
343 return 0;
346 static int
347 lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,
348 struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp,
349 void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
350 struct lpfc_iocbq *),
351 uint32_t rsp_size, uint8_t retry)
353 struct lpfc_hba *phba = vport->phba;
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;
360 bpl++; /* Skip past ct request */
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;
367 status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0,
368 cnt+1, 0, retry);
369 if (status) {
370 lpfc_free_ct_rsp(phba, outmp);
371 return -ENOMEM;
373 return 0;
376 struct lpfc_vport *
377 lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) {
378 struct lpfc_vport *vport_curr;
379 unsigned long flags;
381 spin_lock_irqsave(&phba->hbalock, flags);
382 list_for_each_entry(vport_curr, &phba->port_list, listentry) {
383 if ((vport_curr->fc_myDID) && (vport_curr->fc_myDID == did)) {
384 spin_unlock_irqrestore(&phba->hbalock, flags);
385 return vport_curr;
388 spin_unlock_irqrestore(&phba->hbalock, flags);
389 return NULL;
392 static int
393 lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
395 struct lpfc_hba *phba = vport->phba;
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;
401 uint32_t Did, CTentry;
402 int Cnt;
403 struct list_head head;
405 lpfc_set_disctmo(vport);
406 vport->num_disc_nodes = 0;
407 vport->fc_ns_retry = 0;
410 list_add_tail(&head, &mp->list);
411 list_for_each_entry_safe(mp, next_mp, &head, list) {
412 mlast = mp;
414 Cnt = Size > FCELSSIZE ? FCELSSIZE : Size;
416 Size -= Cnt;
418 if (!ctptr) {
419 ctptr = (uint32_t *) mlast->virt;
420 } else
421 Cnt -= 16; /* subtract length of CT header */
423 /* Loop through entire NameServer list of DIDs */
424 while (Cnt >= sizeof (uint32_t)) {
425 /* Get next DID from NameServer List */
426 CTentry = *ctptr++;
427 Did = ((be32_to_cpu(CTentry)) & Mask_DID);
429 ndlp = NULL;
432 * Check for rscn processing or not
433 * To conserve rpi's, filter out addresses for other
434 * vports on the same physical HBAs.
436 if ((Did != vport->fc_myDID) &&
437 ((lpfc_find_vport_by_did(phba, Did) == NULL) ||
438 vport->cfg_peer_port_login)) {
439 if ((vport->port_type != LPFC_NPIV_PORT) ||
440 (!(vport->ct_flags & FC_CT_RFF_ID)) ||
441 (!vport->cfg_restrict_login)) {
442 ndlp = lpfc_setup_disc_node(vport, Did);
443 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
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);
451 lpfc_printf_vlog(vport,
452 KERN_INFO,
453 LOG_DISCOVERY,
454 "0238 Process "
455 "x%x NameServer Rsp"
456 "Data: x%x x%x x%x\n",
457 Did, ndlp->nlp_flag,
458 vport->fc_flag,
459 vport->fc_rscn_id_cnt);
460 } else {
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);
468 lpfc_printf_vlog(vport,
469 KERN_INFO,
470 LOG_DISCOVERY,
471 "0239 Skip x%x "
472 "NameServer Rsp Data: "
473 "x%x x%x\n",
474 Did, vport->fc_flag,
475 vport->fc_rscn_id_cnt);
478 } else {
479 if (!(vport->fc_flag & FC_RSCN_MODE) ||
480 (lpfc_rscn_payload_check(vport, Did))) {
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);
488 /* This NPortID was previously
489 * a FCP target, * Don't even
490 * bother to send GFF_ID.
492 ndlp = lpfc_findnode_did(vport,
493 Did);
494 if (ndlp &&
495 NLP_CHK_NODE_ACT(ndlp)
496 && (ndlp->nlp_type &
497 NLP_FCP_TARGET))
498 lpfc_setup_disc_node
499 (vport, Did);
500 else if (lpfc_ns_cmd(vport,
501 SLI_CTNS_GFF_ID,
502 0, Did) == 0)
503 vport->num_disc_nodes++;
505 else {
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);
513 lpfc_printf_vlog(vport,
514 KERN_INFO,
515 LOG_DISCOVERY,
516 "0245 Skip x%x "
517 "NameServer Rsp Data: "
518 "x%x x%x\n",
519 Did, vport->fc_flag,
520 vport->fc_rscn_id_cnt);
524 if (CTentry & (be32_to_cpu(SLI_CT_LAST_ENTRY)))
525 goto nsout1;
526 Cnt -= sizeof (uint32_t);
528 ctptr = NULL;
532 nsout1:
533 list_del(&head);
534 return 0;
537 static void
538 lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
539 struct lpfc_iocbq *rspiocb)
541 struct lpfc_vport *vport = cmdiocb->vport;
542 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
543 IOCB_t *irsp;
544 struct lpfc_dmabuf *bmp;
545 struct lpfc_dmabuf *outp;
546 struct lpfc_sli_ct_request *CTrsp;
547 struct lpfc_nodelist *ndlp;
548 int rc;
550 /* First save ndlp, before we overwrite it */
551 ndlp = cmdiocb->context_un.ndlp;
553 /* we pass cmdiocb to state machine which needs rspiocb as well */
554 cmdiocb->context_un.rsp_iocb = rspiocb;
556 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
557 bmp = (struct lpfc_dmabuf *) cmdiocb->context3;
558 irsp = &rspiocb->iocb;
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);
564 /* Don't bother processing response if vport is being torn down. */
565 if (vport->load_flag & FC_UNLOADING) {
566 if (vport->fc_flag & FC_RSCN_MODE)
567 lpfc_els_flush_rscn(vport);
568 goto out;
571 if (lpfc_els_chk_latt(vport)) {
572 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
573 "0216 Link event during NS query\n");
574 if (vport->fc_flag & FC_RSCN_MODE)
575 lpfc_els_flush_rscn(vport);
576 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
577 goto out;
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");
582 if (vport->fc_flag & FC_RSCN_MODE)
583 lpfc_els_flush_rscn(vport);
584 goto out;
586 if (irsp->ulpStatus) {
587 /* Check for retry */
588 if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
589 if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
590 irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)
591 vport->fc_ns_retry++;
593 /* CT command is being retried */
594 rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
595 vport->fc_ns_retry, 0);
596 if (rc == 0)
597 goto out;
599 if (vport->fc_flag & FC_RSCN_MODE)
600 lpfc_els_flush_rscn(vport);
601 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
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);
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)) {
610 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
611 "0208 NameServer Rsp Data: x%x\n",
612 vport->fc_flag);
613 lpfc_ns_rsp(vport, outp,
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 */
618 if ((CTrsp->ReasonCode == SLI_CT_UNABLE_TO_PERFORM_REQ)
619 && (CTrsp->Explanation == SLI_CT_NO_FC4_TYPES)) {
620 lpfc_printf_vlog(vport, KERN_INFO,
621 LOG_DISCOVERY,
622 "0269 No NameServer Entries "
623 "Data: x%x x%x x%x x%x\n",
624 CTrsp->CommandResponse.bits.CmdRsp,
625 (uint32_t) CTrsp->ReasonCode,
626 (uint32_t) CTrsp->Explanation,
627 vport->fc_flag);
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);
634 } else {
635 lpfc_printf_vlog(vport, KERN_INFO,
636 LOG_DISCOVERY,
637 "0240 NameServer Rsp Error "
638 "Data: x%x x%x x%x x%x\n",
639 CTrsp->CommandResponse.bits.CmdRsp,
640 (uint32_t) CTrsp->ReasonCode,
641 (uint32_t) CTrsp->Explanation,
642 vport->fc_flag);
644 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
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);
652 } else {
653 /* NameServer Rsp Error */
654 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
655 "0241 NameServer Rsp Error "
656 "Data: x%x x%x x%x x%x\n",
657 CTrsp->CommandResponse.bits.CmdRsp,
658 (uint32_t) CTrsp->ReasonCode,
659 (uint32_t) CTrsp->Explanation,
660 vport->fc_flag);
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);
669 /* Link up / RSCN discovery */
670 if (vport->num_disc_nodes == 0) {
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.
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);
683 else
684 lpfc_els_flush_rscn(vport);
687 lpfc_disc_start(vport);
689 out:
690 cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
691 lpfc_ct_free_iocb(phba, cmdiocb);
692 return;
695 static void
696 lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
697 struct lpfc_iocbq *rspiocb)
699 struct lpfc_vport *vport = cmdiocb->vport;
700 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
701 IOCB_t *irsp = &rspiocb->iocb;
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;
705 int did, rc, retry;
706 uint8_t fbits;
707 struct lpfc_nodelist *ndlp;
709 did = ((struct lpfc_sli_ct_request *) inp->virt)->un.gff.PortId;
710 did = be32_to_cpu(did);
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);
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];
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)) {
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);
731 goto out;
735 else {
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.
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++;
755 else
756 cmdiocb->retry++;
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;
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],
773 vport->fc_flag, vport->fc_rscn_id_cnt);
776 /* This is a target port, unregistered port, or the GFF_ID failed */
777 ndlp = lpfc_setup_disc_node(vport, did);
778 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
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);
784 } else {
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);
790 out:
791 /* Link up / RSCN discovery */
792 if (vport->num_disc_nodes)
793 vport->num_disc_nodes--;
794 if (vport->num_disc_nodes == 0) {
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.
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);
807 else
808 lpfc_els_flush_rscn(vport);
810 lpfc_disc_start(vport);
812 lpfc_ct_free_iocb(phba, cmdiocb);
813 return;
817 static void
818 lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
819 struct lpfc_iocbq *rspiocb)
821 struct lpfc_vport *vport = cmdiocb->vport;
822 struct lpfc_dmabuf *inp;
823 struct lpfc_dmabuf *outp;
824 IOCB_t *irsp;
825 struct lpfc_sli_ct_request *CTrsp;
826 struct lpfc_nodelist *ndlp;
827 int cmdcode, rc;
828 uint8_t retry;
829 uint32_t latt;
831 /* First save ndlp, before we overwrite it */
832 ndlp = cmdiocb->context_un.ndlp;
834 /* we pass cmdiocb to state machine which needs rspiocb as well */
835 cmdiocb->context_un.rsp_iocb = rspiocb;
837 inp = (struct lpfc_dmabuf *) cmdiocb->context1;
838 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
839 irsp = &rspiocb->iocb;
841 cmdcode = be16_to_cpu(((struct lpfc_sli_ct_request *) inp->virt)->
842 CommandResponse.bits.CmdRsp);
843 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
845 latt = lpfc_els_chk_latt(vport);
847 /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
848 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
849 "0209 CT Request completes, latt %d, "
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);
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);
859 if (irsp->ulpStatus) {
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]);
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;
869 retry = cmdiocb->retry;
870 if (retry >= LPFC_MAX_NS_RETRY)
871 goto out;
873 retry++;
874 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
875 "0250 Retrying NS cmd %x\n", cmdcode);
876 rc = lpfc_ns_cmd(vport, cmdcode, retry, 0);
877 if (rc == 0)
878 goto out;
881 out:
882 cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
883 lpfc_ct_free_iocb(phba, cmdiocb);
884 return;
887 static void
888 lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
889 struct lpfc_iocbq *rspiocb)
891 IOCB_t *irsp = &rspiocb->iocb;
892 struct lpfc_vport *vport = cmdiocb->vport;
894 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
895 struct lpfc_dmabuf *outp;
896 struct lpfc_sli_ct_request *CTrsp;
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;
904 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
905 return;
908 static void
909 lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
910 struct lpfc_iocbq *rspiocb)
912 IOCB_t *irsp = &rspiocb->iocb;
913 struct lpfc_vport *vport = cmdiocb->vport;
915 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
916 struct lpfc_dmabuf *outp;
917 struct lpfc_sli_ct_request *CTrsp;
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;
925 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
926 return;
929 static void
930 lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
931 struct lpfc_iocbq *rspiocb)
933 IOCB_t *irsp = &rspiocb->iocb;
934 struct lpfc_vport *vport = cmdiocb->vport;
936 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
937 struct lpfc_dmabuf *outp;
938 struct lpfc_sli_ct_request *CTrsp;
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;
946 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
947 return;
950 static void
951 lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
952 struct lpfc_iocbq *rspiocb)
954 IOCB_t *irsp = &rspiocb->iocb;
955 struct lpfc_vport *vport = cmdiocb->vport;
957 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
958 struct lpfc_dmabuf *outp;
959 struct lpfc_sli_ct_request *CTrsp;
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;
967 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
968 return;
971 static void
972 lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
973 struct lpfc_iocbq *rspiocb)
975 struct lpfc_vport *vport = cmdiocb->vport;
977 /* even if it fails we will act as though it succeeded. */
978 vport->ct_flags = 0;
979 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
980 return;
983 static void
984 lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
985 struct lpfc_iocbq *rspiocb)
987 IOCB_t *irsp = &rspiocb->iocb;
988 struct lpfc_vport *vport = cmdiocb->vport;
990 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
991 struct lpfc_dmabuf *outp;
992 struct lpfc_sli_ct_request *CTrsp;
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;
1000 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
1001 return;
1005 lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
1006 size_t size)
1008 int n;
1009 uint8_t *wwn = vport->phba->wwpn;
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]);
1016 if (vport->port_type == LPFC_PHYSICAL_PORT)
1017 return n;
1019 if (n < size)
1020 n += snprintf(symbol + n, size - n, " VPort-%d", vport->vpi);
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);
1026 return n;
1030 lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,
1031 size_t size)
1033 char fwrev[16];
1034 int n;
1036 lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
1038 n = snprintf(symbol, size, "Emulex %s FV%s DV%s",
1039 vport->phba->ModelName, fwrev, lpfc_release_version);
1040 return n;
1044 * lpfc_ns_cmd
1045 * Description:
1046 * Issue Cmd to NameServer
1047 * SLI_CTNS_GID_FT
1048 * LI_CTNS_RFT_ID
1051 lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1052 uint8_t retry, uint32_t context)
1054 struct lpfc_nodelist * ndlp;
1055 struct lpfc_hba *phba = vport->phba;
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;
1062 size_t size;
1063 int rc = 0;
1065 ndlp = lpfc_findnode_did(vport, NameServer_DID);
1066 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)
1067 || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) {
1068 rc=1;
1069 goto ns_cmd_exit;
1072 /* fill in BDEs for command */
1073 /* Allocate buffer for command payload */
1074 mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
1075 if (!mp) {
1076 rc=2;
1077 goto ns_cmd_exit;
1080 INIT_LIST_HEAD(&mp->list);
1081 mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
1082 if (!mp->virt) {
1083 rc=3;
1084 goto ns_cmd_free_mp;
1087 /* Allocate buffer for Buffer ptr list */
1088 bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
1089 if (!bmp) {
1090 rc=4;
1091 goto ns_cmd_free_mpvirt;
1094 INIT_LIST_HEAD(&bmp->list);
1095 bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(bmp->phys));
1096 if (!bmp->virt) {
1097 rc=5;
1098 goto ns_cmd_free_bmp;
1101 /* NameServer Req */
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);
1106 bpl = (struct ulp_bde64 *) bmp->virt;
1107 memset(bpl, 0, sizeof(struct ulp_bde64));
1108 bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
1109 bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
1110 bpl->tus.f.bdeFlags = 0;
1111 if (cmdcode == SLI_CTNS_GID_FT)
1112 bpl->tus.f.bdeSize = GID_REQUEST_SZ;
1113 else if (cmdcode == SLI_CTNS_GFF_ID)
1114 bpl->tus.f.bdeSize = GFF_REQUEST_SZ;
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;
1119 else if (cmdcode == SLI_CTNS_RSPN_ID)
1120 bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
1121 else if (cmdcode == SLI_CTNS_RSNN_NN)
1122 bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
1123 else if (cmdcode == SLI_CTNS_DA_ID)
1124 bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
1125 else if (cmdcode == SLI_CTNS_RFF_ID)
1126 bpl->tus.f.bdeSize = RFF_REQUEST_SZ;
1127 else
1128 bpl->tus.f.bdeSize = 0;
1129 bpl->tus.w = le32_to_cpu(bpl->tus.w);
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;
1143 if (vport->port_state < LPFC_NS_QRY)
1144 vport->port_state = LPFC_NS_QRY;
1145 lpfc_set_disctmo(vport);
1146 cmpl = lpfc_cmpl_ct_cmd_gid_ft;
1147 rsp_size = FC_MAX_NS_RSP;
1148 break;
1150 case SLI_CTNS_GFF_ID:
1151 CtReq->CommandResponse.bits.CmdRsp =
1152 be16_to_cpu(SLI_CTNS_GFF_ID);
1153 CtReq->un.gff.PortId = cpu_to_be32(context);
1154 cmpl = lpfc_cmpl_ct_cmd_gff_id;
1155 break;
1157 case SLI_CTNS_RFT_ID:
1158 vport->ct_flags &= ~FC_CT_RFT_ID;
1159 CtReq->CommandResponse.bits.CmdRsp =
1160 be16_to_cpu(SLI_CTNS_RFT_ID);
1161 CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID);
1162 CtReq->un.rft.fcpReg = 1;
1163 cmpl = lpfc_cmpl_ct_cmd_rft_id;
1164 break;
1166 case SLI_CTNS_RNN_ID:
1167 vport->ct_flags &= ~FC_CT_RNN_ID;
1168 CtReq->CommandResponse.bits.CmdRsp =
1169 be16_to_cpu(SLI_CTNS_RNN_ID);
1170 CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID);
1171 memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename,
1172 sizeof (struct lpfc_name));
1173 cmpl = lpfc_cmpl_ct_cmd_rnn_id;
1174 break;
1176 case SLI_CTNS_RSPN_ID:
1177 vport->ct_flags &= ~FC_CT_RSPN_ID;
1178 CtReq->CommandResponse.bits.CmdRsp =
1179 be16_to_cpu(SLI_CTNS_RSPN_ID);
1180 CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID);
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;
1187 case SLI_CTNS_RSNN_NN:
1188 vport->ct_flags &= ~FC_CT_RSNN_NN;
1189 CtReq->CommandResponse.bits.CmdRsp =
1190 be16_to_cpu(SLI_CTNS_RSNN_NN);
1191 memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename,
1192 sizeof (struct lpfc_name));
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);
1197 cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
1198 break;
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);
1203 CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID);
1204 cmpl = lpfc_cmpl_ct_cmd_da_id;
1205 break;
1206 case SLI_CTNS_RFF_ID:
1207 vport->ct_flags &= ~FC_CT_RFF_ID;
1208 CtReq->CommandResponse.bits.CmdRsp =
1209 be16_to_cpu(SLI_CTNS_RFF_ID);
1210 CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);
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;
1216 /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
1217 * to hold ndlp reference for the corresponding callback function.
1219 if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) {
1220 /* On success, The cmpl function will free the buffers */
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);
1224 return 0;
1226 rc=6;
1228 /* Decrement ndlp reference count to release ndlp reference held
1229 * for the failed command's callback function.
1231 lpfc_nlp_put(ndlp);
1233 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
1234 ns_cmd_free_bmp:
1235 kfree(bmp);
1236 ns_cmd_free_mpvirt:
1237 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1238 ns_cmd_free_mp:
1239 kfree(mp);
1240 ns_cmd_exit:
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);
1244 return 1;
1247 static void
1248 lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1249 struct lpfc_iocbq * rspiocb)
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;
1258 struct lpfc_vport *vport = cmdiocb->vport;
1259 IOCB_t *irsp = &rspiocb->iocb;
1260 uint32_t latt;
1262 latt = lpfc_els_chk_latt(vport);
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);
1268 if (latt || irsp->ulpStatus) {
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]);
1274 lpfc_ct_free_iocb(phba, cmdiocb);
1275 return;
1278 ndlp = lpfc_findnode_did(vport, FDMI_DID);
1279 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
1280 goto fail_out;
1282 if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
1283 /* FDMI rsp failed */
1284 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1285 "0220 FDMI rsp failed Data: x%x\n",
1286 be16_to_cpu(fdmi_cmd));
1289 switch (be16_to_cpu(fdmi_cmd)) {
1290 case SLI_MGMT_RHBA:
1291 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA);
1292 break;
1294 case SLI_MGMT_RPA:
1295 break;
1297 case SLI_MGMT_DHBA:
1298 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT);
1299 break;
1301 case SLI_MGMT_DPRT:
1302 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA);
1303 break;
1306 fail_out:
1307 lpfc_ct_free_iocb(phba, cmdiocb);
1308 return;
1312 lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode)
1314 struct lpfc_hba *phba = vport->phba;
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 *);
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;
1334 mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
1335 if (!mp->virt)
1336 goto fdmi_cmd_free_mp;
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;
1343 bmp->virt = lpfc_mbuf_alloc(phba, 0, &(bmp->phys));
1344 if (!bmp->virt)
1345 goto fdmi_cmd_free_bmp;
1347 INIT_LIST_HEAD(&mp->list);
1348 INIT_LIST_HEAD(&bmp->list);
1350 /* FDMI request */
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);
1354 CtReq = (struct lpfc_sli_ct_request *) mp->virt;
1356 memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
1357 CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
1358 CtReq->RevisionId.bits.InId = 0;
1360 CtReq->FsType = SLI_CT_MANAGEMENT_SERVICE;
1361 CtReq->FsSubType = SLI_CT_FDMI_Subtypes;
1362 size = 0;
1364 switch (cmdcode) {
1365 case SLI_MGMT_RHBA:
1367 lpfc_vpd_t *vp = &phba->vpd;
1368 uint32_t i, j, incr;
1369 int len;
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;
1375 memcpy(&rh->hi.PortName, &vport->fc_sparam.portName,
1376 sizeof (struct lpfc_name));
1377 /* One entry (port) per adapter */
1378 rh->rpl.EntryCnt = be32_to_cpu(1);
1379 memcpy(&rh->rpl.pe, &vport->fc_sparam.portName,
1380 sizeof (struct lpfc_name));
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;
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));
1395 memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName,
1396 sizeof (struct lpfc_name));
1397 ab->EntryCnt++;
1398 size += FOURBYTES + sizeof (struct lpfc_name);
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;
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;
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;
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;
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);
1458 ab->EntryCnt++;
1459 size += FOURBYTES + 8;
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;
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;
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,
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;
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",
1496 init_utsname()->sysname,
1497 init_utsname()->release,
1498 init_utsname()->version);
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;
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;
1513 ab->EntryCnt = be32_to_cpu(ab->EntryCnt);
1514 /* Total size */
1515 size = GID_REQUEST_SZ - 4 + size;
1517 break;
1519 case SLI_MGMT_RPA:
1521 lpfc_vpd_t *vp;
1522 struct serv_parm *hsp;
1523 int len;
1525 vp = &phba->vpd;
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,
1533 (uint8_t *) & vport->fc_sparam.portName,
1534 sizeof (struct lpfc_name));
1535 pab->ab.EntryCnt = 0;
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;
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);
1551 ae->un.SupportSpeed = 0;
1552 if (phba->lmt & LMT_10Gb)
1553 ae->un.SupportSpeed = HBA_PORTSPEED_10GBIT;
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;
1563 pab->ab.EntryCnt++;
1564 size += FOURBYTES + 4;
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;
1580 case LA_8GHZ_LINK:
1581 ae->un.PortSpeed = HBA_PORTSPEED_8GBIT;
1582 break;
1583 case LA_10GHZ_LINK:
1584 ae->un.PortSpeed = HBA_PORTSPEED_10GBIT;
1585 break;
1586 default:
1587 ae->un.PortSpeed =
1588 HBA_PORTSPEED_UNKNOWN;
1589 break;
1591 pab->ab.EntryCnt++;
1592 size += FOURBYTES + 4;
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);
1598 hsp = (struct serv_parm *) & vport->fc_sparam;
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;
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;
1616 if (vport->cfg_fdmi_on == 2) {
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",
1622 init_utsname()->nodename);
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;
1631 pab->ab.EntryCnt = be32_to_cpu(pab->ab.EntryCnt);
1632 /* Total size */
1633 size = GID_REQUEST_SZ - 4 + size;
1635 break;
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,
1642 (uint8_t *) & vport->fc_sparam.portName,
1643 sizeof (struct lpfc_name));
1644 size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name);
1645 break;
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,
1652 (uint8_t *) & vport->fc_sparam.portName,
1653 sizeof (struct lpfc_name));
1654 size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name);
1655 break;
1658 bpl = (struct ulp_bde64 *) bmp->virt;
1659 bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
1660 bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
1661 bpl->tus.f.bdeFlags = 0;
1662 bpl->tus.f.bdeSize = size;
1663 bpl->tus.w = le32_to_cpu(bpl->tus.w);
1665 cmpl = lpfc_cmpl_ct_cmd_fdmi;
1667 /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
1668 * to hold ndlp reference for the corresponding callback function.
1670 if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0))
1671 return 0;
1673 /* Decrement ndlp reference count to release ndlp reference held
1674 * for the failed command's callback function.
1676 lpfc_nlp_put(ndlp);
1678 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
1679 fdmi_cmd_free_bmp:
1680 kfree(bmp);
1681 fdmi_cmd_free_mpvirt:
1682 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1683 fdmi_cmd_free_mp:
1684 kfree(mp);
1685 fdmi_cmd_exit:
1686 /* Issue FDMI request failed */
1687 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1688 "0244 Issue FDMI request failed Data: x%x\n",
1689 cmdcode);
1690 return 1;
1693 void
1694 lpfc_fdmi_tmo(unsigned long ptr)
1696 struct lpfc_vport *vport = (struct lpfc_vport *)ptr;
1697 struct lpfc_hba *phba = vport->phba;
1698 uint32_t tmo_posted;
1699 unsigned long iflag;
1701 spin_lock_irqsave(&vport->work_port_lock, iflag);
1702 tmo_posted = vport->work_port_events & WORKER_FDMI_TMO;
1703 if (!tmo_posted)
1704 vport->work_port_events |= WORKER_FDMI_TMO;
1705 spin_unlock_irqrestore(&vport->work_port_lock, iflag);
1707 if (!tmo_posted)
1708 lpfc_worker_wake_up(phba);
1709 return;
1712 void
1713 lpfc_fdmi_timeout_handler(struct lpfc_vport *vport)
1715 struct lpfc_nodelist *ndlp;
1717 ndlp = lpfc_findnode_did(vport, FDMI_DID);
1718 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
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);
1724 return;
1727 void
1728 lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
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;
1737 if (phba->sli_rev == LPFC_SLI_REV4)
1738 sprintf(fwrevision, "%s", vp->rev.opFwName);
1739 else if (vp->rev.rBit) {
1740 if (psli->sli_flag & LPFC_SLI_ACTIVE)
1741 rev = vp->rev.sli2FwRev;
1742 else
1743 rev = vp->rev.sli1FwRev;
1745 b1 = (rev & 0x0000f000) >> 12;
1746 b2 = (rev & 0x00000f00) >> 8;
1747 b3 = (rev & 0x000000c0) >> 6;
1748 b4 = (rev & 0x00000030) >> 4;
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;
1764 b4 = (rev & 0x0000000f);
1766 if (psli->sli_flag & LPFC_SLI_ACTIVE)
1767 fwname = vp->rev.sli2FwName;
1768 else
1769 fwname = vp->rev.sli1FwName;
1771 for (i = 0; i < 16; i++)
1772 if (fwname[i] == 0x20)
1773 fwname[i] = 0;
1775 ptr = (uint32_t*)fwname;
1777 for (i = 0; i < 3; i++)
1778 str[i] = be32_to_cpu(*ptr++);
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);
1796 } else {
1797 rev = vp->rev.smFwRev;
1799 b1 = (rev & 0xff000000) >> 24;
1800 b2 = (rev & 0x00f00000) >> 20;
1801 b3 = (rev & 0x000f0000) >> 16;
1802 c = (rev & 0x0000ff00) >> 8;
1803 b4 = (rev & 0x000000ff);
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);
1812 return;