mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-11 21:14:07 +08:00
scsi: qla2xxx: Migrate NVME N2N handling into state machine
This patch fixes regression introduced for the N2N support for FC-NVMe. For
FC-NVMe with N2N connection, instead of FW initiating the Login, Driver
starts Login process. This patch migrates that new process from a
standalone path into existing session management state machine. With this
state change now driver will not wait for pull NPort ID from FW.
Fixes: edd05de197
("scsi: qla2xxx: Changes to support N2N logins")
Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
0eaaca4c1b
commit
8777e4314d
@ -398,6 +398,8 @@ struct srb_iocb {
|
|||||||
struct completion comp;
|
struct completion comp;
|
||||||
struct els_plogi_payload *els_plogi_pyld;
|
struct els_plogi_payload *els_plogi_pyld;
|
||||||
struct els_plogi_payload *els_resp_pyld;
|
struct els_plogi_payload *els_resp_pyld;
|
||||||
|
u32 tx_size;
|
||||||
|
u32 rx_size;
|
||||||
dma_addr_t els_plogi_pyld_dma;
|
dma_addr_t els_plogi_pyld_dma;
|
||||||
dma_addr_t els_resp_pyld_dma;
|
dma_addr_t els_resp_pyld_dma;
|
||||||
uint32_t fw_status[3];
|
uint32_t fw_status[3];
|
||||||
@ -2312,6 +2314,7 @@ enum fcport_mgt_event {
|
|||||||
FCME_ADISC_DONE,
|
FCME_ADISC_DONE,
|
||||||
FCME_GNNID_DONE,
|
FCME_GNNID_DONE,
|
||||||
FCME_GFPNID_DONE,
|
FCME_GFPNID_DONE,
|
||||||
|
FCME_ELS_PLOGI_DONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum rscn_addr_format {
|
enum rscn_addr_format {
|
||||||
@ -2408,6 +2411,7 @@ typedef struct fc_port {
|
|||||||
struct ct_sns_desc ct_desc;
|
struct ct_sns_desc ct_desc;
|
||||||
enum discovery_state disc_state;
|
enum discovery_state disc_state;
|
||||||
enum login_state fw_login_state;
|
enum login_state fw_login_state;
|
||||||
|
unsigned long dm_login_expire;
|
||||||
unsigned long plogi_nack_done_deadline;
|
unsigned long plogi_nack_done_deadline;
|
||||||
|
|
||||||
u32 login_gen, last_login_gen;
|
u32 login_gen, last_login_gen;
|
||||||
@ -2418,7 +2422,8 @@ typedef struct fc_port {
|
|||||||
u8 iocb[IOCB_SIZE];
|
u8 iocb[IOCB_SIZE];
|
||||||
u8 current_login_state;
|
u8 current_login_state;
|
||||||
u8 last_login_state;
|
u8 last_login_state;
|
||||||
struct completion n2n_done;
|
u16 n2n_link_reset_cnt;
|
||||||
|
u16 n2n_chip_reset;
|
||||||
} fc_port_t;
|
} fc_port_t;
|
||||||
|
|
||||||
#define QLA_FCPORT_SCAN 1
|
#define QLA_FCPORT_SCAN 1
|
||||||
@ -3228,6 +3233,7 @@ enum qla_work_type {
|
|||||||
QLA_EVT_GFPNID,
|
QLA_EVT_GFPNID,
|
||||||
QLA_EVT_SP_RETRY,
|
QLA_EVT_SP_RETRY,
|
||||||
QLA_EVT_IIDMA,
|
QLA_EVT_IIDMA,
|
||||||
|
QLA_EVT_ELS_PLOGI,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -3600,6 +3606,7 @@ struct qla_hw_data {
|
|||||||
uint32_t using_lr_setting:1;
|
uint32_t using_lr_setting:1;
|
||||||
uint32_t rida_fmt2:1;
|
uint32_t rida_fmt2:1;
|
||||||
uint32_t purge_mbox:1;
|
uint32_t purge_mbox:1;
|
||||||
|
uint32_t n2n_bigger:1;
|
||||||
} flags;
|
} flags;
|
||||||
|
|
||||||
uint16_t max_exchg;
|
uint16_t max_exchg;
|
||||||
@ -3908,6 +3915,9 @@ struct qla_hw_data {
|
|||||||
int exchoffld_size;
|
int exchoffld_size;
|
||||||
int exchoffld_count;
|
int exchoffld_count;
|
||||||
|
|
||||||
|
/* n2n */
|
||||||
|
struct els_plogi_payload plogi_els_payld;
|
||||||
|
|
||||||
void *swl;
|
void *swl;
|
||||||
|
|
||||||
/* These are used by mailbox operations. */
|
/* These are used by mailbox operations. */
|
||||||
|
@ -1366,6 +1366,11 @@ struct vp_rpt_id_entry_24xx {
|
|||||||
/* format 1 fabric */
|
/* format 1 fabric */
|
||||||
uint8_t vpstat1_subcode; /* vp_status=1 subcode */
|
uint8_t vpstat1_subcode; /* vp_status=1 subcode */
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
|
#define TOPO_MASK 0xE
|
||||||
|
#define TOPO_FL 0x2
|
||||||
|
#define TOPO_N2N 0x4
|
||||||
|
#define TOPO_F 0x6
|
||||||
|
|
||||||
uint16_t fip_flags;
|
uint16_t fip_flags;
|
||||||
uint8_t rsv2[12];
|
uint8_t rsv2[12];
|
||||||
|
|
||||||
|
@ -45,8 +45,7 @@ extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
|
|||||||
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
|
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
|
||||||
|
|
||||||
extern int qla24xx_els_dcmd_iocb(scsi_qla_host_t *, int, port_id_t);
|
extern int qla24xx_els_dcmd_iocb(scsi_qla_host_t *, int, port_id_t);
|
||||||
extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *,
|
extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *, bool);
|
||||||
port_id_t);
|
|
||||||
|
|
||||||
extern void qla2x00_update_fcports(scsi_qla_host_t *);
|
extern void qla2x00_update_fcports(scsi_qla_host_t *);
|
||||||
|
|
||||||
|
@ -3383,19 +3383,40 @@ int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id)
|
|||||||
|
|
||||||
void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp)
|
void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp)
|
||||||
{
|
{
|
||||||
if (sp->u.iocb_cmd.u.ctarg.req) {
|
struct srb_iocb *c = &sp->u.iocb_cmd;
|
||||||
dma_free_coherent(&vha->hw->pdev->dev,
|
|
||||||
sizeof(struct ct_sns_pkt),
|
switch (sp->type) {
|
||||||
sp->u.iocb_cmd.u.ctarg.req,
|
case SRB_ELS_DCMD:
|
||||||
sp->u.iocb_cmd.u.ctarg.req_dma);
|
if (c->u.els_plogi.els_plogi_pyld)
|
||||||
sp->u.iocb_cmd.u.ctarg.req = NULL;
|
dma_free_coherent(&vha->hw->pdev->dev,
|
||||||
}
|
c->u.els_plogi.tx_size,
|
||||||
if (sp->u.iocb_cmd.u.ctarg.rsp) {
|
c->u.els_plogi.els_plogi_pyld,
|
||||||
dma_free_coherent(&vha->hw->pdev->dev,
|
c->u.els_plogi.els_plogi_pyld_dma);
|
||||||
sizeof(struct ct_sns_pkt),
|
|
||||||
sp->u.iocb_cmd.u.ctarg.rsp,
|
if (c->u.els_plogi.els_resp_pyld)
|
||||||
sp->u.iocb_cmd.u.ctarg.rsp_dma);
|
dma_free_coherent(&vha->hw->pdev->dev,
|
||||||
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
|
c->u.els_plogi.rx_size,
|
||||||
|
c->u.els_plogi.els_resp_pyld,
|
||||||
|
c->u.els_plogi.els_resp_pyld_dma);
|
||||||
|
break;
|
||||||
|
case SRB_CT_PTHRU_CMD:
|
||||||
|
default:
|
||||||
|
if (sp->u.iocb_cmd.u.ctarg.req) {
|
||||||
|
dma_free_coherent(&vha->hw->pdev->dev,
|
||||||
|
sizeof(struct ct_sns_pkt),
|
||||||
|
sp->u.iocb_cmd.u.ctarg.req,
|
||||||
|
sp->u.iocb_cmd.u.ctarg.req_dma);
|
||||||
|
sp->u.iocb_cmd.u.ctarg.req = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sp->u.iocb_cmd.u.ctarg.rsp) {
|
||||||
|
dma_free_coherent(&vha->hw->pdev->dev,
|
||||||
|
sizeof(struct ct_sns_pkt),
|
||||||
|
sp->u.iocb_cmd.u.ctarg.rsp,
|
||||||
|
sp->u.iocb_cmd.u.ctarg.rsp_dma);
|
||||||
|
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp->free(sp);
|
sp->free(sp);
|
||||||
|
@ -419,6 +419,19 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
|
|||||||
__qla24xx_handle_gpdb_event(vha, ea);
|
__qla24xx_handle_gpdb_event(vha, ea);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport)
|
||||||
|
{
|
||||||
|
struct qla_work_evt *e;
|
||||||
|
|
||||||
|
e = qla2x00_alloc_work(vha, QLA_EVT_ELS_PLOGI);
|
||||||
|
if (!e)
|
||||||
|
return QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
e->u.fcport.fcport = fcport;
|
||||||
|
fcport->flags |= FCF_ASYNC_ACTIVE;
|
||||||
|
return qla2x00_post_work(vha, e);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qla2x00_async_adisc_sp_done(void *ptr, int res)
|
qla2x00_async_adisc_sp_done(void *ptr, int res)
|
||||||
{
|
{
|
||||||
@ -467,6 +480,8 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
|
|||||||
|
|
||||||
lio = &sp->u.iocb_cmd;
|
lio = &sp->u.iocb_cmd;
|
||||||
lio->timeout = qla2x00_async_iocb_timeout;
|
lio->timeout = qla2x00_async_iocb_timeout;
|
||||||
|
sp->gen1 = fcport->rscn_gen;
|
||||||
|
sp->gen2 = fcport->login_gen;
|
||||||
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
|
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
|
||||||
|
|
||||||
sp->done = qla2x00_async_adisc_sp_done;
|
sp->done = qla2x00_async_adisc_sp_done;
|
||||||
@ -560,12 +575,17 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
|
|||||||
|
|
||||||
loop_id = le16_to_cpu(e->nport_handle);
|
loop_id = le16_to_cpu(e->nport_handle);
|
||||||
loop_id = (loop_id & 0x7fff);
|
loop_id = (loop_id & 0x7fff);
|
||||||
|
if (fcport->fc4f_nvme)
|
||||||
|
current_login_state = e->current_login_state >> 4;
|
||||||
|
else
|
||||||
|
current_login_state = e->current_login_state & 0xf;
|
||||||
|
|
||||||
|
|
||||||
ql_dbg(ql_dbg_disc, vha, 0x20e2,
|
ql_dbg(ql_dbg_disc, vha, 0x20e2,
|
||||||
"%s found %8phC CLS [%d|%d] ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n",
|
"%s found %8phC CLS [%x|%x] nvme %d ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n",
|
||||||
__func__, fcport->port_name,
|
__func__, fcport->port_name,
|
||||||
e->current_login_state, fcport->fw_login_state,
|
e->current_login_state, fcport->fw_login_state,
|
||||||
id.b.domain, id.b.area, id.b.al_pa,
|
fcport->fc4f_nvme, id.b.domain, id.b.area, id.b.al_pa,
|
||||||
fcport->d_id.b.domain, fcport->d_id.b.area,
|
fcport->d_id.b.domain, fcport->d_id.b.area,
|
||||||
fcport->d_id.b.al_pa, loop_id, fcport->loop_id);
|
fcport->d_id.b.al_pa, loop_id, fcport->loop_id);
|
||||||
|
|
||||||
@ -574,9 +594,13 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
|
|||||||
case DSC_DELETED:
|
case DSC_DELETED:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if ((id.b24 != fcport->d_id.b24) ||
|
if ((id.b24 != fcport->d_id.b24 &&
|
||||||
((fcport->loop_id != FC_NO_LOOP_ID) &&
|
fcport->d_id.b24) ||
|
||||||
(fcport->loop_id != loop_id))) {
|
(fcport->loop_id != FC_NO_LOOP_ID &&
|
||||||
|
fcport->loop_id != loop_id)) {
|
||||||
|
ql_dbg(ql_dbg_disc, vha, 0x20e3,
|
||||||
|
"%s %d %8phC post del sess\n",
|
||||||
|
__func__, __LINE__, fcport->port_name);
|
||||||
qlt_schedule_sess_for_deletion(fcport);
|
qlt_schedule_sess_for_deletion(fcport);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -599,11 +623,6 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
|
|||||||
fcport->login_pause = 1;
|
fcport->login_pause = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcport->fc4f_nvme)
|
|
||||||
current_login_state = e->current_login_state >> 4;
|
|
||||||
else
|
|
||||||
current_login_state = e->current_login_state & 0xf;
|
|
||||||
|
|
||||||
switch (vha->hw->current_topology) {
|
switch (vha->hw->current_topology) {
|
||||||
default:
|
default:
|
||||||
switch (current_login_state) {
|
switch (current_login_state) {
|
||||||
@ -632,6 +651,8 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ISP_CFG_N:
|
case ISP_CFG_N:
|
||||||
|
fcport->fw_login_state = current_login_state;
|
||||||
|
fcport->d_id = id;
|
||||||
switch (current_login_state) {
|
switch (current_login_state) {
|
||||||
case DSC_LS_PRLI_COMP:
|
case DSC_LS_PRLI_COMP:
|
||||||
if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
|
if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
|
||||||
@ -705,12 +726,39 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
|
|||||||
qla24xx_fcport_handle_login(vha, fcport);
|
qla24xx_fcport_handle_login(vha, fcport);
|
||||||
break;
|
break;
|
||||||
case ISP_CFG_N:
|
case ISP_CFG_N:
|
||||||
/*
|
fcport->disc_state = DSC_DELETED;
|
||||||
* FW handles the initial login for n2n.
|
if (time_after_eq(jiffies, fcport->dm_login_expire)) {
|
||||||
* Do link reinit to trigger this auto login.
|
if (fcport->n2n_link_reset_cnt < 2) {
|
||||||
*/
|
fcport->n2n_link_reset_cnt++;
|
||||||
set_bit(N2N_LINK_RESET, &vha->dpc_flags);
|
/*
|
||||||
qla2xxx_wake_dpc(vha);
|
* remote port is not sending PLOGI.
|
||||||
|
* Reset link to kick start his state
|
||||||
|
* machine
|
||||||
|
*/
|
||||||
|
set_bit(N2N_LINK_RESET,
|
||||||
|
&vha->dpc_flags);
|
||||||
|
} else {
|
||||||
|
if (fcport->n2n_chip_reset < 1) {
|
||||||
|
ql_log(ql_log_info, vha, 0x705d,
|
||||||
|
"Chip reset to bring laser down");
|
||||||
|
set_bit(ISP_ABORT_NEEDED,
|
||||||
|
&vha->dpc_flags);
|
||||||
|
fcport->n2n_chip_reset++;
|
||||||
|
} else {
|
||||||
|
ql_log(ql_log_info, vha, 0x705d,
|
||||||
|
"Remote port %8ph is not coming back\n",
|
||||||
|
fcport->port_name);
|
||||||
|
fcport->scan_state = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qla2xxx_wake_dpc(vha);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* report port suppose to do PLOGI. Give him
|
||||||
|
* more time. FW will catch it.
|
||||||
|
*/
|
||||||
|
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1020,9 +1068,9 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ql_dbg(ql_dbg_disc, vha, 0x211b,
|
ql_dbg(ql_dbg_disc, vha, 0x211b,
|
||||||
"Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d.\n",
|
"Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n",
|
||||||
fcport->port_name, sp->handle, fcport->loop_id,
|
fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
|
||||||
fcport->d_id.b24, fcport->login_retry);
|
fcport->login_retry, fcport->fc4f_nvme ? "nvme" : "fc");
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
|
|
||||||
@ -1164,8 +1212,9 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
|
|||||||
fcport->flags &= ~FCF_ASYNC_SENT;
|
fcport->flags &= ~FCF_ASYNC_SENT;
|
||||||
|
|
||||||
ql_dbg(ql_dbg_disc, vha, 0x20d2,
|
ql_dbg(ql_dbg_disc, vha, 0x20d2,
|
||||||
"%s %8phC DS %d LS %d rc %d\n", __func__, fcport->port_name,
|
"%s %8phC DS %d LS %d nvme %x rc %d\n", __func__, fcport->port_name,
|
||||||
fcport->disc_state, pd->current_login_state, ea->rc);
|
fcport->disc_state, pd->current_login_state, fcport->fc4f_nvme,
|
||||||
|
ea->rc);
|
||||||
|
|
||||||
if (fcport->disc_state == DSC_DELETE_PEND)
|
if (fcport->disc_state == DSC_DELETE_PEND)
|
||||||
return;
|
return;
|
||||||
@ -1286,36 +1335,76 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (fcport->disc_state) {
|
switch (fcport->disc_state) {
|
||||||
case DSC_DELETED:
|
case DSC_DELETED:
|
||||||
fcport->login_retry--;
|
|
||||||
wwn = wwn_to_u64(fcport->node_name);
|
wwn = wwn_to_u64(fcport->node_name);
|
||||||
if (wwn == 0) {
|
switch (vha->hw->current_topology) {
|
||||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
case ISP_CFG_N:
|
||||||
"%s %d %8phC post GNNID\n",
|
if (fcport_is_smaller(fcport)) {
|
||||||
__func__, __LINE__, fcport->port_name);
|
/* this adapter is bigger */
|
||||||
qla24xx_post_gnnid_work(vha, fcport);
|
if (fcport->login_retry) {
|
||||||
} else if (fcport->loop_id == FC_NO_LOOP_ID) {
|
if (fcport->loop_id == FC_NO_LOOP_ID) {
|
||||||
ql_dbg(ql_dbg_disc, vha, 0x20bd,
|
qla2x00_find_new_loop_id(vha,
|
||||||
"%s %d %8phC post gnl\n",
|
fcport);
|
||||||
__func__, __LINE__, fcport->port_name);
|
fcport->fw_login_state =
|
||||||
qla24xx_post_gnl_work(vha, fcport);
|
DSC_LS_PORT_UNAVAIL;
|
||||||
} else {
|
}
|
||||||
fcport->login_retry--;
|
fcport->login_retry--;
|
||||||
qla_chk_n2n_b4_login(vha, fcport);
|
qla_post_els_plogi_work(vha, fcport);
|
||||||
|
} else {
|
||||||
|
ql_log(ql_log_info, vha, 0x705d,
|
||||||
|
"Unable to reach remote port %8phC",
|
||||||
|
fcport->port_name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qla24xx_post_gnl_work(vha, fcport);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (wwn == 0) {
|
||||||
|
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||||
|
"%s %d %8phC post GNNID\n",
|
||||||
|
__func__, __LINE__, fcport->port_name);
|
||||||
|
qla24xx_post_gnnid_work(vha, fcport);
|
||||||
|
} else if (fcport->loop_id == FC_NO_LOOP_ID) {
|
||||||
|
ql_dbg(ql_dbg_disc, vha, 0x20bd,
|
||||||
|
"%s %d %8phC post gnl\n",
|
||||||
|
__func__, __LINE__, fcport->port_name);
|
||||||
|
qla24xx_post_gnl_work(vha, fcport);
|
||||||
|
} else {
|
||||||
|
qla_chk_n2n_b4_login(vha, fcport);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DSC_GNL:
|
case DSC_GNL:
|
||||||
if (fcport->login_pause) {
|
switch (vha->hw->current_topology) {
|
||||||
fcport->last_rscn_gen = fcport->rscn_gen;
|
case ISP_CFG_N:
|
||||||
fcport->last_login_gen = fcport->login_gen;
|
if ((fcport->current_login_state & 0xf) == 0x6) {
|
||||||
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
|
ql_dbg(ql_dbg_disc, vha, 0x2118,
|
||||||
|
"%s %d %8phC post GPDB work\n",
|
||||||
|
__func__, __LINE__, fcport->port_name);
|
||||||
|
fcport->chip_reset =
|
||||||
|
vha->hw->base_qpair->chip_reset;
|
||||||
|
qla24xx_post_gpdb_work(vha, fcport, 0);
|
||||||
|
} else {
|
||||||
|
ql_dbg(ql_dbg_disc, vha, 0x2118,
|
||||||
|
"%s %d %8phC post NVMe PRLI\n",
|
||||||
|
__func__, __LINE__, fcport->port_name);
|
||||||
|
qla24xx_post_prli_work(vha, fcport);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (fcport->login_pause) {
|
||||||
|
fcport->last_rscn_gen = fcport->rscn_gen;
|
||||||
|
fcport->last_login_gen = fcport->login_gen;
|
||||||
|
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
qla_chk_n2n_b4_login(vha, fcport);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
qla_chk_n2n_b4_login(vha, fcport);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DSC_LOGIN_FAILED:
|
case DSC_LOGIN_FAILED:
|
||||||
@ -1429,6 +1518,15 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
|
|||||||
qla24xx_fcport_handle_login(vha, fcport);
|
qla24xx_fcport_handle_login(vha, fcport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||||
|
{
|
||||||
|
ql_dbg(ql_dbg_disc, vha, 0x2118,
|
||||||
|
"%s %d %8phC post PRLI\n",
|
||||||
|
__func__, __LINE__, ea->fcport->port_name);
|
||||||
|
qla24xx_post_prli_work(vha, ea->fcport);
|
||||||
|
}
|
||||||
|
|
||||||
void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
|
void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||||
{
|
{
|
||||||
fc_port_t *f, *tf;
|
fc_port_t *f, *tf;
|
||||||
@ -1530,6 +1628,9 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
|
|||||||
case FCME_GFPNID_DONE:
|
case FCME_GFPNID_DONE:
|
||||||
qla24xx_handle_gfpnid_event(vha, ea);
|
qla24xx_handle_gfpnid_event(vha, ea);
|
||||||
break;
|
break;
|
||||||
|
case FCME_ELS_PLOGI_DONE:
|
||||||
|
qla_handle_els_plogi_done(vha, ea);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
BUG_ON(1);
|
BUG_ON(1);
|
||||||
break;
|
break;
|
||||||
@ -4160,7 +4261,8 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
|
|||||||
id.b.al_pa = al_pa;
|
id.b.al_pa = al_pa;
|
||||||
id.b.rsvd_1 = 0;
|
id.b.rsvd_1 = 0;
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
qlt_update_host_map(vha, id);
|
if (!(topo == 2 && ha->flags.n2n_bigger))
|
||||||
|
qlt_update_host_map(vha, id);
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
if (!vha->flags.init_done)
|
if (!vha->flags.init_done)
|
||||||
@ -4813,6 +4915,31 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
|
|||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
/* Inititae N2N login. */
|
||||||
|
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
|
||||||
|
/* borrowing */
|
||||||
|
u32 *bp, i, sz;
|
||||||
|
|
||||||
|
memset(ha->init_cb, 0, ha->init_cb_size);
|
||||||
|
sz = min_t(int, sizeof(struct els_plogi_payload),
|
||||||
|
ha->init_cb_size);
|
||||||
|
rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
|
||||||
|
(void *)ha->init_cb, sz);
|
||||||
|
if (rval == QLA_SUCCESS) {
|
||||||
|
bp = (uint32_t *)ha->init_cb;
|
||||||
|
for (i = 0; i < sz/4 ; i++, bp++)
|
||||||
|
*bp = cpu_to_be32(*bp);
|
||||||
|
|
||||||
|
memcpy(&ha->plogi_els_payld.data, (void *)ha->init_cb,
|
||||||
|
sizeof(ha->plogi_els_payld.data));
|
||||||
|
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
|
||||||
|
} else {
|
||||||
|
ql_dbg(ql_dbg_init, vha, 0x00d1,
|
||||||
|
"PLOGI ELS param read fail.\n");
|
||||||
|
}
|
||||||
|
return QLA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
found_devs = 0;
|
found_devs = 0;
|
||||||
new_fcport = NULL;
|
new_fcport = NULL;
|
||||||
entries = MAX_FIBRE_DEVICES_LOOP;
|
entries = MAX_FIBRE_DEVICES_LOOP;
|
||||||
@ -5105,9 +5232,19 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
|
|||||||
fcport->deleted = 0;
|
fcport->deleted = 0;
|
||||||
fcport->logout_on_delete = 1;
|
fcport->logout_on_delete = 1;
|
||||||
fcport->login_retry = vha->hw->login_retry_count;
|
fcport->login_retry = vha->hw->login_retry_count;
|
||||||
|
fcport->n2n_chip_reset = fcport->n2n_link_reset_cnt = 0;
|
||||||
|
|
||||||
qla2x00_iidma_fcport(vha, fcport);
|
qla2x00_iidma_fcport(vha, fcport);
|
||||||
|
|
||||||
|
switch (vha->hw->current_topology) {
|
||||||
|
case ISP_CFG_N:
|
||||||
|
case ISP_CFG_NL:
|
||||||
|
fcport->keep_nport_handle = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (fcport->fc4f_nvme) {
|
if (fcport->fc4f_nvme) {
|
||||||
qla_nvme_register_remote(vha, fcport);
|
qla_nvme_register_remote(vha, fcport);
|
||||||
fcport->disc_state = DSC_LOGIN_COMPLETE;
|
fcport->disc_state = DSC_LOGIN_COMPLETE;
|
||||||
@ -6992,6 +7129,9 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
|
|||||||
if (ql2xloginretrycount)
|
if (ql2xloginretrycount)
|
||||||
ha->login_retry_count = ql2xloginretrycount;
|
ha->login_retry_count = ql2xloginretrycount;
|
||||||
|
|
||||||
|
/* N2N: driver will initiate Login instead of FW */
|
||||||
|
icb->firmware_options_3 |= BIT_8;
|
||||||
|
|
||||||
/* Enable ZIO. */
|
/* Enable ZIO. */
|
||||||
if (!vha->flags.init_done) {
|
if (!vha->flags.init_done) {
|
||||||
ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
|
ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
|
||||||
@ -8076,6 +8216,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
|
|||||||
/* enable RIDA Format2 */
|
/* enable RIDA Format2 */
|
||||||
icb->firmware_options_3 |= BIT_0;
|
icb->firmware_options_3 |= BIT_0;
|
||||||
|
|
||||||
|
/* N2N: driver will initiate Login instead of FW */
|
||||||
|
icb->firmware_options_3 |= BIT_8;
|
||||||
|
|
||||||
if (IS_QLA27XX(ha)) {
|
if (IS_QLA27XX(ha)) {
|
||||||
icb->firmware_options_3 |= BIT_8;
|
icb->firmware_options_3 |= BIT_8;
|
||||||
ql_dbg(ql_log_info, vha, 0x0075,
|
ql_dbg(ql_log_info, vha, 0x0075,
|
||||||
|
@ -280,8 +280,6 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo)
|
|||||||
init_completion(&sp->comp);
|
init_completion(&sp->comp);
|
||||||
if (IS_QLAFX00(sp->vha->hw) && (sp->type == SRB_FXIOCB_DCMD))
|
if (IS_QLAFX00(sp->vha->hw) && (sp->type == SRB_FXIOCB_DCMD))
|
||||||
init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
|
init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
|
||||||
if (sp->type == SRB_ELS_DCMD)
|
|
||||||
init_completion(&sp->u.iocb_cmd.u.els_logo.comp);
|
|
||||||
add_timer(&sp->u.iocb_cmd.timer);
|
add_timer(&sp->u.iocb_cmd.timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2465,6 +2465,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
|
|||||||
sp->fcport = fcport;
|
sp->fcport = fcport;
|
||||||
elsio->timeout = qla2x00_els_dcmd_iocb_timeout;
|
elsio->timeout = qla2x00_els_dcmd_iocb_timeout;
|
||||||
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
|
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
|
||||||
|
init_completion(&sp->u.iocb_cmd.u.els_logo.comp);
|
||||||
sp->done = qla2x00_els_dcmd_sp_done;
|
sp->done = qla2x00_els_dcmd_sp_done;
|
||||||
sp->free = qla2x00_els_dcmd_sp_free;
|
sp->free = qla2x00_els_dcmd_sp_free;
|
||||||
|
|
||||||
@ -2512,7 +2513,6 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
|
|||||||
{
|
{
|
||||||
scsi_qla_host_t *vha = sp->vha;
|
scsi_qla_host_t *vha = sp->vha;
|
||||||
struct srb_iocb *elsio = &sp->u.iocb_cmd;
|
struct srb_iocb *elsio = &sp->u.iocb_cmd;
|
||||||
uint32_t dsd_len = 24;
|
|
||||||
|
|
||||||
els_iocb->entry_type = ELS_IOCB_TYPE;
|
els_iocb->entry_type = ELS_IOCB_TYPE;
|
||||||
els_iocb->entry_count = 1;
|
els_iocb->entry_count = 1;
|
||||||
@ -2535,20 +2535,21 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
|
|||||||
els_iocb->control_flags = 0;
|
els_iocb->control_flags = 0;
|
||||||
|
|
||||||
if (elsio->u.els_logo.els_cmd == ELS_DCMD_PLOGI) {
|
if (elsio->u.els_logo.els_cmd == ELS_DCMD_PLOGI) {
|
||||||
els_iocb->tx_byte_count = sizeof(struct els_plogi_payload);
|
els_iocb->tx_byte_count = els_iocb->tx_len =
|
||||||
|
sizeof(struct els_plogi_payload);
|
||||||
els_iocb->tx_address[0] =
|
els_iocb->tx_address[0] =
|
||||||
cpu_to_le32(LSD(elsio->u.els_plogi.els_plogi_pyld_dma));
|
cpu_to_le32(LSD(elsio->u.els_plogi.els_plogi_pyld_dma));
|
||||||
els_iocb->tx_address[1] =
|
els_iocb->tx_address[1] =
|
||||||
cpu_to_le32(MSD(elsio->u.els_plogi.els_plogi_pyld_dma));
|
cpu_to_le32(MSD(elsio->u.els_plogi.els_plogi_pyld_dma));
|
||||||
els_iocb->tx_len = dsd_len;
|
|
||||||
|
|
||||||
els_iocb->rx_dsd_count = 1;
|
els_iocb->rx_dsd_count = 1;
|
||||||
els_iocb->rx_byte_count = sizeof(struct els_plogi_payload);
|
els_iocb->rx_byte_count = els_iocb->rx_len =
|
||||||
|
sizeof(struct els_plogi_payload);
|
||||||
els_iocb->rx_address[0] =
|
els_iocb->rx_address[0] =
|
||||||
cpu_to_le32(LSD(elsio->u.els_plogi.els_resp_pyld_dma));
|
cpu_to_le32(LSD(elsio->u.els_plogi.els_resp_pyld_dma));
|
||||||
els_iocb->rx_address[1] =
|
els_iocb->rx_address[1] =
|
||||||
cpu_to_le32(MSD(elsio->u.els_plogi.els_resp_pyld_dma));
|
cpu_to_le32(MSD(elsio->u.els_plogi.els_resp_pyld_dma));
|
||||||
els_iocb->rx_len = dsd_len;
|
|
||||||
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073,
|
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073,
|
||||||
"PLOGI ELS IOCB:\n");
|
"PLOGI ELS IOCB:\n");
|
||||||
ql_dump_buffer(ql_log_info, vha, 0x0109,
|
ql_dump_buffer(ql_log_info, vha, 0x0109,
|
||||||
@ -2577,7 +2578,6 @@ qla2x00_els_dcmd2_iocb_timeout(void *data)
|
|||||||
fc_port_t *fcport = sp->fcport;
|
fc_port_t *fcport = sp->fcport;
|
||||||
struct scsi_qla_host *vha = sp->vha;
|
struct scsi_qla_host *vha = sp->vha;
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
struct srb_iocb *lio = &sp->u.iocb_cmd;
|
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
@ -2593,7 +2593,7 @@ qla2x00_els_dcmd2_iocb_timeout(void *data)
|
|||||||
(res == QLA_SUCCESS) ? "successful" : "failed");
|
(res == QLA_SUCCESS) ? "successful" : "failed");
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
complete(&lio->u.els_plogi.comp);
|
sp->done(sp, QLA_FUNCTION_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2603,17 +2603,54 @@ qla2x00_els_dcmd2_sp_done(void *ptr, int res)
|
|||||||
fc_port_t *fcport = sp->fcport;
|
fc_port_t *fcport = sp->fcport;
|
||||||
struct srb_iocb *lio = &sp->u.iocb_cmd;
|
struct srb_iocb *lio = &sp->u.iocb_cmd;
|
||||||
struct scsi_qla_host *vha = sp->vha;
|
struct scsi_qla_host *vha = sp->vha;
|
||||||
|
struct event_arg ea;
|
||||||
|
struct qla_work_evt *e;
|
||||||
|
|
||||||
ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3072,
|
ql_dbg(ql_dbg_disc, vha, 0x3072,
|
||||||
"%s ELS hdl=%x, portid=%06x done %8phC\n",
|
"%s ELS done rc %d hdl=%x, portid=%06x %8phC\n",
|
||||||
sp->name, sp->handle, fcport->d_id.b24, fcport->port_name);
|
sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name);
|
||||||
|
|
||||||
complete(&lio->u.els_plogi.comp);
|
fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE);
|
||||||
|
del_timer(&sp->u.iocb_cmd.timer);
|
||||||
|
|
||||||
|
if (sp->flags & SRB_WAKEUP_ON_COMP)
|
||||||
|
complete(&lio->u.els_plogi.comp);
|
||||||
|
else {
|
||||||
|
if (res) {
|
||||||
|
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
|
||||||
|
} else {
|
||||||
|
memset(&ea, 0, sizeof(ea));
|
||||||
|
ea.fcport = fcport;
|
||||||
|
ea.rc = res;
|
||||||
|
ea.event = FCME_ELS_PLOGI_DONE;
|
||||||
|
qla2x00_fcport_event_handler(vha, &ea);
|
||||||
|
}
|
||||||
|
|
||||||
|
e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
|
||||||
|
if (!e) {
|
||||||
|
struct srb_iocb *elsio = &sp->u.iocb_cmd;
|
||||||
|
|
||||||
|
if (elsio->u.els_plogi.els_plogi_pyld)
|
||||||
|
dma_free_coherent(&sp->vha->hw->pdev->dev,
|
||||||
|
elsio->u.els_plogi.tx_size,
|
||||||
|
elsio->u.els_plogi.els_plogi_pyld,
|
||||||
|
elsio->u.els_plogi.els_plogi_pyld_dma);
|
||||||
|
|
||||||
|
if (elsio->u.els_plogi.els_resp_pyld)
|
||||||
|
dma_free_coherent(&sp->vha->hw->pdev->dev,
|
||||||
|
elsio->u.els_plogi.rx_size,
|
||||||
|
elsio->u.els_plogi.els_resp_pyld,
|
||||||
|
elsio->u.els_plogi.els_resp_pyld_dma);
|
||||||
|
sp->free(sp);
|
||||||
|
}
|
||||||
|
e->u.iosb.sp = sp;
|
||||||
|
qla2x00_post_work(vha, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||||
fc_port_t *fcport, port_id_t remote_did)
|
fc_port_t *fcport, bool wait)
|
||||||
{
|
{
|
||||||
srb_t *sp;
|
srb_t *sp;
|
||||||
struct srb_iocb *elsio = NULL;
|
struct srb_iocb *elsio = NULL;
|
||||||
@ -2641,9 +2678,13 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
|||||||
|
|
||||||
elsio->timeout = qla2x00_els_dcmd2_iocb_timeout;
|
elsio->timeout = qla2x00_els_dcmd2_iocb_timeout;
|
||||||
init_completion(&elsio->u.els_plogi.comp);
|
init_completion(&elsio->u.els_plogi.comp);
|
||||||
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
|
if (wait)
|
||||||
|
sp->flags = SRB_WAKEUP_ON_COMP;
|
||||||
|
|
||||||
|
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT + 2);
|
||||||
|
|
||||||
sp->done = qla2x00_els_dcmd2_sp_done;
|
sp->done = qla2x00_els_dcmd2_sp_done;
|
||||||
|
elsio->u.els_plogi.tx_size = elsio->u.els_plogi.rx_size = DMA_POOL_SIZE;
|
||||||
|
|
||||||
ptr = elsio->u.els_plogi.els_plogi_pyld =
|
ptr = elsio->u.els_plogi.els_plogi_pyld =
|
||||||
dma_alloc_coherent(&ha->pdev->dev, DMA_POOL_SIZE,
|
dma_alloc_coherent(&ha->pdev->dev, DMA_POOL_SIZE,
|
||||||
@ -2668,33 +2709,52 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
|||||||
|
|
||||||
memset(ptr, 0, sizeof(struct els_plogi_payload));
|
memset(ptr, 0, sizeof(struct els_plogi_payload));
|
||||||
memset(resp_ptr, 0, sizeof(struct els_plogi_payload));
|
memset(resp_ptr, 0, sizeof(struct els_plogi_payload));
|
||||||
|
memcpy(elsio->u.els_plogi.els_plogi_pyld->data,
|
||||||
|
&ha->plogi_els_payld.data,
|
||||||
|
sizeof(elsio->u.els_plogi.els_plogi_pyld->data));
|
||||||
|
|
||||||
elsio->u.els_plogi.els_cmd = els_opcode;
|
elsio->u.els_plogi.els_cmd = els_opcode;
|
||||||
elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
|
elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
|
||||||
qla24xx_get_port_login_templ(vha, ptr_dma + 4,
|
|
||||||
&elsio->u.els_plogi.els_plogi_pyld->data[0],
|
|
||||||
sizeof(struct els_plogi_payload));
|
|
||||||
|
|
||||||
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n");
|
ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n");
|
||||||
ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x0109,
|
ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x0109,
|
||||||
(uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70);
|
(uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70);
|
||||||
|
|
||||||
rval = qla2x00_start_sp(sp);
|
rval = qla2x00_start_sp(sp);
|
||||||
if (rval != QLA_SUCCESS) {
|
if (rval != QLA_SUCCESS) {
|
||||||
rval = QLA_FUNCTION_FAILED;
|
rval = QLA_FUNCTION_FAILED;
|
||||||
goto out;
|
} else {
|
||||||
|
ql_dbg(ql_dbg_disc, vha, 0x3074,
|
||||||
|
"%s PLOGI sent, hdl=%x, loopid=%x, to port_id %06x from port_id %06x\n",
|
||||||
|
sp->name, sp->handle, fcport->loop_id,
|
||||||
|
fcport->d_id.b24, vha->d_id.b24);
|
||||||
}
|
}
|
||||||
|
|
||||||
ql_dbg(ql_dbg_io, vha, 0x3074,
|
if (wait) {
|
||||||
"%s PLOGI sent, hdl=%x, loopid=%x, portid=%06x\n",
|
wait_for_completion(&elsio->u.els_plogi.comp);
|
||||||
sp->name, sp->handle, fcport->loop_id, fcport->d_id.b24);
|
|
||||||
|
|
||||||
wait_for_completion(&elsio->u.els_plogi.comp);
|
if (elsio->u.els_plogi.comp_status != CS_COMPLETE)
|
||||||
|
rval = QLA_FUNCTION_FAILED;
|
||||||
if (elsio->u.els_plogi.comp_status != CS_COMPLETE)
|
} else {
|
||||||
rval = QLA_FUNCTION_FAILED;
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
fcport->flags &= ~(FCF_ASYNC_SENT);
|
||||||
|
if (elsio->u.els_plogi.els_plogi_pyld)
|
||||||
|
dma_free_coherent(&sp->vha->hw->pdev->dev,
|
||||||
|
elsio->u.els_plogi.tx_size,
|
||||||
|
elsio->u.els_plogi.els_plogi_pyld,
|
||||||
|
elsio->u.els_plogi.els_plogi_pyld_dma);
|
||||||
|
|
||||||
|
if (elsio->u.els_plogi.els_resp_pyld)
|
||||||
|
dma_free_coherent(&sp->vha->hw->pdev->dev,
|
||||||
|
elsio->u.els_plogi.rx_size,
|
||||||
|
elsio->u.els_plogi.els_resp_pyld,
|
||||||
|
elsio->u.els_plogi.els_resp_pyld_dma);
|
||||||
|
|
||||||
sp->free(sp);
|
sp->free(sp);
|
||||||
|
done:
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ static struct rom_cmd {
|
|||||||
{ MBC_IOCB_COMMAND_A64 },
|
{ MBC_IOCB_COMMAND_A64 },
|
||||||
{ MBC_GET_ADAPTER_LOOP_ID },
|
{ MBC_GET_ADAPTER_LOOP_ID },
|
||||||
{ MBC_READ_SFP },
|
{ MBC_READ_SFP },
|
||||||
|
{ MBC_GET_RNID_PARAMS },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int is_rom_cmd(uint16_t cmd)
|
static int is_rom_cmd(uint16_t cmd)
|
||||||
@ -3842,30 +3843,68 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
|
|||||||
"Format 1: WWPN %8phC.\n",
|
"Format 1: WWPN %8phC.\n",
|
||||||
vha->port_name);
|
vha->port_name);
|
||||||
|
|
||||||
/* N2N. direct connect */
|
switch (rptid_entry->u.f1.flags & TOPO_MASK) {
|
||||||
if (IS_QLA27XX(ha) &&
|
case TOPO_N2N:
|
||||||
((rptid_entry->u.f1.flags>>1) & 0x7) == 2) {
|
ha->current_topology = ISP_CFG_N;
|
||||||
/* if our portname is higher then initiate N2N login */
|
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
|
||||||
if (wwn_to_u64(vha->port_name) >
|
fcport = qla2x00_find_fcport_by_wwpn(vha,
|
||||||
wwn_to_u64(rptid_entry->u.f1.port_name)) {
|
rptid_entry->u.f1.port_name, 1);
|
||||||
// ??? qlt_update_host_map(vha, id);
|
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
||||||
vha->n2n_id = 0x1;
|
|
||||||
ql_dbg(ql_dbg_async, vha, 0x5075,
|
if (fcport) {
|
||||||
"Format 1: Setting n2n_update_needed for id %d\n",
|
fcport->plogi_nack_done_deadline = jiffies + HZ;
|
||||||
vha->n2n_id);
|
fcport->dm_login_expire = jiffies + 3*HZ;
|
||||||
|
fcport->scan_state = QLA_FCPORT_FOUND;
|
||||||
|
switch (fcport->disc_state) {
|
||||||
|
case DSC_DELETED:
|
||||||
|
set_bit(RELOGIN_NEEDED,
|
||||||
|
&vha->dpc_flags);
|
||||||
|
break;
|
||||||
|
case DSC_DELETE_PEND:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qlt_schedule_sess_for_deletion(fcport);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ql_dbg(ql_dbg_async, vha, 0x5075,
|
id.b24 = 0;
|
||||||
"Format 1: Remote login - Waiting for WWPN %8phC.\n",
|
if (wwn_to_u64(vha->port_name) >
|
||||||
rptid_entry->u.f1.port_name);
|
wwn_to_u64(rptid_entry->u.f1.port_name)) {
|
||||||
|
vha->d_id.b24 = 0;
|
||||||
|
vha->d_id.b.al_pa = 1;
|
||||||
|
ha->flags.n2n_bigger = 1;
|
||||||
|
|
||||||
|
id.b.al_pa = 2;
|
||||||
|
ql_dbg(ql_dbg_async, vha, 0x5075,
|
||||||
|
"Format 1: assign local id %x remote id %x\n",
|
||||||
|
vha->d_id.b24, id.b24);
|
||||||
|
} else {
|
||||||
|
ql_dbg(ql_dbg_async, vha, 0x5075,
|
||||||
|
"Format 1: Remote login - Waiting for WWPN %8phC.\n",
|
||||||
|
rptid_entry->u.f1.port_name);
|
||||||
|
ha->flags.n2n_bigger = 0;
|
||||||
|
}
|
||||||
|
qla24xx_post_newsess_work(vha, &id,
|
||||||
|
rptid_entry->u.f1.port_name,
|
||||||
|
rptid_entry->u.f1.node_name,
|
||||||
|
NULL,
|
||||||
|
FC4_TYPE_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(vha->n2n_port_name, rptid_entry->u.f1.port_name,
|
/* if our portname is higher then initiate N2N login */
|
||||||
WWN_SIZE);
|
|
||||||
set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
|
set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
|
||||||
set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
|
|
||||||
set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
|
|
||||||
ha->flags.n2n_ae = 1;
|
ha->flags.n2n_ae = 1;
|
||||||
return;
|
return;
|
||||||
|
break;
|
||||||
|
case TOPO_FL:
|
||||||
|
ha->current_topology = ISP_CFG_FL;
|
||||||
|
break;
|
||||||
|
case TOPO_F:
|
||||||
|
ha->current_topology = ISP_CFG_F;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha->flags.gpsc_supported = 1;
|
ha->flags.gpsc_supported = 1;
|
||||||
@ -4681,7 +4720,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
|
|||||||
"Done %s.\n", __func__);
|
"Done %s.\n", __func__);
|
||||||
bp = (uint32_t *) buf;
|
bp = (uint32_t *) buf;
|
||||||
for (i = 0; i < (bufsiz-4)/4; i++, bp++)
|
for (i = 0; i < (bufsiz-4)/4; i++, bp++)
|
||||||
*bp = cpu_to_be32(*bp);
|
*bp = le32_to_cpu(*bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
|
@ -30,6 +30,9 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!vha->nvme_local_port && qla_nvme_register_hba(vha))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!(fcport->nvme_prli_service_param &
|
if (!(fcport->nvme_prli_service_param &
|
||||||
(NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)) ||
|
(NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)) ||
|
||||||
(fcport->nvme_flag & NVME_FLAG_REGISTERED))
|
(fcport->nvme_flag & NVME_FLAG_REGISTERED))
|
||||||
@ -676,15 +679,15 @@ void qla_nvme_delete(struct scsi_qla_host *vha)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qla_nvme_register_hba(struct scsi_qla_host *vha)
|
int qla_nvme_register_hba(struct scsi_qla_host *vha)
|
||||||
{
|
{
|
||||||
struct nvme_fc_port_template *tmpl;
|
struct nvme_fc_port_template *tmpl;
|
||||||
struct qla_hw_data *ha;
|
struct qla_hw_data *ha;
|
||||||
struct nvme_fc_port_info pinfo;
|
struct nvme_fc_port_info pinfo;
|
||||||
int ret;
|
int ret = EINVAL;
|
||||||
|
|
||||||
if (!IS_ENABLED(CONFIG_NVME_FC))
|
if (!IS_ENABLED(CONFIG_NVME_FC))
|
||||||
return;
|
return ret;
|
||||||
|
|
||||||
ha = vha->hw;
|
ha = vha->hw;
|
||||||
tmpl = &qla_nvme_fc_transport;
|
tmpl = &qla_nvme_fc_transport;
|
||||||
@ -711,7 +714,9 @@ void qla_nvme_register_hba(struct scsi_qla_host *vha)
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
ql_log(ql_log_warn, vha, 0xffff,
|
ql_log(ql_log_warn, vha, 0xffff,
|
||||||
"register_localport failed: ret=%x\n", ret);
|
"register_localport failed: ret=%x\n", ret);
|
||||||
return;
|
} else {
|
||||||
|
vha->nvme_local_port->private = vha;
|
||||||
}
|
}
|
||||||
vha->nvme_local_port->private = vha;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ struct pt_ls4_rx_unsol {
|
|||||||
/*
|
/*
|
||||||
* Global functions prototype in qla_nvme.c source file.
|
* Global functions prototype in qla_nvme.c source file.
|
||||||
*/
|
*/
|
||||||
void qla_nvme_register_hba(struct scsi_qla_host *);
|
int qla_nvme_register_hba(struct scsi_qla_host *);
|
||||||
int qla_nvme_register_remote(struct scsi_qla_host *, struct fc_port *);
|
int qla_nvme_register_remote(struct scsi_qla_host *, struct fc_port *);
|
||||||
void qla_nvme_delete(struct scsi_qla_host *);
|
void qla_nvme_delete(struct scsi_qla_host *);
|
||||||
void qla_nvme_abort(struct qla_hw_data *, struct srb *sp, int res);
|
void qla_nvme_abort(struct qla_hw_data *, struct srb *sp, int res);
|
||||||
|
@ -4789,7 +4789,6 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
|
|||||||
struct qlt_plogi_ack_t *pla =
|
struct qlt_plogi_ack_t *pla =
|
||||||
(struct qlt_plogi_ack_t *)e->u.new_sess.pla;
|
(struct qlt_plogi_ack_t *)e->u.new_sess.pla;
|
||||||
uint8_t free_fcport = 0;
|
uint8_t free_fcport = 0;
|
||||||
u64 wwn;
|
|
||||||
|
|
||||||
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
ql_dbg(ql_dbg_disc, vha, 0xffff,
|
||||||
"%s %d %8phC enter\n",
|
"%s %d %8phC enter\n",
|
||||||
@ -4817,10 +4816,10 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
|
|||||||
fcport->d_id = e->u.new_sess.id;
|
fcport->d_id = e->u.new_sess.id;
|
||||||
fcport->flags |= FCF_FABRIC_DEVICE;
|
fcport->flags |= FCF_FABRIC_DEVICE;
|
||||||
fcport->fw_login_state = DSC_LS_PLOGI_PEND;
|
fcport->fw_login_state = DSC_LS_PLOGI_PEND;
|
||||||
if (e->u.new_sess.fc4_type & FS_FC4TYPE_FCP)
|
if (e->u.new_sess.fc4_type == FS_FC4TYPE_FCP)
|
||||||
fcport->fc4_type = FC4_TYPE_FCP_SCSI;
|
fcport->fc4_type = FC4_TYPE_FCP_SCSI;
|
||||||
|
|
||||||
if (e->u.new_sess.fc4_type & FS_FC4TYPE_NVME) {
|
if (e->u.new_sess.fc4_type == FS_FC4TYPE_NVME) {
|
||||||
fcport->fc4_type = FC4_TYPE_OTHER;
|
fcport->fc4_type = FC4_TYPE_OTHER;
|
||||||
fcport->fc4f_nvme = FC4_TYPE_NVME;
|
fcport->fc4f_nvme = FC4_TYPE_NVME;
|
||||||
}
|
}
|
||||||
@ -4862,9 +4861,6 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
|
|||||||
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
||||||
|
|
||||||
if (fcport) {
|
if (fcport) {
|
||||||
if (N2N_TOPO(vha->hw))
|
|
||||||
fcport->flags &= ~FCF_FABRIC_DEVICE;
|
|
||||||
|
|
||||||
fcport->id_changed = 1;
|
fcport->id_changed = 1;
|
||||||
fcport->scan_state = QLA_FCPORT_FOUND;
|
fcport->scan_state = QLA_FCPORT_FOUND;
|
||||||
memcpy(fcport->node_name, e->u.new_sess.node_name, WWN_SIZE);
|
memcpy(fcport->node_name, e->u.new_sess.node_name, WWN_SIZE);
|
||||||
@ -4925,12 +4921,22 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
|
|||||||
if (dfcp)
|
if (dfcp)
|
||||||
qlt_schedule_sess_for_deletion(tfcp);
|
qlt_schedule_sess_for_deletion(tfcp);
|
||||||
|
|
||||||
wwn = wwn_to_u64(fcport->node_name);
|
|
||||||
|
|
||||||
if (!wwn)
|
if (N2N_TOPO(vha->hw))
|
||||||
qla24xx_async_gnnid(vha, fcport);
|
fcport->flags &= ~FCF_FABRIC_DEVICE;
|
||||||
else
|
|
||||||
qla24xx_async_gnl(vha, fcport);
|
if (N2N_TOPO(vha->hw)) {
|
||||||
|
if (vha->flags.nvme_enabled) {
|
||||||
|
fcport->fc4f_nvme = 1;
|
||||||
|
fcport->n2n_flag = 1;
|
||||||
|
}
|
||||||
|
fcport->fw_login_state = 0;
|
||||||
|
/*
|
||||||
|
* wait link init done before sending login
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
qla24xx_fcport_handle_login(vha, fcport);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5065,6 +5071,10 @@ qla2x00_do_work(struct scsi_qla_host *vha)
|
|||||||
case QLA_EVT_IIDMA:
|
case QLA_EVT_IIDMA:
|
||||||
qla_do_iidma_work(vha, e->u.fcport.fcport);
|
qla_do_iidma_work(vha, e->u.fcport.fcport);
|
||||||
break;
|
break;
|
||||||
|
case QLA_EVT_ELS_PLOGI:
|
||||||
|
qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI,
|
||||||
|
e->u.fcport.fcport, false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (e->flags & QLA_EVT_FLAG_FREE)
|
if (e->flags & QLA_EVT_FLAG_FREE)
|
||||||
kfree(e);
|
kfree(e);
|
||||||
|
@ -1619,9 +1619,6 @@ static void tcm_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id,
|
|||||||
|
|
||||||
sess->conf_compl_supported = conf_compl_supported;
|
sess->conf_compl_supported = conf_compl_supported;
|
||||||
|
|
||||||
/* Reset logout parameters to default */
|
|
||||||
sess->logout_on_delete = 1;
|
|
||||||
sess->keep_nport_handle = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user