Commit 1f4c7c38 authored by Joe Carnuccio's avatar Joe Carnuccio Committed by Martin K. Petersen

scsi: qla2xxx: Add LR distance support from nvram bit

Signed-off-by: default avatarJoe Carnuccio <joe.carnuccio@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 92d4408e
...@@ -3471,7 +3471,7 @@ struct qla_hw_data { ...@@ -3471,7 +3471,7 @@ struct qla_hw_data {
uint32_t using_lr_setting:1; uint32_t using_lr_setting:1;
} flags; } flags;
u8 long_range_distance; /* 32G & above */ uint16_t long_range_distance; /* 32G & above */
#define LR_DISTANCE_5K 1 #define LR_DISTANCE_5K 1
#define LR_DISTANCE_10K 0 #define LR_DISTANCE_10K 0
...@@ -4027,6 +4027,7 @@ struct qla_hw_data { ...@@ -4027,6 +4027,7 @@ struct qla_hw_data {
struct qlt_hw_data tgt; struct qlt_hw_data tgt;
int allow_cna_fw_dump; int allow_cna_fw_dump;
uint32_t fw_ability_mask;
uint16_t min_link_speed; uint16_t min_link_speed;
uint16_t max_speed_sup; uint16_t max_speed_sup;
...@@ -4034,6 +4035,12 @@ struct qla_hw_data { ...@@ -4034,6 +4035,12 @@ struct qla_hw_data {
uint16_t nvme_last_rptd_aen; /* Last recorded aen count */ uint16_t nvme_last_rptd_aen; /* Last recorded aen count */
}; };
#define FW_ABILITY_MAX_SPEED_MASK 0xFUL
#define FW_ABILITY_MAX_SPEED_16G 0x0
#define FW_ABILITY_MAX_SPEED_32G 0x1
#define FW_ABILITY_MAX_SPEED(ha) \
(ha->fw_ability_mask & FW_ABILITY_MAX_SPEED_MASK)
/* /*
* Qlogic scsi host structure * Qlogic scsi host structure
*/ */
......
...@@ -1699,6 +1699,15 @@ struct access_chip_rsp_84xx { ...@@ -1699,6 +1699,15 @@ struct access_chip_rsp_84xx {
#define FAC_OPT_CMD_UNLOCK_SEMAPHORE 0x04 #define FAC_OPT_CMD_UNLOCK_SEMAPHORE 0x04
#define FAC_OPT_CMD_GET_SECTOR_SIZE 0x05 #define FAC_OPT_CMD_GET_SECTOR_SIZE 0x05
/* enhanced features bit definitions */
#define NEF_LR_DIST_ENABLE BIT_0
/* LR Distance bit positions */
#define LR_DIST_NV_POS 2
#define LR_DIST_FW_POS 12
#define LR_DIST_FW_SHIFT (LR_DIST_FW_POS - LR_DIST_NV_POS)
#define LR_DIST_FW_FIELD(x) ((x) << LR_DIST_FW_SHIFT & 0xf000)
struct nvram_81xx { struct nvram_81xx {
/* NVRAM header. */ /* NVRAM header. */
uint8_t id[4]; uint8_t id[4];
...@@ -1841,16 +1850,13 @@ struct nvram_81xx { ...@@ -1841,16 +1850,13 @@ struct nvram_81xx {
uint8_t reserved_21[16]; uint8_t reserved_21[16];
uint16_t reserved_22[3]; uint16_t reserved_22[3];
/* /* Offset 406 (0x196) Enhanced Features
* BIT 0 = Extended BB credits for LR * BIT 0 = Extended BB credits for LR
* BIT 1 = Virtual Fabric Enable * BIT 1 = Virtual Fabric Enable
* BIT 2 = Enhanced Features Unused * BIT 2-5 = Distance Support if BIT 0 is on
* BIT 3-7 = Enhanced Features Reserved * BIT 6-15 = Unused
*/ */
/* Enhanced Features */ uint16_t enhanced_features;
uint8_t enhanced_features;
uint8_t reserved_23;
uint16_t reserved_24[4]; uint16_t reserved_24[4];
/* Offset 416. */ /* Offset 416. */
......
...@@ -567,6 +567,28 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr, ...@@ -567,6 +567,28 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
#define EXTENDED_BB_CREDITS BIT_0 #define EXTENDED_BB_CREDITS BIT_0
#define NVME_ENABLE_FLAG BIT_3 #define NVME_ENABLE_FLAG BIT_3
static inline uint16_t qla25xx_set_sfp_lr_dist(struct qla_hw_data *ha)
{
uint16_t mb4 = BIT_0;
if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
mb4 |= ha->long_range_distance << LR_DIST_FW_POS;
return mb4;
}
static inline uint16_t qla25xx_set_nvr_lr_dist(struct qla_hw_data *ha)
{
uint16_t mb4 = BIT_0;
if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
struct nvram_81xx *nv = ha->nvram;
mb4 |= LR_DIST_FW_FIELD(nv->enhanced_features);
}
return mb4;
}
/* /*
* qla2x00_execute_fw * qla2x00_execute_fw
...@@ -602,27 +624,25 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) ...@@ -602,27 +624,25 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
mcp->mb[2] = LSW(risc_addr); mcp->mb[2] = LSW(risc_addr);
mcp->mb[3] = 0; mcp->mb[3] = 0;
mcp->mb[4] = 0; mcp->mb[4] = 0;
ha->flags.using_lr_setting = 0;
if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
IS_QLA27XX(ha)) { IS_QLA27XX(ha)) {
if (ql2xautodetectsfp) { if (ql2xautodetectsfp) {
if (ha->flags.detected_lr_sfp) { if (ha->flags.detected_lr_sfp) {
mcp->mb[4] |= EXTENDED_BB_CREDITS; mcp->mb[4] |=
if (IS_QLA27XX(ha)) qla25xx_set_sfp_lr_dist(ha);
mcp->mb[4] |=
(u16)ha->long_range_distance << 12;
ha->flags.using_lr_setting = 1; ha->flags.using_lr_setting = 1;
} }
} else { } else {
struct nvram_81xx *nv = ha->nvram; struct nvram_81xx *nv = ha->nvram;
/* set LR distance if specified in nvram */
if (nv->enhanced_features & if (nv->enhanced_features &
EXTENDED_BB_CREDITS) { NEF_LR_DIST_ENABLE) {
mcp->mb[4] |= EXTENDED_BB_CREDITS; mcp->mb[4] |=
qla25xx_set_nvr_lr_dist(ha);
ha->flags.using_lr_setting = 1; ha->flags.using_lr_setting = 1;
} }
} }
} else {
ha->flags.using_lr_setting = 0;
} }
if (ql2xnvmeenable && IS_QLA27XX(ha)) if (ql2xnvmeenable && IS_QLA27XX(ha))
...@@ -648,7 +668,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) ...@@ -648,7 +668,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD; mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1; mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
mcp->in_mb |= MBX_1; mcp->in_mb |= MBX_3 | MBX_2 | MBX_1;
} else { } else {
mcp->mb[1] = LSW(risc_addr); mcp->mb[1] = LSW(risc_addr);
mcp->out_mb |= MBX_1; mcp->out_mb |= MBX_1;
...@@ -667,10 +687,13 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) ...@@ -667,10 +687,13 @@ 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)) {
ha->fw_ability_mask = mcp->mb[3] << 16 | mcp->mb[2];
ql_dbg(ql_dbg_mbx, vha, 0x119a,
"fw_ability_mask=%x.\n", ha->fw_ability_mask);
ql_dbg(ql_dbg_mbx, vha, 0x1027, ql_dbg(ql_dbg_mbx, vha, 0x1027,
"exchanges=%x.\n", mcp->mb[1]); "exchanges=%x.\n", mcp->mb[1]);
if (IS_QLA27XX(ha)) { if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
ha->max_speed_sup = mcp->mb[2] & 1; ha->max_speed_sup = mcp->mb[2] & BIT_0;
ql_dbg(ql_dbg_mbx, vha, 0x119b, ql_dbg(ql_dbg_mbx, vha, 0x119b,
"Maximum speed supported=%s.\n", "Maximum speed supported=%s.\n",
ha->max_speed_sup ? "32Gps" : "16Gps"); ha->max_speed_sup ? "32Gps" : "16Gps");
...@@ -682,15 +705,12 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) ...@@ -682,15 +705,12 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
mcp->mb[5] == 4 ? "16Gps" : mcp->mb[5] == 4 ? "16Gps" :
mcp->mb[5] == 3 ? "8Gps" : mcp->mb[5] == 3 ? "8Gps" :
mcp->mb[5] == 2 ? "4Gps" : mcp->mb[5] == 2 ? "4Gps" :
"unknown"); "unknown");
} }
} }
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1027,
"Done.\n");
} else {
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
"Done %s.\n", __func__);
} }
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
"Done.\n");
} }
return rval; return rval;
......
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