Skip to content

Commit

Permalink
scsi: qla2xxx: Changes to support N2N logins
Browse files Browse the repository at this point in the history
If we discovered a topology that is N2N then we will issue a login to
the target. If our WWPN is bigger than the target's WWPN then we will
initiate login, otherwise we will just wait for the target to initiate
login.

[mkp: many whitespace errors]

Signed-off-by: Duane Grigsby <duane.grigsby@cavium.com>
Signed-off-by: Michael Hernandez <michael.hernandez@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Tested-by: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Duane Grigsby authored and Martin K. Petersen committed Oct 17, 2017
1 parent c0c462c commit edd05de
Show file tree
Hide file tree
Showing 7 changed files with 459 additions and 21 deletions.
24 changes: 24 additions & 0 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,12 @@ struct els_logo_payload {
uint8_t wwpn[WWN_SIZE];
};

struct els_plogi_payload {
uint8_t opcode;
uint8_t rsvd[3];
uint8_t data[112];
};

struct ct_arg {
void *iocb;
u16 nport_handle;
Expand Down Expand Up @@ -358,6 +364,19 @@ struct srb_iocb {
dma_addr_t els_logo_pyld_dma;
} els_logo;
struct {
#define ELS_DCMD_PLOGI 0x3
uint32_t flags;
uint32_t els_cmd;
struct completion comp;
struct els_plogi_payload *els_plogi_pyld;
struct els_plogi_payload *els_resp_pyld;
dma_addr_t els_plogi_pyld_dma;
dma_addr_t els_resp_pyld_dma;
uint32_t fw_status[3];
__le16 comp_status;
__le16 len;
} els_plogi;
struct {
/*
* Values for flags field below are as
* defined in tsk_mgmt_entry struct
Expand Down Expand Up @@ -2349,6 +2368,7 @@ typedef struct fc_port {
uint8_t fc4_type;
uint8_t fc4f_nvme;
uint8_t scan_state;
uint8_t n2n_flag;

unsigned long last_queue_full;
unsigned long last_ramp_up;
Expand All @@ -2372,6 +2392,7 @@ typedef struct fc_port {
u8 iocb[IOCB_SIZE];
u8 current_login_state;
u8 last_login_state;
struct completion n2n_done;
} fc_port_t;

#define QLA_FCPORT_SCAN 1
Expand Down Expand Up @@ -4228,6 +4249,9 @@ typedef struct scsi_qla_host {
wait_queue_head_t fcport_waitQ;
wait_queue_head_t vref_waitq;
uint8_t min_link_speed_feat;
uint8_t n2n_node_name[WWN_SIZE];
uint8_t n2n_port_name[WWN_SIZE];
uint16_t n2n_id;
} scsi_qla_host_t;

struct qla27xx_image_status {
Expand Down
4 changes: 1 addition & 3 deletions drivers/scsi/qla2xxx/qla_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -753,9 +753,7 @@ struct els_entry_24xx {
uint8_t reserved_2;

uint8_t port_id[3];
uint8_t reserved_3;

uint16_t reserved_4;
uint8_t s_id[3];

uint16_t control_flags; /* Control flags. */
#define ECF_PAYLOAD_DESCR_MASK (BIT_15|BIT_14|BIT_13)
Expand Down
4 changes: 4 additions & 0 deletions drivers/scsi/qla2xxx/qla_gbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ 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 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 *,
port_id_t);

extern void qla2x00_update_fcports(scsi_qla_host_t *);

Expand Down Expand Up @@ -487,6 +489,8 @@ int qla24xx_gidlist_wait(struct scsi_qla_host *, void *, dma_addr_t,
uint16_t *);
int __qla24xx_parse_gpdb(struct scsi_qla_host *, fc_port_t *,
struct port_database_24xx *);
int qla24xx_get_port_login_templ(scsi_qla_host_t *, dma_addr_t,
void *, uint16_t);

extern int qla27xx_get_zio_threshold(scsi_qla_host_t *, uint16_t *);
extern int qla27xx_set_zio_threshold(scsi_qla_host_t *, uint16_t);
Expand Down
135 changes: 131 additions & 4 deletions drivers/scsi/qla2xxx/qla_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,14 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
qla24xx_post_gpdb_work(vha, ea->fcport, 0);
break;
default:
if (ea->fcport->n2n_flag) {
ql_dbg(ql_dbg_disc, vha, 0x2118,
"%s %d %8phC post fc4 prli\n",
__func__, __LINE__, ea->fcport->port_name);
ea->fcport->fc4f_nvme = 0;
ea->fcport->n2n_flag = 0;
qla24xx_post_prli_work(vha, ea->fcport);
}
ql_dbg(ql_dbg_disc, vha, 0x2119,
"%s %d %8phC unhandle event of %x\n",
__func__, __LINE__, ea->fcport->port_name, ea->data[0]);
Expand Down Expand Up @@ -4366,7 +4374,109 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
return (rval);
}

