Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / lpfc / lpfc_els.c
index 36bf58ba750ad3d3b13770acda31f9047d5708ad..3feeb447b7409e560eed9bbac571a41352cf6406 100644 (file)
@@ -457,11 +457,9 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
        struct lpfc_hba  *phba = vport->phba;
        LPFC_MBOXQ_t *mboxq;
        struct lpfc_nodelist *ndlp;
-       struct serv_parm *sp;
        struct lpfc_dmabuf *dmabuf;
        int rc = 0;
 
-       sp = &phba->fc_fabparam;
        /* move forward in case of SLI4 FC port loopback test and pt2pt mode */
        if ((phba->sli_rev == LPFC_SLI_REV4) &&
            !(phba->link_flag & LS_LOOPBACK_MODE) &&
@@ -1028,9 +1026,11 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 stop_rr_fcf_flogi:
                /* FLOGI failure */
                lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
-                               "2858 FLOGI failure Status:x%x/x%x TMO:x%x\n",
+                               "2858 FLOGI failure Status:x%x/x%x TMO:x%x "
+                               "Data x%x x%x\n",
                                irsp->ulpStatus, irsp->un.ulpWord[4],
-                               irsp->ulpTimeout);
+                               irsp->ulpTimeout, phba->hba_flag,
+                               phba->fcf.fcf_flag);
 
                /* Check for retry */
                if (lpfc_els_retry(phba, cmdiocb, rspiocb))
@@ -1154,6 +1154,9 @@ stop_rr_fcf_flogi:
        }
 
 flogifail:
+       spin_lock_irq(&phba->hbalock);
+       phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
+       spin_unlock_irq(&phba->hbalock);
        lpfc_nlp_put(ndlp);
 
        if (!lpfc_error_lost_link(irsp)) {
@@ -1205,14 +1208,11 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        struct serv_parm *sp;
        IOCB_t *icmd;
        struct lpfc_iocbq *elsiocb;
-       struct lpfc_sli_ring *pring;
        uint8_t *pcmd;
        uint16_t cmdsize;
        uint32_t tmo;
        int rc;
 
-       pring = &phba->sli.ring[LPFC_ELS_RING];
-
        cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
        elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
                                     ndlp->nlp_DID, ELS_CMD_FLOGI);
@@ -1454,8 +1454,6 @@ lpfc_initial_fdisc(struct lpfc_vport *vport)
 void
 lpfc_more_plogi(struct lpfc_vport *vport)
 {
-       int sentplogi;
-
        if (vport->num_disc_nodes)
                vport->num_disc_nodes--;
 
@@ -1468,7 +1466,7 @@ lpfc_more_plogi(struct lpfc_vport *vport)
        /* Check to see if there are more PLOGIs to be sent */
        if (vport->fc_flag & FC_NLP_MORE)
                /* go thru NPR nodes and issue any remaining ELS PLOGIs */
-               sentplogi = lpfc_els_disc_plogi(vport);
+               lpfc_els_disc_plogi(vport);
 
        return;
 }
