scsi: qla2xxx: Fix buffer-buffer credit extraction error
authorQuinn Tran <qutran@marvell.com>
Tue, 29 Sep 2020 10:21:47 +0000 (03:21 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 30 Sep 2020 03:22:15 +0000 (23:22 -0400)
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>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c

index fa31301528bde2e222e43cd146a13883286e366b..98814a9a8ea65e7eb7334c286fda8fb1c9e9f3f0 100644 (file)
@@ -3915,6 +3915,7 @@ struct qla_hw_data {
                                /* Enabled in Driver */
                uint32_t        scm_enabled:1;
                uint32_t        max_req_queue_warned:1;
+               uint32_t        plogi_template_valid:1;
        } flags;
 
        uint16_t max_exchg;
@@ -4263,7 +4264,8 @@ struct qla_hw_data {
        int             exchoffld_count;
 
        /* 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;
 
index f71f3a15256c0ff552becca0bdafae39ac71a864..6d69ab23a2f3fa2c3eda4ce8bb622a55009340ae 100644 (file)
@@ -4991,6 +4991,29 @@ qla2x00_free_fcport(fc_port_t *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
  *      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);
 
        qla2x00_get_data_rate(vha);
+       qla_get_login_template(vha);
 
        /* Determine what we need to do */
        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)
 {
-       struct qla_hw_data *ha = vha->hw;
        unsigned long flags;
        fc_port_t *fcport;
-       int rval;
-
-       if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
-               /* borrowing */
-               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;
-               }
-       }
+       if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags))
+               set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
 
        list_for_each_entry(fcport, &vha->vp_fcports, list) {
                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);
        vha->scan.scan_retry++;
        spin_unlock_irqrestore(&vha->work_lock, flags);
index 310db7e4e2334c010fb5098350a4dd094396ad98..3202c9ca42f6ce4d61564fc67249758e6dc32f27 100644 (file)
@@ -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(resp_ptr, 0, sizeof(struct els_plogi_payload));
        memcpy(elsio->u.els_plogi.els_plogi_pyld->data,
-           &ha->plogi_els_payld.data,
-           sizeof(elsio->u.els_plogi.els_plogi_pyld->data));
+           &ha->plogi_els_payld.fl_csp, LOGIN_TEMPLATE_SIZE);
 
        elsio->u.els_plogi.els_cmd = els_opcode;
        elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
index 597617b59fbb5be233b66428fa3862609cd8290f..c1580eec6b276cab1e4ed4c1e63f8a9f1b81c42e 100644 (file)
@@ -4977,45 +4977,6 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
        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
 qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
 {
index c77b8b6279026986ff34fd84473f169ca58f70df..9d6292928c329af33701b63d499537b59121d825 100644 (file)
@@ -5837,12 +5837,10 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
        dma_addr_t rsp_els_dma;
        dma_addr_t rsp_payload_dma;
        dma_addr_t stat_dma;
-       dma_addr_t bbc_dma;
        dma_addr_t sfp_dma;
        struct els_entry_24xx *rsp_els = NULL;
        struct rdp_rsp_payload *rsp_payload = NULL;
        struct link_statistics *stat = NULL;
-       struct buffer_credit_24xx *bbc = NULL;
        uint8_t *sfp = NULL;
        uint16_t sfp_flags = 0;
        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, GFP_KERNEL);
 
-       bbc = dma_alloc_coherent(&ha->pdev->dev, sizeof(*bbc),
-           &bbc_dma, GFP_KERNEL);
-
        /* Prepare Response IOCB */
        rsp_els->entry_type = ELS_IOCB_TYPE;
        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.fcport_rtt = cpu_to_be32(0);
 
-       if (bbc) {
-               memset(bbc, 0, sizeof(*bbc));
-               rval = qla24xx_get_buffer_credits(vha, bbc, bbc_dma);
-               if (!rval) {
-                       rsp_payload->buffer_credit_desc.fcport_b2b =
-                           cpu_to_be32(LSW(bbc->parameter[0]));
-               }
+       if (ha->flags.plogi_template_valid) {
+               uint32_t tmp =
+               be16_to_cpu(ha->plogi_els_payld.fl_csp.sp_bb_cred);
+               rsp_payload->buffer_credit_desc.fcport_b2b = cpu_to_be32(tmp);
        }
 
        if (rsp_payload_length < sizeof(*rsp_payload))
@@ -6226,9 +6218,6 @@ send:
        }
 
 dealloc:
-       if (bbc)
-               dma_free_coherent(&ha->pdev->dev, sizeof(*bbc),
-                   bbc, bbc_dma);
        if (stat)
                dma_free_coherent(&ha->pdev->dev, sizeof(*stat),
                    stat, stat_dma);