lpfc_disc.h 14.1 KB
Newer Older
已提交
1 2
/*******************************************************************
 * This file is part of the Emulex Linux Device Driver for         *
3
 * Fibre Channel Host Bus Adapters.                                *
4 5
 * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term *
 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.     *
6
 * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
7
 * EMULEX and SLI are trademarks of Emulex.                        *
J
James Smart 已提交
8
 * www.broadcom.com                                                *
已提交
9 10
 *                                                                 *
 * This program is free software; you can redistribute it and/or   *
11 12 13 14 15 16 17 18 19 20
 * modify it under the terms of version 2 of the GNU General       *
 * Public License as published by the Free Software Foundation.    *
 * This program is distributed in the hope that it will be useful. *
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
 * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
 * more details, a copy of which can be found in the file COPYING  *
 * included with this package.                                     *
已提交
21 22 23
 *******************************************************************/

#define FC_MAX_HOLD_RSCN     32	      /* max number of deferred RSCNs */
24
#define FC_MAX_NS_RSP        64512    /* max size NameServer rsp */
已提交
25 26 27 28 29 30 31 32
#define FC_MAXLOOP           126      /* max devices supported on a fc loop */
#define LPFC_DISC_FLOGI_TMO  10	      /* Discovery FLOGI ratov */


/* This is the protocol dependent definition for a Node List Entry.
 * This is used by Fibre Channel protocol to support FCP.
 */

33 34 35
/* worker thread events */
enum lpfc_work_type {
	LPFC_EVT_ONLINE,
36
	LPFC_EVT_OFFLINE_PREP,
37 38 39 40
	LPFC_EVT_OFFLINE,
	LPFC_EVT_WARM_START,
	LPFC_EVT_KILL,
	LPFC_EVT_ELS_RETRY,
41
	LPFC_EVT_DEV_LOSS,
42
	LPFC_EVT_FASTPATH_MGMT_EVT,
43
	LPFC_EVT_RESET_HBA,
44 45
};

已提交
46 47 48
/* structure used to queue event to the discovery tasklet */
struct lpfc_work_evt {
	struct list_head      evt_listp;
49 50
	void                 *evt_arg1;
	void                 *evt_arg2;
51
	enum lpfc_work_type   evt;
已提交
52 53
};

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
struct lpfc_scsi_check_condition_event;
struct lpfc_scsi_varqueuedepth_event;
struct lpfc_scsi_event_header;
struct lpfc_fabric_event_header;
struct lpfc_fcprdchkerr_event;

/* structure used for sending events from fast path */
struct lpfc_fast_path_event {
	struct lpfc_work_evt work_evt;
	struct lpfc_vport     *vport;
	union {
		struct lpfc_scsi_check_condition_event check_cond_evt;
		struct lpfc_scsi_varqueuedepth_event queue_depth_evt;
		struct lpfc_scsi_event_header scsi_evt;
		struct lpfc_fabric_event_header fabric_evt;
		struct lpfc_fcprdchkerr_event read_check_error;
	} un;
};
已提交
72

73 74 75 76 77 78
#define LPFC_SLI4_MAX_XRI	1024	/* Used to make the ndlp's xri_bitmap */
#define XRI_BITMAP_ULONGS (LPFC_SLI4_MAX_XRI / BITS_PER_LONG)
struct lpfc_node_rrqs {
	unsigned long xri_bitmap[XRI_BITMAP_ULONGS];
};

已提交
79 80
struct lpfc_nodelist {
	struct list_head nlp_listp;
J
James Smart 已提交
81 82
	struct lpfc_name nlp_portname;
	struct lpfc_name nlp_nodename;
83
	uint32_t         nlp_flag;		/* entry flags */
已提交
84 85 86 87 88 89 90
	uint32_t         nlp_DID;		/* FC D_ID of entry */
	uint32_t         nlp_last_elscmd;	/* Last ELS cmd sent */
	uint16_t         nlp_type;
#define NLP_FC_NODE        0x1			/* entry is an FC node */
#define NLP_FABRIC         0x4			/* entry rep a Fabric entity */
#define NLP_FCP_TARGET     0x8			/* entry is an FCP target */
#define NLP_FCP_INITIATOR  0x10			/* entry is an FCP Initiator */
91 92
#define NLP_NVME_TARGET    0x20			/* entry is a NVME Target */
#define NLP_NVME_INITIATOR 0x40			/* entry is a NVME Initiator */
93
#define NLP_NVME_DISCOVERY 0x80                 /* entry has NVME disc srvc */
94 95 96 97 98 99 100 101 102

