diff options
author | Joe Carnuccio <joe.carnuccio@cavium.com> | 2017-08-24 01:05:17 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-08-25 05:29:29 +0300 |
commit | 1f4c7c380b2f0cbd060b8582a1723b3a98f354d2 (patch) | |
tree | 256e423e45bdc0b76e20264d4f2b272957803570 | |
parent | 92d4408e34667f521cda7192fc8dda3da25d45bc (diff) | |
download | linux-1f4c7c380b2f0cbd060b8582a1723b3a98f354d2.tar.xz |
scsi: qla2xxx: Add LR distance support from nvram bit
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>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 24 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 56 |
3 files changed, 61 insertions, 28 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 0f80b812f4a7..486c075998f6 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3471,7 +3471,7 @@ struct qla_hw_data { uint32_t using_lr_setting:1; } flags; - u8 long_range_distance; /* 32G & above */ + uint16_t long_range_distance; /* 32G & above */ #define LR_DISTANCE_5K 1 #define LR_DISTANCE_10K 0 @@ -4027,6 +4027,7 @@ struct qla_hw_data { struct qlt_hw_data tgt; int allow_cna_fw_dump; + uint32_t fw_ability_mask; uint16_t min_link_speed; uint16_t max_speed_sup; @@ -4034,6 +4035,12 @@ struct qla_hw_data { 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 */ diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 94eb1694fc3e..bec641aae7b3 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -1699,6 +1699,15 @@ struct access_chip_rsp_84xx { #define FAC_OPT_CMD_UNLOCK_SEMAPHORE 0x04 #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 { /* NVRAM header. */ uint8_t id[4]; @@ -1841,16 +1850,13 @@ struct nvram_81xx { uint8_t reserved_21[16]; uint16_t reserved_22[3]; - /* - * BIT 0 = Extended BB credits for LR - * BIT 1 = Virtual Fabric Enable - * BIT 2 = Enhanced Features Unused - * BIT 3-7 = Enhanced Features Reserved + /* Offset 406 (0x196) Enhanced Features + * BIT 0 = Extended BB credits for LR + * BIT 1 = Virtual Fabric Enable + * BIT 2-5 = Distance Support if BIT 0 is on + * BIT 6-15 = Unused */ - /* Enhanced Features */ - uint8_t enhanced_features; - - uint8_t reserved_23; + uint16_t enhanced_features; uint16_t reserved_24[4]; /* Offset 416. */ diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 32bbbd50567d..99502fa90810 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -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 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 @@ -602,27 +624,25 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) mcp->mb[2] = LSW(risc_addr); mcp->mb[3] = 0; mcp->mb[4] = 0; + ha->flags.using_lr_setting = 0; if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { if (ql2xautodetectsfp) { if (ha->flags.detected_lr_sfp) { - mcp->mb[4] |= EXTENDED_BB_CREDITS; - if (IS_QLA27XX(ha)) - mcp->mb[4] |= - (u16)ha->long_range_distance << 12; + mcp->mb[4] |= + qla25xx_set_sfp_lr_dist(ha); ha->flags.using_lr_setting = 1; } } else { struct nvram_81xx *nv = ha->nvram; - + /* set LR distance if specified in nvram */ if (nv->enhanced_features & - EXTENDED_BB_CREDITS) { - mcp->mb[4] |= EXTENDED_BB_CREDITS; + NEF_LR_DIST_ENABLE) { + mcp->mb[4] |= + qla25xx_set_nvr_lr_dist(ha); ha->flags.using_lr_setting = 1; } } - } else { - ha->flags.using_lr_setting = 0; } if (ql2xnvmeenable && IS_QLA27XX(ha)) @@ -648,7 +668,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD; 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 { mcp->mb[1] = LSW(risc_addr); mcp->out_mb |= MBX_1; @@ -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]); } else { 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, "exchanges=%x.\n", mcp->mb[1]); - if (IS_QLA27XX(ha)) { - ha->max_speed_sup = mcp->mb[2] & 1; + if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { + ha->max_speed_sup = mcp->mb[2] & BIT_0; ql_dbg(ql_dbg_mbx, vha, 0x119b, "Maximum speed supported=%s.\n", ha->max_speed_sup ? "32Gps" : "16Gps"); @@ -682,15 +705,12 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) mcp->mb[5] == 4 ? "16Gps" : mcp->mb[5] == 3 ? "8Gps" : 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; |