/*
* N2N Login
* Updates Fibre Channel Device Database with local loop devices.
*
* Input:
* ha = adapter block pointer.
*
* Returns:
*/
static int qla24xx_n2n_handle_login(struct scsi_qla_host *vha,
fc_port_t *fcport)
{
struct qla_hw_data *ha = vha->hw;
int res = QLA_SUCCESS, rval;
int greater_wwpn = 0;
int logged_in = 0;

if (ha->current_topology != ISP_CFG_N)
return res;

if (wwn_to_u64(vha->port_name) >
wwn_to_u64(vha->n2n_port_name)) {
ql_dbg(ql_dbg_disc, vha, 0x2002,
"HBA WWPN is greater %llx > target %llx\n",
wwn_to_u64(vha->port_name),
wwn_to_u64(vha->n2n_port_name));
greater_wwpn = 1;
fcport->d_id.b24 = vha->n2n_id;
}

fcport->loop_id = vha->loop_id;
fcport->fc4f_nvme = 0;
fcport->query = 1;

ql_dbg(ql_dbg_disc, vha, 0x4001,
"Initiate N2N login handler: HBA port_id=%06x loopid=%d\n",
fcport->d_id.b24, vha->loop_id);

/* Fill in member data. */
if (!greater_wwpn) {
rval = qla2x00_get_port_database(vha, fcport, 0);
ql_dbg(ql_dbg_disc, vha, 0x1051,
"Remote login-state (%x/%x) port_id=%06x loop_id=%x, rval=%d\n",
fcport->current_login_state, fcport->last_login_state,
fcport->d_id.b24, fcport->loop_id, rval);

if (((fcport->current_login_state & 0xf) == 0x4) ||
((fcport->current_login_state & 0xf) == 0x6))
logged_in = 1;
}

if (logged_in || greater_wwpn) {
if (!vha->nvme_local_port && vha->flags.nvme_enabled)
qla_nvme_register_hba(vha);

/* Set connected N_Port d_id */
if (vha->flags.nvme_enabled)
fcport->fc4f_nvme = 1;

fcport->scan_state = QLA_FCPORT_FOUND;
fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
fcport->disc_state = DSC_GNL;
fcport->n2n_flag = 1;
fcport->flags = 3;
vha->hw->flags.gpsc_supported = 0;

if (greater_wwpn) {
ql_dbg(ql_dbg_disc, vha, 0x20e5,
"%s %d PLOGI ELS %8phC\n",
__func__, __LINE__, fcport->port_name);

res = qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI,
fcport, fcport->d_id);
}

if (res != QLA_SUCCESS) {
ql_log(ql_log_info, vha, 0xd04d,
"PLOGI Failed: portid=%06x - retrying\n",
fcport->d_id.b24);
res = QLA_SUCCESS;
} else {
/* State 0x6 means FCP PRLI complete */
if ((fcport->current_login_state & 0xf) == 0x6) {
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);
}
}
} else {
/* Wait for next database change */
set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
}

return res;
}

/*
* qla2x00_configure_local_loop
Expand Down Expand Up @@ -4437,6 +4547,14 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
}
}

/* Inititae N2N login. */
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
rval = qla24xx_n2n_handle_login(vha, new_fcport);
if (rval != QLA_SUCCESS)
goto cleanup_allocation;
return QLA_SUCCESS;
}

/* Add devices to port list. */
id_iter = (char *)ha->gid_list;
for (index = 0; index < entries; index++) {
Expand Down Expand Up @@ -4478,10 +4596,13 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
"Failed to retrieve fcport information "
"-- get_port_database=%x, loop_id=0x%04x.\n",
rval2, new_fcport->loop_id);
ql_dbg(ql_dbg_disc, vha, 0x2105,
"Scheduling resync.\n");
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
continue;
/* Skip retry if N2N */
if (ha->current_topology != ISP_CFG_N) {
ql_dbg(ql_dbg_disc, vha, 0x2105,
"Scheduling resync.\n");
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
continue;
}
}

spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
Expand Down Expand Up @@ -7554,6 +7675,12 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
if (qla_tgt_mode_enabled(vha) || qla_dual_mode_enabled(vha))
icb->firmware_options_3 |= BIT_0;

if (IS_QLA27XX(ha)) {
icb->firmware_options_3 |= BIT_8;
ql_dbg(ql_log_info, vha, 0x0075,
"Enabling direct connection.\n");
}

if (rval) {
ql_log(ql_log_warn, vha, 0x0076,
"NVRAM configuration failed.\n");
Expand Down
Loading

0 comments on commit edd05de

Please sign in to comment.