diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index e4cf648c951b..48610bcd6962 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -8042,8 +8042,10 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct ls_rjt stat; uint32_t *payload; uint32_t cmd, did, newnode; + uint32_t vid, flag; uint8_t rjt_exp, rjt_err = 0, init_link = 0; IOCB_t *icmd = &elsiocb->iocb; + struct serv_parm *sp; LPFC_MBOXQ_t *mbox; if (!vport || !(elsiocb->context2)) @@ -8193,6 +8195,22 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, did, vport->port_state, ndlp->nlp_flag); phba->fc_stat.elsRcvFLOGI++; + sp = (struct serv_parm *) + ((uint8_t *)payload + sizeof(uint32_t)); + + /* Check to see if this is firmware generated */ + if (sp->cmn.valid_vendor_ver_level) { + vid = be32_to_cpu(sp->un.vv.vid); + flag = be32_to_cpu(sp->un.vv.flags); + if (vid == LPFC_VV_BRCD_ID) { + /* Drop this FLOGI */ + lpfc_printf_vlog( + vport, KERN_INFO, LOG_ELS, + "3316 Dropping rcv FLOGI: " + "flag x%x\n", flag); + goto lsrjt; + } + } /* If the driver believes fabric discovery is done and is ready, * bounce the link. There is some descrepancy. @@ -8440,6 +8458,8 @@ lsrjt: * link and start over. */ if (init_link) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "3318 Resetting Link, multiple rcv FLOGIs\n"); mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) return; diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index ec1227018913..eb49c720e042 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -525,6 +525,7 @@ struct serv_parm { /* Structure is in Big Endian format */ struct { uint32_t vid; #define LPFC_VV_EMLX_ID 0x454d4c58 /* EMLX */ +#define LPFC_VV_BRCD_ID 0x42524344 /* BRCD */ uint32_t flags; #define LPFC_VV_SUPPRESS_RSP 1 } vv;