Commit 2a3192a3 authored by Joe Carnuccio's avatar Joe Carnuccio Committed by Martin K. Petersen

scsi: qla2xxx: Add Serdes support for ISP28XX

This patch adds sysfs node for serdes_version and also cleans up port_speed
display.
Signed-off-by: default avatarJoe Carnuccio <joe.carnuccio@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent ecc89f25
...@@ -1377,6 +1377,21 @@ qla24xx_84xx_fw_version_show(struct device *dev, ...@@ -1377,6 +1377,21 @@ qla24xx_84xx_fw_version_show(struct device *dev,
return scnprintf(buf, PAGE_SIZE, "\n"); return scnprintf(buf, PAGE_SIZE, "\n");
} }
static ssize_t
qla2x00_serdes_version_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
struct qla_hw_data *ha = vha->hw;
if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
return scnprintf(buf, PAGE_SIZE, "\n");
return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
ha->serdes_version[0], ha->serdes_version[1],
ha->serdes_version[2]);
}
static ssize_t static ssize_t
qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr, qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
...@@ -2220,6 +2235,7 @@ static DEVICE_ATTR(84xx_fw_version, S_IRUGO, qla24xx_84xx_fw_version_show, ...@@ -2220,6 +2235,7 @@ static DEVICE_ATTR(84xx_fw_version, S_IRUGO, qla24xx_84xx_fw_version_show,
NULL); NULL);
static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show, static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
NULL); NULL);
static DEVICE_ATTR(serdes_version, 0444, qla2x00_serdes_version_show, NULL);
static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL); static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL);
static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL); static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL);
static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show, static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show,
...@@ -2272,6 +2288,7 @@ struct device_attribute *qla2x00_host_attrs[] = { ...@@ -2272,6 +2288,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_optrom_fw_version, &dev_attr_optrom_fw_version,
&dev_attr_84xx_fw_version, &dev_attr_84xx_fw_version,
&dev_attr_total_isp_aborts, &dev_attr_total_isp_aborts,
&dev_attr_serdes_version,
&dev_attr_mpi_version, &dev_attr_mpi_version,
&dev_attr_phy_version, &dev_attr_phy_version,
&dev_attr_flash_block_size, &dev_attr_flash_block_size,
...@@ -2328,16 +2345,15 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost) ...@@ -2328,16 +2345,15 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost)
static void static void
qla2x00_get_host_speed(struct Scsi_Host *shost) qla2x00_get_host_speed(struct Scsi_Host *shost)
{ {
struct qla_hw_data *ha = ((struct scsi_qla_host *) scsi_qla_host_t *vha = shost_priv(shost);
(shost_priv(shost)))->hw; u32 speed;
u32 speed = FC_PORTSPEED_UNKNOWN;
if (IS_QLAFX00(ha)) { if (IS_QLAFX00(vha->hw)) {
qlafx00_get_host_speed(shost); qlafx00_get_host_speed(shost);
return; return;
} }
switch (ha->link_data_rate) { switch (vha->hw->link_data_rate) {
case PORT_SPEED_1GB: case PORT_SPEED_1GB:
speed = FC_PORTSPEED_1GBIT; speed = FC_PORTSPEED_1GBIT;
break; break;
...@@ -2362,7 +2378,11 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) ...@@ -2362,7 +2378,11 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
case PORT_SPEED_64GB: case PORT_SPEED_64GB:
speed = FC_PORTSPEED_64GBIT; speed = FC_PORTSPEED_64GBIT;
break; break;
default:
speed = FC_PORTSPEED_UNKNOWN;
break;
} }
fc_host_speed(shost) = speed; fc_host_speed(shost) = speed;
} }
...@@ -2370,7 +2390,7 @@ static void ...@@ -2370,7 +2390,7 @@ static void
qla2x00_get_host_port_type(struct Scsi_Host *shost) qla2x00_get_host_port_type(struct Scsi_Host *shost)
{ {
scsi_qla_host_t *vha = shost_priv(shost); scsi_qla_host_t *vha = shost_priv(shost);
uint32_t port_type = FC_PORTTYPE_UNKNOWN; uint32_t port_type;
if (vha->vp_idx) { if (vha->vp_idx) {
fc_host_port_type(shost) = FC_PORTTYPE_NPIV; fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
...@@ -2389,7 +2409,11 @@ qla2x00_get_host_port_type(struct Scsi_Host *shost) ...@@ -2389,7 +2409,11 @@ qla2x00_get_host_port_type(struct Scsi_Host *shost)
case ISP_CFG_F: case ISP_CFG_F:
port_type = FC_PORTTYPE_NPORT; port_type = FC_PORTTYPE_NPORT;
break; break;
default:
port_type = FC_PORTTYPE_UNKNOWN;
break;
} }
fc_host_port_type(shost) = port_type; fc_host_port_type(shost) = port_type;
} }
...@@ -2451,13 +2475,10 @@ qla2x00_get_starget_port_id(struct scsi_target *starget) ...@@ -2451,13 +2475,10 @@ qla2x00_get_starget_port_id(struct scsi_target *starget)
fc_starget_port_id(starget) = port_id; fc_starget_port_id(starget) = port_id;
} }
static void static inline void
qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
{ {
if (timeout) rport->dev_loss_tmo = timeout ? timeout : 1;
rport->dev_loss_tmo = timeout;
else
rport->dev_loss_tmo = 1;
} }
static void static void
......
...@@ -4023,6 +4023,7 @@ struct qla_hw_data { ...@@ -4023,6 +4023,7 @@ struct qla_hw_data {
uint8_t fw_seriallink_options[4]; uint8_t fw_seriallink_options[4];
uint16_t fw_seriallink_options24[4]; uint16_t fw_seriallink_options24[4];
uint8_t serdes_version[3];
uint8_t mpi_version[3]; uint8_t mpi_version[3];
uint32_t mpi_capabilities; uint32_t mpi_capabilities;
uint8_t phy_version[3]; uint8_t phy_version[3];
...@@ -4034,7 +4035,8 @@ struct qla_hw_data { ...@@ -4034,7 +4035,8 @@ struct qla_hw_data {
/* Firmware dump information. */ /* Firmware dump information. */
struct qla2xxx_fw_dump *fw_dump; struct qla2xxx_fw_dump *fw_dump;
uint32_t fw_dump_len; uint32_t fw_dump_len;
int fw_dumped; bool fw_dumped;
bool fw_dump_mpi;
unsigned long fw_dump_cap_flags; unsigned long fw_dump_cap_flags;
#define RISC_PAUSE_CMPL 0 #define RISC_PAUSE_CMPL 0
#define DMA_SHUTDOWN_CMPL 1 #define DMA_SHUTDOWN_CMPL 1
......
...@@ -2783,6 +2783,31 @@ qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd, ...@@ -2783,6 +2783,31 @@ qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
return &p->p.req; return &p->p.req;
} }
static uint16_t
qla2x00_port_speed_capability(uint16_t speed)
{
switch (speed) {
case BIT_15:
return PORT_SPEED_1GB;
case BIT_14:
return PORT_SPEED_2GB;
case BIT_13:
return PORT_SPEED_4GB;
case BIT_12:
return PORT_SPEED_10GB;
case BIT_11:
return PORT_SPEED_8GB;
case BIT_10:
return PORT_SPEED_16GB;
case BIT_8:
return PORT_SPEED_32GB;
case BIT_7:
return PORT_SPEED_64GB;
default:
return PORT_SPEED_UNKNOWN;
}
}
/** /**
* qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
* @vha: HA context * @vha: HA context
...@@ -2855,31 +2880,8 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list) ...@@ -2855,31 +2880,8 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
} }
rval = QLA_FUNCTION_FAILED; rval = QLA_FUNCTION_FAILED;
} else { } else {
/* Save port-speed */ list->fp_speed = qla2x00_port_speed_capability(
switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { be16_to_cpu(ct_rsp->rsp.gpsc.speed));
case BIT_15:
list[i].fp_speed = PORT_SPEED_1GB;
break;
case BIT_14:
list[i].fp_speed = PORT_SPEED_2GB;
break;
case BIT_13:
list[i].fp_speed = PORT_SPEED_4GB;
break;
case BIT_12:
list[i].fp_speed = PORT_SPEED_10GB;
break;
case BIT_11:
list[i].fp_speed = PORT_SPEED_8GB;
break;
case BIT_10:
list[i].fp_speed = PORT_SPEED_16GB;
break;
case BIT_8:
list[i].fp_speed = PORT_SPEED_32GB;
break;
}
ql_dbg(ql_dbg_disc, vha, 0x205b, ql_dbg(ql_dbg_disc, vha, 0x205b,
"GPSC ext entry - fpn " "GPSC ext entry - fpn "
"%8phN speeds=%04x speed=%04x.\n", "%8phN speeds=%04x speed=%04x.\n",
...@@ -3048,29 +3050,8 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res) ...@@ -3048,29 +3050,8 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
goto done; goto done;
} }
} else { } else {
switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { fcport->fp_speed = qla2x00_port_speed_capability(
case BIT_15: be16_to_cpu(ct_rsp->rsp.gpsc.speed));
fcport->fp_speed = PORT_SPEED_1GB;
break;
case BIT_14:
fcport->fp_speed = PORT_SPEED_2GB;
break;
case BIT_13:
fcport->fp_speed = PORT_SPEED_4GB;
break;
case BIT_12:
fcport->fp_speed = PORT_SPEED_10GB;
break;
case BIT_11:
fcport->fp_speed = PORT_SPEED_8GB;
break;
case BIT_10:
fcport->fp_speed = PORT_SPEED_16GB;
break;
case BIT_8:
fcport->fp_speed = PORT_SPEED_32GB;
break;
}
ql_dbg(ql_dbg_disc, vha, 0x2054, ql_dbg(ql_dbg_disc, vha, 0x2054,
"Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n", "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n",
......
...@@ -714,7 +714,9 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) ...@@ -714,7 +714,9 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
ql_log(ql_log_warn, vha, 0x5003, ql_log(ql_log_warn, vha, 0x5003,
"ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh " "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh "
"mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx); "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx);
ha->fw_dump_mpi =
(IS_QLA27XX(ha) || IS_QLA28XX(ha)) &&
RD_REG_WORD(&reg24->mailbox7) & BIT_8;
ha->isp_ops->fw_dump(vha, 1); ha->isp_ops->fw_dump(vha, 1);
ha->flags.fw_init_done = 0; ha->flags.fw_init_done = 0;
QLA_FW_STOPPED(ha); QLA_FW_STOPPED(ha);
......
...@@ -634,14 +634,15 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr, ...@@ -634,14 +634,15 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
mcp->out_mb |= MBX_4; mcp->out_mb |= MBX_4;
} }
mcp->in_mb = MBX_0; mcp->in_mb = MBX_1|MBX_0;
mcp->tov = MBX_TOV_SECONDS; mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0; mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp); rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_mbx, vha, 0x1023, ql_dbg(ql_dbg_mbx, vha, 0x1023,
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); "Failed=%x mb[0]=%x mb[1]=%x.\n",
rval, mcp->mb[0], mcp->mb[1]);
} else { } else {
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024, ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
"Done %s.\n", __func__); "Done %s.\n", __func__);
...@@ -1057,7 +1058,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) ...@@ -1057,7 +1058,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
mcp->in_mb |= mcp->in_mb |=
MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18| MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18|
MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8; MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7;
mcp->flags = 0; mcp->flags = 0;
mcp->tov = MBX_TOV_SECONDS; mcp->tov = MBX_TOV_SECONDS;
...@@ -1124,6 +1125,9 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) ...@@ -1124,6 +1125,9 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
} }
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
ha->serdes_version[0] = mcp->mb[7] & 0xff;
ha->serdes_version[1] = mcp->mb[8] >> 8;
ha->serdes_version[2] = mcp->mb[8] & 0xff;
ha->mpi_version[0] = mcp->mb[10] & 0xff; ha->mpi_version[0] = mcp->mb[10] & 0xff;
ha->mpi_version[1] = mcp->mb[11] >> 8; ha->mpi_version[1] = mcp->mb[11] >> 8;
ha->mpi_version[2] = mcp->mb[11] & 0xff; ha->mpi_version[2] = mcp->mb[11] & 0xff;
...@@ -3748,7 +3752,7 @@ qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, ...@@ -3748,7 +3752,7 @@ qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
rval = qla2x00_mailbox_command(vha, mcp); rval = qla2x00_mailbox_command(vha, mcp);
/* Return mailbox statuses. */ /* Return mailbox statuses. */
if (mb != NULL) { if (mb) {
mb[0] = mcp->mb[0]; mb[0] = mcp->mb[0];
mb[1] = mcp->mb[1]; mb[1] = mcp->mb[1];
mb[3] = mcp->mb[3]; mb[3] = mcp->mb[3];
...@@ -3783,7 +3787,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, ...@@ -3783,7 +3787,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
mcp->mb[0] = MBC_PORT_PARAMS; mcp->mb[0] = MBC_PORT_PARAMS;
mcp->mb[1] = loop_id; mcp->mb[1] = loop_id;
mcp->mb[2] = BIT_0; mcp->mb[2] = BIT_0;
mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0); mcp->mb[3] = port_speed & 0x3F;
mcp->mb[9] = vha->vp_idx; mcp->mb[9] = vha->vp_idx;
mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_3|MBX_1|MBX_0; mcp->in_mb = MBX_3|MBX_1|MBX_0;
...@@ -3792,7 +3796,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, ...@@ -3792,7 +3796,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
rval = qla2x00_mailbox_command(vha, mcp); rval = qla2x00_mailbox_command(vha, mcp);
/* Return mailbox statuses. */ /* Return mailbox statuses. */
if (mb != NULL) { if (mb) {
mb[0] = mcp->mb[0]; mb[0] = mcp->mb[0];
mb[1] = mcp->mb[1]; mb[1] = mcp->mb[1];
mb[3] = mcp->mb[3]; mb[3] = mcp->mb[3];
...@@ -4823,10 +4827,10 @@ qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp, ...@@ -4823,10 +4827,10 @@ qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_mbx, vha, 0x10e9, ql_dbg(ql_dbg_mbx, vha, 0x10e9,
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
if (mcp->mb[0] == MBS_COMMAND_ERROR && if (mcp->mb[0] == MBS_COMMAND_ERROR && mcp->mb[1] == 0x22) {
mcp->mb[1] == 0x22)
/* sfp is not there */ /* sfp is not there */
rval = QLA_INTERFACE_ERROR; rval = QLA_INTERFACE_ERROR;
}
} else { } else {
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
"Done %s.\n", __func__); "Done %s.\n", __func__);
...@@ -5166,13 +5170,14 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) ...@@ -5166,13 +5170,14 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
mcp->mb[3] = MSW(data); mcp->mb[3] = MSW(data);
mcp->mb[8] = MSW(risc_addr); mcp->mb[8] = MSW(risc_addr);
mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0; mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_0; mcp->in_mb = MBX_1|MBX_0;
mcp->tov = 30; mcp->tov = 30;
mcp->flags = 0; mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp); rval = qla2x00_mailbox_command(vha, mcp);
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_mbx, vha, 0x1101, ql_dbg(ql_dbg_mbx, vha, 0x1101,
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); "Failed=%x mb[0]=%x mb[1]=%x.\n",
rval, mcp->mb[0], mcp->mb[1]);
} else { } else {
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102, ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
"Done %s.\n", __func__); "Done %s.\n", __func__);
......
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