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: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Quinn Tran 2021-08-16 22:13:08 -07:00 committed by Martin K. Petersen
parent 310e69edfb
commit 4de067e5df
11 changed files with 232 additions and 64 deletions

View File

@ -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))

View File

@ -546,31 +546,47 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
__func__);
}
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",
__func__, fcport, fcport->port_name,
fcport->loop_id, fcport->d_id.b24,
fcport->logout_on_delete);
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",
__func__, fcport, fcport->port_name,
fcport->loop_id, fcport->d_id.b24,
fcport->logout_on_delete);
ql_dbg(ql_dbg_edif, vha, 0xf084,
"keep %d els_logo %d disc state %d auth state %d stop state %d\n",
fcport->keep_nport_handle,
fcport->send_els_logo, fcport->disc_state,
fcport->edif.auth_state, fcport->edif.app_stop);
ql_dbg(ql_dbg_edif, vha, 0xf084,
"keep %d els_logo %d disc state %d auth state %d stop state %d\n",
fcport->keep_nport_handle,
fcport->send_els_logo, fcport->disc_state,
fcport->edif.auth_state, fcport->edif.app_stop);
if (atomic_read(&vha->loop_state) == LOOP_DOWN)
break;
if (atomic_read(&vha->loop_state) == LOOP_DOWN)
break;
if (!fcport->edif.secured_login)
continue;
fcport->edif.app_started = 1;
fcport->edif.app_stop = 0;
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,
"%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
__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);
ql_dbg(ql_dbg_edif, vha, 0x911e,
"%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
__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) {
@ -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

View File

@ -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 */

View File

@ -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 {

View File

@ -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);

View File

@ -292,22 +292,6 @@ static void qla2x00_async_login_sp_done(srb_t *sp, int res)
sp->free(sp);
}
static inline bool
fcport_is_smaller(fc_port_t *fcport)
{
if (wwn_to_u64(fcport->port_name) <
wwn_to_u64(fcport->vha->port_name))
return true;
else
return false;
}
static inline bool
fcport_is_bigger(fc_port_t *fcport)
{
return !fcport_is_smaller(fcport);
}
int
qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
uint16_t *data)
@ -818,7 +802,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
default:
switch (current_login_state) {
case DSC_LS_PRLI_COMP:
ql_dbg(ql_dbg_disc + ql_dbg_verbose,
ql_dbg(ql_dbg_disc,
vha, 0x20e4, "%s %d %8phC post gpdb\n",
__func__, __LINE__, fcport->port_name);
@ -864,6 +848,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
*/
qla2x00_set_fcport_disc_state(fcport,
DSC_DELETED);
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
break;
case DSC_LS_PRLI_COMP:
if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
@ -876,6 +861,12 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
data);
break;
case DSC_LS_PLOGI_COMP:
if (vha->hw->flags.edif_enabled &&
vha->e_dbell.db_flags & EDB_ACTIVE) {
/* check to see if App support secure or not */
qla24xx_post_gpdb_work(vha, fcport, 0);
break;
}
if (fcport_is_bigger(fcport)) {
/* local adapter is smaller */
if (fcport->loop_id != FC_NO_LOOP_ID)
@ -1229,7 +1220,7 @@ static void qla2x00_async_prli_sp_done(srb_t *sp, int res)
struct event_arg ea;
ql_dbg(ql_dbg_disc, vha, 0x2129,
"%s %8phC res %d \n", __func__,
"%s %8phC res %x\n", __func__,
sp->fcport->port_name, res);
sp->fcport->flags &= ~FCF_ASYNC_SENT;
@ -1242,6 +1233,8 @@ static void qla2x00_async_prli_sp_done(srb_t *sp, int res)
ea.iop[0] = lio->u.logio.iop[0];
ea.iop[1] = lio->u.logio.iop[1];
ea.sp = sp;
if (res == QLA_OS_TIMER_EXPIRED)
ea.data[0] = QLA_OS_TIMER_EXPIRED;
qla24xx_handle_prli_done_event(vha, &ea);
}
@ -1453,7 +1446,7 @@ static int qla_chk_secure_login(scsi_qla_host_t *vha, fc_port_t *fcport,
fcport->edif.non_secured_login = 1;
}
if (vha->hw->flags.edif_enabled) {
if (fcport->flags & FCF_FCSP_DEVICE) {
if (fcport->edif.secured_login) {
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_AUTH_PEND);
/* Start edif prli timer & ring doorbell for app */
fcport->edif.rx_sa_set = 0;
@ -1476,7 +1469,7 @@ static int qla_chk_secure_login(scsi_qla_host_t *vha, fc_port_t *fcport,
}
rc = 1;
} else {
} else if (qla_ini_mode_enabled(vha) || qla_dual_mode_enabled(vha)) {
ql_dbg(ql_dbg_disc, vha, 0x2117,
"%s %d %8phC post prli\n",
__func__, __LINE__, fcport->port_name);
@ -1500,12 +1493,15 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
fcport->flags &= ~FCF_ASYNC_SENT;
ql_dbg(ql_dbg_disc, vha, 0x20d2,
"%s %8phC DS %d LS %d fc4_type %x rc %d\n", __func__,
"%s %8phC DS %d LS %x fc4_type %x rc %x\n", __func__,
fcport->port_name, fcport->disc_state, pd->current_login_state,
fcport->fc4_type, ea->rc);
if (fcport->disc_state == DSC_DELETE_PEND)
if (fcport->disc_state == DSC_DELETE_PEND) {
ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC\n",
__func__, __LINE__, fcport->port_name);
return;
}
if (NVME_TARGET(vha->hw, fcport))
ls = pd->current_login_state >> 4;
@ -1522,6 +1518,8 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
} else if (ea->sp->gen1 != fcport->rscn_gen) {
qla_rscn_replay(fcport);
qlt_schedule_sess_for_deletion(fcport);
ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC, ls %x\n",
__func__, __LINE__, fcport->port_name, ls);
return;
}
@ -1530,8 +1528,11 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
__qla24xx_parse_gpdb(vha, fcport, pd);
break;
case PDS_PLOGI_COMPLETE:
if (qla_chk_secure_login(vha, fcport, pd))
if (qla_chk_secure_login(vha, fcport, pd)) {
ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC, ls %x\n",
__func__, __LINE__, fcport->port_name, ls);
return;
}
fallthrough;
case PDS_PLOGI_PENDING:
case PDS_PRLI_PENDING:
@ -1542,6 +1543,8 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
}
ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC, ls %x\n",
__func__, __LINE__, fcport->port_name, ls);
return;
case PDS_LOGO_PENDING:
case PDS_PORT_UNAVAILABLE:
@ -1836,6 +1839,13 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
void qla_handle_els_plogi_done(scsi_qla_host_t *vha,
struct event_arg *ea)
{
if (N2N_TOPO(vha->hw) && fcport_is_smaller(ea->fcport) &&
vha->hw->flags.edif_enabled) {
/* check to see if App support Secure */
qla24xx_post_gpdb_work(vha, ea->fcport, 0);
return;
}
/* for pure Target Mode, PRLI will not be initiated */
if (vha->host->active_mode == MODE_TARGET)
return;
@ -2026,12 +2036,12 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
"FCP" : "NVMe", ea->fcport->fc4_type);
if (N2N_TOPO(vha->hw)) {
if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) {
ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
ea->fcport->fc4_type |= FS_FC4TYPE_FCP;
} else {
if (vha->hw->fc4_type_priority == FC4_PRIORITY_FCP) {
ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
ea->fcport->fc4_type |= FS_FC4TYPE_NVME;
} else {
ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
ea->fcport->fc4_type |= FS_FC4TYPE_FCP;
}
if (ea->fcport->n2n_link_reset_cnt < 3) {
@ -2042,6 +2052,7 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
* state machine
*/
set_bit(N2N_LINK_RESET, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
} else {
ql_log(ql_log_warn, vha, 0x2119,
"%s %d %8phC Unable to reconnect\n",
@ -4172,13 +4183,26 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
qla_dual_mode_enabled(vha))
ha->fw_options[2] |= BIT_4;
else
ha->fw_options[2] &= ~BIT_4;
ha->fw_options[2] &= ~(BIT_4);
/* Reserve 1/2 of emergency exchanges for ELS.*/
if (qla2xuseresexchforels)
ha->fw_options[2] |= BIT_8;
else
ha->fw_options[2] &= ~BIT_8;
/*
* N2N: set Secure=1 for PLOGI ACC and
* fw shal not send PRLI after PLOGI Acc
*/
if (ha->flags.edif_enabled &&
vha->e_dbell.db_flags & EDB_ACTIVE) {
ha->fw_options[3] |= BIT_15;
ha->flags.n2n_fw_acc_sec = 1;
} else {
ha->fw_options[3] &= ~BIT_15;
ha->flags.n2n_fw_acc_sec = 0;
}
}
if (ql2xrdpenable || ha->flags.scm_supported_f ||
@ -4381,8 +4405,6 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
ql_dbg(ql_dbg_init, vha, 0x00d1, "Issue init firmware.\n");
if (IS_QLAFX00(ha)) {
rval = qlafx00_init_firmware(vha, ha->init_cb_size);
goto next_check;
@ -4391,6 +4413,12 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
/* Update any ISP specific firmware options before initialization. */
ha->isp_ops->update_fw_options(vha);
ql_dbg(ql_dbg_init, vha, 0x00d1,
"Issue init firmware FW opt 1-3= %08x %08x %08x.\n",
le32_to_cpu(mid_init_cb->init_cb.firmware_options_1),
le32_to_cpu(mid_init_cb->init_cb.firmware_options_2),
le32_to_cpu(mid_init_cb->init_cb.firmware_options_3));
if (ha->flags.npiv_supported) {
if (ha->operating_mode == LOOP && !IS_CNA_CAPABLE(ha))
ha->max_npiv_vports = MIN_MULTI_ID_FABRIC - 1;
@ -4671,7 +4699,10 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
id.b.al_pa = al_pa;
id.b.rsvd_1 = 0;
spin_lock_irqsave(&ha->hardware_lock, flags);
if (!(topo == 2 && ha->flags.n2n_bigger))
if (vha->hw->flags.edif_enabled) {
if (topo != 2)
qlt_update_host_map(vha, id);
} else if (!(topo == 2 && ha->flags.n2n_bigger))
qlt_update_host_map(vha, id);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@ -5313,9 +5344,13 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
"LOOP READY.\n");
ha->flags.fw_init_done = 1;
if (vha->hw->flags.edif_enabled &&
vha->e_dbell.db_flags != EDB_ACTIVE) {
/* wake up authentication app to get ready */
if (ha->flags.edif_enabled &&
!(vha->e_dbell.db_flags & EDB_ACTIVE) &&
N2N_TOPO(vha->hw)) {
/*
* use port online to wake up app to get ready
* for authentication
*/
qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE, 0);
}
@ -5359,6 +5394,8 @@ static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
unsigned long flags;
fc_port_t *fcport;
ql_dbg(ql_dbg_disc, vha, 0x206a, "%s %d.\n", __func__, __LINE__);
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags))
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);

View File

@ -478,3 +478,19 @@ bool qla_pci_disconnected(struct scsi_qla_host *vha,
}
return ret;
}
static inline bool
fcport_is_smaller(fc_port_t *fcport)
{
if (wwn_to_u64(fcport->port_name) <
wwn_to_u64(fcport->vha->port_name))
return true;
else
return false;
}
static inline bool
fcport_is_bigger(fc_port_t *fcport)
{
return !fcport_is_smaller(fcport);
}