@@ -1956,16 +1954,12 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
 {
        struct lpfc_hba  *phba = vport->phba;
        struct serv_parm *sp;
-       IOCB_t *icmd;
        struct lpfc_nodelist *ndlp;
        struct lpfc_iocbq *elsiocb;
-       struct lpfc_sli *psli;
        uint8_t *pcmd;
        uint16_t cmdsize;
        int ret;
 
-       psli = &phba->sli;
-
        ndlp = lpfc_findnode_did(vport, did);
        if (ndlp && !NLP_CHK_NODE_ACT(ndlp))
                ndlp = NULL;
@@ -1977,7 +1971,6 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
        if (!elsiocb)
                return 1;
 
-       icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
 
        /* For PLOGI request, remainder of payload is service parameters */
@@ -2034,10 +2027,8 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        struct lpfc_vport *vport = cmdiocb->vport;
        struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
        IOCB_t *irsp;
-       struct lpfc_sli *psli;
        struct lpfc_nodelist *ndlp;
 
-       psli = &phba->sli;
        /* we pass cmdiocb to state machine which needs rspiocb as well */
        cmdiocb->context_un.rsp_iocb = rspiocb;
 
@@ -2117,7 +2108,6 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
        struct lpfc_hba *phba = vport->phba;
        PRLI *npr;
-       IOCB_t *icmd;
        struct lpfc_iocbq *elsiocb;
        uint8_t *pcmd;
        uint16_t cmdsize;
@@ -2128,7 +2118,6 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        if (!elsiocb)
                return 1;
 
-       icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
 
        /* For PRLI request, remainder of payload is service parameters */
@@ -2413,7 +2402,6 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
        struct lpfc_hba  *phba = vport->phba;
        ADISC *ap;
-       IOCB_t *icmd;
        struct lpfc_iocbq *elsiocb;
        uint8_t *pcmd;
        uint16_t cmdsize;
@@ -2424,7 +2412,6 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        if (!elsiocb)
                return 1;
 
-       icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
 
        /* For ADISC request, remainder of payload is service parameters */
@@ -2478,12 +2465,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        struct lpfc_vport *vport = ndlp->vport;
        struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
        IOCB_t *irsp;
-       struct lpfc_sli *psli;
        struct lpfcMboxq *mbox;
        unsigned long flags;
        uint32_t skip_recovery = 0;
 
-       psli = &phba->sli;
        /* we pass cmdiocb to state machine which needs rspiocb as well */
        cmdiocb->context_un.rsp_iocb = rspiocb;
 
@@ -2609,7 +2594,6 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 {
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
        struct lpfc_hba  *phba = vport->phba;
-       IOCB_t *icmd;
        struct lpfc_iocbq *elsiocb;
        uint8_t *pcmd;
        uint16_t cmdsize;
@@ -2628,7 +2612,6 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        if (!elsiocb)
                return 1;
 
-       icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
        *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
        pcmd += sizeof(uint32_t);
@@ -2742,14 +2725,11 @@ int
 lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
 {
        struct lpfc_hba  *phba = vport->phba;
-       IOCB_t *icmd;
        struct lpfc_iocbq *elsiocb;
-       struct lpfc_sli *psli;
        uint8_t *pcmd;
        uint16_t cmdsize;
        struct lpfc_nodelist *ndlp;
 
-       psli = &phba->sli;
        cmdsize = (sizeof(uint32_t) + sizeof(SCR));
 
        ndlp = lpfc_findnode_did(vport, nportid);
@@ -2776,7 +2756,6 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
                return 1;
        }
 
-       icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
 
        *((uint32_t *) (pcmd)) = ELS_CMD_SCR;
@@ -2836,9 +2815,7 @@ static int
 lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
 {
        struct lpfc_hba  *phba = vport->phba;
-       IOCB_t *icmd;
        struct lpfc_iocbq *elsiocb;
-       struct lpfc_sli *psli;
        FARP *fp;
        uint8_t *pcmd;
        uint32_t *lp;
@@ -2846,7 +2823,6 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
        struct lpfc_nodelist *ondlp;
        struct lpfc_nodelist *ndlp;
 
-       psli = &phba->sli;
        cmdsize = (sizeof(uint32_t) + sizeof(FARP));
 
        ndlp = lpfc_findnode_did(vport, nportid);
@@ -2872,7 +2848,6 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
                return 1;
        }
 
-       icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
 
        *((uint32_t *) (pcmd)) = ELS_CMD_FARPR;
@@ -3922,13 +3897,11 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
        IOCB_t *icmd;
        IOCB_t *oldcmd;
        struct lpfc_iocbq *elsiocb;
-       struct lpfc_sli *psli;
        uint8_t *pcmd;
        uint16_t cmdsize;
        int rc;
        ELS_PKT *els_pkt_ptr;
 
-       psli = &phba->sli;
        oldcmd = &oldiocb->iocb;
 
        switch (flag) {
@@ -4061,12 +4034,10 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
        IOCB_t *icmd;
        IOCB_t *oldcmd;
        struct lpfc_iocbq *elsiocb;
-       struct lpfc_sli *psli;
        uint8_t *pcmd;
        uint16_t cmdsize;
        int rc;
 
-       psli = &phba->sli;
        cmdsize = 2 * sizeof(uint32_t);
        elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
                                     ndlp->nlp_DID, ELS_CMD_LS_RJT);
@@ -4212,13 +4183,10 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
        IOCB_t *icmd;
        IOCB_t *oldcmd;
        struct lpfc_iocbq *elsiocb;
-       struct lpfc_sli *psli;
        uint8_t *pcmd;
        uint16_t cmdsize;
        int rc;
 
-       psli = &phba->sli;
-
        cmdsize = sizeof(uint32_t) + sizeof(PRLI);
        elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
                ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)));
