aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_mbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_mbox.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c306
1 files changed, 260 insertions, 46 deletions
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 8041c3f06f7b..8f42fbfdd29e 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -82,6 +82,22 @@ lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
82} 82}
83 83
84/**********************************************/ 84/**********************************************/
85/* lpfc_heart_beat Issue a HEART_BEAT */
86/* mailbox command */
87/**********************************************/
88void
89lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
90{
91 MAILBOX_t *mb;
92
93 mb = &pmb->mb;
94 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
95 mb->mbxCommand = MBX_HEARTBEAT;
96 mb->mbxOwner = OWN_HOST;
97 return;
98}
99
100/**********************************************/
85/* lpfc_read_la Issue a READ LA */ 101/* lpfc_read_la Issue a READ LA */
86/* mailbox command */ 102/* mailbox command */
87/**********************************************/ 103/**********************************************/
@@ -134,6 +150,7 @@ lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
134void 150void
135lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) 151lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
136{ 152{
153 struct lpfc_vport *vport = phba->pport;
137 MAILBOX_t *mb = &pmb->mb; 154 MAILBOX_t *mb = &pmb->mb;
138 memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); 155 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
139 156
@@ -147,7 +164,7 @@ lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
147 mb->un.varCfgLnk.cr_count = phba->cfg_cr_count; 164 mb->un.varCfgLnk.cr_count = phba->cfg_cr_count;
148 } 165 }
149 166
150 mb->un.varCfgLnk.myId = phba->fc_myDID; 167 mb->un.varCfgLnk.myId = vport->fc_myDID;
151 mb->un.varCfgLnk.edtov = phba->fc_edtov; 168 mb->un.varCfgLnk.edtov = phba->fc_edtov;
152 mb->un.varCfgLnk.arbtov = phba->fc_arbtov; 169 mb->un.varCfgLnk.arbtov = phba->fc_arbtov;
153 mb->un.varCfgLnk.ratov = phba->fc_ratov; 170 mb->un.varCfgLnk.ratov = phba->fc_ratov;
@@ -239,7 +256,7 @@ lpfc_init_link(struct lpfc_hba * phba,
239/* mailbox command */ 256/* mailbox command */
240/**********************************************/ 257/**********************************************/
241int 258int
242lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) 259lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
243{ 260{
244 struct lpfc_dmabuf *mp; 261 struct lpfc_dmabuf *mp;
245 MAILBOX_t *mb; 262 MAILBOX_t *mb;
@@ -270,6 +287,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
270 mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm); 287 mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
271 mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys); 288 mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
272 mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys); 289 mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
290 mb->un.varRdSparm.vpi = vpi;
273 291
274 /* save address for completion */ 292 /* save address for completion */
275 pmb->context1 = mp; 293 pmb->context1 = mp;
@@ -282,7 +300,8 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
282/* mailbox command */ 300/* mailbox command */
283/********************************************/ 301/********************************************/
284void 302void
285lpfc_unreg_did(struct lpfc_hba * phba, uint32_t did, LPFC_MBOXQ_t * pmb) 303lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
304 LPFC_MBOXQ_t * pmb)
286{ 305{
287 MAILBOX_t *mb; 306 MAILBOX_t *mb;
288 307
@@ -290,6 +309,7 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint32_t did, LPFC_MBOXQ_t * pmb)
290 memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); 309 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
291 310
292 mb->un.varUnregDID.did = did; 311 mb->un.varUnregDID.did = did;
312 mb->un.varUnregDID.vpi = vpi;
293 313
294 mb->mbxCommand = MBX_UNREG_D_ID; 314 mb->mbxCommand = MBX_UNREG_D_ID;
295 mb->mbxOwner = OWN_HOST; 315 mb->mbxOwner = OWN_HOST;
@@ -335,19 +355,17 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
335/* mailbox command */ 355/* mailbox command */
336/********************************************/ 356/********************************************/
337int 357int
338lpfc_reg_login(struct lpfc_hba * phba, 358lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
339 uint32_t did, uint8_t * param, LPFC_MBOXQ_t * pmb, uint32_t flag) 359 uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag)
340{ 360{
361 MAILBOX_t *mb = &pmb->mb;
341 uint8_t *sparam; 362 uint8_t *sparam;
342 struct lpfc_dmabuf *mp; 363 struct lpfc_dmabuf *mp;
343 MAILBOX_t *mb;
344 struct lpfc_sli *psli;
345 364
346 psli = &phba->sli;
347 mb = &pmb->mb;
348 memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); 365 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
349 366
350 mb->un.varRegLogin.rpi = 0; 367 mb->un.varRegLogin.rpi = 0;
368 mb->un.varRegLogin.vpi = vpi;
351 mb->un.varRegLogin.did = did; 369 mb->un.varRegLogin.did = did;
352 mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */ 370 mb->un.varWords[30] = flag; /* Set flag to issue action on cmpl */
353 371
@@ -359,12 +377,10 @@ lpfc_reg_login(struct lpfc_hba * phba,
359 kfree(mp); 377 kfree(mp);
360 mb->mbxCommand = MBX_REG_LOGIN64; 378 mb->mbxCommand = MBX_REG_LOGIN64;
361 /* REG_LOGIN: no buffers */ 379 /* REG_LOGIN: no buffers */
362 lpfc_printf_log(phba, 380 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
363 KERN_WARNING, 381 "%d (%d):0302 REG_LOGIN: no buffers, DID x%x, "
364 LOG_MBOX, 382 "flag x%x\n",
365 "%d:0302 REG_LOGIN: no buffers Data x%x x%x\n", 383 phba->brd_no, vpi, did, flag);
366 phba->brd_no,
367 (uint32_t) did, (uint32_t) flag);
368 return (1); 384 return (1);
369 } 385 }
370 INIT_LIST_HEAD(&mp->list); 386 INIT_LIST_HEAD(&mp->list);
@@ -389,7 +405,8 @@ lpfc_reg_login(struct lpfc_hba * phba,
389/* mailbox command */ 405/* mailbox command */
390/**********************************************/ 406/**********************************************/
391void 407void
392lpfc_unreg_login(struct lpfc_hba * phba, uint32_t rpi, LPFC_MBOXQ_t * pmb) 408lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
409 LPFC_MBOXQ_t * pmb)
393{ 410{
394 MAILBOX_t *mb; 411 MAILBOX_t *mb;
395 412
@@ -398,12 +415,52 @@ lpfc_unreg_login(struct lpfc_hba * phba, uint32_t rpi, LPFC_MBOXQ_t * pmb)
398 415
399 mb->un.varUnregLogin.rpi = (uint16_t) rpi; 416 mb->un.varUnregLogin.rpi = (uint16_t) rpi;
400 mb->un.varUnregLogin.rsvd1 = 0; 417 mb->un.varUnregLogin.rsvd1 = 0;
418 mb->un.varUnregLogin.vpi = vpi;
401 419
402 mb->mbxCommand = MBX_UNREG_LOGIN; 420 mb->mbxCommand = MBX_UNREG_LOGIN;
403 mb->mbxOwner = OWN_HOST; 421 mb->mbxOwner = OWN_HOST;
404 return; 422 return;
405} 423}
406 424
425/**************************************************/
426/* lpfc_reg_vpi Issue a REG_VPI */
427/* mailbox command */
428/**************************************************/
429void
430lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid,
431 LPFC_MBOXQ_t *pmb)
432{
433 MAILBOX_t *mb = &pmb->mb;
434
435 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
436
437 mb->un.varRegVpi.vpi = vpi;
438 mb->un.varRegVpi.sid = sid;
439
440 mb->mbxCommand = MBX_REG_VPI;
441 mb->mbxOwner = OWN_HOST;
442 return;
443
444}
445
446/**************************************************/
447/* lpfc_unreg_vpi Issue a UNREG_VNPI */
448/* mailbox command */
449/**************************************************/
450void
451lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
452{
453 MAILBOX_t *mb = &pmb->mb;
454 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
455
456 mb->un.varUnregVpi.vpi = vpi;
457
458 mb->mbxCommand = MBX_UNREG_VPI;
459 mb->mbxOwner = OWN_HOST;
460 return;
461
462}
463
407static void 464static void
408lpfc_config_pcb_setup(struct lpfc_hba * phba) 465lpfc_config_pcb_setup(struct lpfc_hba * phba)
409{ 466{
@@ -412,14 +469,18 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
412 PCB_t *pcbp = &phba->slim2p->pcb; 469 PCB_t *pcbp = &phba->slim2p->pcb;
413 dma_addr_t pdma_addr; 470 dma_addr_t pdma_addr;
414 uint32_t offset; 471 uint32_t offset;
415 uint32_t iocbCnt; 472 uint32_t iocbCnt = 0;
416 int i; 473 int i;
417 474
418 pcbp->maxRing = (psli->num_rings - 1); 475 pcbp->maxRing = (psli->num_rings - 1);
419 476
420 iocbCnt = 0;
421 for (i = 0; i < psli->num_rings; i++) { 477 for (i = 0; i < psli->num_rings; i++) {
422 pring = &psli->ring[i]; 478 pring = &psli->ring[i];
479
480 pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE:
481 SLI2_IOCB_CMD_SIZE;
482 pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE:
483 SLI2_IOCB_RSP_SIZE;
423 /* A ring MUST have both cmd and rsp entries defined to be 484 /* A ring MUST have both cmd and rsp entries defined to be
424 valid */ 485 valid */
425 if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) { 486 if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {
@@ -434,20 +495,18 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
434 continue; 495 continue;
435 } 496 }
436 /* Command ring setup for ring */ 497 /* Command ring setup for ring */
437 pring->cmdringaddr = 498 pring->cmdringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
438 (void *)&phba->slim2p->IOCBs[iocbCnt];
439 pcbp->rdsc[i].cmdEntries = pring->numCiocb; 499 pcbp->rdsc[i].cmdEntries = pring->numCiocb;
440 500
441 offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - 501 offset = (uint8_t *) &phba->slim2p->IOCBs[iocbCnt] -
442 (uint8_t *)phba->slim2p; 502 (uint8_t *) phba->slim2p;
443 pdma_addr = phba->slim2p_mapping + offset; 503 pdma_addr = phba->slim2p_mapping + offset;
444 pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr); 504 pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
445 pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr); 505 pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
446 iocbCnt += pring->numCiocb; 506 iocbCnt += pring->numCiocb;
447 507
448 /* Response ring setup for ring */ 508 /* Response ring setup for ring */
449 pring->rspringaddr = 509 pring->rspringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
450 (void *)&phba->slim2p->IOCBs[iocbCnt];
451 510
452 pcbp->rdsc[i].rspEntries = pring->numRiocb; 511 pcbp->rdsc[i].rspEntries = pring->numRiocb;
453 offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] - 512 offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
@@ -462,16 +521,108 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
462void 521void
463lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) 522lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
464{ 523{
465 MAILBOX_t *mb; 524 MAILBOX_t *mb = &pmb->mb;
466
467 mb = &pmb->mb;
468 memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); 525 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
469 mb->un.varRdRev.cv = 1; 526 mb->un.varRdRev.cv = 1;
527 mb->un.varRdRev.v3req = 1; /* Request SLI3 info */
470 mb->mbxCommand = MBX_READ_REV; 528 mb->mbxCommand = MBX_READ_REV;
471 mb->mbxOwner = OWN_HOST; 529 mb->mbxOwner = OWN_HOST;
472 return; 530 return;
473} 531}
474 532
533static void
534lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb,
535 struct lpfc_hbq_init *hbq_desc)
536{
537 hbqmb->profiles.profile2.seqlenbcnt = hbq_desc->seqlenbcnt;
538 hbqmb->profiles.profile2.maxlen = hbq_desc->maxlen;
539 hbqmb->profiles.profile2.seqlenoff = hbq_desc->seqlenoff;
540}
541
542static void
543lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb,
544 struct lpfc_hbq_init *hbq_desc)
545{
546 hbqmb->profiles.profile3.seqlenbcnt = hbq_desc->seqlenbcnt;
547 hbqmb->profiles.profile3.maxlen = hbq_desc->maxlen;
548 hbqmb->profiles.profile3.cmdcodeoff = hbq_desc->cmdcodeoff;
549 hbqmb->profiles.profile3.seqlenoff = hbq_desc->seqlenoff;
550 memcpy(&hbqmb->profiles.profile3.cmdmatch, hbq_desc->cmdmatch,
551 sizeof(hbqmb->profiles.profile3.cmdmatch));
552}
553
554static void
555lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb,
556 struct lpfc_hbq_init *hbq_desc)
557{
558 hbqmb->profiles.profile5.seqlenbcnt = hbq_desc->seqlenbcnt;
559 hbqmb->profiles.profile5.maxlen = hbq_desc->maxlen;
560 hbqmb->profiles.profile5.cmdcodeoff = hbq_desc->cmdcodeoff;
561 hbqmb->profiles.profile5.seqlenoff = hbq_desc->seqlenoff;
562 memcpy(&hbqmb->profiles.profile5.cmdmatch, hbq_desc->cmdmatch,
563 sizeof(hbqmb->profiles.profile5.cmdmatch));
564}
565
566void
567lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc,
568 uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb)
569{
570 int i;
571 MAILBOX_t *mb = &pmb->mb;
572 struct config_hbq_var *hbqmb = &mb->un.varCfgHbq;
573
574 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
575 hbqmb->entry_count = hbq_desc->entry_count; /* # entries in HBQ */
576 hbqmb->recvNotify = hbq_desc->rn; /* Receive
577 * Notification */
578 hbqmb->numMask = hbq_desc->mask_count; /* # R_CTL/TYPE masks
579 * # in words 0-19 */
580 hbqmb->profile = hbq_desc->profile; /* Selection profile:
581 * 0 = all,
582 * 7 = logentry */
583 hbqmb->ringMask = hbq_desc->ring_mask; /* Binds HBQ to a ring
584 * e.g. Ring0=b0001,
585 * ring2=b0100 */
586 hbqmb->headerLen = hbq_desc->headerLen; /* 0 if not profile 4
587 * or 5 */
588 hbqmb->logEntry = hbq_desc->logEntry; /* Set to 1 if this
589 * HBQ will be used
590 * for LogEntry
591 * buffers */
592 hbqmb->hbqaddrLow = putPaddrLow(phba->hbqslimp.phys) +
593 hbq_entry_index * sizeof(struct lpfc_hbq_entry);
594 hbqmb->hbqaddrHigh = putPaddrHigh(phba->hbqslimp.phys);
595
596 mb->mbxCommand = MBX_CONFIG_HBQ;
597 mb->mbxOwner = OWN_HOST;
598
599 /* Copy info for profiles 2,3,5. Other
600 * profiles this area is reserved
601 */
602 if (hbq_desc->profile == 2)
603 lpfc_build_hbq_profile2(hbqmb, hbq_desc);
604 else if (hbq_desc->profile == 3)
605 lpfc_build_hbq_profile3(hbqmb, hbq_desc);
606 else if (hbq_desc->profile == 5)
607 lpfc_build_hbq_profile5(hbqmb, hbq_desc);
608
609 /* Return if no rctl / type masks for this HBQ */
610 if (!hbq_desc->mask_count)
611 return;
612
613 /* Otherwise we setup specific rctl / type masks for this HBQ */
614 for (i = 0; i < hbq_desc->mask_count; i++) {
615 hbqmb->hbqMasks[i].tmatch = hbq_desc->hbqMasks[i].tmatch;
616 hbqmb->hbqMasks[i].tmask = hbq_desc->hbqMasks[i].tmask;
617 hbqmb->hbqMasks[i].rctlmatch = hbq_desc->hbqMasks[i].rctlmatch;
618 hbqmb->hbqMasks[i].rctlmask = hbq_desc->hbqMasks[i].rctlmask;
619 }
620
621 return;
622}
623
624
625
475void 626void
476lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb) 627lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
477{ 628{
@@ -514,15 +665,16 @@ lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
514} 665}
515 666
516void 667void
517lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) 668lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
518{ 669{
670 MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr;
519 MAILBOX_t *mb = &pmb->mb; 671 MAILBOX_t *mb = &pmb->mb;
520 dma_addr_t pdma_addr; 672 dma_addr_t pdma_addr;
521 uint32_t bar_low, bar_high; 673 uint32_t bar_low, bar_high;
522 size_t offset; 674 size_t offset;
523 struct lpfc_hgp hgp; 675 struct lpfc_hgp hgp;
524 void __iomem *to_slim;
525 int i; 676 int i;
677 uint32_t pgp_offset;
526 678
527 memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); 679 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
528 mb->mbxCommand = MBX_CONFIG_PORT; 680 mb->mbxCommand = MBX_CONFIG_PORT;
@@ -535,12 +687,29 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
535 mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr); 687 mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
536 mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr); 688 mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
537 689
690 /* If HBA supports SLI=3 ask for it */
691
692 if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
693 mb->un.varCfgPort.cerbm = 1; /* Request HBQs */
694 mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */
695 if (phba->max_vpi && phba->cfg_npiv_enable &&
696 phba->vpd.sli3Feat.cmv) {
697 mb->un.varCfgPort.max_vpi = phba->max_vpi;
698 mb->un.varCfgPort.cmv = 1;
699 phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
700 } else
701 mb->un.varCfgPort.max_vpi = phba->max_vpi = 0;
702 } else
703 phba->sli_rev = 2;
704 mb->un.varCfgPort.sli_mode = phba->sli_rev;
705
538 /* Now setup pcb */ 706 /* Now setup pcb */
539 phba->slim2p->pcb.type = TYPE_NATIVE_SLI2; 707 phba->slim2p->pcb.type = TYPE_NATIVE_SLI2;
540 phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2; 708 phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2;
541 709
542 /* Setup Mailbox pointers */ 710 /* Setup Mailbox pointers */
543 phba->slim2p->pcb.mailBoxSize = sizeof(MAILBOX_t); 711 phba->slim2p->pcb.mailBoxSize = offsetof(MAILBOX_t, us) +
712 sizeof(struct sli2_desc);
544 offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p; 713 offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p;
545 pdma_addr = phba->slim2p_mapping + offset; 714 pdma_addr = phba->slim2p_mapping + offset;
546 phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr); 715 phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr);
@@ -568,29 +737,70 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
568 pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low); 737 pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low);
569 pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high); 738 pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high);
570 739
740 /*
741 * Set up HGP - Port Memory
742 *
743 * The port expects the host get/put pointers to reside in memory
744 * following the "non-diagnostic" mode mailbox (32 words, 0x80 bytes)
745 * area of SLIM. In SLI-2 mode, there's an additional 16 reserved
746 * words (0x40 bytes). This area is not reserved if HBQs are
747 * configured in SLI-3.
748 *
749 * CR0Put - SLI2(no HBQs) = 0xc0, With HBQs = 0x80
750 * RR0Get 0xc4 0x84
751 * CR1Put 0xc8 0x88
752 * RR1Get 0xcc 0x8c
753 * CR2Put 0xd0 0x90
754 * RR2Get 0xd4 0x94
755 * CR3Put 0xd8 0x98
756 * RR3Get 0xdc 0x9c
757 *
758 * Reserved 0xa0-0xbf
759 * If HBQs configured:
760 * HBQ 0 Put ptr 0xc0
761 * HBQ 1 Put ptr 0xc4
762 * HBQ 2 Put ptr 0xc8
763 * ......
764 * HBQ(M-1)Put Pointer 0xc0+(M-1)*4
765 *
766 */
767
768 if (phba->sli_rev == 3) {
769 phba->host_gp = &mb_slim->us.s3.host[0];
770 phba->hbq_put = &mb_slim->us.s3.hbq_put[0];
771 } else {
772 phba->host_gp = &mb_slim->us.s2.host[0];
773 phba->hbq_put = NULL;
774 }
571 775
572 /* mask off BAR0's flag bits 0 - 3 */ 776 /* mask off BAR0's flag bits 0 - 3 */
573 phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) + 777 phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +
574 (SLIMOFF*sizeof(uint32_t)); 778 (void __iomem *) phba->host_gp -
779 (void __iomem *)phba->MBslimaddr;
575 if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64) 780 if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64)
576 phba->slim2p->pcb.hgpAddrHigh = bar_high; 781 phba->slim2p->pcb.hgpAddrHigh = bar_high;
577 else 782 else
578 phba->slim2p->pcb.hgpAddrHigh = 0; 783 phba->slim2p->pcb.hgpAddrHigh = 0;
579 /* write HGP data to SLIM at the required longword offset */ 784 /* write HGP data to SLIM at the required longword offset */
580 memset(&hgp, 0, sizeof(struct lpfc_hgp)); 785 memset(&hgp, 0, sizeof(struct lpfc_hgp));
581 to_slim = phba->MBslimaddr + (SLIMOFF*sizeof (uint32_t));
582 786
583 for (i=0; i < phba->sli.num_rings; i++) { 787 for (i=0; i < phba->sli.num_rings; i++) {
584 lpfc_memcpy_to_slim(to_slim, &hgp, sizeof(struct lpfc_hgp)); 788 lpfc_memcpy_to_slim(phba->host_gp + i, &hgp,
585 to_slim += sizeof (struct lpfc_hgp); 789 sizeof(*phba->host_gp));
586 } 790 }
587 791
588 /* Setup Port Group ring pointer */ 792 /* Setup Port Group ring pointer */
589 offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port - 793 if (phba->sli_rev == 3)
590 (uint8_t *)phba->slim2p; 794 pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s3_pgp.port -
591 pdma_addr = phba->slim2p_mapping + offset; 795 (uint8_t *)phba->slim2p;
796 else
797 pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
798 (uint8_t *)phba->slim2p;
799
800 pdma_addr = phba->slim2p_mapping + pgp_offset;
592 phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr); 801 phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr);
593 phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr); 802 phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr);
803 phba->hbq_get = &phba->slim2p->mbx.us.s3_pgp.hbq_get[0];
594 804
595 /* Use callback routine to setp rings in the pcb */ 805 /* Use callback routine to setp rings in the pcb */
596 lpfc_config_pcb_setup(phba); 806 lpfc_config_pcb_setup(phba);
@@ -606,11 +816,7 @@ lpfc_config_port(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
606 816
607 /* Swap PCB if needed */ 817 /* Swap PCB if needed */
608 lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb, 818 lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb,
609 sizeof (PCB_t)); 819 sizeof(PCB_t));
610
611 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
612 "%d:0405 Service Level Interface (SLI) 2 selected\n",
613 phba->brd_no);
614} 820}
615 821
616void 822void
@@ -644,15 +850,23 @@ lpfc_mbox_get(struct lpfc_hba * phba)
644 LPFC_MBOXQ_t *mbq = NULL; 850 LPFC_MBOXQ_t *mbq = NULL;
645 struct lpfc_sli *psli = &phba->sli; 851 struct lpfc_sli *psli = &phba->sli;
646 852
647 list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, 853 list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list);
648 list); 854 if (mbq)
649 if (mbq) {
650 psli->mboxq_cnt--; 855 psli->mboxq_cnt--;
651 }
652 856
653 return mbq; 857 return mbq;
654} 858}
655 859
860void
861lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
862{
863 /* This function expects to be called from interupt context */
864 spin_lock(&phba->hbalock);
865 list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl);
866 spin_unlock(&phba->hbalock);
867 return;
868}
869
656int 870int
657lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd) 871lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd)
658{ 872{