Commit 4879237c authored by Joe Carnuccio's avatar Joe Carnuccio Committed by Martin K. Petersen

scsi: qla2xxx: Handle cases for limiting RDP response payload length

This patch reduces RDP response payload length, if requesting port is a
domain controller (sid 0xfffc01) and fw is earlier than 8.09.00 and fw is
not 8.05.65 then limit the RDP response payload length to maximum of 256
bytes by terminating the response just before the optical element
descriptor.

Link: https://lore.kernel.org/r/20200212214436.25532-15-hmadhani@marvell.comSigned-off-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
Signed-off-by: default avatarJoe Carnuccio <joe.carnuccio@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 576bfde8
...@@ -5769,6 +5769,32 @@ qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id) ...@@ -5769,6 +5769,32 @@ qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id)
return; return;
} }
static bool
qla25xx_rdp_rsp_reduce_size(struct scsi_qla_host *vha,
struct purex_entry_24xx *purex)
{
char fwstr[16];
u32 sid = purex->s_id[2] << 16 | purex->s_id[1] << 8 | purex->s_id[0];
/* Domain Controller is always logged-out. */
/* if RDP request is not from Domain Controller: */
if (sid != 0xfffc01)
return false;
ql_dbg(ql_dbg_init, vha, 0x0181, "%s: s_id=%#x\n", __func__, sid);
vha->hw->isp_ops->fw_version_str(vha, fwstr, sizeof(fwstr));
fwstr[strcspn(fwstr, " ")] = 0;
/* if FW version allows RDP response length upto 2048 bytes: */
if (strcmp(fwstr, "8.09.00") > 0 || strcmp(fwstr, "8.05.65") == 0)
return false;
ql_dbg(ql_dbg_init, vha, 0x0181, "%s: fw=%s\n", __func__, fwstr);
/* RDP response length is to be reduced to maximum 256 bytes */
return true;
}
static uint static uint
qla25xx_rdp_port_speed_capability(struct qla_hw_data *ha) qla25xx_rdp_port_speed_capability(struct qla_hw_data *ha)
{ {
...@@ -5887,6 +5913,7 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt) ...@@ -5887,6 +5913,7 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
struct buffer_credit_24xx *bbc = 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);
int rval; int rval;
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0180, ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0180,
...@@ -5897,6 +5924,14 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt) ...@@ -5897,6 +5924,14 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0182, ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0182,
(void *)purex, sizeof(*purex)); (void *)purex, sizeof(*purex));
if (qla25xx_rdp_rsp_reduce_size(vha, purex)) {
rsp_payload_length =
offsetof(typeof(*rsp_payload), optical_elmt_desc);
ql_dbg(ql_dbg_init, vha, 0x0181,
"Reducing RSP payload length to %u bytes...\n",
rsp_payload_length);
}
rsp_els = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_els), rsp_els = dma_alloc_coherent(&ha->pdev->dev, sizeof(*rsp_els),
&rsp_els_dma, GFP_KERNEL); &rsp_els_dma, GFP_KERNEL);
if (!rsp_els) { if (!rsp_els) {
...@@ -5943,7 +5978,7 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt) ...@@ -5943,7 +5978,7 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
rsp_els->control_flags = EPD_ELS_ACC; rsp_els->control_flags = EPD_ELS_ACC;
rsp_els->rx_byte_count = 0; rsp_els->rx_byte_count = 0;
rsp_els->tx_byte_count = cpu_to_le32(sizeof(*rsp_payload)); rsp_els->tx_byte_count = cpu_to_le32(rsp_payload_length);
put_unaligned_le64(rsp_payload_dma, &rsp_els->tx_address); put_unaligned_le64(rsp_payload_dma, &rsp_els->tx_address);
rsp_els->tx_len = rsp_els->tx_byte_count; rsp_els->tx_len = rsp_els->tx_byte_count;
...@@ -6118,6 +6153,9 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt) ...@@ -6118,6 +6153,9 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
} }
} }
if (rsp_payload_length < sizeof(*rsp_payload))
goto send;
if (sfp) { if (sfp) {
memset(sfp, 0, SFP_RTDI_LEN); memset(sfp, 0, SFP_RTDI_LEN);
rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 0, 64, 0); rval = qla2x00_read_sfp(vha, sfp_dma, sfp, 0xa2, 0, 64, 0);
...@@ -6278,7 +6316,7 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt) ...@@ -6278,7 +6316,7 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0186, ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x0186,
"-------- ELS RSP PAYLOAD -------\n"); "-------- ELS RSP PAYLOAD -------\n");
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0187, ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x0187,
(void *)rsp_payload, rsp_els->tx_byte_count); (void *)rsp_payload, rsp_payload_length);
rval = qla2x00_issue_iocb(vha, rsp_els, rsp_els_dma, 0); rval = qla2x00_issue_iocb(vha, rsp_els, rsp_els_dma, 0);
......
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