1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at
9  * http://www.opensource.org/licenses/cddl1.txt.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2004-2012 Emulex. All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <emlxs.h>
28 
29 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
30 EMLXS_MSG_DEF(EMLXS_FCF_C);
31 
32 /*
33  * STATE MACHINE RULES:
34  *
35  * - State change requests to an XXXX object when operating within
36  * an emlxs_XXXX state management function must be made
37  * using the emlxs_XXXX_state() call.
38  *
39  * - State change requests to an XXXX object when operating outside
40  * an emlxs_XXXX state management function must be made
41  * using the emlxs_XXXX_alloc(), emlxs_XXXX_free(), emlxs_XXXX_event()
42  * or emlxs_XXXX_..._notify() calls.
43  *
44  * - emlxs_XXXX_..._notify() calls are used by routines outside
45  * this fcf module to enter the state machine.
46  *
47  * - It is forbidden to make direct calls to emlxs_XXXX_...._action()
48  * functions.  Only emlxs_XXXX_action() routines may make calls to
49  * emlxs_XXXX_...._action() functions.
50  *
51  * - Its is forbidden to make direct calls to emlxs_XXXX_action().
52  * Only emlxs_XXXX_state() and emlxs_XXXX_event() routines may make
53  * calls to emlxs_XXXX_action().
54  *
55  * - The EMLXS_FCF_LOCK must be held before calling:
56  * emlxs_XXXX_state(), emlxs_XXXX_event() and emlxs_XXXX_action().
57  *
58  * - All other calls touching fcftab, fcfi, vfi, vpi, rpi objects
59  * must hold the EMLXS_FCF_LOCK to protect these objects.
60  */
61 
62 /*
63  * DEBUG MESSAGE TERMINATION RULES:
64  *
65  * - A message should end in ">" if a thread operating outside the
66  * XXXX state machine enters the XXXX state machine with a call to
67  * emlxs_XXXX_event() or emlxs_XXXX_state().  This includes calls made
68  * from emlxs_..._notify(), emlxs_..._mbcmpl() and emlxs_..._timer()
69  * routines since they represent the beginnning of new threads.
70  *
71  * - A message should end in "<" if the thread is about exit
72  * an emlxs_XXXX_..._action() without previously calling the
73  * next emlxs_XXXX_state().  This includes the emlxs_XXXX_action()
74  * and emlxs_XXXX_state() routines themselves since errors
75  * in these routines represent the termination of state change
76  * thread.
77  *
78  * - A message should end in "." if none of the previous
79  * conditions apply.
80  */
81 
82 /* ************************************************************************** */
83 /* FCF Generic */
84 /* ************************************************************************** */
85 
86 /*
87  * EVENT			ARG1
88  * --------------------------------------------
89  * FCF_EVENT_STATE_ENTER	None
90  *
91  * FCF_EVENT_LINKUP		None
92  * FCF_EVENT_LINKDOWN		None
93  * FCF_EVENT_CVL		vpi
94  * FCF_EVENT_FCFTAB_FULL	None
95  * FCF_EVENT_FCF_FOUND		fcf_index
96  * FCF_EVENT_FCF_LOST		fcf_index
97  * FCF_EVENT_FCF_CHANGED	fcf_index
98  *
99  * FCF_EVENT_FCFI_ONLINE	FCFIobj_t*
100  * FCF_EVENT_FCFI_OFFLINE	FCFIobj_t*
101  * FCF_EVENT_FCFI_PAUSE		FCFIobj_t*
102  *
103  * FCF_EVENT_VFI_ONLINE		VFIobj_t*
104  * FCF_EVENT_VFI_OFFLINE	VFIobj_t*
105  * FCF_EVENT_VFI_PAUSE		VFIobj_t*
106  *
107  * FCF_EVENT_VPI_ONLINE		VPIobj_t*
108  * FCF_EVENT_VPI_OFFLINE	VPIobj_t*
109  * FCF_EVENT_VPI_PAUSE		VPIobj_t*
110  *
111  * FCF_EVENT_RPI_ONLINE		RPIobj_t*
112  * FCF_EVENT_RPI_OFFLINE	RPIobj_t*
113  * FCF_EVENT_RPI_PAUSE		RPIobj_t*
114  * FCF_EVENT_RPI_RESUME		RPIobj_t*
115  * FCF_EVENT_RPI_TIMEOUT	RPIobj_t*
116  */
117 
118 /* Order does not matter */
119 emlxs_table_t emlxs_fcf_event_table[] =
120 {
121 	{FCF_EVENT_STATE_ENTER, "E_ENTER"},
122 
123 	{FCF_EVENT_SHUTDOWN, "E_SHUTDOWN"},
124 	{FCF_EVENT_LINKUP, "E_LINKUP"},
125 	{FCF_EVENT_LINKDOWN, "E_LINKDOWN"},
126 	{FCF_EVENT_CVL, "E_CVL"},
127 	{FCF_EVENT_FCFTAB_FULL, "E_TABLE_FULL"},
128 	{FCF_EVENT_FCF_FOUND, "E_FCF_FOUND"},
129 	{FCF_EVENT_FCF_LOST, "E_FCF_LOST"},
130 	{FCF_EVENT_FCF_CHANGED, "E_FCF_CHANGED"},
131 
132 	{FCF_EVENT_FCFI_ONLINE, "E_FCFI_ONLINE"},
133 	{FCF_EVENT_FCFI_OFFLINE, "E_FCFI_OFFLINE"},
134 	{FCF_EVENT_FCFI_PAUSE, "E_FCFI_PAUSE"},
135 
136 	{FCF_EVENT_VFI_ONLINE, "E_VFI_ONLINE"},
137 	{FCF_EVENT_VFI_OFFLINE, "E_VFI_OFFLINE"},
138 	{FCF_EVENT_VFI_PAUSE, "E_VFI_PAUSE"},
139 
140 	{FCF_EVENT_VPI_ONLINE, "E_VPI_ONLINE"},
141 	{FCF_EVENT_VPI_OFFLINE, "E_VPI_OFFLINE"},
142 	{FCF_EVENT_VPI_PAUSE, "E_VPI_PAUSE"},
143 
144 	{FCF_EVENT_RPI_ONLINE, "E_RPI_ONLINE"},
145 	{FCF_EVENT_RPI_OFFLINE, "E_RPI_OFFLINE"},
146 	{FCF_EVENT_RPI_PAUSE, "E_RPI_PAUSE"},
147 	{FCF_EVENT_RPI_RESUME, "E_RPI_RESUME"},
148 
149 }; /* emlxs_fcf_event_table */
150 
151 
152 /* Order does not matter */
153 emlxs_table_t emlxs_fcf_reason_table[] =
154 {
155 	{FCF_REASON_NONE, "R_NONE"},
156 	{FCF_REASON_REENTER, "R_REENTER"},
157 	{FCF_REASON_EVENT, "R_EVENT"},
158 	{FCF_REASON_REQUESTED, "R_REQUESTED"},
159 	{FCF_REASON_NO_MBOX, "R_NO_MBOX"},
160 	{FCF_REASON_NO_BUFFER, "R_NO_BUFFER"},
161 	{FCF_REASON_SEND_FAILED, "R_SEND_FAILED"},
162 	{FCF_REASON_MBOX_FAILED, "R_MBOX_FAILED"},
163 	{FCF_REASON_MBOX_BUSY, "R_MBOX_BUSY"},
164 	{FCF_REASON_NO_FCFI, "R_NO_FCFI"},
165 	{FCF_REASON_NO_VFI, "R_NO_VFI"},
166 	{FCF_REASON_ONLINE_FAILED, "R_ONLINE_FAILED"},
167 	{FCF_REASON_OFFLINE_FAILED, "R_OFFLINE_FAILED"},
168 	{FCF_REASON_OP_FAILED, "R_OP_FAILED"},
169 	{FCF_REASON_NO_PKT, "R_NO_PKT"},
170 	{FCF_REASON_NO_NODE, "R_NO_NODE"},
171 	{FCF_REASON_NOT_ALLOWED, "R_NOT_ALLOWED"},
172 	{FCF_REASON_UNUSED, "R_UNUSED"},
173 	{FCF_REASON_INVALID, "R_INVALID"},
174 
175 }; /* emlxs_fcf_reason_table */
176 
177 
178 /* ********************************************************************** */
179 /* FCFTAB Generic */
180 /* ********************************************************************** */
181 static char 		*emlxs_fcftab_state_xlate(emlxs_port_t *port,
182 				uint32_t state);
183 static uint32_t		emlxs_fcftab_event(emlxs_port_t *port, uint32_t evt,
184 				void *arg1);
185 static uint32_t		emlxs_fcftab_shutdown_action(emlxs_port_t *port,
186 				uint32_t evt, void *arg1);
187 
188 /* ********************************************************************** */
189 /* FC FCFTAB */
190 /* ********************************************************************** */
191 
192 /* Order does not matter */
193 emlxs_table_t emlxs_fc_fcftab_state_table[] =
194 {
195 	{FC_FCFTAB_STATE_SHUTDOWN, "FCFTAB_SHUTDOWN"},
196 	{FC_FCFTAB_STATE_OFFLINE, "FCFTAB_OFFLINE"},
197 
198 	{FC_FCFTAB_STATE_TOPO, "FCFTAB_TOPO"},
199 	{FC_FCFTAB_STATE_TOPO_FAILED, "FCFTAB_TOPO_FAILED"},
200 	{FC_FCFTAB_STATE_TOPO_CMPL, "FCFTAB_TOPO_CMPL"},
201 
202 	{FC_FCFTAB_STATE_CFGLINK, "FCFTAB_CFGLINK"},
203 	{FC_FCFTAB_STATE_CFGLINK_FAILED, "FCFTAB_CFGLINK_FAILED"},
204 	{FC_FCFTAB_STATE_CFGLINK_CMPL, "FCFTAB_CFGLINK_CMPL"},
205 
206 	{FC_FCFTAB_STATE_SPARM, "FCFTAB_SPARM"},
207 	{FC_FCFTAB_STATE_SPARM_FAILED, "FCFTAB_SPARM_FAILED"},
208 	{FC_FCFTAB_STATE_SPARM_CMPL, "FCFTAB_SPARM_CMPL"},
209 
210 	{FC_FCFTAB_STATE_FCFI_OFFLINE_CMPL,
211 	    "FCFTAB_FCFI_OFFLINE_CMPL"},
212 	{FC_FCFTAB_STATE_FCFI_OFFLINE, "FCFTAB_FCFI_OFFLINE"},
213 
214 	{FC_FCFTAB_STATE_FCFI_ONLINE, "FCFTAB_FCFI_ONLINE"},
215 	{FC_FCFTAB_STATE_FCFI_ONLINE_CMPL, "FCFTAB_FCFI_ONLINE_CMPL"},
216 
217 	{FC_FCFTAB_STATE_ONLINE, "FCFTAB_ONLINE"},
218 
219 }; /* emlxs_fc_fcftab_state_table */
220 
221 static void emlxs_fc_fcftab_online_timer(emlxs_hba_t *hba);
222 
223 static uint32_t emlxs_fc_fcftab_offline_action(emlxs_port_t *port,
224 			uint32_t evt, void *arg1);
225 static uint32_t emlxs_fc_fcftab_online_action(emlxs_port_t *port,
226 			uint32_t evt, void *arg1);
227 
228 static uint32_t emlxs_fc_fcftab_topo_cmpl_action(emlxs_port_t *port,
229 			uint32_t evt, void *arg1);
230 static uint32_t emlxs_fc_fcftab_topo_failed_action(emlxs_port_t *port,
231 			uint32_t evt, void *arg1);
232 static uint32_t emlxs_fc_fcftab_topo_action(emlxs_port_t *port,
233 			uint32_t evt, void *arg1);
234 
235 static uint32_t emlxs_fc_fcftab_cfglink_cmpl_action(emlxs_port_t *port,
236 			uint32_t evt, void *arg1);
237 static uint32_t emlxs_fc_fcftab_cfglink_failed_action(emlxs_port_t *port,
238 			uint32_t evt, void *arg1);
239 static uint32_t emlxs_fc_fcftab_cfglink_action(emlxs_port_t *port,
240 			uint32_t evt, void *arg1);
241 
242 static uint32_t emlxs_fc_fcftab_sparm_cmpl_action(emlxs_port_t *port,
243 			uint32_t evt, void *arg1);
244 static uint32_t emlxs_fc_fcftab_sparm_failed_action(emlxs_port_t *port,
245 			uint32_t evt, void *arg1);
246 static uint32_t emlxs_fc_fcftab_sparm_action(emlxs_port_t *port,
247 			uint32_t evt, void *arg1);
248 
249 static uint32_t emlxs_fc_fcftab_linkup_evt_action(emlxs_port_t *port,
250 			uint32_t evt, void *arg1);
251 static uint32_t emlxs_fc_fcftab_linkdown_evt_action(emlxs_port_t *port,
252 			uint32_t evt, void *arg1);
253 
254 static uint32_t emlxs_fc_fcftab_fcfi_online_evt_action(emlxs_port_t *port,
255 			uint32_t evt, void *arg1);
256 static uint32_t emlxs_fc_fcftab_fcfi_offline_evt_action(emlxs_port_t *port,
257 			uint32_t evt, void *arg1);
258 
259 static uint32_t emlxs_fc_fcftab_shutdown_evt_action(emlxs_port_t *port,
260 			uint32_t evt, void *arg1);
261 static uint32_t emlxs_fc_fcftab_fcfi_offline_action(emlxs_port_t *port,
262 			uint32_t evt, void *arg1);
263 static uint32_t emlxs_fc_fcftab_fcfi_offline_cmpl_action(emlxs_port_t *port,
264 			uint32_t evt, void *arg1);
265 static uint32_t emlxs_fc_fcftab_fcfi_online_action(emlxs_port_t *port,
266 			uint32_t evt, void *arg1);
267 static uint32_t emlxs_fc_fcftab_fcfi_online_cmpl_action(emlxs_port_t *port,
268 			uint32_t evt, void *arg1);
269 
270 static char *emlxs_fc_fcftab_state_xlate(uint32_t state);
271 static uint32_t emlxs_fc_fcftab_event(emlxs_port_t *port,
272 			uint32_t evt, void *arg1);
273 static uint32_t emlxs_fc_fcftab_req_handler(emlxs_port_t *port, void *arg1);
274 
275 /*
276  * - Online sequencing can start from FC_FCFTAB_STATE_OFFLINE state
277  *
278  * - Offline sequencing can interrupt the online sequencing at the
279  * entry of the next wait state.
280  *
281  * NORMAL ONLINE SEQ
282  * ---------------------------
283  * LINK_UP event <-- Adapter
284  * FC_FCFTAB_STATE_OFFLINE
285  * FC_FCFTAB_STATE_TOPO
286  *     FC_FCFTAB_STATE_TOPO_CMPL
287  * FC_FCFTAB_STATE_CFGLINK
288  *     FC_FCFTAB_STATE_CFGLINK_CMPL
289  * FC_FCFTAB_STATE_SPARM
290  *     FC_FCFTAB_STATE_SPARM_CMPL
291  * FC_FCFTAB_STATE_FCFI_ONLINE
292  *     FC_FCFTAB_STATE_FCFI_ONLINE_CMPL
293  * FC_FCFTAB_STATE_ONLINE
294  *
295  *
296  * NORMAL OFFLINE SEQ
297  * ---------------------------
298  * LINK_DOWN event <-- Adapter
299  * FC_FCFTAB_STATE_ONLINE
300  * FC_FCFTAB_STATE_FCFI_OFFLINE
301  *     FC_FCFTAB_STATE_FCFI_OFFLINE_CMPL
302  * FC_FCFTAB_STATE_OFFLINE
303  *
304  */
305 /* Order does matter */
306 static void *emlxs_fc_fcftab_action_table[] =
307 {
308 	/* Action routine				Event */
309 /* FC_FCFTAB_STATE_SHUTDOWN  0			(Requires adapter reset) */
310 	(void *) emlxs_fcftab_shutdown_action,		/* STATE_ENTER */
311 	(void *) NULL,					/* SHUTDOWN */
312 	(void *) NULL,					/* LINK_UP */
313 	(void *) NULL,					/* LINK_DOWN */
314 	(void *) NULL,					/* FCFI_ONLINE */
315 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
316 
317 /* FC_FCFTAB_STATE_OFFLINE  1			(Wait for LINK_UP event) */
318 	(void *) emlxs_fc_fcftab_offline_action,	/* STATE_ENTER */
319 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
320 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
321 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
322 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
323 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
324 
325 
326 /* FC_FCFTAB_STATE_TOPO  2			(Wait for topo mbcmpl) */
327 	(void *) emlxs_fc_fcftab_topo_action,		/* STATE_ENTER */
328 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
329 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
330 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
331 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
332 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
333 
334 /* FC_FCFTAB_STATE_TOPO_FAILED  3		(Transitional) */
335 	(void *) emlxs_fc_fcftab_topo_failed_action,	/* STATE_ENTER */
336 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
337 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
338 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
339 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
340 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
341 
342 /* FC_FCFTAB_STATE_TOPO_CMPL  4			(Transitional) */
343 	(void *) emlxs_fc_fcftab_topo_cmpl_action,	/* STATE_ENTER */
344 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
345 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
346 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
347 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
348 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
349 
350 
351 /* FC_FCFTAB_STATE_CFGLINK  5			(Wait for cfglink mbcmpl) */
352 	(void *) emlxs_fc_fcftab_cfglink_action,	/* STATE_ENTER */
353 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
354 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
355 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
356 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
357 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
358 
359 /* FC_FCFTAB_STATE_CFGLINK_FAILED  6		(Transitional) */
360 	(void *) emlxs_fc_fcftab_cfglink_failed_action,	/* STATE_ENTER */
361 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
362 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
363 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
364 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
365 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
366 
367 /* FC_FCFTAB_STATE_CFGLINK_CMPL  7			(Transitional) */
368 	(void *) emlxs_fc_fcftab_cfglink_cmpl_action,	/* STATE_ENTER */
369 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
370 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
371 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
372 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
373 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
374 
375 
376 /* FC_FCFTAB_STATE_SPARM  8			(Wait for sparm mbcmpl) */
377 	(void *) emlxs_fc_fcftab_sparm_action,		/* STATE_ENTER */
378 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
379 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
380 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
381 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
382 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
383 
384 /* FC_FCFTAB_STATE_SPARM_FAILED  9		(Transitional) */
385 	(void *) emlxs_fc_fcftab_sparm_failed_action,	/* STATE_ENTER */
386 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
387 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
388 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
389 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
390 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
391 
392 /* FC_FCFTAB_STATE_SPARM_CMPL  10		(Transitional) */
393 	(void *) emlxs_fc_fcftab_sparm_cmpl_action,	/* STATE_ENTER */
394 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
395 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
396 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
397 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
398 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
399 
400 
401 /* FC_FCFTAB_STATE_FCFI_OFFLINE_CMPL  11	(Transitional) */
402 	(void *) emlxs_fc_fcftab_fcfi_offline_cmpl_action, /* STATE_ENTER */
403 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
404 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
405 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
406 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
407 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
408 
409 /* FC_FCFTAB_STATE_FCFI_OFFLINE  12		(Wait for FCFI_OFFLINE event) */
410 	(void *) emlxs_fc_fcftab_fcfi_offline_action,	/* STATE_ENTER */
411 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
412 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
413 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
414 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
415 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
416 
417 
418 /* FC_FCFTAB_STATE_FCFI_ONLINE  13		(Wait for FCFI_ONLINE event) */
419 	(void *) emlxs_fc_fcftab_fcfi_online_action,	/* STATE_ENTER */
420 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
421 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
422 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
423 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
424 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
425 
426 /* FC_FCFTAB_STATE_FCFI_ONLINE_CMPL  14		(Transitional) */
427 	(void *) emlxs_fc_fcftab_fcfi_online_cmpl_action, /* STATE_ENTER */
428 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
429 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
430 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
431 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
432 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
433 
434 
435 /* FC_FCFTAB_STATE_ONLINE  15			(Wait for LINK_DOWN evt) */
436 	(void *) emlxs_fc_fcftab_online_action,		/* STATE_ENTER */
437 	(void *) emlxs_fc_fcftab_shutdown_evt_action,	/* SHUTDOWN */
438 	(void *) emlxs_fc_fcftab_linkup_evt_action,	/* LINK_UP */
439 	(void *) emlxs_fc_fcftab_linkdown_evt_action,	/* LINK_DOWN */
440 	(void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
441 	(void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
442 
443 }; /* emlxs_fc_fcftab_action_table[] */
444 #define	FC_FCFTAB_ACTION_EVENTS			6
445 #define	FC_FCFTAB_ACTION_STATES			\
446 	(sizeof (emlxs_fc_fcftab_action_table)/ \
447 	(FC_FCFTAB_ACTION_EVENTS * sizeof (void *)))
448 
449 
450 /* ********************************************************************** */
451 /* FCOE FCFTAB */
452 /* ********************************************************************** */
453 
454 /* Order does not matter */
455 emlxs_table_t emlxs_fcoe_fcftab_state_table[] =
456 {
457 	{FCOE_FCFTAB_STATE_SHUTDOWN, "FCFTAB_SHUTDOWN"},
458 	{FCOE_FCFTAB_STATE_OFFLINE, "FCFTAB_OFFLINE"},
459 
460 	{FCOE_FCFTAB_STATE_SOLICIT, "FCFTAB_SOLICIT"},
461 	{FCOE_FCFTAB_STATE_SOLICIT_FAILED, "FCFTAB_SOLICIT_FAILED"},
462 	{FCOE_FCFTAB_STATE_SOLICIT_CMPL, "FCFTAB_SOLICIT_CMPL"},
463 
464 	{FCOE_FCFTAB_STATE_READ, "FCFTAB_READ"},
465 	{FCOE_FCFTAB_STATE_READ_FAILED, "FCFTAB_READ_FAILED"},
466 	{FCOE_FCFTAB_STATE_READ_CMPL, "FCFTAB_READ_CMPL"},
467 
468 	{FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL,
469 	    "FCFTAB_FCFI_OFFLINE_CMPL"},
470 	{FCOE_FCFTAB_STATE_FCFI_OFFLINE, "FCFTAB_FCFI_OFFLINE"},
471 
472 	{FCOE_FCFTAB_STATE_FCFI_ONLINE, "FCFTAB_FCFI_ONLINE"},
473 	{FCOE_FCFTAB_STATE_FCFI_ONLINE_CMPL,
474 	    "FCFTAB_FCFI_ONLINE_CMPL"},
475 
476 	{FCOE_FCFTAB_STATE_ONLINE, "FCFTAB_ONLINE"},
477 
478 }; /* emlxs_fcoe_fcftab_state_table */
479 
480 static uint32_t emlxs_fcoe_fcftab_sol_cmpl_action(emlxs_port_t *port,
481 			uint32_t evt, void *arg1);
482 static uint32_t emlxs_fcoe_fcftab_sol_failed_action(emlxs_port_t *port,
483 			uint32_t evt, void *arg1);
484 static uint32_t emlxs_fcoe_fcftab_sol_action(emlxs_port_t *port,
485 			uint32_t evt, void *arg1);
486 static uint32_t emlxs_fcoe_fcftab_shutdown_evt_action(emlxs_port_t *port,
487 			uint32_t evt, void *arg1);
488 static uint32_t emlxs_fcoe_fcftab_linkdown_evt_action(emlxs_port_t *port,
489 			uint32_t evt, void *arg1);
490 static uint32_t emlxs_fcoe_fcftab_read_action(emlxs_port_t *port,
491 			uint32_t evt, void *arg1);
492 static uint32_t emlxs_fcoe_fcftab_read_failed_action(emlxs_port_t *port,
493 			uint32_t evt, void *arg1);
494 static uint32_t emlxs_fcoe_fcftab_read_cmpl_action(emlxs_port_t *port,
495 			uint32_t evt, void *arg1);
496 static uint32_t emlxs_fcoe_fcftab_fcfi_online_action(emlxs_port_t *port,
497 			uint32_t evt, void *arg1);
498 static uint32_t emlxs_fcoe_fcftab_fcfi_online_cmpl_action(emlxs_port_t *port,
499 			uint32_t evt, void *arg1);
500 static uint32_t emlxs_fcoe_fcftab_fcfi_offline_action(emlxs_port_t *port,
501 			uint32_t evt, void *arg1);
502 static uint32_t emlxs_fcoe_fcftab_fcfi_offline_cmpl_action(emlxs_port_t *port,
503 			uint32_t evt, void *arg1);
504 static uint32_t emlxs_fcoe_fcftab_found_evt_action(emlxs_port_t *port,
505 			uint32_t evt, void *arg1);
506 static uint32_t emlxs_fcoe_fcftab_lost_evt_action(emlxs_port_t *port,
507 			uint32_t evt, void *arg1);
508 static uint32_t emlxs_fcoe_fcftab_changed_evt_action(emlxs_port_t *port,
509 			uint32_t evt, void *arg1);
510 static uint32_t emlxs_fcoe_fcftab_full_evt_action(emlxs_port_t *port,
511 			uint32_t evt, void *arg1);
512 static uint32_t emlxs_fcoe_fcftab_linkup_evt_action(emlxs_port_t *port,
513 			uint32_t evt, void *arg1);
514 static uint32_t emlxs_fcoe_fcftab_cvl_evt_action(emlxs_port_t *port,
515 			uint32_t evt, void *arg1);
516 static uint32_t emlxs_fcoe_fcftab_online_action(emlxs_port_t *port,
517 			uint32_t evt, void *arg1);
518 static uint32_t emlxs_fcoe_fcftab_offline_action(emlxs_port_t *port,
519 			uint32_t evt, void *arg1);
520 static uint32_t emlxs_fcoe_fcftab_fcfi_offline_evt_action(emlxs_port_t *port,
521 			uint32_t evt, void *arg1);
522 static uint32_t emlxs_fcoe_fcftab_fcfi_online_evt_action(emlxs_port_t *port,
523 			uint32_t evt, void *arg1);
524 
525 static void emlxs_fcoe_fcftab_read_timer(emlxs_hba_t *hba);
526 static void emlxs_fcoe_fcftab_sol_timer(emlxs_hba_t *hba);
527 static void emlxs_fcoe_fcftab_offline_timer(emlxs_hba_t *hba);
528 static char *emlxs_fcoe_fcftab_state_xlate(uint32_t state);
529 static uint32_t emlxs_fcoe_fcftab_event(emlxs_port_t *port,
530 			uint32_t evt, void *arg1);
531 static uint32_t emlxs_fcoe_fcftab_state(emlxs_port_t *port, uint16_t state,
532 	uint16_t reason, uint32_t explain, void *arg1);
533 
534 /*
535  * - Online sequencing can start from FCOE_FCFTAB_STATE_OFFLINE state
536  *
537  * - Offline sequencing can interrupt the online sequencing at the
538  * entry of the next wait state.
539  *
540  * NORMAL ONLINE SEQ
541  * ---------------------------
542  * LINK_UP event <-- Adapter
543  * FCOE_FCFTAB_STATE_OFFLINE
544  * FCOE_FCFTAB_STATE_SOLICIT
545  *     FCOE_FCFTAB_STATE_SOLICIT_CMPL
546  * FCOE_FCFTAB_STATE_READ
547  *     FCOE_FCFTAB_STATE_READ_CMPL
548  * FCOE_FCFTAB_STATE_FCFI_OFFLINE
549  *     FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL
550  * FCOE_FCFTAB_STATE_FCFI_ONLINE
551  *     FCOE_FCFTAB_STATE_FCFI_ONLINE_CMPL
552  * FCOE_FCFTAB_STATE_ONLINE
553  *
554  *
555  * NORMAL OFFLINE SEQ
556  * ---------------------------
557  * LINK_DOWN event <-- Adapter
558  * FCOE_FCFTAB_STATE_ONLINE
559  * FCOE_FCFTAB_STATE_FCFI_OFFLINE
560  *     FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL
561  * FCOE_FCFTAB_STATE_OFFLINE
562  *
563  */
564 /* Order does matter */
565 static void *emlxs_fcoe_fcftab_action_table[] =
566 {
567 	/* Action routine				Event */
568 /* FCOE_FCFTAB_STATE_SHUTDOWN  0		(Requires adapter reset) */
569 	(void *) emlxs_fcftab_shutdown_action,		/* STATE_ENTER */
570 	(void *) NULL,					/* SHUTDOWN */
571 	(void *) NULL,					/* LINK_UP */
572 	(void *) NULL,					/* LINK_DOWN */
573 	(void *) NULL,					/* CVL_RECD */
574 	(void *) NULL,					/* FCF_FOUND */
575 	(void *) NULL,					/* FCF_LOST */
576 	(void *) NULL,					/* FCF_CHANGED */
577 	(void *) NULL,					/* TABLE_FULL */
578 	(void *) NULL,					/* FCFI_ONLINE */
579 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
580 
581 /* FCOE_FCFTAB_STATE_OFFLINE  1			(Wait for LINK_UP event) */
582 	(void *) emlxs_fcoe_fcftab_offline_action,	/* STATE_ENTER */
583 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
584 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
585 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
586 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
587 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
588 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
589 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
590 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
591 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
592 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
593 
594 
595 /* FCOE_FCFTAB_STATE_SOLICIT  2			(Wait on fcf_solicit cmpl) */
596 	(void *) emlxs_fcoe_fcftab_sol_action,		/* STATE_ENTER */
597 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
598 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
599 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
600 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
601 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
602 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
603 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
604 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
605 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
606 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
607 
608 /* FCOE_FCFTAB_STATE_SOLICIT_FAILED  3		(Transitional) */
609 	(void *) emlxs_fcoe_fcftab_sol_failed_action,	/* STATE_ENTER */
610 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
611 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
612 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
613 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
614 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
615 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
616 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
617 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
618 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
619 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
620 
621 /* FCOE_FCFTAB_STATE_SOLICIT_CMPL  4		(Wait on fcf timer cmpl) */
622 	(void *) emlxs_fcoe_fcftab_sol_cmpl_action,	/* STATE_ENTER */
623 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
624 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
625 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
626 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
627 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
628 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
629 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
630 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
631 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
632 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
633 
634 
635 /* FCOE_FCFTAB_STATE_READ  5			(Wait on fcf_read cmpl) */
636 	(void *) emlxs_fcoe_fcftab_read_action,		/* STATE_ENTER */
637 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
638 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
639 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
640 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
641 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
642 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
643 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
644 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
645 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
646 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
647 
648 /* FCOE_FCFTAB_STATE_READ_FAILED  6		(Transitional) */
649 	(void *) emlxs_fcoe_fcftab_read_failed_action,	/* STATE_ENTER */
650 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
651 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
652 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
653 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
654 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
655 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
656 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
657 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
658 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
659 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
660 
661 /* FCOE_FCFTAB_STATE_READ_CMPL  7		(Transitional) */
662 	(void *) emlxs_fcoe_fcftab_read_cmpl_action,	/* STATE_ENTER */
663 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
664 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
665 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
666 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
667 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
668 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
669 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
670 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
671 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
672 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
673 
674 
675 /* FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL  8	(Transitional) */
676 	(void *) emlxs_fcoe_fcftab_fcfi_offline_cmpl_action, /* STATE_ENTER */
677 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
678 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
679 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
680 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
681 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
682 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
683 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
684 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
685 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
686 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
687 
688 /* FCOE_FCFTAB_STATE_FCFI_OFFLINE  9		(Wait for FCFI_OFFLINE event) */
689 	(void *) emlxs_fcoe_fcftab_fcfi_offline_action,	/* STATE_ENTER */
690 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
691 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
692 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
693 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
694 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
695 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
696 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
697 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
698 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
699 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
700 
701 
702 /* FCOE_FCFTAB_STATE_FCFI_ONLINE  10		(Wait on FCFI_ONLINE event) */
703 	(void *) emlxs_fcoe_fcftab_fcfi_online_action,	/* STATE_ENTER */
704 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
705 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
706 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
707 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
708 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
709 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
710 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
711 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
712 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
713 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
714 
715 /* FCOE_FCFTAB_STATE_FCFI_ONLINE_CMPL  11	(Transitional) */
716 	(void *) emlxs_fcoe_fcftab_fcfi_online_cmpl_action, /* STATE_ENTER */
717 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
718 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
719 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
720 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
721 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
722 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
723 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
724 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
725 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
726 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
727 
728 
729 /* FCOE_FCFTAB_STATE_ONLINE  12			(Wait for LINK_DOWN event) */
730 	(void *) emlxs_fcoe_fcftab_online_action,	/* STATE_ENTER */
731 	(void *) emlxs_fcoe_fcftab_shutdown_evt_action,	/* SHUTDOWN */
732 	(void *) emlxs_fcoe_fcftab_linkup_evt_action,	/* LINK_UP */
733 	(void *) emlxs_fcoe_fcftab_linkdown_evt_action,	/* LINK_DOWN */
734 	(void *) emlxs_fcoe_fcftab_cvl_evt_action,	/* CVL_RECD */
735 	(void *) emlxs_fcoe_fcftab_found_evt_action,	/* FCF_FOUND */
736 	(void *) emlxs_fcoe_fcftab_lost_evt_action,	/* FCF_LOST */
737 	(void *) emlxs_fcoe_fcftab_changed_evt_action,	/* FCF_CHANGED */
738 	(void *) emlxs_fcoe_fcftab_full_evt_action,	/* TABLE_FULL */
739 	(void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */
740 	(void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */
741 
742 }; /* emlxs_fcoe_fcftab_action_table[] */
743 #define	FCOE_FCFTAB_ACTION_EVENTS			11
744 #define	FCOE_FCFTAB_ACTION_STATES			\
745 	(sizeof (emlxs_fcoe_fcftab_action_table)/ \
746 	(FCOE_FCFTAB_ACTION_EVENTS * sizeof (void *)))
747 
748 
749 
750 
751 /* ********************************************************************** */
752 /* FCFI */
753 /* ********************************************************************** */
754 
755 /* Order does not matter */
756 emlxs_table_t emlxs_fcfi_state_table[] =
757 {
758 	{FCFI_STATE_FREE, "FCFI_FREE"},
759 
760 	{FCFI_STATE_OFFLINE, "FCFI_OFFLINE"},
761 
762 	{FCFI_STATE_UNREG_CMPL, "FCFI_UNREG_CMPL"},
763 	{FCFI_STATE_UNREG_FAILED, "FCFI_UNREG_FAILED"},
764 	{FCFI_STATE_UNREG, "FCFI_UNREG"},
765 
766 	{FCFI_STATE_REG, "FCFI_REG"},
767 	{FCFI_STATE_REG_FAILED, "FCFI_REG_FAILED"},
768 	{FCFI_STATE_REG_CMPL, "FCFI_REG_CMPL"},
769 
770 	{FCFI_STATE_VFI_OFFLINE_CMPL, "FCFI_VFI_OFFLINE_CMPL"},
771 	{FCFI_STATE_VFI_OFFLINE, "FCFI_VFI_OFFLINE"},
772 
773 	{FCFI_STATE_VFI_ONLINE, "FCFI_VFI_ONLINE"},
774 	{FCFI_STATE_VFI_ONLINE_CMPL, "FCFI_VFI_ONLINE_CMPL"},
775 
776 	{FCFI_STATE_PAUSED, "FCFI_PAUSED"},
777 	{FCFI_STATE_ONLINE, "FCFI_ONLINE"},
778 
779 }; /* emlxs_fcfi_state_table */
780 
781 
782 static uint32_t emlxs_fcfi_free_action(emlxs_port_t *port,
783 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
784 static uint32_t emlxs_fcfi_online_evt_action(emlxs_port_t *port,
785 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
786 static uint32_t emlxs_fcfi_offline_evt_action(emlxs_port_t *port,
787 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
788 static uint32_t emlxs_fcfi_pause_evt_action(emlxs_port_t *port,
789 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
790 static uint32_t emlxs_fcfi_reg_action(emlxs_port_t *port,
791 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
792 static uint32_t emlxs_fcfi_unreg_action(emlxs_port_t *port,
793 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
794 static uint32_t emlxs_fcfi_reg_cmpl_action(emlxs_port_t *port,
795 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
796 static uint32_t emlxs_fcfi_unreg_cmpl_action(emlxs_port_t *port,
797 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
798 static uint32_t emlxs_fcfi_vfi_online_action(emlxs_port_t *port,
799 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
800 static uint32_t emlxs_fcfi_vfi_online_cmpl_action(emlxs_port_t *port,
801 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
802 static uint32_t emlxs_fcfi_reg_failed_action(emlxs_port_t *port,
803 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
804 static uint32_t emlxs_fcfi_unreg_failed_action(emlxs_port_t *port,
805 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
806 static uint32_t emlxs_fcfi_vfi_offline_action(emlxs_port_t *port,
807 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
808 static uint32_t emlxs_fcfi_vfi_offline_cmpl_action(emlxs_port_t *port,
809 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
810 static uint32_t emlxs_fcfi_online_action(emlxs_port_t *port,
811 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
812 static uint32_t emlxs_fcfi_paused_action(emlxs_port_t *port,
813 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
814 static uint32_t emlxs_fcfi_offline_action(emlxs_port_t *port,
815 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
816 static uint32_t emlxs_fcfi_vfi_online_evt_action(emlxs_port_t *port,
817 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
818 static uint32_t emlxs_fcfi_vfi_offline_evt_action(emlxs_port_t *port,
819 			FCFIobj_t *fcfp, uint32_t evt, void *arg1);
820 
821 static uint32_t emlxs_fcfi_event(emlxs_port_t *port,
822 			uint32_t evt, void *arg1);
823 static FCFIobj_t *emlxs_fcfi_find(emlxs_port_t *port, FCF_RECORD_t *fcfrec,
824 			uint32_t *fcf_index);
825 static FCFIobj_t *emlxs_fcfi_alloc(emlxs_port_t *port);
826 static uint32_t emlxs_fcfi_free(emlxs_port_t *port, FCFIobj_t *fcfp);
827 static void emlxs_fcfi_update(emlxs_port_t *port, FCFIobj_t *fcfp,
828 			FCF_RECORD_t *fcf_rec, uint32_t event_tag);
829 static char *emlxs_fcfi_state_xlate(uint32_t state);
830 
831 /*
832  * - Online sequencing can start from FCFI_STATE_OFFLINE state or
833  * the FCFI_STATE_VFI_OFFLINE state.
834  *
835  * - Offline sequencing can interrupt the online sequencing at the
836  * entry of the next wait state.
837  *
838  * NORMAL ONLINE SEQ
839  * ---------------------------
840  * FCFI_ONLINE event <-- FCFTAB
841  * FCFI_STATE_OFFLINE
842  * FCFI_STATE_REG
843  *     FCFI_STATE_REG_CMPL
844  * FCFI_STATE_VFI_ONLINE
845  *     FCFI_STATE_VFI_ONLINE_CMPL
846  * FCFI_STATE_ONLINE
847  * FCFI_ONLINE event-->FCFTAB
848  *
849  *
850  * NORMAL OFFLINE SEQ
851  * ---------------------------
852  * FCFI_OFFLINE event <-- FCFTAB
853  * FCFI_STATE_ONLINE
854  * FCFI_STATE_VFI_OFFLINE
855  *     FCFI_STATE_VFI_OFFLINE_CMPL
856  * FCFI_STATE_UNREG
857  *     FCFI_STATE_UNREG_CMPL
858  * FCFI_STATE_OFFLINE
859  * FCFI_OFFLINE event-->FCFTAB
860  *
861  *
862  * NORMAL PAUSE SEQ
863  * ---------------------------
864  * FCFI_PAUSE event <-- FCFTAB
865  * FCFI_STATE_ONLINE
866  * FCFI_STATE_PAUSED
867  *
868  */
869 /* Order does matter */
870 static void *emlxs_fcfi_action_table[] =
871 {
872 	/* Action routine				Event */
873 /* FCFI_STATE_FREE  0			(Wait for allocation) */
874 	(void *) emlxs_fcfi_free_action,		/* STATE_ENTER */
875 	(void *) NULL,					/* FCFI_ONLINE */
876 	(void *) NULL,					/* FCFI_OFFLINE */
877 	(void *) NULL,					/* FCFI_PAUSE */
878 	(void *) NULL,					/* VFI_ONLINE */
879 	(void *) NULL,					/* VFI_OFFLINE */
880 
881 /* FCFI_STATE_OFFLINE  1		(Wait for FCFI_ONLINE event) */
882 	(void *) emlxs_fcfi_offline_action,		/* STATE_ENTER */
883 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
884 	(void *) emlxs_fcfi_offline_evt_action,		/* FCFI_OFFLINE */
885 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
886 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
887 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
888 
889 /* FCFI_STATE_UNREG_CMPL  2		(Transitional)  */
890 	(void *) emlxs_fcfi_unreg_cmpl_action,		/* STATE_ENTER */
891 	(void *) emlxs_fcfi_online_evt_action,  	/* FCFI_ONLINE */
892 	(void *) emlxs_fcfi_offline_evt_action, 	/* FCFI_OFFLINE */
893 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
894 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
895 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
896 
897 /* FCFI_STATE_UNREG_FAILED  3		(Transitional) */
898 	(void *) emlxs_fcfi_unreg_failed_action, 	/* STATE_ENTER */
899 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
900 	(void *) emlxs_fcfi_offline_evt_action,		/* FCFI_OFFLINE */
901 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
902 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
903 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
904 
905 /* FCFI_STATE_UNREG  4			(Wait for unreg_fcfi cmpl) */
906 	(void *) emlxs_fcfi_unreg_action,		/* STATE_ENTER */
907 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
908 	(void *) emlxs_fcfi_offline_evt_action,		/* FCFI_OFFLINE */
909 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
910 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
911 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
912 
913 /* FCFI_STATE_REG  5			(Wait for reg_fcfi cmpl) */
914 	(void *) emlxs_fcfi_reg_action,			/* STATE_ENTER */
915 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
916 	(void *) emlxs_fcfi_offline_evt_action, 	/* FCFI_OFFLINE */
917 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
918 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
919 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
920 
921 /* FCFI_STATE_REG_FAILED  6		(Transitional) */
922 	(void *) emlxs_fcfi_reg_failed_action,		/*  STATE_ENTER */
923 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
924 	(void *) emlxs_fcfi_offline_evt_action,		/* FCFI_OFFLINE */
925 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
926 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
927 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
928 
929 /* FCFI_STATE_REG_CMPL  7		(Transitional) */
930 	(void *) emlxs_fcfi_reg_cmpl_action,		/* STATE_ENTER */
931 	(void *) emlxs_fcfi_online_evt_action,  	/* FCFI_ONLINE */
932 	(void *) emlxs_fcfi_offline_evt_action, 	/* FCFI_OFFLINE */
933 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
934 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
935 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
936 
937 /* FCFI_STATE_VFI_OFFLINE_CMPL  8 	(Transitional) */
938 	(void *) emlxs_fcfi_vfi_offline_cmpl_action,	/* STATE_ENTER */
939 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
940 	(void *) emlxs_fcfi_offline_evt_action,		/* FCFI_OFFLINE */
941 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
942 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
943 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
944 
945 /* FCFI_STATE_VFI_OFFLINE  9		(Wait for VFI_OFFLINE event) */
946 	(void *) emlxs_fcfi_vfi_offline_action,		/* STATE_ENTER */
947 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
948 	(void *) emlxs_fcfi_offline_evt_action, 	/* FCFI_OFFLINE */
949 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
950 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
951 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE * */
952 
953 /* FCFI_STATE_VFI_ONLINE  10		(Wait for VFI_ONLINE event) */
954 	(void *) emlxs_fcfi_vfi_online_action,		/* STATE_ENTER */
955 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
956 	(void *) emlxs_fcfi_offline_evt_action,		/* FCFI_OFFLINE */
957 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
958 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
959 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
960 
961 /* FCFI_STATE_VFI_ONLINE_CMPL  11	(Transitional) */
962 	(void *) emlxs_fcfi_vfi_online_cmpl_action, 	/* STATE_ENTER */
963 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
964 	(void *) emlxs_fcfi_offline_evt_action,		/* FCFI_OFFLINE */
965 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
966 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
967 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
968 
969 
970 /* FCFI_STATE_PAUSED 12			(Wait for FCFI_ONLINE event) */
971 	(void *) emlxs_fcfi_paused_action,		/* STATE_ENTER */
972 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
973 	(void *) emlxs_fcfi_offline_evt_action,		/* FCFI_OFFLINE */
974 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
975 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
976 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
977 
978 /* FCFI_STATE_ONLINE 13			(Wait for FCFI_OFFLINE event) */
979 	(void *) emlxs_fcfi_online_action,		/* STATE_ENTER */
980 	(void *) emlxs_fcfi_online_evt_action,		/* FCFI_ONLINE */
981 	(void *) emlxs_fcfi_offline_evt_action,		/* FCFI_OFFLINE */
982 	(void *) emlxs_fcfi_pause_evt_action,		/* FCFI_PAUSE */
983 	(void *) emlxs_fcfi_vfi_online_evt_action,	/* VFI_ONLINE */
984 	(void *) emlxs_fcfi_vfi_offline_evt_action,	/* VFI_OFFLINE */
985 
986 }; /* emlxs_fcfi_action_table[] */
987 #define	FCFI_ACTION_EVENTS			6
988 #define	FCFI_ACTION_STATES			\
989 	(sizeof (emlxs_fcfi_action_table)/ \
990 	(FCFI_ACTION_EVENTS * sizeof (void *)))
991 
992 
993 /* ********************************************************************** */
994 /* VFI */
995 /* ********************************************************************** */
996 
997 /* Order does not matter */
998 emlxs_table_t emlxs_vfi_state_table[] =
999 {
1000 	{VFI_STATE_OFFLINE, "VFI_OFFLINE"},
1001 
1002 	{VFI_STATE_INIT, "VFI_INIT"},
1003 	{VFI_STATE_INIT_FAILED, "VFI_INIT_FAILED"},
1004 	{VFI_STATE_INIT_CMPL, "VFI_INIT_CMPL"},
1005 
1006 	{VFI_STATE_VPI_OFFLINE_CMPL, "VFI_VPI_OFFLINE_CMPL"},
1007 	{VFI_STATE_VPI_OFFLINE, "VFI_VPI_OFFLINE"},
1008 
1009 	{VFI_STATE_VPI_ONLINE, "VFI_VPI_ONLINE"},
1010 	{VFI_STATE_VPI_ONLINE_CMPL, "VFI_VPI_ONLINE_CMPL"},
1011 
1012 	{VFI_STATE_UNREG_CMPL, "VFI_UNREG_CMPL"},
1013 	{VFI_STATE_UNREG_FAILED, "VFI_UNREG_FAILED"},
1014 	{VFI_STATE_UNREG, "VFI_UNREG"},
1015 
1016 	{VFI_STATE_REG, "VFI_REG"},
1017 	{VFI_STATE_REG_FAILED, "VFI_REG_FAILED"},
1018 	{VFI_STATE_REG_CMPL, "VFI_REG_CMPL"},
1019 
1020 	{VFI_STATE_PAUSED, "VFI_PAUSED"},
1021 	{VFI_STATE_ONLINE, "VFI_ONLINE"},
1022 
1023 }; /* emlxs_vfi_state_table */
1024 
1025 
1026 static uint32_t emlxs_vfi_pause_evt_action(emlxs_port_t *port,
1027 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1028 static uint32_t emlxs_vfi_online_evt_action(emlxs_port_t *port,
1029 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1030 static uint32_t emlxs_vfi_offline_evt_action(emlxs_port_t *port,
1031 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1032 static uint32_t emlxs_vfi_init_action(emlxs_port_t *port,
1033 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1034 static uint32_t emlxs_vfi_init_failed_action(emlxs_port_t *port,
1035 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1036 static uint32_t emlxs_vfi_init_cmpl_action(emlxs_port_t *port,
1037 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1038 static uint32_t emlxs_vfi_offline_action(emlxs_port_t *port,
1039 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1040 static uint32_t emlxs_vfi_online_action(emlxs_port_t *port,
1041 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1042 static uint32_t emlxs_vfi_paused_action(emlxs_port_t *port,
1043 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1044 static uint32_t emlxs_vfi_vpi_online_action(emlxs_port_t *port,
1045 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1046 static uint32_t emlxs_vfi_vpi_online_cmpl_action(emlxs_port_t *port,
1047 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1048 static uint32_t emlxs_vfi_vpi_offline_action(emlxs_port_t *port,
1049 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1050 static uint32_t emlxs_vfi_vpi_offline_cmpl_action(emlxs_port_t *port,
1051 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1052 static uint32_t emlxs_vfi_reg_action(emlxs_port_t *port,
1053 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1054 static uint32_t emlxs_vfi_reg_failed_action(emlxs_port_t *port,
1055 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1056 static uint32_t emlxs_vfi_reg_cmpl_action(emlxs_port_t *port,
1057 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1058 static uint32_t emlxs_vfi_unreg_action(emlxs_port_t *port,
1059 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1060 static uint32_t emlxs_vfi_unreg_failed_action(emlxs_port_t *port,
1061 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1062 static uint32_t emlxs_vfi_unreg_cmpl_action(emlxs_port_t *port,
1063 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1064 static uint32_t emlxs_vfi_vpi_online_evt_action(emlxs_port_t *port,
1065 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1066 static uint32_t emlxs_vfi_vpi_offline_evt_action(emlxs_port_t *port,
1067 			VFIobj_t *vfip, uint32_t evt, void *arg1);
1068 
1069 static uint32_t emlxs_vfi_event(emlxs_port_t *port,
1070 			uint32_t evt, void *arg1);
1071 
1072 
1073 /*
1074  * - Online sequencing can start from VFI_STATE_OFFLINE state or
1075  * the VFI_STATE_VPI_OFFLINE state.
1076  *
1077  * - Offline sequencing can interrupt the online sequencing at the
1078  * entry of the next wait state.
1079  *
1080  * NORMAL ONLINE SEQ
1081  * ---------------------------
1082  * VFI_ONLINE event <-- FCFI
1083  * VFI_STATE_OFFLINE
1084  * VFI_STATE_INIT
1085  *     VFI_STATE_INIT_CMPL
1086  * VFI_STATE_VPI_ONLINE
1087  *     VFI_STATE_VPI_ONLINE_CMPL
1088  * VFI_STATE_REG
1089  *     VFI_STATE_REG_CMPL
1090  * VFI_STATE_ONLINE
1091  * VFI_ONLINE event-->FCFI
1092  *
1093  *
1094  * NORMAL OFFLINE SEQ
1095  * ---------------------------
1096  * VFI_OFFLINE event <-- FCFI
1097  * VFI_STATE_ONLINE
1098  * VFI_STATE_VPI_OFFLINE
1099  *     VFI_STATE_VPI_OFFLINE_CMPL
1100  * VFI_STATE_UNREG
1101  *     VFI_STATE_UNREG_CMPL
1102  * VFI_STATE_OFFLINE
1103  * VFI_OFFLINE event-->FCFI
1104  *
1105  *
1106  * NORMAL PAUSE SEQ
1107  * ---------------------------
1108  * VFI_PAUSE event <-- FCFI
1109  * VFI_STATE_ONLINE
1110  * VFI_STATE_PAUSED
1111  *
1112  */
1113 /* Order does matter */
1114 static void *emlxs_vfi_action_table[] =
1115 {
1116 	/* Action routine				Event */
1117 /* VFI_STATE_OFFLINE  0			(Wait for VFI_ONLINE event) */
1118 	(void *) emlxs_vfi_offline_action,		/* STATE_ENTER */
1119 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1120 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1121 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1122 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1123 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1124 
1125 
1126 /* VFI_STATE_INIT  1			(Wait for init_vfi cmpl) */
1127 	(void *) emlxs_vfi_init_action,			/* STATE_ENTER */
1128 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1129 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1130 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1131 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1132 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1133 
1134 /* VFI_STATE_INIT_FAILED  2		(Transitional) */
1135 	(void *) emlxs_vfi_init_failed_action,		/* STATE_ENTER */
1136 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1137 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1138 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1139 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1140 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1141 
1142 /* VFI_STATE_INIT_CMPL  3		(Transitional) */
1143 	(void *) emlxs_vfi_init_cmpl_action,		/* STATE_ENTER */
1144 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1145 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1146 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1147 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1148 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1149 
1150 
1151 /* VFI_STATE_VPI_OFFLINE_CMPL  4	(Wait for VPI_OFFLINE event) */
1152 	(void *) emlxs_vfi_vpi_offline_cmpl_action,	/* STATE_ENTER */
1153 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1154 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1155 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1156 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1157 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1158 
1159 /* VFI_STATE_VPI_OFFLINE  5		(Wait for VPI_OFFLINE event) */
1160 	(void *) emlxs_vfi_vpi_offline_action,		/* STATE_ENTER */
1161 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1162 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1163 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1164 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1165 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1166 
1167 
1168 /* VFI_STATE_VPI_ONLINE 6		(Wait for VPI_ONLINE event) */
1169 	(void *) emlxs_vfi_vpi_online_action,		/* STATE_ENTER */
1170 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1171 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1172 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1173 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1174 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1175 
1176 /* VFI_STATE_VPI_ONLINE_CMPL  7		(Transitional) */
1177 	(void *) emlxs_vfi_vpi_online_cmpl_action,	/* STATE_ENTER */
1178 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1179 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1180 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1181 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1182 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1183 
1184 
1185 /* VFI_STATE_UNREG_CMPL  8		(Transitional) */
1186 	(void *) emlxs_vfi_unreg_cmpl_action,		/* STATE_ENTER */
1187 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1188 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1189 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1190 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1191 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1192 
1193 /* VFI_STATE_UNREG_FAILED  9		(Transitional) */
1194 	(void *) emlxs_vfi_unreg_failed_action,		/* STATE_ENTER */
1195 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1196 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1197 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1198 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1199 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1200 
1201 /* VFI_STATE_UNREG  10			(Wait for unreg_vfi cmpl) */
1202 	(void *) emlxs_vfi_unreg_action,		/* STATE_ENTER */
1203 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1204 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1205 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1206 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1207 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1208 
1209 
1210 /* VFI_STATE_REG  11			(Wait for reg_vfi cmpl) */
1211 	(void *) emlxs_vfi_reg_action,			/* STATE_ENTER */
1212 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1213 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1214 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1215 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1216 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1217 
1218 /* VFI_STATE_REG_FAILED  12		(Transitional) */
1219 	(void *) emlxs_vfi_reg_failed_action,		/* STATE_ENTER */
1220 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1221 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1222 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1223 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1224 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1225 
1226 /* VFI_STATE_REG_CMPL  13		(Transitional) */
1227 	(void *) emlxs_vfi_reg_cmpl_action,		/* STATE_ENTER */
1228 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1229 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1230 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1231 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1232 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1233 
1234 
1235 /* VFI_STATE_PAUSED  14			(Wait for VFI_OFFLINE event) */
1236 	(void *) emlxs_vfi_paused_action,		/* STATE_ENTER */
1237 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1238 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1239 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1240 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1241 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1242 
1243 /* VFI_STATE_ONLINE  14			(Wait for VFI_OFFLINE event) */
1244 	(void *) emlxs_vfi_online_action,		/* STATE_ENTER */
1245 	(void *) emlxs_vfi_online_evt_action,		/* VFI_ONLINE */
1246 	(void *) emlxs_vfi_offline_evt_action,		/* VFI_OFFLINE */
1247 	(void *) emlxs_vfi_pause_evt_action,		/* VFI_PAUSE */
1248 	(void *) emlxs_vfi_vpi_online_evt_action,	/* VPI_ONLINE */
1249 	(void *) emlxs_vfi_vpi_offline_evt_action,	/* VPI_OFFLINE */
1250 
1251 }; /* emlxs_vfi_action_table[] */
1252 #define	VFI_ACTION_EVENTS			6
1253 #define	VFI_ACTION_STATES			\
1254 	(sizeof (emlxs_vfi_action_table)/ \
1255 	(VFI_ACTION_EVENTS * sizeof (void *)))
1256 
1257 
1258 /* ********************************************************************** */
1259 /* VPI */
1260 /* ********************************************************************** */
1261 
1262 /* Order does not matter */
1263 emlxs_table_t emlxs_vpi_state_table[] =
1264 {
1265 	{VPI_STATE_OFFLINE, "VPI_OFFLINE"},
1266 
1267 	{VPI_STATE_INIT, "VPI_INIT"},
1268 	{VPI_STATE_INIT_FAILED, "VPI_INIT_FAILED"},
1269 	{VPI_STATE_INIT_CMPL, "VPI_INIT_CMPL"},
1270 
1271 	{VPI_STATE_UNREG_CMPL, "VPI_UNREG_CMPL"},
1272 	{VPI_STATE_UNREG_FAILED, "VPI_UNREG_FAILED"},
1273 	{VPI_STATE_UNREG, "VPI_UNREG"},
1274 
1275 	{VPI_STATE_LOGO_CMPL, "VPI_LOGO_CMPL"},
1276 	{VPI_STATE_LOGO_FAILED, "VPI_LOGO_FAILED"},
1277 	{VPI_STATE_LOGO, "VPI_LOGO"},
1278 
1279 	{VPI_STATE_PORT_OFFLINE, "VPI_PORT_OFFLINE"},
1280 	{VPI_STATE_PORT_ONLINE, "VPI_PORT_ONLINE"},
1281 
1282 	{VPI_STATE_LOGI, "VPI_LOGI"},
1283 	{VPI_STATE_LOGI_FAILED, "VPI_LOGI_FAILED"},
1284 	{VPI_STATE_LOGI_CMPL, "VPI_LOGI_CMPL"},
1285 
1286 	{VPI_STATE_REG, "VPI_REG"},
1287 	{VPI_STATE_REG_FAILED, "VPI_REG_FAILED"},
1288 	{VPI_STATE_REG_CMPL, "VPI_REG_CMPL"},
1289 
1290 	{VPI_STATE_PAUSED, "VPI_PAUSED"},
1291 	{VPI_STATE_ONLINE, "VPI_ONLINE"},
1292 
1293 }; /* emlxs_vpi_state_table */
1294 
1295 
1296 static uint32_t emlxs_vpi_online_evt_action(emlxs_port_t *port,
1297 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1298 static uint32_t emlxs_vpi_offline_evt_action(emlxs_port_t *port,
1299 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1300 static uint32_t emlxs_vpi_pause_evt_action(emlxs_port_t *port,
1301 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1302 static uint32_t emlxs_vpi_rpi_online_evt_action(emlxs_port_t *port,
1303 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1304 static uint32_t emlxs_vpi_rpi_offline_evt_action(emlxs_port_t *port,
1305 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1306 static uint32_t emlxs_vpi_rpi_pause_evt_action(emlxs_port_t *port,
1307 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1308 
1309 static uint32_t emlxs_vpi_init_action(emlxs_port_t *port,
1310 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1311 static uint32_t emlxs_vpi_init_failed_action(emlxs_port_t *port,
1312 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1313 static uint32_t emlxs_vpi_init_cmpl_action(emlxs_port_t *port,
1314 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1315 
1316 static uint32_t emlxs_vpi_offline_action(emlxs_port_t *port,
1317 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1318 static uint32_t emlxs_vpi_online_action(emlxs_port_t *port,
1319 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1320 static uint32_t emlxs_vpi_paused_action(emlxs_port_t *port,
1321 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1322 
1323 static uint32_t emlxs_vpi_port_online_action(emlxs_port_t *port,
1324 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1325 static uint32_t emlxs_vpi_port_offline_action(emlxs_port_t *port,
1326 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1327 
1328 static uint32_t emlxs_vpi_logi_cmpl_action(emlxs_port_t *port,
1329 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1330 static uint32_t emlxs_vpi_logi_failed_action(emlxs_port_t *port,
1331 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1332 static uint32_t emlxs_vpi_logi_action(emlxs_port_t *port,
1333 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1334 
1335 static uint32_t emlxs_vpi_reg_action(emlxs_port_t *port,
1336 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1337 static uint32_t emlxs_vpi_reg_failed_action(emlxs_port_t *port,
1338 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1339 static uint32_t emlxs_vpi_reg_cmpl_action(emlxs_port_t *port,
1340 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1341 
1342 static uint32_t emlxs_vpi_unreg_action(emlxs_port_t *port,
1343 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1344 static uint32_t emlxs_vpi_unreg_failed_action(emlxs_port_t *port,
1345 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1346 static uint32_t emlxs_vpi_unreg_cmpl_action(emlxs_port_t *port,
1347 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1348 
1349 static uint32_t emlxs_vpi_logo_action(emlxs_port_t *port,
1350 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1351 static uint32_t emlxs_vpi_logo_failed_action(emlxs_port_t *port,
1352 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1353 static uint32_t emlxs_vpi_logo_cmpl_action(emlxs_port_t *port,
1354 			VPIobj_t *vpip, uint32_t evt, void *arg1);
1355 
1356 static uint32_t emlxs_vpi_event(emlxs_port_t *port,
1357 			uint32_t evt, void *arg1);
1358 static uint32_t emlxs_vpi_logi_cmpl_notify(emlxs_port_t *port,
1359 			RPIobj_t *rpip);
1360 static void emlxs_vpi_logo_handler(emlxs_port_t *port,
1361 			VPIobj_t *vpip);
1362 
1363 /*
1364  * - Online sequencing can only start from VPI_STATE_OFFLINE or
1365  * VPI_STATE_PORT_OFFLINE state.
1366  *
1367  * - Offline sequencing can interrupt the online sequencing at the
1368  * entry of the next wait state.
1369  *
1370  * NORMAL ONLINE SEQ
1371  * ---------------------------
1372  * VPI_ONLINE event <-- VFI
1373  * VPI_STATE_OFFLINE
1374  * VPI_STATE_INIT
1375  *     VPI_STATE_INIT_CMPL
1376  * VPI_STATE_PORT_ONLINE
1377  * VPI_STATE_LOGI
1378  *     VPI_STATE_LOGI_CMPL
1379  * VPI_STATE_REG
1380  *     VPI_STATE_REG_CMPL
1381  * VPI_STATE_ONLINE
1382  * VPI_ONLINE event-->VFI
1383  *
1384  *
1385  * NORMAL OFFLINE SEQ
1386  * ---------------------------
1387  * VPI_OFFLINE event <-- VFI
1388  * VPI_STATE_ONLINE
1389  * VPI_STATE_PORT_OFFLINE
1390  * VPI_STATE_LOGO
1391  *     VPI_STATE_LOGO_CMPL
1392  * VPI_STATE_UNREG
1393  *     VPI_STATE_UNREG_CMPL
1394  * VPI_STATE_OFFLINE
1395  * VPI_OFFLINE event-->VFI
1396  *
1397  *
1398  * NORMAL PAUSE SEQ
1399  * ---------------------------
1400  * VPI_PAUSE event <-- VFI
1401  * VPI_STATE_ONLINE
1402  * VPI_STATE_PORT_OFFLINE
1403  * VPI_STATE_PAUSED
1404  *
1405  */
1406 /* Order does matter */
1407 static void *emlxs_vpi_action_table[] =
1408 {
1409 	/* Action routine				Event */
1410 /* VPI_STATE_OFFLINE  0 		(Wait for VPI_ONLINE event) */
1411 	(void *) emlxs_vpi_offline_action,		/* STATE_ENTER */
1412 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1413 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1414 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1415 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1416 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1417 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1418 
1419 
1420 /* VPI_STATE_INIT  1 			(Wait for init_vpi cmpl) */
1421 	(void *) emlxs_vpi_init_action,			/* STATE_ENTER */
1422 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1423 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1424 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1425 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1426 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1427 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1428 
1429 /* VPI_STATE_INIT_FAILED  2  		(Transitional) */
1430 	(void *) emlxs_vpi_init_failed_action,		/* STATE_ENTER */
1431 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1432 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1433 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1434 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1435 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1436 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1437 
1438 /* VPI_STATE_INIT_CMPL  3 		(Transitional) */
1439 	(void *) emlxs_vpi_init_cmpl_action,		/* STATE_ENTER */
1440 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1441 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1442 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1443 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1444 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1445 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1446 
1447 
1448 /* VPI_STATE_UNREG_CMPL  4 		(Transitional) */
1449 	(void *) emlxs_vpi_unreg_cmpl_action,		/* STATE_ENTER */
1450 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1451 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1452 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1453 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1454 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1455 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1456 
1457 /* VPI_STATE_UNREG_FAILED  5  		(Transitional) */
1458 	(void *) emlxs_vpi_unreg_failed_action,		/* STATE_ENTER */
1459 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1460 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1461 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1462 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1463 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1464 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1465 
1466 /* VPI_STATE_UNREG  6 			(Wait for unreg_vpi cmpl) */
1467 	(void *) emlxs_vpi_unreg_action,		/* STATE_ENTER */
1468 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1469 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1470 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1471 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1472 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1473 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1474 
1475 
1476 /* VPI_STATE_LOGO_CMPL  7 		(Transitional) */
1477 	(void *) emlxs_vpi_logo_cmpl_action,		/* STATE_ENTER */
1478 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1479 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1480 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1481 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1482 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1483 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1484 
1485 /* VPI_STATE_LOGO_FAILED  8  		(Transitional) */
1486 	(void *) emlxs_vpi_logo_failed_action,		/* STATE_ENTER */
1487 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1488 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1489 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1490 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1491 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1492 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1493 
1494 /* VPI_STATE_LOGO  9 			(Transitional) */
1495 	(void *) emlxs_vpi_logo_action,			/* STATE_ENTER */
1496 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1497 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1498 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1499 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1500 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1501 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1502 
1503 
1504 /* VPI_STATE_PORT_OFFLINE  10	(Wait for RPI_OFFLINE or VPI_ONLINE) */
1505 	(void *) emlxs_vpi_port_offline_action,		/* STATE_ENTER */
1506 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1507 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1508 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1509 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1510 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1511 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1512 
1513 /* VPI_STATE_PORT_ONLINE  11 	(Wait for emlxs_vpi_logi_notify() ) */
1514 	(void *) emlxs_vpi_port_online_action,		/* STATE_ENTER */
1515 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1516 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1517 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1518 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1519 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1520 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1521 
1522 
1523 /* VPI_STATE_LOGI  12 		(Wait for emlxs_vpi_logi_cmpl_notify() ) */
1524 	(void *) emlxs_vpi_logi_action,			/* STATE_ENTER */
1525 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1526 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1527 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1528 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1529 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1530 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1531 
1532 /* VPI_STATE_LOGI_FAILED  13  		(Transitional) */
1533 	(void *) emlxs_vpi_logi_failed_action,		/* STATE_ENTER */
1534 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1535 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1536 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1537 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1538 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1539 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1540 
1541 /* VPI_STATE_LOGI_CMPL  14 		(Transitional) */
1542 	(void *) emlxs_vpi_logi_cmpl_action,		/* STATE_ENTER */
1543 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1544 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1545 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1546 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1547 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1548 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1549 
1550 
1551 /* VPI_STATE_REG  15 			(Wait for reg_vpi cmpl) */
1552 	(void *) emlxs_vpi_reg_action,			/* STATE_ENTER */
1553 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1554 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1555 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1556 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1557 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1558 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1559 
1560 /* VPI_STATE_REG_FAILED  16  		(Transitional) */
1561 	(void *) emlxs_vpi_reg_failed_action,		/* STATE_ENTER */
1562 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1563 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1564 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1565 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1566 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1567 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1568 
1569 /* VPI_STATE_REG_CMPL  17 		(Transitional) */
1570 	(void *) emlxs_vpi_reg_cmpl_action,		/* STATE_ENTER */
1571 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1572 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1573 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1574 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1575 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1576 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1577 
1578 
1579 /* VPI_STATE_PAUSED 18			(Wait for VPI_ONLINE() ) */
1580 	(void *) emlxs_vpi_paused_action,		/* STATE_ENTER */
1581 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1582 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1583 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1584 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1585 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1586 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1587 
1588 /* VPI_STATE_ONLINE  19 		(Wait for VPI_OFFLINE event) */
1589 	(void *) emlxs_vpi_online_action,		/* STATE_ENTER */
1590 	(void *) emlxs_vpi_online_evt_action,		/* VPI_ONLINE */
1591 	(void *) emlxs_vpi_offline_evt_action,		/* VPI_OFFLINE */
1592 	(void *) emlxs_vpi_pause_evt_action,		/* VPI_PAUSE */
1593 	(void *) emlxs_vpi_rpi_online_evt_action,	/* RPI_ONLINE */
1594 	(void *) emlxs_vpi_rpi_offline_evt_action,	/* RPI_OFFLINE */
1595 	(void *) emlxs_vpi_rpi_pause_evt_action,	/* RPI_PAUSE */
1596 
1597 }; /* emlxs_vpi_action_table() */
1598 #define	VPI_ACTION_EVENTS			7
1599 #define	VPI_ACTION_STATES			\
1600 	(sizeof (emlxs_vpi_action_table)/ \
1601 	(VPI_ACTION_EVENTS * sizeof (void *)))
1602 
1603 
1604 /* ********************************************************************** */
1605 /* RPI */
1606 /* ********************************************************************** */
1607 
1608 /* Order does not matter */
1609 emlxs_table_t emlxs_rpi_state_table[] =
1610 {
1611 	{RPI_STATE_FREE, "RPI_FREE"},
1612 
1613 	{RPI_STATE_RESERVED, "RPI_RESERVED"},
1614 	{RPI_STATE_OFFLINE, "RPI_OFFLINE"},
1615 
1616 	{RPI_STATE_UNREG_CMPL, "RPI_UNREG_CMPL"},
1617 	{RPI_STATE_UNREG_FAILED, "RPI_UNREG_FAILED"},
1618 	{RPI_STATE_UNREG, "RPI_UNREG"},
1619 
1620 	{RPI_STATE_REG, "RPI_REG"},
1621 	{RPI_STATE_REG_FAILED, "RPI_REG_FAILED"},
1622 	{RPI_STATE_REG_CMPL, "RPI_REG_CMPL"},
1623 
1624 	{RPI_STATE_PAUSED, "RPI_PAUSED"},
1625 
1626 	{RPI_STATE_RESUME, "RPI_RESUME"},
1627 	{RPI_STATE_RESUME_FAILED, "RPI_RESUME_FAILED"},
1628 	{RPI_STATE_RESUME_CMPL, "RPI_RESUME_CMPL"},
1629 
1630 	{RPI_STATE_ONLINE, "RPI_ONLINE"},
1631 
1632 }; /* emlxs_rpi_state_table */
1633 
1634 static uint32_t emlxs_rpi_free_action(emlxs_port_t *port,
1635 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1636 
1637 static uint32_t emlxs_rpi_online_evt_action(emlxs_port_t *port,
1638 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1639 static uint32_t emlxs_rpi_offline_evt_action(emlxs_port_t *port,
1640 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1641 static uint32_t emlxs_rpi_pause_evt_action(emlxs_port_t *port,
1642 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1643 static uint32_t emlxs_rpi_resume_evt_action(emlxs_port_t *port,
1644 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1645 
1646 static uint32_t emlxs_rpi_reg_action(emlxs_port_t *port,
1647 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1648 static uint32_t emlxs_rpi_reg_cmpl_action(emlxs_port_t *port,
1649 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1650 static uint32_t emlxs_rpi_reg_failed_action(emlxs_port_t *port,
1651 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1652 
1653 static uint32_t emlxs_rpi_unreg_action(emlxs_port_t *port,
1654 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1655 static uint32_t emlxs_rpi_unreg_cmpl_action(emlxs_port_t *port,
1656 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1657 static uint32_t emlxs_rpi_unreg_failed_action(emlxs_port_t *port,
1658 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1659 
1660 static uint32_t emlxs_rpi_online_action(emlxs_port_t *port,
1661 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1662 static uint32_t emlxs_rpi_paused_action(emlxs_port_t *port,
1663 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1664 static uint32_t emlxs_rpi_offline_action(emlxs_port_t *port,
1665 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1666 static uint32_t emlxs_rpi_reserved_action(emlxs_port_t *port,
1667 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1668 
1669 static uint32_t emlxs_rpi_resume_failed_action(emlxs_port_t *port,
1670 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1671 static uint32_t emlxs_rpi_resume_cmpl_action(emlxs_port_t *port,
1672 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1673 static uint32_t emlxs_rpi_resume_action(emlxs_port_t *port,
1674 			RPIobj_t *rpip, uint32_t evt, void *arg1);
1675 
1676 static uint32_t emlxs_rpi_event(emlxs_port_t *port,
1677 			uint32_t evt, void *arg1);
1678 static RPIobj_t *emlxs_rpi_alloc(emlxs_port_t *port, uint32_t did);
1679 static uint32_t emlxs_rpi_free(emlxs_port_t *port, RPIobj_t *rpip);
1680 static RPIobj_t *emlxs_rpi_find_did(emlxs_port_t *port, uint32_t did);
1681 
1682 static void emlxs_rpi_resume_handler(emlxs_port_t *port,
1683 			RPIobj_t *rpip);
1684 static void emlxs_rpi_unreg_handler(emlxs_port_t *port,
1685 			RPIobj_t *rpip);
1686 static uint32_t emlxs_rpi_reg_handler(emlxs_port_t *port,
1687 			RPIobj_t *rpip);
1688 
1689 static void emlxs_rpi_idle_timer(emlxs_hba_t *hba);
1690 
1691 static uint32_t emlxs_rpi_state(emlxs_port_t *port, RPIobj_t *rpip,
1692 			uint16_t state, uint16_t reason, uint32_t explain,
1693 			void *arg1);
1694 
1695 static void emlxs_rpi_alloc_fabric_rpi(emlxs_port_t *port);
1696 
1697 static void emlxs_rpi_deferred_cmpl(emlxs_port_t *port, RPIobj_t *rpip,
1698 			uint32_t status);
1699 
1700 /*
1701  * - Online sequencing can start from RPI_STATE_RESERVED state or
1702  * the RPI_STATE_PAUSED state.
1703  *
1704  * - Offline sequencing can interrupt the online sequencing at the
1705  * entry of the next wait state.
1706  *
1707  * NORMAL ONLINE SEQ
1708  * ---------------------------
1709  * RPI_ONLINE event <-- VPI
1710  * RPI_STATE_RESERVED
1711  * RPI_STATE_REG
1712  *     RPI_STATE_REG_CMPL
1713  * RPI_STATE_ONLINE
1714  * RPI_ONLINE event-->VPI
1715  *
1716  *
1717  * NORMAL OFFLINE SEQ
1718  * ---------------------------
1719  * RPI_OFFLINE event <-- VPI
1720  * RPI_STATE_ONLINE
1721  * RPI_STATE_UNREG
1722  *     RPI_STATE_UNREG_CMPL
1723  * RPI_STATE_OFFLINE
1724  * RPI_OFFLINE event-->VPI
1725  *
1726  *
1727  * NORMAL PAUSE SEQ
1728  * ---------------------------
1729  * RPI_PAUSE event <-- VPI
1730  * RPI_STATE_ONLINE
1731  * RPI_STATE_PAUSED
1732  *
1733  */
1734 /* Order does matter */
1735 static void *emlxs_rpi_action_table[] =
1736 {
1737 	/* Action routine				Event */
1738 /* RPI_STATE_FREE  0			(Wait for allocation) */
1739 	(void *) emlxs_rpi_free_action,			/* STATE_ENTER */
1740 	(void *) NULL,					/* RPI_ONLINE */
1741 	(void *) NULL,					/* RPI_OFFLINE */
1742 	(void *) NULL,					/* RPI_PAUSE */
1743 	(void *) NULL,					/* RPI_RESUME */
1744 
1745 /* RPI_STATE_RESERVED  1		(Wait for RPI_ONLINE event) */
1746 	(void *) emlxs_rpi_reserved_action,		/* STATE_ENTER */
1747 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1748 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1749 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1750 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1751 
1752 /* RPI_STATE_OFFLINE  2			(Transitional) */
1753 	(void *) emlxs_rpi_offline_action,		/* STATE_ENTER */
1754 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1755 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1756 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1757 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1758 
1759 /* RPI_STATE_UNREG_CMPL  3		(Transitional)  */
1760 	(void *) emlxs_rpi_unreg_cmpl_action,		/* STATE_ENTER */
1761 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1762 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1763 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1764 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1765 
1766 /* RPI_STATE_UNREG_FAILED  4		(Transitional) */
1767 	(void *) emlxs_rpi_unreg_failed_action, 	/* STATE_ENTER */
1768 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1769 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1770 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1771 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1772 
1773 /* RPI_STATE_UNREG  5			(Wait for unreg_rpi cmpl) */
1774 	(void *) emlxs_rpi_unreg_action,		/* STATE_ENTER */
1775 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1776 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1777 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1778 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1779 
1780 
1781 /* RPI_STATE_REG  6			(Wait for reg_rpi cmpl) */
1782 	(void *) emlxs_rpi_reg_action,			/* STATE_ENTER */
1783 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1784 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1785 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1786 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1787 
1788 /* RPI_STATE_REG_FAILED  7		(Transitional) */
1789 	(void *) emlxs_rpi_reg_failed_action,		/* STATE_ENTER */
1790 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1791 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1792 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1793 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1794 
1795 /* RPI_STATE_REG_CMPL  8		(Transitional) */
1796 	(void *) emlxs_rpi_reg_cmpl_action,		/* STATE_ENTER */
1797 	(void *) emlxs_rpi_online_evt_action,  		/* RPI_ONLINE */
1798 	(void *) emlxs_rpi_offline_evt_action, 		/* RPI_OFFLINE */
1799 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1800 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1801 
1802 
1803 /* RPI_STATE_PAUSED  9			(Wait for RPI_ONLINE) */
1804 	(void *) emlxs_rpi_paused_action,		/* STATE_ENTER */
1805 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1806 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1807 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1808 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1809 
1810 
1811 /* RPI_STATE_RESUME  10			(Wait for resume_rpi mbcmpl) */
1812 	(void *) emlxs_rpi_resume_action,		/* STATE_ENTER */
1813 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1814 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1815 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1816 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1817 
1818 /* RPI_STATE_RESUME_FAILED  11		(Transitional) */
1819 	(void *) emlxs_rpi_resume_failed_action,	/* STATE_ENTER */
1820 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1821 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1822 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1823 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1824 
1825 /* RPI_STATE_RESUME_CMPL  12		(Transitional) */
1826 	(void *) emlxs_rpi_resume_cmpl_action, 		/* STATE_ENTER */
1827 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1828 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1829 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1830 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1831 
1832 
1833 /* RPI_STATE_ONLINE 13			(Wait for RPI_OFFLINE event) */
1834 	(void *) emlxs_rpi_online_action,		/* STATE_ENTER */
1835 	(void *) emlxs_rpi_online_evt_action,		/* RPI_ONLINE */
1836 	(void *) emlxs_rpi_offline_evt_action,		/* RPI_OFFLINE */
1837 	(void *) emlxs_rpi_pause_evt_action,		/* RPI_PAUSE */
1838 	(void *) emlxs_rpi_resume_evt_action,		/* RPI_RESUME */
1839 
1840 }; /* emlxs_rpi_action_table[] */
1841 #define	RPI_ACTION_EVENTS			5
1842 #define	RPI_ACTION_STATES			\
1843 	(sizeof (emlxs_rpi_action_table)/ \
1844 	(RPI_ACTION_EVENTS * sizeof (void *)))
1845 
1846 
1847 /* ************************************************************************** */
1848 /* FCF Generic */
1849 /* ************************************************************************** */
1850 static void
emlxs_fcf_linkdown(emlxs_port_t * port)1851 emlxs_fcf_linkdown(emlxs_port_t *port)
1852 {
1853 	emlxs_hba_t *hba = HBA;
1854 
1855 	if (hba->state <= FC_LINK_DOWN) {
1856 		return;
1857 	}
1858 
1859 	mutex_enter(&EMLXS_PORT_LOCK);
1860 
1861 	if (hba->state <= FC_LINK_DOWN) {
1862 		mutex_exit(&EMLXS_PORT_LOCK);
1863 		return;
1864 	}
1865 
1866 	HBASTATS.LinkDown++;
1867 	EMLXS_STATE_CHANGE_LOCKED(hba, FC_LINK_DOWN);
1868 
1869 	hba->flag &= FC_LINKDOWN_MASK;
1870 	hba->discovery_timer = 0;
1871 	hba->linkup_timer = 0;
1872 
1873 	mutex_exit(&EMLXS_PORT_LOCK);
1874 
1875 	emlxs_log_link_event(port);
1876 
1877 	return;
1878 
1879 } /* emlxs_fcf_linkdown() */
1880 
1881 
1882 static void
emlxs_fcf_linkup(emlxs_port_t * port)1883 emlxs_fcf_linkup(emlxs_port_t *port)
1884 {
1885 	emlxs_hba_t *hba = HBA;
1886 	emlxs_config_t *cfg = &CFG;
1887 
1888 	if (hba->state >= FC_LINK_UP) {
1889 		return;
1890 	}
1891 
1892 	mutex_enter(&EMLXS_PORT_LOCK);
1893 
1894 	if (hba->state >= FC_LINK_UP) {
1895 		mutex_exit(&EMLXS_PORT_LOCK);
1896 		return;
1897 	}
1898 
1899 	/* Check for any mode changes */
1900 	emlxs_mode_set(hba);
1901 
1902 	HBASTATS.LinkUp++;
1903 	EMLXS_STATE_CHANGE_LOCKED(hba, FC_LINK_UP);
1904 
1905 	hba->discovery_timer = hba->timer_tics +
1906 	    cfg[CFG_LINKUP_TIMEOUT].current +
1907 	    cfg[CFG_DISC_TIMEOUT].current;
1908 
1909 	mutex_exit(&EMLXS_PORT_LOCK);
1910 
1911 	emlxs_log_link_event(port);
1912 
1913 	return;
1914 
1915 } /* emlxs_fcf_linkup() */
1916 
1917 
1918 extern void
emlxs_fcf_fini(emlxs_hba_t * hba)1919 emlxs_fcf_fini(emlxs_hba_t *hba)
1920 {
1921 	emlxs_port_t	*port = &PPORT;
1922 	emlxs_port_t	*vport;
1923 	FCFTable_t	*fcftab = &hba->sli.sli4.fcftab;
1924 	uint32_t	i;
1925 	RPIobj_t	*rpip;
1926 
1927 	if (!(hba->sli.sli4.flag & EMLXS_SLI4_FCF_INIT)) {
1928 		return;
1929 	}
1930 
1931 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
1932 	    "fcf_fini: %s flag=%x fcfi_online=%d.",
1933 	    emlxs_fcftab_state_xlate(port, fcftab->state),
1934 	    fcftab->flag, fcftab->fcfi_online);
1935 
1936 	if (!(fcftab->flag & EMLXS_FCFTAB_SHUTDOWN)) {
1937 		(void) emlxs_fcf_shutdown_notify(port, 1);
1938 	}
1939 
1940 	mutex_enter(&EMLXS_FCF_LOCK);
1941 	hba->sli.sli4.flag &= ~EMLXS_SLI4_FCF_INIT;
1942 
1943 	/* Free the FCF memory */
1944 
1945 	kmem_free(fcftab->table,
1946 	    (sizeof (FCFIobj_t) * fcftab->table_count));
1947 
1948 	fcftab->table = NULL;
1949 	fcftab->table_count = 0;
1950 
1951 	/* Free the VFI memory */
1952 
1953 	kmem_free(hba->sli.sli4.VFI_table,
1954 	    (sizeof (VFIobj_t) * hba->sli.sli4.VFICount));
1955 
1956 	hba->sli.sli4.VFI_table = NULL;
1957 	hba->sli.sli4.VFICount = 0;
1958 
1959 	/* Free the VPI Fabric RPI's */
1960 
1961 	for (i = 0; i < MAX_VPORTS; i++) {
1962 		vport = &VPORT(i);
1963 		rpip = vport->vpip->fabric_rpip;
1964 
1965 		if (rpip->state == RPI_STATE_FREE) {
1966 			continue;
1967 		}
1968 
1969 		(void) emlxs_rpi_free(port, rpip);
1970 	}
1971 
1972 	/* Free the RPI memory */
1973 
1974 	rpip = hba->sli.sli4.RPIp;
1975 	for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) {
1976 		if (rpip->state == RPI_STATE_FREE) {
1977 			continue;
1978 		}
1979 
1980 		(void) emlxs_rpi_free(port, rpip);
1981 	}
1982 
1983 	kmem_free(hba->sli.sli4.RPIp,
1984 	    (sizeof (RPIobj_t) * hba->sli.sli4.RPICount));
1985 
1986 	hba->sli.sli4.RPIp = NULL;
1987 	hba->sli.sli4.RPICount = 0;
1988 
1989 	/* Free the mutex */
1990 	mutex_exit(&EMLXS_FCF_LOCK);
1991 	mutex_destroy(&EMLXS_FCF_LOCK);
1992 
1993 	return;
1994 
1995 } /* emlxs_fcf_fini() */
1996 
1997 
1998 extern void
emlxs_fcf_init(emlxs_hba_t * hba)1999 emlxs_fcf_init(emlxs_hba_t *hba)
2000 {
2001 	emlxs_port_t	*port = &PPORT;
2002 	emlxs_port_t	*vport;
2003 	uint16_t	i;
2004 	FCFIobj_t	*fcfp;
2005 	VPIobj_t	*vpip;
2006 	VFIobj_t	*vfip;
2007 	RPIobj_t	*rpip;
2008 	FCFTable_t	*fcftab = &hba->sli.sli4.fcftab;
2009 
2010 	if (hba->sli.sli4.flag & EMLXS_SLI4_FCF_INIT) {
2011 		return;
2012 	}
2013 
2014 	mutex_init(&EMLXS_FCF_LOCK, NULL, MUTEX_DRIVER, NULL);
2015 	mutex_enter(&EMLXS_FCF_LOCK);
2016 
2017 	/* FCFTAB */
2018 
2019 	bzero(fcftab, sizeof (FCFTable_t));
2020 	fcftab->state = FCFTAB_STATE_OFFLINE;
2021 
2022 	/* FCFI */
2023 
2024 	fcftab->table_count = hba->sli.sli4.FCFICount;
2025 	fcftab->table = (FCFIobj_t *)kmem_zalloc(
2026 	    (sizeof (FCFIobj_t) * fcftab->table_count), KM_SLEEP);
2027 
2028 	fcfp = fcftab->table;
2029 	for (i = 0; i < fcftab->table_count; i++, fcfp++) {
2030 		fcfp->index = i;
2031 		fcfp->FCFI  = 0xFFFF;
2032 		fcfp->state = FCFI_STATE_FREE;
2033 	}
2034 
2035 	/* VFI */
2036 
2037 	hba->sli.sli4.VFI_table = (VFIobj_t *)kmem_zalloc(
2038 	    (sizeof (VFIobj_t) * hba->sli.sli4.VFICount), KM_SLEEP);
2039 
2040 	vfip = hba->sli.sli4.VFI_table;
2041 	for (i = 0; i < hba->sli.sli4.VFICount; i++, vfip++) {
2042 		vfip->VFI = emlxs_sli4_index_to_vfi(hba, i);
2043 		vfip->index = i;
2044 		vfip->state = VFI_STATE_OFFLINE;
2045 	}
2046 
2047 	/* VPI */
2048 
2049 	for (i = 0; i < MAX_VPORTS; i++) {
2050 		vport = &VPORT(i);
2051 		vpip = &vport->VPIobj;
2052 
2053 		bzero(vpip, sizeof (VPIobj_t));
2054 		vpip->index = i;
2055 		vpip->VPI = emlxs_sli4_index_to_vpi(hba, i);
2056 		vpip->port = vport;
2057 		vpip->state = VPI_STATE_OFFLINE;
2058 		vport->vpip = vpip;
2059 
2060 		/* Init the Fabric RPI's */
2061 		rpip = &vpip->fabric_rpi;
2062 		rpip->state = RPI_STATE_FREE;
2063 		rpip->index = 0xffff;
2064 		rpip->RPI   = FABRIC_RPI;
2065 		rpip->did   = FABRIC_DID;
2066 		rpip->vpip  = vpip;
2067 		vpip->fabric_rpip = rpip;
2068 	}
2069 
2070 	/* RPI */
2071 
2072 	hba->sli.sli4.RPIp = (RPIobj_t *)kmem_zalloc(
2073 	    (sizeof (RPIobj_t) * hba->sli.sli4.RPICount), KM_SLEEP);
2074 
2075 	rpip = hba->sli.sli4.RPIp;
2076 	for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) {
2077 		rpip->state = RPI_STATE_FREE;
2078 		rpip->RPI = emlxs_sli4_index_to_rpi(hba, i);
2079 		rpip->index = i;
2080 	}
2081 
2082 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2083 	    "fcf_init: %s flag=%x fcfi=%d vfi=%d vpi=%d rpi=%d.",
2084 	    emlxs_fcftab_state_xlate(port, fcftab->state),
2085 	    fcftab->flag,
2086 	    fcftab->table_count,
2087 	    hba->sli.sli4.VFICount,
2088 	    MAX_VPORTS,
2089 	    hba->sli.sli4.RPICount);
2090 
2091 	hba->sli.sli4.flag |= EMLXS_SLI4_FCF_INIT;
2092 	mutex_exit(&EMLXS_FCF_LOCK);
2093 
2094 	return;
2095 
2096 } /* emlxs_fcf_init() */
2097 
2098 
2099 static char *
emlxs_fcf_event_xlate(uint32_t state)2100 emlxs_fcf_event_xlate(uint32_t state)
2101 {
2102 	static char buffer[32];
2103 	uint32_t i;
2104 	uint32_t count;
2105 
2106 	count = sizeof (emlxs_fcf_event_table) / sizeof (emlxs_table_t);
2107 	for (i = 0; i < count; i++) {
2108 		if (state == emlxs_fcf_event_table[i].code) {
2109 			return (emlxs_fcf_event_table[i].string);
2110 		}
2111 	}
2112 
2113 	(void) snprintf(buffer, sizeof (buffer), "event=0x%x", state);
2114 	return (buffer);
2115 
2116 } /* emlxs_fcf_event_xlate() */
2117 
2118 
2119 static char *
emlxs_fcf_reason_xlate(uint32_t reason)2120 emlxs_fcf_reason_xlate(uint32_t reason)
2121 {
2122 	static char buffer[32];
2123 	uint32_t i;
2124 	uint32_t count;
2125 
2126 	count = sizeof (emlxs_fcf_reason_table) / sizeof (emlxs_table_t);
2127 	for (i = 0; i < count; i++) {
2128 		if (reason == emlxs_fcf_reason_table[i].code) {
2129 			return (emlxs_fcf_reason_table[i].string);
2130 		}
2131 	}
2132 
2133 	(void) snprintf(buffer, sizeof (buffer), "reason=0x%x", reason);
2134 	return (buffer);
2135 
2136 } /* emlxs_fcf_reason_xlate() */
2137 
2138 
2139 extern void
emlxs_fcf_timer_notify(emlxs_hba_t * hba)2140 emlxs_fcf_timer_notify(emlxs_hba_t *hba)
2141 {
2142 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2143 
2144 	if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
2145 		return;
2146 	}
2147 
2148 	if (fcftab->table == 0) {
2149 		return;
2150 	}
2151 
2152 	mutex_enter(&EMLXS_FCF_LOCK);
2153 
2154 	if (SLI4_FCOE_MODE) {
2155 		emlxs_fcoe_fcftab_sol_timer(hba);
2156 
2157 		emlxs_fcoe_fcftab_read_timer(hba);
2158 
2159 		emlxs_fcoe_fcftab_offline_timer(hba);
2160 	} else {
2161 		emlxs_fc_fcftab_online_timer(hba);
2162 	}
2163 
2164 	emlxs_rpi_idle_timer(hba);
2165 
2166 	mutex_exit(&EMLXS_FCF_LOCK);
2167 
2168 	return;
2169 
2170 } /* emlxs_fcf_timer_notify() */
2171 
2172 
2173 extern uint32_t
emlxs_fcf_shutdown_notify(emlxs_port_t * port,uint32_t wait)2174 emlxs_fcf_shutdown_notify(emlxs_port_t *port, uint32_t wait)
2175 {
2176 	emlxs_hba_t *hba = HBA;
2177 	emlxs_port_t *pport = &PPORT;
2178 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2179 	uint32_t rval = 0;
2180 	uint32_t i;
2181 
2182 	if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
2183 		return (1);
2184 	}
2185 
2186 	if (!(pport->flag & EMLXS_PORT_BOUND) ||
2187 	    (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
2188 		return (1);
2189 	}
2190 
2191 	if (fcftab->flag & EMLXS_FCFTAB_SHUTDOWN) {
2192 		return (0);
2193 	}
2194 
2195 	mutex_enter(&EMLXS_FCF_LOCK);
2196 
2197 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2198 	    "fcf_shutdown_notify: %s flag=%x "
2199 	    "fcfi_online=%d. Shutting down FCFTAB. >",
2200 	    emlxs_fcftab_state_xlate(port, fcftab->state),
2201 	    fcftab->flag, fcftab->fcfi_online);
2202 
2203 	rval = emlxs_fcftab_event(port, FCF_EVENT_SHUTDOWN, 0);
2204 
2205 	if (wait && (rval == 0)) {
2206 		/* Wait for shutdown flag */
2207 		i = 0;
2208 		while (!(fcftab->flag & EMLXS_FCFTAB_SHUTDOWN) && (i++ < 120)) {
2209 			mutex_exit(&EMLXS_FCF_LOCK);
2210 			BUSYWAIT_MS(1000);
2211 			mutex_enter(&EMLXS_FCF_LOCK);
2212 		}
2213 
2214 		if (!(fcftab->flag & EMLXS_FCFTAB_SHUTDOWN)) {
2215 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
2216 			    "fcf_shutdown_notify: %s flag=%x "
2217 			    "fcfi_online=%d. Shutdown timeout.",
2218 			    emlxs_fcftab_state_xlate(port, fcftab->state),
2219 			    fcftab->flag, fcftab->fcfi_online);
2220 			rval = 1;
2221 		}
2222 	}
2223 
2224 	mutex_exit(&EMLXS_FCF_LOCK);
2225 
2226 	return (rval);
2227 
2228 } /* emlxs_fcf_shutdown_notify() */
2229 
2230 
2231 extern uint32_t
emlxs_fcf_linkup_notify(emlxs_port_t * port)2232 emlxs_fcf_linkup_notify(emlxs_port_t *port)
2233 {
2234 	emlxs_hba_t *hba = HBA;
2235 	emlxs_port_t *pport = &PPORT;
2236 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2237 	uint32_t rval = 0;
2238 
2239 	if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
2240 		return (1);
2241 	}
2242 
2243 	if (!(pport->flag & EMLXS_PORT_BOUND) ||
2244 	    (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
2245 		return (1);
2246 	}
2247 
2248 	mutex_enter(&EMLXS_FCF_LOCK);
2249 
2250 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2251 	    "fcf_linkup_notify: %s flag=%x "
2252 	    "fcfi_online=%d. FCFTAB Link up. >",
2253 	    emlxs_fcftab_state_xlate(port, fcftab->state),
2254 	    fcftab->flag, fcftab->fcfi_online);
2255 
2256 	rval = emlxs_fcftab_event(port, FCF_EVENT_LINKUP, 0);
2257 
2258 	mutex_exit(&EMLXS_FCF_LOCK);
2259 
2260 	return (rval);
2261 
2262 } /* emlxs_fcf_linkup_notify() */
2263 
2264 
2265 extern uint32_t
emlxs_fcf_linkdown_notify(emlxs_port_t * port)2266 emlxs_fcf_linkdown_notify(emlxs_port_t *port)
2267 {
2268 	emlxs_hba_t *hba = HBA;
2269 	emlxs_port_t *pport = &PPORT;
2270 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2271 	uint32_t rval = 0;
2272 
2273 	if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
2274 		return (1);
2275 	}
2276 
2277 	if (!(pport->flag & EMLXS_PORT_BOUND) ||
2278 	    (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
2279 		return (1);
2280 	}
2281 
2282 	mutex_enter(&EMLXS_FCF_LOCK);
2283 
2284 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2285 	    "fcf_linkdown_notify: %s flag=%x "
2286 	    "fcfi_online=%d. FCFTAB Link down. >",
2287 	    emlxs_fcftab_state_xlate(port, fcftab->state),
2288 	    fcftab->flag, fcftab->fcfi_online);
2289 
2290 	rval = emlxs_fcftab_event(port, FCF_EVENT_LINKDOWN, 0);
2291 
2292 	mutex_exit(&EMLXS_FCF_LOCK);
2293 
2294 	return (rval);
2295 
2296 } /* emlxs_fcf_linkdown_notify() */
2297 
2298 
2299 extern uint32_t
emlxs_fcf_cvl_notify(emlxs_port_t * port,uint32_t vpi)2300 emlxs_fcf_cvl_notify(emlxs_port_t *port, uint32_t vpi)
2301 {
2302 	emlxs_hba_t *hba = HBA;
2303 	emlxs_port_t *pport = &PPORT;
2304 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2305 	uint32_t rval = 0;
2306 
2307 	if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
2308 		return (1);
2309 	}
2310 
2311 	if (!(pport->flag & EMLXS_PORT_BOUND) ||
2312 	    (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
2313 		return (1);
2314 	}
2315 
2316 	mutex_enter(&EMLXS_FCF_LOCK);
2317 
2318 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2319 	    "fcf_cvl_notify: %s flag=%x "
2320 	    "fcfi_online=%d. FCFTAB FCF CVL. >",
2321 	    emlxs_fcftab_state_xlate(port, fcftab->state),
2322 	    fcftab->flag, fcftab->fcfi_online);
2323 
2324 	rval = emlxs_fcftab_event(port, FCF_EVENT_CVL,
2325 	    (void *)((unsigned long)vpi));
2326 
2327 	mutex_exit(&EMLXS_FCF_LOCK);
2328 
2329 	return (rval);
2330 
2331 } /* emlxs_fcf_cvl_notify() */
2332 
2333 
2334 extern uint32_t
emlxs_fcf_full_notify(emlxs_port_t * port)2335 emlxs_fcf_full_notify(emlxs_port_t *port)
2336 {
2337 	emlxs_hba_t *hba = HBA;
2338 	emlxs_port_t *pport = &PPORT;
2339 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2340 	uint32_t rval = 0;
2341 
2342 	if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
2343 		return (1);
2344 	}
2345 
2346 	if (!(pport->flag & EMLXS_PORT_BOUND) ||
2347 	    (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
2348 		return (1);
2349 	}
2350 
2351 	mutex_enter(&EMLXS_FCF_LOCK);
2352 
2353 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2354 	    "fcf_full_notify: %s flag=%x "
2355 	    "fcfi_online=%d. FCFTAB FCF full. >",
2356 	    emlxs_fcftab_state_xlate(port, fcftab->state),
2357 	    fcftab->flag, fcftab->fcfi_online);
2358 
2359 	rval = emlxs_fcftab_event(port, FCF_EVENT_FCFTAB_FULL, 0);
2360 
2361 	mutex_exit(&EMLXS_FCF_LOCK);
2362 
2363 	return (rval);
2364 
2365 } /* emlxs_fcf_full_notify() */
2366 
2367 
2368 extern uint32_t
emlxs_fcf_found_notify(emlxs_port_t * port,uint32_t fcf_index)2369 emlxs_fcf_found_notify(emlxs_port_t *port, uint32_t fcf_index)
2370 {
2371 	emlxs_hba_t *hba = HBA;
2372 	emlxs_port_t *pport = &PPORT;
2373 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2374 	uint32_t rval = 0;
2375 
2376 	if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
2377 		return (1);
2378 	}
2379 
2380 	if (!(pport->flag & EMLXS_PORT_BOUND) ||
2381 	    (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
2382 		return (1);
2383 	}
2384 
2385 	mutex_enter(&EMLXS_FCF_LOCK);
2386 
2387 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2388 	    "fcf_found_notify: %s flag=%x "
2389 	    "fcfi_online=%d. FCFTAB FCF found. >",
2390 	    emlxs_fcftab_state_xlate(port, fcftab->state),
2391 	    fcftab->flag, fcftab->fcfi_online);
2392 
2393 	rval = emlxs_fcftab_event(port, FCF_EVENT_FCF_FOUND,
2394 	    (void *)((unsigned long)fcf_index));
2395 
2396 	mutex_exit(&EMLXS_FCF_LOCK);
2397 
2398 	return (rval);
2399 
2400 } /* emlxs_fcf_found_notify() */
2401 
2402 
2403 extern uint32_t
emlxs_fcf_changed_notify(emlxs_port_t * port,uint32_t fcf_index)2404 emlxs_fcf_changed_notify(emlxs_port_t *port, uint32_t fcf_index)
2405 {
2406 	emlxs_hba_t *hba = HBA;
2407 	emlxs_port_t *pport = &PPORT;
2408 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2409 	uint32_t rval = 0;
2410 
2411 	if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
2412 		return (1);
2413 	}
2414 
2415 	if (!(pport->flag & EMLXS_PORT_BOUND) ||
2416 	    (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
2417 		return (1);
2418 	}
2419 
2420 	mutex_enter(&EMLXS_FCF_LOCK);
2421 
2422 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2423 	    "fcf_changes_notify: %s flag=%x "
2424 	    "fcfi_online=%d. FCFTAB FCF changed. >",
2425 	    emlxs_fcftab_state_xlate(port, fcftab->state),
2426 	    fcftab->flag, fcftab->fcfi_online);
2427 
2428 	rval = emlxs_fcftab_event(port, FCF_EVENT_FCF_CHANGED,
2429 	    (void *)((unsigned long)fcf_index));
2430 
2431 	mutex_exit(&EMLXS_FCF_LOCK);
2432 
2433 	return (rval);
2434 
2435 } /* emlxs_fcf_changed_notify() */
2436 
2437 
2438 extern uint32_t
emlxs_fcf_lost_notify(emlxs_port_t * port,uint32_t fcf_index)2439 emlxs_fcf_lost_notify(emlxs_port_t *port, uint32_t fcf_index)
2440 {
2441 	emlxs_hba_t *hba = HBA;
2442 	emlxs_port_t *pport = &PPORT;
2443 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2444 	uint32_t rval = 0;
2445 
2446 	if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
2447 		return (1);
2448 	}
2449 
2450 	if (!(pport->flag & EMLXS_PORT_BOUND) ||
2451 	    (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
2452 		return (1);
2453 	}
2454 
2455 	mutex_enter(&EMLXS_FCF_LOCK);
2456 
2457 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2458 	    "fcf_lost_notify: %s flag=%x "
2459 	    "fcfi_online=%d. FCFTAB FCF lost. >",
2460 	    emlxs_fcftab_state_xlate(port, fcftab->state),
2461 	    fcftab->flag, fcftab->fcfi_online);
2462 
2463 	rval = emlxs_fcftab_event(port, FCF_EVENT_FCF_LOST,
2464 	    (void *)((unsigned long)fcf_index));
2465 
2466 	mutex_exit(&EMLXS_FCF_LOCK);
2467 
2468 	return (rval);
2469 
2470 } /* emlxs_fcf_lost_notify() */
2471 
2472 
2473 /* ************************************************************************** */
2474 /* FCFTAB Generic */
2475 /* ************************************************************************** */
2476 
2477 static char *
emlxs_fcftab_state_xlate(emlxs_port_t * port,uint32_t state)2478 emlxs_fcftab_state_xlate(emlxs_port_t *port, uint32_t state)
2479 {
2480 	emlxs_hba_t *hba = HBA;
2481 
2482 	if (SLI4_FCOE_MODE) {
2483 		return (emlxs_fcoe_fcftab_state_xlate(state));
2484 	} else {
2485 		return (emlxs_fc_fcftab_state_xlate(state));
2486 	}
2487 
2488 } /* emlxs_fcftab_state_xlate() */
2489 
2490 static uint32_t
emlxs_fcftab_event(emlxs_port_t * port,uint32_t evt,void * arg1)2491 emlxs_fcftab_event(emlxs_port_t *port, uint32_t evt, void *arg1)
2492 {
2493 	emlxs_hba_t *hba = HBA;
2494 
2495 	if (SLI4_FCOE_MODE) {
2496 		return (emlxs_fcoe_fcftab_event(port, evt, arg1));
2497 	} else {
2498 		return (emlxs_fc_fcftab_event(port, evt, arg1));
2499 	}
2500 
2501 } /* emlxs_fcftab_event() */
2502 
2503 
2504 /*ARGSUSED*/
2505 static uint32_t
emlxs_fcftab_shutdown_action(emlxs_port_t * port,uint32_t evt,void * arg1)2506 emlxs_fcftab_shutdown_action(emlxs_port_t *port, uint32_t evt,
2507     void *arg1)
2508 {
2509 	emlxs_hba_t *hba = HBA;
2510 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2511 	FCFIobj_t *fcfp;
2512 	uint32_t i;
2513 	uint32_t online;
2514 
2515 	if (fcftab->state != FCFTAB_STATE_SHUTDOWN) {
2516 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
2517 		    "fcftab_shutdown_action:%x %s:%s arg=%p. "
2518 		    "Invalid state. <",
2519 		    fcftab->TID,
2520 		    emlxs_fcftab_state_xlate(port, fcftab->state),
2521 		    emlxs_fcf_event_xlate(evt), arg1);
2522 		return (1);
2523 	}
2524 
2525 	fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
2526 
2527 	if (fcftab->prev_state != FCFTAB_STATE_SHUTDOWN) {
2528 		/* Offline all FCF's */
2529 		online = 0;
2530 		fcfp = fcftab->table;
2531 		for (i = 0; i < fcftab->table_count; i++, fcfp++) {
2532 
2533 			if (fcfp->state <= FCFI_STATE_OFFLINE) {
2534 				continue;
2535 			}
2536 
2537 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2538 			    "fcftab_shutdown_action:%x fcfi_online=%d. "
2539 			    "Offlining FCFI:%d. >",
2540 			    fcftab->TID,
2541 			    fcftab->fcfi_online,
2542 			    fcfp->fcf_index);
2543 
2544 			(void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_OFFLINE,
2545 			    fcfp);
2546 
2547 			online++;
2548 		}
2549 
2550 		if (!online) {
2551 			goto done;
2552 		}
2553 
2554 		return (0);
2555 	}
2556 
2557 	/* Check FCF states */
2558 	online = 0;
2559 	fcfp = fcftab->table;
2560 	for (i = 0; i < fcftab->table_count; i++, fcfp++) {
2561 
2562 		if (fcfp->state <= FCFI_STATE_OFFLINE) {
2563 			continue;
2564 		}
2565 
2566 		online++;
2567 	}
2568 
2569 	if (online) {
2570 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2571 		    "fcftab_shutdown_action:%x %s:%s arg=%p. "
2572 		    "fcfi_online=%d,%d <",
2573 		    fcftab->TID,
2574 		    emlxs_fcftab_state_xlate(port, fcftab->state),
2575 		    emlxs_fcf_event_xlate(evt), arg1,
2576 		    online, fcftab->fcfi_online);
2577 
2578 		return (0);
2579 	}
2580 
2581 done:
2582 	/* Free FCF table */
2583 	fcfp = fcftab->table;
2584 	for (i = 0; i < fcftab->table_count; i++, fcfp++) {
2585 
2586 		if (fcfp->state == FCFI_STATE_FREE) {
2587 			continue;
2588 		}
2589 
2590 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2591 		    "fcftab_shutdown_action:%x. Freeing FCFI:%d. >",
2592 		    fcftab->TID,
2593 		    fcfp->fcf_index);
2594 
2595 		(void) emlxs_fcfi_free(port, fcfp);
2596 	}
2597 
2598 	/* Clean the selection table */
2599 	bzero(fcftab->fcfi, sizeof (fcftab->fcfi));
2600 	fcftab->fcfi_count = 0;
2601 
2602 	fcftab->flag |= EMLXS_FCFTAB_SHUTDOWN;
2603 
2604 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2605 	    "fcftab_shutdown_action:%x %s:%s arg=%p flag=%x fcfi_online=%d. "
2606 	    "Shutdown. <",
2607 	    fcftab->TID,
2608 	    emlxs_fcftab_state_xlate(port, fcftab->state),
2609 	    emlxs_fcf_event_xlate(evt), arg1,
2610 	    fcftab->flag, fcftab->fcfi_online);
2611 
2612 	return (0);
2613 
2614 } /* emlxs_fcftab_shutdown_action() */
2615 
2616 
2617 /* ************************************************************************** */
2618 /* FC FCFTAB */
2619 /* ************************************************************************** */
2620 
2621 static char *
emlxs_fc_fcftab_state_xlate(uint32_t state)2622 emlxs_fc_fcftab_state_xlate(uint32_t state)
2623 {
2624 	static char buffer[32];
2625 	uint32_t i;
2626 	uint32_t count;
2627 
2628 	count = sizeof (emlxs_fc_fcftab_state_table) / sizeof (emlxs_table_t);
2629 	for (i = 0; i < count; i++) {
2630 		if (state == emlxs_fc_fcftab_state_table[i].code) {
2631 			return (emlxs_fc_fcftab_state_table[i].string);
2632 		}
2633 	}
2634 
2635 	(void) snprintf(buffer, sizeof (buffer), "state=0x%x", state);
2636 	return (buffer);
2637 
2638 } /* emlxs_fc_fcftab_state_xlate() */
2639 
2640 
2641 static uint32_t
emlxs_fc_fcftab_action(emlxs_port_t * port,uint32_t evt,void * arg1)2642 emlxs_fc_fcftab_action(emlxs_port_t *port, uint32_t evt,
2643     void *arg1)
2644 {
2645 	emlxs_hba_t *hba = HBA;
2646 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2647 	uint32_t rval = 0;
2648 	uint32_t(*func) (emlxs_port_t *, uint32_t, void *);
2649 	uint32_t index;
2650 	uint32_t events;
2651 	uint16_t state;
2652 
2653 	/* Convert event to action table index */
2654 	switch (evt) {
2655 	case FCF_EVENT_STATE_ENTER:
2656 		index = 0;
2657 		break;
2658 	case FCF_EVENT_SHUTDOWN:
2659 		index = 1;
2660 		break;
2661 	case FCF_EVENT_LINKUP:
2662 		index = 2;
2663 		break;
2664 	case FCF_EVENT_LINKDOWN:
2665 		index = 3;
2666 		break;
2667 	case FCF_EVENT_FCFI_ONLINE:
2668 		index = 4;
2669 		break;
2670 	case FCF_EVENT_FCFI_OFFLINE:
2671 		index = 5;
2672 		break;
2673 	default:
2674 		return (1);
2675 	}
2676 
2677 	events = FC_FCFTAB_ACTION_EVENTS;
2678 	state  = fcftab->state;
2679 
2680 	index += (state * events);
2681 	func   = (uint32_t(*) (emlxs_port_t *, uint32_t, void *))
2682 	    emlxs_fc_fcftab_action_table[index];
2683 
2684 	if (!func) {
2685 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
2686 		    "fc_fcftab_action:%x %s:%s arg=%p. No action. <",
2687 		    fcftab->TID,
2688 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
2689 		    emlxs_fcf_event_xlate(evt), arg1);
2690 
2691 		return (1);
2692 	}
2693 
2694 	rval = (func)(port, evt, arg1);
2695 
2696 	return (rval);
2697 
2698 } /* emlxs_fc_fcftab_action() */
2699 
2700 
2701 static uint32_t
emlxs_fc_fcftab_event(emlxs_port_t * port,uint32_t evt,void * arg1)2702 emlxs_fc_fcftab_event(emlxs_port_t *port, uint32_t evt,
2703     void *arg1)
2704 {
2705 	emlxs_hba_t *hba = HBA;
2706 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2707 	uint32_t rval = 0;
2708 
2709 	/* Filter events */
2710 	switch (evt) {
2711 	case FCF_EVENT_SHUTDOWN:
2712 	case FCF_EVENT_LINKUP:
2713 	case FCF_EVENT_LINKDOWN:
2714 	case FCF_EVENT_FCFI_ONLINE:
2715 	case FCF_EVENT_FCFI_OFFLINE:
2716 		break;
2717 
2718 	default:
2719 		return (1);
2720 	}
2721 
2722 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
2723 	    "fc_fcftab_event:%x %s:%s arg=%p.",
2724 	    fcftab->TID,
2725 	    emlxs_fc_fcftab_state_xlate(fcftab->state),
2726 	    emlxs_fcf_event_xlate(evt), arg1);
2727 
2728 	rval = emlxs_fc_fcftab_action(port, evt, arg1);
2729 
2730 	return (rval);
2731 
2732 } /* emlxs_fc_fcftab_event() */
2733 
2734 
2735 /* EMLXS_FCF_LOCK must be held to enter */
2736 /*ARGSUSED*/
2737 static uint32_t
emlxs_fc_fcftab_state(emlxs_port_t * port,uint16_t state,uint16_t reason,uint32_t explain,void * arg1)2738 emlxs_fc_fcftab_state(emlxs_port_t *port, uint16_t state, uint16_t reason,
2739     uint32_t explain, void *arg1)
2740 {
2741 	emlxs_hba_t *hba = HBA;
2742 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2743 	uint32_t rval = 0;
2744 
2745 	if (state >= FC_FCFTAB_ACTION_STATES) {
2746 		return (1);
2747 	}
2748 
2749 	if ((fcftab->state == state) &&
2750 	    (reason != FCF_REASON_REENTER)) {
2751 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
2752 		    "fcftab_state:%x %s:%s:0x%x arg=%p. "
2753 		    "State not changed. <",
2754 		    fcftab->TID,
2755 		    emlxs_fc_fcftab_state_xlate(state),
2756 		    emlxs_fcf_reason_xlate(reason),
2757 		    explain, arg1);
2758 		return (1);
2759 	}
2760 
2761 	if (!reason) {
2762 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
2763 		    "fcftab_state:%x %s-->%s arg=%p",
2764 		    fcftab->TID,
2765 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
2766 		    emlxs_fc_fcftab_state_xlate(state), arg1);
2767 	} else if (reason == FCF_REASON_EVENT) {
2768 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
2769 		    "fcftab_state:%x %s-->%s:%s:%s arg=%p",
2770 		    fcftab->TID,
2771 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
2772 		    emlxs_fc_fcftab_state_xlate(state),
2773 		    emlxs_fcf_reason_xlate(reason),
2774 		    emlxs_fcf_event_xlate(explain), arg1);
2775 	} else if (explain) {
2776 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
2777 		    "fcftab_state:%x %s-->%s:%s:0x%x arg=%p",
2778 		    fcftab->TID,
2779 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
2780 		    emlxs_fc_fcftab_state_xlate(state),
2781 		    emlxs_fcf_reason_xlate(reason),
2782 		    explain, arg1);
2783 	} else {
2784 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
2785 		    "fcftab_state:%x %s-->%s:%s arg=%p",
2786 		    fcftab->TID,
2787 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
2788 		    emlxs_fc_fcftab_state_xlate(state),
2789 		    emlxs_fcf_reason_xlate(reason), arg1);
2790 	}
2791 
2792 	fcftab->prev_state = fcftab->state;
2793 	fcftab->prev_reason = fcftab->reason;
2794 	fcftab->state = state;
2795 	fcftab->reason = reason;
2796 
2797 	rval = emlxs_fc_fcftab_action(port, FCF_EVENT_STATE_ENTER, arg1);
2798 
2799 	return (rval);
2800 
2801 } /* emlxs_fc_fcftab_state() */
2802 
2803 
2804 static void
emlxs_fc_fcftab_online_timer(emlxs_hba_t * hba)2805 emlxs_fc_fcftab_online_timer(emlxs_hba_t *hba)
2806 {
2807 	emlxs_port_t *port = &PPORT;
2808 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2809 
2810 	/* Check FCF timer */
2811 	if (!fcftab->online_timer ||
2812 	    (hba->timer_tics < fcftab->online_timer)) {
2813 		return;
2814 	}
2815 	fcftab->online_timer = 0;
2816 
2817 	switch (fcftab->state) {
2818 	case FC_FCFTAB_STATE_ONLINE:
2819 		emlxs_fcf_linkup(port);
2820 
2821 		fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
2822 		fcftab->flag |= EMLXS_FC_FCFTAB_TOPO_REQ;
2823 		fcftab->generation++;
2824 
2825 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2826 		    "fc_fcftab_online_timer:%x %s gen=%x. Read topology. >",
2827 		    fcftab->TID,
2828 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
2829 		    fcftab->generation);
2830 
2831 		(void) emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO,
2832 		    FCF_REASON_EVENT, 0, 0);
2833 		break;
2834 
2835 	default:
2836 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2837 		    "fc_fcftab_online_timer:%x %s",
2838 		    fcftab->TID,
2839 		    emlxs_fc_fcftab_state_xlate(fcftab->state));
2840 		break;
2841 	}
2842 
2843 	return;
2844 
2845 }  /* emlxs_fc_fcftab_online_timer() */
2846 
2847 
2848 /*ARGSUSED*/
2849 static uint32_t
emlxs_fc_fcftab_offline_action(emlxs_port_t * port,uint32_t evt,void * arg1)2850 emlxs_fc_fcftab_offline_action(emlxs_port_t *port, uint32_t evt,
2851     void *arg1)
2852 {
2853 	emlxs_hba_t *hba = HBA;
2854 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2855 	uint32_t rval = 0;
2856 
2857 	if (fcftab->state != FC_FCFTAB_STATE_OFFLINE) {
2858 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
2859 		    "fc_fcftab_offline_action:%x %s:%s arg=%p. "
2860 		    "Invalid state. <",
2861 		    fcftab->TID,
2862 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
2863 		    emlxs_fcf_event_xlate(evt), arg1);
2864 		return (1);
2865 	}
2866 
2867 	fcftab->flag &= ~EMLXS_FC_FCFTAB_OFFLINE_REQ;
2868 
2869 	if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
2870 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2871 		    "fc_fcftab_offline_action:%x %s:%s arg=%p flag=%x. "
2872 		    "Handling request.",
2873 		    fcftab->TID,
2874 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
2875 		    emlxs_fcf_event_xlate(evt), arg1,
2876 		    fcftab->flag);
2877 
2878 		rval = emlxs_fc_fcftab_req_handler(port, arg1);
2879 		return (rval);
2880 	}
2881 
2882 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2883 	    "fc_fcftab_offline_action:%x %s:%s arg=%p fcfi_online=%d. "
2884 	    "Offline. <",
2885 	    fcftab->TID,
2886 	    emlxs_fc_fcftab_state_xlate(fcftab->state),
2887 	    emlxs_fcf_event_xlate(evt), arg1,
2888 	    fcftab->fcfi_online);
2889 
2890 	return (0);
2891 
2892 } /* emlxs_fc_fcftab_offline_action() */
2893 
2894 
2895 /*ARGSUSED*/
2896 static uint32_t
emlxs_fc_fcftab_online_action(emlxs_port_t * port,uint32_t evt,void * arg1)2897 emlxs_fc_fcftab_online_action(emlxs_port_t *port, uint32_t evt,
2898     void *arg1)
2899 {
2900 	emlxs_hba_t *hba = HBA;
2901 	emlxs_port_t *pport = &PPORT;
2902 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2903 	uint32_t rval = 0;
2904 
2905 	if (fcftab->state != FC_FCFTAB_STATE_ONLINE) {
2906 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
2907 		    "fc_fcftab_online_action:%x %s:%s arg=%p. "
2908 		    "Invalid state. <",
2909 		    fcftab->TID,
2910 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
2911 		    emlxs_fcf_event_xlate(evt), arg1);
2912 		return (1);
2913 	}
2914 
2915 	if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
2916 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2917 		    "fc_fcftab_online_action:%x flag=%x. "
2918 		    "Handling requested.",
2919 		    fcftab->TID,
2920 		    fcftab->flag);
2921 
2922 		rval = emlxs_fc_fcftab_req_handler(port, arg1);
2923 		return (rval);
2924 	}
2925 
2926 	if (fcftab->fcfi_online == 0) {
2927 		if (!(pport->flag & EMLXS_PORT_BOUND) ||
2928 		    (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
2929 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2930 			    "fc_fcftab_online_action:%x %s:%s "
2931 			    "fcfi_online=0. Pport not bound. <",
2932 			    fcftab->TID,
2933 			    emlxs_fcoe_fcftab_state_xlate(fcftab->state),
2934 			    emlxs_fcf_event_xlate(evt));
2935 		} else {
2936 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2937 			    "fc_fcftab_online_action:%x %s:%s "
2938 			    "fcfi_online=0. Starting online timer. <",
2939 			    fcftab->TID,
2940 			    emlxs_fcoe_fcftab_state_xlate(fcftab->state),
2941 			    emlxs_fcf_event_xlate(evt));
2942 
2943 			/* Start the online timer */
2944 			fcftab->online_timer = hba->timer_tics + 1;
2945 		}
2946 
2947 		emlxs_fcf_linkdown(port);
2948 
2949 		return (0);
2950 	}
2951 
2952 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2953 	    "fc_fcftab_online_action:%x flag=%x fcfi_online=%d. "
2954 	    "Online. <",
2955 	    fcftab->TID,
2956 	    fcftab->flag,
2957 	    fcftab->fcfi_online);
2958 
2959 	emlxs_fcf_linkup(port);
2960 
2961 	return (0);
2962 
2963 } /* emlxs_fc_fcftab_online_action() */
2964 
2965 
2966 /*ARGSUSED*/
2967 static uint32_t
emlxs_fc_fcftab_topo_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)2968 emlxs_fc_fcftab_topo_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
2969 {
2970 	emlxs_port_t *port = (emlxs_port_t *)mbq->port;
2971 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
2972 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
2973 	MATCHMAP *mp;
2974 	uint8_t *alpa_map;
2975 	uint32_t j;
2976 	uint16_t TID;
2977 
2978 	mutex_enter(&EMLXS_FCF_LOCK);
2979 	TID = (uint16_t)((unsigned long)mbq->context);
2980 
2981 	if (fcftab->state != FC_FCFTAB_STATE_TOPO) {
2982 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2983 		    "fc_fcftab_topo_mbcmpl:%x state=%s.",
2984 		    TID,
2985 		    emlxs_fc_fcftab_state_xlate(fcftab->state));
2986 
2987 		mutex_exit(&EMLXS_FCF_LOCK);
2988 		return (0);
2989 	}
2990 
2991 	if (TID != fcftab->generation) {
2992 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
2993 		    "fc_fcftab_topo_mbcmpl:%x %s. "
2994 		    "Incorrect generation %x. Dropping.",
2995 		    TID,
2996 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
2997 		    fcftab->generation);
2998 
2999 		mutex_exit(&EMLXS_FCF_LOCK);
3000 		return (0);
3001 	}
3002 
3003 	if (mb4->mbxStatus) {
3004 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3005 		    "fc_fcftab_topo_mbcmpl:%x failed. %s. >",
3006 		    fcftab->TID,
3007 		    emlxs_mb_xlate_status(mb4->mbxStatus));
3008 
3009 		if (mb4->mbxStatus == MBXERR_NO_RESOURCES) {
3010 			(void) emlxs_fc_fcftab_state(port,
3011 			    FC_FCFTAB_STATE_TOPO_FAILED,
3012 			    FCF_REASON_MBOX_BUSY, mb4->mbxStatus, 0);
3013 		} else {
3014 			(void) emlxs_fc_fcftab_state(port,
3015 			    FC_FCFTAB_STATE_TOPO_FAILED,
3016 			    FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
3017 		}
3018 
3019 		mutex_exit(&EMLXS_FCF_LOCK);
3020 		return (0);
3021 	}
3022 
3023 	if (mb4->un.varReadLA.attType == AT_LINK_DOWN) {
3024 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3025 		    "fc_fcftab_topo_mbcmpl:%x  Linkdown attention. "
3026 		    "Offline requested.",
3027 		    fcftab->TID);
3028 
3029 		fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
3030 		fcftab->flag |= EMLXS_FC_FCFTAB_OFFLINE_REQ;
3031 		(void) emlxs_fc_fcftab_req_handler(port, 0);
3032 
3033 		mutex_exit(&EMLXS_FCF_LOCK);
3034 		return (0);
3035 	}
3036 
3037 	if (hba->link_event_tag != mb4->un.varReadLA.eventTag) {
3038 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3039 		    "fc_fcftab_topo_mbcmpl:%x Event tag invalid. %x != %x",
3040 		    fcftab->TID,
3041 		    hba->link_event_tag, mb4->un.varReadLA.eventTag);
3042 	}
3043 
3044 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3045 	    "fc_fcftab_topo_mbcmpl:%x state=%s type=%s iotag=%d "
3046 	    "alpa=%x. >",
3047 	    fcftab->TID,
3048 	    emlxs_fc_fcftab_state_xlate(fcftab->state),
3049 	    (mb4->un.varReadLA.attType == AT_LINK_UP)?"linkup":"linkdown",
3050 	    hba->link_event_tag,
3051 	    (uint32_t)mb4->un.varReadLA.granted_AL_PA);
3052 
3053 	/* Link is up */
3054 
3055 	/* Save the linkspeed & topology */
3056 	hba->linkspeed = mb4->un.varReadLA.UlnkSpeed;
3057 	hba->topology = mb4->un.varReadLA.topology;
3058 
3059 	if (hba->topology != TOPOLOGY_LOOP) {
3060 		port->did = 0;
3061 		port->lip_type = 0;
3062 		hba->flag &= ~FC_BYPASSED_MODE;
3063 		bzero((caddr_t)port->alpa_map, 128);
3064 
3065 		goto done;
3066 	}
3067 
3068 	/* TOPOLOGY_LOOP */
3069 
3070 	port->lip_type = mb4->un.varReadLA.lipType;
3071 
3072 	if (mb4->un.varReadLA.pb) {
3073 		hba->flag |= FC_BYPASSED_MODE;
3074 	} else {
3075 		hba->flag &= ~FC_BYPASSED_MODE;
3076 	}
3077 
3078 	/* Save the granted_alpa and alpa_map */
3079 
3080 	port->granted_alpa = mb4->un.varReadLA.granted_AL_PA;
3081 	mp = (MATCHMAP *)mbq->bp;
3082 	alpa_map = (uint8_t *)port->alpa_map;
3083 
3084 	bcopy((caddr_t)mp->virt, (caddr_t)alpa_map, 128);
3085 
3086 	/* Check number of devices in map */
3087 	if (alpa_map[0] > 127) {
3088 		alpa_map[0] = 127;
3089 	}
3090 
3091 	EMLXS_MSGF(EMLXS_CONTEXT,
3092 	    &emlxs_link_atten_msg,
3093 	    "alpa_map: %d device(s): "
3094 	    "%02x %02x %02x %02x %02x %02x %02x %02x",
3095 	    alpa_map[0], alpa_map[1],
3096 	    alpa_map[2], alpa_map[3],
3097 	    alpa_map[4], alpa_map[5],
3098 	    alpa_map[6], alpa_map[7],
3099 	    alpa_map[8]);
3100 
3101 	for (j = 9; j <= alpa_map[0]; j += 8) {
3102 		EMLXS_MSGF(EMLXS_CONTEXT,
3103 		    &emlxs_link_atten_msg,
3104 		    "alpa_map:               "
3105 		    "%02x %02x %02x %02x %02x %02x %02x %02x",
3106 		    alpa_map[j],
3107 		    alpa_map[j + 1],
3108 		    alpa_map[j + 2],
3109 		    alpa_map[j + 3],
3110 		    alpa_map[j + 4],
3111 		    alpa_map[j + 5],
3112 		    alpa_map[j + 6],
3113 		    alpa_map[j + 7]);
3114 	}
3115 
3116 done:
3117 
3118 	(void) emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO_CMPL,
3119 	    0, 0, 0);
3120 
3121 	mutex_exit(&EMLXS_FCF_LOCK);
3122 	return (0);
3123 
3124 } /* emlxs_fc_fcftab_topo_mbcmpl() */
3125 
3126 
3127 /*ARGSUSED*/
3128 static uint32_t
emlxs_fc_fcftab_topo_action(emlxs_port_t * port,uint32_t evt,void * arg1)3129 emlxs_fc_fcftab_topo_action(emlxs_port_t *port, uint32_t evt,
3130     void *arg1)
3131 {
3132 	emlxs_hba_t *hba = HBA;
3133 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3134 	MAILBOXQ *mbq;
3135 	MAILBOX4 *mb4;
3136 	uint32_t rval = 0;
3137 	MATCHMAP *mp;
3138 
3139 	if (fcftab->state != FC_FCFTAB_STATE_TOPO) {
3140 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
3141 		    "fc_fcftab_topo_action:%x %s:%s arg=%p. "
3142 		    "Invalid state. <",
3143 		    fcftab->TID,
3144 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
3145 		    emlxs_fcf_event_xlate(evt), arg1);
3146 		return (1);
3147 	}
3148 
3149 	if ((fcftab->prev_state != FC_FCFTAB_STATE_TOPO_FAILED) ||
3150 	    (fcftab->flag & EMLXS_FC_FCFTAB_TOPO_REQ)) {
3151 		fcftab->flag &= ~EMLXS_FC_FCFTAB_TOPO_REQ;
3152 		fcftab->attempts = 0;
3153 	}
3154 
3155 	if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
3156 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3157 		    "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. "
3158 		    "Handling request.",
3159 		    fcftab->TID,
3160 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
3161 		    emlxs_fcf_event_xlate(evt), arg1,
3162 		    fcftab->generation,
3163 		    fcftab->flag);
3164 
3165 		rval = emlxs_fc_fcftab_req_handler(port, arg1);
3166 		return (rval);
3167 	}
3168 
3169 	if (fcftab->attempts == 0) {
3170 		fcftab->TID = fcftab->generation;
3171 	}
3172 
3173 	if (hba->topology != TOPOLOGY_LOOP) {
3174 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3175 		    "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. "
3176 		    "Fabric Topology. Skipping READ_TOPO.",
3177 		    fcftab->TID,
3178 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
3179 		    emlxs_fcf_event_xlate(evt), arg1,
3180 		    fcftab->generation,
3181 		    fcftab->flag);
3182 
3183 		port->did = 0;
3184 		port->lip_type = 0;
3185 		hba->flag &= ~FC_BYPASSED_MODE;
3186 		bzero((caddr_t)port->alpa_map, 128);
3187 
3188 		rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK,
3189 		    FCF_REASON_EVENT, evt, arg1);
3190 		return (rval);
3191 	}
3192 
3193 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3194 	    "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. "
3195 	    "Sending READ_TOPO. <",
3196 	    fcftab->TID,
3197 	    emlxs_fc_fcftab_state_xlate(fcftab->state),
3198 	    emlxs_fcf_event_xlate(evt), arg1,
3199 	    fcftab->generation,
3200 	    fcftab->flag);
3201 
3202 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
3203 		rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO_FAILED,
3204 		    FCF_REASON_NO_MBOX, 0, arg1);
3205 		return (rval);
3206 	}
3207 	mb4 = (MAILBOX4*)mbq;
3208 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
3209 
3210 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
3211 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
3212 
3213 		rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO_FAILED,
3214 		    FCF_REASON_NO_BUFFER, 0, arg1);
3215 		return (rval);
3216 	}
3217 	bzero(mp->virt, mp->size);
3218 
3219 	mbq->nonembed = NULL;
3220 	mbq->bp = (void *)mp;
3221 	mbq->mbox_cmpl = emlxs_fc_fcftab_topo_mbcmpl;
3222 	mbq->context = (void *)((unsigned long)fcftab->TID);
3223 	mbq->port = (void *)port;
3224 
3225 	mb4->un.varSLIConfig.be.embedded = 0;
3226 	mb4->mbxCommand = MBX_READ_TOPOLOGY;
3227 	mb4->mbxOwner = OWN_HOST;
3228 
3229 	mb4->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
3230 	mb4->un.varReadLA.un.lilpBde64.addrHigh = PADDR_HI(mp->phys);
3231 	mb4->un.varReadLA.un.lilpBde64.addrLow = PADDR_LO(mp->phys);
3232 
3233 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
3234 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
3235 		emlxs_mem_put(hba, MEM_BUF, (void *)mp);
3236 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
3237 
3238 		rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO_FAILED,
3239 		    FCF_REASON_SEND_FAILED, rval, arg1);
3240 
3241 		return (rval);
3242 	}
3243 
3244 	return (0);
3245 
3246 } /* emlxs_fc_fcftab_topo_action() */
3247 
3248 
3249 /*ARGSUSED*/
3250 static uint32_t
emlxs_fc_fcftab_topo_failed_action(emlxs_port_t * port,uint32_t evt,void * arg1)3251 emlxs_fc_fcftab_topo_failed_action(emlxs_port_t *port, uint32_t evt,
3252     void *arg1)
3253 {
3254 	emlxs_hba_t *hba = HBA;
3255 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3256 	uint32_t rval = 0;
3257 
3258 	fcftab->attempts++;
3259 
3260 	if (fcftab->state != FC_FCFTAB_STATE_TOPO_FAILED) {
3261 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
3262 		    "fc_fcftab_topo_failed_action:%x %s:%s arg=%p "
3263 		    "attempt=%d. Invalid state. <",
3264 		    fcftab->TID,
3265 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
3266 		    emlxs_fcf_event_xlate(evt),
3267 		    arg1, fcftab->attempts);
3268 		return (1);
3269 	}
3270 
3271 	if ((fcftab->reason == FCF_REASON_MBOX_FAILED) ||
3272 	    (fcftab->reason == FCF_REASON_SEND_FAILED) ||
3273 	    (fcftab->attempts >= 3)) {
3274 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3275 		    "fc_fcftab_topo_failed_action:%x %s:%s arg=%p "
3276 		    "attempt=%d reason=%x. Giving up.",
3277 		    fcftab->TID,
3278 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
3279 		    emlxs_fcf_event_xlate(evt), arg1,
3280 		    fcftab->attempts,
3281 		    fcftab->reason);
3282 
3283 		rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO_CMPL,
3284 		    FCF_REASON_OP_FAILED, fcftab->attempts, arg1);
3285 
3286 	} else {
3287 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3288 		    "fc_fcftab_topo_failed_action:%x %s:%s arg=%p "
3289 		    "attempt=%d reason=%x. Retrying.",
3290 		    fcftab->TID,
3291 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
3292 		    emlxs_fcf_event_xlate(evt), arg1,
3293 		    fcftab->attempts,
3294 		    fcftab->reason);
3295 
3296 		rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO,
3297 		    FCF_REASON_OP_FAILED, fcftab->attempts, arg1);
3298 	}
3299 
3300 	return (rval);
3301 
3302 } /* emlxs_fc_fcftab_topo_failed_action() */
3303 
3304 
3305 /*ARGSUSED*/
3306 static uint32_t
emlxs_fc_fcftab_topo_cmpl_action(emlxs_port_t * port,uint32_t evt,void * arg1)3307 emlxs_fc_fcftab_topo_cmpl_action(emlxs_port_t *port, uint32_t evt,
3308     void *arg1)
3309 {
3310 	emlxs_hba_t *hba = HBA;
3311 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3312 	uint32_t rval = 0;
3313 
3314 	if (fcftab->state != FC_FCFTAB_STATE_TOPO_CMPL) {
3315 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
3316 		    "fc_fcftab_topo_cmpl_action:%x %s:%s arg=%p. "
3317 		    "Invalid state. <",
3318 		    fcftab->TID,
3319 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
3320 		    emlxs_fcf_event_xlate(evt), arg1);
3321 		return (1);
3322 	}
3323 
3324 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3325 	    "fc_fcftab_topo_cmpl_action:%x attempts=%d. "
3326 	    "Config link.",
3327 	    fcftab->TID,
3328 	    fcftab->attempts);
3329 
3330 	rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK,
3331 	    FCF_REASON_EVENT, evt, arg1);
3332 
3333 	return (rval);
3334 
3335 } /* emlxs_fc_fcftab_topo_cmpl_action() */
3336 
3337 
3338 /*ARGSUSED*/
3339 static uint32_t
emlxs_fc_fcftab_cfglink_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)3340 emlxs_fc_fcftab_cfglink_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
3341 {
3342 	emlxs_port_t *port = (emlxs_port_t *)mbq->port;
3343 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3344 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
3345 	uint16_t TID;
3346 
3347 	mutex_enter(&EMLXS_FCF_LOCK);
3348 	TID = (uint16_t)((unsigned long)mbq->context);
3349 
3350 	if (fcftab->state != FC_FCFTAB_STATE_CFGLINK) {
3351 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3352 		    "fc_fcftab_cfglink_mbcmpl:%x state=%s.",
3353 		    TID,
3354 		    emlxs_fc_fcftab_state_xlate(fcftab->state));
3355 
3356 		mutex_exit(&EMLXS_FCF_LOCK);
3357 		return (0);
3358 	}
3359 
3360 	if (TID != fcftab->generation) {
3361 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3362 		    "fc_fcftab_cfglink_mbcmpl:%x %s. "
3363 		    "Incorrect generation %x. Dropping.",
3364 		    TID,
3365 		    emlxs_fc_fcftab_state_xlate(fcftab->state),
3366 		    fcftab->generation);
3367 
3368 		mutex_exit(&EMLXS_FCF_LOCK);
3369 		return (0);
3370 	}
3371 
3372 	if (mb4->mbxStatus) {
3373 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3374 		    "fc_fcftab_cfglink_mbcmpl:%x failed. %s. >",
3375 		    fcftab->TID,
3376 		    emlxs_mb_xlate_status(mb4->mbxStatus));
3377 
3378 		if (mb4->mbxStatus == MBXERR_NO_RESOURCES) {
3379 			(void) emlxs_fc_fcftab_state(port,
3380 			    FC_FCFTAB_STATE_CFGLINK_FAILED,
3381 			    FCF_REASON_MBOX_BUSY, mb4->mbxStatus, 0);
3382 		} else {
3383 			(void) emlxs_fc_fcftab_state(port,
3384 			    FC_FCFTAB_STATE_CFGLINK_FAILED,
3385 			    FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
3386 		}
3387 
3388 		mutex_exit(&EMLXS_FCF_LOCK);
3389 		return (0);
3390 	}
3391 
3392 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
3393 	    "fc_fcftab_cfglink_mbcmpl:%x. >",
3394 	    fcftab->TID);
3395 
3396 	(void) emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK_CMPL,
3397 	    0, 0, 0);
3398 
3399 	mutex_exit(&EMLXS_FCF_LOCK);
3400 	return (0);
3401 
3402 } /* emlxs_fc_fcftab_cfglink_mbcmpl() */
3403 
3404 
3405 
3406 /*ARGSUSED*/
3407 static uint32_t
emlxs_fc_fcftab_cfglink_action(emlxs_port_t * port,uint32_t evt,void * arg1)3408 emlxs_fc_fcftab_cfglink_action(emlxs_port_t *port, uint32_t evt,
3409     void *arg1)
3410 {
3411 	emlxs_hba_t *hba = HBA;
3412 	emlxs_config_t *cfg = &CFG;
3413 	FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3414 	MAILBOXQ *mbq;
3415 	MAILBOX4 *mb4;
3416 	uint32_t rval = 0;
3417 
3418 	if (fcftab->state != FC_FCFTAB_STATE_CFGLINK) {
3419 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,