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

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

scsi: qla2xxx: Add LR distance support from nvram bit

parent 92d4408e
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -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
 */
+15 −9
Original line number Diff line number Diff line
@@ -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];

	/*
	/* Offset 406 (0x196) Enhanced Features
	 * BIT 0    = Extended BB credits for LR
	 * BIT 1    = Virtual Fabric Enable
	 * BIT 2 = Enhanced Features Unused
	 * BIT 3-7 = Enhanced Features Reserved
	 * 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. */
+38 −18
Original line number Diff line number Diff line
@@ -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;
					    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");
@@ -685,12 +708,9 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
						"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;