scsi: qla2xxx: Add support for minimum link speed
Signed-off-by: Sawan Chandak <sawan.chandak@cavium.com> Signed-off-by: Joe Carnuccio <joe.carnuccio@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
committed by
Martin K. Petersen
parent
343f7def32
commit
92d4408e34
@@ -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]);
|
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(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
|
||||||
static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_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);
|
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_show,
|
||||||
qla2x00_allow_cna_fw_dump_store);
|
qla2x00_allow_cna_fw_dump_store);
|
||||||
static DEVICE_ATTR(pep_version, S_IRUGO, qla2x00_pep_version_show, NULL);
|
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[] = {
|
struct device_attribute *qla2x00_host_attrs[] = {
|
||||||
&dev_attr_driver_version,
|
&dev_attr_driver_version,
|
||||||
@@ -1560,6 +1594,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
|
|||||||
&dev_attr_fw_dump_size,
|
&dev_attr_fw_dump_size,
|
||||||
&dev_attr_allow_cna_fw_dump,
|
&dev_attr_allow_cna_fw_dump,
|
||||||
&dev_attr_pep_version,
|
&dev_attr_pep_version,
|
||||||
|
&dev_attr_min_link_speed,
|
||||||
|
&dev_attr_max_speed_sup,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -902,6 +902,7 @@ struct mbx_cmd_32 {
|
|||||||
#define MBA_SHUTDOWN_REQUESTED 0x8062 /* Shutdown Requested */
|
#define MBA_SHUTDOWN_REQUESTED 0x8062 /* Shutdown Requested */
|
||||||
#define MBA_TEMPERATURE_ALERT 0x8070 /* Temperature Alert */
|
#define MBA_TEMPERATURE_ALERT 0x8070 /* Temperature Alert */
|
||||||
#define MBA_DPORT_DIAGNOSTICS 0x8080 /* D-port Diagnostics */
|
#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_FW_INIT_FAILURE 0x8401 /* Firmware initialization failure */
|
||||||
#define MBA_MIRROR_LUN_CHANGE 0x8402 /* Mirror LUN State Change
|
#define MBA_MIRROR_LUN_CHANGE 0x8402 /* Mirror LUN State Change
|
||||||
Notification */
|
Notification */
|
||||||
@@ -4026,6 +4027,8 @@ struct qla_hw_data {
|
|||||||
|
|
||||||
struct qlt_hw_data tgt;
|
struct qlt_hw_data tgt;
|
||||||
int allow_cna_fw_dump;
|
int allow_cna_fw_dump;
|
||||||
|
uint16_t min_link_speed;
|
||||||
|
uint16_t max_speed_sup;
|
||||||
|
|
||||||
atomic_t nvme_active_aen_cnt;
|
atomic_t nvme_active_aen_cnt;
|
||||||
uint16_t nvme_last_rptd_aen; /* Last recorded aen count */
|
uint16_t nvme_last_rptd_aen; /* Last recorded aen count */
|
||||||
@@ -4212,6 +4215,7 @@ typedef struct scsi_qla_host {
|
|||||||
int fcport_count;
|
int fcport_count;
|
||||||
wait_queue_head_t fcport_waitQ;
|
wait_queue_head_t fcport_waitQ;
|
||||||
wait_queue_head_t vref_waitq;
|
wait_queue_head_t vref_waitq;
|
||||||
|
uint8_t min_link_speed_feat;
|
||||||
} scsi_qla_host_t;
|
} scsi_qla_host_t;
|
||||||
|
|
||||||
struct qla27xx_image_status {
|
struct qla27xx_image_status {
|
||||||
|
|||||||
@@ -1745,7 +1745,9 @@ struct nvram_81xx {
|
|||||||
uint16_t reserved_6_3[14];
|
uint16_t reserved_6_3[14];
|
||||||
|
|
||||||
/* Offset 192. */
|
/* 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
|
* BIT 0 = Enable spinup delay
|
||||||
|
|||||||
@@ -1233,6 +1233,11 @@ global_port_update:
|
|||||||
schedule_work(&ha->board_disable);
|
schedule_work(&ha->board_disable);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MBA_TRANS_INSERT:
|
||||||
|
ql_dbg(ql_dbg_async, vha, 0x5091,
|
||||||
|
"Transceiver Insertion: %04x\n", mb[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ql_dbg(ql_dbg_async, vha, 0x5057,
|
ql_dbg(ql_dbg_async, vha, 0x5057,
|
||||||
"Unknown AEN:%04x %04x %04x %04x\n",
|
"Unknown AEN:%04x %04x %04x %04x\n",
|
||||||
|
|||||||
@@ -628,6 +628,19 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
|
|||||||
if (ql2xnvmeenable && IS_QLA27XX(ha))
|
if (ql2xnvmeenable && IS_QLA27XX(ha))
|
||||||
mcp->mb[4] |= NVME_ENABLE_FLAG;
|
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)
|
if (ha->flags.exlogins_enabled)
|
||||||
mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;
|
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]);
|
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
|
||||||
} else {
|
} else {
|
||||||
if (IS_FWI2_CAPABLE(ha)) {
|
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,
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1027,
|
||||||
"Done exchanges=%x.\n", mcp->mb[1]);
|
"Done.\n");
|
||||||
} else {
|
} else {
|
||||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
|
||||||
"Done %s.\n", __func__);
|
"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",
|
"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]);
|
rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
|
||||||
} else {
|
} 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,
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
|
||||||
"Done %s.\n", __func__);
|
"Done %s.\n", __func__);
|
||||||
}
|
}
|
||||||
@@ -1892,6 +1927,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
|
|||||||
int rval;
|
int rval;
|
||||||
mbx_cmd_t mc;
|
mbx_cmd_t mc;
|
||||||
mbx_cmd_t *mcp = &mc;
|
mbx_cmd_t *mcp = &mc;
|
||||||
|
struct qla_hw_data *ha = vha->hw;
|
||||||
|
|
||||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
|
||||||
"Entered %s.\n", __func__);
|
"Entered %s.\n", __func__);
|
||||||
@@ -1920,7 +1956,11 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
|
|||||||
/*EMPTY*/
|
/*EMPTY*/
|
||||||
ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
|
ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
|
||||||
} else {
|
} 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,
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
|
||||||
"Done %s.\n", __func__);
|
"Done %s.\n", __func__);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user