Commit e63d2ea8 authored by Martin K. Petersen's avatar Martin K. Petersen
Browse files

Merge patch series "qla2xxx driver enhancements"

Nilesh Javali <njavali@marvell.com> says:

Please apply the qla2xxx driver enhancements to the SCSI tree at your
earliest convenience.

Link: https://lore.kernel.org/r/20221222043933.2825-1-njavali@marvell.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents 8fe66bad f7d1ba35
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -2732,7 +2732,7 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
	spin_lock_irqsave(host->host_lock, flags);
	/* Confirm port has not reappeared before clearing pointers. */
	if (rport->port_state != FC_PORTSTATE_ONLINE) {
		fcport->rport = fcport->drport = NULL;
		fcport->rport = NULL;
		*((fc_port_t **)rport->dd_data) = NULL;
	}
	spin_unlock_irqrestore(host->host_lock, flags);
@@ -3171,8 +3171,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)

	set_bit(VPORT_DELETE, &vha->dpc_flags);

	while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
	    test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
	while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))
		msleep(1000);


+31 −14
Original line number Diff line number Diff line
@@ -384,6 +384,13 @@ struct els_reject {
struct req_que;
struct qla_tgt_sess;

struct qla_buf_dsc {
	u16 tag;
#define TAG_FREED 0xffff
	void *buf;
	dma_addr_t buf_dma;
};

/*
 * SCSI Request Block
 */
@@ -392,14 +399,16 @@ struct srb_cmd {
	uint32_t request_sense_length;
	uint32_t fw_sense_length;
	uint8_t *request_sense_ptr;
	struct ct6_dsd *ct6_ctx;
	struct crc_context *crc_ctx;
	struct ct6_dsd ct6_ctx;
	struct qla_buf_dsc buf_dsc;
};

/*
 * SRB flag definitions
 */
#define SRB_DMA_VALID			BIT_0	/* Command sent to ISP */
#define SRB_GOT_BUF			BIT_1
#define SRB_FCP_CMND_DMA_VALID		BIT_12	/* DIF: DSD List valid */
#define SRB_CRC_CTX_DMA_VALID		BIT_2	/* DIF: context DMA valid */
#define SRB_CRC_PROT_DMA_VALID		BIT_4	/* DIF: prot DMA valid */
@@ -2485,7 +2494,6 @@ struct ct_sns_desc {

enum discovery_state {
	DSC_DELETED,
	DSC_GNN_ID,
	DSC_GNL,
	DSC_LOGIN_PEND,
	DSC_LOGIN_FAILED,
@@ -2596,7 +2604,7 @@ typedef struct fc_port {

	int login_retry;

	struct fc_rport *rport, *drport;
	struct fc_rport *rport;
	u32 supported_classes;

	uint8_t fc4_type;
@@ -2699,7 +2707,6 @@ extern const char *const port_state_str[5];

static const char *const port_dstate_str[] = {
	[DSC_DELETED]		= "DELETED",
	[DSC_GNN_ID]		= "GNN_ID",
	[DSC_GNL]		= "GNL",
	[DSC_LOGIN_PEND]	= "LOGIN_PEND",
	[DSC_LOGIN_FAILED]	= "LOGIN_FAILED",
@@ -3462,6 +3469,7 @@ struct qla_msix_entry {
	int have_irq;
	int in_use;
	uint32_t vector;
	uint32_t vector_base0;
	uint16_t entry;
	char name[30];
	void *handle;
@@ -3479,7 +3487,6 @@ enum qla_work_type {
	QLA_EVT_ASYNC_ADISC,
	QLA_EVT_UEVENT,
	QLA_EVT_AENFX,
	QLA_EVT_GPNID,
	QLA_EVT_UNMAP,
	QLA_EVT_NEW_SESS,
	QLA_EVT_GPDB,
@@ -3493,7 +3500,6 @@ enum qla_work_type {
	QLA_EVT_GPNFT,
	QLA_EVT_GPNFT_DONE,
	QLA_EVT_GNNFT_DONE,
	QLA_EVT_GNNID,
	QLA_EVT_GFPNID,
	QLA_EVT_SP_RETRY,
	QLA_EVT_IIDMA,
@@ -3534,9 +3540,6 @@ struct qla_work_evt {
		struct {
			srb_t *sp;
		} iosb;
		struct {
			port_id_t id;
		} gpnid;
		struct {
			port_id_t id;
			u8 port_name[8];
@@ -3544,7 +3547,7 @@ struct qla_work_evt {
			void *pla;
			u8 fc4_type;
		} new_sess;
		struct { /*Get PDB, Get Speed, update fcport, gnl, gidpn */
		struct { /*Get PDB, Get Speed, update fcport, gnl */
			fc_port_t *fcport;
			u8 opt;
		} fcport;
@@ -3729,6 +3732,19 @@ struct qla_fw_resources {

#define QLA_IOCB_PCT_LIMIT 95

struct  qla_buf_pool {
	u16 num_bufs;
	u16 num_active;
	u16 max_used;
	u16 num_alloc;
	u16 prev_max;
	u16 pad;
	uint32_t take_snapshot:1;
	unsigned long *buf_map;
	void **buf_array;
	dma_addr_t *dma_array;
};

/*Queue pair data structure */
struct qla_qpair {
	spinlock_t qp_lock;
@@ -3782,6 +3798,7 @@ struct qla_qpair {
	struct qla_tgt_counters tgt_counters;
	uint16_t cpuid;
	struct qla_fw_resources fwres ____cacheline_aligned;
	struct  qla_buf_pool buf_pool;
	u32	cmd_cnt;
	u32	cmd_completion_cnt;
	u32	prev_completion_cnt;
@@ -3942,7 +3959,6 @@ struct qlt_hw_data {
	__le32 __iomem *atio_q_out;

	const struct qla_tgt_func_tmpl *tgt_ops;
	struct qla_tgt_vp_map *tgt_vp_map;

	int saved_set;
	__le16	saved_exchange_count;
@@ -4110,6 +4126,7 @@ struct qla_hw_data {
	struct req_que **req_q_map;
	struct rsp_que **rsp_q_map;
	struct qla_qpair **queue_pair_map;
	struct qla_qpair **qp_cpu_map;
	unsigned long req_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)];
	unsigned long rsp_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)];
	unsigned long qpair_qid_map[(QLA_MAX_QUEUES / 8)
@@ -4766,6 +4783,7 @@ struct qla_hw_data {
	spinlock_t sadb_lock;	/* protects list */
	struct els_reject elsrej;
	u8 edif_post_stop_cnt_down;
	struct qla_vp_map *vp_map;
};

#define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES))
@@ -4861,6 +4879,7 @@ typedef struct scsi_qla_host {
#define LOOP_READY	5
#define LOOP_DEAD	6

	unsigned long   buf_expired;
	unsigned long   relogin_jif;
	unsigned long   dpc_flags;
#define RESET_MARKER_NEEDED	0	/* Send marker to ISP. */
@@ -4876,7 +4895,6 @@ typedef struct scsi_qla_host {
#define ISP_ABORT_RETRY		10	/* ISP aborted. */
#define BEACON_BLINK_NEEDED	11
#define REGISTER_FDMI_NEEDED	12
#define FCPORT_UPDATE_NEEDED	13
#define VP_DPC_NEEDED		14	/* wake up for VP dpc handling */
#define UNLOADING		15
#define NPIV_CONFIG_NEEDED	16
@@ -5026,7 +5044,6 @@ typedef struct scsi_qla_host {
	uint8_t n2n_port_name[WWN_SIZE];
	uint16_t	n2n_id;
	__le16 dport_data[4];
	struct list_head gpnid_list;
	struct fab_scan scan;
	uint8_t	scm_fabric_connection_flags;

@@ -5068,7 +5085,7 @@ struct qla27xx_image_status {
#define SET_AL_PA	2
#define RESET_VP_IDX	3
#define RESET_AL_PA	4
struct qla_tgt_vp_map {
struct qla_vp_map {
	uint8_t	idx;
	scsi_qla_host_t *vha;
};
+59 −30
Original line number Diff line number Diff line
@@ -479,6 +479,49 @@ void qla2x00_release_all_sadb(struct scsi_qla_host *vha, struct fc_port *fcport)
	spin_unlock_irqrestore(&ha->sadb_lock, flags);
}

/**
 * qla_delete_n2n_sess_and_wait: search for N2N session, tear it down and
 *    wait for tear down to complete.  In N2N topology, there is only one
 *    session being active in tracking the remote device.
 * @vha: host adapter pointer
 * return code:  0 - found the session and completed the tear down.
 *	1 - timeout occurred.  Caller to use link bounce to reset.
 */
static int qla_delete_n2n_sess_and_wait(scsi_qla_host_t *vha)
{
	struct fc_port *fcport;
	int rc = -EIO;
	ulong expire = jiffies + 23 * HZ;

	if (!N2N_TOPO(vha->hw))
		return 0;

	fcport = NULL;
	list_for_each_entry(fcport, &vha->vp_fcports, list) {
		if (!fcport->n2n_flag)
			continue;

		ql_dbg(ql_dbg_disc, fcport->vha, 0x2016,
		       "%s reset sess at app start \n", __func__);

		qla_edif_sa_ctl_init(vha, fcport);
		qlt_schedule_sess_for_deletion(fcport);

		while (time_before_eq(jiffies, expire)) {
			if (fcport->disc_state != DSC_DELETE_PEND) {
				rc = 0;
				break;
			}
			msleep(1);
		}

		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
		break;
	}

	return rc;
}

/**
 * qla_edif_app_start:  application has announce its present
 * @vha: host adapter pointer
@@ -518,18 +561,17 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
			fcport->n2n_link_reset_cnt = 0;

		if (vha->hw->flags.n2n_fw_acc_sec) {
			list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list)
				qla_edif_sa_ctl_init(vha, fcport);

			bool link_bounce = false;
			/*
			 * While authentication app was not running, remote device
			 * could still try to login with this local port.  Let's
			 * clear the state and try again.
			 * reset the session, reconnect and re-authenticate.
			 */
			qla2x00_wait_for_sess_deletion(vha);
			if (qla_delete_n2n_sess_and_wait(vha))
				link_bounce = true;

			/* bounce the link to get the other guy to relogin */
			if (!vha->hw->flags.n2n_bigger) {
			/* bounce the link to start login */
			if (!vha->hw->flags.n2n_bigger || link_bounce) {
				set_bit(N2N_LINK_RESET, &vha->dpc_flags);
				qla2xxx_wake_dpc(vha);
			}
@@ -925,7 +967,9 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
			if (!(fcport->flags & FCF_FCSP_DEVICE))
				continue;

			tdid = app_req.remote_pid;
			tdid.b.domain = app_req.remote_pid.domain;
			tdid.b.area = app_req.remote_pid.area;
			tdid.b.al_pa = app_req.remote_pid.al_pa;

			ql_dbg(ql_dbg_edif, vha, 0x2058,
			    "APP request entry - portid=%06x.\n", tdid.b24);
@@ -3007,26 +3051,16 @@ qla28xx_start_scsi_edif(srb_t *sp)
			goto queuing_error;
	}

	ctx = sp->u.scmd.ct6_ctx =
	    mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
	if (!ctx) {
		ql_log(ql_log_fatal, vha, 0x3010,
		    "Failed to allocate ctx for cmd=%p.\n", cmd);
		goto queuing_error;
	}

	memset(ctx, 0, sizeof(struct ct6_dsd));
	ctx->fcp_cmnd = dma_pool_zalloc(ha->fcp_cmnd_dma_pool,
	    GFP_ATOMIC, &ctx->fcp_cmnd_dma);
	if (!ctx->fcp_cmnd) {
	if (qla_get_buf(vha, sp->qpair, &sp->u.scmd.buf_dsc)) {
		ql_log(ql_log_fatal, vha, 0x3011,
		    "Failed to allocate fcp_cmnd for cmd=%p.\n", cmd);
		    "Failed to allocate buf for fcp_cmnd for cmd=%p.\n", cmd);
		goto queuing_error;
	}

	/* Initialize the DSD list and dma handle */
	INIT_LIST_HEAD(&ctx->dsd_list);
	ctx->dsd_use_cnt = 0;
	sp->flags |= SRB_GOT_BUF;
	ctx = &sp->u.scmd.ct6_ctx;
	ctx->fcp_cmnd = sp->u.scmd.buf_dsc.buf;
	ctx->fcp_cmnd_dma = sp->u.scmd.buf_dsc.buf_dma;

	if (cmd->cmd_len > 16) {
		additional_cdb_len = cmd->cmd_len - 16;
@@ -3145,7 +3179,6 @@ qla28xx_start_scsi_edif(srb_t *sp)
	cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len);
	put_unaligned_le64(ctx->fcp_cmnd_dma, &cmd_pkt->fcp_cmnd_dseg_address);

	sp->flags |= SRB_FCP_CMND_DMA_VALID;
	cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
	/* Set total data segment count. */
	cmd_pkt->entry_count = (uint8_t)req_cnt;
@@ -3177,15 +3210,11 @@ qla28xx_start_scsi_edif(srb_t *sp)
	return QLA_SUCCESS;

queuing_error_fcp_cmnd:
	dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, ctx->fcp_cmnd_dma);
queuing_error:
	if (tot_dsds)
		scsi_dma_unmap(cmd);

	if (sp->u.scmd.ct6_ctx) {
		mempool_free(sp->u.scmd.ct6_ctx, ha->ctx_mempool);
		sp->u.scmd.ct6_ctx = NULL;
	}
	qla_put_buf(sp->qpair, &sp->u.scmd.buf_dsc);
	qla_put_fw_resources(sp->qpair, &sp->iores);
	spin_unlock_irqrestore(lock, flags);

+2 −0
Original line number Diff line number Diff line
@@ -145,4 +145,6 @@ struct enode {
	(qla_ini_mode_enabled(_s->vha) && (_s->disc_state == DSC_DELETE_PEND || \
	 _s->disc_state == DSC_DELETED))

#define EDIF_CAP(_ha) (ql2xsecenable && IS_QLA28XX(_ha))

#endif	/* __QLA_EDIF_H */
+14 −1
Original line number Diff line number Diff line
@@ -89,7 +89,20 @@ struct app_plogi_reply {
struct app_pinfo_req {
	struct app_id app_info;
	uint8_t	 num_ports;
	port_id_t remote_pid;
	struct {
#ifdef __BIG_ENDIAN
		uint8_t domain;
		uint8_t area;
		uint8_t al_pa;
#elif defined(__LITTLE_ENDIAN)
		uint8_t al_pa;
		uint8_t area;
		uint8_t domain;
#else
#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!"
#endif
		uint8_t rsvd_1;
	} remote_pid;
	uint8_t		version;
	uint8_t		pad[VND_CMD_PAD_SIZE];
	uint8_t		reserved[VND_CMD_APP_RESERVED_SIZE];
Loading