	uint16_t	nlp_fc4_type;		/* FC types node supports. */
						/* Assigned from GID_FF, only
						 * FCP (0x8) and NVME (0x28)
						 * supported.
						 */
#define NLP_FC4_NONE	0x0
#define NLP_FC4_FCP	0x1			/* FC4 Type FCP (value x8)) */
#define NLP_FC4_NVME	0x2			/* FC4 TYPE NVME (value x28) */
已提交
103 104 105

	uint16_t        nlp_rpi;
	uint16_t        nlp_state;		/* state transition indicator */
106
	uint16_t        nlp_prev_state;		/* state transition indicator */
已提交
107 108 109 110 111 112 113 114 115
	uint16_t        nlp_xri;		/* output exchange id for RPI */
	uint16_t        nlp_sid;		/* scsi id */
#define NLP_NO_SID		0xffff
	uint16_t	nlp_maxframe;		/* Max RCV frame size */
	uint8_t		nlp_class_sup;		/* Supported Classes */
	uint8_t         nlp_retry;		/* used for ELS retries */
	uint8_t         nlp_fcp_info;	        /* class info, bits 0-3 */
#define NLP_FCP_2_DEVICE   0x10			/* FCP-2 device */

116 117 118 119 120 121
	uint16_t        nlp_usg_map;	/* ndlp management usage bitmap */
#define NLP_USG_NODE_ACT_BIT	0x1	/* Indicate ndlp is actively used */
#define NLP_USG_IACT_REQ_BIT	0x2	/* Request to inactivate ndlp */
#define NLP_USG_FREE_REQ_BIT	0x4	/* Request to invoke ndlp memory free */
#define NLP_USG_FREE_ACK_BIT	0x8	/* Indicate ndlp memory free invoked */

已提交
122
	struct timer_list   nlp_delayfunc;	/* Used for delayed ELS cmds */
123
	struct lpfc_hba *phba;
124 125
	struct fc_rport *rport;		/* scsi_transport_fc port structure */
	struct lpfc_nvme_rport *nrport;	/* nvme transport rport struct. */
J
James Smart 已提交
126
	struct lpfc_vport *vport;
已提交
127
	struct lpfc_work_evt els_retry_evt;
128
	struct lpfc_work_evt dev_loss_evt;
129
	struct kref     kref;
130 131 132
	atomic_t cmd_pending;
	uint32_t cmd_qdepth;
	unsigned long last_change_time;
133
	unsigned long *active_rrqs_xri_bitmap;
134
	struct lpfc_scsicmd_bkt *lat_data;	/* Latency data */
135 136
	uint32_t fc4_prli_sent;
	uint32_t upcall_flags;
137 138
#define NLP_WAIT_FOR_UNREG    0x1

139 140
	uint32_t nvme_fb_size; /* NVME target's supported byte cnt */
#define NVME_FB_BIT_SHIFT 9    /* PRLI Rsp first burst in 512B units. */
已提交
141
};
142 143 144 145 146 147 148 149 150 151
struct lpfc_node_rrq {
	struct list_head list;
	uint16_t xritag;
	uint16_t send_rrq;
	uint16_t rxid;
	uint32_t         nlp_DID;		/* FC D_ID of entry */
	struct lpfc_vport *vport;
	struct lpfc_nodelist *ndlp;
	unsigned long rrq_stop_time;
};
已提交
152

153 154 155
#define lpfc_ndlp_check_qdepth(phba, ndlp) \
	(ndlp->cmd_qdepth < phba->sli4_hba.max_cfg_param.max_xri)

已提交
156
/* Defines for nlp_flag (uint32) */
157 158
#define NLP_IGNR_REG_CMPL  0x00000001 /* Rcvd rscn before we cmpl reg login */
#define NLP_REG_LOGIN_SEND 0x00000002   /* sent reglogin to adapter */
159
#define NLP_SUPPRESS_RSP   0x00000010	/* Remote NPort supports suppress rsp */
160 161 162 163 164 165
#define NLP_PLOGI_SND      0x00000020	/* sent PLOGI request for this entry */
#define NLP_PRLI_SND       0x00000040	/* sent PRLI request for this entry */
#define NLP_ADISC_SND      0x00000080	/* sent ADISC request for this entry */
#define NLP_LOGO_SND       0x00000100	/* sent LOGO request for this entry */
#define NLP_RNID_SND       0x00000400	/* sent RNID request for this entry */
#define NLP_ELS_SND_MASK   0x000007e0	/* sent ELS request for this entry */
166
#define NLP_NVMET_RECOV    0x00001000   /* NVMET auditing node for recovery. */
167
#define NLP_FCP_PRLI_RJT   0x00002000   /* Rport does not support FCP PRLI. */
168 169 170 171 172 173
#define NLP_DEFER_RM       0x00010000	/* Remove this ndlp if no longer used */
#define NLP_DELAY_TMO      0x00020000	/* delay timeout is running for node */
#define NLP_NPR_2B_DISC    0x00040000	/* node is included in num_disc_nodes */
#define NLP_RCV_PLOGI      0x00080000	/* Rcv'ed PLOGI from remote system */
#define NLP_LOGO_ACC       0x00100000	/* Process LOGO after ACC completes */
#define NLP_TGT_NO_SCSIID  0x00200000	/* good PRLI but no binding for scsid */
174
#define NLP_ISSUE_LOGO     0x00400000	/* waiting to issue a LOGO */
J
James Smart 已提交
175
#define NLP_IN_DEV_LOSS    0x00800000	/* devloss in progress */
176
#define NLP_ACC_REGLOGIN   0x01000000	/* Issue Reg Login after successful
已提交
177
					   ACC */