View File

@ -2745,7 +2745,10 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
els_iocb->s_id[0] = vha->d_id.b.domain;
if (elsio->u.els_logo.els_cmd == ELS_DCMD_PLOGI) {
els_iocb->control_flags = 0;
if (vha->hw->flags.edif_enabled)
els_iocb->control_flags = cpu_to_le16(ECF_SEC_LOGIN);
else
els_iocb->control_flags = 0;
els_iocb->tx_byte_count = els_iocb->tx_len =
cpu_to_le32(sizeof(struct els_plogi_payload));
put_unaligned_le64(elsio->u.els_plogi.els_plogi_pyld_dma,
@ -2985,7 +2988,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
elsio = &sp->u.iocb_cmd;
ql_dbg(ql_dbg_io, vha, 0x3073,
"Enter: PLOGI portid=%06x\n", fcport->d_id.b24);
"%s Enter: PLOGI portid=%06x\n", __func__, fcport->d_id.b24);
sp->type = SRB_ELS_DCMD;
sp->name = "ELS_DCMD";
@ -3028,6 +3031,13 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
elsio->u.els_plogi.els_cmd = els_opcode;
elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
if (els_opcode == ELS_DCMD_PLOGI && vha->hw->flags.edif_enabled &&
vha->e_dbell.db_flags & EDB_ACTIVE) {
struct fc_els_flogi *p = ptr;
p->fl_csp.sp_features |= cpu_to_be16(FC_SP_FT_SEC);
}
ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n");
ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x0109,
(uint8_t *)elsio->u.els_plogi.els_plogi_pyld,

View File

@ -1141,7 +1141,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
if (IS_QLA28XX(ha) && ha->flags.edif_hw && ql2xsecenable &&
(ha->fw_attributes_ext[0] & FW_ATTR_EXT0_EDIF)) {
ha->flags.edif_enabled = 1;
ql_log(ql_log_info + ql_dbg_edif, vha, 0xffff,
ql_log(ql_log_info, vha, 0xffff,
"%s: edif is enabled\n", __func__);
}
}
@ -4049,6 +4049,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
fcport->scan_state = QLA_FCPORT_FOUND;
fcport->n2n_flag = 1;
fcport->keep_nport_handle = 1;
fcport->login_retry = vha->hw->login_retry_count;
if (wwn_to_u64(vha->port_name) >
wwn_to_u64(fcport->port_name)) {

View File

@ -3964,7 +3964,6 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
qla2x00_schedule_rport_del(vha, fcport);
}
qla_edif_sess_down(vha, fcport);
/*
* We may need to retry the login, so don't change the state of the
* port but do the retries.
@ -7343,6 +7342,10 @@ qla2x00_timer(struct timer_list *t)
}
}
/* check if edif running */
if (vha->hw->flags.edif_enabled)
qla_edif_timer(vha);
/* Process any deferred work. */
if (!list_empty(&vha->work_list)) {
unsigned long flags;

View File

@ -638,6 +638,7 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport,
if (vha->hw->flags.edif_enabled &&
(le16_to_cpu(ntfy->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP)) {
fcport->flags |= FCF_FCSP_DEVICE;
fcport->edif.secured_login = 1;
}
break;
case SRB_NACK_PRLI:
@ -937,6 +938,11 @@ qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo)
qlt_port_logo_t *tmp;
int res;
if (test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags)) {
res = 0;
goto out;
}
mutex_lock(&vha->vha_tgt.tgt_mutex);
list_for_each_entry(tmp, &vha->logo_list, list) {
@ -957,6 +963,7 @@ qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo)
list_del(&logo->list);
mutex_unlock(&vha->vha_tgt.tgt_mutex);
out:
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf098,
"Finished LOGO to %02x:%02x:%02x, dropped %d cmds, res = %#x\n",
logo->id.b.domain, logo->id.b.area, logo->id.b.al_pa,
@ -987,6 +994,7 @@ void qlt_free_session_done(struct work_struct *work)
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",
@ -997,6 +1005,7 @@ void qlt_free_session_done(struct work_struct *work)
"%s bypassing release_all_sadb\n",
__func__);
}
qla_edif_sess_down(vha, sess);
}
qla2x00_mark_device_lost(vha, sess, 0);
@ -4808,6 +4817,23 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
goto out;
}
if (vha->hw->flags.edif_enabled) {
if (!(vha->e_dbell.db_flags & EDB_ACTIVE)) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s %d Term INOT due to app not started lid=%d, NportID %06X ",
__func__, __LINE__, loop_id, port_id.b24);
qlt_send_term_imm_notif(vha, iocb, 1);
goto out;
} else if (iocb->u.isp24.status_subcode == ELS_PLOGI &&
!(le16_to_cpu(iocb->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP)) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s %d Term INOT due to unsecure lid=%d, NportID %06X ",
__func__, __LINE__, loop_id, port_id.b24);
qlt_send_term_imm_notif(vha, iocb, 1);
goto out;
}
}
pla = qlt_plogi_ack_find_add(vha, &port_id, iocb);
if (!pla) {
ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
@ -4876,6 +4902,10 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
sess->loop_id = loop_id;
if (iocb->u.isp24.status_subcode == ELS_PLOGI) {
/* remote port has assigned Port ID */
if (N2N_TOPO(vha->hw) && fcport_is_bigger(sess))
vha->d_id = sess->d_id;
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s %8phC - send port online\n",
__func__, sess->port_name);
@ -4995,6 +5025,16 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
sess = qla2x00_find_fcport_by_wwpn(vha,
iocb->u.isp24.port_name, 1);
if (vha->hw->flags.edif_enabled && sess &&
(!(sess->flags & FCF_FCSP_DEVICE) ||
!sess->edif.authok)) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s %d %8phC Term PRLI due to unauthorize PRLI\n",
__func__, __LINE__, iocb->u.isp24.port_name);
qlt_send_term_imm_notif(vha, iocb, 1);
break;
}
if (sess && sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN]) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s %d %8phC Term PRLI due to PLOGI ACK not completed\n",
@ -5043,6 +5083,16 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
bool delete = false;
int sec;
if (vha->hw->flags.edif_enabled && sess &&
(!(sess->flags & FCF_FCSP_DEVICE) ||
!sess->edif.authok)) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s %d %8phC Term PRLI due to unauthorize prli\n",
__func__, __LINE__, iocb->u.isp24.port_name);
qlt_send_term_imm_notif(vha, iocb, 1);
break;
}
spin_lock_irqsave(&tgt->ha->tgt.sess_lock, flags);
switch (sess->fw_login_state) {
case DSC_LS_PLOGI_PEND:
@ -5232,7 +5282,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
}
/*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
* ha->hardware_lock supposed to be held on entry.
* Might drop it, then reacquire.
*/
static void qlt_handle_imm_notify(struct scsi_qla_host *vha,
struct imm_ntfy_from_isp *iocb)