Commit 4de067e5 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: edif: Add N2N support for EDIF

For EDIF + N2N to work, firmware 9.8 or later is required. The driver will
pause after PLOGI to allow app to authenticate. Once authentication
completes, app will tell driver to do PRLI.

Link: https://lore.kernel.org/r/20210817051315.2477-6-njavali@marvell.com


Signed-off-by: default avatarQuinn Tran <qutran@marvell.com>
Signed-off-by: default avatarNilesh Javali <njavali@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 310e69ed
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2633,6 +2633,7 @@ typedef struct fc_port {
		uint64_t	rx_bytes;
		uint8_t		non_secured_login;
		uint8_t		auth_state;
		uint16_t	authok:1;
		uint16_t	rekey_cnt;
		struct list_head edif_indx_list;
		spinlock_t  indx_list_lock;
@@ -4023,6 +4024,7 @@ struct qla_hw_data {
		uint32_t	scm_enabled:1;
		uint32_t	edif_hw:1;
		uint32_t	edif_enabled:1;
		uint32_t	n2n_fw_acc_sec:1;
		uint32_t	plogi_template_valid:1;
		uint32_t	port_isolated:1;
	} flags;
@@ -4720,6 +4722,7 @@ struct qla_hw_data {
	struct list_head sadb_rx_index_list;
	spinlock_t sadb_lock;	/* protects list */
	struct els_reject elsrej;
	u8 edif_post_stop_cnt_down;
};

#define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES))
+70 −25
Original line number Diff line number Diff line
@@ -546,6 +546,13 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
		     __func__);
	}

	if (N2N_TOPO(vha->hw)) {
		if (vha->hw->flags.n2n_fw_acc_sec)
			set_bit(N2N_LINK_RESET, &vha->dpc_flags);
		else
			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
		qla2xxx_wake_dpc(vha);
	} else {
		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
			ql_dbg(ql_dbg_edif, vha, 0xf084,
			       "%s: sess %p %8phC lid %#04x s_id %06x logout %d\n",
@@ -561,8 +568,15 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)

			if (atomic_read(&vha->loop_state) == LOOP_DOWN)
				break;
			if (!fcport->edif.secured_login)
				continue;

			fcport->edif.app_started = 1;
			if (fcport->edif.app_stop ||
			    (fcport->disc_state != DSC_LOGIN_COMPLETE &&
			     fcport->disc_state != DSC_LOGIN_PEND &&
			     fcport->disc_state != DSC_DELETED)) {
				/* no activity */
				fcport->edif.app_stop = 0;

				ql_dbg(ql_dbg_edif, vha, 0x911e,
@@ -570,8 +584,10 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
				       __func__, fcport->port_name);
				fcport->edif.app_sess_online = 1;
				qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0);
			}
			qla_edif_sa_ctl_init(vha, fcport);
		}
	}

	if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
		/* mark as active since an app is now present */
@@ -763,6 +779,7 @@ qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job)

	SET_DID_STATUS(bsg_reply->result, DID_OK);
	appplogireply.prli_status = 1;
	fcport->edif.authok = 1;
	if (!(fcport->edif.rx_sa_set && fcport->edif.tx_sa_set)) {
		ql_dbg(ql_dbg_edif, vha, 0x911e,
		    "%s: wwpn %8phC Both SA indexes has not been SET TX %d, RX %d.\n",
@@ -929,8 +946,9 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
			app_reply->ports[pcnt].remote_pid = fcport->d_id;

			ql_dbg(ql_dbg_edif, vha, 0x2058,
			    "Found FC_SP fcport - nn %8phN pn %8phN pcnt %d portid=%06x\n",
			    fcport->node_name, fcport->port_name, pcnt, fcport->d_id.b24);
			    "Found FC_SP fcport - nn %8phN pn %8phN pcnt %d portid=%06x secure %d.\n",
			    fcport->node_name, fcport->port_name, pcnt,
			    fcport->d_id.b24, fcport->edif.secured_login);

			switch (fcport->edif.auth_state) {
			case VND_CMD_AUTH_STATE_ELS_RCVD:
@@ -2012,6 +2030,33 @@ qla_edb_getnext(scsi_qla_host_t *vha)
	return edbnode;
}

void
qla_edif_timer(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;

	if (!vha->vp_idx && N2N_TOPO(ha) && ha->flags.n2n_fw_acc_sec) {
		if (vha->e_dbell.db_flags != EDB_ACTIVE &&
		    ha->edif_post_stop_cnt_down) {
			ha->edif_post_stop_cnt_down--;

			/*
			 * turn off auto 'Plogi Acc + secure=1' feature
			 * Set Add FW option[3]
			 * BIT_15, if.
			 */
			if (ha->edif_post_stop_cnt_down == 0) {
				ql_dbg(ql_dbg_async, vha, 0x911d,
				       "%s chip reset to turn off PLOGI ACC + secure\n",
				       __func__);
				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
			}
		} else {
			ha->edif_post_stop_cnt_down = 60;
		}
	}
}

/*
 * app uses separate thread to read this. It'll wait until the doorbell
 * is rung by the driver or the max wait time has expired
+2 −2
Original line number Diff line number Diff line
@@ -129,8 +129,8 @@ struct enode {
};

#define EDIF_SESSION_DOWN(_s) \
	(_s->disc_state == DSC_DELETE_PEND || \
	(qla_ini_mode_enabled(_s->vha) && (_s->disc_state == DSC_DELETE_PEND || \
	 _s->disc_state == DSC_DELETED || \
	 !_s->edif.app_sess_online)
	 !_s->edif.app_sess_online))

#endif	/* __QLA_EDIF_H */
+1 −0
Original line number Diff line number Diff line
@@ -810,6 +810,7 @@ struct els_entry_24xx {
#define EPD_RX_XCHG		(3 << 13)
#define ECF_CLR_PASSTHRU_PEND	BIT_12
#define ECF_INCL_FRAME_HDR	BIT_11
#define ECF_SEC_LOGIN		BIT_3

	union {
		struct {
+1 −0
Original line number Diff line number Diff line
@@ -990,6 +990,7 @@ void qla_enode_init(scsi_qla_host_t *vha);
void qla_enode_stop(scsi_qla_host_t *vha);
void qla_edif_flush_sa_ctl_lists(fc_port_t *fcport);
void qla_edb_init(scsi_qla_host_t *vha);
void qla_edif_timer(scsi_qla_host_t *vha);
int qla28xx_start_scsi_edif(srb_t *sp);
void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb);
void qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb);
Loading