libata-sff: separate out BMDMA qc_issue
[safe/jmp/linux-2.6] / drivers / scsi / bfa / ns.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  * @page ns_sm_info VPORT NS State Machine
20  *
21  * @section ns_sm_interactions VPORT NS State Machine Interactions
22  *
23  * @section ns_sm VPORT NS State Machine
24  *      img ns_sm.jpg
25  */
26 #include <bfa.h>
27 #include <bfa_svc.h>
28 #include <bfa_iocfc.h>
29 #include "fcs_lport.h"
30 #include "fcs_rport.h"
31 #include "fcs_trcmod.h"
32 #include "fcs_fcxp.h"
33 #include "fcs.h"
34 #include "lport_priv.h"
35
36 BFA_TRC_FILE(FCS, NS);
37
38 /*
39  * forward declarations
40  */
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,
54                                                void *cbarg,
55                                                bfa_status_t req_status,
56                                                u32 rsp_len,
57                                                u32 resid_len,
58                                                struct fchs_s *rsp_fchs);
59 static void     bfa_fcs_port_ns_rspn_id_response(void *fcsarg,
60                                                  struct bfa_fcxp_s *fcxp,
61                                                  void *cbarg,
62                                                  bfa_status_t req_status,
63                                                  u32 rsp_len,
64                                                  u32 resid_len,
65                                                  struct fchs_s *rsp_fchs);
66 static void     bfa_fcs_port_ns_rft_id_response(void *fcsarg,
67                                                 struct bfa_fcxp_s *fcxp,
68                                                 void *cbarg,
69                                                 bfa_status_t req_status,
70                                                 u32 rsp_len,
71                                                 u32 resid_len,
72                                                 struct fchs_s *rsp_fchs);
73 static void     bfa_fcs_port_ns_rff_id_response(void *fcsarg,
74                                                 struct bfa_fcxp_s *fcxp,
75                                                 void *cbarg,
76                                                 bfa_status_t req_status,
77                                                 u32 rsp_len,
78                                                 u32 resid_len,
79                                                 struct fchs_s *rsp_fchs);
80 static void     bfa_fcs_port_ns_gid_ft_response(void *fcsarg,
81                                                 struct bfa_fcxp_s *fcxp,
82                                                 void *cbarg,
83                                                 bfa_status_t req_status,
84                                                 u32 rsp_len,
85                                                 u32 resid_len,
86                                                 struct fchs_s *rsp_fchs);
87 static void     bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
88                                                    u32 *pid_buf,
89                                                    u32 n_pids);
90
91 static void     bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port);
92 /**
93  *  fcs_ns_sm FCS nameserver interface state machine
94  */
95
96 /**
97  * VPort NS State Machine events
98  */
99 enum vport_ns_event {
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,
111 };
112
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);
147 /**
148  *              Start in offline state - awaiting linkup
149  */
150 static void
151 bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
152                            enum vport_ns_event event)
153 {
154         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
155         bfa_trc(ns->port->fcs, event);
156
157         switch (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);
161                 break;
162
163         case NSSM_EVENT_PORT_OFFLINE:
164                 break;
165
166         default:
167                 bfa_sm_fault(ns->port->fcs, event);
168         }
169 }
170
171 static void
172 bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
173                                  enum vport_ns_event event)
174 {
175         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
176         bfa_trc(ns->port->fcs, event);
177
178         switch (event) {
179         case NSSM_EVENT_PLOGI_SENT:
180                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi);
181                 break;
182
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),
186                                        &ns->fcxp_wqe);
187                 break;
188
189         default:
190                 bfa_sm_fault(ns->port->fcs, event);
191         }
192 }
193
194 static void
195 bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
196                          enum vport_ns_event event)
197 {
198         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
199         bfa_trc(ns->port->fcs, event);
200
201         switch (event) {
202         case NSSM_EVENT_RSP_ERROR:
203                 /*
204                  * Start timer for a delayed retry
205                  */
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);
211                 break;
212
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);
216                 break;
217
218         case NSSM_EVENT_PORT_OFFLINE:
219                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
220                 bfa_fcxp_discard(ns->fcxp);
221                 break;
222
223         default:
224                 bfa_sm_fault(ns->port->fcs, event);
225         }
226 }
227
228 static void
229 bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
230                                enum vport_ns_event event)
231 {
232         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
233         bfa_trc(ns->port->fcs, event);
234
235         switch (event) {
236         case NSSM_EVENT_TIMEOUT:
237                 /*
238                  * Retry Timer Expired. Re-send
239                  */
240                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending);
241                 bfa_fcs_port_ns_send_plogi(ns, NULL);
242                 break;
243
244         case NSSM_EVENT_PORT_OFFLINE:
245                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
246                 bfa_timer_stop(&ns->timer);
247                 break;
248
249         default:
250                 bfa_sm_fault(ns->port->fcs, event);
251         }
252 }
253
254 static void
255 bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
256                                    enum vport_ns_event event)
257 {
258         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
259         bfa_trc(ns->port->fcs, event);
260
261         switch (event) {
262         case NSSM_EVENT_RSPNID_SENT:
263                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id);
264                 break;
265
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),
269                                        &ns->fcxp_wqe);
270                 break;
271
272         default:
273                 bfa_sm_fault(ns->port->fcs, event);
274         }
275 }
276
277 static void
278 bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
279                            enum vport_ns_event event)
280 {
281         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
282         bfa_trc(ns->port->fcs, event);
283
284         switch (event) {
285         case NSSM_EVENT_RSP_ERROR:
286                 /*
287                  * Start timer for a delayed retry
288                  */
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);
294                 break;
295
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);
299                 break;
300
301         case NSSM_EVENT_PORT_OFFLINE:
302                 bfa_fcxp_discard(ns->fcxp);
303                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
304                 break;
305
306         default:
307                 bfa_sm_fault(ns->port->fcs, event);
308         }
309 }
310
311 static void
312 bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
313                                  enum vport_ns_event event)
314 {
315         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
316         bfa_trc(ns->port->fcs, event);
317
318         switch (event) {
319         case NSSM_EVENT_TIMEOUT:
320                 /*
321                  * Retry Timer Expired. Re-send
322                  */
323                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id);
324                 bfa_fcs_port_ns_send_rspn_id(ns, NULL);
325                 break;
326
327         case NSSM_EVENT_PORT_OFFLINE:
328                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
329                 bfa_timer_stop(&ns->timer);
330                 break;
331
332         default:
333                 bfa_sm_fault(ns->port->fcs, event);
334         }
335 }
336
337 static void
338 bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
339                                   enum vport_ns_event event)
340 {
341         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
342         bfa_trc(ns->port->fcs, event);
343
344         switch (event) {
345         case NSSM_EVENT_RFTID_SENT:
346                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id);
347                 break;
348
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),
352                                        &ns->fcxp_wqe);
353                 break;
354
355         default:
356                 bfa_sm_fault(ns->port->fcs, event);
357         }
358 }
359
360 static void
361 bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
362                           enum vport_ns_event event)
363 {
364         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
365         bfa_trc(ns->port->fcs, event);
366
367         switch (event) {
368         case NSSM_EVENT_RSP_OK:
369                 /*
370                  * Now move to register FC4 Features
371                  */
372                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id);
373                 bfa_fcs_port_ns_send_rff_id(ns, NULL);
374                 break;
375
376         case NSSM_EVENT_RSP_ERROR:
377                 /*
378                  * Start timer for a delayed retry
379                  */
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);
385                 break;
386
387         case NSSM_EVENT_PORT_OFFLINE:
388                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
389                 bfa_fcxp_discard(ns->fcxp);
390                 break;
391
392         default:
393                 bfa_sm_fault(ns->port->fcs, event);
394         }
395 }
396
397 static void
398 bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
399                                 enum vport_ns_event event)
400 {
401         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
402         bfa_trc(ns->port->fcs, event);
403
404         switch (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);
408                 break;
409
410         case NSSM_EVENT_PORT_OFFLINE:
411                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
412                 bfa_timer_stop(&ns->timer);
413                 break;
414
415         default:
416                 bfa_sm_fault(ns->port->fcs, event);
417         }
418 }
419
420 static void
421 bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
422                                   enum vport_ns_event event)
423 {
424         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
425         bfa_trc(ns->port->fcs, event);
426
427         switch (event) {
428         case NSSM_EVENT_RFFID_SENT:
429                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id);
430                 break;
431
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),
435                                        &ns->fcxp_wqe);
436                 break;
437
438         default:
439                 bfa_sm_fault(ns->port->fcs, event);
440         }
441 }
442
443 static void
444 bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
445                           enum vport_ns_event event)
446 {
447         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
448         bfa_trc(ns->port->fcs, event);
449
450         switch (event) {
451         case NSSM_EVENT_RSP_OK:
452
453                 /*
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.
457                  */
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);
461                         return;
462                 }
463
464                 /*
465                  * If the port role is Initiator Mode issue NS query.
466                  * If it is Target Mode, skip this and go to online.
467                  */
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);
473                 }
474                 /*
475                  * kick off mgmt srvr state machine
476                  */
477                 bfa_fcs_port_ms_online(ns->port);
478                 break;
479
480         case NSSM_EVENT_RSP_ERROR:
481                 /*
482                  * Start timer for a delayed retry
483                  */
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);
489                 break;
490
491         case NSSM_EVENT_PORT_OFFLINE:
492                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
493                 bfa_fcxp_discard(ns->fcxp);
494                 break;
495
496         default:
497                 bfa_sm_fault(ns->port->fcs, event);
498         }
499 }
500
501 static void
502 bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
503                                 enum vport_ns_event event)
504 {
505         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
506         bfa_trc(ns->port->fcs, event);
507
508         switch (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);
512                 break;
513
514         case NSSM_EVENT_PORT_OFFLINE:
515                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
516                 bfa_timer_stop(&ns->timer);
517                 break;
518
519         default:
520                 bfa_sm_fault(ns->port->fcs, event);
521         }
522 }
523 static void
524 bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
525                                   enum vport_ns_event event)
526 {
527         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
528         bfa_trc(ns->port->fcs, event);
529
530         switch (event) {
531         case NSSM_EVENT_GIDFT_SENT:
532                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft);
533                 break;
534
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),
538                                        &ns->fcxp_wqe);
539                 break;
540
541         default:
542                 bfa_sm_fault(ns->port->fcs, event);
543         }
544 }
545
546 static void
547 bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
548                           enum vport_ns_event event)
549 {
550         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
551         bfa_trc(ns->port->fcs, event);
552
553         switch (event) {
554         case NSSM_EVENT_RSP_OK:
555                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
556                 break;
557
558         case NSSM_EVENT_RSP_ERROR:
559                 /*
560                  * TBD: for certain reject codes, we don't need to retry
561                  */
562                 /*
563                  * Start timer for a delayed retry
564                  */
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);
570                 break;
571
572         case NSSM_EVENT_PORT_OFFLINE:
573                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
574                 bfa_fcxp_discard(ns->fcxp);
575                 break;
576
577         default:
578                 bfa_sm_fault(ns->port->fcs, event);
579         }
580 }
581
582 static void
583 bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
584                                 enum vport_ns_event event)
585 {
586         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
587         bfa_trc(ns->port->fcs, event);
588
589         switch (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);
593                 break;
594
595         case NSSM_EVENT_PORT_OFFLINE:
596                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
597                 bfa_timer_stop(&ns->timer);
598                 break;
599
600         default:
601                 bfa_sm_fault(ns->port->fcs, event);
602         }
603 }
604
605 static void
606 bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
607                           enum vport_ns_event event)
608 {
609         bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
610         bfa_trc(ns->port->fcs, event);
611
612         switch (event) {
613         case NSSM_EVENT_PORT_OFFLINE:
614                 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
615                 break;
616
617         case NSSM_EVENT_NS_QUERY:
618                 /*
619                  * If the port role is Initiator Mode issue NS query.
620                  * If it is Target Mode, skip this and go to online.
621                  */
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);
625                 };
626                 break;
627
628         default:
629                 bfa_sm_fault(ns->port->fcs, event);
630         }
631 }
632
633
634
635 /**
636  *  ns_pvt Nameserver local functions
637  */
638
639 static void
640 bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
641 {
642         struct bfa_fcs_port_ns_s *ns = ns_cbarg;
643         struct bfa_fcs_port_s *port = ns->port;
644         struct fchs_s          fchs;
645         int             len;
646         struct bfa_fcxp_s *fcxp;
647
648         bfa_trc(port->fcs, port->pid);
649
650         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
651         if (!fcxp) {
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);
655                 return;
656         }
657         ns->fcxp = fcxp;
658
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_fcport_get_maxfrsize(port->fcs->bfa));
664
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++;
669
670         bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
671 }
672
673 static void
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)
678 {
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;
684
685         bfa_trc(port->fcs, req_status);
686         bfa_trc(port->fcs, port->port_cfg.pwwn);
687
688         /*
689          * Sanity Checks
690          */
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);
695                 return;
696         }
697
698         els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
699
700         switch (els_cmd->els_code) {
701
702         case FC_ELS_ACC:
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);
707                         break;
708                 }
709                 port->stats.ns_plogi_accepts++;
710                 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
711                 break;
712
713         case FC_ELS_LS_RJT:
714                 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
715
716                 bfa_trc(port->fcs, ls_rjt->reason_code);
717                 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
718
719                 port->stats.ns_rejects++;
720
721                 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
722                 break;
723
724         default:
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);
728         }
729 }
730
731 /**
732  * Register the symbolic port name.
733  */
734 static void
735 bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
736 {
737         struct bfa_fcs_port_ns_s *ns = ns_cbarg;
738         struct bfa_fcs_port_s *port = ns->port;
739         struct fchs_s          fchs;
740         int             len;
741         struct bfa_fcxp_s *fcxp;
742         u8         symbl[256];
743         u8        *psymbl = &symbl[0];
744
745         bfa_os_memset(symbl, 0, sizeof(symbl));
746
747         bfa_trc(port->fcs, port->port_cfg.pwwn);
748
749         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
750         if (!fcxp) {
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);
754                 return;
755         }
756         ns->fcxp = fcxp;
757
758         /*
759          * for V-Port, form a Port Symbolic Name
760          */
761         if (port->vport) {
762                 /**For Vports,
763                  *  we append the vport's port symbolic name to that of the base port.
764                  */
765
766                 strncpy((char *)psymbl,
767                         (char *)
768                         &(bfa_fcs_port_get_psym_name
769                           (bfa_fcs_get_base_port(port->fcs))),
770                         strlen((char *)
771                                &bfa_fcs_port_get_psym_name(bfa_fcs_get_base_port
772                                                            (port->fcs))));
773
774                 /*
775                  * Ensure we have a null terminating string.
776                  */
777                 ((char *)
778                  psymbl)[strlen((char *)
779                                 &bfa_fcs_port_get_psym_name
780                                 (bfa_fcs_get_base_port(port->fcs)))] = 0;
781
782                 strncat((char *)psymbl,
783                         (char *)&(bfa_fcs_port_get_psym_name(port)),
784                         strlen((char *)&bfa_fcs_port_get_psym_name(port)));
785         } else {
786                 psymbl = (u8 *) &(bfa_fcs_port_get_psym_name(port));
787         }
788
789         len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
790                               bfa_fcs_port_get_fcid(port), 0, psymbl);
791
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);
795
796         port->stats.ns_rspnid_sent++;
797
798         bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
799 }
800
801 static void
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)
806 {
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;
810
811         bfa_trc(port->fcs, port->port_cfg.pwwn);
812
813         /*
814          * Sanity Checks
815          */
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);
820                 return;
821         }
822
823         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
824         cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
825
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);
829                 return;
830         }
831
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);
836 }
837
838 /**
839  * Register FC4-Types
840  * TBD, Need to retrieve this from the OS driver, in case IPFC is enabled ?
841  */
842 static void
843 bfa_fcs_port_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
844 {
845         struct bfa_fcs_port_ns_s *ns = ns_cbarg;
846         struct bfa_fcs_port_s *port = ns->port;
847         struct fchs_s          fchs;
848         int             len;
849         struct bfa_fcxp_s *fcxp;
850
851         bfa_trc(port->fcs, port->port_cfg.pwwn);
852
853         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
854         if (!fcxp) {
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);
858                 return;
859         }
860         ns->fcxp = fcxp;
861
862         len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
863                              bfa_fcs_port_get_fcid(port), 0,
864                              port->port_cfg.roles);
865
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);
869
870         port->stats.ns_rftid_sent++;
871         bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
872 }
873
874 static void
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)
879 {
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;
883
884         bfa_trc(port->fcs, port->port_cfg.pwwn);
885
886         /*
887          * Sanity Checks
888          */
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);
893                 return;
894         }
895
896         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
897         cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
898
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);
902                 return;
903         }
904
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);
909 }
910
911 /**
912 * Register FC4-Features : Should be done after RFT_ID
913  */
914 static void
915 bfa_fcs_port_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
916 {
917         struct bfa_fcs_port_ns_s *ns = ns_cbarg;
918         struct bfa_fcs_port_s *port = ns->port;
919         struct fchs_s          fchs;
920         int             len;
921         struct bfa_fcxp_s *fcxp;
922         u8         fc4_ftrs = 0;
923
924         bfa_trc(port->fcs, port->port_cfg.pwwn);
925
926         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
927         if (!fcxp) {
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);
931                 return;
932         }
933         ns->fcxp = fcxp;
934
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;
939
940         len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
941                              bfa_fcs_port_get_fcid(port), 0, FC_TYPE_FCP,
942                              fc4_ftrs);
943
944         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
945                       FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rff_id_response,
946                       (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
947
948         port->stats.ns_rffid_sent++;
949         bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
950 }
951
952 static void
953 bfa_fcs_port_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
954                                 void *cbarg, bfa_status_t req_status,
955                                 u32 rsp_len, u32 resid_len,
956                                 struct fchs_s *rsp_fchs)
957 {
958         struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
959         struct bfa_fcs_port_s *port = ns->port;
960         struct ct_hdr_s       *cthdr = NULL;
961
962         bfa_trc(port->fcs, port->port_cfg.pwwn);
963
964         /*
965          * Sanity Checks
966          */
967         if (req_status != BFA_STATUS_OK) {
968                 bfa_trc(port->fcs, req_status);
969                 port->stats.ns_rffid_rsp_err++;
970                 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
971                 return;
972         }
973
974         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
975         cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
976
977         if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
978                 port->stats.ns_rffid_accepts++;
979                 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
980                 return;
981         }
982
983         port->stats.ns_rffid_rejects++;
984         bfa_trc(port->fcs, cthdr->reason_code);
985         bfa_trc(port->fcs, cthdr->exp_code);
986
987         if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
988                 /*
989                  * if this command is not supported, we don't retry
990                  */
991                 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
992         } else {
993                 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
994         }
995 }
996
997 /**
998  * Query Fabric for FC4-Types Devices.
999  *
1000 *  TBD : Need to use a local (FCS private) response buffer, since the response
1001  * can be larger than 2K.
1002  */
1003 static void
1004 bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1005 {
1006         struct bfa_fcs_port_ns_s *ns = ns_cbarg;
1007         struct bfa_fcs_port_s *port = ns->port;
1008         struct fchs_s          fchs;
1009         int             len;
1010         struct bfa_fcxp_s *fcxp;
1011
1012         bfa_trc(port->fcs, port->pid);
1013
1014         fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1015         if (!fcxp) {
1016                 port->stats.ns_gidft_alloc_wait++;
1017                 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
1018                                     bfa_fcs_port_ns_send_gid_ft, ns);
1019                 return;
1020         }
1021         ns->fcxp = fcxp;
1022
1023         /*
1024          * This query is only initiated for FCP initiator mode.
1025          */
1026         len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ns->port->pid,
1027                               FC_TYPE_FCP);
1028
1029         bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1030                       FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_gid_ft_response,
1031                       (void *)ns, bfa_fcxp_get_maxrsp(port->fcs->bfa),
1032                       FC_RA_TOV);
1033
1034         port->stats.ns_gidft_sent++;
1035
1036         bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
1037 }
1038
1039 static void
1040 bfa_fcs_port_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
1041                                 void *cbarg, bfa_status_t req_status,
1042                                 u32 rsp_len, u32 resid_len,
1043                                 struct fchs_s *rsp_fchs)
1044 {
1045         struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
1046         struct bfa_fcs_port_s *port = ns->port;
1047         struct ct_hdr_s       *cthdr = NULL;
1048         u32        n_pids;
1049
1050         bfa_trc(port->fcs, port->port_cfg.pwwn);
1051
1052         /*
1053          * Sanity Checks
1054          */
1055         if (req_status != BFA_STATUS_OK) {
1056                 bfa_trc(port->fcs, req_status);
1057                 port->stats.ns_gidft_rsp_err++;
1058                 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
1059                 return;
1060         }
1061
1062         if (resid_len != 0) {
1063                 /*
1064                  * TBD : we will need to allocate a larger buffer & retry the
1065                  * command
1066                  */
1067                 bfa_trc(port->fcs, rsp_len);
1068                 bfa_trc(port->fcs, resid_len);
1069                 return;
1070         }
1071
1072         cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1073         cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
1074
1075         switch (cthdr->cmd_rsp_code) {
1076
1077         case CT_RSP_ACCEPT:
1078
1079                 port->stats.ns_gidft_accepts++;
1080                 n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
1081                 bfa_trc(port->fcs, n_pids);
1082                 bfa_fcs_port_ns_process_gidft_pids(port,
1083                                                    (u32 *) (cthdr + 1),
1084                                                    n_pids);
1085                 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
1086                 break;
1087
1088         case CT_RSP_REJECT:
1089
1090                 /*
1091                  * Check the reason code  & explanation.
1092                  * There may not have been any FC4 devices in the fabric
1093                  */
1094                 port->stats.ns_gidft_rejects++;
1095                 bfa_trc(port->fcs, cthdr->reason_code);
1096                 bfa_trc(port->fcs, cthdr->exp_code);
1097
1098                 if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
1099                     && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
1100
1101                         bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
1102                 } else {
1103                         /*
1104                          * for all other errors, retry
1105                          */
1106                         bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
1107                 }
1108                 break;
1109
1110         default:
1111                 port->stats.ns_gidft_unknown_rsp++;
1112                 bfa_trc(port->fcs, cthdr->cmd_rsp_code);
1113                 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
1114         }
1115 }
1116
1117 /**
1118  *     This routine will be called by bfa_timer on timer timeouts.
1119  *
1120  *      param[in]       port    - pointer to bfa_fcs_port_t.
1121  *
1122  *      return
1123  *              void
1124  *
1125 *       Special Considerations:
1126  *
1127  *      note
1128  */
1129 static void
1130 bfa_fcs_port_ns_timeout(void *arg)
1131 {
1132         struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)arg;
1133
1134         ns->port->stats.ns_timeouts++;
1135         bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
1136 }
1137
1138 /*
1139  * Process the PID list in GID_FT response
1140  */
1141 static void
1142 bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
1143                                    u32 *pid_buf, u32 n_pids)
1144 {
1145         struct fcgs_gidft_resp_s *gidft_entry;
1146         struct bfa_fcs_rport_s *rport;
1147         u32        ii;
1148
1149         for (ii = 0; ii < n_pids; ii++) {
1150                 gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
1151
1152                 if (gidft_entry->pid == port->pid)
1153                         continue;
1154
1155                 /*
1156                  * Check if this rport already exists
1157                  */
1158                 rport = bfa_fcs_port_get_rport_by_pid(port, gidft_entry->pid);
1159                 if (rport == NULL) {
1160                         /*
1161                          * this is a new device. create rport
1162                          */
1163                         rport = bfa_fcs_rport_create(port, gidft_entry->pid);
1164                 } else {
1165                         /*
1166                          * this rport already exists
1167                          */
1168                         bfa_fcs_rport_scn(rport);
1169                 }
1170
1171                 bfa_trc(port->fcs, gidft_entry->pid);
1172
1173                 /*
1174                  * if the last entry bit is set, bail out.
1175                  */
1176                 if (gidft_entry->last)
1177                         return;
1178         }
1179 }
1180
1181 /**
1182  *  fcs_ns_public FCS nameserver public interfaces
1183  */
1184
1185 /*
1186  * Functions called by port/fab.
1187  * These will send relevant Events to the ns state machine.
1188  */
1189 void
1190 bfa_fcs_port_ns_init(struct bfa_fcs_port_s *port)
1191 {
1192         struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1193
1194         ns->port = port;
1195         bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
1196 }
1197
1198 void
1199 bfa_fcs_port_ns_offline(struct bfa_fcs_port_s *port)
1200 {
1201         struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1202
1203         ns->port = port;
1204         bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
1205 }
1206
1207 void
1208 bfa_fcs_port_ns_online(struct bfa_fcs_port_s *port)
1209 {
1210         struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1211
1212         ns->port = port;
1213         bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
1214 }
1215
1216 void
1217 bfa_fcs_port_ns_query(struct bfa_fcs_port_s *port)
1218 {
1219         struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1220
1221         bfa_trc(port->fcs, port->pid);
1222         bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
1223 }
1224
1225 static void
1226 bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port)
1227 {
1228
1229         struct bfa_fcs_rport_s *rport;
1230         u8         nwwns;
1231         wwn_t          *wwns;
1232         int             ii;
1233
1234         bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, &wwns);
1235
1236         for (ii = 0; ii < nwwns; ++ii) {
1237                 rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
1238                 bfa_assert(rport);
1239         }
1240 }
1241
1242