@@ -4315,12 +4283,10 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
        RNID *rn;
        IOCB_t *icmd, *oldcmd;
        struct lpfc_iocbq *elsiocb;
-       struct lpfc_sli *psli;
        uint8_t *pcmd;
        uint16_t cmdsize;
        int rc;
 
-       psli = &phba->sli;
        cmdsize = sizeof(uint32_t) + sizeof(uint32_t)
                                        + (2 * sizeof(struct lpfc_name));
        if (format)
@@ -4447,12 +4413,10 @@ lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data,
 {
        struct lpfc_hba  *phba = vport->phba;
        struct lpfc_iocbq *elsiocb;
-       struct lpfc_sli *psli;
        uint8_t *pcmd;
        uint16_t cmdsize;
        int rc;
 
-       psli = &phba->sli;
        cmdsize = oldiocb->iocb.unsli3.rcvsli3.acc_len;
 
        /* The accumulated length can exceed the BPL_SIZE.  For
@@ -4746,6 +4710,8 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba)
 
        desc->info.port_speed.speed = cpu_to_be16(rdp_speed);
 
+       if (phba->lmt & LMT_32Gb)
+               rdp_cap |= RDP_PS_32GB;
        if (phba->lmt & LMT_16Gb)
                rdp_cap |= RDP_PS_16GB;
        if (phba->lmt & LMT_10Gb)
@@ -5181,14 +5147,12 @@ lpfc_els_rcv_lcb(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
 {
        struct lpfc_hba *phba = vport->phba;
        struct lpfc_dmabuf *pcmd;
-       IOCB_t *icmd;
        uint8_t *lp;
        struct fc_lcb_request_frame *beacon;
        struct lpfc_lcb_context *lcb_context;
        uint8_t state, rjt_err;
        struct ls_rjt stat;
 
-       icmd = &cmdiocb->iocb;
        pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
        lp = (uint8_t *)pcmd->virt;
        beacon = (struct fc_lcb_request_frame *)pcmd->virt;
@@ -5444,7 +5408,7 @@ lpfc_send_rscn_event(struct lpfc_vport *vport,
 
        fc_host_post_vendor_event(shost,
                fc_get_event_number(),
-               sizeof(struct lpfc_els_event_header) + payload_len,
+               sizeof(struct lpfc_rscn_event_header) + payload_len,
                (char *)rscn_event_data,
                LPFC_NL_VENDOR_ID);
 
@@ -5481,13 +5445,11 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
        struct lpfc_hba  *phba = vport->phba;
        struct lpfc_dmabuf *pcmd;
        uint32_t *lp, *datap;
-       IOCB_t *icmd;
        uint32_t payload_len, length, nportid, *cmd;
        int rscn_cnt;
        int rscn_id = 0, hba_id = 0;
        int i;
 
-       icmd = &cmdiocb->iocb;
        pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
        lp = (uint32_t *) pcmd->virt;
 
@@ -5893,6 +5855,13 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
                return 1;
        }
 
+       /* send our FLOGI first */
+       if (vport->port_state < LPFC_FLOGI) {
+               vport->fc_myDID = 0;
+               lpfc_initial_flogi(vport);
+               vport->fc_myDID = Fabric_DID;
+       }
+
        /* Send back ACC */
        lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
 
@@ -5943,12 +5912,10 @@ lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
 {
        struct lpfc_dmabuf *pcmd;
        uint32_t *lp;
-       IOCB_t *icmd;
        RNID *rn;
        struct ls_rjt stat;
        uint32_t cmd;
 
-       icmd = &cmdiocb->iocb;
        pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
        lp = (uint32_t *) pcmd->virt;
 
@@ -6259,7 +6226,6 @@ lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
 {
        struct lpfc_hba *phba = vport->phba;
        LPFC_MBOXQ_t *mbox;
-       struct lpfc_dmabuf *pcmd;
        struct ls_rjt stat;
 
        if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
@@ -6267,8 +6233,6 @@ lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
                /* reject the unsolicited RPS request and done with it */
                goto reject_out;
 
-       pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
-
        mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
        if (mbox) {
                lpfc_read_lnk_stat(phba, mbox);
@@ -6482,7 +6446,6 @@ lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 {
        struct lpfc_hba  *phba = vport->phba;
        struct RRQ *els_rrq;
-       IOCB_t *icmd;
        struct lpfc_iocbq *elsiocb;
        uint8_t *pcmd;
        uint16_t cmdsize;
@@ -6501,7 +6464,6 @@ lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
        if (!elsiocb)
                return 1;
 
-       icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
 
        /* For RRQ request, remainder of payload is Exchange IDs */
@@ -7374,6 +7336,15 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                         "Data: x%x x%x x%x x%x\n",
                        cmd, did, vport->port_state, vport->fc_flag,
                        vport->fc_myDID, vport->fc_prevDID);
+
+       /* reject till our FLOGI completes */
+       if ((vport->port_state < LPFC_FABRIC_CFG_LINK) &&
+               (cmd != ELS_CMD_FLOGI)) {
+               rjt_err = LSRJT_UNABLE_TPC;
+               rjt_exp = LSEXP_NOTHING_MORE;
+               goto lsrjt;
+       }
+
        switch (cmd) {
        case ELS_CMD_PLOGI:
                lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
@@ -7411,20 +7382,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                                rjt_exp = LSEXP_NOTHING_MORE;
                                break;
                        }
-                       /* We get here, and drop thru, if we are PT2PT with
-                        * another NPort and the other side has initiated
-                        * the PLOGI before responding to our FLOGI.
-                        */
-                       if (phba->sli_rev == LPFC_SLI_REV4 &&
-                           (phba->fc_topology_changed ||
-                            vport->fc_myDID != vport->fc_prevDID)) {
-                               lpfc_unregister_fcf_prep(phba);
-                               spin_lock_irq(shost->host_lock);
-                               vport->fc_flag &= ~FC_VFI_REGISTERED;
-                               spin_unlock_irq(shost->host_lock);
-                               phba->fc_topology_changed = 0;
-                               lpfc_issue_reg_vfi(vport);
-                       }
                }
 
                spin_lock_irq(shost->host_lock);
@@ -7655,6 +7612,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                break;
        }
 
+lsrjt:
        /* check if need to LS_RJT received ELS cmd */
        if (rjt_err) {
                memset(&stat, 0, sizeof(stat));
@@ -8428,7 +8386,6 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
        struct lpfc_hba  *phba = vport->phba;
-       IOCB_t *icmd;
        struct lpfc_iocbq *elsiocb;
        uint8_t *pcmd;
        uint16_t cmdsize;
@@ -8439,7 +8396,6 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        if (!elsiocb)
                return 1;
 
-       icmd = &elsiocb->iocb;
        pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
        *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
        pcmd += sizeof(uint32_t);