Commit df648afa authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen

scsi: qla2xxx: edif: Wait for app to ack on sess down

On session deletion, wait for app to acknowledge before moving on. This
allows both app and driver to stay in sync. In addition, this gives a
chance for authentication app to do any type of cleanup before moving on.

Link: https://lore.kernel.org/r/20220607044627.19563-4-njavali@marvell.com
Fixes: dd30706e ("scsi: qla2xxx: edif: Add key update")
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 7a7b0b48
...@@ -2626,7 +2626,6 @@ typedef struct fc_port { ...@@ -2626,7 +2626,6 @@ typedef struct fc_port {
struct { struct {
uint32_t enable:1; /* device is edif enabled/req'd */ uint32_t enable:1; /* device is edif enabled/req'd */
uint32_t app_stop:2; uint32_t app_stop:2;
uint32_t app_started:1;
uint32_t aes_gmac:1; uint32_t aes_gmac:1;
uint32_t app_sess_online:1; uint32_t app_sess_online:1;
uint32_t tx_sa_set:1; uint32_t tx_sa_set:1;
...@@ -2637,6 +2636,7 @@ typedef struct fc_port { ...@@ -2637,6 +2636,7 @@ typedef struct fc_port {
uint32_t rx_rekey_cnt; uint32_t rx_rekey_cnt;
uint64_t tx_bytes; uint64_t tx_bytes;
uint64_t rx_bytes; uint64_t rx_bytes;
uint8_t sess_down_acked;
uint8_t auth_state; uint8_t auth_state;
uint16_t authok:1; uint16_t authok:1;
uint16_t rekey_cnt; uint16_t rekey_cnt;
......
...@@ -257,14 +257,8 @@ qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id) ...@@ -257,14 +257,8 @@ qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id)
f = NULL; f = NULL;
list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) { list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) {
if ((f->flags & FCF_FCSP_DEVICE)) { if (f->d_id.b24 == id->b24)
ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x2058, return f;
"Found secure fcport - nn %8phN pn %8phN portid=0x%x, 0x%x.\n",
f->node_name, f->port_name,
f->d_id.b24, id->b24);
if (f->d_id.b24 == id->b24)
return f;
}
} }
return NULL; return NULL;
} }
...@@ -526,7 +520,6 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) ...@@ -526,7 +520,6 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
fcport->edif.app_stop = 0; fcport->edif.app_stop = 0;
fcport->edif.app_sess_online = 0; fcport->edif.app_sess_online = 0;
fcport->edif.app_started = 1;
if (fcport->scan_state != QLA_FCPORT_FOUND) if (fcport->scan_state != QLA_FCPORT_FOUND)
continue; continue;
...@@ -628,9 +621,6 @@ qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job) ...@@ -628,9 +621,6 @@ qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
fcport->send_els_logo = 1; fcport->send_els_logo = 1;
qlt_schedule_sess_for_deletion(fcport); qlt_schedule_sess_for_deletion(fcport);
/* qla_edif_flush_sa_ctl_lists(fcport); */
fcport->edif.app_started = 0;
} }
} }
...@@ -1047,6 +1037,40 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job) ...@@ -1047,6 +1037,40 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
return rval; return rval;
} }
static int32_t
qla_edif_ack(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
struct fc_port *fcport;
struct aen_complete_cmd ack;
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, &ack, sizeof(ack));
ql_dbg(ql_dbg_edif, vha, 0x70cf,
"%s: %06x event_code %x\n",
__func__, ack.port_id.b24, ack.event_code);
fcport = qla2x00_find_fcport_by_pid(vha, &ack.port_id);
SET_DID_STATUS(bsg_reply->result, DID_OK);
if (!fcport) {
ql_dbg(ql_dbg_edif, vha, 0x70cf,
"%s: unable to find fcport %06x \n",
__func__, ack.port_id.b24);
return 0;
}
switch (ack.event_code) {
case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
fcport->edif.sess_down_acked = 1;
break;
default:
break;
}
return 0;
}
int32_t int32_t
qla_edif_app_mgmt(struct bsg_job *bsg_job) qla_edif_app_mgmt(struct bsg_job *bsg_job)
{ {
...@@ -1109,6 +1133,9 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) ...@@ -1109,6 +1133,9 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
case QL_VND_SC_GET_STATS: case QL_VND_SC_GET_STATS:
rval = qla_edif_app_getstats(vha, bsg_job); rval = qla_edif_app_getstats(vha, bsg_job);
break; break;
case QL_VND_SC_AEN_COMPLETE:
rval = qla_edif_ack(vha, bsg_job);
break;
default: default:
ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n", ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n",
__func__, __func__,
...@@ -3512,14 +3539,29 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job) ...@@ -3512,14 +3539,29 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess) void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
{ {
u16 cnt = 0;
if (sess->edif.app_sess_online && DBELL_ACTIVE(vha)) { if (sess->edif.app_sess_online && DBELL_ACTIVE(vha)) {
ql_dbg(ql_dbg_disc, vha, 0xf09c, ql_dbg(ql_dbg_disc, vha, 0xf09c,
"%s: sess %8phN send port_offline event\n", "%s: sess %8phN send port_offline event\n",
__func__, sess->port_name); __func__, sess->port_name);
sess->edif.app_sess_online = 0; sess->edif.app_sess_online = 0;
sess->edif.sess_down_acked = 0;
qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SESSION_SHUTDOWN, qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SESSION_SHUTDOWN,
sess->d_id.b24, 0, sess); sess->d_id.b24, 0, sess);
qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24); qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24);
while (!READ_ONCE(sess->edif.sess_down_acked) &&
!test_bit(VPORT_DELETE, &vha->dpc_flags)) {
msleep(100);
cnt++;
if (cnt > 100)
break;
}
sess->edif.sess_down_acked = 0;
ql_dbg(ql_dbg_disc, vha, 0xf09c,
"%s: sess %8phN port_offline event completed\n",
__func__, sess->port_name);
} }
} }
......
...@@ -1480,7 +1480,6 @@ static int qla_chk_secure_login(scsi_qla_host_t *vha, fc_port_t *fcport, ...@@ -1480,7 +1480,6 @@ static int qla_chk_secure_login(scsi_qla_host_t *vha, fc_port_t *fcport,
ql_dbg(ql_dbg_disc, vha, 0x20ef, ql_dbg(ql_dbg_disc, vha, 0x20ef,
"%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n", "%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n",
__func__, __LINE__, fcport->port_name); __func__, __LINE__, fcport->port_name);
fcport->edif.app_started = 1;
fcport->edif.app_sess_online = 1; fcport->edif.app_sess_online = 1;
qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED, qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED,
...@@ -5273,9 +5272,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) ...@@ -5273,9 +5272,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
INIT_LIST_HEAD(&fcport->edif.tx_sa_list); INIT_LIST_HEAD(&fcport->edif.tx_sa_list);
INIT_LIST_HEAD(&fcport->edif.rx_sa_list); INIT_LIST_HEAD(&fcport->edif.rx_sa_list);
if (vha->e_dbell.db_flags == EDB_ACTIVE)
fcport->edif.app_started = 1;
spin_lock_init(&fcport->edif.indx_list_lock); spin_lock_init(&fcport->edif.indx_list_lock);
INIT_LIST_HEAD(&fcport->edif.edif_indx_list); INIT_LIST_HEAD(&fcport->edif.edif_indx_list);
......
...@@ -981,22 +981,6 @@ void qlt_free_session_done(struct work_struct *work) ...@@ -981,22 +981,6 @@ void qlt_free_session_done(struct work_struct *work)
sess->send_els_logo); sess->send_els_logo);
if (!IS_SW_RESV_ADDR(sess->d_id)) { if (!IS_SW_RESV_ADDR(sess->d_id)) {
if (ha->flags.edif_enabled &&
(!own || own->iocb.u.isp24.status_subcode == ELS_PLOGI)) {
sess->edif.authok = 0;
if (!ha->flags.host_shutting_down) {
ql_dbg(ql_dbg_edif, vha, 0x911e,
"%s wwpn %8phC calling qla2x00_release_all_sadb\n",
__func__, sess->port_name);
qla2x00_release_all_sadb(vha, sess);
} else {
ql_dbg(ql_dbg_edif, vha, 0x911e,
"%s bypassing release_all_sadb\n",
__func__);
}
qla_edif_clear_appdata(vha, sess);
qla_edif_sess_down(vha, sess);
}
qla2x00_mark_device_lost(vha, sess, 0); qla2x00_mark_device_lost(vha, sess, 0);
if (sess->send_els_logo) { if (sess->send_els_logo) {
...@@ -1042,6 +1026,25 @@ void qlt_free_session_done(struct work_struct *work) ...@@ -1042,6 +1026,25 @@ void qlt_free_session_done(struct work_struct *work)
sess->nvme_flag |= NVME_FLAG_DELETING; sess->nvme_flag |= NVME_FLAG_DELETING;
qla_nvme_unregister_remote_port(sess); qla_nvme_unregister_remote_port(sess);
} }
if (ha->flags.edif_enabled &&
(!own || (own &&
own->iocb.u.isp24.status_subcode == ELS_PLOGI))) {
sess->edif.authok = 0;
if (!ha->flags.host_shutting_down) {
ql_dbg(ql_dbg_edif, vha, 0x911e,
"%s wwpn %8phC calling qla2x00_release_all_sadb\n",
__func__, sess->port_name);
qla2x00_release_all_sadb(vha, sess);
} else {
ql_dbg(ql_dbg_edif, vha, 0x911e,
"%s bypassing release_all_sadb\n",
__func__);
}
qla_edif_clear_appdata(vha, sess);
qla_edif_sess_down(vha, sess);
}
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment