aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJamie Wellnitz <Jamie.Wellnitz@emulex.com>2006-02-28 19:25:15 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-02-28 19:52:50 -0500
commit7bb3b137abf2b7073e683c14cfe062d811d35247 (patch)
tree3293962805fc790ef90fd5aa28171cb419dd82c4 /drivers/scsi/lpfc
parent0228aadd0fb1d8ca90efbe74291f3b5b753c2da2 (diff)
[SCSI] lpfc 8.1.2: Handling of ELS commands RRQ, RPS, RPL and LIRR correctly
Handling of ELS commands RRQ, RPS, RPL and LIRR correctly Signed-off-by: Jamie Wellnitz <Jamie.Wellnitz@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c274
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h47
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c17
5 files changed, 309 insertions, 34 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 7a0da125aa7d..14151de23fd7 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -121,7 +121,9 @@ struct lpfc_stats {
121 uint32_t elsRcvLOGO; 121 uint32_t elsRcvLOGO;
122 uint32_t elsRcvPRLO; 122 uint32_t elsRcvPRLO;
123 uint32_t elsRcvPRLI; 123 uint32_t elsRcvPRLI;
124 uint32_t elsRcvRRQ; 124 uint32_t elsRcvLIRR;
125 uint32_t elsRcvRPS;
126 uint32_t elsRcvRPL;
125 uint32_t elsXmitFLOGI; 127 uint32_t elsXmitFLOGI;
126 uint32_t elsXmitPLOGI; 128 uint32_t elsXmitPLOGI;
127 uint32_t elsXmitPRLI; 129 uint32_t elsXmitPRLI;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index eda353b918ab..0ae49811b916 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -26,6 +26,7 @@ void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
26void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *); 26void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
27int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *); 27int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *);
28void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *); 28void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
29void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
29void lpfc_set_slim(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); 30void lpfc_set_slim(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
30int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *, 31int lpfc_reg_login(struct lpfc_hba *, uint32_t, uint8_t *, LPFC_MBOXQ_t *,
31 uint32_t); 32 uint32_t);
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 20f1a0713db2..9c9e7661de59 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -2654,41 +2654,243 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba,
2654} 2654}
2655 2655
2656static int 2656static int
2657lpfc_els_rcv_rrq(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, 2657lpfc_els_rcv_lirr(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
2658 struct lpfc_nodelist * ndlp)
2659{
2660 struct ls_rjt stat;
2661
2662 /* For now, unconditionally reject this command */
2663 stat.un.b.lsRjtRsvd0 = 0;
2664 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2665 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
2666 stat.un.b.vendorUnique = 0;
2667 lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
2668 return 0;
2669}
2670
2671void
2672lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
2673{
2674 struct lpfc_sli *psli;
2675 struct lpfc_sli_ring *pring;
2676 MAILBOX_t *mb;
2677 IOCB_t *icmd;
2678 RPS_RSP *rps_rsp;
2679 uint8_t *pcmd;
2680 struct lpfc_iocbq *elsiocb;
2681 struct lpfc_nodelist *ndlp;
2682 uint16_t xri, status;
2683 uint32_t cmdsize;
2684
2685 psli = &phba->sli;
2686 pring = &psli->ring[LPFC_ELS_RING];
2687 mb = &pmb->mb;
2688
2689 ndlp = (struct lpfc_nodelist *) pmb->context2;
2690 xri = (uint16_t) ((unsigned long)(pmb->context1));
2691 pmb->context1 = 0;
2692 pmb->context2 = 0;
2693
2694 if (mb->mbxStatus) {
2695 mempool_free( pmb, phba->mbox_mem_pool);
2696 return;
2697 }
2698
2699 cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t);
2700 mempool_free( pmb, phba->mbox_mem_pool);
2701 if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, 3,
2702 ndlp, ELS_CMD_ACC)) == 0) {
2703 return;
2704 }
2705
2706 icmd = &elsiocb->iocb;
2707 icmd->ulpContext = xri;
2708
2709 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2710 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
2711 pcmd += sizeof (uint32_t); /* Skip past command */
2712 rps_rsp = (RPS_RSP *)pcmd;
2713
2714 if (phba->fc_topology != TOPOLOGY_LOOP)
2715 status = 0x10;
2716 else
2717 status = 0x8;
2718 if (phba->fc_flag & FC_FABRIC)
2719 status |= 0x4;
2720
2721 rps_rsp->rsvd1 = 0;
2722 rps_rsp->portStatus = be16_to_cpu(status);
2723 rps_rsp->linkFailureCnt = be32_to_cpu(mb->un.varRdLnk.linkFailureCnt);
2724 rps_rsp->lossSyncCnt = be32_to_cpu(mb->un.varRdLnk.lossSyncCnt);
2725 rps_rsp->lossSignalCnt = be32_to_cpu(mb->un.varRdLnk.lossSignalCnt);
2726 rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt);
2727 rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord);
2728 rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt);
2729
2730 /* Xmit ELS RPS ACC response tag <ulpIoTag> */
2731 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
2732 "%d:0128 Xmit ELS RPS ACC response tag x%x "
2733 "Data: x%x x%x x%x x%x x%x\n",
2734 phba->brd_no,
2735 elsiocb->iocb.ulpIoTag,
2736 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2737 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2738
2739 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
2740 phba->fc_stat.elsXmitACC++;
2741 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2742 lpfc_els_free_iocb(phba, elsiocb);
2743 }
2744 return;
2745}
2746
2747static int
2748lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
2658 struct lpfc_nodelist * ndlp) 2749 struct lpfc_nodelist * ndlp)
2659{ 2750{
2660 struct lpfc_dmabuf *pcmd;
2661 uint32_t *lp; 2751 uint32_t *lp;
2752 uint8_t flag;
2753 LPFC_MBOXQ_t *mbox;
2754 struct lpfc_dmabuf *pcmd;
2755 RPS *rps;
2756 struct ls_rjt stat;
2757
2758 if((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
2759 (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
2760 stat.un.b.lsRjtRsvd0 = 0;
2761 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2762 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
2763 stat.un.b.vendorUnique = 0;
2764 lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
2765 }
2766
2767 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
2768 lp = (uint32_t *) pcmd->virt;
2769 flag = (be32_to_cpu(*lp++) & 0xf);
2770 rps = (RPS *) lp;
2771
2772 if ((flag == 0) ||
2773 ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) ||
2774 ((flag == 2) && (memcmp(&rps->un.portName, &phba->fc_portname,
2775 sizeof (struct lpfc_name)) == 0))) {
2776 if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC))) {
2777 lpfc_read_lnk_stat(phba, mbox);
2778 mbox->context1 =
2779 (void *)((unsigned long)cmdiocb->iocb.ulpContext);
2780 mbox->context2 = ndlp;
2781 mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
2782 if (lpfc_sli_issue_mbox (phba, mbox,
2783 (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) {
2784 /* Mbox completion will send ELS Response */
2785 return 0;
2786 }
2787 mempool_free(mbox, phba->mbox_mem_pool);
2788 }
2789 }
2790 stat.un.b.lsRjtRsvd0 = 0;
2791 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2792 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
2793 stat.un.b.vendorUnique = 0;
2794 lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
2795 return 0;
2796}
2797
2798int
2799lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize,
2800 struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp)
2801{
2662 IOCB_t *icmd; 2802 IOCB_t *icmd;
2803 IOCB_t *oldcmd;
2804 RPL_RSP rpl_rsp;
2805 struct lpfc_iocbq *elsiocb;
2663 struct lpfc_sli_ring *pring; 2806 struct lpfc_sli_ring *pring;
2664 struct lpfc_sli *psli; 2807 struct lpfc_sli *psli;
2665 RRQ *rrq; 2808 uint8_t *pcmd;
2666 uint32_t cmd, did;
2667 2809
2668 psli = &phba->sli; 2810 psli = &phba->sli;
2669 pring = &psli->ring[LPFC_FCP_RING]; 2811 pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
2670 icmd = &cmdiocb->iocb; 2812
2671 did = icmd->un.elsreq64.remoteID; 2813 if ((elsiocb =
2814 lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
2815 ndlp, ELS_CMD_ACC)) == 0) {
2816 return 1;
2817 }
2818 icmd = &elsiocb->iocb;
2819 oldcmd = &oldiocb->iocb;
2820 icmd->ulpContext = oldcmd->ulpContext; /* Xri */
2821
2822 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2823 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
2824 pcmd += sizeof (uint16_t);
2825 *((uint16_t *)(pcmd)) = be16_to_cpu(cmdsize);
2826 pcmd += sizeof(uint16_t);
2827
2828 /* Setup the RPL ACC payload */
2829 rpl_rsp.listLen = be32_to_cpu(1);
2830 rpl_rsp.index = 0;
2831 rpl_rsp.port_num_blk.portNum = 0;
2832 rpl_rsp.port_num_blk.portID = be32_to_cpu(phba->fc_myDID);
2833 memcpy(&rpl_rsp.port_num_blk.portName, &phba->fc_portname,
2834 sizeof(struct lpfc_name));
2835
2836 memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t));
2837
2838
2839 /* Xmit ELS RPL ACC response tag <ulpIoTag> */
2840 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
2841 "%d:0128 Xmit ELS RPL ACC response tag x%x "
2842 "Data: x%x x%x x%x x%x x%x\n",
2843 phba->brd_no,
2844 elsiocb->iocb.ulpIoTag,
2845 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
2846 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
2847
2848 elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
2849
2850 phba->fc_stat.elsXmitACC++;
2851 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2852 lpfc_els_free_iocb(phba, elsiocb);
2853 return 1;
2854 }
2855 return 0;
2856}
2857
2858static int
2859lpfc_els_rcv_rpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
2860 struct lpfc_nodelist * ndlp)
2861{
2862 struct lpfc_dmabuf *pcmd;
2863 uint32_t *lp;
2864 uint32_t maxsize;
2865 uint16_t cmdsize;
2866 RPL *rpl;
2867 struct ls_rjt stat;
2868
2869 if((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
2870 (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
2871 stat.un.b.lsRjtRsvd0 = 0;
2872 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2873 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
2874 stat.un.b.vendorUnique = 0;
2875 lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
2876 }
2877
2672 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; 2878 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
2673 lp = (uint32_t *) pcmd->virt; 2879 lp = (uint32_t *) pcmd->virt;
2880 rpl = (RPL *) (lp + 1);
2674 2881
2675 cmd = *lp++; 2882 maxsize = be32_to_cpu(rpl->maxsize);
2676 rrq = (RRQ *) lp;
2677 2883
2678 /* RRQ received */ 2884 /* We support only one port */
2679 /* Get oxid / rxid from payload and abort it */ 2885 if ((rpl->index == 0) &&
2680 spin_lock_irq(phba->host->host_lock); 2886 ((maxsize == 0) ||
2681 if ((rrq->SID == be32_to_cpu(phba->fc_myDID))) { 2887 ((maxsize * sizeof(uint32_t)) >= sizeof(RPL_RSP)))) {
2682 lpfc_sli_abort_iocb(phba, pring, 0, 0, rrq->Oxid, 2888 cmdsize = sizeof(uint32_t) + sizeof(RPL_RSP);
2683 LPFC_CTX_CTX);
2684 } else {
2685 lpfc_sli_abort_iocb(phba, pring, 0, 0, rrq->Rxid,
2686 LPFC_CTX_CTX);
2687 } 2889 }
2688 2890 else {
2689 spin_unlock_irq(phba->host->host_lock); 2891 cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t);
2690 /* ACCEPT the rrq request */ 2892 }
2691 lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); 2893 lpfc_els_rsp_rpl_acc(phba, cmdsize, cmdiocb, ndlp);
2692 2894
2693 return 0; 2895 return 0;
2694} 2896}
@@ -3201,10 +3403,6 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
3201 phba->fc_stat.elsRcvFAN++; 3403 phba->fc_stat.elsRcvFAN++;
3202 lpfc_els_rcv_fan(phba, elsiocb, ndlp); 3404 lpfc_els_rcv_fan(phba, elsiocb, ndlp);
3203 break; 3405 break;
3204 case ELS_CMD_RRQ:
3205 phba->fc_stat.elsRcvRRQ++;
3206 lpfc_els_rcv_rrq(phba, elsiocb, ndlp);
3207 break;
3208 case ELS_CMD_PRLI: 3406 case ELS_CMD_PRLI:
3209 phba->fc_stat.elsRcvPRLI++; 3407 phba->fc_stat.elsRcvPRLI++;
3210 if (phba->hba_state < LPFC_DISC_AUTH) { 3408 if (phba->hba_state < LPFC_DISC_AUTH) {
@@ -3213,9 +3411,33 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
3213 } 3411 }
3214 lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLI); 3412 lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLI);
3215 break; 3413 break;
3414 case ELS_CMD_LIRR:
3415 phba->fc_stat.elsRcvLIRR++;
3416 lpfc_els_rcv_lirr(phba, elsiocb, ndlp);
3417 if (newnode) {
3418 mempool_free( ndlp, phba->nlp_mem_pool);
3419 }
3420 break;
3421 case ELS_CMD_RPS:
3422 phba->fc_stat.elsRcvRPS++;
3423 lpfc_els_rcv_rps(phba, elsiocb, ndlp);
3424 if (newnode) {
3425 mempool_free( ndlp, phba->nlp_mem_pool);
3426 }
3427 break;
3428 case ELS_CMD_RPL:
3429 phba->fc_stat.elsRcvRPL++;
3430 lpfc_els_rcv_rpl(phba, elsiocb, ndlp);
3431 if (newnode) {
3432 mempool_free( ndlp, phba->nlp_mem_pool);
3433 }
3434 break;
3216 case ELS_CMD_RNID: 3435 case ELS_CMD_RNID:
3217 phba->fc_stat.elsRcvRNID++; 3436 phba->fc_stat.elsRcvRNID++;
3218 lpfc_els_rcv_rnid(phba, elsiocb, ndlp); 3437 lpfc_els_rcv_rnid(phba, elsiocb, ndlp);
3438 if (newnode) {
3439 mempool_free( ndlp, phba->nlp_mem_pool);
3440 }
3219 break; 3441 break;
3220 default: 3442 default:
3221 /* Unsupported ELS command, reject */ 3443 /* Unsupported ELS command, reject */
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 1ea565e0561f..e613dd07d2ad 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -454,10 +454,13 @@ struct serv_parm { /* Structure is in Big Endian format */
454#define ELS_CMD_ADISC 0x52000000 454#define ELS_CMD_ADISC 0x52000000
455#define ELS_CMD_FARP 0x54000000 455#define ELS_CMD_FARP 0x54000000
456#define ELS_CMD_FARPR 0x55000000 456#define ELS_CMD_FARPR 0x55000000
457#define ELS_CMD_RPS 0x56000000
458#define ELS_CMD_RPL 0x57000000
457#define ELS_CMD_FAN 0x60000000 459#define ELS_CMD_FAN 0x60000000
458#define ELS_CMD_RSCN 0x61040000 460#define ELS_CMD_RSCN 0x61040000
459#define ELS_CMD_SCR 0x62000000 461#define ELS_CMD_SCR 0x62000000
460#define ELS_CMD_RNID 0x78000000 462#define ELS_CMD_RNID 0x78000000
463#define ELS_CMD_LIRR 0x7A000000
461#else /* __LITTLE_ENDIAN_BITFIELD */ 464#else /* __LITTLE_ENDIAN_BITFIELD */
462#define ELS_CMD_MASK 0xffff 465#define ELS_CMD_MASK 0xffff
463#define ELS_RSP_MASK 0xff 466#define ELS_RSP_MASK 0xff
@@ -486,10 +489,13 @@ struct serv_parm { /* Structure is in Big Endian format */
486#define ELS_CMD_ADISC 0x52 489#define ELS_CMD_ADISC 0x52
487#define ELS_CMD_FARP 0x54 490#define ELS_CMD_FARP 0x54
488#define ELS_CMD_FARPR 0x55 491#define ELS_CMD_FARPR 0x55
492#define ELS_CMD_RPS 0x56
493#define ELS_CMD_RPL 0x57
489#define ELS_CMD_FAN 0x60 494#define ELS_CMD_FAN 0x60
490#define ELS_CMD_RSCN 0x0461 495#define ELS_CMD_RSCN 0x0461
491#define ELS_CMD_SCR 0x62 496#define ELS_CMD_SCR 0x62
492#define ELS_CMD_RNID 0x78 497#define ELS_CMD_RNID 0x78
498#define ELS_CMD_LIRR 0x7A
493#endif 499#endif
494 500
495/* 501/*
@@ -758,12 +764,40 @@ typedef struct _RNID { /* Structure is in Big Endian format */
758 } un; 764 } un;
759} RNID; 765} RNID;
760 766
761typedef struct _RRQ { /* Structure is in Big Endian format */ 767typedef struct _RPS { /* Structure is in Big Endian format */
762 uint32_t SID; 768 union {
763 uint16_t Oxid; 769 uint32_t portNum;
764 uint16_t Rxid; 770 struct lpfc_name portName;
765 uint8_t resv[32]; /* optional association hdr */ 771 } un;
766} RRQ; 772} RPS;
773
774typedef struct _RPS_RSP { /* Structure is in Big Endian format */
775 uint16_t rsvd1;
776 uint16_t portStatus;
777 uint32_t linkFailureCnt;
778 uint32_t lossSyncCnt;
779 uint32_t lossSignalCnt;
780 uint32_t primSeqErrCnt;
781 uint32_t invalidXmitWord;
782 uint32_t crcCnt;
783} RPS_RSP;
784
785typedef struct _RPL { /* Structure is in Big Endian format */
786 uint32_t maxsize;
787 uint32_t index;
788} RPL;
789
790typedef struct _PORT_NUM_BLK {
791 uint32_t portNum;
792 uint32_t portID;
793 struct lpfc_name portName;
794} PORT_NUM_BLK;
795
796typedef struct _RPL_RSP { /* Structure is in Big Endian format */
797 uint32_t listLen;
798 uint32_t index;
799 PORT_NUM_BLK port_num_blk;
800} RPL_RSP;
767 801
768/* This is used for RSCN command */ 802/* This is used for RSCN command */
769typedef struct _D_ID { /* Structure is in Big Endian format */ 803typedef struct _D_ID { /* Structure is in Big Endian format */
@@ -804,7 +838,6 @@ typedef struct _ELS_PKT { /* Structure is in Big Endian format */
804 FARP farp; /* Payload for FARP/ACC */ 838 FARP farp; /* Payload for FARP/ACC */
805 FAN fan; /* Payload for FAN */ 839 FAN fan; /* Payload for FAN */
806 SCR scr; /* Payload for SCR/ACC */ 840 SCR scr; /* Payload for SCR/ACC */
807 RRQ rrq; /* Payload for RRQ */
808 RNID rnid; /* Payload for RNID */ 841 RNID rnid; /* Payload for RNID */
809 uint8_t pad[128 - 4]; /* Pad out to payload of 128 bytes */ 842 uint8_t pad[128 - 4]; /* Pad out to payload of 128 bytes */
810 } un; 843 } un;
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index e3bc8d3f7302..6c4b21a32c7f 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -336,6 +336,23 @@ lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
336 return; 336 return;
337} 337}
338 338
339/*************************************************/
340/* lpfc_read_lnk_stat Issue a READ LINK STATUS */
341/* mailbox command */
342/*************************************************/
343void
344lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
345{
346 MAILBOX_t *mb;
347
348 mb = &pmb->mb;
349 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
350
351 mb->mbxCommand = MBX_READ_LNK_STAT;
352 mb->mbxOwner = OWN_HOST;
353 return;
354}
355
339/********************************************/ 356/********************************************/
340/* lpfc_reg_login Issue a REG_LOGIN */ 357/* lpfc_reg_login Issue a REG_LOGIN */
341/* mailbox command */ 358/* mailbox command */