qla2xxx: Add framework for async fabric discovery
Currently code performs a full scan of the fabric for every RSCN. Its an expensive process in a noisy large SAN. This patch optimizes expensive fabric discovery process by scanning switch for the affected port when RSCN is received. Currently Initiator Mode code makes login/logout decision without knowledge of target mode. This causes driver and firmware to go out-of-sync. This framework synchronizes both initiator mode personality and target mode personality in making login/logout decision. This patch adds following capabilities in the driver - Send Notification Acknowledgement asynchronously. - Update session/fcport state asynchronously. - Create a session or fcport struct asynchronously. - Send GNL asynchronously. The command will ask FW to provide a list of FC Port entries FW knows about. - Send GPDB asynchronously. The command will ask FW to provide detail data of an FC Port FW knows about or perform ADISC to verify the state of the session. - Send GPNID asynchronously. The command will ask switch to provide WWPN for provided NPort ID. - Send GPSC asynchronously. The command will ask switch to provide registered port speed for provided WWPN. - Send GIDPN asynchronously. The command will ask the switch to provide Nport ID for provided WWPN. - In driver unload path, schedule all session for deletion and wait for deletion to complete before allowing driver unload to proceed. Signed-off-by: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> [ bvanassche: fixed spelling in patch description ] Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
committed by
Nicholas Bellinger
parent
5d964837c6
commit
726b854870
@@ -55,6 +55,8 @@
|
||||
|
||||
#include "qla_settings.h"
|
||||
|
||||
#define MODE_DUAL (MODE_TARGET | MODE_INITIATOR)
|
||||
|
||||
/*
|
||||
* Data bit definitions
|
||||
*/
|
||||
@@ -251,6 +253,14 @@
|
||||
|
||||
#define MAX_CMDSZ 16 /* SCSI maximum CDB size. */
|
||||
#include "qla_fw.h"
|
||||
|
||||
struct name_list_extended {
|
||||
struct get_name_list_extended *l;
|
||||
dma_addr_t ldma;
|
||||
struct list_head fcports; /* protect by sess_list */
|
||||
u32 size;
|
||||
u8 sent;
|
||||
};
|
||||
/*
|
||||
* Timeout timer counts in seconds
|
||||
*/
|
||||
@@ -309,6 +319,17 @@ struct els_logo_payload {
|
||||
uint8_t wwpn[WWN_SIZE];
|
||||
};
|
||||
|
||||
struct ct_arg {
|
||||
void *iocb;
|
||||
u16 nport_handle;
|
||||
dma_addr_t req_dma;
|
||||
dma_addr_t rsp_dma;
|
||||
u32 req_size;
|
||||
u32 rsp_size;
|
||||
void *req;
|
||||
void *rsp;
|
||||
};
|
||||
|
||||
/*
|
||||
* SRB extensions.
|
||||
*/
|
||||
@@ -320,6 +341,7 @@ struct srb_iocb {
|
||||
#define SRB_LOGIN_COND_PLOGI BIT_1
|
||||
#define SRB_LOGIN_SKIP_PRLI BIT_2
|
||||
uint16_t data[2];
|
||||
u32 iop[2];
|
||||
} logio;
|
||||
struct {
|
||||
#define ELS_DCMD_TIMEOUT 20
|
||||
@@ -372,6 +394,16 @@ struct srb_iocb {
|
||||
__le16 comp_status;
|
||||
struct completion comp;
|
||||
} abt;
|
||||
struct ct_arg ctarg;
|
||||
struct {
|
||||
__le16 in_mb[28]; /* fr fw */
|
||||
__le16 out_mb[28]; /* to fw */
|
||||
void *out, *in;
|
||||
dma_addr_t out_dma, in_dma;
|
||||
} mbx;
|
||||
struct {
|
||||
struct imm_ntfy_from_isp *ntfy;
|
||||
} nack;
|
||||
} u;
|
||||
|
||||
struct timer_list timer;
|
||||
@@ -392,16 +424,24 @@ struct srb_iocb {
|
||||
#define SRB_FXIOCB_BCMD 11
|
||||
#define SRB_ABT_CMD 12
|
||||
#define SRB_ELS_DCMD 13
|
||||
#define SRB_MB_IOCB 14
|
||||
#define SRB_CT_PTHRU_CMD 15
|
||||
#define SRB_NACK_PLOGI 16
|
||||
#define SRB_NACK_PRLI 17
|
||||
#define SRB_NACK_LOGO 18
|
||||
|
||||
typedef struct srb {
|
||||
atomic_t ref_count;
|
||||
struct fc_port *fcport;
|
||||
void *vha;
|
||||
uint32_t handle;
|
||||
uint16_t flags;
|
||||
uint16_t type;
|
||||
char *name;
|
||||
int iocbs;
|
||||
struct qla_qpair *qpair;
|
||||
u32 gen1; /* scratch */
|
||||
u32 gen2; /* scratch */
|
||||
union {
|
||||
struct srb_iocb iocb_cmd;
|
||||
struct bsg_job *bsg_job;
|
||||
@@ -2101,6 +2141,18 @@ typedef struct {
|
||||
#define FC4_TYPE_OTHER 0x0
|
||||
#define FC4_TYPE_UNKNOWN 0xff
|
||||
|
||||
/* mailbox command 4G & above */
|
||||
struct mbx_24xx_entry {
|
||||
uint8_t entry_type;
|
||||
uint8_t entry_count;
|
||||
uint8_t sys_define1;
|
||||
uint8_t entry_status;
|
||||
uint32_t handle;
|
||||
uint16_t mb[28];
|
||||
};
|
||||
|
||||
#define IOCB_SIZE 64
|
||||
|
||||
/*
|
||||
* Fibre channel port type.
|
||||
*/
|
||||
@@ -2113,6 +2165,12 @@ typedef enum {
|
||||
FCT_TARGET
|
||||
} fc_port_type_t;
|
||||
|
||||
enum qla_sess_deletion {
|
||||
QLA_SESS_DELETION_NONE = 0,
|
||||
QLA_SESS_DELETION_IN_PROGRESS,
|
||||
QLA_SESS_DELETED,
|
||||
};
|
||||
|
||||
enum qlt_plogi_link_t {
|
||||
QLT_PLOGI_LINK_SAME_WWN,
|
||||
QLT_PLOGI_LINK_CONFLICT,
|
||||
@@ -2124,6 +2182,48 @@ struct qlt_plogi_ack_t {
|
||||
struct imm_ntfy_from_isp iocb;
|
||||
port_id_t id;
|
||||
int ref_count;
|
||||
void *fcport;
|
||||
};
|
||||
|
||||
struct ct_sns_desc {
|
||||
struct ct_sns_pkt *ct_sns;
|
||||
dma_addr_t ct_sns_dma;
|
||||
};
|
||||
|
||||
enum discovery_state {
|
||||
DSC_DELETED,
|
||||
DSC_GID_PN,
|
||||
DSC_GNL,
|
||||
DSC_LOGIN_PEND,
|
||||
DSC_LOGIN_FAILED,
|
||||
DSC_GPDB,
|
||||
DSC_GPSC,
|
||||
DSC_UPD_FCPORT,
|
||||
DSC_LOGIN_COMPLETE,
|
||||
DSC_DELETE_PEND,
|
||||
};
|
||||
|
||||
enum login_state { /* FW control Target side */
|
||||
DSC_LS_LLIOCB_SENT = 2,
|
||||
DSC_LS_PLOGI_PEND,
|
||||
DSC_LS_PLOGI_COMP,
|
||||
DSC_LS_PRLI_PEND,
|
||||
DSC_LS_PRLI_COMP,
|
||||
DSC_LS_PORT_UNAVAIL,
|
||||
DSC_LS_PRLO_PEND = 9,
|
||||
DSC_LS_LOGO_PEND,
|
||||
};
|
||||
|
||||
enum fcport_mgt_event {
|
||||
FCME_RELOGIN = 1,
|
||||
FCME_RSCN,
|
||||
FCME_GIDPN_DONE,
|
||||
FCME_PLOGI_DONE, /* Initiator side sent LLIOCB */
|
||||
FCME_GNL_DONE,
|
||||
FCME_GPSC_DONE,
|
||||
FCME_GPDB_DONE,
|
||||
FCME_GPNID_DONE,
|
||||
FCME_DELETE_DONE,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2143,9 +2243,13 @@ typedef struct fc_port {
|
||||
unsigned int deleted:2;
|
||||
unsigned int local:1;
|
||||
unsigned int logout_on_delete:1;
|
||||
unsigned int logo_ack_needed:1;
|
||||
unsigned int keep_nport_handle:1;
|
||||
unsigned int send_els_logo:1;
|
||||
unsigned int login_pause:1;
|
||||
unsigned int login_succ:1;
|
||||
|
||||
struct fc_port *conflict;
|
||||
unsigned char logout_completed;
|
||||
int generation;
|
||||
|
||||
@@ -2186,8 +2290,30 @@ typedef struct fc_port {
|
||||
|
||||
unsigned long retry_delay_timestamp;
|
||||
struct qla_tgt_sess *tgt_session;
|
||||
struct ct_sns_desc ct_desc;
|
||||
enum discovery_state disc_state;
|
||||
enum login_state fw_login_state;
|
||||
u32 login_gen, last_login_gen;
|
||||
u32 rscn_gen, last_rscn_gen;
|
||||
u32 chip_reset;
|
||||
struct list_head gnl_entry;
|
||||
struct work_struct del_work;
|
||||
u8 iocb[IOCB_SIZE];
|
||||
} fc_port_t;
|
||||
|
||||
#define QLA_FCPORT_SCAN 1
|
||||
#define QLA_FCPORT_FOUND 2
|
||||
|
||||
struct event_arg {
|
||||
enum fcport_mgt_event event;
|
||||
fc_port_t *fcport;
|
||||
srb_t *sp;
|
||||
port_id_t id;
|
||||
u16 data[2], rc;
|
||||
u8 port_name[WWN_SIZE];
|
||||
u32 iop[2];
|
||||
};
|
||||
|
||||
#include "qla_mr.h"
|
||||
|
||||
/*
|
||||
@@ -2265,6 +2391,10 @@ static const char * const port_state_str[] = {
|
||||
#define GFT_ID_REQ_SIZE (16 + 4)
|
||||
#define GFT_ID_RSP_SIZE (16 + 32)
|
||||
|
||||
#define GID_PN_CMD 0x121
|
||||
#define GID_PN_REQ_SIZE (16 + 8)
|
||||
#define GID_PN_RSP_SIZE (16 + 4)
|
||||
|
||||
#define RFT_ID_CMD 0x217
|
||||
#define RFT_ID_REQ_SIZE (16 + 4 + 32)
|
||||
#define RFT_ID_RSP_SIZE 16
|
||||
@@ -2590,6 +2720,10 @@ struct ct_sns_req {
|
||||
uint8_t reserved;
|
||||
uint8_t port_name[3];
|
||||
} gff_id;
|
||||
|
||||
struct {
|
||||
uint8_t port_name[8];
|
||||
} gid_pn;
|
||||
} req;
|
||||
};
|
||||
|
||||
@@ -2669,6 +2803,10 @@ struct ct_sns_rsp {
|
||||
struct {
|
||||
uint8_t fc4_features[128];
|
||||
} gff_id;
|
||||
struct {
|
||||
uint8_t reserved;
|
||||
uint8_t port_id[3];
|
||||
} gid_pn;
|
||||
} rsp;
|
||||
};
|
||||
|
||||
@@ -2810,11 +2948,11 @@ struct isp_operations {
|
||||
|
||||
uint16_t (*calc_req_entries) (uint16_t);
|
||||
void (*build_iocbs) (srb_t *, cmd_entry_t *, uint16_t);
|
||||
void * (*prep_ms_iocb) (struct scsi_qla_host *, uint32_t, uint32_t);
|
||||
void * (*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t,
|
||||
void *(*prep_ms_iocb) (struct scsi_qla_host *, struct ct_arg *);
|
||||
void *(*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t,
|
||||
uint32_t);
|
||||
|
||||
uint8_t * (*read_nvram) (struct scsi_qla_host *, uint8_t *,
|
||||
uint8_t *(*read_nvram) (struct scsi_qla_host *, uint8_t *,
|
||||
uint32_t, uint32_t);
|
||||
int (*write_nvram) (struct scsi_qla_host *, uint8_t *, uint32_t,
|
||||
uint32_t);
|
||||
@@ -2876,13 +3014,21 @@ enum qla_work_type {
|
||||
QLA_EVT_AEN,
|
||||
QLA_EVT_IDC_ACK,
|
||||
QLA_EVT_ASYNC_LOGIN,
|
||||
QLA_EVT_ASYNC_LOGIN_DONE,
|
||||
QLA_EVT_ASYNC_LOGOUT,
|
||||
QLA_EVT_ASYNC_LOGOUT_DONE,
|
||||
QLA_EVT_ASYNC_ADISC,
|
||||
QLA_EVT_ASYNC_ADISC_DONE,
|
||||
QLA_EVT_UEVENT,
|
||||
QLA_EVT_AENFX,
|
||||
QLA_EVT_GIDPN,
|
||||
QLA_EVT_GPNID,
|
||||
QLA_EVT_GPNID_DONE,
|
||||
QLA_EVT_NEW_SESS,
|
||||
QLA_EVT_GPDB,
|
||||
QLA_EVT_GPSC,
|
||||
QLA_EVT_UPD_FCPORT,
|
||||
QLA_EVT_GNL,
|
||||
QLA_EVT_NACK,
|
||||
};
|
||||
|
||||
|
||||
@@ -2918,6 +3064,23 @@ struct qla_work_evt {
|
||||
struct {
|
||||
srb_t *sp;
|
||||
} iosb;
|
||||
struct {
|
||||
port_id_t id;
|
||||
} gpnid;
|
||||
struct {
|
||||
port_id_t id;
|
||||
u8 port_name[8];
|
||||
void *pla;
|
||||
} new_sess;
|
||||
struct { /*Get PDB, Get Speed, update fcport, gnl, gidpn */
|
||||
fc_port_t *fcport;
|
||||
u8 opt;
|
||||
} fcport;
|
||||
struct {
|
||||
fc_port_t *fcport;
|
||||
u8 iocb[IOCB_SIZE];
|
||||
int type;
|
||||
} nack;
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -3899,6 +4062,10 @@ typedef struct scsi_qla_host {
|
||||
struct qla8044_reset_template reset_tmplt;
|
||||
struct qla_tgt_counters tgt_counters;
|
||||
uint16_t bbcr;
|
||||
struct name_list_extended gnl;
|
||||
/* Count of active session/fcport */
|
||||
int fcport_count;
|
||||
wait_queue_head_t fcport_waitQ;
|
||||
} scsi_qla_host_t;
|
||||
|
||||
struct qla27xx_image_status {
|
||||
|
||||
Reference in New Issue
Block a user