blob: ddd4ba9317e6367c0dab349fb386a32e384975b7 [file] [log] [blame]
Jing Huang7725ccf2009-09-23 17:46:15 -07001/*
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
34BFA_TRC_FILE(FCS, FABRIC);
35
36#define BFA_FCS_FABRIC_RETRY_DELAY (2000) /* Milliseconds */
37#define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */
38
Jing Huangf8ceafd2009-09-25 12:29:54 -070039#define bfa_fcs_fabric_set_opertype(__fabric) do { \
Krishna Gudipati1c8a4c32010-03-05 19:37:37 -080040 if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \
Jing Huangf8ceafd2009-09-25 12:29:54 -070041 == BFA_PPORT_TOPOLOGY_P2P) \
42 (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \
43 else \
44 (__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT; \
Jing Huang7725ccf2009-09-23 17:46:15 -070045} while (0)
46
47/*
48 * forward declarations
49 */
50static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
51static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
52static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
53static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
54static void bfa_fcs_fabric_delay(void *cbarg);
55static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
56static void bfa_fcs_fabric_delete_comp(void *cbarg);
57static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
58 struct fchs_s *fchs, u16 len);
59static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
60 struct fchs_s *fchs, u16 len);
61static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
62static 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 */
75enum 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
97static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
98 enum bfa_fcs_fabric_event event);
99static void bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
100 enum bfa_fcs_fabric_event event);
101static void bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
102 enum bfa_fcs_fabric_event event);
103static void bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
104 enum bfa_fcs_fabric_event event);
105static void bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
106 enum bfa_fcs_fabric_event event);
107static void bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
108 enum bfa_fcs_fabric_event event);
109static void bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
110 enum bfa_fcs_fabric_event event);
111static void bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
112 enum bfa_fcs_fabric_event event);
113static void bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
114 enum bfa_fcs_fabric_event event);
115static void bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
116 enum bfa_fcs_fabric_event event);
117static void bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
118 enum bfa_fcs_fabric_event event);
119static void bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
120 enum bfa_fcs_fabric_event event);
121static void bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
122 enum bfa_fcs_fabric_event event);
123static 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 */
128static void
129bfa_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);
Krishna Gudipatie6714322010-03-03 17:44:02 -0800139 bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
Jing Huang7725ccf2009-09-23 17:46:15 -0700140 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 */
154static void
155bfa_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:
Krishna Gudipati1c8a4c32010-03-05 19:37:37 -0800163 if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
Jing Huang7725ccf2009-09-23 17:46:15 -0700164 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 */
188static void
189bfa_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 */
217static void
218bfa_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
Krishna Gudipati1c8a4c32010-03-05 19:37:37 -0800227 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
Jing Huang7725ccf2009-09-23 17:46:15 -0700228 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;
Krishna Gudipati1c8a4c32010-03-05 19:37:37 -0800254 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
Jing Huang7725ccf2009-09-23 17:46:15 -0700255 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
276static void
277bfa_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 */
308static void
309bfa_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 */
348static void
349bfa_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 */
374static void
375bfa_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 */
400static void
401bfa_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);
Krishna Gudipati1c8a4c32010-03-05 19:37:37 -0800421 bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
Jing Huang7725ccf2009-09-23 17:46:15 -0700422 break;
423
424 default:
425 bfa_sm_fault(fabric->fcs, event);
426 }
427}
428
429/**
430 * Fabric is online - normal operating state.
431 */
432static void
433bfa_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 */
467static void
468bfa_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 */
491static void
492bfa_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 */
502static void
503bfa_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 */
517static void
518bfa_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
548static void
549bfa_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 */
561void
562bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
563{
564 struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
Krishna Gudipati25e29342010-03-05 19:38:17 -0800565 char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
Jing Huang7725ccf2009-09-23 17:46:15 -0700566 struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
567
Krishna Gudipati25e29342010-03-05 19:38:17 -0800568 bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
Jing Huang7725ccf2009-09-23 17:46:15 -0700569
570 /*
571 * Model name/number
572 */
Krishna Gudipati25e29342010-03-05 19:38:17 -0800573 strncpy((char *)&port_cfg->sym_name, model,
Jing Huang7725ccf2009-09-23 17:46:15 -0700574 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 */
631void
632bfa_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 */
712static void
713bfa_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
Krishna Gudipati1c8a4c32010-03-05 19:37:37 -0800719 if (bfa_fcport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
720 alpa = bfa_fcport_get_myalpa(bfa);
Jing Huang7725ccf2009-09-23 17:46:15 -0700721
Krishna Gudipati1c8a4c32010-03-05 19:37:37 -0800722 bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
Jing Huang7725ccf2009-09-23 17:46:15 -0700723 pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
724
725 fabric->stats.flogi_sent++;
726}
727
728static void
729bfa_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
750static void
751bfa_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
773static void
774bfa_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 */
784static void
785bfa_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;
Jing Huangd9883542010-07-08 19:46:26 -0700792 bfa_fcs_vport_fcs_delete(vport);
Jing Huang7725ccf2009-09-23 17:46:15 -0700793 }
794
795 bfa_fcs_port_delete(&fabric->bport);
796 bfa_wc_wait(&fabric->wc);
797}
798
799static void
800bfa_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/**
Krishna Gudipati82794a22010-03-03 17:43:30 -0800814 * Attach time initialization
Jing Huang7725ccf2009-09-23 17:46:15 -0700815 */
816void
Krishna Gudipati82794a22010-03-03 17:43:30 -0800817bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
Jing Huang7725ccf2009-09-23 17:46:15 -0700818{
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);
Krishna Gudipatie6714322010-03-03 17:44:02 -0800841 bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
Krishna Gudipati82794a22010-03-03 17:43:30 -0800842}
843
844void
845bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
846{
847 bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
Jing Huang7725ccf2009-09-23 17:46:15 -0700848 bfa_trc(fcs, 0);
849}
850
851/**
852 * Module cleanup
853 */
854void
855bfa_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 */
872void
873bfa_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 */
885void
886bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs)
887{
888}
889
890bfa_boolean_t
891bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
892{
Jing Huangf8ceafd2009-09-25 12:29:54 -0700893 return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback);
Jing Huang7725ccf2009-09-23 17:46:15 -0700894}
895
Krishna Gudipatif926a052010-03-05 19:36:00 -0800896bfa_boolean_t
897bfa_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
Jing Huang7725ccf2009-09-23 17:46:15 -0700902enum bfa_pport_type
903bfa_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 */
911void
912bfa_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 */
921void
922bfa_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 */
939void
940bfa_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 */
958void
959bfa_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 */
970void
971bfa_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 */
983int
984bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric)
985{
Jing Huangf8ceafd2009-09-25 12:29:54 -0700986 return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online);
Jing Huang7725ccf2009-09-23 17:46:15 -0700987}
988
989
990bfa_status_t
991bfa_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 */
1002struct bfa_fcs_vport_s *
1003bfa_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 */
1024u16
1025bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric)
1026{
Jing Huangf8ceafd2009-09-25 12:29:54 -07001027 return fabric->num_vports;
Jing Huang7725ccf2009-09-23 17:46:15 -07001028}
1029
Jing Huang4f1806b2010-07-08 19:50:15 -07001030/*
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
1041u16
1042bfa_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
Jing Huang7725ccf2009-09-23 17:46:15 -07001056/**
1057 * Unsolicited frame receive handling.
1058 */
1059void
1060bfa_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 */
1126static void
1127bfa_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 */
1150static void
1151bfa_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
1183static void
1184bfa_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,
Krishna Gudipati1c8a4c32010-03-05 19:37:37 -08001203 pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa),
1204 bfa_fcport_get_rx_bbcredit(bfa));
Jing Huang7725ccf2009-09-23 17:46:15 -07001205
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 */
1217static void
1218bfa_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 */
1234void
1235bfa_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 */
1248static void
1249bfa_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
Krishna Gudipati0a4b1fc2010-03-05 19:37:57 -08001262 bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event),
1263 pwwn_ptr, fwwn_ptr);
Jing Huang7725ccf2009-09-23 17:46:15 -07001264
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 */
1276void
1277bfa_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/**
Jing Huang15b64a82010-07-08 19:48:12 -07001300 *
1301 * @param[in] fabric - fabric
1302 * @param[in] node_symname -
1303 * Caller allocated buffer to receive the symbolic name
1304 *
1305 * @return - none
1306 */
1307void
1308bfa_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/**
Jing Huang7725ccf2009-09-23 17:46:15 -07001316 * Not used by FCS.
1317 */
1318void
1319bfa_cb_lps_flogo_comp(void *bfad, void *uarg)
1320{
1321}
1322
1323