blob: b9f9e15a02a15e6cbcb96289ac3569f62ab20a31 [file] [log] [blame]
Jing Huang7725ccf2009-09-23 17:46:15 -07001/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07002 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
Jing Huang7725ccf2009-09-23 17:46:15 -07003 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
Jing Huang5fbe25c2010-10-18 17:17:23 -070018/*
Jing Huang7725ccf2009-09-23 17:46:15 -070019 * bfa_fcs.c BFA FCS main
20 */
21
Maggie Zhangf16a1752010-12-09 19:12:32 -080022#include "bfad_drv.h"
Krishna Gudipatia36c61f2010-09-15 11:50:55 -070023#include "bfa_fcs.h"
24#include "bfa_fcbuild.h"
Krishna Gudipatia36c61f2010-09-15 11:50:55 -070025
26BFA_TRC_FILE(FCS, FCS);
Jing Huang7725ccf2009-09-23 17:46:15 -070027
Jing Huang5fbe25c2010-10-18 17:17:23 -070028/*
Jing Huang7725ccf2009-09-23 17:46:15 -070029 * FCS sub-modules
30 */
31struct bfa_fcs_mod_s {
Krishna Gudipati82794a22010-03-03 17:43:30 -080032 void (*attach) (struct bfa_fcs_s *fcs);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -070033 void (*modinit) (struct bfa_fcs_s *fcs);
34 void (*modexit) (struct bfa_fcs_s *fcs);
Jing Huang7725ccf2009-09-23 17:46:15 -070035};
36
37#define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
38
39static struct bfa_fcs_mod_s fcs_modules[] = {
Krishna Gudipatia36c61f2010-09-15 11:50:55 -070040 { bfa_fcs_port_attach, NULL, NULL },
Krishna Gudipati82794a22010-03-03 17:43:30 -080041 { bfa_fcs_uf_attach, NULL, NULL },
42 { bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
Krishna Gudipatia36c61f2010-09-15 11:50:55 -070043 bfa_fcs_fabric_modexit },
Jing Huang7725ccf2009-09-23 17:46:15 -070044};
45
Jing Huang5fbe25c2010-10-18 17:17:23 -070046/*
Jing Huang7725ccf2009-09-23 17:46:15 -070047 * fcs_api BFA FCS API
48 */
49
50static void
51bfa_fcs_exit_comp(void *fcs_cbarg)
52{
Krishna Gudipatia36c61f2010-09-15 11:50:55 -070053 struct bfa_fcs_s *fcs = fcs_cbarg;
54 struct bfad_s *bfad = fcs->bfad;
Jing Huang7725ccf2009-09-23 17:46:15 -070055
56 complete(&bfad->comp);
57}
58
59
60
Jing Huang5fbe25c2010-10-18 17:17:23 -070061/*
Jing Huang7725ccf2009-09-23 17:46:15 -070062 * fcs_api BFA FCS API
63 */
64
Jing Huang5fbe25c2010-10-18 17:17:23 -070065/*
Krishna Gudipati82794a22010-03-03 17:43:30 -080066 * fcs attach -- called once to initialize data structures at driver attach time
Jing Huang7725ccf2009-09-23 17:46:15 -070067 */
68void
Krishna Gudipati82794a22010-03-03 17:43:30 -080069bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
Krishna Gudipatia36c61f2010-09-15 11:50:55 -070070 bfa_boolean_t min_cfg)
Jing Huang7725ccf2009-09-23 17:46:15 -070071{
Krishna Gudipatia36c61f2010-09-15 11:50:55 -070072 int i;
Jing Huang7725ccf2009-09-23 17:46:15 -070073 struct bfa_fcs_mod_s *mod;
74
75 fcs->bfa = bfa;
76 fcs->bfad = bfad;
77 fcs->min_cfg = min_cfg;
78
Maggie Zhangf7f738122010-12-09 19:08:43 -080079 bfa->fcs = BFA_TRUE;
Jing Huang7725ccf2009-09-23 17:46:15 -070080 fcbuild_init();
81
Krishna Gudipatia36c61f2010-09-15 11:50:55 -070082 for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
Jing Huang7725ccf2009-09-23 17:46:15 -070083 mod = &fcs_modules[i];
Krishna Gudipati82794a22010-03-03 17:43:30 -080084 if (mod->attach)
85 mod->attach(fcs);
86 }
87}
88
Jing Huang5fbe25c2010-10-18 17:17:23 -070089/*
Krishna Gudipati82794a22010-03-03 17:43:30 -080090 * fcs initialization, called once after bfa initialization is complete
91 */
92void
93bfa_fcs_init(struct bfa_fcs_s *fcs)
94{
Krishna Gudipati75332a72011-06-13 15:54:31 -070095 int i;
Krishna Gudipati82794a22010-03-03 17:43:30 -080096 struct bfa_fcs_mod_s *mod;
97
Krishna Gudipatia36c61f2010-09-15 11:50:55 -070098 for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
Krishna Gudipati82794a22010-03-03 17:43:30 -080099 mod = &fcs_modules[i];
100 if (mod->modinit)
101 mod->modinit(fcs);
Jing Huang7725ccf2009-09-23 17:46:15 -0700102 }
Krishna Gudipati75332a72011-06-13 15:54:31 -0700103}
104
105/*
106 * FCS update cfg - reset the pwwn/nwwn of fabric base logical port
107 * with values learned during bfa_init firmware GETATTR REQ.
108 */
109void
110bfa_fcs_update_cfg(struct bfa_fcs_s *fcs)
111{
112 struct bfa_fcs_fabric_s *fabric = &fcs->fabric;
113 struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
114 struct bfa_ioc_s *ioc = &fabric->fcs->bfa->ioc;
115
116 port_cfg->nwwn = ioc->attr->nwwn;
117 port_cfg->pwwn = ioc->attr->pwwn;
118}
119
120/*
121 * fcs pbc vport initialization
122 */
123void
124bfa_fcs_pbc_vport_init(struct bfa_fcs_s *fcs)
125{
126 int i, npbc_vports;
127 struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];
128
Jing Huangd9883542010-07-08 19:46:26 -0700129 /* Initialize pbc vports */
130 if (!fcs->min_cfg) {
131 npbc_vports =
Krishna Gudipati75332a72011-06-13 15:54:31 -0700132 bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
Jing Huangd9883542010-07-08 19:46:26 -0700133 for (i = 0; i < npbc_vports; i++)
134 bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
135 }
Jing Huang7725ccf2009-09-23 17:46:15 -0700136}
137
Jing Huang5fbe25c2010-10-18 17:17:23 -0700138/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700139 * brief
140 * FCS driver details initialization.
Jing Huang7725ccf2009-09-23 17:46:15 -0700141 *
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700142 * param[in] fcs FCS instance
143 * param[in] driver_info Driver Details
Jing Huang7725ccf2009-09-23 17:46:15 -0700144 *
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700145 * return None
Jing Huang7725ccf2009-09-23 17:46:15 -0700146 */
147void
148bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
149 struct bfa_fcs_driver_info_s *driver_info)
150{
151
152 fcs->driver_info = *driver_info;
153
154 bfa_fcs_fabric_psymb_init(&fcs->fabric);
155}
156
Jing Huang5fbe25c2010-10-18 17:17:23 -0700157/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700158 * brief
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700159 * FCS instance cleanup and exit.
Jing Huang7725ccf2009-09-23 17:46:15 -0700160 *
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700161 * param[in] fcs FCS instance
162 * return None
Jing Huang7725ccf2009-09-23 17:46:15 -0700163 */
164void
165bfa_fcs_exit(struct bfa_fcs_s *fcs)
166{
167 struct bfa_fcs_mod_s *mod;
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700168 int nmods, i;
Jing Huang7725ccf2009-09-23 17:46:15 -0700169
170 bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
171
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700172 nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
173
174 for (i = 0; i < nmods; i++) {
Jing Huang7725ccf2009-09-23 17:46:15 -0700175
176 mod = &fcs_modules[i];
Krishna Gudipati82794a22010-03-03 17:43:30 -0800177 if (mod->modexit) {
178 bfa_wc_up(&fcs->wc);
179 mod->modexit(fcs);
180 }
Jing Huang7725ccf2009-09-23 17:46:15 -0700181 }
182
183 bfa_wc_wait(&fcs->wc);
184}
185
186
Jing Huang5fbe25c2010-10-18 17:17:23 -0700187/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700188 * Fabric module implementation.
189 */
Jing Huang7725ccf2009-09-23 17:46:15 -0700190
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700191#define BFA_FCS_FABRIC_RETRY_DELAY (2000) /* Milliseconds */
192#define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */
193
194#define bfa_fcs_fabric_set_opertype(__fabric) do { \
195 if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \
196 == BFA_PORT_TOPOLOGY_P2P) \
197 (__fabric)->oper_type = BFA_PORT_TYPE_NPORT; \
198 else \
199 (__fabric)->oper_type = BFA_PORT_TYPE_NLPORT; \
200} while (0)
201
202/*
203 * forward declarations
204 */
205static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
206static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
207static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
208static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
209static void bfa_fcs_fabric_delay(void *cbarg);
210static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
211static void bfa_fcs_fabric_delete_comp(void *cbarg);
212static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
213 struct fchs_s *fchs, u16 len);
214static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
215 struct fchs_s *fchs, u16 len);
216static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
217static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
218 struct bfa_fcxp_s *fcxp, void *cbarg,
219 bfa_status_t status,
220 u32 rsp_len,
221 u32 resid_len,
222 struct fchs_s *rspfchs);
Krishna Gudipatibe540a92011-06-13 15:53:04 -0700223static u8 bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric);
224static bfa_boolean_t bfa_fcs_fabric_is_bbscn_enabled(
225 struct bfa_fcs_fabric_s *fabric);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700226
227static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
228 enum bfa_fcs_fabric_event event);
229static void bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
230 enum bfa_fcs_fabric_event event);
231static void bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
232 enum bfa_fcs_fabric_event event);
233static void bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
234 enum bfa_fcs_fabric_event event);
235static void bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
236 enum bfa_fcs_fabric_event event);
237static void bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
238 enum bfa_fcs_fabric_event event);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700239static void bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
240 enum bfa_fcs_fabric_event event);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700241static void bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
242 enum bfa_fcs_fabric_event event);
243static void bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
244 enum bfa_fcs_fabric_event event);
245static void bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
246 enum bfa_fcs_fabric_event event);
247static void bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
248 enum bfa_fcs_fabric_event event);
Jing Huang5fbe25c2010-10-18 17:17:23 -0700249/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700250 * Beginning state before fabric creation.
251 */
252static void
253bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
254 enum bfa_fcs_fabric_event event)
255{
256 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
257 bfa_trc(fabric->fcs, event);
258
259 switch (event) {
260 case BFA_FCS_FABRIC_SM_CREATE:
261 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
262 bfa_fcs_fabric_init(fabric);
263 bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
264 break;
265
266 case BFA_FCS_FABRIC_SM_LINK_UP:
267 case BFA_FCS_FABRIC_SM_LINK_DOWN:
268 break;
269
270 default:
271 bfa_sm_fault(fabric->fcs, event);
272 }
273}
274
Jing Huang5fbe25c2010-10-18 17:17:23 -0700275/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700276 * Beginning state before fabric creation.
277 */
278static void
279bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
280 enum bfa_fcs_fabric_event event)
281{
282 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
283 bfa_trc(fabric->fcs, event);
284
285 switch (event) {
286 case BFA_FCS_FABRIC_SM_START:
287 if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
288 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
289 bfa_fcs_fabric_login(fabric);
290 } else
291 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
292 break;
293
294 case BFA_FCS_FABRIC_SM_LINK_UP:
295 case BFA_FCS_FABRIC_SM_LINK_DOWN:
296 break;
297
298 case BFA_FCS_FABRIC_SM_DELETE:
Krishna Gudipatidd5aaf42011-06-13 15:51:24 -0700299 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
300 bfa_fcs_fabric_delete(fabric);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700301 break;
302
303 default:
304 bfa_sm_fault(fabric->fcs, event);
305 }
306}
307
Jing Huang5fbe25c2010-10-18 17:17:23 -0700308/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700309 * Link is down, awaiting LINK UP event from port. This is also the
310 * first state at fabric creation.
311 */
312static void
313bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
314 enum bfa_fcs_fabric_event event)
315{
316 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
317 bfa_trc(fabric->fcs, event);
318
319 switch (event) {
320 case BFA_FCS_FABRIC_SM_LINK_UP:
321 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
322 bfa_fcs_fabric_login(fabric);
323 break;
324
325 case BFA_FCS_FABRIC_SM_RETRY_OP:
326 break;
327
328 case BFA_FCS_FABRIC_SM_DELETE:
329 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
330 bfa_fcs_fabric_delete(fabric);
331 break;
332
333 default:
334 bfa_sm_fault(fabric->fcs, event);
335 }
336}
337
Jing Huang5fbe25c2010-10-18 17:17:23 -0700338/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700339 * FLOGI is in progress, awaiting FLOGI reply.
340 */
341static void
342bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
343 enum bfa_fcs_fabric_event event)
344{
345 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
346 bfa_trc(fabric->fcs, event);
347
348 switch (event) {
349 case BFA_FCS_FABRIC_SM_CONT_OP:
350
351 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
Krishna Gudipatibe540a92011-06-13 15:53:04 -0700352 fabric->bb_credit,
353 bfa_fcs_fabric_oper_bbscn(fabric));
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700354 fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
355
356 if (fabric->auth_reqd && fabric->is_auth) {
357 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth);
358 bfa_trc(fabric->fcs, event);
359 } else {
360 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
361 bfa_fcs_fabric_notify_online(fabric);
362 }
363 break;
364
365 case BFA_FCS_FABRIC_SM_RETRY_OP:
366 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry);
367 bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer,
368 bfa_fcs_fabric_delay, fabric,
369 BFA_FCS_FABRIC_RETRY_DELAY);
370 break;
371
372 case BFA_FCS_FABRIC_SM_LOOPBACK:
373 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
Maggie Zhangf7f738122010-12-09 19:08:43 -0800374 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700375 bfa_fcs_fabric_set_opertype(fabric);
376 break;
377
378 case BFA_FCS_FABRIC_SM_NO_FABRIC:
379 fabric->fab_type = BFA_FCS_FABRIC_N2N;
380 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
Krishna Gudipatibe540a92011-06-13 15:53:04 -0700381 fabric->bb_credit,
382 bfa_fcs_fabric_oper_bbscn(fabric));
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700383 bfa_fcs_fabric_notify_online(fabric);
384 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
385 break;
386
387 case BFA_FCS_FABRIC_SM_LINK_DOWN:
388 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
Maggie Zhangf7f738122010-12-09 19:08:43 -0800389 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700390 break;
391
392 case BFA_FCS_FABRIC_SM_DELETE:
393 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
Maggie Zhangf7f738122010-12-09 19:08:43 -0800394 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700395 bfa_fcs_fabric_delete(fabric);
396 break;
397
398 default:
399 bfa_sm_fault(fabric->fcs, event);
400 }
401}
402
403
404static void
405bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
406 enum bfa_fcs_fabric_event event)
407{
408 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
409 bfa_trc(fabric->fcs, event);
410
411 switch (event) {
412 case BFA_FCS_FABRIC_SM_DELAYED:
413 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
414 bfa_fcs_fabric_login(fabric);
415 break;
416
417 case BFA_FCS_FABRIC_SM_LINK_DOWN:
418 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
419 bfa_timer_stop(&fabric->delay_timer);
420 break;
421
422 case BFA_FCS_FABRIC_SM_DELETE:
423 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
424 bfa_timer_stop(&fabric->delay_timer);
425 bfa_fcs_fabric_delete(fabric);
426 break;
427
428 default:
429 bfa_sm_fault(fabric->fcs, event);
430 }
431}
432
Jing Huang5fbe25c2010-10-18 17:17:23 -0700433/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700434 * Authentication is in progress, awaiting authentication results.
435 */
436static void
437bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
438 enum bfa_fcs_fabric_event event)
439{
440 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
441 bfa_trc(fabric->fcs, event);
442
443 switch (event) {
444 case BFA_FCS_FABRIC_SM_AUTH_FAILED:
445 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
Maggie Zhangf7f738122010-12-09 19:08:43 -0800446 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700447 break;
448
449 case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
450 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
451 bfa_fcs_fabric_notify_online(fabric);
452 break;
453
454 case BFA_FCS_FABRIC_SM_PERF_EVFP:
455 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp);
456 break;
457
458 case BFA_FCS_FABRIC_SM_LINK_DOWN:
459 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
Maggie Zhangf7f738122010-12-09 19:08:43 -0800460 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700461 break;
462
463 case BFA_FCS_FABRIC_SM_DELETE:
464 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
465 bfa_fcs_fabric_delete(fabric);
466 break;
467
468 default:
469 bfa_sm_fault(fabric->fcs, event);
470 }
471}
472
Jing Huang5fbe25c2010-10-18 17:17:23 -0700473/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700474 * Authentication failed
475 */
Maggie Zhangf7f738122010-12-09 19:08:43 -0800476void
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700477bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
478 enum bfa_fcs_fabric_event event)
479{
480 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
481 bfa_trc(fabric->fcs, event);
482
483 switch (event) {
484 case BFA_FCS_FABRIC_SM_LINK_DOWN:
485 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
486 bfa_fcs_fabric_notify_offline(fabric);
487 break;
488
489 case BFA_FCS_FABRIC_SM_DELETE:
490 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
491 bfa_fcs_fabric_delete(fabric);
492 break;
493
494 default:
495 bfa_sm_fault(fabric->fcs, event);
496 }
497}
498
Jing Huang5fbe25c2010-10-18 17:17:23 -0700499/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700500 * Port is in loopback mode.
501 */
Maggie Zhangf7f738122010-12-09 19:08:43 -0800502void
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700503bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
504 enum bfa_fcs_fabric_event event)
505{
506 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
507 bfa_trc(fabric->fcs, event);
508
509 switch (event) {
510 case BFA_FCS_FABRIC_SM_LINK_DOWN:
511 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
512 bfa_fcs_fabric_notify_offline(fabric);
513 break;
514
515 case BFA_FCS_FABRIC_SM_DELETE:
516 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
517 bfa_fcs_fabric_delete(fabric);
518 break;
519
520 default:
521 bfa_sm_fault(fabric->fcs, event);
522 }
523}
524
Jing Huang5fbe25c2010-10-18 17:17:23 -0700525/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700526 * There is no attached fabric - private loop or NPort-to-NPort topology.
527 */
528static void
529bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
530 enum bfa_fcs_fabric_event event)
531{
532 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
533 bfa_trc(fabric->fcs, event);
534
535 switch (event) {
536 case BFA_FCS_FABRIC_SM_LINK_DOWN:
537 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
Maggie Zhangf7f738122010-12-09 19:08:43 -0800538 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700539 bfa_fcs_fabric_notify_offline(fabric);
540 break;
541
542 case BFA_FCS_FABRIC_SM_DELETE:
543 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
544 bfa_fcs_fabric_delete(fabric);
545 break;
546
547 case BFA_FCS_FABRIC_SM_NO_FABRIC:
548 bfa_trc(fabric->fcs, fabric->bb_credit);
549 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
Krishna Gudipatibe540a92011-06-13 15:53:04 -0700550 fabric->bb_credit,
551 bfa_fcs_fabric_oper_bbscn(fabric));
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700552 break;
553
554 default:
555 bfa_sm_fault(fabric->fcs, event);
556 }
557}
558
Jing Huang5fbe25c2010-10-18 17:17:23 -0700559/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700560 * Fabric is online - normal operating state.
561 */
Maggie Zhangf7f738122010-12-09 19:08:43 -0800562void
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700563bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
564 enum bfa_fcs_fabric_event event)
565{
566 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
567 bfa_trc(fabric->fcs, event);
568
569 switch (event) {
570 case BFA_FCS_FABRIC_SM_LINK_DOWN:
571 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
Maggie Zhangf7f738122010-12-09 19:08:43 -0800572 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700573 bfa_fcs_fabric_notify_offline(fabric);
574 break;
575
576 case BFA_FCS_FABRIC_SM_DELETE:
577 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
578 bfa_fcs_fabric_delete(fabric);
579 break;
580
581 case BFA_FCS_FABRIC_SM_AUTH_FAILED:
582 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
Maggie Zhangf7f738122010-12-09 19:08:43 -0800583 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700584 break;
585
586 case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
587 break;
588
589 default:
590 bfa_sm_fault(fabric->fcs, event);
591 }
592}
593
Jing Huang5fbe25c2010-10-18 17:17:23 -0700594/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700595 * Exchanging virtual fabric parameters.
596 */
597static void
598bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
599 enum bfa_fcs_fabric_event event)
600{
601 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
602 bfa_trc(fabric->fcs, event);
603
604 switch (event) {
605 case BFA_FCS_FABRIC_SM_CONT_OP:
606 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done);
607 break;
608
609 case BFA_FCS_FABRIC_SM_ISOLATE:
610 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated);
611 break;
612
613 default:
614 bfa_sm_fault(fabric->fcs, event);
615 }
616}
617
Jing Huang5fbe25c2010-10-18 17:17:23 -0700618/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700619 * EVFP exchange complete and VFT tagging is enabled.
620 */
621static void
622bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
623 enum bfa_fcs_fabric_event event)
624{
625 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
626 bfa_trc(fabric->fcs, event);
627}
628
Jing Huang5fbe25c2010-10-18 17:17:23 -0700629/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700630 * Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
631 */
632static void
633bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
634 enum bfa_fcs_fabric_event event)
635{
636 struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
637 char pwwn_ptr[BFA_STRING_32];
638
639 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
640 bfa_trc(fabric->fcs, event);
641 wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn);
642
Jing Huang88166242010-12-09 17:11:53 -0800643 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700644 "Port is isolated due to VF_ID mismatch. "
645 "PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.",
646 pwwn_ptr, fabric->fcs->port_vfid,
647 fabric->event_arg.swp_vfid);
648}
649
Jing Huang5fbe25c2010-10-18 17:17:23 -0700650/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700651 * Fabric is being deleted, awaiting vport delete completions.
652 */
653static void
654bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
655 enum bfa_fcs_fabric_event event)
656{
657 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
658 bfa_trc(fabric->fcs, event);
659
660 switch (event) {
661 case BFA_FCS_FABRIC_SM_DELCOMP:
662 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
Maggie Zhangf7f738122010-12-09 19:08:43 -0800663 bfa_wc_down(&fabric->fcs->wc);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700664 break;
665
666 case BFA_FCS_FABRIC_SM_LINK_UP:
667 break;
668
669 case BFA_FCS_FABRIC_SM_LINK_DOWN:
670 bfa_fcs_fabric_notify_offline(fabric);
671 break;
672
673 default:
674 bfa_sm_fault(fabric->fcs, event);
675 }
676}
677
678
679
Jing Huang5fbe25c2010-10-18 17:17:23 -0700680/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700681 * fcs_fabric_private fabric private functions
682 */
683
684static void
685bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
686{
687 struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
688
689 port_cfg->roles = BFA_LPORT_ROLE_FCP_IM;
Maggie Zhangf7f738122010-12-09 19:08:43 -0800690 port_cfg->nwwn = fabric->fcs->bfa->ioc.attr->nwwn;
691 port_cfg->pwwn = fabric->fcs->bfa->ioc.attr->pwwn;
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700692}
693
Jing Huang5fbe25c2010-10-18 17:17:23 -0700694/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700695 * Port Symbolic Name Creation for base port.
696 */
697void
698bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
699{
700 struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
701 char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
702 struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
703
704 bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
705
706 /* Model name/number */
707 strncpy((char *)&port_cfg->sym_name, model,
708 BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
709 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
710 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
711
712 /* Driver Version */
713 strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
714 BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
715 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
716 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
717
718 /* Host machine name */
719 strncat((char *)&port_cfg->sym_name,
720 (char *)driver_info->host_machine_name,
721 BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
722 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
723 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
724
725 /*
726 * Host OS Info :
727 * If OS Patch Info is not there, do not truncate any bytes from the
728 * OS name string and instead copy the entire OS info string (64 bytes).
729 */
730 if (driver_info->host_os_patch[0] == '\0') {
731 strncat((char *)&port_cfg->sym_name,
732 (char *)driver_info->host_os_name,
733 BFA_FCS_OS_STR_LEN);
734 strncat((char *)&port_cfg->sym_name,
735 BFA_FCS_PORT_SYMBNAME_SEPARATOR,
736 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
737 } else {
738 strncat((char *)&port_cfg->sym_name,
739 (char *)driver_info->host_os_name,
740 BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
741 strncat((char *)&port_cfg->sym_name,
742 BFA_FCS_PORT_SYMBNAME_SEPARATOR,
743 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
744
745 /* Append host OS Patch Info */
746 strncat((char *)&port_cfg->sym_name,
747 (char *)driver_info->host_os_patch,
748 BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
749 }
750
751 /* null terminate */
752 port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
753}
754
Jing Huang5fbe25c2010-10-18 17:17:23 -0700755/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700756 * bfa lps login completion callback
757 */
758void
759bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
760{
761 struct bfa_fcs_fabric_s *fabric = uarg;
762
763 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
764 bfa_trc(fabric->fcs, status);
765
766 switch (status) {
767 case BFA_STATUS_OK:
768 fabric->stats.flogi_accepts++;
769 break;
770
771 case BFA_STATUS_INVALID_MAC:
772 /* Only for CNA */
773 fabric->stats.flogi_acc_err++;
774 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
775
776 return;
777
778 case BFA_STATUS_EPROTOCOL:
Maggie Zhangf7f738122010-12-09 19:08:43 -0800779 switch (fabric->lps->ext_status) {
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700780 case BFA_EPROTO_BAD_ACCEPT:
781 fabric->stats.flogi_acc_err++;
782 break;
783
784 case BFA_EPROTO_UNKNOWN_RSP:
785 fabric->stats.flogi_unknown_rsp++;
786 break;
787
788 default:
789 break;
790 }
791 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
792
793 return;
794
795 case BFA_STATUS_FABRIC_RJT:
796 fabric->stats.flogi_rejects++;
Krishna Gudipatibe540a92011-06-13 15:53:04 -0700797 if (fabric->lps->lsrjt_rsn == FC_LS_RJT_RSN_LOGICAL_ERROR &&
798 fabric->lps->lsrjt_expl == FC_LS_RJT_EXP_NO_ADDL_INFO)
799 fabric->fcs->bbscn_flogi_rjt = BFA_TRUE;
800
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700801 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
802 return;
803
804 default:
805 fabric->stats.flogi_rsp_err++;
806 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
807 return;
808 }
809
Maggie Zhangf7f738122010-12-09 19:08:43 -0800810 fabric->bb_credit = fabric->lps->pr_bbcred;
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700811 bfa_trc(fabric->fcs, fabric->bb_credit);
812
Maggie Zhangf7f738122010-12-09 19:08:43 -0800813 if (!(fabric->lps->brcd_switch))
814 fabric->fabric_name = fabric->lps->pr_nwwn;
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700815
816 /*
817 * Check port type. It should be 1 = F-port.
818 */
Maggie Zhangf7f738122010-12-09 19:08:43 -0800819 if (fabric->lps->fport) {
820 fabric->bport.pid = fabric->lps->lp_pid;
821 fabric->is_npiv = fabric->lps->npiv_en;
822 fabric->is_auth = fabric->lps->auth_req;
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700823 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
824 } else {
825 /*
826 * Nport-2-Nport direct attached
827 */
828 fabric->bport.port_topo.pn2n.rem_port_wwn =
Maggie Zhangf7f738122010-12-09 19:08:43 -0800829 fabric->lps->pr_pwwn;
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700830 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
831 }
832
833 bfa_trc(fabric->fcs, fabric->bport.pid);
834 bfa_trc(fabric->fcs, fabric->is_npiv);
835 bfa_trc(fabric->fcs, fabric->is_auth);
836}
Jing Huang5fbe25c2010-10-18 17:17:23 -0700837/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700838 * Allocate and send FLOGI.
839 */
840static void
841bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
842{
843 struct bfa_s *bfa = fabric->fcs->bfa;
844 struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
Krishna Gudipatibe540a92011-06-13 15:53:04 -0700845 u8 alpa = 0, bb_scn = 0;
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700846
847 if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
848 alpa = bfa_fcport_get_myalpa(bfa);
849
Krishna Gudipatibe540a92011-06-13 15:53:04 -0700850 if (bfa_fcs_fabric_is_bbscn_enabled(fabric) &&
851 (!fabric->fcs->bbscn_flogi_rjt))
852 bb_scn = BFA_FCS_PORT_DEF_BB_SCN;
853
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700854 bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
Krishna Gudipatibe540a92011-06-13 15:53:04 -0700855 pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd, bb_scn);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700856
857 fabric->stats.flogi_sent++;
858}
859
860static void
861bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
862{
863 struct bfa_fcs_vport_s *vport;
864 struct list_head *qe, *qen;
865
866 bfa_trc(fabric->fcs, fabric->fabric_name);
867
868 bfa_fcs_fabric_set_opertype(fabric);
869 fabric->stats.fabric_onlines++;
870
Jing Huang5fbe25c2010-10-18 17:17:23 -0700871 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700872 * notify online event to base and then virtual ports
873 */
874 bfa_fcs_lport_online(&fabric->bport);
875
876 list_for_each_safe(qe, qen, &fabric->vport_q) {
877 vport = (struct bfa_fcs_vport_s *) qe;
878 bfa_fcs_vport_online(vport);
879 }
880}
881
882static void
883bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
884{
885 struct bfa_fcs_vport_s *vport;
886 struct list_head *qe, *qen;
887
888 bfa_trc(fabric->fcs, fabric->fabric_name);
889 fabric->stats.fabric_offlines++;
890
Jing Huang5fbe25c2010-10-18 17:17:23 -0700891 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700892 * notify offline event first to vports and then base port.
893 */
894 list_for_each_safe(qe, qen, &fabric->vport_q) {
895 vport = (struct bfa_fcs_vport_s *) qe;
896 bfa_fcs_vport_offline(vport);
897 }
898
899 bfa_fcs_lport_offline(&fabric->bport);
900
901 fabric->fabric_name = 0;
902 fabric->fabric_ip_addr[0] = 0;
903}
904
905static void
906bfa_fcs_fabric_delay(void *cbarg)
907{
908 struct bfa_fcs_fabric_s *fabric = cbarg;
909
910 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
911}
912
Jing Huang5fbe25c2010-10-18 17:17:23 -0700913/*
Krishna Gudipatibe540a92011-06-13 15:53:04 -0700914 * Computes operating BB_SCN value
915 */
916static u8
917bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric)
918{
919 u8 pr_bbscn = fabric->lps->pr_bbscn;
920
921 if (!(fabric->fcs->bbscn_enabled && pr_bbscn))
922 return 0;
923
924 /* return max of local/remote bb_scn values */
925 return ((pr_bbscn > BFA_FCS_PORT_DEF_BB_SCN) ?
926 pr_bbscn : BFA_FCS_PORT_DEF_BB_SCN);
927}
928
929/*
930 * Check if BB_SCN can be enabled.
931 */
932static bfa_boolean_t
933bfa_fcs_fabric_is_bbscn_enabled(struct bfa_fcs_fabric_s *fabric)
934{
935 if (bfa_ioc_get_fcmode(&fabric->fcs->bfa->ioc) &&
936 fabric->fcs->bbscn_enabled &&
937 !bfa_fcport_is_qos_enabled(fabric->fcs->bfa) &&
938 !bfa_fcport_is_trunk_enabled(fabric->fcs->bfa))
939 return BFA_TRUE;
940 else
941 return BFA_FALSE;
942}
943
944/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700945 * Delete all vports and wait for vport delete completions.
946 */
947static void
948bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
949{
950 struct bfa_fcs_vport_s *vport;
951 struct list_head *qe, *qen;
952
953 list_for_each_safe(qe, qen, &fabric->vport_q) {
954 vport = (struct bfa_fcs_vport_s *) qe;
955 bfa_fcs_vport_fcs_delete(vport);
956 }
957
958 bfa_fcs_lport_delete(&fabric->bport);
959 bfa_wc_wait(&fabric->wc);
960}
961
962static void
963bfa_fcs_fabric_delete_comp(void *cbarg)
964{
965 struct bfa_fcs_fabric_s *fabric = cbarg;
966
967 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
968}
969
Jing Huang5fbe25c2010-10-18 17:17:23 -0700970/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700971 * fcs_fabric_public fabric public functions
972 */
973
Jing Huang5fbe25c2010-10-18 17:17:23 -0700974/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700975 * Attach time initialization.
976 */
977void
978bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
979{
980 struct bfa_fcs_fabric_s *fabric;
981
982 fabric = &fcs->fabric;
Jing Huang6a18b162010-10-18 17:08:54 -0700983 memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700984
Jing Huang5fbe25c2010-10-18 17:17:23 -0700985 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700986 * Initialize base fabric.
987 */
988 fabric->fcs = fcs;
989 INIT_LIST_HEAD(&fabric->vport_q);
990 INIT_LIST_HEAD(&fabric->vf_q);
991 fabric->lps = bfa_lps_alloc(fcs->bfa);
Jing Huangd4b671c2010-12-26 21:46:35 -0800992 WARN_ON(!fabric->lps);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700993
Jing Huang5fbe25c2010-10-18 17:17:23 -0700994 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -0700995 * Initialize fabric delete completion handler. Fabric deletion is
996 * complete when the last vport delete is complete.
997 */
998 bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric);
999 bfa_wc_up(&fabric->wc); /* For the base port */
1000
1001 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
1002 bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
1003}
1004
1005void
1006bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
1007{
1008 bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
1009 bfa_trc(fcs, 0);
1010}
1011
Jing Huang5fbe25c2010-10-18 17:17:23 -07001012/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001013 * Module cleanup
1014 */
1015void
1016bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
1017{
1018 struct bfa_fcs_fabric_s *fabric;
1019
1020 bfa_trc(fcs, 0);
1021
Jing Huang5fbe25c2010-10-18 17:17:23 -07001022 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001023 * Cleanup base fabric.
1024 */
1025 fabric = &fcs->fabric;
1026 bfa_lps_delete(fabric->lps);
1027 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE);
1028}
1029
Jing Huang5fbe25c2010-10-18 17:17:23 -07001030/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001031 * Fabric module start -- kick starts FCS actions
1032 */
1033void
1034bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
1035{
1036 struct bfa_fcs_fabric_s *fabric;
1037
1038 bfa_trc(fcs, 0);
1039 fabric = &fcs->fabric;
1040 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
1041}
1042
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001043
Jing Huang5fbe25c2010-10-18 17:17:23 -07001044/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001045 * Link up notification from BFA physical port module.
1046 */
1047void
1048bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
1049{
1050 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
1051 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
1052}
1053
Jing Huang5fbe25c2010-10-18 17:17:23 -07001054/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001055 * Link down notification from BFA physical port module.
1056 */
1057void
1058bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
1059{
1060 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
Krishna Gudipatibe540a92011-06-13 15:53:04 -07001061 fabric->fcs->bbscn_flogi_rjt = BFA_FALSE;
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001062 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
1063}
1064
Jing Huang5fbe25c2010-10-18 17:17:23 -07001065/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001066 * A child vport is being created in the fabric.
1067 *
1068 * Call from vport module at vport creation. A list of base port and vports
1069 * belonging to a fabric is maintained to propagate link events.
1070 *
1071 * param[in] fabric - Fabric instance. This can be a base fabric or vf.
1072 * param[in] vport - Vport being created.
1073 *
1074 * @return None (always succeeds)
1075 */
1076void
1077bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
1078 struct bfa_fcs_vport_s *vport)
1079{
Jing Huang5fbe25c2010-10-18 17:17:23 -07001080 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001081 * - add vport to fabric's vport_q
1082 */
1083 bfa_trc(fabric->fcs, fabric->vf_id);
1084
1085 list_add_tail(&vport->qe, &fabric->vport_q);
1086 fabric->num_vports++;
1087 bfa_wc_up(&fabric->wc);
1088}
1089
Jing Huang5fbe25c2010-10-18 17:17:23 -07001090/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001091 * A child vport is being deleted from fabric.
1092 *
1093 * Vport is being deleted.
1094 */
1095void
1096bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
1097 struct bfa_fcs_vport_s *vport)
1098{
1099 list_del(&vport->qe);
1100 fabric->num_vports--;
1101 bfa_wc_down(&fabric->wc);
1102}
1103
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001104
Jing Huang5fbe25c2010-10-18 17:17:23 -07001105/*
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001106 * Lookup for a vport within a fabric given its pwwn
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001107 */
1108struct bfa_fcs_vport_s *
1109bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
1110{
1111 struct bfa_fcs_vport_s *vport;
1112 struct list_head *qe;
1113
1114 list_for_each(qe, &fabric->vport_q) {
1115 vport = (struct bfa_fcs_vport_s *) qe;
1116 if (bfa_fcs_lport_get_pwwn(&vport->lport) == pwwn)
1117 return vport;
1118 }
1119
1120 return NULL;
1121}
1122
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001123
1124/*
1125 * Get OUI of the attached switch.
1126 *
1127 * Note : Use of this function should be avoided as much as possible.
1128 * This function should be used only if there is any requirement
1129* to check for FOS version below 6.3.
1130 * To check if the attached fabric is a brocade fabric, use
1131 * bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
1132 * or above only.
1133 */
1134
1135u16
1136bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
1137{
1138 wwn_t fab_nwwn;
1139 u8 *tmp;
1140 u16 oui;
1141
Maggie Zhangf7f738122010-12-09 19:08:43 -08001142 fab_nwwn = fabric->lps->pr_nwwn;
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001143
1144 tmp = (u8 *)&fab_nwwn;
1145 oui = (tmp[3] << 8) | tmp[4];
1146
1147 return oui;
1148}
Jing Huang5fbe25c2010-10-18 17:17:23 -07001149/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001150 * Unsolicited frame receive handling.
1151 */
1152void
1153bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1154 u16 len)
1155{
1156 u32 pid = fchs->d_id;
1157 struct bfa_fcs_vport_s *vport;
1158 struct list_head *qe;
1159 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1160 struct fc_logi_s *flogi = (struct fc_logi_s *) els_cmd;
1161
1162 bfa_trc(fabric->fcs, len);
1163 bfa_trc(fabric->fcs, pid);
1164
Jing Huang5fbe25c2010-10-18 17:17:23 -07001165 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001166 * Look for our own FLOGI frames being looped back. This means an
1167 * external loopback cable is in place. Our own FLOGI frames are
1168 * sometimes looped back when switch port gets temporarily bypassed.
1169 */
Maggie Zhangf16a1752010-12-09 19:12:32 -08001170 if ((pid == bfa_ntoh3b(FC_FABRIC_PORT)) &&
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001171 (els_cmd->els_code == FC_ELS_FLOGI) &&
1172 (flogi->port_name == bfa_fcs_lport_get_pwwn(&fabric->bport))) {
1173 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
1174 return;
1175 }
1176
Jing Huang5fbe25c2010-10-18 17:17:23 -07001177 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001178 * FLOGI/EVFP exchanges should be consumed by base fabric.
1179 */
Maggie Zhangf16a1752010-12-09 19:12:32 -08001180 if (fchs->d_id == bfa_hton3b(FC_FABRIC_PORT)) {
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001181 bfa_trc(fabric->fcs, pid);
1182 bfa_fcs_fabric_process_uf(fabric, fchs, len);
1183 return;
1184 }
1185
1186 if (fabric->bport.pid == pid) {
Jing Huang5fbe25c2010-10-18 17:17:23 -07001187 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001188 * All authentication frames should be routed to auth
1189 */
1190 bfa_trc(fabric->fcs, els_cmd->els_code);
1191 if (els_cmd->els_code == FC_ELS_AUTH) {
1192 bfa_trc(fabric->fcs, els_cmd->els_code);
1193 return;
1194 }
1195
1196 bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
1197 bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
1198 return;
1199 }
1200
Jing Huang5fbe25c2010-10-18 17:17:23 -07001201 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001202 * look for a matching local port ID
1203 */
1204 list_for_each(qe, &fabric->vport_q) {
1205 vport = (struct bfa_fcs_vport_s *) qe;
1206 if (vport->lport.pid == pid) {
1207 bfa_fcs_lport_uf_recv(&vport->lport, fchs, len);
1208 return;
1209 }
1210 }
1211 bfa_trc(fabric->fcs, els_cmd->els_code);
1212 bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
1213}
1214
Jing Huang5fbe25c2010-10-18 17:17:23 -07001215/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001216 * Unsolicited frames to be processed by fabric.
1217 */
1218static void
1219bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1220 u16 len)
1221{
1222 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1223
1224 bfa_trc(fabric->fcs, els_cmd->els_code);
1225
1226 switch (els_cmd->els_code) {
1227 case FC_ELS_FLOGI:
1228 bfa_fcs_fabric_process_flogi(fabric, fchs, len);
1229 break;
1230
1231 default:
1232 /*
1233 * need to generate a LS_RJT
1234 */
1235 break;
1236 }
1237}
1238
Jing Huang5fbe25c2010-10-18 17:17:23 -07001239/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001240 * Process incoming FLOGI
1241 */
1242static void
1243bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
1244 struct fchs_s *fchs, u16 len)
1245{
1246 struct fc_logi_s *flogi = (struct fc_logi_s *) (fchs + 1);
1247 struct bfa_fcs_lport_s *bport = &fabric->bport;
1248
1249 bfa_trc(fabric->fcs, fchs->s_id);
1250
1251 fabric->stats.flogi_rcvd++;
1252 /*
1253 * Check port type. It should be 0 = n-port.
1254 */
1255 if (flogi->csp.port_type) {
1256 /*
1257 * @todo: may need to send a LS_RJT
1258 */
1259 bfa_trc(fabric->fcs, flogi->port_name);
1260 fabric->stats.flogi_rejected++;
1261 return;
1262 }
1263
Jing Huangba816ea2010-10-18 17:10:50 -07001264 fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred);
Krishna Gudipatibe540a92011-06-13 15:53:04 -07001265 fabric->lps->pr_bbscn = (be16_to_cpu(flogi->csp.rxsz) >> 12);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001266 bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
1267 bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
1268
1269 /*
1270 * Send a Flogi Acc
1271 */
1272 bfa_fcs_fabric_send_flogi_acc(fabric);
1273 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
1274}
1275
1276static void
1277bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1278{
1279 struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
1280 struct bfa_fcs_lport_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
1281 struct bfa_s *bfa = fabric->fcs->bfa;
1282 struct bfa_fcxp_s *fcxp;
1283 u16 reqlen;
1284 struct fchs_s fchs;
1285
1286 fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
Jing Huang5fbe25c2010-10-18 17:17:23 -07001287 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001288 * Do not expect this failure -- expect remote node to retry
1289 */
1290 if (!fcxp)
1291 return;
1292
1293 reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
Maggie Zhangf16a1752010-12-09 19:12:32 -08001294 bfa_hton3b(FC_FABRIC_PORT),
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001295 n2n_port->reply_oxid, pcfg->pwwn,
1296 pcfg->nwwn,
1297 bfa_fcport_get_maxfrsize(bfa),
Krishna Gudipatibe540a92011-06-13 15:53:04 -07001298 bfa_fcport_get_rx_bbcredit(bfa),
1299 bfa_fcs_fabric_oper_bbscn(fabric));
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001300
Maggie Zhangf7f738122010-12-09 19:08:43 -08001301 bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->lp_tag,
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001302 BFA_FALSE, FC_CLASS_3,
1303 reqlen, &fchs, bfa_fcs_fabric_flogiacc_comp, fabric,
1304 FC_MAX_PDUSZ, 0);
1305}
1306
Jing Huang5fbe25c2010-10-18 17:17:23 -07001307/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001308 * Flogi Acc completion callback.
1309 */
1310static void
1311bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1312 bfa_status_t status, u32 rsp_len,
1313 u32 resid_len, struct fchs_s *rspfchs)
1314{
1315 struct bfa_fcs_fabric_s *fabric = cbarg;
1316
1317 bfa_trc(fabric->fcs, status);
1318}
1319
1320/*
1321 *
1322 * @param[in] fabric - fabric
1323 * @param[in] wwn_t - new fabric name
1324 *
1325 * @return - none
1326 */
1327void
1328bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1329 wwn_t fabric_name)
1330{
1331 struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
1332 char pwwn_ptr[BFA_STRING_32];
1333 char fwwn_ptr[BFA_STRING_32];
1334
1335 bfa_trc(fabric->fcs, fabric_name);
1336
1337 if (fabric->fabric_name == 0) {
1338 /*
1339 * With BRCD switches, we don't get Fabric Name in FLOGI.
1340 * Don't generate a fabric name change event in this case.
1341 */
1342 fabric->fabric_name = fabric_name;
1343 } else {
1344 fabric->fabric_name = fabric_name;
1345 wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport));
1346 wwn2str(fwwn_ptr,
1347 bfa_fcs_lport_get_fabric_name(&fabric->bport));
Jing Huang88166242010-12-09 17:11:53 -08001348 BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001349 "Base port WWN = %s Fabric WWN = %s\n",
1350 pwwn_ptr, fwwn_ptr);
1351 }
1352}
1353
Jing Huang5fbe25c2010-10-18 17:17:23 -07001354/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001355 * Returns FCS vf structure for a given vf_id.
1356 *
1357 * param[in] vf_id - VF_ID
1358 *
1359 * return
1360 * If lookup succeeds, retuns fcs vf object, otherwise returns NULL
1361 */
1362bfa_fcs_vf_t *
1363bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id)
1364{
1365 bfa_trc(fcs, vf_id);
1366 if (vf_id == FC_VF_ID_NULL)
1367 return &fcs->fabric;
1368
1369 return NULL;
1370}
1371
Jing Huang5fbe25c2010-10-18 17:17:23 -07001372/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001373 * BFA FCS PPORT ( physical port)
1374 */
1375static void
1376bfa_fcs_port_event_handler(void *cbarg, enum bfa_port_linkstate event)
1377{
1378 struct bfa_fcs_s *fcs = cbarg;
1379
1380 bfa_trc(fcs, event);
1381
1382 switch (event) {
1383 case BFA_PORT_LINKUP:
1384 bfa_fcs_fabric_link_up(&fcs->fabric);
1385 break;
1386
1387 case BFA_PORT_LINKDOWN:
1388 bfa_fcs_fabric_link_down(&fcs->fabric);
1389 break;
1390
1391 default:
Jing Huangd4b671c2010-12-26 21:46:35 -08001392 WARN_ON(1);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001393 }
1394}
1395
1396void
1397bfa_fcs_port_attach(struct bfa_fcs_s *fcs)
1398{
1399 bfa_fcport_event_register(fcs->bfa, bfa_fcs_port_event_handler, fcs);
1400}
1401
Jing Huang5fbe25c2010-10-18 17:17:23 -07001402/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001403 * BFA FCS UF ( Unsolicited Frames)
1404 */
1405
Jing Huang5fbe25c2010-10-18 17:17:23 -07001406/*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001407 * BFA callback for unsolicited frame receive handler.
1408 *
1409 * @param[in] cbarg callback arg for receive handler
1410 * @param[in] uf unsolicited frame descriptor
1411 *
1412 * @return None
1413 */
1414static void
1415bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
1416{
1417 struct bfa_fcs_s *fcs = (struct bfa_fcs_s *) cbarg;
1418 struct fchs_s *fchs = bfa_uf_get_frmbuf(uf);
1419 u16 len = bfa_uf_get_frmlen(uf);
1420 struct fc_vft_s *vft;
1421 struct bfa_fcs_fabric_s *fabric;
1422
Jing Huang5fbe25c2010-10-18 17:17:23 -07001423 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001424 * check for VFT header
1425 */
1426 if (fchs->routing == FC_RTG_EXT_HDR &&
1427 fchs->cat_info == FC_CAT_VFT_HDR) {
1428 bfa_stats(fcs, uf.tagged);
1429 vft = bfa_uf_get_frmbuf(uf);
1430 if (fcs->port_vfid == vft->vf_id)
1431 fabric = &fcs->fabric;
1432 else
1433 fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id);
1434
Jing Huang5fbe25c2010-10-18 17:17:23 -07001435 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001436 * drop frame if vfid is unknown
1437 */
1438 if (!fabric) {
Jing Huangd4b671c2010-12-26 21:46:35 -08001439 WARN_ON(1);
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001440 bfa_stats(fcs, uf.vfid_unknown);
1441 bfa_uf_free(uf);
1442 return;
1443 }
1444
Jing Huang5fbe25c2010-10-18 17:17:23 -07001445 /*
Krishna Gudipatia36c61f2010-09-15 11:50:55 -07001446 * skip vft header
1447 */
1448 fchs = (struct fchs_s *) (vft + 1);
1449 len -= sizeof(struct fc_vft_s);
1450
1451 bfa_trc(fcs, vft->vf_id);
1452 } else {
1453 bfa_stats(fcs, uf.untagged);
1454 fabric = &fcs->fabric;
1455 }
1456
1457 bfa_trc(fcs, ((u32 *) fchs)[0]);
1458 bfa_trc(fcs, ((u32 *) fchs)[1]);
1459 bfa_trc(fcs, ((u32 *) fchs)[2]);
1460 bfa_trc(fcs, ((u32 *) fchs)[3]);
1461 bfa_trc(fcs, ((u32 *) fchs)[4]);
1462 bfa_trc(fcs, ((u32 *) fchs)[5]);
1463 bfa_trc(fcs, len);
1464
1465 bfa_fcs_fabric_uf_recv(fabric, fchs, len);
1466 bfa_uf_free(uf);
1467}
1468
1469void
1470bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
1471{
1472 bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
1473}