178
#define NLP_NPR_ADISC      0x02000000	/* Issue ADISC when dq'ed from
已提交
179
					   NPR list */
180 181
#define NLP_RM_DFLT_RPI    0x04000000	/* need to remove leftover dflt RPI */
#define NLP_NODEV_REMOVE   0x08000000	/* Defer removal till discovery ends */
182
#define NLP_TARGET_REMOVE  0x10000000   /* Target remove in process */
183
#define NLP_SC_REQ         0x20000000	/* Target requires authentication */
184
#define NLP_FIRSTBURST     0x40000000	/* Target supports FirstBurst */
185
#define NLP_RPI_REGISTERED 0x80000000	/* nlp_rpi is valid */
已提交
186

187

188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
/* ndlp usage management macros */
#define NLP_CHK_NODE_ACT(ndlp)		(((ndlp)->nlp_usg_map \
						& NLP_USG_NODE_ACT_BIT) \
					&& \
					!((ndlp)->nlp_usg_map \
						& NLP_USG_FREE_ACK_BIT))
#define NLP_SET_NODE_ACT(ndlp)		((ndlp)->nlp_usg_map \
						|= NLP_USG_NODE_ACT_BIT)
#define NLP_INT_NODE_ACT(ndlp)		((ndlp)->nlp_usg_map \
						= NLP_USG_NODE_ACT_BIT)
#define NLP_CLR_NODE_ACT(ndlp)		((ndlp)->nlp_usg_map \
						&= ~NLP_USG_NODE_ACT_BIT)
#define NLP_CHK_IACT_REQ(ndlp)          ((ndlp)->nlp_usg_map \
						& NLP_USG_IACT_REQ_BIT)
#define NLP_SET_IACT_REQ(ndlp)          ((ndlp)->nlp_usg_map \
						|= NLP_USG_IACT_REQ_BIT)
#define NLP_CHK_FREE_REQ(ndlp)		((ndlp)->nlp_usg_map \
						& NLP_USG_FREE_REQ_BIT)
#define NLP_SET_FREE_REQ(ndlp)		((ndlp)->nlp_usg_map \
						|= NLP_USG_FREE_REQ_BIT)
#define NLP_CHK_FREE_ACK(ndlp)		((ndlp)->nlp_usg_map \
						& NLP_USG_FREE_ACK_BIT)
#define NLP_SET_FREE_ACK(ndlp)		((ndlp)->nlp_usg_map \
						|= NLP_USG_FREE_ACK_BIT)

已提交
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
/* There are 4 different double linked lists nodelist entries can reside on.
 * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used
 * when Link Up discovery or Registered State Change Notification (RSCN)
 * processing is needed.  Each list holds the nodes that require a PLOGI or
 * ADISC Extended Link Service (ELS) request.  These lists keep track of the
 * nodes affected by an RSCN, or a Link Up (Typically, all nodes are effected
 * by Link Up) event.  The unmapped_list contains all nodes that have
 * successfully logged into at the Fibre Channel level.  The
 * mapped_list will contain all nodes that are mapped FCP targets.
 *
 * The bind list is a list of undiscovered (potentially non-existent) nodes
 * that we have saved binding information on. This information is used when
 * nodes transition from the unmapped to the mapped list.
 */

