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

scsi: qla2xxx: Add vendor extended RDP additions and amendments

This patch adds RDP command support in the driver. With the help of new
ql2xsmartsan parameter, driver will use PUREX IOCB mode to send RDP command
to switch and will be able to receive various diagnostic data.

Link: https://lore.kernel.org/r/20200212214436.25532-8-hmadhani@marvell.com


Signed-off-by: default avatarJoe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 818c7f87
Loading
Loading
Loading
Loading
+135 −0
Original line number Diff line number Diff line
@@ -1267,6 +1267,9 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
#define RNID_TYPE_SET_VERSION	0x9
#define RNID_TYPE_ASIC_TEMP	0xC

#define ELS_CMD_MAP_SIZE	32
#define ELS_COMMAND_RDP		0x18

/*
 * Firmware state codes from get firmware state mailbox command
 */
@@ -3562,6 +3565,133 @@ struct qlfc_fw {
	uint32_t len;
};

struct rdp_req_payload {
	uint32_t	els_request;
	uint32_t	desc_list_len;

	/* NPIV descriptor */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint8_t  reserved;
		uint8_t  nport_id[3];
	} npiv_desc;
};

struct rdp_rsp_payload {
	struct {
		uint32_t cmd;
		uint32_t len;
	} hdr;

	/* LS Request Info descriptor */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint32_t req_payload_word_0;
	} ls_req_info_desc;

	/* LS Request Info descriptor */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint32_t req_payload_word_0;
	} ls_req_info_desc2;

	/* SFP diagnostic param descriptor */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint16_t temperature;
		uint16_t vcc;
		uint16_t tx_bias;
		uint16_t tx_power;
		uint16_t rx_power;
		uint16_t sfp_flags;
	} sfp_diag_desc;

	/* Port Speed Descriptor */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint16_t speed_capab;
		uint16_t operating_speed;
	} port_speed_desc;

	/* Link Error Status Descriptor */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint32_t link_fail_cnt;
		uint32_t loss_sync_cnt;
		uint32_t loss_sig_cnt;
		uint32_t prim_seq_err_cnt;
		uint32_t inval_xmit_word_cnt;
		uint32_t inval_crc_cnt;
		uint8_t  pn_port_phy_type;
		uint8_t  reserved[3];
	} ls_err_desc;

	/* Port name description with diag param */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint8_t WWNN[WWN_SIZE];
		uint8_t WWPN[WWN_SIZE];
	} port_name_diag_desc;

	/* Port Name desc for Direct attached Fx_Port or Nx_Port */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint8_t WWNN[WWN_SIZE];
		uint8_t WWPN[WWN_SIZE];
	} port_name_direct_desc;

	/* Buffer Credit descriptor */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint32_t fcport_b2b;
		uint32_t attached_fcport_b2b;
		uint32_t fcport_rtt;
	} buffer_credit_desc;

	/* Optical Element Data Descriptor */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint16_t high_alarm;
		uint16_t low_alarm;
		uint16_t high_warn;
		uint16_t low_warn;
		uint32_t element_flags;
	} optical_elmt_desc[5];

	/* Optical Product Data Descriptor */
	struct {
		uint32_t desc_tag;
		uint32_t desc_len;
		uint8_t  vendor_name[16];
		uint8_t  part_number[16];
		uint8_t  serial_number[16];
		uint8_t  revision[4];
		uint8_t  date[8];
	} optical_prod_desc;
};

#define RDP_DESC_LEN(obj) \
	(sizeof(obj) - sizeof((obj).desc_tag) - sizeof((obj).desc_len))

#define RDP_PORT_SPEED_1GB		BIT_15
#define RDP_PORT_SPEED_2GB		BIT_14
#define RDP_PORT_SPEED_4GB		BIT_13
#define RDP_PORT_SPEED_10GB		BIT_12
#define RDP_PORT_SPEED_8GB		BIT_11
#define RDP_PORT_SPEED_16GB		BIT_10
#define RDP_PORT_SPEED_32GB		BIT_9
#define RDP_PORT_SPEED_UNKNOWN		BIT_0

