2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
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
25 #include "bfa_fcbuild.h"
27 BFA_TRC_FILE(FCS
, FCS
);
32 struct bfa_fcs_mod_s
{
33 void (*attach
) (struct bfa_fcs_s
*fcs
);
34 void (*modinit
) (struct bfa_fcs_s
*fcs
);
35 void (*modexit
) (struct bfa_fcs_s
*fcs
);
38 #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
40 static struct bfa_fcs_mod_s fcs_modules
[] = {
41 { bfa_fcs_port_attach
, NULL
, NULL
},
42 { bfa_fcs_uf_attach
, NULL
, NULL
},
43 { bfa_fcs_fabric_attach
, bfa_fcs_fabric_modinit
,
44 bfa_fcs_fabric_modexit
},
52 bfa_fcs_exit_comp(void *fcs_cbarg
)
54 struct bfa_fcs_s
*fcs
= fcs_cbarg
;
55 struct bfad_s
*bfad
= fcs
->bfad
;
57 complete(&bfad
->comp
);
67 * fcs attach -- called once to initialize data structures at driver attach time
70 bfa_fcs_attach(struct bfa_fcs_s
*fcs
, struct bfa_s
*bfa
, struct bfad_s
*bfad
,
71 bfa_boolean_t min_cfg
)
74 struct bfa_fcs_mod_s
*mod
;
78 fcs
->min_cfg
= min_cfg
;
83 for (i
= 0; i
< sizeof(fcs_modules
) / sizeof(fcs_modules
[0]); i
++) {
84 mod
= &fcs_modules
[i
];
91 * fcs initialization, called once after bfa initialization is complete
94 bfa_fcs_init(struct bfa_fcs_s
*fcs
)
97 struct bfa_fcs_mod_s
*mod
;
99 for (i
= 0; i
< sizeof(fcs_modules
) / sizeof(fcs_modules
[0]); i
++) {
100 mod
= &fcs_modules
[i
];
107 * FCS update cfg - reset the pwwn/nwwn of fabric base logical port
108 * with values learned during bfa_init firmware GETATTR REQ.
111 bfa_fcs_update_cfg(struct bfa_fcs_s
*fcs
)
113 struct bfa_fcs_fabric_s
*fabric
= &fcs
->fabric
;
114 struct bfa_lport_cfg_s
*port_cfg
= &fabric
->bport
.port_cfg
;
115 struct bfa_ioc_s
*ioc
= &fabric
->fcs
->bfa
->ioc
;
117 port_cfg
->nwwn
= ioc
->attr
->nwwn
;
118 port_cfg
->pwwn
= ioc
->attr
->pwwn
;
122 * fcs pbc vport initialization
125 bfa_fcs_pbc_vport_init(struct bfa_fcs_s
*fcs
)
128 struct bfi_pbc_vport_s pbc_vports
[BFI_PBC_MAX_VPORTS
];
130 /* Initialize pbc vports */
133 bfa_iocfc_get_pbc_vports(fcs
->bfa
, pbc_vports
);
134 for (i
= 0; i
< npbc_vports
; i
++)
135 bfa_fcb_pbc_vport_create(fcs
->bfa
->bfad
, pbc_vports
[i
]);
141 * FCS driver details initialization.
143 * param[in] fcs FCS instance
144 * param[in] driver_info Driver Details
149 bfa_fcs_driver_info_init(struct bfa_fcs_s
*fcs
,
150 struct bfa_fcs_driver_info_s
*driver_info
)
153 fcs
->driver_info
= *driver_info
;
155 bfa_fcs_fabric_psymb_init(&fcs
->fabric
);
160 * FCS instance cleanup and exit.
162 * param[in] fcs FCS instance
166 bfa_fcs_exit(struct bfa_fcs_s
*fcs
)
168 struct bfa_fcs_mod_s
*mod
;
171 bfa_wc_init(&fcs
->wc
, bfa_fcs_exit_comp
, fcs
);
173 nmods
= sizeof(fcs_modules
) / sizeof(fcs_modules
[0]);
175 for (i
= 0; i
< nmods
; i
++) {
177 mod
= &fcs_modules
[i
];
184 bfa_wc_wait(&fcs
->wc
);
189 * Fabric module implementation.
192 #define BFA_FCS_FABRIC_RETRY_DELAY (2000) /* Milliseconds */
193 #define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */
195 #define bfa_fcs_fabric_set_opertype(__fabric) do { \
196 if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \
197 == BFA_PORT_TOPOLOGY_P2P) { \
198 if (fabric->fab_type == BFA_FCS_FABRIC_SWITCHED) \
199 (__fabric)->oper_type = BFA_PORT_TYPE_NPORT; \
201 (__fabric)->oper_type = BFA_PORT_TYPE_P2P; \
203 (__fabric)->oper_type = BFA_PORT_TYPE_NLPORT; \
207 * forward declarations
209 static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s
*fabric
);
210 static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s
*fabric
);
211 static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s
*fabric
);
212 static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s
*fabric
);
213 static void bfa_fcs_fabric_delay(void *cbarg
);
214 static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s
*fabric
);
215 static void bfa_fcs_fabric_delete_comp(void *cbarg
);
216 static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s
*fabric
,
217 struct fchs_s
*fchs
, u16 len
);
218 static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s
*fabric
,
219 struct fchs_s
*fchs
, u16 len
);
220 static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s
*fabric
);
221 static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg
,
222 struct bfa_fcxp_s
*fcxp
, void *cbarg
,
226 struct fchs_s
*rspfchs
);
227 static u8
bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s
*fabric
);
228 static bfa_boolean_t
bfa_fcs_fabric_is_bbscn_enabled(
229 struct bfa_fcs_fabric_s
*fabric
);
231 static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s
*fabric
,
232 enum bfa_fcs_fabric_event event
);
233 static void bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s
*fabric
,
234 enum bfa_fcs_fabric_event event
);
235 static void bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s
*fabric
,
236 enum bfa_fcs_fabric_event event
);
237 static void bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s
*fabric
,
238 enum bfa_fcs_fabric_event event
);
239 static void bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s
*fabric
,
240 enum bfa_fcs_fabric_event event
);
241 static void bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s
*fabric
,
242 enum bfa_fcs_fabric_event event
);
243 static void bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s
*fabric
,
244 enum bfa_fcs_fabric_event event
);
245 static void bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s
*fabric
,
246 enum bfa_fcs_fabric_event event
);
247 static void bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s
*fabric
,
248 enum bfa_fcs_fabric_event event
);
249 static void bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s
*fabric
,
250 enum bfa_fcs_fabric_event event
);
251 static void bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s
*fabric
,
252 enum bfa_fcs_fabric_event event
);
254 * Beginning state before fabric creation.
257 bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s
*fabric
,
258 enum bfa_fcs_fabric_event event
)
260 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
261 bfa_trc(fabric
->fcs
, event
);
264 case BFA_FCS_FABRIC_SM_CREATE
:
265 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_created
);
266 bfa_fcs_fabric_init(fabric
);
267 bfa_fcs_lport_init(&fabric
->bport
, &fabric
->bport
.port_cfg
);
270 case BFA_FCS_FABRIC_SM_LINK_UP
:
271 case BFA_FCS_FABRIC_SM_LINK_DOWN
:
275 bfa_sm_fault(fabric
->fcs
, event
);
280 * Beginning state before fabric creation.
283 bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s
*fabric
,
284 enum bfa_fcs_fabric_event event
)
286 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
287 bfa_trc(fabric
->fcs
, event
);
290 case BFA_FCS_FABRIC_SM_START
:
291 if (bfa_fcport_is_linkup(fabric
->fcs
->bfa
)) {
292 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_flogi
);
293 bfa_fcs_fabric_login(fabric
);
295 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_linkdown
);
298 case BFA_FCS_FABRIC_SM_LINK_UP
:
299 case BFA_FCS_FABRIC_SM_LINK_DOWN
:
302 case BFA_FCS_FABRIC_SM_DELETE
:
303 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_deleting
);
304 bfa_fcs_fabric_delete(fabric
);
308 bfa_sm_fault(fabric
->fcs
, event
);
313 * Link is down, awaiting LINK UP event from port. This is also the
314 * first state at fabric creation.
317 bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s
*fabric
,
318 enum bfa_fcs_fabric_event event
)
320 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
321 bfa_trc(fabric
->fcs
, event
);
324 case BFA_FCS_FABRIC_SM_LINK_UP
:
325 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_flogi
);
326 bfa_fcs_fabric_login(fabric
);
329 case BFA_FCS_FABRIC_SM_RETRY_OP
:
332 case BFA_FCS_FABRIC_SM_DELETE
:
333 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_deleting
);
334 bfa_fcs_fabric_delete(fabric
);
338 bfa_sm_fault(fabric
->fcs
, event
);
343 * FLOGI is in progress, awaiting FLOGI reply.
346 bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s
*fabric
,
347 enum bfa_fcs_fabric_event event
)
349 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
350 bfa_trc(fabric
->fcs
, event
);
353 case BFA_FCS_FABRIC_SM_CONT_OP
:
355 bfa_fcport_set_tx_bbcredit(fabric
->fcs
->bfa
,
357 bfa_fcs_fabric_oper_bbscn(fabric
));
358 fabric
->fab_type
= BFA_FCS_FABRIC_SWITCHED
;
360 if (fabric
->auth_reqd
&& fabric
->is_auth
) {
361 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_auth
);
362 bfa_trc(fabric
->fcs
, event
);
364 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_online
);
365 bfa_fcs_fabric_notify_online(fabric
);
369 case BFA_FCS_FABRIC_SM_RETRY_OP
:
370 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_flogi_retry
);
371 bfa_timer_start(fabric
->fcs
->bfa
, &fabric
->delay_timer
,
372 bfa_fcs_fabric_delay
, fabric
,
373 BFA_FCS_FABRIC_RETRY_DELAY
);
376 case BFA_FCS_FABRIC_SM_LOOPBACK
:
377 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_loopback
);
378 bfa_sm_send_event(fabric
->lps
, BFA_LPS_SM_OFFLINE
);
379 bfa_fcs_fabric_set_opertype(fabric
);
382 case BFA_FCS_FABRIC_SM_NO_FABRIC
:
383 fabric
->fab_type
= BFA_FCS_FABRIC_N2N
;
384 bfa_fcport_set_tx_bbcredit(fabric
->fcs
->bfa
,
386 bfa_fcs_fabric_oper_bbscn(fabric
));
387 bfa_fcs_fabric_notify_online(fabric
);
388 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_nofabric
);
391 case BFA_FCS_FABRIC_SM_LINK_DOWN
:
392 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_linkdown
);
393 bfa_sm_send_event(fabric
->lps
, BFA_LPS_SM_OFFLINE
);
396 case BFA_FCS_FABRIC_SM_DELETE
:
397 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_deleting
);
398 bfa_sm_send_event(fabric
->lps
, BFA_LPS_SM_OFFLINE
);
399 bfa_fcs_fabric_delete(fabric
);
403 bfa_sm_fault(fabric
->fcs
, event
);
409 bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s
*fabric
,
410 enum bfa_fcs_fabric_event event
)
412 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
413 bfa_trc(fabric
->fcs
, event
);
416 case BFA_FCS_FABRIC_SM_DELAYED
:
417 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_flogi
);
418 bfa_fcs_fabric_login(fabric
);
421 case BFA_FCS_FABRIC_SM_LINK_DOWN
:
422 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_linkdown
);
423 bfa_timer_stop(&fabric
->delay_timer
);
426 case BFA_FCS_FABRIC_SM_DELETE
:
427 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_deleting
);
428 bfa_timer_stop(&fabric
->delay_timer
);
429 bfa_fcs_fabric_delete(fabric
);
433 bfa_sm_fault(fabric
->fcs
, event
);
438 * Authentication is in progress, awaiting authentication results.
441 bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s
*fabric
,
442 enum bfa_fcs_fabric_event event
)
444 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
445 bfa_trc(fabric
->fcs
, event
);
448 case BFA_FCS_FABRIC_SM_AUTH_FAILED
:
449 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_auth_failed
);
450 bfa_sm_send_event(fabric
->lps
, BFA_LPS_SM_OFFLINE
);
453 case BFA_FCS_FABRIC_SM_AUTH_SUCCESS
:
454 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_online
);
455 bfa_fcs_fabric_notify_online(fabric
);
458 case BFA_FCS_FABRIC_SM_PERF_EVFP
:
459 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_evfp
);
462 case BFA_FCS_FABRIC_SM_LINK_DOWN
:
463 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_linkdown
);
464 bfa_sm_send_event(fabric
->lps
, BFA_LPS_SM_OFFLINE
);
467 case BFA_FCS_FABRIC_SM_DELETE
:
468 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_deleting
);
469 bfa_fcs_fabric_delete(fabric
);
473 bfa_sm_fault(fabric
->fcs
, event
);
478 * Authentication failed
481 bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s
*fabric
,
482 enum bfa_fcs_fabric_event event
)
484 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
485 bfa_trc(fabric
->fcs
, event
);
488 case BFA_FCS_FABRIC_SM_LINK_DOWN
:
489 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_linkdown
);
490 bfa_fcs_fabric_notify_offline(fabric
);
493 case BFA_FCS_FABRIC_SM_DELETE
:
494 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_deleting
);
495 bfa_fcs_fabric_delete(fabric
);
499 bfa_sm_fault(fabric
->fcs
, event
);
504 * Port is in loopback mode.
507 bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s
*fabric
,
508 enum bfa_fcs_fabric_event event
)
510 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
511 bfa_trc(fabric
->fcs
, event
);
514 case BFA_FCS_FABRIC_SM_LINK_DOWN
:
515 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_linkdown
);
516 bfa_fcs_fabric_notify_offline(fabric
);
519 case BFA_FCS_FABRIC_SM_DELETE
:
520 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_deleting
);
521 bfa_fcs_fabric_delete(fabric
);
525 bfa_sm_fault(fabric
->fcs
, event
);
530 * There is no attached fabric - private loop or NPort-to-NPort topology.
533 bfa_fcs_fabric_sm_nofabric(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
);
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
);
546 case BFA_FCS_FABRIC_SM_DELETE
:
547 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_deleting
);
548 bfa_fcs_fabric_delete(fabric
);
551 case BFA_FCS_FABRIC_SM_NO_FABRIC
:
552 bfa_trc(fabric
->fcs
, fabric
->bb_credit
);
553 bfa_fcport_set_tx_bbcredit(fabric
->fcs
->bfa
,
555 bfa_fcs_fabric_oper_bbscn(fabric
));
558 case BFA_FCS_FABRIC_SM_RETRY_OP
:
562 bfa_sm_fault(fabric
->fcs
, event
);
567 * Fabric is online - normal operating state.
570 bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s
*fabric
,
571 enum bfa_fcs_fabric_event event
)
573 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
574 bfa_trc(fabric
->fcs
, event
);
577 case BFA_FCS_FABRIC_SM_LINK_DOWN
:
578 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_linkdown
);
579 bfa_sm_send_event(fabric
->lps
, BFA_LPS_SM_OFFLINE
);
580 bfa_fcs_fabric_notify_offline(fabric
);
583 case BFA_FCS_FABRIC_SM_DELETE
:
584 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_deleting
);
585 bfa_fcs_fabric_delete(fabric
);
588 case BFA_FCS_FABRIC_SM_AUTH_FAILED
:
589 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_auth_failed
);
590 bfa_sm_send_event(fabric
->lps
, BFA_LPS_SM_OFFLINE
);
593 case BFA_FCS_FABRIC_SM_AUTH_SUCCESS
:
597 bfa_sm_fault(fabric
->fcs
, event
);
602 * Exchanging virtual fabric parameters.
605 bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s
*fabric
,
606 enum bfa_fcs_fabric_event event
)
608 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
609 bfa_trc(fabric
->fcs
, event
);
612 case BFA_FCS_FABRIC_SM_CONT_OP
:
613 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_evfp_done
);
616 case BFA_FCS_FABRIC_SM_ISOLATE
:
617 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_isolated
);
621 bfa_sm_fault(fabric
->fcs
, event
);
626 * EVFP exchange complete and VFT tagging is enabled.
629 bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s
*fabric
,
630 enum bfa_fcs_fabric_event event
)
632 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
633 bfa_trc(fabric
->fcs
, event
);
637 * Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
640 bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s
*fabric
,
641 enum bfa_fcs_fabric_event event
)
643 struct bfad_s
*bfad
= (struct bfad_s
*)fabric
->fcs
->bfad
;
644 char pwwn_ptr
[BFA_STRING_32
];
646 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
647 bfa_trc(fabric
->fcs
, event
);
648 wwn2str(pwwn_ptr
, fabric
->bport
.port_cfg
.pwwn
);
650 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
651 "Port is isolated due to VF_ID mismatch. "
652 "PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.",
653 pwwn_ptr
, fabric
->fcs
->port_vfid
,
654 fabric
->event_arg
.swp_vfid
);
658 * Fabric is being deleted, awaiting vport delete completions.
661 bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s
*fabric
,
662 enum bfa_fcs_fabric_event event
)
664 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
665 bfa_trc(fabric
->fcs
, event
);
668 case BFA_FCS_FABRIC_SM_DELCOMP
:
669 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_uninit
);
670 bfa_wc_down(&fabric
->fcs
->wc
);
673 case BFA_FCS_FABRIC_SM_LINK_UP
:
676 case BFA_FCS_FABRIC_SM_LINK_DOWN
:
677 bfa_fcs_fabric_notify_offline(fabric
);
681 bfa_sm_fault(fabric
->fcs
, event
);
688 * fcs_fabric_private fabric private functions
692 bfa_fcs_fabric_init(struct bfa_fcs_fabric_s
*fabric
)
694 struct bfa_lport_cfg_s
*port_cfg
= &fabric
->bport
.port_cfg
;
696 port_cfg
->roles
= BFA_LPORT_ROLE_FCP_IM
;
697 port_cfg
->nwwn
= fabric
->fcs
->bfa
->ioc
.attr
->nwwn
;
698 port_cfg
->pwwn
= fabric
->fcs
->bfa
->ioc
.attr
->pwwn
;
702 * Port Symbolic Name Creation for base port.
705 bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s
*fabric
)
707 struct bfa_lport_cfg_s
*port_cfg
= &fabric
->bport
.port_cfg
;
708 char model
[BFA_ADAPTER_MODEL_NAME_LEN
] = {0};
709 struct bfa_fcs_driver_info_s
*driver_info
= &fabric
->fcs
->driver_info
;
711 bfa_ioc_get_adapter_model(&fabric
->fcs
->bfa
->ioc
, model
);
713 /* Model name/number */
714 strncpy((char *)&port_cfg
->sym_name
, model
,
715 BFA_FCS_PORT_SYMBNAME_MODEL_SZ
);
716 strncat((char *)&port_cfg
->sym_name
, BFA_FCS_PORT_SYMBNAME_SEPARATOR
,
717 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR
));
720 strncat((char *)&port_cfg
->sym_name
, (char *)driver_info
->version
,
721 BFA_FCS_PORT_SYMBNAME_VERSION_SZ
);
722 strncat((char *)&port_cfg
->sym_name
, BFA_FCS_PORT_SYMBNAME_SEPARATOR
,
723 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR
));
725 /* Host machine name */
726 strncat((char *)&port_cfg
->sym_name
,
727 (char *)driver_info
->host_machine_name
,
728 BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ
);
729 strncat((char *)&port_cfg
->sym_name
, BFA_FCS_PORT_SYMBNAME_SEPARATOR
,
730 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR
));
734 * If OS Patch Info is not there, do not truncate any bytes from the
735 * OS name string and instead copy the entire OS info string (64 bytes).
737 if (driver_info
->host_os_patch
[0] == '\0') {
738 strncat((char *)&port_cfg
->sym_name
,
739 (char *)driver_info
->host_os_name
,
741 strncat((char *)&port_cfg
->sym_name
,
742 BFA_FCS_PORT_SYMBNAME_SEPARATOR
,
743 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR
));
745 strncat((char *)&port_cfg
->sym_name
,
746 (char *)driver_info
->host_os_name
,
747 BFA_FCS_PORT_SYMBNAME_OSINFO_SZ
);
748 strncat((char *)&port_cfg
->sym_name
,
749 BFA_FCS_PORT_SYMBNAME_SEPARATOR
,
750 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR
));
752 /* Append host OS Patch Info */
753 strncat((char *)&port_cfg
->sym_name
,
754 (char *)driver_info
->host_os_patch
,
755 BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ
);
759 port_cfg
->sym_name
.symname
[BFA_SYMNAME_MAXLEN
- 1] = 0;
763 * bfa lps login completion callback
766 bfa_cb_lps_flogi_comp(void *bfad
, void *uarg
, bfa_status_t status
)
768 struct bfa_fcs_fabric_s
*fabric
= uarg
;
770 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
771 bfa_trc(fabric
->fcs
, status
);
775 fabric
->stats
.flogi_accepts
++;
778 case BFA_STATUS_INVALID_MAC
:
780 fabric
->stats
.flogi_acc_err
++;
781 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_RETRY_OP
);
785 case BFA_STATUS_EPROTOCOL
:
786 switch (fabric
->lps
->ext_status
) {
787 case BFA_EPROTO_BAD_ACCEPT
:
788 fabric
->stats
.flogi_acc_err
++;
791 case BFA_EPROTO_UNKNOWN_RSP
:
792 fabric
->stats
.flogi_unknown_rsp
++;
798 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_RETRY_OP
);
802 case BFA_STATUS_FABRIC_RJT
:
803 fabric
->stats
.flogi_rejects
++;
804 if (fabric
->lps
->lsrjt_rsn
== FC_LS_RJT_RSN_LOGICAL_ERROR
&&
805 fabric
->lps
->lsrjt_expl
== FC_LS_RJT_EXP_NO_ADDL_INFO
)
806 fabric
->fcs
->bbscn_flogi_rjt
= BFA_TRUE
;
808 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_RETRY_OP
);
812 fabric
->stats
.flogi_rsp_err
++;
813 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_RETRY_OP
);
817 fabric
->bb_credit
= fabric
->lps
->pr_bbcred
;
818 bfa_trc(fabric
->fcs
, fabric
->bb_credit
);
820 if (!(fabric
->lps
->brcd_switch
))
821 fabric
->fabric_name
= fabric
->lps
->pr_nwwn
;
824 * Check port type. It should be 1 = F-port.
826 if (fabric
->lps
->fport
) {
827 fabric
->bport
.pid
= fabric
->lps
->lp_pid
;
828 fabric
->is_npiv
= fabric
->lps
->npiv_en
;
829 fabric
->is_auth
= fabric
->lps
->auth_req
;
830 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_CONT_OP
);
833 * Nport-2-Nport direct attached
835 fabric
->bport
.port_topo
.pn2n
.rem_port_wwn
=
836 fabric
->lps
->pr_pwwn
;
837 fabric
->fab_type
= BFA_FCS_FABRIC_N2N
;
838 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_NO_FABRIC
);
841 bfa_trc(fabric
->fcs
, fabric
->bport
.pid
);
842 bfa_trc(fabric
->fcs
, fabric
->is_npiv
);
843 bfa_trc(fabric
->fcs
, fabric
->is_auth
);
846 * Allocate and send FLOGI.
849 bfa_fcs_fabric_login(struct bfa_fcs_fabric_s
*fabric
)
851 struct bfa_s
*bfa
= fabric
->fcs
->bfa
;
852 struct bfa_lport_cfg_s
*pcfg
= &fabric
->bport
.port_cfg
;
853 u8 alpa
= 0, bb_scn
= 0;
855 if (bfa_fcport_get_topology(bfa
) == BFA_PORT_TOPOLOGY_LOOP
)
856 alpa
= bfa_fcport_get_myalpa(bfa
);
858 if (bfa_fcs_fabric_is_bbscn_enabled(fabric
) &&
859 (!fabric
->fcs
->bbscn_flogi_rjt
))
860 bb_scn
= BFA_FCS_PORT_DEF_BB_SCN
;
862 bfa_lps_flogi(fabric
->lps
, fabric
, alpa
, bfa_fcport_get_maxfrsize(bfa
),
863 pcfg
->pwwn
, pcfg
->nwwn
, fabric
->auth_reqd
, bb_scn
);
865 fabric
->stats
.flogi_sent
++;
869 bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s
*fabric
)
871 struct bfa_fcs_vport_s
*vport
;
872 struct list_head
*qe
, *qen
;
874 bfa_trc(fabric
->fcs
, fabric
->fabric_name
);
876 bfa_fcs_fabric_set_opertype(fabric
);
877 fabric
->stats
.fabric_onlines
++;
880 * notify online event to base and then virtual ports
882 bfa_fcs_lport_online(&fabric
->bport
);
884 list_for_each_safe(qe
, qen
, &fabric
->vport_q
) {
885 vport
= (struct bfa_fcs_vport_s
*) qe
;
886 bfa_fcs_vport_online(vport
);
891 bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s
*fabric
)
893 struct bfa_fcs_vport_s
*vport
;
894 struct list_head
*qe
, *qen
;
896 bfa_trc(fabric
->fcs
, fabric
->fabric_name
);
897 fabric
->stats
.fabric_offlines
++;
900 * notify offline event first to vports and then base port.
902 list_for_each_safe(qe
, qen
, &fabric
->vport_q
) {
903 vport
= (struct bfa_fcs_vport_s
*) qe
;
904 bfa_fcs_vport_offline(vport
);
907 bfa_fcs_lport_offline(&fabric
->bport
);
909 fabric
->fabric_name
= 0;
910 fabric
->fabric_ip_addr
[0] = 0;
914 bfa_fcs_fabric_delay(void *cbarg
)
916 struct bfa_fcs_fabric_s
*fabric
= cbarg
;
918 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_DELAYED
);
922 * Computes operating BB_SCN value
925 bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s
*fabric
)
927 u8 pr_bbscn
= fabric
->lps
->pr_bbscn
;
928 struct bfa_fcport_s
*fcport
= BFA_FCPORT_MOD(fabric
->fcs
->bfa
);
930 if (!(fcport
->cfg
.bb_scn_state
&& pr_bbscn
))
933 /* return max of local/remote bb_scn values */
934 return ((pr_bbscn
> BFA_FCS_PORT_DEF_BB_SCN
) ?
935 pr_bbscn
: BFA_FCS_PORT_DEF_BB_SCN
);
939 * Check if BB_SCN can be enabled.
942 bfa_fcs_fabric_is_bbscn_enabled(struct bfa_fcs_fabric_s
*fabric
)
944 struct bfa_fcport_s
*fcport
= BFA_FCPORT_MOD(fabric
->fcs
->bfa
);
946 if (bfa_ioc_get_fcmode(&fabric
->fcs
->bfa
->ioc
) &&
947 fcport
->cfg
.bb_scn_state
&&
948 !bfa_fcport_is_qos_enabled(fabric
->fcs
->bfa
) &&
949 !bfa_fcport_is_trunk_enabled(fabric
->fcs
->bfa
))
956 * Delete all vports and wait for vport delete completions.
959 bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s
*fabric
)
961 struct bfa_fcs_vport_s
*vport
;
962 struct list_head
*qe
, *qen
;
964 list_for_each_safe(qe
, qen
, &fabric
->vport_q
) {
965 vport
= (struct bfa_fcs_vport_s
*) qe
;
966 bfa_fcs_vport_fcs_delete(vport
);
969 bfa_fcs_lport_delete(&fabric
->bport
);
970 bfa_wc_wait(&fabric
->wc
);
974 bfa_fcs_fabric_delete_comp(void *cbarg
)
976 struct bfa_fcs_fabric_s
*fabric
= cbarg
;
978 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_DELCOMP
);
982 * fcs_fabric_public fabric public functions
986 * Attach time initialization.
989 bfa_fcs_fabric_attach(struct bfa_fcs_s
*fcs
)
991 struct bfa_fcs_fabric_s
*fabric
;
993 fabric
= &fcs
->fabric
;
994 memset(fabric
, 0, sizeof(struct bfa_fcs_fabric_s
));
997 * Initialize base fabric.
1000 INIT_LIST_HEAD(&fabric
->vport_q
);
1001 INIT_LIST_HEAD(&fabric
->vf_q
);
1002 fabric
->lps
= bfa_lps_alloc(fcs
->bfa
);
1003 WARN_ON(!fabric
->lps
);
1006 * Initialize fabric delete completion handler. Fabric deletion is
1007 * complete when the last vport delete is complete.
1009 bfa_wc_init(&fabric
->wc
, bfa_fcs_fabric_delete_comp
, fabric
);
1010 bfa_wc_up(&fabric
->wc
); /* For the base port */
1012 bfa_sm_set_state(fabric
, bfa_fcs_fabric_sm_uninit
);
1013 bfa_fcs_lport_attach(&fabric
->bport
, fabric
->fcs
, FC_VF_ID_NULL
, NULL
);
1017 bfa_fcs_fabric_modinit(struct bfa_fcs_s
*fcs
)
1019 bfa_sm_send_event(&fcs
->fabric
, BFA_FCS_FABRIC_SM_CREATE
);
1027 bfa_fcs_fabric_modexit(struct bfa_fcs_s
*fcs
)
1029 struct bfa_fcs_fabric_s
*fabric
;
1034 * Cleanup base fabric.
1036 fabric
= &fcs
->fabric
;
1037 bfa_lps_delete(fabric
->lps
);
1038 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_DELETE
);
1042 * Fabric module start -- kick starts FCS actions
1045 bfa_fcs_fabric_modstart(struct bfa_fcs_s
*fcs
)
1047 struct bfa_fcs_fabric_s
*fabric
;
1050 fabric
= &fcs
->fabric
;
1051 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_START
);
1056 * Link up notification from BFA physical port module.
1059 bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s
*fabric
)
1061 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
1062 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_LINK_UP
);
1066 * Link down notification from BFA physical port module.
1069 bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s
*fabric
)
1071 bfa_trc(fabric
->fcs
, fabric
->bport
.port_cfg
.pwwn
);
1072 fabric
->fcs
->bbscn_flogi_rjt
= BFA_FALSE
;
1073 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_LINK_DOWN
);
1077 * A child vport is being created in the fabric.
1079 * Call from vport module at vport creation. A list of base port and vports
1080 * belonging to a fabric is maintained to propagate link events.
1082 * param[in] fabric - Fabric instance. This can be a base fabric or vf.
1083 * param[in] vport - Vport being created.
1085 * @return None (always succeeds)
1088 bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s
*fabric
,
1089 struct bfa_fcs_vport_s
*vport
)
1092 * - add vport to fabric's vport_q
1094 bfa_trc(fabric
->fcs
, fabric
->vf_id
);
1096 list_add_tail(&vport
->qe
, &fabric
->vport_q
);
1097 fabric
->num_vports
++;
1098 bfa_wc_up(&fabric
->wc
);
1102 * A child vport is being deleted from fabric.
1104 * Vport is being deleted.
1107 bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s
*fabric
,
1108 struct bfa_fcs_vport_s
*vport
)
1110 list_del(&vport
->qe
);
1111 fabric
->num_vports
--;
1112 bfa_wc_down(&fabric
->wc
);
1117 * Lookup for a vport within a fabric given its pwwn
1119 struct bfa_fcs_vport_s
*
1120 bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s
*fabric
, wwn_t pwwn
)
1122 struct bfa_fcs_vport_s
*vport
;
1123 struct list_head
*qe
;
1125 list_for_each(qe
, &fabric
->vport_q
) {
1126 vport
= (struct bfa_fcs_vport_s
*) qe
;
1127 if (bfa_fcs_lport_get_pwwn(&vport
->lport
) == pwwn
)
1136 * Get OUI of the attached switch.
1138 * Note : Use of this function should be avoided as much as possible.
1139 * This function should be used only if there is any requirement
1140 * to check for FOS version below 6.3.
1141 * To check if the attached fabric is a brocade fabric, use
1142 * bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
1147 bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s
*fabric
)
1153 fab_nwwn
= fabric
->lps
->pr_nwwn
;
1155 tmp
= (u8
*)&fab_nwwn
;
1156 oui
= (tmp
[3] << 8) | tmp
[4];
1161 * Unsolicited frame receive handling.
1164 bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s
*fabric
, struct fchs_s
*fchs
,
1167 u32 pid
= fchs
->d_id
;
1168 struct bfa_fcs_vport_s
*vport
;
1169 struct list_head
*qe
;
1170 struct fc_els_cmd_s
*els_cmd
= (struct fc_els_cmd_s
*) (fchs
+ 1);
1171 struct fc_logi_s
*flogi
= (struct fc_logi_s
*) els_cmd
;
1173 bfa_trc(fabric
->fcs
, len
);
1174 bfa_trc(fabric
->fcs
, pid
);
1177 * Look for our own FLOGI frames being looped back. This means an
1178 * external loopback cable is in place. Our own FLOGI frames are
1179 * sometimes looped back when switch port gets temporarily bypassed.
1181 if ((pid
== bfa_ntoh3b(FC_FABRIC_PORT
)) &&
1182 (els_cmd
->els_code
== FC_ELS_FLOGI
) &&
1183 (flogi
->port_name
== bfa_fcs_lport_get_pwwn(&fabric
->bport
))) {
1184 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_LOOPBACK
);
1189 * FLOGI/EVFP exchanges should be consumed by base fabric.
1191 if (fchs
->d_id
== bfa_hton3b(FC_FABRIC_PORT
)) {
1192 bfa_trc(fabric
->fcs
, pid
);
1193 bfa_fcs_fabric_process_uf(fabric
, fchs
, len
);
1197 if (fabric
->bport
.pid
== pid
) {
1199 * All authentication frames should be routed to auth
1201 bfa_trc(fabric
->fcs
, els_cmd
->els_code
);
1202 if (els_cmd
->els_code
== FC_ELS_AUTH
) {
1203 bfa_trc(fabric
->fcs
, els_cmd
->els_code
);
1207 bfa_trc(fabric
->fcs
, *(u8
*) ((u8
*) fchs
));
1208 bfa_fcs_lport_uf_recv(&fabric
->bport
, fchs
, len
);
1213 * look for a matching local port ID
1215 list_for_each(qe
, &fabric
->vport_q
) {
1216 vport
= (struct bfa_fcs_vport_s
*) qe
;
1217 if (vport
->lport
.pid
== pid
) {
1218 bfa_fcs_lport_uf_recv(&vport
->lport
, fchs
, len
);
1222 bfa_trc(fabric
->fcs
, els_cmd
->els_code
);
1223 bfa_fcs_lport_uf_recv(&fabric
->bport
, fchs
, len
);
1227 * Unsolicited frames to be processed by fabric.
1230 bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s
*fabric
, struct fchs_s
*fchs
,
1233 struct fc_els_cmd_s
*els_cmd
= (struct fc_els_cmd_s
*) (fchs
+ 1);
1235 bfa_trc(fabric
->fcs
, els_cmd
->els_code
);
1237 switch (els_cmd
->els_code
) {
1239 bfa_fcs_fabric_process_flogi(fabric
, fchs
, len
);
1244 * need to generate a LS_RJT
1251 * Process incoming FLOGI
1254 bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s
*fabric
,
1255 struct fchs_s
*fchs
, u16 len
)
1257 struct fc_logi_s
*flogi
= (struct fc_logi_s
*) (fchs
+ 1);
1258 struct bfa_fcs_lport_s
*bport
= &fabric
->bport
;
1260 bfa_trc(fabric
->fcs
, fchs
->s_id
);
1262 fabric
->stats
.flogi_rcvd
++;
1264 * Check port type. It should be 0 = n-port.
1266 if (flogi
->csp
.port_type
) {
1268 * @todo: may need to send a LS_RJT
1270 bfa_trc(fabric
->fcs
, flogi
->port_name
);
1271 fabric
->stats
.flogi_rejected
++;
1275 fabric
->bb_credit
= be16_to_cpu(flogi
->csp
.bbcred
);
1276 fabric
->lps
->pr_bbscn
= (be16_to_cpu(flogi
->csp
.rxsz
) >> 12);
1277 bport
->port_topo
.pn2n
.rem_port_wwn
= flogi
->port_name
;
1278 bport
->port_topo
.pn2n
.reply_oxid
= fchs
->ox_id
;
1283 bfa_fcs_fabric_send_flogi_acc(fabric
);
1284 bfa_sm_send_event(fabric
, BFA_FCS_FABRIC_SM_NO_FABRIC
);
1288 bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s
*fabric
)
1290 struct bfa_lport_cfg_s
*pcfg
= &fabric
->bport
.port_cfg
;
1291 struct bfa_fcs_lport_n2n_s
*n2n_port
= &fabric
->bport
.port_topo
.pn2n
;
1292 struct bfa_s
*bfa
= fabric
->fcs
->bfa
;
1293 struct bfa_fcxp_s
*fcxp
;
1297 fcxp
= bfa_fcs_fcxp_alloc(fabric
->fcs
);
1299 * Do not expect this failure -- expect remote node to retry
1304 reqlen
= fc_flogi_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
1305 bfa_hton3b(FC_FABRIC_PORT
),
1306 n2n_port
->reply_oxid
, pcfg
->pwwn
,
1308 bfa_fcport_get_maxfrsize(bfa
),
1309 bfa_fcport_get_rx_bbcredit(bfa
),
1310 bfa_fcs_fabric_oper_bbscn(fabric
));
1312 bfa_fcxp_send(fcxp
, NULL
, fabric
->vf_id
, fabric
->lps
->bfa_tag
,
1313 BFA_FALSE
, FC_CLASS_3
,
1314 reqlen
, &fchs
, bfa_fcs_fabric_flogiacc_comp
, fabric
,
1319 * Flogi Acc completion callback.
1322 bfa_fcs_fabric_flogiacc_comp(void *fcsarg
, struct bfa_fcxp_s
*fcxp
, void *cbarg
,
1323 bfa_status_t status
, u32 rsp_len
,
1324 u32 resid_len
, struct fchs_s
*rspfchs
)
1326 struct bfa_fcs_fabric_s
*fabric
= cbarg
;
1328 bfa_trc(fabric
->fcs
, status
);
1333 * Send AEN notification
1336 bfa_fcs_fabric_aen_post(struct bfa_fcs_lport_s
*port
,
1337 enum bfa_port_aen_event event
)
1339 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fabric
->fcs
->bfad
;
1340 struct bfa_aen_entry_s
*aen_entry
;
1342 bfad_get_aen_entry(bfad
, aen_entry
);
1346 aen_entry
->aen_data
.port
.pwwn
= bfa_fcs_lport_get_pwwn(port
);
1347 aen_entry
->aen_data
.port
.fwwn
= bfa_fcs_lport_get_fabric_name(port
);
1349 /* Send the AEN notification */
1350 bfad_im_post_vendor_event(aen_entry
, bfad
, ++port
->fcs
->fcs_aen_seq
,
1351 BFA_AEN_CAT_PORT
, event
);
1356 * @param[in] fabric - fabric
1357 * @param[in] wwn_t - new fabric name
1362 bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s
*fabric
,
1365 struct bfad_s
*bfad
= (struct bfad_s
*)fabric
->fcs
->bfad
;
1366 char pwwn_ptr
[BFA_STRING_32
];
1367 char fwwn_ptr
[BFA_STRING_32
];
1369 bfa_trc(fabric
->fcs
, fabric_name
);
1371 if (fabric
->fabric_name
== 0) {
1373 * With BRCD switches, we don't get Fabric Name in FLOGI.
1374 * Don't generate a fabric name change event in this case.
1376 fabric
->fabric_name
= fabric_name
;
1378 fabric
->fabric_name
= fabric_name
;
1379 wwn2str(pwwn_ptr
, bfa_fcs_lport_get_pwwn(&fabric
->bport
));
1381 bfa_fcs_lport_get_fabric_name(&fabric
->bport
));
1382 BFA_LOG(KERN_WARNING
, bfad
, bfa_log_level
,
1383 "Base port WWN = %s Fabric WWN = %s\n",
1384 pwwn_ptr
, fwwn_ptr
);
1385 bfa_fcs_fabric_aen_post(&fabric
->bport
,
1386 BFA_PORT_AEN_FABRIC_NAME_CHANGE
);
1391 * Returns FCS vf structure for a given vf_id.
1393 * param[in] vf_id - VF_ID
1396 * If lookup succeeds, retuns fcs vf object, otherwise returns NULL
1399 bfa_fcs_vf_lookup(struct bfa_fcs_s
*fcs
, u16 vf_id
)
1401 bfa_trc(fcs
, vf_id
);
1402 if (vf_id
== FC_VF_ID_NULL
)
1403 return &fcs
->fabric
;
1409 * Return the list of local logical ports present in the given VF.
1411 * @param[in] vf vf for which logical ports are returned
1412 * @param[out] lpwwn returned logical port wwn list
1413 * @param[in,out] nlports in:size of lpwwn list;
1414 * out:total elements present,
1415 * actual elements returned is limited by the size
1418 bfa_fcs_vf_get_ports(bfa_fcs_vf_t
*vf
, wwn_t lpwwn
[], int *nlports
)
1420 struct list_head
*qe
;
1421 struct bfa_fcs_vport_s
*vport
;
1423 struct bfa_fcs_s
*fcs
;
1425 if (vf
== NULL
|| lpwwn
== NULL
|| *nlports
== 0)
1430 bfa_trc(fcs
, vf
->vf_id
);
1431 bfa_trc(fcs
, (uint32_t) *nlports
);
1433 lpwwn
[i
++] = vf
->bport
.port_cfg
.pwwn
;
1435 list_for_each(qe
, &vf
->vport_q
) {
1439 vport
= (struct bfa_fcs_vport_s
*) qe
;
1440 lpwwn
[i
++] = vport
->lport
.port_cfg
.pwwn
;
1448 * BFA FCS PPORT ( physical port)
1451 bfa_fcs_port_event_handler(void *cbarg
, enum bfa_port_linkstate event
)
1453 struct bfa_fcs_s
*fcs
= cbarg
;
1455 bfa_trc(fcs
, event
);
1458 case BFA_PORT_LINKUP
:
1459 bfa_fcs_fabric_link_up(&fcs
->fabric
);
1462 case BFA_PORT_LINKDOWN
:
1463 bfa_fcs_fabric_link_down(&fcs
->fabric
);
1472 bfa_fcs_port_attach(struct bfa_fcs_s
*fcs
)
1474 bfa_fcport_event_register(fcs
->bfa
, bfa_fcs_port_event_handler
, fcs
);
1478 * BFA FCS UF ( Unsolicited Frames)
1482 * BFA callback for unsolicited frame receive handler.
1484 * @param[in] cbarg callback arg for receive handler
1485 * @param[in] uf unsolicited frame descriptor
1490 bfa_fcs_uf_recv(void *cbarg
, struct bfa_uf_s
*uf
)
1492 struct bfa_fcs_s
*fcs
= (struct bfa_fcs_s
*) cbarg
;
1493 struct fchs_s
*fchs
= bfa_uf_get_frmbuf(uf
);
1494 u16 len
= bfa_uf_get_frmlen(uf
);
1495 struct fc_vft_s
*vft
;
1496 struct bfa_fcs_fabric_s
*fabric
;
1499 * check for VFT header
1501 if (fchs
->routing
== FC_RTG_EXT_HDR
&&
1502 fchs
->cat_info
== FC_CAT_VFT_HDR
) {
1503 bfa_stats(fcs
, uf
.tagged
);
1504 vft
= bfa_uf_get_frmbuf(uf
);
1505 if (fcs
->port_vfid
== vft
->vf_id
)
1506 fabric
= &fcs
->fabric
;
1508 fabric
= bfa_fcs_vf_lookup(fcs
, (u16
) vft
->vf_id
);
1511 * drop frame if vfid is unknown
1515 bfa_stats(fcs
, uf
.vfid_unknown
);
1523 fchs
= (struct fchs_s
*) (vft
+ 1);
1524 len
-= sizeof(struct fc_vft_s
);
1526 bfa_trc(fcs
, vft
->vf_id
);
1528 bfa_stats(fcs
, uf
.untagged
);
1529 fabric
= &fcs
->fabric
;
1532 bfa_trc(fcs
, ((u32
*) fchs
)[0]);
1533 bfa_trc(fcs
, ((u32
*) fchs
)[1]);
1534 bfa_trc(fcs
, ((u32
*) fchs
)[2]);
1535 bfa_trc(fcs
, ((u32
*) fchs
)[3]);
1536 bfa_trc(fcs
, ((u32
*) fchs
)[4]);
1537 bfa_trc(fcs
, ((u32
*) fchs
)[5]);
1540 bfa_fcs_fabric_uf_recv(fabric
, fchs
, len
);
1545 bfa_fcs_uf_attach(struct bfa_fcs_s
*fcs
)
1547 bfa_uf_recv_register(fcs
->bfa
, bfa_fcs_uf_recv
, fcs
);