Staging: ti-st: update TODO
[sfrench/cifs-2.6.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_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  *              Unsolicited frame receive handling.
1032  */
1033 void
1034 bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1035                        u16 len)
1036 {
1037         u32        pid = fchs->d_id;
1038         struct bfa_fcs_vport_s *vport;
1039         struct list_head *qe;
1040         struct fc_els_cmd_s   *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1041         struct fc_logi_s     *flogi = (struct fc_logi_s *) els_cmd;
1042
1043         bfa_trc(fabric->fcs, len);
1044         bfa_trc(fabric->fcs, pid);
1045
1046         /**
1047          * Look for our own FLOGI frames being looped back. This means an
1048          * external loopback cable is in place. Our own FLOGI frames are
1049          * sometimes looped back when switch port gets temporarily bypassed.
1050          */
1051         if ((pid == bfa_os_ntoh3b(FC_FABRIC_PORT))
1052             && (els_cmd->els_code == FC_ELS_FLOGI)
1053             && (flogi->port_name == bfa_fcs_port_get_pwwn(&fabric->bport))) {
1054                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
1055                 return;
1056         }
1057
1058         /**
1059          * FLOGI/EVFP exchanges should be consumed by base fabric.
1060          */
1061         if (fchs->d_id == bfa_os_hton3b(FC_FABRIC_PORT)) {
1062                 bfa_trc(fabric->fcs, pid);
1063                 bfa_fcs_fabric_process_uf(fabric, fchs, len);
1064                 return;
1065         }
1066
1067         if (fabric->bport.pid == pid) {
1068                 /**
1069                  * All authentication frames should be routed to auth
1070                  */
1071                 bfa_trc(fabric->fcs, els_cmd->els_code);
1072                 if (els_cmd->els_code == FC_ELS_AUTH) {
1073                         bfa_trc(fabric->fcs, els_cmd->els_code);
1074                         fabric->auth.response = (u8 *) els_cmd;
1075                         return;
1076                 }
1077
1078                 bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
1079                 bfa_fcs_port_uf_recv(&fabric->bport, fchs, len);
1080                 return;
1081         }
1082
1083         /**
1084          * look for a matching local port ID
1085          */
1086         list_for_each(qe, &fabric->vport_q) {
1087                 vport = (struct bfa_fcs_vport_s *)qe;
1088                 if (vport->lport.pid == pid) {
1089                         bfa_fcs_port_uf_recv(&vport->lport, fchs, len);
1090                         return;
1091                 }
1092         }
1093         bfa_trc(fabric->fcs, els_cmd->els_code);
1094         bfa_fcs_port_uf_recv(&fabric->bport, fchs, len);
1095 }
1096
1097 /**
1098  *              Unsolicited frames to be processed by fabric.
1099  */
1100 static void
1101 bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1102                           u16 len)
1103 {
1104         struct fc_els_cmd_s   *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1105
1106         bfa_trc(fabric->fcs, els_cmd->els_code);
1107
1108         switch (els_cmd->els_code) {
1109         case FC_ELS_FLOGI:
1110                 bfa_fcs_fabric_process_flogi(fabric, fchs, len);
1111                 break;
1112
1113         default:
1114                 /*
1115                  * need to generate a LS_RJT
1116                  */
1117                 break;
1118         }
1119 }
1120
1121 /**
1122  *      Process incoming FLOGI
1123  */
1124 static void
1125 bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
1126                         struct fchs_s *fchs, u16 len)
1127 {
1128         struct fc_logi_s     *flogi = (struct fc_logi_s *) (fchs + 1);
1129         struct bfa_fcs_port_s *bport = &fabric->bport;
1130
1131         bfa_trc(fabric->fcs, fchs->s_id);
1132
1133         fabric->stats.flogi_rcvd++;
1134         /*
1135          * Check port type. It should be 0 = n-port.
1136          */
1137         if (flogi->csp.port_type) {
1138                 /*
1139                  * @todo: may need to send a LS_RJT
1140                  */
1141                 bfa_trc(fabric->fcs, flogi->port_name);
1142                 fabric->stats.flogi_rejected++;
1143                 return;
1144         }
1145
1146         fabric->bb_credit = bfa_os_ntohs(flogi->csp.bbcred);
1147         bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
1148         bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
1149
1150         /*
1151          * Send a Flogi Acc
1152          */
1153         bfa_fcs_fabric_send_flogi_acc(fabric);
1154         bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
1155 }
1156
1157 static void
1158 bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1159 {
1160         struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
1161         struct bfa_fcs_port_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
1162         struct bfa_s   *bfa = fabric->fcs->bfa;
1163         struct bfa_fcxp_s *fcxp;
1164         u16        reqlen;
1165         struct fchs_s          fchs;
1166
1167         fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
1168         /**
1169          * Do not expect this failure -- expect remote node to retry
1170          */
1171         if (!fcxp)
1172                 return;
1173
1174         reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1175                                     bfa_os_hton3b(FC_FABRIC_PORT),
1176                                     n2n_port->reply_oxid, pcfg->pwwn,
1177                                     pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa),
1178                                     bfa_fcport_get_rx_bbcredit(bfa));
1179
1180         bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps),
1181                         BFA_FALSE, FC_CLASS_3, reqlen, &fchs,
1182                         bfa_fcs_fabric_flogiacc_comp, fabric,
1183                         FC_MAX_PDUSZ, 0); /* Timeout 0 indicates no
1184                                            * response expected
1185                                            */
1186 }
1187
1188 /**
1189  *   Flogi Acc completion callback.
1190  */
1191 static void
1192 bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1193                              bfa_status_t status, u32 rsp_len,
1194                              u32 resid_len, struct fchs_s *rspfchs)
1195 {
1196         struct bfa_fcs_fabric_s *fabric = cbarg;
1197
1198         bfa_trc(fabric->fcs, status);
1199 }
1200
1201 /*
1202  *
1203  * @param[in] fabric - fabric
1204  * @param[in] result - 1
1205  *
1206  * @return - none
1207  */
1208 void
1209 bfa_fcs_auth_finished(struct bfa_fcs_fabric_s *fabric, enum auth_status status)
1210 {
1211         bfa_trc(fabric->fcs, status);
1212
1213         if (status == FC_AUTH_STATE_SUCCESS)
1214                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_SUCCESS);
1215         else
1216                 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_FAILED);
1217 }
1218
1219 /**
1220  * Send AEN notification
1221  */
1222 static void
1223 bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port,
1224                         enum bfa_port_aen_event event)
1225 {
1226         union bfa_aen_data_u aen_data;
1227         struct bfa_log_mod_s *logmod = port->fcs->logm;
1228         wwn_t           pwwn = bfa_fcs_port_get_pwwn(port);
1229         wwn_t           fwwn = bfa_fcs_port_get_fabric_name(port);
1230         char            pwwn_ptr[BFA_STRING_32];
1231         char            fwwn_ptr[BFA_STRING_32];
1232
1233         wwn2str(pwwn_ptr, pwwn);
1234         wwn2str(fwwn_ptr, fwwn);
1235
1236         bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event),
1237                 pwwn_ptr, fwwn_ptr);
1238
1239         aen_data.port.pwwn = pwwn;
1240         aen_data.port.fwwn = fwwn;
1241 }
1242
1243 /*
1244  *
1245  * @param[in] fabric - fabric
1246  * @param[in] wwn_t - new fabric name
1247  *
1248  * @return - none
1249  */
1250 void
1251 bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1252                                wwn_t fabric_name)
1253 {
1254         bfa_trc(fabric->fcs, fabric_name);
1255
1256         if (fabric->fabric_name == 0) {
1257                 /*
1258                  * With BRCD switches, we don't get Fabric Name in FLOGI.
1259                  * Don't generate a fabric name change event in this case.
1260                  */
1261                 fabric->fabric_name = fabric_name;
1262         } else {
1263                 fabric->fabric_name = fabric_name;
1264                 /*
1265                  * Generate a Event
1266                  */
1267                 bfa_fcs_fabric_aen_post(&fabric->bport,
1268                                         BFA_PORT_AEN_FABRIC_NAME_CHANGE);
1269         }
1270
1271 }
1272
1273 /**
1274  * Not used by FCS.
1275  */
1276 void
1277 bfa_cb_lps_flogo_comp(void *bfad, void *uarg)
1278 {
1279 }
1280
1281