Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92d4408e authored by Sawan Chandak's avatar Sawan Chandak Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Add support for minimum link speed

parent 343f7def
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -1481,6 +1481,38 @@ qla2x00_pep_version_show(struct device *dev, struct device_attribute *attr,
	    ha->pep_version[0], ha->pep_version[1], ha->pep_version[2]);
}

static ssize_t
qla2x00_min_link_speed_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))
		return scnprintf(buf, PAGE_SIZE, "\n");

	return scnprintf(buf, PAGE_SIZE, "%s\n",
	    ha->min_link_speed == 5 ? "32Gps" :
	    ha->min_link_speed == 4 ? "16Gps" :
	    ha->min_link_speed == 3 ? "8Gps" :
	    ha->min_link_speed == 2 ? "4Gps" :
	    ha->min_link_speed != 0 ? "unknown" : "");
}

static ssize_t
qla2x00_max_speed_sup_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))
		return scnprintf(buf, PAGE_SIZE, "\n");

	return scnprintf(buf, PAGE_SIZE, "%s\n",
	    ha->max_speed_sup ? "32Gps" : "16Gps");
}

static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
@@ -1526,6 +1558,8 @@ static DEVICE_ATTR(allow_cna_fw_dump, S_IRUGO | S_IWUSR,
		   qla2x00_allow_cna_fw_dump_show,
		   qla2x00_allow_cna_fw_dump_store);
static DEVICE_ATTR(pep_version, S_IRUGO, qla2x00_pep_version_show, NULL);
static DEVICE_ATTR(min_link_speed, S_IRUGO, qla2x00_min_link_speed_show, NULL);
static DEVICE_ATTR(max_speed_sup, S_IRUGO, qla2x00_max_speed_sup_show, NULL);

struct device_attribute *qla2x00_host_attrs[] = {
	&dev_attr_driver_version,
@@ -1560,6 +1594,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
	&dev_attr_fw_dump_size,
	&dev_attr_allow_cna_fw_dump,
	&dev_attr_pep_version,
	&dev_attr_min_link_speed,
	&dev_attr_max_speed_sup,
	NULL,
};

+4 −0
Original line number Diff line number Diff line
@@ -902,6 +902,7 @@ struct mbx_cmd_32 {
#define MBA_SHUTDOWN_REQUESTED	0x8062	/* Shutdown Requested */
#define MBA_TEMPERATURE_ALERT	0x8070	/* Temperature Alert */
#define MBA_DPORT_DIAGNOSTICS	0x8080	/* D-port Diagnostics */
#define MBA_TRANS_INSERT	0x8130	/* Transceiver Insertion */
#define MBA_FW_INIT_FAILURE	0x8401	/* Firmware initialization failure */
#define MBA_MIRROR_LUN_CHANGE	0x8402	/* Mirror LUN State Change
					   Notification */
@@ -4026,6 +4027,8 @@ struct qla_hw_data {

	struct qlt_hw_data tgt;
	int	allow_cna_fw_dump;
	uint16_t min_link_speed;
	uint16_t max_speed_sup;

	atomic_t        nvme_active_aen_cnt;
	uint16_t        nvme_last_rptd_aen;             /* Last recorded aen count */
@@ -4212,6 +4215,7 @@ typedef struct scsi_qla_host {
	int fcport_count;
	wait_queue_head_t fcport_waitQ;
	wait_queue_head_t vref_waitq;
	uint8_t min_link_speed_feat;
} scsi_qla_host_t;

struct qla27xx_image_status {
+3 −1
Original line number Diff line number Diff line
@@ -1745,7 +1745,9 @@ struct nvram_81xx {
	uint16_t reserved_6_3[14];

	/* Offset 192. */
	uint16_t reserved_7[32];
	uint8_t min_link_speed;
	uint8_t reserved_7_0;
	uint16_t reserved_7[31];

	/*
	 * BIT 0  = Enable spinup delay
+5 −0
Original line number Diff line number Diff line
@@ -1233,6 +1233,11 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
			schedule_work(&ha->board_disable);
		break;

	case MBA_TRANS_INSERT:
		ql_dbg(ql_dbg_async, vha, 0x5091,
		    "Transceiver Insertion: %04x\n", mb[1]);
		break;

	default:
		ql_dbg(ql_dbg_async, vha, 0x5057,
		    "Unknown AEN:%04x %04x %04x %04x\n",
+43 −3
Original line number Diff line number Diff line
@@ -628,6 +628,19 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
		if (ql2xnvmeenable && IS_QLA27XX(ha))
			mcp->mb[4] |= NVME_ENABLE_FLAG;

		if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
			struct nvram_81xx *nv = ha->nvram;
			/* set minimum speed if specified in nvram */
			if (nv->min_link_speed >= 2 &&
			    nv->min_link_speed <= 5) {
				mcp->mb[4] |= BIT_4;
				mcp->mb[11] = nv->min_link_speed;
				mcp->out_mb |= MBX_11;
				mcp->in_mb |= BIT_5;
				vha->min_link_speed_feat = nv->min_link_speed;
			}
		}

		if (ha->flags.exlogins_enabled)
			mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;

@@ -654,8 +667,26 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
	} else {
		if (IS_FWI2_CAPABLE(ha)) {
			ql_dbg(ql_dbg_mbx, vha, 0x1027,
			    "exchanges=%x.\n", mcp->mb[1]);
			if (IS_QLA27XX(ha)) {
				ha->max_speed_sup = mcp->mb[2] & 1;
				ql_dbg(ql_dbg_mbx, vha, 0x119b,
				    "Maximum speed supported=%s.\n",
				    ha->max_speed_sup ? "32Gps" : "16Gps");
				if (vha->min_link_speed_feat) {
					ha->min_link_speed = mcp->mb[5];
					ql_dbg(ql_dbg_mbx, vha, 0x119c,
					    "Minimum speed set=%s.\n",
					    mcp->mb[5] == 5 ? "32Gps" :
					    mcp->mb[5] == 4 ? "16Gps" :
					    mcp->mb[5] == 3 ? "8Gps" :
					    mcp->mb[5] == 2 ? "4Gps" :
					    "unknown");
				}
			}
			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1027,
			    "Done exchanges=%x.\n", mcp->mb[1]);
			    "Done.\n");
		} else {
			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
			    "Done %s.\n", __func__);
@@ -1687,7 +1718,11 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
		    "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
	} else {
		/*EMPTY*/
		if (IS_QLA27XX(ha)) {
			if (mcp->mb[2] == 6 || mcp->mb[3] == 2)
				ql_dbg(ql_dbg_mbx, vha, 0x119d,
				    "Invalid SFP/Validation Failed\n");
		}
		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
		    "Done %s.\n", __func__);
	}
@@ -1892,6 +1927,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
	int rval;
	mbx_cmd_t mc;
	mbx_cmd_t *mcp = &mc;
	struct qla_hw_data *ha = vha->hw;

	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
	    "Entered %s.\n", __func__);
@@ -1920,7 +1956,11 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
		/*EMPTY*/
		ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
	} else {
		/*EMPTY*/
		if (IS_QLA27XX(ha)) {
			if (mcp->mb[2] == 6 || mcp->mb[3] == 2)
				ql_dbg(ql_dbg_mbx, vha, 0x119e,
				    "Invalid SFP/Validation Failed\n");
		}
		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
		    "Done %s.\n", __func__);
	}