Commit 9efea843 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: edif: Add detection of secure device

Some FC adapters from Marvell offer the ability to encrypt data in flight
(EDIF). This feature requires an application to act as an authenticator.

There is no FC switch scan service that can indicate whether a device is
secure or non-secure.

In order to detect whether the remote port supports encrypted operation,
driver must first do a PLOGI with the remote device. On completion of the
PLOGI, driver will query firmware to see if the device supports secure
login. To do that, driver + firmware must advertise the security bit via
PLOGI's service parameter. The remote device shall respond using the same
service parameter whether it supports it or not.

Link: https://lore.kernel.org/r/20210624052606.21613-8-njavali@marvell.com


Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Co-developed-by: default avatarLarry Wisneski <Larry.Wisneski@marvell.com>
Signed-off-by: default avatarLarry Wisneski <Larry.Wisneski@marvell.com>
Co-developed-by: default avatarDuane Grigsby <duane.grigsby@marvell.com>
Signed-off-by: default avatarDuane Grigsby <duane.grigsby@marvell.com>
Co-developed-by: default avatarRick Hicksted Jr <rhicksted@marvell.com>
Signed-off-by: default avatarRick Hicksted Jr <rhicksted@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 8a4bb2c1
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -492,6 +492,7 @@ struct srb_iocb {
#define SRB_LOGIN_SKIP_PRLI	BIT_2
#define SRB_LOGIN_NVME_PRLI	BIT_3
#define SRB_LOGIN_PRLI_ONLY	BIT_4
#define SRB_LOGIN_FCSP		BIT_5
			uint16_t data[2];
			u32 iop[2];
		} logio;
@@ -2343,6 +2344,7 @@ struct imm_ntfy_from_isp {
			__le16	nport_handle;
			uint16_t reserved_2;
			__le16	flags;
#define NOTIFY24XX_FLAGS_FCSP		BIT_5
#define NOTIFY24XX_FLAGS_GLOBAL_TPRLO   BIT_1
#define NOTIFY24XX_FLAGS_PUREX_IOCB     BIT_0
			__le16	srr_rx_id;
@@ -2682,7 +2684,8 @@ static const char * const port_dstate_str[] = {
	"UPD_FCPORT",
	"LOGIN_COMPLETE",
	"ADISC",
	"DELETE_PEND"
	"DELETE_PEND",
	"LOGIN_AUTH_PEND",
};

/*
+31 −0
Original line number Diff line number Diff line
@@ -2366,6 +2366,26 @@ qla28xx_sa_update_iocb_entry(scsi_qla_host_t *v, struct req_que *req,
	sp->done(sp, 0);
}

/**********************************************
 * edif update/delete sa_index list functions *
 **********************************************/

/* clear the edif_indx_list for this port */
void qla_edif_list_del(fc_port_t *fcport)
{
	struct edif_list_entry *indx_lst;
	struct edif_list_entry *tindx_lst;
	struct list_head *indx_list = &fcport->edif.edif_indx_list;
	unsigned long flags = 0;

	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);
	list_for_each_entry_safe(indx_lst, tindx_lst, indx_list, next) {
		list_del(&indx_lst->next);
		kfree(indx_lst);
	}
	spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
}

/******************
 * SADB functions *
 ******************/
@@ -2791,3 +2811,14 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
done:
	return rval;
}

void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
{
	if (sess->edif.app_sess_online && vha->e_dbell.db_flags & EDB_ACTIVE) {
		ql_dbg(ql_dbg_disc, vha, 0xf09c,
			"%s: sess %8phN send port_offline event\n",
			__func__, sess->port_name);
		sess->edif.app_sess_online = 0;
		qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24);
	}
}
+6 −2
Original line number Diff line number Diff line
@@ -82,10 +82,11 @@ struct port_database_24xx {
	uint8_t port_name[WWN_SIZE];
	uint8_t node_name[WWN_SIZE];

	uint8_t reserved_3[4];
	uint8_t reserved_3[2];
	uint16_t nvme_first_burst_size;
	uint16_t prli_nvme_svc_param_word_0;	/* Bits 15-0 of word 0 */
	uint16_t prli_nvme_svc_param_word_3;	/* Bits 15-0 of word 3 */
	uint16_t nvme_first_burst_size;
	uint8_t secure_login;
	uint8_t reserved_4[14];
};

@@ -897,6 +898,7 @@ struct logio_entry_24xx {
#define LCF_FCP2_OVERRIDE	BIT_9	/* Set/Reset word 3 of PRLI. */
#define LCF_CLASS_2		BIT_8	/* Enable class 2 during PLOGI. */
#define LCF_FREE_NPORT		BIT_7	/* Release NPORT handle after LOGO. */
#define LCF_COMMON_FEAT		BIT_7	/* PLOGI - Set Common Features Field */
#define LCF_EXPL_LOGO		BIT_6	/* Perform an explicit LOGO. */
#define LCF_NVME_PRLI		BIT_6   /* Perform NVME FC4 PRLI */
#define LCF_SKIP_PRLI		BIT_5	/* Skip PRLI after PLOGI. */
@@ -921,6 +923,8 @@ struct logio_entry_24xx {
	uint8_t rsp_size;		/* Response size in 32bit words. */

	__le32	io_parameter[11];	/* General I/O parameters. */
#define LIO_COMM_FEAT_FCSP	BIT_21
#define LIO_COMM_FEAT_CIO	BIT_31
#define LSC_SCODE_NOLINK	0x01
#define LSC_SCODE_NOIOCB	0x02
#define LSC_SCODE_NOXCB		0x03
+3 −0
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ void qla24xx_free_purex_item(struct purex_item *item);
extern bool qla24xx_risc_firmware_invalid(uint32_t *);
void qla_init_iocb_limit(scsi_qla_host_t *);

void qla_edif_list_del(fc_port_t *fcport);
void qla_edif_sadb_release(struct qla_hw_data *ha);
int qla_edif_sadb_build_free_pool(struct qla_hw_data *ha);
void qla_edif_sadb_release_free_pool(struct qla_hw_data *ha);
@@ -138,7 +139,9 @@ void qla_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha,
		srb_t *sp, struct sts_entry_24xx *sts24);
void qlt_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, fc_port_t *fcport,
		struct ctio7_from_24xx *ctio);
void qla2x00_release_all_sadb(struct scsi_qla_host *vha, struct fc_port *fcport);
int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsgjob);
void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess);
const char *sc_to_str(uint16_t cmd);

/*
+4 −0
Original line number Diff line number Diff line
@@ -2826,6 +2826,10 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea)
	if (fcport->disc_state == DSC_DELETE_PEND)
		return;

	/* We will figure-out what happen after AUTH completes */
	if (fcport->disc_state == DSC_LOGIN_AUTH_PEND)
		return;

	if (ea->sp->gen2 != fcport->login_gen) {
		/* target side must have changed it. */
		ql_dbg(ql_dbg_disc, vha, 0x20d3,
Loading