/* Defines for nlp_state */
#define NLP_STE_UNUSED_NODE       0x0	/* node is just allocated */
#define NLP_STE_PLOGI_ISSUE       0x1	/* PLOGI was sent to NL_PORT */
#define NLP_STE_ADISC_ISSUE       0x2	/* ADISC was sent to NL_PORT */
#define NLP_STE_REG_LOGIN_ISSUE   0x3	/* REG_LOGIN was issued for NL_PORT */
#define NLP_STE_PRLI_ISSUE        0x4	/* PRLI was sent to NL_PORT */
234 235 236 237 238
#define NLP_STE_LOGO_ISSUE	  0x5	/* LOGO was sent to NL_PORT */
#define NLP_STE_UNMAPPED_NODE     0x6	/* PRLI completed from NL_PORT */
#define NLP_STE_MAPPED_NODE       0x7	/* Identified as a FCP Target */
#define NLP_STE_NPR_NODE          0x8	/* NPort disappeared */
#define NLP_STE_MAX_STATE         0x9
已提交
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
#define NLP_STE_FREED_NODE        0xff	/* node entry was freed to MEM_NLP */

/* For UNUSED_NODE state, the node has just been allocated.
 * For PLOGI_ISSUE and REG_LOGIN_ISSUE, the node is on
 * the PLOGI list. For REG_LOGIN_COMPL, the node is taken off the PLOGI list
 * and put on the unmapped list. For ADISC processing, the node is taken off
 * the ADISC list and placed on either the mapped or unmapped list (depending
 * on its previous state). Once on the unmapped list, a PRLI is issued and the
 * state changed to PRLI_ISSUE. When the PRLI completion occurs, the state is
 * changed to PRLI_COMPL. If the completion indicates a mapped
 * node, the node is taken off the unmapped list. The binding list is checked
 * for a valid binding, or a binding is automatically assigned. If binding
 * assignment is unsuccessful, the node is left on the unmapped list. If
 * binding assignment is successful, the associated binding list entry (if
 * any) is removed, and the node is placed on the mapped list.
 */
/*
 * For a Link Down, all nodes on the ADISC, PLOGI, unmapped or mapped
257
 * lists will receive a DEVICE_RECOVERY event. If the linkdown or devloss timers
已提交
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
 * expire, all effected nodes will receive a DEVICE_RM event.
 */
/*
 * For a Link Up or RSCN, all nodes will move from the mapped / unmapped lists
 * to either the ADISC or PLOGI list.  After a Nameserver query or ALPA loopmap
 * check, additional nodes may be added (DEVICE_ADD) or removed (DEVICE_RM) to /
 * from the PLOGI or ADISC lists. Once the PLOGI and ADISC lists are populated,
 * we will first process the ADISC list.  32 entries are processed initially and
 * ADISC is initited for each one.  Completions / Events for each node are
 * funnelled thru the state machine.  As each node finishes ADISC processing, it
 * starts ADISC for any nodes waiting for ADISC processing. If no nodes are
 * waiting, and the ADISC list count is identically 0, then we are done. For
 * Link Up discovery, since all nodes on the PLOGI list are UNREG_LOGIN'ed, we
 * can issue a CLEAR_LA and reenable Link Events. Next we will process the PLOGI
 * list.  32 entries are processed initially and PLOGI is initited for each one.
 * Completions / Events for each node are funnelled thru the state machine.  As
 * each node finishes PLOGI processing, it starts PLOGI for any nodes waiting
 * for PLOGI processing. If no nodes are waiting, and the PLOGI list count is
 * identically 0, then we are done. We have now completed discovery / RSCN
 * handling. Upon completion, ALL nodes should be on either the mapped or
 * unmapped lists.
 */

/* Defines for Node List Entry Events that could happen */
#define NLP_EVT_RCV_PLOGI         0x0	/* Rcv'd an ELS PLOGI command */
#define NLP_EVT_RCV_PRLI          0x1	/* Rcv'd an ELS PRLI  command */
#define NLP_EVT_RCV_LOGO          0x2	/* Rcv'd an ELS LOGO  command */
#define NLP_EVT_RCV_ADISC         0x3	/* Rcv'd an ELS ADISC command */
#define NLP_EVT_RCV_PDISC         0x4	/* Rcv'd an ELS PDISC command */
#define NLP_EVT_RCV_PRLO          0x5	/* Rcv'd an ELS PRLO  command */
#define NLP_EVT_CMPL_PLOGI        0x6	/* Sent an ELS PLOGI command */
#define NLP_EVT_CMPL_PRLI         0x7	/* Sent an ELS PRLI  command */
#define NLP_EVT_CMPL_LOGO         0x8	/* Sent an ELS LOGO  command */
#define NLP_EVT_CMPL_ADISC        0x9	/* Sent an ELS ADISC command */
#define NLP_EVT_CMPL_REG_LOGIN    0xa	/* REG_LOGIN mbox cmd completed */
#define NLP_EVT_DEVICE_RM         0xb	/* Device not found in NS / ALPAmap */
#define NLP_EVT_DEVICE_RECOVERY   0xc	/* Device existence unknown */
#define NLP_EVT_MAX_EVENT         0xd