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

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: edd05de1 ("scsi: qla2xxx: Changes to support N2N logins")
Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 0eaaca4c
...@@ -398,6 +398,8 @@ struct srb_iocb { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 *); ...@@ -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) ...@@ -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);
......
This diff is collapsed.
...@@ -280,8 +280,6 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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_disc, vha, 0x3072,
"%s ELS done rc %d hdl=%x, portid=%06x %8phC\n",
sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name);
ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3072, fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE);
"%s ELS hdl=%x, portid=%06x done %8phC\n", del_timer(&sp->u.iocb_cmd.timer);
sp->name, sp->handle, fcport->d_id.b24, fcport->port_name);
complete(&lio->u.els_plogi.comp); 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, ...@@ -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, ...@@ -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) if (elsio->u.els_plogi.comp_status != CS_COMPLETE)
rval = QLA_FUNCTION_FAILED; rval = QLA_FUNCTION_FAILED;
} else {
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 { ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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;
} }
/* /*
......
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