struct scsi_qlt_host {
	void *target_lport_ptr;
	struct mutex tgt_mutex;
@@ -3965,6 +4095,8 @@ struct qla_hw_data {

#define SFP_DEV_SIZE    512
#define SFP_BLOCK_SIZE  64
#define SFP_RTDI_LEN	SFP_BLOCK_SIZE

	void		*sfp_data;
	dma_addr_t	sfp_data_dma;

@@ -4424,6 +4556,8 @@ typedef struct scsi_qla_host {
#define ISP_ABORT_TO_ROM	33
#define VPORT_DELETE		34

#define PROCESS_PUREX_IOCB	63

	unsigned long	pci_flags;
#define PFLG_DISCONNECTED	0	/* PCI device removed */
#define PFLG_DRIVER_REMOVING	1	/* PCI driver .remove */
@@ -4532,6 +4666,7 @@ typedef struct scsi_qla_host {
	uint16_t ql2xexchoffld;
	uint16_t ql2xiniexchg;

	void	*purex_data;
	struct name_list_extended gnl;
	/* Count of active session/fcport */
	int fcport_count;
+44 −0
Original line number Diff line number Diff line
@@ -723,6 +723,50 @@ struct ct_entry_24xx {
	struct dsd64 dsd[2];
};

/*
 * ISP queue - PUREX IOCB entry structure definition
 */
#define PUREX_IOCB_TYPE		0x51	/* CT Pass Through IOCB entry */
typedef struct purex_entry_24xx {
	uint8_t entry_type;		/* Entry type. */
	uint8_t entry_count;		/* Entry count. */
	uint8_t sys_define;		/* System defined. */
	uint8_t entry_status;		/* Entry Status. */

	uint16_t reserved1;
	uint8_t vp_idx;
	uint8_t reserved2;

	uint16_t status_flags;
	uint16_t nport_handle;

	uint16_t frame_size;
	uint16_t trunc_frame_size;

	uint32_t rx_xchg_addr;

	uint8_t d_id[3];
	uint8_t r_ctl;

	uint8_t s_id[3];
	uint8_t cs_ctl;

	uint8_t f_ctl[3];
	uint8_t type;

	uint16_t seq_cnt;
	uint8_t df_ctl;
	uint8_t seq_id;

	uint16_t rx_id;
	uint16_t ox_id;
	uint32_t param;

	uint8_t els_frame_payload[20];
} purex_entry_24xx_t;

#define PUREX_ENTRY_SIZE	(sizeof(purex_entry_24xx_t))

/*
 * ISP queue - ELS Pass-Through entry structure definition.
 */
+3 −0
Original line number Diff line number Diff line
@@ -457,6 +457,9 @@ qla82xx_set_driver_version(scsi_qla_host_t *, char *);
extern int
qla25xx_set_driver_version(scsi_qla_host_t *, char *);

extern int
qla25xx_set_els_cmds_supported(scsi_qla_host_t *);

extern int
qla24xx_get_buffer_credits(scsi_qla_host_t *, struct buffer_credit_24xx *,
	dma_addr_t);
+14 −1
Original line number Diff line number Diff line
@@ -3708,6 +3708,10 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
			    "ISP Firmware failed checksum.\n");
			goto failed;
		}

		/* Enable PUREX PASSTHRU */
		if (ql2xsmartsan)
			qla25xx_set_els_cmds_supported(vha);
	} else
		goto failed;

@@ -3929,7 +3933,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)

	/* Update Serial Link options. */
	if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
		return;
		goto enable_purex;

	rval = qla2x00_set_serdes_params(vha,
	    le16_to_cpu(ha->fw_seriallink_options24[1]),
@@ -3939,6 +3943,12 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
		ql_log(ql_log_warn, vha, 0x0104,
		    "Unable to update Serial Link options (%x).\n", rval);
	}

enable_purex:
	if (ql2xsmartsan)
		ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;

	qla2x00_set_fw_options(vha, ha->fw_options);
}

void
@@ -8672,6 +8682,9 @@ qla83xx_update_fw_options(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;

	if (ql2xsmartsan)
		ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;

	qla2x00_set_fw_options(vha, ha->fw_options);
}

+10 −0
Original line number Diff line number Diff line
@@ -31,6 +31,13 @@ const char *const port_state_str[] = {
	"ONLINE"
};

static void qla24xx_purex_iocb(scsi_qla_host_t *vha, struct req_que *req,
	struct sts_entry_24xx *pkt)
{
	memcpy(vha->purex_data, pkt, PUREX_ENTRY_SIZE);
	set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
}

/**
 * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
 * @irq: interrupt number
@@ -3128,6 +3135,9 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
			qla_ctrlvp_completed(vha, rsp->req,
			    (struct vp_ctrl_entry_24xx *)pkt);
			break;
		case PUREX_IOCB_TYPE:
			qla24xx_purex_iocb(vha, rsp->req, pkt);
			break;
		default:
			/* Type Not Supported. */
			ql_dbg(ql_dbg_async, vha, 0x5042,
Loading