Skip to content

Commit 726b854

Browse files
Quinn TranNicholas Bellinger
authored andcommitted
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 <[email protected]> Signed-off-by: Himanshu Madhani <[email protected]> [ bvanassche: fixed spelling in patch description ] Signed-off-by: Bart Van Assche <[email protected]> Signed-off-by: Nicholas Bellinger <[email protected]>
1 parent 5d96483 commit 726b854

File tree

13 files changed

+3114
-987
lines changed

13 files changed

+3114
-987
lines changed

drivers/scsi/qla2xxx/qla_attr.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,6 +2163,9 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
21632163
clear_bit(vha->vp_idx, ha->vp_idx_map);
21642164
mutex_unlock(&ha->vport_lock);
21652165

2166+
dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l,
2167+
vha->gnl.ldma);
2168+
21662169
if (vha->qpair->vp_idx == vha->vp_idx) {
21672170
if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS)
21682171
ql_log(ql_log_warn, vha, 0x7087,

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 171 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555

5656
#include "qla_settings.h"
5757

58+
#define MODE_DUAL (MODE_TARGET | MODE_INITIATOR)
59+
5860
/*
5961
* Data bit definitions
6062
*/
@@ -251,6 +253,14 @@
251253

252254
#define MAX_CMDSZ 16 /* SCSI maximum CDB size. */
253255
#include "qla_fw.h"
256+
257+
struct name_list_extended {
258+
struct get_name_list_extended *l;
259+
dma_addr_t ldma;
260+
struct list_head fcports; /* protect by sess_list */
261+
u32 size;
262+
u8 sent;
263+
};
254264
/*
255265
* Timeout timer counts in seconds
256266
*/
@@ -309,6 +319,17 @@ struct els_logo_payload {
309319
uint8_t wwpn[WWN_SIZE];
310320
};
311321

322+
struct ct_arg {
323+
void *iocb;
324+
u16 nport_handle;
325+
dma_addr_t req_dma;
326+
dma_addr_t rsp_dma;
327+
u32 req_size;
328+
u32 rsp_size;
329+
void *req;
330+
void *rsp;
331+
};
332+
312333
/*
313334
* SRB extensions.
314335
*/
@@ -320,6 +341,7 @@ struct srb_iocb {
320341
#define SRB_LOGIN_COND_PLOGI BIT_1
321342
#define SRB_LOGIN_SKIP_PRLI BIT_2
322343
uint16_t data[2];
344+
u32 iop[2];
323345
} logio;
324346
struct {
325347
#define ELS_DCMD_TIMEOUT 20
@@ -372,6 +394,16 @@ struct srb_iocb {
372394
__le16 comp_status;
373395
struct completion comp;
374396
} abt;
397+
struct ct_arg ctarg;
398+
struct {
399+
__le16 in_mb[28]; /* fr fw */
400+
__le16 out_mb[28]; /* to fw */
401+
void *out, *in;
402+
dma_addr_t out_dma, in_dma;
403+
} mbx;
404+
struct {
405+
struct imm_ntfy_from_isp *ntfy;
406+
} nack;
375407
} u;
376408

377409
struct timer_list timer;
@@ -392,16 +424,24 @@ struct srb_iocb {
392424
#define SRB_FXIOCB_BCMD 11
393425
#define SRB_ABT_CMD 12
394426
#define SRB_ELS_DCMD 13
427+
#define SRB_MB_IOCB 14
428+
#define SRB_CT_PTHRU_CMD 15
429+
#define SRB_NACK_PLOGI 16
430+
#define SRB_NACK_PRLI 17
431+
#define SRB_NACK_LOGO 18
395432

396433
typedef struct srb {
397434
atomic_t ref_count;
398435
struct fc_port *fcport;
436+
void *vha;
399437
uint32_t handle;
400438
uint16_t flags;
401439
uint16_t type;
402440
char *name;
403441
int iocbs;
404442
struct qla_qpair *qpair;
443+
u32 gen1; /* scratch */
444+
u32 gen2; /* scratch */
405445
union {
406446
struct srb_iocb iocb_cmd;
407447
struct bsg_job *bsg_job;
@@ -2101,6 +2141,18 @@ typedef struct {
21012141
#define FC4_TYPE_OTHER 0x0
21022142
#define FC4_TYPE_UNKNOWN 0xff
21032143

2144+
/* mailbox command 4G & above */
2145+
struct mbx_24xx_entry {
2146+
uint8_t entry_type;
2147+
uint8_t entry_count;
2148+
uint8_t sys_define1;
2149+
uint8_t entry_status;
2150+
uint32_t handle;
2151+
uint16_t mb[28];
2152+
};
2153+
2154+
#define IOCB_SIZE 64
2155+
21042156
/*
21052157
* Fibre channel port type.
21062158
*/
@@ -2113,6 +2165,12 @@ typedef enum {
21132165
FCT_TARGET
21142166
} fc_port_type_t;
21152167

2168+
enum qla_sess_deletion {
2169+
QLA_SESS_DELETION_NONE = 0,
2170+
QLA_SESS_DELETION_IN_PROGRESS,
2171+
QLA_SESS_DELETED,
2172+
};
2173+
21162174
enum qlt_plogi_link_t {
21172175
QLT_PLOGI_LINK_SAME_WWN,
21182176
QLT_PLOGI_LINK_CONFLICT,
@@ -2124,6 +2182,48 @@ struct qlt_plogi_ack_t {
21242182
struct imm_ntfy_from_isp iocb;
21252183
port_id_t id;
21262184
int ref_count;
2185+
void *fcport;
2186+
};
2187+
2188+
struct ct_sns_desc {
2189+
struct ct_sns_pkt *ct_sns;
2190+
dma_addr_t ct_sns_dma;
2191+
};
2192+
2193+
enum discovery_state {
2194+
DSC_DELETED,
2195+
DSC_GID_PN,
2196+
DSC_GNL,
2197+
DSC_LOGIN_PEND,
2198+
DSC_LOGIN_FAILED,
2199+
DSC_GPDB,
2200+
DSC_GPSC,
2201+
DSC_UPD_FCPORT,
2202+
DSC_LOGIN_COMPLETE,
2203+
DSC_DELETE_PEND,
2204+
};
2205+
2206+
enum login_state { /* FW control Target side */
2207+
DSC_LS_LLIOCB_SENT = 2,
2208+
DSC_LS_PLOGI_PEND,
2209+
DSC_LS_PLOGI_COMP,
2210+
DSC_LS_PRLI_PEND,
2211+
DSC_LS_PRLI_COMP,
2212+
DSC_LS_PORT_UNAVAIL,
2213+
DSC_LS_PRLO_PEND = 9,
2214+
DSC_LS_LOGO_PEND,
2215+
};
2216+
2217+
enum fcport_mgt_event {
2218+
FCME_RELOGIN = 1,
2219+
FCME_RSCN,
2220+
FCME_GIDPN_DONE,
2221+
FCME_PLOGI_DONE, /* Initiator side sent LLIOCB */
2222+
FCME_GNL_DONE,
2223+
FCME_GPSC_DONE,
2224+
FCME_GPDB_DONE,
2225+
FCME_GPNID_DONE,
2226+
FCME_DELETE_DONE,
21272227
};
21282228

21292229
/*
@@ -2143,9 +2243,13 @@ typedef struct fc_port {
21432243
unsigned int deleted:2;
21442244
unsigned int local:1;
21452245
unsigned int logout_on_delete:1;
2246+
unsigned int logo_ack_needed:1;
21462247
unsigned int keep_nport_handle:1;
21472248
unsigned int send_els_logo:1;
2249+
unsigned int login_pause:1;
2250+
unsigned int login_succ:1;
21482251

2252+
struct fc_port *conflict;
21492253
unsigned char logout_completed;
21502254
int generation;
21512255

@@ -2186,8 +2290,30 @@ typedef struct fc_port {
21862290

21872291
unsigned long retry_delay_timestamp;
21882292
struct qla_tgt_sess *tgt_session;
2293+
struct ct_sns_desc ct_desc;
2294+
enum discovery_state disc_state;
2295+
enum login_state fw_login_state;
2296+
u32 login_gen, last_login_gen;
2297+
u32 rscn_gen, last_rscn_gen;
2298+
u32 chip_reset;
2299+
struct list_head gnl_entry;
2300+
struct work_struct del_work;
2301+
u8 iocb[IOCB_SIZE];
21892302
} fc_port_t;
21902303

2304+
#define QLA_FCPORT_SCAN 1
2305+
#define QLA_FCPORT_FOUND 2
2306+
2307+
struct event_arg {
2308+
enum fcport_mgt_event event;
2309+
fc_port_t *fcport;
2310+
srb_t *sp;
2311+
port_id_t id;
2312+
u16 data[2], rc;
2313+
u8 port_name[WWN_SIZE];
2314+
u32 iop[2];
2315+
};
2316+
21912317
#include "qla_mr.h"
21922318

21932319
/*
@@ -2265,6 +2391,10 @@ static const char * const port_state_str[] = {
22652391
#define GFT_ID_REQ_SIZE (16 + 4)
22662392
#define GFT_ID_RSP_SIZE (16 + 32)
22672393

2394+
#define GID_PN_CMD 0x121
2395+
#define GID_PN_REQ_SIZE (16 + 8)
2396+
#define GID_PN_RSP_SIZE (16 + 4)
2397+
22682398
#define RFT_ID_CMD 0x217
22692399
#define RFT_ID_REQ_SIZE (16 + 4 + 32)
22702400
#define RFT_ID_RSP_SIZE 16
@@ -2590,6 +2720,10 @@ struct ct_sns_req {
25902720
uint8_t reserved;
25912721
uint8_t port_name[3];
25922722
} gff_id;
2723+
2724+
struct {
2725+
uint8_t port_name[8];
2726+
} gid_pn;
25932727
} req;
25942728
};
25952729

@@ -2669,6 +2803,10 @@ struct ct_sns_rsp {
26692803
struct {
26702804
uint8_t fc4_features[128];
26712805
} gff_id;
2806+
struct {
2807+
uint8_t reserved;
2808+
uint8_t port_id[3];
2809+
} gid_pn;
26722810
} rsp;
26732811
};
26742812

@@ -2810,11 +2948,11 @@ struct isp_operations {
28102948

28112949
uint16_t (*calc_req_entries) (uint16_t);
28122950
void (*build_iocbs) (srb_t *, cmd_entry_t *, uint16_t);
2813-
void * (*prep_ms_iocb) (struct scsi_qla_host *, uint32_t, uint32_t);
2814-
void * (*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t,
2951+
void *(*prep_ms_iocb) (struct scsi_qla_host *, struct ct_arg *);
2952+
void *(*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t,
28152953
uint32_t);
28162954

2817-
uint8_t * (*read_nvram) (struct scsi_qla_host *, uint8_t *,
2955+
uint8_t *(*read_nvram) (struct scsi_qla_host *, uint8_t *,
28182956
uint32_t, uint32_t);
28192957
int (*write_nvram) (struct scsi_qla_host *, uint8_t *, uint32_t,
28202958
uint32_t);
@@ -2876,13 +3014,21 @@ enum qla_work_type {
28763014
QLA_EVT_AEN,
28773015
QLA_EVT_IDC_ACK,
28783016
QLA_EVT_ASYNC_LOGIN,
2879-
QLA_EVT_ASYNC_LOGIN_DONE,
28803017
QLA_EVT_ASYNC_LOGOUT,
28813018
QLA_EVT_ASYNC_LOGOUT_DONE,
28823019
QLA_EVT_ASYNC_ADISC,
28833020
QLA_EVT_ASYNC_ADISC_DONE,
28843021
QLA_EVT_UEVENT,
28853022
QLA_EVT_AENFX,
3023+
QLA_EVT_GIDPN,
3024+
QLA_EVT_GPNID,
3025+
QLA_EVT_GPNID_DONE,
3026+
QLA_EVT_NEW_SESS,
3027+
QLA_EVT_GPDB,
3028+
QLA_EVT_GPSC,
3029+
QLA_EVT_UPD_FCPORT,
3030+
QLA_EVT_GNL,
3031+
QLA_EVT_NACK,
28863032
};
28873033

28883034

@@ -2918,6 +3064,23 @@ struct qla_work_evt {
29183064
struct {
29193065
srb_t *sp;
29203066
} iosb;
3067+
struct {
3068+
port_id_t id;
3069+
} gpnid;
3070+
struct {
3071+
port_id_t id;
3072+
u8 port_name[8];
3073+
void *pla;
3074+
} new_sess;
3075+
struct { /*Get PDB, Get Speed, update fcport, gnl, gidpn */
3076+
fc_port_t *fcport;
3077+
u8 opt;
3078+
} fcport;
3079+
struct {
3080+
fc_port_t *fcport;
3081+
u8 iocb[IOCB_SIZE];
3082+
int type;
3083+
} nack;
29213084
} u;
29223085
};
29233086

@@ -3899,6 +4062,10 @@ typedef struct scsi_qla_host {
38994062
struct qla8044_reset_template reset_tmplt;
39004063
struct qla_tgt_counters tgt_counters;
39014064
uint16_t bbcr;
4065+
struct name_list_extended gnl;
4066+
/* Count of active session/fcport */
4067+
int fcport_count;
4068+
wait_queue_head_t fcport_waitQ;
39024069
} scsi_qla_host_t;
39034070

39044071
struct qla27xx_image_status {

drivers/scsi/qla2xxx/qla_fw.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,37 @@ struct port_database_24xx {
7272
uint8_t reserved_3[24];
7373
};
7474

75+
/*
76+
* MB 75h returns a list of DB entries similar to port_database_24xx(64B).
77+
* However, in this case it returns 1st 40 bytes.
78+
*/
79+
struct get_name_list_extended {
80+
__le16 flags;
81+
u8 current_login_state;
82+
u8 last_login_state;
83+
u8 hard_address[3];
84+
u8 reserved_1;
85+
u8 port_id[3];
86+
u8 sequence_id;
87+
__le16 port_timer;
88+
__le16 nport_handle; /* N_PORT handle. */
89+
__le16 receive_data_size;
90+
__le16 reserved_2;
91+
92+
/* PRLI SVC Param are Big endian */
93+
u8 prli_svc_param_word_0[2]; /* Bits 15-0 of word 0 */
94+
u8 prli_svc_param_word_3[2]; /* Bits 15-0 of word 3 */
95+
u8 port_name[WWN_SIZE];
96+
u8 node_name[WWN_SIZE];
97+
};
98+
99+
/* MB 75h: This is the short version of the database */
100+
struct get_name_list {
101+
u8 port_node_name[WWN_SIZE]; /* B7 most sig, B0 least sig */
102+
__le16 nport_handle;
103+
u8 reserved;
104+
};
105+
75106
struct vp_database_24xx {
76107
uint16_t vp_status;
77108
uint8_t options;

0 commit comments

Comments
 (0)