scsi: qla2xxx: Fix buffer-buffer credit extraction error
Current code uses wrong mailbox option to extract bbc from firmware. This field is nested inside of PLOGI payload. Extract bbc from PLOGI template payload. Link: https://lore.kernel.org/r/20200929102152.32278-3-njavali@marvell.com Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Quinn Tran <qutran@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
7dc0f671d8
commit
44f5a37d1e
|
@ -3915,6 +3915,7 @@ struct qla_hw_data {
|
||||||
/* Enabled in Driver */
|
/* Enabled in Driver */
|
||||||
uint32_t scm_enabled:1;
|
uint32_t scm_enabled:1;
|
||||||
uint32_t max_req_queue_warned:1;
|
uint32_t max_req_queue_warned:1;
|
||||||
|
uint32_t plogi_template_valid:1;
|
||||||
} flags;
|
} flags;
|
||||||
|
|
||||||
uint16_t max_exchg;
|
uint16_t max_exchg;
|
||||||
|
@ -4263,7 +4264,8 @@ struct qla_hw_data {
|
||||||
int exchoffld_count;
|
int exchoffld_count;
|
||||||
|
|
||||||
/* n2n */
|
/* n2n */
|
||||||
struct els_plogi_payload plogi_els_payld;
|
struct fc_els_flogi plogi_els_payld;
|
||||||
|
#define LOGIN_TEMPLATE_SIZE (sizeof(struct fc_els_flogi) - 4)
|
||||||
|
|
||||||
void *swl;
|
void *swl;
|
||||||
|
|
||||||
|
|
|
@ -4991,6 +4991,29 @@ qla2x00_free_fcport(fc_port_t *fcport)
|
||||||
kfree(fcport);
|
kfree(fcport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qla_get_login_template(scsi_qla_host_t *vha)
|
||||||
|
{
|
||||||
|
struct qla_hw_data *ha = vha->hw;
|
||||||
|
int rval;
|
||||||
|
u32 *bp, sz;
|
||||||
|
__be32 *q;
|
||||||
|
|
||||||
|
memset(ha->init_cb, 0, ha->init_cb_size);
|
||||||
|
sz = min_t(int, sizeof(struct fc_els_flogi), ha->init_cb_size);
|
||||||
|
rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
|
||||||
|
ha->init_cb, sz);
|
||||||
|
if (rval != QLA_SUCCESS) {
|
||||||
|
ql_dbg(ql_dbg_init, vha, 0x00d1,
|
||||||
|
"PLOGI ELS param read fail.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
q = (__be32 *)&ha->plogi_els_payld.fl_csp;
|
||||||
|
|
||||||
|
bp = (uint32_t *)ha->init_cb;
|
||||||
|
cpu_to_be32_array(q, bp, sz / 4);
|
||||||
|
ha->flags.plogi_template_valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* qla2x00_configure_loop
|
* qla2x00_configure_loop
|
||||||
* Updates Fibre Channel Device Database with what is actually on loop.
|
* Updates Fibre Channel Device Database with what is actually on loop.
|
||||||
|
@ -5034,6 +5057,7 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
|
||||||
clear_bit(RSCN_UPDATE, &vha->dpc_flags);
|
clear_bit(RSCN_UPDATE, &vha->dpc_flags);
|
||||||
|
|
||||||
qla2x00_get_data_rate(vha);
|
qla2x00_get_data_rate(vha);
|
||||||
|
qla_get_login_template(vha);
|
||||||
|
|
||||||
/* Determine what we need to do */
|
/* Determine what we need to do */
|
||||||
if ((ha->current_topology == ISP_CFG_FL ||
|
if ((ha->current_topology == ISP_CFG_FL ||
|
||||||
|
@ -5118,32 +5142,11 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
|
||||||
|
|
||||||
static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
|
static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
|
||||||
{
|
{
|
||||||
struct qla_hw_data *ha = vha->hw;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
fc_port_t *fcport;
|
fc_port_t *fcport;
|
||||||
int rval;
|
|
||||||
|
|
||||||
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
|
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags))
|
||||||
/* borrowing */
|
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
|
||||||
u32 *bp, sz;
|
|
||||||
|
|
||||||
memset(ha->init_cb, 0, ha->init_cb_size);
|
|
||||||
sz = min_t(int, sizeof(struct els_plogi_payload),
|
|
||||||
ha->init_cb_size);
|
|
||||||
rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
|
|
||||||
ha->init_cb, sz);
|
|
||||||
if (rval == QLA_SUCCESS) {
|
|
||||||
__be32 *q = &ha->plogi_els_payld.data[0];
|
|
||||||
|
|
||||||
bp = (uint32_t *)ha->init_cb;
|
|
||||||
cpu_to_be32_array(q, bp, sz / 4);
|
|
||||||
memcpy(bp, q, sizeof(ha->plogi_els_payld.data));
|
|
||||||
} else {
|
|
||||||
ql_dbg(ql_dbg_init, vha, 0x00d1,
|
|
||||||
"PLOGI ELS param read fail.\n");
|
|
||||||
goto skip_login;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry(fcport, &vha->vp_fcports, list) {
|
list_for_each_entry(fcport, &vha->vp_fcports, list) {
|
||||||
if (fcport->n2n_flag) {
|
if (fcport->n2n_flag) {
|
||||||
|
@ -5152,7 +5155,6 @@ static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_login:
|
|
||||||
spin_lock_irqsave(&vha->work_lock, flags);
|
spin_lock_irqsave(&vha->work_lock, flags);
|
||||||
vha->scan.scan_retry++;
|
vha->scan.scan_retry++;
|
||||||
spin_unlock_irqrestore(&vha->work_lock, flags);
|
spin_unlock_irqrestore(&vha->work_lock, flags);
|
||||||
|
|
|
@ -3013,8 +3013,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||||
memset(ptr, 0, sizeof(struct els_plogi_payload));
|
memset(ptr, 0, sizeof(struct els_plogi_payload));
|
||||||
memset(resp_ptr, 0, sizeof(struct els_plogi_payload));
|
memset(resp_ptr, 0, sizeof(struct els_plogi_payload));
|
||||||
memcpy(elsio->u.els_plogi.els_plogi_pyld->data,
|
memcpy(elsio->u.els_plogi.els_plogi_pyld->data,
|
||||||
&ha->plogi_els_payld.data,
|
&ha->plogi_els_payld.fl_csp, LOGIN_TEMPLATE_SIZE);
|
||||||
sizeof(elsio->u.els_plogi.els_plogi_pyld->data));
|
|
||||||
|
|
||||||
elsio->u.els_plogi.els_cmd = els_opcode;
|
elsio->u.els_plogi.els_cmd = els_opcode;
|
||||||
elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
|
elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
|
||||||
|
|
|
@ -4977,45 +4977,6 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
qla24xx_get_buffer_credits(scsi_qla_host_t *vha, struct buffer_credit_24xx *bbc,
|
|
||||||
dma_addr_t bbc_dma)
|
|
||||||
{
|
|
||||||
mbx_cmd_t mc;
|
|
||||||
mbx_cmd_t *mcp = &mc;
|
|
||||||
int rval;
|
|
||||||
|
|
||||||
if (!IS_FWI2_CAPABLE(vha->hw))
|
|
||||||
return QLA_FUNCTION_FAILED;
|
|
||||||
|
|
||||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118e,
|
|
||||||
"Entered %s.\n", __func__);
|
|
||||||
|
|
||||||
mcp->mb[0] = MBC_GET_RNID_PARAMS;
|
|
||||||
mcp->mb[1] = RNID_BUFFER_CREDITS << 8;
|
|
||||||
mcp->mb[2] = MSW(LSD(bbc_dma));
|
|
||||||
mcp->mb[3] = LSW(LSD(bbc_dma));
|
|
||||||
mcp->mb[6] = MSW(MSD(bbc_dma));
|
|
||||||
mcp->mb[7] = LSW(MSD(bbc_dma));
|
|
||||||
mcp->mb[8] = sizeof(*bbc) / sizeof(*bbc->parameter);
|
|
||||||
mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
|
||||||
mcp->in_mb = MBX_1|MBX_0;
|
|
||||||
mcp->buf_size = sizeof(*bbc);
|
|
||||||
mcp->flags = MBX_DMA_IN;
|
|
||||||
mcp->tov = MBX_TOV_SECONDS;
|
|
||||||
rval = qla2x00_mailbox_command(vha, mcp);
|
|
||||||
|
|
||||||
if (rval != QLA_SUCCESS) {
|
|
||||||
ql_dbg(ql_dbg_mbx, vha, 0x118f,
|
|
||||||
"Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
|
|
||||||
} else {
|
|
||||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1190,
|
|
||||||
"Done %s.\n", __func__);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
|
qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5837,12 +5837,10 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
|
||||||
dma_addr_t rsp_els_dma;
|
dma_addr_t rsp_els_dma;
|
||||||
dma_addr_t rsp_payload_dma;
|
dma_addr_t rsp_payload_dma;
|
||||||
dma_addr_t stat_dma;
|
dma_addr_t stat_dma;
|
||||||
dma_addr_t bbc_dma;
|
|
||||||
dma_addr_t sfp_dma;
|
dma_addr_t sfp_dma;
|
||||||
struct els_entry_24xx *rsp_els = NULL;
|
struct els_entry_24xx *rsp_els = NULL;
|
||||||
struct rdp_rsp_payload *rsp_payload = NULL;
|
struct rdp_rsp_payload *rsp_payload = NULL;
|
||||||
struct link_statistics *stat = NULL;
|
struct link_statistics *stat = NULL;
|
||||||
struct buffer_credit_24xx *bbc = NULL;
|
|
||||||
uint8_t *sfp = NULL;
|
uint8_t *sfp = NULL;
|
||||||
uint16_t sfp_flags = 0;
|
uint16_t sfp_flags = 0;
|
||||||
uint rsp_payload_length = sizeof(*rsp_payload);
|
uint rsp_payload_length = sizeof(*rsp_payload);
|
||||||
|
@ -5886,9 +5884,6 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
|
||||||
stat = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stat),
|
stat = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stat),
|
||||||
&stat_dma, GFP_KERNEL);
|
&stat_dma, GFP_KERNEL);
|
||||||
|
|
||||||
bbc = dma_alloc_coherent(&ha->pdev->dev, sizeof(*bbc),
|
|
||||||
&bbc_dma, GFP_KERNEL);
|
|
||||||
|
|
||||||
/* Prepare Response IOCB */
|
/* Prepare Response IOCB */
|
||||||
rsp_els->entry_type = ELS_IOCB_TYPE;
|
rsp_els->entry_type = ELS_IOCB_TYPE;
|
||||||
rsp_els->entry_count = 1;
|
rsp_els->entry_count = 1;
|
||||||
|
@ -6042,13 +6037,10 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
|
||||||
rsp_payload->buffer_credit_desc.attached_fcport_b2b = cpu_to_be32(0);
|
rsp_payload->buffer_credit_desc.attached_fcport_b2b = cpu_to_be32(0);
|
||||||
rsp_payload->buffer_credit_desc.fcport_rtt = cpu_to_be32(0);
|
rsp_payload->buffer_credit_desc.fcport_rtt = cpu_to_be32(0);
|
||||||
|
|
||||||
if (bbc) {
|
if (ha->flags.plogi_template_valid) {
|
||||||
memset(bbc, 0, sizeof(*bbc));
|
uint32_t tmp =
|
||||||
rval = qla24xx_get_buffer_credits(vha, bbc, bbc_dma);
|
be16_to_cpu(ha->plogi_els_payld.fl_csp.sp_bb_cred);
|
||||||
if (!rval) {
|
rsp_payload->buffer_credit_desc.fcport_b2b = cpu_to_be32(tmp);
|
||||||
rsp_payload->buffer_credit_desc.fcport_b2b =
|
|
||||||
cpu_to_be32(LSW(bbc->parameter[0]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rsp_payload_length < sizeof(*rsp_payload))
|
if (rsp_payload_length < sizeof(*rsp_payload))
|
||||||
|
@ -6226,9 +6218,6 @@ send:
|
||||||
}
|
}
|
||||||
|
|
||||||
dealloc:
|
dealloc:
|
||||||
if (bbc)
|
|
||||||
dma_free_coherent(&ha->pdev->dev, sizeof(*bbc),
|
|
||||||
bbc, bbc_dma);
|
|
||||||
if (stat)
|
if (stat)
|
||||||
dma_free_coherent(&ha->pdev->dev, sizeof(*stat),
|
dma_free_coherent(&ha->pdev->dev, sizeof(*stat),
|
||||||
stat, stat_dma);
|
stat, stat_dma);
|
||||||
|
|
Loading…
Reference in New Issue