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,
3420 "fc_fcftab_cfglink_action:%x %s:%s arg=%p. "
3421 "Invalid state. <",
3422 fcftab->TID,
3423 emlxs_fc_fcftab_state_xlate(fcftab->state),
3424 emlxs_fcf_event_xlate(evt), arg1);
3425 return (1);
3426 }
3427
3428 if ((fcftab->prev_state != FC_FCFTAB_STATE_CFGLINK_FAILED) ||
3429 (fcftab->flag & EMLXS_FC_FCFTAB_CFGLINK_REQ)) {
3430 fcftab->flag &= ~EMLXS_FC_FCFTAB_CFGLINK_REQ;
3431 fcftab->attempts = 0;
3432 }
3433
3434 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
3435 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3436 "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. "
3437 "Handling request.",
3438 fcftab->TID,
3439 emlxs_fc_fcftab_state_xlate(fcftab->state),
3440 emlxs_fcf_event_xlate(evt), arg1,
3441 fcftab->generation,
3442 fcftab->flag);
3443
3444 rval = emlxs_fc_fcftab_req_handler(port, arg1);
3445 return (rval);
3446 }
3447
3448 if (fcftab->attempts == 0) {
3449 fcftab->TID = fcftab->generation;
3450 }
3451
3452 if (hba->topology != TOPOLOGY_LOOP) {
3453 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3454 "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. "
3455 "Fabric Topology. Skipping CONFIG_LINK.",
3456 fcftab->TID,
3457 emlxs_fc_fcftab_state_xlate(fcftab->state),
3458 emlxs_fcf_event_xlate(evt), arg1,
3459 fcftab->generation,
3460 fcftab->flag);
3461
3462 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM,
3463 FCF_REASON_EVENT, evt, arg1);
3464 return (rval);
3465 }
3466
3467 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3468 "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. "
3469 "Sending CONFIG_LINK. <",
3470 fcftab->TID,
3471 emlxs_fc_fcftab_state_xlate(fcftab->state),
3472 emlxs_fcf_event_xlate(evt), arg1,
3473 fcftab->generation,
3474 fcftab->flag);
3475
3476 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
3477 rval = emlxs_fc_fcftab_state(port,
3478 FC_FCFTAB_STATE_CFGLINK_FAILED,
3479 FCF_REASON_NO_MBOX, 0, arg1);
3480 return (rval);
3481 }
3482 mb4 = (MAILBOX4*)mbq;
3483 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
3484
3485 mbq->nonembed = NULL;
3486 mbq->mbox_cmpl = emlxs_fc_fcftab_cfglink_mbcmpl;
3487 mbq->context = (void *)((unsigned long)fcftab->TID);
3488 mbq->port = (void *)port;
3489
3490 mb4->un.varSLIConfig.be.embedded = 0;
3491 mb4->mbxCommand = MBX_CONFIG_LINK;
3492 mb4->mbxOwner = OWN_HOST;
3493
3494 if (cfg[CFG_CR_DELAY].current) {
3495 mb4->un.varCfgLnk.cr = 1;
3496 mb4->un.varCfgLnk.ci = 1;
3497 mb4->un.varCfgLnk.cr_delay = cfg[CFG_CR_DELAY].current;
3498 mb4->un.varCfgLnk.cr_count = cfg[CFG_CR_COUNT].current;
3499 }
3500
3501 if (cfg[CFG_ACK0].current) {
3502 mb4->un.varCfgLnk.ack0_enable = 1;
3503 }
3504
3505 mb4->un.varCfgLnk.myId = port->did;
3506 mb4->un.varCfgLnk.edtov = hba->fc_edtov;
3507 mb4->un.varCfgLnk.arbtov = hba->fc_arbtov;
3508 mb4->un.varCfgLnk.ratov = hba->fc_ratov;
3509 mb4->un.varCfgLnk.rttov = hba->fc_rttov;
3510 mb4->un.varCfgLnk.altov = hba->fc_altov;
3511 mb4->un.varCfgLnk.crtov = hba->fc_crtov;
3512
3513
3514 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
3515 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
3516 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
3517
3518 rval = emlxs_fc_fcftab_state(port,
3519 FC_FCFTAB_STATE_CFGLINK_FAILED,
3520 FCF_REASON_SEND_FAILED, rval, arg1);
3521
3522 return (rval);
3523 }
3524
3525 return (0);
3526
3527 } /* emlxs_fc_fcftab_cfglink_action() */
3528
3529
3530 /*ARGSUSED*/
3531 static uint32_t
emlxs_fc_fcftab_cfglink_failed_action(emlxs_port_t * port,uint32_t evt,void * arg1)3532 emlxs_fc_fcftab_cfglink_failed_action(emlxs_port_t *port, uint32_t evt,
3533 void *arg1)
3534 {
3535 emlxs_hba_t *hba = HBA;
3536 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3537 uint32_t rval = 0;
3538
3539 fcftab->attempts++;
3540
3541 if (fcftab->state != FC_FCFTAB_STATE_CFGLINK_FAILED) {
3542 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
3543 "fc_fcftab_cfglink_failed_action:%x %s:%s arg=%p "
3544 "attempt=%d. Invalid state. <",
3545 fcftab->TID,
3546 emlxs_fc_fcftab_state_xlate(fcftab->state),
3547 emlxs_fcf_event_xlate(evt),
3548 arg1, fcftab->attempts);
3549 return (1);
3550 }
3551
3552 if ((fcftab->reason == FCF_REASON_MBOX_FAILED) ||
3553 (fcftab->reason == FCF_REASON_SEND_FAILED) ||
3554 (fcftab->attempts >= 3)) {
3555 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3556 "fc_fcftab_cfglink_failed_action:%x %s:%s arg=%p "
3557 "attempt=%d reason=%x. Giving up.",
3558 fcftab->TID,
3559 emlxs_fc_fcftab_state_xlate(fcftab->state),
3560 emlxs_fcf_event_xlate(evt), arg1,
3561 fcftab->attempts,
3562 fcftab->reason);
3563
3564 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK_CMPL,
3565 FCF_REASON_OP_FAILED, fcftab->attempts, arg1);
3566
3567 } else {
3568 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3569 "fc_fcftab_cfglink_failed_action:%x %s:%s arg=%p "
3570 "attempt=%d reason=%x. Retrying.",
3571 fcftab->TID,
3572 emlxs_fc_fcftab_state_xlate(fcftab->state),
3573 emlxs_fcf_event_xlate(evt), arg1,
3574 fcftab->attempts,
3575 fcftab->reason);
3576
3577 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK,
3578 FCF_REASON_OP_FAILED, fcftab->attempts, arg1);
3579 }
3580
3581 return (rval);
3582
3583 } /* emlxs_fc_fcftab_cfglink_failed_action() */
3584
3585
3586 /*ARGSUSED*/
3587 static uint32_t
emlxs_fc_fcftab_cfglink_cmpl_action(emlxs_port_t * port,uint32_t evt,void * arg1)3588 emlxs_fc_fcftab_cfglink_cmpl_action(emlxs_port_t *port, uint32_t evt,
3589 void *arg1)
3590 {
3591 emlxs_hba_t *hba = HBA;
3592 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3593 uint32_t rval = 0;
3594
3595 if (fcftab->state != FC_FCFTAB_STATE_CFGLINK_CMPL) {
3596 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
3597 "fc_fcftab_cfglink_cmpl_action:%x %s:%s arg=%p. "
3598 "Invalid state. <",
3599 fcftab->TID,
3600 emlxs_fc_fcftab_state_xlate(fcftab->state),
3601 emlxs_fcf_event_xlate(evt), arg1);
3602 return (1);
3603 }
3604
3605 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3606 "fc_fcftab_cfglink_cmpl_action:%x attempts=%d. "
3607 "Read SPARM.",
3608 fcftab->TID,
3609 fcftab->attempts);
3610
3611 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM,
3612 FCF_REASON_EVENT, evt, arg1);
3613
3614 return (rval);
3615
3616 } /* emlxs_fc_fcftab_cfglink_cmpl_action() */
3617
3618
3619 /*ARGSUSED*/
3620 static uint32_t
emlxs_fc_fcftab_sparm_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)3621 emlxs_fc_fcftab_sparm_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
3622 {
3623 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
3624 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3625 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
3626 MATCHMAP *mp;
3627 emlxs_port_t *vport;
3628 VPIobj_t *vpip;
3629 int32_t i;
3630 uint8_t null_wwn[8];
3631 uint16_t TID;
3632
3633 mutex_enter(&EMLXS_FCF_LOCK);
3634 TID = (uint16_t)((unsigned long)mbq->context);
3635
3636 if (fcftab->state != FC_FCFTAB_STATE_SPARM) {
3637 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3638 "fc_fcftab_sparm_mbcmpl:%x state=%s.",
3639 TID,
3640 emlxs_fc_fcftab_state_xlate(fcftab->state));
3641
3642 mutex_exit(&EMLXS_FCF_LOCK);
3643 return (0);
3644 }
3645
3646 if (TID != fcftab->generation) {
3647 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3648 "fc_fcftab_sparm_mbcmpl:%x %s. "
3649 "Incorrect generation %x. Dropping.",
3650 TID,
3651 emlxs_fc_fcftab_state_xlate(fcftab->state),
3652 fcftab->generation);
3653
3654 mutex_exit(&EMLXS_FCF_LOCK);
3655 return (0);
3656 }
3657
3658 if (mb4->mbxStatus) {
3659 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3660 "fc_fcftab_sparm_mbcmpl:%x failed. %s. >",
3661 fcftab->TID,
3662 emlxs_mb_xlate_status(mb4->mbxStatus));
3663
3664 if (mb4->mbxStatus == MBXERR_NO_RESOURCES) {
3665 (void) emlxs_fc_fcftab_state(port,
3666 FC_FCFTAB_STATE_SPARM_FAILED,
3667 FCF_REASON_MBOX_BUSY, mb4->mbxStatus, 0);
3668 } else {
3669 (void) emlxs_fc_fcftab_state(port,
3670 FC_FCFTAB_STATE_SPARM_FAILED,
3671 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
3672 }
3673
3674 mutex_exit(&EMLXS_FCF_LOCK);
3675 return (0);
3676 }
3677
3678 /* Save the parameters */
3679 mp = (MATCHMAP *)mbq->bp;
3680 bcopy((caddr_t)mp->virt, (caddr_t)&hba->sparam, sizeof (SERV_PARM));
3681
3682 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
3683 "fc_fcftab_sparm_mbcmpl:%x edtov=%x,%x bbc=%x. >",
3684 fcftab->TID,
3685 hba->fc_edtov, hba->sparam.cmn.e_d_tov,
3686 hba->sparam.cmn.bbCreditlsb);
3687
3688 /* Initialize the node name and port name only once */
3689 bzero(null_wwn, 8);
3690 if ((bcmp((caddr_t)&hba->wwnn, (caddr_t)null_wwn, 8) == 0) &&
3691 (bcmp((caddr_t)&hba->wwpn, (caddr_t)null_wwn, 8) == 0)) {
3692 bcopy((caddr_t)&hba->sparam.nodeName,
3693 (caddr_t)&hba->wwnn, sizeof (NAME_TYPE));
3694
3695 bcopy((caddr_t)&hba->sparam.portName,
3696 (caddr_t)&hba->wwpn, sizeof (NAME_TYPE));
3697 } else {
3698 bcopy((caddr_t)&hba->wwnn,
3699 (caddr_t)&hba->sparam.nodeName, sizeof (NAME_TYPE));
3700
3701 bcopy((caddr_t)&hba->wwpn,
3702 (caddr_t)&hba->sparam.portName, sizeof (NAME_TYPE));
3703 }
3704
3705 /* Update all bound ports */
3706 for (i = 0; i < MAX_VPORTS; i++) {
3707 vport = &VPORT(i);
3708 vpip = vport->vpip;
3709
3710 if (!(vport->flag & EMLXS_PORT_BOUND) ||
3711 (vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
3712 continue;
3713 }
3714
3715 bcopy((caddr_t)&hba->sparam,
3716 (caddr_t)&vport->sparam,
3717 sizeof (SERV_PARM));
3718
3719 bcopy((caddr_t)&vport->wwnn,
3720 (caddr_t)&vport->sparam.nodeName,
3721 sizeof (NAME_TYPE));
3722
3723 bcopy((caddr_t)&vport->wwpn,
3724 (caddr_t)&vport->sparam.portName,
3725 sizeof (NAME_TYPE));
3726 }
3727
3728 (void) emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM_CMPL,
3729 0, 0, 0);
3730
3731 mutex_exit(&EMLXS_FCF_LOCK);
3732 return (0);
3733
3734 } /* emlxs_fc_fcftab_sparm_mbcmpl() */
3735
3736
3737 /*ARGSUSED*/
3738 static uint32_t
emlxs_fc_fcftab_sparm_action(emlxs_port_t * port,uint32_t evt,void * arg1)3739 emlxs_fc_fcftab_sparm_action(emlxs_port_t *port, uint32_t evt,
3740 void *arg1)
3741 {
3742 emlxs_hba_t *hba = HBA;
3743 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3744 MAILBOXQ *mbq;
3745 MAILBOX4 *mb4;
3746 uint32_t rval = 0;
3747 MATCHMAP *mp;
3748
3749 if (fcftab->state != FC_FCFTAB_STATE_SPARM) {
3750 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
3751 "fc_fcftab_sparm_action:%x %s:%s arg=%p. "
3752 "Invalid state. <",
3753 fcftab->TID,
3754 emlxs_fc_fcftab_state_xlate(fcftab->state),
3755 emlxs_fcf_event_xlate(evt), arg1);
3756 return (1);
3757 }
3758
3759 if ((fcftab->prev_state != FC_FCFTAB_STATE_SPARM_FAILED) ||
3760 (fcftab->flag & EMLXS_FC_FCFTAB_SPARM_REQ)) {
3761 fcftab->flag &= ~EMLXS_FC_FCFTAB_SPARM_REQ;
3762 fcftab->attempts = 0;
3763 }
3764
3765 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
3766 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3767 "fc_fcftab_read_action:%x %s:%s arg=%p flag=%x. "
3768 "Handling request.",
3769 fcftab->TID,
3770 emlxs_fc_fcftab_state_xlate(fcftab->state),
3771 emlxs_fcf_event_xlate(evt), arg1,
3772 fcftab->flag);
3773
3774 rval = emlxs_fc_fcftab_req_handler(port, arg1);
3775 return (rval);
3776 }
3777
3778 if (fcftab->attempts == 0) {
3779 fcftab->TID = fcftab->generation;
3780 }
3781
3782 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3783 "fc_fcftab_read_action:%x %s:%s arg=%p attempts=%d. "
3784 "Reading SPARM. <",
3785 fcftab->TID,
3786 emlxs_fc_fcftab_state_xlate(fcftab->state),
3787 emlxs_fcf_event_xlate(evt), arg1,
3788 fcftab->attempts);
3789
3790 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
3791 rval = emlxs_fc_fcftab_state(port,
3792 FC_FCFTAB_STATE_SPARM_FAILED,
3793 FCF_REASON_NO_MBOX, 0, arg1);
3794 return (rval);
3795 }
3796 mb4 = (MAILBOX4*)mbq;
3797 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
3798
3799 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
3800 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
3801
3802 rval = emlxs_fc_fcftab_state(port,
3803 FC_FCFTAB_STATE_SPARM_FAILED,
3804 FCF_REASON_NO_BUFFER, 0, arg1);
3805 return (rval);
3806 }
3807 bzero(mp->virt, mp->size);
3808
3809 mbq->nonembed = NULL;
3810 mbq->bp = (void *)mp;
3811 mbq->mbox_cmpl = emlxs_fc_fcftab_sparm_mbcmpl;
3812 mbq->context = (void *)((unsigned long)fcftab->TID);
3813 mbq->port = (void *)port;
3814
3815 mb4->un.varSLIConfig.be.embedded = 0;
3816 mb4->mbxCommand = MBX_READ_SPARM64;
3817 mb4->mbxOwner = OWN_HOST;
3818
3819 mb4->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
3820 mb4->un.varRdSparm.un.sp64.addrHigh = PADDR_HI(mp->phys);
3821 mb4->un.varRdSparm.un.sp64.addrLow = PADDR_LO(mp->phys);
3822
3823 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
3824 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
3825 emlxs_mem_put(hba, MEM_BUF, (void *)mp);
3826 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
3827
3828 rval = emlxs_fc_fcftab_state(port,
3829 FC_FCFTAB_STATE_SPARM_FAILED,
3830 FCF_REASON_SEND_FAILED, rval, arg1);
3831
3832 return (rval);
3833 }
3834
3835 return (0);
3836
3837 } /* emlxs_fc_fcftab_sparm_action() */
3838
3839
3840 /*ARGSUSED*/
3841 static uint32_t
emlxs_fc_fcftab_sparm_failed_action(emlxs_port_t * port,uint32_t evt,void * arg1)3842 emlxs_fc_fcftab_sparm_failed_action(emlxs_port_t *port, uint32_t evt,
3843 void *arg1)
3844 {
3845 emlxs_hba_t *hba = HBA;
3846 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3847 uint32_t rval = 0;
3848
3849 fcftab->attempts++;
3850
3851 if (fcftab->state != FC_FCFTAB_STATE_SPARM_FAILED) {
3852 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
3853 "fc_fcftab_sparm_failed_action:%x %s:%s arg=%p "
3854 "attempt=%d. Invalid state. <",
3855 fcftab->TID,
3856 emlxs_fc_fcftab_state_xlate(fcftab->state),
3857 emlxs_fcf_event_xlate(evt),
3858 arg1, fcftab->attempts);
3859 return (1);
3860 }
3861
3862 if ((fcftab->reason == FCF_REASON_MBOX_FAILED) ||
3863 (fcftab->reason == FCF_REASON_SEND_FAILED) ||
3864 (fcftab->attempts >= 3)) {
3865 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3866 "fc_fcftab_read_failed_action:%x %s:%s arg=%p "
3867 "attempt=%d reason=%x. Giving up.",
3868 fcftab->TID,
3869 emlxs_fc_fcftab_state_xlate(fcftab->state),
3870 emlxs_fcf_event_xlate(evt), arg1,
3871 fcftab->attempts,
3872 fcftab->reason);
3873
3874 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM_CMPL,
3875 FCF_REASON_OP_FAILED, fcftab->attempts, arg1);
3876 } else {
3877 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3878 "fc_fcftab_read_failed_action:%x %s:%s arg=%p "
3879 "attempt=%d reason=%x. Retrying.",
3880 fcftab->TID,
3881 emlxs_fc_fcftab_state_xlate(fcftab->state),
3882 emlxs_fcf_event_xlate(evt), arg1,
3883 fcftab->attempts,
3884 fcftab->reason);
3885
3886 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM,
3887 FCF_REASON_OP_FAILED, fcftab->attempts, arg1);
3888 }
3889
3890 return (rval);
3891
3892 } /* emlxs_fc_fcftab_sparm_failed_action() */
3893
3894
3895 /*ARGSUSED*/
3896 static uint32_t
emlxs_fc_fcftab_sparm_cmpl_action(emlxs_port_t * port,uint32_t evt,void * arg1)3897 emlxs_fc_fcftab_sparm_cmpl_action(emlxs_port_t *port, uint32_t evt,
3898 void *arg1)
3899 {
3900 emlxs_hba_t *hba = HBA;
3901 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3902 uint32_t rval = 0;
3903
3904 if (fcftab->state != FC_FCFTAB_STATE_SPARM_CMPL) {
3905 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
3906 "fc_fcftab_sparm_cmpl_action:%x %s:%s arg=%p. "
3907 "Invalid state. <",
3908 fcftab->TID,
3909 emlxs_fc_fcftab_state_xlate(fcftab->state),
3910 emlxs_fcf_event_xlate(evt), arg1);
3911 return (1);
3912 }
3913
3914 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3915 "fc_fcftab_sparm_cmpl_action:%x attempts=%d. "
3916 "Bring FCFTAB online.",
3917 fcftab->TID,
3918 fcftab->attempts);
3919
3920 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_ONLINE,
3921 FCF_REASON_EVENT, evt, arg1);
3922
3923 return (rval);
3924
3925 } /* emlxs_fc_fcftab_sparm_cmpl_action() */
3926
3927
3928 /*ARGSUSED*/
3929 static void
emlxs_fc_fcftab_process(emlxs_port_t * port)3930 emlxs_fc_fcftab_process(emlxs_port_t *port)
3931 {
3932 emlxs_hba_t *hba = HBA;
3933 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
3934 FCFIobj_t *fcfp;
3935 FCF_RECORD_t fcf_record;
3936 FCF_RECORD_t *fcf_rec;
3937 uint8_t bitmap[512];
3938 uint16_t i;
3939
3940 /* Get the FCFI */
3941 fcfp = fcftab->fcfi[0];
3942
3943 if (!fcfp) {
3944 /* Allocate an fcfi */
3945 fcfp = emlxs_fcfi_alloc(port);
3946 }
3947
3948 if (!fcfp) {
3949 fcftab->fcfi_count = 0;
3950
3951 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3952 "fc_fcftab_process:%x No FCF available.",
3953 fcftab->TID);
3954 return;
3955 }
3956
3957 if (fcfp->flag & EMLXS_FCFI_SELECTED) {
3958 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3959 "fc_fcftab_process:%x fcfi=%d %s. "
3960 "FCF still selected.",
3961 fcftab->TID,
3962 fcfp->fcf_index,
3963 emlxs_fcfi_state_xlate(fcfp->state));
3964 } else {
3965 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
3966 "fc_fcftab_process:%x fcfi=%d %s. "
3967 "New FCF selected.",
3968 fcftab->TID,
3969 fcfp->fcf_index,
3970 emlxs_fcfi_state_xlate(fcfp->state));
3971 }
3972
3973 /* Initalize an fcf_rec */
3974 fcf_rec = &fcf_record;
3975 bzero(fcf_rec, sizeof (FCF_RECORD_t));
3976
3977 fcf_rec->max_recv_size = EMLXS_FCOE_MAX_RCV_SZ;
3978 fcf_rec->fka_adv_period = 0;
3979 fcf_rec->fip_priority = 128;
3980
3981 #ifdef EMLXS_BIG_ENDIAN
3982 fcf_rec->fcf_mac_address_hi[0] = FCOE_FCF_MAC3;
3983 fcf_rec->fcf_mac_address_hi[1] = FCOE_FCF_MAC2;
3984 fcf_rec->fcf_mac_address_hi[2] = FCOE_FCF_MAC1;
3985 fcf_rec->fcf_mac_address_hi[3] = FCOE_FCF_MAC0;
3986 fcf_rec->fcf_mac_address_low[0] = FCOE_FCF_MAC5;
3987 fcf_rec->fcf_mac_address_low[1] = FCOE_FCF_MAC4;
3988 fcf_rec->fc_map[0] = hba->sli.sli4.cfgFCOE.FCMap[2];
3989 fcf_rec->fc_map[1] = hba->sli.sli4.cfgFCOE.FCMap[1];
3990 fcf_rec->fc_map[2] = hba->sli.sli4.cfgFCOE.FCMap[0];
3991 #endif /* EMLXS_BIG_ENDIAN */
3992 #ifdef EMLXS_LITTLE_ENDIAN
3993 fcf_rec->fcf_mac_address_hi[0] = FCOE_FCF_MAC0;
3994 fcf_rec->fcf_mac_address_hi[1] = FCOE_FCF_MAC1;
3995 fcf_rec->fcf_mac_address_hi[2] = FCOE_FCF_MAC2;
3996 fcf_rec->fcf_mac_address_hi[3] = FCOE_FCF_MAC3;
3997 fcf_rec->fcf_mac_address_low[0] = FCOE_FCF_MAC4;
3998 fcf_rec->fcf_mac_address_low[1] = FCOE_FCF_MAC5;
3999 fcf_rec->fc_map[0] = hba->sli.sli4.cfgFCOE.FCMap[0];
4000 fcf_rec->fc_map[1] = hba->sli.sli4.cfgFCOE.FCMap[1];
4001 fcf_rec->fc_map[2] = hba->sli.sli4.cfgFCOE.FCMap[2];
4002 #endif /* EMLXS_LITTLE_ENDIAN */
4003
4004 if (hba->sli.sli4.cfgFCOE.fip_flags & TLV_FCOE_VLAN) {
4005 bzero((void *) bitmap, 512);
4006 i = hba->sli.sli4.cfgFCOE.VLanId;
4007 bitmap[i / 8] = (1 << (i % 8));
4008 BE_SWAP32_BCOPY(bitmap, fcf_rec->vlan_bitmap, 512);
4009 } else {
4010 bzero((void *) bitmap, 512);
4011 bitmap[0] = 1; /* represents bit 0 */
4012 BE_SWAP32_BCOPY(bitmap, fcf_rec->vlan_bitmap, 512);
4013 }
4014
4015 fcf_rec->fcf_valid = 1;
4016 fcf_rec->fcf_available = 1;
4017
4018 /* Update the FCFI */
4019 emlxs_fcfi_update(port, fcfp, fcf_rec, hba->link_event_tag);
4020
4021 /* Select the FCFI */
4022 fcfp->flag &= ~EMLXS_FCFI_FAILED;
4023 fcfp->flag |= EMLXS_FCFI_SELECTED;
4024 fcftab->fcfi[0] = fcfp;
4025 fcftab->fcfi_count = 1;
4026
4027 return;
4028
4029 } /* emlxs_fc_fcftab_process() */
4030
4031
4032 /*ARGSUSED*/
4033 static uint32_t
emlxs_fc_fcftab_fcfi_online_action(emlxs_port_t * port,uint32_t evt,void * arg1)4034 emlxs_fc_fcftab_fcfi_online_action(emlxs_port_t *port, uint32_t evt,
4035 void *arg1)
4036 {
4037 emlxs_hba_t *hba = HBA;
4038 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4039 uint32_t rval = 0;
4040 FCFIobj_t *fcfp;
4041
4042 if (fcftab->state != FC_FCFTAB_STATE_FCFI_ONLINE) {
4043 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4044 "fc_fcftab_fcfi_online_action:%x %s:%s arg=%p. "
4045 "Invalid state. <",
4046 fcftab->TID,
4047 emlxs_fc_fcftab_state_xlate(fcftab->state),
4048 emlxs_fcf_event_xlate(evt), arg1);
4049 return (1);
4050 }
4051
4052 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
4053 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4054 "fc_fcftab_fcfi_online_action:%x flag=%x. "
4055 "Handling request.",
4056 fcftab->TID,
4057 fcftab->flag);
4058
4059 rval = emlxs_fc_fcftab_req_handler(port, arg1);
4060 return (rval);
4061 }
4062
4063 emlxs_fc_fcftab_process(port);
4064
4065 fcfp = fcftab->fcfi[0];
4066 if (!fcfp) {
4067 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4068 "fc_fcftab_fcfi_online_action:%x. "
4069 "No FCF available. Offlining.",
4070 fcftab->TID);
4071
4072 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
4073 fcftab->flag |= EMLXS_FC_FCFTAB_OFFLINE_REQ;
4074 rval = emlxs_fc_fcftab_req_handler(port, arg1);
4075
4076 mutex_exit(&EMLXS_FCF_LOCK);
4077 return (rval);
4078 }
4079
4080 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4081 "fc_fcftab_fcfi_online_action:%x fcfi_count=%d. "
4082 "Onlining FCFI:%d. >",
4083 fcftab->TID,
4084 fcftab->fcfi_count,
4085 fcfp->fcf_index);
4086
4087 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_ONLINE, fcfp);
4088
4089 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_ONLINE_CMPL,
4090 FCF_REASON_EVENT, evt, arg1);
4091
4092 return (rval);
4093
4094 } /* emlxs_fc_fcftab_fcfi_online_action() */
4095
4096
4097 /*ARGSUSED*/
4098 static uint32_t
emlxs_fc_fcftab_fcfi_online_cmpl_action(emlxs_port_t * port,uint32_t evt,void * arg1)4099 emlxs_fc_fcftab_fcfi_online_cmpl_action(emlxs_port_t *port, uint32_t evt,
4100 void *arg1)
4101 {
4102 emlxs_hba_t *hba = HBA;
4103 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4104 uint32_t rval = 0;
4105
4106 if (fcftab->state != FC_FCFTAB_STATE_FCFI_ONLINE_CMPL) {
4107 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4108 "fc_fcftab_fcfi_online_cmpl_action:%x %s:%s arg=%p. "
4109 "Invalid state. <",
4110 fcftab->TID,
4111 emlxs_fc_fcftab_state_xlate(fcftab->state),
4112 emlxs_fcf_event_xlate(evt), arg1);
4113 return (1);
4114 }
4115
4116 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
4117 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4118 "fc_fcftab_fcfi_online_cmpl_action:%x %s:%s arg=%p "
4119 "flag=%x. Handling request.",
4120 fcftab->TID,
4121 emlxs_fc_fcftab_state_xlate(fcftab->state),
4122 emlxs_fcf_event_xlate(evt), arg1,
4123 fcftab->flag);
4124
4125 rval = emlxs_fc_fcftab_req_handler(port, arg1);
4126 return (rval);
4127 }
4128
4129 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4130 "fc_fcftab_fcfi_online_cmpl_action:%x %s:%s arg=%p. "
4131 "Going online.",
4132 fcftab->TID,
4133 emlxs_fc_fcftab_state_xlate(fcftab->state),
4134 emlxs_fcf_event_xlate(evt), arg1);
4135
4136 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_ONLINE,
4137 FCF_REASON_EVENT, evt, arg1);
4138
4139 return (rval);
4140
4141 } /* emlxs_fc_fcftab_fcfi_online_cmpl_action() */
4142
4143
4144 /*ARGSUSED*/
4145 static uint32_t
emlxs_fc_fcftab_fcfi_offline_action(emlxs_port_t * port,uint32_t evt,void * arg1)4146 emlxs_fc_fcftab_fcfi_offline_action(emlxs_port_t *port, uint32_t evt,
4147 void *arg1)
4148 {
4149 emlxs_hba_t *hba = HBA;
4150 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4151 uint32_t rval = 0;
4152 FCFIobj_t *fcfp;
4153
4154 if (fcftab->state != FC_FCFTAB_STATE_FCFI_OFFLINE) {
4155 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4156 "fc_fcftab_fcftab_offline_action:%x %s:%s arg=%p. "
4157 "Invalid state. <",
4158 fcftab->TID,
4159 emlxs_fc_fcftab_state_xlate(fcftab->state),
4160 emlxs_fcf_event_xlate(evt), arg1);
4161 return (1);
4162 }
4163
4164 if (fcftab->fcfi_online) {
4165 fcfp = fcftab->fcfi[0];
4166
4167 if (!(fcfp->flag & EMLXS_FCFI_OFFLINE_REQ)) {
4168 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4169 "fc_fcftab_fcfi_offline_action:%d. "
4170 "Offlining FCFI:%d. >",
4171 fcftab->TID,
4172 fcfp->fcf_index);
4173
4174 rval = emlxs_fcfi_event(port,
4175 FCF_EVENT_FCFI_OFFLINE, fcfp);
4176
4177 return (rval);
4178 }
4179
4180 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4181 "fc_fcftab_fcfi_offline_action:%x fcfi_online=%d. "
4182 "Waiting on FCF. <",
4183 fcftab->TID,
4184 fcftab->fcfi_online);
4185
4186 return (0);
4187 }
4188
4189 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4190 "fc_fcftab_fcfi_offline_action:%x %s:%s arg=%p.",
4191 fcftab->TID,
4192 emlxs_fc_fcftab_state_xlate(fcftab->state),
4193 emlxs_fcf_event_xlate(evt), arg1);
4194
4195 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_OFFLINE_CMPL,
4196 FCF_REASON_EVENT, evt, arg1);
4197
4198 return (rval);
4199
4200 } /* emlxs_fc_fcftab_fcfi_offline_action() */
4201
4202
4203 /*ARGSUSED*/
4204 static uint32_t
emlxs_fc_fcftab_fcfi_offline_cmpl_action(emlxs_port_t * port,uint32_t evt,void * arg1)4205 emlxs_fc_fcftab_fcfi_offline_cmpl_action(emlxs_port_t *port, uint32_t evt,
4206 void *arg1)
4207 {
4208 emlxs_hba_t *hba = HBA;
4209 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4210 uint32_t rval = 0;
4211
4212 if (fcftab->state != FC_FCFTAB_STATE_FCFI_OFFLINE_CMPL) {
4213 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4214 "fc_fcftab_fcftab_offline_cmpl_action:%x %s:%s arg=%p. "
4215 "Invalid state. <",
4216 fcftab->TID,
4217 emlxs_fc_fcftab_state_xlate(fcftab->state),
4218 emlxs_fcf_event_xlate(evt), arg1);
4219 return (1);
4220 }
4221
4222 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
4223 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4224 "fc_fcftab_fcfi_offline_cmpl_action:%x %s:%s arg=%p. "
4225 "Handling request.",
4226 fcftab->TID,
4227 emlxs_fc_fcftab_state_xlate(fcftab->state),
4228 emlxs_fcf_event_xlate(evt), arg1);
4229
4230 rval = emlxs_fc_fcftab_req_handler(port, arg1);
4231 return (rval);
4232 }
4233
4234 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4235 "fc_fcftab_fcftab_offline_cmpl_action:%x %s:%s arg=%p. "
4236 "Returning FCF(s) online.",
4237 fcftab->TID,
4238 emlxs_fc_fcftab_state_xlate(fcftab->state),
4239 emlxs_fcf_event_xlate(evt), arg1);
4240
4241 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_ONLINE,
4242 FCF_REASON_EVENT, evt, arg1);
4243
4244 return (rval);
4245
4246 } /* emlxs_fc_fcftab_fcfi_offline_cmpl_action() */
4247
4248
4249 /*ARGSUSED*/
4250 static uint32_t
emlxs_fc_fcftab_linkup_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)4251 emlxs_fc_fcftab_linkup_evt_action(emlxs_port_t *port, uint32_t evt,
4252 void *arg1)
4253 {
4254 emlxs_hba_t *hba = HBA;
4255 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4256 uint32_t rval = 0;
4257
4258 if (evt != FCF_EVENT_LINKUP) {
4259 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4260 "fc_fcftab_linkup_evt_action:%x %s:%s arg=%p flag=%x. "
4261 "Invalid event type. <",
4262 fcftab->TID,
4263 emlxs_fc_fcftab_state_xlate(fcftab->state),
4264 emlxs_fcf_event_xlate(evt), arg1,
4265 fcftab->flag);
4266 return (1);
4267 }
4268
4269 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4270 "fc_fcftab_linkup_evt_action:%x %s:%s arg=%p gen=%x. Link up.",
4271 fcftab->TID,
4272 emlxs_fc_fcftab_state_xlate(fcftab->state),
4273 emlxs_fcf_event_xlate(evt), arg1,
4274 fcftab->generation);
4275
4276 emlxs_fcf_linkup(port);
4277
4278 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
4279 fcftab->flag |= EMLXS_FC_FCFTAB_TOPO_REQ;
4280 fcftab->generation++;
4281
4282 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4283 "fc_fcftab_linkup_evt_action:%x %s gen=%x. "
4284 "Read topology.",
4285 fcftab->TID,
4286 emlxs_fc_fcftab_state_xlate(fcftab->state),
4287 fcftab->generation);
4288
4289 switch (fcftab->state) {
4290 case FC_FCFTAB_STATE_TOPO:
4291 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO,
4292 FCF_REASON_REENTER, evt, arg1);
4293 break;
4294
4295 default:
4296 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO,
4297 FCF_REASON_EVENT, evt, arg1);
4298 break;
4299 }
4300
4301 return (rval);
4302
4303 } /* emlxs_fc_fcftab_linkup_evt_action() */
4304
4305
4306 /*ARGSUSED*/
4307 static uint32_t
emlxs_fc_fcftab_linkdown_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)4308 emlxs_fc_fcftab_linkdown_evt_action(emlxs_port_t *port, uint32_t evt,
4309 void *arg1)
4310 {
4311 emlxs_hba_t *hba = HBA;
4312 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4313 uint32_t rval = 0;
4314 uint32_t i;
4315 FCFIobj_t *fcfp;
4316
4317 if (evt != FCF_EVENT_LINKDOWN) {
4318 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4319 "fc_fcftab_linkdown_evt_action:%x %s:%s arg=%p flag=%x. "
4320 "Invalid event type. <",
4321 fcftab->TID,
4322 emlxs_fc_fcftab_state_xlate(fcftab->state),
4323 emlxs_fcf_event_xlate(evt), arg1,
4324 fcftab->flag);
4325 return (1);
4326 }
4327
4328 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
4329 fcftab->flag |= EMLXS_FC_FCFTAB_OFFLINE_REQ;
4330
4331 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4332 "fc_fcftab_linkdown_evt_action:%x %s:%s arg=%p flag=%x. Linkdown.",
4333 fcftab->TID,
4334 emlxs_fc_fcftab_state_xlate(fcftab->state),
4335 emlxs_fcf_event_xlate(evt), arg1,
4336 fcftab->flag);
4337
4338 emlxs_fcf_linkdown(port);
4339
4340 /* Pause all active FCFI's */
4341 for (i = 0; i < fcftab->fcfi_count; i++) {
4342 fcfp = fcftab->fcfi[i];
4343
4344 if ((fcfp->state == FCFI_STATE_OFFLINE) ||
4345 (fcfp->state == FCFI_STATE_PAUSED)) {
4346 break;
4347 }
4348
4349 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4350 "fc_fcftab_linkdown_evt_action:%x. "
4351 "Pausing FCFI:%d. >",
4352 fcftab->TID,
4353 fcfp->fcf_index);
4354
4355 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_PAUSE, fcfp);
4356 }
4357
4358 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4359 "fc_fcftab_linkdown_evt_action:%x "
4360 "Going offline.",
4361 fcftab->TID);
4362
4363 switch (fcftab->state) {
4364 case FC_FCFTAB_STATE_OFFLINE:
4365 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_OFFLINE,
4366 FCF_REASON_REENTER, evt, arg1);
4367 break;
4368
4369 default:
4370 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_OFFLINE,
4371 FCF_REASON_EVENT, evt, arg1);
4372 break;
4373 }
4374
4375 return (rval);
4376
4377 } /* emlxs_fc_fcftab_linkdown_evt_action() */
4378
4379
4380 /*ARGSUSED*/
4381 static uint32_t
emlxs_fc_fcftab_fcfi_offline_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)4382 emlxs_fc_fcftab_fcfi_offline_evt_action(emlxs_port_t *port, uint32_t evt,
4383 void *arg1)
4384 {
4385 emlxs_hba_t *hba = HBA;
4386 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4387 uint32_t rval = 0;
4388 FCFIobj_t *fcfp;
4389
4390 if (evt != FCF_EVENT_FCFI_OFFLINE) {
4391 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4392 "fc_fcftab_fcftab_offline_evt_action:%x %s:%s arg=%p "
4393 "flag=%x. Invalid event type. <",
4394 fcftab->TID,
4395 emlxs_fc_fcftab_state_xlate(fcftab->state),
4396 emlxs_fcf_event_xlate(evt), arg1,
4397 fcftab->flag);
4398 return (1);
4399 }
4400
4401 fcfp = (FCFIobj_t *)arg1;
4402
4403 switch (fcftab->state) {
4404 case FC_FCFTAB_STATE_SHUTDOWN:
4405 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4406 "fc_fcftab_fcfi_offline_evt_action:%x fcfi:%d. "
4407 "Shutting down.",
4408 fcftab->TID,
4409 fcfp->fcf_index);
4410
4411 /* This will trigger final shutdown */
4412 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SHUTDOWN,
4413 FCF_REASON_REENTER, evt, arg1);
4414 break;
4415
4416 case FC_FCFTAB_STATE_FCFI_OFFLINE:
4417 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4418 "fc_fcftab_fcfi_offline_evt_action:%x fcfi:%d. Offlining.",
4419 fcftab->TID,
4420 fcfp->fcf_index);
4421
4422 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_OFFLINE,
4423 FCF_REASON_REENTER, evt, arg1);
4424 break;
4425
4426 case FC_FCFTAB_STATE_FCFI_ONLINE:
4427 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4428 "fc_fcftab_fcfi_offline_evt_action:%x fcfi:%d. "
4429 "Retrying FCF.",
4430 fcftab->TID,
4431 fcfp->fcf_index);
4432
4433 fcfp->flag |= EMLXS_FCFI_FAILED;
4434
4435 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_ONLINE,
4436 FCF_REASON_REENTER, evt, arg1);
4437 break;
4438
4439 case FC_FCFTAB_STATE_ONLINE:
4440 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4441 "fc_fcftab_fcfi_offline_evt_action:%x fcfi:%d.",
4442 fcftab->TID,
4443 fcfp->fcf_index);
4444
4445 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_ONLINE,
4446 FCF_REASON_REENTER, evt, arg1);
4447 break;
4448
4449 default:
4450 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4451 "fc_fcftab_fcfi_offline_evt_action:%x %s fcfi:%d.",
4452 fcftab->TID,
4453 emlxs_fc_fcftab_state_xlate(fcftab->state),
4454 fcfp->fcf_index);
4455 break;
4456 }
4457
4458 return (rval);
4459
4460 } /* emlxs_fc_fcftab_fcfi_offline_evt_action() */
4461
4462
4463 /*ARGSUSED*/
4464 static uint32_t
emlxs_fc_fcftab_fcfi_online_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)4465 emlxs_fc_fcftab_fcfi_online_evt_action(emlxs_port_t *port, uint32_t evt,
4466 void *arg1)
4467 {
4468 emlxs_hba_t *hba = HBA;
4469 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4470 uint32_t rval = 0;
4471 FCFIobj_t *fcfp;
4472
4473 if (evt != FCF_EVENT_FCFI_ONLINE) {
4474 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4475 "fc_fcftab_fcftab_online_evt_action:%x %s:%s arg=%p "
4476 "flag=%x. Invalid event type. <",
4477 fcftab->TID,
4478 emlxs_fc_fcftab_state_xlate(fcftab->state),
4479 emlxs_fcf_event_xlate(evt), arg1,
4480 fcftab->flag);
4481 return (1);
4482 }
4483
4484 fcfp = (FCFIobj_t *)arg1;
4485
4486 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4487 "fc_fcftab_fcfi_online_evt_action:%d fcfi:%d. <",
4488 fcftab->TID,
4489 fcfp->fcf_index);
4490
4491 return (rval);
4492
4493 } /* emlxs_fc_fcftab_fcfi_online_evt_action() */
4494
4495
4496 /*ARGSUSED*/
4497 static uint32_t
emlxs_fc_fcftab_shutdown_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)4498 emlxs_fc_fcftab_shutdown_evt_action(emlxs_port_t *port, uint32_t evt,
4499 void *arg1)
4500 {
4501 emlxs_hba_t *hba = HBA;
4502 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4503 uint32_t rval = 0;
4504
4505 if (evt != FCF_EVENT_SHUTDOWN) {
4506 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4507 "fc_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. "
4508 "Invalid event type. <",
4509 fcftab->TID,
4510 emlxs_fc_fcftab_state_xlate(fcftab->state),
4511 emlxs_fcf_event_xlate(evt), arg1,
4512 fcftab->flag);
4513 return (1);
4514 }
4515
4516 if (fcftab->flag & EMLXS_FCFTAB_SHUTDOWN) {
4517 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4518 "fc_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. "
4519 "Already shut down. <",
4520 fcftab->TID,
4521 emlxs_fc_fcftab_state_xlate(fcftab->state),
4522 emlxs_fcf_event_xlate(evt), arg1,
4523 fcftab->flag);
4524 return (1);
4525 }
4526
4527 if (fcftab->state == FC_FCFTAB_STATE_SHUTDOWN) {
4528 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4529 "fc_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. "
4530 "Already shutting down. <",
4531 fcftab->TID,
4532 emlxs_fc_fcftab_state_xlate(fcftab->state),
4533 emlxs_fcf_event_xlate(evt), arg1,
4534 fcftab->flag);
4535 return (1);
4536 }
4537
4538 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4539 "fc_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. "
4540 "Shutting down.",
4541 fcftab->TID,
4542 emlxs_fc_fcftab_state_xlate(fcftab->state),
4543 emlxs_fcf_event_xlate(evt), arg1,
4544 fcftab->flag);
4545
4546 emlxs_fcf_linkdown(port);
4547
4548 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SHUTDOWN,
4549 FCF_REASON_EVENT, evt, arg1);
4550
4551 return (rval);
4552
4553 } /* emlxs_fc_fcftab_shutdown_evt_action() */
4554
4555
4556 static uint32_t
emlxs_fc_fcftab_req_handler(emlxs_port_t * port,void * arg1)4557 emlxs_fc_fcftab_req_handler(emlxs_port_t *port, void *arg1)
4558 {
4559 emlxs_hba_t *hba = HBA;
4560 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4561 uint32_t rval = 0;
4562
4563 if (!(fcftab->flag & EMLXS_FCFTAB_REQ_MASK)) {
4564 return (1);
4565 }
4566
4567 if (fcftab->flag & EMLXS_FC_FCFTAB_OFFLINE_REQ) {
4568 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_OFFLINE,
4569 FCF_REASON_REQUESTED, 0, arg1);
4570 }
4571
4572 else if (fcftab->flag & EMLXS_FC_FCFTAB_TOPO_REQ) {
4573 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO,
4574 FCF_REASON_REQUESTED, 0, arg1);
4575 }
4576
4577 else if (fcftab->flag & EMLXS_FC_FCFTAB_CFGLINK_REQ) {
4578 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK,
4579 FCF_REASON_REQUESTED, 0, arg1);
4580 }
4581
4582 else if (fcftab->flag & EMLXS_FC_FCFTAB_SPARM_REQ) {
4583 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM,
4584 FCF_REASON_REQUESTED, 0, arg1);
4585 }
4586
4587 return (rval);
4588
4589 } /* emlxs_fc_fcftab_req_handler() */
4590
4591
4592
4593 /* ************************************************************************** */
4594 /* FCOE FCFTAB */
4595 /* ************************************************************************** */
4596
4597 static char *
emlxs_fcoe_fcftab_state_xlate(uint32_t state)4598 emlxs_fcoe_fcftab_state_xlate(uint32_t state)
4599 {
4600 static char buffer[32];
4601 uint32_t i;
4602 uint32_t count;
4603
4604 count = sizeof (emlxs_fcoe_fcftab_state_table) / sizeof (emlxs_table_t);
4605 for (i = 0; i < count; i++) {
4606 if (state == emlxs_fcoe_fcftab_state_table[i].code) {
4607 return (emlxs_fcoe_fcftab_state_table[i].string);
4608 }
4609 }
4610
4611 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state);
4612 return (buffer);
4613
4614 } /* emlxs_fcoe_fcftab_state_xlate() */
4615
4616
4617 static uint32_t
emlxs_fcoe_fcftab_action(emlxs_port_t * port,uint32_t evt,void * arg1)4618 emlxs_fcoe_fcftab_action(emlxs_port_t *port, uint32_t evt,
4619 void *arg1)
4620 {
4621 emlxs_hba_t *hba = HBA;
4622 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4623 uint32_t rval = 0;
4624 uint32_t(*func) (emlxs_port_t *, uint32_t, void *);
4625 uint32_t index;
4626 uint32_t events;
4627 uint16_t state;
4628
4629 /* Convert event to action table index */
4630 switch (evt) {
4631 case FCF_EVENT_STATE_ENTER:
4632 index = 0;
4633 break;
4634 case FCF_EVENT_SHUTDOWN:
4635 index = 1;
4636 break;
4637 case FCF_EVENT_LINKUP:
4638 index = 2;
4639 break;
4640 case FCF_EVENT_LINKDOWN:
4641 index = 3;
4642 break;
4643 case FCF_EVENT_CVL:
4644 index = 4;
4645 break;
4646 case FCF_EVENT_FCF_FOUND:
4647 index = 5;
4648 break;
4649 case FCF_EVENT_FCF_LOST:
4650 index = 6;
4651 break;
4652 case FCF_EVENT_FCF_CHANGED:
4653 index = 7;
4654 break;
4655 case FCF_EVENT_FCFTAB_FULL:
4656 index = 8;
4657 break;
4658 case FCF_EVENT_FCFI_ONLINE:
4659 index = 9;
4660 break;
4661 case FCF_EVENT_FCFI_OFFLINE:
4662 index = 10;
4663 break;
4664 default:
4665 return (1);
4666 }
4667
4668 events = FCOE_FCFTAB_ACTION_EVENTS;
4669 state = fcftab->state;
4670
4671 index += (state * events);
4672 func = (uint32_t(*) (emlxs_port_t *, uint32_t, void *))
4673 emlxs_fcoe_fcftab_action_table[index];
4674
4675 if (!func) {
4676 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
4677 "fcoe_fcftab_action:%x %s:%s arg=%p. No action. <",
4678 fcftab->TID,
4679 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4680 emlxs_fcf_event_xlate(evt), arg1);
4681
4682 return (1);
4683 }
4684
4685 rval = (func)(port, evt, arg1);
4686
4687 return (rval);
4688
4689 } /* emlxs_fcoe_fcftab_action() */
4690
4691
4692 static uint32_t
emlxs_fcoe_fcftab_event(emlxs_port_t * port,uint32_t evt,void * arg1)4693 emlxs_fcoe_fcftab_event(emlxs_port_t *port, uint32_t evt,
4694 void *arg1)
4695 {
4696 emlxs_hba_t *hba = HBA;
4697 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4698 uint32_t rval = 0;
4699
4700 /* Filter events */
4701 switch (evt) {
4702 case FCF_EVENT_SHUTDOWN:
4703 case FCF_EVENT_LINKUP:
4704 case FCF_EVENT_LINKDOWN:
4705 case FCF_EVENT_CVL:
4706 case FCF_EVENT_FCF_FOUND:
4707 case FCF_EVENT_FCF_LOST:
4708 case FCF_EVENT_FCF_CHANGED:
4709 case FCF_EVENT_FCFTAB_FULL:
4710 case FCF_EVENT_FCFI_OFFLINE:
4711 case FCF_EVENT_FCFI_ONLINE:
4712 break;
4713
4714 default:
4715 return (1);
4716 }
4717
4718 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
4719 "fcoe_fcftab_event:%x %s:%s arg=%p.",
4720 fcftab->TID,
4721 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4722 emlxs_fcf_event_xlate(evt), arg1);
4723
4724 rval = emlxs_fcoe_fcftab_action(port, evt, arg1);
4725
4726 return (rval);
4727
4728 } /* emlxs_fcoe_fcftab_event() */
4729
4730
4731 /* EMLXS_FCF_LOCK must be held to enter */
4732 /*ARGSUSED*/
4733 static uint32_t
emlxs_fcoe_fcftab_state(emlxs_port_t * port,uint16_t state,uint16_t reason,uint32_t explain,void * arg1)4734 emlxs_fcoe_fcftab_state(emlxs_port_t *port, uint16_t state, uint16_t reason,
4735 uint32_t explain, void *arg1)
4736 {
4737 emlxs_hba_t *hba = HBA;
4738 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4739 uint32_t rval = 0;
4740
4741 if (state >= FCOE_FCFTAB_ACTION_STATES) {
4742 return (1);
4743 }
4744
4745 if ((fcftab->state == state) &&
4746 (reason != FCF_REASON_REENTER)) {
4747 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4748 "fcftab_state:%x %s:%s:0x%x arg=%p. "
4749 "State not changed. <",
4750 fcftab->TID,
4751 emlxs_fcoe_fcftab_state_xlate(state),
4752 emlxs_fcf_reason_xlate(reason),
4753 explain, arg1);
4754 return (1);
4755 }
4756
4757 if (!reason) {
4758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
4759 "fcftab_state:%x %s-->%s arg=%p",
4760 fcftab->TID,
4761 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4762 emlxs_fcoe_fcftab_state_xlate(state), arg1);
4763 } else if (reason == FCF_REASON_EVENT) {
4764 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
4765 "fcftab_state:%x %s-->%s:%s:%s arg=%p",
4766 fcftab->TID,
4767 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4768 emlxs_fcoe_fcftab_state_xlate(state),
4769 emlxs_fcf_reason_xlate(reason),
4770 emlxs_fcf_event_xlate(explain), arg1);
4771 } else if (explain) {
4772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
4773 "fcftab_state:%x %s-->%s:%s:0x%x arg=%p",
4774 fcftab->TID,
4775 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4776 emlxs_fcoe_fcftab_state_xlate(state),
4777 emlxs_fcf_reason_xlate(reason),
4778 explain, arg1);
4779 } else {
4780 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
4781 "fcftab_state:%x %s-->%s:%s arg=%p",
4782 fcftab->TID,
4783 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4784 emlxs_fcoe_fcftab_state_xlate(state),
4785 emlxs_fcf_reason_xlate(reason), arg1);
4786 }
4787
4788 fcftab->prev_state = fcftab->state;
4789 fcftab->prev_reason = fcftab->reason;
4790 fcftab->state = state;
4791 fcftab->reason = reason;
4792
4793 rval = emlxs_fcoe_fcftab_action(port, FCF_EVENT_STATE_ENTER, arg1);
4794
4795 return (rval);
4796
4797 } /* emlxs_fcoe_fcftab_state() */
4798
4799
4800 /*ARGSUSED*/
4801 static uint32_t
emlxs_fcoe_fcftab_fcfi_offline_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)4802 emlxs_fcoe_fcftab_fcfi_offline_evt_action(emlxs_port_t *port, uint32_t evt,
4803 void *arg1)
4804 {
4805 emlxs_hba_t *hba = HBA;
4806 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4807 uint32_t rval = 0;
4808 FCFIobj_t *fcfp;
4809
4810 if (evt != FCF_EVENT_FCFI_OFFLINE) {
4811 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4812 "fcoe_fcftab_fcfi_offline_evt_action:%x %s:%s arg=%p "
4813 "flag=%x. Invalid event type. <",
4814 fcftab->TID,
4815 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4816 emlxs_fcf_event_xlate(evt), arg1,
4817 fcftab->flag);
4818 return (1);
4819 }
4820
4821 fcfp = (FCFIobj_t *)arg1;
4822
4823 switch (fcftab->state) {
4824 case FCOE_FCFTAB_STATE_SHUTDOWN:
4825 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4826 "fcoe_fcftab_fcfi_offline_evt_action:%x fcfi:%d. "
4827 "Shutting down.",
4828 fcftab->TID,
4829 fcfp->fcf_index);
4830
4831 /* This will trigger final shutdown */
4832 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SHUTDOWN,
4833 FCF_REASON_REENTER, evt, arg1);
4834 break;
4835
4836 case FCOE_FCFTAB_STATE_FCFI_OFFLINE:
4837 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4838 "fcoe_fcftab_fcfi_offline_evt_action:%x fcfi:%d. "
4839 "Offlining.",
4840 fcftab->TID,
4841 fcfp->fcf_index);
4842
4843 rval = emlxs_fcoe_fcftab_state(port,
4844 FCOE_FCFTAB_STATE_FCFI_OFFLINE,
4845 FCF_REASON_REENTER, evt, arg1);
4846 break;
4847
4848 case FCOE_FCFTAB_STATE_FCFI_ONLINE:
4849 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4850 "fcoe_fcftab_fcfi_offline_evt_action:%x fcfi:%d. "
4851 "Attempting failover.",
4852 fcftab->TID,
4853 fcfp->fcf_index);
4854
4855 fcfp->flag |= EMLXS_FCFI_FAILED;
4856
4857 rval = emlxs_fcoe_fcftab_state(port,
4858 FCOE_FCFTAB_STATE_FCFI_ONLINE,
4859 FCF_REASON_REENTER, evt, arg1);
4860 break;
4861
4862 case FCOE_FCFTAB_STATE_ONLINE:
4863 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4864 "fcoe_fcftab_fcfi_offline_evt_action:%x fcfi:%d.",
4865 fcftab->TID,
4866 fcfp->fcf_index);
4867
4868 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_ONLINE,
4869 FCF_REASON_REENTER, evt, arg1);
4870 break;
4871
4872 default:
4873 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4874 "fcoe_fcftab_fcfi_offline_evt_action:%x %s fcfi:%d.",
4875 fcftab->TID,
4876 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4877 fcfp->fcf_index);
4878 break;
4879 }
4880
4881 return (rval);
4882
4883 } /* emlxs_fcoe_fcftab_fcfi_offline_evt_action() */
4884
4885
4886 /*ARGSUSED*/
4887 static uint32_t
emlxs_fcoe_fcftab_fcfi_online_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)4888 emlxs_fcoe_fcftab_fcfi_online_evt_action(emlxs_port_t *port, uint32_t evt,
4889 void *arg1)
4890 {
4891 emlxs_hba_t *hba = HBA;
4892 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4893 uint32_t rval = 0;
4894 FCFIobj_t *fcfp;
4895
4896 if (evt != FCF_EVENT_FCFI_ONLINE) {
4897 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4898 "fcoe_fcftab_fcfi_online_evt_action:%x %s:%s arg=%p "
4899 "flag=%x. Invalid event type. <",
4900 fcftab->TID,
4901 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4902 emlxs_fcf_event_xlate(evt), arg1,
4903 fcftab->flag);
4904 return (1);
4905 }
4906
4907 fcfp = (FCFIobj_t *)arg1;
4908
4909 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4910 "fcoe_fcftab_fcfi_online_evt_action:%x fcfi:%d. <",
4911 fcftab->TID,
4912 fcfp->fcf_index);
4913
4914 return (rval);
4915
4916 } /* emlxs_fcoe_fcftab_fcfi_online_evt_action() */
4917
4918
4919 /*ARGSUSED*/
4920 static uint32_t
emlxs_fcoe_fcftab_cvl_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)4921 emlxs_fcoe_fcftab_cvl_evt_action(emlxs_port_t *port, uint32_t evt,
4922 void *arg1)
4923 {
4924 emlxs_hba_t *hba = HBA;
4925 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4926 uint32_t rval = 0;
4927 emlxs_port_t *vport;
4928 uint32_t vpi;
4929 VPIobj_t *vpip;
4930
4931 if (evt != FCF_EVENT_CVL) {
4932 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4933 "fcoe_fcftab_cvl_evt_action:%x %s:%s arg=%p flag=%x. "
4934 "Invalid event type. <",
4935 fcftab->TID,
4936 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4937 emlxs_fcf_event_xlate(evt), arg1,
4938 fcftab->flag);
4939 return (1);
4940 }
4941
4942 /* Pause VPI */
4943 vpi = (uint32_t)((unsigned long)arg1);
4944 vport = &VPORT(vpi);
4945 vpip = vport->vpip;
4946
4947 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4948 "fcoe_fcftab_cvl_evt_action:%x %s gen=%x. Pausing VPI:%d. >",
4949 fcftab->TID,
4950 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4951 fcftab->generation,
4952 vpip->VPI);
4953
4954 rval = emlxs_vpi_event(vport, FCF_EVENT_VPI_PAUSE, vpip);
4955
4956 switch (fcftab->state) {
4957 case FCOE_FCFTAB_STATE_SOLICIT:
4958 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4959 "fcoe_fcftab_cvl_evt_action:%x %s gen=%x. "
4960 "Already soliciting. <",
4961 fcftab->TID,
4962 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4963 fcftab->generation);
4964 break;
4965
4966 default:
4967 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
4968 fcftab->flag |= EMLXS_FCOE_FCFTAB_SOL_REQ;
4969 fcftab->generation++;
4970
4971 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
4972 "fcoe_fcftab_cvl_evt_action:%x %s gen=%x. Soliciting.",
4973 fcftab->TID,
4974 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
4975 fcftab->generation);
4976
4977 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT,
4978 FCF_REASON_EVENT, evt, arg1);
4979 break;
4980 }
4981
4982 return (rval);
4983
4984 } /* emlxs_fcoe_fcftab_cvl_evt_action() */
4985
4986
4987 /*ARGSUSED*/
4988 static uint32_t
emlxs_fcoe_fcftab_linkup_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)4989 emlxs_fcoe_fcftab_linkup_evt_action(emlxs_port_t *port, uint32_t evt,
4990 void *arg1)
4991 {
4992 emlxs_hba_t *hba = HBA;
4993 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
4994 uint32_t rval = 0;
4995
4996 if (evt != FCF_EVENT_LINKUP) {
4997 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
4998 "fcoe_fcftab_linkup_evt_action:%x %s:%s arg=%p flag=%x. "
4999 "Invalid event type. <",
5000 fcftab->TID,
5001 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5002 emlxs_fcf_event_xlate(evt), arg1,
5003 fcftab->flag);
5004 return (1);
5005 }
5006
5007 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5008 "fcoe_fcftab_linkup_evt_action:%x %s:%s arg=%p gen=%x. Link up.",
5009 fcftab->TID,
5010 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5011 emlxs_fcf_event_xlate(evt), arg1,
5012 fcftab->generation);
5013
5014 emlxs_fcf_linkup(port);
5015
5016 switch (fcftab->state) {
5017 case FCOE_FCFTAB_STATE_SOLICIT:
5018 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5019 "fcoe_fcftab_linkup_evt_action:%x %s gen=%x. "
5020 "Already soliciting. <",
5021 fcftab->TID,
5022 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5023 fcftab->generation);
5024 break;
5025
5026 default:
5027 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
5028 fcftab->flag |= EMLXS_FCOE_FCFTAB_SOL_REQ;
5029 fcftab->generation++;
5030
5031 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5032 "fcoe_fcftab_linkup_evt_action:%x %s gen=%x. Soliciting.",
5033 fcftab->TID,
5034 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5035 fcftab->generation);
5036
5037 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT,
5038 FCF_REASON_EVENT, evt, arg1);
5039 break;
5040 }
5041
5042 return (rval);
5043
5044 } /* emlxs_fcoe_fcftab_linkup_evt_action() */
5045
5046
5047 /*ARGSUSED*/
5048 static uint32_t
emlxs_fcoe_fcftab_linkdown_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)5049 emlxs_fcoe_fcftab_linkdown_evt_action(emlxs_port_t *port, uint32_t evt,
5050 void *arg1)
5051 {
5052 emlxs_hba_t *hba = HBA;
5053 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5054 uint32_t rval = 0;
5055 int32_t i;
5056 FCFIobj_t *fcfp;
5057
5058 if (evt != FCF_EVENT_LINKDOWN) {
5059 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
5060 "fcoe_fcftab_linkdown_evt_action:%x %s:%s arg=%p "
5061 "flag=%x. Invalid event type. <",
5062 fcftab->TID,
5063 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5064 emlxs_fcf_event_xlate(evt), arg1,
5065 fcftab->flag);
5066 return (1);
5067 }
5068
5069 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
5070 fcftab->flag |= EMLXS_FCOE_FCFTAB_OFFLINE_REQ;
5071
5072 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5073 "fcoe_fcftab_linkdown_evt_action:%x %s:%s arg=%p flag=%x. "
5074 "Linkdown.",
5075 fcftab->TID,
5076 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5077 emlxs_fcf_event_xlate(evt), arg1,
5078 fcftab->flag);
5079
5080 emlxs_fcf_linkdown(port);
5081
5082 /* Pause all active FCFI's */
5083 for (i = 0; i < fcftab->fcfi_count; i++) {
5084 fcfp = fcftab->fcfi[i];
5085
5086 if ((fcfp->state == FCFI_STATE_OFFLINE) ||
5087 (fcfp->state == FCFI_STATE_PAUSED)) {
5088 break;
5089 }
5090
5091 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5092 "fcoe_fcftab_linkdown_evt_action:%x Pausing FCFI:%d. >",
5093 fcftab->TID,
5094 fcfp->fcf_index);
5095
5096 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_PAUSE, fcfp);
5097 }
5098
5099 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5100 "fcoe_fcftab_linkdown_evt_action:%x "
5101 "Going offline.",
5102 fcftab->TID);
5103
5104 switch (fcftab->state) {
5105 case FCOE_FCFTAB_STATE_OFFLINE:
5106 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_OFFLINE,
5107 FCF_REASON_REENTER, evt, arg1);
5108 break;
5109
5110 default:
5111 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_OFFLINE,
5112 FCF_REASON_EVENT, evt, arg1);
5113 break;
5114 }
5115
5116 return (rval);
5117
5118 } /* emlxs_fcoe_fcftab_linkdown_evt_action() */
5119
5120
5121 /*ARGSUSED*/
5122 static uint32_t
emlxs_fcoe_fcftab_shutdown_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)5123 emlxs_fcoe_fcftab_shutdown_evt_action(emlxs_port_t *port, uint32_t evt,
5124 void *arg1)
5125 {
5126 emlxs_hba_t *hba = HBA;
5127 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5128 uint32_t rval = 0;
5129
5130 if (evt != FCF_EVENT_SHUTDOWN) {
5131 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
5132 "fcoe_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. "
5133 "Invalid event type. <",
5134 fcftab->TID,
5135 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5136 emlxs_fcf_event_xlate(evt), arg1,
5137 fcftab->flag);
5138 return (1);
5139 }
5140
5141 if (fcftab->flag & EMLXS_FCFTAB_SHUTDOWN) {
5142 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5143 "fcoe_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. "
5144 "Already shut down. <",
5145 fcftab->TID,
5146 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5147 emlxs_fcf_event_xlate(evt), arg1,
5148 fcftab->flag);
5149 return (1);
5150 }
5151
5152 if (fcftab->state == FCOE_FCFTAB_STATE_SHUTDOWN) {
5153 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5154 "fcoe_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. "
5155 "Already shutting down. <",
5156 fcftab->TID,
5157 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5158 emlxs_fcf_event_xlate(evt), arg1,
5159 fcftab->flag);
5160 return (1);
5161 }
5162
5163 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5164 "fcoe_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. "
5165 "Shutting down.",
5166 fcftab->TID,
5167 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5168 emlxs_fcf_event_xlate(evt), arg1,
5169 fcftab->flag);
5170
5171 emlxs_fcf_linkdown(port);
5172
5173 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SHUTDOWN,
5174 FCF_REASON_EVENT, evt, arg1);
5175
5176 return (rval);
5177
5178 } /* emlxs_fcoe_fcftab_shutdown_evt_action() */
5179
5180
5181 static uint32_t
emlxs_fcoe_fcftab_req_handler(emlxs_port_t * port,void * arg1)5182 emlxs_fcoe_fcftab_req_handler(emlxs_port_t *port, void *arg1)
5183 {
5184 emlxs_hba_t *hba = HBA;
5185 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5186 uint32_t rval = 0;
5187
5188 if (!(fcftab->flag & EMLXS_FCFTAB_REQ_MASK)) {
5189 return (1);
5190 }
5191
5192 if (fcftab->flag & EMLXS_FCOE_FCFTAB_OFFLINE_REQ) {
5193 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_OFFLINE,
5194 FCF_REASON_REQUESTED, 0, arg1);
5195 }
5196
5197 else if (fcftab->flag & EMLXS_FCOE_FCFTAB_SOL_REQ) {
5198 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT,
5199 FCF_REASON_REQUESTED, 0, arg1);
5200 }
5201
5202 else if (fcftab->flag & EMLXS_FCOE_FCFTAB_READ_REQ) {
5203 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_READ,
5204 FCF_REASON_REQUESTED, 0, FCFTAB_READ_ALL);
5205 }
5206
5207 return (rval);
5208
5209 } /* emlxs_fcoe_fcftab_req_handler() */
5210
5211
5212 static void
emlxs_fcoe_fcftab_read_timer(emlxs_hba_t * hba)5213 emlxs_fcoe_fcftab_read_timer(emlxs_hba_t *hba)
5214 {
5215 emlxs_port_t *port = &PPORT;
5216 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5217
5218 /* Check FCF timer */
5219 if (!fcftab->read_timer ||
5220 (hba->timer_tics < fcftab->read_timer)) {
5221 return;
5222 }
5223 fcftab->read_timer = 0;
5224 fcftab->flag |= EMLXS_FCOE_FCFTAB_READ_REQ;
5225
5226 switch (fcftab->state) {
5227 case FCOE_FCFTAB_STATE_SOLICIT_CMPL:
5228 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5229 "fcoe_fcftab_timer:%x %s >",
5230 fcftab->TID,
5231 emlxs_fcoe_fcftab_state_xlate(fcftab->state));
5232
5233 (void) emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_READ,
5234 0, 0, FCFTAB_READ_ALL);
5235 break;
5236
5237 default:
5238 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5239 "fcoe_fcftab_timer:%x %s",
5240 fcftab->TID,
5241 emlxs_fcoe_fcftab_state_xlate(fcftab->state));
5242 break;
5243 }
5244
5245 return;
5246
5247 } /* emlxs_fcoe_fcftab_read_timer() */
5248
5249
5250 static void
emlxs_fcoe_fcftab_sol_timer(emlxs_hba_t * hba)5251 emlxs_fcoe_fcftab_sol_timer(emlxs_hba_t *hba)
5252 {
5253 emlxs_port_t *port = &PPORT;
5254 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5255
5256 /* Check FCF timer */
5257 if (!fcftab->sol_timer ||
5258 (hba->timer_tics < fcftab->sol_timer)) {
5259 return;
5260 }
5261 fcftab->sol_timer = 0;
5262
5263 switch (fcftab->state) {
5264 case FCOE_FCFTAB_STATE_ONLINE:
5265 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
5266 fcftab->flag |= EMLXS_FCOE_FCFTAB_SOL_REQ;
5267 fcftab->generation++;
5268
5269 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5270 "fcoe_fcftab_sol_timer:%x %s gen=%x. Soliciting. >",
5271 fcftab->TID,
5272 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5273 fcftab->generation);
5274
5275 (void) emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT,
5276 FCF_REASON_EVENT, 0, 0);
5277 break;
5278
5279 default:
5280 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5281 "fcoe_fcftab_sol_timer:%x %s",
5282 fcftab->TID,
5283 emlxs_fcoe_fcftab_state_xlate(fcftab->state));
5284 break;
5285 }
5286
5287 return;
5288
5289 } /* emlxs_fcoe_fcftab_sol_timer() */
5290
5291
5292 static void
emlxs_fcoe_fcftab_offline_timer(emlxs_hba_t * hba)5293 emlxs_fcoe_fcftab_offline_timer(emlxs_hba_t *hba)
5294 {
5295 emlxs_port_t *port = &PPORT;
5296 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5297 uint32_t i;
5298 FCFIobj_t *fcfp;
5299
5300 for (i = 0; i < fcftab->fcfi_count; i++) {
5301 fcfp = fcftab->fcfi[i];
5302
5303 /* Check offline timer */
5304 if (!fcfp->offline_timer ||
5305 (hba->timer_tics < fcfp->offline_timer)) {
5306 continue;
5307 }
5308 fcfp->offline_timer = 0;
5309
5310 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5311 "fcoe_fcftab_offline_timer:%x. Offlining FCFI:%d. >",
5312 fcftab->TID,
5313 fcfp->fcf_index);
5314
5315 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_OFFLINE, fcfp);
5316 }
5317
5318 return;
5319
5320 } /* emlxs_fcoe_fcftab_offline_timer() */
5321
5322
5323 /*ARGSUSED*/
5324 static uint32_t
emlxs_fcoe_fcftab_sol_failed_action(emlxs_port_t * port,uint32_t evt,void * arg1)5325 emlxs_fcoe_fcftab_sol_failed_action(emlxs_port_t *port, uint32_t evt,
5326 void *arg1)
5327 {
5328 emlxs_hba_t *hba = HBA;
5329 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5330 uint32_t rval = 0;
5331
5332 fcftab->attempts++;
5333
5334 if (fcftab->state != FCOE_FCFTAB_STATE_SOLICIT_FAILED) {
5335 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
5336 "fcoe_fcftab_sol_failed_action:%x %s:%s arg=%p "
5337 "attempt=%d. Invalid state. <",
5338 fcftab->TID,
5339 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5340 emlxs_fcf_event_xlate(evt),
5341 arg1, fcftab->attempts);
5342 return (1);
5343 }
5344
5345 if ((fcftab->reason == FCF_REASON_MBOX_FAILED) ||
5346 (fcftab->reason == FCF_REASON_SEND_FAILED) ||
5347 (fcftab->attempts >= 3)) {
5348 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5349 "fcoe_fcftab_sol_failed_action:%x %s:%s arg=%p "
5350 "attempt=%d reason=%x. Giving up.",
5351 fcftab->TID,
5352 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5353 emlxs_fcf_event_xlate(evt), arg1,
5354 fcftab->attempts,
5355 fcftab->reason);
5356
5357 rval = emlxs_fcoe_fcftab_state(port,
5358 FCOE_FCFTAB_STATE_SOLICIT_CMPL,
5359 FCF_REASON_OP_FAILED, 0, arg1);
5360 } else {
5361 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5362 "fcoe_fcftab_sol_failed_action:%x %s:%s arg=%p "
5363 "attempt=%d reason=%x. Retrying.",
5364 fcftab->TID,
5365 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5366 emlxs_fcf_event_xlate(evt), arg1,
5367 fcftab->attempts,
5368 fcftab->reason);
5369
5370 rval = emlxs_fcoe_fcftab_state(port,
5371 FCOE_FCFTAB_STATE_SOLICIT,
5372 FCF_REASON_OP_FAILED, 0, arg1);
5373 }
5374
5375 return (rval);
5376
5377 } /* emlxs_fcoe_fcftab_sol_failed_action() */
5378
5379
5380 /*ARGSUSED*/
5381 static uint32_t
emlxs_fcoe_fcftab_sol_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)5382 emlxs_fcoe_fcftab_sol_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
5383 {
5384 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
5385 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5386 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
5387 uint16_t TID;
5388 mbox_rsp_hdr_t *hdr_rsp;
5389 MATCHMAP *mp;
5390 uint32_t status = MGMT_STATUS_FCF_IN_USE;
5391 uint32_t xstatus = 0;
5392 uint32_t fip_mode = 1;
5393
5394 mutex_enter(&EMLXS_FCF_LOCK);
5395 TID = (uint16_t)((unsigned long)mbq->context);
5396
5397 if (mbq->nonembed) {
5398 fip_mode = 0;
5399
5400 mp = (MATCHMAP *)mbq->nonembed;
5401 mbq->nonembed = NULL;
5402
5403 hdr_rsp = (mbox_rsp_hdr_t *)mp->virt;
5404 status = hdr_rsp->status;
5405 xstatus = hdr_rsp->extra_status;
5406
5407 emlxs_mem_put(hba, MEM_BUF, (void *)mp);
5408 }
5409
5410 if (fcftab->state != FCOE_FCFTAB_STATE_SOLICIT) {
5411 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5412 "fcoe_fcftab_sol_mbcmpl:%x %s.",
5413 TID,
5414 emlxs_fcoe_fcftab_state_xlate(fcftab->state));
5415
5416 mutex_exit(&EMLXS_FCF_LOCK);
5417 return (0);
5418 }
5419
5420 if (TID != fcftab->generation) {
5421 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5422 "fcoe_fcftab_sol_mbcmpl:%x %s. "
5423 "Incorrect generation %x. Dropping.",
5424 TID,
5425 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5426 fcftab->generation);
5427
5428 mutex_exit(&EMLXS_FCF_LOCK);
5429 return (0);
5430 }
5431
5432 if (mb4->mbxStatus) {
5433 if (fip_mode) {
5434 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5435 "fcoe_fcftab_sol_mbcmpl:%x failed. %s. >",
5436 fcftab->TID,
5437 emlxs_mb_xlate_status(mb4->mbxStatus));
5438
5439 (void) emlxs_fcoe_fcftab_state(port,
5440 FCOE_FCFTAB_STATE_SOLICIT_FAILED,
5441 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
5442
5443 mutex_exit(&EMLXS_FCF_LOCK);
5444 return (0);
5445
5446 } else if ((status == 0)||(status != MGMT_STATUS_FCF_IN_USE)) {
5447 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5448 "fcoe_fcftab_sol_mbcmpl:%x failed. %s %x,%x. >",
5449 fcftab->TID,
5450 emlxs_mb_xlate_status(mb4->mbxStatus),
5451 status, xstatus);
5452
5453 (void) emlxs_fcoe_fcftab_state(port,
5454 FCOE_FCFTAB_STATE_SOLICIT_FAILED,
5455 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
5456
5457 mutex_exit(&EMLXS_FCF_LOCK);
5458 return (0);
5459 }
5460 }
5461
5462 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5463 "fcoe_fcftab_sol_mbcmpl:%x %s gen=%x. Solicit complete. >",
5464 fcftab->TID,
5465 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5466 fcftab->generation);
5467
5468 (void) emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT_CMPL,
5469 0, 0, 0);
5470
5471 mutex_exit(&EMLXS_FCF_LOCK);
5472 return (0);
5473
5474 } /* emlxs_fcoe_fcftab_sol_mbcmpl() */
5475
5476
5477 /*ARGSUSED*/
5478 static uint32_t
emlxs_fcoe_fcftab_sol_action(emlxs_port_t * port,uint32_t evt,void * arg1)5479 emlxs_fcoe_fcftab_sol_action(emlxs_port_t *port, uint32_t evt,
5480 void *arg1)
5481 {
5482 emlxs_hba_t *hba = HBA;
5483 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5484 MAILBOXQ *mbq;
5485 MAILBOX4 *mb4;
5486 MATCHMAP *mp = NULL;
5487 uint32_t rval = 0;
5488
5489 if (fcftab->state != FCOE_FCFTAB_STATE_SOLICIT) {
5490 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
5491 "fcoe_fcftab_sol_action:%x %s:%s arg=%p. "
5492 "Invalid state. <",
5493 fcftab->TID,
5494 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5495 emlxs_fcf_event_xlate(evt), arg1);
5496 return (1);
5497 }
5498
5499 if ((fcftab->prev_state != FCOE_FCFTAB_STATE_SOLICIT_FAILED) ||
5500 (fcftab->flag & EMLXS_FCOE_FCFTAB_SOL_REQ)) {
5501 fcftab->flag &= ~EMLXS_FCOE_FCFTAB_SOL_REQ;
5502 fcftab->attempts = 0;
5503 }
5504
5505 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
5506 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5507 "fcoe_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. "
5508 "Handling request.",
5509 fcftab->TID,
5510 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5511 emlxs_fcf_event_xlate(evt), arg1,
5512 fcftab->generation,
5513 fcftab->flag);
5514
5515 rval = emlxs_fcoe_fcftab_req_handler(port, arg1);
5516 return (rval);
5517 }
5518
5519 if (fcftab->attempts == 0) {
5520 fcftab->TID = fcftab->generation;
5521 }
5522
5523 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5524 "fcoe_fcftab_sol_action:%x %s:%s arg=%p gen=%x fip=%x. "
5525 "Requesting solicit. <",
5526 fcftab->TID,
5527 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5528 emlxs_fcf_event_xlate(evt), arg1,
5529 fcftab->generation,
5530 ((hba->flag & FC_FIP_SUPPORTED)? 1:0));
5531
5532 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
5533 rval = emlxs_fcoe_fcftab_state(port,
5534 FCOE_FCFTAB_STATE_SOLICIT_FAILED,
5535 FCF_REASON_NO_MBOX, 0, 0);
5536 return (rval);
5537 }
5538
5539 mb4 = (MAILBOX4*)mbq;
5540 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
5541
5542 if (hba->flag & FC_FIP_SUPPORTED) {
5543 IOCTL_FCOE_REDISCOVER_FCF_TABLE *fcf;
5544
5545 mbq->nonembed = NULL;
5546 mbq->mbox_cmpl = emlxs_fcoe_fcftab_sol_mbcmpl;
5547 mbq->context = (void *)((unsigned long)fcftab->TID);
5548 mbq->port = (void *)port;
5549
5550 mb4->un.varSLIConfig.be.embedded = 1;
5551 mb4->mbxCommand = MBX_SLI_CONFIG;
5552 mb4->mbxOwner = OWN_HOST;
5553 mb4->un.varSLIConfig.be.payload_length =
5554 sizeof (IOCTL_FCOE_REDISCOVER_FCF_TABLE) +
5555 IOCTL_HEADER_SZ;
5556 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
5557 IOCTL_SUBSYSTEM_FCOE;
5558 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
5559 FCOE_OPCODE_REDISCOVER_FCF_TABLE;
5560 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
5561 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
5562 sizeof (IOCTL_FCOE_REDISCOVER_FCF_TABLE);
5563
5564 fcf = (IOCTL_FCOE_REDISCOVER_FCF_TABLE *)
5565 &mb4->un.varSLIConfig.payload;
5566 fcf->params.request.fcf_count = 0; /* invalidate FCF table */
5567
5568 } else { /* Non-FIP */
5569
5570 /* Non-FIP uses a persistent FCF entry that */
5571 /* we must add to the table */
5572
5573 IOCTL_FCOE_ADD_FCF_TABLE *fcf;
5574 mbox_req_hdr_t *hdr_req;
5575 FCF_RECORD_t *fcf_rec;
5576 uint8_t bitmap[512];
5577 uint16_t i;
5578
5579 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
5580 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
5581
5582 rval = emlxs_fcoe_fcftab_state(port,
5583 FCOE_FCFTAB_STATE_SOLICIT_FAILED,
5584 FCF_REASON_NO_BUFFER, 0, arg1);
5585 return (rval);
5586 }
5587 bzero(mp->virt, mp->size);
5588
5589 mbq->nonembed = (void *)mp;
5590 mbq->mbox_cmpl = emlxs_fcoe_fcftab_sol_mbcmpl;
5591 mbq->context = (void *)((unsigned long)fcftab->generation);
5592 mbq->port = (void *)port;
5593
5594 mb4->un.varSLIConfig.be.embedded = 0;
5595 mb4->mbxCommand = MBX_SLI_CONFIG;
5596 mb4->mbxOwner = OWN_HOST;
5597
5598 hdr_req = (mbox_req_hdr_t *)mp->virt;
5599 hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE;
5600 hdr_req->opcode = FCOE_OPCODE_ADD_FCF_TABLE;
5601 hdr_req->timeout = 0;
5602 hdr_req->req_length = sizeof (IOCTL_FCOE_ADD_FCF_TABLE);
5603
5604 fcf = (IOCTL_FCOE_ADD_FCF_TABLE *)(hdr_req + 1);
5605 fcf->params.request.fcf_index = 0;
5606
5607 fcf_rec = &fcf->params.request.fcf_entry;
5608 fcf_rec->max_recv_size = EMLXS_FCOE_MAX_RCV_SZ;
5609 fcf_rec->fka_adv_period = 0;
5610 fcf_rec->fip_priority = 128;
5611
5612 #ifdef EMLXS_BIG_ENDIAN
5613 fcf_rec->fcf_mac_address_hi[0] = FCOE_FCF_MAC3;
5614 fcf_rec->fcf_mac_address_hi[1] = FCOE_FCF_MAC2;
5615 fcf_rec->fcf_mac_address_hi[2] = FCOE_FCF_MAC1;
5616 fcf_rec->fcf_mac_address_hi[3] = FCOE_FCF_MAC0;
5617 fcf_rec->fcf_mac_address_low[0] = FCOE_FCF_MAC5;
5618 fcf_rec->fcf_mac_address_low[1] = FCOE_FCF_MAC4;
5619 fcf_rec->fc_map[0] = hba->sli.sli4.cfgFCOE.FCMap[2];
5620 fcf_rec->fc_map[1] = hba->sli.sli4.cfgFCOE.FCMap[1];
5621 fcf_rec->fc_map[2] = hba->sli.sli4.cfgFCOE.FCMap[0];
5622 #endif /* EMLXS_BIG_ENDIAN */
5623 #ifdef EMLXS_LITTLE_ENDIAN
5624 fcf_rec->fcf_mac_address_hi[0] = FCOE_FCF_MAC0;
5625 fcf_rec->fcf_mac_address_hi[1] = FCOE_FCF_MAC1;
5626 fcf_rec->fcf_mac_address_hi[2] = FCOE_FCF_MAC2;
5627 fcf_rec->fcf_mac_address_hi[3] = FCOE_FCF_MAC3;
5628 fcf_rec->fcf_mac_address_low[0] = FCOE_FCF_MAC4;
5629 fcf_rec->fcf_mac_address_low[1] = FCOE_FCF_MAC5;
5630 fcf_rec->fc_map[0] = hba->sli.sli4.cfgFCOE.FCMap[0];
5631 fcf_rec->fc_map[1] = hba->sli.sli4.cfgFCOE.FCMap[1];
5632 fcf_rec->fc_map[2] = hba->sli.sli4.cfgFCOE.FCMap[2];
5633 #endif /* EMLXS_LITTLE_ENDIAN */
5634
5635 if (hba->sli.sli4.cfgFCOE.fip_flags & TLV_FCOE_VLAN) {
5636 bzero((void *) bitmap, 512);
5637 i = hba->sli.sli4.cfgFCOE.VLanId;
5638 bitmap[i / 8] = (1 << (i % 8));
5639 BE_SWAP32_BCOPY(bitmap, fcf_rec->vlan_bitmap, 512);
5640 } else {
5641 bzero((void *) bitmap, 512);
5642 bitmap[0] = 1; /* represents bit 0 */
5643 BE_SWAP32_BCOPY(bitmap, fcf_rec->vlan_bitmap, 512);
5644 }
5645
5646 fcf_rec->fcf_valid = 1;
5647 fcf_rec->fcf_available = 1;
5648 }
5649
5650 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
5651 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
5652 if (mp) {
5653 emlxs_mem_put(hba, MEM_BUF, (void *)mp);
5654 }
5655 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
5656
5657 rval = emlxs_fcoe_fcftab_state(port,
5658 FCOE_FCFTAB_STATE_SOLICIT_FAILED,
5659 FCF_REASON_SEND_FAILED, rval, 0);
5660
5661 return (rval);
5662 }
5663
5664 return (0);
5665
5666 } /* emlxs_fcoe_fcftab_sol_action() */
5667
5668
5669 /*ARGSUSED*/
5670 static uint32_t
emlxs_fcoe_fcftab_sol_cmpl_action(emlxs_port_t * port,uint32_t evt,void * arg1)5671 emlxs_fcoe_fcftab_sol_cmpl_action(emlxs_port_t *port, uint32_t evt,
5672 void *arg1)
5673 {
5674 emlxs_hba_t *hba = HBA;
5675 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5676 uint32_t rval = 0;
5677 emlxs_config_t *cfg = &CFG;
5678
5679 if (fcftab->state != FCOE_FCFTAB_STATE_SOLICIT_CMPL) {
5680 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
5681 "fcoe_fcftab_sol_cmpl_action:%x %s:%s arg=%p "
5682 "Invalid state. <",
5683 fcftab->TID,
5684 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5685 emlxs_fcf_event_xlate(evt), arg1);
5686 return (1);
5687 }
5688
5689 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
5690 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5691 "fcoe_fcftab_sol_cmpl_action:%x %s:%s arg=%p gen=%d "
5692 "flag=%x. Handling request.",
5693 fcftab->TID,
5694 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5695 emlxs_fcf_event_xlate(evt), arg1,
5696 fcftab->generation,
5697 fcftab->flag);
5698
5699 rval = emlxs_fcoe_fcftab_req_handler(port, arg1);
5700 return (rval);
5701 }
5702
5703 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5704 "fcoe_fcftab_sol_cmpl_action:%x %s:%s arg=%p gen=%d. "
5705 "Starting timer (%d secs).",
5706 fcftab->TID,
5707 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5708 emlxs_fcf_event_xlate(evt), arg1,
5709 fcftab->generation,
5710 cfg[CFG_FCF_SOLICIT_DELAY].current);
5711
5712 /* Start the read timer */
5713 fcftab->read_timer = hba->timer_tics +
5714 cfg[CFG_FCF_SOLICIT_DELAY].current;
5715
5716 return (0);
5717
5718 } /* emlxs_fcoe_fcftab_sol_cmpl_action() */
5719
5720
5721 /*ARGSUSED*/
5722 static uint32_t
emlxs_fcoe_fcftab_read_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)5723 emlxs_fcoe_fcftab_read_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
5724 {
5725 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
5726 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5727 MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
5728 mbox_rsp_hdr_t *hdr_rsp;
5729 IOCTL_FCOE_READ_FCF_TABLE *fcf;
5730 FCF_RECORD_t *fcfrec;
5731 FCFIobj_t *fcfp;
5732 MATCHMAP *mp;
5733 uint32_t context;
5734 uint16_t index;
5735 uint16_t TID;
5736 uint32_t event_tag;
5737
5738 mutex_enter(&EMLXS_FCF_LOCK);
5739 context = (uint32_t)((unsigned long)mbq->context);
5740 TID = (uint16_t)(context >> 16);
5741 index = (uint16_t)(context & 0xFFFF);
5742
5743 if (fcftab->state != FCOE_FCFTAB_STATE_READ) {
5744 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5745 "fcoe_fcftab_read_mbcmpl:%x index=%d %s.",
5746 TID, index,
5747 emlxs_fcoe_fcftab_state_xlate(fcftab->state));
5748
5749 mutex_exit(&EMLXS_FCF_LOCK);
5750 return (0);
5751 }
5752
5753 if (TID != fcftab->generation) {
5754 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5755 "fcoe_fcftab_read_mbcmpl:%x index=%d %s. "
5756 "Incorrect generation %x. Dropping.",
5757 TID, index,
5758 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5759 fcftab->generation);
5760
5761 mutex_exit(&EMLXS_FCF_LOCK);
5762 return (0);
5763 }
5764
5765 mp = (MATCHMAP *)mbq->nonembed;
5766 hdr_rsp = (mbox_rsp_hdr_t *)mp->virt;
5767
5768 if (mb4->mbxStatus || hdr_rsp->status) {
5769 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5770 "fcoe_fcftab_read_mbcmpl:%x index=%d failed. %s %x,%x. >",
5771 fcftab->TID, index,
5772 emlxs_mb_xlate_status(mb4->mbxStatus),
5773 hdr_rsp->status, hdr_rsp->extra_status);
5774
5775 (void) emlxs_fcoe_fcftab_state(port,
5776 FCOE_FCFTAB_STATE_READ_FAILED,
5777 FCF_REASON_MBOX_FAILED, mb4->mbxStatus,
5778 (void*)((unsigned long)index));
5779
5780 mutex_exit(&EMLXS_FCF_LOCK);
5781 return (0);
5782 }
5783
5784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5785 "fcoe_fcftab_read_mbcmpl:%x index=%d %s",
5786 fcftab->TID, index,
5787 emlxs_fcoe_fcftab_state_xlate(fcftab->state));
5788
5789 fcf = (IOCTL_FCOE_READ_FCF_TABLE *)(hdr_rsp + 1);
5790 fcfrec = &fcf->params.response.fcf_entry[0];
5791
5792 #ifdef EMLXS_BIG_ENDIAN
5793 {
5794 uint32_t *iptr;
5795 uint32_t i;
5796 uint8_t j;
5797 uint16_t s;
5798 uint16_t *sptr;
5799
5800 /* Fix up data in FCF record */
5801 SWAP32_BUFFER(&fcfrec->fabric_name_identifier[0], 8);
5802 SWAP32_BUFFER(&fcfrec->switch_name_identifier[0], 8);
5803 SWAP32_BUFFER(&fcfrec->vlan_bitmap[0], 512);
5804
5805 iptr = (uint32_t *)&fcfrec->fcf_mac_address_hi[0];
5806 i = *iptr;
5807 *iptr = SWAP32(i);
5808
5809 sptr = (uint16_t *)&fcfrec->fcf_mac_address_low[0];
5810 s = *sptr;
5811 *sptr = SWAP16(s);
5812
5813 j = fcfrec->fc_map[0];
5814 fcfrec->fc_map[0] = fcfrec->fc_map[2];
5815 fcfrec->fc_map[2] = j;
5816 }
5817 #endif /* EMLXS_BIG_ENDIAN */
5818
5819 event_tag = fcf->params.response.event_tag;
5820
5821 /* Try to find existing fcfrec */
5822 fcfp = emlxs_fcfi_find(port, fcfrec, 0);
5823
5824 /* If not found, allocate a new one */
5825 if (!fcfp) {
5826 fcfp = emlxs_fcfi_alloc(port);
5827 }
5828
5829 if (!fcfp) {
5830 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5831 "fcoe_fcftab_read_mbcmpl:%x index=%d failed. "
5832 "Unable to allocate fcfi. >",
5833 fcftab->TID, index);
5834
5835 (void) emlxs_fcoe_fcftab_state(port,
5836 FCOE_FCFTAB_STATE_READ_FAILED,
5837 FCF_REASON_NO_FCFI, 0,
5838 (void*)((unsigned long)index));
5839
5840 mutex_exit(&EMLXS_FCF_LOCK);
5841 return (0);
5842 }
5843
5844 /* Update the FCFI */
5845 emlxs_fcfi_update(port, fcfp, fcfrec, event_tag);
5846
5847 /* Check if another record needs to be acquired */
5848 if (fcf->params.response.next_valid_fcf_index != 0xffff) {
5849 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5850 "fcoe_fcftab_read_mbcmpl:%x. Read next. >",
5851 fcftab->TID);
5852
5853 (void) emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_READ,
5854 FCF_REASON_REENTER, 0,
5855 (void *)((unsigned long)fcf->params.response.
5856 next_valid_fcf_index));
5857 } else {
5858 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5859 "fcoe_fcftab_read_mbcmpl:%x. Read complete. >",
5860 fcftab->TID);
5861
5862 (void) emlxs_fcoe_fcftab_state(port,
5863 FCOE_FCFTAB_STATE_READ_CMPL,
5864 0, 0, (void*)((unsigned long)index));
5865 }
5866
5867 mutex_exit(&EMLXS_FCF_LOCK);
5868 return (0);
5869
5870 } /* emlxs_fcoe_fcftab_read_mbcmpl() */
5871
5872
5873 /*ARGSUSED*/
5874 static uint32_t
emlxs_fcoe_fcftab_read_action(emlxs_port_t * port,uint32_t evt,void * arg1)5875 emlxs_fcoe_fcftab_read_action(emlxs_port_t *port, uint32_t evt,
5876 void *arg1)
5877 {
5878 emlxs_hba_t *hba = HBA;
5879 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5880 MAILBOXQ *mbq;
5881 MAILBOX4 *mb4;
5882 IOCTL_FCOE_READ_FCF_TABLE *fcf;
5883 uint32_t rval = 0;
5884 MATCHMAP *mp;
5885 mbox_req_hdr_t *hdr_req;
5886 uint16_t index = (uint16_t)((unsigned long)arg1);
5887 uint32_t context;
5888
5889 if (fcftab->state != FCOE_FCFTAB_STATE_READ) {
5890 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
5891 "fcoe_fcftab_read_action:%x %s:%s arg=%p. "
5892 "Invalid state. <",
5893 fcftab->TID,
5894 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5895 emlxs_fcf_event_xlate(evt), arg1);
5896 return (1);
5897 }
5898
5899 if ((fcftab->prev_state != FCOE_FCFTAB_STATE_READ_FAILED) ||
5900 (fcftab->flag & EMLXS_FCOE_FCFTAB_READ_REQ)) {
5901 fcftab->flag &= ~EMLXS_FCOE_FCFTAB_READ_REQ;
5902 fcftab->attempts = 0;
5903 }
5904
5905 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
5906 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5907 "fcoe_fcftab_read_action:%x %s:%s arg=%p flag=%x. "
5908 "Handling request.",
5909 fcftab->TID,
5910 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5911 emlxs_fcf_event_xlate(evt), arg1,
5912 fcftab->flag);
5913
5914 rval = emlxs_fcoe_fcftab_req_handler(port, arg1);
5915 return (rval);
5916 }
5917
5918 if (fcftab->attempts == 0) {
5919 fcftab->TID = fcftab->generation;
5920 }
5921
5922 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
5923 "fcoe_fcftab_read_action:%x %s:%s arg=%p attempts=%d. "
5924 "Reading FCF. <",
5925 fcftab->TID,
5926 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
5927 emlxs_fcf_event_xlate(evt), arg1,
5928 fcftab->attempts);
5929
5930 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
5931 rval = emlxs_fcoe_fcftab_state(port,
5932 FCOE_FCFTAB_STATE_READ_FAILED,
5933 FCF_REASON_NO_MBOX, 0, arg1);
5934 return (rval);
5935 }
5936 mb4 = (MAILBOX4*)mbq;
5937 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
5938
5939 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
5940 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
5941
5942 rval = emlxs_fcoe_fcftab_state(port,
5943 FCOE_FCFTAB_STATE_READ_FAILED,
5944 FCF_REASON_NO_BUFFER, 0, arg1);
5945 return (rval);
5946 }
5947 bzero(mp->virt, mp->size);
5948
5949 mbq->nonembed = (void *)mp;
5950 mbq->mbox_cmpl = emlxs_fcoe_fcftab_read_mbcmpl;
5951
5952 context = ((uint32_t)fcftab->TID << 16) | (uint32_t)index;
5953 mbq->context = (void *)((unsigned long)context);
5954 mbq->port = (void *)port;
5955
5956 mb4->un.varSLIConfig.be.embedded = 0;
5957 mb4->mbxCommand = MBX_SLI_CONFIG;
5958 mb4->mbxOwner = OWN_HOST;
5959
5960 hdr_req = (mbox_req_hdr_t *)mp->virt;
5961 hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE;
5962 hdr_req->opcode = FCOE_OPCODE_READ_FCF_TABLE;
5963 hdr_req->timeout = 0;
5964 hdr_req->req_length = sizeof (IOCTL_FCOE_READ_FCF_TABLE);
5965
5966 fcf = (IOCTL_FCOE_READ_FCF_TABLE *)(hdr_req + 1);
5967 fcf->params.request.fcf_index = index;
5968
5969 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
5970 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
5971 emlxs_mem_put(hba, MEM_BUF, (void *)mp);
5972 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
5973
5974 rval = emlxs_fcoe_fcftab_state(port,
5975 FCOE_FCFTAB_STATE_READ_FAILED,
5976 FCF_REASON_SEND_FAILED, rval, arg1);
5977
5978 return (rval);
5979 }
5980
5981 return (0);
5982
5983 } /* emlxs_fcoe_fcftab_read_action() */
5984
5985
5986 /*ARGSUSED*/
5987 static uint32_t
emlxs_fcoe_fcftab_read_failed_action(emlxs_port_t * port,uint32_t evt,void * arg1)5988 emlxs_fcoe_fcftab_read_failed_action(emlxs_port_t *port, uint32_t evt,
5989 void *arg1)
5990 {
5991 emlxs_hba_t *hba = HBA;
5992 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
5993 uint32_t rval = 0;
5994
5995 fcftab->attempts++;
5996
5997 if (fcftab->state != FCOE_FCFTAB_STATE_READ_FAILED) {
5998 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
5999 "fcoe_fcftab_read_failed_action:%x %s:%s arg=%p "
6000 "attempt=%d. Invalid state. <",
6001 fcftab->TID,
6002 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6003 emlxs_fcf_event_xlate(evt),
6004 arg1, fcftab->attempts);
6005 return (1);
6006 }
6007
6008 if ((fcftab->reason == FCF_REASON_MBOX_FAILED) ||
6009 (fcftab->reason == FCF_REASON_SEND_FAILED) ||
6010 (fcftab->attempts >= 3)) {
6011 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6012 "fcoe_fcftab_read_failed_action:%x %s:%s arg=%p "
6013 "attempt=%d reason=%x. Giving up.",
6014 fcftab->TID,
6015 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6016 emlxs_fcf_event_xlate(evt), arg1,
6017 fcftab->attempts,
6018 fcftab->reason);
6019
6020 rval = emlxs_fcoe_fcftab_state(port,
6021 FCOE_FCFTAB_STATE_READ_CMPL,
6022 FCF_REASON_OP_FAILED, fcftab->attempts, arg1);
6023 } else {
6024 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6025 "fcoe_fcftab_read_failed_action:%x %s:%s arg=%p "
6026 "attempt=%d reason=%x. Retrying.",
6027 fcftab->TID,
6028 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6029 emlxs_fcf_event_xlate(evt), arg1,
6030 fcftab->attempts,
6031 fcftab->reason);
6032
6033 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_READ,
6034 FCF_REASON_OP_FAILED, fcftab->attempts, FCFTAB_READ_ALL);
6035 }
6036
6037 return (rval);
6038
6039 } /* emlxs_fcoe_fcftab_read_failed_action() */
6040
6041
6042 /*ARGSUSED*/
6043 static uint32_t
emlxs_fcoe_fcftab_read_cmpl_action(emlxs_port_t * port,uint32_t evt,void * arg1)6044 emlxs_fcoe_fcftab_read_cmpl_action(emlxs_port_t *port, uint32_t evt,
6045 void *arg1)
6046 {
6047 emlxs_hba_t *hba = HBA;
6048 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6049 uint32_t rval = 0;
6050 FCFIobj_t *fcfp;
6051 uint32_t i;
6052
6053 if (fcftab->state != FCOE_FCFTAB_STATE_READ_CMPL) {
6054 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
6055 "fcoe_fcftab_read_cmpl_action:%x %s:%s arg=%p. "
6056 "Invalid state. <",
6057 fcftab->TID,
6058 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6059 emlxs_fcf_event_xlate(evt), arg1);
6060 return (1);
6061 }
6062
6063 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6064 "fcoe_fcftab_read_cmpl_action:%x %s:%s arg=%p attempts=%d. "
6065 "Cleaning table.",
6066 fcftab->TID,
6067 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6068 emlxs_fcf_event_xlate(evt), arg1,
6069 fcftab->attempts);
6070
6071 /* Clean FCFI table */
6072 fcfp = fcftab->table;
6073 for (i = 0; i < fcftab->table_count; i++, fcfp++) {
6074 if (fcfp->state == FCFI_STATE_FREE) {
6075 continue;
6076 }
6077
6078 /* Adjust the freshness flag */
6079 if (fcfp->generation == fcftab->generation) {
6080 fcfp->flag |= EMLXS_FCFI_FRESH;
6081 } else {
6082 fcfp->flag &= ~EMLXS_FCFI_FRESH;
6083 }
6084
6085 /* Clear the failed bit */
6086 fcfp->flag &= ~EMLXS_FCFI_FAILED;
6087
6088 /* Free all stale unselected entries now */
6089 if (!(fcfp->flag & EMLXS_FCFI_FRESH) &&
6090 !(fcfp->flag & EMLXS_FCFI_SELECTED)) {
6091 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6092 "fcoe_fcftab_read_cmpl_action:%x. FCF stale. "
6093 "Freeing FCFI:%d. >",
6094 fcftab->TID,
6095 fcfp->fcf_index);
6096
6097 (void) emlxs_fcfi_free(port, fcfp);
6098 continue;
6099 }
6100 }
6101
6102 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_FCFI_ONLINE,
6103 FCF_REASON_EVENT, evt, arg1);
6104
6105 return (rval);
6106
6107 } /* emlxs_fcoe_fcftab_read_cmpl_action() */
6108
6109
6110 static FCFIobj_t *
emlxs_fcoe_fcftab_fcfi_select(emlxs_port_t * port,char * fabric_wwn)6111 emlxs_fcoe_fcftab_fcfi_select(emlxs_port_t *port, char *fabric_wwn)
6112 {
6113 emlxs_hba_t *hba = HBA;
6114 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6115 FCFIobj_t *fcfp;
6116 FCFIobj_t *fcfp1;
6117 uint32_t mask;
6118 uint32_t viable;
6119 uint32_t i;
6120 uint32_t j;
6121 uint32_t rnum;
6122 timespec_t time;
6123 FCFIobj_t **fcf_table;
6124 uint32_t fcf_table_count;
6125
6126 mask = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE|
6127 EMLXS_FCFI_CONFIGURED|EMLXS_FCFI_FRESH|
6128 EMLXS_FCFI_FAILED|EMLXS_FCFI_SELECTED);
6129 viable = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE|
6130 EMLXS_FCFI_CONFIGURED|EMLXS_FCFI_FRESH);
6131
6132 /* Tag & count viable entries */
6133 fcf_table_count = 0;
6134 fcfp = 0;
6135 fcfp1 = fcftab->table;
6136 for (i = 0; i < fcftab->table_count; i++, fcfp1++) {
6137 if (fcfp1->state == FCFI_STATE_FREE) {
6138 fcfp1->flag &= ~EMLXS_FCFI_TAGGED;
6139 continue;
6140 }
6141
6142 if ((fcfp1->flag & mask) != viable) {
6143 fcfp1->flag &= ~EMLXS_FCFI_TAGGED;
6144 continue;
6145 }
6146
6147 if (fabric_wwn &&
6148 bcmp(fabric_wwn,
6149 fcfp1->fcf_rec.fabric_name_identifier, 8)) {
6150 fcfp1->flag &= ~EMLXS_FCFI_TAGGED;
6151 continue;
6152 }
6153
6154 fcfp1->flag |= EMLXS_FCFI_TAGGED;
6155 fcfp = fcfp1;
6156 fcf_table_count++;
6157 }
6158
6159 if (fcf_table_count == 0) {
6160 return (NULL);
6161 }
6162
6163 if (fcf_table_count == 1) {
6164 return (fcfp);
6165 }
6166
6167 /* We found more than one viable entry */
6168
6169 fcf_table = (FCFIobj_t **)kmem_zalloc(
6170 (sizeof (uintptr_t) * fcf_table_count), KM_SLEEP);
6171
6172 /* Find the highest priority tagged entry(s) */
6173 for (i = 0; i < fcf_table_count; i++) {
6174 fcfp = 0;
6175 fcfp1 = fcftab->table;
6176 for (j = 0; j < fcftab->table_count; j++, fcfp1++) {
6177 if (!(fcfp1->flag & EMLXS_FCFI_TAGGED)) {
6178 continue;
6179 }
6180
6181 if (!fcfp ||
6182 (fcfp1->priority > fcfp->priority)) {
6183 fcfp = fcfp1;
6184 }
6185 }
6186
6187 if (fcf_table[0] &&
6188 (fcf_table[0]->priority > fcfp->priority)) {
6189 break;
6190 }
6191
6192 fcfp->flag &= ~EMLXS_FCFI_TAGGED;
6193 fcf_table[i] = fcfp;
6194 }
6195
6196 /* If more than one entry has the highest priority, */
6197 /* then randomly select one of the highest. */
6198 if (i > 1) {
6199 /* Pick a random number from 0 to (i-1) */
6200 /* This algorithm uses the lower 16 bits of the nanosecond */
6201 /* clock to determine the value */
6202 bzero(&time, sizeof (timespec_t));
6203 gethrestime(&time);
6204 rnum = (uint32_t)(time.tv_nsec & 0xFFFF);
6205
6206 fcfp = fcf_table[(rnum%i)];
6207 } else {
6208 fcfp = fcf_table[0];
6209 }
6210
6211 /* Free the priority table */
6212 kmem_free(fcf_table, (sizeof (uintptr_t) * fcf_table_count));
6213
6214 return (fcfp);
6215
6216 } /* emlxs_fcoe_fcftab_fcfi_select() */
6217
6218
6219 /*ARGSUSED*/
6220 static void
emlxs_fcoe_fcftab_process(emlxs_port_t * port)6221 emlxs_fcoe_fcftab_process(emlxs_port_t *port)
6222 {
6223 emlxs_hba_t *hba = HBA;
6224 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6225 FCFIobj_t *fcfp;
6226 FCFIobj_t *prev_fcfp;
6227 uint32_t i;
6228 uint32_t j;
6229 uint32_t count;
6230 uint32_t mask;
6231 uint32_t viable;
6232 emlxs_config_t *cfg = &CFG;
6233
6234 mask = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE|
6235 EMLXS_FCFI_CONFIGURED|EMLXS_FCFI_FRESH|
6236 EMLXS_FCFI_FAILED);
6237 viable = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE|
6238 EMLXS_FCFI_CONFIGURED|EMLXS_FCFI_FRESH);
6239
6240 /* Deselection process */
6241 for (i = 0; i < FCFTAB_MAX_FCFI_COUNT; i++) {
6242 fcfp = fcftab->fcfi[i];
6243
6244 if (!fcfp) {
6245 continue;
6246 }
6247
6248 /* Check if entry is viable */
6249 if ((fcfp->flag & mask) == viable) {
6250 if (fcfp->offline_timer) {
6251 fcfp->offline_timer = 0;
6252
6253 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6254 "fcoe_fcftab_process:%x %d fcfi=%d %s. "
6255 "FCF viable. Offline timer disabled.",
6256 fcftab->TID,
6257 i, fcfp->fcf_index,
6258 emlxs_fcfi_state_xlate(fcfp->state),
6259 cfg[CFG_FCF_FAILOVER_DELAY].current);
6260 }
6261 continue;
6262 }
6263
6264 /* Previous entry is no longer viable */
6265
6266 /* If FCF is still online */
6267 if (fcfp->state > FCFI_STATE_OFFLINE) {
6268 if (fcfp->offline_timer == 0) {
6269 /* Set the offline timer */
6270 fcfp->offline_timer = hba->timer_tics +
6271 cfg[CFG_FCF_FAILOVER_DELAY].current;
6272
6273 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6274 "fcoe_fcftab_process:%x %d fcfi=%d %s. "
6275 "No longer viable. "
6276 "Offlining FCF (%d secs).",
6277 fcftab->TID,
6278 i, fcfp->fcf_index,
6279 emlxs_fcfi_state_xlate(fcfp->state),
6280 cfg[CFG_FCF_FAILOVER_DELAY].current);
6281 }
6282 continue;
6283 }
6284
6285 /* Deselect it */
6286 fcfp->flag &= ~EMLXS_FCFI_SELECTED;
6287
6288 if (!(fcfp->flag & EMLXS_FCFI_FRESH)) {
6289 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6290 "fcoe_fcftab_process:%x %d. "
6291 "No longer viable. Freeing FCFI:%d. >",
6292 fcftab->TID,
6293 i, fcfp->fcf_index);
6294
6295 (void) emlxs_fcfi_free(port, fcfp);
6296 } else {
6297 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6298 "fcoe_fcftab_process:%x %d fcfi=%d %s. "
6299 "No longer viable. FCF deselected.",
6300 fcftab->TID,
6301 i, fcfp->fcf_index,
6302 emlxs_fcfi_state_xlate(fcfp->state));
6303 }
6304 }
6305
6306 /* Reselection process */
6307 for (i = 0; i < FCFTAB_MAX_FCFI_COUNT; i++) {
6308 prev_fcfp = fcftab->fcfi[i];
6309 fcftab->fcfi[i] = NULL;
6310
6311 /* If no previous selection, then make new one */
6312 if (!prev_fcfp) {
6313 /* Select an fcf on any fabric */
6314 fcfp = emlxs_fcoe_fcftab_fcfi_select(port, 0);
6315
6316 if (fcfp) {
6317 fcfp->flag |= EMLXS_FCFI_SELECTED;
6318 fcftab->fcfi[i] = fcfp;
6319
6320 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6321 "fcoe_fcftab_process:%x %d fcfi=%d %s. "
6322 "New FCF selected.",
6323 fcftab->TID,
6324 i, fcfp->fcf_index,
6325 emlxs_fcfi_state_xlate(fcfp->state));
6326 } else {
6327 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6328 "fcoe_fcftab_process:%x %d. "
6329 "No FCF available.",
6330 fcftab->TID,
6331 i);
6332 }
6333 continue;
6334 }
6335
6336 /* If previous entry is still selected, keep it */
6337 if (prev_fcfp->flag & EMLXS_FCFI_SELECTED) {
6338 fcfp = prev_fcfp;
6339 fcftab->fcfi[i] = fcfp;
6340
6341 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6342 "fcoe_fcftab_process:%x %d fcfi=%d %s. "
6343 "FCF still selected.",
6344 fcftab->TID,
6345 i, fcfp->fcf_index,
6346 emlxs_fcfi_state_xlate(fcfp->state));
6347 continue;
6348 }
6349
6350 /* Previous entry is no longer selected */
6351
6352 /* Select a new fcf from same fabric */
6353 fcfp = emlxs_fcoe_fcftab_fcfi_select(port,
6354 (char *)prev_fcfp->fcf_rec.fabric_name_identifier);
6355
6356 if (fcfp) {
6357 fcfp->flag |= EMLXS_FCFI_SELECTED;
6358 fcftab->fcfi[i] = fcfp;
6359
6360 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6361 "fcoe_fcftab_process:%x %d fcfi=%d %s. "
6362 "New FCF, same fabric selected.",
6363 fcftab->TID,
6364 i, fcfp->fcf_index,
6365 emlxs_fcfi_state_xlate(fcfp->state));
6366 continue;
6367 }
6368
6369 /* Select fcf from any fabric */
6370 fcfp = emlxs_fcoe_fcftab_fcfi_select(port, 0);
6371
6372 if (fcfp) {
6373 fcfp->flag |= EMLXS_FCFI_SELECTED;
6374 fcftab->fcfi[i] = fcfp;
6375
6376 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6377 "fcoe_fcftab_process:%x %d fcfi=%d %s. "
6378 "New FCF, new fabric selected.",
6379 fcftab->TID,
6380 i, fcfp->fcf_index,
6381 emlxs_fcfi_state_xlate(fcfp->state));
6382 continue;
6383 }
6384
6385 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6386 "fcoe_fcftab_process:%x %d. No FCF available.",
6387 fcftab->TID,
6388 i);
6389 }
6390
6391 /* Pack entries */
6392 count = 0;
6393 for (i = 0; i < FCFTAB_MAX_FCFI_COUNT; i++) {
6394 if (fcftab->fcfi[i]) {
6395 count++;
6396 continue;
6397 }
6398
6399 for (j = i+1; j < FCFTAB_MAX_FCFI_COUNT; j++) {
6400 if (fcftab->fcfi[j] == NULL) {
6401 continue;
6402 }
6403
6404 fcftab->fcfi[i] = fcftab->fcfi[j];
6405 fcftab->fcfi[j] = NULL;
6406 count++;
6407 break;
6408 }
6409
6410 if (j == FCFTAB_MAX_FCFI_COUNT) {
6411 break;
6412 }
6413 }
6414 fcftab->fcfi_count = count;
6415
6416 return;
6417
6418 } /* emlxs_fcoe_fcftab_process() */
6419
6420
6421 /*ARGSUSED*/
6422 static uint32_t
emlxs_fcoe_fcftab_fcfi_online_action(emlxs_port_t * port,uint32_t evt,void * arg1)6423 emlxs_fcoe_fcftab_fcfi_online_action(emlxs_port_t *port, uint32_t evt,
6424 void *arg1)
6425 {
6426 emlxs_hba_t *hba = HBA;
6427 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6428 FCFIobj_t *fcfp;
6429 uint32_t rval = 0;
6430 uint32_t i;
6431 uint32_t offline_count = 0;
6432 uint32_t online_count = 0;
6433
6434 if (fcftab->state != FCOE_FCFTAB_STATE_FCFI_ONLINE) {
6435 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6436 "fcoe_fcftab_fcfi_online_action:%x %s:%s arg=%p. "
6437 "Invalid state. <",
6438 fcftab->TID,
6439 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6440 emlxs_fcf_event_xlate(evt), arg1);
6441 return (1);
6442 }
6443
6444 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
6445 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6446 "fcoe_fcftab_fcfi_online_action:%x flag=%x. "
6447 "Handling request.",
6448 fcftab->TID,
6449 fcftab->flag);
6450
6451 rval = emlxs_fcoe_fcftab_req_handler(port, arg1);
6452 return (rval);
6453 }
6454
6455 emlxs_fcoe_fcftab_process(port);
6456
6457 for (i = 0; i < fcftab->fcfi_count; i++) {
6458 fcfp = fcftab->fcfi[i];
6459
6460 if (fcfp->offline_timer == 0) {
6461 online_count++;
6462
6463 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6464 "fcoe_fcftab_fcfi_online_action:%x fcfi_count=%d. "
6465 "Onlining FCFI:%d. >",
6466 fcftab->TID,
6467 fcftab->fcfi_count,
6468 fcfp->fcf_index);
6469
6470 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_ONLINE,
6471 fcfp);
6472 } else {
6473 offline_count++;
6474
6475 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6476 "fcoe_fcftab_fcfi_online_action:%x fcfi_count=%d. "
6477 "Offlining fcfi:%d.",
6478 fcftab->TID,
6479 fcftab->fcfi_count,
6480 fcfp->fcf_index);
6481 }
6482 }
6483
6484 if (offline_count) {
6485 /* Wait for FCF's to go offline */
6486 rval = emlxs_fcoe_fcftab_state(port,
6487 FCOE_FCFTAB_STATE_FCFI_OFFLINE,
6488 FCF_REASON_EVENT, evt, arg1);
6489
6490 /* Service timer now */
6491 emlxs_fcoe_fcftab_offline_timer(hba);
6492
6493 return (rval);
6494 }
6495
6496 if (!online_count) {
6497 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6498 "fcoe_fcftab_fcfi_online_action:%x fcfi_count=%d.",
6499 fcftab->TID,
6500 fcftab->fcfi_count);
6501 }
6502
6503 rval = emlxs_fcoe_fcftab_state(port,
6504 FCOE_FCFTAB_STATE_FCFI_ONLINE_CMPL,
6505 FCF_REASON_EVENT, evt, arg1);
6506
6507 return (rval);
6508
6509 } /* emlxs_fcoe_fcftab_fcfi_online_action() */
6510
6511
6512 /*ARGSUSED*/
6513 static uint32_t
emlxs_fcoe_fcftab_fcfi_online_cmpl_action(emlxs_port_t * port,uint32_t evt,void * arg1)6514 emlxs_fcoe_fcftab_fcfi_online_cmpl_action(emlxs_port_t *port, uint32_t evt,
6515 void *arg1)
6516 {
6517 emlxs_hba_t *hba = HBA;
6518 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6519 uint32_t rval = 0;
6520
6521 if (fcftab->state != FCOE_FCFTAB_STATE_FCFI_ONLINE_CMPL) {
6522 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
6523 "fcoe_fcftab_fcfi_online_cmpl_action:%x %s:%s arg=%p. "
6524 "Invalid state. <",
6525 fcftab->TID,
6526 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6527 emlxs_fcf_event_xlate(evt), arg1);
6528 return (1);
6529 }
6530
6531 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
6532 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6533 "fcoe_fcftab_fcfi_online_cmpl_action:%x %s:%s "
6534 "arg=%p flag=%x. Handling request.",
6535 fcftab->TID,
6536 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6537 emlxs_fcf_event_xlate(evt), arg1,
6538 fcftab->flag);
6539
6540 rval = emlxs_fcoe_fcftab_req_handler(port, arg1);
6541 return (rval);
6542 }
6543
6544 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6545 "fcoe_fcftab_fcfi_online_cmpl_action:%x %s:%s arg=%p. "
6546 "Going online.",
6547 fcftab->TID,
6548 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6549 emlxs_fcf_event_xlate(evt), arg1);
6550
6551 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_ONLINE,
6552 FCF_REASON_EVENT, evt, arg1);
6553
6554 return (rval);
6555
6556 } /* emlxs_fcoe_fcftab_fcfi_online_cmpl_action() */
6557
6558
6559 /*ARGSUSED*/
6560 static uint32_t
emlxs_fcoe_fcftab_fcfi_offline_action(emlxs_port_t * port,uint32_t evt,void * arg1)6561 emlxs_fcoe_fcftab_fcfi_offline_action(emlxs_port_t *port, uint32_t evt,
6562 void *arg1)
6563 {
6564 emlxs_hba_t *hba = HBA;
6565 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6566 FCFIobj_t *fcfp;
6567 uint32_t rval = 0;
6568 int32_t i;
6569 uint32_t fcfi_offline;
6570
6571 if (fcftab->state != FCOE_FCFTAB_STATE_FCFI_OFFLINE) {
6572 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
6573 "fcoe_fcftab_fcfi_offline_action:%x %s:%s arg=%p. "
6574 "Invalid state. <",
6575 fcftab->TID,
6576 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6577 emlxs_fcf_event_xlate(evt), arg1);
6578 return (1);
6579 }
6580
6581 /* Check for FCF's going offline */
6582 fcfi_offline = 0;
6583 for (i = 0; i < fcftab->fcfi_count; i++) {
6584 fcfp = fcftab->fcfi[i];
6585
6586 if (fcfp->state <= FCFI_STATE_OFFLINE) {
6587 continue;
6588 }
6589
6590 if (fcfp->offline_timer ||
6591 (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ)) {
6592 fcfi_offline++;
6593 }
6594 }
6595
6596 if (fcfi_offline) {
6597 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6598 "fcoe_fcftab_fcfi_offline_action:%x %s:%s arg=%p "
6599 "fcfi_offline=%d. <",
6600 fcftab->TID,
6601 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6602 emlxs_fcf_event_xlate(evt), arg1,
6603 fcfi_offline);
6604
6605 return (0);
6606 }
6607
6608 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6609 "fcoe_fcftab_fcfi_offline_action:%x %s:%s arg=%p.",
6610 fcftab->TID,
6611 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6612 emlxs_fcf_event_xlate(evt), arg1);
6613
6614 rval = emlxs_fcoe_fcftab_state(port,
6615 FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL,
6616 FCF_REASON_EVENT, evt, arg1);
6617
6618 return (rval);
6619
6620 } /* emlxs_fcoe_fcftab_fcfi_offline_action() */
6621
6622
6623 /*ARGSUSED*/
6624 static uint32_t
emlxs_fcoe_fcftab_fcfi_offline_cmpl_action(emlxs_port_t * port,uint32_t evt,void * arg1)6625 emlxs_fcoe_fcftab_fcfi_offline_cmpl_action(emlxs_port_t *port, uint32_t evt,
6626 void *arg1)
6627 {
6628 emlxs_hba_t *hba = HBA;
6629 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6630 uint32_t rval = 0;
6631
6632 if (fcftab->state != FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL) {
6633 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
6634 "fcoe_fcftab_fcfi_offline_cmpl_action:%x %s:%s arg=%p. "
6635 "Invalid state. <",
6636 fcftab->TID,
6637 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6638 emlxs_fcf_event_xlate(evt), arg1);
6639 return (1);
6640 }
6641
6642 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
6643 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6644 "fcoe_fcftab_fcfi_offline_cmpl_action:%x %s:%s arg=%p. "
6645 "Handling request.",
6646 fcftab->TID,
6647 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6648 emlxs_fcf_event_xlate(evt), arg1);
6649
6650 rval = emlxs_fcoe_fcftab_req_handler(port, arg1);
6651 return (rval);
6652 }
6653
6654 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6655 "fcoe_fcftab_fcfi_offline_cmpl_action:%x %s:%s arg=%p. "
6656 "Returning FCF(s) online.",
6657 fcftab->TID,
6658 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6659 emlxs_fcf_event_xlate(evt), arg1);
6660
6661 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_FCFI_ONLINE,
6662 FCF_REASON_EVENT, evt, arg1);
6663
6664 return (rval);
6665
6666 } /* emlxs_fcoe_fcftab_fcfi_offline_cmpl_action() */
6667
6668
6669 /*ARGSUSED*/
6670 static uint32_t
emlxs_fcoe_fcftab_found_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)6671 emlxs_fcoe_fcftab_found_evt_action(emlxs_port_t *port, uint32_t evt,
6672 void *arg1)
6673 {
6674 emlxs_hba_t *hba = HBA;
6675 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6676 uint32_t fcf_index = (uint32_t)((unsigned long)arg1);
6677 FCFIobj_t *fcfp;
6678 uint32_t rval = 0;
6679
6680 if (evt != FCF_EVENT_FCF_FOUND) {
6681 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6682 "fcoe_fcftab_found_evt_action:%x %s:%s fcf_index=%d. "
6683 "Invalid event type. <",
6684 fcftab->TID,
6685 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6686 emlxs_fcf_event_xlate(evt),
6687 fcf_index);
6688
6689 return (1);
6690 }
6691
6692 switch (fcftab->state) {
6693 case FCOE_FCFTAB_STATE_SOLICIT:
6694 case FCOE_FCFTAB_STATE_SOLICIT_CMPL:
6695 case FCOE_FCFTAB_STATE_READ:
6696 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6697 "fcoe_fcftab_found_evt_action:%x %s:%s "
6698 "fcf_index=%d gen=%x. <",
6699 fcftab->TID,
6700 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6701 emlxs_fcf_event_xlate(evt),
6702 fcf_index, fcftab->generation);
6703 break;
6704
6705 /* case FCOE_FCFTAB_STATE_FCFI_OFFLINE: */
6706 default:
6707
6708 /* Scan for matching fcf index in table */
6709 fcfp = emlxs_fcfi_find(port, 0, &fcf_index);
6710
6711 if (fcfp && (fcfp->flag & EMLXS_FCFI_SELECTED)) {
6712
6713 /* Trigger table read */
6714 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
6715 fcftab->flag |= EMLXS_FCOE_FCFTAB_READ_REQ;
6716 fcftab->generation++;
6717
6718 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6719 "fcoe_fcftab_found_evt_action:%x %s:%s "
6720 "fcf_index=%d gen=%x. Read FCF table.",
6721 fcftab->TID,
6722 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6723 emlxs_fcf_event_xlate(evt),
6724 fcf_index, fcftab->generation);
6725
6726 rval = emlxs_fcoe_fcftab_state(port,
6727 FCOE_FCFTAB_STATE_READ,
6728 FCF_REASON_EVENT, evt, arg1);
6729
6730 break;
6731 }
6732
6733 /* Check if we need more FCF's */
6734 if (fcftab->fcfi_online < FCFTAB_MAX_FCFI_COUNT) {
6735
6736 /* Trigger table read */
6737 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
6738 fcftab->flag |= EMLXS_FCOE_FCFTAB_READ_REQ;
6739 fcftab->generation++;
6740
6741 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6742 "fcoe_fcftab_found_evt_action:%x %s:%s "
6743 "fcf_index=%d gen=%x fcfi_online=%d. "
6744 "Read FCF table.",
6745 fcftab->TID,
6746 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6747 emlxs_fcf_event_xlate(evt),
6748 fcf_index, fcftab->generation,
6749 fcftab->fcfi_online);
6750
6751 rval = emlxs_fcoe_fcftab_state(port,
6752 FCOE_FCFTAB_STATE_READ,
6753 FCF_REASON_EVENT, evt, arg1);
6754
6755 break;
6756 }
6757
6758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6759 "fcoe_fcftab_found_evt_action:%x %s:%s fcfi=%d. "
6760 "FCF not needed. <",
6761 fcftab->TID,
6762 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6763 emlxs_fcf_event_xlate(evt),
6764 fcf_index);
6765
6766 break;
6767 }
6768
6769 return (rval);
6770
6771 } /* emlxs_fcoe_fcftab_found_evt_action() */
6772
6773
6774 /*ARGSUSED*/
6775 static uint32_t
emlxs_fcoe_fcftab_lost_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)6776 emlxs_fcoe_fcftab_lost_evt_action(emlxs_port_t *port, uint32_t evt,
6777 void *arg1)
6778 {
6779 emlxs_hba_t *hba = HBA;
6780 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6781 FCFIobj_t *fcfp;
6782 uint32_t fcf_index = (uint32_t)((unsigned long)arg1);
6783 emlxs_port_t *vport;
6784 VPIobj_t *vpip;
6785 uint32_t i;
6786 uint32_t rval = 0;
6787
6788 if (evt != FCF_EVENT_FCF_LOST) {
6789 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6790 "fcoe_fcftab_lost_evt_action:%x %s:%s fcf_index=%d. "
6791 "Invalid event type. <",
6792 fcftab->TID,
6793 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6794 emlxs_fcf_event_xlate(evt),
6795 fcf_index);
6796
6797 return (1);
6798 }
6799
6800 /* Scan for matching fcf index in table */
6801 fcfp = emlxs_fcfi_find(port, 0, &fcf_index);
6802
6803 if (!fcfp) {
6804 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6805 "fcoe_fcftab_lost_evt_action:%x %s:%s fcf_index=%d. "
6806 "FCF not found. <",
6807 fcftab->TID,
6808 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6809 emlxs_fcf_event_xlate(evt),
6810 fcf_index);
6811
6812 return (0);
6813 }
6814
6815 if (!(fcfp->flag & EMLXS_FCFI_SELECTED)) {
6816 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6817 "fcoe_fcftab_changed_evt_action:%x %s:%s fcf_index=%d. "
6818 "FCF not selected. <",
6819 fcftab->TID,
6820 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6821 emlxs_fcf_event_xlate(evt),
6822 fcf_index);
6823
6824 return (0);
6825 }
6826
6827 /* Offline VPI's of this FCFI */
6828 for (i = 0; i <= hba->vpi_max; i++) {
6829 vport = &VPORT(i);
6830 vpip = vport->vpip;
6831
6832 if ((vpip->state == VPI_STATE_OFFLINE) ||
6833 (vpip->vfip->fcfp != fcfp)) {
6834 continue;
6835 }
6836
6837 /* Fabric logo is implied */
6838 emlxs_vpi_logo_handler(port, vpip);
6839
6840 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6841 "fcoe_fcftab_lost_evt_action:%x %s:%s fcf_index=%d gen=%x. "
6842 "Offlining VPI:%d. >",
6843 fcftab->TID,
6844 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6845 emlxs_fcf_event_xlate(evt),
6846 fcf_index, fcftab->generation,
6847 vpip->VPI);
6848
6849 (void) emlxs_vpi_event(port, FCF_EVENT_VPI_OFFLINE, vpip);
6850 }
6851
6852 switch (fcftab->state) {
6853 case FCOE_FCFTAB_STATE_SOLICIT:
6854 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6855 "fcoe_fcftab_lost_evt_action:%x %s gen=%x. "
6856 "Already soliciting. <",
6857 fcftab->TID,
6858 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6859 fcftab->generation);
6860 break;
6861
6862 default:
6863 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
6864 fcftab->flag |= EMLXS_FCOE_FCFTAB_SOL_REQ;
6865 fcftab->generation++;
6866
6867 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6868 "fcoe_fcftab_lost_evt_action:%x %s gen=%x. Soliciting.",
6869 fcftab->TID,
6870 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6871 fcftab->generation);
6872
6873 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT,
6874 FCF_REASON_EVENT, evt, arg1);
6875 break;
6876 }
6877
6878 return (rval);
6879
6880 } /* emlxs_fcoe_fcftab_lost_evt_action() */
6881
6882
6883 /*ARGSUSED*/
6884 static uint32_t
emlxs_fcoe_fcftab_changed_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)6885 emlxs_fcoe_fcftab_changed_evt_action(emlxs_port_t *port, uint32_t evt,
6886 void *arg1)
6887 {
6888 emlxs_hba_t *hba = HBA;
6889 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6890 FCFIobj_t *fcfp;
6891 uint32_t fcf_index = (uint32_t)((unsigned long)arg1);
6892 uint32_t rval = 0;
6893
6894 if (evt != FCF_EVENT_FCF_CHANGED) {
6895 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6896 "fcoe_fcftab_changed_evt_action:%x %s:%s fcf_index=%d. "
6897 "Invalid event type. <",
6898 fcftab->TID,
6899 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6900 emlxs_fcf_event_xlate(evt),
6901 fcf_index);
6902
6903 return (1);
6904 }
6905
6906 switch (fcftab->state) {
6907 case FCOE_FCFTAB_STATE_SOLICIT:
6908 case FCOE_FCFTAB_STATE_SOLICIT_CMPL:
6909 case FCOE_FCFTAB_STATE_READ:
6910 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6911 "fcoe_fcftab_changed_evt_action:%x %s:%s "
6912 "fcf_index=%d gen=%x. <",
6913 fcftab->TID,
6914 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6915 emlxs_fcf_event_xlate(evt),
6916 fcf_index, fcftab->generation);
6917 break;
6918
6919 /* case FCOE_FCFTAB_STATE_FCFI_OFFLINE: */
6920 default:
6921
6922 /* Scan for matching fcf index in table */
6923 fcfp = emlxs_fcfi_find(port, 0, &fcf_index);
6924
6925 if (fcfp && (fcfp->flag & EMLXS_FCFI_SELECTED)) {
6926
6927 /* Trigger table read */
6928 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
6929 fcftab->flag |= EMLXS_FCOE_FCFTAB_READ_REQ;
6930 fcftab->generation++;
6931
6932 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6933 "fcoe_fcftab_changed_evt_action:%x %s:%s "
6934 "fcf_index=%d gen=%x. Read FCF table.",
6935 fcftab->TID,
6936 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6937 emlxs_fcf_event_xlate(evt),
6938 fcf_index, fcftab->generation);
6939
6940 rval = emlxs_fcoe_fcftab_state(port,
6941 FCOE_FCFTAB_STATE_READ,
6942 FCF_REASON_EVENT, evt, arg1);
6943
6944 break;
6945 }
6946
6947 /* Check if we need more FCF's */
6948 if (fcftab->fcfi_online < FCFTAB_MAX_FCFI_COUNT) {
6949
6950 /* Trigger table read */
6951 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
6952 fcftab->flag |= EMLXS_FCOE_FCFTAB_READ_REQ;
6953 fcftab->generation++;
6954
6955 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6956 "fcoe_fcftab_changed_evt_action:%x %s:%s "
6957 "fcf_index=%d gen=%x fcfi_online=%d. "
6958 "Read FCF table.",
6959 fcftab->TID,
6960 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6961 emlxs_fcf_event_xlate(evt),
6962 fcf_index, fcftab->generation,
6963 fcftab->fcfi_online);
6964
6965 rval = emlxs_fcoe_fcftab_state(port,
6966 FCOE_FCFTAB_STATE_READ,
6967 FCF_REASON_EVENT, evt, arg1);
6968
6969 break;
6970 }
6971
6972 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
6973 "fcoe_fcftab_changed_evt_action:%x %s:%s fcfi=%d. "
6974 "FCF not needed. <",
6975 fcftab->TID,
6976 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
6977 emlxs_fcf_event_xlate(evt),
6978 fcf_index);
6979
6980 break;
6981 }
6982
6983 return (rval);
6984
6985 } /* emlxs_fcoe_fcftab_changed_evt_action() */
6986
6987
6988 /*ARGSUSED*/
6989 static uint32_t
emlxs_fcoe_fcftab_fcf_delete(emlxs_port_t * port,uint32_t fcf_index)6990 emlxs_fcoe_fcftab_fcf_delete(emlxs_port_t *port, uint32_t fcf_index)
6991 {
6992 emlxs_hba_t *hba = HBA;
6993 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
6994 MAILBOXQ *mbq;
6995 MAILBOX4 *mb4;
6996 MATCHMAP *mp = NULL;
6997 uint32_t rval = 0;
6998
6999 IOCTL_FCOE_DELETE_FCF_TABLE *fcf;
7000 mbox_req_hdr_t *hdr_req;
7001
7002 if (fcf_index >= fcftab->fcfi_count) {
7003 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7004 "fcoe_fcftab_fcf_delete:%x fcfi:%d failed. "
7005 "Out of range.",
7006 fcftab->TID,
7007 fcf_index);
7008
7009 return (1);
7010 }
7011
7012 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
7013 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7014 "fcoe_fcftab_fcf_delete:%x fcfi:%d failed. "
7015 "Unable to allocate mailbox.",
7016 fcftab->TID,
7017 fcf_index);
7018
7019 return (1);
7020 }
7021
7022 mb4 = (MAILBOX4*)mbq;
7023 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
7024
7025 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
7026 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7027 "fcoe_fcftab_fcf_delete:%x fcfi:%d failed. "
7028 "Unable to allocate buffer.",
7029 fcftab->TID,
7030 fcf_index);
7031
7032 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
7033 return (1);
7034 }
7035 bzero(mp->virt, mp->size);
7036
7037 mbq->nonembed = (void *)mp;
7038 mbq->mbox_cmpl = NULL;
7039 mbq->context = (void *)((unsigned long)fcf_index);
7040 mbq->port = (void *)port;
7041
7042 mb4->un.varSLIConfig.be.embedded = 0;
7043 mb4->mbxCommand = MBX_SLI_CONFIG;
7044 mb4->mbxOwner = OWN_HOST;
7045
7046 hdr_req = (mbox_req_hdr_t *)mp->virt;
7047 hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE;
7048 hdr_req->opcode = FCOE_OPCODE_DELETE_FCF_TABLE;
7049 hdr_req->timeout = 0;
7050 hdr_req->req_length = sizeof (IOCTL_FCOE_DELETE_FCF_TABLE);
7051
7052 fcf = (IOCTL_FCOE_DELETE_FCF_TABLE *)(hdr_req + 1);
7053 fcf->params.request.fcf_count = 1;
7054 fcf->params.request.fcf_indexes[0] = (uint16_t)fcf_index;
7055
7056 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7057 "fcoe_fcftab_fcf_delete:%x fcfi:%d. <",
7058 fcftab->TID,
7059 fcf_index);
7060
7061 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
7062 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
7063 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7064 "fcoe_fcftab_fcf_delete:%x fcfi:%d failed. "
7065 "Unable to send request.",
7066 fcftab->TID,
7067 fcf_index);
7068
7069 if (mp) {
7070 emlxs_mem_put(hba, MEM_BUF, (void *)mp);
7071 }
7072 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
7073
7074 return (1);
7075 }
7076
7077 return (0);
7078
7079
7080 } /* emlxs_fcoe_fcftab_fcf_delete() */
7081
7082
7083 /*ARGSUSED*/
7084 static uint32_t
emlxs_fcoe_fcftab_full_evt_action(emlxs_port_t * port,uint32_t evt,void * arg1)7085 emlxs_fcoe_fcftab_full_evt_action(emlxs_port_t *port, uint32_t evt,
7086 void *arg1)
7087 {
7088 emlxs_hba_t *hba = HBA;
7089 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
7090 FCFIobj_t *fcfp;
7091 uint32_t rval = 0;
7092 uint32_t mask;
7093 uint32_t viable;
7094 uint32_t i;
7095 uint32_t count;
7096
7097 if (evt != FCF_EVENT_FCFTAB_FULL) {
7098 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7099 "fcoe_fcftab_full_evt_action:%x %s:%s arg=%p. "
7100 "Invalid event type. <",
7101 fcftab->TID,
7102 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7103 emlxs_fcf_event_xlate(evt), arg1);
7104
7105 return (1);
7106 }
7107
7108 if (fcftab->fcfi_online == FCFTAB_MAX_FCFI_COUNT) {
7109 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7110 "fcoe_fcftab_full_evt_action:%x %s:%s arg=%p "
7111 "fcfi_online=%d. <",
7112 fcftab->TID,
7113 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7114 emlxs_fcf_event_xlate(evt), arg1,
7115 fcftab->fcfi_online);
7116
7117 return (0);
7118 }
7119
7120 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7121 "fcoe_fcftab_full_evt_action:%x %s:%s arg=%p fcfi_online=%d. "
7122 "Cleaning table...",
7123 fcftab->TID,
7124 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7125 emlxs_fcf_event_xlate(evt), arg1,
7126 fcftab->fcfi_online);
7127
7128 mask = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE|
7129 EMLXS_FCFI_CONFIGURED);
7130 viable = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE|
7131 EMLXS_FCFI_CONFIGURED);
7132
7133 count = 0;
7134 fcfp = fcftab->table;
7135 for (i = 0; i < fcftab->table_count; i++, fcfp++) {
7136 if (fcfp->state == FCFI_STATE_FREE) {
7137 continue;
7138 }
7139
7140 if (fcfp->flag & EMLXS_FCFI_SELECTED) {
7141 continue;
7142 }
7143
7144 if ((fcfp->flag & mask) == viable) {
7145 continue;
7146 }
7147
7148 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7149 "fcoe_fcftab_full_evt_action:%x. "
7150 "Deleting FCFI:%d %x. >",
7151 fcftab->TID,
7152 fcfp->fcf_index,
7153 fcfp->flag);
7154
7155 (void) emlxs_fcfi_free(port, fcfp);
7156
7157 (void) emlxs_fcoe_fcftab_fcf_delete(port, fcfp->fcf_index);
7158
7159 count++;
7160 }
7161
7162 if (!count) {
7163 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7164 "fcoe_fcftab_full_evt_action:%x %s:%s arg=%p. "
7165 "All FCF's are viable. <",
7166 fcftab->TID,
7167 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7168 emlxs_fcf_event_xlate(evt), arg1);
7169
7170 return (0);
7171 }
7172
7173 switch (fcftab->state) {
7174 case FCOE_FCFTAB_STATE_SOLICIT:
7175 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7176 "fcoe_fcftab_full_evt_action:%x %s gen=%x. "
7177 "Already soliciting. <",
7178 fcftab->TID,
7179 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7180 fcftab->generation);
7181 break;
7182
7183 default:
7184 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK;
7185 fcftab->flag |= EMLXS_FCOE_FCFTAB_SOL_REQ;
7186 fcftab->generation++;
7187
7188 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7189 "fcoe_fcftab_full_evt_action:%x %s gen=%x. Soliciting.",
7190 fcftab->TID,
7191 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7192 fcftab->generation);
7193
7194 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT,
7195 FCF_REASON_EVENT, evt, arg1);
7196 break;
7197 }
7198
7199 return (rval);
7200
7201 } /* emlxs_fcoe_fcftab_full_evt_action() */
7202
7203
7204 /*ARGSUSED*/
7205 static uint32_t
emlxs_fcoe_fcftab_online_action(emlxs_port_t * port,uint32_t evt,void * arg1)7206 emlxs_fcoe_fcftab_online_action(emlxs_port_t *port, uint32_t evt,
7207 void *arg1)
7208 {
7209 emlxs_hba_t *hba = HBA;
7210 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
7211 emlxs_config_t *cfg = &CFG;
7212 FCFIobj_t *fcfp;
7213 uint32_t rval = 0;
7214 uint32_t mask;
7215 uint32_t viable;
7216 uint32_t i;
7217 uint32_t count = 0;
7218
7219 if (fcftab->state != FCOE_FCFTAB_STATE_ONLINE) {
7220 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
7221 "fcoe_fcftab_online_action:%x %s:%s arg=%p. "
7222 "Invalid state. <",
7223 fcftab->TID,
7224 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7225 emlxs_fcf_event_xlate(evt), arg1);
7226 return (1);
7227 }
7228
7229 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
7230 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7231 "fcoe_fcftab_online_action:%x flag=%x. "
7232 "Handling request.",
7233 fcftab->TID,
7234 fcftab->flag);
7235
7236 rval = emlxs_fcoe_fcftab_req_handler(port, arg1);
7237 return (rval);
7238 }
7239
7240 if (fcftab->fcfi_online == 0) {
7241 mask = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE|
7242 EMLXS_FCFI_CONFIGURED);
7243 viable = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE|
7244 EMLXS_FCFI_CONFIGURED);
7245
7246 /* Count viable FCF's in table */
7247 count = 0;
7248 fcfp = fcftab->table;
7249 for (i = 0; i < fcftab->table_count; i++, fcfp++) {
7250 if (fcfp->state == FCFI_STATE_FREE) {
7251 continue;
7252 }
7253
7254 if ((fcfp->flag & mask) == viable) {
7255 count++;
7256 }
7257 }
7258
7259 if (count) {
7260 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7261 "fcoe_fcftab_online_action:%x %s:%s "
7262 "fcfi_online=0,%d,%d. Starting resolicit timer. <",
7263 fcftab->TID,
7264 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7265 emlxs_fcf_event_xlate(evt),
7266 fcftab->fcfi_count, count);
7267
7268 /* Start the solicit timer */
7269 fcftab->sol_timer = hba->timer_tics +
7270 cfg[CFG_FCF_RESOLICIT_DELAY].current;
7271 } else {
7272 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7273 "fcoe_fcftab_online_action:%x %s:%s "
7274 "fcfi_online=0,%d,0. Wait for FCF event. <",
7275 fcftab->TID,
7276 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7277 emlxs_fcf_event_xlate(evt),
7278 fcftab->fcfi_count);
7279 }
7280
7281 emlxs_fcf_linkdown(port);
7282
7283 return (0);
7284 }
7285
7286 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7287 "fcoe_fcftab_online_action:%x flag=%x fcfi_online=%d. "
7288 "Online. <",
7289 fcftab->TID,
7290 fcftab->flag,
7291 fcftab->fcfi_online);
7292
7293 emlxs_fcf_linkup(port);
7294
7295 return (rval);
7296
7297 } /* emlxs_fcoe_fcftab_online_action() */
7298
7299
7300 /*ARGSUSED*/
7301 static uint32_t
emlxs_fcoe_fcftab_offline_action(emlxs_port_t * port,uint32_t evt,void * arg1)7302 emlxs_fcoe_fcftab_offline_action(emlxs_port_t *port, uint32_t evt,
7303 void *arg1)
7304 {
7305 emlxs_hba_t *hba = HBA;
7306 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
7307 uint32_t rval = 0;
7308
7309 if (fcftab->state != FCOE_FCFTAB_STATE_OFFLINE) {
7310 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
7311 "fcoe_fcftab_offline_action:%x %s:%s arg=%p. "
7312 "Invalid state. <",
7313 fcftab->TID,
7314 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7315 emlxs_fcf_event_xlate(evt), arg1);
7316 return (1);
7317 }
7318
7319
7320 fcftab->flag &= ~EMLXS_FCOE_FCFTAB_OFFLINE_REQ;
7321
7322 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) {
7323 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7324 "fcoe_fcftab_offline_action:%x %s:%s arg=%p flag=%x. "
7325 "Handling request.",
7326 fcftab->TID,
7327 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7328 emlxs_fcf_event_xlate(evt), arg1,
7329 fcftab->flag);
7330
7331 rval = emlxs_fcoe_fcftab_req_handler(port, arg1);
7332 return (rval);
7333 }
7334
7335 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7336 "fcoe_fcftab_offline_action:%x %s:%s arg=%p fcfi_online=%d. "
7337 "Offline. <",
7338 fcftab->TID,
7339 emlxs_fcoe_fcftab_state_xlate(fcftab->state),
7340 emlxs_fcf_event_xlate(evt), arg1,
7341 fcftab->fcfi_online);
7342
7343 return (rval);
7344
7345 } /* emlxs_fcoe_fcftab_offline_action() */
7346
7347
7348 /* ************************************************************************** */
7349 /* FCFI */
7350 /* ************************************************************************** */
7351
7352 static char *
emlxs_fcfi_state_xlate(uint32_t state)7353 emlxs_fcfi_state_xlate(uint32_t state)
7354 {
7355 static char buffer[32];
7356 uint32_t i;
7357 uint32_t count;
7358
7359 count = sizeof (emlxs_fcfi_state_table) / sizeof (emlxs_table_t);
7360 for (i = 0; i < count; i++) {
7361 if (state == emlxs_fcfi_state_table[i].code) {
7362 return (emlxs_fcfi_state_table[i].string);
7363 }
7364 }
7365
7366 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state);
7367 return (buffer);
7368
7369 } /* emlxs_fcfi_state_xlate() */
7370
7371
7372 static uint32_t
emlxs_fcfi_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)7373 emlxs_fcfi_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
7374 void *arg1)
7375 {
7376 uint32_t rval = 0;
7377 uint32_t(*func) (emlxs_port_t *, FCFIobj_t *, uint32_t, void *);
7378 uint32_t index;
7379 uint32_t events;
7380 uint16_t state;
7381
7382 /* Convert event to action table index */
7383 switch (evt) {
7384 case FCF_EVENT_STATE_ENTER:
7385 index = 0;
7386 break;
7387 case FCF_EVENT_FCFI_ONLINE:
7388 index = 1;
7389 break;
7390 case FCF_EVENT_FCFI_OFFLINE:
7391 index = 2;
7392 break;
7393 case FCF_EVENT_FCFI_PAUSE:
7394 index = 3;
7395 break;
7396 case FCF_EVENT_VFI_ONLINE:
7397 index = 4;
7398 break;
7399 case FCF_EVENT_VFI_OFFLINE:
7400 index = 5;
7401 break;
7402 default:
7403 return (1);
7404 }
7405
7406 events = FCFI_ACTION_EVENTS;
7407 state = fcfp->state;
7408
7409 index += (state * events);
7410 func = (uint32_t(*) (emlxs_port_t *, FCFIobj_t *, uint32_t, void *))
7411 emlxs_fcfi_action_table[index];
7412
7413 if (!func) {
7414 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
7415 "fcfi_action:%d %s:%s arg=%p. No action. <",
7416 fcfp->fcf_index,
7417 emlxs_fcfi_state_xlate(fcfp->state),
7418 emlxs_fcf_event_xlate(evt), arg1);
7419
7420 return (1);
7421 }
7422
7423 rval = (func)(port, fcfp, evt, arg1);
7424
7425 return (rval);
7426
7427 } /* emlxs_fcfi_action() */
7428
7429
7430 static uint32_t
emlxs_fcfi_event(emlxs_port_t * port,uint32_t evt,void * arg1)7431 emlxs_fcfi_event(emlxs_port_t *port, uint32_t evt,
7432 void *arg1)
7433 {
7434 FCFIobj_t *fcfp = NULL;
7435 VFIobj_t *vfip = NULL;
7436 uint32_t rval = 0;
7437
7438 /* Filter events and acquire fcfi context */
7439 switch (evt) {
7440 case FCF_EVENT_VFI_ONLINE:
7441 case FCF_EVENT_VFI_OFFLINE:
7442 vfip = (VFIobj_t *)arg1;
7443
7444 if (!vfip) {
7445 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
7446 "fcfi_event: %s arg=%p. Null VFI found. <",
7447 emlxs_fcf_event_xlate(evt), arg1);
7448
7449 return (1);
7450 }
7451
7452 fcfp = vfip->fcfp;
7453 if (!fcfp) {
7454 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
7455 "fcfi_event: %s arg=%p. FCF not found. <",
7456 emlxs_fcf_event_xlate(evt), arg1);
7457
7458 return (1);
7459 }
7460 break;
7461
7462 case FCF_EVENT_FCFI_ONLINE:
7463 case FCF_EVENT_FCFI_OFFLINE:
7464 case FCF_EVENT_FCFI_PAUSE:
7465 fcfp = (FCFIobj_t *)arg1;
7466 if (!fcfp) {
7467 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
7468 "fcfi_event: %s arg=%p. Null FCFI found. <",
7469 emlxs_fcf_event_xlate(evt), arg1);
7470
7471 return (1);
7472 }
7473 break;
7474
7475 default:
7476 return (1);
7477 }
7478
7479 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
7480 "fcfi_event:%d %s:%s arg=%p",
7481 fcfp->fcf_index,
7482 emlxs_fcfi_state_xlate(fcfp->state),
7483 emlxs_fcf_event_xlate(evt), arg1);
7484
7485 rval = emlxs_fcfi_action(port, fcfp, evt, arg1);
7486
7487 return (rval);
7488
7489 } /* emlxs_fcfi_event() */
7490
7491
7492 /* EMLXS_FCF_LOCK must be held to enter */
7493 /*ARGSUSED*/
7494 static uint32_t
emlxs_fcfi_state(emlxs_port_t * port,FCFIobj_t * fcfp,uint16_t state,uint16_t reason,uint32_t explain,void * arg1)7495 emlxs_fcfi_state(emlxs_port_t *port, FCFIobj_t *fcfp, uint16_t state,
7496 uint16_t reason, uint32_t explain, void *arg1)
7497 {
7498 uint32_t rval = 0;
7499
7500 if (state >= FCFI_ACTION_STATES) {
7501 return (1);
7502 }
7503
7504 if ((fcfp->state == state) &&
7505 (reason != FCF_REASON_REENTER)) {
7506 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
7507 "fcfi_state:%d %s:%s:0x%x arg=%p. "
7508 "State not changed. <",
7509 fcfp->fcf_index,
7510 emlxs_fcfi_state_xlate(state),
7511 emlxs_fcf_reason_xlate(reason),
7512 explain, arg1);
7513 return (1);
7514 }
7515
7516 if (!reason) {
7517 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
7518 "fcfi_state:%d %s-->%s arg=%p",
7519 fcfp->fcf_index,
7520 emlxs_fcfi_state_xlate(fcfp->state),
7521 emlxs_fcfi_state_xlate(state), arg1);
7522 } else if (reason == FCF_REASON_EVENT) {
7523 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
7524 "fcfi_state:%d %s-->%s:%s:%s arg=%p",
7525 fcfp->fcf_index,
7526 emlxs_fcfi_state_xlate(fcfp->state),
7527 emlxs_fcfi_state_xlate(state),
7528 emlxs_fcf_reason_xlate(reason),
7529 emlxs_fcf_event_xlate(explain), arg1);
7530 } else if (explain) {
7531 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
7532 "fcfi_state:%d %s-->%s:%s:0x%x arg=%p",
7533 fcfp->fcf_index,
7534 emlxs_fcfi_state_xlate(fcfp->state),
7535 emlxs_fcfi_state_xlate(state),
7536 emlxs_fcf_reason_xlate(reason),
7537 explain, arg1);
7538 } else {
7539 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
7540 "fcfi_state:%d %s-->%s:%s arg=%p",
7541 fcfp->fcf_index,
7542 emlxs_fcfi_state_xlate(fcfp->state),
7543 emlxs_fcfi_state_xlate(state),
7544 emlxs_fcf_reason_xlate(reason), arg1);
7545 }
7546
7547 fcfp->prev_state = fcfp->state;
7548 fcfp->prev_reason = fcfp->reason;
7549 fcfp->state = state;
7550 fcfp->reason = reason;
7551
7552 rval = emlxs_fcfi_action(port, fcfp, FCF_EVENT_STATE_ENTER, arg1);
7553
7554 return (rval);
7555
7556 } /* emlxs_fcfi_state() */
7557
7558
7559 static FCFIobj_t *
emlxs_fcfi_alloc(emlxs_port_t * port)7560 emlxs_fcfi_alloc(emlxs_port_t *port)
7561 {
7562 emlxs_hba_t *hba = HBA;
7563 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
7564 uint16_t i;
7565 FCFIobj_t *fcfp;
7566
7567 fcfp = fcftab->table;
7568 for (i = 0; i < fcftab->table_count; i++, fcfp++) {
7569 if (fcfp->state == FCFI_STATE_FREE) {
7570
7571 bzero(fcfp, sizeof (FCFIobj_t));
7572 fcfp->index = i;
7573 fcfp->FCFI = 0xFFFF;
7574
7575 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7576 "fcfi_alloc:%d. Allocating FCFI. >",
7577 fcfp->index);
7578
7579 (void) emlxs_fcfi_state(port, fcfp, FCFI_STATE_OFFLINE,
7580 0, 0, 0);
7581 return (fcfp);
7582 }
7583 }
7584
7585 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7586 "fcfi_alloc: Out of FCFI objects.",
7587 fcfp->index);
7588
7589 return (NULL);
7590
7591 } /* emlxs_fcfi_alloc() */
7592
7593
7594 static uint32_t
emlxs_fcfi_free(emlxs_port_t * port,FCFIobj_t * fcfp)7595 emlxs_fcfi_free(emlxs_port_t *port, FCFIobj_t *fcfp)
7596 {
7597 uint32_t rval = 0;
7598
7599 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_FREE, 0, 0, 0);
7600
7601 return (rval);
7602
7603 } /* emlxs_fcfi_free() */
7604
7605
7606 static FCFIobj_t *
emlxs_fcfi_find(emlxs_port_t * port,FCF_RECORD_t * fcfrec,uint32_t * fcf_index)7607 emlxs_fcfi_find(emlxs_port_t *port, FCF_RECORD_t *fcfrec, uint32_t *fcf_index)
7608 {
7609 emlxs_hba_t *hba = HBA;
7610 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
7611 uint32_t i;
7612 uint32_t index;
7613 FCFIobj_t *fcfp;
7614
7615 if (fcfrec) {
7616 /* Check for a matching FCF index, fabric name, */
7617 /* and mac address */
7618 fcfp = fcftab->table;
7619 for (i = 0; i < fcftab->table_count; i++, fcfp++) {
7620 if (fcfp->state == FCFI_STATE_FREE) {
7621 continue;
7622 }
7623
7624 if ((fcfp->fcf_index == fcfrec->fcf_index) &&
7625 (bcmp((char *)fcfrec->fabric_name_identifier,
7626 fcfp->fcf_rec.fabric_name_identifier, 8) == 0) &&
7627 (bcmp((char *)fcfrec->fcf_mac_address_hi,
7628 fcfp->fcf_rec.fcf_mac_address_hi, 4) == 0) &&
7629 (bcmp((char *)fcfrec->fcf_mac_address_low,
7630 fcfp->fcf_rec.fcf_mac_address_low, 2) == 0)) {
7631 return (fcfp);
7632 }
7633 }
7634
7635 } else if (fcf_index) {
7636 /* Check for a matching FCF index only */
7637 index = *fcf_index;
7638 fcfp = fcftab->table;
7639 for (i = 0; i < fcftab->table_count; i++, fcfp++) {
7640 if (fcfp->state == FCFI_STATE_FREE) {
7641 continue;
7642 }
7643
7644 if (fcfp->fcf_index == index) {
7645 return (fcfp);
7646 }
7647 }
7648 }
7649
7650 return (NULL);
7651
7652 } /* emlxs_fcfi_find() */
7653
7654
7655 /*ARGSUSED*/
7656 static uint32_t
emlxs_fcfi_free_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)7657 emlxs_fcfi_free_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
7658 void *arg1)
7659 {
7660
7661 if (fcfp->state != FCFI_STATE_FREE) {
7662 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
7663 "fcfi_free_action:%d %s:%s arg=%p. "
7664 "Invalid state. <",
7665 fcfp->fcf_index,
7666 emlxs_fcfi_state_xlate(fcfp->state),
7667 emlxs_fcf_event_xlate(evt), arg1);
7668 return (1);
7669 }
7670
7671 if (fcfp->vfi_online) {
7672 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
7673 "fcfi_free_action:%d flag=%x vfi_online=%d",
7674 fcfp->fcf_index,
7675 fcfp->flag,
7676 fcfp->vfi_online);
7677 }
7678
7679 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7680 "fcfi_free_action:%d flag=%x. FCF freed. <",
7681 fcfp->fcf_index,
7682 fcfp->flag);
7683
7684 fcfp->flag = 0;
7685
7686 return (0);
7687
7688 } /* emlxs_fcfi_free_action() */
7689
7690
7691 /*ARGSUSED*/
7692 static uint32_t
emlxs_fcfi_offline_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)7693 emlxs_fcfi_offline_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
7694 void *arg1)
7695 {
7696 emlxs_hba_t *hba = HBA;
7697 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
7698 uint32_t rval = 0;
7699
7700 if (fcfp->state != FCFI_STATE_OFFLINE) {
7701 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7702 "fcfi_offline_action:%d %s:%s arg=%p. "
7703 "Invalid state. <",
7704 fcfp->fcf_index,
7705 emlxs_fcfi_state_xlate(fcfp->state),
7706 emlxs_fcf_event_xlate(evt), arg1);
7707 return (1);
7708 }
7709
7710 fcfp->flag &= ~(EMLXS_FCFI_OFFLINE_REQ | EMLXS_FCFI_PAUSE_REQ);
7711
7712 if (fcfp->prev_state == FCFI_STATE_FREE) {
7713 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7714 "fcfi_offline_action:%d fcfi_online=%d. <",
7715 fcfp->fcf_index,
7716 fcftab->fcfi_online);
7717
7718 return (0);
7719 }
7720
7721 if (fcfp->vfi_online) {
7722 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
7723 "fcfi_offline_action:%d vfi_online=%d.",
7724 fcfp->fcf_index,
7725 fcfp->vfi_online);
7726 }
7727
7728 if (fcfp->flag & EMLXS_FCFI_FCFTAB) {
7729 fcfp->flag &= ~EMLXS_FCFI_FCFTAB;
7730
7731 if (fcftab->fcfi_online) {
7732 fcftab->fcfi_online--;
7733 }
7734 }
7735
7736 /* Check if online was requested */
7737 if (fcfp->flag & EMLXS_FCFI_ONLINE_REQ) {
7738
7739 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7740 "fcfi_offline_action:%d fcfi_online=%d. "
7741 "Online requested.",
7742 fcfp->fcf_index,
7743 fcftab->fcfi_online);
7744
7745 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG,
7746 FCF_REASON_REQUESTED, 0, arg1);
7747 return (rval);
7748 }
7749
7750 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7751 "fcfi_offline_action:%d fcfi_online=%d. "
7752 "FCFI offline. Notifying fcftab. >",
7753 fcfp->fcf_index,
7754 fcftab->fcfi_online);
7755
7756 /* Notify FCFTAB */
7757 rval = emlxs_fcftab_event(port, FCF_EVENT_FCFI_OFFLINE, fcfp);
7758
7759 return (rval);
7760
7761 } /* emlxs_fcfi_offline_action() */
7762
7763
7764 /*ARGSUSED*/
7765 static uint32_t
emlxs_fcfi_vfi_online_evt_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)7766 emlxs_fcfi_vfi_online_evt_action(emlxs_port_t *port, FCFIobj_t *fcfp,
7767 uint32_t evt, void *arg1)
7768 {
7769 uint32_t rval = 0;
7770
7771 if (evt != FCF_EVENT_VFI_ONLINE) {
7772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
7773 "fcfi_vfi_online_evt_action:%d %s:%s arg=%p flag=%x. "
7774 "Invalid event type. <",
7775 fcfp->fcf_index,
7776 emlxs_fcfi_state_xlate(fcfp->state),
7777 emlxs_fcf_event_xlate(evt), arg1,
7778 fcfp->flag);
7779 return (1);
7780 }
7781
7782 switch (fcfp->state) {
7783 case FCFI_STATE_ONLINE:
7784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7785 "fcfi_vfi_online_evt_action:%d flag=%x vfi_online=%d. "
7786 "Reentering online.",
7787 fcfp->fcf_index,
7788 fcfp->flag,
7789 fcfp->vfi_online);
7790
7791 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_ONLINE,
7792 FCF_REASON_REENTER, evt, arg1);
7793 break;
7794
7795 case FCFI_STATE_VFI_ONLINE:
7796 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7797 "fcfi_vfi_online_evt_action:%d flag=%x vfi_online=%d. "
7798 "Online cmpl.",
7799 fcfp->fcf_index,
7800 fcfp->flag,
7801 fcfp->vfi_online);
7802
7803 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_ONLINE_CMPL,
7804 FCF_REASON_EVENT, evt, arg1);
7805 break;
7806
7807 default:
7808 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7809 "fcfi_vfi_online_evt_action:%d flag=%x vfi_online=%d. <",
7810 fcfp->fcf_index,
7811 fcfp->flag,
7812 fcfp->vfi_online);
7813 return (0);
7814 }
7815
7816 return (rval);
7817
7818 } /* emlxs_fcfi_vfi_online_evt_action() */
7819
7820
7821 /*ARGSUSED*/
7822 static uint32_t
emlxs_fcfi_offline_handler(emlxs_port_t * port,FCFIobj_t * fcfp,void * arg1)7823 emlxs_fcfi_offline_handler(emlxs_port_t *port, FCFIobj_t *fcfp, void *arg1)
7824 {
7825 uint32_t rval = 0;
7826
7827 if (!(fcfp->flag & EMLXS_FCFI_OFFLINE_REQ)) {
7828 return (0);
7829 }
7830
7831 if (fcfp->vfi_online) {
7832 if (fcfp->flag & EMLXS_FCFI_PAUSE_REQ) {
7833 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_PAUSED,
7834 FCF_REASON_REQUESTED, 0, arg1);
7835 } else {
7836 rval = emlxs_fcfi_state(port, fcfp,
7837 FCFI_STATE_VFI_OFFLINE, FCF_REASON_REQUESTED,
7838 0, arg1);
7839 }
7840
7841 } else if (fcfp->flag & EMLXS_FCFI_REG) {
7842 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG,
7843 FCF_REASON_REQUESTED, 0, arg1);
7844
7845 } else {
7846 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_OFFLINE,
7847 FCF_REASON_REQUESTED, 0, arg1);
7848 }
7849
7850 return (rval);
7851
7852 } /* emlxs_fcfi_offline_handler() */
7853
7854
7855 /*ARGSUSED*/
7856 static uint32_t
emlxs_fcfi_vfi_offline_evt_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)7857 emlxs_fcfi_vfi_offline_evt_action(emlxs_port_t *port, FCFIobj_t *fcfp,
7858 uint32_t evt, void *arg1)
7859 {
7860 uint32_t rval = 0;
7861 VFIobj_t *vfip;
7862
7863 if (evt != FCF_EVENT_VFI_OFFLINE) {
7864 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
7865 "fcfi_vfi_offline_evt_action:%d %s:%s arg=%p flag=%x. "
7866 "Invalid event type. <",
7867 fcfp->fcf_index,
7868 emlxs_fcfi_state_xlate(fcfp->state),
7869 emlxs_fcf_event_xlate(evt), arg1,
7870 fcfp->flag);
7871 return (1);
7872 }
7873
7874 vfip = (VFIobj_t *)arg1;
7875 vfip->fcfp = NULL;
7876
7877 switch (fcfp->state) {
7878 case FCFI_STATE_VFI_ONLINE:
7879 case FCFI_STATE_ONLINE:
7880 if (fcfp->vfi_online == 0) {
7881 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7882 "fcfi_vfi_offline_evt_action:%d flag=%x "
7883 "vfi_online=%d. Offlining.",
7884 fcfp->fcf_index,
7885 fcfp->flag, fcfp->vfi_online);
7886
7887 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK;
7888 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ;
7889
7890 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1);
7891 } else {
7892 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7893 "fcfi_vfi_offline_evt_action:%d flag=%x "
7894 "vfi_online=%d. <",
7895 fcfp->fcf_index,
7896 fcfp->flag, fcfp->vfi_online);
7897 }
7898 break;
7899
7900 case FCFI_STATE_PAUSED:
7901 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7902 "fcfi_vfi_offline_evt_action:%d flag=%x vfi_online=%d. <",
7903 fcfp->fcf_index,
7904 fcfp->flag, fcfp->vfi_online);
7905 break;
7906
7907 case FCFI_STATE_VFI_OFFLINE:
7908 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7909 "fcfi_vfi_offline_evt_action:%d flag=%x. Offline cmpl.",
7910 fcfp->fcf_index,
7911 fcfp->flag);
7912
7913 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_OFFLINE_CMPL,
7914 FCF_REASON_EVENT, evt, arg1);
7915 break;
7916
7917 case FCFI_STATE_VFI_OFFLINE_CMPL:
7918 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7919 "fcfi_vfi_offline_evt_action:%d flag=%x. Offline cmpl.",
7920 fcfp->fcf_index,
7921 fcfp->flag);
7922
7923 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_OFFLINE_CMPL,
7924 FCF_REASON_REENTER, evt, arg1);
7925 break;
7926
7927 default:
7928 if (fcfp->vfi_online == 0) {
7929 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7930 "fcfi_vfi_offline_evt_action:%d flag=%x "
7931 "vfi_online=%d. Offline requested. <",
7932 fcfp->fcf_index,
7933 fcfp->flag, fcfp->vfi_online);
7934
7935 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK;
7936 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ;
7937 } else {
7938 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7939 "fcfi_vfi_offline_evt_action:%d flag = %x "
7940 "vfi_online=%d. <",
7941 fcfp->fcf_index,
7942 fcfp->flag, fcfp->vfi_online);
7943 }
7944 return (0);
7945 }
7946
7947 return (rval);
7948
7949 } /* emlxs_fcfi_vfi_offline_evt_action() */
7950
7951
7952 /*ARGSUSED*/
7953 static uint32_t
emlxs_fcfi_online_evt_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)7954 emlxs_fcfi_online_evt_action(emlxs_port_t *port, FCFIobj_t *fcfp,
7955 uint32_t evt, void *arg1)
7956 {
7957 uint32_t rval = 0;
7958
7959 if (evt != FCF_EVENT_FCFI_ONLINE) {
7960 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
7961 "fcfi_online_evt_action:%d %s:%s arg=%p. "
7962 "Invalid event type. <",
7963 fcfp->fcf_index,
7964 emlxs_fcfi_state_xlate(fcfp->state),
7965 emlxs_fcf_event_xlate(evt), arg1);
7966 return (1);
7967 }
7968
7969 if (fcfp->flag & EMLXS_FCFI_ONLINE_REQ) {
7970 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7971 "fcfi_online_evt_action:%d. "
7972 "Online already requested. <",
7973 fcfp->fcf_index);
7974 return (1);
7975 }
7976
7977 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK;
7978 fcfp->flag |= EMLXS_FCFI_ONLINE_REQ;
7979
7980 switch (fcfp->state) {
7981 case FCFI_STATE_OFFLINE:
7982 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7983 "fcfi_online_evt_action:%d flag=%x. Initiating online.",
7984 fcfp->fcf_index,
7985 fcfp->flag);
7986
7987 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG,
7988 FCF_REASON_EVENT, evt, arg1);
7989 break;
7990
7991 case FCFI_STATE_VFI_OFFLINE:
7992 case FCFI_STATE_PAUSED:
7993 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
7994 "fcfi_online_evt_action:%d flag=%x. Initiating online.",
7995 fcfp->fcf_index,
7996 fcfp->flag);
7997
7998 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_ONLINE,
7999 FCF_REASON_EVENT, evt, arg1);
8000 break;
8001
8002 case FCFI_STATE_ONLINE:
8003 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8004 "fcfi_online_evt_action:%d flag=%x. Reentering online.",
8005 fcfp->fcf_index,
8006 fcfp->flag);
8007
8008 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_ONLINE,
8009 FCF_REASON_REENTER, evt, arg1);
8010 break;
8011
8012 default:
8013 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8014 "fcfi_online_evt_action:%d flag=%x. <",
8015 fcfp->fcf_index,
8016 fcfp->flag);
8017 break;
8018 }
8019
8020 return (rval);
8021
8022 } /* emlxs_fcfi_online_evt_action() */
8023
8024
8025 /*ARGSUSED*/
8026 static uint32_t
emlxs_fcfi_vfi_online_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8027 emlxs_fcfi_vfi_online_action(emlxs_port_t *port, FCFIobj_t *fcfp,
8028 uint32_t evt, void *arg1)
8029 {
8030 emlxs_hba_t *hba = HBA;
8031 uint32_t i;
8032 uint32_t rval = 0;
8033 VFIobj_t *vfip;
8034
8035 if (fcfp->state != FCFI_STATE_VFI_ONLINE) {
8036 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8037 "fcfi_vfi_online_action:%d %s:%s arg=%p. "
8038 "Invalid state. <",
8039 fcfp->fcf_index,
8040 emlxs_fcfi_state_xlate(fcfp->state),
8041 emlxs_fcf_event_xlate(evt), arg1);
8042 return (1);
8043 }
8044
8045 if (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) {
8046 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8047 "fcfi_vfi_online_action:%d. Offline requested.",
8048 fcfp->fcf_index);
8049
8050 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1);
8051 return (rval);
8052 }
8053
8054 if (fcfp->vfi_online > 0) {
8055 /* Waking up out after being paused */
8056
8057 /* Find first VFI of this FCFI */
8058 vfip = hba->sli.sli4.VFI_table;
8059 for (i = 0; i < hba->sli.sli4.VFICount; i++, vfip++) {
8060 if (vfip->fcfp == fcfp) {
8061 break;
8062 }
8063 }
8064
8065 } else {
8066
8067 /* Find first available VFI */
8068 vfip = hba->sli.sli4.VFI_table;
8069 for (i = 0; i < hba->sli.sli4.VFICount; i++, vfip++) {
8070 if (vfip->fcfp == NULL) {
8071 vfip->fcfp = fcfp;
8072 break;
8073 }
8074 }
8075 }
8076
8077 if (i == hba->sli.sli4.VFICount) {
8078 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8079 "fcfi_vfi_online_action:%d vfi_online=%d. "
8080 "No VFI found. Offlining.",
8081 fcfp->fcf_index,
8082 fcfp->vfi_online);
8083
8084 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK;
8085 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ;
8086
8087 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1);
8088 return (rval);
8089 }
8090
8091 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8092 "fcfi_vfi_online_action:%d vfi_online=%d. Onlining VFI:%d. >",
8093 fcfp->fcf_index,
8094 fcfp->vfi_online,
8095 vfip->VFI);
8096
8097 rval = emlxs_vfi_event(port, FCF_EVENT_VFI_ONLINE, vfip);
8098
8099 /* Wait for FCF_EVENT_VFI_ONLINE in return */
8100
8101 return (rval);
8102
8103 } /* emlxs_fcfi_vfi_online_action() */
8104
8105
8106 /*ARGSUSED*/
8107 static uint32_t
emlxs_fcfi_vfi_online_cmpl_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8108 emlxs_fcfi_vfi_online_cmpl_action(emlxs_port_t *port, FCFIobj_t *fcfp,
8109 uint32_t evt, void *arg1)
8110 {
8111 uint32_t rval = 0;
8112
8113 if (fcfp->state != FCFI_STATE_VFI_ONLINE_CMPL) {
8114 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8115 "fcfi_vfi_online_cmpl_action:%d %s:%s arg=%p. "
8116 "Invalid state. <",
8117 fcfp->fcf_index,
8118 emlxs_fcfi_state_xlate(fcfp->state),
8119 emlxs_fcf_event_xlate(evt), arg1);
8120 return (1);
8121 }
8122
8123 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8124 "fcfi_vfi_online_cmpl_action:%d. Going online.",
8125 fcfp->fcf_index);
8126
8127 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_ONLINE,
8128 FCF_REASON_EVENT, evt, arg1);
8129
8130 return (rval);
8131
8132 } /* emlxs_fcfi_vfi_online_cmpl_action() */
8133
8134
8135 /*ARGSUSED*/
8136 static uint32_t
emlxs_fcfi_vfi_offline_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8137 emlxs_fcfi_vfi_offline_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
8138 void *arg1)
8139 {
8140 emlxs_hba_t *hba = HBA;
8141 VFIobj_t *vfip;
8142 uint32_t rval = 0;
8143 int32_t i;
8144
8145 if (fcfp->state != FCFI_STATE_VFI_OFFLINE) {
8146 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8147 "fcfi_vfi_offline_action:%d %s:%s arg=%p. "
8148 "Invalid state. <",
8149 fcfp->fcf_index,
8150 emlxs_fcfi_state_xlate(fcfp->state),
8151 emlxs_fcf_event_xlate(evt), arg1);
8152
8153 return (1);
8154 }
8155
8156 if (fcfp->flag & EMLXS_FCFI_PAUSE_REQ) {
8157 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8158 "fcfi_vfi_offline_action:%d vfi_online=%d. Pausing.",
8159 fcfp->fcf_index,
8160 fcfp->vfi_online);
8161
8162 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_PAUSED,
8163 FCF_REASON_EVENT, evt, arg1);
8164
8165 return (rval);
8166 }
8167
8168 if (fcfp->vfi_online == 0) {
8169 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8170 "fcfi_vfi_offline_action:%d. "
8171 "VFI already offline. Skipping VFI offline.",
8172 fcfp->fcf_index);
8173
8174 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG,
8175 FCF_REASON_EVENT, evt, arg1);
8176
8177 return (rval);
8178 }
8179
8180 /* Offline VFI's of this FCFI */
8181 for (i = (hba->sli.sli4.VFICount-1); i >= 0; i--) {
8182 vfip = &hba->sli.sli4.VFI_table[i];
8183
8184 if ((vfip->fcfp != fcfp) ||
8185 (vfip->state == VFI_STATE_OFFLINE) ||
8186 (vfip->flag & EMLXS_VFI_OFFLINE_REQ)) {
8187 continue;
8188 }
8189
8190 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8191 "fcfi_vfi_offline_action:%d. Offlining VFI:%d >",
8192 fcfp->fcf_index,
8193 vfip->VFI);
8194
8195 (void) emlxs_vfi_event(port, FCF_EVENT_VFI_OFFLINE, vfip);
8196 }
8197
8198 /* Wait for FCF_EVENT_VFI_OFFLINE in return */
8199
8200 return (0);
8201
8202 } /* emlxs_fcfi_vfi_offline_action() */
8203
8204
8205 /*ARGSUSED*/
8206 static uint32_t
emlxs_fcfi_paused_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8207 emlxs_fcfi_paused_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
8208 void *arg1)
8209 {
8210 emlxs_hba_t *hba = HBA;
8211 VFIobj_t *vfip;
8212 int32_t i;
8213
8214 if (fcfp->state != FCFI_STATE_PAUSED) {
8215 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8216 "fcfi_paused_action:%d %s:%s arg=%p. "
8217 "Invalid state. <",
8218 fcfp->fcf_index,
8219 emlxs_fcfi_state_xlate(fcfp->state),
8220 emlxs_fcf_event_xlate(evt), arg1);
8221
8222 return (1);
8223 }
8224
8225 fcfp->flag &= ~(EMLXS_FCFI_OFFLINE_REQ | EMLXS_FCFI_PAUSE_REQ);
8226
8227 /* Pause all VFI's of this FCFI */
8228 for (i = (hba->sli.sli4.VFICount-1); i >= 0; i--) {
8229 vfip = &hba->sli.sli4.VFI_table[i];
8230
8231 if ((vfip->state == VFI_STATE_OFFLINE) ||
8232 (vfip->state == VFI_STATE_PAUSED) ||
8233 (vfip->fcfp != fcfp)) {
8234 continue;
8235 }
8236
8237 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8238 "fcfi_paused_action:%d vfi_online=%d. Pausing VFI:%d. >",
8239 fcfp->fcf_index,
8240 fcfp->vfi_online,
8241 vfip->VFI);
8242
8243 (void) emlxs_vfi_event(port, FCF_EVENT_VFI_PAUSE, vfip);
8244 }
8245
8246 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8247 "fcfi_paused_action:%d vfi_online=%d. FCFI paused. <",
8248 fcfp->fcf_index,
8249 fcfp->vfi_online);
8250
8251 return (0);
8252
8253 } /* emlxs_fcfi_paused_action() */
8254
8255
8256 /*ARGSUSED*/
8257 static uint32_t
emlxs_fcfi_vfi_offline_cmpl_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8258 emlxs_fcfi_vfi_offline_cmpl_action(emlxs_port_t *port, FCFIobj_t *fcfp,
8259 uint32_t evt, void *arg1)
8260 {
8261 uint32_t rval = 0;
8262
8263 if (fcfp->state != FCFI_STATE_VFI_OFFLINE_CMPL) {
8264 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8265 "fcfi_vfi_offline_cmpl_action:%d %s:%s arg=%p. "
8266 "Invalid state. <",
8267 fcfp->fcf_index,
8268 emlxs_fcfi_state_xlate(fcfp->state),
8269 emlxs_fcf_event_xlate(evt), arg1);
8270 return (1);
8271 }
8272
8273 if ((fcfp->vfi_online == 0) &&
8274 (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ)) {
8275 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8276 "fcfi_vfi_offline_cmpl_action:%d vfi_online=%d. "
8277 "Unregistering.",
8278 fcfp->fcf_index,
8279 fcfp->vfi_online);
8280
8281 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG,
8282 FCF_REASON_EVENT, evt, arg1);
8283 } else {
8284 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8285 "fcfi_vfi_offline_cmpl_action:%d vfi_online=%d. <",
8286 fcfp->fcf_index,
8287 fcfp->vfi_online);
8288 }
8289
8290 return (rval);
8291
8292 } /* emlxs_fcfi_vfi_offline_cmpl_action() */
8293
8294
8295 /*ARGSUSED*/
8296 static uint32_t
emlxs_fcfi_offline_evt_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8297 emlxs_fcfi_offline_evt_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
8298 void *arg1)
8299 {
8300 uint32_t rval = 0;
8301
8302 if (evt != FCF_EVENT_FCFI_OFFLINE) {
8303 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8304 "fcfi_offline_evt_action:%d %s:%s arg=%p. "
8305 "Invalid event type. <",
8306 fcfp->fcf_index,
8307 emlxs_fcfi_state_xlate(fcfp->state),
8308 emlxs_fcf_event_xlate(evt), arg1);
8309 return (1);
8310 }
8311
8312 if ((fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) &&
8313 !(fcfp->flag & EMLXS_FCFI_PAUSE_REQ)) {
8314 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8315 "fcfi_offline_evt_action:%d. Offline already requested. <",
8316 fcfp->fcf_index);
8317 return (1);
8318 }
8319
8320 switch (fcfp->state) {
8321 case FCFI_STATE_OFFLINE:
8322 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8323 "fcfi_offline_evt_action:%d flag=%x. Already offline. <",
8324 fcfp->fcf_index,
8325 fcfp->flag);
8326 break;
8327
8328 /* Wait states */
8329 case FCFI_STATE_VFI_ONLINE:
8330 case FCFI_STATE_VFI_OFFLINE:
8331 case FCFI_STATE_REG:
8332 case FCFI_STATE_ONLINE:
8333 case FCFI_STATE_PAUSED:
8334 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK;
8335 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ;
8336
8337 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8338 "fcfi_offline_evt_action:%d flag=%x. Handling offline.",
8339 fcfp->fcf_index,
8340 fcfp->flag);
8341
8342 /* Handle offline now */
8343 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1);
8344 break;
8345
8346 /* Transitional states */
8347 default:
8348 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK;
8349 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ;
8350
8351 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8352 "fcfi_offline_evt_action:%d. "
8353 "Invalid state. <",
8354 fcfp->fcf_index);
8355 break;
8356 }
8357
8358 return (rval);
8359
8360 } /* emlxs_fcfi_offline_evt_action() */
8361
8362
8363 /*ARGSUSED*/
8364 static uint32_t
emlxs_fcfi_pause_evt_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8365 emlxs_fcfi_pause_evt_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
8366 void *arg1)
8367 {
8368 uint32_t rval = 0;
8369
8370 if (evt != FCF_EVENT_FCFI_PAUSE) {
8371 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8372 "fcfi_pause_evt_action:%d %s:%s arg=%p. "
8373 "Invalid event type. <",
8374 fcfp->fcf_index,
8375 emlxs_fcfi_state_xlate(fcfp->state),
8376 emlxs_fcf_event_xlate(evt), arg1);
8377 return (1);
8378 }
8379
8380 if (fcfp->flag & EMLXS_FCFI_PAUSE_REQ) {
8381 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8382 "fcfi_pause_evt_action:%d. Pause already requested. <",
8383 fcfp->fcf_index);
8384 return (1);
8385 }
8386
8387 if (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) {
8388 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8389 "fcfi_pause_evt_action:%d. Offline already requested. <",
8390 fcfp->fcf_index);
8391 return (1);
8392 }
8393
8394 switch (fcfp->state) {
8395 case FCFI_STATE_OFFLINE:
8396 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8397 "fcfi_pause_evt_action:%d flag=%x. Already offline. <",
8398 fcfp->fcf_index,
8399 fcfp->flag);
8400 break;
8401
8402 case FCFI_STATE_PAUSED:
8403 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8404 "fcfi_pause_evt_action:%d flag=%x. Already paused. <",
8405 fcfp->fcf_index,
8406 fcfp->flag);
8407 break;
8408
8409 /* Wait states */
8410 case FCFI_STATE_VFI_ONLINE:
8411 case FCFI_STATE_VFI_OFFLINE:
8412 case FCFI_STATE_REG:
8413 case FCFI_STATE_ONLINE:
8414 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK;
8415 fcfp->flag |= (EMLXS_FCFI_OFFLINE_REQ | EMLXS_FCFI_PAUSE_REQ);
8416
8417 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8418 "fcfi_pause_evt_action:%d flag=%x. Handle pause request.",
8419 fcfp->fcf_index,
8420 fcfp->flag);
8421
8422 /* Handle offline now */
8423 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1);
8424 break;
8425
8426 /* Transitional states */
8427 default:
8428 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK;
8429 fcfp->flag |= (EMLXS_FCFI_OFFLINE_REQ | EMLXS_FCFI_PAUSE_REQ);
8430
8431 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8432 "fcfi_pause_evt_action:%d. "
8433 "Invalid state. <",
8434 fcfp->fcf_index);
8435 break;
8436 }
8437
8438 return (rval);
8439
8440 } /* emlxs_fcfi_pause_evt_action() */
8441
8442
8443 /*ARGSUSED*/
8444 static uint32_t
emlxs_fcfi_unreg_failed_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8445 emlxs_fcfi_unreg_failed_action(emlxs_port_t *port, FCFIobj_t *fcfp,
8446 uint32_t evt, void *arg1)
8447 {
8448 uint32_t rval = 0;
8449
8450 fcfp->attempts++;
8451
8452 if (fcfp->state != FCFI_STATE_UNREG_FAILED) {
8453 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8454 "fcfi_unreg_failed_action:%d %s:%s arg=%p attempt=%d. "
8455 "Invalid state. <",
8456 fcfp->fcf_index,
8457 emlxs_fcfi_state_xlate(fcfp->state),
8458 emlxs_fcf_event_xlate(evt),
8459 arg1, fcfp->attempts);
8460 return (1);
8461 }
8462
8463 if ((fcfp->reason == FCF_REASON_SEND_FAILED) ||
8464 (fcfp->attempts >= 3)) {
8465 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8466 "fcfi_unreg_failed_action:%d attempt=%d reason=%x. "
8467 "Unreg cmpl.",
8468 fcfp->fcf_index,
8469 fcfp->attempts,
8470 fcfp->reason);
8471
8472 fcfp->flag &= ~EMLXS_FCFI_REG;
8473
8474 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG_CMPL,
8475 FCF_REASON_OP_FAILED, fcfp->attempts, arg1);
8476 } else {
8477 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8478 "fcfi_unreg_failed_action:%d attempt=%d. Unregistering.",
8479 fcfp->fcf_index,
8480 arg1, fcfp->attempts);
8481
8482 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG,
8483 FCF_REASON_OP_FAILED, fcfp->attempts, arg1);
8484 }
8485
8486 return (rval);
8487
8488 } /* emlxs_fcfi_unreg_failed_action() */
8489
8490
8491 /*ARGSUSED*/
8492 static uint32_t
emlxs_fcfi_reg_failed_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8493 emlxs_fcfi_reg_failed_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
8494 void *arg1)
8495 {
8496 uint32_t rval = 0;
8497
8498 fcfp->attempts++;
8499
8500 if (fcfp->state != FCFI_STATE_REG_FAILED) {
8501 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8502 "fcfi_reg_failed_action:%d %s:%s arg=%p attempt=%d. "
8503 "Invalid state. <",
8504 fcfp->fcf_index,
8505 emlxs_fcfi_state_xlate(fcfp->state),
8506 emlxs_fcf_event_xlate(evt), arg1,
8507 fcfp->attempts);
8508 return (1);
8509 }
8510
8511 if ((fcfp->reason == FCF_REASON_SEND_FAILED) ||
8512 (fcfp->attempts >= 3)) {
8513 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8514 "fcfi_reg_failed_action:%d attempt=%d reason=%x. Reg cmpl.",
8515 fcfp->fcf_index,
8516 fcfp->attempts,
8517 fcfp->reason);
8518
8519 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK;
8520 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ;
8521
8522 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG_CMPL,
8523 FCF_REASON_OP_FAILED, fcfp->attempts, arg1);
8524 } else {
8525 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8526 "fcfi_reg_failed_action:%d attempt=%d. Registering.",
8527 fcfp->fcf_index,
8528 fcfp->attempts);
8529
8530 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG,
8531 FCF_REASON_OP_FAILED, fcfp->attempts, arg1);
8532 }
8533
8534 return (rval);
8535
8536 } /* emlxs_fcfi_reg_failed_action() */
8537
8538
8539 /*ARGSUSED*/
8540 static uint32_t
emlxs_fcfi_reg_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)8541 emlxs_fcfi_reg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
8542 {
8543 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
8544 MAILBOX4 *mb4;
8545 FCFIobj_t *fcfp;
8546
8547 fcfp = (FCFIobj_t *)mbq->context;
8548 mb4 = (MAILBOX4 *)mbq;
8549
8550 mutex_enter(&EMLXS_FCF_LOCK);
8551
8552 if (fcfp->state != FCFI_STATE_REG) {
8553 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8554 "fcfi_reg_mbcmpl:%d state=%s.",
8555 fcfp->fcf_index,
8556 emlxs_fcfi_state_xlate(fcfp->state));
8557
8558 mutex_exit(&EMLXS_FCF_LOCK);
8559 return (0);
8560 }
8561
8562 if (mb4->mbxStatus) {
8563 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8564 "fcfi_reg_mbcmpl:%d failed. %s. >",
8565 fcfp->fcf_index,
8566 emlxs_mb_xlate_status(mb4->mbxStatus));
8567
8568 (void) emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG_FAILED,
8569 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
8570
8571 mutex_exit(&EMLXS_FCF_LOCK);
8572 return (0);
8573 }
8574
8575 fcfp->FCFI = mb4->un.varRegFCFI.FCFI;
8576
8577 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8578 "fcfi_reg_mbcmpl:%d FCFI=%d. Reg complete. >",
8579 fcfp->fcf_index,
8580 fcfp->FCFI);
8581
8582 fcfp->flag |= EMLXS_FCFI_REG;
8583
8584 (void) emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG_CMPL,
8585 0, 0, 0);
8586 mutex_exit(&EMLXS_FCF_LOCK);
8587 return (0);
8588
8589 } /* emlxs_fcfi_reg_mbcmpl() */
8590
8591
8592 /*ARGSUSED*/
8593 static uint32_t
emlxs_fcfi_reg_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8594 emlxs_fcfi_reg_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
8595 void *arg1)
8596 {
8597 emlxs_hba_t *hba = HBA;
8598 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
8599 MAILBOX4 *mb4;
8600 MAILBOXQ *mbq;
8601 uint32_t rval = 0;
8602
8603 if (fcfp->state != FCFI_STATE_REG) {
8604 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8605 "fcfi_reg_action:%d %s:%s arg=%p. "
8606 "Invalid state. <",
8607 fcfp->fcf_index,
8608 emlxs_fcfi_state_xlate(fcfp->state),
8609 emlxs_fcf_event_xlate(evt), arg1);
8610 return (1);
8611 }
8612
8613 if (!(fcfp->flag & EMLXS_FCFI_FCFTAB)) {
8614 fcfp->flag |= EMLXS_FCFI_FCFTAB;
8615 fcftab->fcfi_online++;
8616 }
8617
8618 if (fcfp->prev_state != FCFI_STATE_REG_FAILED) {
8619 fcfp->attempts = 0;
8620 }
8621
8622 if (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) {
8623 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8624 "fcfi_reg_action:%d attempts=%d. Offline requested.",
8625 fcfp->fcf_index,
8626 fcfp->attempts);
8627
8628 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1);
8629 return (rval);
8630 }
8631
8632 if (fcfp->flag & EMLXS_FCFI_REG) {
8633 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8634 "fcfi_reg_action:%d. Already registered. "
8635 "Skipping REG_FCFI update.",
8636 fcfp->fcf_index);
8637
8638 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_ONLINE,
8639 FCF_REASON_EVENT, evt, arg1);
8640 return (rval);
8641 }
8642
8643 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8644 "fcfi_reg_action:%d attempts=%d. Sending REG_FCFI. <",
8645 fcfp->fcf_index,
8646 fcfp->attempts);
8647
8648 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
8649 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG_FAILED,
8650 FCF_REASON_NO_MBOX, 0, arg1);
8651
8652 return (rval);
8653 }
8654 mb4 = (MAILBOX4*)mbq;
8655 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
8656
8657 mbq->mbox_cmpl = emlxs_fcfi_reg_mbcmpl;
8658 mbq->context = (void *)fcfp;
8659 mbq->port = (void *)port;
8660
8661 mb4->mbxCommand = MBX_REG_FCFI;
8662 mb4->mbxOwner = OWN_HOST;
8663 mb4->un.varRegFCFI.FCFI = 0; /* FCFI will be returned by firmware */
8664 mb4->un.varRegFCFI.InfoIndex = fcfp->fcf_index;
8665
8666 mb4->un.varRegFCFI.RQId0 = hba->sli.sli4.rq[EMLXS_FCFI_RQ0_INDEX].qid;
8667 mb4->un.varRegFCFI.Id0_rctl_mask = EMLXS_FCFI_RQ0_RMASK;
8668 mb4->un.varRegFCFI.Id0_rctl = EMLXS_FCFI_RQ0_RCTL;
8669 mb4->un.varRegFCFI.Id0_type_mask = EMLXS_FCFI_RQ0_TMASK;
8670 mb4->un.varRegFCFI.Id0_type = EMLXS_FCFI_RQ0_TYPE;
8671
8672 mb4->un.varRegFCFI.RQId1 = 0xffff;
8673 mb4->un.varRegFCFI.RQId2 = 0xffff;
8674 mb4->un.varRegFCFI.RQId3 = 0xffff;
8675
8676 if (fcfp->flag & EMLXS_FCFI_VLAN_ID) {
8677 mb4->un.varRegFCFI.vv = 1;
8678 mb4->un.varRegFCFI.vlanTag = fcfp->vlan_id;
8679 }
8680
8681 /* Ignore the fcf record and force FPMA */
8682 mb4->un.varRegFCFI.mam = EMLXS_REG_FCFI_MAM_FPMA;
8683
8684 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
8685 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
8686 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
8687
8688 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG_FAILED,
8689 FCF_REASON_SEND_FAILED, rval, arg1);
8690
8691 return (rval);
8692 }
8693
8694 return (0);
8695
8696 } /* emlxs_fcfi_reg_action() */
8697
8698
8699 /*ARGSUSED*/
8700 static uint32_t
emlxs_fcfi_reg_cmpl_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8701 emlxs_fcfi_reg_cmpl_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
8702 void *arg1)
8703 {
8704 uint32_t rval = 0;
8705
8706 if (fcfp->state != FCFI_STATE_REG_CMPL) {
8707 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8708 "fcfi_reg_cmpl_action:%d %s:%s arg=%p. "
8709 "Invalid state. <",
8710 fcfp->fcf_index,
8711 emlxs_fcfi_state_xlate(fcfp->state),
8712 emlxs_fcf_event_xlate(evt), arg1);
8713 return (1);
8714 }
8715
8716 if (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) {
8717 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8718 "fcfi_reg_cmpl_action:%d. Offline requested.",
8719 fcfp->fcf_index);
8720
8721 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1);
8722 return (rval);
8723 }
8724
8725 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8726 "fcfi_reg_cmpl_action:%d attempts=%d. Reg cmpl.",
8727 fcfp->fcf_index,
8728 fcfp->attempts);
8729
8730 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_ONLINE,
8731 FCF_REASON_EVENT, evt, arg1);
8732
8733 return (rval);
8734
8735 } /* emlxs_fcfi_reg_cmpl_action() */
8736
8737
8738 /*ARGSUSED*/
8739 static uint32_t
emlxs_fcfi_unreg_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)8740 emlxs_fcfi_unreg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
8741 {
8742 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
8743 MAILBOX4 *mb4;
8744 FCFIobj_t *fcfp;
8745
8746 fcfp = (FCFIobj_t *)mbq->context;
8747 mb4 = (MAILBOX4 *)mbq;
8748
8749 mutex_enter(&EMLXS_FCF_LOCK);
8750
8751 if (fcfp->state != FCFI_STATE_UNREG) {
8752 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8753 "fcfi_unreg_mbcmpl:%d state=%s.",
8754 fcfp->fcf_index,
8755 emlxs_fcfi_state_xlate(fcfp->state));
8756
8757 mutex_exit(&EMLXS_FCF_LOCK);
8758 return (0);
8759 }
8760
8761 if (mb4->mbxStatus) {
8762 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8763 "fcfi_unreg_mbcmpl:%d failed. %s. >",
8764 fcfp->fcf_index,
8765 emlxs_mb_xlate_status(mb4->mbxStatus));
8766
8767 (void) emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG_FAILED,
8768 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
8769
8770 mutex_exit(&EMLXS_FCF_LOCK);
8771 return (0);
8772 }
8773
8774 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8775 "fcfi_unreg_mbcmpl:%d. Unreg complete. >",
8776 fcfp->fcf_index);
8777
8778 fcfp->flag &= ~EMLXS_FCFI_REG;
8779 (void) emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG_CMPL,
8780 0, 0, 0);
8781
8782 mutex_exit(&EMLXS_FCF_LOCK);
8783 return (0);
8784
8785 } /* emlxs_fcfi_unreg_mbcmpl() */
8786
8787
8788 /*ARGSUSED*/
8789 static uint32_t
emlxs_fcfi_unreg_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8790 emlxs_fcfi_unreg_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
8791 void *arg1)
8792 {
8793 emlxs_hba_t *hba = HBA;
8794 MAILBOX4 *mb4;
8795 MAILBOXQ *mbq;
8796 uint32_t rval = 0;
8797
8798 if (fcfp->state != FCFI_STATE_UNREG) {
8799 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8800 "fcfi_unreg_action:%d %s:%s arg=%p. "
8801 "Invalid state. <",
8802 fcfp->fcf_index,
8803 emlxs_fcfi_state_xlate(fcfp->state),
8804 emlxs_fcf_event_xlate(evt), arg1);
8805 return (1);
8806 }
8807
8808 if (!(fcfp->flag & EMLXS_FCFI_REG)) {
8809 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8810 "fcfi_unreg_action:%d. Not registered. "
8811 "Skipping UNREG_FCFI.",
8812 fcfp->fcf_index);
8813
8814 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_OFFLINE,
8815 FCF_REASON_EVENT, evt, arg1);
8816 return (rval);
8817 }
8818
8819 if (fcfp->prev_state != FCFI_STATE_UNREG_FAILED) {
8820 fcfp->attempts = 0;
8821 }
8822
8823 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8824 "fcfi_unreg_action:%d attempts=%d. Sending UNREG_FCFI. <",
8825 fcfp->fcf_index,
8826 fcfp->attempts);
8827
8828 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
8829 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG_FAILED,
8830 FCF_REASON_NO_MBOX, 0, arg1);
8831 return (rval);
8832 }
8833 mb4 = (MAILBOX4*)mbq;
8834 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
8835
8836 mbq->mbox_cmpl = emlxs_fcfi_unreg_mbcmpl;
8837 mbq->context = (void *)fcfp;
8838 mbq->port = (void *)port;
8839
8840 mb4->mbxCommand = MBX_UNREG_FCFI;
8841 mb4->mbxOwner = OWN_HOST;
8842 mb4->un.varUnRegFCFI.FCFI = fcfp->FCFI;
8843
8844 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
8845 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
8846 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
8847
8848 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG_FAILED,
8849 FCF_REASON_SEND_FAILED, rval, arg1);
8850
8851 return (rval);
8852 }
8853
8854 return (0);
8855
8856 } /* emlxs_fcfi_unreg_action() */
8857
8858
8859 /*ARGSUSED*/
8860 static uint32_t
emlxs_fcfi_unreg_cmpl_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8861 emlxs_fcfi_unreg_cmpl_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
8862 void *arg1)
8863 {
8864 uint32_t rval = 0;
8865
8866 if (fcfp->state != FCFI_STATE_UNREG_CMPL) {
8867 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8868 "fcfi_unreg_cmpl_action:%d %s:%s arg=%p. "
8869 "Invalid state. <",
8870 fcfp->fcf_index,
8871 emlxs_fcfi_state_xlate(fcfp->state),
8872 emlxs_fcf_event_xlate(evt), arg1);
8873 return (1);
8874 }
8875
8876 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8877 "fcfi_unreg_cmpl_action:%d attempts=%d. Going offline.",
8878 fcfp->fcf_index,
8879 emlxs_fcfi_state_xlate(fcfp->state),
8880 emlxs_fcf_event_xlate(evt), arg1,
8881 fcfp->attempts);
8882
8883 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_OFFLINE,
8884 FCF_REASON_EVENT, evt, arg1);
8885
8886 return (rval);
8887
8888 } /* emlxs_fcfi_unreg_cmpl_action() */
8889
8890
8891 /*ARGSUSED*/
8892 static uint32_t
emlxs_fcfi_online_action(emlxs_port_t * port,FCFIobj_t * fcfp,uint32_t evt,void * arg1)8893 emlxs_fcfi_online_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt,
8894 void *arg1)
8895 {
8896 emlxs_hba_t *hba = HBA;
8897 uint32_t rval = 0;
8898 VFIobj_t *vfip;
8899 uint32_t i;
8900
8901 if (fcfp->state != FCFI_STATE_ONLINE) {
8902 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
8903 "fcfi_online_action:%d %s:%s arg=%p. "
8904 "Invalid state. <",
8905 fcfp->fcf_index,
8906 emlxs_fcfi_state_xlate(fcfp->state),
8907 emlxs_fcf_event_xlate(evt), arg1);
8908 return (1);
8909 }
8910
8911 fcfp->flag &= ~EMLXS_FCFI_ONLINE_REQ;
8912
8913 if (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) {
8914 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8915 "fcfi_online_action:%d attempts=%d. Offline requested.",
8916 fcfp->fcf_index,
8917 fcfp->attempts);
8918
8919 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1);
8920 return (rval);
8921 }
8922
8923 /* Online remaining VFI's for this FCFI */
8924 vfip = hba->sli.sli4.VFI_table;
8925 for (i = 0; i < hba->sli.sli4.VFICount; i++, vfip++) {
8926 if (vfip->fcfp != fcfp) {
8927 continue;
8928 }
8929
8930 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8931 "fcfi_online_action:%d vfi_online=%d. Onlining VFI:%d. >",
8932 fcfp->fcf_index,
8933 fcfp->vfi_online,
8934 vfip->VFI);
8935
8936 (void) emlxs_vfi_event(port, FCF_EVENT_VFI_ONLINE, vfip);
8937 }
8938
8939 if (fcfp->prev_state != FCFI_STATE_ONLINE) {
8940 /* Perform VSAN discovery check when first VFI goes online */
8941 if (fcfp->vfi_online < FCFI_MAX_VFI_COUNT) {
8942
8943 /* Perform VSAN Discovery (TBD) */
8944 /* For now we only need 1 VFI */
8945
8946 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8947 "fcfi_online_action:%d vfi_online=%d. "
8948 "VSAN discovery required.",
8949 fcfp->fcf_index,
8950 fcfp->vfi_online);
8951 }
8952 }
8953
8954 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
8955 "fcfi_online_action:%d vfi_online=%d. "
8956 "FCFI online. Notifying fcftab. >",
8957 fcfp->fcf_index,
8958 fcfp->vfi_online);
8959
8960 /* Notify FCFTAB */
8961 rval = emlxs_fcftab_event(port, FCF_EVENT_FCFI_ONLINE, fcfp);
8962
8963 return (rval);
8964
8965 } /* emlxs_fcfi_online_action() */
8966
8967
8968 /*ARGSUSED*/
8969 static int
emlxs_fcf_configured(emlxs_port_t * port,FCFIobj_t * fcfp)8970 emlxs_fcf_configured(emlxs_port_t *port, FCFIobj_t *fcfp)
8971 {
8972 emlxs_hba_t *hba = HBA;
8973 int i;
8974 uint32_t entry_count;
8975 uint32_t valid_entry;
8976 uint32_t match_found;
8977 uint16_t VLanId;
8978 FCF_RECORD_t *fcfrec = &fcfp->fcf_rec;
8979 uint32_t j;
8980 uint32_t k;
8981
8982 /* Init the primary flag, we may set it later */
8983 fcfp->flag &= ~(EMLXS_FCFI_PRIMARY|EMLXS_FCFI_BOOT);
8984
8985 if (!(hba->flag & FC_FIP_SUPPORTED)) {
8986 if (!hba->sli.sli4.cfgFCOE.length) {
8987 /* Nothing specified, so everything matches */
8988 /* For nonFIP only use index 0 */
8989 if (fcfrec->fcf_index == 0) {
8990 return (1); /* success */
8991 }
8992 return (0);
8993 }
8994
8995 /* Just check FCMap for now */
8996 if (bcmp((char *)fcfrec->fc_map,
8997 hba->sli.sli4.cfgFCOE.FCMap, 3) == 0) {
8998 return (1); /* success */
8999 }
9000 return (0);
9001 }
9002
9003 /* For FIP mode, the FCF record must match Config Region 23 */
9004
9005 entry_count = (hba->sli.sli4.cfgFCF.length * sizeof (uint32_t)) /
9006 sizeof (tlv_fcfconnectentry_t);
9007 valid_entry = 0;
9008 match_found = 0;
9009
9010 for (i = 0; i < entry_count; i++) {
9011
9012 if (!hba->sli.sli4.cfgFCF.entry[i].Valid) {
9013 continue;
9014 }
9015
9016 if (hba->sli.sli4.cfgFCF.entry[i].FabricNameValid) {
9017 valid_entry = 1;
9018
9019 if (bcmp((char *)fcfrec->fabric_name_identifier,
9020 hba->sli.sli4.cfgFCF.entry[i].FabricName, 8)) {
9021 match_found = 0;
9022 continue;
9023 }
9024
9025 match_found = 1;
9026 }
9027
9028 if (hba->sli.sli4.cfgFCF.entry[i].SwitchNameValid) {
9029 valid_entry = 1;
9030
9031 if (bcmp((char *)fcfrec->switch_name_identifier,
9032 hba->sli.sli4.cfgFCF.entry[i].SwitchName, 8)) {
9033 match_found = 0;
9034 continue;
9035 }
9036
9037 match_found = 1;
9038 }
9039
9040 if (hba->sli.sli4.cfgFCF.entry[i].VLanValid) {
9041 valid_entry = 1;
9042
9043 if (!(fcfp->flag & EMLXS_FCFI_VLAN_ID)) {
9044 match_found = 0;
9045 continue;
9046 }
9047
9048 VLanId = hba->sli.sli4.cfgFCF.entry[i].VLanId;
9049 j = VLanId / 8;
9050 k = 1 << (VLanId % 8);
9051
9052 if (!(fcfrec->vlan_bitmap[j] & k)) {
9053 match_found = 0;
9054 continue;
9055 }
9056
9057 /* Assign requested vlan_id to this FCF */
9058 fcfp->vlan_id = VLanId;
9059
9060 match_found = 1;
9061 }
9062
9063 /* If a match was found */
9064 if (match_found) {
9065 if (hba->sli.sli4.cfgFCF.entry[i].Primary) {
9066 fcfp->flag |= EMLXS_FCFI_PRIMARY;
9067 }
9068 if (hba->sli.sli4.cfgFCF.entry[i].Boot) {
9069 fcfp->flag |= EMLXS_FCFI_BOOT;
9070 }
9071 return (1);
9072 }
9073 }
9074
9075 /* If no valid entries found, then allow any fabric */
9076 if (!valid_entry) {
9077 return (1);
9078 }
9079
9080 return (0);
9081
9082 } /* emlxs_fcf_configured() */
9083
9084
9085 static void
emlxs_fcfi_update(emlxs_port_t * port,FCFIobj_t * fcfp,FCF_RECORD_t * fcf_rec,uint32_t event_tag)9086 emlxs_fcfi_update(emlxs_port_t *port, FCFIobj_t *fcfp, FCF_RECORD_t *fcf_rec,
9087 uint32_t event_tag)
9088 {
9089 emlxs_hba_t *hba = HBA;
9090 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
9091 uint16_t i;
9092
9093 bcopy((char *)fcf_rec, &fcfp->fcf_rec, sizeof (FCF_RECORD_t));
9094 fcfp->fcf_index = fcf_rec->fcf_index;
9095
9096 /* Clear VLAN info */
9097 fcfp->vlan_id = 0;
9098 fcfp->flag &= ~EMLXS_FCFI_VLAN_ID;
9099
9100 /* Check if fcf is a member of a VLAN */
9101 for (i = 0; i < 4096; i++) {
9102 if (fcf_rec->vlan_bitmap[i / 8] & (1 << (i % 8))) {
9103 /* For now assign the VLAN id of the first VLAN found */
9104 fcfp->vlan_id = i;
9105 fcfp->flag |= EMLXS_FCFI_VLAN_ID;
9106 break;
9107 }
9108 }
9109
9110 if (fcf_rec->fcf_available) {
9111 fcfp->flag |= EMLXS_FCFI_AVAILABLE;
9112 } else {
9113 fcfp->flag &= ~EMLXS_FCFI_AVAILABLE;
9114 }
9115
9116 if (fcf_rec->fcf_valid && !fcf_rec->fcf_sol) {
9117 fcfp->flag |= EMLXS_FCFI_VALID;
9118 } else {
9119 fcfp->flag &= ~EMLXS_FCFI_VALID;
9120 }
9121
9122 /* Check config region 23 */
9123 /* Also sets BOOT and PRIMARY cfg bits as needed */
9124 if (emlxs_fcf_configured(port, fcfp)) {
9125 fcfp->flag |= EMLXS_FCFI_CONFIGURED;
9126 } else {
9127 fcfp->flag &= ~EMLXS_FCFI_CONFIGURED;
9128 }
9129
9130 /* Set fcfp priority. Used by selection alogithm */
9131 /* Combination of BOOT:PRIMARY:~fip_priority */
9132 fcfp->priority = (fcfp->flag & EMLXS_FCFI_BOOT)? 0x200:0;
9133 fcfp->priority |= (fcfp->flag & EMLXS_FCFI_PRIMARY)? 0x100:0;
9134 fcfp->priority |= ~(fcf_rec->fip_priority & 0xff);
9135
9136 fcfp->event_tag = event_tag;
9137 fcfp->generation = fcftab->generation;
9138 fcfp->flag |= EMLXS_FCFI_FRESH;
9139
9140 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9141 "fcfi:%d gen=%x iotag=%d flag=%x sol=%x avl=%x val=%x state=%x "
9142 "map=%x pri=%x vid=%x",
9143 fcf_rec->fcf_index,
9144 fcfp->generation,
9145 fcfp->event_tag,
9146 fcfp->flag,
9147 fcf_rec->fcf_sol,
9148 fcf_rec->fcf_available,
9149 fcf_rec->fcf_valid,
9150 fcf_rec->fcf_state,
9151 fcf_rec->mac_address_provider,
9152 fcfp->priority,
9153 fcfp->vlan_id);
9154
9155 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9156 "fcfi:%d mac=%02x:%02x:%02x:%02x:%02x:%02x "
9157 "fabric=%02x%02x%02x%02x%02x%02x%02x%02x "
9158 "switch=%02x%02x%02x%02x%02x%02x%02x%02x",
9159 fcfp->fcf_index,
9160 fcf_rec->fcf_mac_address_hi[0],
9161 fcf_rec->fcf_mac_address_hi[1],
9162 fcf_rec->fcf_mac_address_hi[2],
9163 fcf_rec->fcf_mac_address_hi[3],
9164 fcf_rec->fcf_mac_address_low[0],
9165 fcf_rec->fcf_mac_address_low[1],
9166
9167 fcf_rec->fabric_name_identifier[0],
9168 fcf_rec->fabric_name_identifier[1],
9169 fcf_rec->fabric_name_identifier[2],
9170 fcf_rec->fabric_name_identifier[3],
9171 fcf_rec->fabric_name_identifier[4],
9172 fcf_rec->fabric_name_identifier[5],
9173 fcf_rec->fabric_name_identifier[6],
9174 fcf_rec->fabric_name_identifier[7],
9175
9176 fcf_rec->switch_name_identifier[0],
9177 fcf_rec->switch_name_identifier[1],
9178 fcf_rec->switch_name_identifier[2],
9179 fcf_rec->switch_name_identifier[3],
9180 fcf_rec->switch_name_identifier[4],
9181 fcf_rec->switch_name_identifier[5],
9182 fcf_rec->switch_name_identifier[6],
9183 fcf_rec->switch_name_identifier[7]);
9184
9185 return;
9186
9187 } /* emlxs_fcfi_update() */
9188
9189
9190 /* ************************************************************************** */
9191 /* VFI */
9192 /* ************************************************************************** */
9193
9194 static char *
emlxs_vfi_state_xlate(uint32_t state)9195 emlxs_vfi_state_xlate(uint32_t state)
9196 {
9197 static char buffer[32];
9198 uint32_t i;
9199 uint32_t count;
9200
9201 count = sizeof (emlxs_vfi_state_table) / sizeof (emlxs_table_t);
9202 for (i = 0; i < count; i++) {
9203 if (state == emlxs_vfi_state_table[i].code) {
9204 return (emlxs_vfi_state_table[i].string);
9205 }
9206 }
9207
9208 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state);
9209 return (buffer);
9210
9211 } /* emlxs_vfi_state_xlate() */
9212
9213
9214 static uint32_t
emlxs_vfi_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)9215 emlxs_vfi_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
9216 void *arg1)
9217 {
9218 uint32_t rval = 0;
9219 uint32_t(*func) (emlxs_port_t *, VFIobj_t *, uint32_t, void *);
9220 uint32_t index;
9221 uint32_t events;
9222 uint16_t state;
9223
9224 /* Convert event to action table index */
9225 switch (evt) {
9226 case FCF_EVENT_STATE_ENTER:
9227 index = 0;
9228 break;
9229 case FCF_EVENT_VFI_ONLINE:
9230 index = 1;
9231 break;
9232 case FCF_EVENT_VFI_OFFLINE:
9233 index = 2;
9234 break;
9235 case FCF_EVENT_VFI_PAUSE:
9236 index = 3;
9237 break;
9238 case FCF_EVENT_VPI_ONLINE:
9239 index = 4;
9240 break;
9241 case FCF_EVENT_VPI_OFFLINE:
9242 index = 5;
9243 break;
9244 default:
9245 return (1);
9246 }
9247
9248 events = VFI_ACTION_EVENTS;
9249 state = vfip->state;
9250
9251 index += (state * events);
9252 func = (uint32_t(*) (emlxs_port_t *, VFIobj_t *, uint32_t, void *))
9253 emlxs_vfi_action_table[index];
9254
9255 if (!func) {
9256 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
9257 "vfi_action:%d %s:%s arg=%p. No action. <",
9258 vfip->VFI,
9259 emlxs_vfi_state_xlate(state),
9260 emlxs_fcf_event_xlate(evt), arg1);
9261
9262 return (1);
9263 }
9264
9265 rval = (func)(port, vfip, evt, arg1);
9266
9267 return (rval);
9268
9269 } /* emlxs_vfi_action() */
9270
9271
9272 static uint32_t
emlxs_vfi_event(emlxs_port_t * port,uint32_t evt,void * arg1)9273 emlxs_vfi_event(emlxs_port_t *port, uint32_t evt,
9274 void *arg1)
9275 {
9276 VPIobj_t *vpip = NULL;
9277 VFIobj_t *vfip = NULL;
9278 uint32_t rval = 0;
9279
9280 /* Filter events and acquire fcfi context */
9281 switch (evt) {
9282 case FCF_EVENT_VPI_ONLINE:
9283 case FCF_EVENT_VPI_OFFLINE:
9284 vpip = (VPIobj_t *)arg1;
9285
9286 if (!vpip) {
9287 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
9288 "vfi_event: %s arg=%p. Null VPI found. <",
9289 emlxs_fcf_event_xlate(evt), arg1);
9290
9291 return (1);
9292 }
9293
9294 vfip = vpip->vfip;
9295
9296 if (!vfip) {
9297 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
9298 "vfi_event: %s arg=%p. VFI not found. <",
9299 emlxs_fcf_event_xlate(evt), arg1);
9300
9301 return (1);
9302 }
9303 break;
9304
9305 case FCF_EVENT_VFI_ONLINE:
9306 case FCF_EVENT_VFI_OFFLINE:
9307 case FCF_EVENT_VFI_PAUSE:
9308 vfip = (VFIobj_t *)arg1;
9309
9310 if (!vfip) {
9311 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
9312 "vfi_event: %s arg=%p. VFI not found. <",
9313 emlxs_fcf_event_xlate(evt), arg1);
9314
9315 return (1);
9316 }
9317 break;
9318
9319 default:
9320 return (1);
9321 }
9322
9323 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
9324 "vfi_event:%d %s:%s arg=%p",
9325 vfip->VFI,
9326 emlxs_vfi_state_xlate(vfip->state),
9327 emlxs_fcf_event_xlate(evt), arg1);
9328
9329 rval = emlxs_vfi_action(port, vfip, evt, arg1);
9330
9331 return (rval);
9332
9333 } /* emlxs_vfi_event() */
9334
9335
9336 /*ARGSUSED*/
9337 static uint32_t
emlxs_vfi_state(emlxs_port_t * port,VFIobj_t * vfip,uint16_t state,uint16_t reason,uint32_t explain,void * arg1)9338 emlxs_vfi_state(emlxs_port_t *port, VFIobj_t *vfip, uint16_t state,
9339 uint16_t reason, uint32_t explain, void *arg1)
9340 {
9341 uint32_t rval = 0;
9342
9343 if (state >= VFI_ACTION_STATES) {
9344 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
9345 "vfi_state:%d %s. "
9346 "Invalid state. <",
9347 vfip->VFI,
9348 emlxs_vfi_state_xlate(vfip->state));
9349 return (1);
9350 }
9351
9352 if ((vfip->state == state) &&
9353 (reason != FCF_REASON_REENTER)) {
9354 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
9355 "vfi_state:%d %s:%s:0x%x arg=%p. "
9356 "State not changed. <",
9357 vfip->VFI,
9358 emlxs_vfi_state_xlate(vfip->state),
9359 emlxs_fcf_reason_xlate(reason),
9360 explain, arg1);
9361
9362 return (1);
9363 }
9364
9365 if (!reason) {
9366 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
9367 "vfi_state:%d %s-->%s arg=%p",
9368 vfip->VFI,
9369 emlxs_vfi_state_xlate(vfip->state),
9370 emlxs_vfi_state_xlate(state), arg1);
9371 } else if (reason == FCF_REASON_EVENT) {
9372 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
9373 "vfi_state:%d %s-->%s:%s:%s arg=%p",
9374 vfip->VFI,
9375 emlxs_vfi_state_xlate(vfip->state),
9376 emlxs_vfi_state_xlate(state),
9377 emlxs_fcf_reason_xlate(reason),
9378 emlxs_fcf_event_xlate(explain), arg1);
9379 } else if (explain) {
9380 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
9381 "vfi_state:%d %s-->%s:%s:0x%x arg=%p",
9382 vfip->VFI,
9383 emlxs_vfi_state_xlate(vfip->state),
9384 emlxs_vfi_state_xlate(state),
9385 emlxs_fcf_reason_xlate(reason),
9386 explain, arg1);
9387 } else {
9388 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
9389 "vfi_state:%d %s-->%s:%s arg=%p",
9390 vfip->VFI,
9391 emlxs_vfi_state_xlate(vfip->state),
9392 emlxs_vfi_state_xlate(state),
9393 emlxs_fcf_reason_xlate(reason), arg1);
9394 }
9395
9396 vfip->prev_state = vfip->state;
9397 vfip->prev_reason = vfip->reason;
9398 vfip->state = state;
9399 vfip->reason = reason;
9400
9401 rval = emlxs_vfi_action(port, vfip, FCF_EVENT_STATE_ENTER, arg1);
9402
9403 return (rval);
9404
9405 } /* emlxs_vfi_state() */
9406
9407
9408 /*ARGSUSED*/
9409 static uint32_t
emlxs_vfi_vpi_online_evt_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)9410 emlxs_vfi_vpi_online_evt_action(emlxs_port_t *port, VFIobj_t *vfip,
9411 uint32_t evt, void *arg1)
9412 {
9413 uint32_t rval = 0;
9414
9415 if (evt != FCF_EVENT_VPI_ONLINE) {
9416 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
9417 "vfi_vpi_online_evt_action:%d %s:%s arg=%p flag=%x. "
9418 "Invalid event type. <",
9419 vfip->VFI,
9420 emlxs_vfi_state_xlate(vfip->state),
9421 emlxs_fcf_event_xlate(evt), arg1,
9422 vfip->flag);
9423 return (1);
9424 }
9425
9426 switch (vfip->state) {
9427 case VFI_STATE_ONLINE:
9428 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9429 "vfi_vpi_online_evt_action:%d flag=%x vpi_online=%d. "
9430 "Reentering online.",
9431 vfip->VFI,
9432 vfip->flag,
9433 vfip->vpi_online);
9434
9435 rval = emlxs_vfi_state(port, vfip, VFI_STATE_ONLINE,
9436 FCF_REASON_REENTER, evt, arg1);
9437 break;
9438
9439 case VFI_STATE_VPI_ONLINE:
9440 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9441 "vfi_vpi_online_evt_action:%d flag=%x vpi_online=%d. "
9442 "Online cmpl.",
9443 vfip->VFI,
9444 vfip->flag,
9445 vfip->vpi_online);
9446
9447 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_ONLINE_CMPL,
9448 FCF_REASON_EVENT, evt, arg1);
9449 break;
9450
9451 default:
9452 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9453 "vfi_vpi_online_evt_action:%d flag=%x vpi_online=%d. <",
9454 vfip->VFI,
9455 vfip->flag,
9456 vfip->vpi_online);
9457
9458 return (1);
9459 }
9460
9461 return (rval);
9462
9463 } /* emlxs_vfi_vpi_online_evt_action() */
9464
9465
9466 /*ARGSUSED*/
9467 static uint32_t
emlxs_vfi_offline_handler(emlxs_port_t * port,VFIobj_t * vfip,void * arg1)9468 emlxs_vfi_offline_handler(emlxs_port_t *port, VFIobj_t *vfip, void *arg1)
9469 {
9470 uint32_t rval = 0;
9471
9472 if (!(vfip->flag & EMLXS_VFI_OFFLINE_REQ)) {
9473 return (0);
9474 }
9475
9476 if (vfip->vpi_online) {
9477 if (vfip->flag & EMLXS_VFI_PAUSE_REQ) {
9478 rval = emlxs_vfi_state(port, vfip, VFI_STATE_PAUSED,
9479 FCF_REASON_REQUESTED, 0, arg1);
9480 } else {
9481 rval = emlxs_vfi_state(port, vfip,
9482 VFI_STATE_VPI_OFFLINE, FCF_REASON_REQUESTED,
9483 0, arg1);
9484 }
9485
9486 } else if (vfip->flag & EMLXS_VFI_REG) {
9487 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG,
9488 FCF_REASON_REQUESTED, 0, arg1);
9489
9490 } else if (vfip->flag & EMLXS_VFI_INIT) {
9491 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG,
9492 FCF_REASON_REQUESTED, 0, arg1);
9493
9494 } else {
9495 rval = emlxs_vfi_state(port, vfip, VFI_STATE_OFFLINE,
9496 FCF_REASON_REQUESTED, 0, arg1);
9497 }
9498
9499 return (rval);
9500
9501 } /* emlxs_vfi_offline_handler() */
9502
9503
9504 /*ARGSUSED*/
9505 static uint32_t
emlxs_vfi_vpi_offline_evt_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)9506 emlxs_vfi_vpi_offline_evt_action(emlxs_port_t *port, VFIobj_t *vfip,
9507 uint32_t evt, void *arg1)
9508 {
9509 uint32_t rval = 0;
9510 VPIobj_t *vpip;
9511
9512 if (evt != FCF_EVENT_VPI_OFFLINE) {
9513 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
9514 "vfi_vpi_offline_evt_action:%d %s:%s arg=%p flag=%x. "
9515 "Invalid event type. <",
9516 vfip->VFI,
9517 emlxs_vfi_state_xlate(vfip->state),
9518 emlxs_fcf_event_xlate(evt), arg1,
9519 vfip->flag);
9520 return (1);
9521 }
9522
9523 /* Disconnect VPI object from VFI */
9524 vpip = (VPIobj_t *)arg1;
9525 vpip->vfip = NULL;
9526
9527 switch (vfip->state) {
9528 case VFI_STATE_ONLINE:
9529 case VFI_STATE_VPI_ONLINE:
9530 if (vfip->vpi_online == 0) {
9531 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9532 "vfi_vpi_offline_evt_action:%d flag=%x "
9533 "vpi_online=%d. Offlining.",
9534 vfip->VFI,
9535 vfip->flag, vfip->vpi_online);
9536
9537 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
9538 vfip->flag |= EMLXS_VFI_OFFLINE_REQ;
9539 rval = emlxs_vfi_offline_handler(port, vfip, arg1);
9540 } else {
9541 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9542 "vfi_vpi_offline_evt_action:%d flag=%x "
9543 "vpi_online=%d. <",
9544 vfip->VFI,
9545 vfip->flag, vfip->vpi_online);
9546 }
9547 break;
9548
9549 case VFI_STATE_PAUSED:
9550 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9551 "vfi_vpi_offline_evt_action:%d flag=%x vpi_online=%d. <",
9552 vfip->VFI,
9553 vfip->flag, vfip->vpi_online);
9554 break;
9555
9556 case VFI_STATE_VPI_OFFLINE:
9557 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9558 "vfi_vpi_offline_evt_action:%d flag=%x. VPI offline cmpl.",
9559 vfip->VFI,
9560 vfip->flag);
9561
9562 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_OFFLINE_CMPL,
9563 FCF_REASON_EVENT, evt, arg1);
9564 break;
9565
9566 case VFI_STATE_VPI_OFFLINE_CMPL:
9567 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9568 "vfi_vpi_offline_evt_action:%d flag=%x. VPI offline cmpl.",
9569 vfip->VFI,
9570 vfip->flag);
9571
9572 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_OFFLINE_CMPL,
9573 FCF_REASON_REENTER, evt, arg1);
9574 break;
9575
9576 default:
9577 if (vfip->vpi_online == 0) {
9578 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9579 "vfi_vpi_offline_evt_action:%d flag=%x "
9580 "vpi_online=%d. Requesting offline. <",
9581 vfip->VFI,
9582 vfip->flag, vfip->vpi_online);
9583
9584 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
9585 vfip->flag |= EMLXS_VFI_OFFLINE_REQ;
9586 } else {
9587 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9588 "vfi_vpi_offline_evt_action:%d flag=%x "
9589 "vpi_online=%d. <",
9590 vfip->VFI,
9591 vfip->flag, vfip->vpi_online);
9592 }
9593 return (1);
9594 }
9595
9596 return (rval);
9597
9598 } /* emlxs_vfi_vpi_offline_evt_action() */
9599
9600
9601 /*ARGSUSED*/
9602 static uint32_t
emlxs_vfi_online_evt_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)9603 emlxs_vfi_online_evt_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
9604 void *arg1)
9605 {
9606 emlxs_hba_t *hba = HBA;
9607 emlxs_port_t *vport;
9608 VPIobj_t *vpip;
9609 uint32_t rval = 0;
9610 uint32_t i;
9611
9612 if (evt != FCF_EVENT_VFI_ONLINE) {
9613 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
9614 "vfi_online_evt_action:%d %s:%s arg=%p flag=%x. "
9615 "Invalid event type. <",
9616 vfip->VFI,
9617 emlxs_vfi_state_xlate(vfip->state),
9618 emlxs_fcf_event_xlate(evt), arg1,
9619 vfip->flag);
9620 return (1);
9621 }
9622
9623 if (vfip->flag & EMLXS_VFI_ONLINE_REQ) {
9624 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9625 "vfi_online_evt_action:%d flag=%x. "
9626 "Online already requested. <",
9627 vfip->VFI,
9628 vfip->flag);
9629 return (0);
9630 }
9631
9632 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
9633
9634 switch (vfip->state) {
9635 case VFI_STATE_OFFLINE:
9636 vfip->flag |= EMLXS_VFI_ONLINE_REQ;
9637 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9638 "vfi_online_evt_action:%d flag=%x. Initiating online.",
9639 vfip->VFI,
9640 vfip->flag);
9641
9642 rval = emlxs_vfi_state(port, vfip, VFI_STATE_INIT,
9643 FCF_REASON_EVENT, evt, arg1);
9644 break;
9645
9646 case VFI_STATE_VPI_OFFLINE:
9647 case VFI_STATE_PAUSED:
9648 vfip->flag |= EMLXS_VFI_ONLINE_REQ;
9649 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9650 "vfi_online_evt_action:%d flag=%x. Initiating online.",
9651 vfip->VFI,
9652 vfip->flag);
9653
9654 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_ONLINE,
9655 FCF_REASON_EVENT, evt, arg1);
9656 break;
9657
9658 case VFI_STATE_ONLINE:
9659 /* Online all VPI's belonging to this vfi */
9660 for (i = 0; i <= hba->vpi_max; i++) {
9661 vport = &VPORT(i);
9662 vpip = vport->vpip;
9663
9664 if (!(vport->flag & EMLXS_PORT_BOUND) ||
9665 (vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
9666 continue;
9667 }
9668
9669 if (vpip->vfip != vfip) {
9670 continue;
9671 }
9672
9673 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9674 "vfi_online_evt_action:%d. Onlining VPI:%d >",
9675 vfip->VFI,
9676 vpip->VPI);
9677
9678 (void) emlxs_vpi_event(vport, FCF_EVENT_VPI_ONLINE,
9679 vpip);
9680 }
9681 break;
9682
9683 default:
9684 vfip->flag |= EMLXS_VFI_ONLINE_REQ;
9685 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9686 "vfi_online_evt_action:%d flag=%x. <",
9687 vfip->VFI,
9688 vfip->flag);
9689 return (1);
9690 }
9691
9692 return (rval);
9693
9694 } /* emlxs_vfi_online_evt_action() */
9695
9696
9697 /*ARGSUSED*/
9698 static uint32_t
emlxs_vfi_offline_evt_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)9699 emlxs_vfi_offline_evt_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
9700 void *arg1)
9701 {
9702 uint32_t rval = 0;
9703
9704 if (evt != FCF_EVENT_VFI_OFFLINE) {
9705 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
9706 "vfi_offline_evt_action:%d %s:%s arg=%p flag=%x. "
9707 "Invalid event type. <",
9708 vfip->VFI,
9709 emlxs_vfi_state_xlate(vfip->state),
9710 emlxs_fcf_event_xlate(evt), arg1,
9711 vfip->flag);
9712 return (1);
9713 }
9714
9715 if ((vfip->flag & EMLXS_VFI_OFFLINE_REQ) &&
9716 !(vfip->flag & EMLXS_VFI_PAUSE_REQ)) {
9717 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9718 "vfi_offline_evt_action:%d flag=%x. "
9719 "Offline already requested. <",
9720 vfip->VFI,
9721 vfip->flag);
9722 return (0);
9723 }
9724
9725 switch (vfip->state) {
9726 case VFI_STATE_OFFLINE:
9727 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9728 "vfi_offline_evt_action:%d flag=%x. "
9729 "Already offline. <",
9730 vfip->VFI,
9731 vfip->flag);
9732 break;
9733
9734 /* Wait states */
9735 case VFI_STATE_VPI_ONLINE:
9736 case VFI_STATE_VPI_OFFLINE:
9737 case VFI_STATE_VPI_OFFLINE_CMPL:
9738 case VFI_STATE_INIT:
9739 case VFI_STATE_REG:
9740 case VFI_STATE_ONLINE:
9741 case VFI_STATE_PAUSED:
9742 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
9743 vfip->flag |= EMLXS_VFI_OFFLINE_REQ;
9744
9745 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9746 "vfi_offline_evt_action:%d flag=%x. Handling offline.",
9747 vfip->VFI,
9748 vfip->flag);
9749
9750 /* Handle offline now */
9751 rval = emlxs_vfi_offline_handler(port, vfip, arg1);
9752 break;
9753
9754 default:
9755 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
9756 vfip->flag |= EMLXS_VFI_OFFLINE_REQ;
9757
9758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9759 "vfi_offline_evt_action:%d flag=%x. <",
9760 vfip->VFI,
9761 vfip->flag);
9762 break;
9763 }
9764
9765 return (rval);
9766
9767 } /* emlxs_vfi_offline_evt_action() */
9768
9769
9770 /*ARGSUSED*/
9771 static uint32_t
emlxs_vfi_pause_evt_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)9772 emlxs_vfi_pause_evt_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
9773 void *arg1)
9774 {
9775 uint32_t rval = 0;
9776
9777 if (evt != FCF_EVENT_VFI_PAUSE) {
9778 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
9779 "vfi_pause_evt_action:%d %s:%s arg=%p flag=%x. "
9780 "Invalid event type. <",
9781 vfip->VFI,
9782 emlxs_vfi_state_xlate(vfip->state),
9783 emlxs_fcf_event_xlate(evt), arg1,
9784 vfip->flag);
9785 return (1);
9786 }
9787
9788 if (vfip->flag & EMLXS_VFI_PAUSE_REQ) {
9789 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9790 "vfi_pause_evt_action:%d flag=%x. "
9791 "Pause already requested. <",
9792 vfip->VFI,
9793 vfip->flag);
9794 return (0);
9795 }
9796
9797 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) {
9798 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9799 "vfi_pause_evt_action:%d flag=%x. "
9800 "Offline already requested. <",
9801 vfip->VFI,
9802 vfip->flag);
9803 return (0);
9804 }
9805
9806 switch (vfip->state) {
9807 case VFI_STATE_OFFLINE:
9808 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9809 "vfi_pause_evt_action:%d flag=%x. "
9810 "Already offline. <",
9811 vfip->VFI,
9812 vfip->flag);
9813 break;
9814
9815 case VFI_STATE_PAUSED:
9816 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9817 "vfi_pause_evt_action:%d flag=%x. "
9818 "Already paused. <",
9819 vfip->VFI,
9820 vfip->flag);
9821 break;
9822
9823 /* Wait states */
9824 case VFI_STATE_VPI_ONLINE:
9825 case VFI_STATE_VPI_OFFLINE_CMPL:
9826 case VFI_STATE_INIT:
9827 case VFI_STATE_REG:
9828 case VFI_STATE_ONLINE:
9829 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
9830 vfip->flag |= (EMLXS_VFI_OFFLINE_REQ | EMLXS_VFI_PAUSE_REQ);
9831
9832 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9833 "vfi_pause_evt_action:%d flag=%x. Handling offline.",
9834 vfip->VFI,
9835 vfip->flag);
9836
9837 /* Handle offline now */
9838 rval = emlxs_vfi_offline_handler(port, vfip, arg1);
9839 break;
9840
9841 default:
9842 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
9843 vfip->flag |= (EMLXS_VFI_OFFLINE_REQ | EMLXS_VFI_PAUSE_REQ);
9844
9845 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9846 "vfi_pause_evt_action:%d flag=%x. <",
9847 vfip->VFI,
9848 vfip->flag);
9849 break;
9850 }
9851
9852 return (rval);
9853
9854 } /* emlxs_vfi_pause_evt_action() */
9855
9856
9857 /*ARGSUSED*/
9858 static uint32_t
emlxs_vfi_offline_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)9859 emlxs_vfi_offline_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
9860 void *arg1)
9861 {
9862 uint32_t rval = 0;
9863
9864 if (vfip->state != VFI_STATE_OFFLINE) {
9865 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9866 "vfi_offline_action:%d %s:%s arg=%p. "
9867 "Invalid state. <",
9868 vfip->VFI,
9869 emlxs_vfi_state_xlate(vfip->state),
9870 emlxs_fcf_event_xlate(evt), arg1);
9871 return (1);
9872 }
9873
9874 if (!vfip->fcfp) {
9875 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9876 "vfi_offline_action:%d %s:%s arg=%p flag=%x. "
9877 "Null fcfp found. <",
9878 vfip->VFI,
9879 emlxs_vfi_state_xlate(vfip->state),
9880 emlxs_fcf_event_xlate(evt), arg1,
9881 vfip->flag);
9882 return (1);
9883 }
9884
9885 vfip->flag &= ~(EMLXS_VFI_OFFLINE_REQ | EMLXS_VFI_PAUSE_REQ);
9886
9887 if (vfip->prev_state == VFI_STATE_OFFLINE) {
9888 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9889 "vfi_offline_action:%d vfi_online=%d. <",
9890 vfip->VFI,
9891 vfip->fcfp->vfi_online);
9892
9893 return (0);
9894 }
9895
9896 if (vfip->vpi_online) {
9897 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
9898 "vfi_offline_action:%d vpi_online=%d. VPI's still online.",
9899 vfip->VFI,
9900 vfip->vpi_online);
9901 }
9902
9903 if (vfip->flag & EMLXS_VFI_FCFI) {
9904 vfip->flag &= ~EMLXS_VFI_FCFI;
9905
9906 if (vfip->fcfp->vfi_online) {
9907 vfip->fcfp->vfi_online--;
9908 }
9909 }
9910
9911 /* Check if online was requested */
9912 if (vfip->flag & EMLXS_VFI_ONLINE_REQ) {
9913 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9914 "vfi_offline_action:%d vfi_online=%d. Online requested.",
9915 vfip->VFI,
9916 vfip->fcfp->vfi_online);
9917
9918 rval = emlxs_vfi_state(port, vfip, VFI_STATE_INIT,
9919 FCF_REASON_REQUESTED, 0, arg1);
9920 return (rval);
9921 }
9922
9923 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9924 "vfi_offline_action:%d vfi_online=%d. "
9925 "VFI offline. Notifying FCFI:%d >",
9926 vfip->VFI,
9927 vfip->fcfp->vfi_online,
9928 vfip->fcfp->fcf_index);
9929
9930 /* Notify FCFI */
9931 rval = emlxs_fcfi_event(port, FCF_EVENT_VFI_OFFLINE, vfip);
9932
9933 return (rval);
9934
9935 } /* emlxs_vfi_offline_action() */
9936
9937
9938 /*ARGSUSED*/
9939 static uint32_t
emlxs_vfi_init_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)9940 emlxs_vfi_init_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
9941 {
9942 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
9943 VFIobj_t *vfip;
9944 MAILBOX4 *mb4;
9945
9946 vfip = (VFIobj_t *)mbq->context;
9947 mb4 = (MAILBOX4 *)mbq;
9948
9949 mutex_enter(&EMLXS_FCF_LOCK);
9950
9951 if (vfip->state != VFI_STATE_INIT) {
9952 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9953 "vfi_init_mbcmpl:%d %s.",
9954 vfip->VFI,
9955 emlxs_vfi_state_xlate(vfip->state));
9956
9957 mutex_exit(&EMLXS_FCF_LOCK);
9958 return (0);
9959 }
9960
9961 if (mb4->mbxStatus) {
9962 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9963 "vfi_init_mbcmpl:%d failed. %s. >",
9964 vfip->VFI,
9965 emlxs_mb_xlate_status(mb4->mbxStatus));
9966
9967 (void) emlxs_vfi_state(port, vfip, VFI_STATE_INIT_FAILED,
9968 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
9969
9970 mutex_exit(&EMLXS_FCF_LOCK);
9971 return (0);
9972 }
9973
9974 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
9975 "vfi_init_mbcmpl:%d. Init complete. >",
9976 vfip->VFI,
9977 mb4->mbxStatus);
9978
9979 vfip->flag |= EMLXS_VFI_INIT;
9980 (void) emlxs_vfi_state(port, vfip, VFI_STATE_INIT_CMPL, 0, 0, 0);
9981
9982 mutex_exit(&EMLXS_FCF_LOCK);
9983 return (0);
9984
9985 } /* emlxs_vfi_init_mbcmpl() */
9986
9987
9988 /*ARGSUSED*/
9989 static uint32_t
emlxs_vfi_init_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)9990 emlxs_vfi_init_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
9991 void *arg1)
9992 {
9993 emlxs_hba_t *hba = HBA;
9994 MAILBOXQ *mbq;
9995 MAILBOX4 *mb4;
9996 uint32_t rval = 0;
9997
9998 if (vfip->state != VFI_STATE_INIT) {
9999 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10000 "vfi_init_action:%d %s:%s arg=%p. "
10001 "Invalid state. <",
10002 vfip->VFI,
10003 emlxs_vfi_state_xlate(vfip->state),
10004 emlxs_fcf_event_xlate(evt), arg1);
10005 return (1);
10006 }
10007
10008 if (!(vfip->flag & EMLXS_VFI_FCFI)) {
10009 vfip->flag |= EMLXS_VFI_FCFI;
10010 vfip->fcfp->vfi_online++;
10011 }
10012
10013 if (vfip->prev_state != VFI_STATE_INIT_FAILED) {
10014 vfip->attempts = 0;
10015 }
10016
10017 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) {
10018 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10019 "vfi_init_action:%d attempts=%d. Offline requested.",
10020 vfip->VFI,
10021 vfip->attempts);
10022
10023 rval = emlxs_vfi_offline_handler(port, vfip, arg1);
10024 return (rval);
10025 }
10026
10027 if (vfip->flag & EMLXS_VFI_INIT) {
10028 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10029 "vfi_init_action:%d flag=%x. "
10030 "Already init'd. Skipping INIT_VFI.",
10031 vfip->VFI);
10032
10033 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_ONLINE,
10034 FCF_REASON_EVENT, evt, arg1);
10035 return (rval);
10036 }
10037
10038 if (((hba->sli_intf & SLI_INTF_IF_TYPE_MASK) ==
10039 SLI_INTF_IF_TYPE_0) && (vfip->fcfp->vfi_online == 1)) {
10040 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10041 "vfi_init_action:%d. First VFI. Skipping INIT_VFI.",
10042 vfip->VFI);
10043
10044 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_ONLINE,
10045 FCF_REASON_EVENT, evt, arg1);
10046 return (rval);
10047 }
10048
10049 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10050 "vfi_init_action:%d vfi_online=%d attempts=%d. Sending INIT_VFI. <",
10051 vfip->VFI,
10052 vfip->fcfp->vfi_online,
10053 vfip->attempts);
10054
10055 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
10056 rval = emlxs_vfi_state(port, vfip, FCFI_STATE_REG_FAILED,
10057 FCF_REASON_NO_MBOX, 0, arg1);
10058 return (rval);
10059 }
10060 mb4 = (MAILBOX4*)mbq;
10061 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
10062
10063 mbq->nonembed = NULL;
10064 mbq->mbox_cmpl = emlxs_vfi_init_mbcmpl;
10065 mbq->context = (void *)vfip;
10066 mbq->port = (void *)port;
10067
10068 mb4->mbxCommand = MBX_INIT_VFI;
10069 mb4->mbxOwner = OWN_HOST;
10070 mb4->un.varInitVFI4.fcfi = vfip->fcfp->FCFI;
10071 mb4->un.varInitVFI4.vfi = vfip->VFI;
10072
10073 /* ??? This function is untested and incomplete */
10074
10075 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
10076 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
10077 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
10078
10079 rval = emlxs_vfi_state(port, vfip, VFI_STATE_INIT_FAILED,
10080 FCF_REASON_SEND_FAILED, rval, arg1);
10081
10082 return (rval);
10083 }
10084
10085 return (0);
10086
10087 } /* emlxs_vfi_init_action() */
10088
10089
10090 /*ARGSUSED*/
10091 static uint32_t
emlxs_vfi_init_failed_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10092 emlxs_vfi_init_failed_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10093 void *arg1)
10094 {
10095 uint32_t rval = 0;
10096
10097 vfip->attempts++;
10098
10099 if (vfip->state != VFI_STATE_INIT_FAILED) {
10100 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
10101 "vfi_init_action:%d %s:%s arg=%p attempt=%d. "
10102 "Invalid state. <",
10103 vfip->VFI,
10104 emlxs_vfi_state_xlate(vfip->state),
10105 emlxs_fcf_event_xlate(evt), arg1,
10106 vfip->attempts);
10107 return (1);
10108 }
10109
10110 if ((vfip->reason == FCF_REASON_SEND_FAILED) ||
10111 (vfip->attempts >= 3)) {
10112 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10113 "vfi_init_action:%d attempt=%d reason=%x. Init cmpl.",
10114 vfip->VFI,
10115 vfip->attempts,
10116 vfip->reason);
10117
10118 vfip->flag &= ~(EMLXS_VFI_REG | EMLXS_VFI_INIT);
10119
10120 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
10121 vfip->flag |= EMLXS_VFI_OFFLINE_REQ;
10122 rval = emlxs_vfi_state(port, vfip, VFI_STATE_INIT_CMPL,
10123 FCF_REASON_OP_FAILED, vfip->attempts, arg1);
10124 } else {
10125 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10126 "vfi_init_action:%d attempt=%d. Initializing.",
10127 vfip->VFI,
10128 vfip->attempts);
10129
10130 rval = emlxs_vfi_state(port, vfip, VFI_STATE_INIT,
10131 FCF_REASON_OP_FAILED, vfip->attempts, arg1);
10132 }
10133
10134 return (rval);
10135
10136 } /* emlxs_vfi_init_failed_action() */
10137
10138
10139 /*ARGSUSED*/
10140 static uint32_t
emlxs_vfi_init_cmpl_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10141 emlxs_vfi_init_cmpl_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10142 void *arg1)
10143 {
10144 uint32_t rval = 0;
10145
10146 if (vfip->state != VFI_STATE_INIT_CMPL) {
10147 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10148 "vfi_init_cmpl_action:%d %s:%s arg=%p. "
10149 "Invalid state. <",
10150 vfip->VFI,
10151 emlxs_vfi_state_xlate(vfip->state),
10152 emlxs_fcf_event_xlate(evt), arg1);
10153 return (1);
10154 }
10155
10156 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10157 "vfi_init_cmpl_action:%d attempts=%d. Init cmpl.",
10158 vfip->VFI,
10159 vfip->attempts);
10160
10161 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_ONLINE,
10162 FCF_REASON_EVENT, evt, arg1);
10163
10164 return (rval);
10165
10166 } /* emlxs_vfi_init_cmpl_action() */
10167
10168
10169 /*ARGSUSED*/
10170 static uint32_t
emlxs_vfi_vpi_online_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10171 emlxs_vfi_vpi_online_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10172 void *arg1)
10173 {
10174 emlxs_hba_t *hba = HBA;
10175 uint32_t rval = 0;
10176 uint32_t i;
10177 emlxs_port_t *vport;
10178 VPIobj_t *vpip;
10179
10180 if (vfip->state != VFI_STATE_VPI_ONLINE) {
10181 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10182 "vfi_vpi_online_action:%d %s:%s arg=%p. "
10183 "Invalid state. <",
10184 vfip->VFI,
10185 emlxs_vfi_state_xlate(vfip->state),
10186 emlxs_fcf_event_xlate(evt), arg1);
10187 return (1);
10188 }
10189
10190 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) {
10191 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10192 "vfi_vpi_online_action:%d. Offline requested.",
10193 vfip->VFI);
10194
10195 rval = emlxs_vfi_offline_handler(port, vfip, arg1);
10196 return (rval);
10197 }
10198
10199 if (vfip->logi_count) {
10200 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
10201 "vfi_vpi_online_action:%d vpi_online=%d logi_count=%d. "
10202 "VPI already logged in.",
10203 vfip->VFI,
10204 vfip->vpi_online,
10205 vfip->logi_count);
10206 }
10207
10208 if (vfip->vpi_online) {
10209 /* Waking up after being paused */
10210
10211 /* Find first VPI of this VFI */
10212 for (i = 0; i <= hba->vpi_max; i++) {
10213 vport = &VPORT(i);
10214 vpip = vport->vpip;
10215
10216 if (!(vport->flag & EMLXS_PORT_BOUND) ||
10217 (vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
10218 continue;
10219 }
10220
10221 if (vpip->vfip == vfip) {
10222 break;
10223 }
10224 }
10225
10226 } else {
10227
10228 /* Find first available VPI */
10229 for (i = 0; i <= hba->vpi_max; i++) {
10230 vport = &VPORT(i);
10231 vpip = vport->vpip;
10232
10233 if (!(vport->flag & EMLXS_PORT_BOUND) ||
10234 (vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
10235 continue;
10236 }
10237
10238 if (vpip->vfip == NULL) {
10239 vpip->vfip = vfip;
10240 break;
10241 }
10242 }
10243 }
10244
10245 if (i > hba->vpi_max) {
10246 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10247 "vfi_vpi_online_action:%d vpi_online=%d logi_count=%d. "
10248 "No VPI found. Offlining.",
10249 vfip->VFI,
10250 vfip->vpi_online,
10251 vfip->logi_count);
10252
10253 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
10254 vfip->flag |= EMLXS_VFI_OFFLINE_REQ;
10255 rval = emlxs_vfi_offline_handler(port, vfip, arg1);
10256 return (rval);
10257 }
10258
10259 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10260 "vfi_vpi_online_action:%d vpi_online=%d logi_count=%d. "
10261 "Onlining VPI:%d >",
10262 vfip->VFI,
10263 vfip->vpi_online,
10264 vfip->logi_count,
10265 vpip->VPI);
10266
10267 rval = emlxs_vpi_event(port, FCF_EVENT_VPI_ONLINE, vpip);
10268
10269 /* Wait for FCF_EVENT_VPI_ONLINE in return */
10270
10271 return (rval);
10272
10273 } /* emlxs_vfi_vpi_online_action() */
10274
10275
10276 /*ARGSUSED*/
10277 static uint32_t
emlxs_vfi_vpi_online_cmpl_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10278 emlxs_vfi_vpi_online_cmpl_action(emlxs_port_t *port, VFIobj_t *vfip,
10279 uint32_t evt, void *arg1)
10280 {
10281 uint32_t rval = 0;
10282 VPIobj_t *vpip = (VPIobj_t *)arg1;
10283
10284 if (vfip->state != VFI_STATE_VPI_ONLINE_CMPL) {
10285 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10286 "vfi_vpi_online_cmpl_action:%d %s:%s arg=%p. "
10287 "Invalid state. <",
10288 vfip->VFI,
10289 emlxs_vfi_state_xlate(vfip->state),
10290 emlxs_fcf_event_xlate(evt), arg1);
10291 return (1);
10292 }
10293
10294 if (vpip == vfip->flogi_vpip) {
10295 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10296 "vfi_vpi_online_cmpl_action:%d flag=%x vpi_online=%d "
10297 "logi_count=%d. flogi_vpi. Registering.",
10298 vfip->VFI,
10299 vfip->flag,
10300 vfip->vpi_online,
10301 vfip->logi_count);
10302
10303 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG,
10304 FCF_REASON_EVENT, evt, arg1);
10305 } else {
10306 /* Waking up after pause */
10307 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10308 "vfi_vpi_online_cmpl_action:%d flag=%x vpi_online=%d "
10309 "logi_count=%d. Going online.",
10310 vfip->VFI,
10311 vfip->flag,
10312 vfip->vpi_online,
10313 vfip->logi_count);
10314
10315 rval = emlxs_vfi_state(port, vfip, VFI_STATE_ONLINE,
10316 FCF_REASON_EVENT, evt, arg1);
10317 }
10318
10319 return (rval);
10320
10321 } /* emlxs_vfi_vpi_online_cmpl_action() */
10322
10323
10324 /*ARGSUSED*/
10325 static uint32_t
emlxs_vfi_vpi_offline_cmpl_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10326 emlxs_vfi_vpi_offline_cmpl_action(emlxs_port_t *port, VFIobj_t *vfip,
10327 uint32_t evt, void *arg1)
10328 {
10329 uint32_t rval = 0;
10330
10331 if (vfip->state != VFI_STATE_VPI_OFFLINE_CMPL) {
10332 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10333 "vfi_vpi_offline_cmpl_action:%d %s:%s arg=%p. "
10334 "Invalid state. <",
10335 vfip->VFI,
10336 emlxs_vfi_state_xlate(vfip->state),
10337 emlxs_fcf_event_xlate(evt), arg1);
10338 return (1);
10339 }
10340
10341 if ((vfip->vpi_online == 0) &&
10342 (vfip->flag & EMLXS_VFI_OFFLINE_REQ)) {
10343 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10344 "vfi_vpi_offline_cmpl_action:%d vpi_online=%d. "
10345 "Unregistering.",
10346 vfip->VFI,
10347 vfip->vpi_online);
10348
10349 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG,
10350 FCF_REASON_EVENT, evt, arg1);
10351 } else {
10352 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10353 "vfi_vpi_offline_cmpl_action:%d vpi_online=%d. <",
10354 vfip->VFI,
10355 vfip->vpi_online);
10356 }
10357
10358 return (rval);
10359
10360 } /* emlxs_vfi_vpi_offline_cmpl_action() */
10361
10362
10363 /*ARGSUSED*/
10364 static uint32_t
emlxs_vfi_vpi_offline_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10365 emlxs_vfi_vpi_offline_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10366 void *arg1)
10367 {
10368 emlxs_hba_t *hba = HBA;
10369 emlxs_port_t *vport;
10370 uint32_t rval = 0;
10371 int32_t i;
10372 VPIobj_t *vpip;
10373
10374 if (vfip->state != VFI_STATE_VPI_OFFLINE) {
10375 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10376 "vfi_vpi_offline_action:%d %s:%s arg=%p. "
10377 "Invalid state. <",
10378 vfip->VFI,
10379 emlxs_vfi_state_xlate(vfip->state),
10380 emlxs_fcf_event_xlate(evt), arg1);
10381 return (1);
10382 }
10383
10384 if (vfip->flag & EMLXS_VFI_PAUSE_REQ) {
10385 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10386 "vfi_vpi_offline_action:%d vpi_online=%d. Pausing.",
10387 vfip->VFI,
10388 vfip->vpi_online);
10389
10390 rval = emlxs_vfi_state(port, vfip, VFI_STATE_PAUSED,
10391 FCF_REASON_EVENT, evt, arg1);
10392
10393 return (rval);
10394 }
10395
10396 if (vfip->vpi_online == 0) {
10397 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10398 "vfi_vpi_offline_action:%d vpi_online=%d. "
10399 "VPI already offline. Skipping VPI offline.",
10400 vfip->VFI,
10401 vfip->vpi_online);
10402
10403 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG,
10404 FCF_REASON_EVENT, evt, arg1);
10405
10406 return (rval);
10407 }
10408
10409 /* Offline all VPI's of this VFI */
10410 for (i = hba->vpi_max; i >= 0; i--) {
10411 vport = &VPORT(i);
10412 vpip = vport->vpip;
10413
10414 if ((vpip->state == VPI_STATE_OFFLINE) ||
10415 (vpip->vfip != vfip)) {
10416 continue;
10417 }
10418
10419 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10420 "vfi_vpi_offline_action:%d. Offlining VPI:%d. >",
10421 vfip->VFI,
10422 vpip->VPI);
10423
10424 (void) emlxs_vpi_event(vport, FCF_EVENT_VPI_OFFLINE, vpip);
10425 }
10426
10427 /* Wait for FCF_EVENT_VPI_OFFLINE in return */
10428
10429 return (0);
10430
10431 } /* emlxs_vfi_vpi_offline_action() */
10432
10433
10434 /*ARGSUSED*/
10435 static uint32_t
emlxs_vfi_paused_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10436 emlxs_vfi_paused_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10437 void *arg1)
10438 {
10439 emlxs_hba_t *hba = HBA;
10440 emlxs_port_t *vport;
10441 int32_t i;
10442 VPIobj_t *vpip;
10443
10444 if (vfip->state != VFI_STATE_PAUSED) {
10445 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10446 "vfi_paused_action:%d %s:%s arg=%p. "
10447 "Invalid state. <",
10448 vfip->VFI,
10449 emlxs_vfi_state_xlate(vfip->state),
10450 emlxs_fcf_event_xlate(evt), arg1);
10451 return (1);
10452 }
10453
10454 vfip->flag &= ~(EMLXS_VFI_OFFLINE_REQ | EMLXS_VFI_PAUSE_REQ);
10455
10456 /* Pause all VPI's of this VFI */
10457 for (i = hba->vpi_max; i >= 0; i--) {
10458 vport = &VPORT(i);
10459 vpip = vport->vpip;
10460
10461 if ((vpip->state == VPI_STATE_PAUSED) ||
10462 (vpip->vfip != vfip)) {
10463 continue;
10464 }
10465
10466 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10467 "vfi_paused_action:%d vpi_online=%d. Pausing VPI:%d. >",
10468 vfip->VFI,
10469 vfip->vpi_online,
10470 vpip->VPI);
10471
10472 (void) emlxs_vpi_event(vport, FCF_EVENT_VPI_PAUSE, vpip);
10473 }
10474
10475 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10476 "vfi_paused_action:%d vpi_online=%d. VFI paused. <",
10477 vfip->VFI,
10478 vfip->vpi_online);
10479
10480 return (0);
10481
10482 } /* emlxs_vfi_paused_action() */
10483
10484
10485 /*ARGSUSED*/
10486 static uint32_t
emlxs_vfi_unreg_failed_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10487 emlxs_vfi_unreg_failed_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10488 void *arg1)
10489 {
10490 uint32_t rval = 0;
10491
10492 vfip->attempts++;
10493
10494 if (vfip->state != VFI_STATE_UNREG_FAILED) {
10495 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
10496 "vfi_unreg_failed_action:%d %s:%s arg=%p attempt=%d. "
10497 "Invalid state. <",
10498 vfip->VFI,
10499 emlxs_vfi_state_xlate(vfip->state),
10500 emlxs_fcf_event_xlate(evt), arg1,
10501 vfip->attempts);
10502 return (1);
10503 }
10504
10505 if (vfip->attempts >= 3) {
10506 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10507 "vfi_unreg_failed_action:%d attempt=%d. Unreg cmpl.",
10508 vfip->VFI,
10509 vfip->attempts);
10510
10511 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
10512 vfip->flag |= EMLXS_VFI_OFFLINE_REQ;
10513 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG_CMPL,
10514 FCF_REASON_OP_FAILED, vfip->attempts, arg1);
10515 } else {
10516 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10517 "vfi_unreg_failed_action:%d attempt=%d. Unregistering.",
10518 vfip->VFI,
10519 vfip->attempts);
10520
10521 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG,
10522 FCF_REASON_OP_FAILED, vfip->attempts, arg1);
10523 }
10524
10525 return (rval);
10526
10527 } /* emlxs_vfi_unreg_failed_action() */
10528
10529
10530 /*ARGSUSED*/
10531 static uint32_t
emlxs_vfi_unreg_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)10532 emlxs_vfi_unreg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
10533 {
10534 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
10535 MAILBOX4 *mb4;
10536 VFIobj_t *vfip;
10537
10538 vfip = (VFIobj_t *)mbq->context;
10539 mb4 = (MAILBOX4 *)mbq;
10540
10541 mutex_enter(&EMLXS_FCF_LOCK);
10542
10543 if (vfip->state != VFI_STATE_UNREG) {
10544 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10545 "vfi_unreg_mbcmpl:%d state=%s.",
10546 vfip->VFI,
10547 emlxs_vfi_state_xlate(vfip->state));
10548
10549 mutex_exit(&EMLXS_FCF_LOCK);
10550 return (0);
10551 }
10552
10553 if (mb4->mbxStatus) {
10554 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10555 "vfi_unreg_mbcmpl:%d failed. %s. >",
10556 vfip->VFI,
10557 emlxs_mb_xlate_status(mb4->mbxStatus));
10558
10559 (void) emlxs_vfi_state(port, vfip, VFI_STATE_UNREG_FAILED,
10560 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, (void *)mbq->sbp);
10561
10562 mutex_exit(&EMLXS_FCF_LOCK);
10563 return (0);
10564 }
10565
10566 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10567 "vfi_unreg_mbcmpl:%d. Unreg complete. >",
10568 vfip->VFI);
10569
10570 vfip->flag &= ~(EMLXS_VFI_REG | EMLXS_VFI_INIT);
10571 (void) emlxs_vfi_state(port, vfip, VFI_STATE_UNREG_CMPL,
10572 0, 0, 0);
10573
10574 mutex_exit(&EMLXS_FCF_LOCK);
10575 return (0);
10576
10577 } /* emlxs_vfi_unreg_mbcmpl() */
10578
10579
10580 /*ARGSUSED*/
10581 static uint32_t
emlxs_vfi_unreg_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10582 emlxs_vfi_unreg_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10583 void *arg1)
10584 {
10585 emlxs_hba_t *hba = HBA;
10586 MAILBOX4 *mb4;
10587 MAILBOXQ *mbq;
10588 uint32_t rval = 0;
10589
10590 if (vfip->state != VFI_STATE_UNREG) {
10591 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
10592 "vfi_unreg_action:%d %s:%s arg=%p. "
10593 "Invalid state. <",
10594 vfip->VFI,
10595 emlxs_vfi_state_xlate(vfip->state),
10596 emlxs_fcf_event_xlate(evt), arg1);
10597 return (1);
10598 }
10599
10600 if (!(vfip->flag & EMLXS_VFI_REG)) {
10601 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10602 "vfi_unreg_action:%d. Not registered. Skipping UNREG_VFI.",
10603 vfip->VFI);
10604
10605 rval = emlxs_vfi_state(port, vfip, VFI_STATE_OFFLINE,
10606 FCF_REASON_EVENT, evt, arg1);
10607 return (rval);
10608 }
10609
10610 if (vfip->prev_state != VFI_STATE_UNREG_FAILED) {
10611 vfip->attempts = 0;
10612 }
10613
10614 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10615 "vfi_unreg_action:%d attempts=%d. Sending UNREG_VFI. <",
10616 vfip->VFI,
10617 vfip->attempts);
10618
10619 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
10620 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG_FAILED,
10621 FCF_REASON_NO_MBOX, 0, arg1);
10622
10623 return (rval);
10624 }
10625 mb4 = (MAILBOX4*)mbq;
10626 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
10627
10628 mbq->nonembed = NULL;
10629 mbq->mbox_cmpl = emlxs_vfi_unreg_mbcmpl;
10630 mbq->context = (void *)vfip;
10631 mbq->port = (void *)port;
10632
10633 mb4->un.varUnRegVFI4.vfi = vfip->VFI;
10634 mb4->mbxCommand = MBX_UNREG_VFI;
10635 mb4->mbxOwner = OWN_HOST;
10636
10637 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
10638 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
10639 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
10640
10641 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG_FAILED,
10642 FCF_REASON_SEND_FAILED, rval, arg1);
10643
10644 return (rval);
10645 }
10646
10647 return (0);
10648
10649 } /* emlxs_vfi_unreg_action() */
10650
10651
10652 /*ARGSUSED*/
10653 static uint32_t
emlxs_vfi_unreg_cmpl_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10654 emlxs_vfi_unreg_cmpl_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10655 void *arg1)
10656 {
10657 uint32_t rval = 0;
10658
10659 if (vfip->state != VFI_STATE_UNREG_CMPL) {
10660 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
10661 "vfi_unreg_cmpl_action:%d %s:%s arg=%p. "
10662 "Invalid state. <",
10663 vfip->VFI,
10664 emlxs_vfi_state_xlate(vfip->state),
10665 emlxs_fcf_event_xlate(evt), arg1);
10666 return (1);
10667 }
10668
10669 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10670 "vfi_unreg_cmpl_action:%d attempts=%d. Going offline.",
10671 vfip->VFI,
10672 vfip->attempts);
10673
10674 rval = emlxs_vfi_state(port, vfip, VFI_STATE_OFFLINE,
10675 FCF_REASON_EVENT, evt, arg1);
10676
10677 return (rval);
10678
10679 } /* emlxs_vfi_unreg_cmpl_action() */
10680
10681
10682 /*ARGSUSED*/
10683 static uint32_t
emlxs_vfi_reg_failed_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10684 emlxs_vfi_reg_failed_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10685 void *arg1)
10686 {
10687 uint32_t rval = 0;
10688
10689 vfip->attempts++;
10690
10691 if (vfip->state != VFI_STATE_REG_FAILED) {
10692 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
10693 "vfi_reg_failed_action:%d %s:%s arg=%p attempt=%d. "
10694 "Invalid state. <",
10695 vfip->VFI,
10696 emlxs_vfi_state_xlate(vfip->state),
10697 emlxs_fcf_event_xlate(evt), arg1,
10698 vfip->attempts);
10699 return (1);
10700 }
10701
10702 if ((vfip->reason == FCF_REASON_SEND_FAILED) ||
10703 (vfip->attempts >= 3)) {
10704 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10705 "vfi_reg_failed_action:%d attempt=%d reason=%x. Reg cmpl.",
10706 vfip->VFI,
10707 vfip->attempts,
10708 vfip->reason);
10709
10710 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
10711 vfip->flag |= EMLXS_VFI_OFFLINE_REQ;
10712 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG_CMPL,
10713 FCF_REASON_OP_FAILED, vfip->attempts, arg1);
10714 } else {
10715 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10716 "vfi_reg_failed_action:%d attempt=%d. Registering.",
10717 vfip->VFI,
10718 vfip->attempts);
10719
10720 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG,
10721 FCF_REASON_OP_FAILED, vfip->attempts, arg1);
10722 }
10723
10724 return (rval);
10725
10726 } /* emlxs_vfi_reg_failed_action() */
10727
10728
10729 /*ARGSUSED*/
10730 static uint32_t
emlxs_vfi_reg_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)10731 emlxs_vfi_reg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
10732 {
10733 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
10734 MAILBOX4 *mb4;
10735 VFIobj_t *vfip;
10736 MATCHMAP *mp;
10737
10738 vfip = (VFIobj_t *)mbq->context;
10739 mb4 = (MAILBOX4 *)mbq;
10740
10741 mutex_enter(&EMLXS_FCF_LOCK);
10742
10743 if (vfip->state != VFI_STATE_REG) {
10744 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10745 "vfi_reg_mbcmpl:%d state=%s.",
10746 vfip->VFI,
10747 emlxs_vfi_state_xlate(vfip->state));
10748
10749 mutex_exit(&EMLXS_FCF_LOCK);
10750 return (0);
10751 }
10752
10753 if (mb4->mbxStatus) {
10754 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10755 "vfi_reg_mbcmpl:%d failed. %s. >",
10756 vfip->VFI,
10757 emlxs_mb_xlate_status(mb4->mbxStatus));
10758
10759 (void) emlxs_vfi_state(port, vfip, VFI_STATE_REG_FAILED,
10760 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, (void *)mbq->sbp);
10761
10762 mutex_exit(&EMLXS_FCF_LOCK);
10763 return (0);
10764 }
10765
10766 /* Archive a copy of the sparams in case we need them later */
10767 mp = (MATCHMAP *)mbq->bp;
10768 bcopy((uint32_t *)mp->virt, (uint32_t *)&vfip->sparam,
10769 sizeof (SERV_PARM));
10770
10771 if (vfip->flogi_vpip) {
10772 if (mb4->un.varRegVFI4.vp == 1) {
10773 vfip->flogi_vpip->flag |= EMLXS_VPI_REG;
10774 }
10775 vfip->flogi_vpip = NULL;
10776 }
10777
10778 vfip->flag |= EMLXS_VFI_REG;
10779
10780 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10781 "vfi_reg_mbcmpl:%d. Reg complete. >",
10782 vfip->VFI);
10783
10784 (void) emlxs_vfi_state(port, vfip, VFI_STATE_REG_CMPL, 0, 0, 0);
10785
10786 mutex_exit(&EMLXS_FCF_LOCK);
10787 return (0);
10788
10789 } /* emlxs_vfi_reg_mbcmpl() */
10790
10791
10792 /*ARGSUSED*/
10793 static uint32_t
emlxs_vfi_reg_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10794 emlxs_vfi_reg_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10795 void *arg1)
10796 {
10797 emlxs_hba_t *hba = HBA;
10798 MAILBOX4 *mb4;
10799 MAILBOXQ *mbq;
10800 MATCHMAP *mp;
10801 uint32_t rval = 0;
10802 uint32_t edtov;
10803 uint32_t ratov;
10804 SERV_PARM *flogi_sparam;
10805 uint32_t *wwpn;
10806
10807 if (vfip->state != VFI_STATE_REG) {
10808 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
10809 "vfi_reg_action:%d %s:%s arg=%p. "
10810 "Invalid state. <",
10811 vfip->VFI,
10812 emlxs_vfi_state_xlate(vfip->state),
10813 emlxs_fcf_event_xlate(evt), arg1);
10814 return (1);
10815 }
10816
10817 if (vfip->prev_state != VFI_STATE_REG_FAILED) {
10818 vfip->attempts = 0;
10819 }
10820
10821 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) {
10822 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10823 "vfi_reg_action:%d %attempts=%d. Offline requested.",
10824 vfip->VFI,
10825 vfip->attempts);
10826
10827 rval = emlxs_vfi_offline_handler(port, vfip, arg1);
10828 return (rval);
10829 }
10830
10831 if (!vfip->flogi_vpip) {
10832 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10833 "vfi_reg_action:%d %attempts=%d. No flogi_vpi found.",
10834 vfip->VFI,
10835 vfip->attempts);
10836
10837 vfip->flag &= ~EMLXS_VFI_REQ_MASK;
10838 vfip->flag |= EMLXS_VFI_OFFLINE_REQ;
10839
10840 rval = emlxs_vfi_offline_handler(port, vfip, arg1);
10841 return (rval);
10842 }
10843
10844 if ((hba->model_info.chip & EMLXS_BE_CHIPS) &&
10845 (vfip->flag & EMLXS_VFI_REG)) {
10846 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10847 "vfi_reg_action:%d flag=%x. "
10848 "Already registered. Skipping REG_VFI update.",
10849 vfip->VFI);
10850
10851 rval = emlxs_vfi_state(port, vfip, VFI_STATE_ONLINE,
10852 FCF_REASON_EVENT, evt, arg1);
10853 return (rval);
10854 }
10855
10856 /* Get the flogi_vpip's fabric_rpip's service parameters */
10857 flogi_sparam = &vfip->flogi_vpip->fabric_rpip->sparam;
10858
10859 if (flogi_sparam->cmn.edtovResolution) {
10860 edtov = (LE_SWAP32(flogi_sparam->cmn.e_d_tov) + 999999) /
10861 1000000;
10862 } else {
10863 edtov = LE_SWAP32(flogi_sparam->cmn.e_d_tov);
10864 }
10865
10866 ratov = (LE_SWAP32(flogi_sparam->cmn.w2.r_a_tov) + 999) / 1000;
10867
10868 if (vfip->flag & EMLXS_VFI_REG) {
10869 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10870 "vfi_reg_action:%d attempts=%d edtov=%d ratov=%d. "
10871 "Updating REG_VFI. <",
10872 vfip->VFI,
10873 vfip->attempts,
10874 edtov, ratov);
10875 } else {
10876 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10877 "vfi_reg_action:%d attempts=%d edtov=%d ratov=%d. "
10878 "Sending REG_VFI. <",
10879 vfip->VFI,
10880 vfip->attempts,
10881 edtov, ratov);
10882 }
10883
10884 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
10885 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG_FAILED,
10886 FCF_REASON_NO_MBOX, 0, arg1);
10887
10888 return (rval);
10889 }
10890 mb4 = (MAILBOX4*)mbq;
10891 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
10892
10893 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
10894 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
10895
10896 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG_FAILED,
10897 FCF_REASON_NO_BUFFER, 0, arg1);
10898
10899 return (1);
10900 }
10901
10902 mbq->bp = (void *)mp;
10903 mbq->nonembed = NULL;
10904
10905 mbq->mbox_cmpl = emlxs_vfi_reg_mbcmpl;
10906 mbq->context = (void *)vfip;
10907 mbq->port = (void *)port;
10908
10909 mb4->mbxCommand = MBX_REG_VFI;
10910 mb4->mbxOwner = OWN_HOST;
10911
10912 mb4->un.varRegVFI4.vfi = vfip->VFI;
10913 mb4->un.varRegVFI4.upd = (vfip->flag & EMLXS_VFI_REG)? 1:0;
10914
10915 /* If the flogi_vpip was not previously registered, */
10916 /* perform the REG_VPI now */
10917 if (!(vfip->flogi_vpip->flag & EMLXS_VPI_REG)) {
10918 mb4->un.varRegVFI4.vp = 1;
10919 mb4->un.varRegVFI4.vpi = vfip->flogi_vpip->VPI;
10920 }
10921
10922 mb4->un.varRegVFI4.fcfi = vfip->fcfp->FCFI;
10923 wwpn = (uint32_t *)&port->wwpn;
10924 mb4->un.varRegVFI4.portname[0] = BE_SWAP32(*wwpn);
10925 wwpn++;
10926 mb4->un.varRegVFI4.portname[1] = BE_SWAP32(*wwpn);
10927 mb4->un.varRegVFI4.sid = port->did;
10928 mb4->un.varRegVFI4.edtov = edtov;
10929 mb4->un.varRegVFI4.ratov = ratov;
10930 mb4->un.varRegVFI4.bde.tus.f.bdeSize = sizeof (SERV_PARM);
10931 mb4->un.varRegVFI4.bde.addrHigh = PADDR_HI(mp->phys);
10932 mb4->un.varRegVFI4.bde.addrLow = PADDR_LO(mp->phys);
10933 bcopy((uint32_t *)flogi_sparam, (uint32_t *)mp->virt,
10934 sizeof (SERV_PARM));
10935
10936 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
10937 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
10938 emlxs_mem_put(hba, MEM_BUF, (void *)mp);
10939 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
10940
10941 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG_FAILED,
10942 FCF_REASON_SEND_FAILED, rval, arg1);
10943
10944 return (rval);
10945 }
10946
10947 return (0);
10948
10949 } /* emlxs_vfi_reg_action() */
10950
10951
10952 /*ARGSUSED*/
10953 static uint32_t
emlxs_vfi_reg_cmpl_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10954 emlxs_vfi_reg_cmpl_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10955 void *arg1)
10956 {
10957 uint32_t rval = 0;
10958
10959 if (vfip->state != VFI_STATE_REG_CMPL) {
10960 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
10961 "vfi_reg_cmpl_action:%d %s:%s arg=%p. "
10962 "Invalid state. <",
10963 vfip->VFI,
10964 emlxs_vfi_state_xlate(vfip->state),
10965 emlxs_fcf_event_xlate(evt), arg1);
10966 return (1);
10967 }
10968
10969 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) {
10970 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10971 "vfi_reg_cmpl_action:%d attempts=%d. Offline requested.",
10972 vfip->VFI,
10973 vfip->attempts);
10974
10975 rval = emlxs_vfi_offline_handler(port, vfip, arg1);
10976 return (rval);
10977 }
10978
10979 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
10980 "vfi_reg_cmpl_action:%d attempts=%d. Going online.",
10981 vfip->VFI,
10982 vfip->attempts);
10983
10984 rval = emlxs_vfi_state(port, vfip, VFI_STATE_ONLINE,
10985 FCF_REASON_EVENT, evt, arg1);
10986
10987 return (rval);
10988
10989 } /* emlxs_vfi_reg_cmpl_action() */
10990
10991
10992 /*ARGSUSED*/
10993 static uint32_t
emlxs_vfi_online_action(emlxs_port_t * port,VFIobj_t * vfip,uint32_t evt,void * arg1)10994 emlxs_vfi_online_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt,
10995 void *arg1)
10996 {
10997 emlxs_hba_t *hba = HBA;
10998 uint32_t i;
10999 uint32_t rval = 0;
11000 VPIobj_t *vpip = port->vpip;
11001 emlxs_port_t *vport;
11002
11003 if (vfip->state != VFI_STATE_ONLINE) {
11004 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11005 "vfi_online_action:%d %s:%s arg=%p. "
11006 "Invalid state. <",
11007 vfip->VFI,
11008 emlxs_vfi_state_xlate(vfip->state),
11009 emlxs_fcf_event_xlate(evt), arg1);
11010 return (1);
11011 }
11012
11013 vfip->flag &= ~EMLXS_VFI_ONLINE_REQ;
11014
11015 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) {
11016 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11017 "vfi_online_action:%d attempts=%d. Offline requested.",
11018 vfip->VFI,
11019 vfip->attempts);
11020
11021 rval = emlxs_vfi_offline_handler(port, vfip, arg1);
11022 return (rval);
11023 }
11024
11025 /* Take the port's Fabric RPI online now */
11026 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11027 "vfi_online_action:%d. Onlining Fabric RPI. >",
11028 vfip->VFI);
11029
11030 /* This will complete the FLOGI/FDISC back to Leadville */
11031 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_ONLINE,
11032 vpip->fabric_rpip);
11033
11034 /* FLOGI/FDISC has been completed back to Leadville */
11035 /* It is now safe to accept unsolicited requests */
11036 vpip->flag |= EMLXS_VPI_PORT_ENABLED;
11037
11038 /* Online remaining VPI's */
11039 for (i = 0; i <= hba->vpi_max; i++) {
11040 vport = &VPORT(i);
11041 vpip = vport->vpip;
11042
11043 if (!(vport->flag & EMLXS_PORT_BOUND) ||
11044 (vpip->flag & EMLXS_VPI_PORT_UNBIND)) {
11045 continue;
11046 }
11047
11048 if ((vpip->state == VPI_STATE_ONLINE) ||
11049 (vpip->flag & EMLXS_VPI_ONLINE_REQ)) {
11050 continue;
11051 }
11052
11053 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11054 "vfi_online_action:%d vpi_online=%d logi_count=%d. "
11055 "Onlining VPI:%d >",
11056 vfip->VFI,
11057 vfip->vpi_online,
11058 vfip->logi_count,
11059 vpip->VPI);
11060
11061 vpip->vfip = vfip;
11062 (void) emlxs_vpi_event(vport, FCF_EVENT_VPI_ONLINE, vpip);
11063 }
11064
11065 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11066 "vfi_online_action:%d vpi_online=%d logi_count=%d. "
11067 "VFI online. Notifying FCFI:%d. >",
11068 vfip->VFI,
11069 vfip->vpi_online,
11070 vfip->logi_count,
11071 vfip->fcfp->fcf_index);
11072
11073 /* Notify FCFI */
11074 rval = emlxs_fcfi_event(port, FCF_EVENT_VFI_ONLINE, vfip);
11075
11076 return (rval);
11077
11078 } /* emlxs_vfi_online_action() */
11079
11080
11081 /* ************************************************************************** */
11082 /* VPI */
11083 /* ************************************************************************** */
11084
11085 static char *
emlxs_vpi_state_xlate(uint32_t state)11086 emlxs_vpi_state_xlate(uint32_t state)
11087 {
11088 static char buffer[32];
11089 uint32_t i;
11090 uint32_t count;
11091
11092 count = sizeof (emlxs_vpi_state_table) / sizeof (emlxs_table_t);
11093 for (i = 0; i < count; i++) {
11094 if (state == emlxs_vpi_state_table[i].code) {
11095 return (emlxs_vpi_state_table[i].string);
11096 }
11097 }
11098
11099 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state);
11100 return (buffer);
11101
11102 } /* emlxs_vpi_state_xlate() */
11103
11104
11105 static uint32_t
emlxs_vpi_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)11106 emlxs_vpi_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
11107 void *arg1)
11108 {
11109 uint32_t rval = 0;
11110 uint32_t(*func) (emlxs_port_t *, VPIobj_t *, uint32_t, void *);
11111 uint32_t index;
11112 uint32_t events;
11113 uint16_t state;
11114
11115 /* Convert event to action table index */
11116 switch (evt) {
11117 case FCF_EVENT_STATE_ENTER:
11118 index = 0;
11119 break;
11120 case FCF_EVENT_VPI_ONLINE:
11121 index = 1;
11122 break;
11123 case FCF_EVENT_VPI_OFFLINE:
11124 index = 2;
11125 break;
11126 case FCF_EVENT_VPI_PAUSE:
11127 index = 3;
11128 break;
11129 case FCF_EVENT_RPI_ONLINE:
11130 index = 4;
11131 break;
11132 case FCF_EVENT_RPI_OFFLINE:
11133 index = 5;
11134 break;
11135 case FCF_EVENT_RPI_PAUSE:
11136 index = 6;
11137 break;
11138 default:
11139 return (1);
11140 }
11141
11142 events = VPI_ACTION_EVENTS;
11143 state = vpip->state;
11144
11145 index += (state * events);
11146 func = (uint32_t(*) (emlxs_port_t *, VPIobj_t *, uint32_t, void *))
11147 emlxs_vpi_action_table[index];
11148
11149 if (!func) {
11150 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
11151 "vpi_action:%d %s:%s arg=%p. No action. <",
11152 vpip->VPI,
11153 emlxs_vpi_state_xlate(vpip->state),
11154 emlxs_fcf_event_xlate(evt), arg1);
11155
11156 return (1);
11157 }
11158
11159 rval = (func)(port, vpip, evt, arg1);
11160
11161 return (rval);
11162
11163 } /* emlxs_vpi_action() */
11164
11165
11166 static uint32_t
emlxs_vpi_event(emlxs_port_t * port,uint32_t evt,void * arg1)11167 emlxs_vpi_event(emlxs_port_t *port, uint32_t evt,
11168 void *arg1)
11169 {
11170 VPIobj_t *vpip = NULL;
11171 RPIobj_t *rpip;
11172 uint32_t rval = 0;
11173
11174 /* Filter events and acquire fcfi context */
11175 switch (evt) {
11176 case FCF_EVENT_RPI_ONLINE:
11177 case FCF_EVENT_RPI_OFFLINE:
11178 case FCF_EVENT_RPI_PAUSE:
11179 rpip = (RPIobj_t *)arg1;
11180
11181 if (!rpip) {
11182 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
11183 "vpi_event: %s arg=%p. Null RPI found. <",
11184 emlxs_fcf_event_xlate(evt), arg1);
11185
11186 return (1);
11187 }
11188
11189 vpip = rpip->vpip;
11190 break;
11191
11192 case FCF_EVENT_VPI_ONLINE:
11193 case FCF_EVENT_VPI_PAUSE:
11194 case FCF_EVENT_VPI_OFFLINE:
11195 vpip = (VPIobj_t *)arg1;
11196
11197 if (!vpip) {
11198 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
11199 "vpi_event: %s arg=%p. Null VPI found. <",
11200 emlxs_fcf_event_xlate(evt), arg1);
11201
11202 return (1);
11203 }
11204
11205 break;
11206
11207 default:
11208 return (1);
11209 }
11210
11211 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
11212 "vpi_event:%d %s:%s arg=%p",
11213 vpip->VPI,
11214 emlxs_vpi_state_xlate(vpip->state),
11215 emlxs_fcf_event_xlate(evt), arg1);
11216
11217 rval = emlxs_vpi_action(port, vpip, evt, arg1);
11218
11219 return (rval);
11220
11221 } /* emlxs_vpi_event() */
11222
11223
11224 /*ARGSUSED*/
11225 static uint32_t
emlxs_vpi_state(emlxs_port_t * port,VPIobj_t * vpip,uint16_t state,uint16_t reason,uint32_t explain,void * arg1)11226 emlxs_vpi_state(emlxs_port_t *port, VPIobj_t *vpip, uint16_t state,
11227 uint16_t reason, uint32_t explain, void *arg1)
11228 {
11229 uint32_t rval = 0;
11230
11231 if (state >= VPI_ACTION_STATES) {
11232 return (1);
11233 }
11234
11235 if ((vpip->state == state) &&
11236 (reason != FCF_REASON_REENTER)) {
11237 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
11238 "vpi_state:%d %s:%s:0x%x arg=%p. "
11239 "State not changed. <",
11240 vpip->VPI,
11241 emlxs_vpi_state_xlate(vpip->state),
11242 emlxs_fcf_reason_xlate(reason),
11243 explain, arg1);
11244 return (1);
11245 }
11246
11247 if (!reason) {
11248 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
11249 "vpi_state:%d %s-->%s arg=%p",
11250 vpip->VPI,
11251 emlxs_vpi_state_xlate(vpip->state),
11252 emlxs_vpi_state_xlate(state), arg1);
11253 } else if (reason == FCF_REASON_EVENT) {
11254 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
11255 "vpi_state:%d %s-->%s:%s:%s arg=%p",
11256 vpip->VPI,
11257 emlxs_vpi_state_xlate(vpip->state),
11258 emlxs_vpi_state_xlate(state),
11259 emlxs_fcf_reason_xlate(reason),
11260 emlxs_fcf_event_xlate(explain), arg1);
11261 } else if (explain) {
11262 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
11263 "vpi_state:%d %s-->%s:%s:0x%x arg=%p",
11264 vpip->VPI,
11265 emlxs_vpi_state_xlate(vpip->state),
11266 emlxs_vpi_state_xlate(state),
11267 emlxs_fcf_reason_xlate(reason),
11268 explain, arg1);
11269 } else {
11270 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
11271 "vpi_state:%d %s-->%s:%s arg=%p",
11272 vpip->VPI,
11273 emlxs_vpi_state_xlate(vpip->state),
11274 emlxs_vpi_state_xlate(state),
11275 emlxs_fcf_reason_xlate(reason), arg1);
11276 }
11277
11278 vpip->prev_state = vpip->state;
11279 vpip->prev_reason = vpip->reason;
11280 vpip->state = state;
11281 vpip->reason = reason;
11282
11283 rval = emlxs_vpi_action(port, vpip, FCF_EVENT_STATE_ENTER, arg1);
11284
11285 return (rval);
11286
11287 } /* emlxs_vpi_state() */
11288
11289
11290 extern uint32_t
emlxs_vpi_port_bind_notify(emlxs_port_t * port)11291 emlxs_vpi_port_bind_notify(emlxs_port_t *port)
11292 {
11293 emlxs_hba_t *hba = HBA;
11294 VPIobj_t *vpip = port->vpip;
11295 FCFTable_t *fcftab = &hba->sli.sli4.fcftab;
11296 uint32_t rval = 0;
11297 VFIobj_t *vfip;
11298 VFIobj_t *vfip1;
11299 uint32_t i = 0;
11300 FCFIobj_t *fcfp;
11301 FCFIobj_t *fcfp1;
11302
11303 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
11304 return (1);
11305 }
11306
11307 if (hba->state < FC_LINK_UP) {
11308 if (port->vpi == 0) {
11309 (void) emlxs_reset_link(hba, 1, 0);
11310
11311 /* Wait for VPI to go online */
11312 while ((vpip->state != VPI_STATE_PORT_ONLINE) &&
11313 (hba->state != FC_ERROR)) {
11314 delay(drv_usectohz(500000));
11315 if (i++ > 30) {
11316 break;
11317 }
11318 }
11319 }
11320 return (0);
11321 }
11322
11323 mutex_enter(&EMLXS_FCF_LOCK);
11324
11325 if (vpip->vfip) {
11326 vfip = vpip->vfip;
11327 fcfp = vfip->fcfp;
11328 goto done;
11329 }
11330
11331 /* We need to select a VFI for this VPI */
11332
11333 /* First find a selected Fabric */
11334 fcfp = NULL;
11335 for (i = 0; i < fcftab->fcfi_count; i++) {
11336 fcfp1 = fcftab->fcfi[i];
11337
11338 if (fcfp1->flag & EMLXS_FCFI_SELECTED) {
11339 fcfp = fcfp1;
11340 break;
11341 }
11342 }
11343
11344 if (!fcfp) {
11345 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11346 "vpi_port_bind_notify:%d %s. "
11347 "No FCF available yet.",
11348 vpip->VPI,
11349 emlxs_vpi_state_xlate(vpip->state));
11350
11351 mutex_exit(&EMLXS_FCF_LOCK);
11352 return (0);
11353 }
11354
11355 /* Find first available VFI for this FCFI */
11356 vfip = NULL;
11357 vfip1 = hba->sli.sli4.VFI_table;
11358 for (i = 0; i < hba->sli.sli4.VFICount; i++, vfip1++) {
11359 if (vfip1->fcfp == fcfp) {
11360 vfip = vfip1;
11361 break;
11362 }
11363 }
11364
11365 if (!vfip) {
11366 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11367 "vpi_port_bind_notify:%d %s fcfi:%d. "
11368 "No VFI available yet.",
11369 vpip->VPI,
11370 emlxs_vpi_state_xlate(vpip->state),
11371 fcfp->fcf_index);
11372
11373 mutex_exit(&EMLXS_FCF_LOCK);
11374 return (0);
11375 }
11376
11377 vpip->vfip = vfip;
11378 done:
11379
11380 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11381 "vpi_port_bind_notify:%d %s fcfi:%d vfi:%d. Onlining VPI:%d >",
11382 vpip->VPI,
11383 emlxs_vpi_state_xlate(vpip->state),
11384 fcfp->fcf_index,
11385 vfip->VFI,
11386 vpip->VPI);
11387
11388 rval = emlxs_vpi_event(port, FCF_EVENT_VPI_ONLINE, vpip);
11389
11390 mutex_exit(&EMLXS_FCF_LOCK);
11391
11392 return (rval);
11393
11394 } /* emlxs_vpi_port_bind_notify() */
11395
11396
11397 extern uint32_t
emlxs_vpi_port_unbind_notify(emlxs_port_t * port,uint32_t wait)11398 emlxs_vpi_port_unbind_notify(emlxs_port_t *port, uint32_t wait)
11399 {
11400 emlxs_hba_t *hba = HBA;
11401 VPIobj_t *vpip = port->vpip;
11402 uint32_t rval = 0;
11403 VFIobj_t *vfip;
11404 uint32_t i;
11405 FCFIobj_t *fcfp;
11406
11407 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
11408 return (1);
11409 }
11410
11411 if (!(hba->sli.sli4.flag & EMLXS_SLI4_FCF_INIT)) {
11412 return (0);
11413 }
11414
11415 mutex_enter(&EMLXS_FCF_LOCK);
11416
11417 if (vpip->state == VPI_STATE_OFFLINE) {
11418 mutex_exit(&EMLXS_FCF_LOCK);
11419 return (0);
11420 }
11421
11422 /*
11423 * Set flag to indicate that emlxs_vpi_port_unbind_notify
11424 * has been called
11425 */
11426 vpip->flag |= EMLXS_VPI_PORT_UNBIND;
11427
11428 vfip = vpip->vfip;
11429 fcfp = vfip->fcfp;
11430
11431 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11432 "vpi_port_unbind_notify:%d %s fcfi:%d vfi:%d. "
11433 "Offlining VPI:%d,%d >",
11434 vpip->VPI,
11435 emlxs_vpi_state_xlate(vpip->state),
11436 fcfp->fcf_index,
11437 vfip->VFI,
11438 vpip->index, vpip->VPI);
11439
11440 rval = emlxs_vpi_event(port, FCF_EVENT_VPI_OFFLINE, vpip);
11441
11442 if (wait && (rval == 0)) {
11443 /* Wait for VPI to go offline */
11444 i = 0;
11445 while (i++ < 120) {
11446 if (vpip->state == VPI_STATE_OFFLINE) {
11447 break;
11448 }
11449
11450 mutex_exit(&EMLXS_FCF_LOCK);
11451 BUSYWAIT_MS(1000);
11452 mutex_enter(&EMLXS_FCF_LOCK);
11453 }
11454
11455 if (i >= 120) {
11456 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
11457 "vpi_port_unbind_notify:%d %s fcfi:%d vfi:%d "
11458 "rpi_online=%d,%d. Offline timeout.",
11459 vpip->VPI,
11460 emlxs_vpi_state_xlate(vpip->state),
11461 fcfp->fcf_index,
11462 vfip->VFI,
11463 vpip->rpi_online, vpip->rpi_paused);
11464 }
11465 }
11466
11467 vpip->flag &= ~EMLXS_VPI_PORT_UNBIND;
11468
11469 mutex_exit(&EMLXS_FCF_LOCK);
11470
11471 return (rval);
11472
11473 } /* emlxs_vpi_port_unbind_notify() */
11474
11475
11476 /*ARGSUSED*/
11477 static uint32_t
emlxs_vpi_rpi_offline_evt_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)11478 emlxs_vpi_rpi_offline_evt_action(emlxs_port_t *port, VPIobj_t *vpip,
11479 uint32_t evt, void *arg1)
11480 {
11481 uint32_t rval = 0;
11482 RPIobj_t *rpip = (RPIobj_t *)arg1;
11483
11484 if (evt != FCF_EVENT_RPI_OFFLINE) {
11485 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
11486 "vpi_rpi_offline_evt_action:%d %s:%s arg=%p flag=%x. "
11487 "Invalid event type. <",
11488 vpip->VPI,
11489 emlxs_vpi_state_xlate(vpip->state),
11490 emlxs_fcf_event_xlate(evt), arg1,
11491 vpip->flag);
11492 return (1);
11493 }
11494
11495 switch (vpip->state) {
11496 case VPI_STATE_LOGO:
11497 /* rpi_online will be checked when LOGO is complete */
11498 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11499 "vpi_rpi_offline_evt_action:%d rpi_online=%d,%d did=%x "
11500 "rpi=%d. Waiting for LOGO. <",
11501 vpip->VPI,
11502 vpip->rpi_online, vpip->rpi_paused,
11503 rpip->did, rpip->RPI);
11504
11505 rval = 0;
11506 break;
11507
11508 case VPI_STATE_PORT_OFFLINE:
11509 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11510 "vpi_rpi_offline_evt_action:%d rpi_online=%d,%d did=%x "
11511 "rpi=%d.",
11512 vpip->VPI,
11513 vpip->rpi_online, vpip->rpi_paused,
11514 rpip->did, rpip->RPI);
11515
11516 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE,
11517 FCF_REASON_REENTER, evt, arg1);
11518 break;
11519
11520 case VPI_STATE_PAUSED:
11521 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11522 "vpi_rpi_offline_evt_action:%d rpi_online=%d,%d did=%x "
11523 "rpi=%d. VPI paused. <",
11524 vpip->VPI,
11525 vpip->rpi_online, vpip->rpi_paused,
11526 rpip->did, rpip->RPI);
11527
11528 rval = 0;
11529 break;
11530
11531 case VPI_STATE_ONLINE:
11532 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11533 "vpi_rpi_offline_evt_action:%d rpi_online=%d,%d did=%x "
11534 "rpi=%d. <",
11535 vpip->VPI,
11536 vpip->rpi_online, vpip->rpi_paused,
11537 rpip->did, rpip->RPI);
11538
11539 rval = 0;
11540 break;
11541
11542 default:
11543 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11544 "vpi_rpi_offline_evt_action:%d rpi_online=%d,%d did=%x "
11545 "rpi=%d. "
11546 "Invalid state. <",
11547 vpip->VPI,
11548 vpip->rpi_online, vpip->rpi_paused,
11549 rpip->did, rpip->RPI);
11550
11551 rval = 1;
11552 break;
11553 }
11554
11555 return (rval);
11556
11557 } /* emlxs_vpi_rpi_offline_evt_action() */
11558
11559
11560 /*ARGSUSED*/
11561 static uint32_t
emlxs_vpi_rpi_pause_evt_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)11562 emlxs_vpi_rpi_pause_evt_action(emlxs_port_t *port, VPIobj_t *vpip,
11563 uint32_t evt, void *arg1)
11564 {
11565 uint32_t rval = 0;
11566 RPIobj_t *rpip = (RPIobj_t *)arg1;
11567
11568 if (evt != FCF_EVENT_RPI_PAUSE) {
11569 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
11570 "vpi_rpi_pause_evt_action:%d %s:%s arg=%p flag=%x. "
11571 "Invalid event type. <",
11572 vpip->VPI,
11573 emlxs_vpi_state_xlate(vpip->state),
11574 emlxs_fcf_event_xlate(evt), arg1,
11575 vpip->flag);
11576 return (1);
11577 }
11578
11579 switch (vpip->state) {
11580 case VPI_STATE_LOGO:
11581 /* rpi_online will be checked when LOGO is complete */
11582 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11583 "vpi_rpi_pause_evt_action:%d rpi_online=%d,%d did=%x "
11584 "rpi=%d. Waiting for LOGO. <",
11585 vpip->VPI,
11586 vpip->rpi_online, vpip->rpi_paused,
11587 rpip->did, rpip->RPI);
11588
11589 rval = 0;
11590 break;
11591
11592 case VPI_STATE_PORT_OFFLINE:
11593 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11594 "vpi_rpi_pause_evt_action:%d rpi_online=%d,%d did=%x "
11595 "rpi=%d.",
11596 vpip->VPI,
11597 vpip->rpi_online, vpip->rpi_paused,
11598 rpip->did, rpip->RPI);
11599
11600 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE,
11601 FCF_REASON_REENTER, 0, 0);
11602 break;
11603
11604 case VPI_STATE_PAUSED:
11605 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11606 "vpi_rpi_pause_evt_action:%d rpi_online=%d,%d did=%x "
11607 "rpi=%d. VPI already paused. <",
11608 vpip->VPI,
11609 vpip->rpi_online, vpip->rpi_paused,
11610 rpip->did, rpip->RPI);
11611
11612 rval = 0;
11613 break;
11614
11615 default:
11616 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11617 "vpi_rpi_pause_evt_action:%d rpi_online=%d,%d did=%x "
11618 "rpi=%d. "
11619 "Invalid state. <",
11620 vpip->VPI,
11621 vpip->rpi_online, vpip->rpi_paused,
11622 rpip->did, rpip->RPI);
11623
11624 rval = 1;
11625 break;
11626 }
11627
11628 return (rval);
11629
11630 } /* emlxs_vpi_rpi_pause_evt_action() */
11631
11632
11633 /*ARGSUSED*/
11634 static uint32_t
emlxs_vpi_rpi_online_evt_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)11635 emlxs_vpi_rpi_online_evt_action(emlxs_port_t *port, VPIobj_t *vpip,
11636 uint32_t evt, void *arg1)
11637 {
11638 RPIobj_t *rpip = (RPIobj_t *)arg1;
11639
11640 if (evt != FCF_EVENT_RPI_ONLINE) {
11641 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
11642 "vpi_rpi_online_evt_action:%d %s:%s arg=%p flag=%x. "
11643 "Invalid event type. <",
11644 vpip->VPI,
11645 emlxs_vpi_state_xlate(vpip->state),
11646 emlxs_fcf_event_xlate(evt), arg1,
11647 vpip->flag);
11648 return (1);
11649 }
11650
11651 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11652 "vpi_rpi_online_evt_action:%d rpi_online=%d,%d did=%x rpi=%d. <",
11653 vpip->VPI,
11654 vpip->rpi_online, vpip->rpi_paused,
11655 rpip->did, rpip->RPI);
11656
11657 return (0);
11658
11659 } /* emlxs_vpi_rpi_online_evt_action() */
11660
11661
11662 /*ARGSUSED*/
11663 static uint32_t
emlxs_vpi_online_evt_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)11664 emlxs_vpi_online_evt_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
11665 void *arg1)
11666 {
11667 uint32_t rval = 0;
11668
11669 if (evt != FCF_EVENT_VPI_ONLINE) {
11670 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
11671 "vpi_online_evt_action:%d %s:%s arg=%p flag=%x. "
11672 "Invalid event type. <",
11673 vpip->VPI,
11674 emlxs_vpi_state_xlate(vpip->state),
11675 emlxs_fcf_event_xlate(evt), arg1,
11676 vpip->flag);
11677 return (1);
11678 }
11679
11680 if (vpip->flag & EMLXS_VPI_ONLINE_REQ) {
11681 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11682 "vpi_online_evt_action:%d flag=%x. "
11683 "Online already requested. <",
11684 vpip->VPI,
11685 vpip->flag);
11686 return (1);
11687 }
11688
11689 vpip->flag &= ~EMLXS_VPI_REQ_MASK;
11690 vpip->flag |= EMLXS_VPI_ONLINE_REQ;
11691
11692 switch (vpip->state) {
11693 case VPI_STATE_OFFLINE:
11694 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11695 "vpi_online_evt_action:%d flag=%x. Initiating online.",
11696 vpip->VPI,
11697 vpip->flag);
11698
11699 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT,
11700 FCF_REASON_EVENT, evt, arg1);
11701 break;
11702
11703 case VPI_STATE_PORT_OFFLINE:
11704 case VPI_STATE_PAUSED:
11705 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11706 "vpi_online_evt_action:%d flag=%x. Initiating online.",
11707 vpip->VPI,
11708 vpip->flag);
11709
11710 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE,
11711 FCF_REASON_EVENT, evt, arg1);
11712 break;
11713
11714 default:
11715 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11716 "vpi_online_evt_action:%d flag=%x. <",
11717 vpip->VPI,
11718 vpip->flag);
11719 return (1);
11720 }
11721
11722 return (rval);
11723
11724 } /* emlxs_vpi_online_evt_action() */
11725
11726
11727 /*ARGSUSED*/
11728 static uint32_t
emlxs_vpi_offline_handler(emlxs_port_t * port,VPIobj_t * vpip,void * arg1)11729 emlxs_vpi_offline_handler(emlxs_port_t *port, VPIobj_t *vpip, void *arg1)
11730 {
11731 uint32_t rval = 0;
11732
11733 if (!(vpip->flag & EMLXS_VPI_OFFLINE_REQ)) {
11734 return (0);
11735 }
11736
11737 if (vpip->flag & EMLXS_VPI_PORT_ONLINE) {
11738 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE,
11739 FCF_REASON_REQUESTED, 0, arg1);
11740
11741 } else if (vpip->flag & EMLXS_VPI_LOGI) {
11742 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO,
11743 FCF_REASON_REQUESTED, 0, arg1);
11744
11745 } else if (vpip->flag & EMLXS_VPI_REG) {
11746 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG,
11747 FCF_REASON_REQUESTED, 0, arg1);
11748
11749 } else if (vpip->flag & EMLXS_VPI_INIT) {
11750 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG,
11751 FCF_REASON_REQUESTED, 0, arg1);
11752
11753 } else {
11754 rval = emlxs_vpi_state(port, vpip, VPI_STATE_OFFLINE,
11755 FCF_REASON_REQUESTED, 0, arg1);
11756 }
11757
11758 return (rval);
11759
11760 } /* emlxs_vpi_offline_handler() */
11761
11762
11763 /*ARGSUSED*/
11764 static uint32_t
emlxs_vpi_offline_evt_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)11765 emlxs_vpi_offline_evt_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
11766 void *arg1)
11767 {
11768 uint32_t rval = 0;
11769 uint32_t pause_req;
11770
11771 if (evt != FCF_EVENT_VPI_OFFLINE) {
11772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
11773 "vpi_offline_evt_action:%d %s:%s arg=%p flag=%x. "
11774 "Invalid event type. <",
11775 vpip->VPI,
11776 emlxs_vpi_state_xlate(vpip->state),
11777 emlxs_fcf_event_xlate(evt), arg1,
11778 vpip->flag);
11779 return (1);
11780 }
11781
11782 if ((vpip->flag & EMLXS_VPI_OFFLINE_REQ) &&
11783 !(vpip->flag & EMLXS_VPI_PAUSE_REQ)) {
11784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11785 "vpi_offline_evt_action:%d flag=%x. "
11786 "Offline already requested. <",
11787 vpip->VPI,
11788 vpip->flag);
11789 return (1);
11790 }
11791
11792 pause_req = vpip->flag & EMLXS_VPI_PAUSE_REQ;
11793
11794 vpip->flag &= ~EMLXS_VPI_REQ_MASK;
11795 vpip->flag |= EMLXS_VPI_OFFLINE_REQ;
11796
11797 switch (vpip->state) {
11798 case VPI_STATE_PORT_OFFLINE:
11799 if (pause_req || vpip->rpi_paused) {
11800 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11801 "vpi_offline_evt_action:%d flag=%x. Clear nodes.",
11802 vpip->VPI,
11803 vpip->flag);
11804
11805 vpip->flag |= EMLXS_VPI_PORT_ONLINE;
11806
11807 rval = emlxs_vpi_state(port, vpip,
11808 VPI_STATE_PORT_OFFLINE, FCF_REASON_REENTER, evt,
11809 arg1);
11810
11811 break;
11812 }
11813
11814 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11815 "vpi_offline_evt_action:%d flag=%x. Handling offline.",
11816 vpip->VPI,
11817 vpip->flag);
11818
11819 /* Handle offline now */
11820 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
11821 break;
11822
11823 case VPI_STATE_PAUSED:
11824 if (vpip->rpi_paused) {
11825 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11826 "vpi_offline_evt_action:%d flag=%x. Clear nodes.",
11827 vpip->VPI,
11828 vpip->flag);
11829
11830 vpip->flag |= EMLXS_VPI_PORT_ONLINE;
11831
11832 rval = emlxs_vpi_state(port, vpip,
11833 VPI_STATE_PORT_OFFLINE, FCF_REASON_EVENT, evt,
11834 arg1);
11835
11836 break;
11837 }
11838
11839 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11840 "vpi_offline_evt_action:%d flag=%x. Handling offline.",
11841 vpip->VPI,
11842 vpip->flag);
11843
11844 /* Handle offline now */
11845 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
11846 break;
11847
11848 /* wait states */
11849 case VPI_STATE_UNREG:
11850 case VPI_STATE_PORT_ONLINE:
11851 case VPI_STATE_LOGI:
11852 case VPI_STATE_INIT:
11853 case VPI_STATE_REG:
11854 case VPI_STATE_ONLINE:
11855 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11856 "vpi_offline_evt_action:%d flag=%x. Handling offline.",
11857 vpip->VPI,
11858 vpip->flag);
11859
11860 /* Handle offline now */
11861 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
11862 break;
11863
11864 /* Transitional states */
11865 default:
11866 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11867 "vpi_offline_evt_action:%d flag=%x. <",
11868 vpip->VPI,
11869 vpip->flag);
11870 break;
11871 }
11872
11873 return (rval);
11874
11875 } /* emlxs_vpi_offline_evt_action() */
11876
11877
11878 /*ARGSUSED*/
11879 static uint32_t
emlxs_vpi_pause_evt_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)11880 emlxs_vpi_pause_evt_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
11881 void *arg1)
11882 {
11883 emlxs_hba_t *hba = HBA;
11884 uint32_t rval = 0;
11885
11886 if (evt != FCF_EVENT_VPI_PAUSE) {
11887 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
11888 "vpi_pause_evt_action:%d %s:%s arg=%p flag=%x. "
11889 "Invalid event type. <",
11890 vpip->VPI,
11891 emlxs_vpi_state_xlate(vpip->state),
11892 emlxs_fcf_event_xlate(evt), arg1,
11893 vpip->flag);
11894 return (1);
11895 }
11896
11897 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) {
11898 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11899 "vpi_pause_evt_action:%d flag=%x. "
11900 "Pause already requested. <",
11901 vpip->VPI,
11902 vpip->flag);
11903 return (1);
11904 }
11905
11906 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) {
11907 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11908 "vpi_pause_evt_action:%d flag=%x. "
11909 "Offline already requested. <",
11910 vpip->VPI,
11911 vpip->flag);
11912 return (1);
11913 }
11914
11915 if (SLI4_FC_MODE || !(hba->sli.sli4.flag & EMLXS_SLI4_DOWN_LINK)) {
11916 /* Fabric logo is implied */
11917 emlxs_vpi_logo_handler(port, vpip);
11918 }
11919
11920 switch (vpip->state) {
11921 case VPI_STATE_PORT_OFFLINE:
11922 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11923 "vpi_pause_evt_action:%d flag=%x. "
11924 "Already offline. <",
11925 vpip->VPI,
11926 vpip->flag);
11927 break;
11928
11929 case VPI_STATE_PAUSED:
11930 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11931 "vpi_pause_evt_action:%d flag=%x. "
11932 "Already paused. <",
11933 vpip->VPI,
11934 vpip->flag);
11935 break;
11936
11937 /* Wait states */
11938 case VPI_STATE_UNREG:
11939 case VPI_STATE_PORT_ONLINE:
11940 case VPI_STATE_LOGI:
11941 case VPI_STATE_INIT:
11942 case VPI_STATE_REG:
11943 case VPI_STATE_ONLINE:
11944 vpip->flag &= ~EMLXS_VPI_REQ_MASK;
11945 vpip->flag |= (EMLXS_VPI_OFFLINE_REQ | EMLXS_VPI_PAUSE_REQ);
11946
11947 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11948 "vpi_pause_evt_action:%d flag=%x. Handling offline.",
11949 vpip->VPI,
11950 vpip->flag);
11951
11952 /* Handle offline now */
11953 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
11954 break;
11955
11956 /* Transitional states */
11957 default:
11958 vpip->flag &= ~EMLXS_VPI_REQ_MASK;
11959 vpip->flag |= (EMLXS_VPI_OFFLINE_REQ | EMLXS_VPI_PAUSE_REQ);
11960
11961 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
11962 "vpi_pause_evt_action:%d flag=%x. <",
11963 vpip->VPI,
11964 vpip->flag);
11965 break;
11966 }
11967
11968 return (rval);
11969
11970 } /* emlxs_vpi_pause_evt_action() */
11971
11972
11973 /* ARGSUSED */
11974 static void
emlxs_deferred_cmpl_thread(emlxs_hba_t * hba,void * arg1,void * arg2)11975 emlxs_deferred_cmpl_thread(emlxs_hba_t *hba, void *arg1, void *arg2)
11976 {
11977 emlxs_deferred_cmpl_t *cmpl = (emlxs_deferred_cmpl_t *)arg1;
11978 uint32_t status = (uint32_t)((unsigned long)arg2);
11979 emlxs_port_t *port;
11980 uint32_t mbxStatus;
11981 emlxs_buf_t *sbp;
11982 fc_unsol_buf_t *ubp;
11983 IOCBQ *iocbq;
11984
11985 mbxStatus = (status)? MBX_FAILURE:MBX_SUCCESS;
11986
11987 port = cmpl->port;
11988 sbp = (emlxs_buf_t *)cmpl->arg1;
11989 ubp = (fc_unsol_buf_t *)cmpl->arg2;
11990 iocbq = (IOCBQ *)cmpl->arg3;
11991
11992 kmem_free(cmpl, sizeof (emlxs_deferred_cmpl_t));
11993
11994 emlxs_mb_deferred_cmpl(port, mbxStatus, sbp, ubp, iocbq);
11995
11996 return;
11997
11998 } /* emlxs_deferred_cmpl_thread() */
11999
12000
12001
12002
12003 /* ARGSUSED */
12004 static void
emlxs_port_offline_thread(emlxs_hba_t * hba,void * arg1,void * arg2)12005 emlxs_port_offline_thread(emlxs_hba_t *hba, void *arg1, void *arg2)
12006 {
12007 emlxs_port_t *port = (emlxs_port_t *)arg1;
12008 uint32_t scope = (uint32_t)((unsigned long)arg2);
12009
12010 (void) emlxs_port_offline(port, scope);
12011 return;
12012
12013 } /* emlxs_port_offline_thread() */
12014
12015
12016 /* ARGSUSED */
12017 static void
emlxs_port_online_thread(emlxs_hba_t * hba,void * arg1,void * arg2)12018 emlxs_port_online_thread(emlxs_hba_t *hba, void *arg1, void *arg2)
12019 {
12020 emlxs_port_t *port = (emlxs_port_t *)arg1;
12021
12022 (void) emlxs_port_online(port);
12023 return;
12024
12025 } /* emlxs_port_online_thread() */
12026
12027
12028 /*ARGSUSED*/
12029 static void
emlxs_vpi_logo_handler(emlxs_port_t * port,VPIobj_t * vpip)12030 emlxs_vpi_logo_handler(emlxs_port_t *port, VPIobj_t *vpip)
12031 {
12032 vpip->flag &= ~EMLXS_VPI_LOGI;
12033 if (vpip->flag & EMLXS_VPI_VFI_LOGI) {
12034 vpip->flag &= ~EMLXS_VPI_VFI_LOGI;
12035 if (vpip->vfip == NULL) {
12036 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12037 "emlxs_vpi_logo_handler: invalid state "
12038 "(vpip->vfip == NULL), vpip=%p", vpip);
12039 return;
12040 }
12041 if (vpip->vfip->logi_count) {
12042 vpip->vfip->logi_count--;
12043 }
12044 if (vpip == vpip->vfip->flogi_vpip) {
12045 vpip->vfip->flogi_vpip = NULL;
12046 }
12047 }
12048 } /* emlxs_vpi_logo_handler() */
12049
12050
12051 /*ARGSUSED*/
12052 static uint32_t
emlxs_vpi_port_offline_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)12053 emlxs_vpi_port_offline_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
12054 void *arg1)
12055 {
12056 emlxs_hba_t *hba = HBA;
12057 uint32_t rval = 0;
12058 uint32_t scope;
12059
12060 if (vpip->state != VPI_STATE_PORT_OFFLINE) {
12061 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12062 "vpi_port_offline_action:%d %s:%s arg=%p. "
12063 "Invalid state. <",
12064 vpip->VPI,
12065 emlxs_vpi_state_xlate(vpip->state),
12066 emlxs_fcf_event_xlate(evt), arg1);
12067 return (1);
12068 }
12069
12070 if (vpip->flag & EMLXS_VPI_PORT_ONLINE) {
12071 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12072 "vpi_port_offline_action:%d flag=%x. Offlining port...",
12073 vpip->VPI,
12074 vpip->flag);
12075
12076 vpip->flag &= ~(EMLXS_VPI_PORT_ONLINE|EMLXS_VPI_PORT_ENABLED);
12077
12078 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) {
12079 scope = 0xFFFFFFFF; /* Clear all non-FCP2 nodes */
12080 /* Pause FCP2 nodes */
12081 } else {
12082 scope = 0xFDFFFFFF; /* Clear all nodes */
12083 }
12084
12085 emlxs_thread_spawn(hba, emlxs_port_offline_thread,
12086 (void *)vpip->port, (void *)((unsigned long)scope));
12087
12088 if (vpip->flag & EMLXS_VPI_LOGI) {
12089 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO,
12090 FCF_REASON_EVENT, evt, arg1);
12091
12092 return (rval);
12093 }
12094 }
12095
12096 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) {
12097 if (vpip->rpi_online > vpip->rpi_paused) {
12098 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12099 "vpi_port_offline_action:%d rpi_online=%d,%d. "
12100 "Pausing. Waiting for RPI's. <",
12101 vpip->VPI,
12102 vpip->rpi_online, vpip->rpi_paused);
12103 return (0);
12104 }
12105
12106 /* Take the Fabric RPI offline now */
12107 if (vpip->fabric_rpip->state != RPI_STATE_FREE) {
12108 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12109 "vpi_port_offline_action:%d. "
12110 "Offlining Fabric RPI. >",
12111 vpip->VPI);
12112
12113 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE,
12114 vpip->fabric_rpip);
12115 }
12116
12117 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12118 "vpi_port_offline_action:%d rpi_online=%d,%d. Pausing.",
12119 vpip->VPI,
12120 vpip->rpi_online, vpip->rpi_paused);
12121
12122 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PAUSED,
12123 FCF_REASON_EVENT, evt, arg1);
12124
12125 return (rval);
12126 }
12127
12128 if (vpip->rpi_online > 0) {
12129 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12130 "vpi_port_offline_action:%d rpi_online=%d,%d. Offlining. "
12131 "Waiting for RPI's. <",
12132 vpip->VPI,
12133 vpip->rpi_online, vpip->rpi_paused);
12134
12135 return (0);
12136 }
12137
12138 /* Take the Fabric RPI offline now */
12139 if (vpip->fabric_rpip->state != RPI_STATE_FREE) {
12140 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12141 "vpi_port_offline_action:%d. Offlining Fabric RPI. >",
12142 vpip->VPI);
12143
12144 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE,
12145 vpip->fabric_rpip);
12146 }
12147
12148 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12149 "vpi_port_offline_action:%d rpi_online=%d,%d. Offlining. "
12150 "Unreg VPI.",
12151 vpip->VPI,
12152 vpip->rpi_online, vpip->rpi_paused);
12153
12154 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG,
12155 FCF_REASON_EVENT, evt, arg1);
12156
12157 return (rval);
12158
12159 } /* emlxs_vpi_port_offline_action() */
12160
12161
12162 /*ARGSUSED*/
12163 static uint32_t
emlxs_vpi_paused_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)12164 emlxs_vpi_paused_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
12165 void *arg1)
12166 {
12167 if (vpip->state != VPI_STATE_PAUSED) {
12168 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12169 "vpi_paused_action:%d %s:%s arg=%p. "
12170 "Invalid state. <",
12171 vpip->VPI,
12172 emlxs_vpi_state_xlate(vpip->state),
12173 emlxs_fcf_event_xlate(evt), arg1);
12174 return (1);
12175 }
12176
12177 vpip->flag &= ~(EMLXS_VPI_OFFLINE_REQ | EMLXS_VPI_PAUSE_REQ);
12178
12179 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12180 "vpi_paused_action:%d rpi_online=%d,%d. VPI paused. <",
12181 vpip->VPI,
12182 vpip->rpi_online, vpip->rpi_paused);
12183
12184 return (0);
12185
12186 } /* emlxs_vpi_paused_action() */
12187
12188
12189 /*ARGSUSED*/
12190 static uint32_t
emlxs_vpi_offline_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)12191 emlxs_vpi_offline_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
12192 void *arg1)
12193 {
12194 uint32_t rval = 0;
12195
12196 if (vpip->state != VPI_STATE_OFFLINE) {
12197 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12198 "vpi_offline_action:%d %s:%s arg=%p. "
12199 "Invalid state. <",
12200 vpip->VPI,
12201 emlxs_vpi_state_xlate(vpip->state),
12202 emlxs_fcf_event_xlate(evt), arg1);
12203 return (1);
12204 }
12205
12206 if (!vpip->vfip) {
12207 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12208 "vpi_offline_action:%d %s:%s arg=%p flag=%x. "
12209 "Null vfip found. <",
12210 vpip->VPI,
12211 emlxs_vpi_state_xlate(vpip->state),
12212 emlxs_fcf_event_xlate(evt), arg1,
12213 vpip->flag);
12214 return (1);
12215 }
12216
12217 /* Take the Fabric RPI offline, if still active */
12218 if (vpip->fabric_rpip->state != RPI_STATE_FREE) {
12219 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12220 "vpi_offline_action:%d. Offlining Fabric RPI. >",
12221 vpip->VPI);
12222
12223 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE,
12224 vpip->fabric_rpip);
12225 }
12226
12227 vpip->flag &= ~(EMLXS_VPI_OFFLINE_REQ | EMLXS_VPI_PAUSE_REQ);
12228
12229 if (vpip->flag & EMLXS_VPI_VFI) {
12230 vpip->flag &= ~EMLXS_VPI_VFI;
12231
12232 if (vpip->vfip->vpi_online) {
12233 vpip->vfip->vpi_online--;
12234 }
12235 }
12236
12237 /* Check if online was requested */
12238 if (vpip->flag & EMLXS_VPI_ONLINE_REQ) {
12239 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12240 "vpi_offline_action:%d vpi_online=%d. Online requested.",
12241 vpip->VPI,
12242 vpip->vfip->vpi_online);
12243
12244 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT,
12245 FCF_REASON_REQUESTED, 0, arg1);
12246 return (rval);
12247 }
12248
12249 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12250 "vpi_offline_action:%d vpi_online=%d. "
12251 "VPI offline. Notifying VFI:%d. >",
12252 vpip->VPI,
12253 vpip->vfip->vpi_online,
12254 vpip->vfip->VFI);
12255
12256 /* Notify VFI */
12257 rval = emlxs_vfi_event(port, FCF_EVENT_VPI_OFFLINE, vpip);
12258
12259 return (rval);
12260
12261 } /* emlxs_vpi_offline_action() */
12262
12263
12264 /*ARGSUSED*/
12265 static uint32_t
emlxs_vpi_init_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)12266 emlxs_vpi_init_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
12267 {
12268 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
12269 VPIobj_t *vpip;
12270 MAILBOX4 *mb4;
12271
12272 vpip = (VPIobj_t *)mbq->context;
12273 mb4 = (MAILBOX4 *)mbq;
12274
12275 mutex_enter(&EMLXS_FCF_LOCK);
12276
12277 if (vpip->state != VPI_STATE_INIT) {
12278 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12279 "vpi_init_mbcmpl:%d %s.",
12280 vpip->VPI,
12281 emlxs_vpi_state_xlate(vpip->state));
12282
12283 mutex_exit(&EMLXS_FCF_LOCK);
12284 return (0);
12285 }
12286
12287 if (mb4->mbxStatus) {
12288 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12289 "vpi_init_mbcmpl:%d failed. %s. >",
12290 vpip->VPI,
12291 emlxs_mb_xlate_status(mb4->mbxStatus));
12292
12293 (void) emlxs_vpi_state(port, vpip, VPI_STATE_INIT_FAILED,
12294 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
12295
12296 mutex_exit(&EMLXS_FCF_LOCK);
12297 return (0);
12298 }
12299
12300 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12301 "vpi_init_mbcmpl:%d. Init complete. >",
12302 vpip->VPI,
12303 mb4->mbxStatus);
12304
12305 vpip->flag |= EMLXS_VPI_INIT;
12306 (void) emlxs_vpi_state(port, vpip, VPI_STATE_INIT_CMPL,
12307 0, 0, 0);
12308
12309 mutex_exit(&EMLXS_FCF_LOCK);
12310 return (0);
12311
12312 } /* emlxs_vpi_init_mbcmpl() */
12313
12314
12315 /*ARGSUSED*/
12316 static uint32_t
emlxs_vpi_init_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)12317 emlxs_vpi_init_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
12318 void *arg1)
12319 {
12320 emlxs_hba_t *hba = HBA;
12321 MAILBOXQ *mbq;
12322 MAILBOX4 *mb4;
12323 uint32_t rval = 0;
12324
12325 if (vpip->state != VPI_STATE_INIT) {
12326 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12327 "vpi_init_action:%d %s:%s arg=%p. "
12328 "Invalid state. <",
12329 vpip->VPI,
12330 emlxs_vpi_state_xlate(vpip->state),
12331 emlxs_fcf_event_xlate(evt), arg1);
12332 return (1);
12333 }
12334
12335 if (vpip->prev_state != VPI_STATE_INIT_FAILED) {
12336 vpip->attempts = 0;
12337 }
12338
12339 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) {
12340 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12341 "vpi_init_action:%d attempts=%d. Offline requested.",
12342 vpip->VPI,
12343 vpip->attempts);
12344
12345 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
12346 return (rval);
12347 }
12348
12349 if (!(vpip->flag & EMLXS_VPI_VFI)) {
12350 vpip->flag |= EMLXS_VPI_VFI;
12351 vpip->vfip->vpi_online++;
12352 }
12353
12354 if (((hba->sli_intf & SLI_INTF_IF_TYPE_MASK) ==
12355 SLI_INTF_IF_TYPE_0) && (vpip->vfip->vpi_online == 1)) {
12356 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12357 "vpi_init_action:%d. First VPI. Skipping INIT_VPI.",
12358 vpip->VPI);
12359
12360 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE,
12361 FCF_REASON_EVENT, evt, arg1);
12362 return (rval);
12363 }
12364
12365 if (vpip->flag & EMLXS_VPI_INIT) {
12366 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12367 "vpi_init_action:%d flag=%x. "
12368 "Already init'd. Skipping INIT_VPI.",
12369 vpip->VPI);
12370
12371 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE,
12372 FCF_REASON_EVENT, evt, arg1);
12373 return (rval);
12374 }
12375
12376 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12377 "vpi_init_action:%d vpi_online=%d attempts=%d. Sending INIT_VPI. <",
12378 vpip->VPI,
12379 vpip->vfip->vpi_online,
12380 vpip->attempts);
12381
12382 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
12383 rval = emlxs_vpi_state(port, vpip, FCFI_STATE_REG_FAILED,
12384 FCF_REASON_NO_MBOX, 0, arg1);
12385 return (rval);
12386 }
12387 mb4 = (MAILBOX4*)mbq;
12388 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
12389
12390 mbq->nonembed = NULL;
12391 mbq->mbox_cmpl = emlxs_vpi_init_mbcmpl;
12392 mbq->context = (void *)vpip;
12393 mbq->port = (void *)port;
12394
12395 mb4->mbxCommand = MBX_INIT_VPI;
12396 mb4->mbxOwner = OWN_HOST;
12397 mb4->un.varInitVPI4.vfi = vpip->vfip->VFI;
12398 mb4->un.varInitVPI4.vpi = vpip->VPI;
12399
12400 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
12401 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
12402 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
12403
12404 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT_FAILED,
12405 FCF_REASON_SEND_FAILED, rval, arg1);
12406
12407 return (rval);
12408 }
12409
12410 return (0);
12411
12412 } /* emlxs_vpi_init_action() */
12413
12414
12415 /*ARGSUSED*/
12416 static uint32_t
emlxs_vpi_init_failed_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)12417 emlxs_vpi_init_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
12418 void *arg1)
12419 {
12420 uint32_t rval = 0;
12421
12422 vpip->attempts++;
12423
12424 if (vpip->state != VPI_STATE_INIT_FAILED) {
12425 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
12426 "vpi_init_action:%d %s:%s arg=%p attempt=%d. "
12427 "Invalid state. <",
12428 vpip->VPI,
12429 emlxs_vpi_state_xlate(vpip->state),
12430 emlxs_fcf_event_xlate(evt), arg1,
12431 vpip->attempts);
12432 return (1);
12433 }
12434
12435 if ((vpip->reason == FCF_REASON_SEND_FAILED) ||
12436 (vpip->attempts >= 3)) {
12437 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12438 "vpi_init_action:%d attempt=%d reason=%x. Init cmpl.",
12439 vpip->VPI,
12440 vpip->attempts,
12441 vpip->reason);
12442
12443 vpip->flag &= ~(EMLXS_VPI_REG | EMLXS_VPI_INIT);
12444
12445 vpip->flag &= ~EMLXS_VPI_REQ_MASK;
12446 vpip->flag |= EMLXS_VPI_OFFLINE_REQ;
12447 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT_CMPL,
12448 FCF_REASON_OP_FAILED, vpip->attempts, arg1);
12449 } else {
12450 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12451 "vpi_init_action:%d attempt=%d. Initializing.",
12452 vpip->VPI,
12453 vpip->attempts);
12454
12455 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT,
12456 FCF_REASON_OP_FAILED, vpip->attempts, arg1);
12457 }
12458
12459 return (rval);
12460
12461 } /* emlxs_vpi_init_failed_action() */
12462
12463
12464 /*ARGSUSED*/
12465 static uint32_t
emlxs_vpi_init_cmpl_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)12466 emlxs_vpi_init_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
12467 void *arg1)
12468 {
12469 uint32_t rval = 0;
12470
12471 if (vpip->state != VPI_STATE_INIT_CMPL) {
12472 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12473 "vpi_init_cmpl_action:%d %s:%s arg=%p. "
12474 "Invalid state. <",
12475 vpip->VPI,
12476 emlxs_vpi_state_xlate(vpip->state),
12477 emlxs_fcf_event_xlate(evt), arg1);
12478 return (1);
12479 }
12480
12481 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12482 "vpi_init_cmpl_action:%d attempts=%d. Onlining port.",
12483 vpip->VPI,
12484 vpip->attempts);
12485
12486 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE,
12487 FCF_REASON_EVENT, evt, arg1);
12488 return (rval);
12489
12490 } /* emlxs_vpi_init_cmpl_action() */
12491
12492
12493 /*ARGSUSED*/
12494 static uint32_t
emlxs_vpi_port_online_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)12495 emlxs_vpi_port_online_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
12496 void *arg1)
12497 {
12498 emlxs_hba_t *hba = HBA;
12499 emlxs_config_t *cfg = &CFG;
12500 uint32_t rval = 0;
12501
12502 if (vpip->state != VPI_STATE_PORT_ONLINE) {
12503 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12504 "vpi_port_online_action:%d %s:%s arg=%p. "
12505 "Invalid state. <",
12506 vpip->VPI,
12507 emlxs_vpi_state_xlate(vpip->state),
12508 emlxs_fcf_event_xlate(evt), arg1);
12509 return (1);
12510 }
12511
12512 if (vpip->flag & EMLXS_VPI_PORT_ONLINE) {
12513 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12514 "vpi_port_online_action:%d. Port already online.",
12515 vpip->VPI);
12516 }
12517
12518 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) {
12519 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12520 "vpi_port_online_action:%d. Offline requested.",
12521 vpip->VPI);
12522
12523 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
12524 return (rval);
12525 }
12526
12527 /* Initialize the Fabric RPI */
12528 if (vpip->fabric_rpip->state == RPI_STATE_FREE) {
12529 emlxs_rpi_alloc_fabric_rpi(vpip->port);
12530 }
12531
12532 /* Notify ULP */
12533 vpip->flag |= EMLXS_VPI_PORT_ONLINE;
12534
12535 if (hba->flag & FC_LOOPBACK_MODE) {
12536 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12537 "vpi_port_online_action:%d. Loopback mode. "
12538 "Registering VPI.",
12539 vpip->VPI);
12540
12541 if (hba->topology != TOPOLOGY_LOOP) {
12542 port->did = 1;
12543 }
12544
12545 vpip->vfip->flogi_vpip = vpip;
12546
12547 bcopy((void *)&vpip->port->sparam,
12548 (void *)&vpip->fabric_rpip->sparam,
12549 sizeof (SERV_PARM));
12550
12551 /* Update the VPI Fabric RPI */
12552 vpip->fabric_rpip->sparam.cmn.w2.r_a_tov =
12553 LE_SWAP32((FF_DEF_RATOV * 1000));
12554
12555 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG,
12556 FCF_REASON_EVENT, evt, arg1);
12557
12558 return (rval);
12559 }
12560
12561 if ((hba->topology == TOPOLOGY_LOOP) && ! (port->did)) {
12562 port->did = port->granted_alpa;
12563 }
12564
12565 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12566 "vpi_port_online_action:%d vpi_online=%d. Onlining port... <",
12567 vpip->VPI,
12568 vpip->vfip->vpi_online);
12569
12570 if (SLI4_FC_MODE && (port->vpi == 0)) {
12571 mutex_enter(&EMLXS_PORT_LOCK);
12572 hba->linkup_timer = hba->timer_tics +
12573 cfg[CFG_LINKUP_TIMEOUT].current;
12574 mutex_exit(&EMLXS_PORT_LOCK);
12575 } else {
12576 emlxs_thread_spawn(hba, emlxs_port_online_thread,
12577 (void *)vpip->port, 0);
12578 }
12579
12580 /* Wait for emlxs_vpi_logi_notify() */
12581
12582 return (0);
12583
12584 } /* emlxs_vpi_port_online_action() */
12585
12586
12587 extern uint32_t
emlxs_vpi_logi_notify(emlxs_port_t * port,emlxs_buf_t * sbp)12588 emlxs_vpi_logi_notify(emlxs_port_t *port, emlxs_buf_t *sbp)
12589 {
12590 VPIobj_t *vpip = port->vpip;
12591 emlxs_hba_t *hba = HBA;
12592 uint32_t rval = 0;
12593
12594 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
12595 return (1);
12596 }
12597
12598 mutex_enter(&EMLXS_FCF_LOCK);
12599
12600 if (vpip->state == VPI_STATE_OFFLINE) {
12601 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12602 "vpi_logi_notify:%d %s.",
12603 vpip->VPI,
12604 emlxs_vpi_state_xlate(vpip->state));
12605
12606 mutex_exit(&EMLXS_FCF_LOCK);
12607
12608 return (1);
12609 }
12610
12611 if (vpip->state != VPI_STATE_PORT_ONLINE) {
12612 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
12613 "vpi_logi_notify:%d %s. "
12614 "Invalid state.",
12615 vpip->VPI,
12616 emlxs_vpi_state_xlate(vpip->state));
12617
12618 mutex_exit(&EMLXS_FCF_LOCK);
12619
12620 return (1);
12621 }
12622
12623 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12624 "vpi_logi_notify:%d %s. "
12625 "Logging in. >",
12626 vpip->VPI,
12627 emlxs_vpi_state_xlate(vpip->state));
12628
12629 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI,
12630 0, 0, sbp);
12631
12632 if (rval) {
12633 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12634 "vpi_logi_notify:%d %s rval=%d.",
12635 vpip->VPI,
12636 emlxs_vpi_state_xlate(vpip->state),
12637 rval);
12638 }
12639
12640 mutex_exit(&EMLXS_FCF_LOCK);
12641
12642 return (rval);
12643
12644 } /* emlxs_vpi_logi_notify() */
12645
12646
12647 static uint32_t
emlxs_vpi_logi_cmpl_notify(emlxs_port_t * port,RPIobj_t * rpip)12648 emlxs_vpi_logi_cmpl_notify(emlxs_port_t *port, RPIobj_t *rpip)
12649 {
12650 emlxs_hba_t *hba = HBA;
12651 VPIobj_t *vpip = port->vpip;
12652 uint32_t rval = 0;
12653
12654 /* EMLXS_FCF_LOCK must be held when calling this routine */
12655
12656 if (vpip->state != VPI_STATE_LOGI) {
12657 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
12658 "vpi_logi_cmpl_notify:%d %s. "
12659 "Invalid state.",
12660 vpip->VPI,
12661 emlxs_vpi_state_xlate(vpip->state));
12662 return (1);
12663 }
12664
12665 if (rpip->RPI == FABRIC_RPI) {
12666 if (hba->flag & FC_PT_TO_PT) {
12667 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12668 "vpi_logi_cmpl_notify:%d %s. P2P mode. "
12669 "Completing FLOGI.",
12670 vpip->VPI,
12671 emlxs_vpi_state_xlate(vpip->state));
12672
12673 /* Complete the FLOGI/FDISC now */
12674 if (rpip->cmpl) {
12675 emlxs_rpi_deferred_cmpl(port, rpip, 0);
12676 }
12677
12678 /* Wait for P2P PLOGI completion to continue */
12679 return (0);
12680 }
12681
12682 if (!rpip->cmpl || !rpip->cmpl->arg1) {
12683 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
12684 "vpi_logi_cmpl_notify:%d. Null sbp.",
12685 vpip->VPI);
12686 return (1);
12687 }
12688
12689 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12690 "vpi_logi_cmpl_notify:%d %s. Fabric mode. "
12691 "Completing login. >",
12692 vpip->VPI,
12693 emlxs_vpi_state_xlate(vpip->state));
12694
12695 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI_CMPL,
12696 0, 0, 0);
12697
12698 if (rval) {
12699 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12700 "vpi_logi_cmpl_notify:%d %s rval=%d.",
12701 vpip->VPI,
12702 emlxs_vpi_state_xlate(vpip->state),
12703 rval);
12704 }
12705
12706 return (rval);
12707 }
12708
12709 if (hba->flag & FC_PT_TO_PT) {
12710 if (port->did == 0) {
12711 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12712 "vpi_logi_cmpl_notify:%d %s did=0. P2P mode. "
12713 "Wait for PLOGI compl.",
12714 vpip->VPI,
12715 emlxs_vpi_state_xlate(vpip->state));
12716
12717 if (rpip->cmpl) {
12718 emlxs_rpi_deferred_cmpl(port, rpip, 0);
12719 }
12720
12721 /* Wait for P2P PLOGI completion to continue */
12722 return (0);
12723 }
12724
12725 vpip->p2p_rpip = rpip;
12726
12727 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12728 "vpi_logi_cmpl_notify:%d %s. P2P mode. "
12729 "Completing login. >",
12730 vpip->VPI,
12731 emlxs_vpi_state_xlate(vpip->state));
12732
12733 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI_CMPL,
12734 0, 0, 0);
12735
12736 if (rval) {
12737 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12738 "vpi_logi_cmpl_notify:%d %s rval=%d.",
12739 vpip->VPI,
12740 emlxs_vpi_state_xlate(vpip->state),
12741 rval);
12742 }
12743
12744 return (rval);
12745 }
12746
12747 return (1);
12748
12749 } /* emlxs_vpi_logi_cmpl_notify() */
12750
12751
12752 extern uint32_t
emlxs_vpi_logi_failed_notify(emlxs_port_t * port,emlxs_buf_t * sbp)12753 emlxs_vpi_logi_failed_notify(emlxs_port_t *port, emlxs_buf_t *sbp)
12754 {
12755 emlxs_hba_t *hba = HBA;
12756 VPIobj_t *vpip = port->vpip;
12757 RPIobj_t *rpip = vpip->fabric_rpip;
12758 uint32_t rval = 0;
12759 emlxs_deferred_cmpl_t *cmpl;
12760
12761 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
12762 return (1);
12763 }
12764
12765 mutex_enter(&EMLXS_FCF_LOCK);
12766
12767 if (vpip->state != VPI_STATE_LOGI) {
12768 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12769 "vpi_logi_failed_notify:%d %s. "
12770 "Invalid state.",
12771 vpip->VPI,
12772 emlxs_vpi_state_xlate(vpip->state));
12773
12774 /* Fabric logo is implied */
12775 emlxs_vpi_logo_handler(port, vpip);
12776
12777 mutex_exit(&EMLXS_FCF_LOCK);
12778
12779 return (1);
12780 }
12781
12782 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12783 "vpi_logi_failed_notify:%d %s. "
12784 "Failing login. >",
12785 vpip->VPI,
12786 emlxs_vpi_state_xlate(vpip->state));
12787
12788 /* For safety */
12789 if (rpip->cmpl) {
12790 emlxs_rpi_deferred_cmpl(port, rpip, 1);
12791 }
12792
12793 if (sbp) {
12794 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc(
12795 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP);
12796
12797 cmpl->port = port;
12798 cmpl->arg1 = (void *)sbp;
12799 cmpl->arg2 = 0;
12800 cmpl->arg3 = 0;
12801
12802 rpip->cmpl = cmpl;
12803 }
12804
12805 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI_FAILED,
12806 FCF_REASON_OP_FAILED, 1, 0);
12807
12808 if (rval && rpip->cmpl) {
12809 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t));
12810 rpip->cmpl = 0;
12811 }
12812
12813 mutex_exit(&EMLXS_FCF_LOCK);
12814 return (rval);
12815
12816 } /* emlxs_vpi_logi_failed_notify() */
12817
12818
12819 extern uint32_t
emlxs_vpi_logo_cmpl_notify(emlxs_port_t * port)12820 emlxs_vpi_logo_cmpl_notify(emlxs_port_t *port)
12821 {
12822 emlxs_hba_t *hba = HBA;
12823 VPIobj_t *vpip = port->vpip;
12824 uint32_t rval = 0;
12825 VFIobj_t *vfip;
12826 FCFIobj_t *fcfp;
12827
12828 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
12829 return (1);
12830 }
12831
12832 mutex_enter(&EMLXS_FCF_LOCK);
12833
12834 /* Fabric logo is complete */
12835 emlxs_vpi_logo_handler(port, vpip);
12836
12837 if ((vpip->state == VPI_STATE_OFFLINE) ||
12838 (vpip->flag & EMLXS_VPI_OFFLINE_REQ)) {
12839 /* Already offline. Do nothing */
12840 mutex_exit(&EMLXS_FCF_LOCK);
12841 return (0);
12842 }
12843
12844 vfip = vpip->vfip;
12845 fcfp = vfip->fcfp;
12846
12847 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12848 "vpi_logo_cmpl_notify:%d %s fcfi:%d vfi:%d. "
12849 "Offlining VPI:%d,%d >",
12850 vpip->VPI,
12851 emlxs_vpi_state_xlate(vpip->state),
12852 fcfp->fcf_index,
12853 vfip->VFI,
12854 vpip->index, vpip->VPI);
12855
12856 rval = emlxs_vpi_event(port, FCF_EVENT_VPI_OFFLINE, vpip);
12857
12858 mutex_exit(&EMLXS_FCF_LOCK);
12859
12860 return (rval);
12861
12862 } /* emlxs_vpi_logo_cmpl_notify() */
12863
12864
12865 /*ARGSUSED*/
12866 static uint32_t
emlxs_vpi_logi_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)12867 emlxs_vpi_logi_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
12868 void *arg1)
12869 {
12870 emlxs_hba_t *hba = HBA;
12871 emlxs_buf_t *sbp = (emlxs_buf_t *)arg1;
12872 fc_packet_t *pkt = PRIV2PKT(sbp);
12873 uint32_t rval = 0;
12874
12875 if (vpip->state != VPI_STATE_LOGI) {
12876 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12877 "vpi_logi_action:%d %s:%s arg=%p. "
12878 "Invalid state. <",
12879 vpip->VPI,
12880 emlxs_vpi_state_xlate(vpip->state),
12881 emlxs_fcf_event_xlate(evt), arg1);
12882 return (1);
12883 }
12884
12885 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) {
12886 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12887 "vpi_logi_action:%d. Offline requested.",
12888 vpip->VPI);
12889
12890 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
12891 return (rval);
12892 }
12893
12894 if (vpip->flag & EMLXS_VPI_LOGI) {
12895 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
12896 "vpi_logi_action:%d flag=%x. LOGI already set.",
12897 vpip->VPI, vpip->flag);
12898
12899 /* Fabric logo is implied */
12900 emlxs_vpi_logo_handler(port, vpip);
12901 }
12902
12903 /* Check if FC_PT_TO_PT is set */
12904 if (hba->flag & FC_PT_TO_PT) {
12905 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12906 "vpi_logi_action:%d logi_count=%d. FLOGI set. P2P. <",
12907 vpip->VPI,
12908 vpip->vfip->logi_count);
12909
12910 *((uint32_t *)pkt->pkt_cmd) = (uint32_t)ELS_CMD_FLOGI;
12911
12912 vpip->vfip->flogi_vpip = vpip;
12913
12914 if (vpip->vfip->logi_count == 0) {
12915 vpip->vfip->logi_count++;
12916 vpip->flag |= EMLXS_VPI_VFI_LOGI;
12917 }
12918
12919 return (0);
12920 }
12921
12922 /* Set login command based on vfi logi_count */
12923 if (vpip->vfip->logi_count == 0) {
12924 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12925 "vpi_logi_action:%d logi_count=%d. FLOGI set. <",
12926 vpip->VPI,
12927 vpip->vfip->logi_count);
12928
12929 *((uint32_t *)pkt->pkt_cmd) = (uint32_t)ELS_CMD_FLOGI;
12930
12931 vpip->vfip->flogi_vpip = vpip;
12932 } else {
12933 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12934 "vpi_logi_action:%d logi_count=%d. FDISC set. <",
12935 vpip->VPI,
12936 vpip->vfip->logi_count);
12937
12938 *((uint32_t *)pkt->pkt_cmd) = (uint32_t)ELS_CMD_FDISC;
12939 }
12940
12941 vpip->vfip->logi_count++;
12942 vpip->flag |= EMLXS_VPI_VFI_LOGI;
12943
12944 return (0);
12945
12946 } /* emlxs_vpi_logi_action() */
12947
12948
12949 /*ARGSUSED*/
12950 static uint32_t
emlxs_vpi_logi_failed_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)12951 emlxs_vpi_logi_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
12952 void *arg1)
12953 {
12954 emlxs_hba_t *hba = HBA;
12955 uint32_t rval = 0;
12956
12957 if (vpip->state != VPI_STATE_LOGI_FAILED) {
12958 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12959 "vpi_logi_failed_action:%d %s:%s arg=%p. "
12960 "Invalid state. <",
12961 vpip->VPI,
12962 emlxs_vpi_state_xlate(vpip->state),
12963 emlxs_fcf_event_xlate(evt), arg1);
12964 return (1);
12965 }
12966
12967 /* Fabric logo is implied */
12968 emlxs_vpi_logo_handler(port, vpip);
12969
12970 if (hba->topology == TOPOLOGY_LOOP) {
12971 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12972 "vpi_logi_failed_action:%d. Private loop. "
12973 "Registering VPI.",
12974 vpip->VPI);
12975
12976 /* Update the VPI flogi_vpip pointer for loop */
12977 /* because the vpi_logo_handler cleared it */
12978 vpip->vfip->flogi_vpip = vpip;
12979
12980 bcopy((void *)&vpip->port->sparam,
12981 (void *)&vpip->fabric_rpip->sparam,
12982 sizeof (SERV_PARM));
12983
12984 /* Update the VPI Fabric RPI */
12985 vpip->fabric_rpip->sparam.cmn.w2.r_a_tov =
12986 LE_SWAP32((FF_DEF_RATOV * 1000));
12987
12988 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG,
12989 FCF_REASON_EVENT, evt, arg1);
12990 return (rval);
12991 }
12992
12993 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
12994 "vpi_logi_failed_action:%d. Requesting offline.",
12995 vpip->VPI);
12996
12997 vpip->flag &= ~EMLXS_VPI_REQ_MASK;
12998 vpip->flag |= EMLXS_VPI_OFFLINE_REQ;
12999 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
13000
13001 return (rval);
13002
13003 } /* emlxs_vpi_logi_failed_action() */
13004
13005
13006 /*ARGSUSED*/
13007 static uint32_t
emlxs_vpi_logi_cmpl_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13008 emlxs_vpi_logi_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13009 void *arg1)
13010 {
13011 emlxs_hba_t *hba = HBA;
13012 uint32_t rval = 0;
13013 char buffer1[64];
13014 char buffer2[64];
13015 uint32_t new_config = 0;
13016
13017 if (vpip->state != VPI_STATE_LOGI_CMPL) {
13018 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13019 "vpi_logi_cmpl_action:%d %s:%s arg=%p. "
13020 "Invalid state. <",
13021 vpip->VPI,
13022 emlxs_vpi_state_xlate(vpip->state),
13023 emlxs_fcf_event_xlate(evt), arg1);
13024 return (1);
13025 }
13026
13027 vpip->flag |= EMLXS_VPI_LOGI;
13028
13029 /* Check for new fabric */
13030 if (port->prev_did) {
13031 if (SLI4_FCOE_MODE) {
13032 /* Check for FCF change */
13033 if (((port->prev_did != port->did) ||
13034 bcmp(&port->prev_fabric_sparam.portName,
13035 &port->fabric_sparam.portName, 8)) &&
13036 emlxs_nport_count(port)) {
13037 new_config = 1;
13038 }
13039 } else {
13040 uint32_t old_topo;
13041 uint32_t new_topo;
13042
13043 /* Check for topology change (0=loop 1=fabric) */
13044 old_topo = ((port->prev_did && 0xFFFF00) == 0)? 0:1;
13045 new_topo = ((port->did && 0xFFFF00) == 0)? 0:1;
13046
13047 if (old_topo != new_topo) {
13048 new_config = 1;
13049
13050 /* Check for any switch change */
13051 } else if ((port->prev_did != port->did) ||
13052 bcmp(&port->prev_fabric_sparam.portName,
13053 &port->fabric_sparam.portName, 8)) {
13054 new_config = 1;
13055 }
13056 }
13057 }
13058
13059 if (new_config) {
13060 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13061 "vpi_logi_cmpl_action:%d. "
13062 "New config. Offlining port.",
13063 vpip->VPI);
13064
13065 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13066 "vpi_logi_cmpl_action: prev_wwpn=%s wwpn=%s prev_did=%x "
13067 "did=%x.",
13068 emlxs_wwn_xlate(buffer1, sizeof (buffer1),
13069 (uint8_t *)&port->prev_fabric_sparam.portName),
13070 emlxs_wwn_xlate(buffer2, sizeof (buffer2),
13071 (uint8_t *)&port->fabric_sparam.portName),
13072 port->prev_did, port->did);
13073
13074 vpip->flag &= ~EMLXS_VPI_REQ_MASK;
13075 vpip->flag |= EMLXS_VPI_OFFLINE_REQ;
13076 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
13077
13078 return (rval);
13079 }
13080
13081 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13082 "vpi_logi_cmpl_action:%d. Registering.",
13083 vpip->VPI);
13084
13085 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG,
13086 FCF_REASON_EVENT, evt, arg1);
13087
13088 return (rval);
13089
13090 } /* emlxs_vpi_logi_cmpl_action() */
13091
13092
13093 /*ARGSUSED*/
13094 static uint32_t
emlxs_vpi_logo_failed_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13095 emlxs_vpi_logo_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13096 void *arg1)
13097 {
13098 emlxs_hba_t *hba = HBA;
13099 uint32_t rval = 0;
13100
13101 vpip->attempts++;
13102
13103 if (vpip->state != VPI_STATE_LOGO_FAILED) {
13104 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
13105 "vpi_logo_failed_action:%d %s:%s arg=%p attempt=%d. "
13106 "Invalid state. <",
13107 vpip->VPI,
13108 emlxs_vpi_state_xlate(vpip->state),
13109 emlxs_fcf_event_xlate(evt), arg1,
13110 vpip->attempts);
13111 return (1);
13112 }
13113
13114 if (hba->state <= FC_LINK_DOWN) {
13115 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13116 "vpi_logo_failed_action:%d attempt=%d. Logo cmpl.",
13117 vpip->VPI,
13118 vpip->attempts);
13119
13120 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_CMPL,
13121 FCF_REASON_OP_FAILED, vpip->attempts, arg1);
13122 } else if (vpip->attempts >= 3) {
13123 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13124 "vpi_logo_failed_action:%d attempt=%d. Logo cmpl.",
13125 vpip->VPI,
13126 vpip->attempts);
13127
13128 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_CMPL,
13129 FCF_REASON_OP_FAILED, vpip->attempts, arg1);
13130 } else {
13131 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13132 "vpi_logo_failed_action:%d attempt=%d. Logging out.",
13133 vpip->VPI,
13134 vpip->attempts);
13135
13136 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO,
13137 FCF_REASON_OP_FAILED, vpip->attempts, arg1);
13138 }
13139
13140 return (rval);
13141
13142 } /* emlxs_vpi_logo_failed_action() */
13143
13144
13145 /*ARGSUSED*/
13146 static uint32_t
emlxs_vpi_logo_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13147 emlxs_vpi_logo_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13148 void *arg1)
13149 {
13150 emlxs_hba_t *hba = HBA;
13151 emlxs_port_t *vport = vpip->port;
13152 uint32_t rval = 0;
13153 uint32_t did;
13154 uint32_t sid;
13155 fc_packet_t *pkt;
13156 ELS_PKT *els;
13157
13158 if (vpip->state != VPI_STATE_LOGO) {
13159 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
13160 "vpi_logo_action:%d %s:%s arg=%p. "
13161 "Invalid state. <",
13162 vpip->VPI,
13163 emlxs_vpi_state_xlate(vpip->state),
13164 emlxs_fcf_event_xlate(evt), arg1);
13165 return (1);
13166 }
13167
13168 if (!(vpip->flag & EMLXS_VPI_LOGI)) {
13169 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13170 "vpi_logo_action:%d. No login. Skipping LOGO.",
13171 vpip->VPI);
13172
13173 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE,
13174 FCF_REASON_EVENT, evt, arg1);
13175 return (rval);
13176 }
13177
13178 if (!(hba->flag & FC_ONLINE_MODE) &&
13179 !(hba->flag & FC_OFFLINING_MODE)) {
13180 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13181 "vpi_logo_action:%d. HBA offline. Skipping LOGO.",
13182 vpip->VPI);
13183
13184 /* Fabric logo is implied */
13185 emlxs_vpi_logo_handler(port, vpip);
13186
13187 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE,
13188 FCF_REASON_EVENT, evt, arg1);
13189 return (rval);
13190 }
13191
13192 if (SLI4_FC_MODE) {
13193 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13194 "vpi_logo_action:%d. FC mode. Skipping LOGO.",
13195 vpip->VPI);
13196
13197 /* Fabric logo is implied */
13198 emlxs_vpi_logo_handler(port, vpip);
13199
13200 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE,
13201 FCF_REASON_EVENT, evt, arg1);
13202 return (rval);
13203 }
13204
13205 if (vpip->prev_state != VPI_STATE_LOGO_FAILED) {
13206 vpip->attempts = 0;
13207 }
13208
13209 did = FABRIC_DID;
13210 sid = (vport->did)? vport->did:vport->prev_did;
13211
13212 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13213 "vpi_logo_action:%d attempts=%d sid=%x did=%x. Sending LOGO. <",
13214 vpip->VPI,
13215 vpip->attempts,
13216 sid, did);
13217
13218 pkt = emlxs_pkt_alloc(vport,
13219 (sizeof (uint32_t) + sizeof (LOGO)),
13220 (sizeof (uint32_t) + sizeof (LOGO)), 0, KM_NOSLEEP);
13221
13222 if (!pkt) {
13223 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_FAILED,
13224 FCF_REASON_NO_PKT, 0, arg1);
13225
13226 return (rval);
13227 }
13228
13229 pkt->pkt_tran_type = FC_PKT_EXCHANGE;
13230 pkt->pkt_timeout = (2 * hba->fc_ratov);
13231
13232 /* Build the fc header */
13233 pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did);
13234 pkt->pkt_cmd_fhdr.r_ctl =
13235 R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
13236 pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(sid);
13237 pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
13238 pkt->pkt_cmd_fhdr.f_ctl =
13239 F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE;
13240 pkt->pkt_cmd_fhdr.seq_id = 0;
13241 pkt->pkt_cmd_fhdr.df_ctl = 0;
13242 pkt->pkt_cmd_fhdr.seq_cnt = 0;
13243 pkt->pkt_cmd_fhdr.ox_id = 0xffff;
13244 pkt->pkt_cmd_fhdr.rx_id = 0xffff;
13245 pkt->pkt_cmd_fhdr.ro = 0;
13246
13247 /* Build the command */
13248 els = (ELS_PKT *)pkt->pkt_cmd;
13249 els->elsCode = 0x05;
13250 els->un.logo.un.nPortId32 = pkt->pkt_cmd_fhdr.s_id;
13251 bcopy((uint8_t *)&vport->wwpn,
13252 (uint8_t *)&els->un.logo.portName, 8);
13253
13254 /* Send the pkt now */
13255 rval = emlxs_pkt_send(pkt, 0);
13256 if (rval != FC_SUCCESS) {
13257 /* Free the pkt */
13258 emlxs_pkt_free(pkt);
13259
13260 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_FAILED,
13261 FCF_REASON_SEND_FAILED, rval, arg1);
13262
13263 return (rval);
13264 }
13265
13266 /* For now we will send and forget */
13267 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_CMPL,
13268 FCF_REASON_EVENT, evt, arg1);
13269
13270 return (rval);
13271
13272 } /* emlxs_vpi_logo_action() */
13273
13274
13275 /*ARGSUSED*/
13276 static uint32_t
emlxs_vpi_logo_cmpl_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13277 emlxs_vpi_logo_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13278 void *arg1)
13279 {
13280 uint32_t rval = 0;
13281
13282 if (vpip->state != VPI_STATE_LOGO_CMPL) {
13283 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
13284 "vpi_logo_cmpl_action:%d %s:%s arg=%p. "
13285 "Invalid state. <",
13286 vpip->VPI,
13287 emlxs_vpi_state_xlate(vpip->state),
13288 emlxs_fcf_event_xlate(evt), arg1);
13289 return (1);
13290 }
13291
13292 /* Fabric logo is complete */
13293 emlxs_vpi_logo_handler(port, vpip);
13294
13295 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13296 "vpi_logo_cmpl_action:%d attempts=%d. Offline RPI's.",
13297 vpip->VPI,
13298 vpip->attempts);
13299
13300 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE,
13301 FCF_REASON_EVENT, evt, arg1);
13302
13303 return (rval);
13304
13305 } /* emlxs_vpi_logo_cmpl_action() */
13306
13307
13308 /*ARGSUSED*/
13309 static uint32_t
emlxs_vpi_unreg_failed_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13310 emlxs_vpi_unreg_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13311 void *arg1)
13312 {
13313 uint32_t rval = 0;
13314
13315 vpip->attempts++;
13316
13317 if (vpip->state != VPI_STATE_UNREG_FAILED) {
13318 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
13319 "vpi_unreg_failed_action:%d %s:%s arg=%p attempt=%d. "
13320 "Invalid state. <",
13321 vpip->VPI,
13322 emlxs_vpi_state_xlate(vpip->state),
13323 emlxs_fcf_event_xlate(evt), arg1,
13324 vpip->attempts);
13325 return (1);
13326 }
13327
13328 if ((vpip->reason == FCF_REASON_SEND_FAILED) ||
13329 (vpip->attempts >= 3)) {
13330 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13331 "vpi_unreg_failed_action:%d attempt=%d. Unreg cmpl.",
13332 vpip->VPI,
13333 vpip->attempts);
13334
13335 vpip->flag &= ~(EMLXS_VPI_REG | EMLXS_VPI_INIT);
13336
13337 vpip->flag &= ~EMLXS_VPI_REQ_MASK;
13338 vpip->flag |= EMLXS_VPI_OFFLINE_REQ;
13339 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_CMPL,
13340 FCF_REASON_OP_FAILED, vpip->attempts, arg1);
13341 } else {
13342 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13343 "vpi_unreg_failed_action:%d attempt=%d. Unregistering.",
13344 vpip->VPI,
13345 vpip->attempts);
13346
13347 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG,
13348 FCF_REASON_OP_FAILED, vpip->attempts, arg1);
13349 }
13350
13351 return (rval);
13352
13353 } /* emlxs_vpi_unreg_failed_action() */
13354
13355
13356 /*ARGSUSED*/
13357 static uint32_t
emlxs_vpi_unreg_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)13358 emlxs_vpi_unreg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
13359 {
13360 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
13361 MAILBOX4 *mb4;
13362 VPIobj_t *vpip;
13363
13364 vpip = (VPIobj_t *)mbq->context;
13365 mb4 = (MAILBOX4 *)mbq;
13366
13367 mutex_enter(&EMLXS_FCF_LOCK);
13368
13369 if (vpip->state != VPI_STATE_UNREG) {
13370 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13371 "vpi_unreg_mbcmpl:%d state=%s.",
13372 vpip->VPI,
13373 emlxs_vpi_state_xlate(vpip->state));
13374
13375 mutex_exit(&EMLXS_FCF_LOCK);
13376 return (0);
13377 }
13378
13379 if (mb4->mbxStatus) {
13380 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13381 "vpi_unreg_mbcmpl:%d failed. %s. >",
13382 vpip->VPI,
13383 emlxs_mb_xlate_status(mb4->mbxStatus));
13384
13385 (void) emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_FAILED,
13386 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, (void *)mbq->sbp);
13387
13388 mutex_exit(&EMLXS_FCF_LOCK);
13389 return (0);
13390 }
13391
13392 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13393 "vpi_unreg_mbcmpl:%d. Unreg complete. >",
13394 vpip->VPI);
13395
13396 vpip->flag &= ~(EMLXS_VPI_REG | EMLXS_VPI_INIT);
13397 (void) emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_CMPL, 0, 0, 0);
13398
13399 mutex_exit(&EMLXS_FCF_LOCK);
13400 return (0);
13401
13402 } /* emlxs_vpi_unreg_mbcmpl() */
13403
13404
13405 /*ARGSUSED*/
13406 static uint32_t
emlxs_vpi_unreg_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13407 emlxs_vpi_unreg_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13408 void *arg1)
13409 {
13410 emlxs_hba_t *hba = HBA;
13411 MAILBOX4 *mb4;
13412 MAILBOXQ *mbq;
13413 uint32_t rval = 0;
13414
13415 if (vpip->state != VPI_STATE_UNREG) {
13416 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
13417 "vpi_unreg_action:%d %s:%s arg=%p. "
13418 "Invalid state. <",
13419 vpip->VPI,
13420 emlxs_vpi_state_xlate(vpip->state),
13421 emlxs_fcf_event_xlate(evt), arg1);
13422 return (1);
13423 }
13424
13425 if ((vpip->rpi_online > vpip->rpi_paused) ||
13426 (vpip->fabric_rpip->state != RPI_STATE_FREE)) {
13427 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13428 "vpi_unreg_action:%d rpi_online=%d,%d fstate=%x. "
13429 "Waiting for RPI's.", vpip->VPI, vpip->rpi_online,
13430 vpip->rpi_paused, vpip->fabric_rpip->state);
13431
13432 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE,
13433 FCF_REASON_EVENT, evt, arg1);
13434 return (rval);
13435 }
13436
13437 if (!(vpip->flag & EMLXS_VPI_REG)) {
13438 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13439 "vpi_unreg_action:%d. Not registered. Skipping UNREG_VPI.",
13440 vpip->VPI);
13441
13442 rval = emlxs_vpi_state(port, vpip, VPI_STATE_OFFLINE,
13443 FCF_REASON_EVENT, evt, arg1);
13444 return (rval);
13445 }
13446
13447 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) {
13448 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13449 "vpi_unreg_action:%d rpi_online=%d,%d. Pausing.",
13450 vpip->VPI,
13451 vpip->rpi_online, vpip->rpi_paused);
13452
13453 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PAUSED,
13454 FCF_REASON_EVENT, evt, arg1);
13455 return (rval);
13456 }
13457
13458 if (vpip->prev_state != VPI_STATE_UNREG_FAILED) {
13459 vpip->attempts = 0;
13460 }
13461
13462 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13463 "vpi_unreg_action:%d attempts=%d. Sending UNREG_VPI. <",
13464 vpip->VPI,
13465 vpip->attempts);
13466
13467 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
13468 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_FAILED,
13469 FCF_REASON_NO_MBOX, 0, arg1);
13470
13471 return (rval);
13472 }
13473 mb4 = (MAILBOX4*)mbq;
13474 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
13475
13476 mbq->nonembed = NULL;
13477 mbq->mbox_cmpl = emlxs_vpi_unreg_mbcmpl;
13478 mbq->context = (void *)vpip;
13479 mbq->port = (void *)vpip->port;
13480
13481 mb4->un.varUnRegVPI4.ii = 0; /* index is a VPI */
13482 mb4->un.varUnRegVPI4.index = vpip->VPI;
13483 mb4->mbxCommand = MBX_UNREG_VPI;
13484 mb4->mbxOwner = OWN_HOST;
13485
13486 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
13487 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
13488 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
13489
13490 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_FAILED,
13491 FCF_REASON_SEND_FAILED, rval, arg1);
13492
13493 return (rval);
13494 }
13495
13496 return (0);
13497
13498 } /* emlxs_vpi_unreg_action() */
13499
13500
13501 /*ARGSUSED*/
13502 static uint32_t
emlxs_vpi_unreg_cmpl_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13503 emlxs_vpi_unreg_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13504 void *arg1)
13505 {
13506 uint32_t rval = 0;
13507
13508 if (vpip->state != VPI_STATE_UNREG_CMPL) {
13509 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
13510 "vpi_unreg_cmpl_action:%d %s:%s arg=%p. "
13511 "Invalid state. <",
13512 vpip->VPI,
13513 emlxs_vpi_state_xlate(vpip->state),
13514 emlxs_fcf_event_xlate(evt), arg1);
13515 return (1);
13516 }
13517
13518 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13519 "vpi_unreg_cmpl_action:%d attempts=%d. Going offline.",
13520 vpip->VPI,
13521 vpip->attempts);
13522
13523 rval = emlxs_vpi_state(port, vpip, VPI_STATE_OFFLINE,
13524 FCF_REASON_EVENT, evt, arg1);
13525
13526 return (rval);
13527
13528 } /* emlxs_vpi_unreg_cmpl_action() */
13529
13530
13531 /*ARGSUSED*/
13532 static uint32_t
emlxs_vpi_reg_failed_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13533 emlxs_vpi_reg_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13534 void *arg1)
13535 {
13536 uint32_t rval = 0;
13537
13538 vpip->attempts++;
13539
13540 if (vpip->state != VPI_STATE_REG_FAILED) {
13541 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
13542 "vpi_reg_failed_action:%d %s:%s arg=%p attempt=%d. "
13543 "Invalid state. <",
13544 vpip->VPI,
13545 emlxs_vpi_state_xlate(vpip->state),
13546 emlxs_fcf_event_xlate(evt), arg1,
13547 vpip->attempts);
13548 return (1);
13549 }
13550
13551 if ((vpip->reason == FCF_REASON_SEND_FAILED) ||
13552 (vpip->attempts >= 3)) {
13553 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13554 "vpi_reg_failed_action:%d attempt=%d reason=%x. Reg cmpl.",
13555 vpip->VPI,
13556 vpip->attempts,
13557 vpip->reason);
13558
13559 vpip->flag &= ~EMLXS_VPI_REQ_MASK;
13560 vpip->flag |= EMLXS_VPI_OFFLINE_REQ;
13561 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG_CMPL,
13562 FCF_REASON_OP_FAILED, vpip->attempts, arg1);
13563 } else {
13564 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13565 "vpi_reg_failed_action:%d attempt=%d. Registering.",
13566 vpip->VPI,
13567 vpip->attempts);
13568
13569 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG,
13570 FCF_REASON_OP_FAILED, vpip->attempts, arg1);
13571 }
13572
13573 return (rval);
13574
13575 } /* emlxs_vpi_reg_failed_action() */
13576
13577
13578 /*ARGSUSED*/
13579 static uint32_t
emlxs_vpi_reg_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)13580 emlxs_vpi_reg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
13581 {
13582 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
13583 MAILBOX4 *mb4;
13584 VPIobj_t *vpip;
13585
13586 vpip = (VPIobj_t *)mbq->context;
13587 mb4 = (MAILBOX4 *)mbq;
13588
13589 mutex_enter(&EMLXS_FCF_LOCK);
13590
13591 if (vpip->state != VPI_STATE_REG) {
13592 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13593 "vpi_reg_mbcmpl:%d state=%s.",
13594 vpip->VPI,
13595 emlxs_vpi_state_xlate(vpip->state));
13596
13597 mutex_exit(&EMLXS_FCF_LOCK);
13598 return (0);
13599 }
13600
13601 if (mb4->mbxStatus) {
13602 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13603 "vpi_reg_mbcmpl:%d failed. %s. >",
13604 vpip->VPI,
13605 emlxs_mb_xlate_status(mb4->mbxStatus));
13606
13607 if (mb4->mbxStatus == MBXERR_DID_INCONSISTENT) {
13608 vpip->flag |= EMLXS_VPI_OFFLINE_REQ;
13609 }
13610
13611 (void) emlxs_vpi_state(port, vpip, VPI_STATE_REG_FAILED,
13612 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
13613
13614 mutex_exit(&EMLXS_FCF_LOCK);
13615 return (0);
13616 }
13617
13618 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13619 "vpi_reg_mbcmpl:%d. Reg complete. >",
13620 vpip->VPI);
13621
13622 vpip->flag |= EMLXS_VPI_REG;
13623 (void) emlxs_vpi_state(port, vpip, VPI_STATE_REG_CMPL,
13624 0, 0, 0);
13625
13626 mutex_exit(&EMLXS_FCF_LOCK);
13627 return (0);
13628
13629 } /* emlxs_vpi_reg_mbcmpl() */
13630
13631
13632 /*ARGSUSED*/
13633 static uint32_t
emlxs_vpi_reg_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13634 emlxs_vpi_reg_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13635 void *arg1)
13636 {
13637 emlxs_hba_t *hba = HBA;
13638 uint32_t *wwpn;
13639 MAILBOX *mb;
13640 MAILBOXQ *mbq;
13641 uint32_t rval = 0;
13642
13643 if (vpip->state != VPI_STATE_REG) {
13644 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
13645 "vpi_reg_action:%d %s:%s arg=%p. "
13646 "Invalid state. <",
13647 vpip->VPI,
13648 emlxs_vpi_state_xlate(vpip->state),
13649 emlxs_fcf_event_xlate(evt), arg1);
13650 return (1);
13651 }
13652
13653 if (vpip->prev_state != VPI_STATE_REG_FAILED) {
13654 vpip->attempts = 0;
13655 }
13656
13657 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) {
13658 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13659 "vpi_reg_action:%d attempts=%d. Offline requested.",
13660 vpip->VPI,
13661 vpip->attempts);
13662
13663 rval = emlxs_vpi_offline_handler(port, vpip, 0);
13664 return (rval);
13665 }
13666
13667 if (!(vpip->vfip->flag & EMLXS_VFI_REG)) {
13668 /* We can't register the VPI until our VFI is registered */
13669
13670 /* If this is the flogi_vpip, then we can skip the REG_VPI. */
13671 /* REG_VPI will be performed later during REG_VFI */
13672 if (vpip == vpip->vfip->flogi_vpip) {
13673 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13674 "vpi_reg_action:%d. flogi_vpi. Skipping REG_VPI.",
13675 vpip->VPI);
13676
13677 rval = emlxs_vpi_state(port, vpip, VPI_STATE_ONLINE,
13678 FCF_REASON_EVENT, evt, arg1);
13679
13680 return (rval);
13681 }
13682
13683 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13684 "vpi_reg_action:%d attempts=%d. VFI not registered. "
13685 "Offlining.",
13686 vpip->VPI,
13687 vpip->attempts);
13688
13689 vpip->flag &= ~EMLXS_VPI_REQ_MASK;
13690 vpip->flag |= EMLXS_VPI_OFFLINE_REQ;
13691 rval = emlxs_vpi_offline_handler(port, vpip, 0);
13692 return (rval);
13693 }
13694
13695 if (vpip->flag & EMLXS_VPI_REG) {
13696 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13697 "vpi_reg_action:%d attempts=%d. Updating REG_VPI. <",
13698 vpip->VPI,
13699 vpip->attempts);
13700 } else {
13701 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13702 "vpi_reg_action:%d attempts=%d. Sending REG_VPI. <",
13703 vpip->VPI,
13704 vpip->attempts);
13705 }
13706
13707 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
13708 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG_FAILED,
13709 FCF_REASON_NO_MBOX, 0, arg1);
13710
13711 return (rval);
13712 }
13713 mb = (MAILBOX*)mbq;
13714 bzero((void *) mb, MAILBOX_CMD_BSIZE);
13715
13716 mbq->nonembed = NULL;
13717 mbq->mbox_cmpl = emlxs_vpi_reg_mbcmpl;
13718 mbq->context = (void *)vpip;
13719 mbq->port = (void *)vpip->port;
13720
13721 mb->un.varRegVpi.vfi = vpip->vfip->VFI;
13722 mb->un.varRegVpi.upd = (vpip->flag & EMLXS_VPI_REG)? 1:0;
13723
13724 wwpn = (uint32_t *)&port->wwpn;
13725 mb->un.varRegVpi.portname[0] = BE_SWAP32(*wwpn);
13726 wwpn++;
13727 mb->un.varRegVpi.portname[1] = BE_SWAP32(*wwpn);
13728
13729 mb->un.varRegVpi.vpi = vpip->VPI;
13730 mb->un.varRegVpi.sid = vpip->port->did;
13731 mb->mbxCommand = MBX_REG_VPI;
13732 mb->mbxOwner = OWN_HOST;
13733
13734 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
13735 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
13736 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
13737
13738 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG_FAILED,
13739 FCF_REASON_SEND_FAILED, rval, arg1);
13740
13741 return (rval);
13742 }
13743
13744 return (0);
13745
13746 } /* emlxs_vpi_reg_action() */
13747
13748
13749 /*ARGSUSED*/
13750 static uint32_t
emlxs_vpi_reg_cmpl_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13751 emlxs_vpi_reg_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13752 void *arg1)
13753 {
13754 uint32_t rval = 0;
13755
13756 if (vpip->state != VPI_STATE_REG_CMPL) {
13757 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
13758 "vpi_reg_cmpl_action:%d %s:%s arg=%p. "
13759 "Invalid state. <",
13760 vpip->VPI,
13761 emlxs_vpi_state_xlate(vpip->state),
13762 emlxs_fcf_event_xlate(evt), arg1);
13763 return (1);
13764 }
13765
13766 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) {
13767 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13768 "vpi_reg_cmpl_action:%d attempts=%d. Offline requested.",
13769 vpip->VPI,
13770 vpip->attempts);
13771
13772 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
13773 return (rval);
13774 }
13775
13776 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13777 "vpi_reg_cmpl_action:%d attempts=%d. Going online.",
13778 vpip->VPI,
13779 vpip->attempts);
13780
13781 rval = emlxs_vpi_state(port, vpip, VPI_STATE_ONLINE,
13782 FCF_REASON_EVENT, evt, arg1);
13783
13784 return (rval);
13785
13786 } /* emlxs_vpi_reg_cmpl_action() */
13787
13788
13789 /*ARGSUSED*/
13790 static uint32_t
emlxs_vpi_online_action(emlxs_port_t * port,VPIobj_t * vpip,uint32_t evt,void * arg1)13791 emlxs_vpi_online_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt,
13792 void *arg1)
13793 {
13794 uint32_t rval = 0;
13795
13796 if (vpip->state != VPI_STATE_ONLINE) {
13797 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13798 "vpi_online_action:%d %s:%s arg=%p. "
13799 "Invalid state. <",
13800 vpip->VPI,
13801 emlxs_vpi_state_xlate(vpip->state),
13802 emlxs_fcf_event_xlate(evt), arg1);
13803 return (1);
13804 }
13805
13806 vpip->flag &= ~EMLXS_VPI_ONLINE_REQ;
13807
13808 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) {
13809 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13810 "vpi_online_action:%d attempts=%d. Offline requested.",
13811 vpip->VPI,
13812 vpip->attempts);
13813
13814 rval = emlxs_vpi_offline_handler(port, vpip, arg1);
13815 return (rval);
13816 }
13817
13818 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
13819 "vpi_online_action:%d. VPI online. Notifying VFI:%d >",
13820 vpip->VPI,
13821 vpip->vfip->VFI);
13822
13823 /* Notify VFI */
13824 rval = emlxs_vfi_event(port, FCF_EVENT_VPI_ONLINE, vpip);
13825
13826 return (rval);
13827
13828 } /* emlxs_vpi_online_action() */
13829
13830
13831 /* ************************************************************************** */
13832 /* RPI */
13833 /* ************************************************************************** */
13834
13835 static char *
emlxs_rpi_state_xlate(uint32_t state)13836 emlxs_rpi_state_xlate(uint32_t state)
13837 {
13838 static char buffer[32];
13839 uint32_t i;
13840 uint32_t count;
13841
13842 count = sizeof (emlxs_rpi_state_table) / sizeof (emlxs_table_t);
13843 for (i = 0; i < count; i++) {
13844 if (state == emlxs_rpi_state_table[i].code) {
13845 return (emlxs_rpi_state_table[i].string);
13846 }
13847 }
13848
13849 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state);
13850 return (buffer);
13851
13852 } /* emlxs_rpi_state_xlate() */
13853
13854
13855 static uint32_t
emlxs_rpi_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)13856 emlxs_rpi_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
13857 void *arg1)
13858 {
13859 uint32_t rval = 0;
13860 uint32_t(*func) (emlxs_port_t *, RPIobj_t *, uint32_t, void *);
13861 uint32_t index;
13862 uint32_t events;
13863 uint16_t state;
13864
13865 /* Convert event to action table index */
13866 switch (evt) {
13867 case FCF_EVENT_STATE_ENTER:
13868 index = 0;
13869 break;
13870 case FCF_EVENT_RPI_ONLINE:
13871 index = 1;
13872 break;
13873 case FCF_EVENT_RPI_OFFLINE:
13874 index = 2;
13875 break;
13876 case FCF_EVENT_RPI_PAUSE:
13877 index = 3;
13878 break;
13879 case FCF_EVENT_RPI_RESUME:
13880 index = 4;
13881 break;
13882 default:
13883 return (1);
13884 }
13885
13886 events = RPI_ACTION_EVENTS;
13887 state = rpip->state;
13888
13889 index += (state * events);
13890 func = (uint32_t(*) (emlxs_port_t *, RPIobj_t *, uint32_t, void *))
13891 emlxs_rpi_action_table[index];
13892
13893 if (!func) {
13894 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
13895 "rpi_action:%d %s:%s arg=%p. No action. <",
13896 rpip->RPI,
13897 emlxs_rpi_state_xlate(rpip->state),
13898 emlxs_fcf_event_xlate(evt), arg1);
13899
13900 return (1);
13901 }
13902
13903 rval = (func)(port, rpip, evt, arg1);
13904
13905 return (rval);
13906
13907 } /* emlxs_rpi_action() */
13908
13909
13910 static uint32_t
emlxs_rpi_event(emlxs_port_t * port,uint32_t evt,void * arg1)13911 emlxs_rpi_event(emlxs_port_t *port, uint32_t evt,
13912 void *arg1)
13913 {
13914 RPIobj_t *rpip = NULL;
13915 uint32_t rval = 0;
13916
13917 /* Filter events and acquire fcfi context */
13918 switch (evt) {
13919 case FCF_EVENT_RPI_ONLINE:
13920 case FCF_EVENT_RPI_OFFLINE:
13921 case FCF_EVENT_RPI_PAUSE:
13922 case FCF_EVENT_RPI_RESUME:
13923 rpip = (RPIobj_t *)arg1;
13924
13925 if (!rpip) {
13926 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
13927 "rpi_event: %s arg=%p. Null RPI found. <",
13928 emlxs_fcf_event_xlate(evt), arg1);
13929
13930 return (1);
13931 }
13932
13933 break;
13934
13935 default:
13936 return (1);
13937 }
13938
13939 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg,
13940 "rpi_event:%d %s:%s arg=%p",
13941 rpip->RPI,
13942 emlxs_rpi_state_xlate(rpip->state),
13943 emlxs_fcf_event_xlate(evt), arg1);
13944
13945 rval = emlxs_rpi_action(port, rpip, evt, arg1);
13946
13947 return (rval);
13948
13949 } /* emlxs_rpi_event() */
13950
13951
13952 /*ARGSUSED*/
13953 static uint32_t
emlxs_rpi_state(emlxs_port_t * port,RPIobj_t * rpip,uint16_t state,uint16_t reason,uint32_t explain,void * arg1)13954 emlxs_rpi_state(emlxs_port_t *port, RPIobj_t *rpip, uint16_t state,
13955 uint16_t reason, uint32_t explain, void *arg1)
13956 {
13957 uint32_t rval = 0;
13958
13959 if (state >= RPI_ACTION_STATES) {
13960 return (1);
13961 }
13962
13963 if ((rpip->state == state) &&
13964 (reason != FCF_REASON_REENTER)) {
13965 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
13966 "rpi_state:%d %s:%s:0x%x arg=%p. State not changed. <",
13967 rpip->RPI,
13968 emlxs_rpi_state_xlate(rpip->state),
13969 emlxs_fcf_reason_xlate(reason),
13970 explain, arg1);
13971 return (1);
13972 }
13973
13974 if (!reason) {
13975 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
13976 "rpi_state:%d %s-->%s arg=%p",
13977 rpip->RPI,
13978 emlxs_rpi_state_xlate(rpip->state),
13979 emlxs_rpi_state_xlate(state), arg1);
13980 } else if (reason == FCF_REASON_EVENT) {
13981 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
13982 "rpi_state:%d %s-->%s:%s:%s arg=%p",
13983 rpip->RPI,
13984 emlxs_rpi_state_xlate(rpip->state),
13985 emlxs_rpi_state_xlate(state),
13986 emlxs_fcf_reason_xlate(reason),
13987 emlxs_fcf_event_xlate(explain), arg1);
13988 } else if (explain) {
13989 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
13990 "rpi_state:%d %s-->%s:%s:0x%x arg=%p",
13991 rpip->RPI,
13992 emlxs_rpi_state_xlate(rpip->state),
13993 emlxs_rpi_state_xlate(state),
13994 emlxs_fcf_reason_xlate(reason),
13995 explain, arg1);
13996 } else {
13997 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg,
13998 "rpi_state:%d %s-->%s:%s arg=%p",
13999 rpip->RPI,
14000 emlxs_rpi_state_xlate(rpip->state),
14001 emlxs_rpi_state_xlate(state),
14002 emlxs_fcf_reason_xlate(reason), arg1);
14003 }
14004
14005 rpip->prev_state = rpip->state;
14006 rpip->prev_reason = rpip->reason;
14007 rpip->state = state;
14008 rpip->reason = reason;
14009
14010 rval = emlxs_rpi_action(port, rpip, FCF_EVENT_STATE_ENTER, arg1);
14011
14012 return (rval);
14013
14014 } /* emlxs_rpi_state() */
14015
14016
14017 static void
emlxs_rpi_deferred_cmpl(emlxs_port_t * port,RPIobj_t * rpip,uint32_t status)14018 emlxs_rpi_deferred_cmpl(emlxs_port_t *port, RPIobj_t *rpip, uint32_t status)
14019 {
14020 emlxs_hba_t *hba = HBA;
14021 emlxs_deferred_cmpl_t *cmpl;
14022
14023 if (!rpip->cmpl) {
14024 return;
14025 }
14026
14027 cmpl = rpip->cmpl;
14028 rpip->cmpl = 0;
14029
14030 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14031 "rpi_deferred_cmpl:%d. status=%x ...",
14032 port->vpip->VPI,
14033 status);
14034
14035 emlxs_thread_spawn(hba, emlxs_deferred_cmpl_thread, (void *)cmpl,
14036 (void*)(uintptr_t)status);
14037
14038 return;
14039
14040 } /* emlxs_rpi_deferred_cmpl() */
14041
14042
14043 static void
emlxs_rpi_idle_timer(emlxs_hba_t * hba)14044 emlxs_rpi_idle_timer(emlxs_hba_t *hba)
14045 {
14046 emlxs_config_t *cfg = &CFG;
14047 RPIobj_t *rpip;
14048 uint32_t i;
14049
14050 /* This timer monitors for idle timeout of an RPI in a */
14051 /* RESERVED state. */
14052 /* This means that the RPI was reserved, but never registered. */
14053 /* If the RPI sits for too long (~2 secs) in this state we free it */
14054 rpip = hba->sli.sli4.RPIp;
14055 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) {
14056 if (rpip->state != RPI_STATE_RESERVED) {
14057 continue;
14058 }
14059
14060 /* If RPI is active, then clear timer. */
14061 if (rpip->xri_count) {
14062 rpip->idle_timer = 0;
14063 continue;
14064 }
14065
14066 /* If an F-port RPI is found idle, then free it. */
14067 /* Since an F-port RPI is never registered after the login */
14068 /* completes, it is safe to free it immediately. */
14069 if ((rpip->did == FABRIC_DID) ||
14070 (rpip->did == SCR_DID)) {
14071 goto free_it;
14072 }
14073
14074 /* Start idle timer if not already active */
14075 if (!rpip->idle_timer) {
14076 rpip->idle_timer = hba->timer_tics +
14077 cfg[CFG_FCF_RPI_IDLE_TIMEOUT].current;
14078 }
14079
14080 /* Check for idle timeout */
14081 if (hba->timer_tics < rpip->idle_timer) {
14082 continue;
14083 }
14084 rpip->idle_timer = 0;
14085
14086 free_it:
14087 (void) emlxs_rpi_state(rpip->vpip->port, rpip, RPI_STATE_FREE,
14088 FCF_REASON_UNUSED, 0, 0);
14089 }
14090
14091 return;
14092
14093 } /* emlxs_rpi_idle_timer() */
14094
14095
14096 static RPIobj_t *
emlxs_rpi_alloc(emlxs_port_t * port,uint32_t did)14097 emlxs_rpi_alloc(emlxs_port_t *port, uint32_t did)
14098 {
14099 emlxs_hba_t *hba = HBA;
14100 uint16_t i;
14101 RPIobj_t *rpip;
14102
14103 rpip = hba->sli.sli4.RPIp;
14104 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) {
14105 /* To be consistent with SLI3, the RPI assignment */
14106 /* starts with 1. ONLY one SLI4 HBA in the entire */
14107 /* system will be sacrificed by one RPI and that */
14108 /* is the one having RPI base equal 0. */
14109 if ((rpip->state == RPI_STATE_FREE) && (rpip->RPI != 0)) {
14110
14111 bzero(rpip, sizeof (RPIobj_t));
14112 rpip->index = i;
14113 rpip->RPI = emlxs_sli4_index_to_rpi(hba, i);
14114 rpip->vpip = port->vpip;
14115 rpip->did = did;
14116
14117 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14118 "rpi_alloc:%d. RPI allocated. >",
14119 rpip->RPI);
14120
14121 (void) emlxs_rpi_state(port, rpip, RPI_STATE_RESERVED,
14122 0, 0, 0);
14123
14124 return (rpip);
14125 }
14126 }
14127
14128 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14129 "rpi_alloc: Out of RPI objects.");
14130
14131 return (NULL);
14132
14133 } /* emlxs_rpi_alloc() */
14134
14135
14136 /* Special routine for VPI object */
14137 static void
emlxs_rpi_alloc_fabric_rpi(emlxs_port_t * port)14138 emlxs_rpi_alloc_fabric_rpi(emlxs_port_t *port)
14139 {
14140 RPIobj_t *fabric_rpip;
14141
14142 fabric_rpip = port->vpip->fabric_rpip;
14143
14144 if (fabric_rpip->state != RPI_STATE_FREE) {
14145 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14146 "rpi_alloc_fabric_rpi: Fabric RPI active:%s.",
14147 emlxs_rpi_state_xlate(fabric_rpip->state));
14148 return;
14149 }
14150
14151 bzero(fabric_rpip, sizeof (RPIobj_t));
14152 fabric_rpip->index = 0xffff;
14153 fabric_rpip->RPI = FABRIC_RPI;
14154 fabric_rpip->did = FABRIC_DID;
14155 fabric_rpip->vpip = port->vpip;
14156
14157 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14158 "rpi_alloc_fabric_rpi: Allocating Fabric RPI. >");
14159
14160 (void) emlxs_rpi_state(port, fabric_rpip, RPI_STATE_RESERVED,
14161 0, 0, 0);
14162
14163 return;
14164
14165 } /* emlxs_rpi_alloc_fabric_rpi() */
14166
14167
14168 static uint32_t
emlxs_rpi_free(emlxs_port_t * port,RPIobj_t * rpip)14169 emlxs_rpi_free(emlxs_port_t *port, RPIobj_t *rpip)
14170 {
14171 uint32_t rval = 0;
14172
14173 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14174 "rpi_free:%d did=%x. Freeing RPI. >",
14175 rpip->RPI, rpip->did);
14176
14177 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 0, 0, 0);
14178
14179 return (rval);
14180
14181 } /* emlxs_rpi_free() */
14182
14183
14184 extern RPIobj_t *
emlxs_rpi_find(emlxs_port_t * port,uint16_t rpi)14185 emlxs_rpi_find(emlxs_port_t *port, uint16_t rpi)
14186 {
14187 emlxs_hba_t *hba = HBA;
14188 RPIobj_t *rpip;
14189 uint32_t index;
14190
14191 /* Special handling for Fabric RPI */
14192 if (rpi == FABRIC_RPI) {
14193 return (port->vpip->fabric_rpip);
14194 }
14195
14196 index = emlxs_sli4_rpi_to_index(hba, rpi);
14197
14198 if (index >= hba->sli.sli4.RPICount) {
14199 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14200 "rpi_find:%d. RPI Invalid.",
14201 rpi);
14202
14203 return (NULL);
14204 }
14205
14206 rpip = &hba->sli.sli4.RPIp[index];
14207
14208 if (rpip->state == RPI_STATE_FREE) {
14209 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14210 "rpi_find:%d RPI not active",
14211 rpi);
14212
14213 return (NULL);
14214 }
14215
14216 return (rpip);
14217
14218 } /* emlxs_rpi_find() */
14219
14220
14221 static RPIobj_t *
emlxs_rpi_find_did(emlxs_port_t * port,uint32_t did)14222 emlxs_rpi_find_did(emlxs_port_t *port, uint32_t did)
14223 {
14224 emlxs_hba_t *hba = HBA;
14225 RPIobj_t *rpip;
14226 RPIobj_t *rpip1;
14227 uint32_t i;
14228
14229 rpip1 = NULL;
14230 rpip = hba->sli.sli4.RPIp;
14231 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) {
14232 if (rpip->state == RPI_STATE_FREE) {
14233 continue;
14234 }
14235
14236 if ((rpip->did == did) && (rpip->vpip == port->vpip)) {
14237 rpip1 = rpip;
14238 break;
14239 }
14240 }
14241
14242 return (rpip1);
14243
14244 } /* emlxs_rpi_find_did() */
14245
14246
14247 extern RPIobj_t *
emlxs_rpi_reserve_notify(emlxs_port_t * port,uint32_t did,XRIobj_t * xrip)14248 emlxs_rpi_reserve_notify(emlxs_port_t *port, uint32_t did, XRIobj_t *xrip)
14249 {
14250 emlxs_hba_t *hba = HBA;
14251 RPIobj_t *rpip;
14252
14253 /* xrip will be NULL for unsolicited BLS requests */
14254
14255 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
14256 return (NULL);
14257 }
14258
14259 mutex_enter(&EMLXS_FCF_LOCK);
14260
14261 rpip = emlxs_rpi_find_did(port, did);
14262
14263 if (!rpip) {
14264 rpip = emlxs_rpi_alloc(port, did);
14265 }
14266
14267 if (!rpip) {
14268 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14269 "rpi_reserve_notify: Unable to reserve an rpi. "
14270 "did=%x xri=%d.",
14271 did, ((xrip)?xrip->XRI:0));
14272
14273 mutex_exit(&EMLXS_FCF_LOCK);
14274 return (NULL);
14275 }
14276
14277 /* Bind the XRI */
14278 if (xrip) {
14279 mutex_enter(&EMLXS_FCTAB_LOCK);
14280 xrip->reserved_rpip = rpip;
14281 rpip->xri_count++;
14282 mutex_exit(&EMLXS_FCTAB_LOCK);
14283 }
14284
14285 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14286 "rpi_reserve_notify:%d did=%x xri=%d.",
14287 rpip->RPI, rpip->did, ((xrip)?xrip->XRI:0));
14288
14289 mutex_exit(&EMLXS_FCF_LOCK);
14290
14291 return (rpip);
14292
14293 } /* emlxs_rpi_reserve_notify() */
14294
14295
14296 extern RPIobj_t *
emlxs_rpi_alloc_notify(emlxs_port_t * port,uint32_t did)14297 emlxs_rpi_alloc_notify(emlxs_port_t *port, uint32_t did)
14298 {
14299 emlxs_hba_t *hba = HBA;
14300 RPIobj_t *rpip;
14301
14302 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
14303 return (NULL);
14304 }
14305
14306 mutex_enter(&EMLXS_FCF_LOCK);
14307
14308 rpip = emlxs_rpi_alloc(port, did);
14309
14310 mutex_exit(&EMLXS_FCF_LOCK);
14311
14312 return (rpip);
14313
14314 } /* emlxs_rpi_alloc_notify() */
14315
14316
14317 extern uint32_t
emlxs_rpi_free_notify(emlxs_port_t * port,RPIobj_t * rpip)14318 emlxs_rpi_free_notify(emlxs_port_t *port, RPIobj_t *rpip)
14319 {
14320 emlxs_hba_t *hba = HBA;
14321 uint32_t rval = 0;
14322
14323 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
14324 return (1);
14325 }
14326
14327 if (!rpip) {
14328 return (1);
14329 }
14330
14331 /* Fabric RPI will be handled automatically */
14332 if (rpip->RPI == FABRIC_RPI) {
14333 return (1);
14334 }
14335
14336 mutex_enter(&EMLXS_FCF_LOCK);
14337
14338 rval = emlxs_rpi_free(port, rpip);
14339
14340 mutex_exit(&EMLXS_FCF_LOCK);
14341
14342 return (rval);
14343
14344 } /* emlxs_rpi_free_notify() */
14345
14346
14347 extern uint32_t
emlxs_rpi_pause_notify(emlxs_port_t * port,RPIobj_t * rpip)14348 emlxs_rpi_pause_notify(emlxs_port_t *port, RPIobj_t *rpip)
14349 {
14350 emlxs_hba_t *hba = HBA;
14351
14352 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
14353 return (1);
14354 }
14355
14356 if (!rpip) {
14357 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14358 "rpi_pause_notify: No RPI provided.");
14359 return (1);
14360 }
14361
14362 /* Fabric RPI will be handled automatically */
14363 if (rpip->RPI == FABRIC_RPI) {
14364 return (1);
14365 }
14366
14367 mutex_enter(&EMLXS_FCF_LOCK);
14368
14369 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14370 "rpi_pause_notify:%d %s. Pausing RPI. >",
14371 rpip->RPI,
14372 emlxs_rpi_state_xlate(rpip->state));
14373
14374 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_PAUSE, rpip);
14375
14376 mutex_exit(&EMLXS_FCF_LOCK);
14377
14378 return (0);
14379
14380 } /* emlxs_rpi_pause_notify() */
14381
14382
14383 extern uint32_t
emlxs_rpi_online_notify(emlxs_port_t * port,RPIobj_t * rpip,uint32_t did,SERV_PARM * sparam,void * arg1,void * arg2,void * arg3)14384 emlxs_rpi_online_notify(emlxs_port_t *port, RPIobj_t *rpip, uint32_t did,
14385 SERV_PARM *sparam, void *arg1, void *arg2, void *arg3)
14386 {
14387 emlxs_hba_t *hba = HBA;
14388 emlxs_deferred_cmpl_t *cmpl;
14389 uint32_t allocated = 0;
14390 uint32_t rval = 0;
14391
14392 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
14393 return (1);
14394 }
14395
14396 if ((did == port->did) && (!(hba->flag & FC_LOOPBACK_MODE))) {
14397 /* We never register our local port */
14398 return (1);
14399 }
14400
14401 mutex_enter(&EMLXS_FCF_LOCK);
14402
14403 if (!rpip && (did == FABRIC_DID)) {
14404 /* We never online the Fabric DID other */
14405 /* than the fabric_rpip */
14406 rpip = port->vpip->fabric_rpip;
14407 }
14408
14409 if (!rpip) {
14410 rpip = emlxs_rpi_find_did(port, did);
14411 }
14412
14413 if (!rpip) {
14414 rpip = emlxs_rpi_alloc(port, did);
14415 allocated = 1;
14416 }
14417
14418 if (!rpip) {
14419 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14420 "rpi_online_notify: Unable to allocate an rpi. did=%x",
14421 did);
14422
14423 mutex_exit(&EMLXS_FCF_LOCK);
14424 return (1);
14425 }
14426
14427 /* Initialize RPI node info */
14428 bcopy((void *)sparam, (void *)&rpip->sparam, sizeof (SERV_PARM));
14429
14430 if (arg1 || arg2 || arg3) {
14431 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc(
14432 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP);
14433
14434 cmpl->port = port;
14435 cmpl->arg1 = arg1;
14436 cmpl->arg2 = arg2;
14437 cmpl->arg3 = arg3;
14438
14439 /* For safety */
14440 if (rpip->cmpl) {
14441 emlxs_rpi_deferred_cmpl(port, rpip, 1);
14442 }
14443
14444 rpip->cmpl = cmpl;
14445 }
14446
14447 if ((rpip->RPI == FABRIC_RPI) ||
14448 (hba->flag & FC_PT_TO_PT)) {
14449 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14450 "rpi_online_notify:%d %s. %s. Login cmpl.",
14451 rpip->RPI,
14452 emlxs_rpi_state_xlate(rpip->state),
14453 ((allocated)? "Allocated":"Updated"));
14454
14455 rval = emlxs_vpi_logi_cmpl_notify(port, rpip);
14456
14457 if (rval && rpip->cmpl) {
14458 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t));
14459 rpip->cmpl = 0;
14460 }
14461
14462 mutex_exit(&EMLXS_FCF_LOCK);
14463 return (rval);
14464 }
14465
14466 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14467 "rpi_online_notify:%d %s. %s. Onlining RPI. >",
14468 rpip->RPI,
14469 emlxs_rpi_state_xlate(rpip->state),
14470 ((allocated)? "Allocated":"Updated"));
14471
14472 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_ONLINE, rpip);
14473
14474 if (rpip->cmpl) {
14475 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14476 "rpi_online_notify:%d %s. Deferred args not completed.",
14477 rpip->RPI,
14478 emlxs_rpi_state_xlate(rpip->state));
14479
14480 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t));
14481 rpip->cmpl = 0;
14482
14483 mutex_exit(&EMLXS_FCF_LOCK);
14484 return (1);
14485 }
14486
14487 mutex_exit(&EMLXS_FCF_LOCK);
14488 return (0);
14489
14490 } /* emlxs_rpi_online_notify() */
14491
14492
14493 extern uint32_t
emlxs_rpi_offline_notify(emlxs_port_t * port,RPIobj_t * rpip,void * arg1,void * arg2,void * arg3)14494 emlxs_rpi_offline_notify(emlxs_port_t *port, RPIobj_t *rpip,
14495 void *arg1, void *arg2, void *arg3)
14496 {
14497 emlxs_hba_t *hba = HBA;
14498 emlxs_deferred_cmpl_t *cmpl;
14499
14500 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
14501 return (1);
14502 }
14503
14504 if (!rpip) {
14505 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14506 "rpi_offline_notify: No RPI provided.");
14507 return (1);
14508 }
14509
14510 /* Fabric RPI will be handled automatically */
14511 if (rpip->RPI == FABRIC_RPI) {
14512 return (1);
14513 }
14514
14515 mutex_enter(&EMLXS_FCF_LOCK);
14516
14517 if (arg1 || arg2 || arg3) {
14518 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc(
14519 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP);
14520
14521 cmpl->port = port;
14522 cmpl->arg1 = arg1;
14523 cmpl->arg2 = arg2;
14524 cmpl->arg3 = arg3;
14525
14526 rpip->cmpl = cmpl;
14527 }
14528
14529 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14530 "rpi_offline_notify:%d %s. Offlining RPI. >",
14531 rpip->RPI,
14532 emlxs_rpi_state_xlate(rpip->state));
14533
14534 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE, rpip);
14535
14536 if (rpip->cmpl) {
14537 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14538 "rpi_offline_notify:%d %s. Deferred args not completed.",
14539 rpip->RPI,
14540 emlxs_rpi_state_xlate(rpip->state));
14541
14542 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t));
14543 rpip->cmpl = 0;
14544
14545 mutex_exit(&EMLXS_FCF_LOCK);
14546 return (1);
14547 }
14548
14549 mutex_exit(&EMLXS_FCF_LOCK);
14550
14551 return (0);
14552
14553 } /* emlxs_rpi_offline_notify() */
14554
14555
14556 extern uint32_t
emlxs_rpi_resume_notify(emlxs_port_t * port,RPIobj_t * rpip,emlxs_buf_t * sbp)14557 emlxs_rpi_resume_notify(emlxs_port_t *port, RPIobj_t *rpip, emlxs_buf_t *sbp)
14558 {
14559 emlxs_hba_t *hba = HBA;
14560 emlxs_deferred_cmpl_t *cmpl;
14561
14562 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
14563 return (1);
14564 }
14565
14566 if (!rpip) {
14567 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14568 "rpi_resume_notify: No RPI provided.");
14569 return (1);
14570 }
14571
14572 /* Fabric RPI will be handled automatically */
14573 if (rpip->RPI == FABRIC_RPI) {
14574 return (1);
14575 }
14576
14577 mutex_enter(&EMLXS_FCF_LOCK);
14578
14579 if (rpip->state != RPI_STATE_PAUSED) {
14580 mutex_exit(&EMLXS_FCF_LOCK);
14581 return (1);
14582 }
14583
14584 if (sbp) {
14585 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc(
14586 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP);
14587
14588 cmpl->port = port;
14589 cmpl->arg1 = (void *)sbp;
14590 cmpl->arg2 = 0;
14591 cmpl->arg3 = 0;
14592
14593 rpip->cmpl = cmpl;
14594 }
14595
14596 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14597 "rpi_resume_notify:%d %s. Resuming RPI. >",
14598 rpip->RPI,
14599 emlxs_rpi_state_xlate(rpip->state));
14600
14601 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_RESUME, rpip);
14602
14603 if (rpip->cmpl) {
14604 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14605 "rpi_resume_notify:%d %s. Deferred args not completed.",
14606 rpip->RPI,
14607 emlxs_rpi_state_xlate(rpip->state));
14608
14609 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t));
14610 rpip->cmpl = 0;
14611
14612 mutex_exit(&EMLXS_FCF_LOCK);
14613 return (1);
14614 }
14615
14616 mutex_exit(&EMLXS_FCF_LOCK);
14617
14618 return (0);
14619
14620 } /* emlxs_rpi_resume_notify() */
14621
14622
14623 /*ARGSUSED*/
14624 static uint32_t
emlxs_rpi_free_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)14625 emlxs_rpi_free_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
14626 void *arg1)
14627 {
14628 emlxs_hba_t *hba = HBA;
14629 XRIobj_t *xrip;
14630 XRIobj_t *next_xrip;
14631
14632 if (rpip->state != RPI_STATE_FREE) {
14633 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14634 "rpi_free_action:%d %s:%s arg=%p. "
14635 "Invalid state. <",
14636 rpip->RPI,
14637 emlxs_rpi_state_xlate(rpip->state),
14638 emlxs_fcf_event_xlate(evt), arg1);
14639 return (1);
14640 }
14641
14642 if (rpip->cmpl) {
14643 emlxs_rpi_deferred_cmpl(port, rpip, 1);
14644 }
14645
14646 if (rpip->vpip->p2p_rpip == rpip) {
14647 rpip->vpip->p2p_rpip = NULL;
14648 }
14649
14650 /* Break node/RPI binding */
14651 rw_enter(&port->node_rwlock, RW_WRITER);
14652 if (rpip->node) {
14653 rpip->node->rpip = NULL;
14654 rpip->node = NULL;
14655 }
14656 rw_exit(&port->node_rwlock);
14657
14658 /* Remove all XRIs under this RPI */
14659 mutex_enter(&EMLXS_FCTAB_LOCK);
14660 xrip = (XRIobj_t *)hba->sli.sli4.XRIinuse_f;
14661 while (xrip != (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) {
14662 next_xrip = xrip->_f;
14663 if (xrip->rpip == rpip) {
14664 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14665 "rpi_free_action:%d xri_count=%d. "
14666 "Removing XRI:%d iotag:%d.",
14667 rpip->RPI,
14668 rpip->xri_count,
14669 xrip->XRI, xrip->iotag);
14670
14671 rpip->xri_count--;
14672 xrip->rpip = NULL;
14673 }
14674
14675 if (xrip->reserved_rpip == rpip) {
14676 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14677 "rpi_free_action:%d xri_count=%d. "
14678 "Removing XRI:%d iotag:%d.",
14679 rpip->RPI,
14680 rpip->xri_count,
14681 xrip->XRI, xrip->iotag);
14682
14683 rpip->xri_count--;
14684 xrip->reserved_rpip = NULL;
14685 }
14686
14687 xrip = next_xrip;
14688 }
14689 mutex_exit(&EMLXS_FCTAB_LOCK);
14690
14691 if (rpip->xri_count) {
14692 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14693 "rpi_free_action:%d. xri_count=%d",
14694 rpip->RPI,
14695 rpip->xri_count);
14696 }
14697
14698 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14699 "rpi_free_action:%d flag=%x. RPI freed. <",
14700 rpip->RPI,
14701 rpip->flag);
14702
14703 rpip->flag = 0;
14704
14705 return (0);
14706
14707 } /* emlxs_rpi_free_action() */
14708
14709
14710 /*ARGSUSED*/
14711 static uint32_t
emlxs_rpi_online_evt_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)14712 emlxs_rpi_online_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
14713 void *arg1)
14714 {
14715 uint32_t rval = 1;
14716
14717 if (evt != FCF_EVENT_RPI_ONLINE) {
14718 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14719 "rpi_online_evt_action:%d %s:%s arg=%p. "
14720 "Invalid event type. <",
14721 rpip->RPI,
14722 emlxs_rpi_state_xlate(rpip->state),
14723 emlxs_fcf_event_xlate(evt), arg1);
14724 return (1);
14725 }
14726
14727 switch (rpip->state) {
14728 case RPI_STATE_REG:
14729 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14730 "rpi_online_evt_action:%d flag=%x. Registering.",
14731 rpip->RPI,
14732 rpip->flag);
14733
14734 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG,
14735 FCF_REASON_REENTER, evt, arg1);
14736 break;
14737
14738 default:
14739 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14740 "rpi_online_evt_action:%d flag=%x. Registering.",
14741 rpip->RPI,
14742 rpip->flag);
14743
14744 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG,
14745 FCF_REASON_EVENT, evt, arg1);
14746 break;
14747 }
14748
14749 return (rval);
14750
14751 } /* emlxs_rpi_online_evt_action() */
14752
14753
14754 /*ARGSUSED*/
14755 static uint32_t
emlxs_rpi_offline_evt_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)14756 emlxs_rpi_offline_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
14757 void *arg1)
14758 {
14759 uint32_t rval = 1;
14760
14761 if (evt != FCF_EVENT_RPI_OFFLINE) {
14762 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14763 "rpi_offline_evt_action:%d %s:%s arg=%p. "
14764 "Invalid event type. <",
14765 rpip->RPI,
14766 emlxs_rpi_state_xlate(rpip->state),
14767 emlxs_fcf_event_xlate(evt), arg1);
14768 return (1);
14769 }
14770
14771 switch (rpip->state) {
14772 case RPI_STATE_RESERVED:
14773 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14774 "rpi_offline_evt_action:%d flag=%x. Freeing RPI.",
14775 rpip->RPI,
14776 rpip->flag);
14777
14778 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE,
14779 FCF_REASON_EVENT, evt, arg1);
14780 break;
14781
14782 case RPI_STATE_UNREG:
14783 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14784 "rpi_offline_evt_action:%d flag=%x. "
14785 "Already unregistering. <",
14786 rpip->RPI,
14787 rpip->flag);
14788
14789 break;
14790
14791 default:
14792 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14793 "rpi_offline_evt_action:%d flag=%x. Unregistering.",
14794 rpip->RPI,
14795 rpip->flag);
14796
14797 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG,
14798 FCF_REASON_EVENT, evt, arg1);
14799 break;
14800
14801 }
14802
14803 return (rval);
14804
14805 } /* emlxs_rpi_offline_evt_action() */
14806
14807
14808 /*ARGSUSED*/
14809 static uint32_t
emlxs_rpi_pause_evt_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)14810 emlxs_rpi_pause_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
14811 void *arg1)
14812 {
14813 VPIobj_t *vpip;
14814 uint32_t rval = 1;
14815
14816 vpip = rpip->vpip;
14817
14818 if (evt != FCF_EVENT_RPI_PAUSE) {
14819 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14820 "rpi_pause_evt_action:%d %s:%s arg=%p flag=%x. "
14821 "Invalid event type. <",
14822 rpip->RPI,
14823 emlxs_rpi_state_xlate(rpip->state),
14824 emlxs_fcf_event_xlate(evt), arg1,
14825 rpip->flag);
14826 return (1);
14827 }
14828
14829 switch (rpip->state) {
14830 case RPI_STATE_RESERVED:
14831 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14832 "rpi_pause_evt_action:%d flag=%x. Freeing RPI.",
14833 rpip->RPI,
14834 rpip->flag);
14835
14836 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE,
14837 FCF_REASON_EVENT, evt, arg1);
14838 break;
14839
14840 case RPI_STATE_UNREG:
14841 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14842 "rpi_pause_evt_action:%d flag=%x. Not online. <",
14843 rpip->RPI,
14844 rpip->flag);
14845
14846 break;
14847
14848 case RPI_STATE_PAUSED:
14849 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14850 "rpi_pause_evt_action:%d flag=%x. Already paused. <",
14851 rpip->RPI,
14852 rpip->flag);
14853
14854 break;
14855
14856 case RPI_STATE_REG:
14857 case RPI_STATE_ONLINE:
14858 case RPI_STATE_RESUME:
14859 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14860 "rpi_pause_evt_action:%d flag=%x. Pausing.",
14861 rpip->RPI,
14862 rpip->flag);
14863
14864 /* Don't pause an RPI, if the VPI is not pausing too */
14865 if (!(vpip->flag & EMLXS_VPI_PAUSE_REQ)) {
14866 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14867 "rpi_pause_evt_action:%d rpi_online=%d,%d "
14868 "xri_count=%d. VPI:%d pause not requested. "
14869 "Unregistering.", rpip->RPI,
14870 vpip->rpi_online, vpip->rpi_paused,
14871 rpip->xri_count, vpip->VPI);
14872
14873 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG,
14874 FCF_REASON_EVENT, evt, arg1);
14875 break;
14876 }
14877
14878 rval = emlxs_rpi_state(port, rpip, RPI_STATE_PAUSED,
14879 FCF_REASON_EVENT, evt, arg1);
14880 break;
14881
14882 default:
14883 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14884 "rpi_pause_evt_action:%d flag=%x. <",
14885 rpip->RPI,
14886 rpip->flag);
14887 break;
14888 }
14889
14890 return (rval);
14891
14892 } /* emlxs_rpi_pause_evt_action() */
14893
14894
14895 /*ARGSUSED*/
14896 static uint32_t
emlxs_rpi_resume_evt_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)14897 emlxs_rpi_resume_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
14898 void *arg1)
14899 {
14900 uint32_t rval = 1;
14901
14902 if (evt != FCF_EVENT_RPI_RESUME) {
14903 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
14904 "rpi_resume_evt_action:%d %s:%s arg=%p flag=%x. "
14905 "Invalid event type. <",
14906 rpip->RPI,
14907 emlxs_rpi_state_xlate(rpip->state),
14908 emlxs_fcf_event_xlate(evt), arg1,
14909 rpip->flag);
14910 return (1);
14911 }
14912
14913 switch (rpip->state) {
14914 case RPI_STATE_PAUSED:
14915 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14916 "rpi_resume_evt_action:%d flag=%x. Resuming.",
14917 rpip->RPI,
14918 rpip->flag);
14919
14920 rval = emlxs_rpi_state(port, rpip, RPI_STATE_RESUME,
14921 FCF_REASON_EVENT, evt, arg1);
14922 break;
14923
14924 default:
14925 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14926 "rpi_resume_evt_action:%d flag=%x. Not paused. <",
14927 rpip->RPI,
14928 rpip->flag);
14929 break;
14930 }
14931
14932 return (rval);
14933
14934 } /* emlxs_rpi_resume_evt_action() */
14935
14936
14937 /*ARGSUSED*/
14938 static uint32_t
emlxs_rpi_reserved_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)14939 emlxs_rpi_reserved_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
14940 void *arg1)
14941 {
14942 VPIobj_t *vpip;
14943
14944 vpip = rpip->vpip;
14945
14946 if (rpip->state != RPI_STATE_RESERVED) {
14947 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14948 "rpi_reserved_action:%d %s:%s arg=%p. "
14949 "Invalid state. <",
14950 rpip->RPI,
14951 emlxs_rpi_state_xlate(rpip->state),
14952 emlxs_fcf_event_xlate(evt), arg1);
14953 return (1);
14954 }
14955
14956 if (rpip->prev_state != RPI_STATE_FREE) {
14957 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14958 "rpi_reserved_action:%d %s:%s arg=%p. "
14959 "Invalid previous state. %s <",
14960 rpip->RPI,
14961 emlxs_rpi_state_xlate(rpip->state),
14962 emlxs_fcf_event_xlate(evt), arg1,
14963 emlxs_rpi_state_xlate(rpip->prev_state));
14964
14965 return (1);
14966 }
14967
14968 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14969 "rpi_reserved_action:%d rpi_online=%d,%d. <",
14970 rpip->RPI,
14971 vpip->rpi_online, vpip->rpi_paused);
14972
14973 return (0);
14974
14975 } /* emlxs_rpi_reserved_action() */
14976
14977
14978 /*ARGSUSED*/
14979 static uint32_t
emlxs_rpi_offline_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)14980 emlxs_rpi_offline_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
14981 void *arg1)
14982 {
14983 uint32_t rval = 0;
14984 VPIobj_t *vpip;
14985
14986 vpip = rpip->vpip;
14987
14988 if (rpip->state != RPI_STATE_OFFLINE) {
14989 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
14990 "rpi_offline_action:%d %s:%s arg=%p. "
14991 "Invalid state. <",
14992 rpip->RPI,
14993 emlxs_rpi_state_xlate(rpip->state),
14994 emlxs_fcf_event_xlate(evt), arg1);
14995 return (1);
14996 }
14997
14998 if (rpip->flag & EMLXS_RPI_PAUSED) {
14999 rpip->flag &= ~EMLXS_RPI_PAUSED;
15000
15001 if (vpip->rpi_paused) {
15002 vpip->rpi_paused--;
15003 }
15004 }
15005
15006 if (rpip->flag & EMLXS_RPI_VPI) {
15007 rpip->flag &= ~EMLXS_RPI_VPI;
15008
15009 if (vpip->rpi_online) {
15010 vpip->rpi_online--;
15011 }
15012
15013 /* Added protection */
15014 if (vpip->rpi_online < vpip->rpi_paused) {
15015 vpip->rpi_paused = vpip->rpi_online;
15016 }
15017 }
15018
15019 if (rpip->RPI == FABRIC_RPI) {
15020 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15021 "rpi_offline_action:%d rpi_online=%d,%d xri_count=%d. "
15022 "Fabric RPI offline. Freeing.",
15023 rpip->RPI,
15024 vpip->rpi_online, vpip->rpi_paused,
15025 rpip->xri_count);
15026
15027 /* Free RPI */
15028 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 0, 0, 0);
15029
15030 return (rval);
15031 }
15032
15033 if ((vpip->rpi_online == 0) ||
15034 (vpip->rpi_online == vpip->rpi_paused)) {
15035 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15036 "rpi_offline_action:%d rpi_online=%d,%d xri_count=%d. "
15037 "RPI offline. "
15038 "Notifying VPI:%d >",
15039 rpip->RPI,
15040 vpip->rpi_online, vpip->rpi_paused,
15041 rpip->xri_count,
15042 vpip->VPI);
15043
15044 /* Notify VPI */
15045 (void) emlxs_vpi_event(port, FCF_EVENT_RPI_OFFLINE, rpip);
15046
15047 } else {
15048 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15049 "rpi_offline_action:%d rpi_online=%d,%d xri_count=%d. "
15050 "RPI offline. Freeing.",
15051 rpip->RPI,
15052 vpip->rpi_online, vpip->rpi_paused,
15053 rpip->xri_count);
15054 }
15055
15056 /* Free RPI */
15057 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 0, 0, 0);
15058
15059 return (rval);
15060
15061 } /* emlxs_rpi_offline_action() */
15062
15063
15064 /*ARGSUSED*/
15065 static uint32_t
emlxs_rpi_paused_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)15066 emlxs_rpi_paused_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
15067 void *arg1)
15068 {
15069 VPIobj_t *vpip;
15070 uint32_t rval = 0;
15071
15072 vpip = rpip->vpip;
15073
15074 if (rpip->state != RPI_STATE_PAUSED) {
15075 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15076 "rpi_paused_action:%d %s:%s arg=%p. "
15077 "Invalid state. <",
15078 rpip->RPI,
15079 emlxs_rpi_state_xlate(rpip->state),
15080 emlxs_fcf_event_xlate(evt), arg1);
15081 return (1);
15082 }
15083
15084 if (!(vpip->flag & EMLXS_VPI_PAUSE_REQ)) {
15085 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15086 "rpi_paused_action:%d rpi_online=%d,%d xri_count=%d. "
15087 "VPI:%d pause not requested. Unregistering.",
15088 rpip->RPI,
15089 vpip->rpi_online, vpip->rpi_paused,
15090 rpip->xri_count,
15091 vpip->VPI);
15092
15093 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG,
15094 FCF_REASON_EVENT, evt, arg1);
15095 return (rval);
15096 }
15097
15098 if (!(rpip->flag & EMLXS_RPI_PAUSED)) {
15099 rpip->flag |= EMLXS_RPI_PAUSED;
15100 vpip->rpi_paused++;
15101 }
15102
15103 /* Check if all RPI's have been paused for a VPI */
15104 if (vpip->rpi_online == vpip->rpi_paused) {
15105 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15106 "rpi_paused_action:%d rpi_online=%d,%d xri_count=%d. "
15107 "RPI paused. "
15108 "Notifying VPI:%d >",
15109 rpip->RPI,
15110 vpip->rpi_online, vpip->rpi_paused,
15111 rpip->xri_count,
15112 vpip->VPI);
15113
15114 /* Notify VPI */
15115 (void) emlxs_vpi_event(port, FCF_EVENT_RPI_PAUSE, rpip);
15116
15117 } else {
15118 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15119 "rpi_paused_action:%d rpi_online=%d,%d xri_count=%d. "
15120 "RPI paused. <",
15121 rpip->RPI,
15122 vpip->rpi_online, vpip->rpi_paused,
15123 rpip->xri_count);
15124 }
15125
15126 return (0);
15127
15128 } /* emlxs_rpi_paused_action() */
15129
15130
15131 /*ARGSUSED*/
15132 static uint32_t
emlxs_rpi_unreg_failed_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)15133 emlxs_rpi_unreg_failed_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
15134 void *arg1)
15135 {
15136 uint32_t rval = 0;
15137
15138 rpip->attempts++;
15139
15140 if (rpip->state != RPI_STATE_UNREG_FAILED) {
15141 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
15142 "rpi_unreg_failed_action:%d %s:%s arg=%p attempt=%d. "
15143 "Invalid state. <",
15144 rpip->RPI,
15145 emlxs_rpi_state_xlate(rpip->state),
15146 emlxs_fcf_event_xlate(evt), arg1,
15147 rpip->attempts);
15148 return (1);
15149 }
15150
15151 if ((rpip->reason == FCF_REASON_SEND_FAILED) ||
15152 !(rpip->flag & EMLXS_RPI_REG)) {
15153
15154 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15155 "rpi_unreg_failed_action:%d reason=%x flag=%x. "
15156 "Going offline.",
15157 rpip->RPI,
15158 rpip->reason,
15159 rpip->flag);
15160
15161 rpip->flag &= ~EMLXS_RPI_REG;
15162
15163 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE,
15164 FCF_REASON_OP_FAILED, rpip->attempts, arg1);
15165 } else {
15166 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15167 "rpi_unreg_failed_action:%d flag=%x. Going online.",
15168 rpip->RPI,
15169 rpip->flag);
15170
15171 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE,
15172 FCF_REASON_OP_FAILED, rpip->attempts, arg1);
15173 }
15174
15175 return (rval);
15176
15177 } /* emlxs_rpi_unreg_failed_action() */
15178
15179
15180 static void
emlxs_rpi_unreg_handler(emlxs_port_t * port,RPIobj_t * rpip)15181 emlxs_rpi_unreg_handler(emlxs_port_t *port, RPIobj_t *rpip)
15182 {
15183 emlxs_hba_t *hba = HBA;
15184 VPIobj_t *vpip = rpip->vpip;
15185 emlxs_node_t *node = rpip->node;
15186 XRIobj_t *xrip;
15187 XRIobj_t *next_xrip;
15188
15189 /* Special handling for Fabric RPI */
15190 if (rpip->RPI == FABRIC_RPI) {
15191 if (node) {
15192 (void) emlxs_tx_node_flush(port, node, 0, 0, 0);
15193 (void) emlxs_chipq_node_flush(port, 0, node, 0);
15194 }
15195
15196 /* Clear all reserved XRIs under this RPI */
15197 mutex_enter(&EMLXS_FCTAB_LOCK);
15198 xrip = (XRIobj_t *)hba->sli.sli4.XRIinuse_f;
15199 while (xrip != (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) {
15200 next_xrip = xrip->_f;
15201 /* We don't need to worry about xrip->reserved_rpip */
15202 /* here because the Fabric RPI can never be reserved */
15203 /* by an xri. */
15204 if ((xrip->rpip == rpip) &&
15205 (xrip->flag & EMLXS_XRI_RESERVED)) {
15206 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15207 "rpi_unreg_handler:%d xri_count=%d. "
15208 "Unreserving XRI:%d iotag:%d.",
15209 rpip->RPI,
15210 rpip->xri_count,
15211 xrip->XRI, xrip->iotag);
15212
15213 (void) emlxs_sli4_unreserve_xri(port,
15214 xrip->XRI, 0);
15215 }
15216 xrip = next_xrip;
15217 }
15218 mutex_exit(&EMLXS_FCTAB_LOCK);
15219 }
15220
15221 rpip->flag &= ~EMLXS_RPI_REG;
15222
15223 if (rpip->flag & EMLXS_RPI_PAUSED) {
15224 rpip->flag &= ~EMLXS_RPI_PAUSED;
15225
15226 if (vpip->rpi_paused) {
15227 vpip->rpi_paused--;
15228 }
15229 }
15230
15231 if (rpip->flag & EMLXS_RPI_VPI) {
15232 rpip->flag &= ~EMLXS_RPI_VPI;
15233
15234 if (vpip->rpi_online) {
15235 vpip->rpi_online--;
15236 }
15237
15238 /* Added protection */
15239 if (vpip->rpi_online < vpip->rpi_paused) {
15240 vpip->rpi_paused = vpip->rpi_online;
15241 }
15242 }
15243
15244 rw_enter(&port->node_rwlock, RW_WRITER);
15245 if (node) {
15246 rpip->node = NULL;
15247 node->rpip = NULL;
15248 }
15249 rw_exit(&port->node_rwlock);
15250
15251 if (node) {
15252 emlxs_node_rm(port, node);
15253 }
15254
15255 return;
15256
15257 } /* emlxs_rpi_unreg_handler() */
15258
15259
15260 /*ARGSUSED*/
15261 static uint32_t
emlxs_rpi_unreg_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)15262 emlxs_rpi_unreg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
15263 {
15264 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
15265 MAILBOX4 *mb4;
15266 RPIobj_t *rpip;
15267
15268 mutex_enter(&EMLXS_FCF_LOCK);
15269
15270 rpip = (RPIobj_t *)mbq->context;
15271
15272 mb4 = (MAILBOX4 *)mbq;
15273
15274 if (rpip->state != RPI_STATE_UNREG) {
15275 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15276 "rpi_unreg_mbcmpl:%d state=%s. "
15277 "No longer in RPI_STATE_UNREG.",
15278 rpip->RPI,
15279 emlxs_rpi_state_xlate(rpip->state));
15280
15281 mutex_exit(&EMLXS_FCF_LOCK);
15282 return (0);
15283 }
15284
15285 if (mb4->mbxStatus) {
15286 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15287 "rpi_unreg_mbcmpl:%d failed. %s. >",
15288 rpip->RPI,
15289 emlxs_mb_xlate_status(mb4->mbxStatus));
15290
15291 (void) emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_FAILED,
15292 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
15293
15294 mutex_exit(&EMLXS_FCF_LOCK);
15295 return (0);
15296 }
15297
15298 emlxs_rpi_unreg_handler(port, rpip);
15299
15300 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15301 "rpi_unreg_mbcmpl:%d Unregistered. Unreg complete. >",
15302 rpip->RPI);
15303
15304 (void) emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_CMPL,
15305 0, 0, 0);
15306
15307 mutex_exit(&EMLXS_FCF_LOCK);
15308 return (0);
15309
15310 } /* emlxs_rpi_unreg_mbcmpl() */
15311
15312
15313 /*ARGSUSED*/
15314 static uint32_t
emlxs_rpi_unreg_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)15315 emlxs_rpi_unreg_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
15316 void *arg1)
15317 {
15318 emlxs_hba_t *hba = HBA;
15319 MAILBOX4 *mb4;
15320 MAILBOXQ *mbq;
15321 uint32_t rval = 0;
15322 VPIobj_t *vpip = rpip->vpip;
15323
15324 if (rpip->state != RPI_STATE_UNREG) {
15325 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
15326 "rpi_unreg_action:%d %s:%s arg=%p. "
15327 "Invalid state. <",
15328 rpip->RPI,
15329 emlxs_rpi_state_xlate(rpip->state),
15330 emlxs_fcf_event_xlate(evt), arg1);
15331 return (1);
15332 }
15333
15334 if (!(rpip->flag & EMLXS_RPI_REG)) {
15335 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15336 "rpi_unreg_action:%d. Not registered. Going offline.",
15337 rpip->RPI);
15338
15339 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE,
15340 FCF_REASON_EVENT, evt, arg1);
15341
15342 return (rval);
15343 }
15344
15345 if (rpip->prev_state != RPI_STATE_UNREG_FAILED) {
15346 rpip->attempts = 0;
15347 }
15348
15349 if (rpip->RPI == FABRIC_RPI) {
15350 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15351 "rpi_unreg_action:%d did=%x vpi=%d. Fabric RPI. "
15352 "Going offline.",
15353 rpip->RPI,
15354 rpip->did,
15355 rpip->vpip->VPI);
15356
15357 /* Don't send UNREG_RPI, but process it as if we did */
15358 emlxs_rpi_unreg_handler(port, rpip);
15359
15360 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE,
15361 FCF_REASON_EVENT, evt, arg1);
15362
15363 return (rval);
15364 }
15365
15366 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15367 "rpi_unreg_action:%d attempts=%d. Sending UNREG_RPI. <",
15368 rpip->RPI,
15369 rpip->attempts);
15370
15371 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
15372
15373 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_FAILED,
15374 FCF_REASON_NO_MBOX, 0, arg1);
15375
15376 return (rval);
15377 }
15378 mb4 = (MAILBOX4*)mbq;
15379 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
15380
15381 mbq->nonembed = NULL;
15382 mbq->mbox_cmpl = emlxs_rpi_unreg_mbcmpl;
15383 mbq->context = (void *)rpip;
15384 mbq->port = (void *)port;
15385
15386 mb4->mbxCommand = MBX_UNREG_RPI;
15387 mb4->mbxOwner = OWN_HOST;
15388 mb4->un.varUnregLogin.rpi = rpip->RPI;
15389 mb4->un.varUnregLogin.vpi = vpip->VPI;
15390
15391 if (rpip->cmpl) {
15392 mbq->sbp = rpip->cmpl->arg1;
15393 mbq->ubp = rpip->cmpl->arg2;
15394 mbq->iocbq = rpip->cmpl->arg3;
15395 }
15396
15397 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
15398 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
15399 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
15400
15401 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_FAILED,
15402 FCF_REASON_SEND_FAILED, rval, arg1);
15403
15404 return (rval);
15405 }
15406
15407 if (rpip->cmpl) {
15408 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t));
15409 rpip->cmpl = 0;
15410 }
15411
15412 return (0);
15413
15414 } /* emlxs_rpi_unreg_action() */
15415
15416
15417 /*ARGSUSED*/
15418 static uint32_t
emlxs_rpi_unreg_cmpl_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)15419 emlxs_rpi_unreg_cmpl_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
15420 void *arg1)
15421 {
15422 uint32_t rval = 0;
15423
15424 if (rpip->state != RPI_STATE_UNREG_CMPL) {
15425 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
15426 "rpi_unreg_cmpl_action:%d %s:%s arg=%p. "
15427 "Invalid state. <",
15428 rpip->RPI,
15429 emlxs_rpi_state_xlate(rpip->state),
15430 emlxs_fcf_event_xlate(evt), arg1);
15431 return (1);
15432 }
15433
15434 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15435 "rpi_unreg_cmpl_action:%d flag=%x. Going offline.",
15436 rpip->RPI,
15437 rpip->flag);
15438
15439 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE,
15440 FCF_REASON_EVENT, evt, arg1);
15441
15442 return (rval);
15443
15444 } /* emlxs_rpi_unreg_cmpl_action() */
15445
15446
15447 /*ARGSUSED*/
15448 static uint32_t
emlxs_rpi_reg_failed_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)15449 emlxs_rpi_reg_failed_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
15450 void *arg1)
15451 {
15452 uint32_t rval = 0;
15453
15454 rpip->attempts++;
15455
15456 if (rpip->state != RPI_STATE_REG_FAILED) {
15457 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
15458 "rpi_reg_failed_action:%d %s:%s arg=%p attempt=%d. "
15459 "Invalid state. <",
15460 rpip->RPI,
15461 emlxs_rpi_state_xlate(rpip->state),
15462 emlxs_fcf_event_xlate(evt), arg1,
15463 rpip->attempts);
15464 return (1);
15465 }
15466
15467 if ((rpip->reason == FCF_REASON_SEND_FAILED) ||
15468 !(rpip->flag & EMLXS_RPI_REG)) {
15469 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15470 "rpi_reg_failed_action:%d reason=%x flag=%x. "
15471 "Going offline.",
15472 rpip->RPI,
15473 rpip->reason,
15474 rpip->flag);
15475
15476 rpip->flag &= ~EMLXS_RPI_REG;
15477
15478 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE,
15479 FCF_REASON_OP_FAILED, rpip->attempts, arg1);
15480 } else {
15481 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15482 "rpi_reg_failed_action:%d flag=%x. Unregistering",
15483 rpip->RPI,
15484 rpip->flag);
15485
15486 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG,
15487 FCF_REASON_OP_FAILED, rpip->attempts, arg1);
15488 }
15489
15490 return (rval);
15491
15492 } /* emlxs_rpi_reg_failed_action() */
15493
15494
15495 static uint32_t
emlxs_rpi_reg_handler(emlxs_port_t * port,RPIobj_t * rpip)15496 emlxs_rpi_reg_handler(emlxs_port_t *port, RPIobj_t *rpip)
15497 {
15498 emlxs_hba_t *hba = HBA;
15499 VPIobj_t *vpip;
15500 emlxs_node_t *node;
15501
15502 vpip = rpip->vpip;
15503
15504 rpip->flag |= EMLXS_RPI_REG;
15505
15506 if (rpip->flag & EMLXS_RPI_PAUSED) {
15507 rpip->flag &= ~EMLXS_RPI_PAUSED;
15508
15509 if (vpip->rpi_paused) {
15510 vpip->rpi_paused--;
15511 }
15512 }
15513
15514 if (!(rpip->flag & EMLXS_RPI_VPI) && (rpip->RPI != FABRIC_RPI)) {
15515 rpip->flag |= EMLXS_RPI_VPI;
15516 vpip->rpi_online++;
15517 }
15518
15519 /* If private loop and this is fabric RPI, then exit now */
15520 if (!(hba->flag & FC_FABRIC_ATTACHED) && (rpip->RPI == FABRIC_RPI)) {
15521 return (0);
15522 }
15523
15524 /* Create or update the node */
15525 node = emlxs_node_create(port, rpip->did, rpip->RPI, &rpip->sparam);
15526
15527 if (!node) {
15528 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15529 "rpi_reg_handler:%d. Node create failed. Reg failed.",
15530 rpip->RPI);
15531
15532 return (FCF_REASON_NO_NODE);
15533 }
15534
15535 return (0);
15536
15537 } /* emlxs_rpi_reg_handler() */
15538
15539
15540 /*ARGSUSED*/
15541 static uint32_t
emlxs_rpi_reg_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)15542 emlxs_rpi_reg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
15543 {
15544 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
15545 MAILBOX4 *mb4;
15546 RPIobj_t *rpip;
15547 emlxs_node_t *node;
15548 uint32_t rval = 0;
15549
15550 mutex_enter(&EMLXS_FCF_LOCK);
15551
15552 rpip = (RPIobj_t *)mbq->context;
15553 mb4 = (MAILBOX4 *)mbq;
15554
15555 if (rpip->state != RPI_STATE_REG) {
15556 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15557 "rpi_reg_mbcmpl:%d state=%s. No longer in RPI_STATE_REG.",
15558 rpip->RPI,
15559 emlxs_rpi_state_xlate(rpip->state));
15560
15561 mutex_exit(&EMLXS_FCF_LOCK);
15562 return (0);
15563 }
15564
15565 if (mb4->mbxStatus) {
15566 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15567 "rpi_reg_mbcmpl:%d failed. %s. >",
15568 rpip->RPI,
15569 emlxs_mb_xlate_status(mb4->mbxStatus));
15570
15571 (void) emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED,
15572 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0);
15573
15574 mutex_exit(&EMLXS_FCF_LOCK);
15575 return (0);
15576 }
15577
15578 rval = emlxs_rpi_reg_handler(port, rpip);
15579
15580 if (rval) {
15581 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15582 "rpi_reg_mbcmpl:%d. Reg failed. >",
15583 rpip->RPI);
15584
15585 mb4->mbxStatus = MBX_FAILURE;
15586
15587 (void) emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED,
15588 rval, 0, 0);
15589
15590 mutex_exit(&EMLXS_FCF_LOCK);
15591 return (0);
15592 }
15593
15594 node = rpip->node;
15595
15596 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15597 "rpi_reg_mbcmpl:%d Registered. Reg complete. >",
15598 rpip->RPI);
15599
15600 (void) emlxs_rpi_state(port, rpip, RPI_STATE_REG_CMPL, 0, 0, 0);
15601
15602 mutex_exit(&EMLXS_FCF_LOCK);
15603
15604 /* Needed for FCT trigger in emlxs_mb_deferred_cmpl */
15605 if (mbq->sbp) {
15606 ((emlxs_buf_t *)mbq->sbp)->node = node;
15607 }
15608
15609 #ifdef DHCHAP_SUPPORT
15610 if (mbq->sbp || mbq->ubp) {
15611 if (emlxs_dhc_auth_start(port, node, (uint8_t *)mbq->sbp,
15612 (uint8_t *)mbq->ubp) == 0) {
15613 /* Auth started - auth completion will */
15614 /* handle sbp and ubp now */
15615 mbq->sbp = NULL;
15616 mbq->ubp = NULL;
15617 }
15618 }
15619 #endif /* DHCHAP_SUPPORT */
15620
15621 return (0);
15622
15623 } /* emlxs_rpi_reg_mbcmpl() */
15624
15625
15626 /*ARGSUSED*/
15627 static uint32_t
emlxs_rpi_reg_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)15628 emlxs_rpi_reg_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
15629 void *arg1)
15630 {
15631 emlxs_hba_t *hba = HBA;
15632 MAILBOX4 *mb4;
15633 MAILBOXQ *mbq;
15634 MATCHMAP *mp;
15635 uint32_t rval = 0;
15636
15637 if (rpip->state != RPI_STATE_REG) {
15638 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
15639 "rpi_reg_action:%d %s:%s arg=%p. "
15640 "Invalid state. <",
15641 rpip->RPI,
15642 emlxs_rpi_state_xlate(rpip->state),
15643 emlxs_fcf_event_xlate(evt), arg1);
15644 return (1);
15645 }
15646
15647 if (rpip->RPI == FABRIC_RPI) {
15648 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15649 "rpi_reg_action:%d did=%x vpi=%d. Fabric RPI. "
15650 "Going online.",
15651 rpip->RPI,
15652 rpip->did,
15653 rpip->vpip->VPI);
15654
15655 /* Don't send REG_RPI, but process it as if we did */
15656 rval = emlxs_rpi_reg_handler(port, rpip);
15657
15658 if (rval) {
15659 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED,
15660 rval, 0, 0);
15661
15662 return (rval);
15663 }
15664
15665 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE,
15666 FCF_REASON_EVENT, evt, arg1);
15667
15668 return (rval);
15669 }
15670
15671 if (rpip->prev_state != RPI_STATE_REG_FAILED) {
15672 rpip->attempts = 0;
15673 }
15674
15675 if (rpip->flag & EMLXS_RPI_REG) {
15676 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15677 "rpi_reg_action:%d attempts=%d. "
15678 "Updating REG_RPI. <",
15679 rpip->RPI,
15680 rpip->attempts);
15681 } else {
15682 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15683 "rpi_reg_action:%d attempts=%d. "
15684 "Sending REG_RPI. <",
15685 rpip->RPI,
15686 rpip->attempts);
15687 }
15688
15689 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
15690
15691 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED,
15692 FCF_REASON_NO_MBOX, 0, arg1);
15693
15694 return (rval);
15695 }
15696
15697 mb4 = (MAILBOX4*)mbq;
15698 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
15699
15700 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
15701 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
15702
15703 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED,
15704 FCF_REASON_NO_BUFFER, 0, arg1);
15705
15706 return (rval);
15707 }
15708
15709 mbq->bp = (void *)mp;
15710 mbq->nonembed = NULL;
15711
15712 mbq->mbox_cmpl = emlxs_rpi_reg_mbcmpl;
15713 mbq->context = (void *)rpip;
15714 mbq->port = (void *)port;
15715
15716 mb4->mbxCommand = MBX_REG_RPI;
15717 mb4->mbxOwner = OWN_HOST;
15718
15719 mb4->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
15720 mb4->un.varRegLogin.un.sp64.addrHigh = PADDR_HI(mp->phys);
15721 mb4->un.varRegLogin.un.sp64.addrLow = PADDR_LO(mp->phys);
15722 mb4->un.varRegLogin.did = rpip->did;
15723 mb4->un.varWords[30] = 0; /* flags */
15724
15725 mb4->un.varRegLogin.vpi = rpip->vpip->VPI;
15726 mb4->un.varRegLogin.rpi = rpip->RPI;
15727 mb4->un.varRegLogin.update = (rpip->flag & EMLXS_RPI_REG)? 1:0;
15728
15729 bcopy((void *)&rpip->sparam, (void *)mp->virt, sizeof (SERV_PARM));
15730
15731 if (rpip->cmpl) {
15732 mbq->sbp = rpip->cmpl->arg1;
15733 mbq->ubp = rpip->cmpl->arg2;
15734 mbq->iocbq = rpip->cmpl->arg3;
15735 }
15736
15737 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
15738 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
15739 emlxs_mem_put(hba, MEM_BUF, (void *)mp);
15740 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
15741
15742 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED,
15743 FCF_REASON_SEND_FAILED, rval, arg1);
15744
15745 return (rval);
15746 }
15747
15748 if (rpip->cmpl) {
15749 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t));
15750 rpip->cmpl = 0;
15751 }
15752
15753 return (0);
15754
15755 } /* emlxs_rpi_reg_action() */
15756
15757
15758 /*ARGSUSED*/
15759 static uint32_t
emlxs_rpi_reg_cmpl_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)15760 emlxs_rpi_reg_cmpl_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
15761 void *arg1)
15762 {
15763 uint32_t rval = 0;
15764
15765 if (rpip->state != RPI_STATE_REG_CMPL) {
15766 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
15767 "rpi_reg_cmpl_action:%d %s:%s arg=%p. "
15768 "Invalid state. <",
15769 rpip->RPI,
15770 emlxs_rpi_state_xlate(rpip->state),
15771 emlxs_fcf_event_xlate(evt), arg1);
15772 return (1);
15773 }
15774
15775 if (rpip->flag & EMLXS_RPI_REG) {
15776 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15777 "rpi_reg_cmpl_action:%d flag=%x. Going online.",
15778 rpip->RPI,
15779 rpip->flag);
15780
15781 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE,
15782 FCF_REASON_EVENT, evt, arg1);
15783 } else {
15784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15785 "rpi_reg_cmpl_action:%d flag=%x. Going offline.",
15786 rpip->RPI,
15787 rpip->flag);
15788
15789 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE,
15790 FCF_REASON_OP_FAILED, rpip->attempts, arg1);
15791 }
15792
15793 return (rval);
15794
15795 } /* emlxs_rpi_reg_cmpl_action() */
15796
15797
15798 /*ARGSUSED*/
15799 static uint32_t
emlxs_rpi_resume_failed_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)15800 emlxs_rpi_resume_failed_action(emlxs_port_t *port, RPIobj_t *rpip,
15801 uint32_t evt, void *arg1)
15802 {
15803 uint32_t rval = 0;
15804
15805 rpip->attempts++;
15806
15807 if (rpip->state != RPI_STATE_RESUME_FAILED) {
15808 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
15809 "rpi_resume_failed_action:%d %s:%s arg=%p attempt=%d. "
15810 "Invalid state. <",
15811 rpip->RPI,
15812 emlxs_rpi_state_xlate(rpip->state),
15813 emlxs_fcf_event_xlate(evt), arg1,
15814 rpip->attempts);
15815 return (1);
15816 }
15817
15818 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15819 "rpi_resume_failed_action:%d attempt=%d. Unregistering.",
15820 rpip->RPI,
15821 rpip->attempts);
15822
15823 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG,
15824 FCF_REASON_OP_FAILED, rpip->attempts, arg1);
15825
15826 return (rval);
15827
15828 } /* emlxs_rpi_resume_failed_action() */
15829
15830
15831 /*ARGSUSED*/
15832 static void
emlxs_rpi_resume_handler(emlxs_port_t * port,RPIobj_t * rpip)15833 emlxs_rpi_resume_handler(emlxs_port_t *port, RPIobj_t *rpip)
15834 {
15835 if (rpip->flag & EMLXS_RPI_PAUSED) {
15836 rpip->flag &= ~EMLXS_RPI_PAUSED;
15837
15838 if (rpip->vpip->rpi_paused) {
15839 rpip->vpip->rpi_paused--;
15840 }
15841 }
15842
15843 return;
15844
15845 } /* emlxs_rpi_resume_handler() */
15846
15847
15848 /*ARGSUSED*/
15849 static uint32_t
emlxs_rpi_resume_mbcmpl(emlxs_hba_t * hba,MAILBOXQ * mbq)15850 emlxs_rpi_resume_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
15851 {
15852 emlxs_port_t *port = (emlxs_port_t *)mbq->port;
15853 MAILBOX4 *mb4;
15854 RPIobj_t *rpip;
15855
15856 mutex_enter(&EMLXS_FCF_LOCK);
15857
15858 rpip = (RPIobj_t *)mbq->context;
15859 mb4 = (MAILBOX4 *)mbq;
15860
15861 if (rpip->state != RPI_STATE_RESUME) {
15862 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15863 "rpi_resume_mbcmpl:%d state=%s. "
15864 "No longer in RPI_STATE_RESUME.",
15865 rpip->RPI,
15866 emlxs_rpi_state_xlate(rpip->state));
15867
15868 mutex_exit(&EMLXS_FCF_LOCK);
15869 return (0);
15870 }
15871
15872 if (mb4->mbxStatus) {
15873 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15874 "rpi_resume_mbcmpl:%d failed. %s. >",
15875 rpip->RPI,
15876 emlxs_mb_xlate_status(mb4->mbxStatus));
15877
15878 (void) emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_FAILED,
15879 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, (void *)mbq->sbp);
15880
15881 mutex_exit(&EMLXS_FCF_LOCK);
15882 return (0);
15883 }
15884
15885 emlxs_rpi_resume_handler(port, rpip);
15886
15887 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15888 "rpi_resume_mbcmpl:%d Resumed. Resume complete. >",
15889 rpip->RPI);
15890
15891 (void) emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_CMPL, 0, 0, 0);
15892
15893 mutex_exit(&EMLXS_FCF_LOCK);
15894
15895 return (0);
15896
15897 } /* emlxs_rpi_resume_mbcmpl() */
15898
15899
15900 /*ARGSUSED*/
15901 static uint32_t
emlxs_rpi_resume_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)15902 emlxs_rpi_resume_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
15903 void *arg1)
15904 {
15905 emlxs_hba_t *hba = HBA;
15906 MAILBOX4 *mb4;
15907 MAILBOXQ *mbq;
15908 uint32_t rval = 0;
15909
15910 if (rpip->state != RPI_STATE_RESUME) {
15911 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
15912 "rpi_resume_action:%d %s:%s arg=%p. "
15913 "Invalid state. <",
15914 rpip->RPI,
15915 emlxs_rpi_state_xlate(rpip->state),
15916 emlxs_fcf_event_xlate(evt), arg1);
15917 return (1);
15918 }
15919
15920 if (!(rpip->flag & EMLXS_RPI_PAUSED)) {
15921 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15922 "rpi_resume_action:%d flag=%x. Not Paused. Going online.",
15923 rpip->RPI, rpip->flag);
15924
15925 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE,
15926 FCF_REASON_EVENT, evt, arg1);
15927
15928 return (rval);
15929 }
15930
15931 if (rpip->RPI == FABRIC_RPI) {
15932 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15933 "rpi_resume_action:%d. Fabric RPI. "
15934 "Going online.",
15935 rpip->RPI);
15936
15937 /* Don't send RESUME_RPI, but process it as if we did */
15938 emlxs_rpi_resume_handler(port, rpip);
15939
15940 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE,
15941 FCF_REASON_EVENT, evt, arg1);
15942
15943 return (rval);
15944 }
15945
15946 if (rpip->prev_state != RPI_STATE_RESUME_FAILED) {
15947 rpip->attempts = 0;
15948 }
15949
15950 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
15951 "rpi_resume_action:%d attempts=%d. Sending RESUME_RPI. <",
15952 rpip->RPI,
15953 rpip->attempts);
15954
15955 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
15956
15957 rval = emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_FAILED,
15958 FCF_REASON_NO_MBOX, 0, arg1);
15959
15960 return (rval);
15961 }
15962 mb4 = (MAILBOX4*)mbq;
15963 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
15964
15965 mbq->nonembed = NULL;
15966 mbq->mbox_cmpl = emlxs_rpi_resume_mbcmpl;
15967 mbq->context = (void *)rpip;
15968 mbq->port = (void *)port;
15969
15970 mb4->mbxCommand = MBX_RESUME_RPI;
15971 mb4->mbxOwner = OWN_HOST;
15972
15973 mb4->un.varResumeRPI.EventTag = hba->link_event_tag;
15974 mb4->un.varResumeRPI.RPI = rpip->RPI;
15975
15976 if (rpip->cmpl) {
15977 mbq->sbp = rpip->cmpl->arg1;
15978 mbq->ubp = rpip->cmpl->arg2;
15979 mbq->iocbq = rpip->cmpl->arg3;
15980 }
15981
15982 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
15983 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
15984 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
15985
15986 rval = emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_FAILED,
15987 FCF_REASON_SEND_FAILED, rval, arg1);
15988
15989 return (rval);
15990 }
15991
15992 if (rpip->cmpl) {
15993 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t));
15994 rpip->cmpl = 0;
15995 }
15996
15997 return (0);
15998
15999 } /* emlxs_rpi_resume_action() */
16000
16001
16002 static uint32_t
emlxs_rpi_resume_cmpl_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)16003 emlxs_rpi_resume_cmpl_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
16004 void *arg1)
16005 {
16006 uint32_t rval = 0;
16007
16008 if (rpip->state != RPI_STATE_RESUME_CMPL) {
16009 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg,
16010 "rpi_resume_cmpl_action:%d %s:%s arg=%p. "
16011 "Invalid state. <",
16012 rpip->RPI,
16013 emlxs_rpi_state_xlate(rpip->state),
16014 emlxs_fcf_event_xlate(evt), arg1);
16015 return (1);
16016 }
16017
16018 if (rpip->flag & EMLXS_RPI_PAUSED) {
16019 if (rpip->flag & EMLXS_RPI_REG) {
16020 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
16021 "rpi_reg_cmpl_action:%d flag=%x. Unregistering.",
16022 rpip->RPI,
16023 rpip->flag);
16024
16025 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG,
16026 FCF_REASON_OP_FAILED, rpip->attempts, arg1);
16027 } else {
16028 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
16029 "rpi_reg_cmpl_action:%d flag=%x. Going offline.",
16030 rpip->RPI,
16031 rpip->flag);
16032
16033 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE,
16034 FCF_REASON_OP_FAILED, rpip->attempts, arg1);
16035 }
16036 } else {
16037 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
16038 "rpi_resume_cmpl_action:%d flag=%x. Going online.",
16039 rpip->RPI,
16040 rpip->flag);
16041
16042 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE,
16043 FCF_REASON_OP_FAILED, rpip->attempts, arg1);
16044 }
16045
16046 return (rval);
16047
16048 } /* emlxs_rpi_resume_cmpl_action() */
16049
16050
16051 /*ARGSUSED*/
16052 static uint32_t
emlxs_rpi_online_action(emlxs_port_t * port,RPIobj_t * rpip,uint32_t evt,void * arg1)16053 emlxs_rpi_online_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt,
16054 void *arg1)
16055 {
16056 emlxs_hba_t *hba = HBA;
16057 uint32_t rval = 0;
16058 RPIobj_t *p2p_rpip;
16059
16060 if (rpip->state != RPI_STATE_ONLINE) {
16061 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
16062 "rpi_online_action:%d %s:%s arg=%p. "
16063 "Invalid state. <",
16064 rpip->RPI,
16065 emlxs_rpi_state_xlate(rpip->state),
16066 emlxs_fcf_event_xlate(evt), arg1);
16067 return (1);
16068 }
16069
16070 if (rpip->RPI == FABRIC_RPI) {
16071 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
16072 "rpi_online_action:%d did=%x. Fabric RPI online. <",
16073 rpip->RPI,
16074 rpip->did,
16075 rpip->vpip->VPI);
16076
16077 /* Now register the p2p_rpip */
16078 p2p_rpip = rpip->vpip->p2p_rpip;
16079 if (p2p_rpip) {
16080 rpip->vpip->p2p_rpip = NULL;
16081
16082 rval = emlxs_rpi_state(port, p2p_rpip, RPI_STATE_REG,
16083 FCF_REASON_EVENT, evt, arg1);
16084 }
16085
16086 EMLXS_STATE_CHANGE(hba, FC_READY);
16087
16088 if (rpip->cmpl) {
16089 emlxs_rpi_deferred_cmpl(port, rpip, 0);
16090 }
16091
16092 return (0);
16093 }
16094
16095 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg,
16096 "rpi_online_action:%d did=%x. RPI online. Notifying VPI:%d. >",
16097 rpip->RPI,
16098 rpip->did,
16099 rpip->vpip->VPI);
16100
16101 /* Notify VPI */
16102 rval = emlxs_vpi_event(port, FCF_EVENT_RPI_ONLINE, rpip);
16103
16104 return (rval);
16105
16106 } /* emlxs_rpi_online_action() */
16107