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

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
Loading
Loading
Loading
Loading
+32 −11
Original line number Diff line number Diff line
@@ -1377,6 +1377,21 @@ qla24xx_84xx_fw_version_show(struct device *dev,
	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
qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
    char *buf)
@@ -2220,6 +2235,7 @@ static DEVICE_ATTR(84xx_fw_version, S_IRUGO, qla24xx_84xx_fw_version_show,
		   NULL);
static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
		   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(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL);
static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show,
@@ -2272,6 +2288,7 @@ struct device_attribute *qla2x00_host_attrs[] = {
	&dev_attr_optrom_fw_version,
	&dev_attr_84xx_fw_version,
	&dev_attr_total_isp_aborts,
	&dev_attr_serdes_version,
	&dev_attr_mpi_version,
	&dev_attr_phy_version,
	&dev_attr_flash_block_size,
@@ -2328,16 +2345,15 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost)
static void
qla2x00_get_host_speed(struct Scsi_Host *shost)
{
	struct qla_hw_data *ha = ((struct scsi_qla_host *)
					(shost_priv(shost)))->hw;
	u32 speed = FC_PORTSPEED_UNKNOWN;
	scsi_qla_host_t *vha = shost_priv(shost);
	u32 speed;

	if (IS_QLAFX00(ha)) {
	if (IS_QLAFX00(vha->hw)) {
		qlafx00_get_host_speed(shost);
		return;
	}

	switch (ha->link_data_rate) {
	switch (vha->hw->link_data_rate) {
	case PORT_SPEED_1GB:
		speed = FC_PORTSPEED_1GBIT;
		break;
@@ -2362,7 +2378,11 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
	case PORT_SPEED_64GB:
		speed = FC_PORTSPEED_64GBIT;
		break;
	default:
		speed = FC_PORTSPEED_UNKNOWN;
		break;
	}

	fc_host_speed(shost) = speed;
}

@@ -2370,7 +2390,7 @@ static void
qla2x00_get_host_port_type(struct Scsi_Host *shost)
{
	scsi_qla_host_t *vha = shost_priv(shost);
	uint32_t port_type = FC_PORTTYPE_UNKNOWN;
	uint32_t port_type;

	if (vha->vp_idx) {
		fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
@@ -2389,7 +2409,11 @@ qla2x00_get_host_port_type(struct Scsi_Host *shost)
	case ISP_CFG_F:
		port_type = FC_PORTTYPE_NPORT;
		break;
	default:
		port_type = FC_PORTTYPE_UNKNOWN;
		break;
	}

	fc_host_port_type(shost) = port_type;
}

@@ -2451,13 +2475,10 @@ qla2x00_get_starget_port_id(struct scsi_target *starget)
	fc_starget_port_id(starget) = port_id;
}

static void
static inline void
qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
{
	if (timeout)
		rport->dev_loss_tmo = timeout;
	else
		rport->dev_loss_tmo = 1;
	rport->dev_loss_tmo = timeout ? timeout : 1;
}

static void
+3 −1
Original line number Diff line number Diff line
@@ -4023,6 +4023,7 @@ struct qla_hw_data {
	uint8_t		fw_seriallink_options[4];
	uint16_t	fw_seriallink_options24[4];

	uint8_t		serdes_version[3];
	uint8_t		mpi_version[3];
	uint32_t	mpi_capabilities;
	uint8_t		phy_version[3];
@@ -4034,7 +4035,8 @@ struct qla_hw_data {
	/* Firmware dump information. */
	struct qla2xxx_fw_dump *fw_dump;
	uint32_t	fw_dump_len;
	int		fw_dumped;
	bool		fw_dumped;
	bool		fw_dump_mpi;
	unsigned long	fw_dump_cap_flags;
#define RISC_PAUSE_CMPL		0
#define DMA_SHUTDOWN_CMPL	1
+29 −48
Original line number Diff line number Diff line
@@ -2783,6 +2783,31 @@ qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
	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.
 * @vha: HA context
@@ -2855,31 +2880,8 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
			}
			rval = QLA_FUNCTION_FAILED;
		} else {
			/* Save port-speed */
			switch (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;
			}

			list->fp_speed = qla2x00_port_speed_capability(
			    be16_to_cpu(ct_rsp->rsp.gpsc.speed));
			ql_dbg(ql_dbg_disc, vha, 0x205b,
			    "GPSC ext entry - fpn "
			    "%8phN speeds=%04x speed=%04x.\n",
@@ -3048,29 +3050,8 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
			goto done;
		}
	} else {
		switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
		case BIT_15:
			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;
		}
		fcport->fp_speed = qla2x00_port_speed_capability(
		    be16_to_cpu(ct_rsp->rsp.gpsc.speed));

		ql_dbg(ql_dbg_disc, vha, 0x2054,
		    "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n",
+3 −1
Original line number Diff line number Diff line
@@ -714,7 +714,9 @@ skip_rio:
		ql_log(ql_log_warn, vha, 0x5003,
		    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh "
		    "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->flags.fw_init_done = 0;
		QLA_FW_STOPPED(ha);
+15 −10
Original line number Diff line number Diff line
@@ -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->in_mb = MBX_0;
	mcp->in_mb = MBX_1|MBX_0;
	mcp->tov = MBX_TOV_SECONDS;
	mcp->flags = 0;
	rval = qla2x00_mailbox_command(vha, mcp);

	if (rval != QLA_SUCCESS) {
		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 {
		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
		    "Done %s.\n", __func__);
@@ -1057,7 +1058,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
	if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
		mcp->in_mb |=
		    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->tov = MBX_TOV_SECONDS;
@@ -1124,6 +1125,9 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
	}

	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[1] = mcp->mb[11] >> 8;
		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,
	rval = qla2x00_mailbox_command(vha, mcp);

	/* Return mailbox statuses. */
	if (mb != NULL) {
	if (mb) {
		mb[0] = mcp->mb[0];
		mb[1] = mcp->mb[1];
		mb[3] = mcp->mb[3];
@@ -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[1] = loop_id;
	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->out_mb = MBX_9|MBX_3|MBX_2|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,
	rval = qla2x00_mailbox_command(vha, mcp);

	/* Return mailbox statuses. */
	if (mb != NULL) {
	if (mb) {
		mb[0] = mcp->mb[0];
		mb[1] = mcp->mb[1];
		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,
	if (rval != QLA_SUCCESS) {
		ql_dbg(ql_dbg_mbx, vha, 0x10e9,
		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
		if (mcp->mb[0] == MBS_COMMAND_ERROR &&
		    mcp->mb[1] == 0x22)
		if (mcp->mb[0] == MBS_COMMAND_ERROR && mcp->mb[1] == 0x22) {
			/* sfp is not there */
			rval = QLA_INTERFACE_ERROR;
		}
	} else {
		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
		    "Done %s.\n", __func__);
@@ -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[8] = MSW(risc_addr);
	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->flags = 0;
	rval = qla2x00_mailbox_command(vha, mcp);
	if (rval != QLA_SUCCESS) {
		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 {
		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
		    "Done %s.\n", __func__);