2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
19 * @page ns_sm_info VPORT NS State Machine
21 * @section ns_sm_interactions VPORT NS State Machine Interactions
23 * @section ns_sm VPORT NS State Machine
28 #include <bfa_iocfc.h>
29 #include "fcs_lport.h"
30 #include "fcs_rport.h"
31 #include "fcs_trcmod.h"
34 #include "lport_priv.h"
36 BFA_TRC_FILE(FCS
, NS
);
39 * forward declarations
41 static void bfa_fcs_port_ns_send_plogi(void *ns_cbarg
,
42 struct bfa_fcxp_s
*fcxp_alloced
);
43 static void bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg
,
44 struct bfa_fcxp_s
*fcxp_alloced
);
45 static void bfa_fcs_port_ns_send_rft_id(void *ns_cbarg
,
46 struct bfa_fcxp_s
*fcxp_alloced
);
47 static void bfa_fcs_port_ns_send_rff_id(void *ns_cbarg
,
48 struct bfa_fcxp_s
*fcxp_alloced
);
49 static void bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg
,
50 struct bfa_fcxp_s
*fcxp_alloced
);
51 static void bfa_fcs_port_ns_timeout(void *arg
);
52 static void bfa_fcs_port_ns_plogi_response(void *fcsarg
,
53 struct bfa_fcxp_s
*fcxp
,
55 bfa_status_t req_status
,
58 struct fchs_s
*rsp_fchs
);
59 static void bfa_fcs_port_ns_rspn_id_response(void *fcsarg
,
60 struct bfa_fcxp_s
*fcxp
,
62 bfa_status_t req_status
,
65 struct fchs_s
*rsp_fchs
);
66 static void bfa_fcs_port_ns_rft_id_response(void *fcsarg
,
67 struct bfa_fcxp_s
*fcxp
,
69 bfa_status_t req_status
,
72 struct fchs_s
*rsp_fchs
);
73 static void bfa_fcs_port_ns_rff_id_response(void *fcsarg
,
74 struct bfa_fcxp_s
*fcxp
,
76 bfa_status_t req_status
,
79 struct fchs_s
*rsp_fchs
);
80 static void bfa_fcs_port_ns_gid_ft_response(void *fcsarg
,
81 struct bfa_fcxp_s
*fcxp
,
83 bfa_status_t req_status
,
86 struct fchs_s
*rsp_fchs
);
87 static void bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s
*port
,
91 static void bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s
*port
);
93 * fcs_ns_sm FCS nameserver interface state machine
97 * VPort NS State Machine events
100 NSSM_EVENT_PORT_ONLINE
= 1,
101 NSSM_EVENT_PORT_OFFLINE
= 2,
102 NSSM_EVENT_PLOGI_SENT
= 3,
103 NSSM_EVENT_RSP_OK
= 4,
104 NSSM_EVENT_RSP_ERROR
= 5,
105 NSSM_EVENT_TIMEOUT
= 6,
106 NSSM_EVENT_NS_QUERY
= 7,
107 NSSM_EVENT_RSPNID_SENT
= 8,
108 NSSM_EVENT_RFTID_SENT
= 9,
109 NSSM_EVENT_RFFID_SENT
= 10,
110 NSSM_EVENT_GIDFT_SENT
= 11,
113 static void bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s
*ns
,
114 enum vport_ns_event event
);
115 static void bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s
*ns
,
116 enum vport_ns_event event
);
117 static void bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s
*ns
,
118 enum vport_ns_event event
);
119 static void bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s
*ns
,
120 enum vport_ns_event event
);
121 static void bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s
*ns
,
122 enum vport_ns_event event
);
123 static void bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s
*ns
,
124 enum vport_ns_event event
);
125 static void bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s
*ns
,
126 enum vport_ns_event event
);
127 static void bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s
*ns
,
128 enum vport_ns_event event
);
129 static void bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s
*ns
,
130 enum vport_ns_event event
);
131 static void bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s
*ns
,
132 enum vport_ns_event event
);
133 static void bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s
*ns
,
134 enum vport_ns_event event
);
135 static void bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s
*ns
,
136 enum vport_ns_event event
);
137 static void bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s
*ns
,
138 enum vport_ns_event event
);
139 static void bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s
*ns
,
140 enum vport_ns_event event
);
141 static void bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s
*ns
,
142 enum vport_ns_event event
);
143 static void bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s
*ns
,
144 enum vport_ns_event event
);
145 static void bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s
*ns
,
146 enum vport_ns_event event
);
148 * Start in offline state - awaiting linkup
151 bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s
*ns
,
152 enum vport_ns_event event
)
154 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
155 bfa_trc(ns
->port
->fcs
, event
);
158 case NSSM_EVENT_PORT_ONLINE
:
159 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_plogi_sending
);
160 bfa_fcs_port_ns_send_plogi(ns
, NULL
);
163 case NSSM_EVENT_PORT_OFFLINE
:
172 bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s
*ns
,
173 enum vport_ns_event event
)
175 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
176 bfa_trc(ns
->port
->fcs
, event
);
179 case NSSM_EVENT_PLOGI_SENT
:
180 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_plogi
);
183 case NSSM_EVENT_PORT_OFFLINE
:
184 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
185 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
195 bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s
*ns
,
196 enum vport_ns_event event
)
198 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
199 bfa_trc(ns
->port
->fcs
, event
);
202 case NSSM_EVENT_RSP_ERROR
:
204 * Start timer for a delayed retry
206 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_plogi_retry
);
207 ns
->port
->stats
.ns_retries
++;
208 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
), &ns
->timer
,
209 bfa_fcs_port_ns_timeout
, ns
,
210 BFA_FCS_RETRY_TIMEOUT
);
213 case NSSM_EVENT_RSP_OK
:
214 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_sending_rspn_id
);
215 bfa_fcs_port_ns_send_rspn_id(ns
, NULL
);
218 case NSSM_EVENT_PORT_OFFLINE
:
219 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
220 bfa_fcxp_discard(ns
->fcxp
);
229 bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s
*ns
,
230 enum vport_ns_event event
)
232 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
233 bfa_trc(ns
->port
->fcs
, event
);
236 case NSSM_EVENT_TIMEOUT
:
238 * Retry Timer Expired. Re-send
240 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_plogi_sending
);
241 bfa_fcs_port_ns_send_plogi(ns
, NULL
);
244 case NSSM_EVENT_PORT_OFFLINE
:
245 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
246 bfa_timer_stop(&ns
->timer
);
255 bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s
*ns
,
256 enum vport_ns_event event
)
258 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
259 bfa_trc(ns
->port
->fcs
, event
);
262 case NSSM_EVENT_RSPNID_SENT
:
263 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_rspn_id
);
266 case NSSM_EVENT_PORT_OFFLINE
:
267 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
268 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
278 bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s
*ns
,
279 enum vport_ns_event event
)
281 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
282 bfa_trc(ns
->port
->fcs
, event
);
285 case NSSM_EVENT_RSP_ERROR
:
287 * Start timer for a delayed retry
289 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_rspn_id_retry
);
290 ns
->port
->stats
.ns_retries
++;
291 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
), &ns
->timer
,
292 bfa_fcs_port_ns_timeout
, ns
,
293 BFA_FCS_RETRY_TIMEOUT
);
296 case NSSM_EVENT_RSP_OK
:
297 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_sending_rft_id
);
298 bfa_fcs_port_ns_send_rft_id(ns
, NULL
);
301 case NSSM_EVENT_PORT_OFFLINE
:
302 bfa_fcxp_discard(ns
->fcxp
);
303 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
312 bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s
*ns
,
313 enum vport_ns_event event
)
315 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
316 bfa_trc(ns
->port
->fcs
, event
);
319 case NSSM_EVENT_TIMEOUT
:
321 * Retry Timer Expired. Re-send
323 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_sending_rspn_id
);
324 bfa_fcs_port_ns_send_rspn_id(ns
, NULL
);
327 case NSSM_EVENT_PORT_OFFLINE
:
328 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
329 bfa_timer_stop(&ns
->timer
);
338 bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s
*ns
,
339 enum vport_ns_event event
)
341 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
342 bfa_trc(ns
->port
->fcs
, event
);
345 case NSSM_EVENT_RFTID_SENT
:
346 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_rft_id
);
349 case NSSM_EVENT_PORT_OFFLINE
:
350 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
351 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
361 bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s
*ns
,
362 enum vport_ns_event event
)
364 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
365 bfa_trc(ns
->port
->fcs
, event
);
368 case NSSM_EVENT_RSP_OK
:
370 * Now move to register FC4 Features
372 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_sending_rff_id
);
373 bfa_fcs_port_ns_send_rff_id(ns
, NULL
);
376 case NSSM_EVENT_RSP_ERROR
:
378 * Start timer for a delayed retry
380 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_rft_id_retry
);
381 ns
->port
->stats
.ns_retries
++;
382 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
), &ns
->timer
,
383 bfa_fcs_port_ns_timeout
, ns
,
384 BFA_FCS_RETRY_TIMEOUT
);
387 case NSSM_EVENT_PORT_OFFLINE
:
388 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
389 bfa_fcxp_discard(ns
->fcxp
);
398 bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s
*ns
,
399 enum vport_ns_event event
)
401 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
402 bfa_trc(ns
->port
->fcs
, event
);
405 case NSSM_EVENT_TIMEOUT
:
406 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_sending_rft_id
);
407 bfa_fcs_port_ns_send_rft_id(ns
, NULL
);
410 case NSSM_EVENT_PORT_OFFLINE
:
411 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
412 bfa_timer_stop(&ns
->timer
);
421 bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s
*ns
,
422 enum vport_ns_event event
)
424 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
425 bfa_trc(ns
->port
->fcs
, event
);
428 case NSSM_EVENT_RFFID_SENT
:
429 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_rff_id
);
432 case NSSM_EVENT_PORT_OFFLINE
:
433 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
434 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
444 bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s
*ns
,
445 enum vport_ns_event event
)
447 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
448 bfa_trc(ns
->port
->fcs
, event
);
451 case NSSM_EVENT_RSP_OK
:
454 * If min cfg mode is enabled, we donot initiate rport
455 * discovery with the fabric. Instead, we will retrieve the
456 * boot targets from HAL/FW.
458 if (__fcs_min_cfg(ns
->port
->fcs
)) {
459 bfa_fcs_port_ns_boot_target_disc(ns
->port
);
460 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_online
);
465 * If the port role is Initiator Mode issue NS query.
466 * If it is Target Mode, skip this and go to online.
468 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns
->port
)) {
469 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_sending_gid_ft
);
470 bfa_fcs_port_ns_send_gid_ft(ns
, NULL
);
471 } else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns
->port
)) {
472 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_online
);
475 * kick off mgmt srvr state machine
477 bfa_fcs_port_ms_online(ns
->port
);
480 case NSSM_EVENT_RSP_ERROR
:
482 * Start timer for a delayed retry
484 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_rff_id_retry
);
485 ns
->port
->stats
.ns_retries
++;
486 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
), &ns
->timer
,
487 bfa_fcs_port_ns_timeout
, ns
,
488 BFA_FCS_RETRY_TIMEOUT
);
491 case NSSM_EVENT_PORT_OFFLINE
:
492 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
493 bfa_fcxp_discard(ns
->fcxp
);
502 bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s
*ns
,
503 enum vport_ns_event event
)
505 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
506 bfa_trc(ns
->port
->fcs
, event
);
509 case NSSM_EVENT_TIMEOUT
:
510 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_sending_rff_id
);
511 bfa_fcs_port_ns_send_rff_id(ns
, NULL
);
514 case NSSM_EVENT_PORT_OFFLINE
:
515 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
516 bfa_timer_stop(&ns
->timer
);
524 bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s
*ns
,
525 enum vport_ns_event event
)
527 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
528 bfa_trc(ns
->port
->fcs
, event
);
531 case NSSM_EVENT_GIDFT_SENT
:
532 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_gid_ft
);
535 case NSSM_EVENT_PORT_OFFLINE
:
536 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
537 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
),
547 bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s
*ns
,
548 enum vport_ns_event event
)
550 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
551 bfa_trc(ns
->port
->fcs
, event
);
554 case NSSM_EVENT_RSP_OK
:
555 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_online
);
558 case NSSM_EVENT_RSP_ERROR
:
560 * TBD: for certain reject codes, we don't need to retry
563 * Start timer for a delayed retry
565 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_gid_ft_retry
);
566 ns
->port
->stats
.ns_retries
++;
567 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns
->port
), &ns
->timer
,
568 bfa_fcs_port_ns_timeout
, ns
,
569 BFA_FCS_RETRY_TIMEOUT
);
572 case NSSM_EVENT_PORT_OFFLINE
:
573 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
574 bfa_fcxp_discard(ns
->fcxp
);
583 bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s
*ns
,
584 enum vport_ns_event event
)
586 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
587 bfa_trc(ns
->port
->fcs
, event
);
590 case NSSM_EVENT_TIMEOUT
:
591 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_sending_gid_ft
);
592 bfa_fcs_port_ns_send_gid_ft(ns
, NULL
);
595 case NSSM_EVENT_PORT_OFFLINE
:
596 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
597 bfa_timer_stop(&ns
->timer
);
606 bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s
*ns
,
607 enum vport_ns_event event
)
609 bfa_trc(ns
->port
->fcs
, ns
->port
->port_cfg
.pwwn
);
610 bfa_trc(ns
->port
->fcs
, event
);
613 case NSSM_EVENT_PORT_OFFLINE
:
614 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
617 case NSSM_EVENT_NS_QUERY
:
619 * If the port role is Initiator Mode issue NS query.
620 * If it is Target Mode, skip this and go to online.
622 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns
->port
)) {
623 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_sending_gid_ft
);
624 bfa_fcs_port_ns_send_gid_ft(ns
, NULL
);
636 * ns_pvt Nameserver local functions
640 bfa_fcs_port_ns_send_plogi(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
642 struct bfa_fcs_port_ns_s
*ns
= ns_cbarg
;
643 struct bfa_fcs_port_s
*port
= ns
->port
;
646 struct bfa_fcxp_s
*fcxp
;
648 bfa_trc(port
->fcs
, port
->pid
);
650 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
652 port
->stats
.ns_plogi_alloc_wait
++;
653 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
654 bfa_fcs_port_ns_send_plogi
, ns
);
659 len
= fc_plogi_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
660 bfa_os_hton3b(FC_NAME_SERVER
),
661 bfa_fcs_port_get_fcid(port
), 0,
662 port
->port_cfg
.pwwn
, port
->port_cfg
.nwwn
,
663 bfa_pport_get_maxfrsize(port
->fcs
->bfa
));
665 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
666 FC_CLASS_3
, len
, &fchs
, bfa_fcs_port_ns_plogi_response
,
667 (void *)ns
, FC_MAX_PDUSZ
, FC_RA_TOV
);
668 port
->stats
.ns_plogi_sent
++;
670 bfa_sm_send_event(ns
, NSSM_EVENT_PLOGI_SENT
);
674 bfa_fcs_port_ns_plogi_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
675 void *cbarg
, bfa_status_t req_status
,
676 u32 rsp_len
, u32 resid_len
,
677 struct fchs_s
*rsp_fchs
)
679 struct bfa_fcs_port_ns_s
*ns
= (struct bfa_fcs_port_ns_s
*)cbarg
;
680 struct bfa_fcs_port_s
*port
= ns
->port
;
681 /* struct fc_logi_s *plogi_resp; */
682 struct fc_els_cmd_s
*els_cmd
;
683 struct fc_ls_rjt_s
*ls_rjt
;
685 bfa_trc(port
->fcs
, req_status
);
686 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
691 if (req_status
!= BFA_STATUS_OK
) {
692 bfa_trc(port
->fcs
, req_status
);
693 port
->stats
.ns_plogi_rsp_err
++;
694 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
698 els_cmd
= (struct fc_els_cmd_s
*) BFA_FCXP_RSP_PLD(fcxp
);
700 switch (els_cmd
->els_code
) {
703 if (rsp_len
< sizeof(struct fc_logi_s
)) {
704 bfa_trc(port
->fcs
, rsp_len
);
705 port
->stats
.ns_plogi_acc_err
++;
706 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
709 port
->stats
.ns_plogi_accepts
++;
710 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
714 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
716 bfa_trc(port
->fcs
, ls_rjt
->reason_code
);
717 bfa_trc(port
->fcs
, ls_rjt
->reason_code_expl
);
719 port
->stats
.ns_rejects
++;
721 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
725 port
->stats
.ns_plogi_unknown_rsp
++;
726 bfa_trc(port
->fcs
, els_cmd
->els_code
);
727 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
732 * Register the symbolic port name.
735 bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
737 struct bfa_fcs_port_ns_s
*ns
= ns_cbarg
;
738 struct bfa_fcs_port_s
*port
= ns
->port
;
741 struct bfa_fcxp_s
*fcxp
;
743 u8
*psymbl
= &symbl
[0];
745 bfa_os_memset(symbl
, 0, sizeof(symbl
));
747 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
749 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
751 port
->stats
.ns_rspnid_alloc_wait
++;
752 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
753 bfa_fcs_port_ns_send_rspn_id
, ns
);
759 * for V-Port, form a Port Symbolic Name
763 * we append the vport's port symbolic name to that of the base port.
766 strncpy((char *)psymbl
,
768 &(bfa_fcs_port_get_psym_name
769 (bfa_fcs_get_base_port(port
->fcs
))),
771 &bfa_fcs_port_get_psym_name(bfa_fcs_get_base_port
775 * Ensure we have a null terminating string.
778 psymbl
)[strlen((char *)
779 &bfa_fcs_port_get_psym_name
780 (bfa_fcs_get_base_port(port
->fcs
)))] = 0;
782 strncat((char *)psymbl
,
783 (char *)&(bfa_fcs_port_get_psym_name(port
)),
784 strlen((char *)&bfa_fcs_port_get_psym_name(port
)));
786 psymbl
= (u8
*) &(bfa_fcs_port_get_psym_name(port
));
789 len
= fc_rspnid_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
790 bfa_fcs_port_get_fcid(port
), 0, psymbl
);
792 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
793 FC_CLASS_3
, len
, &fchs
, bfa_fcs_port_ns_rspn_id_response
,
794 (void *)ns
, FC_MAX_PDUSZ
, FC_RA_TOV
);
796 port
->stats
.ns_rspnid_sent
++;
798 bfa_sm_send_event(ns
, NSSM_EVENT_RSPNID_SENT
);
802 bfa_fcs_port_ns_rspn_id_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
803 void *cbarg
, bfa_status_t req_status
,
804 u32 rsp_len
, u32 resid_len
,
805 struct fchs_s
*rsp_fchs
)
807 struct bfa_fcs_port_ns_s
*ns
= (struct bfa_fcs_port_ns_s
*)cbarg
;
808 struct bfa_fcs_port_s
*port
= ns
->port
;
809 struct ct_hdr_s
*cthdr
= NULL
;
811 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
816 if (req_status
!= BFA_STATUS_OK
) {
817 bfa_trc(port
->fcs
, req_status
);
818 port
->stats
.ns_rspnid_rsp_err
++;
819 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
823 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
824 cthdr
->cmd_rsp_code
= bfa_os_ntohs(cthdr
->cmd_rsp_code
);
826 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
827 port
->stats
.ns_rspnid_accepts
++;
828 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
832 port
->stats
.ns_rspnid_rejects
++;
833 bfa_trc(port
->fcs
, cthdr
->reason_code
);
834 bfa_trc(port
->fcs
, cthdr
->exp_code
);
835 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
840 * TBD, Need to retrieve this from the OS driver, in case IPFC is enabled ?
843 bfa_fcs_port_ns_send_rft_id(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
845 struct bfa_fcs_port_ns_s
*ns
= ns_cbarg
;
846 struct bfa_fcs_port_s
*port
= ns
->port
;
849 struct bfa_fcxp_s
*fcxp
;
851 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
853 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
855 port
->stats
.ns_rftid_alloc_wait
++;
856 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
857 bfa_fcs_port_ns_send_rft_id
, ns
);
862 len
= fc_rftid_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
863 bfa_fcs_port_get_fcid(port
), 0,
864 port
->port_cfg
.roles
);
866 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
867 FC_CLASS_3
, len
, &fchs
, bfa_fcs_port_ns_rft_id_response
,
868 (void *)ns
, FC_MAX_PDUSZ
, FC_RA_TOV
);
870 port
->stats
.ns_rftid_sent
++;
871 bfa_sm_send_event(ns
, NSSM_EVENT_RFTID_SENT
);
875 bfa_fcs_port_ns_rft_id_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
876 void *cbarg
, bfa_status_t req_status
,
877 u32 rsp_len
, u32 resid_len
,
878 struct fchs_s
*rsp_fchs
)
880 struct bfa_fcs_port_ns_s
*ns
= (struct bfa_fcs_port_ns_s
*)cbarg
;
881 struct bfa_fcs_port_s
*port
= ns
->port
;
882 struct ct_hdr_s
*cthdr
= NULL
;
884 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
889 if (req_status
!= BFA_STATUS_OK
) {
890 bfa_trc(port
->fcs
, req_status
);
891 port
->stats
.ns_rftid_rsp_err
++;
892 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
896 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
897 cthdr
->cmd_rsp_code
= bfa_os_ntohs(cthdr
->cmd_rsp_code
);
899 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
900 port
->stats
.ns_rftid_accepts
++;
901 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
905 port
->stats
.ns_rftid_rejects
++;
906 bfa_trc(port
->fcs
, cthdr
->reason_code
);
907 bfa_trc(port
->fcs
, cthdr
->exp_code
);
908 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
912 * Register FC4-Features : Should be done after RFT_ID
915 bfa_fcs_port_ns_send_rff_id(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
917 struct bfa_fcs_port_ns_s
*ns
= ns_cbarg
;
918 struct bfa_fcs_port_s
*port
= ns
->port
;
921 struct bfa_fcxp_s
*fcxp
;
924 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
926 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
928 port
->stats
.ns_rffid_alloc_wait
++;
929 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
930 bfa_fcs_port_ns_send_rff_id
, ns
);
935 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns
->port
)) {
936 fc4_ftrs
= FC_GS_FCP_FC4_FEATURE_INITIATOR
;
937 } else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns
->port
)) {
938 fc4_ftrs
= FC_GS_FCP_FC4_FEATURE_TARGET
;
941 len
= fc_rffid_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
942 bfa_fcs_port_get_fcid(port
), 0, FC_TYPE_FCP
,
945 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
946 FC_CLASS_3
, len
, &fchs
, bfa_fcs_port_ns_rff_id_response
,
947 (void *)ns
, FC_MAX_PDUSZ
, FC_RA_TOV
);
949 port
->stats
.ns_rffid_sent
++;
950 bfa_sm_send_event(ns
, NSSM_EVENT_RFFID_SENT
);
954 bfa_fcs_port_ns_rff_id_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
955 void *cbarg
, bfa_status_t req_status
,
956 u32 rsp_len
, u32 resid_len
,
957 struct fchs_s
*rsp_fchs
)
959 struct bfa_fcs_port_ns_s
*ns
= (struct bfa_fcs_port_ns_s
*)cbarg
;
960 struct bfa_fcs_port_s
*port
= ns
->port
;
961 struct ct_hdr_s
*cthdr
= NULL
;
963 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
968 if (req_status
!= BFA_STATUS_OK
) {
969 bfa_trc(port
->fcs
, req_status
);
970 port
->stats
.ns_rffid_rsp_err
++;
971 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
975 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
976 cthdr
->cmd_rsp_code
= bfa_os_ntohs(cthdr
->cmd_rsp_code
);
978 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
979 port
->stats
.ns_rffid_accepts
++;
980 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
984 port
->stats
.ns_rffid_rejects
++;
985 bfa_trc(port
->fcs
, cthdr
->reason_code
);
986 bfa_trc(port
->fcs
, cthdr
->exp_code
);
988 if (cthdr
->reason_code
== CT_RSN_NOT_SUPP
) {
990 * if this command is not supported, we don't retry
992 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
994 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
999 * Query Fabric for FC4-Types Devices.
1001 * TBD : Need to use a local (FCS private) response buffer, since the response
1002 * can be larger than 2K.
1005 bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1007 struct bfa_fcs_port_ns_s
*ns
= ns_cbarg
;
1008 struct bfa_fcs_port_s
*port
= ns
->port
;
1011 struct bfa_fcxp_s
*fcxp
;
1013 bfa_trc(port
->fcs
, port
->pid
);
1015 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1017 port
->stats
.ns_gidft_alloc_wait
++;
1018 bfa_fcxp_alloc_wait(port
->fcs
->bfa
, &ns
->fcxp_wqe
,
1019 bfa_fcs_port_ns_send_gid_ft
, ns
);
1025 * This query is only initiated for FCP initiator mode.
1027 len
= fc_gid_ft_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
), ns
->port
->pid
,
1030 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1031 FC_CLASS_3
, len
, &fchs
, bfa_fcs_port_ns_gid_ft_response
,
1032 (void *)ns
, bfa_fcxp_get_maxrsp(port
->fcs
->bfa
),
1035 port
->stats
.ns_gidft_sent
++;
1037 bfa_sm_send_event(ns
, NSSM_EVENT_GIDFT_SENT
);
1041 bfa_fcs_port_ns_gid_ft_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
,
1042 void *cbarg
, bfa_status_t req_status
,
1043 u32 rsp_len
, u32 resid_len
,
1044 struct fchs_s
*rsp_fchs
)
1046 struct bfa_fcs_port_ns_s
*ns
= (struct bfa_fcs_port_ns_s
*)cbarg
;
1047 struct bfa_fcs_port_s
*port
= ns
->port
;
1048 struct ct_hdr_s
*cthdr
= NULL
;
1051 bfa_trc(port
->fcs
, port
->port_cfg
.pwwn
);
1056 if (req_status
!= BFA_STATUS_OK
) {
1057 bfa_trc(port
->fcs
, req_status
);
1058 port
->stats
.ns_gidft_rsp_err
++;
1059 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
1063 if (resid_len
!= 0) {
1065 * TBD : we will need to allocate a larger buffer & retry the
1068 bfa_trc(port
->fcs
, rsp_len
);
1069 bfa_trc(port
->fcs
, resid_len
);
1073 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1074 cthdr
->cmd_rsp_code
= bfa_os_ntohs(cthdr
->cmd_rsp_code
);
1076 switch (cthdr
->cmd_rsp_code
) {
1080 port
->stats
.ns_gidft_accepts
++;
1081 n_pids
= (fc_get_ctresp_pyld_len(rsp_len
) / sizeof(u32
));
1082 bfa_trc(port
->fcs
, n_pids
);
1083 bfa_fcs_port_ns_process_gidft_pids(port
,
1084 (u32
*) (cthdr
+ 1),
1086 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
1092 * Check the reason code & explanation.
1093 * There may not have been any FC4 devices in the fabric
1095 port
->stats
.ns_gidft_rejects
++;
1096 bfa_trc(port
->fcs
, cthdr
->reason_code
);
1097 bfa_trc(port
->fcs
, cthdr
->exp_code
);
1099 if ((cthdr
->reason_code
== CT_RSN_UNABLE_TO_PERF
)
1100 && (cthdr
->exp_code
== CT_NS_EXP_FT_NOT_REG
)) {
1102 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_OK
);
1105 * for all other errors, retry
1107 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
1112 port
->stats
.ns_gidft_unknown_rsp
++;
1113 bfa_trc(port
->fcs
, cthdr
->cmd_rsp_code
);
1114 bfa_sm_send_event(ns
, NSSM_EVENT_RSP_ERROR
);
1119 * This routine will be called by bfa_timer on timer timeouts.
1121 * param[in] port - pointer to bfa_fcs_port_t.
1126 * Special Considerations:
1131 bfa_fcs_port_ns_timeout(void *arg
)
1133 struct bfa_fcs_port_ns_s
*ns
= (struct bfa_fcs_port_ns_s
*)arg
;
1135 ns
->port
->stats
.ns_timeouts
++;
1136 bfa_sm_send_event(ns
, NSSM_EVENT_TIMEOUT
);
1140 * Process the PID list in GID_FT response
1143 bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s
*port
,
1144 u32
*pid_buf
, u32 n_pids
)
1146 struct fcgs_gidft_resp_s
*gidft_entry
;
1147 struct bfa_fcs_rport_s
*rport
;
1150 for (ii
= 0; ii
< n_pids
; ii
++) {
1151 gidft_entry
= (struct fcgs_gidft_resp_s
*) &pid_buf
[ii
];
1153 if (gidft_entry
->pid
== port
->pid
)
1157 * Check if this rport already exists
1159 rport
= bfa_fcs_port_get_rport_by_pid(port
, gidft_entry
->pid
);
1160 if (rport
== NULL
) {
1162 * this is a new device. create rport
1164 rport
= bfa_fcs_rport_create(port
, gidft_entry
->pid
);
1167 * this rport already exists
1169 bfa_fcs_rport_scn(rport
);
1172 bfa_trc(port
->fcs
, gidft_entry
->pid
);
1175 * if the last entry bit is set, bail out.
1177 if (gidft_entry
->last
)
1183 * fcs_ns_public FCS nameserver public interfaces
1187 * Functions called by port/fab.
1188 * These will send relevant Events to the ns state machine.
1191 bfa_fcs_port_ns_init(struct bfa_fcs_port_s
*port
)
1193 struct bfa_fcs_port_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
1196 bfa_sm_set_state(ns
, bfa_fcs_port_ns_sm_offline
);
1200 bfa_fcs_port_ns_offline(struct bfa_fcs_port_s
*port
)
1202 struct bfa_fcs_port_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
1205 bfa_sm_send_event(ns
, NSSM_EVENT_PORT_OFFLINE
);
1209 bfa_fcs_port_ns_online(struct bfa_fcs_port_s
*port
)
1211 struct bfa_fcs_port_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
1214 bfa_sm_send_event(ns
, NSSM_EVENT_PORT_ONLINE
);
1218 bfa_fcs_port_ns_query(struct bfa_fcs_port_s
*port
)
1220 struct bfa_fcs_port_ns_s
*ns
= BFA_FCS_GET_NS_FROM_PORT(port
);
1222 bfa_trc(port
->fcs
, port
->pid
);
1223 bfa_sm_send_event(ns
, NSSM_EVENT_NS_QUERY
);
1227 bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s
*port
)
1230 struct bfa_fcs_rport_s
*rport
;
1235 bfa_iocfc_get_bootwwns(port
->fcs
->bfa
, &nwwns
, &wwns
);
1237 for (ii
= 0; ii
< nwwns
; ++ii
) {
1238 rport
= bfa_fcs_rport_create_by_wwn(port
, wwns
[ii
]);