Commit c868595d authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.3.6 : FCoE Protocol Fixes

FCoE Protocol fixes.
 - Fixed FIP frame designation for ELS commands.
 - Fix CVL received on Port 1 not processed by driver.
 - Fix Zeroed frame on wire after FLOGI
 - Fix vport keep-alive does not contain the correct WWN.
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 832151f4
...@@ -290,8 +290,8 @@ struct lpfc_vport { ...@@ -290,8 +290,8 @@ struct lpfc_vport {
uint16_t vpi; uint16_t vpi;
uint16_t vfi; uint16_t vfi;
uint8_t vfi_state; uint8_t vpi_state;
#define LPFC_VFI_REGISTERED 0x1 #define LPFC_VPI_REGISTERED 0x1
uint32_t fc_flag; /* FC flags */ uint32_t fc_flag; /* FC flags */
/* Several of these flags are HBA centric and should be moved to /* Several of these flags are HBA centric and should be moved to
......
...@@ -177,9 +177,22 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, ...@@ -177,9 +177,22 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
((elscmd == ELS_CMD_FLOGI) || ((elscmd == ELS_CMD_FLOGI) ||
(elscmd == ELS_CMD_FDISC) || (elscmd == ELS_CMD_FDISC) ||
(elscmd == ELS_CMD_LOGO))) (elscmd == ELS_CMD_LOGO)))
elsiocb->iocb_flag |= LPFC_FIP_ELS; switch (elscmd) {
case ELS_CMD_FLOGI:
elsiocb->iocb_flag |= ((ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT)
& LPFC_FIP_ELS_ID_MASK);
break;
case ELS_CMD_FDISC:
elsiocb->iocb_flag |= ((ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT)
& LPFC_FIP_ELS_ID_MASK);
break;
case ELS_CMD_LOGO:
elsiocb->iocb_flag |= ((ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT)
& LPFC_FIP_ELS_ID_MASK);
break;
}
else else
elsiocb->iocb_flag &= ~LPFC_FIP_ELS; elsiocb->iocb_flag &= ~LPFC_FIP_ELS_ID_MASK;
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
...@@ -591,7 +604,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -591,7 +604,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
} else { } else {
ndlp->nlp_type |= NLP_FABRIC; ndlp->nlp_type |= NLP_FABRIC;
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
if (vport->vfi_state & LPFC_VFI_REGISTERED) { if (vport->vpi_state & LPFC_VPI_REGISTERED) {
lpfc_start_fdiscs(phba); lpfc_start_fdiscs(phba);
lpfc_do_scr_ns_plogi(phba, vport); lpfc_do_scr_ns_plogi(phba, vport);
} else } else
...@@ -5401,7 +5414,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -5401,7 +5414,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
if (lpfc_els_chk_latt(vport)) if (lpfc_els_chk_latt(vport))
goto dropit; goto dropit;
/* Ignore traffic recevied during vport shutdown. */ /* Ignore traffic received during vport shutdown. */
if (vport->load_flag & FC_UNLOADING) if (vport->load_flag & FC_UNLOADING)
goto dropit; goto dropit;
......
...@@ -1798,8 +1798,8 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) ...@@ -1798,8 +1798,8 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_vport_set_state(vport, FC_VPORT_FAILED);
goto fail_free_mem; goto fail_free_mem;
} }
/* Mark the vport has registered with its VFI */ /* The VPI is implicitly registered when the VFI is registered */
vport->vfi_state |= LPFC_VFI_REGISTERED; vport->vpi_state |= LPFC_VPI_REGISTERED;
if (vport->port_state == LPFC_FABRIC_CFG_LINK) { if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
lpfc_start_fdiscs(phba); lpfc_start_fdiscs(phba);
...@@ -2257,6 +2257,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -2257,6 +2257,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
mb->mbxStatus); mb->mbxStatus);
break; break;
} }
vport->vpi_state &= ~LPFC_VPI_REGISTERED;
vport->unreg_vpi_cmpl = VPORT_OK; vport->unreg_vpi_cmpl = VPORT_OK;
mempool_free(pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
/* /*
...@@ -2314,6 +2315,7 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -2314,6 +2315,7 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
goto out; goto out;
} }
vport->vpi_state |= LPFC_VPI_REGISTERED;
vport->num_disc_nodes = 0; vport->num_disc_nodes = 0;
/* go thru NPR list and issue ELS PLOGIs */ /* go thru NPR list and issue ELS PLOGIs */
if (vport->fc_npr_cnt) if (vport->fc_npr_cnt)
...@@ -4464,7 +4466,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) ...@@ -4464,7 +4466,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
lpfc_mbx_unreg_vpi(vports[i]); lpfc_mbx_unreg_vpi(vports[i]);
vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
vports[i]->vfi_state &= ~LPFC_VFI_REGISTERED; vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
} }
lpfc_destroy_vport_work_array(phba, vports); lpfc_destroy_vport_work_array(phba, vports);
......
...@@ -2293,8 +2293,7 @@ typedef struct { ...@@ -2293,8 +2293,7 @@ typedef struct {
uint32_t rsvd1; uint32_t rsvd1;
uint32_t rsvd2:8; uint32_t rsvd2:8;
uint32_t sid:24; uint32_t sid:24;
uint32_t rsvd3; uint32_t wwn[2];
uint32_t rsvd4;
uint32_t rsvd5; uint32_t rsvd5;
uint16_t vfi; uint16_t vfi;
uint16_t vpi; uint16_t vpi;
...@@ -2302,8 +2301,7 @@ typedef struct { ...@@ -2302,8 +2301,7 @@ typedef struct {
uint32_t rsvd1; uint32_t rsvd1;
uint32_t sid:24; uint32_t sid:24;
uint32_t rsvd2:8; uint32_t rsvd2:8;
uint32_t rsvd3; uint32_t wwn[2];
uint32_t rsvd4;
uint32_t rsvd5; uint32_t rsvd5;
uint16_t vpi; uint16_t vpi;
uint16_t vfi; uint16_t vfi;
......
...@@ -453,6 +453,13 @@ struct lpfc_wqe_generic{ ...@@ -453,6 +453,13 @@ struct lpfc_wqe_generic{
#define lpfc_wqe_gen_wqec_SHIFT 7 #define lpfc_wqe_gen_wqec_SHIFT 7
#define lpfc_wqe_gen_wqec_MASK 0x00000001 #define lpfc_wqe_gen_wqec_MASK 0x00000001
#define lpfc_wqe_gen_wqec_WORD word11 #define lpfc_wqe_gen_wqec_WORD word11
#define ELS_ID_FLOGI 3
#define ELS_ID_FDISC 2
#define ELS_ID_LOGO 1
#define ELS_ID_DEFAULT 0
#define lpfc_wqe_gen_els_id_SHIFT 4
#define lpfc_wqe_gen_els_id_MASK 0x00000003
#define lpfc_wqe_gen_els_id_WORD word11
#define lpfc_wqe_gen_cmd_type_SHIFT 0 #define lpfc_wqe_gen_cmd_type_SHIFT 0
#define lpfc_wqe_gen_cmd_type_MASK 0x0000000F #define lpfc_wqe_gen_cmd_type_MASK 0x0000000F
#define lpfc_wqe_gen_cmd_type_WORD word11 #define lpfc_wqe_gen_cmd_type_WORD word11
...@@ -1395,8 +1402,7 @@ struct lpfc_mbx_reg_vfi { ...@@ -1395,8 +1402,7 @@ struct lpfc_mbx_reg_vfi {
#define lpfc_reg_vfi_fcfi_SHIFT 0 #define lpfc_reg_vfi_fcfi_SHIFT 0
#define lpfc_reg_vfi_fcfi_MASK 0x0000FFFF #define lpfc_reg_vfi_fcfi_MASK 0x0000FFFF
#define lpfc_reg_vfi_fcfi_WORD word2 #define lpfc_reg_vfi_fcfi_WORD word2
uint32_t word3_rsvd; uint32_t wwn[2];
uint32_t word4_rsvd;
struct ulp_bde64 bde; struct ulp_bde64 bde;
uint32_t word8_rsvd; uint32_t word8_rsvd;
uint32_t word9_rsvd; uint32_t word9_rsvd;
......
...@@ -2229,7 +2229,7 @@ lpfc_offline_prep(struct lpfc_hba * phba) ...@@ -2229,7 +2229,7 @@ lpfc_offline_prep(struct lpfc_hba * phba)
if (vports[i]->load_flag & FC_UNLOADING) if (vports[i]->load_flag & FC_UNLOADING)
continue; continue;
vports[i]->vfi_state &= ~LPFC_VFI_REGISTERED; vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
shost = lpfc_shost_from_vport(vports[i]); shost = lpfc_shost_from_vport(vports[i]);
list_for_each_entry_safe(ndlp, next_ndlp, list_for_each_entry_safe(ndlp, next_ndlp,
&vports[i]->fc_nodes, &vports[i]->fc_nodes,
...@@ -3047,7 +3047,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, ...@@ -3047,7 +3047,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
"2718 Clear Virtual Link Received for VPI 0x%x" "2718 Clear Virtual Link Received for VPI 0x%x"
" tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag); " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
vport = lpfc_find_vport_by_vpid(phba, vport = lpfc_find_vport_by_vpid(phba,
acqe_fcoe->index /*- phba->vpi_base*/); acqe_fcoe->index - phba->vpi_base);
if (!vport) if (!vport)
break; break;
ndlp = lpfc_findnode_did(vport, Fabric_DID); ndlp = lpfc_findnode_did(vport, Fabric_DID);
......
...@@ -820,6 +820,10 @@ lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb) ...@@ -820,6 +820,10 @@ lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb)
mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base; mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base;
mb->un.varRegVpi.sid = vport->fc_myDID; mb->un.varRegVpi.sid = vport->fc_myDID;
mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base; mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
memcpy(mb->un.varRegVpi.wwn, &vport->fc_portname,
sizeof(struct lpfc_name));
mb->un.varRegVpi.wwn[0] = cpu_to_le32(mb->un.varRegVpi.wwn[0]);
mb->un.varRegVpi.wwn[1] = cpu_to_le32(mb->un.varRegVpi.wwn[1]);
mb->mbxCommand = MBX_REG_VPI; mb->mbxCommand = MBX_REG_VPI;
mb->mbxOwner = OWN_HOST; mb->mbxOwner = OWN_HOST;
...@@ -1818,6 +1822,9 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys) ...@@ -1818,6 +1822,9 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys)
bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base); bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base);
bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi); bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi);
bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base); bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base);
memcpy(reg_vfi->wwn, &vport->fc_portname, sizeof(struct lpfc_name));
reg_vfi->wwn[0] = cpu_to_le32(reg_vfi->wwn[0]);
reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]);
reg_vfi->bde.addrHigh = putPaddrHigh(phys); reg_vfi->bde.addrHigh = putPaddrHigh(phys);
reg_vfi->bde.addrLow = putPaddrLow(phys); reg_vfi->bde.addrLow = putPaddrLow(phys);
reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam); reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
......
...@@ -5756,12 +5756,13 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, ...@@ -5756,12 +5756,13 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
uint8_t cmnd; uint8_t cmnd;
uint16_t xritag; uint16_t xritag;
struct ulp_bde64 *bpl = NULL; struct ulp_bde64 *bpl = NULL;
uint32_t els_id = ELS_ID_DEFAULT;
fip = phba->hba_flag & HBA_FIP_SUPPORT; fip = phba->hba_flag & HBA_FIP_SUPPORT;
/* The fcp commands will set command type */ /* The fcp commands will set command type */
if (iocbq->iocb_flag & LPFC_IO_FCP) if (iocbq->iocb_flag & LPFC_IO_FCP)
command_type = FCP_COMMAND; command_type = FCP_COMMAND;
else if (fip && (iocbq->iocb_flag & LPFC_FIP_ELS)) else if (fip && (iocbq->iocb_flag & LPFC_FIP_ELS_ID_MASK))
command_type = ELS_COMMAND_FIP; command_type = ELS_COMMAND_FIP;
else else
command_type = ELS_COMMAND_NON_FIP; command_type = ELS_COMMAND_NON_FIP;
...@@ -5822,6 +5823,13 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, ...@@ -5822,6 +5823,13 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
bf_set(lpfc_wqe_gen_ct, &wqe->generic, ct); bf_set(lpfc_wqe_gen_ct, &wqe->generic, ct);
bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0); bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0);
/* CCP CCPE PV PRI in word10 were set in the memcpy */ /* CCP CCPE PV PRI in word10 were set in the memcpy */
if (command_type == ELS_COMMAND_FIP) {
els_id = ((iocbq->iocb_flag & LPFC_FIP_ELS_ID_MASK)
>> LPFC_FIP_ELS_ID_SHIFT);
}
bf_set(lpfc_wqe_gen_els_id, &wqe->generic, els_id);
break; break;
case CMD_XMIT_SEQUENCE64_CR: case CMD_XMIT_SEQUENCE64_CR:
/* word3 iocb=io_tag32 wqe=payload_offset */ /* word3 iocb=io_tag32 wqe=payload_offset */
...@@ -11282,7 +11290,7 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, ...@@ -11282,7 +11290,7 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
} }
fcfi = bf_get(lpfc_rcqe_fcf_id, &dmabuf->cq_event.cqe.rcqe_cmpl); fcfi = bf_get(lpfc_rcqe_fcf_id, &dmabuf->cq_event.cqe.rcqe_cmpl);
vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi); vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
if (!vport) { if (!vport || !(vport->vpi_state & LPFC_VPI_REGISTERED)) {
/* throw out the frame */ /* throw out the frame */
lpfc_in_buf_free(phba, &dmabuf->dbuf); lpfc_in_buf_free(phba, &dmabuf->dbuf);
return; return;
......
...@@ -60,7 +60,8 @@ struct lpfc_iocbq { ...@@ -60,7 +60,8 @@ struct lpfc_iocbq {
#define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */ #define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */
#define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */ #define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */
#define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */ #define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */
#define LPFC_FIP_ELS 0x40 #define LPFC_FIP_ELS_ID_MASK 0xc0 /* ELS_ID range 0-3 */
#define LPFC_FIP_ELS_ID_SHIFT 6
uint8_t abort_count; uint8_t abort_count;
uint8_t rsvd2; uint8_t rsvd2;
......
...@@ -389,7 +389,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) ...@@ -389,7 +389,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
* by the port. * by the port.
*/ */
if ((phba->sli_rev == LPFC_SLI_REV4) && if ((phba->sli_rev == LPFC_SLI_REV4) &&
(pport->vfi_state & LPFC_VFI_REGISTERED)) { (pport->vpi_state & LPFC_VPI_REGISTERED)) {
rc = lpfc_sli4_init_vpi(phba, vpi); rc = lpfc_sli4_init_vpi(phba, vpi);
if (rc) { if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment