diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-10-20 00:10:27 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-10-20 00:10:27 -0300 |
commit | d0b2f91bede3bd5e3d24dd6803e56eee959c1797 (patch) | |
tree | 7fee4ab0509879c373c4f2cbd5b8a5be5b4041ee /drivers/scsi/lpfc/lpfc_els.c | |
parent | e914f8eb445e8f74b00303c19c2ffceaedd16a05 (diff) |
Linux-libre 4.8.2-gnupck-4.8.2-gnu
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 290 |
1 files changed, 191 insertions, 99 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 0498f5760..c0af32f24 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -594,6 +594,7 @@ static uint8_t lpfc_check_clean_addr_bit(struct lpfc_vport *vport, struct serv_parm *sp) { + struct lpfc_hba *phba = vport->phba; uint8_t fabric_param_changed = 0; struct Scsi_Host *shost = lpfc_shost_from_vport(vport); @@ -615,7 +616,7 @@ lpfc_check_clean_addr_bit(struct lpfc_vport *vport, * - lpfc_delay_discovery module parameter is set. */ if (fabric_param_changed && !sp->cmn.clean_address_bit && - (vport->fc_prevDID || lpfc_delay_discovery)) { + (vport->fc_prevDID || phba->cfg_delay_discovery)) { spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_DISC_DELAYED; spin_unlock_irq(shost->host_lock); @@ -3299,6 +3300,12 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, FC_VPORT_FABRIC_REJ_WWN); } break; + case LSRJT_VENDOR_UNIQUE: + if ((stat.un.b.vendorUnique == 0x45) && + (cmd == ELS_CMD_FLOGI)) { + goto out_retry; + } + break; } break; @@ -3344,6 +3351,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if ((vport->load_flag & FC_UNLOADING) != 0) retry = 0; +out_retry: if (retry) { if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_FDISC)) { /* Stop retrying PLOGI and FDISC if in FCF discovery */ @@ -4609,7 +4617,7 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport) return sentplogi; } -void +uint32_t lpfc_rdp_res_link_service(struct fc_rdp_link_service_desc *desc, uint32_t word0) { @@ -4617,9 +4625,11 @@ lpfc_rdp_res_link_service(struct fc_rdp_link_service_desc *desc, desc->tag = cpu_to_be32(RDP_LINK_SERVICE_DESC_TAG); desc->payload.els_req = word0; desc->length = cpu_to_be32(sizeof(desc->payload)); + + return sizeof(struct fc_rdp_link_service_desc); } -void +uint32_t lpfc_rdp_res_sfp_desc(struct fc_rdp_sfp_desc *desc, uint8_t *page_a0, uint8_t *page_a2) { @@ -4680,9 +4690,11 @@ lpfc_rdp_res_sfp_desc(struct fc_rdp_sfp_desc *desc, desc->sfp_info.flags = cpu_to_be16(flag); desc->length = cpu_to_be32(sizeof(desc->sfp_info)); + + return sizeof(struct fc_rdp_sfp_desc); } -void +uint32_t lpfc_rdp_res_link_error(struct fc_rdp_link_error_status_desc *desc, READ_LNK_VAR *stat) { @@ -4707,134 +4719,181 @@ lpfc_rdp_res_link_error(struct fc_rdp_link_error_status_desc *desc, desc->info.link_status.invalid_crc_cnt = cpu_to_be32(stat->crcCnt); desc->length = cpu_to_be32(sizeof(desc->info)); + + return sizeof(struct fc_rdp_link_error_status_desc); } -void +uint32_t lpfc_rdp_res_bbc_desc(struct fc_rdp_bbc_desc *desc, READ_LNK_VAR *stat, struct lpfc_vport *vport) { + uint32_t bbCredit; + desc->tag = cpu_to_be32(RDP_BBC_DESC_TAG); - desc->bbc_info.port_bbc = cpu_to_be32( - vport->fc_sparam.cmn.bbCreditMsb | - vport->fc_sparam.cmn.bbCreditlsb << 8); - if (vport->phba->fc_topology != LPFC_TOPOLOGY_LOOP) - desc->bbc_info.attached_port_bbc = cpu_to_be32( - vport->phba->fc_fabparam.cmn.bbCreditMsb | - vport->phba->fc_fabparam.cmn.bbCreditlsb << 8); - else + bbCredit = vport->fc_sparam.cmn.bbCreditLsb | + (vport->fc_sparam.cmn.bbCreditMsb << 8); + desc->bbc_info.port_bbc = cpu_to_be32(bbCredit); + if (vport->phba->fc_topology != LPFC_TOPOLOGY_LOOP) { + bbCredit = vport->phba->fc_fabparam.cmn.bbCreditLsb | + (vport->phba->fc_fabparam.cmn.bbCreditMsb << 8); + desc->bbc_info.attached_port_bbc = cpu_to_be32(bbCredit); + } else { desc->bbc_info.attached_port_bbc = 0; + } desc->bbc_info.rtt = 0; desc->length = cpu_to_be32(sizeof(desc->bbc_info)); + + return sizeof(struct fc_rdp_bbc_desc); } -void -lpfc_rdp_res_oed_temp_desc(struct fc_rdp_oed_sfp_desc *desc, uint8_t *page_a2) +uint32_t +lpfc_rdp_res_oed_temp_desc(struct lpfc_hba *phba, + struct fc_rdp_oed_sfp_desc *desc, uint8_t *page_a2) { - uint32_t flags; + uint32_t flags = 0; desc->tag = cpu_to_be32(RDP_OED_DESC_TAG); - desc->oed_info.hi_alarm = - cpu_to_be16(page_a2[SSF_TEMP_HIGH_ALARM]); - desc->oed_info.lo_alarm = cpu_to_be16(page_a2[SSF_TEMP_LOW_ALARM]); - desc->oed_info.hi_warning = - cpu_to_be16(page_a2[SSF_TEMP_HIGH_WARNING]); - desc->oed_info.lo_warning = - cpu_to_be16(page_a2[SSF_TEMP_LOW_WARNING]); - flags = 0xf; /* All four are valid */ + desc->oed_info.hi_alarm = page_a2[SSF_TEMP_HIGH_ALARM]; + desc->oed_info.lo_alarm = page_a2[SSF_TEMP_LOW_ALARM]; + desc->oed_info.hi_warning = page_a2[SSF_TEMP_HIGH_WARNING]; + desc->oed_info.lo_warning = page_a2[SSF_TEMP_LOW_WARNING]; + + if (phba->sfp_alarm & LPFC_TRANSGRESSION_HIGH_TEMPERATURE) + flags |= RDP_OET_HIGH_ALARM; + if (phba->sfp_alarm & LPFC_TRANSGRESSION_LOW_TEMPERATURE) + flags |= RDP_OET_LOW_ALARM; + if (phba->sfp_warning & LPFC_TRANSGRESSION_HIGH_TEMPERATURE) + flags |= RDP_OET_HIGH_WARNING; + if (phba->sfp_warning & LPFC_TRANSGRESSION_LOW_TEMPERATURE) + flags |= RDP_OET_LOW_WARNING; + flags |= ((0xf & RDP_OED_TEMPERATURE) << RDP_OED_TYPE_SHIFT); desc->oed_info.function_flags = cpu_to_be32(flags); desc->length = cpu_to_be32(sizeof(desc->oed_info)); + return sizeof(struct fc_rdp_oed_sfp_desc); } -void -lpfc_rdp_res_oed_voltage_desc(struct fc_rdp_oed_sfp_desc *desc, +uint32_t +lpfc_rdp_res_oed_voltage_desc(struct lpfc_hba *phba, + struct fc_rdp_oed_sfp_desc *desc, uint8_t *page_a2) { - uint32_t flags; + uint32_t flags = 0; desc->tag = cpu_to_be32(RDP_OED_DESC_TAG); - desc->oed_info.hi_alarm = - cpu_to_be16(page_a2[SSF_VOLTAGE_HIGH_ALARM]); - desc->oed_info.lo_alarm = cpu_to_be16(page_a2[SSF_VOLTAGE_LOW_ALARM]); - desc->oed_info.hi_warning = - cpu_to_be16(page_a2[SSF_VOLTAGE_HIGH_WARNING]); - desc->oed_info.lo_warning = - cpu_to_be16(page_a2[SSF_VOLTAGE_LOW_WARNING]); - flags = 0xf; /* All four are valid */ + desc->oed_info.hi_alarm = page_a2[SSF_VOLTAGE_HIGH_ALARM]; + desc->oed_info.lo_alarm = page_a2[SSF_VOLTAGE_LOW_ALARM]; + desc->oed_info.hi_warning = page_a2[SSF_VOLTAGE_HIGH_WARNING]; + desc->oed_info.lo_warning = page_a2[SSF_VOLTAGE_LOW_WARNING]; + + if (phba->sfp_alarm & LPFC_TRANSGRESSION_HIGH_VOLTAGE) + flags |= RDP_OET_HIGH_ALARM; + if (phba->sfp_alarm & LPFC_TRANSGRESSION_LOW_VOLTAGE) + flags |= RDP_OET_LOW_ALARM; + if (phba->sfp_warning & LPFC_TRANSGRESSION_HIGH_VOLTAGE) + flags |= RDP_OET_HIGH_WARNING; + if (phba->sfp_warning & LPFC_TRANSGRESSION_LOW_VOLTAGE) + flags |= RDP_OET_LOW_WARNING; + flags |= ((0xf & RDP_OED_VOLTAGE) << RDP_OED_TYPE_SHIFT); desc->oed_info.function_flags = cpu_to_be32(flags); desc->length = cpu_to_be32(sizeof(desc->oed_info)); + return sizeof(struct fc_rdp_oed_sfp_desc); } -void -lpfc_rdp_res_oed_txbias_desc(struct fc_rdp_oed_sfp_desc *desc, +uint32_t +lpfc_rdp_res_oed_txbias_desc(struct lpfc_hba *phba, + struct fc_rdp_oed_sfp_desc *desc, uint8_t *page_a2) { - uint32_t flags; + uint32_t flags = 0; desc->tag = cpu_to_be32(RDP_OED_DESC_TAG); - desc->oed_info.hi_alarm = - cpu_to_be16(page_a2[SSF_BIAS_HIGH_ALARM]); - desc->oed_info.lo_alarm = cpu_to_be16(page_a2[SSF_BIAS_LOW_ALARM]); - desc->oed_info.hi_warning = - cpu_to_be16(page_a2[SSF_BIAS_HIGH_WARNING]); - desc->oed_info.lo_warning = - cpu_to_be16(page_a2[SSF_BIAS_LOW_WARNING]); - flags = 0xf; /* All four are valid */ + desc->oed_info.hi_alarm = page_a2[SSF_BIAS_HIGH_ALARM]; + desc->oed_info.lo_alarm = page_a2[SSF_BIAS_LOW_ALARM]; + desc->oed_info.hi_warning = page_a2[SSF_BIAS_HIGH_WARNING]; + desc->oed_info.lo_warning = page_a2[SSF_BIAS_LOW_WARNING]; + + if (phba->sfp_alarm & LPFC_TRANSGRESSION_HIGH_TXBIAS) + flags |= RDP_OET_HIGH_ALARM; + if (phba->sfp_alarm & LPFC_TRANSGRESSION_LOW_TXBIAS) + flags |= RDP_OET_LOW_ALARM; + if (phba->sfp_warning & LPFC_TRANSGRESSION_HIGH_TXBIAS) + flags |= RDP_OET_HIGH_WARNING; + if (phba->sfp_warning & LPFC_TRANSGRESSION_LOW_TXBIAS) + flags |= RDP_OET_LOW_WARNING; + flags |= ((0xf & RDP_OED_TXBIAS) << RDP_OED_TYPE_SHIFT); desc->oed_info.function_flags = cpu_to_be32(flags); desc->length = cpu_to_be32(sizeof(desc->oed_info)); + return sizeof(struct fc_rdp_oed_sfp_desc); } -void -lpfc_rdp_res_oed_txpower_desc(struct fc_rdp_oed_sfp_desc *desc, +uint32_t +lpfc_rdp_res_oed_txpower_desc(struct lpfc_hba *phba, + struct fc_rdp_oed_sfp_desc *desc, uint8_t *page_a2) { - uint32_t flags; + uint32_t flags = 0; desc->tag = cpu_to_be32(RDP_OED_DESC_TAG); - desc->oed_info.hi_alarm = - cpu_to_be16(page_a2[SSF_TXPOWER_HIGH_ALARM]); - desc->oed_info.lo_alarm = cpu_to_be16(page_a2[SSF_TXPOWER_LOW_ALARM]); - desc->oed_info.hi_warning = - cpu_to_be16(page_a2[SSF_TXPOWER_HIGH_WARNING]); - desc->oed_info.lo_warning = - cpu_to_be16(page_a2[SSF_TXPOWER_LOW_WARNING]); - flags = 0xf; /* All four are valid */ + desc->oed_info.hi_alarm = page_a2[SSF_TXPOWER_HIGH_ALARM]; + desc->oed_info.lo_alarm = page_a2[SSF_TXPOWER_LOW_ALARM]; + desc->oed_info.hi_warning = page_a2[SSF_TXPOWER_HIGH_WARNING]; + desc->oed_info.lo_warning = page_a2[SSF_TXPOWER_LOW_WARNING]; + + if (phba->sfp_alarm & LPFC_TRANSGRESSION_HIGH_TXPOWER) + flags |= RDP_OET_HIGH_ALARM; + if (phba->sfp_alarm & LPFC_TRANSGRESSION_LOW_TXPOWER) + flags |= RDP_OET_LOW_ALARM; + if (phba->sfp_warning & LPFC_TRANSGRESSION_HIGH_TXPOWER) + flags |= RDP_OET_HIGH_WARNING; + if (phba->sfp_warning & LPFC_TRANSGRESSION_LOW_TXPOWER) + flags |= RDP_OET_LOW_WARNING; + flags |= ((0xf & RDP_OED_TXPOWER) << RDP_OED_TYPE_SHIFT); desc->oed_info.function_flags = cpu_to_be32(flags); desc->length = cpu_to_be32(sizeof(desc->oed_info)); + return sizeof(struct fc_rdp_oed_sfp_desc); } -void -lpfc_rdp_res_oed_rxpower_desc(struct fc_rdp_oed_sfp_desc *desc, +uint32_t +lpfc_rdp_res_oed_rxpower_desc(struct lpfc_hba *phba, + struct fc_rdp_oed_sfp_desc *desc, uint8_t *page_a2) { - uint32_t flags; + uint32_t flags = 0; desc->tag = cpu_to_be32(RDP_OED_DESC_TAG); - desc->oed_info.hi_alarm = - cpu_to_be16(page_a2[SSF_RXPOWER_HIGH_ALARM]); - desc->oed_info.lo_alarm = cpu_to_be16(page_a2[SSF_RXPOWER_LOW_ALARM]); - desc->oed_info.hi_warning = - cpu_to_be16(page_a2[SSF_RXPOWER_HIGH_WARNING]); - desc->oed_info.lo_warning = - cpu_to_be16(page_a2[SSF_RXPOWER_LOW_WARNING]); - flags = 0xf; /* All four are valid */ + desc->oed_info.hi_alarm = page_a2[SSF_RXPOWER_HIGH_ALARM]; + desc->oed_info.lo_alarm = page_a2[SSF_RXPOWER_LOW_ALARM]; + desc->oed_info.hi_warning = page_a2[SSF_RXPOWER_HIGH_WARNING]; + desc->oed_info.lo_warning = page_a2[SSF_RXPOWER_LOW_WARNING]; + + if (phba->sfp_alarm & LPFC_TRANSGRESSION_HIGH_RXPOWER) + flags |= RDP_OET_HIGH_ALARM; + if (phba->sfp_alarm & LPFC_TRANSGRESSION_LOW_RXPOWER) + flags |= RDP_OET_LOW_ALARM; + if (phba->sfp_warning & LPFC_TRANSGRESSION_HIGH_RXPOWER) + flags |= RDP_OET_HIGH_WARNING; + if (phba->sfp_warning & LPFC_TRANSGRESSION_LOW_RXPOWER) + flags |= RDP_OET_LOW_WARNING; + flags |= ((0xf & RDP_OED_RXPOWER) << RDP_OED_TYPE_SHIFT); desc->oed_info.function_flags = cpu_to_be32(flags); desc->length = cpu_to_be32(sizeof(desc->oed_info)); + return sizeof(struct fc_rdp_oed_sfp_desc); } -void +uint32_t lpfc_rdp_res_opd_desc(struct fc_rdp_opd_sfp_desc *desc, uint8_t *page_a0, struct lpfc_vport *vport) { @@ -4845,9 +4904,10 @@ lpfc_rdp_res_opd_desc(struct fc_rdp_opd_sfp_desc *desc, memcpy(desc->opd_info.revision, &page_a0[SSF_VENDOR_REV], 2); memcpy(desc->opd_info.date, &page_a0[SSF_DATE_CODE], 8); desc->length = cpu_to_be32(sizeof(desc->opd_info)); + return sizeof(struct fc_rdp_opd_sfp_desc); } -int +uint32_t lpfc_rdp_res_fec_desc(struct fc_fec_rdp_desc *desc, READ_LNK_VAR *stat) { if (bf_get(lpfc_read_link_stat_gec2, stat) == 0) @@ -4864,7 +4924,7 @@ lpfc_rdp_res_fec_desc(struct fc_fec_rdp_desc *desc, READ_LNK_VAR *stat) return sizeof(struct fc_fec_rdp_desc); } -void +uint32_t lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) { uint16_t rdp_cap = 0; @@ -4923,9 +4983,10 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) desc->info.port_speed.capabilities = cpu_to_be16(rdp_cap); desc->length = cpu_to_be32(sizeof(desc->info)); + return sizeof(struct fc_rdp_port_speed_desc); } -void +uint32_t lpfc_rdp_res_diag_port_names(struct fc_rdp_port_name_desc *desc, struct lpfc_hba *phba) { @@ -4939,9 +5000,10 @@ lpfc_rdp_res_diag_port_names(struct fc_rdp_port_name_desc *desc, sizeof(desc->port_names.wwpn)); desc->length = cpu_to_be32(sizeof(desc->port_names)); + return sizeof(struct fc_rdp_port_name_desc); } -void +uint32_t lpfc_rdp_res_attach_port_names(struct fc_rdp_port_name_desc *desc, struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { @@ -4962,6 +5024,7 @@ lpfc_rdp_res_attach_port_names(struct fc_rdp_port_name_desc *desc, } desc->length = cpu_to_be32(sizeof(desc->port_names)); + return sizeof(struct fc_rdp_port_name_desc); } void @@ -4976,8 +5039,9 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, uint8_t *pcmd; struct ls_rjt *stat; struct fc_rdp_res_frame *rdp_res; - uint32_t cmdsize; - int rc, fec_size; + uint32_t cmdsize, len; + uint16_t *flag_ptr; + int rc; if (status != SUCCESS) goto error; @@ -5008,39 +5072,61 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, memset(pcmd, 0, sizeof(struct fc_rdp_res_frame)); *((uint32_t *) (pcmd)) = ELS_CMD_ACC; + /* Update Alarm and Warning */ + flag_ptr = (uint16_t *)(rdp_context->page_a2 + SSF_ALARM_FLAGS); + phba->sfp_alarm |= *flag_ptr; + flag_ptr = (uint16_t *)(rdp_context->page_a2 + SSF_WARNING_FLAGS); + phba->sfp_warning |= *flag_ptr; + /* For RDP payload */ - lpfc_rdp_res_link_service(&rdp_res->link_service_desc, ELS_CMD_RDP); + len = 8; + len += lpfc_rdp_res_link_service((struct fc_rdp_link_service_desc *) + (len + pcmd), ELS_CMD_RDP); - lpfc_rdp_res_sfp_desc(&rdp_res->sfp_desc, + len += lpfc_rdp_res_sfp_desc((struct fc_rdp_sfp_desc *)(len + pcmd), rdp_context->page_a0, rdp_context->page_a2); - lpfc_rdp_res_speed(&rdp_res->portspeed_desc, phba); - lpfc_rdp_res_link_error(&rdp_res->link_error_desc, - &rdp_context->link_stat); - lpfc_rdp_res_diag_port_names(&rdp_res->diag_port_names_desc, phba); - lpfc_rdp_res_attach_port_names(&rdp_res->attached_port_names_desc, - vport, ndlp); - lpfc_rdp_res_bbc_desc(&rdp_res->bbc_desc, &rdp_context->link_stat, - vport); - lpfc_rdp_res_oed_temp_desc(&rdp_res->oed_temp_desc, - rdp_context->page_a2); - lpfc_rdp_res_oed_voltage_desc(&rdp_res->oed_voltage_desc, - rdp_context->page_a2); - lpfc_rdp_res_oed_txbias_desc(&rdp_res->oed_txbias_desc, - rdp_context->page_a2); - lpfc_rdp_res_oed_txpower_desc(&rdp_res->oed_txpower_desc, - rdp_context->page_a2); - lpfc_rdp_res_oed_rxpower_desc(&rdp_res->oed_rxpower_desc, - rdp_context->page_a2); - lpfc_rdp_res_opd_desc(&rdp_res->opd_desc, rdp_context->page_a0, vport); - fec_size = lpfc_rdp_res_fec_desc(&rdp_res->fec_desc, + len += lpfc_rdp_res_speed((struct fc_rdp_port_speed_desc *)(len + pcmd), + phba); + len += lpfc_rdp_res_link_error((struct fc_rdp_link_error_status_desc *) + (len + pcmd), &rdp_context->link_stat); + len += lpfc_rdp_res_diag_port_names((struct fc_rdp_port_name_desc *) + (len + pcmd), phba); + len += lpfc_rdp_res_attach_port_names((struct fc_rdp_port_name_desc *) + (len + pcmd), vport, ndlp); + len += lpfc_rdp_res_fec_desc((struct fc_fec_rdp_desc *)(len + pcmd), &rdp_context->link_stat); - rdp_res->length = cpu_to_be32(fec_size + RDP_DESC_PAYLOAD_SIZE); + /* Check if nport is logged, BZ190632 */ + if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED)) + goto lpfc_skip_descriptor; + + len += lpfc_rdp_res_bbc_desc((struct fc_rdp_bbc_desc *)(len + pcmd), + &rdp_context->link_stat, vport); + len += lpfc_rdp_res_oed_temp_desc(phba, + (struct fc_rdp_oed_sfp_desc *)(len + pcmd), + rdp_context->page_a2); + len += lpfc_rdp_res_oed_voltage_desc(phba, + (struct fc_rdp_oed_sfp_desc *)(len + pcmd), + rdp_context->page_a2); + len += lpfc_rdp_res_oed_txbias_desc(phba, + (struct fc_rdp_oed_sfp_desc *)(len + pcmd), + rdp_context->page_a2); + len += lpfc_rdp_res_oed_txpower_desc(phba, + (struct fc_rdp_oed_sfp_desc *)(len + pcmd), + rdp_context->page_a2); + len += lpfc_rdp_res_oed_rxpower_desc(phba, + (struct fc_rdp_oed_sfp_desc *)(len + pcmd), + rdp_context->page_a2); + len += lpfc_rdp_res_opd_desc((struct fc_rdp_opd_sfp_desc *)(len + pcmd), + rdp_context->page_a0, vport); + +lpfc_skip_descriptor: + rdp_res->length = cpu_to_be32(len - 8); elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; /* Now that we know the true size of the payload, update the BPL */ bpl = (struct ulp_bde64 *) (((struct lpfc_dmabuf *)(elsiocb->context3))->virt); - bpl->tus.f.bdeSize = (fec_size + RDP_DESC_PAYLOAD_SIZE + 8); + bpl->tus.f.bdeSize = len; bpl->tus.f.bdeFlags = 0; bpl->tus.w = le32_to_cpu(bpl->tus.w); @@ -5165,6 +5251,12 @@ lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, be32_to_cpu(rdp_req->nport_id_desc.nport_id), be32_to_cpu(rdp_req->nport_id_desc.length)); + if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED) && + !phba->cfg_enable_SmartSAN) { + rjt_err = LSRJT_UNABLE_TPC; + rjt_expl = LSEXP_PORT_LOGIN_REQ; + goto error; + } if (sizeof(struct fc_rdp_nport_desc) != be32_to_cpu(rdp_req->rdp_des_length)) goto rjt_logerr; |