Blackfin: bf548-ezkit/bf561-ezkit: update nor flash layout
[zen-stable.git] / drivers / scsi / bfa / bfa_fcs.c
blob9b43ca4b67788cd133880b2c647d75bb8859a877
1 /*
2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
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
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.
19 * bfa_fcs.c BFA FCS main
22 #include "bfad_drv.h"
23 #include "bfa_fcs.h"
24 #include "bfa_fcbuild.h"
26 BFA_TRC_FILE(FCS, FCS);
29 * FCS sub-modules
31 struct bfa_fcs_mod_s {
32 void (*attach) (struct bfa_fcs_s *fcs);
33 void (*modinit) (struct bfa_fcs_s *fcs);
34 void (*modexit) (struct bfa_fcs_s *fcs);
37 #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
39 static struct bfa_fcs_mod_s fcs_modules[] = {
40 { bfa_fcs_port_attach, NULL, NULL },
41 { bfa_fcs_uf_attach, NULL, NULL },
42 { bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit,
43 bfa_fcs_fabric_modexit },
47 * fcs_api BFA FCS API
50 static void
51 bfa_fcs_exit_comp(void *fcs_cbarg)
53 struct bfa_fcs_s *fcs = fcs_cbarg;
54 struct bfad_s *bfad = fcs->bfad;
56 complete(&bfad->comp);
62 * fcs_api BFA FCS API
66 * fcs attach -- called once to initialize data structures at driver attach time
68 void
69 bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
70 bfa_boolean_t min_cfg)
72 int i;
73 struct bfa_fcs_mod_s *mod;
75 fcs->bfa = bfa;
76 fcs->bfad = bfad;
77 fcs->min_cfg = min_cfg;
79 bfa->fcs = BFA_TRUE;
80 fcbuild_init();
82 for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
83 mod = &fcs_modules[i];
84 if (mod->attach)
85 mod->attach(fcs);
90 * fcs initialization, called once after bfa initialization is complete
92 void
93 bfa_fcs_init(struct bfa_fcs_s *fcs)
95 int i, npbc_vports;
96 struct bfa_fcs_mod_s *mod;
97 struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];
99 for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
100 mod = &fcs_modules[i];
101 if (mod->modinit)
102 mod->modinit(fcs);
104 /* Initialize pbc vports */
105 if (!fcs->min_cfg) {
106 npbc_vports =
107 bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
108 for (i = 0; i < npbc_vports; i++)
109 bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
115 * brief
116 * FCS driver details initialization.
118 * param[in] fcs FCS instance
119 * param[in] driver_info Driver Details
121 * return None
123 void
124 bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
125 struct bfa_fcs_driver_info_s *driver_info)
128 fcs->driver_info = *driver_info;
130 bfa_fcs_fabric_psymb_init(&fcs->fabric);
134 * brief
135 * FCS instance cleanup and exit.
137 * param[in] fcs FCS instance
138 * return None
140 void
141 bfa_fcs_exit(struct bfa_fcs_s *fcs)
143 struct bfa_fcs_mod_s *mod;
144 int nmods, i;
146 bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
148 nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
150 for (i = 0; i < nmods; i++) {
152 mod = &fcs_modules[i];
153 if (mod->modexit) {
154 bfa_wc_up(&fcs->wc);
155 mod->modexit(fcs);
159 bfa_wc_wait(&fcs->wc);
164 * Fabric module implementation.
167 #define BFA_FCS_FABRIC_RETRY_DELAY (2000) /* Milliseconds */
168 #define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */
170 #define bfa_fcs_fabric_set_opertype(__fabric) do { \
171 if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \
172 == BFA_PORT_TOPOLOGY_P2P) \
173 (__fabric)->oper_type = BFA_PORT_TYPE_NPORT; \
174 else \
175 (__fabric)->oper_type = BFA_PORT_TYPE_NLPORT; \
176 } while (0)
179 * forward declarations
181 static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
182 static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
183 static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
184 static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
185 static void bfa_fcs_fabric_delay(void *cbarg);
186 static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
187 static void bfa_fcs_fabric_delete_comp(void *cbarg);
188 static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
189 struct fchs_s *fchs, u16 len);
190 static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
191 struct fchs_s *fchs, u16 len);
192 static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
193 static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
194 struct bfa_fcxp_s *fcxp, void *cbarg,
195 bfa_status_t status,
196 u32 rsp_len,
197 u32 resid_len,
198 struct fchs_s *rspfchs);
200 static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
201 enum bfa_fcs_fabric_event event);
202 static void bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
203 enum bfa_fcs_fabric_event event);
204 static void bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
205 enum bfa_fcs_fabric_event event);
206 static void bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
207 enum bfa_fcs_fabric_event event);
208 static void bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
209 enum bfa_fcs_fabric_event event);
210 static void bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
211 enum bfa_fcs_fabric_event event);
212 static void bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
213 enum bfa_fcs_fabric_event event);
214 static void bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
215 enum bfa_fcs_fabric_event event);
216 static void bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
217 enum bfa_fcs_fabric_event event);
218 static void bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
219 enum bfa_fcs_fabric_event event);
220 static void bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
221 enum bfa_fcs_fabric_event event);
223 * Beginning state before fabric creation.
225 static void
226 bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
227 enum bfa_fcs_fabric_event event)
229 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
230 bfa_trc(fabric->fcs, event);
232 switch (event) {
233 case BFA_FCS_FABRIC_SM_CREATE:
234 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
235 bfa_fcs_fabric_init(fabric);
236 bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
237 break;
239 case BFA_FCS_FABRIC_SM_LINK_UP:
240 case BFA_FCS_FABRIC_SM_LINK_DOWN:
241 break;
243 default:
244 bfa_sm_fault(fabric->fcs, event);
249 * Beginning state before fabric creation.
251 static void
252 bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
253 enum bfa_fcs_fabric_event event)
255 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
256 bfa_trc(fabric->fcs, event);
258 switch (event) {
259 case BFA_FCS_FABRIC_SM_START:
260 if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
261 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
262 bfa_fcs_fabric_login(fabric);
263 } else
264 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
265 break;
267 case BFA_FCS_FABRIC_SM_LINK_UP:
268 case BFA_FCS_FABRIC_SM_LINK_DOWN:
269 break;
271 case BFA_FCS_FABRIC_SM_DELETE:
272 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
273 bfa_wc_down(&fabric->fcs->wc);
274 break;
276 default:
277 bfa_sm_fault(fabric->fcs, event);
282 * Link is down, awaiting LINK UP event from port. This is also the
283 * first state at fabric creation.
285 static void
286 bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
287 enum bfa_fcs_fabric_event event)
289 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
290 bfa_trc(fabric->fcs, event);
292 switch (event) {
293 case BFA_FCS_FABRIC_SM_LINK_UP:
294 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
295 bfa_fcs_fabric_login(fabric);
296 break;
298 case BFA_FCS_FABRIC_SM_RETRY_OP:
299 break;
301 case BFA_FCS_FABRIC_SM_DELETE:
302 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
303 bfa_fcs_fabric_delete(fabric);
304 break;
306 default:
307 bfa_sm_fault(fabric->fcs, event);
312 * FLOGI is in progress, awaiting FLOGI reply.
314 static void
315 bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
316 enum bfa_fcs_fabric_event event)
318 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
319 bfa_trc(fabric->fcs, event);
321 switch (event) {
322 case BFA_FCS_FABRIC_SM_CONT_OP:
324 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
325 fabric->bb_credit);
326 fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
328 if (fabric->auth_reqd && fabric->is_auth) {
329 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth);
330 bfa_trc(fabric->fcs, event);
331 } else {
332 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
333 bfa_fcs_fabric_notify_online(fabric);
335 break;
337 case BFA_FCS_FABRIC_SM_RETRY_OP:
338 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry);
339 bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer,
340 bfa_fcs_fabric_delay, fabric,
341 BFA_FCS_FABRIC_RETRY_DELAY);
342 break;
344 case BFA_FCS_FABRIC_SM_LOOPBACK:
345 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
346 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
347 bfa_fcs_fabric_set_opertype(fabric);
348 break;
350 case BFA_FCS_FABRIC_SM_NO_FABRIC:
351 fabric->fab_type = BFA_FCS_FABRIC_N2N;
352 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
353 fabric->bb_credit);
354 bfa_fcs_fabric_notify_online(fabric);
355 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
356 break;
358 case BFA_FCS_FABRIC_SM_LINK_DOWN:
359 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
360 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
361 break;
363 case BFA_FCS_FABRIC_SM_DELETE:
364 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
365 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
366 bfa_fcs_fabric_delete(fabric);
367 break;
369 default:
370 bfa_sm_fault(fabric->fcs, event);
375 static void
376 bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
377 enum bfa_fcs_fabric_event event)
379 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
380 bfa_trc(fabric->fcs, event);
382 switch (event) {
383 case BFA_FCS_FABRIC_SM_DELAYED:
384 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
385 bfa_fcs_fabric_login(fabric);
386 break;
388 case BFA_FCS_FABRIC_SM_LINK_DOWN:
389 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
390 bfa_timer_stop(&fabric->delay_timer);
391 break;
393 case BFA_FCS_FABRIC_SM_DELETE:
394 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
395 bfa_timer_stop(&fabric->delay_timer);
396 bfa_fcs_fabric_delete(fabric);
397 break;
399 default:
400 bfa_sm_fault(fabric->fcs, event);
405 * Authentication is in progress, awaiting authentication results.
407 static void
408 bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
409 enum bfa_fcs_fabric_event event)
411 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
412 bfa_trc(fabric->fcs, event);
414 switch (event) {
415 case BFA_FCS_FABRIC_SM_AUTH_FAILED:
416 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
417 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
418 break;
420 case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
421 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
422 bfa_fcs_fabric_notify_online(fabric);
423 break;
425 case BFA_FCS_FABRIC_SM_PERF_EVFP:
426 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp);
427 break;
429 case BFA_FCS_FABRIC_SM_LINK_DOWN:
430 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
431 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
432 break;
434 case BFA_FCS_FABRIC_SM_DELETE:
435 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
436 bfa_fcs_fabric_delete(fabric);
437 break;
439 default:
440 bfa_sm_fault(fabric->fcs, event);
445 * Authentication failed
447 void
448 bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
449 enum bfa_fcs_fabric_event event)
451 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
452 bfa_trc(fabric->fcs, event);
454 switch (event) {
455 case BFA_FCS_FABRIC_SM_LINK_DOWN:
456 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
457 bfa_fcs_fabric_notify_offline(fabric);
458 break;
460 case BFA_FCS_FABRIC_SM_DELETE:
461 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
462 bfa_fcs_fabric_delete(fabric);
463 break;
465 default:
466 bfa_sm_fault(fabric->fcs, event);
471 * Port is in loopback mode.
473 void
474 bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
475 enum bfa_fcs_fabric_event event)
477 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
478 bfa_trc(fabric->fcs, event);
480 switch (event) {
481 case BFA_FCS_FABRIC_SM_LINK_DOWN:
482 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
483 bfa_fcs_fabric_notify_offline(fabric);
484 break;
486 case BFA_FCS_FABRIC_SM_DELETE:
487 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
488 bfa_fcs_fabric_delete(fabric);
489 break;
491 default:
492 bfa_sm_fault(fabric->fcs, event);
497 * There is no attached fabric - private loop or NPort-to-NPort topology.
499 static void
500 bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
501 enum bfa_fcs_fabric_event event)
503 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
504 bfa_trc(fabric->fcs, event);
506 switch (event) {
507 case BFA_FCS_FABRIC_SM_LINK_DOWN:
508 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
509 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
510 bfa_fcs_fabric_notify_offline(fabric);
511 break;
513 case BFA_FCS_FABRIC_SM_DELETE:
514 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
515 bfa_fcs_fabric_delete(fabric);
516 break;
518 case BFA_FCS_FABRIC_SM_NO_FABRIC:
519 bfa_trc(fabric->fcs, fabric->bb_credit);
520 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
521 fabric->bb_credit);
522 break;
524 default:
525 bfa_sm_fault(fabric->fcs, event);
530 * Fabric is online - normal operating state.
532 void
533 bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
534 enum bfa_fcs_fabric_event event)
536 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
537 bfa_trc(fabric->fcs, event);
539 switch (event) {
540 case BFA_FCS_FABRIC_SM_LINK_DOWN:
541 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
542 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
543 bfa_fcs_fabric_notify_offline(fabric);
544 break;
546 case BFA_FCS_FABRIC_SM_DELETE:
547 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
548 bfa_fcs_fabric_delete(fabric);
549 break;
551 case BFA_FCS_FABRIC_SM_AUTH_FAILED:
552 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
553 bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
554 break;
556 case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
557 break;
559 default:
560 bfa_sm_fault(fabric->fcs, event);
565 * Exchanging virtual fabric parameters.
567 static void
568 bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
569 enum bfa_fcs_fabric_event event)
571 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
572 bfa_trc(fabric->fcs, event);
574 switch (event) {
575 case BFA_FCS_FABRIC_SM_CONT_OP:
576 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done);
577 break;
579 case BFA_FCS_FABRIC_SM_ISOLATE:
580 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated);
581 break;
583 default:
584 bfa_sm_fault(fabric->fcs, event);
589 * EVFP exchange complete and VFT tagging is enabled.
591 static void
592 bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
593 enum bfa_fcs_fabric_event event)
595 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
596 bfa_trc(fabric->fcs, event);
600 * Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
602 static void
603 bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
604 enum bfa_fcs_fabric_event event)
606 struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
607 char pwwn_ptr[BFA_STRING_32];
609 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
610 bfa_trc(fabric->fcs, event);
611 wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn);
613 BFA_LOG(KERN_INFO, bfad, bfa_log_level,
614 "Port is isolated due to VF_ID mismatch. "
615 "PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.",
616 pwwn_ptr, fabric->fcs->port_vfid,
617 fabric->event_arg.swp_vfid);
621 * Fabric is being deleted, awaiting vport delete completions.
623 static void
624 bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
625 enum bfa_fcs_fabric_event event)
627 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
628 bfa_trc(fabric->fcs, event);
630 switch (event) {
631 case BFA_FCS_FABRIC_SM_DELCOMP:
632 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
633 bfa_wc_down(&fabric->fcs->wc);
634 break;
636 case BFA_FCS_FABRIC_SM_LINK_UP:
637 break;
639 case BFA_FCS_FABRIC_SM_LINK_DOWN:
640 bfa_fcs_fabric_notify_offline(fabric);
641 break;
643 default:
644 bfa_sm_fault(fabric->fcs, event);
651 * fcs_fabric_private fabric private functions
654 static void
655 bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
657 struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
659 port_cfg->roles = BFA_LPORT_ROLE_FCP_IM;
660 port_cfg->nwwn = fabric->fcs->bfa->ioc.attr->nwwn;
661 port_cfg->pwwn = fabric->fcs->bfa->ioc.attr->pwwn;
665 * Port Symbolic Name Creation for base port.
667 void
668 bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
670 struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
671 char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
672 struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
674 bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
676 /* Model name/number */
677 strncpy((char *)&port_cfg->sym_name, model,
678 BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
679 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
680 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
682 /* Driver Version */
683 strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
684 BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
685 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
686 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
688 /* Host machine name */
689 strncat((char *)&port_cfg->sym_name,
690 (char *)driver_info->host_machine_name,
691 BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
692 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
693 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
696 * Host OS Info :
697 * If OS Patch Info is not there, do not truncate any bytes from the
698 * OS name string and instead copy the entire OS info string (64 bytes).
700 if (driver_info->host_os_patch[0] == '\0') {
701 strncat((char *)&port_cfg->sym_name,
702 (char *)driver_info->host_os_name,
703 BFA_FCS_OS_STR_LEN);
704 strncat((char *)&port_cfg->sym_name,
705 BFA_FCS_PORT_SYMBNAME_SEPARATOR,
706 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
707 } else {
708 strncat((char *)&port_cfg->sym_name,
709 (char *)driver_info->host_os_name,
710 BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
711 strncat((char *)&port_cfg->sym_name,
712 BFA_FCS_PORT_SYMBNAME_SEPARATOR,
713 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
715 /* Append host OS Patch Info */
716 strncat((char *)&port_cfg->sym_name,
717 (char *)driver_info->host_os_patch,
718 BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
721 /* null terminate */
722 port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
726 * bfa lps login completion callback
728 void
729 bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
731 struct bfa_fcs_fabric_s *fabric = uarg;
733 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
734 bfa_trc(fabric->fcs, status);
736 switch (status) {
737 case BFA_STATUS_OK:
738 fabric->stats.flogi_accepts++;
739 break;
741 case BFA_STATUS_INVALID_MAC:
742 /* Only for CNA */
743 fabric->stats.flogi_acc_err++;
744 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
746 return;
748 case BFA_STATUS_EPROTOCOL:
749 switch (fabric->lps->ext_status) {
750 case BFA_EPROTO_BAD_ACCEPT:
751 fabric->stats.flogi_acc_err++;
752 break;
754 case BFA_EPROTO_UNKNOWN_RSP:
755 fabric->stats.flogi_unknown_rsp++;
756 break;
758 default:
759 break;
761 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
763 return;
765 case BFA_STATUS_FABRIC_RJT:
766 fabric->stats.flogi_rejects++;
767 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
768 return;
770 default:
771 fabric->stats.flogi_rsp_err++;
772 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
773 return;
776 fabric->bb_credit = fabric->lps->pr_bbcred;
777 bfa_trc(fabric->fcs, fabric->bb_credit);
779 if (!(fabric->lps->brcd_switch))
780 fabric->fabric_name = fabric->lps->pr_nwwn;
783 * Check port type. It should be 1 = F-port.
785 if (fabric->lps->fport) {
786 fabric->bport.pid = fabric->lps->lp_pid;
787 fabric->is_npiv = fabric->lps->npiv_en;
788 fabric->is_auth = fabric->lps->auth_req;
789 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
790 } else {
792 * Nport-2-Nport direct attached
794 fabric->bport.port_topo.pn2n.rem_port_wwn =
795 fabric->lps->pr_pwwn;
796 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
799 bfa_trc(fabric->fcs, fabric->bport.pid);
800 bfa_trc(fabric->fcs, fabric->is_npiv);
801 bfa_trc(fabric->fcs, fabric->is_auth);
804 * Allocate and send FLOGI.
806 static void
807 bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
809 struct bfa_s *bfa = fabric->fcs->bfa;
810 struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
811 u8 alpa = 0;
813 if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
814 alpa = bfa_fcport_get_myalpa(bfa);
816 bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
817 pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
819 fabric->stats.flogi_sent++;
822 static void
823 bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
825 struct bfa_fcs_vport_s *vport;
826 struct list_head *qe, *qen;
828 bfa_trc(fabric->fcs, fabric->fabric_name);
830 bfa_fcs_fabric_set_opertype(fabric);
831 fabric->stats.fabric_onlines++;
834 * notify online event to base and then virtual ports
836 bfa_fcs_lport_online(&fabric->bport);
838 list_for_each_safe(qe, qen, &fabric->vport_q) {
839 vport = (struct bfa_fcs_vport_s *) qe;
840 bfa_fcs_vport_online(vport);
844 static void
845 bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
847 struct bfa_fcs_vport_s *vport;
848 struct list_head *qe, *qen;
850 bfa_trc(fabric->fcs, fabric->fabric_name);
851 fabric->stats.fabric_offlines++;
854 * notify offline event first to vports and then base port.
856 list_for_each_safe(qe, qen, &fabric->vport_q) {
857 vport = (struct bfa_fcs_vport_s *) qe;
858 bfa_fcs_vport_offline(vport);
861 bfa_fcs_lport_offline(&fabric->bport);
863 fabric->fabric_name = 0;
864 fabric->fabric_ip_addr[0] = 0;
867 static void
868 bfa_fcs_fabric_delay(void *cbarg)
870 struct bfa_fcs_fabric_s *fabric = cbarg;
872 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
876 * Delete all vports and wait for vport delete completions.
878 static void
879 bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
881 struct bfa_fcs_vport_s *vport;
882 struct list_head *qe, *qen;
884 list_for_each_safe(qe, qen, &fabric->vport_q) {
885 vport = (struct bfa_fcs_vport_s *) qe;
886 bfa_fcs_vport_fcs_delete(vport);
889 bfa_fcs_lport_delete(&fabric->bport);
890 bfa_wc_wait(&fabric->wc);
893 static void
894 bfa_fcs_fabric_delete_comp(void *cbarg)
896 struct bfa_fcs_fabric_s *fabric = cbarg;
898 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
902 * fcs_fabric_public fabric public functions
906 * Attach time initialization.
908 void
909 bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
911 struct bfa_fcs_fabric_s *fabric;
913 fabric = &fcs->fabric;
914 memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
917 * Initialize base fabric.
919 fabric->fcs = fcs;
920 INIT_LIST_HEAD(&fabric->vport_q);
921 INIT_LIST_HEAD(&fabric->vf_q);
922 fabric->lps = bfa_lps_alloc(fcs->bfa);
923 WARN_ON(!fabric->lps);
926 * Initialize fabric delete completion handler. Fabric deletion is
927 * complete when the last vport delete is complete.
929 bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric);
930 bfa_wc_up(&fabric->wc); /* For the base port */
932 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
933 bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
936 void
937 bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
939 bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
940 bfa_trc(fcs, 0);
944 * Module cleanup
946 void
947 bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
949 struct bfa_fcs_fabric_s *fabric;
951 bfa_trc(fcs, 0);
954 * Cleanup base fabric.
956 fabric = &fcs->fabric;
957 bfa_lps_delete(fabric->lps);
958 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE);
962 * Fabric module start -- kick starts FCS actions
964 void
965 bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
967 struct bfa_fcs_fabric_s *fabric;
969 bfa_trc(fcs, 0);
970 fabric = &fcs->fabric;
971 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
976 * Link up notification from BFA physical port module.
978 void
979 bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
981 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
982 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
986 * Link down notification from BFA physical port module.
988 void
989 bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
991 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
992 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
996 * A child vport is being created in the fabric.
998 * Call from vport module at vport creation. A list of base port and vports
999 * belonging to a fabric is maintained to propagate link events.
1001 * param[in] fabric - Fabric instance. This can be a base fabric or vf.
1002 * param[in] vport - Vport being created.
1004 * @return None (always succeeds)
1006 void
1007 bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
1008 struct bfa_fcs_vport_s *vport)
1011 * - add vport to fabric's vport_q
1013 bfa_trc(fabric->fcs, fabric->vf_id);
1015 list_add_tail(&vport->qe, &fabric->vport_q);
1016 fabric->num_vports++;
1017 bfa_wc_up(&fabric->wc);
1021 * A child vport is being deleted from fabric.
1023 * Vport is being deleted.
1025 void
1026 bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
1027 struct bfa_fcs_vport_s *vport)
1029 list_del(&vport->qe);
1030 fabric->num_vports--;
1031 bfa_wc_down(&fabric->wc);
1036 * Lookup for a vport within a fabric given its pwwn
1038 struct bfa_fcs_vport_s *
1039 bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
1041 struct bfa_fcs_vport_s *vport;
1042 struct list_head *qe;
1044 list_for_each(qe, &fabric->vport_q) {
1045 vport = (struct bfa_fcs_vport_s *) qe;
1046 if (bfa_fcs_lport_get_pwwn(&vport->lport) == pwwn)
1047 return vport;
1050 return NULL;
1055 * Get OUI of the attached switch.
1057 * Note : Use of this function should be avoided as much as possible.
1058 * This function should be used only if there is any requirement
1059 * to check for FOS version below 6.3.
1060 * To check if the attached fabric is a brocade fabric, use
1061 * bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
1062 * or above only.
1066 bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
1068 wwn_t fab_nwwn;
1069 u8 *tmp;
1070 u16 oui;
1072 fab_nwwn = fabric->lps->pr_nwwn;
1074 tmp = (u8 *)&fab_nwwn;
1075 oui = (tmp[3] << 8) | tmp[4];
1077 return oui;
1080 * Unsolicited frame receive handling.
1082 void
1083 bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1084 u16 len)
1086 u32 pid = fchs->d_id;
1087 struct bfa_fcs_vport_s *vport;
1088 struct list_head *qe;
1089 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1090 struct fc_logi_s *flogi = (struct fc_logi_s *) els_cmd;
1092 bfa_trc(fabric->fcs, len);
1093 bfa_trc(fabric->fcs, pid);
1096 * Look for our own FLOGI frames being looped back. This means an
1097 * external loopback cable is in place. Our own FLOGI frames are
1098 * sometimes looped back when switch port gets temporarily bypassed.
1100 if ((pid == bfa_ntoh3b(FC_FABRIC_PORT)) &&
1101 (els_cmd->els_code == FC_ELS_FLOGI) &&
1102 (flogi->port_name == bfa_fcs_lport_get_pwwn(&fabric->bport))) {
1103 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
1104 return;
1108 * FLOGI/EVFP exchanges should be consumed by base fabric.
1110 if (fchs->d_id == bfa_hton3b(FC_FABRIC_PORT)) {
1111 bfa_trc(fabric->fcs, pid);
1112 bfa_fcs_fabric_process_uf(fabric, fchs, len);
1113 return;
1116 if (fabric->bport.pid == pid) {
1118 * All authentication frames should be routed to auth
1120 bfa_trc(fabric->fcs, els_cmd->els_code);
1121 if (els_cmd->els_code == FC_ELS_AUTH) {
1122 bfa_trc(fabric->fcs, els_cmd->els_code);
1123 return;
1126 bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
1127 bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
1128 return;
1132 * look for a matching local port ID
1134 list_for_each(qe, &fabric->vport_q) {
1135 vport = (struct bfa_fcs_vport_s *) qe;
1136 if (vport->lport.pid == pid) {
1137 bfa_fcs_lport_uf_recv(&vport->lport, fchs, len);
1138 return;
1141 bfa_trc(fabric->fcs, els_cmd->els_code);
1142 bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len);
1146 * Unsolicited frames to be processed by fabric.
1148 static void
1149 bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1150 u16 len)
1152 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1154 bfa_trc(fabric->fcs, els_cmd->els_code);
1156 switch (els_cmd->els_code) {
1157 case FC_ELS_FLOGI:
1158 bfa_fcs_fabric_process_flogi(fabric, fchs, len);
1159 break;
1161 default:
1163 * need to generate a LS_RJT
1165 break;
1170 * Process incoming FLOGI
1172 static void
1173 bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
1174 struct fchs_s *fchs, u16 len)
1176 struct fc_logi_s *flogi = (struct fc_logi_s *) (fchs + 1);
1177 struct bfa_fcs_lport_s *bport = &fabric->bport;
1179 bfa_trc(fabric->fcs, fchs->s_id);
1181 fabric->stats.flogi_rcvd++;
1183 * Check port type. It should be 0 = n-port.
1185 if (flogi->csp.port_type) {
1187 * @todo: may need to send a LS_RJT
1189 bfa_trc(fabric->fcs, flogi->port_name);
1190 fabric->stats.flogi_rejected++;
1191 return;
1194 fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred);
1195 bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
1196 bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
1199 * Send a Flogi Acc
1201 bfa_fcs_fabric_send_flogi_acc(fabric);
1202 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
1205 static void
1206 bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1208 struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
1209 struct bfa_fcs_lport_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
1210 struct bfa_s *bfa = fabric->fcs->bfa;
1211 struct bfa_fcxp_s *fcxp;
1212 u16 reqlen;
1213 struct fchs_s fchs;
1215 fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
1217 * Do not expect this failure -- expect remote node to retry
1219 if (!fcxp)
1220 return;
1222 reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1223 bfa_hton3b(FC_FABRIC_PORT),
1224 n2n_port->reply_oxid, pcfg->pwwn,
1225 pcfg->nwwn,
1226 bfa_fcport_get_maxfrsize(bfa),
1227 bfa_fcport_get_rx_bbcredit(bfa));
1229 bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->lp_tag,
1230 BFA_FALSE, FC_CLASS_3,
1231 reqlen, &fchs, bfa_fcs_fabric_flogiacc_comp, fabric,
1232 FC_MAX_PDUSZ, 0);
1236 * Flogi Acc completion callback.
1238 static void
1239 bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1240 bfa_status_t status, u32 rsp_len,
1241 u32 resid_len, struct fchs_s *rspfchs)
1243 struct bfa_fcs_fabric_s *fabric = cbarg;
1245 bfa_trc(fabric->fcs, status);
1250 * @param[in] fabric - fabric
1251 * @param[in] wwn_t - new fabric name
1253 * @return - none
1255 void
1256 bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1257 wwn_t fabric_name)
1259 struct bfad_s *bfad = (struct bfad_s *)fabric->fcs->bfad;
1260 char pwwn_ptr[BFA_STRING_32];
1261 char fwwn_ptr[BFA_STRING_32];
1263 bfa_trc(fabric->fcs, fabric_name);
1265 if (fabric->fabric_name == 0) {
1267 * With BRCD switches, we don't get Fabric Name in FLOGI.
1268 * Don't generate a fabric name change event in this case.
1270 fabric->fabric_name = fabric_name;
1271 } else {
1272 fabric->fabric_name = fabric_name;
1273 wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport));
1274 wwn2str(fwwn_ptr,
1275 bfa_fcs_lport_get_fabric_name(&fabric->bport));
1276 BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
1277 "Base port WWN = %s Fabric WWN = %s\n",
1278 pwwn_ptr, fwwn_ptr);
1283 * Returns FCS vf structure for a given vf_id.
1285 * param[in] vf_id - VF_ID
1287 * return
1288 * If lookup succeeds, retuns fcs vf object, otherwise returns NULL
1290 bfa_fcs_vf_t *
1291 bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id)
1293 bfa_trc(fcs, vf_id);
1294 if (vf_id == FC_VF_ID_NULL)
1295 return &fcs->fabric;
1297 return NULL;
1301 * BFA FCS PPORT ( physical port)
1303 static void
1304 bfa_fcs_port_event_handler(void *cbarg, enum bfa_port_linkstate event)
1306 struct bfa_fcs_s *fcs = cbarg;
1308 bfa_trc(fcs, event);
1310 switch (event) {
1311 case BFA_PORT_LINKUP:
1312 bfa_fcs_fabric_link_up(&fcs->fabric);
1313 break;
1315 case BFA_PORT_LINKDOWN:
1316 bfa_fcs_fabric_link_down(&fcs->fabric);
1317 break;
1319 default:
1320 WARN_ON(1);
1324 void
1325 bfa_fcs_port_attach(struct bfa_fcs_s *fcs)
1327 bfa_fcport_event_register(fcs->bfa, bfa_fcs_port_event_handler, fcs);
1331 * BFA FCS UF ( Unsolicited Frames)
1335 * BFA callback for unsolicited frame receive handler.
1337 * @param[in] cbarg callback arg for receive handler
1338 * @param[in] uf unsolicited frame descriptor
1340 * @return None
1342 static void
1343 bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
1345 struct bfa_fcs_s *fcs = (struct bfa_fcs_s *) cbarg;
1346 struct fchs_s *fchs = bfa_uf_get_frmbuf(uf);
1347 u16 len = bfa_uf_get_frmlen(uf);
1348 struct fc_vft_s *vft;
1349 struct bfa_fcs_fabric_s *fabric;
1352 * check for VFT header
1354 if (fchs->routing == FC_RTG_EXT_HDR &&
1355 fchs->cat_info == FC_CAT_VFT_HDR) {
1356 bfa_stats(fcs, uf.tagged);
1357 vft = bfa_uf_get_frmbuf(uf);
1358 if (fcs->port_vfid == vft->vf_id)
1359 fabric = &fcs->fabric;
1360 else
1361 fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id);
1364 * drop frame if vfid is unknown
1366 if (!fabric) {
1367 WARN_ON(1);
1368 bfa_stats(fcs, uf.vfid_unknown);
1369 bfa_uf_free(uf);
1370 return;
1374 * skip vft header
1376 fchs = (struct fchs_s *) (vft + 1);
1377 len -= sizeof(struct fc_vft_s);
1379 bfa_trc(fcs, vft->vf_id);
1380 } else {
1381 bfa_stats(fcs, uf.untagged);
1382 fabric = &fcs->fabric;
1385 bfa_trc(fcs, ((u32 *) fchs)[0]);
1386 bfa_trc(fcs, ((u32 *) fchs)[1]);
1387 bfa_trc(fcs, ((u32 *) fchs)[2]);
1388 bfa_trc(fcs, ((u32 *) fchs)[3]);
1389 bfa_trc(fcs, ((u32 *) fchs)[4]);
1390 bfa_trc(fcs, ((u32 *) fchs)[5]);
1391 bfa_trc(fcs, len);
1393 bfa_fcs_fabric_uf_recv(fabric, fchs, len);
1394 bfa_uf_free(uf);
1397 void
1398 bfa_fcs_uf_attach(struct bfa_fcs_s *fcs)
1400 bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);