upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / scsi / bfa / fabric.c
1 /*
2  * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3  * 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
18 /**
19  *  fabric.c Fabric module implementation.
20  */
21
22 #include "fcs_fabric.h"
23 #include "fcs_lport.h"
24 #include "fcs_vport.h"
25 #include "fcs_trcmod.h"
26 #include "fcs_fcxp.h"
27 #include "fcs_auth.h"
28 #include "fcs.h"
29 #include "fcbuild.h"
30 #include <log/bfa_log_fcs.h>
31 #include <aen/bfa_aen_port.h>
32 #include <bfa_svc.h>
33
34 BFA_TRC_FILE(FCS, FABRIC);
35
36 #define BFA_FCS_FABRIC_RETRY_DELAY      (2000)  /* Milliseconds */
37 #define BFA_FCS_FABRIC_CLEANUP_DELAY    (10000) /* Milliseconds */
38
39 #define bfa_fcs_fabric_set_opertype(__fabric) do {             \
40         if (bfa_fcport_get_topology((__fabric)->fcs->bfa)       \
41                                 == BFA_PPORT_TOPOLOGY_P2P)     \
42                 (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT;  \
43         else                                                   \
44                 (__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT; \
45 } while (0)
46
47 /*
48  * forward declarations
49  */
50 static void     bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
51 static void     bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
52 static void     bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
53 static void     bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
54 static void     bfa_fcs_fabric_delay(void *cbarg);
55 static void     bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
56 static void     bfa_fcs_fabric_delete_comp(void *cbarg);
57 static void     bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
58                                           struct fchs_s *fchs, u16 len);
59 static void     bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
60                                              struct fchs_s *fchs, u16 len);
61 static void     bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
62 static void     bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
63                                              struct bfa_fcxp_s *fcxp,
64                                              void *cbarg, bfa_status_t status,
65                                              u32 rsp_len,
66                                              u32 resid_len,
67                                              struct fchs_s *rspfchs);
68 /**
69  *  fcs_fabric_sm fabric state machine functions
70  */
71
72 /**
73  * Fabric state machine events
74  */
75 enum bfa_fcs_fabric_event {
76         BFA_FCS_FABRIC_SM_CREATE = 1,   /*  fabric create from driver */
77         BFA_FCS_FABRIC_SM_DELETE = 2,   /*  fabric delete from driver */
78         BFA_FCS_FABRIC_SM_LINK_DOWN = 3,        /*  link down from port */
79         BFA_FCS_FABRIC_SM_LINK_UP = 4,  /*  link up from port */
80         BFA_FCS_FABRIC_SM_CONT_OP = 5,  /*  continue op from flogi/auth */
81         BFA_FCS_FABRIC_SM_RETRY_OP = 6, /*  continue op from flogi/auth */
82         BFA_FCS_FABRIC_SM_NO_FABRIC = 7,        /*  no fabric from flogi/auth
83                                                  */
84         BFA_FCS_FABRIC_SM_PERF_EVFP = 8,        /*  perform EVFP from
85                                                  *flogi/auth */
86         BFA_FCS_FABRIC_SM_ISOLATE = 9,  /*  isolate from EVFP processing */
87         BFA_FCS_FABRIC_SM_NO_TAGGING = 10,/*  no VFT tagging from EVFP */
88         BFA_FCS_FABRIC_SM_DELAYED = 11, /*  timeout delay event */
89         BFA_FCS_FABRIC_SM_AUTH_FAILED = 12,     /*  authentication failed */
90         BFA_FCS_FABRIC_SM_AUTH_SUCCESS = 13,    /*  authentication successful
91                                                  */
92         BFA_FCS_FABRIC_SM_DELCOMP = 14, /*  all vports deleted event */
93         BFA_FCS_FABRIC_SM_LOOPBACK = 15,        /*  Received our own FLOGI */
94         BFA_FCS_FABRIC_SM_START = 16,   /*  fabric delete from driver */
95 };
96
97 static void     bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
98                                          enum bfa_fcs_fabric_event event);
99 static void     bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
100                                           enum bfa_fcs_fabric_event event);
101 static void     bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
102                                            enum bfa_fcs_fabric_event event);
103 static void     bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
104                                         enum bfa_fcs_fabric_event event);
105 static void     bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
106                                               enum bfa_fcs_fabric_event event);
107 static void     bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
108                                        enum bfa_fcs_fabric_event event);
109 static void     bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
110                                               enum bfa_fcs_fabric_event event);
111 static void     bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
112                                            enum bfa_fcs_fabric_event event);
113 static void     bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
114                                            enum bfa_fcs_fabric_event event);
115 static void     bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
116                                          enum bfa_fcs_fabric_event event);
117 static void     bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
118                                        enum bfa_fcs_fabric_event event);
119 static void     bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
120                                             enum bfa_fcs_fabric_event event);
121 static void     bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
122                                            enum bfa_fcs_fabric_event event);
123 static void     bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
124                                            enum bfa_fcs_fabric_event event);
125 /**
126  *   Beginning state before fabric creation.
127  */
128 static void
129 bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
130                          enum bfa_fcs_fabric_event event)
131 {
132         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
133         bfa_trc(fabric->fcs, event);
134
135         switch (event) {
136         case BFA_FCS_FABRIC_SM_CREATE:
137                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
138                 bfa_fcs_fabric_init(fabric);
139                 bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
140                 break;
141
142         case BFA_FCS_FABRIC_SM_LINK_UP:
143         case BFA_FCS_FABRIC_SM_LINK_DOWN:
144                 break;
145
146         default:
147                 bfa_sm_fault(fabric->fcs, event);
148         }
149 }
150
151 /**
152  *   Beginning state before fabric creation.
153  */
154 static void
155 bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
156                           enum bfa_fcs_fabric_event event)
157 {
158         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
159         bfa_trc(fabric->fcs, event);
160
161         switch (event) {
162         case BFA_FCS_FABRIC_SM_START:
163                 if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
164                         bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
165                         bfa_fcs_fabric_login(fabric);
166                 } else
167                         bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
168                 break;
169
170         case BFA_FCS_FABRIC_SM_LINK_UP:
171         case BFA_FCS_FABRIC_SM_LINK_DOWN:
172                 break;
173
174         case BFA_FCS_FABRIC_SM_DELETE:
175                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
176                 bfa_fcs_modexit_comp(fabric->fcs);
177                 break;
178
179         default:
180                 bfa_sm_fault(fabric->fcs, event);
181         }
182 }
183
184 /**
185  *   Link is down, awaiting LINK UP event from port. This is also the
186  *   first state at fabric creation.
187  */
188 static void
189 bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
190                            enum bfa_fcs_fabric_event event)
191 {
192         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
193         bfa_trc(fabric->fcs, event);
194
195         switch (event) {
196         case BFA_FCS_FABRIC_SM_LINK_UP:
197                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
198                 bfa_fcs_fabric_login(fabric);
199                 break;
200
201         case BFA_FCS_FABRIC_SM_RETRY_OP:
202                 break;
203
204         case BFA_FCS_FABRIC_SM_DELETE:
205                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
206                 bfa_fcs_fabric_delete(fabric);
207                 break;
208
209         default:
210                 bfa_sm_fault(fabric->fcs, event);
211         }
212 }
213
214 /**
215  *   FLOGI is in progress, awaiting FLOGI reply.
216  */
217 static void
218 bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
219                         enum bfa_fcs_fabric_event event)
220 {
221         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
222         bfa_trc(fabric->fcs, event);
223
224         switch (event) {
225         case BFA_FCS_FABRIC_SM_CONT_OP:
226
227                 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
228                 fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
229
230                 if (fabric->auth_reqd && fabric->is_auth) {
231                         bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth);
232                         bfa_trc(fabric->fcs, event);
233                 } else {
234                         bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
235                         bfa_fcs_fabric_notify_online(fabric);
236                 }
237                 break;
238
239         case BFA_FCS_FABRIC_SM_RETRY_OP:
240                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry);
241                 bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer,
242                                 bfa_fcs_fabric_delay, fabric,
243                                 BFA_FCS_FABRIC_RETRY_DELAY);
244                 break;
245
246         case BFA_FCS_FABRIC_SM_LOOPBACK:
247                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
248                 bfa_lps_discard(fabric->lps);
249                 bfa_fcs_fabric_set_opertype(fabric);
250                 break;
251
252         case BFA_FCS_FABRIC_SM_NO_FABRIC:
253                 fabric->fab_type = BFA_FCS_FABRIC_N2N;
254                 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
255                 bfa_fcs_fabric_notify_online(fabric);
256                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
257                 break;
258
259         case BFA_FCS_FABRIC_SM_LINK_DOWN:
260                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
261                 bfa_lps_discard(fabric->lps);
262                 break;
263
264         case BFA_FCS_FABRIC_SM_DELETE:
265                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
266                 bfa_lps_discard(fabric->lps);
267                 bfa_fcs_fabric_delete(fabric);
268                 break;
269
270         default:
271                 bfa_sm_fault(fabric->fcs, event);
272         }
273 }
274
275
276 static void
277 bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
278                               enum bfa_fcs_fabric_event event)
279 {
280         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
281         bfa_trc(fabric->fcs, event);
282
283         switch (event) {
284         case BFA_FCS_FABRIC_SM_DELAYED:
285                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
286                 bfa_fcs_fabric_login(fabric);
287                 break;
288
289         case BFA_FCS_FABRIC_SM_LINK_DOWN:
290                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
291                 bfa_timer_stop(&fabric->delay_timer);
292                 break;
293
294         case BFA_FCS_FABRIC_SM_DELETE:
295                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
296                 bfa_timer_stop(&fabric->delay_timer);
297                 bfa_fcs_fabric_delete(fabric);
298                 break;
299
300         default:
301                 bfa_sm_fault(fabric->fcs, event);
302         }
303 }
304
305 /**
306  *   Authentication is in progress, awaiting authentication results.
307  */
308 static void
309 bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
310                        enum bfa_fcs_fabric_event event)
311 {
312         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
313         bfa_trc(fabric->fcs, event);
314
315         switch (event) {
316         case BFA_FCS_FABRIC_SM_AUTH_FAILED:
317                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
318                 bfa_lps_discard(fabric->lps);
319                 break;
320
321         case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
322                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
323                 bfa_fcs_fabric_notify_online(fabric);
324                 break;
325
326         case BFA_FCS_FABRIC_SM_PERF_EVFP:
327                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp);
328                 break;
329
330         case BFA_FCS_FABRIC_SM_LINK_DOWN:
331                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
332                 bfa_lps_discard(fabric->lps);
333                 break;
334
335         case BFA_FCS_FABRIC_SM_DELETE:
336                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
337                 bfa_fcs_fabric_delete(fabric);
338                 break;
339
340         default:
341                 bfa_sm_fault(fabric->fcs, event);
342         }
343 }
344
345 /**
346  *   Authentication failed
347  */
348 static void
349 bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
350                               enum bfa_fcs_fabric_event event)
351 {
352         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
353         bfa_trc(fabric->fcs, event);
354
355         switch (event) {
356         case BFA_FCS_FABRIC_SM_LINK_DOWN:
357                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
358                 bfa_fcs_fabric_notify_offline(fabric);
359                 break;
360
361         case BFA_FCS_FABRIC_SM_DELETE:
362                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
363                 bfa_fcs_fabric_delete(fabric);
364                 break;
365
366         default:
367                 bfa_sm_fault(fabric->fcs, event);
368         }
369 }
370
371 /**
372  *   Port is in loopback mode.
373  */
374 static void
375 bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
376                            enum bfa_fcs_fabric_event event)
377 {
378         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
379         bfa_trc(fabric->fcs, event);
380
381         switch (event) {
382         case BFA_FCS_FABRIC_SM_LINK_DOWN:
383                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
384                 bfa_fcs_fabric_notify_offline(fabric);
385                 break;
386
387         case BFA_FCS_FABRIC_SM_DELETE:
388                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
389                 bfa_fcs_fabric_delete(fabric);
390                 break;
391
392         default:
393                 bfa_sm_fault(fabric->fcs, event);
394         }
395 }
396
397 /**
398  *   There is no attached fabric - private loop or NPort-to-NPort topology.
399  */
400 static void
401 bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
402                            enum bfa_fcs_fabric_event event)
403 {
404         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
405         bfa_trc(fabric->fcs, event);
406
407         switch (event) {
408         case BFA_FCS_FABRIC_SM_LINK_DOWN:
409                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
410                 bfa_lps_discard(fabric->lps);
411                 bfa_fcs_fabric_notify_offline(fabric);
412                 break;
413
414         case BFA_FCS_FABRIC_SM_DELETE:
415                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
416                 bfa_fcs_fabric_delete(fabric);
417                 break;
418
419         case BFA_FCS_FABRIC_SM_NO_FABRIC:
420                 bfa_trc(fabric->fcs, fabric->bb_credit);
421                 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
422                 break;
423
424         default:
425                 bfa_sm_fault(fabric->fcs, event);
426         }
427 }
428
429 /**
430  *   Fabric is online - normal operating state.
431  */
432 static void
433 bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
434                          enum bfa_fcs_fabric_event event)
435 {
436         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
437         bfa_trc(fabric->fcs, event);
438
439         switch (event) {
440         case BFA_FCS_FABRIC_SM_LINK_DOWN:
441                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
442                 bfa_lps_discard(fabric->lps);
443                 bfa_fcs_fabric_notify_offline(fabric);
444                 break;
445
446         case BFA_FCS_FABRIC_SM_DELETE:
447                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
448                 bfa_fcs_fabric_delete(fabric);
449                 break;
450
451         case BFA_FCS_FABRIC_SM_AUTH_FAILED:
452                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
453                 bfa_lps_discard(fabric->lps);
454                 break;
455
456         case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
457                 break;
458
459         default:
460                 bfa_sm_fault(fabric->fcs, event);
461         }
462 }
463
464 /**
465  *   Exchanging virtual fabric parameters.
466  */
467 static void
468 bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
469                        enum bfa_fcs_fabric_event event)
470 {
471         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
472         bfa_trc(fabric->fcs, event);
473
474         switch (event) {
475         case BFA_FCS_FABRIC_SM_CONT_OP:
476                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done);
477                 break;
478
479         case BFA_FCS_FABRIC_SM_ISOLATE:
480                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated);
481                 break;
482
483         default:
484                 bfa_sm_fault(fabric->fcs, event);
485         }
486 }
487
488 /**
489  *   EVFP exchange complete and VFT tagging is enabled.
490  */
491 static void
492 bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
493                             enum bfa_fcs_fabric_event event)
494 {
495         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
496         bfa_trc(fabric->fcs, event);
497 }
498
499 /**
500  *   Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
501  */
502 static void
503 bfa_fcs_fabric_sm_isolated(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         bfa_log(fabric->fcs->logm, BFA_LOG_FCS_FABRIC_ISOLATED,
510                 fabric->bport.port_cfg.pwwn, fabric->fcs->port_vfid,
511                 fabric->event_arg.swp_vfid);
512 }
513
514 /**
515  *   Fabric is being deleted, awaiting vport delete completions.
516  */
517 static void
518 bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
519                            enum bfa_fcs_fabric_event event)
520 {
521         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
522         bfa_trc(fabric->fcs, event);
523
524         switch (event) {
525         case BFA_FCS_FABRIC_SM_DELCOMP:
526                 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
527                 bfa_fcs_modexit_comp(fabric->fcs);
528                 break;
529
530         case BFA_FCS_FABRIC_SM_LINK_UP:
531                 break;
532
533         case BFA_FCS_FABRIC_SM_LINK_DOWN:
534                 bfa_fcs_fabric_notify_offline(fabric);
535                 break;
536
537         default:
538                 bfa_sm_fault(fabric->fcs, event);
539         }
540 }
541
542
543
544 /**
545  *  fcs_fabric_private fabric private functions
546  */
547
548 static void
549 bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
550 {
551         struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
552
553         port_cfg->roles = BFA_PORT_ROLE_FCP_IM;
554         port_cfg->nwwn = bfa_ioc_get_nwwn(&fabric->fcs->bfa->ioc);
555         port_cfg->pwwn = bfa_ioc_get_pwwn(&fabric->fcs->bfa->ioc);
556 }
557
558 /**
559  * Port Symbolic Name Creation for base port.
560  */
561 void
562 bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
563 {
564         struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
565         char            model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
566         struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
567
568         bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
569
570         /*
571          * Model name/number
572          */
573         strncpy((char *)&port_cfg->sym_name, model,
574                 BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
575         strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
576                 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
577
578         /*
579          * Driver Version
580          */
581         strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
582                 BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
583         strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
584                 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
585
586         /*
587          * Host machine name
588          */
589         strncat((char *)&port_cfg->sym_name,
590                 (char *)driver_info->host_machine_name,
591                 BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
592         strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
593                 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
594
595         /*
596          * Host OS Info :
597          * If OS Patch Info is not there, do not truncate any bytes from the
598          * OS name string and instead copy the entire OS info string (64 bytes).
599          */
600         if (driver_info->host_os_patch[0] == '\0') {
601                 strncat((char *)&port_cfg->sym_name,
602                         (char *)driver_info->host_os_name, BFA_FCS_OS_STR_LEN);
603                 strncat((char *)&port_cfg->sym_name,
604                         BFA_FCS_PORT_SYMBNAME_SEPARATOR,
605                         sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
606         } else {
607                 strncat((char *)&port_cfg->sym_name,
608                         (char *)driver_info->host_os_name,
609                         BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
610                 strncat((char *)&port_cfg->sym_name,
611                         BFA_FCS_PORT_SYMBNAME_SEPARATOR,
612                         sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
613
614                 /*
615                  * Append host OS Patch Info
616                  */
617                 strncat((char *)&port_cfg->sym_name,
618                         (char *)driver_info->host_os_patch,
619                         BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
620         }
621
622         /*
623          * null terminate
624          */
625         port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
626 }
627
628 /**
629  * bfa lps login completion callback
630  */
631 void
632 bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
633 {
634         struct bfa_fcs_fabric_s *fabric = uarg;
635
636         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
637         bfa_trc(fabric->fcs, status);
638
639         switch (status) {
640         case BFA_STATUS_OK:
641                 fabric->stats.flogi_accepts++;
642                 break;
643
644         case BFA_STATUS_INVALID_MAC:
645                 /*
646                  * Only for CNA
647                  */
648                 fabric->stats.flogi_acc_err++;
649                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
650
651                 return;
652
653         case BFA_STATUS_EPROTOCOL:
654                 switch (bfa_lps_get_extstatus(fabric->lps)) {
655                 case BFA_EPROTO_BAD_ACCEPT:
656                         fabric->stats.flogi_acc_err++;
657                         break;
658
659                 case BFA_EPROTO_UNKNOWN_RSP:
660                         fabric->stats.flogi_unknown_rsp++;
661                         break;
662
663                 default:
664                         break;
665                 }
666                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
667
668                 return;
669
670         case BFA_STATUS_FABRIC_RJT:
671                 fabric->stats.flogi_rejects++;
672                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
673                 return;
674
675         default:
676                 fabric->stats.flogi_rsp_err++;
677                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
678                 return;
679         }
680
681         fabric->bb_credit = bfa_lps_get_peer_bbcredit(fabric->lps);
682         bfa_trc(fabric->fcs, fabric->bb_credit);
683
684         if (!bfa_lps_is_brcd_fabric(fabric->lps))
685                 fabric->fabric_name = bfa_lps_get_peer_nwwn(fabric->lps);
686
687         /*
688          * Check port type. It should be 1 = F-port.
689          */
690         if (bfa_lps_is_fport(fabric->lps)) {
691                 fabric->bport.pid = bfa_lps_get_pid(fabric->lps);
692                 fabric->is_npiv = bfa_lps_is_npiv_en(fabric->lps);
693                 fabric->is_auth = bfa_lps_is_authreq(fabric->lps);
694                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
695         } else {
696                 /*
697                  * Nport-2-Nport direct attached
698                  */
699                 fabric->bport.port_topo.pn2n.rem_port_wwn =
700                         bfa_lps_get_peer_pwwn(fabric->lps);
701                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
702         }
703
704         bfa_trc(fabric->fcs, fabric->bport.pid);
705         bfa_trc(fabric->fcs, fabric->is_npiv);
706         bfa_trc(fabric->fcs, fabric->is_auth);
707 }
708
709 /**
710  *              Allocate and send FLOGI.
711  */
712 static void
713 bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
714 {
715         struct bfa_s   *bfa = fabric->fcs->bfa;
716         struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
717         u8         alpa = 0;
718
719         if (bfa_fcport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
720                 alpa = bfa_fcport_get_myalpa(bfa);
721
722         bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
723                       pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
724
725         fabric->stats.flogi_sent++;
726 }
727
728 static void
729 bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
730 {
731         struct bfa_fcs_vport_s *vport;
732         struct list_head *qe, *qen;
733
734         bfa_trc(fabric->fcs, fabric->fabric_name);
735
736         bfa_fcs_fabric_set_opertype(fabric);
737         fabric->stats.fabric_onlines++;
738
739         /**
740          * notify online event to base and then virtual ports
741          */
742         bfa_fcs_port_online(&fabric->bport);
743
744         list_for_each_safe(qe, qen, &fabric->vport_q) {
745                 vport = (struct bfa_fcs_vport_s *)qe;
746                 bfa_fcs_vport_online(vport);
747         }
748 }
749
750 static void
751 bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
752 {
753         struct bfa_fcs_vport_s *vport;
754         struct list_head *qe, *qen;
755
756         bfa_trc(fabric->fcs, fabric->fabric_name);
757         fabric->stats.fabric_offlines++;
758
759         /**
760          * notify offline event first to vports and then base port.
761          */
762         list_for_each_safe(qe, qen, &fabric->vport_q) {
763                 vport = (struct bfa_fcs_vport_s *)qe;
764                 bfa_fcs_vport_offline(vport);
765         }
766
767         bfa_fcs_port_offline(&fabric->bport);
768
769         fabric->fabric_name = 0;
770         fabric->fabric_ip_addr[0] = 0;
771 }
772
773 static void
774 bfa_fcs_fabric_delay(void *cbarg)
775 {
776         struct bfa_fcs_fabric_s *fabric = cbarg;
777
778         bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
779 }
780
781 /**
782  * Delete all vports and wait for vport delete completions.
783  */
784 static void
785 bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
786 {
787         struct bfa_fcs_vport_s *vport;
788         struct list_head *qe, *qen;
789
790         list_for_each_safe(qe, qen, &fabric->vport_q) {
791                 vport = (struct bfa_fcs_vport_s *)qe;
792                 bfa_fcs_vport_fcs_delete(vport);
793         }
794
795         bfa_fcs_port_delete(&fabric->bport);
796         bfa_wc_wait(&fabric->wc);
797 }
798
799 static void
800 bfa_fcs_fabric_delete_comp(void *cbarg)
801 {
802         struct bfa_fcs_fabric_s *fabric = cbarg;
803
804         bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
805 }
806
807
808
809 /**
810  *  fcs_fabric_public fabric public functions
811  */
812
813 /**
814  *   Attach time initialization
815  */
816 void
817 bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
818 {
819         struct bfa_fcs_fabric_s *fabric;
820
821         fabric = &fcs->fabric;
822         bfa_os_memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
823
824         /**
825          * Initialize base fabric.
826          */
827         fabric->fcs = fcs;
828         INIT_LIST_HEAD(&fabric->vport_q);
829         INIT_LIST_HEAD(&fabric->vf_q);
830         fabric->lps = bfa_lps_alloc(fcs->bfa);
831         bfa_assert(fabric->lps);
832
833         /**
834          * Initialize fabric delete completion handler. Fabric deletion is complete
835          * when the last vport delete is complete.
836          */
837         bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric);
838         bfa_wc_up(&fabric->wc); /* For the base port */
839
840         bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
841         bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
842 }
843
844 void
845 bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
846 {
847         bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
848         bfa_trc(fcs, 0);
849 }
850
851 /**
852  *   Module cleanup
853  */
854 void
855 bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
856 {
857         struct bfa_fcs_fabric_s *fabric;
858
859         bfa_trc(fcs, 0);
860
861         /**
862          * Cleanup base fabric.
863          */
864         fabric = &fcs->fabric;
865         bfa_lps_delete(fabric->lps);
866         bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE);
867 }
868
869 /**
870  * Fabric module start -- kick starts FCS actions
871  */
872 void
873 bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
874 {
875         struct bfa_fcs_fabric_s *fabric;
876
877         bfa_trc(fcs, 0);
878         fabric = &fcs->fabric;
879         bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
880 }
881
882 /**
883  *   Suspend fabric activity as part of driver suspend.
884  */
885 void
886 bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs)
887 {
888 }
889
890 bfa_boolean_t
891 bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
892 {
893         return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback);
894 }
895
896 bfa_boolean_t
897 bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric)
898 {
899         return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_auth_failed);
900 }
901
902 enum bfa_pport_type
903 bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
904 {
905         return fabric->oper_type;
906 }
907
908 /**
909  *   Link up notification from BFA physical port module.
910  */
911 void
912 bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
913 {
914         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
915         bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
916 }
917
918 /**
919  *   Link down notification from BFA physical port module.
920  */
921 void
922 bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
923 {
924         bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
925         bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
926 }
927
928 /**
929  *   A child vport is being created in the fabric.
930  *
931  *   Call from vport module at vport creation. A list of base port and vports
932  *   belonging to a fabric is maintained to propagate link events.
933  *
934  *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
935  *   param[in] vport  - Vport being created.
936  *
937  *   @return None (always succeeds)
938  */
939 void
940 bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
941                         struct bfa_fcs_vport_s *vport)
942 {
943         /**
944          * - add vport to fabric's vport_q
945          */
946         bfa_trc(fabric->fcs, fabric->vf_id);
947
948         list_add_tail(&vport->qe, &fabric->vport_q);
949         fabric->num_vports++;
950         bfa_wc_up(&fabric->wc);
951 }
952
953 /**
954  *   A child vport is being deleted from fabric.
955  *
956  *   Vport is being deleted.
957  */
958 void
959 bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
960                         struct bfa_fcs_vport_s *vport)
961 {
962         list_del(&vport->qe);
963         fabric->num_vports--;
964         bfa_wc_down(&fabric->wc);
965 }
966
967 /**
968  *   Base port is deleted.
969  */
970 void
971 bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric)
972 {
973         bfa_wc_down(&fabric->wc);
974 }
975
976 /**
977  *    Check if fabric is online.
978  *
979  *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
980  *
981  *   @return  TRUE/FALSE
982  */
983 int
984 bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric)
985 {
986         return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online);
987 }
988
989
990 bfa_status_t
991 bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf, struct bfa_fcs_s *fcs,
992                      struct bfa_port_cfg_s *port_cfg,
993                      struct bfad_vf_s *vf_drv)
994 {
995         bfa_sm_set_state(vf, bfa_fcs_fabric_sm_uninit);
996         return BFA_STATUS_OK;
997 }
998
999 /**
1000  * Lookup for a vport withing a fabric given its pwwn
1001  */
1002 struct bfa_fcs_vport_s *
1003 bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
1004 {
1005         struct bfa_fcs_vport_s *vport;
1006         struct list_head *qe;
1007
1008         list_for_each(qe, &fabric->vport_q) {
1009                 vport = (struct bfa_fcs_vport_s *)qe;
1010                 if (bfa_fcs_port_get_pwwn(&vport->lport) == pwwn)
1011                         return vport;
1012         }
1013
1014         return NULL;
1015 }
1016
1017 /**
1018  *    In a given fabric, return the number of lports.
1019  *
1020  *   param[in] fabric - Fabric instance. This can be a base fabric or vf.
1021  *
1022 *    @return : 1 or more.
1023  */
1024 u16
1025 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric)
1026 {
1027         return fabric->num_vports;
1028 }
1029
1030 /*
1031  *  Get OUI of the attached switch.
1032  *
1033  *  Note : Use of this function should be avoided as much as possible.
1034  *         This function should be used only if there is any requirement
1035  *         to check for FOS version below 6.3.
1036  *         To check if the attached fabric is a brocade fabric, use
1037  *         bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
1038  *         or above only.
1039  */
1040
1041 u16
1042 bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
1043 {
1044         wwn_t fab_nwwn;
1045         u8 *tmp;
1046         u16 oui;
1047
1048         fab_nwwn = bfa_lps_get_peer_nwwn(fabric->lps);
1049
1050         tmp = (uint8_t *)&fab_nwwn;
1051         oui = (tmp[3] << 8) | tmp[4];
1052
1053         return oui;
1054 }
1055
1056 /**
1057  *              Unsolicited frame receive handling.
1058  */
1059 void
1060 bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1061                        u16 len)
1062 {
1063         u32        pid = fchs->d_id;
1064         struct bfa_fcs_vport_s *vport;
1065         struct list_head *qe;
1066         struct fc_els_cmd_s   *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1067         struct fc_logi_s     *flogi = (struct fc_logi_s *) els_cmd;
1068
1069         bfa_trc(fabric->fcs, len);
1070         bfa_trc(fabric->fcs, pid);
1071
1072         /**
1073          * Look for our own FLOGI frames being looped back. This means an
1074          * external loopback cable is in place. Our own FLOGI frames are
1075          * sometimes looped back when switch port gets temporarily bypassed.
1076          */
1077         if ((pid == bfa_os_ntoh3b(FC_FABRIC_PORT))
1078             && (els_cmd->els_code == FC_ELS_FLOGI)
1079             && (flogi->port_name == bfa_fcs_port_get_pwwn(&fabric->bport))) {
1080                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
1081                 return;
1082         }
1083
1084         /**
1085          * FLOGI/EVFP exchanges should be consumed by base fabric.
1086          */
1087         if (fchs->d_id == bfa_os_hton3b(FC_FABRIC_PORT)) {
1088                 bfa_trc(fabric->fcs, pid);
1089                 bfa_fcs_fabric_process_uf(fabric, fchs, len);
1090                 return;
1091         }
1092
1093         if (fabric->bport.pid == pid) {
1094                 /**
1095                  * All authentication frames should be routed to auth
1096                  */
1097                 bfa_trc(fabric->fcs, els_cmd->els_code);
1098                 if (els_cmd->els_code == FC_ELS_AUTH) {
1099                         bfa_trc(fabric->fcs, els_cmd->els_code);
1100                         fabric->auth.response = (u8 *) els_cmd;
1101                         return;
1102                 }
1103
1104                 bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
1105                 bfa_fcs_port_uf_recv(&fabric->bport, fchs, len);
1106                 return;
1107         }
1108
1109         /**
1110          * look for a matching local port ID
1111          */
1112         list_for_each(qe, &fabric->vport_q) {
1113                 vport = (struct bfa_fcs_vport_s *)qe;
1114                 if (vport->lport.pid == pid) {
1115                         bfa_fcs_port_uf_recv(&vport->lport, fchs, len);
1116                         return;
1117                 }
1118         }
1119         bfa_trc(fabric->fcs, els_cmd->els_code);
1120         bfa_fcs_port_uf_recv(&fabric->bport, fchs, len);
1121 }
1122
1123 /**
1124  *              Unsolicited frames to be processed by fabric.
1125  */
1126 static void
1127 bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1128                           u16 len)
1129 {
1130         struct fc_els_cmd_s   *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1131
1132         bfa_trc(fabric->fcs, els_cmd->els_code);
1133
1134         switch (els_cmd->els_code) {
1135         case FC_ELS_FLOGI:
1136                 bfa_fcs_fabric_process_flogi(fabric, fchs, len);
1137                 break;
1138
1139         default:
1140                 /*
1141                  * need to generate a LS_RJT
1142                  */
1143                 break;
1144         }
1145 }
1146
1147 /**
1148  *      Process incoming FLOGI
1149  */
1150 static void
1151 bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
1152                         struct fchs_s *fchs, u16 len)
1153 {
1154         struct fc_logi_s     *flogi = (struct fc_logi_s *) (fchs + 1);
1155         struct bfa_fcs_port_s *bport = &fabric->bport;
1156
1157         bfa_trc(fabric->fcs, fchs->s_id);
1158
1159         fabric->stats.flogi_rcvd++;
1160         /*
1161          * Check port type. It should be 0 = n-port.
1162          */
1163         if (flogi->csp.port_type) {
1164                 /*
1165                  * @todo: may need to send a LS_RJT
1166                  */
1167                 bfa_trc(fabric->fcs, flogi->port_name);
1168                 fabric->stats.flogi_rejected++;
1169                 return;
1170         }
1171
1172         fabric->bb_credit = bfa_os_ntohs(flogi->csp.bbcred);
1173         bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
1174         bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
1175
1176         /*
1177          * Send a Flogi Acc
1178          */
1179         bfa_fcs_fabric_send_flogi_acc(fabric);
1180         bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
1181 }
1182
1183 static void
1184 bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1185 {
1186         struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
1187         struct bfa_fcs_port_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
1188         struct bfa_s   *bfa = fabric->fcs->bfa;
1189         struct bfa_fcxp_s *fcxp;
1190         u16        reqlen;
1191         struct fchs_s          fchs;
1192
1193         fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
1194         /**
1195          * Do not expect this failure -- expect remote node to retry
1196          */
1197         if (!fcxp)
1198                 return;
1199
1200         reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1201                                     bfa_os_hton3b(FC_FABRIC_PORT),
1202                                     n2n_port->reply_oxid, pcfg->pwwn,
1203                                     pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa),
1204                                     bfa_fcport_get_rx_bbcredit(bfa));
1205
1206         bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps),
1207                         BFA_FALSE, FC_CLASS_3, reqlen, &fchs,
1208                         bfa_fcs_fabric_flogiacc_comp, fabric,
1209                         FC_MAX_PDUSZ, 0); /* Timeout 0 indicates no
1210                                            * response expected
1211                                            */
1212 }
1213
1214 /**
1215  *   Flogi Acc completion callback.
1216  */
1217 static void
1218 bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1219                              bfa_status_t status, u32 rsp_len,
1220                              u32 resid_len, struct fchs_s *rspfchs)
1221 {
1222         struct bfa_fcs_fabric_s *fabric = cbarg;
1223
1224         bfa_trc(fabric->fcs, status);
1225 }
1226
1227 /*
1228  *
1229  * @param[in] fabric - fabric
1230  * @param[in] result - 1
1231  *
1232  * @return - none
1233  */
1234 void
1235 bfa_fcs_auth_finished(struct bfa_fcs_fabric_s *fabric, enum auth_status status)
1236 {
1237         bfa_trc(fabric->fcs, status);
1238
1239         if (status == FC_AUTH_STATE_SUCCESS)
1240                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_SUCCESS);
1241         else
1242                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_FAILED);
1243 }
1244
1245 /**
1246  * Send AEN notification
1247  */
1248 static void
1249 bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port,
1250                         enum bfa_port_aen_event event)
1251 {
1252         union bfa_aen_data_u aen_data;
1253         struct bfa_log_mod_s *logmod = port->fcs->logm;
1254         wwn_t           pwwn = bfa_fcs_port_get_pwwn(port);
1255         wwn_t           fwwn = bfa_fcs_port_get_fabric_name(port);
1256         char            pwwn_ptr[BFA_STRING_32];
1257         char            fwwn_ptr[BFA_STRING_32];
1258
1259         wwn2str(pwwn_ptr, pwwn);
1260         wwn2str(fwwn_ptr, fwwn);
1261
1262         bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event),
1263                 pwwn_ptr, fwwn_ptr);
1264
1265         aen_data.port.pwwn = pwwn;
1266         aen_data.port.fwwn = fwwn;
1267 }
1268
1269 /*
1270  *
1271  * @param[in] fabric - fabric
1272  * @param[in] wwn_t - new fabric name
1273  *
1274  * @return - none
1275  */
1276 void
1277 bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1278                                wwn_t fabric_name)
1279 {
1280         bfa_trc(fabric->fcs, fabric_name);
1281
1282         if (fabric->fabric_name == 0) {
1283                 /*
1284                  * With BRCD switches, we don't get Fabric Name in FLOGI.
1285                  * Don't generate a fabric name change event in this case.
1286                  */
1287                 fabric->fabric_name = fabric_name;
1288         } else {
1289                 fabric->fabric_name = fabric_name;
1290                 /*
1291                  * Generate a Event
1292                  */
1293                 bfa_fcs_fabric_aen_post(&fabric->bport,
1294                                         BFA_PORT_AEN_FABRIC_NAME_CHANGE);
1295         }
1296
1297 }
1298
1299 /**
1300  *
1301  * @param[in] fabric - fabric
1302  * @param[in] node_symname -
1303  *              Caller allocated buffer to receive the symbolic name
1304  *
1305  * @return - none
1306  */
1307 void
1308 bfa_fcs_get_sym_name(const struct bfa_fcs_s *fcs, char *node_symname)
1309 {
1310         bfa_os_memcpy(node_symname,
1311                         fcs->fabric.bport.port_cfg.sym_name.symname,
1312                         BFA_SYMNAME_MAXLEN);
1313 }
1314
1315 /**
1316  * Not used by FCS.
1317  */
1318 void
1319 bfa_cb_lps_flogo_comp(void *bfad, void *uarg)
1320 {
1321 }
1322
1323