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