1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <linux/blkdev.h>
26#include <linux/pci.h>
27#include <linux/interrupt.h>
28#include <linux/slab.h>
29#include <linux/utsname.h>
30
31#include <scsi/scsi.h>
32#include <scsi/scsi_device.h>
33#include <scsi/scsi_host.h>
34#include <scsi/scsi_transport_fc.h>
35#include <scsi/fc/fc_fs.h>
36
37#include "lpfc_hw4.h"
38#include "lpfc_hw.h"
39#include "lpfc_sli.h"
40#include "lpfc_sli4.h"
41#include "lpfc_nl.h"
42#include "lpfc_disc.h"
43#include "lpfc_scsi.h"
44#include "lpfc.h"
45#include "lpfc_logmsg.h"
46#include "lpfc_crtn.h"
47#include "lpfc_version.h"
48#include "lpfc_vport.h"
49#include "lpfc_debugfs.h"
50
51
52#define HBA_PORTSPEED_1GFC 0x00000001
53#define HBA_PORTSPEED_2GFC 0x00000002
54#define HBA_PORTSPEED_4GFC 0x00000008
55#define HBA_PORTSPEED_10GFC 0x00000004
56#define HBA_PORTSPEED_8GFC 0x00000010
57#define HBA_PORTSPEED_16GFC 0x00000020
58#define HBA_PORTSPEED_32GFC 0x00000040
59#define HBA_PORTSPEED_20GFC 0x00000080
60#define HBA_PORTSPEED_40GFC 0x00000100
61#define HBA_PORTSPEED_128GFC 0x00000200
62#define HBA_PORTSPEED_64GFC 0x00000400
63#define HBA_PORTSPEED_256GFC 0x00000800
64#define HBA_PORTSPEED_UNKNOWN 0x00008000
65#define HBA_PORTSPEED_10GE 0x00010000
66#define HBA_PORTSPEED_40GE 0x00020000
67#define HBA_PORTSPEED_100GE 0x00040000
68#define HBA_PORTSPEED_25GE 0x00080000
69#define HBA_PORTSPEED_50GE 0x00100000
70#define HBA_PORTSPEED_400GE 0x00200000
71
72#define FOURBYTES 4
73
74
75static char *lpfc_release_version = LPFC_DRIVER_VERSION;
76
77static void
78lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
79 struct lpfc_dmabuf *mp, uint32_t size)
80{
81 if (!mp) {
82 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
83 "0146 Ignoring unsolicited CT No HBQ "
84 "status = x%x\n",
85 piocbq->iocb.ulpStatus);
86 }
87 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
88 "0145 Ignoring unsolicted CT HBQ Size:%d "
89 "status = x%x\n",
90 size, piocbq->iocb.ulpStatus);
91}
92
93static void
94lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
95 struct lpfc_dmabuf *mp, uint32_t size)
96{
97 lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size);
98}
99
100void
101lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
102 struct lpfc_iocbq *piocbq)
103{
104 struct lpfc_dmabuf *mp = NULL;
105 IOCB_t *icmd = &piocbq->iocb;
106 int i;
107 struct lpfc_iocbq *iocbq;
108 dma_addr_t paddr;
109 uint32_t size;
110 struct list_head head;
111 struct lpfc_dmabuf *bdeBuf;
112
113 if (lpfc_bsg_ct_unsol_event(phba, pring, piocbq) == 0)
114 return;
115
116 if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
117 lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
118 } else if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
119 ((icmd->un.ulpWord[4] & IOERR_PARAM_MASK) ==
120 IOERR_RCV_BUFFER_WAITING)) {
121
122 phba->fc_stat.NoRcvBuf++;
123 if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
124 lpfc_post_buffer(phba, pring, 2);
125 return;
126 }
127
128
129
130
131 if (icmd->ulpBdeCount == 0)
132 return;
133
134 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
135 INIT_LIST_HEAD(&head);
136 list_add_tail(&head, &piocbq->list);
137 list_for_each_entry(iocbq, &head, list) {
138 icmd = &iocbq->iocb;
139 if (icmd->ulpBdeCount == 0)
140 continue;
141 bdeBuf = iocbq->context2;
142 iocbq->context2 = NULL;
143 size = icmd->un.cont64[0].tus.f.bdeSize;
144 lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size);
145 lpfc_in_buf_free(phba, bdeBuf);
146 if (icmd->ulpBdeCount == 2) {
147 bdeBuf = iocbq->context3;
148 iocbq->context3 = NULL;
149 size = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize;
150 lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf,
151 size);
152 lpfc_in_buf_free(phba, bdeBuf);
153 }
154 }
155 list_del(&head);
156 } else {
157 INIT_LIST_HEAD(&head);
158 list_add_tail(&head, &piocbq->list);
159 list_for_each_entry(iocbq, &head, list) {
160 icmd = &iocbq->iocb;
161 if (icmd->ulpBdeCount == 0)
162 lpfc_ct_unsol_buffer(phba, iocbq, NULL, 0);
163 for (i = 0; i < icmd->ulpBdeCount; i++) {
164 paddr = getPaddr(icmd->un.cont64[i].addrHigh,
165 icmd->un.cont64[i].addrLow);
166 mp = lpfc_sli_ringpostbuf_get(phba, pring,
167 paddr);
168 size = icmd->un.cont64[i].tus.f.bdeSize;
169 lpfc_ct_unsol_buffer(phba, iocbq, mp, size);
170 lpfc_in_buf_free(phba, mp);
171 }
172 lpfc_post_buffer(phba, pring, i);
173 }
174 list_del(&head);
175 }
176}
177
178
179
180
181
182
183
184
185
186
187
188int
189lpfc_ct_handle_unsol_abort(struct lpfc_hba *phba, struct hbq_dmabuf *dmabuf)
190{
191 int handled;
192
193
194 handled = lpfc_bsg_ct_unsol_abort(phba, dmabuf);
195
196 return handled;
197}
198
199static void
200lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist)
201{
202 struct lpfc_dmabuf *mlast, *next_mlast;
203
204 list_for_each_entry_safe(mlast, next_mlast, &mlist->list, list) {
205 lpfc_mbuf_free(phba, mlast->virt, mlast->phys);
206 list_del(&mlast->list);
207 kfree(mlast);
208 }
209 lpfc_mbuf_free(phba, mlist->virt, mlist->phys);
210 kfree(mlist);
211 return;
212}
213
214static struct lpfc_dmabuf *
215lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl,
216 uint32_t size, int *entries)
217{
218 struct lpfc_dmabuf *mlist = NULL;
219 struct lpfc_dmabuf *mp;
220 int cnt, i = 0;
221
222
223 cnt = size > FCELSSIZE ? FCELSSIZE: size;
224
225 while (size) {
226
227 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
228 if (!mp) {
229 if (mlist)
230 lpfc_free_ct_rsp(phba, mlist);
231 return NULL;
232 }
233
234 INIT_LIST_HEAD(&mp->list);
235
236 if (cmdcode == be16_to_cpu(SLI_CTNS_GID_FT) ||
237 cmdcode == be16_to_cpu(SLI_CTNS_GFF_ID))
238 mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
239 else
240 mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
241
242 if (!mp->virt) {
243 kfree(mp);
244 if (mlist)
245 lpfc_free_ct_rsp(phba, mlist);
246 return NULL;
247 }
248
249
250 if (!mlist)
251 mlist = mp;
252 else
253 list_add_tail(&mp->list, &mlist->list);
254
255 bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
256
257 bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
258 bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
259 bpl->tus.f.bdeSize = (uint16_t) cnt;
260 bpl->tus.w = le32_to_cpu(bpl->tus.w);
261 bpl++;
262
263 i++;
264 size -= cnt;
265 }
266
267 *entries = i;
268 return mlist;
269}
270
271int
272lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb)
273{
274 struct lpfc_dmabuf *buf_ptr;
275
276 if (ctiocb->context_un.ndlp) {
277 lpfc_nlp_put(ctiocb->context_un.ndlp);
278 ctiocb->context_un.ndlp = NULL;
279 }
280 if (ctiocb->context1) {
281 buf_ptr = (struct lpfc_dmabuf *) ctiocb->context1;
282 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
283 kfree(buf_ptr);
284 ctiocb->context1 = NULL;
285 }
286 if (ctiocb->context2) {
287 lpfc_free_ct_rsp(phba, (struct lpfc_dmabuf *) ctiocb->context2);
288 ctiocb->context2 = NULL;
289 }
290
291 if (ctiocb->context3) {
292 buf_ptr = (struct lpfc_dmabuf *) ctiocb->context3;
293 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
294 kfree(buf_ptr);
295 ctiocb->context3 = NULL;
296 }
297 lpfc_sli_release_iocbq(phba, ctiocb);
298 return 0;
299}
300
301
302
303
304
305
306
307
308
309
310
311
312static int
313lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
314 struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp,
315 void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
316 struct lpfc_iocbq *),
317 struct lpfc_nodelist *ndlp, uint32_t usr_flg, uint32_t num_entry,
318 uint32_t tmo, uint8_t retry)
319{
320 struct lpfc_hba *phba = vport->phba;
321 IOCB_t *icmd;
322 struct lpfc_iocbq *geniocb;
323 int rc;
324
325
326 geniocb = lpfc_sli_get_iocbq(phba);
327
328 if (geniocb == NULL)
329 return 1;
330
331 icmd = &geniocb->iocb;
332 icmd->un.genreq64.bdl.ulpIoTag32 = 0;
333 icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
334 icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
335 icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
336 icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64));
337
338 if (usr_flg)
339 geniocb->context3 = NULL;
340 else
341 geniocb->context3 = (uint8_t *) bmp;
342
343
344 geniocb->context1 = (uint8_t *) inp;
345 geniocb->context2 = (uint8_t *) outp;
346 geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
347
348
349 icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
350
351
352 icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
353 icmd->un.genreq64.w5.hcsw.Dfctl = 0;
354 icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
355 icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
356
357 if (!tmo) {
358
359 tmo = (3 * phba->fc_ratov);
360 }
361 icmd->ulpTimeout = tmo;
362 icmd->ulpBdeCount = 1;
363 icmd->ulpLe = 1;
364 icmd->ulpClass = CLASS3;
365 icmd->ulpContext = ndlp->nlp_rpi;
366 if (phba->sli_rev == LPFC_SLI_REV4)
367 icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
368
369 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
370
371 icmd->ulpCt_h = 0;
372 icmd->ulpCt_l = 0;
373 }
374
375
376 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
377 "0119 Issue GEN REQ IOCB to NPORT x%x "
378 "Data: x%x x%x\n",
379 ndlp->nlp_DID, icmd->ulpIoTag,
380 vport->port_state);
381 geniocb->iocb_cmpl = cmpl;
382 geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
383 geniocb->vport = vport;
384 geniocb->retry = retry;
385 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);
386
387 if (rc == IOCB_ERROR) {
388 lpfc_sli_release_iocbq(phba, geniocb);
389 return 1;
390 }
391
392 return 0;
393}
394
395
396
397
398
399
400
401
402
403
404
405static int
406lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,
407 struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp,
408 void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
409 struct lpfc_iocbq *),
410 uint32_t rsp_size, uint8_t retry)
411{
412 struct lpfc_hba *phba = vport->phba;
413 struct ulp_bde64 *bpl = (struct ulp_bde64 *) bmp->virt;
414 struct lpfc_dmabuf *outmp;
415 int cnt = 0, status;
416 int cmdcode = ((struct lpfc_sli_ct_request *) inmp->virt)->
417 CommandResponse.bits.CmdRsp;
418
419 bpl++;
420
421
422 outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt);
423 if (!outmp)
424 return -ENOMEM;
425
426
427
428
429
430 cnt += 1;
431 status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0,
432 cnt, 0, retry);
433 if (status) {
434 lpfc_free_ct_rsp(phba, outmp);
435 return -ENOMEM;
436 }
437 return 0;
438}
439
440struct lpfc_vport *
441lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) {
442 struct lpfc_vport *vport_curr;
443 unsigned long flags;
444
445 spin_lock_irqsave(&phba->hbalock, flags);
446 list_for_each_entry(vport_curr, &phba->port_list, listentry) {
447 if ((vport_curr->fc_myDID) && (vport_curr->fc_myDID == did)) {
448 spin_unlock_irqrestore(&phba->hbalock, flags);
449 return vport_curr;
450 }
451 }
452 spin_unlock_irqrestore(&phba->hbalock, flags);
453 return NULL;
454}
455
456static int
457lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
458{
459 struct lpfc_hba *phba = vport->phba;
460 struct lpfc_sli_ct_request *Response =
461 (struct lpfc_sli_ct_request *) mp->virt;
462 struct lpfc_nodelist *ndlp = NULL;
463 struct lpfc_dmabuf *mlast, *next_mp;
464 uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;
465 uint32_t Did, CTentry;
466 int Cnt;
467 struct list_head head;
468
469 lpfc_set_disctmo(vport);
470 vport->num_disc_nodes = 0;
471 vport->fc_ns_retry = 0;
472
473
474 list_add_tail(&head, &mp->list);
475 list_for_each_entry_safe(mp, next_mp, &head, list) {
476 mlast = mp;
477
478 Cnt = Size > FCELSSIZE ? FCELSSIZE : Size;
479
480 Size -= Cnt;
481
482 if (!ctptr) {
483 ctptr = (uint32_t *) mlast->virt;
484 } else
485 Cnt -= 16;
486
487
488 while (Cnt >= sizeof(uint32_t)) {
489
490 CTentry = *ctptr++;
491 Did = ((be32_to_cpu(CTentry)) & Mask_DID);
492
493 ndlp = NULL;
494
495
496
497
498
499
500 if ((Did != vport->fc_myDID) &&
501 ((lpfc_find_vport_by_did(phba, Did) == NULL) ||
502 vport->cfg_peer_port_login)) {
503 if ((vport->port_type != LPFC_NPIV_PORT) ||
504 (!(vport->ct_flags & FC_CT_RFF_ID)) ||
505 (!vport->cfg_restrict_login)) {
506 ndlp = lpfc_setup_disc_node(vport, Did);
507 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
508 lpfc_debugfs_disc_trc(vport,
509 LPFC_DISC_TRC_CT,
510 "Parse GID_FTrsp: "
511 "did:x%x flg:x%x x%x",
512 Did, ndlp->nlp_flag,
513 vport->fc_flag);
514
515 lpfc_printf_vlog(vport,
516 KERN_INFO,
517 LOG_DISCOVERY,
518 "0238 Process "
519 "x%x NameServer Rsp"
520 "Data: x%x x%x x%x\n",
521 Did, ndlp->nlp_flag,
522 vport->fc_flag,
523 vport->fc_rscn_id_cnt);
524 } else {
525 lpfc_debugfs_disc_trc(vport,
526 LPFC_DISC_TRC_CT,
527 "Skip1 GID_FTrsp: "
528 "did:x%x flg:x%x cnt:%d",
529 Did, vport->fc_flag,
530 vport->fc_rscn_id_cnt);
531
532 lpfc_printf_vlog(vport,
533 KERN_INFO,
534 LOG_DISCOVERY,
535 "0239 Skip x%x "
536 "NameServer Rsp Data: "
537 "x%x x%x\n",
538 Did, vport->fc_flag,
539 vport->fc_rscn_id_cnt);
540 }
541
542 } else {
543 if (!(vport->fc_flag & FC_RSCN_MODE) ||
544 (lpfc_rscn_payload_check(vport, Did))) {
545 lpfc_debugfs_disc_trc(vport,
546 LPFC_DISC_TRC_CT,
547 "Query GID_FTrsp: "
548 "did:x%x flg:x%x cnt:%d",
549 Did, vport->fc_flag,
550 vport->fc_rscn_id_cnt);
551
552
553
554
555
556 ndlp = lpfc_findnode_did(vport,
557 Did);
558 if (ndlp &&
559 NLP_CHK_NODE_ACT(ndlp)
560 && (ndlp->nlp_type &
561 NLP_FCP_TARGET))
562 lpfc_setup_disc_node
563 (vport, Did);
564 else if (lpfc_ns_cmd(vport,
565 SLI_CTNS_GFF_ID,
566 0, Did) == 0)
567 vport->num_disc_nodes++;
568 else
569 lpfc_setup_disc_node
570 (vport, Did);
571 }
572 else {
573 lpfc_debugfs_disc_trc(vport,
574 LPFC_DISC_TRC_CT,
575 "Skip2 GID_FTrsp: "
576 "did:x%x flg:x%x cnt:%d",
577 Did, vport->fc_flag,
578 vport->fc_rscn_id_cnt);
579
580 lpfc_printf_vlog(vport,
581 KERN_INFO,
582 LOG_DISCOVERY,
583 "0245 Skip x%x "
584 "NameServer Rsp Data: "
585 "x%x x%x\n",
586 Did, vport->fc_flag,
587 vport->fc_rscn_id_cnt);
588 }
589 }
590 }
591 if (CTentry & (cpu_to_be32(SLI_CT_LAST_ENTRY)))
592 goto nsout1;
593 Cnt -= sizeof(uint32_t);
594 }
595 ctptr = NULL;
596
597 }
598
599nsout1:
600 list_del(&head);
601 return 0;
602}
603
604static void
605lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
606 struct lpfc_iocbq *rspiocb)
607{
608 struct lpfc_vport *vport = cmdiocb->vport;
609 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
610 IOCB_t *irsp;
611 struct lpfc_dmabuf *outp;
612 struct lpfc_sli_ct_request *CTrsp;
613 struct lpfc_nodelist *ndlp;
614 int rc;
615
616
617 ndlp = cmdiocb->context_un.ndlp;
618
619
620 cmdiocb->context_un.rsp_iocb = rspiocb;
621
622 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
623 irsp = &rspiocb->iocb;
624
625 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
626 "GID_FT cmpl: status:x%x/x%x rtry:%d",
627 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_ns_retry);
628
629
630 if (vport->load_flag & FC_UNLOADING) {
631 if (vport->fc_flag & FC_RSCN_MODE)
632 lpfc_els_flush_rscn(vport);
633 goto out;
634 }
635
636 if (lpfc_els_chk_latt(vport)) {
637 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
638 "0216 Link event during NS query\n");
639 if (vport->fc_flag & FC_RSCN_MODE)
640 lpfc_els_flush_rscn(vport);
641 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
642 goto out;
643 }
644 if (lpfc_error_lost_link(irsp)) {
645 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
646 "0226 NS query failed due to link event\n");
647 if (vport->fc_flag & FC_RSCN_MODE)
648 lpfc_els_flush_rscn(vport);
649 goto out;
650 }
651 if (irsp->ulpStatus) {
652
653 if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
654 if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
655 (irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
656 IOERR_NO_RESOURCES)
657 vport->fc_ns_retry++;
658
659
660 rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
661 vport->fc_ns_retry, 0);
662 if (rc == 0)
663 goto out;
664 }
665 if (vport->fc_flag & FC_RSCN_MODE)
666 lpfc_els_flush_rscn(vport);
667 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
668 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
669 "0257 GID_FT Query error: 0x%x 0x%x\n",
670 irsp->ulpStatus, vport->fc_ns_retry);
671 } else {
672
673 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
674 if (CTrsp->CommandResponse.bits.CmdRsp ==
675 cpu_to_be16(SLI_CT_RESPONSE_FS_ACC)) {
676 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
677 "0208 NameServer Rsp Data: x%x\n",
678 vport->fc_flag);
679 lpfc_ns_rsp(vport, outp,
680 (uint32_t) (irsp->un.genreq64.bdl.bdeSize));
681 } else if (CTrsp->CommandResponse.bits.CmdRsp ==
682 be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
683
684 if ((CTrsp->ReasonCode == SLI_CT_UNABLE_TO_PERFORM_REQ)
685 && (CTrsp->Explanation == SLI_CT_NO_FC4_TYPES)) {
686 lpfc_printf_vlog(vport, KERN_INFO,
687 LOG_DISCOVERY,
688 "0269 No NameServer Entries "
689 "Data: x%x x%x x%x x%x\n",
690 CTrsp->CommandResponse.bits.CmdRsp,
691 (uint32_t) CTrsp->ReasonCode,
692 (uint32_t) CTrsp->Explanation,
693 vport->fc_flag);
694
695 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
696 "GID_FT no entry cmd:x%x rsn:x%x exp:x%x",
697 (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
698 (uint32_t) CTrsp->ReasonCode,
699 (uint32_t) CTrsp->Explanation);
700 } else {
701 lpfc_printf_vlog(vport, KERN_INFO,
702 LOG_DISCOVERY,
703 "0240 NameServer Rsp Error "
704 "Data: x%x x%x x%x x%x\n",
705 CTrsp->CommandResponse.bits.CmdRsp,
706 (uint32_t) CTrsp->ReasonCode,
707 (uint32_t) CTrsp->Explanation,
708 vport->fc_flag);
709
710 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
711 "GID_FT rsp err1 cmd:x%x rsn:x%x exp:x%x",
712 (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
713 (uint32_t) CTrsp->ReasonCode,
714 (uint32_t) CTrsp->Explanation);
715 }
716
717
718 } else {
719
720 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
721 "0241 NameServer Rsp Error "
722 "Data: x%x x%x x%x x%x\n",
723 CTrsp->CommandResponse.bits.CmdRsp,
724 (uint32_t) CTrsp->ReasonCode,
725 (uint32_t) CTrsp->Explanation,
726 vport->fc_flag);
727
728 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
729 "GID_FT rsp err2 cmd:x%x rsn:x%x exp:x%x",
730 (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
731 (uint32_t) CTrsp->ReasonCode,
732 (uint32_t) CTrsp->Explanation);
733 }
734 }
735
736 if (vport->num_disc_nodes == 0) {
737
738
739
740
741
742 if (vport->port_state >= LPFC_DISC_AUTH) {
743 if (vport->fc_flag & FC_RSCN_MODE) {
744 lpfc_els_flush_rscn(vport);
745 spin_lock_irq(shost->host_lock);
746 vport->fc_flag |= FC_RSCN_MODE;
747 spin_unlock_irq(shost->host_lock);
748 }
749 else
750 lpfc_els_flush_rscn(vport);
751 }
752
753 lpfc_disc_start(vport);
754 }
755out:
756 cmdiocb->context_un.ndlp = ndlp;
757 lpfc_ct_free_iocb(phba, cmdiocb);
758 return;
759}
760
761static void
762lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
763 struct lpfc_iocbq *rspiocb)
764{
765 struct lpfc_vport *vport = cmdiocb->vport;
766 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
767 IOCB_t *irsp = &rspiocb->iocb;
768 struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1;
769 struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2;
770 struct lpfc_sli_ct_request *CTrsp;
771 int did, rc, retry;
772 uint8_t fbits;
773 struct lpfc_nodelist *ndlp;
774
775 did = ((struct lpfc_sli_ct_request *) inp->virt)->un.gff.PortId;
776 did = be32_to_cpu(did);
777
778 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
779 "GFF_ID cmpl: status:x%x/x%x did:x%x",
780 irsp->ulpStatus, irsp->un.ulpWord[4], did);
781
782 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
783
784 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
785 fbits = CTrsp->un.gff_acc.fbits[FCP_TYPE_FEATURE_OFFSET];
786
787 if (CTrsp->CommandResponse.bits.CmdRsp ==
788 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
789 if ((fbits & FC4_FEATURE_INIT) &&
790 !(fbits & FC4_FEATURE_TARGET)) {
791 lpfc_printf_vlog(vport, KERN_INFO,
792 LOG_DISCOVERY,
793 "0270 Skip x%x GFF "
794 "NameServer Rsp Data: (init) "
795 "x%x x%x\n", did, fbits,
796 vport->fc_rscn_id_cnt);
797 goto out;
798 }
799 }
800 }
801 else {
802
803 if (cmdiocb->retry < LPFC_MAX_NS_RETRY) {
804 retry = 1;
805 if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
806 switch ((irsp->un.ulpWord[4] &
807 IOERR_PARAM_MASK)) {
808
809 case IOERR_NO_RESOURCES:
810
811
812
813 break;
814 case IOERR_LINK_DOWN:
815 case IOERR_SLI_ABORTED:
816 case IOERR_SLI_DOWN:
817 retry = 0;
818 break;
819 default:
820 cmdiocb->retry++;
821 }
822 }
823 else
824 cmdiocb->retry++;
825
826 if (retry) {
827
828 rc = lpfc_ns_cmd(vport, SLI_CTNS_GFF_ID,
829 cmdiocb->retry, did);
830 if (rc == 0) {
831
832 lpfc_ct_free_iocb(phba, cmdiocb);
833 return;
834 }
835 }
836 }
837 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
838 "0267 NameServer GFF Rsp "
839 "x%x Error (%d %d) Data: x%x x%x\n",
840 did, irsp->ulpStatus, irsp->un.ulpWord[4],
841 vport->fc_flag, vport->fc_rscn_id_cnt);
842 }
843
844
845 ndlp = lpfc_setup_disc_node(vport, did);
846 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
847 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
848 "0242 Process x%x GFF "
849 "NameServer Rsp Data: x%x x%x x%x\n",
850 did, ndlp->nlp_flag, vport->fc_flag,
851 vport->fc_rscn_id_cnt);
852 } else {
853 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
854 "0243 Skip x%x GFF "
855 "NameServer Rsp Data: x%x x%x\n", did,
856 vport->fc_flag, vport->fc_rscn_id_cnt);
857 }
858out:
859
860 if (vport->num_disc_nodes)
861 vport->num_disc_nodes--;
862 if (vport->num_disc_nodes == 0) {
863
864
865
866
867
868 if (vport->port_state >= LPFC_DISC_AUTH) {
869 if (vport->fc_flag & FC_RSCN_MODE) {
870 lpfc_els_flush_rscn(vport);
871 spin_lock_irq(shost->host_lock);
872 vport->fc_flag |= FC_RSCN_MODE;
873 spin_unlock_irq(shost->host_lock);
874 }
875 else
876 lpfc_els_flush_rscn(vport);
877 }
878 lpfc_disc_start(vport);
879 }
880 lpfc_ct_free_iocb(phba, cmdiocb);
881 return;
882}
883
884
885static void
886lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
887 struct lpfc_iocbq *rspiocb)
888{
889 struct lpfc_vport *vport = cmdiocb->vport;
890 struct lpfc_dmabuf *inp;
891 struct lpfc_dmabuf *outp;
892 IOCB_t *irsp;
893 struct lpfc_sli_ct_request *CTrsp;
894 struct lpfc_nodelist *ndlp;
895 int cmdcode, rc;
896 uint8_t retry;
897 uint32_t latt;
898
899
900 ndlp = cmdiocb->context_un.ndlp;
901
902
903 cmdiocb->context_un.rsp_iocb = rspiocb;
904
905 inp = (struct lpfc_dmabuf *) cmdiocb->context1;
906 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
907 irsp = &rspiocb->iocb;
908
909 cmdcode = be16_to_cpu(((struct lpfc_sli_ct_request *) inp->virt)->
910 CommandResponse.bits.CmdRsp);
911 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
912
913 latt = lpfc_els_chk_latt(vport);
914
915
916 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
917 "0209 CT Request completes, latt %d, "
918 "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n",
919 latt, irsp->ulpStatus,
920 CTrsp->CommandResponse.bits.CmdRsp,
921 cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag);
922
923 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
924 "CT cmd cmpl: status:x%x/x%x cmd:x%x",
925 irsp->ulpStatus, irsp->un.ulpWord[4], cmdcode);
926
927 if (irsp->ulpStatus) {
928 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
929 "0268 NS cmd x%x Error (x%x x%x)\n",
930 cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]);
931
932 if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
933 (((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
934 IOERR_SLI_DOWN) ||
935 ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
936 IOERR_SLI_ABORTED)))
937 goto out;
938
939 retry = cmdiocb->retry;
940 if (retry >= LPFC_MAX_NS_RETRY)
941 goto out;
942
943 retry++;
944 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
945 "0250 Retrying NS cmd %x\n", cmdcode);
946 rc = lpfc_ns_cmd(vport, cmdcode, retry, 0);
947 if (rc == 0)
948 goto out;
949 }
950
951out:
952 cmdiocb->context_un.ndlp = ndlp;
953 lpfc_ct_free_iocb(phba, cmdiocb);
954 return;
955}
956
957static void
958lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
959 struct lpfc_iocbq *rspiocb)
960{
961 IOCB_t *irsp = &rspiocb->iocb;
962 struct lpfc_vport *vport = cmdiocb->vport;
963
964 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
965 struct lpfc_dmabuf *outp;
966 struct lpfc_sli_ct_request *CTrsp;
967
968 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
969 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
970 if (CTrsp->CommandResponse.bits.CmdRsp ==
971 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
972 vport->ct_flags |= FC_CT_RFT_ID;
973 }
974 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
975 return;
976}
977
978static void
979lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
980 struct lpfc_iocbq *rspiocb)
981{
982 IOCB_t *irsp = &rspiocb->iocb;
983 struct lpfc_vport *vport = cmdiocb->vport;
984
985 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
986 struct lpfc_dmabuf *outp;
987 struct lpfc_sli_ct_request *CTrsp;
988
989 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
990 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
991 if (CTrsp->CommandResponse.bits.CmdRsp ==
992 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
993 vport->ct_flags |= FC_CT_RNN_ID;
994 }
995 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
996 return;
997}
998
999static void
1000lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1001 struct lpfc_iocbq *rspiocb)
1002{
1003 IOCB_t *irsp = &rspiocb->iocb;
1004 struct lpfc_vport *vport = cmdiocb->vport;
1005
1006 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
1007 struct lpfc_dmabuf *outp;
1008 struct lpfc_sli_ct_request *CTrsp;
1009
1010 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
1011 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
1012 if (CTrsp->CommandResponse.bits.CmdRsp ==
1013 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
1014 vport->ct_flags |= FC_CT_RSPN_ID;
1015 }
1016 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
1017 return;
1018}
1019
1020static void
1021lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1022 struct lpfc_iocbq *rspiocb)
1023{
1024 IOCB_t *irsp = &rspiocb->iocb;
1025 struct lpfc_vport *vport = cmdiocb->vport;
1026
1027 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
1028 struct lpfc_dmabuf *outp;
1029 struct lpfc_sli_ct_request *CTrsp;
1030
1031 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
1032 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
1033 if (CTrsp->CommandResponse.bits.CmdRsp ==
1034 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
1035 vport->ct_flags |= FC_CT_RSNN_NN;
1036 }
1037 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
1038 return;
1039}
1040
1041static void
1042lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1043 struct lpfc_iocbq *rspiocb)
1044{
1045 struct lpfc_vport *vport = cmdiocb->vport;
1046
1047
1048 vport->ct_flags = 0;
1049 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
1050 return;
1051}
1052
1053static void
1054lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1055 struct lpfc_iocbq *rspiocb)
1056{
1057 IOCB_t *irsp = &rspiocb->iocb;
1058 struct lpfc_vport *vport = cmdiocb->vport;
1059
1060 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
1061 struct lpfc_dmabuf *outp;
1062 struct lpfc_sli_ct_request *CTrsp;
1063
1064 outp = (struct lpfc_dmabuf *) cmdiocb->context2;
1065 CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
1066 if (CTrsp->CommandResponse.bits.CmdRsp ==
1067 be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
1068 vport->ct_flags |= FC_CT_RFF_ID;
1069 }
1070 lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
1071 return;
1072}
1073
1074int
1075lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
1076 size_t size)
1077{
1078 int n;
1079 uint8_t *wwn = vport->phba->wwpn;
1080
1081 n = snprintf(symbol, size,
1082 "Emulex PPN-%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1083 wwn[0], wwn[1], wwn[2], wwn[3],
1084 wwn[4], wwn[5], wwn[6], wwn[7]);
1085
1086 if (vport->port_type == LPFC_PHYSICAL_PORT)
1087 return n;
1088
1089 if (n < size)
1090 n += snprintf(symbol + n, size - n, " VPort-%d", vport->vpi);
1091
1092 if (n < size &&
1093 strlen(vport->fc_vport->symbolic_name))
1094 n += snprintf(symbol + n, size - n, " VName-%s",
1095 vport->fc_vport->symbolic_name);
1096 return n;
1097}
1098
1099int
1100lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,
1101 size_t size)
1102{
1103 char fwrev[FW_REV_STR_SIZE];
1104 int n;
1105
1106 lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
1107
1108 n = snprintf(symbol, size, "Emulex %s", vport->phba->ModelName);
1109
1110 if (size < n)
1111 return n;
1112 n += snprintf(symbol + n, size - n, " FV%s", fwrev);
1113
1114 if (size < n)
1115 return n;
1116 n += snprintf(symbol + n, size - n, " DV%s", lpfc_release_version);
1117
1118 if (size < n)
1119 return n;
1120 n += snprintf(symbol + n, size - n, " HN:%s", init_utsname()->nodename);
1121
1122
1123 if (size < n)
1124 return n;
1125 n += snprintf(symbol + n, size - n, " OS:%s", init_utsname()->sysname);
1126
1127 return n;
1128}
1129
1130static uint32_t
1131lpfc_find_map_node(struct lpfc_vport *vport)
1132{
1133 struct lpfc_nodelist *ndlp, *next_ndlp;
1134 struct Scsi_Host *shost;
1135 uint32_t cnt = 0;
1136
1137 shost = lpfc_shost_from_vport(vport);
1138 spin_lock_irq(shost->host_lock);
1139 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
1140 if (ndlp->nlp_type & NLP_FABRIC)
1141 continue;
1142 if ((ndlp->nlp_state == NLP_STE_MAPPED_NODE) ||
1143 (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE))
1144 cnt++;
1145 }
1146 spin_unlock_irq(shost->host_lock);
1147 return cnt;
1148}
1149
1150
1151
1152
1153
1154
1155
1156
1157int
1158lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1159 uint8_t retry, uint32_t context)
1160{
1161 struct lpfc_nodelist * ndlp;
1162 struct lpfc_hba *phba = vport->phba;
1163 struct lpfc_dmabuf *mp, *bmp;
1164 struct lpfc_sli_ct_request *CtReq;
1165 struct ulp_bde64 *bpl;
1166 void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
1167 struct lpfc_iocbq *) = NULL;
1168 uint32_t rsp_size = 1024;
1169 size_t size;
1170 int rc = 0;
1171
1172 ndlp = lpfc_findnode_did(vport, NameServer_DID);
1173 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)
1174 || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) {
1175 rc=1;
1176 goto ns_cmd_exit;
1177 }
1178
1179
1180
1181 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
1182 if (!mp) {
1183 rc=2;
1184 goto ns_cmd_exit;
1185 }
1186
1187 INIT_LIST_HEAD(&mp->list);
1188 mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
1189 if (!mp->virt) {
1190 rc=3;
1191 goto ns_cmd_free_mp;
1192 }
1193
1194
1195 bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
1196 if (!bmp) {
1197 rc=4;
1198 goto ns_cmd_free_mpvirt;
1199 }
1200
1201 INIT_LIST_HEAD(&bmp->list);
1202 bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(bmp->phys));
1203 if (!bmp->virt) {
1204 rc=5;
1205 goto ns_cmd_free_bmp;
1206 }
1207
1208
1209 lpfc_printf_vlog(vport, KERN_INFO ,LOG_DISCOVERY,
1210 "0236 NameServer Req Data: x%x x%x x%x\n",
1211 cmdcode, vport->fc_flag, vport->fc_rscn_id_cnt);
1212
1213 bpl = (struct ulp_bde64 *) bmp->virt;
1214 memset(bpl, 0, sizeof(struct ulp_bde64));
1215 bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
1216 bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
1217 bpl->tus.f.bdeFlags = 0;
1218 if (cmdcode == SLI_CTNS_GID_FT)
1219 bpl->tus.f.bdeSize = GID_REQUEST_SZ;
1220 else if (cmdcode == SLI_CTNS_GFF_ID)
1221 bpl->tus.f.bdeSize = GFF_REQUEST_SZ;
1222 else if (cmdcode == SLI_CTNS_RFT_ID)
1223 bpl->tus.f.bdeSize = RFT_REQUEST_SZ;
1224 else if (cmdcode == SLI_CTNS_RNN_ID)
1225 bpl->tus.f.bdeSize = RNN_REQUEST_SZ;
1226 else if (cmdcode == SLI_CTNS_RSPN_ID)
1227 bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
1228 else if (cmdcode == SLI_CTNS_RSNN_NN)
1229 bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
1230 else if (cmdcode == SLI_CTNS_DA_ID)
1231 bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
1232 else if (cmdcode == SLI_CTNS_RFF_ID)
1233 bpl->tus.f.bdeSize = RFF_REQUEST_SZ;
1234 else
1235 bpl->tus.f.bdeSize = 0;
1236 bpl->tus.w = le32_to_cpu(bpl->tus.w);
1237
1238 CtReq = (struct lpfc_sli_ct_request *) mp->virt;
1239 memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
1240 CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
1241 CtReq->RevisionId.bits.InId = 0;
1242 CtReq->FsType = SLI_CT_DIRECTORY_SERVICE;
1243 CtReq->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER;
1244 CtReq->CommandResponse.bits.Size = 0;
1245 switch (cmdcode) {
1246 case SLI_CTNS_GID_FT:
1247 CtReq->CommandResponse.bits.CmdRsp =
1248 cpu_to_be16(SLI_CTNS_GID_FT);
1249 CtReq->un.gid.Fc4Type = SLI_CTPT_FCP;
1250 if (vport->port_state < LPFC_NS_QRY)
1251 vport->port_state = LPFC_NS_QRY;
1252 lpfc_set_disctmo(vport);
1253 cmpl = lpfc_cmpl_ct_cmd_gid_ft;
1254 rsp_size = FC_MAX_NS_RSP;
1255 break;
1256
1257 case SLI_CTNS_GFF_ID:
1258 CtReq->CommandResponse.bits.CmdRsp =
1259 cpu_to_be16(SLI_CTNS_GFF_ID);
1260 CtReq->un.gff.PortId = cpu_to_be32(context);
1261 cmpl = lpfc_cmpl_ct_cmd_gff_id;
1262 break;
1263
1264 case SLI_CTNS_RFT_ID:
1265 vport->ct_flags &= ~FC_CT_RFT_ID;
1266 CtReq->CommandResponse.bits.CmdRsp =
1267 cpu_to_be16(SLI_CTNS_RFT_ID);
1268 CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID);
1269 CtReq->un.rft.fcpReg = 1;
1270 cmpl = lpfc_cmpl_ct_cmd_rft_id;
1271 break;
1272
1273 case SLI_CTNS_RNN_ID:
1274 vport->ct_flags &= ~FC_CT_RNN_ID;
1275 CtReq->CommandResponse.bits.CmdRsp =
1276 cpu_to_be16(SLI_CTNS_RNN_ID);
1277 CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID);
1278 memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename,
1279 sizeof(struct lpfc_name));
1280 cmpl = lpfc_cmpl_ct_cmd_rnn_id;
1281 break;
1282
1283 case SLI_CTNS_RSPN_ID:
1284 vport->ct_flags &= ~FC_CT_RSPN_ID;
1285 CtReq->CommandResponse.bits.CmdRsp =
1286 cpu_to_be16(SLI_CTNS_RSPN_ID);
1287 CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID);
1288 size = sizeof(CtReq->un.rspn.symbname);
1289 CtReq->un.rspn.len =
1290 lpfc_vport_symbolic_port_name(vport,
1291 CtReq->un.rspn.symbname, size);
1292 cmpl = lpfc_cmpl_ct_cmd_rspn_id;
1293 break;
1294 case SLI_CTNS_RSNN_NN:
1295 vport->ct_flags &= ~FC_CT_RSNN_NN;
1296 CtReq->CommandResponse.bits.CmdRsp =
1297 cpu_to_be16(SLI_CTNS_RSNN_NN);
1298 memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename,
1299 sizeof(struct lpfc_name));
1300 size = sizeof(CtReq->un.rsnn.symbname);
1301 CtReq->un.rsnn.len =
1302 lpfc_vport_symbolic_node_name(vport,
1303 CtReq->un.rsnn.symbname, size);
1304 cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
1305 break;
1306 case SLI_CTNS_DA_ID:
1307
1308 CtReq->CommandResponse.bits.CmdRsp =
1309 cpu_to_be16(SLI_CTNS_DA_ID);
1310 CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID);
1311 cmpl = lpfc_cmpl_ct_cmd_da_id;
1312 break;
1313 case SLI_CTNS_RFF_ID:
1314 vport->ct_flags &= ~FC_CT_RFF_ID;
1315 CtReq->CommandResponse.bits.CmdRsp =
1316 cpu_to_be16(SLI_CTNS_RFF_ID);
1317 CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);
1318 CtReq->un.rff.fbits = FC4_FEATURE_INIT;
1319 CtReq->un.rff.type_code = FC_TYPE_FCP;
1320 cmpl = lpfc_cmpl_ct_cmd_rff_id;
1321 break;
1322 }
1323
1324
1325
1326 if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) {
1327
1328 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
1329 "Issue CT cmd: cmd:x%x did:x%x",
1330 cmdcode, ndlp->nlp_DID, 0);
1331 return 0;
1332 }
1333 rc=6;
1334
1335
1336
1337
1338 lpfc_nlp_put(ndlp);
1339
1340 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
1341ns_cmd_free_bmp:
1342 kfree(bmp);
1343ns_cmd_free_mpvirt:
1344 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1345ns_cmd_free_mp:
1346 kfree(mp);
1347ns_cmd_exit:
1348 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
1349 "0266 Issue NameServer Req x%x err %d Data: x%x x%x\n",
1350 cmdcode, rc, vport->fc_flag, vport->fc_rscn_id_cnt);
1351 return 1;
1352}
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363static void
1364lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1365 struct lpfc_iocbq *rspiocb)
1366{
1367 struct lpfc_vport *vport = cmdiocb->vport;
1368 struct lpfc_dmabuf *inp = cmdiocb->context1;
1369 struct lpfc_dmabuf *outp = cmdiocb->context2;
1370 struct lpfc_sli_ct_request *CTcmd = inp->virt;
1371 struct lpfc_sli_ct_request *CTrsp = outp->virt;
1372 uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
1373 uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
1374 IOCB_t *irsp = &rspiocb->iocb;
1375 struct lpfc_nodelist *ndlp;
1376 uint32_t latt, cmd, err;
1377
1378 latt = lpfc_els_chk_latt(vport);
1379 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
1380 "FDMI cmpl: status:x%x/x%x latt:%d",
1381 irsp->ulpStatus, irsp->un.ulpWord[4], latt);
1382
1383 if (latt || irsp->ulpStatus) {
1384
1385
1386 if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
1387 switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) {
1388 case IOERR_SLI_ABORTED:
1389 case IOERR_ABORT_IN_PROGRESS:
1390 case IOERR_SEQUENCE_TIMEOUT:
1391 case IOERR_ILLEGAL_FRAME:
1392 case IOERR_NO_RESOURCES:
1393 case IOERR_ILLEGAL_COMMAND:
1394 cmdiocb->retry++;
1395 if (cmdiocb->retry >= LPFC_FDMI_MAX_RETRY)
1396 break;
1397
1398
1399 err = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING,
1400 cmdiocb, 0);
1401 if (err == IOCB_ERROR)
1402 break;
1403 return;
1404 default:
1405 break;
1406 }
1407 }
1408
1409 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1410 "0229 FDMI cmd %04x failed, latt = %d "
1411 "ulpStatus: x%x, rid x%x\n",
1412 be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus,
1413 irsp->un.ulpWord[4]);
1414 }
1415 lpfc_ct_free_iocb(phba, cmdiocb);
1416
1417 ndlp = lpfc_findnode_did(vport, FDMI_DID);
1418 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
1419 return;
1420
1421
1422 cmd = be16_to_cpu(fdmi_cmd);
1423 if (fdmi_rsp == cpu_to_be16(SLI_CT_RESPONSE_FS_RJT)) {
1424
1425 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1426 "0220 FDMI cmd failed FS_RJT Data: x%x", cmd);
1427
1428
1429 switch (cmd) {
1430 case SLI_MGMT_RHBA:
1431 if (vport->fdmi_hba_mask == LPFC_FDMI2_HBA_ATTR) {
1432
1433 vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR;
1434 vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
1435
1436 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);
1437 }
1438 return;
1439
1440 case SLI_MGMT_RPRT:
1441 if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) {
1442
1443 vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
1444
1445 lpfc_fdmi_cmd(vport, ndlp, cmd, 0);
1446 }
1447 if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) {
1448 vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
1449
1450 lpfc_fdmi_cmd(vport, ndlp, cmd, 0);
1451 }
1452 return;
1453
1454 case SLI_MGMT_RPA:
1455 if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) {
1456
1457 vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR;
1458 vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
1459
1460 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);
1461 }
1462 if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) {
1463 vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
1464
1465 lpfc_fdmi_cmd(vport, ndlp, cmd, 0);
1466 }
1467 return;
1468 }
1469 }
1470
1471
1472
1473
1474
1475
1476 switch (cmd) {
1477 case SLI_MGMT_RHBA:
1478 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, 0);
1479 break;
1480
1481 case SLI_MGMT_DHBA:
1482 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0);
1483 break;
1484
1485 case SLI_MGMT_DPRT:
1486 if (vport->port_type == LPFC_PHYSICAL_PORT)
1487 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA, 0);
1488 else
1489 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0);
1490 break;
1491 }
1492 return;
1493}
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503void
1504lpfc_fdmi_num_disc_check(struct lpfc_vport *vport)
1505{
1506 struct lpfc_hba *phba = vport->phba;
1507 struct lpfc_nodelist *ndlp;
1508 uint16_t cnt;
1509
1510 if (!lpfc_is_link_up(phba))
1511 return;
1512
1513
1514 if (!(vport->fc_flag & FC_FABRIC))
1515 return;
1516
1517 if (!(vport->fdmi_port_mask & LPFC_FDMI_PORT_ATTR_num_disc))
1518 return;
1519
1520 cnt = lpfc_find_map_node(vport);
1521 if (cnt == vport->fdmi_num_disc)
1522 return;
1523
1524 ndlp = lpfc_findnode_did(vport, FDMI_DID);
1525 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
1526 return;
1527
1528 if (vport->port_type == LPFC_PHYSICAL_PORT) {
1529 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA,
1530 LPFC_FDMI_PORT_ATTR_num_disc);
1531 } else {
1532 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT,
1533 LPFC_FDMI_PORT_ATTR_num_disc);
1534 }
1535}
1536
1537
1538static int
1539lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad)
1540{
1541 struct lpfc_fdmi_attr_entry *ae;
1542 uint32_t size;
1543
1544 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1545 memset(ae, 0, sizeof(struct lpfc_name));
1546
1547 memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName,
1548 sizeof(struct lpfc_name));
1549 size = FOURBYTES + sizeof(struct lpfc_name);
1550 ad->AttrLen = cpu_to_be16(size);
1551 ad->AttrType = cpu_to_be16(RHBA_NODENAME);
1552 return size;
1553}
1554static int
1555lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport,
1556 struct lpfc_fdmi_attr_def *ad)
1557{
1558 struct lpfc_fdmi_attr_entry *ae;
1559 uint32_t len, size;
1560
1561 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1562 memset(ae, 0, 256);
1563
1564 strncpy(ae->un.AttrString,
1565 "Emulex Corporation",
1566 sizeof(ae->un.AttrString));
1567 len = strnlen(ae->un.AttrString,
1568 sizeof(ae->un.AttrString));
1569 len += (len & 3) ? (4 - (len & 3)) : 4;
1570 size = FOURBYTES + len;
1571 ad->AttrLen = cpu_to_be16(size);
1572 ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER);
1573 return size;
1574}
1575
1576static int
1577lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad)
1578{
1579 struct lpfc_hba *phba = vport->phba;
1580 struct lpfc_fdmi_attr_entry *ae;
1581 uint32_t len, size;
1582
1583 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1584 memset(ae, 0, 256);
1585
1586 strncpy(ae->un.AttrString, phba->SerialNumber,
1587 sizeof(ae->un.AttrString));
1588 len = strnlen(ae->un.AttrString,
1589 sizeof(ae->un.AttrString));
1590 len += (len & 3) ? (4 - (len & 3)) : 4;
1591 size = FOURBYTES + len;
1592 ad->AttrLen = cpu_to_be16(size);
1593 ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER);
1594 return size;
1595}
1596
1597static int
1598lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport,
1599 struct lpfc_fdmi_attr_def *ad)
1600{
1601 struct lpfc_hba *phba = vport->phba;
1602 struct lpfc_fdmi_attr_entry *ae;
1603 uint32_t len, size;
1604
1605 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1606 memset(ae, 0, 256);
1607
1608 strncpy(ae->un.AttrString, phba->ModelName,
1609 sizeof(ae->un.AttrString));
1610 len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
1611 len += (len & 3) ? (4 - (len & 3)) : 4;
1612 size = FOURBYTES + len;
1613 ad->AttrLen = cpu_to_be16(size);
1614 ad->AttrType = cpu_to_be16(RHBA_MODEL);
1615 return size;
1616}
1617
1618static int
1619lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport,
1620 struct lpfc_fdmi_attr_def *ad)
1621{
1622 struct lpfc_hba *phba = vport->phba;
1623 struct lpfc_fdmi_attr_entry *ae;
1624 uint32_t len, size;
1625
1626 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1627 memset(ae, 0, 256);
1628
1629 strncpy(ae->un.AttrString, phba->ModelDesc,
1630 sizeof(ae->un.AttrString));
1631 len = strnlen(ae->un.AttrString,
1632 sizeof(ae->un.AttrString));
1633 len += (len & 3) ? (4 - (len & 3)) : 4;
1634 size = FOURBYTES + len;
1635 ad->AttrLen = cpu_to_be16(size);
1636 ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION);
1637 return size;
1638}
1639
1640static int
1641lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport,
1642 struct lpfc_fdmi_attr_def *ad)
1643{
1644 struct lpfc_hba *phba = vport->phba;
1645 lpfc_vpd_t *vp = &phba->vpd;
1646 struct lpfc_fdmi_attr_entry *ae;
1647 uint32_t i, j, incr, size;
1648
1649 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1650 memset(ae, 0, 256);
1651
1652
1653 incr = vp->rev.biuRev;
1654 for (i = 0; i < 8; i++) {
1655 j = (incr & 0xf);
1656 if (j <= 9)
1657 ae->un.AttrString[7 - i] =
1658 (char)((uint8_t) 0x30 +
1659 (uint8_t) j);
1660 else
1661 ae->un.AttrString[7 - i] =
1662 (char)((uint8_t) 0x61 +
1663 (uint8_t) (j - 10));
1664 incr = (incr >> 4);
1665 }
1666 size = FOURBYTES + 8;
1667 ad->AttrLen = cpu_to_be16(size);
1668 ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION);
1669 return size;
1670}
1671
1672static int
1673lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport,
1674 struct lpfc_fdmi_attr_def *ad)
1675{
1676 struct lpfc_fdmi_attr_entry *ae;
1677 uint32_t len, size;
1678
1679 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1680 memset(ae, 0, 256);
1681
1682 strncpy(ae->un.AttrString, lpfc_release_version,
1683 sizeof(ae->un.AttrString));
1684 len = strnlen(ae->un.AttrString,
1685 sizeof(ae->un.AttrString));
1686 len += (len & 3) ? (4 - (len & 3)) : 4;
1687 size = FOURBYTES + len;
1688 ad->AttrLen = cpu_to_be16(size);
1689 ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION);
1690 return size;
1691}
1692
1693static int
1694lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport,
1695 struct lpfc_fdmi_attr_def *ad)
1696{
1697 struct lpfc_hba *phba = vport->phba;
1698 struct lpfc_fdmi_attr_entry *ae;
1699 uint32_t len, size;
1700
1701 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1702 memset(ae, 0, 256);
1703
1704 if (phba->sli_rev == LPFC_SLI_REV4)
1705 lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
1706 else
1707 strncpy(ae->un.AttrString, phba->OptionROMVersion,
1708 sizeof(ae->un.AttrString));
1709 len = strnlen(ae->un.AttrString,
1710 sizeof(ae->un.AttrString));
1711 len += (len & 3) ? (4 - (len & 3)) : 4;
1712 size = FOURBYTES + len;
1713 ad->AttrLen = cpu_to_be16(size);
1714 ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION);
1715 return size;
1716}
1717
1718static int
1719lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport,
1720 struct lpfc_fdmi_attr_def *ad)
1721{
1722 struct lpfc_hba *phba = vport->phba;
1723 struct lpfc_fdmi_attr_entry *ae;
1724 uint32_t len, size;
1725
1726 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1727 memset(ae, 0, 256);
1728
1729 lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
1730 len = strnlen(ae->un.AttrString,
1731 sizeof(ae->un.AttrString));
1732 len += (len & 3) ? (4 - (len & 3)) : 4;
1733 size = FOURBYTES + len;
1734 ad->AttrLen = cpu_to_be16(size);
1735 ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION);
1736 return size;
1737}
1738
1739static int
1740lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport,
1741 struct lpfc_fdmi_attr_def *ad)
1742{
1743 struct lpfc_fdmi_attr_entry *ae;
1744 uint32_t len, size;
1745
1746 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1747 memset(ae, 0, 256);
1748
1749 snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s %s %s",
1750 init_utsname()->sysname,
1751 init_utsname()->release,
1752 init_utsname()->version);
1753
1754 len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
1755 len += (len & 3) ? (4 - (len & 3)) : 4;
1756 size = FOURBYTES + len;
1757 ad->AttrLen = cpu_to_be16(size);
1758 ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION);
1759 return size;
1760}
1761
1762static int
1763lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport,
1764 struct lpfc_fdmi_attr_def *ad)
1765{
1766 struct lpfc_fdmi_attr_entry *ae;
1767 uint32_t size;
1768
1769 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1770
1771 ae->un.AttrInt = cpu_to_be32(LPFC_MAX_CT_SIZE);
1772 size = FOURBYTES + sizeof(uint32_t);
1773 ad->AttrLen = cpu_to_be16(size);
1774 ad->AttrType = cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN);
1775 return size;
1776}
1777
1778static int
1779lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport,
1780 struct lpfc_fdmi_attr_def *ad)
1781{
1782 struct lpfc_fdmi_attr_entry *ae;
1783 uint32_t len, size;
1784
1785 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1786 memset(ae, 0, 256);
1787
1788 len = lpfc_vport_symbolic_node_name(vport,
1789 ae->un.AttrString, 256);
1790 len += (len & 3) ? (4 - (len & 3)) : 4;
1791 size = FOURBYTES + len;
1792 ad->AttrLen = cpu_to_be16(size);
1793 ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME);
1794 return size;
1795}
1796
1797static int
1798lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport,
1799 struct lpfc_fdmi_attr_def *ad)
1800{
1801 struct lpfc_fdmi_attr_entry *ae;
1802 uint32_t size;
1803
1804 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1805
1806
1807 ae->un.AttrInt = cpu_to_be32(0);
1808 size = FOURBYTES + sizeof(uint32_t);
1809 ad->AttrLen = cpu_to_be16(size);
1810 ad->AttrType = cpu_to_be16(RHBA_VENDOR_INFO);
1811 return size;
1812}
1813
1814static int
1815lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport,
1816 struct lpfc_fdmi_attr_def *ad)
1817{
1818 struct lpfc_fdmi_attr_entry *ae;
1819 uint32_t size;
1820
1821 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1822
1823
1824 ae->un.AttrInt = cpu_to_be32(1);
1825 size = FOURBYTES + sizeof(uint32_t);
1826 ad->AttrLen = cpu_to_be16(size);
1827 ad->AttrType = cpu_to_be16(RHBA_NUM_PORTS);
1828 return size;
1829}
1830
1831static int
1832lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport,
1833 struct lpfc_fdmi_attr_def *ad)
1834{
1835 struct lpfc_fdmi_attr_entry *ae;
1836 uint32_t size;
1837
1838 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1839 memset(ae, 0, sizeof(struct lpfc_name));
1840
1841 memcpy(&ae->un.AttrWWN, &vport->fabric_nodename,
1842 sizeof(struct lpfc_name));
1843 size = FOURBYTES + sizeof(struct lpfc_name);
1844 ad->AttrLen = cpu_to_be16(size);
1845 ad->AttrType = cpu_to_be16(RHBA_FABRIC_WWNN);
1846 return size;
1847}
1848
1849static int
1850lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport,
1851 struct lpfc_fdmi_attr_def *ad)
1852{
1853 struct lpfc_hba *phba = vport->phba;
1854 struct lpfc_fdmi_attr_entry *ae;
1855 uint32_t len, size;
1856
1857 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1858 memset(ae, 0, 256);
1859
1860 lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
1861 len = strnlen(ae->un.AttrString,
1862 sizeof(ae->un.AttrString));
1863 len += (len & 3) ? (4 - (len & 3)) : 4;
1864 size = FOURBYTES + len;
1865 ad->AttrLen = cpu_to_be16(size);
1866 ad->AttrType = cpu_to_be16(RHBA_BIOS_VERSION);
1867 return size;
1868}
1869
1870static int
1871lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport,
1872 struct lpfc_fdmi_attr_def *ad)
1873{
1874 struct lpfc_fdmi_attr_entry *ae;
1875 uint32_t size;
1876
1877 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1878
1879
1880 ae->un.AttrInt = cpu_to_be32(0);
1881 size = FOURBYTES + sizeof(uint32_t);
1882 ad->AttrLen = cpu_to_be16(size);
1883 ad->AttrType = cpu_to_be16(RHBA_BIOS_STATE);
1884 return size;
1885}
1886
1887static int
1888lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport,
1889 struct lpfc_fdmi_attr_def *ad)
1890{
1891 struct lpfc_fdmi_attr_entry *ae;
1892 uint32_t len, size;
1893
1894 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1895 memset(ae, 0, 256);
1896
1897 strncpy(ae->un.AttrString, "EMULEX",
1898 sizeof(ae->un.AttrString));
1899 len = strnlen(ae->un.AttrString,
1900 sizeof(ae->un.AttrString));
1901 len += (len & 3) ? (4 - (len & 3)) : 4;
1902 size = FOURBYTES + len;
1903 ad->AttrLen = cpu_to_be16(size);
1904 ad->AttrType = cpu_to_be16(RHBA_VENDOR_ID);
1905 return size;
1906}
1907
1908
1909static int
1910lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport,
1911 struct lpfc_fdmi_attr_def *ad)
1912{
1913 struct lpfc_fdmi_attr_entry *ae;
1914 uint32_t size;
1915
1916 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1917 memset(ae, 0, 32);
1918
1919 ae->un.AttrTypes[3] = 0x02;
1920 ae->un.AttrTypes[2] = 0x01;
1921 ae->un.AttrTypes[7] = 0x01;
1922 size = FOURBYTES + 32;
1923 ad->AttrLen = cpu_to_be16(size);
1924 ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES);
1925 return size;
1926}
1927
1928static int
1929lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport,
1930 struct lpfc_fdmi_attr_def *ad)
1931{
1932 struct lpfc_hba *phba = vport->phba;
1933 struct lpfc_fdmi_attr_entry *ae;
1934 uint32_t size;
1935
1936 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1937
1938 ae->un.AttrInt = 0;
1939 if (!(phba->hba_flag & HBA_FCOE_MODE)) {
1940 if (phba->lmt & LMT_32Gb)
1941 ae->un.AttrInt |= HBA_PORTSPEED_32GFC;
1942 if (phba->lmt & LMT_16Gb)
1943 ae->un.AttrInt |= HBA_PORTSPEED_16GFC;
1944 if (phba->lmt & LMT_10Gb)
1945 ae->un.AttrInt |= HBA_PORTSPEED_10GFC;
1946 if (phba->lmt & LMT_8Gb)
1947 ae->un.AttrInt |= HBA_PORTSPEED_8GFC;
1948 if (phba->lmt & LMT_4Gb)
1949 ae->un.AttrInt |= HBA_PORTSPEED_4GFC;
1950 if (phba->lmt & LMT_2Gb)
1951 ae->un.AttrInt |= HBA_PORTSPEED_2GFC;
1952 if (phba->lmt & LMT_1Gb)
1953 ae->un.AttrInt |= HBA_PORTSPEED_1GFC;
1954 } else {
1955
1956 switch (phba->fc_linkspeed) {
1957 case LPFC_ASYNC_LINK_SPEED_10GBPS:
1958 ae->un.AttrInt = HBA_PORTSPEED_10GE;
1959 break;
1960 case LPFC_ASYNC_LINK_SPEED_25GBPS:
1961 ae->un.AttrInt = HBA_PORTSPEED_25GE;
1962 break;
1963 case LPFC_ASYNC_LINK_SPEED_40GBPS:
1964 ae->un.AttrInt = HBA_PORTSPEED_40GE;
1965 break;
1966 case LPFC_ASYNC_LINK_SPEED_100GBPS:
1967 ae->un.AttrInt = HBA_PORTSPEED_100GE;
1968 break;
1969 }
1970 }
1971 ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
1972 size = FOURBYTES + sizeof(uint32_t);
1973 ad->AttrLen = cpu_to_be16(size);
1974 ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED);
1975 return size;
1976}
1977
1978static int
1979lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport,
1980 struct lpfc_fdmi_attr_def *ad)
1981{
1982 struct lpfc_hba *phba = vport->phba;
1983 struct lpfc_fdmi_attr_entry *ae;
1984 uint32_t size;
1985
1986 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1987
1988 if (!(phba->hba_flag & HBA_FCOE_MODE)) {
1989 switch (phba->fc_linkspeed) {
1990 case LPFC_LINK_SPEED_1GHZ:
1991 ae->un.AttrInt = HBA_PORTSPEED_1GFC;
1992 break;
1993 case LPFC_LINK_SPEED_2GHZ:
1994 ae->un.AttrInt = HBA_PORTSPEED_2GFC;
1995 break;
1996 case LPFC_LINK_SPEED_4GHZ:
1997 ae->un.AttrInt = HBA_PORTSPEED_4GFC;
1998 break;
1999 case LPFC_LINK_SPEED_8GHZ:
2000 ae->un.AttrInt = HBA_PORTSPEED_8GFC;
2001 break;
2002 case LPFC_LINK_SPEED_10GHZ:
2003 ae->un.AttrInt = HBA_PORTSPEED_10GFC;
2004 break;
2005 case LPFC_LINK_SPEED_16GHZ:
2006 ae->un.AttrInt = HBA_PORTSPEED_16GFC;
2007 break;
2008 case LPFC_LINK_SPEED_32GHZ:
2009 ae->un.AttrInt = HBA_PORTSPEED_32GFC;
2010 break;
2011 default:
2012 ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN;
2013 break;
2014 }
2015 } else {
2016 switch (phba->fc_linkspeed) {
2017 case LPFC_ASYNC_LINK_SPEED_10GBPS:
2018 ae->un.AttrInt = HBA_PORTSPEED_10GE;
2019 break;
2020 case LPFC_ASYNC_LINK_SPEED_25GBPS:
2021 ae->un.AttrInt = HBA_PORTSPEED_25GE;
2022 break;
2023 case LPFC_ASYNC_LINK_SPEED_40GBPS:
2024 ae->un.AttrInt = HBA_PORTSPEED_40GE;
2025 break;
2026 case LPFC_ASYNC_LINK_SPEED_100GBPS:
2027 ae->un.AttrInt = HBA_PORTSPEED_100GE;
2028 break;
2029 default:
2030 ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN;
2031 break;
2032 }
2033 }
2034
2035 ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
2036 size = FOURBYTES + sizeof(uint32_t);
2037 ad->AttrLen = cpu_to_be16(size);
2038 ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED);
2039 return size;
2040}
2041
2042static int
2043lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport,
2044 struct lpfc_fdmi_attr_def *ad)
2045{
2046 struct serv_parm *hsp;
2047 struct lpfc_fdmi_attr_entry *ae;
2048 uint32_t size;
2049
2050 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2051
2052 hsp = (struct serv_parm *)&vport->fc_sparam;
2053 ae->un.AttrInt = (((uint32_t) hsp->cmn.bbRcvSizeMsb) << 8) |
2054 (uint32_t) hsp->cmn.bbRcvSizeLsb;
2055 ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
2056 size = FOURBYTES + sizeof(uint32_t);
2057 ad->AttrLen = cpu_to_be16(size);
2058 ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE);
2059 return size;
2060}
2061
2062static int
2063lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport,
2064 struct lpfc_fdmi_attr_def *ad)
2065{
2066 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2067 struct lpfc_fdmi_attr_entry *ae;
2068 uint32_t len, size;
2069
2070 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2071 memset(ae, 0, 256);
2072
2073 snprintf(ae->un.AttrString, sizeof(ae->un.AttrString),
2074 "/sys/class/scsi_host/host%d", shost->host_no);
2075 len = strnlen((char *)ae->un.AttrString,
2076 sizeof(ae->un.AttrString));
2077 len += (len & 3) ? (4 - (len & 3)) : 4;
2078 size = FOURBYTES + len;
2079 ad->AttrLen = cpu_to_be16(size);
2080 ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME);
2081 return size;
2082}
2083
2084static int
2085lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport,
2086 struct lpfc_fdmi_attr_def *ad)
2087{
2088 struct lpfc_fdmi_attr_entry *ae;
2089 uint32_t len, size;
2090
2091 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2092 memset(ae, 0, 256);
2093
2094 snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s",
2095 init_utsname()->nodename);
2096
2097 len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
2098 len += (len & 3) ? (4 - (len & 3)) : 4;
2099 size = FOURBYTES + len;
2100 ad->AttrLen = cpu_to_be16(size);
2101 ad->AttrType = cpu_to_be16(RPRT_HOST_NAME);
2102 return size;
2103}
2104
2105static int
2106lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport,
2107 struct lpfc_fdmi_attr_def *ad)
2108{
2109 struct lpfc_fdmi_attr_entry *ae;
2110 uint32_t size;
2111
2112 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2113 memset(ae, 0, sizeof(struct lpfc_name));
2114
2115 memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName,
2116 sizeof(struct lpfc_name));
2117 size = FOURBYTES + sizeof(struct lpfc_name);
2118 ad->AttrLen = cpu_to_be16(size);
2119 ad->AttrType = cpu_to_be16(RPRT_NODENAME);
2120 return size;
2121}
2122
2123static int
2124lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport,
2125 struct lpfc_fdmi_attr_def *ad)
2126{
2127 struct lpfc_fdmi_attr_entry *ae;
2128 uint32_t size;
2129
2130 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2131 memset(ae, 0, sizeof(struct lpfc_name));
2132
2133 memcpy(&ae->un.AttrWWN, &vport->fc_sparam.portName,
2134 sizeof(struct lpfc_name));
2135 size = FOURBYTES + sizeof(struct lpfc_name);
2136 ad->AttrLen = cpu_to_be16(size);
2137 ad->AttrType = cpu_to_be16(RPRT_PORTNAME);
2138 return size;
2139}
2140
2141static int
2142lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport,
2143 struct lpfc_fdmi_attr_def *ad)
2144{
2145 struct lpfc_fdmi_attr_entry *ae;
2146 uint32_t len, size;
2147
2148 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2149 memset(ae, 0, 256);
2150
2151 len = lpfc_vport_symbolic_port_name(vport, ae->un.AttrString, 256);
2152 len += (len & 3) ? (4 - (len & 3)) : 4;
2153 size = FOURBYTES + len;
2154 ad->AttrLen = cpu_to_be16(size);
2155 ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME);
2156 return size;
2157}
2158
2159static int
2160lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport,
2161 struct lpfc_fdmi_attr_def *ad)
2162{
2163 struct lpfc_hba *phba = vport->phba;
2164 struct lpfc_fdmi_attr_entry *ae;
2165 uint32_t size;
2166
2167 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2168 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP)
2169 ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NLPORT);
2170 else
2171 ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NPORT);
2172 size = FOURBYTES + sizeof(uint32_t);
2173 ad->AttrLen = cpu_to_be16(size);
2174 ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE);
2175 return size;
2176}
2177
2178static int
2179lpfc_fdmi_port_attr_class(struct lpfc_vport *vport,
2180 struct lpfc_fdmi_attr_def *ad)
2181{
2182 struct lpfc_fdmi_attr_entry *ae;
2183 uint32_t size;
2184
2185 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2186 ae->un.AttrInt = cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3);
2187 size = FOURBYTES + sizeof(uint32_t);
2188 ad->AttrLen = cpu_to_be16(size);
2189 ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS);
2190 return size;
2191}
2192
2193static int
2194lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport,
2195 struct lpfc_fdmi_attr_def *ad)
2196{
2197 struct lpfc_fdmi_attr_entry *ae;
2198 uint32_t size;
2199
2200 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2201 memset(ae, 0, sizeof(struct lpfc_name));
2202
2203 memcpy(&ae->un.AttrWWN, &vport->fabric_portname,
2204 sizeof(struct lpfc_name));
2205 size = FOURBYTES + sizeof(struct lpfc_name);
2206 ad->AttrLen = cpu_to_be16(size);
2207 ad->AttrType = cpu_to_be16(RPRT_FABRICNAME);
2208 return size;
2209}
2210
2211static int
2212lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport,
2213 struct lpfc_fdmi_attr_def *ad)
2214{
2215 struct lpfc_fdmi_attr_entry *ae;
2216 uint32_t size;
2217
2218 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2219 memset(ae, 0, 32);
2220
2221 ae->un.AttrTypes[3] = 0x02;
2222 ae->un.AttrTypes[2] = 0x01;
2223 ae->un.AttrTypes[7] = 0x01;
2224 size = FOURBYTES + 32;
2225 ad->AttrLen = cpu_to_be16(size);
2226 ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES);
2227 return size;
2228}
2229
2230static int
2231lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport,
2232 struct lpfc_fdmi_attr_def *ad)
2233{
2234 struct lpfc_fdmi_attr_entry *ae;
2235 uint32_t size;
2236
2237 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2238
2239 ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTSTATE_ONLINE);
2240 size = FOURBYTES + sizeof(uint32_t);
2241 ad->AttrLen = cpu_to_be16(size);
2242 ad->AttrType = cpu_to_be16(RPRT_PORT_STATE);
2243 return size;
2244}
2245
2246static int
2247lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport,
2248 struct lpfc_fdmi_attr_def *ad)
2249{
2250 struct lpfc_fdmi_attr_entry *ae;
2251 uint32_t size;
2252
2253 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2254 vport->fdmi_num_disc = lpfc_find_map_node(vport);
2255 ae->un.AttrInt = cpu_to_be32(vport->fdmi_num_disc);
2256 size = FOURBYTES + sizeof(uint32_t);
2257 ad->AttrLen = cpu_to_be16(size);
2258 ad->AttrType = cpu_to_be16(RPRT_DISC_PORT);
2259 return size;
2260}
2261
2262static int
2263lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport,
2264 struct lpfc_fdmi_attr_def *ad)
2265{
2266 struct lpfc_fdmi_attr_entry *ae;
2267 uint32_t size;
2268
2269 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2270 ae->un.AttrInt = cpu_to_be32(vport->fc_myDID);
2271 size = FOURBYTES + sizeof(uint32_t);
2272 ad->AttrLen = cpu_to_be16(size);
2273 ad->AttrType = cpu_to_be16(RPRT_PORT_ID);
2274 return size;
2275}
2276
2277static int
2278lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport,
2279 struct lpfc_fdmi_attr_def *ad)
2280{
2281 struct lpfc_fdmi_attr_entry *ae;
2282 uint32_t len, size;
2283
2284 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2285 memset(ae, 0, 256);
2286
2287 strncpy(ae->un.AttrString, "Smart SAN Initiator",
2288 sizeof(ae->un.AttrString));
2289 len = strnlen(ae->un.AttrString,
2290 sizeof(ae->un.AttrString));
2291 len += (len & 3) ? (4 - (len & 3)) : 4;
2292 size = FOURBYTES + len;
2293 ad->AttrLen = cpu_to_be16(size);
2294 ad->AttrType = cpu_to_be16(RPRT_SMART_SERVICE);
2295 return size;
2296}
2297
2298static int
2299lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport,
2300 struct lpfc_fdmi_attr_def *ad)
2301{
2302 struct lpfc_fdmi_attr_entry *ae;
2303 uint32_t size;
2304
2305 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2306 memset(ae, 0, 256);
2307
2308 memcpy(&ae->un.AttrString, &vport->fc_sparam.nodeName,
2309 sizeof(struct lpfc_name));
2310 memcpy((((uint8_t *)&ae->un.AttrString) +
2311 sizeof(struct lpfc_name)),
2312 &vport->fc_sparam.portName, sizeof(struct lpfc_name));
2313 size = FOURBYTES + (2 * sizeof(struct lpfc_name));
2314 ad->AttrLen = cpu_to_be16(size);
2315 ad->AttrType = cpu_to_be16(RPRT_SMART_GUID);
2316 return size;
2317}
2318
2319static int
2320lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport,
2321 struct lpfc_fdmi_attr_def *ad)
2322{
2323 struct lpfc_fdmi_attr_entry *ae;
2324 uint32_t len, size;
2325
2326 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2327 memset(ae, 0, 256);
2328
2329 strncpy(ae->un.AttrString, "Smart SAN Version 2.0",
2330 sizeof(ae->un.AttrString));
2331 len = strnlen(ae->un.AttrString,
2332 sizeof(ae->un.AttrString));
2333 len += (len & 3) ? (4 - (len & 3)) : 4;
2334 size = FOURBYTES + len;
2335 ad->AttrLen = cpu_to_be16(size);
2336 ad->AttrType = cpu_to_be16(RPRT_SMART_VERSION);
2337 return size;
2338}
2339
2340static int
2341lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport,
2342 struct lpfc_fdmi_attr_def *ad)
2343{
2344 struct lpfc_hba *phba = vport->phba;
2345 struct lpfc_fdmi_attr_entry *ae;
2346 uint32_t len, size;
2347
2348 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2349 memset(ae, 0, 256);
2350
2351 strncpy(ae->un.AttrString, phba->ModelName,
2352 sizeof(ae->un.AttrString));
2353 len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
2354 len += (len & 3) ? (4 - (len & 3)) : 4;
2355 size = FOURBYTES + len;
2356 ad->AttrLen = cpu_to_be16(size);
2357 ad->AttrType = cpu_to_be16(RPRT_SMART_MODEL);
2358 return size;
2359}
2360
2361static int
2362lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport,
2363 struct lpfc_fdmi_attr_def *ad)
2364{
2365 struct lpfc_fdmi_attr_entry *ae;
2366 uint32_t size;
2367
2368 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2369
2370
2371 if (vport->vpi)
2372 ae->un.AttrInt = cpu_to_be32(2);
2373 else
2374 ae->un.AttrInt = cpu_to_be32(1);
2375 size = FOURBYTES + sizeof(uint32_t);
2376 ad->AttrLen = cpu_to_be16(size);
2377 ad->AttrType = cpu_to_be16(RPRT_SMART_PORT_INFO);
2378 return size;
2379}
2380
2381static int
2382lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport,
2383 struct lpfc_fdmi_attr_def *ad)
2384{
2385 struct lpfc_fdmi_attr_entry *ae;
2386 uint32_t size;
2387
2388 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2389 ae->un.AttrInt = cpu_to_be32(0);
2390 size = FOURBYTES + sizeof(uint32_t);
2391 ad->AttrLen = cpu_to_be16(size);
2392 ad->AttrType = cpu_to_be16(RPRT_SMART_QOS);
2393 return size;
2394}
2395
2396static int
2397lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport,
2398 struct lpfc_fdmi_attr_def *ad)
2399{
2400 struct lpfc_fdmi_attr_entry *ae;
2401 uint32_t size;
2402
2403 ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2404 ae->un.AttrInt = cpu_to_be32(1);
2405 size = FOURBYTES + sizeof(uint32_t);
2406 ad->AttrLen = cpu_to_be16(size);
2407 ad->AttrType = cpu_to_be16(RPRT_SMART_SECURITY);
2408 return size;
2409}
2410
2411
2412int (*lpfc_fdmi_hba_action[])
2413 (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = {
2414
2415 lpfc_fdmi_hba_attr_wwnn,
2416 lpfc_fdmi_hba_attr_manufacturer,
2417 lpfc_fdmi_hba_attr_sn,
2418 lpfc_fdmi_hba_attr_model,
2419 lpfc_fdmi_hba_attr_description,
2420 lpfc_fdmi_hba_attr_hdw_ver,
2421 lpfc_fdmi_hba_attr_drvr_ver,
2422 lpfc_fdmi_hba_attr_rom_ver,
2423 lpfc_fdmi_hba_attr_fmw_ver,
2424 lpfc_fdmi_hba_attr_os_ver,
2425 lpfc_fdmi_hba_attr_ct_len,
2426 lpfc_fdmi_hba_attr_symbolic_name,
2427 lpfc_fdmi_hba_attr_vendor_info,
2428 lpfc_fdmi_hba_attr_num_ports,
2429 lpfc_fdmi_hba_attr_fabric_wwnn,
2430 lpfc_fdmi_hba_attr_bios_ver,
2431 lpfc_fdmi_hba_attr_bios_state,
2432 lpfc_fdmi_hba_attr_vendor_id,
2433};
2434
2435
2436int (*lpfc_fdmi_port_action[])
2437 (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = {
2438
2439 lpfc_fdmi_port_attr_fc4type,
2440 lpfc_fdmi_port_attr_support_speed,
2441 lpfc_fdmi_port_attr_speed,
2442 lpfc_fdmi_port_attr_max_frame,
2443 lpfc_fdmi_port_attr_os_devname,
2444 lpfc_fdmi_port_attr_host_name,
2445 lpfc_fdmi_port_attr_wwnn,
2446 lpfc_fdmi_port_attr_wwpn,
2447 lpfc_fdmi_port_attr_symbolic_name,
2448 lpfc_fdmi_port_attr_port_type,
2449 lpfc_fdmi_port_attr_class,
2450 lpfc_fdmi_port_attr_fabric_wwpn,
2451 lpfc_fdmi_port_attr_active_fc4type,
2452 lpfc_fdmi_port_attr_port_state,
2453 lpfc_fdmi_port_attr_num_disc,
2454 lpfc_fdmi_port_attr_nportid,
2455 lpfc_fdmi_smart_attr_service,
2456 lpfc_fdmi_smart_attr_guid,
2457 lpfc_fdmi_smart_attr_version,
2458 lpfc_fdmi_smart_attr_model,
2459 lpfc_fdmi_smart_attr_port_info,
2460 lpfc_fdmi_smart_attr_qos,
2461 lpfc_fdmi_smart_attr_security,
2462};
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473int
2474lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2475 int cmdcode, uint32_t new_mask)
2476{
2477 struct lpfc_hba *phba = vport->phba;
2478 struct lpfc_dmabuf *mp, *bmp;
2479 struct lpfc_sli_ct_request *CtReq;
2480 struct ulp_bde64 *bpl;
2481 uint32_t bit_pos;
2482 uint32_t size;
2483 uint32_t rsp_size;
2484 uint32_t mask;
2485 struct lpfc_fdmi_reg_hba *rh;
2486 struct lpfc_fdmi_port_entry *pe;
2487 struct lpfc_fdmi_reg_portattr *pab = NULL;
2488 struct lpfc_fdmi_attr_block *ab = NULL;
2489 int (*func)(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad);
2490 void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *,
2491 struct lpfc_iocbq *);
2492
2493 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
2494 return 0;
2495
2496 cmpl = lpfc_cmpl_ct_disc_fdmi;
2497
2498
2499
2500 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2501 if (!mp)
2502 goto fdmi_cmd_exit;
2503
2504 mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
2505 if (!mp->virt)
2506 goto fdmi_cmd_free_mp;
2507
2508
2509 bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2510 if (!bmp)
2511 goto fdmi_cmd_free_mpvirt;
2512
2513 bmp->virt = lpfc_mbuf_alloc(phba, 0, &(bmp->phys));
2514 if (!bmp->virt)
2515 goto fdmi_cmd_free_bmp;
2516
2517 INIT_LIST_HEAD(&mp->list);
2518 INIT_LIST_HEAD(&bmp->list);
2519
2520
2521 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2522 "0218 FDMI Request Data: x%x x%x x%x\n",
2523 vport->fc_flag, vport->port_state, cmdcode);
2524 CtReq = (struct lpfc_sli_ct_request *)mp->virt;
2525
2526
2527 memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
2528 CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
2529 CtReq->RevisionId.bits.InId = 0;
2530
2531 CtReq->FsType = SLI_CT_MANAGEMENT_SERVICE;
2532 CtReq->FsSubType = SLI_CT_FDMI_Subtypes;
2533
2534 CtReq->CommandResponse.bits.CmdRsp = cpu_to_be16(cmdcode);
2535 rsp_size = LPFC_BPL_SIZE;
2536 size = 0;
2537
2538
2539 switch (cmdcode) {
2540 case SLI_MGMT_RHAT:
2541 case SLI_MGMT_RHBA:
2542 rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID;
2543
2544 memcpy(&rh->hi.PortName, &phba->pport->fc_sparam.portName,
2545 sizeof(struct lpfc_name));
2546
2547 if (cmdcode == SLI_MGMT_RHBA) {
2548
2549
2550 rh->rpl.EntryCnt = cpu_to_be32(1);
2551 memcpy(&rh->rpl.pe, &phba->pport->fc_sparam.portName,
2552 sizeof(struct lpfc_name));
2553
2554
2555 size = 2 * sizeof(struct lpfc_name) +
2556 FOURBYTES;
2557 } else {
2558 size = sizeof(struct lpfc_name);
2559 }
2560 ab = (struct lpfc_fdmi_attr_block *)((uint8_t *)rh + size);
2561 ab->EntryCnt = 0;
2562 size += FOURBYTES;
2563 bit_pos = 0;
2564 if (new_mask)
2565 mask = new_mask;
2566 else
2567 mask = vport->fdmi_hba_mask;
2568
2569
2570 while (mask) {
2571 if (mask & 0x1) {
2572 func = lpfc_fdmi_hba_action[bit_pos];
2573 size += func(vport,
2574 (struct lpfc_fdmi_attr_def *)
2575 ((uint8_t *)rh + size));
2576 ab->EntryCnt++;
2577 if ((size + 256) >
2578 (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
2579 goto hba_out;
2580 }
2581 mask = mask >> 1;
2582 bit_pos++;
2583 }
2584hba_out:
2585 ab->EntryCnt = cpu_to_be32(ab->EntryCnt);
2586
2587 size = GID_REQUEST_SZ - 4 + size;
2588 break;
2589
2590 case SLI_MGMT_RPRT:
2591 case SLI_MGMT_RPA:
2592 pab = (struct lpfc_fdmi_reg_portattr *)&CtReq->un.PortID;
2593 if (cmdcode == SLI_MGMT_RPRT) {
2594 rh = (struct lpfc_fdmi_reg_hba *)pab;
2595
2596 memcpy(&rh->hi.PortName,
2597 &phba->pport->fc_sparam.portName,
2598 sizeof(struct lpfc_name));
2599 pab = (struct lpfc_fdmi_reg_portattr *)
2600 ((uint8_t *)pab + sizeof(struct lpfc_name));
2601 }
2602
2603 memcpy((uint8_t *)&pab->PortName,
2604 (uint8_t *)&vport->fc_sparam.portName,
2605 sizeof(struct lpfc_name));
2606 size += sizeof(struct lpfc_name) + FOURBYTES;
2607 pab->ab.EntryCnt = 0;
2608 bit_pos = 0;
2609 if (new_mask)
2610 mask = new_mask;
2611 else
2612 mask = vport->fdmi_port_mask;
2613
2614
2615 while (mask) {
2616 if (mask & 0x1) {
2617 func = lpfc_fdmi_port_action[bit_pos];
2618 size += func(vport,
2619 (struct lpfc_fdmi_attr_def *)
2620 ((uint8_t *)pab + size));
2621 pab->ab.EntryCnt++;
2622 if ((size + 256) >
2623 (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
2624 goto port_out;
2625 }
2626 mask = mask >> 1;
2627 bit_pos++;
2628 }
2629port_out:
2630 pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt);
2631
2632 if (cmdcode == SLI_MGMT_RPRT)
2633 size += sizeof(struct lpfc_name);
2634 size = GID_REQUEST_SZ - 4 + size;
2635 break;
2636
2637 case SLI_MGMT_GHAT:
2638 case SLI_MGMT_GRPL:
2639 rsp_size = FC_MAX_NS_RSP;
2640 case SLI_MGMT_DHBA:
2641 case SLI_MGMT_DHAT:
2642 pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID;
2643 memcpy((uint8_t *)&pe->PortName,
2644 (uint8_t *)&vport->fc_sparam.portName,
2645 sizeof(struct lpfc_name));
2646 size = GID_REQUEST_SZ - 4 + sizeof(struct lpfc_name);
2647 break;
2648
2649 case SLI_MGMT_GPAT:
2650 case SLI_MGMT_GPAS:
2651 rsp_size = FC_MAX_NS_RSP;
2652 case SLI_MGMT_DPRT:
2653 case SLI_MGMT_DPA:
2654 pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID;
2655 memcpy((uint8_t *)&pe->PortName,
2656 (uint8_t *)&vport->fc_sparam.portName,
2657 sizeof(struct lpfc_name));
2658 size = GID_REQUEST_SZ - 4 + sizeof(struct lpfc_name);
2659 break;
2660 case SLI_MGMT_GRHL:
2661 size = GID_REQUEST_SZ - 4;
2662 break;
2663 default:
2664 lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY,
2665 "0298 FDMI cmdcode x%x not supported\n",
2666 cmdcode);
2667 goto fdmi_cmd_free_bmpvirt;
2668 }
2669 CtReq->CommandResponse.bits.Size = cpu_to_be16(rsp_size);
2670
2671 bpl = (struct ulp_bde64 *)bmp->virt;
2672 bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys));
2673 bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys));
2674 bpl->tus.f.bdeFlags = 0;
2675 bpl->tus.f.bdeSize = size;
2676
2677
2678
2679
2680
2681 if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, 0))
2682 return 0;
2683
2684
2685
2686
2687
2688 lpfc_nlp_put(ndlp);
2689
2690fdmi_cmd_free_bmpvirt:
2691 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
2692fdmi_cmd_free_bmp:
2693 kfree(bmp);
2694fdmi_cmd_free_mpvirt:
2695 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2696fdmi_cmd_free_mp:
2697 kfree(mp);
2698fdmi_cmd_exit:
2699
2700 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2701 "0244 Issue FDMI request failed Data: x%x\n",
2702 cmdcode);
2703 return 1;
2704}
2705
2706
2707
2708
2709
2710
2711
2712
2713void
2714lpfc_delayed_disc_tmo(unsigned long ptr)
2715{
2716 struct lpfc_vport *vport = (struct lpfc_vport *)ptr;
2717 struct lpfc_hba *phba = vport->phba;
2718 uint32_t tmo_posted;
2719 unsigned long iflag;
2720
2721 spin_lock_irqsave(&vport->work_port_lock, iflag);
2722 tmo_posted = vport->work_port_events & WORKER_DELAYED_DISC_TMO;
2723 if (!tmo_posted)
2724 vport->work_port_events |= WORKER_DELAYED_DISC_TMO;
2725 spin_unlock_irqrestore(&vport->work_port_lock, iflag);
2726
2727 if (!tmo_posted)
2728 lpfc_worker_wake_up(phba);
2729 return;
2730}
2731
2732
2733
2734
2735
2736
2737
2738
2739void
2740lpfc_delayed_disc_timeout_handler(struct lpfc_vport *vport)
2741{
2742 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2743
2744 spin_lock_irq(shost->host_lock);
2745 if (!(vport->fc_flag & FC_DISC_DELAYED)) {
2746 spin_unlock_irq(shost->host_lock);
2747 return;
2748 }
2749 vport->fc_flag &= ~FC_DISC_DELAYED;
2750 spin_unlock_irq(shost->host_lock);
2751
2752 lpfc_do_scr_ns_plogi(vport->phba, vport);
2753}
2754
2755void
2756lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
2757{
2758 struct lpfc_sli *psli = &phba->sli;
2759 lpfc_vpd_t *vp = &phba->vpd;
2760 uint32_t b1, b2, b3, b4, i, rev;
2761 char c;
2762 uint32_t *ptr, str[4];
2763 uint8_t *fwname;
2764
2765 if (phba->sli_rev == LPFC_SLI_REV4)
2766 snprintf(fwrevision, FW_REV_STR_SIZE, "%s", vp->rev.opFwName);
2767 else if (vp->rev.rBit) {
2768 if (psli->sli_flag & LPFC_SLI_ACTIVE)
2769 rev = vp->rev.sli2FwRev;
2770 else
2771 rev = vp->rev.sli1FwRev;
2772
2773 b1 = (rev & 0x0000f000) >> 12;
2774 b2 = (rev & 0x00000f00) >> 8;
2775 b3 = (rev & 0x000000c0) >> 6;
2776 b4 = (rev & 0x00000030) >> 4;
2777
2778 switch (b4) {
2779 case 0:
2780 c = 'N';
2781 break;
2782 case 1:
2783 c = 'A';
2784 break;
2785 case 2:
2786 c = 'B';
2787 break;
2788 case 3:
2789 c = 'X';
2790 break;
2791 default:
2792 c = 0;
2793 break;
2794 }
2795 b4 = (rev & 0x0000000f);
2796
2797 if (psli->sli_flag & LPFC_SLI_ACTIVE)
2798 fwname = vp->rev.sli2FwName;
2799 else
2800 fwname = vp->rev.sli1FwName;
2801
2802 for (i = 0; i < 16; i++)
2803 if (fwname[i] == 0x20)
2804 fwname[i] = 0;
2805
2806 ptr = (uint32_t*)fwname;
2807
2808 for (i = 0; i < 3; i++)
2809 str[i] = be32_to_cpu(*ptr++);
2810
2811 if (c == 0) {
2812 if (flag)
2813 sprintf(fwrevision, "%d.%d%d (%s)",
2814 b1, b2, b3, (char *)str);
2815 else
2816 sprintf(fwrevision, "%d.%d%d", b1,
2817 b2, b3);
2818 } else {
2819 if (flag)
2820 sprintf(fwrevision, "%d.%d%d%c%d (%s)",
2821 b1, b2, b3, c,
2822 b4, (char *)str);
2823 else
2824 sprintf(fwrevision, "%d.%d%d%c%d",
2825 b1, b2, b3, c, b4);
2826 }
2827 } else {
2828 rev = vp->rev.smFwRev;
2829
2830 b1 = (rev & 0xff000000) >> 24;
2831 b2 = (rev & 0x00f00000) >> 20;
2832 b3 = (rev & 0x000f0000) >> 16;
2833 c = (rev & 0x0000ff00) >> 8;
2834 b4 = (rev & 0x000000ff);
2835
2836 sprintf(fwrevision, "%d.%d%d%c%d", b1, b2, b3, c, b4);
2837 }
2838 return;
2839}
2840