aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_mbox.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-06-17 20:56:38 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-06-17 23:27:39 -0400
commit92d7f7b0cde3ad2260e7462b40867b57efd49851 (patch)
treefadb1d8f1a817c2f85937b5e9c3b830bdecb5555 /drivers/scsi/lpfc/lpfc_mbox.c
parented957684294618602b48f1950b0c9bbcb036583f (diff)
[SCSI] lpfc: NPIV: add NPIV support on top of SLI-3
NPIV support is added to the driver. It utilizes the interfaces of the fc transport for the creation and deletion of vports. Within the driver, a new Scsi_Host is created for each NPIV instance, and is paired with a new instance of a FC port. This allows N FC Port elements to share a single Adapter. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mbox.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c131
1 files changed, 96 insertions, 35 deletions
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 977799c2b2c2..277eb6132e81 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -106,7 +106,7 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
106 */ 106 */
107 pmb->context1 = (uint8_t *) mp; 107 pmb->context1 = (uint8_t *) mp;
108 mb->mbxOwner = OWN_HOST; 108 mb->mbxOwner = OWN_HOST;
109 return 0; 109 return (0);
110} 110}
111 111
112/**********************************************/ 112/**********************************************/
@@ -209,7 +209,7 @@ lpfc_init_link(struct lpfc_hba * phba,
209 */ 209 */
210 vpd = &phba->vpd; 210 vpd = &phba->vpd;
211 if (vpd->rev.feaLevelHigh >= 0x02){ 211 if (vpd->rev.feaLevelHigh >= 0x02){
212 switch (linkspeed){ 212 switch(linkspeed){
213 case LINK_SPEED_1G: 213 case LINK_SPEED_1G:
214 case LINK_SPEED_2G: 214 case LINK_SPEED_2G:
215 case LINK_SPEED_4G: 215 case LINK_SPEED_4G:
@@ -232,7 +232,6 @@ lpfc_init_link(struct lpfc_hba * phba,
232 mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK; 232 mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK;
233 mb->mbxOwner = OWN_HOST; 233 mb->mbxOwner = OWN_HOST;
234 mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA; 234 mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA;
235 mb->un.varInitLnk.link_flags |= FLAGS_UNREG_LOGIN_ALL;
236 return; 235 return;
237} 236}
238 237
@@ -241,7 +240,7 @@ lpfc_init_link(struct lpfc_hba * phba,
241/* mailbox command */ 240/* mailbox command */
242/**********************************************/ 241/**********************************************/
243int 242int
244lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) 243lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
245{ 244{
246 struct lpfc_dmabuf *mp; 245 struct lpfc_dmabuf *mp;
247 MAILBOX_t *mb; 246 MAILBOX_t *mb;
@@ -265,18 +264,19 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
265 LOG_MBOX, 264 LOG_MBOX,
266 "%d:0301 READ_SPARAM: no buffers\n", 265 "%d:0301 READ_SPARAM: no buffers\n",
267 phba->brd_no); 266 phba->brd_no);
268 return 1; 267 return (1);
269 } 268 }
270 INIT_LIST_HEAD(&mp->list); 269 INIT_LIST_HEAD(&mp->list);
271 mb->mbxCommand = MBX_READ_SPARM64; 270 mb->mbxCommand = MBX_READ_SPARM64;
272 mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); 271 mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
273 mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys); 272 mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
274 mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys); 273 mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
274 mb->un.varRdSparm.vpi = vpi;
275 275
276 /* save address for completion */ 276 /* save address for completion */
277 pmb->context1 = mp; 277 pmb->context1 = mp;
278 278
279 return 0; 279 return (0);
280} 280}
281 281
282/********************************************/ 282/********************************************/
@@ -284,7 +284,8 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
284/* mailbox command */ 284/* mailbox command */
285/********************************************/ 285/********************************************/
286void 286void
287lpfc_unreg_did(struct lpfc_hba *phba, uint32_t did, LPFC_MBOXQ_t *pmb) 287lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
288 LPFC_MBOXQ_t * pmb)
288{ 289{
289 MAILBOX_t *mb; 290 MAILBOX_t *mb;
290 291
@@ -292,6 +293,7 @@ lpfc_unreg_did(struct lpfc_hba *phba, uint32_t did, LPFC_MBOXQ_t *pmb)
292 memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); 293 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
293 294
294 mb->un.varUnregDID.did = did; 295 mb->un.varUnregDID.did = did;
296 mb->un.varUnregDID.vpi = vpi;
295 297
296 mb->mbxCommand = MBX_UNREG_D_ID; 298 mb->mbxCommand = MBX_UNREG_D_ID;
297 mb->mbxOwner = OWN_HOST; 299 mb->mbxOwner = OWN_HOST;
@@ -337,8 +339,8 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
337/* mailbox command */ 339/* mailbox command */
338/********************************************/ 340/********************************************/
339int 341int
340lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param, 342lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
341 LPFC_MBOXQ_t *pmb, uint32_t flag) 343 uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag)
342{ 344{
343 MAILBOX_t *mb = &pmb->mb; 345 MAILBOX_t *mb = &pmb->mb;
344 uint8_t *sparam; 346 uint8_t *sparam;
@@ -347,6 +349,7 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param,
347 memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); 349 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
348 350
349 mb->un.varRegLogin.rpi = 0; 351 mb->un.varRegLogin.rpi = 0;
352 mb->un.varRegLogin.vpi = vpi;
350 mb->un.varRegLogin.did = did; 353 mb->un.varRegLogin.did = did;
351 mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ 354 mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */
352 355
@@ -358,13 +361,11 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param,
358 kfree(mp); 361 kfree(mp);
359 mb->mbxCommand = MBX_REG_LOGIN64; 362 mb->mbxCommand = MBX_REG_LOGIN64;
360 /* REG_LOGIN: no buffers */ 363 /* REG_LOGIN: no buffers */
361 lpfc_printf_log(phba, 364 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
362 KERN_WARNING, 365 "%d (%d):0302 REG_LOGIN: no buffers, DID x%x, "
363 LOG_MBOX, 366 "flag x%x\n",
364 "%d:0302 REG_LOGIN: no buffers Data x%x x%x\n", 367 phba->brd_no, vpi, did, flag);
365 phba->brd_no, 368 return (1);
366 (uint32_t) did, (uint32_t) flag);
367 return 1;
368 } 369 }
369 INIT_LIST_HEAD(&mp->list); 370 INIT_LIST_HEAD(&mp->list);
370 sparam = mp->virt; 371 sparam = mp->virt;
@@ -380,7 +381,7 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param,
380 mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys); 381 mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
381 mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys); 382 mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
382 383
383 return 0; 384 return (0);
384} 385}
385 386
386/**********************************************/ 387/**********************************************/
@@ -388,7 +389,8 @@ lpfc_reg_login(struct lpfc_hba *phba, uint32_t did, uint8_t *param,
388/* mailbox command */ 389/* mailbox command */
389/**********************************************/ 390/**********************************************/
390void 391void
391lpfc_unreg_login(struct lpfc_hba *phba, uint32_t rpi, LPFC_MBOXQ_t * pmb) 392lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
393 LPFC_MBOXQ_t * pmb)
392{ 394{
393 MAILBOX_t *mb; 395 MAILBOX_t *mb;
394 396
@@ -397,12 +399,52 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint32_t rpi, LPFC_MBOXQ_t * pmb)
397 399
398 mb->un.varUnregLogin.rpi = (uint16_t) rpi; 400 mb->un.varUnregLogin.rpi = (uint16_t) rpi;
399 mb->un.varUnregLogin.rsvd1 = 0; 401 mb->un.varUnregLogin.rsvd1 = 0;
402 mb->un.varUnregLogin.vpi = vpi;
400 403
401 mb->mbxCommand = MBX_UNREG_LOGIN; 404 mb->mbxCommand = MBX_UNREG_LOGIN;
402 mb->mbxOwner = OWN_HOST; 405 mb->mbxOwner = OWN_HOST;
403 return; 406 return;
404} 407}
405 408
409/**************************************************/
410/* lpfc_reg_vpi Issue a REG_VPI */
411/* mailbox command */
412/**************************************************/
413void
414lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid,
415 LPFC_MBOXQ_t *pmb)
416{
417 MAILBOX_t *mb = &pmb->mb;
418
419 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
420
421 mb->un.varRegVpi.vpi = vpi;
422 mb->un.varRegVpi.sid = sid;
423
424 mb->mbxCommand = MBX_REG_VPI;
425 mb->mbxOwner = OWN_HOST;
426 return;
427
428}
429
430/**************************************************/
431/* lpfc_unreg_vpi Issue a UNREG_VNPI */
432/* mailbox command */
433/**************************************************/
434void
435lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
436{
437 MAILBOX_t *mb = &pmb->mb;
438 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
439
440 mb->un.varUnregVpi.vpi = vpi;
441
442 mb->mbxCommand = MBX_UNREG_VPI;
443 mb->mbxOwner = OWN_HOST;
444 return;
445
446}
447
406static void 448static void
407lpfc_config_pcb_setup(struct lpfc_hba * phba) 449lpfc_config_pcb_setup(struct lpfc_hba * phba)
408{ 450{
@@ -420,9 +462,9 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
420 pring = &psli->ring[i]; 462 pring = &psli->ring[i];
421 463
422 pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE: 464 pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE:
423 SLI2_IOCB_CMD_SIZE; 465 SLI2_IOCB_CMD_SIZE;
424 pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE: 466 pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE:
425 SLI2_IOCB_RSP_SIZE; 467 SLI2_IOCB_RSP_SIZE;
426 /* A ring MUST have both cmd and rsp entries defined to be 468 /* A ring MUST have both cmd and rsp entries defined to be
427 valid */ 469 valid */
428 if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) { 470 if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {
@@ -437,18 +479,18 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
437 continue; 479 continue;
438 } 480 }
439 /* Command ring setup for ring */ 481 /* Command ring setup for ring */
440 pring->cmdringaddr = (void *)&phba->slim2p->IOCBs[iocbCnt]; 482 pring->cmdringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
441 pcbp->rdsc[i].cmdEntries = pring->numCiocb; 483 pcbp->rdsc[i].cmdEntries = pring->numCiocb;
442 484
443 offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - 485 offset = (uint8_t *) &phba->slim2p->IOCBs[iocbCnt] -
444 (uint8_t *)phba->slim2p; 486 (uint8_t *) phba->slim2p;
445 pdma_addr = phba->slim2p_mapping + offset; 487 pdma_addr = phba->slim2p_mapping + offset;
446 pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr); 488 pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
447 pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr); 489 pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
448 iocbCnt += pring->numCiocb; 490 iocbCnt += pring->numCiocb;
449 491
450 /* Response ring setup for ring */ 492 /* Response ring setup for ring */
451 pring->rspringaddr = (void *)&phba->slim2p->IOCBs[iocbCnt]; 493 pring->rspringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
452 494
453 pcbp->rdsc[i].rspEntries = pring->numRiocb; 495 pcbp->rdsc[i].rspEntries = pring->numRiocb;
454 offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - 496 offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
@@ -519,7 +561,7 @@ lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc,
519 * Notification */ 561 * Notification */
520 hbqmb->numMask = hbq_desc->mask_count; /* # R_CTL/TYPE masks 562 hbqmb->numMask = hbq_desc->mask_count; /* # R_CTL/TYPE masks
521 * # in words 0-19 */ 563 * # in words 0-19 */
522 hbqmb->profile = hbq_desc->profile; /* Selection profile: 564 hbqmb->profile = hbq_desc->profile; /* Selection profile:
523 * 0 = all, 565 * 0 = all,
524 * 7 = logentry */ 566 * 7 = logentry */
525 hbqmb->ringMask = hbq_desc->ring_mask; /* Binds HBQ to a ring 567 hbqmb->ringMask = hbq_desc->ring_mask; /* Binds HBQ to a ring
@@ -538,9 +580,9 @@ lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc,
538 mb->mbxCommand = MBX_CONFIG_HBQ; 580 mb->mbxCommand = MBX_CONFIG_HBQ;
539 mb->mbxOwner = OWN_HOST; 581 mb->mbxOwner = OWN_HOST;
540 582
541 /* Copy info for profiles 2,3,5. Other 583 /* Copy info for profiles 2,3,5. Other
542 * profiles this area is reserved 584 * profiles this area is reserved
543 */ 585 */
544 if (hbq_desc->profile == 2) 586 if (hbq_desc->profile == 2)
545 lpfc_build_hbq_profile2(hbqmb, hbq_desc); 587 lpfc_build_hbq_profile2(hbqmb, hbq_desc);
546 else if (hbq_desc->profile == 3) 588 else if (hbq_desc->profile == 3)
@@ -563,6 +605,8 @@ lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc,
563 return; 605 return;
564} 606}
565 607
608
609
566void 610void
567lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) 611lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
568{ 612{
@@ -605,7 +649,7 @@ lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
605} 649}
606 650
607void 651void
608lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) 652lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
609{ 653{
610 MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr; 654 MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr;
611 MAILBOX_t *mb = &pmb->mb; 655 MAILBOX_t *mb = &pmb->mb;
@@ -629,11 +673,19 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
629 673
630 /* If HBA supports SLI=3 ask for it */ 674 /* If HBA supports SLI=3 ask for it */
631 675
632 mb->un.varCfgPort.sli_mode = phba->sli_rev; 676 if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
633 if (phba->sli_rev == 3) {
634 mb->un.varCfgPort.cerbm = 1; /* Request HBQs */ 677 mb->un.varCfgPort.cerbm = 1; /* Request HBQs */
635 mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */ 678 mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */
636 } 679 if (phba->max_vpi && lpfc_npiv_enable &&
680 phba->vpd.sli3Feat.cmv) {
681 mb->un.varCfgPort.max_vpi = phba->max_vpi;
682 mb->un.varCfgPort.cmv = 1;
683 phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
684 } else
685 mb->un.varCfgPort.max_vpi = phba->max_vpi = 0;
686 } else
687 phba->sli_rev = 2;
688 mb->un.varCfgPort.sli_mode = phba->sli_rev;
637 689
638 /* Now setup pcb */ 690 /* Now setup pcb */
639 phba->slim2p->pcb.type = TYPE_NATIVE_SLI2; 691 phba->slim2p->pcb.type = TYPE_NATIVE_SLI2;
@@ -748,7 +800,7 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
748 800
749 /* Swap PCB if needed */ 801 /* Swap PCB if needed */
750 lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb, 802 lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb,
751 sizeof (PCB_t)); 803 sizeof(PCB_t));
752} 804}
753 805
754void 806void
@@ -783,13 +835,22 @@ lpfc_mbox_get(struct lpfc_hba * phba)
783 struct lpfc_sli *psli = &phba->sli; 835 struct lpfc_sli *psli = &phba->sli;
784 836
785 list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list); 837 list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list);
786 if (mbq) { 838 if (mbq)
787 psli->mboxq_cnt--; 839 psli->mboxq_cnt--;
788 }
789 840
790 return mbq; 841 return mbq;
791} 842}
792 843
844void
845lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
846{
847 /* This function expects to be called from interupt context */
848 spin_lock(&phba->hbalock);
849 list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl);
850 spin_unlock(&phba->hbalock);
851 return;
852}
853
793int 854int
794lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) 855lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd)
795{ 856{