Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bfa_fcs_lport.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005-2010 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 #include "bfad_drv.h"
19 #include "bfad_im.h"
20 #include "bfa_fcs.h"
21 #include "bfa_fcbuild.h"
22 #include "bfa_fc.h"
23 
25 
26 /*
27  * ALPA to LIXA bitmap mapping
28  *
29  * ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31
30  * is for L_bit (login required) and is filled as ALPA 0x00 here.
31  */
32 static const u8 loop_alpa_map[] = {
33  0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x0F, 0x10, /* Word 0 Bits 31..24 */
34  0x17, 0x18, 0x1B, 0x1D, 0x1E, 0x1F, 0x23, 0x25, /* Word 0 Bits 23..16 */
35  0x26, 0x27, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, /* Word 0 Bits 15..08 */
36  0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x39, 0x3A, /* Word 0 Bits 07..00 */
37 
38  0x3C, 0x43, 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, /* Word 1 Bits 31..24 */
39  0x4C, 0x4D, 0x4E, 0x51, 0x52, 0x53, 0x54, 0x55, /* Word 1 Bits 23..16 */
40  0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x67, /* Word 1 Bits 15..08 */
41  0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, /* Word 1 Bits 07..00 */
42 
43  0x73, 0x74, 0x75, 0x76, 0x79, 0x7A, 0x7C, 0x80, /* Word 2 Bits 31..24 */
44  0x81, 0x82, 0x84, 0x88, 0x8F, 0x90, 0x97, 0x98, /* Word 2 Bits 23..16 */
45  0x9B, 0x9D, 0x9E, 0x9F, 0xA3, 0xA5, 0xA6, 0xA7, /* Word 2 Bits 15..08 */
46  0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xB1, 0xB2, /* Word 2 Bits 07..00 */
47 
48  0xB3, 0xB4, 0xB5, 0xB6, 0xB9, 0xBA, 0xBC, 0xC3, /* Word 3 Bits 31..24 */
49  0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, /* Word 3 Bits 23..16 */
50  0xCE, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD9, /* Word 3 Bits 15..08 */
51  0xDA, 0xDC, 0xE0, 0xE1, 0xE2, 0xE4, 0xE8, 0xEF, /* Word 3 Bits 07..00 */
52 };
53 
54 static void bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port,
55  struct fchs_s *rx_fchs, u8 reason_code,
56  u8 reason_code_expl);
57 static void bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
58  struct fchs_s *rx_fchs, struct fc_logi_s *plogi);
59 static void bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port);
60 static void bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port);
61 static void bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port);
62 static void bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port);
63 static void bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port);
64 static void bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port);
65 static void bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port,
66  struct fchs_s *rx_fchs,
67  struct fc_echo_s *echo, u16 len);
68 static void bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port,
69  struct fchs_s *rx_fchs,
70  struct fc_rnid_cmd_s *rnid, u16 len);
71 static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
72  struct fc_rnid_general_topology_data_s *gen_topo_data);
73 
74 static void bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port);
75 static void bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port);
76 static void bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port);
77 
78 static void bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port);
79 static void bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port);
80 static void bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port);
81 
82 static void bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port);
83 static void bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port);
84 static void bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port);
85 
86 static struct {
87  void (*init) (struct bfa_fcs_lport_s *port);
90 } __port_action[] = {
91  {
92  bfa_fcs_lport_unknown_init, bfa_fcs_lport_unknown_online,
93  bfa_fcs_lport_unknown_offline}, {
94  bfa_fcs_lport_fab_init, bfa_fcs_lport_fab_online,
95  bfa_fcs_lport_fab_offline}, {
96  bfa_fcs_lport_n2n_init, bfa_fcs_lport_n2n_online,
97  bfa_fcs_lport_n2n_offline}, {
98  bfa_fcs_lport_loop_init, bfa_fcs_lport_loop_online,
99  bfa_fcs_lport_loop_offline},
100  };
101 
102 /*
103  * fcs_port_sm FCS logical port state machine
104  */
105 
113 };
114 
115 static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port,
117 static void bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port,
119 static void bfa_fcs_lport_sm_online(struct bfa_fcs_lport_s *port,
121 static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port,
123 static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port,
125 static void bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
127 
128 static void
129 bfa_fcs_lport_sm_uninit(
130  struct bfa_fcs_lport_s *port,
132 {
133  bfa_trc(port->fcs, port->port_cfg.pwwn);
134  bfa_trc(port->fcs, event);
135 
136  switch (event) {
138  bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
139  break;
140 
141  default:
142  bfa_sm_fault(port->fcs, event);
143  }
144 }
145 
146 static void
147 bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port,
148  enum bfa_fcs_lport_event event)
149 {
150  bfa_trc(port->fcs, port->port_cfg.pwwn);
151  bfa_trc(port->fcs, event);
152 
153  switch (event) {
155  bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
156  bfa_fcs_lport_online_actions(port);
157  break;
158 
160  bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
161  bfa_fcs_lport_deleted(port);
162  break;
163 
165  /* If vport - send completion call back */
166  if (port->vport)
168  else
169  bfa_wc_down(&(port->fabric->stop_wc));
170  break;
171 
173  break;
174 
175  default:
176  bfa_sm_fault(port->fcs, event);
177  }
178 }
179 
180 static void
181 bfa_fcs_lport_sm_online(
182  struct bfa_fcs_lport_s *port,
183  enum bfa_fcs_lport_event event)
184 {
185  struct bfa_fcs_rport_s *rport;
186  struct list_head *qe, *qen;
187 
188  bfa_trc(port->fcs, port->port_cfg.pwwn);
189  bfa_trc(port->fcs, event);
190 
191  switch (event) {
193  bfa_sm_set_state(port, bfa_fcs_lport_sm_offline);
194  bfa_fcs_lport_offline_actions(port);
195  break;
196 
198  __port_action[port->fabric->fab_type].offline(port);
199 
200  if (port->num_rports == 0) {
201  bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
202  /* If vport - send completion call back */
203  if (port->vport)
205  else
206  bfa_wc_down(&(port->fabric->stop_wc));
207  } else {
208  bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
209  list_for_each_safe(qe, qen, &port->rport_q) {
210  rport = (struct bfa_fcs_rport_s *) qe;
212  }
213  }
214  break;
215 
217 
218  __port_action[port->fabric->fab_type].offline(port);
219 
220  if (port->num_rports == 0) {
221  bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
222  bfa_fcs_lport_deleted(port);
223  } else {
224  bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
225  list_for_each_safe(qe, qen, &port->rport_q) {
226  rport = (struct bfa_fcs_rport_s *) qe;
228  }
229  }
230  break;
231 
233  break;
234 
235  default:
236  bfa_sm_fault(port->fcs, event);
237  }
238 }
239 
240 static void
241 bfa_fcs_lport_sm_offline(
242  struct bfa_fcs_lport_s *port,
243  enum bfa_fcs_lport_event event)
244 {
245  struct bfa_fcs_rport_s *rport;
246  struct list_head *qe, *qen;
247 
248  bfa_trc(port->fcs, port->port_cfg.pwwn);
249  bfa_trc(port->fcs, event);
250 
251  switch (event) {
253  bfa_sm_set_state(port, bfa_fcs_lport_sm_online);
254  bfa_fcs_lport_online_actions(port);
255  break;
256 
258  if (port->num_rports == 0) {
259  bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
260  /* If vport - send completion call back */
261  if (port->vport)
263  else
264  bfa_wc_down(&(port->fabric->stop_wc));
265  } else {
266  bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping);
267  list_for_each_safe(qe, qen, &port->rport_q) {
268  rport = (struct bfa_fcs_rport_s *) qe;
270  }
271  }
272  break;
273 
275  if (port->num_rports == 0) {
276  bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
277  bfa_fcs_lport_deleted(port);
278  } else {
279  bfa_sm_set_state(port, bfa_fcs_lport_sm_deleting);
280  list_for_each_safe(qe, qen, &port->rport_q) {
281  rport = (struct bfa_fcs_rport_s *) qe;
283  }
284  }
285  break;
286 
289  break;
290 
291  default:
292  bfa_sm_fault(port->fcs, event);
293  }
294 }
295 
296 static void
297 bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port,
298  enum bfa_fcs_lport_event event)
299 {
300  bfa_trc(port->fcs, port->port_cfg.pwwn);
301  bfa_trc(port->fcs, event);
302 
303  switch (event) {
305  if (port->num_rports == 0) {
306  bfa_sm_set_state(port, bfa_fcs_lport_sm_init);
307  /* If vport - send completion call back */
308  if (port->vport)
310  else
311  bfa_wc_down(&(port->fabric->stop_wc));
312  }
313  break;
314 
315  default:
316  bfa_sm_fault(port->fcs, event);
317  }
318 }
319 
320 static void
321 bfa_fcs_lport_sm_deleting(
322  struct bfa_fcs_lport_s *port,
323  enum bfa_fcs_lport_event event)
324 {
325  bfa_trc(port->fcs, port->port_cfg.pwwn);
326  bfa_trc(port->fcs, event);
327 
328  switch (event) {
330  if (port->num_rports == 0) {
331  bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit);
332  bfa_fcs_lport_deleted(port);
333  }
334  break;
335 
336  default:
337  bfa_sm_fault(port->fcs, event);
338  }
339 }
340 
341 /*
342  * fcs_port_pvt
343  */
344 
345 /*
346  * Send AEN notification
347  */
348 static void
349 bfa_fcs_lport_aen_post(struct bfa_fcs_lport_s *port,
350  enum bfa_lport_aen_event event)
351 {
352  struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
353  struct bfa_aen_entry_s *aen_entry;
354 
355  bfad_get_aen_entry(bfad, aen_entry);
356  if (!aen_entry)
357  return;
358 
359  aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
360  aen_entry->aen_data.lport.roles = port->port_cfg.roles;
361  aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
362  bfa_fcs_get_base_port(port->fcs));
363  aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
364 
365  /* Send the AEN notification */
366  bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
367  BFA_AEN_CAT_LPORT, event);
368 }
369 
370 /*
371  * Send a LS reject
372  */
373 static void
374 bfa_fcs_lport_send_ls_rjt(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
375  u8 reason_code, u8 reason_code_expl)
376 {
377  struct fchs_s fchs;
378  struct bfa_fcxp_s *fcxp;
379  struct bfa_rport_s *bfa_rport = NULL;
380  int len;
381 
382  bfa_trc(port->fcs, rx_fchs->d_id);
383  bfa_trc(port->fcs, rx_fchs->s_id);
384 
385  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
386  if (!fcxp)
387  return;
388 
389  len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
390  rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
391  rx_fchs->ox_id, reason_code, reason_code_expl);
392 
393  bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
394  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
395  FC_MAX_PDUSZ, 0);
396 }
397 
398 /*
399  * Send a FCCT Reject
400  */
401 static void
402 bfa_fcs_lport_send_fcgs_rjt(struct bfa_fcs_lport_s *port,
403  struct fchs_s *rx_fchs, u8 reason_code, u8 reason_code_expl)
404 {
405  struct fchs_s fchs;
406  struct bfa_fcxp_s *fcxp;
407  struct bfa_rport_s *bfa_rport = NULL;
408  int len;
409  struct ct_hdr_s *rx_cthdr = (struct ct_hdr_s *)(rx_fchs + 1);
410  struct ct_hdr_s *ct_hdr;
411 
412  bfa_trc(port->fcs, rx_fchs->d_id);
413  bfa_trc(port->fcs, rx_fchs->s_id);
414 
415  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
416  if (!fcxp)
417  return;
418 
419  ct_hdr = bfa_fcxp_get_reqbuf(fcxp);
420  ct_hdr->gs_type = rx_cthdr->gs_type;
421  ct_hdr->gs_sub_type = rx_cthdr->gs_sub_type;
422 
423  len = fc_gs_rjt_build(&fchs, ct_hdr, rx_fchs->s_id,
425  rx_fchs->ox_id, reason_code, reason_code_expl);
426 
427  bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
428  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
429  FC_MAX_PDUSZ, 0);
430 }
431 
432 /*
433  * Process incoming plogi from a remote port.
434  */
435 static void
436 bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
437  struct fchs_s *rx_fchs, struct fc_logi_s *plogi)
438 {
439  struct bfa_fcs_rport_s *rport;
440 
441  bfa_trc(port->fcs, rx_fchs->d_id);
442  bfa_trc(port->fcs, rx_fchs->s_id);
443 
444  /*
445  * If min cfg mode is enabled, drop any incoming PLOGIs
446  */
447  if (__fcs_min_cfg(port->fcs)) {
448  bfa_trc(port->fcs, rx_fchs->s_id);
449  return;
450  }
451 
452  if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
453  bfa_trc(port->fcs, rx_fchs->s_id);
454  /*
455  * send a LS reject
456  */
457  bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
460  return;
461  }
462 
463  /*
464  * Direct Attach P2P mode : verify address assigned by the r-port.
465  */
466  if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
467  (memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
468  (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
469  if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
470  /* Address assigned to us cannot be a WKA */
471  bfa_fcs_lport_send_ls_rjt(port, rx_fchs,
474  return;
475  }
476  port->pid = rx_fchs->d_id;
477  bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
478  }
479 
480  /*
481  * First, check if we know the device by pwwn.
482  */
483  rport = bfa_fcs_lport_get_rport_by_pwwn(port, plogi->port_name);
484  if (rport) {
485  /*
486  * Direct Attach P2P mode : handle address assigned by r-port.
487  */
488  if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
489  (memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
490  (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
491  port->pid = rx_fchs->d_id;
492  bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
493  rport->pid = rx_fchs->s_id;
494  }
495  bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
496  return;
497  }
498 
499  /*
500  * Next, lookup rport by PID.
501  */
502  rport = bfa_fcs_lport_get_rport_by_pid(port, rx_fchs->s_id);
503  if (!rport) {
504  /*
505  * Inbound PLOGI from a new device.
506  */
507  bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
508  return;
509  }
510 
511  /*
512  * Rport is known only by PID.
513  */
514  if (rport->pwwn) {
515  /*
516  * This is a different device with the same pid. Old device
517  * disappeared. Send implicit LOGO to old device.
518  */
519  WARN_ON(rport->pwwn == plogi->port_name);
521 
522  /*
523  * Inbound PLOGI from a new device (with old PID).
524  */
525  bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
526  return;
527  }
528 
529  /*
530  * PLOGI crossing each other.
531  */
532  WARN_ON(rport->pwwn != WWN_NULL);
533  bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
534 }
535 
536 /*
537  * Process incoming ECHO.
538  * Since it does not require a login, it is processed here.
539  */
540 static void
541 bfa_fcs_lport_echo(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
542  struct fc_echo_s *echo, u16 rx_len)
543 {
544  struct fchs_s fchs;
545  struct bfa_fcxp_s *fcxp;
546  struct bfa_rport_s *bfa_rport = NULL;
547  int len, pyld_len;
548 
549  bfa_trc(port->fcs, rx_fchs->s_id);
550  bfa_trc(port->fcs, rx_fchs->d_id);
551 
552  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
553  if (!fcxp)
554  return;
555 
556  len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
557  rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
558  rx_fchs->ox_id);
559 
560  /*
561  * Copy the payload (if any) from the echo frame
562  */
563  pyld_len = rx_len - sizeof(struct fchs_s);
564  bfa_trc(port->fcs, rx_len);
565  bfa_trc(port->fcs, pyld_len);
566 
567  if (pyld_len > len)
568  memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
569  sizeof(struct fc_echo_s), (echo + 1),
570  (pyld_len - sizeof(struct fc_echo_s)));
571 
572  bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
573  BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
574  FC_MAX_PDUSZ, 0);
575 }
576 
577 /*
578  * Process incoming RNID.
579  * Since it does not require a login, it is processed here.
580  */
581 static void
582 bfa_fcs_lport_rnid(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs,
583  struct fc_rnid_cmd_s *rnid, u16 rx_len)
584 {
585  struct fc_rnid_common_id_data_s common_id_data;
586  struct fc_rnid_general_topology_data_s gen_topo_data;
587  struct fchs_s fchs;
588  struct bfa_fcxp_s *fcxp;
589  struct bfa_rport_s *bfa_rport = NULL;
590  u16 len;
592 
593  bfa_trc(port->fcs, rx_fchs->s_id);
594  bfa_trc(port->fcs, rx_fchs->d_id);
595  bfa_trc(port->fcs, rx_len);
596 
597  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
598  if (!fcxp)
599  return;
600 
601  /*
602  * Check Node Indentification Data Format
603  * We only support General Topology Discovery Format.
604  * For any other requested Data Formats, we return Common Node Id Data
605  * only, as per FC-LS.
606  */
607  bfa_trc(port->fcs, rnid->node_id_data_format);
609  data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
610  /*
611  * Get General topology data for this port
612  */
613  bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
614  } else {
615  data_format = RNID_NODEID_DATA_FORMAT_COMMON;
616  }
617 
618  /*
619  * Copy the Node Id Info
620  */
621  common_id_data.port_name = bfa_fcs_lport_get_pwwn(port);
622  common_id_data.node_name = bfa_fcs_lport_get_nwwn(port);
623 
624  len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
625  rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
626  rx_fchs->ox_id, data_format, &common_id_data,
627  &gen_topo_data);
628 
629  bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
630  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
631  FC_MAX_PDUSZ, 0);
632 }
633 
634 /*
635  * Fill out General Topolpgy Discovery Data for RNID ELS.
636  */
637 static void
638 bfa_fs_port_get_gen_topo_data(struct bfa_fcs_lport_s *port,
639  struct fc_rnid_general_topology_data_s *gen_topo_data)
640 {
641  memset(gen_topo_data, 0,
642  sizeof(struct fc_rnid_general_topology_data_s));
643 
645  gen_topo_data->phy_port_num = 0; /* @todo */
646  gen_topo_data->num_attached_nodes = cpu_to_be32(1);
647 }
648 
649 static void
650 bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
651 {
652  struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
653  char lpwwn_buf[BFA_STRING_32];
654 
655  bfa_trc(port->fcs, port->fabric->oper_type);
656 
657  __port_action[port->fabric->fab_type].init(port);
658  __port_action[port->fabric->fab_type].online(port);
659 
660  wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
662  "Logical port online: WWN = %s Role = %s\n",
663  lpwwn_buf, "Initiator");
664  bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_ONLINE);
665 
666  bfad->bfad_flags |= BFAD_PORT_ONLINE;
667 }
668 
669 static void
670 bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
671 {
672  struct list_head *qe, *qen;
673  struct bfa_fcs_rport_s *rport;
674  struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
675  char lpwwn_buf[BFA_STRING_32];
676 
677  bfa_trc(port->fcs, port->fabric->oper_type);
678 
679  __port_action[port->fabric->fab_type].offline(port);
680 
681  wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
682  if (bfa_sm_cmp_state(port->fabric,
685  "Logical port lost fabric connectivity: WWN = %s Role = %s\n",
686  lpwwn_buf, "Initiator");
687  bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
688  } else {
690  "Logical port taken offline: WWN = %s Role = %s\n",
691  lpwwn_buf, "Initiator");
692  bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_OFFLINE);
693  }
694 
695  list_for_each_safe(qe, qen, &port->rport_q) {
696  rport = (struct bfa_fcs_rport_s *) qe;
698  }
699 }
700 
701 static void
702 bfa_fcs_lport_unknown_init(struct bfa_fcs_lport_s *port)
703 {
704  WARN_ON(1);
705 }
706 
707 static void
708 bfa_fcs_lport_unknown_online(struct bfa_fcs_lport_s *port)
709 {
710  WARN_ON(1);
711 }
712 
713 static void
714 bfa_fcs_lport_unknown_offline(struct bfa_fcs_lport_s *port)
715 {
716  WARN_ON(1);
717 }
718 
719 static void
720 bfa_fcs_lport_abts_acc(struct bfa_fcs_lport_s *port, struct fchs_s *rx_fchs)
721 {
722  struct fchs_s fchs;
723  struct bfa_fcxp_s *fcxp;
724  int len;
725 
726  bfa_trc(port->fcs, rx_fchs->d_id);
727  bfa_trc(port->fcs, rx_fchs->s_id);
728 
729  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
730  if (!fcxp)
731  return;
732 
733  len = fc_ba_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
734  rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
735  rx_fchs->ox_id, 0);
736 
737  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
738  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
739  FC_MAX_PDUSZ, 0);
740 }
741 static void
742 bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
743 {
744  struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
745  char lpwwn_buf[BFA_STRING_32];
746 
747  wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
749  "Logical port deleted: WWN = %s Role = %s\n",
750  lpwwn_buf, "Initiator");
751  bfa_fcs_lport_aen_post(port, BFA_LPORT_AEN_DELETE);
752 
753  /* Base port will be deleted by the OS driver */
754  if (port->vport)
756  else
757  bfa_wc_down(&port->fabric->wc);
758 }
759 
760 
761 /*
762  * Unsolicited frame receive handling.
763  */
764 void
766  struct fchs_s *fchs, u16 len)
767 {
768  u32 pid = fchs->s_id;
769  struct bfa_fcs_rport_s *rport = NULL;
770  struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
771 
772  bfa_stats(lport, uf_recvs);
773  bfa_trc(lport->fcs, fchs->type);
774 
775  if (!bfa_fcs_lport_is_online(lport)) {
776  bfa_stats(lport, uf_recv_drops);
777  return;
778  }
779 
780  /*
781  * First, handle ELSs that donot require a login.
782  */
783  /*
784  * Handle PLOGI first
785  */
786  if ((fchs->type == FC_TYPE_ELS) &&
787  (els_cmd->els_code == FC_ELS_PLOGI)) {
788  bfa_fcs_lport_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
789  return;
790  }
791 
792  /*
793  * Handle ECHO separately.
794  */
795  if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
796  bfa_fcs_lport_echo(lport, fchs,
797  (struct fc_echo_s *)els_cmd, len);
798  return;
799  }
800 
801  /*
802  * Handle RNID separately.
803  */
804  if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
805  bfa_fcs_lport_rnid(lport, fchs,
806  (struct fc_rnid_cmd_s *) els_cmd, len);
807  return;
808  }
809 
810  if (fchs->type == FC_TYPE_BLS) {
811  if ((fchs->routing == FC_RTG_BASIC_LINK) &&
812  (fchs->cat_info == FC_CAT_ABTS))
813  bfa_fcs_lport_abts_acc(lport, fchs);
814  return;
815  }
816 
817  if (fchs->type == FC_TYPE_SERVICES) {
818  /*
819  * Unhandled FC-GS frames. Send a FC-CT Reject
820  */
821  bfa_fcs_lport_send_fcgs_rjt(lport, fchs, CT_RSN_NOT_SUPP,
823  return;
824  }
825 
826  /*
827  * look for a matching remote port ID
828  */
829  rport = bfa_fcs_lport_get_rport_by_pid(lport, pid);
830  if (rport) {
831  bfa_trc(rport->fcs, fchs->s_id);
832  bfa_trc(rport->fcs, fchs->d_id);
833  bfa_trc(rport->fcs, fchs->type);
834 
835  bfa_fcs_rport_uf_recv(rport, fchs, len);
836  return;
837  }
838 
839  /*
840  * Only handles ELS frames for now.
841  */
842  if (fchs->type != FC_TYPE_ELS) {
843  bfa_trc(lport->fcs, fchs->s_id);
844  bfa_trc(lport->fcs, fchs->d_id);
845  /* ignore type FC_TYPE_FC_FSS */
846  if (fchs->type != FC_TYPE_FC_FSS)
847  bfa_sm_fault(lport->fcs, fchs->type);
848  return;
849  }
850 
851  bfa_trc(lport->fcs, els_cmd->els_code);
852  if (els_cmd->els_code == FC_ELS_RSCN) {
853  bfa_fcs_lport_scn_process_rscn(lport, fchs, len);
854  return;
855  }
856 
857  if (els_cmd->els_code == FC_ELS_LOGO) {
858  /*
859  * @todo Handle LOGO frames received.
860  */
861  return;
862  }
863 
864  if (els_cmd->els_code == FC_ELS_PRLI) {
865  /*
866  * @todo Handle PRLI frames received.
867  */
868  return;
869  }
870 
871  /*
872  * Unhandled ELS frames. Send a LS_RJT.
873  */
874  bfa_fcs_lport_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
876 
877 }
878 
879 /*
880  * PID based Lookup for a R-Port in the Port R-Port Queue
881  */
882 struct bfa_fcs_rport_s *
884 {
885  struct bfa_fcs_rport_s *rport;
886  struct list_head *qe;
887 
888  list_for_each(qe, &port->rport_q) {
889  rport = (struct bfa_fcs_rport_s *) qe;
890  if (rport->pid == pid)
891  return rport;
892  }
893 
894  bfa_trc(port->fcs, pid);
895  return NULL;
896 }
897 
898 /*
899  * OLD_PID based Lookup for a R-Port in the Port R-Port Queue
900  */
901 struct bfa_fcs_rport_s *
903 {
904  struct bfa_fcs_rport_s *rport;
905  struct list_head *qe;
906 
907  list_for_each(qe, &port->rport_q) {
908  rport = (struct bfa_fcs_rport_s *) qe;
909  if (rport->old_pid == pid)
910  return rport;
911  }
912 
913  bfa_trc(port->fcs, pid);
914  return NULL;
915 }
916 
917 /*
918  * PWWN based Lookup for a R-Port in the Port R-Port Queue
919  */
920 struct bfa_fcs_rport_s *
922 {
923  struct bfa_fcs_rport_s *rport;
924  struct list_head *qe;
925 
926  list_for_each(qe, &port->rport_q) {
927  rport = (struct bfa_fcs_rport_s *) qe;
928  if (wwn_is_equal(rport->pwwn, pwwn))
929  return rport;
930  }
931 
932  bfa_trc(port->fcs, pwwn);
933  return NULL;
934 }
935 
936 /*
937  * NWWN based Lookup for a R-Port in the Port R-Port Queue
938  */
939 struct bfa_fcs_rport_s *
941 {
942  struct bfa_fcs_rport_s *rport;
943  struct list_head *qe;
944 
945  list_for_each(qe, &port->rport_q) {
946  rport = (struct bfa_fcs_rport_s *) qe;
947  if (wwn_is_equal(rport->nwwn, nwwn))
948  return rport;
949  }
950 
951  bfa_trc(port->fcs, nwwn);
952  return NULL;
953 }
954 
955 /*
956  * PWWN & PID based Lookup for a R-Port in the Port R-Port Queue
957  */
958 struct bfa_fcs_rport_s *
960  wwn_t pwwn, u32 pid)
961 {
962  struct bfa_fcs_rport_s *rport;
963  struct list_head *qe;
964 
965  list_for_each(qe, &port->rport_q) {
966  rport = (struct bfa_fcs_rport_s *) qe;
967  if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid)
968  return rport;
969  }
970 
971  bfa_trc(port->fcs, pwwn);
972  return NULL;
973 }
974 
975 /*
976  * Called by rport module when new rports are discovered.
977  */
978 void
980  struct bfa_fcs_lport_s *port,
981  struct bfa_fcs_rport_s *rport)
982 {
983  list_add_tail(&rport->qe, &port->rport_q);
984  port->num_rports++;
985 }
986 
987 /*
988  * Called by rport module to when rports are deleted.
989  */
990 void
992  struct bfa_fcs_lport_s *port,
993  struct bfa_fcs_rport_s *rport)
994 {
995  WARN_ON(!bfa_q_is_on_q(&port->rport_q, rport));
996  list_del(&rport->qe);
997  port->num_rports--;
998 
1000 }
1001 
1002 /*
1003  * Called by fabric for base port when fabric login is complete.
1004  * Called by vport for virtual ports when FDISC is complete.
1005  */
1006 void
1008 {
1010 }
1011 
1012 /*
1013  * Called by fabric for base port when fabric goes offline.
1014  * Called by vport for virtual ports when virtual port becomes offline.
1015  */
1016 void
1018 {
1020 }
1021 
1022 /*
1023  * Called by fabric for base port and by vport for virtual ports
1024  * when target mode driver is unloaded.
1025  */
1026 void
1028 {
1030 }
1031 
1032 /*
1033  * Called by fabric to delete base lport and associated resources.
1034  *
1035  * Called by vport to delete lport and associated resources. Should call
1036  * bfa_fcs_vport_delete_comp() for vports on completion.
1037  */
1038 void
1040 {
1042 }
1043 
1044 /*
1045  * Return TRUE if port is online, else return FALSE
1046  */
1049 {
1050  return bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online);
1051 }
1052 
1053 /*
1054  * Attach time initialization of logical ports.
1055  */
1056 void
1058  u16 vf_id, struct bfa_fcs_vport_s *vport)
1059 {
1060  lport->fcs = fcs;
1061  lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
1062  lport->vport = vport;
1063  lport->lp_tag = (vport) ? vport->lps->bfa_tag :
1064  lport->fabric->lps->bfa_tag;
1065 
1066  INIT_LIST_HEAD(&lport->rport_q);
1067  lport->num_rports = 0;
1068 }
1069 
1070 /*
1071  * Logical port initialization of base or virtual port.
1072  * Called by fabric for base port or by vport for virtual ports.
1073  */
1074 
1075 void
1077  struct bfa_lport_cfg_s *port_cfg)
1078 {
1079  struct bfa_fcs_vport_s *vport = lport->vport;
1080  struct bfad_s *bfad = (struct bfad_s *)lport->fcs->bfad;
1081  char lpwwn_buf[BFA_STRING_32];
1082 
1083  lport->port_cfg = *port_cfg;
1084 
1085  lport->bfad_port = bfa_fcb_lport_new(lport->fcs->bfad, lport,
1086  lport->port_cfg.roles,
1087  lport->fabric->vf_drv,
1088  vport ? vport->vport_drv : NULL);
1089 
1090  wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport));
1092  "New logical port created: WWN = %s Role = %s\n",
1093  lpwwn_buf, "Initiator");
1094  bfa_fcs_lport_aen_post(lport, BFA_LPORT_AEN_NEW);
1095 
1096  bfa_sm_set_state(lport, bfa_fcs_lport_sm_uninit);
1098 }
1099 
1100 /*
1101  * fcs_lport_api
1102  */
1103 
1104 void
1106  struct bfa_fcs_lport_s *port,
1107  struct bfa_lport_attr_s *port_attr)
1108 {
1109  if (bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
1110  port_attr->pid = port->pid;
1111  else
1112  port_attr->pid = 0;
1113 
1114  port_attr->port_cfg = port->port_cfg;
1115 
1116  if (port->fabric) {
1117  port_attr->port_type = port->fabric->oper_type;
1118  port_attr->loopback = bfa_sm_cmp_state(port->fabric,
1120  port_attr->authfail =
1121  bfa_sm_cmp_state(port->fabric,
1123  port_attr->fabric_name = bfa_fcs_lport_get_fabric_name(port);
1124  memcpy(port_attr->fabric_ip_addr,
1127 
1128  if (port->vport != NULL) {
1129  port_attr->port_type = BFA_PORT_TYPE_VPORT;
1130  port_attr->fpma_mac =
1131  port->vport->lps->lp_mac;
1132  } else {
1133  port_attr->fpma_mac =
1134  port->fabric->lps->lp_mac;
1135  }
1136  } else {
1137  port_attr->port_type = BFA_PORT_TYPE_UNKNOWN;
1138  port_attr->state = BFA_LPORT_UNINIT;
1139  }
1140 }
1141 
1142 /*
1143  * bfa_fcs_lport_fab port fab functions
1144  */
1145 
1146 /*
1147  * Called by port to initialize fabric services of the base port.
1148  */
1149 static void
1150 bfa_fcs_lport_fab_init(struct bfa_fcs_lport_s *port)
1151 {
1152  bfa_fcs_lport_ns_init(port);
1153  bfa_fcs_lport_scn_init(port);
1154  bfa_fcs_lport_ms_init(port);
1155 }
1156 
1157 /*
1158  * Called by port to notify transition to online state.
1159  */
1160 static void
1161 bfa_fcs_lport_fab_online(struct bfa_fcs_lport_s *port)
1162 {
1165 }
1166 
1167 /*
1168  * Called by port to notify transition to offline state.
1169  */
1170 static void
1171 bfa_fcs_lport_fab_offline(struct bfa_fcs_lport_s *port)
1172 {
1176 }
1177 
1178 /*
1179  * bfa_fcs_lport_n2n functions
1180  */
1181 
1182 /*
1183  * Called by fcs/port to initialize N2N topology.
1184  */
1185 static void
1186 bfa_fcs_lport_n2n_init(struct bfa_fcs_lport_s *port)
1187 {
1188 }
1189 
1190 /*
1191  * Called by fcs/port to notify transition to online state.
1192  */
1193 static void
1194 bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
1195 {
1196  struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1197  struct bfa_lport_cfg_s *pcfg = &port->port_cfg;
1198  struct bfa_fcs_rport_s *rport;
1199 
1200  bfa_trc(port->fcs, pcfg->pwwn);
1201 
1202  /*
1203  * If our PWWN is > than that of the r-port, we have to initiate PLOGI
1204  * and assign an Address. if not, we need to wait for its PLOGI.
1205  *
1206  * If our PWWN is < than that of the remote port, it will send a PLOGI
1207  * with the PIDs assigned. The rport state machine take care of this
1208  * incoming PLOGI.
1209  */
1210  if (memcmp
1211  ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
1212  sizeof(wwn_t)) > 0) {
1213  port->pid = N2N_LOCAL_PID;
1215  /*
1216  * First, check if we know the device by pwwn.
1217  */
1218  rport = bfa_fcs_lport_get_rport_by_pwwn(port,
1219  n2n_port->rem_port_wwn);
1220  if (rport) {
1221  bfa_trc(port->fcs, rport->pid);
1222  bfa_trc(port->fcs, rport->pwwn);
1223  rport->pid = N2N_REMOTE_PID;
1225  return;
1226  }
1227 
1228  /*
1229  * In n2n there can be only one rport. Delete the old one
1230  * whose pid should be zero, because it is offline.
1231  */
1232  if (port->num_rports > 0) {
1233  rport = bfa_fcs_lport_get_rport_by_pid(port, 0);
1234  WARN_ON(rport == NULL);
1235  if (rport) {
1236  bfa_trc(port->fcs, rport->pwwn);
1238  }
1239  }
1241  }
1242 }
1243 
1244 /*
1245  * Called by fcs/port to notify transition to offline state.
1246  */
1247 static void
1248 bfa_fcs_lport_n2n_offline(struct bfa_fcs_lport_s *port)
1249 {
1250  struct bfa_fcs_lport_n2n_s *n2n_port = &port->port_topo.pn2n;
1251 
1252  bfa_trc(port->fcs, port->pid);
1253  port->pid = 0;
1254  n2n_port->rem_port_wwn = 0;
1255  n2n_port->reply_oxid = 0;
1256 }
1257 
1258 void
1260 {
1261  int i = 0, j = 0, bit = 0, alpa_bit = 0;
1262  u8 k = 0;
1263  struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(port->fcs->bfa);
1264 
1265  port->port_topo.ploop.alpabm_valid = fcport->alpabm_valid;
1266  port->pid = fcport->myalpa;
1267  port->pid = bfa_hton3b(port->pid);
1268 
1269  for (i = 0; i < (FC_ALPA_MAX / 8); i++) {
1270  for (j = 0, alpa_bit = 0; j < 8; j++, alpa_bit++) {
1271  bfa_trc(port->fcs->bfa, fcport->alpabm.alpa_bm[i]);
1272  bit = (fcport->alpabm.alpa_bm[i] & (1 << (7 - j)));
1273  if (bit) {
1274  port->port_topo.ploop.alpa_pos_map[k] =
1275  loop_alpa_map[(i * 8) + alpa_bit];
1276  k++;
1277  bfa_trc(port->fcs->bfa, k);
1278  bfa_trc(port->fcs->bfa,
1279  port->port_topo.ploop.alpa_pos_map[k]);
1280  }
1281  }
1282  }
1283  port->port_topo.ploop.num_alpa = k;
1284 }
1285 
1286 /*
1287  * Called by fcs/port to initialize Loop topology.
1288  */
1289 static void
1290 bfa_fcs_lport_loop_init(struct bfa_fcs_lport_s *port)
1291 {
1292 }
1293 
1294 /*
1295  * Called by fcs/port to notify transition to online state.
1296  */
1297 static void
1298 bfa_fcs_lport_loop_online(struct bfa_fcs_lport_s *port)
1299 {
1300  u8 num_alpa = 0, alpabm_valid = 0;
1301  struct bfa_fcs_rport_s *rport;
1302  u8 *alpa_map = NULL;
1303  int i = 0;
1304  u32 pid;
1305 
1307 
1308  num_alpa = port->port_topo.ploop.num_alpa;
1309  alpabm_valid = port->port_topo.ploop.alpabm_valid;
1310  alpa_map = port->port_topo.ploop.alpa_pos_map;
1311 
1312  bfa_trc(port->fcs->bfa, port->pid);
1313  bfa_trc(port->fcs->bfa, num_alpa);
1314  if (alpabm_valid == 1) {
1315  for (i = 0; i < num_alpa; i++) {
1316  bfa_trc(port->fcs->bfa, alpa_map[i]);
1317  if (alpa_map[i] != bfa_hton3b(port->pid)) {
1318  pid = alpa_map[i];
1319  bfa_trc(port->fcs->bfa, pid);
1320  rport = bfa_fcs_lport_get_rport_by_pid(port,
1321  bfa_hton3b(pid));
1322  if (!rport)
1323  rport = bfa_fcs_rport_create(port,
1324  bfa_hton3b(pid));
1325  }
1326  }
1327  } else {
1328  for (i = 0; i < MAX_ALPA_COUNT; i++) {
1329  if (alpa_map[i] != port->pid) {
1330  pid = loop_alpa_map[i];
1331  bfa_trc(port->fcs->bfa, pid);
1332  rport = bfa_fcs_lport_get_rport_by_pid(port,
1333  bfa_hton3b(pid));
1334  if (!rport)
1335  rport = bfa_fcs_rport_create(port,
1336  bfa_hton3b(pid));
1337  }
1338  }
1339  }
1340 }
1341 
1342 /*
1343  * Called by fcs/port to notify transition to offline state.
1344  */
1345 static void
1346 bfa_fcs_lport_loop_offline(struct bfa_fcs_lport_s *port)
1347 {
1348 }
1349 
1350 #define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
1351 
1352 /*
1353  * forward declarations
1354  */
1355 static void bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg,
1356  struct bfa_fcxp_s *fcxp_alloced);
1357 static void bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg,
1358  struct bfa_fcxp_s *fcxp_alloced);
1359 static void bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg,
1360  struct bfa_fcxp_s *fcxp_alloced);
1361 static void bfa_fcs_lport_fdmi_rhba_response(void *fcsarg,
1362  struct bfa_fcxp_s *fcxp,
1363  void *cbarg,
1364  bfa_status_t req_status,
1365  u32 rsp_len,
1366  u32 resid_len,
1367  struct fchs_s *rsp_fchs);
1368 static void bfa_fcs_lport_fdmi_rprt_response(void *fcsarg,
1369  struct bfa_fcxp_s *fcxp,
1370  void *cbarg,
1371  bfa_status_t req_status,
1372  u32 rsp_len,
1373  u32 resid_len,
1374  struct fchs_s *rsp_fchs);
1375 static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg,
1376  struct bfa_fcxp_s *fcxp,
1377  void *cbarg,
1378  bfa_status_t req_status,
1379  u32 rsp_len,
1380  u32 resid_len,
1381  struct fchs_s *rsp_fchs);
1382 static void bfa_fcs_lport_fdmi_timeout(void *arg);
1383 static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1384  u8 *pyld);
1385 static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1386  u8 *pyld);
1387 static u16 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi,
1388  u8 *pyld);
1389 static u16 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *
1390  fdmi, u8 *pyld);
1391 static void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1392  struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
1393 static void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
1394  struct bfa_fcs_fdmi_port_attr_s *port_attr);
1396 
1397 /*
1398  * fcs_fdmi_sm FCS FDMI state machine
1399  */
1400 
1401 /*
1402  * FDMI State Machine events
1403  */
1413 };
1414 
1415 static void bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1416  enum port_fdmi_event event);
1417 static void bfa_fcs_lport_fdmi_sm_sending_rhba(
1418  struct bfa_fcs_lport_fdmi_s *fdmi,
1419  enum port_fdmi_event event);
1420 static void bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1421  enum port_fdmi_event event);
1422 static void bfa_fcs_lport_fdmi_sm_rhba_retry(
1423  struct bfa_fcs_lport_fdmi_s *fdmi,
1424  enum port_fdmi_event event);
1425 static void bfa_fcs_lport_fdmi_sm_sending_rprt(
1426  struct bfa_fcs_lport_fdmi_s *fdmi,
1427  enum port_fdmi_event event);
1428 static void bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1429  enum port_fdmi_event event);
1430 static void bfa_fcs_lport_fdmi_sm_rprt_retry(
1431  struct bfa_fcs_lport_fdmi_s *fdmi,
1432  enum port_fdmi_event event);
1433 static void bfa_fcs_lport_fdmi_sm_sending_rpa(
1434  struct bfa_fcs_lport_fdmi_s *fdmi,
1435  enum port_fdmi_event event);
1436 static void bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1437  enum port_fdmi_event event);
1438 static void bfa_fcs_lport_fdmi_sm_rpa_retry(
1439  struct bfa_fcs_lport_fdmi_s *fdmi,
1440  enum port_fdmi_event event);
1441 static void bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1442  enum port_fdmi_event event);
1443 static void bfa_fcs_lport_fdmi_sm_disabled(
1444  struct bfa_fcs_lport_fdmi_s *fdmi,
1445  enum port_fdmi_event event);
1446 /*
1447  * Start in offline state - awaiting MS to send start.
1448  */
1449 static void
1450 bfa_fcs_lport_fdmi_sm_offline(struct bfa_fcs_lport_fdmi_s *fdmi,
1451  enum port_fdmi_event event)
1452 {
1453  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1454 
1455  bfa_trc(port->fcs, port->port_cfg.pwwn);
1456  bfa_trc(port->fcs, event);
1457 
1458  fdmi->retry_cnt = 0;
1459 
1460  switch (event) {
1462  if (port->vport) {
1463  /*
1464  * For Vports, register a new port.
1465  */
1466  bfa_sm_set_state(fdmi,
1467  bfa_fcs_lport_fdmi_sm_sending_rprt);
1468  bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1469  } else {
1470  /*
1471  * For a base port, we should first register the HBA
1472  * attribute. The HBA attribute also contains the base
1473  * port registration.
1474  */
1475  bfa_sm_set_state(fdmi,
1476  bfa_fcs_lport_fdmi_sm_sending_rhba);
1477  bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1478  }
1479  break;
1480 
1482  break;
1483 
1484  default:
1485  bfa_sm_fault(port->fcs, event);
1486  }
1487 }
1488 
1489 static void
1490 bfa_fcs_lport_fdmi_sm_sending_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1491  enum port_fdmi_event event)
1492 {
1493  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1494 
1495  bfa_trc(port->fcs, port->port_cfg.pwwn);
1496  bfa_trc(port->fcs, event);
1497 
1498  switch (event) {
1500  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rhba);
1501  break;
1502 
1504  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1506  &fdmi->fcxp_wqe);
1507  break;
1508 
1509  default:
1510  bfa_sm_fault(port->fcs, event);
1511  }
1512 }
1513 
1514 static void
1515 bfa_fcs_lport_fdmi_sm_rhba(struct bfa_fcs_lport_fdmi_s *fdmi,
1516  enum port_fdmi_event event)
1517 {
1518  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1519 
1520  bfa_trc(port->fcs, port->port_cfg.pwwn);
1521  bfa_trc(port->fcs, event);
1522 
1523  switch (event) {
1525  /*
1526  * if max retries have not been reached, start timer for a
1527  * delayed retry
1528  */
1529  if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1530  bfa_sm_set_state(fdmi,
1531  bfa_fcs_lport_fdmi_sm_rhba_retry);
1533  &fdmi->timer,
1534  bfa_fcs_lport_fdmi_timeout, fdmi,
1536  } else {
1537  /*
1538  * set state to offline
1539  */
1540  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1541  }
1542  break;
1543 
1544  case FDMISM_EVENT_RSP_OK:
1545  /*
1546  * Initiate Register Port Attributes
1547  */
1548  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1549  fdmi->retry_cnt = 0;
1550  bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1551  break;
1552 
1554  bfa_fcxp_discard(fdmi->fcxp);
1555  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1556  break;
1557 
1558  default:
1559  bfa_sm_fault(port->fcs, event);
1560  }
1561 }
1562 
1563 static void
1564 bfa_fcs_lport_fdmi_sm_rhba_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1565  enum port_fdmi_event event)
1566 {
1567  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1568 
1569  bfa_trc(port->fcs, port->port_cfg.pwwn);
1570  bfa_trc(port->fcs, event);
1571 
1572  switch (event) {
1573  case FDMISM_EVENT_TIMEOUT:
1574  /*
1575  * Retry Timer Expired. Re-send
1576  */
1577  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rhba);
1578  bfa_fcs_lport_fdmi_send_rhba(fdmi, NULL);
1579  break;
1580 
1582  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1583  bfa_timer_stop(&fdmi->timer);
1584  break;
1585 
1586  default:
1587  bfa_sm_fault(port->fcs, event);
1588  }
1589 }
1590 
1591 /*
1592 * RPRT : Register Port
1593  */
1594 static void
1595 bfa_fcs_lport_fdmi_sm_sending_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1596  enum port_fdmi_event event)
1597 {
1598  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1599 
1600  bfa_trc(port->fcs, port->port_cfg.pwwn);
1601  bfa_trc(port->fcs, event);
1602 
1603  switch (event) {
1605  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rprt);
1606  break;
1607 
1609  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1611  &fdmi->fcxp_wqe);
1612  break;
1613 
1614  default:
1615  bfa_sm_fault(port->fcs, event);
1616  }
1617 }
1618 
1619 static void
1620 bfa_fcs_lport_fdmi_sm_rprt(struct bfa_fcs_lport_fdmi_s *fdmi,
1621  enum port_fdmi_event event)
1622 {
1623  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1624 
1625  bfa_trc(port->fcs, port->port_cfg.pwwn);
1626  bfa_trc(port->fcs, event);
1627 
1628  switch (event) {
1630  /*
1631  * if max retries have not been reached, start timer for a
1632  * delayed retry
1633  */
1634  if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1635  bfa_sm_set_state(fdmi,
1636  bfa_fcs_lport_fdmi_sm_rprt_retry);
1638  &fdmi->timer,
1639  bfa_fcs_lport_fdmi_timeout, fdmi,
1641 
1642  } else {
1643  /*
1644  * set state to offline
1645  */
1646  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1647  fdmi->retry_cnt = 0;
1648  }
1649  break;
1650 
1651  case FDMISM_EVENT_RSP_OK:
1652  fdmi->retry_cnt = 0;
1653  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1654  break;
1655 
1657  bfa_fcxp_discard(fdmi->fcxp);
1658  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1659  break;
1660 
1661  default:
1662  bfa_sm_fault(port->fcs, event);
1663  }
1664 }
1665 
1666 static void
1667 bfa_fcs_lport_fdmi_sm_rprt_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1668  enum port_fdmi_event event)
1669 {
1670  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1671 
1672  bfa_trc(port->fcs, port->port_cfg.pwwn);
1673  bfa_trc(port->fcs, event);
1674 
1675  switch (event) {
1676  case FDMISM_EVENT_TIMEOUT:
1677  /*
1678  * Retry Timer Expired. Re-send
1679  */
1680  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rprt);
1681  bfa_fcs_lport_fdmi_send_rprt(fdmi, NULL);
1682  break;
1683 
1685  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1686  bfa_timer_stop(&fdmi->timer);
1687  break;
1688 
1689  default:
1690  bfa_sm_fault(port->fcs, event);
1691  }
1692 }
1693 
1694 /*
1695  * Register Port Attributes
1696  */
1697 static void
1698 bfa_fcs_lport_fdmi_sm_sending_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1699  enum port_fdmi_event event)
1700 {
1701  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1702 
1703  bfa_trc(port->fcs, port->port_cfg.pwwn);
1704  bfa_trc(port->fcs, event);
1705 
1706  switch (event) {
1707  case FDMISM_EVENT_RPA_SENT:
1708  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa);
1709  break;
1710 
1712  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1714  &fdmi->fcxp_wqe);
1715  break;
1716 
1717  default:
1718  bfa_sm_fault(port->fcs, event);
1719  }
1720 }
1721 
1722 static void
1723 bfa_fcs_lport_fdmi_sm_rpa(struct bfa_fcs_lport_fdmi_s *fdmi,
1724  enum port_fdmi_event event)
1725 {
1726  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1727 
1728  bfa_trc(port->fcs, port->port_cfg.pwwn);
1729  bfa_trc(port->fcs, event);
1730 
1731  switch (event) {
1733  /*
1734  * if max retries have not been reached, start timer for a
1735  * delayed retry
1736  */
1737  if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
1738  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_rpa_retry);
1740  &fdmi->timer,
1741  bfa_fcs_lport_fdmi_timeout, fdmi,
1743  } else {
1744  /*
1745  * set state to offline
1746  */
1747  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1748  fdmi->retry_cnt = 0;
1749  }
1750  break;
1751 
1752  case FDMISM_EVENT_RSP_OK:
1753  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_online);
1754  fdmi->retry_cnt = 0;
1755  break;
1756 
1758  bfa_fcxp_discard(fdmi->fcxp);
1759  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1760  break;
1761 
1762  default:
1763  bfa_sm_fault(port->fcs, event);
1764  }
1765 }
1766 
1767 static void
1768 bfa_fcs_lport_fdmi_sm_rpa_retry(struct bfa_fcs_lport_fdmi_s *fdmi,
1769  enum port_fdmi_event event)
1770 {
1771  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1772 
1773  bfa_trc(port->fcs, port->port_cfg.pwwn);
1774  bfa_trc(port->fcs, event);
1775 
1776  switch (event) {
1777  case FDMISM_EVENT_TIMEOUT:
1778  /*
1779  * Retry Timer Expired. Re-send
1780  */
1781  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_sending_rpa);
1782  bfa_fcs_lport_fdmi_send_rpa(fdmi, NULL);
1783  break;
1784 
1786  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1787  bfa_timer_stop(&fdmi->timer);
1788  break;
1789 
1790  default:
1791  bfa_sm_fault(port->fcs, event);
1792  }
1793 }
1794 
1795 static void
1796 bfa_fcs_lport_fdmi_sm_online(struct bfa_fcs_lport_fdmi_s *fdmi,
1797  enum port_fdmi_event event)
1798 {
1799  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1800 
1801  bfa_trc(port->fcs, port->port_cfg.pwwn);
1802  bfa_trc(port->fcs, event);
1803 
1804  switch (event) {
1806  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
1807  break;
1808 
1809  default:
1810  bfa_sm_fault(port->fcs, event);
1811  }
1812 }
1813 /*
1814  * FDMI is disabled state.
1815  */
1816 static void
1817 bfa_fcs_lport_fdmi_sm_disabled(struct bfa_fcs_lport_fdmi_s *fdmi,
1818  enum port_fdmi_event event)
1819 {
1820  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1821 
1822  bfa_trc(port->fcs, port->port_cfg.pwwn);
1823  bfa_trc(port->fcs, event);
1824 
1825  /* No op State. It can only be enabled at Driver Init. */
1826 }
1827 
1828 /*
1829 * RHBA : Register HBA Attributes.
1830  */
1831 static void
1832 bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1833 {
1834  struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
1835  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1836  struct fchs_s fchs;
1837  int len, attr_len;
1838  struct bfa_fcxp_s *fcxp;
1839  u8 *pyld;
1840 
1841  bfa_trc(port->fcs, port->port_cfg.pwwn);
1842 
1843  fcxp = fcxp_alloced ? fcxp_alloced :
1845  if (!fcxp) {
1846  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1847  bfa_fcs_lport_fdmi_send_rhba, fdmi, BFA_TRUE);
1848  return;
1849  }
1850  fdmi->fcxp = fcxp;
1851 
1852  pyld = bfa_fcxp_get_reqbuf(fcxp);
1853  memset(pyld, 0, FC_MAX_PDUSZ);
1854 
1855  len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
1856  FDMI_RHBA);
1857 
1858  attr_len =
1859  bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi,
1860  (u8 *) ((struct ct_hdr_s *) pyld
1861  + 1));
1862 
1863  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1864  FC_CLASS_3, (len + attr_len), &fchs,
1865  bfa_fcs_lport_fdmi_rhba_response, (void *)fdmi,
1867 
1869 }
1870 
1871 static u16
1872 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
1873 {
1874  struct bfa_fcs_lport_s *port = fdmi->ms->port;
1875  struct bfa_fcs_fdmi_hba_attr_s hba_attr;
1876  struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr;
1877  struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld;
1878  struct fdmi_attr_s *attr;
1879  u8 *curr_ptr;
1880  u16 len, count;
1881  u16 templen;
1882 
1883  /*
1884  * get hba attributes
1885  */
1886  bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
1887 
1888  rhba->hba_id = bfa_fcs_lport_get_pwwn(port);
1889  rhba->port_list.num_ports = cpu_to_be32(1);
1890  rhba->port_list.port_entry = bfa_fcs_lport_get_pwwn(port);
1891 
1892  len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
1893 
1894  count = 0;
1895  len += sizeof(rhba->hba_attr_blk.attr_count);
1896 
1897  /*
1898  * fill out the invididual entries of the HBA attrib Block
1899  */
1900  curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
1901 
1902  /*
1903  * Node Name
1904  */
1905  attr = (struct fdmi_attr_s *) curr_ptr;
1907  templen = sizeof(wwn_t);
1908  memcpy(attr->value, &bfa_fcs_lport_get_nwwn(port), templen);
1909  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1910  len += templen;
1911  count++;
1912  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1913  sizeof(templen));
1914 
1915  /*
1916  * Manufacturer
1917  */
1918  attr = (struct fdmi_attr_s *) curr_ptr;
1920  templen = (u16) strlen(fcs_hba_attr->manufacturer);
1921  memcpy(attr->value, fcs_hba_attr->manufacturer, templen);
1922  templen = fc_roundup(templen, sizeof(u32));
1923  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1924  len += templen;
1925  count++;
1926  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1927  sizeof(templen));
1928 
1929  /*
1930  * Serial Number
1931  */
1932  attr = (struct fdmi_attr_s *) curr_ptr;
1934  templen = (u16) strlen(fcs_hba_attr->serial_num);
1935  memcpy(attr->value, fcs_hba_attr->serial_num, templen);
1936  templen = fc_roundup(templen, sizeof(u32));
1937  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1938  len += templen;
1939  count++;
1940  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1941  sizeof(templen));
1942 
1943  /*
1944  * Model
1945  */
1946  attr = (struct fdmi_attr_s *) curr_ptr;
1948  templen = (u16) strlen(fcs_hba_attr->model);
1949  memcpy(attr->value, fcs_hba_attr->model, templen);
1950  templen = fc_roundup(templen, sizeof(u32));
1951  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1952  len += templen;
1953  count++;
1954  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1955  sizeof(templen));
1956 
1957  /*
1958  * Model Desc
1959  */
1960  attr = (struct fdmi_attr_s *) curr_ptr;
1962  templen = (u16) strlen(fcs_hba_attr->model_desc);
1963  memcpy(attr->value, fcs_hba_attr->model_desc, templen);
1964  templen = fc_roundup(templen, sizeof(u32));
1965  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1966  len += templen;
1967  count++;
1968  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1969  sizeof(templen));
1970 
1971  /*
1972  * H/W Version
1973  */
1974  if (fcs_hba_attr->hw_version[0] != '\0') {
1975  attr = (struct fdmi_attr_s *) curr_ptr;
1977  templen = (u16) strlen(fcs_hba_attr->hw_version);
1978  memcpy(attr->value, fcs_hba_attr->hw_version, templen);
1979  templen = fc_roundup(templen, sizeof(u32));
1980  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1981  len += templen;
1982  count++;
1983  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1984  sizeof(templen));
1985  }
1986 
1987  /*
1988  * Driver Version
1989  */
1990  attr = (struct fdmi_attr_s *) curr_ptr;
1992  templen = (u16) strlen(fcs_hba_attr->driver_version);
1993  memcpy(attr->value, fcs_hba_attr->driver_version, templen);
1994  templen = fc_roundup(templen, sizeof(u32));
1995  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
1996  len += templen;
1997  count++;
1998  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
1999  sizeof(templen));
2000 
2001  /*
2002  * Option Rom Version
2003  */
2004  if (fcs_hba_attr->option_rom_ver[0] != '\0') {
2005  attr = (struct fdmi_attr_s *) curr_ptr;
2007  templen = (u16) strlen(fcs_hba_attr->option_rom_ver);
2008  memcpy(attr->value, fcs_hba_attr->option_rom_ver, templen);
2009  templen = fc_roundup(templen, sizeof(u32));
2010  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2011  len += templen;
2012  count++;
2013  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2014  sizeof(templen));
2015  }
2016 
2017  attr = (struct fdmi_attr_s *) curr_ptr;
2019  templen = (u16) strlen(fcs_hba_attr->fw_version);
2020  memcpy(attr->value, fcs_hba_attr->fw_version, templen);
2021  templen = fc_roundup(templen, sizeof(u32));
2022  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2023  len += templen;
2024  count++;
2025  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2026  sizeof(templen));
2027 
2028  /*
2029  * OS Name
2030  */
2031  if (fcs_hba_attr->os_name[0] != '\0') {
2032  attr = (struct fdmi_attr_s *) curr_ptr;
2034  templen = (u16) strlen(fcs_hba_attr->os_name);
2035  memcpy(attr->value, fcs_hba_attr->os_name, templen);
2036  templen = fc_roundup(templen, sizeof(u32));
2037  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2038  len += templen;
2039  count++;
2040  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2041  sizeof(templen));
2042  }
2043 
2044  /*
2045  * MAX_CT_PAYLOAD
2046  */
2047  attr = (struct fdmi_attr_s *) curr_ptr;
2049  templen = sizeof(fcs_hba_attr->max_ct_pyld);
2050  memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen);
2051  len += templen;
2052  count++;
2053  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2054  sizeof(templen));
2055 
2056  /*
2057  * Update size of payload
2058  */
2059  len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
2060 
2061  rhba->hba_attr_blk.attr_count = cpu_to_be32(count);
2062  return len;
2063 }
2064 
2065 static void
2066 bfa_fcs_lport_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2067  void *cbarg, bfa_status_t req_status,
2068  u32 rsp_len, u32 resid_len,
2069  struct fchs_s *rsp_fchs)
2070 {
2071  struct bfa_fcs_lport_fdmi_s *fdmi =
2072  (struct bfa_fcs_lport_fdmi_s *) cbarg;
2073  struct bfa_fcs_lport_s *port = fdmi->ms->port;
2074  struct ct_hdr_s *cthdr = NULL;
2075 
2076  bfa_trc(port->fcs, port->port_cfg.pwwn);
2077 
2078  /*
2079  * Sanity Checks
2080  */
2081  if (req_status != BFA_STATUS_OK) {
2082  bfa_trc(port->fcs, req_status);
2084  return;
2085  }
2086 
2087  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2088  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2089 
2090  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2092  return;
2093  }
2094 
2095  bfa_trc(port->fcs, cthdr->reason_code);
2096  bfa_trc(port->fcs, cthdr->exp_code);
2098 }
2099 
2100 /*
2101 * RPRT : Register Port
2102  */
2103 static void
2104 bfa_fcs_lport_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2105 {
2106  struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
2107  struct bfa_fcs_lport_s *port = fdmi->ms->port;
2108  struct fchs_s fchs;
2109  u16 len, attr_len;
2110  struct bfa_fcxp_s *fcxp;
2111  u8 *pyld;
2112 
2113  bfa_trc(port->fcs, port->port_cfg.pwwn);
2114 
2115  fcxp = fcxp_alloced ? fcxp_alloced :
2117  if (!fcxp) {
2118  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2119  bfa_fcs_lport_fdmi_send_rprt, fdmi, BFA_TRUE);
2120  return;
2121  }
2122  fdmi->fcxp = fcxp;
2123 
2124  pyld = bfa_fcxp_get_reqbuf(fcxp);
2125  memset(pyld, 0, FC_MAX_PDUSZ);
2126 
2127  len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2128  FDMI_RPRT);
2129 
2130  attr_len =
2131  bfa_fcs_lport_fdmi_build_rprt_pyld(fdmi,
2132  (u8 *) ((struct ct_hdr_s *) pyld
2133  + 1));
2134 
2135  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2136  FC_CLASS_3, len + attr_len, &fchs,
2137  bfa_fcs_lport_fdmi_rprt_response, (void *)fdmi,
2139 
2141 }
2142 
2143 /*
2144  * This routine builds Port Attribute Block that used in RPA, RPRT commands.
2145  */
2146 static u16
2147 bfa_fcs_lport_fdmi_build_portattr_block(struct bfa_fcs_lport_fdmi_s *fdmi,
2148  u8 *pyld)
2149 {
2150  struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
2151  struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld;
2152  struct fdmi_attr_s *attr;
2153  u8 *curr_ptr;
2154  u16 len;
2155  u8 count = 0;
2156  u16 templen;
2157 
2158  /*
2159  * get port attributes
2160  */
2161  bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
2162 
2163  len = sizeof(port_attrib->attr_count);
2164 
2165  /*
2166  * fill out the invididual entries
2167  */
2168  curr_ptr = (u8 *) &port_attrib->port_attr;
2169 
2170  /*
2171  * FC4 Types
2172  */
2173  attr = (struct fdmi_attr_s *) curr_ptr;
2175  templen = sizeof(fcs_port_attr.supp_fc4_types);
2176  memcpy(attr->value, fcs_port_attr.supp_fc4_types, templen);
2177  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2178  len += templen;
2179  ++count;
2180  attr->len =
2181  cpu_to_be16(templen + sizeof(attr->type) +
2182  sizeof(templen));
2183 
2184  /*
2185  * Supported Speed
2186  */
2187  attr = (struct fdmi_attr_s *) curr_ptr;
2189  templen = sizeof(fcs_port_attr.supp_speed);
2190  memcpy(attr->value, &fcs_port_attr.supp_speed, templen);
2191  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2192  len += templen;
2193  ++count;
2194  attr->len =
2195  cpu_to_be16(templen + sizeof(attr->type) +
2196  sizeof(templen));
2197 
2198  /*
2199  * current Port Speed
2200  */
2201  attr = (struct fdmi_attr_s *) curr_ptr;
2203  templen = sizeof(fcs_port_attr.curr_speed);
2204  memcpy(attr->value, &fcs_port_attr.curr_speed, templen);
2205  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2206  len += templen;
2207  ++count;
2208  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2209  sizeof(templen));
2210 
2211  /*
2212  * max frame size
2213  */
2214  attr = (struct fdmi_attr_s *) curr_ptr;
2216  templen = sizeof(fcs_port_attr.max_frm_size);
2217  memcpy(attr->value, &fcs_port_attr.max_frm_size, templen);
2218  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2219  len += templen;
2220  ++count;
2221  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2222  sizeof(templen));
2223 
2224  /*
2225  * OS Device Name
2226  */
2227  if (fcs_port_attr.os_device_name[0] != '\0') {
2228  attr = (struct fdmi_attr_s *) curr_ptr;
2230  templen = (u16) strlen(fcs_port_attr.os_device_name);
2231  memcpy(attr->value, fcs_port_attr.os_device_name, templen);
2232  templen = fc_roundup(templen, sizeof(u32));
2233  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2234  len += templen;
2235  ++count;
2236  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2237  sizeof(templen));
2238  }
2239  /*
2240  * Host Name
2241  */
2242  if (fcs_port_attr.host_name[0] != '\0') {
2243  attr = (struct fdmi_attr_s *) curr_ptr;
2245  templen = (u16) strlen(fcs_port_attr.host_name);
2246  memcpy(attr->value, fcs_port_attr.host_name, templen);
2247  templen = fc_roundup(templen, sizeof(u32));
2248  curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
2249  len += templen;
2250  ++count;
2251  attr->len = cpu_to_be16(templen + sizeof(attr->type) +
2252  sizeof(templen));
2253  }
2254 
2255  /*
2256  * Update size of payload
2257  */
2258  port_attrib->attr_count = cpu_to_be32(count);
2259  len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
2260  return len;
2261 }
2262 
2263 static u16
2264 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2265 {
2266  struct bfa_fcs_lport_s *port = fdmi->ms->port;
2267  struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld;
2268  u16 len;
2269 
2271  rprt->port_name = bfa_fcs_lport_get_pwwn(port);
2272 
2273  len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2274  (u8 *) &rprt->port_attr_blk);
2275 
2276  len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
2277 
2278  return len;
2279 }
2280 
2281 static void
2282 bfa_fcs_lport_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2283  void *cbarg, bfa_status_t req_status,
2284  u32 rsp_len, u32 resid_len,
2285  struct fchs_s *rsp_fchs)
2286 {
2287  struct bfa_fcs_lport_fdmi_s *fdmi =
2288  (struct bfa_fcs_lport_fdmi_s *) cbarg;
2289  struct bfa_fcs_lport_s *port = fdmi->ms->port;
2290  struct ct_hdr_s *cthdr = NULL;
2291 
2292  bfa_trc(port->fcs, port->port_cfg.pwwn);
2293 
2294  /*
2295  * Sanity Checks
2296  */
2297  if (req_status != BFA_STATUS_OK) {
2298  bfa_trc(port->fcs, req_status);
2300  return;
2301  }
2302 
2303  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2304  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2305 
2306  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2308  return;
2309  }
2310 
2311  bfa_trc(port->fcs, cthdr->reason_code);
2312  bfa_trc(port->fcs, cthdr->exp_code);
2314 }
2315 
2316 /*
2317 * RPA : Register Port Attributes.
2318  */
2319 static void
2320 bfa_fcs_lport_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2321 {
2322  struct bfa_fcs_lport_fdmi_s *fdmi = fdmi_cbarg;
2323  struct bfa_fcs_lport_s *port = fdmi->ms->port;
2324  struct fchs_s fchs;
2325  u16 len, attr_len;
2326  struct bfa_fcxp_s *fcxp;
2327  u8 *pyld;
2328 
2329  bfa_trc(port->fcs, port->port_cfg.pwwn);
2330 
2331  fcxp = fcxp_alloced ? fcxp_alloced :
2333  if (!fcxp) {
2334  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
2335  bfa_fcs_lport_fdmi_send_rpa, fdmi, BFA_TRUE);
2336  return;
2337  }
2338  fdmi->fcxp = fcxp;
2339 
2340  pyld = bfa_fcxp_get_reqbuf(fcxp);
2341  memset(pyld, 0, FC_MAX_PDUSZ);
2342 
2343  len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_lport_get_fcid(port),
2344  FDMI_RPA);
2345 
2346  attr_len = bfa_fcs_lport_fdmi_build_rpa_pyld(fdmi,
2347  (u8 *) ((struct ct_hdr_s *) pyld + 1));
2348 
2349  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2350  FC_CLASS_3, len + attr_len, &fchs,
2351  bfa_fcs_lport_fdmi_rpa_response, (void *)fdmi,
2353 
2355 }
2356 
2357 static u16
2358 bfa_fcs_lport_fdmi_build_rpa_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld)
2359 {
2360  struct bfa_fcs_lport_s *port = fdmi->ms->port;
2361  struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld;
2362  u16 len;
2363 
2364  rpa->port_name = bfa_fcs_lport_get_pwwn(port);
2365 
2366  len = bfa_fcs_lport_fdmi_build_portattr_block(fdmi,
2367  (u8 *) &rpa->port_attr_blk);
2368 
2369  len += sizeof(rpa->port_name);
2370 
2371  return len;
2372 }
2373 
2374 static void
2375 bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2376  void *cbarg, bfa_status_t req_status, u32 rsp_len,
2377  u32 resid_len, struct fchs_s *rsp_fchs)
2378 {
2379  struct bfa_fcs_lport_fdmi_s *fdmi =
2380  (struct bfa_fcs_lport_fdmi_s *) cbarg;
2381  struct bfa_fcs_lport_s *port = fdmi->ms->port;
2382  struct ct_hdr_s *cthdr = NULL;
2383 
2384  bfa_trc(port->fcs, port->port_cfg.pwwn);
2385 
2386  /*
2387  * Sanity Checks
2388  */
2389  if (req_status != BFA_STATUS_OK) {
2390  bfa_trc(port->fcs, req_status);
2392  return;
2393  }
2394 
2395  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2396  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2397 
2398  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2400  return;
2401  }
2402 
2403  bfa_trc(port->fcs, cthdr->reason_code);
2404  bfa_trc(port->fcs, cthdr->exp_code);
2406 }
2407 
2408 static void
2409 bfa_fcs_lport_fdmi_timeout(void *arg)
2410 {
2411  struct bfa_fcs_lport_fdmi_s *fdmi = (struct bfa_fcs_lport_fdmi_s *) arg;
2412 
2414 }
2415 
2416 static void
2417 bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2418  struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
2419 {
2420  struct bfa_fcs_lport_s *port = fdmi->ms->port;
2421  struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
2422  struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
2423 
2424  memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
2425 
2426  bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc,
2427  hba_attr->manufacturer);
2428  bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc,
2429  hba_attr->serial_num);
2430  bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2431  hba_attr->model);
2432  bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc,
2433  hba_attr->model_desc);
2434  bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc,
2435  hba_attr->hw_version);
2436  bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc,
2437  hba_attr->option_rom_ver);
2438  bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc,
2439  hba_attr->fw_version);
2440 
2441  strncpy(hba_attr->driver_version, (char *)driver_info->version,
2442  sizeof(hba_attr->driver_version));
2443 
2444  strncpy(hba_attr->os_name, driver_info->host_os_name,
2445  sizeof(hba_attr->os_name));
2446 
2447  /*
2448  * If there is a patch level, append it
2449  * to the os name along with a separator
2450  */
2451  if (driver_info->host_os_patch[0] != '\0') {
2454  strncat(hba_attr->os_name, driver_info->host_os_patch,
2455  sizeof(driver_info->host_os_patch));
2456  }
2457 
2458  /* Retrieve the max frame size from the port attr */
2459  bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
2460  hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size;
2461 }
2462 
2463 static void
2464 bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
2465  struct bfa_fcs_fdmi_port_attr_s *port_attr)
2466 {
2467  struct bfa_fcs_lport_s *port = fdmi->ms->port;
2468  struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
2469  struct bfa_port_attr_s pport_attr;
2470 
2471  memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
2472 
2473  /*
2474  * get pport attributes from hal
2475  */
2476  bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2477 
2478  /*
2479  * get FC4 type Bitmask
2480  */
2482 
2483  /*
2484  * Supported Speeds
2485  */
2486  switch (pport_attr.speed_supported) {
2487  case BFA_PORT_SPEED_16GBPS:
2488  port_attr->supp_speed =
2490  break;
2491 
2492  case BFA_PORT_SPEED_10GBPS:
2493  port_attr->supp_speed =
2495  break;
2496 
2497  case BFA_PORT_SPEED_8GBPS:
2498  port_attr->supp_speed =
2500  break;
2501 
2502  case BFA_PORT_SPEED_4GBPS:
2503  port_attr->supp_speed =
2505  break;
2506 
2507  default:
2508  bfa_sm_fault(port->fcs, pport_attr.speed_supported);
2509  }
2510 
2511  /*
2512  * Current Speed
2513  */
2514  port_attr->curr_speed = cpu_to_be32(
2515  bfa_fcs_fdmi_convert_speed(pport_attr.speed));
2516 
2517  /*
2518  * Max PDU Size.
2519  */
2520  port_attr->max_frm_size = cpu_to_be32(pport_attr.pport_cfg.maxfrsize);
2521 
2522  /*
2523  * OS device Name
2524  */
2525  strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
2526  sizeof(port_attr->os_device_name));
2527 
2528  /*
2529  * Host name
2530  */
2531  strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
2532  sizeof(port_attr->host_name));
2533 
2534 }
2535 
2536 /*
2537  * Convert BFA speed to FDMI format.
2538  */
2539 u32
2541 {
2542  u32 ret;
2543 
2544  switch (pport_speed) {
2545  case BFA_PORT_SPEED_1GBPS:
2546  case BFA_PORT_SPEED_2GBPS:
2547  ret = pport_speed;
2548  break;
2549 
2550  case BFA_PORT_SPEED_4GBPS:
2551  ret = FDMI_TRANS_SPEED_4G;
2552  break;
2553 
2554  case BFA_PORT_SPEED_8GBPS:
2555  ret = FDMI_TRANS_SPEED_8G;
2556  break;
2557 
2558  case BFA_PORT_SPEED_10GBPS:
2559  ret = FDMI_TRANS_SPEED_10G;
2560  break;
2561 
2562  case BFA_PORT_SPEED_16GBPS:
2563  ret = FDMI_TRANS_SPEED_16G;
2564  break;
2565 
2566  default:
2568  }
2569  return ret;
2570 }
2571 
2572 void
2574 {
2575  struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2576 
2577  fdmi->ms = ms;
2578  if (ms->port->fcs->fdmi_enabled)
2579  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_offline);
2580  else
2581  bfa_sm_set_state(fdmi, bfa_fcs_lport_fdmi_sm_disabled);
2582 }
2583 
2584 void
2586 {
2587  struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2588 
2589  fdmi->ms = ms;
2591 }
2592 
2593 void
2595 {
2596  struct bfa_fcs_lport_fdmi_s *fdmi = &ms->fdmi;
2597 
2598  fdmi->ms = ms;
2600 }
2601 
2602 #define BFA_FCS_MS_CMD_MAX_RETRIES 2
2603 
2604 /*
2605  * forward declarations
2606  */
2607 static void bfa_fcs_lport_ms_send_plogi(void *ms_cbarg,
2608  struct bfa_fcxp_s *fcxp_alloced);
2609 static void bfa_fcs_lport_ms_timeout(void *arg);
2610 static void bfa_fcs_lport_ms_plogi_response(void *fcsarg,
2611  struct bfa_fcxp_s *fcxp,
2612  void *cbarg,
2613  bfa_status_t req_status,
2614  u32 rsp_len,
2615  u32 resid_len,
2616  struct fchs_s *rsp_fchs);
2617 
2618 static void bfa_fcs_lport_ms_send_gmal(void *ms_cbarg,
2619  struct bfa_fcxp_s *fcxp_alloced);
2620 static void bfa_fcs_lport_ms_gmal_response(void *fcsarg,
2621  struct bfa_fcxp_s *fcxp,
2622  void *cbarg,
2623  bfa_status_t req_status,
2624  u32 rsp_len,
2625  u32 resid_len,
2626  struct fchs_s *rsp_fchs);
2627 static void bfa_fcs_lport_ms_send_gfn(void *ms_cbarg,
2628  struct bfa_fcxp_s *fcxp_alloced);
2629 static void bfa_fcs_lport_ms_gfn_response(void *fcsarg,
2630  struct bfa_fcxp_s *fcxp,
2631  void *cbarg,
2632  bfa_status_t req_status,
2633  u32 rsp_len,
2634  u32 resid_len,
2635  struct fchs_s *rsp_fchs);
2636 /*
2637  * fcs_ms_sm FCS MS state machine
2638  */
2639 
2640 /*
2641  * MS State Machine events
2642  */
2651 };
2652 
2653 static void bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2654  enum port_ms_event event);
2655 static void bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2656  enum port_ms_event event);
2657 static void bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2658  enum port_ms_event event);
2659 static void bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2660  enum port_ms_event event);
2661 static void bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2662  enum port_ms_event event);
2663 static void bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2664  enum port_ms_event event);
2665 static void bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2666  enum port_ms_event event);
2667 static void bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
2668  enum port_ms_event event);
2669 static void bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
2670  enum port_ms_event event);
2671 static void bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
2672  enum port_ms_event event);
2673 static void bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2674  enum port_ms_event event);
2675 /*
2676  * Start in offline state - awaiting NS to send start.
2677  */
2678 static void
2679 bfa_fcs_lport_ms_sm_offline(struct bfa_fcs_lport_ms_s *ms,
2680  enum port_ms_event event)
2681 {
2682  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2683  bfa_trc(ms->port->fcs, event);
2684 
2685  switch (event) {
2687  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2688  bfa_fcs_lport_ms_send_plogi(ms, NULL);
2689  break;
2690 
2692  break;
2693 
2694  default:
2695  bfa_sm_fault(ms->port->fcs, event);
2696  }
2697 }
2698 
2699 static void
2700 bfa_fcs_lport_ms_sm_plogi_sending(struct bfa_fcs_lport_ms_s *ms,
2701  enum port_ms_event event)
2702 {
2703  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2704  bfa_trc(ms->port->fcs, event);
2705 
2706  switch (event) {
2707  case MSSM_EVENT_FCXP_SENT:
2708  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi);
2709  break;
2710 
2712  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2714  &ms->fcxp_wqe);
2715  break;
2716 
2717  default:
2718  bfa_sm_fault(ms->port->fcs, event);
2719  }
2720 }
2721 
2722 static void
2723 bfa_fcs_lport_ms_sm_plogi(struct bfa_fcs_lport_ms_s *ms,
2724  enum port_ms_event event)
2725 {
2726  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2727  bfa_trc(ms->port->fcs, event);
2728 
2729  switch (event) {
2730  case MSSM_EVENT_RSP_ERROR:
2731  /*
2732  * Start timer for a delayed retry
2733  */
2734  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_retry);
2735  ms->port->stats.ms_retries++;
2737  &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2739  break;
2740 
2741  case MSSM_EVENT_RSP_OK:
2742  /*
2743  * since plogi is done, now invoke MS related sub-modules
2744  */
2746 
2747  /*
2748  * if this is a Vport, go to online state.
2749  */
2750  if (ms->port->vport) {
2751  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
2752  break;
2753  }
2754 
2755  /*
2756  * For a base port we need to get the
2757  * switch's IP address.
2758  */
2759  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2760  bfa_fcs_lport_ms_send_gmal(ms, NULL);
2761  break;
2762 
2764  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2765  bfa_fcxp_discard(ms->fcxp);
2766  break;
2767 
2768  default:
2769  bfa_sm_fault(ms->port->fcs, event);
2770  }
2771 }
2772 
2773 static void
2774 bfa_fcs_lport_ms_sm_plogi_retry(struct bfa_fcs_lport_ms_s *ms,
2775  enum port_ms_event event)
2776 {
2777  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2778  bfa_trc(ms->port->fcs, event);
2779 
2780  switch (event) {
2781  case MSSM_EVENT_TIMEOUT:
2782  /*
2783  * Retry Timer Expired. Re-send
2784  */
2785  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_plogi_sending);
2786  bfa_fcs_lport_ms_send_plogi(ms, NULL);
2787  break;
2788 
2790  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2791  bfa_timer_stop(&ms->timer);
2792  break;
2793 
2794  default:
2795  bfa_sm_fault(ms->port->fcs, event);
2796  }
2797 }
2798 
2799 static void
2800 bfa_fcs_lport_ms_sm_online(struct bfa_fcs_lport_ms_s *ms,
2801  enum port_ms_event event)
2802 {
2803  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2804  bfa_trc(ms->port->fcs, event);
2805 
2806  switch (event) {
2808  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2809  break;
2810 
2812  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2813  ms->retry_cnt = 0;
2814  bfa_fcs_lport_ms_send_gfn(ms, NULL);
2815  break;
2816 
2817  default:
2818  bfa_sm_fault(ms->port->fcs, event);
2819  }
2820 }
2821 
2822 static void
2823 bfa_fcs_lport_ms_sm_gmal_sending(struct bfa_fcs_lport_ms_s *ms,
2824  enum port_ms_event event)
2825 {
2826  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2827  bfa_trc(ms->port->fcs, event);
2828 
2829  switch (event) {
2830  case MSSM_EVENT_FCXP_SENT:
2831  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal);
2832  break;
2833 
2835  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2837  &ms->fcxp_wqe);
2838  break;
2839 
2840  default:
2841  bfa_sm_fault(ms->port->fcs, event);
2842  }
2843 }
2844 
2845 static void
2846 bfa_fcs_lport_ms_sm_gmal(struct bfa_fcs_lport_ms_s *ms,
2847  enum port_ms_event event)
2848 {
2849  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2850  bfa_trc(ms->port->fcs, event);
2851 
2852  switch (event) {
2853  case MSSM_EVENT_RSP_ERROR:
2854  /*
2855  * Start timer for a delayed retry
2856  */
2857  if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
2858  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_retry);
2859  ms->port->stats.ms_retries++;
2861  &ms->timer, bfa_fcs_lport_ms_timeout, ms,
2863  } else {
2864  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2865  bfa_fcs_lport_ms_send_gfn(ms, NULL);
2866  ms->retry_cnt = 0;
2867  }
2868  break;
2869 
2870  case MSSM_EVENT_RSP_OK:
2871  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
2872  bfa_fcs_lport_ms_send_gfn(ms, NULL);
2873  break;
2874 
2876  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2877  bfa_fcxp_discard(ms->fcxp);
2878  break;
2879 
2880  default:
2881  bfa_sm_fault(ms->port->fcs, event);
2882  }
2883 }
2884 
2885 static void
2886 bfa_fcs_lport_ms_sm_gmal_retry(struct bfa_fcs_lport_ms_s *ms,
2887  enum port_ms_event event)
2888 {
2889  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
2890  bfa_trc(ms->port->fcs, event);
2891 
2892  switch (event) {
2893  case MSSM_EVENT_TIMEOUT:
2894  /*
2895  * Retry Timer Expired. Re-send
2896  */
2897  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gmal_sending);
2898  bfa_fcs_lport_ms_send_gmal(ms, NULL);
2899  break;
2900 
2902  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
2903  bfa_timer_stop(&ms->timer);
2904  break;
2905 
2906  default:
2907  bfa_sm_fault(ms->port->fcs, event);
2908  }
2909 }
2910 /*
2911  * ms_pvt MS local functions
2912  */
2913 
2914 static void
2915 bfa_fcs_lport_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2916 {
2917  struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
2918  bfa_fcs_lport_t *port = ms->port;
2919  struct fchs_s fchs;
2920  int len;
2921  struct bfa_fcxp_s *fcxp;
2922 
2923  bfa_trc(port->fcs, port->pid);
2924 
2925  fcxp = fcxp_alloced ? fcxp_alloced :
2926  bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
2927  if (!fcxp) {
2928  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
2929  bfa_fcs_lport_ms_send_gmal, ms, BFA_TRUE);
2930  return;
2931  }
2932  ms->fcxp = fcxp;
2933 
2934  len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2935  bfa_fcs_lport_get_fcid(port),
2936  port->fabric->lps->pr_nwwn);
2937 
2938  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2939  FC_CLASS_3, len, &fchs,
2940  bfa_fcs_lport_ms_gmal_response, (void *)ms,
2942 
2944 }
2945 
2946 static void
2947 bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
2948  void *cbarg, bfa_status_t req_status,
2949  u32 rsp_len, u32 resid_len,
2950  struct fchs_s *rsp_fchs)
2951 {
2952  struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
2953  bfa_fcs_lport_t *port = ms->port;
2954  struct ct_hdr_s *cthdr = NULL;
2955  struct fcgs_gmal_resp_s *gmal_resp;
2956  struct fcgs_gmal_entry_s *gmal_entry;
2957  u32 num_entries;
2958  u8 *rsp_str;
2959 
2960  bfa_trc(port->fcs, req_status);
2961  bfa_trc(port->fcs, port->port_cfg.pwwn);
2962 
2963  /*
2964  * Sanity Checks
2965  */
2966  if (req_status != BFA_STATUS_OK) {
2967  bfa_trc(port->fcs, req_status);
2969  return;
2970  }
2971 
2972  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2973  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2974 
2975  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2976  gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
2977 
2978  num_entries = be32_to_cpu(gmal_resp->ms_len);
2979  if (num_entries == 0) {
2981  return;
2982  }
2983  /*
2984  * The response could contain multiple Entries.
2985  * Entries for SNMP interface, etc.
2986  * We look for the entry with a telnet prefix.
2987  * First "http://" entry refers to IP addr
2988  */
2989 
2990  gmal_entry = (struct fcgs_gmal_entry_s *)gmal_resp->ms_ma;
2991  while (num_entries > 0) {
2992  if (strncmp(gmal_entry->prefix,
2994  sizeof(gmal_entry->prefix)) == 0) {
2995 
2996  /*
2997  * if the IP address is terminating with a '/',
2998  * remove it.
2999  * Byte 0 consists of the length of the string.
3000  */
3001  rsp_str = &(gmal_entry->prefix[0]);
3002  if (rsp_str[gmal_entry->len-1] == '/')
3003  rsp_str[gmal_entry->len-1] = 0;
3004 
3005  /* copy IP Address to fabric */
3007  gmal_entry->ip_addr,
3009  break;
3010  } else {
3011  --num_entries;
3012  ++gmal_entry;
3013  }
3014  }
3015 
3017  return;
3018  }
3019 
3020  bfa_trc(port->fcs, cthdr->reason_code);
3021  bfa_trc(port->fcs, cthdr->exp_code);
3023 }
3024 
3025 static void
3026 bfa_fcs_lport_ms_sm_gfn_sending(struct bfa_fcs_lport_ms_s *ms,
3027  enum port_ms_event event)
3028 {
3029  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3030  bfa_trc(ms->port->fcs, event);
3031 
3032  switch (event) {
3033  case MSSM_EVENT_FCXP_SENT:
3034  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn);
3035  break;
3036 
3038  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3040  &ms->fcxp_wqe);
3041  break;
3042 
3043  default:
3044  bfa_sm_fault(ms->port->fcs, event);
3045  }
3046 }
3047 
3048 static void
3049 bfa_fcs_lport_ms_sm_gfn(struct bfa_fcs_lport_ms_s *ms,
3050  enum port_ms_event event)
3051 {
3052  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3053  bfa_trc(ms->port->fcs, event);
3054 
3055  switch (event) {
3056  case MSSM_EVENT_RSP_ERROR:
3057  /*
3058  * Start timer for a delayed retry
3059  */
3060  if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
3061  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_retry);
3062  ms->port->stats.ms_retries++;
3064  &ms->timer, bfa_fcs_lport_ms_timeout, ms,
3066  } else {
3067  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
3068  ms->retry_cnt = 0;
3069  }
3070  break;
3071 
3072  case MSSM_EVENT_RSP_OK:
3073  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_online);
3074  break;
3075 
3077  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3078  bfa_fcxp_discard(ms->fcxp);
3079  break;
3080 
3081  default:
3082  bfa_sm_fault(ms->port->fcs, event);
3083  }
3084 }
3085 
3086 static void
3087 bfa_fcs_lport_ms_sm_gfn_retry(struct bfa_fcs_lport_ms_s *ms,
3088  enum port_ms_event event)
3089 {
3090  bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
3091  bfa_trc(ms->port->fcs, event);
3092 
3093  switch (event) {
3094  case MSSM_EVENT_TIMEOUT:
3095  /*
3096  * Retry Timer Expired. Re-send
3097  */
3098  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_gfn_sending);
3099  bfa_fcs_lport_ms_send_gfn(ms, NULL);
3100  break;
3101 
3103  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3104  bfa_timer_stop(&ms->timer);
3105  break;
3106 
3107  default:
3108  bfa_sm_fault(ms->port->fcs, event);
3109  }
3110 }
3111 /*
3112  * ms_pvt MS local functions
3113  */
3114 
3115 static void
3116 bfa_fcs_lport_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3117 {
3118  struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
3119  bfa_fcs_lport_t *port = ms->port;
3120  struct fchs_s fchs;
3121  int len;
3122  struct bfa_fcxp_s *fcxp;
3123 
3124  bfa_trc(port->fcs, port->pid);
3125 
3126  fcxp = fcxp_alloced ? fcxp_alloced :
3127  bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3128  if (!fcxp) {
3129  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3130  bfa_fcs_lport_ms_send_gfn, ms, BFA_TRUE);
3131  return;
3132  }
3133  ms->fcxp = fcxp;
3134 
3135  len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3136  bfa_fcs_lport_get_fcid(port),
3137  port->fabric->lps->pr_nwwn);
3138 
3139  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3140  FC_CLASS_3, len, &fchs,
3141  bfa_fcs_lport_ms_gfn_response, (void *)ms,
3143 
3145 }
3146 
3147 static void
3148 bfa_fcs_lport_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3149  void *cbarg, bfa_status_t req_status, u32 rsp_len,
3150  u32 resid_len, struct fchs_s *rsp_fchs)
3151 {
3152  struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3153  bfa_fcs_lport_t *port = ms->port;
3154  struct ct_hdr_s *cthdr = NULL;
3155  wwn_t *gfn_resp;
3156 
3157  bfa_trc(port->fcs, req_status);
3158  bfa_trc(port->fcs, port->port_cfg.pwwn);
3159 
3160  /*
3161  * Sanity Checks
3162  */
3163  if (req_status != BFA_STATUS_OK) {
3164  bfa_trc(port->fcs, req_status);
3166  return;
3167  }
3168 
3169  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
3170  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
3171 
3172  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
3173  gfn_resp = (wwn_t *)(cthdr + 1);
3174  /* check if it has actually changed */
3175  if ((memcmp((void *)&bfa_fcs_lport_get_fabric_name(port),
3176  gfn_resp, sizeof(wwn_t)) != 0)) {
3177  bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
3178  }
3180  return;
3181  }
3182 
3183  bfa_trc(port->fcs, cthdr->reason_code);
3184  bfa_trc(port->fcs, cthdr->exp_code);
3186 }
3187 
3188 /*
3189  * ms_pvt MS local functions
3190  */
3191 
3192 static void
3193 bfa_fcs_lport_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3194 {
3195  struct bfa_fcs_lport_ms_s *ms = ms_cbarg;
3196  struct bfa_fcs_lport_s *port = ms->port;
3197  struct fchs_s fchs;
3198  int len;
3199  struct bfa_fcxp_s *fcxp;
3200 
3201  bfa_trc(port->fcs, port->pid);
3202 
3203  fcxp = fcxp_alloced ? fcxp_alloced :
3205  if (!fcxp) {
3206  port->stats.ms_plogi_alloc_wait++;
3207  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
3208  bfa_fcs_lport_ms_send_plogi, ms, BFA_TRUE);
3209  return;
3210  }
3211  ms->fcxp = fcxp;
3212 
3213  len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
3215  bfa_fcs_lport_get_fcid(port), 0,
3216  port->port_cfg.pwwn, port->port_cfg.nwwn,
3217  bfa_fcport_get_maxfrsize(port->fcs->bfa),
3218  bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
3219 
3220  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3221  FC_CLASS_3, len, &fchs,
3222  bfa_fcs_lport_ms_plogi_response, (void *)ms,
3224 
3225  port->stats.ms_plogi_sent++;
3227 }
3228 
3229 static void
3230 bfa_fcs_lport_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
3231  void *cbarg, bfa_status_t req_status,
3232  u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs)
3233 {
3234  struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) cbarg;
3235  struct bfa_fcs_lport_s *port = ms->port;
3236  struct fc_els_cmd_s *els_cmd;
3237  struct fc_ls_rjt_s *ls_rjt;
3238 
3239  bfa_trc(port->fcs, req_status);
3240  bfa_trc(port->fcs, port->port_cfg.pwwn);
3241 
3242  /*
3243  * Sanity Checks
3244  */
3245  if (req_status != BFA_STATUS_OK) {
3246  port->stats.ms_plogi_rsp_err++;
3247  bfa_trc(port->fcs, req_status);
3249  return;
3250  }
3251 
3252  els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
3253 
3254  switch (els_cmd->els_code) {
3255 
3256  case FC_ELS_ACC:
3257  if (rsp_len < sizeof(struct fc_logi_s)) {
3258  bfa_trc(port->fcs, rsp_len);
3259  port->stats.ms_plogi_acc_err++;
3261  break;
3262  }
3263  port->stats.ms_plogi_accepts++;
3265  break;
3266 
3267  case FC_ELS_LS_RJT:
3268  ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3269 
3270  bfa_trc(port->fcs, ls_rjt->reason_code);
3271  bfa_trc(port->fcs, ls_rjt->reason_code_expl);
3272 
3273  port->stats.ms_rejects++;
3275  break;
3276 
3277  default:
3278  port->stats.ms_plogi_unknown_rsp++;
3279  bfa_trc(port->fcs, els_cmd->els_code);
3281  }
3282 }
3283 
3284 static void
3285 bfa_fcs_lport_ms_timeout(void *arg)
3286 {
3287  struct bfa_fcs_lport_ms_s *ms = (struct bfa_fcs_lport_ms_s *) arg;
3288 
3289  ms->port->stats.ms_timeouts++;
3291 }
3292 
3293 
3294 void
3296 {
3297  struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3298 
3299  ms->port = port;
3300  bfa_sm_set_state(ms, bfa_fcs_lport_ms_sm_offline);
3301 
3302  /*
3303  * Invoke init routines of sub modules.
3304  */
3306 }
3307 
3308 void
3310 {
3311  struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3312 
3313  ms->port = port;
3316 }
3317 
3318 void
3320 {
3321  struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3322 
3323  ms->port = port;
3325 }
3326 void
3328 {
3329  struct bfa_fcs_lport_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
3330 
3331  /* todo. Handle this only when in Online state */
3332  if (bfa_sm_cmp_state(ms, bfa_fcs_lport_ms_sm_online))
3334 }
3335 
3336 /*
3337  * @page ns_sm_info VPORT NS State Machine
3338  *
3339  * @section ns_sm_interactions VPORT NS State Machine Interactions
3340  *
3341  * @section ns_sm VPORT NS State Machine
3342  * img ns_sm.jpg
3343  */
3344 
3345 /*
3346  * forward declarations
3347  */
3348 static void bfa_fcs_lport_ns_send_plogi(void *ns_cbarg,
3349  struct bfa_fcxp_s *fcxp_alloced);
3350 static void bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg,
3351  struct bfa_fcxp_s *fcxp_alloced);
3352 static void bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg,
3353  struct bfa_fcxp_s *fcxp_alloced);
3354 static void bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg,
3355  struct bfa_fcxp_s *fcxp_alloced);
3356 static void bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg,
3357  struct bfa_fcxp_s *fcxp_alloced);
3358 static void bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg,
3359  struct bfa_fcxp_s *fcxp_alloced);
3360 static void bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg,
3361  struct bfa_fcxp_s *fcxp_alloced);
3362 static void bfa_fcs_lport_ns_timeout(void *arg);
3363 static void bfa_fcs_lport_ns_plogi_response(void *fcsarg,
3364  struct bfa_fcxp_s *fcxp,
3365  void *cbarg,
3366  bfa_status_t req_status,
3367  u32 rsp_len,
3368  u32 resid_len,
3369  struct fchs_s *rsp_fchs);
3370 static void bfa_fcs_lport_ns_rspn_id_response(void *fcsarg,
3371  struct bfa_fcxp_s *fcxp,
3372  void *cbarg,
3373  bfa_status_t req_status,
3374  u32 rsp_len,
3375  u32 resid_len,
3376  struct fchs_s *rsp_fchs);
3377 static void bfa_fcs_lport_ns_rft_id_response(void *fcsarg,
3378  struct bfa_fcxp_s *fcxp,
3379  void *cbarg,
3380  bfa_status_t req_status,
3381  u32 rsp_len,
3382  u32 resid_len,
3383  struct fchs_s *rsp_fchs);
3384 static void bfa_fcs_lport_ns_rff_id_response(void *fcsarg,
3385  struct bfa_fcxp_s *fcxp,
3386  void *cbarg,
3387  bfa_status_t req_status,
3388  u32 rsp_len,
3389  u32 resid_len,
3390  struct fchs_s *rsp_fchs);
3391 static void bfa_fcs_lport_ns_gid_ft_response(void *fcsarg,
3392  struct bfa_fcxp_s *fcxp,
3393  void *cbarg,
3394  bfa_status_t req_status,
3395  u32 rsp_len,
3396  u32 resid_len,
3397  struct fchs_s *rsp_fchs);
3398 static void bfa_fcs_lport_ns_rnn_id_response(void *fcsarg,
3399  struct bfa_fcxp_s *fcxp,
3400  void *cbarg,
3401  bfa_status_t req_status,
3402  u32 rsp_len,
3403  u32 resid_len,
3404  struct fchs_s *rsp_fchs);
3405 static void bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg,
3406  struct bfa_fcxp_s *fcxp,
3407  void *cbarg,
3408  bfa_status_t req_status,
3409  u32 rsp_len,
3410  u32 resid_len,
3411  struct fchs_s *rsp_fchs);
3412 static void bfa_fcs_lport_ns_process_gidft_pids(
3413  struct bfa_fcs_lport_s *port,
3414  u32 *pid_buf, u32 n_pids);
3415 
3416 static void bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port);
3417 /*
3418  * fcs_ns_sm FCS nameserver interface state machine
3419  */
3420 
3421 /*
3422  * VPort NS State Machine events
3423  */
3438 };
3439 
3440 static void bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3441  enum vport_ns_event event);
3442 static void bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3443  enum vport_ns_event event);
3444 static void bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3445  enum vport_ns_event event);
3446 static void bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3447  enum vport_ns_event event);
3448 static void bfa_fcs_lport_ns_sm_sending_rspn_id(
3449  struct bfa_fcs_lport_ns_s *ns,
3450  enum vport_ns_event event);
3451 static void bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3452  enum vport_ns_event event);
3453 static void bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3454  enum vport_ns_event event);
3455 static void bfa_fcs_lport_ns_sm_sending_rft_id(
3456  struct bfa_fcs_lport_ns_s *ns,
3457  enum vport_ns_event event);
3458 static void bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3459  enum vport_ns_event event);
3460 static void bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3461  enum vport_ns_event event);
3462 static void bfa_fcs_lport_ns_sm_sending_rff_id(
3463  struct bfa_fcs_lport_ns_s *ns,
3464  enum vport_ns_event event);
3465 static void bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
3466  enum vport_ns_event event);
3467 static void bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3468  enum vport_ns_event event);
3469 static void bfa_fcs_lport_ns_sm_sending_gid_ft(
3470  struct bfa_fcs_lport_ns_s *ns,
3471  enum vport_ns_event event);
3472 static void bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
3473  enum vport_ns_event event);
3474 static void bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
3475  enum vport_ns_event event);
3476 static void bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
3477  enum vport_ns_event event);
3478 static void bfa_fcs_lport_ns_sm_sending_rnn_id(
3479  struct bfa_fcs_lport_ns_s *ns,
3480  enum vport_ns_event event);
3481 static void bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns,
3482  enum vport_ns_event event);
3483 static void bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3484  enum vport_ns_event event);
3485 static void bfa_fcs_lport_ns_sm_sending_rsnn_nn(
3486  struct bfa_fcs_lport_ns_s *ns,
3487  enum vport_ns_event event);
3488 static void bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
3489  enum vport_ns_event event);
3490 static void bfa_fcs_lport_ns_sm_rsnn_nn_retry(
3491  struct bfa_fcs_lport_ns_s *ns,
3492  enum vport_ns_event event);
3493 /*
3494  * Start in offline state - awaiting linkup
3495  */
3496 static void
3497 bfa_fcs_lport_ns_sm_offline(struct bfa_fcs_lport_ns_s *ns,
3498  enum vport_ns_event event)
3499 {
3500  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3501  bfa_trc(ns->port->fcs, event);
3502 
3503  switch (event) {
3505  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3506  bfa_fcs_lport_ns_send_plogi(ns, NULL);
3507  break;
3508 
3510  break;
3511 
3512  default:
3513  bfa_sm_fault(ns->port->fcs, event);
3514  }
3515 }
3516 
3517 static void
3518 bfa_fcs_lport_ns_sm_plogi_sending(struct bfa_fcs_lport_ns_s *ns,
3519  enum vport_ns_event event)
3520 {
3521  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3522  bfa_trc(ns->port->fcs, event);
3523 
3524  switch (event) {
3525  case NSSM_EVENT_PLOGI_SENT:
3526  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi);
3527  break;
3528 
3530  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3532  &ns->fcxp_wqe);
3533  break;
3534 
3535  default:
3536  bfa_sm_fault(ns->port->fcs, event);
3537  }
3538 }
3539 
3540 static void
3541 bfa_fcs_lport_ns_sm_plogi(struct bfa_fcs_lport_ns_s *ns,
3542  enum vport_ns_event event)
3543 {
3544  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3545  bfa_trc(ns->port->fcs, event);
3546 
3547  switch (event) {
3548  case NSSM_EVENT_RSP_ERROR:
3549  /*
3550  * Start timer for a delayed retry
3551  */
3552  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_retry);
3553  ns->port->stats.ns_retries++;
3555  &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3557  break;
3558 
3559  case NSSM_EVENT_RSP_OK:
3560  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id);
3561  ns->num_rnnid_retries = 0;
3562  bfa_fcs_lport_ns_send_rnn_id(ns, NULL);
3563  break;
3564 
3566  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3567  bfa_fcxp_discard(ns->fcxp);
3568  break;
3569 
3570  default:
3571  bfa_sm_fault(ns->port->fcs, event);
3572  }
3573 }
3574 
3575 static void
3576 bfa_fcs_lport_ns_sm_plogi_retry(struct bfa_fcs_lport_ns_s *ns,
3577  enum vport_ns_event event)
3578 {
3579  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3580  bfa_trc(ns->port->fcs, event);
3581 
3582  switch (event) {
3583  case NSSM_EVENT_TIMEOUT:
3584  /*
3585  * Retry Timer Expired. Re-send
3586  */
3587  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_plogi_sending);
3588  bfa_fcs_lport_ns_send_plogi(ns, NULL);
3589  break;
3590 
3592  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3593  bfa_timer_stop(&ns->timer);
3594  break;
3595 
3596  default:
3597  bfa_sm_fault(ns->port->fcs, event);
3598  }
3599 }
3600 
3601 static void
3602 bfa_fcs_lport_ns_sm_sending_rnn_id(struct bfa_fcs_lport_ns_s *ns,
3603  enum vport_ns_event event)
3604 {
3605  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3606  bfa_trc(ns->port->fcs, event);
3607 
3608  switch (event) {
3609  case NSSM_EVENT_RNNID_SENT:
3610  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id);
3611  break;
3612 
3614  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3616  &ns->fcxp_wqe);
3617  break;
3618  default:
3619  bfa_sm_fault(ns->port->fcs, event);
3620  }
3621 }
3622 
3623 static void
3624 bfa_fcs_lport_ns_sm_rnn_id(struct bfa_fcs_lport_ns_s *ns,
3625  enum vport_ns_event event)
3626 {
3627  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3628  bfa_trc(ns->port->fcs, event);
3629 
3630  switch (event) {
3631  case NSSM_EVENT_RSP_OK:
3632  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn);
3633  ns->num_rnnid_retries = 0;
3634  ns->num_rsnn_nn_retries = 0;
3635  bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL);
3636  break;
3637 
3638  case NSSM_EVENT_RSP_ERROR:
3640  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rnn_id_retry);
3641  ns->port->stats.ns_retries++;
3642  ns->num_rnnid_retries++;
3644  &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3646  } else {
3647  bfa_sm_set_state(ns,
3648  bfa_fcs_lport_ns_sm_sending_rspn_id);
3649  bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3650  }
3651  break;
3652 
3654  bfa_fcxp_discard(ns->fcxp);
3655  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3656  break;
3657 
3658  default:
3659  bfa_sm_fault(ns->port->fcs, event);
3660  }
3661 }
3662 
3663 static void
3664 bfa_fcs_lport_ns_sm_rnn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3665  enum vport_ns_event event)
3666 {
3667  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3668  bfa_trc(ns->port->fcs, event);
3669 
3670  switch (event) {
3671  case NSSM_EVENT_TIMEOUT:
3672  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rnn_id);
3673  bfa_fcs_lport_ns_send_rnn_id(ns, NULL);
3674  break;
3675 
3677  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3678  bfa_timer_stop(&ns->timer);
3679  break;
3680 
3681  default:
3682  bfa_sm_fault(ns->port->fcs, event);
3683  }
3684 }
3685 
3686 static void
3687 bfa_fcs_lport_ns_sm_sending_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
3688  enum vport_ns_event event)
3689 {
3690  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3691  bfa_trc(ns->port->fcs, event);
3692 
3693  switch (event) {
3695  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn);
3696  break;
3697 
3699  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3701  &ns->fcxp_wqe);
3702  break;
3703 
3704  default:
3705  bfa_sm_fault(ns->port->fcs, event);
3706  }
3707 }
3708 
3709 static void
3710 bfa_fcs_lport_ns_sm_rsnn_nn(struct bfa_fcs_lport_ns_s *ns,
3711  enum vport_ns_event event)
3712 {
3713  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3714  bfa_trc(ns->port->fcs, event);
3715 
3716  switch (event) {
3717  case NSSM_EVENT_RSP_OK:
3718  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3719  ns->num_rsnn_nn_retries = 0;
3720  bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3721  break;
3722 
3723  case NSSM_EVENT_RSP_ERROR:
3725  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rsnn_nn_retry);
3726  ns->port->stats.ns_retries++;
3727  ns->num_rsnn_nn_retries++;
3729  &ns->timer, bfa_fcs_lport_ns_timeout,
3730  ns, BFA_FCS_RETRY_TIMEOUT);
3731  } else {
3732  bfa_sm_set_state(ns,
3733  bfa_fcs_lport_ns_sm_sending_rspn_id);
3734  bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3735  }
3736  break;
3737 
3739  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3740  bfa_fcxp_discard(ns->fcxp);
3741  break;
3742 
3743  default:
3744  bfa_sm_fault(ns->port->fcs, event);
3745  }
3746 }
3747 
3748 static void
3749 bfa_fcs_lport_ns_sm_rsnn_nn_retry(struct bfa_fcs_lport_ns_s *ns,
3750  enum vport_ns_event event)
3751 {
3752  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3753  bfa_trc(ns->port->fcs, event);
3754 
3755  switch (event) {
3756  case NSSM_EVENT_TIMEOUT:
3757  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rsnn_nn);
3758  bfa_fcs_lport_ns_send_rsnn_nn(ns, NULL);
3759  break;
3760 
3762  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3763  bfa_timer_stop(&ns->timer);
3764  break;
3765 
3766  default:
3767  bfa_sm_fault(ns->port->fcs, event);
3768  }
3769 }
3770 
3771 static void
3772 bfa_fcs_lport_ns_sm_sending_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3773  enum vport_ns_event event)
3774 {
3775  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3776  bfa_trc(ns->port->fcs, event);
3777 
3778  switch (event) {
3780  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id);
3781  break;
3782 
3784  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3786  &ns->fcxp_wqe);
3787  break;
3788 
3789  default:
3790  bfa_sm_fault(ns->port->fcs, event);
3791  }
3792 }
3793 
3794 static void
3795 bfa_fcs_lport_ns_sm_rspn_id(struct bfa_fcs_lport_ns_s *ns,
3796  enum vport_ns_event event)
3797 {
3798  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3799  bfa_trc(ns->port->fcs, event);
3800 
3801  switch (event) {
3802  case NSSM_EVENT_RSP_ERROR:
3803  /*
3804  * Start timer for a delayed retry
3805  */
3806  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry);
3807  ns->port->stats.ns_retries++;
3809  &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3811  break;
3812 
3813  case NSSM_EVENT_RSP_OK:
3814  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
3815  bfa_fcs_lport_ns_send_rft_id(ns, NULL);
3816  break;
3817 
3819  bfa_fcxp_discard(ns->fcxp);
3820  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3821  break;
3822 
3823  default:
3824  bfa_sm_fault(ns->port->fcs, event);
3825  }
3826 }
3827 
3828 static void
3829 bfa_fcs_lport_ns_sm_rspn_id_retry(struct bfa_fcs_lport_ns_s *ns,
3830  enum vport_ns_event event)
3831 {
3832  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3833  bfa_trc(ns->port->fcs, event);
3834 
3835  switch (event) {
3836  case NSSM_EVENT_TIMEOUT:
3837  /*
3838  * Retry Timer Expired. Re-send
3839  */
3840  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rspn_id);
3841  bfa_fcs_lport_ns_send_rspn_id(ns, NULL);
3842  break;
3843 
3845  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3846  bfa_timer_stop(&ns->timer);
3847  break;
3848 
3849  default:
3850  bfa_sm_fault(ns->port->fcs, event);
3851  }
3852 }
3853 
3854 static void
3855 bfa_fcs_lport_ns_sm_sending_rft_id(struct bfa_fcs_lport_ns_s *ns,
3856  enum vport_ns_event event)
3857 {
3858  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3859  bfa_trc(ns->port->fcs, event);
3860 
3861  switch (event) {
3862  case NSSM_EVENT_RFTID_SENT:
3863  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id);
3864  break;
3865 
3867  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3869  &ns->fcxp_wqe);
3870  break;
3871 
3872  default:
3873  bfa_sm_fault(ns->port->fcs, event);
3874  }
3875 }
3876 
3877 static void
3878 bfa_fcs_lport_ns_sm_rft_id(struct bfa_fcs_lport_ns_s *ns,
3879  enum vport_ns_event event)
3880 {
3881  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3882  bfa_trc(ns->port->fcs, event);
3883 
3884  switch (event) {
3885  case NSSM_EVENT_RSP_OK:
3886  /* Now move to register FC4 Features */
3887  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
3888  bfa_fcs_lport_ns_send_rff_id(ns, NULL);
3889  break;
3890 
3891  case NSSM_EVENT_RSP_ERROR:
3892  /*
3893  * Start timer for a delayed retry
3894  */
3895  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rft_id_retry);
3896  ns->port->stats.ns_retries++;
3898  &ns->timer, bfa_fcs_lport_ns_timeout, ns,
3900  break;
3901 
3903  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3904  bfa_fcxp_discard(ns->fcxp);
3905  break;
3906 
3907  default:
3908  bfa_sm_fault(ns->port->fcs, event);
3909  }
3910 }
3911 
3912 static void
3913 bfa_fcs_lport_ns_sm_rft_id_retry(struct bfa_fcs_lport_ns_s *ns,
3914  enum vport_ns_event event)
3915 {
3916  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3917  bfa_trc(ns->port->fcs, event);
3918 
3919  switch (event) {
3920  case NSSM_EVENT_TIMEOUT:
3921  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rft_id);
3922  bfa_fcs_lport_ns_send_rft_id(ns, NULL);
3923  break;
3924 
3926  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3927  bfa_timer_stop(&ns->timer);
3928  break;
3929 
3930  default:
3931  bfa_sm_fault(ns->port->fcs, event);
3932  }
3933 }
3934 
3935 static void
3936 bfa_fcs_lport_ns_sm_sending_rff_id(struct bfa_fcs_lport_ns_s *ns,
3937  enum vport_ns_event event)
3938 {
3939  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3940  bfa_trc(ns->port->fcs, event);
3941 
3942  switch (event) {
3943  case NSSM_EVENT_RFFID_SENT:
3944  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id);
3945  break;
3946 
3948  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
3950  &ns->fcxp_wqe);
3951  break;
3952 
3953  default:
3954  bfa_sm_fault(ns->port->fcs, event);
3955  }
3956 }
3957 
3958 static void
3959 bfa_fcs_lport_ns_sm_rff_id(struct bfa_fcs_lport_ns_s *ns,
3960  enum vport_ns_event event)
3961 {
3962  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
3963  bfa_trc(ns->port->fcs, event);
3964 
3965  switch (event) {
3966  case NSSM_EVENT_RSP_OK:
3967 
3968  /*
3969  * If min cfg mode is enabled, we donot initiate rport
3970  * discovery with the fabric. Instead, we will retrieve the
3971  * boot targets from HAL/FW.
3972  */
3973  if (__fcs_min_cfg(ns->port->fcs)) {
3974  bfa_fcs_lport_ns_boot_target_disc(ns->port);
3975  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
3976  return;
3977  }
3978 
3979  /*
3980  * If the port role is Initiator Mode issue NS query.
3981  * If it is Target Mode, skip this and go to online.
3982  */
3984  bfa_sm_set_state(ns,
3985  bfa_fcs_lport_ns_sm_sending_gid_ft);
3986  bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
3987  }
3988  /*
3989  * kick off mgmt srvr state machine
3990  */
3992  break;
3993 
3994  case NSSM_EVENT_RSP_ERROR:
3995  /*
3996  * Start timer for a delayed retry
3997  */
3998  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_rff_id_retry);
3999  ns->port->stats.ns_retries++;
4001  &ns->timer, bfa_fcs_lport_ns_timeout, ns,
4003  break;
4004 
4006  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4007  bfa_fcxp_discard(ns->fcxp);
4008  break;
4009 
4010  default:
4011  bfa_sm_fault(ns->port->fcs, event);
4012  }
4013 }
4014 
4015 static void
4016 bfa_fcs_lport_ns_sm_rff_id_retry(struct bfa_fcs_lport_ns_s *ns,
4017  enum vport_ns_event event)
4018 {
4019  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4020  bfa_trc(ns->port->fcs, event);
4021 
4022  switch (event) {
4023  case NSSM_EVENT_TIMEOUT:
4024  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_rff_id);
4025  bfa_fcs_lport_ns_send_rff_id(ns, NULL);
4026  break;
4027 
4029  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4030  bfa_timer_stop(&ns->timer);
4031  break;
4032 
4033  default:
4034  bfa_sm_fault(ns->port->fcs, event);
4035  }
4036 }
4037 static void
4038 bfa_fcs_lport_ns_sm_sending_gid_ft(struct bfa_fcs_lport_ns_s *ns,
4039  enum vport_ns_event event)
4040 {
4041  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4042  bfa_trc(ns->port->fcs, event);
4043 
4044  switch (event) {
4045  case NSSM_EVENT_GIDFT_SENT:
4046  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft);
4047  break;
4048 
4050  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4052  &ns->fcxp_wqe);
4053  break;
4054 
4055  default:
4056  bfa_sm_fault(ns->port->fcs, event);
4057  }
4058 }
4059 
4060 static void
4061 bfa_fcs_lport_ns_sm_gid_ft(struct bfa_fcs_lport_ns_s *ns,
4062  enum vport_ns_event event)
4063 {
4064  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4065  bfa_trc(ns->port->fcs, event);
4066 
4067  switch (event) {
4068  case NSSM_EVENT_RSP_OK:
4069  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_online);
4070  break;
4071 
4072  case NSSM_EVENT_RSP_ERROR:
4073  /*
4074  * TBD: for certain reject codes, we don't need to retry
4075  */
4076  /*
4077  * Start timer for a delayed retry
4078  */
4079  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_gid_ft_retry);
4080  ns->port->stats.ns_retries++;
4082  &ns->timer, bfa_fcs_lport_ns_timeout, ns,
4084  break;
4085 
4087  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4088  bfa_fcxp_discard(ns->fcxp);
4089  break;
4090 
4091  case NSSM_EVENT_NS_QUERY:
4092  break;
4093 
4094  default:
4095  bfa_sm_fault(ns->port->fcs, event);
4096  }
4097 }
4098 
4099 static void
4100 bfa_fcs_lport_ns_sm_gid_ft_retry(struct bfa_fcs_lport_ns_s *ns,
4101  enum vport_ns_event event)
4102 {
4103  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4104  bfa_trc(ns->port->fcs, event);
4105 
4106  switch (event) {
4107  case NSSM_EVENT_TIMEOUT:
4108  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_sending_gid_ft);
4109  bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
4110  break;
4111 
4113  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4114  bfa_timer_stop(&ns->timer);
4115  break;
4116 
4117  default:
4118  bfa_sm_fault(ns->port->fcs, event);
4119  }
4120 }
4121 
4122 static void
4123 bfa_fcs_lport_ns_sm_online(struct bfa_fcs_lport_ns_s *ns,
4124  enum vport_ns_event event)
4125 {
4126  bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
4127  bfa_trc(ns->port->fcs, event);
4128 
4129  switch (event) {
4131  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4132  break;
4133 
4134  case NSSM_EVENT_NS_QUERY:
4135  /*
4136  * If the port role is Initiator Mode issue NS query.
4137  * If it is Target Mode, skip this and go to online.
4138  */
4140  bfa_sm_set_state(ns,
4141  bfa_fcs_lport_ns_sm_sending_gid_ft);
4142  bfa_fcs_lport_ns_send_gid_ft(ns, NULL);
4143  };
4144  break;
4145 
4146  default:
4147  bfa_sm_fault(ns->port->fcs, event);
4148  }
4149 }
4150 
4151 
4152 
4153 /*
4154  * ns_pvt Nameserver local functions
4155  */
4156 
4157 static void
4158 bfa_fcs_lport_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4159 {
4160  struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4161  struct bfa_fcs_lport_s *port = ns->port;
4162  struct fchs_s fchs;
4163  int len;
4164  struct bfa_fcxp_s *fcxp;
4165 
4166  bfa_trc(port->fcs, port->pid);
4167 
4168  fcxp = fcxp_alloced ? fcxp_alloced :
4170  if (!fcxp) {
4171  port->stats.ns_plogi_alloc_wait++;
4172  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4173  bfa_fcs_lport_ns_send_plogi, ns, BFA_TRUE);
4174  return;
4175  }
4176  ns->fcxp = fcxp;
4177 
4178  len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4180  bfa_fcs_lport_get_fcid(port), 0,
4181  port->port_cfg.pwwn, port->port_cfg.nwwn,
4182  bfa_fcport_get_maxfrsize(port->fcs->bfa),
4183  bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
4184 
4185  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4186  FC_CLASS_3, len, &fchs,
4187  bfa_fcs_lport_ns_plogi_response, (void *)ns,
4189  port->stats.ns_plogi_sent++;
4190 
4192 }
4193 
4194 static void
4195 bfa_fcs_lport_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4196  void *cbarg, bfa_status_t req_status, u32 rsp_len,
4197  u32 resid_len, struct fchs_s *rsp_fchs)
4198 {
4199  struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4200  struct bfa_fcs_lport_s *port = ns->port;
4201  /* struct fc_logi_s *plogi_resp; */
4202  struct fc_els_cmd_s *els_cmd;
4203  struct fc_ls_rjt_s *ls_rjt;
4204 
4205  bfa_trc(port->fcs, req_status);
4206  bfa_trc(port->fcs, port->port_cfg.pwwn);
4207 
4208  /*
4209  * Sanity Checks
4210  */
4211  if (req_status != BFA_STATUS_OK) {
4212  bfa_trc(port->fcs, req_status);
4213  port->stats.ns_plogi_rsp_err++;
4215  return;
4216  }
4217 
4218  els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
4219 
4220  switch (els_cmd->els_code) {
4221 
4222  case FC_ELS_ACC:
4223  if (rsp_len < sizeof(struct fc_logi_s)) {
4224  bfa_trc(port->fcs, rsp_len);
4225  port->stats.ns_plogi_acc_err++;
4227  break;
4228  }
4229  port->stats.ns_plogi_accepts++;
4231  break;
4232 
4233  case FC_ELS_LS_RJT:
4234  ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
4235 
4236  bfa_trc(port->fcs, ls_rjt->reason_code);
4237  bfa_trc(port->fcs, ls_rjt->reason_code_expl);
4238 
4239  port->stats.ns_rejects++;
4240 
4242  break;
4243 
4244  default:
4245  port->stats.ns_plogi_unknown_rsp++;
4246  bfa_trc(port->fcs, els_cmd->els_code);
4248  }
4249 }
4250 
4251 /*
4252  * Register node name for port_id
4253  */
4254 static void
4255 bfa_fcs_lport_ns_send_rnn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4256 {
4257  struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4258  struct bfa_fcs_lport_s *port = ns->port;
4259  struct fchs_s fchs;
4260  int len;
4261  struct bfa_fcxp_s *fcxp;
4262 
4263  bfa_trc(port->fcs, port->port_cfg.pwwn);
4264 
4265  fcxp = fcxp_alloced ? fcxp_alloced :
4267  if (!fcxp) {
4268  port->stats.ns_rnnid_alloc_wait++;
4269  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4270  bfa_fcs_lport_ns_send_rnn_id, ns, BFA_TRUE);
4271  return;
4272  }
4273 
4274  ns->fcxp = fcxp;
4275 
4276  len = fc_rnnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4277  bfa_fcs_lport_get_fcid(port),
4278  bfa_fcs_lport_get_fcid(port),
4279  bfa_fcs_lport_get_nwwn(port));
4280 
4281  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4282  FC_CLASS_3, len, &fchs,
4283  bfa_fcs_lport_ns_rnn_id_response, (void *)ns,
4285 
4286  port->stats.ns_rnnid_sent++;
4288 }
4289 
4290 static void
4291 bfa_fcs_lport_ns_rnn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4292  void *cbarg, bfa_status_t req_status,
4293  u32 rsp_len, u32 resid_len,
4294  struct fchs_s *rsp_fchs)
4295 
4296 {
4297  struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4298  struct bfa_fcs_lport_s *port = ns->port;
4299  struct ct_hdr_s *cthdr = NULL;
4300 
4301  bfa_trc(port->fcs, port->port_cfg.pwwn);
4302 
4303  /*
4304  * Sanity Checks
4305  */
4306  if (req_status != BFA_STATUS_OK) {
4307  bfa_trc(port->fcs, req_status);
4308  port->stats.ns_rnnid_rsp_err++;
4310  return;
4311  }
4312 
4313  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4314  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4315 
4316  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4317  port->stats.ns_rnnid_accepts++;
4319  return;
4320  }
4321 
4322  port->stats.ns_rnnid_rejects++;
4323  bfa_trc(port->fcs, cthdr->reason_code);
4324  bfa_trc(port->fcs, cthdr->exp_code);
4326 }
4327 
4328 /*
4329  * Register the symbolic node name for a given node name.
4330  */
4331 static void
4332 bfa_fcs_lport_ns_send_rsnn_nn(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4333 {
4334  struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4335  struct bfa_fcs_lport_s *port = ns->port;
4336  struct fchs_s fchs;
4337  int len;
4338  struct bfa_fcxp_s *fcxp;
4339  u8 *nsymbl;
4340 
4341  bfa_trc(port->fcs, port->port_cfg.pwwn);
4342 
4343  fcxp = fcxp_alloced ? fcxp_alloced :
4345  if (!fcxp) {
4346  port->stats.ns_rsnn_nn_alloc_wait++;
4347  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4348  bfa_fcs_lport_ns_send_rsnn_nn, ns, BFA_TRUE);
4349  return;
4350  }
4351  ns->fcxp = fcxp;
4352 
4353  nsymbl = (u8 *) &(bfa_fcs_lport_get_nsym_name(
4354  bfa_fcs_get_base_port(port->fcs)));
4355 
4356  len = fc_rsnn_nn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4357  bfa_fcs_lport_get_fcid(port),
4358  bfa_fcs_lport_get_nwwn(port), nsymbl);
4359 
4360  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4361  FC_CLASS_3, len, &fchs,
4362  bfa_fcs_lport_ns_rsnn_nn_response, (void *)ns,
4364 
4365  port->stats.ns_rsnn_nn_sent++;
4366 
4368 }
4369 
4370 static void
4371 bfa_fcs_lport_ns_rsnn_nn_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4372  void *cbarg, bfa_status_t req_status,
4373  u32 rsp_len, u32 resid_len,
4374  struct fchs_s *rsp_fchs)
4375 {
4376  struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4377  struct bfa_fcs_lport_s *port = ns->port;
4378  struct ct_hdr_s *cthdr = NULL;
4379 
4380  bfa_trc(port->fcs, port->port_cfg.pwwn);
4381 
4382  /*
4383  * Sanity Checks
4384  */
4385  if (req_status != BFA_STATUS_OK) {
4386  bfa_trc(port->fcs, req_status);
4387  port->stats.ns_rsnn_nn_rsp_err++;
4389  return;
4390  }
4391 
4392  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4393  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4394 
4395  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4396  port->stats.ns_rsnn_nn_accepts++;
4398  return;
4399  }
4400 
4401  port->stats.ns_rsnn_nn_rejects++;
4402  bfa_trc(port->fcs, cthdr->reason_code);
4403  bfa_trc(port->fcs, cthdr->exp_code);
4405 }
4406 
4407 /*
4408  * Register the symbolic port name.
4409  */
4410 static void
4411 bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4412 {
4413  struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4414  struct bfa_fcs_lport_s *port = ns->port;
4415  struct fchs_s fchs;
4416  int len;
4417  struct bfa_fcxp_s *fcxp;
4418  u8 symbl[256];
4419  u8 *psymbl = &symbl[0];
4420 
4421  memset(symbl, 0, sizeof(symbl));
4422 
4423  bfa_trc(port->fcs, port->port_cfg.pwwn);
4424 
4425  fcxp = fcxp_alloced ? fcxp_alloced :
4427  if (!fcxp) {
4428  port->stats.ns_rspnid_alloc_wait++;
4429  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4430  bfa_fcs_lport_ns_send_rspn_id, ns, BFA_TRUE);
4431  return;
4432  }
4433  ns->fcxp = fcxp;
4434 
4435  /*
4436  * for V-Port, form a Port Symbolic Name
4437  */
4438  if (port->vport) {
4439  /*
4440  * For Vports, we append the vport's port symbolic name
4441  * to that of the base port.
4442  */
4443 
4444  strncpy((char *)psymbl,
4445  (char *) &
4447  (bfa_fcs_get_base_port(port->fcs))),
4448  strlen((char *) &
4450  (port->fcs))));
4451 
4452  /* Ensure we have a null terminating string. */
4453  ((char *)psymbl)[strlen((char *) &
4455  (port->fcs)))] = 0;
4456  strncat((char *)psymbl,
4457  (char *) &(bfa_fcs_lport_get_psym_name(port)),
4458  strlen((char *) &bfa_fcs_lport_get_psym_name(port)));
4459  } else {
4460  psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port));
4461  }
4462 
4463  len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4464  bfa_fcs_lport_get_fcid(port), 0, psymbl);
4465 
4466  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4467  FC_CLASS_3, len, &fchs,
4468  bfa_fcs_lport_ns_rspn_id_response, (void *)ns,
4470 
4471  port->stats.ns_rspnid_sent++;
4472 
4474 }
4475 
4476 static void
4477 bfa_fcs_lport_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4478  void *cbarg, bfa_status_t req_status,
4479  u32 rsp_len, u32 resid_len,
4480  struct fchs_s *rsp_fchs)
4481 {
4482  struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4483  struct bfa_fcs_lport_s *port = ns->port;
4484  struct ct_hdr_s *cthdr = NULL;
4485 
4486  bfa_trc(port->fcs, port->port_cfg.pwwn);
4487 
4488  /*
4489  * Sanity Checks
4490  */
4491  if (req_status != BFA_STATUS_OK) {
4492  bfa_trc(port->fcs, req_status);
4493  port->stats.ns_rspnid_rsp_err++;
4495  return;
4496  }
4497 
4498  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4499  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4500 
4501  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4502  port->stats.ns_rspnid_accepts++;
4504  return;
4505  }
4506 
4507  port->stats.ns_rspnid_rejects++;
4508  bfa_trc(port->fcs, cthdr->reason_code);
4509  bfa_trc(port->fcs, cthdr->exp_code);
4511 }
4512 
4513 /*
4514  * Register FC4-Types
4515  */
4516 static void
4517 bfa_fcs_lport_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4518 {
4519  struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4520  struct bfa_fcs_lport_s *port = ns->port;
4521  struct fchs_s fchs;
4522  int len;
4523  struct bfa_fcxp_s *fcxp;
4524 
4525  bfa_trc(port->fcs, port->port_cfg.pwwn);
4526 
4527  fcxp = fcxp_alloced ? fcxp_alloced :
4529  if (!fcxp) {
4530  port->stats.ns_rftid_alloc_wait++;
4531  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4532  bfa_fcs_lport_ns_send_rft_id, ns, BFA_TRUE);
4533  return;
4534  }
4535  ns->fcxp = fcxp;
4536 
4537  len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4538  bfa_fcs_lport_get_fcid(port), 0, port->port_cfg.roles);
4539 
4540  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4541  FC_CLASS_3, len, &fchs,
4542  bfa_fcs_lport_ns_rft_id_response, (void *)ns,
4544 
4545  port->stats.ns_rftid_sent++;
4547 }
4548 
4549 static void
4550 bfa_fcs_lport_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4551  void *cbarg, bfa_status_t req_status,
4552  u32 rsp_len, u32 resid_len,
4553  struct fchs_s *rsp_fchs)
4554 {
4555  struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4556  struct bfa_fcs_lport_s *port = ns->port;
4557  struct ct_hdr_s *cthdr = NULL;
4558 
4559  bfa_trc(port->fcs, port->port_cfg.pwwn);
4560 
4561  /*
4562  * Sanity Checks
4563  */
4564  if (req_status != BFA_STATUS_OK) {
4565  bfa_trc(port->fcs, req_status);
4566  port->stats.ns_rftid_rsp_err++;
4568  return;
4569  }
4570 
4571  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4572  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4573 
4574  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4575  port->stats.ns_rftid_accepts++;
4577  return;
4578  }
4579 
4580  port->stats.ns_rftid_rejects++;
4581  bfa_trc(port->fcs, cthdr->reason_code);
4582  bfa_trc(port->fcs, cthdr->exp_code);
4584 }
4585 
4586 /*
4587  * Register FC4-Features : Should be done after RFT_ID
4588  */
4589 static void
4590 bfa_fcs_lport_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4591 {
4592  struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4593  struct bfa_fcs_lport_s *port = ns->port;
4594  struct fchs_s fchs;
4595  int len;
4596  struct bfa_fcxp_s *fcxp;
4597  u8 fc4_ftrs = 0;
4598 
4599  bfa_trc(port->fcs, port->port_cfg.pwwn);
4600 
4601  fcxp = fcxp_alloced ? fcxp_alloced :
4603  if (!fcxp) {
4604  port->stats.ns_rffid_alloc_wait++;
4605  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4606  bfa_fcs_lport_ns_send_rff_id, ns, BFA_TRUE);
4607  return;
4608  }
4609  ns->fcxp = fcxp;
4610 
4613 
4614  len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4615  bfa_fcs_lport_get_fcid(port), 0,
4616  FC_TYPE_FCP, fc4_ftrs);
4617 
4618  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4619  FC_CLASS_3, len, &fchs,
4620  bfa_fcs_lport_ns_rff_id_response, (void *)ns,
4622 
4623  port->stats.ns_rffid_sent++;
4625 }
4626 
4627 static void
4628 bfa_fcs_lport_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4629  void *cbarg, bfa_status_t req_status,
4630  u32 rsp_len, u32 resid_len,
4631  struct fchs_s *rsp_fchs)
4632 {
4633  struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4634  struct bfa_fcs_lport_s *port = ns->port;
4635  struct ct_hdr_s *cthdr = NULL;
4636 
4637  bfa_trc(port->fcs, port->port_cfg.pwwn);
4638 
4639  /*
4640  * Sanity Checks
4641  */
4642  if (req_status != BFA_STATUS_OK) {
4643  bfa_trc(port->fcs, req_status);
4644  port->stats.ns_rffid_rsp_err++;
4646  return;
4647  }
4648 
4649  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4650  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4651 
4652  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
4653  port->stats.ns_rffid_accepts++;
4655  return;
4656  }
4657 
4658  port->stats.ns_rffid_rejects++;
4659  bfa_trc(port->fcs, cthdr->reason_code);
4660  bfa_trc(port->fcs, cthdr->exp_code);
4661 
4662  if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
4663  /* if this command is not supported, we don't retry */
4665  } else
4667 }
4668 /*
4669  * Query Fabric for FC4-Types Devices.
4670  *
4671 * TBD : Need to use a local (FCS private) response buffer, since the response
4672  * can be larger than 2K.
4673  */
4674 static void
4675 bfa_fcs_lport_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
4676 {
4677  struct bfa_fcs_lport_ns_s *ns = ns_cbarg;
4678  struct bfa_fcs_lport_s *port = ns->port;
4679  struct fchs_s fchs;
4680  int len;
4681  struct bfa_fcxp_s *fcxp;
4682 
4683  bfa_trc(port->fcs, port->pid);
4684 
4685  fcxp = fcxp_alloced ? fcxp_alloced :
4687  if (!fcxp) {
4688  port->stats.ns_gidft_alloc_wait++;
4689  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4690  bfa_fcs_lport_ns_send_gid_ft, ns, BFA_TRUE);
4691  return;
4692  }
4693  ns->fcxp = fcxp;
4694 
4695  /*
4696  * This query is only initiated for FCP initiator mode.
4697  */
4698  len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4699  ns->port->pid, FC_TYPE_FCP);
4700 
4701  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
4702  FC_CLASS_3, len, &fchs,
4703  bfa_fcs_lport_ns_gid_ft_response, (void *)ns,
4704  bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_FCCT_TOV);
4705 
4706  port->stats.ns_gidft_sent++;
4707 
4709 }
4710 
4711 static void
4712 bfa_fcs_lport_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
4713  void *cbarg, bfa_status_t req_status,
4714  u32 rsp_len, u32 resid_len,
4715  struct fchs_s *rsp_fchs)
4716 {
4717  struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) cbarg;
4718  struct bfa_fcs_lport_s *port = ns->port;
4719  struct ct_hdr_s *cthdr = NULL;
4720  u32 n_pids;
4721 
4722  bfa_trc(port->fcs, port->port_cfg.pwwn);
4723 
4724  /*
4725  * Sanity Checks
4726  */
4727  if (req_status != BFA_STATUS_OK) {
4728  bfa_trc(port->fcs, req_status);
4729  port->stats.ns_gidft_rsp_err++;
4731  return;
4732  }
4733 
4734  if (resid_len != 0) {
4735  /*
4736  * TBD : we will need to allocate a larger buffer & retry the
4737  * command
4738  */
4739  bfa_trc(port->fcs, rsp_len);
4740  bfa_trc(port->fcs, resid_len);
4741  return;
4742  }
4743 
4744  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
4745  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
4746 
4747  switch (cthdr->cmd_rsp_code) {
4748 
4749  case CT_RSP_ACCEPT:
4750 
4751  port->stats.ns_gidft_accepts++;
4752  n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
4753  bfa_trc(port->fcs, n_pids);
4754  bfa_fcs_lport_ns_process_gidft_pids(port,
4755  (u32 *) (cthdr + 1),
4756  n_pids);
4758  break;
4759 
4760  case CT_RSP_REJECT:
4761 
4762  /*
4763  * Check the reason code & explanation.
4764  * There may not have been any FC4 devices in the fabric
4765  */
4766  port->stats.ns_gidft_rejects++;
4767  bfa_trc(port->fcs, cthdr->reason_code);
4768  bfa_trc(port->fcs, cthdr->exp_code);
4769 
4770  if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
4771  && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
4772 
4774  } else {
4775  /*
4776  * for all other errors, retry
4777  */
4779  }
4780  break;
4781 
4782  default:
4783  port->stats.ns_gidft_unknown_rsp++;
4784  bfa_trc(port->fcs, cthdr->cmd_rsp_code);
4786  }
4787 }
4788 
4789 /*
4790  * This routine will be called by bfa_timer on timer timeouts.
4791  *
4792  * param[in] port - pointer to bfa_fcs_lport_t.
4793  *
4794  * return
4795  * void
4796  *
4797  * Special Considerations:
4798  *
4799  * note
4800  */
4801 static void
4802 bfa_fcs_lport_ns_timeout(void *arg)
4803 {
4804  struct bfa_fcs_lport_ns_s *ns = (struct bfa_fcs_lport_ns_s *) arg;
4805 
4806  ns->port->stats.ns_timeouts++;
4808 }
4809 
4810 /*
4811  * Process the PID list in GID_FT response
4812  */
4813 static void
4814 bfa_fcs_lport_ns_process_gidft_pids(struct bfa_fcs_lport_s *port, u32 *pid_buf,
4815  u32 n_pids)
4816 {
4817  struct fcgs_gidft_resp_s *gidft_entry;
4818  struct bfa_fcs_rport_s *rport;
4819  u32 ii;
4820  struct bfa_fcs_fabric_s *fabric = port->fabric;
4821  struct bfa_fcs_vport_s *vport;
4822  struct list_head *qe;
4823  u8 found = 0;
4824 
4825  for (ii = 0; ii < n_pids; ii++) {
4826  gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
4827 
4828  if (gidft_entry->pid == port->pid)
4829  continue;
4830 
4831  /*
4832  * Ignore PID if it is of base port
4833  * (Avoid vports discovering base port as remote port)
4834  */
4835  if (gidft_entry->pid == fabric->bport.pid)
4836  continue;
4837 
4838  /*
4839  * Ignore PID if it is of vport created on the same base port
4840  * (Avoid vport discovering every other vport created on the
4841  * same port as remote port)
4842  */
4843  list_for_each(qe, &fabric->vport_q) {
4844  vport = (struct bfa_fcs_vport_s *) qe;
4845  if (vport->lport.pid == gidft_entry->pid)
4846  found = 1;
4847  }
4848 
4849  if (found) {
4850  found = 0;
4851  continue;
4852  }
4853 
4854  /*
4855  * Check if this rport already exists
4856  */
4857  rport = bfa_fcs_lport_get_rport_by_pid(port, gidft_entry->pid);
4858  if (rport == NULL) {
4859  /*
4860  * this is a new device. create rport
4861  */
4862  rport = bfa_fcs_rport_create(port, gidft_entry->pid);
4863  } else {
4864  /*
4865  * this rport already exists
4866  */
4867  bfa_fcs_rport_scn(rport);
4868  }
4869 
4870  bfa_trc(port->fcs, gidft_entry->pid);
4871 
4872  /*
4873  * if the last entry bit is set, bail out.
4874  */
4875  if (gidft_entry->last)
4876  return;
4877  }
4878 }
4879 
4880 /*
4881  * fcs_ns_public FCS nameserver public interfaces
4882  */
4883 
4884 /*
4885  * Functions called by port/fab.
4886  * These will send relevant Events to the ns state machine.
4887  */
4888 void
4890 {
4891  struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4892 
4893  ns->port = port;
4894  bfa_sm_set_state(ns, bfa_fcs_lport_ns_sm_offline);
4895 }
4896 
4897 void
4899 {
4900  struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4901 
4902  ns->port = port;
4904 }
4905 
4906 void
4908 {
4909  struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4910 
4911  ns->port = port;
4913 }
4914 
4915 void
4917 {
4918  struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
4919 
4920  bfa_trc(port->fcs, port->pid);
4921  if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_online))
4923 }
4924 
4925 static void
4926 bfa_fcs_lport_ns_boot_target_disc(bfa_fcs_lport_t *port)
4927 {
4928 
4929  struct bfa_fcs_rport_s *rport;
4930  u8 nwwns;
4932  int ii;
4933 
4934  bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, wwns);
4935 
4936  for (ii = 0 ; ii < nwwns; ++ii) {
4937  rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
4938  WARN_ON(!rport);
4939  }
4940 }
4941 
4942 void
4943 bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced)
4944 {
4945  struct bfa_fcs_lport_ns_s *ns = cbarg;
4946  struct bfa_fcs_lport_s *port = ns->port;
4947  struct fchs_s fchs;
4948  struct bfa_fcxp_s *fcxp;
4949  u8 symbl[256];
4950  u8 *psymbl = &symbl[0];
4951  int len;
4952 
4953  if (!bfa_sm_cmp_state(port, bfa_fcs_lport_sm_online))
4954  return;
4955 
4956  /* Avoid sending RSPN in the following states. */
4957  if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_offline) ||
4958  bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_sending) ||
4959  bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi) ||
4960  bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_plogi_retry) ||
4961  bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_rspn_id_retry))
4962  return;
4963 
4964  memset(symbl, 0, sizeof(symbl));
4965  bfa_trc(port->fcs, port->port_cfg.pwwn);
4966 
4967  fcxp = fcxp_alloced ? fcxp_alloced :
4969  if (!fcxp) {
4970  port->stats.ns_rspnid_alloc_wait++;
4971  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
4973  return;
4974  }
4975 
4976  ns->fcxp = fcxp;
4977 
4978  if (port->vport) {
4979  /*
4980  * For Vports, we append the vport's port symbolic name
4981  * to that of the base port.
4982  */
4983  strncpy((char *)psymbl, (char *)&(bfa_fcs_lport_get_psym_name
4984  (bfa_fcs_get_base_port(port->fcs))),
4986  bfa_fcs_get_base_port(port->fcs))));
4987 
4988  /* Ensure we have a null terminating string. */
4989  ((char *)psymbl)[strlen((char *)&bfa_fcs_lport_get_psym_name(
4990  bfa_fcs_get_base_port(port->fcs)))] = 0;
4991 
4992  strncat((char *)psymbl,
4993  (char *)&(bfa_fcs_lport_get_psym_name(port)),
4994  strlen((char *)&bfa_fcs_lport_get_psym_name(port)));
4995  }
4996 
4997  len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
4998  bfa_fcs_lport_get_fcid(port), 0, psymbl);
4999 
5000  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
5001  FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
5002 
5003  port->stats.ns_rspnid_sent++;
5004 }
5005 
5006 /*
5007  * FCS SCN
5008  */
5009 
5010 #define FC_QOS_RSCN_EVENT 0x0c
5011 #define FC_FABRIC_NAME_RSCN_EVENT 0x0d
5012 
5013 /*
5014  * forward declarations
5015  */
5016 static void bfa_fcs_lport_scn_send_scr(void *scn_cbarg,
5017  struct bfa_fcxp_s *fcxp_alloced);
5018 static void bfa_fcs_lport_scn_scr_response(void *fcsarg,
5019  struct bfa_fcxp_s *fcxp,
5020  void *cbarg,
5021  bfa_status_t req_status,
5022  u32 rsp_len,
5023  u32 resid_len,
5024  struct fchs_s *rsp_fchs);
5025 static void bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
5026  struct fchs_s *rx_fchs);
5027 static void bfa_fcs_lport_scn_timeout(void *arg);
5028 
5029 /*
5030  * fcs_scm_sm FCS SCN state machine
5031  */
5032 
5033 /*
5034  * VPort SCN State Machine events
5035  */
5043 };
5044 
5045 static void bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
5046  enum port_scn_event event);
5047 static void bfa_fcs_lport_scn_sm_sending_scr(
5048  struct bfa_fcs_lport_scn_s *scn,
5049  enum port_scn_event event);
5050 static void bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
5051  enum port_scn_event event);
5052 static void bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
5053  enum port_scn_event event);
5054 static void bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
5055  enum port_scn_event event);
5056 
5057 /*
5058  * Starting state - awaiting link up.
5059  */
5060 static void
5061 bfa_fcs_lport_scn_sm_offline(struct bfa_fcs_lport_scn_s *scn,
5062  enum port_scn_event event)
5063 {
5064  switch (event) {
5066  bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
5067  bfa_fcs_lport_scn_send_scr(scn, NULL);
5068  break;
5069 
5071  break;
5072 
5073  default:
5074  bfa_sm_fault(scn->port->fcs, event);
5075  }
5076 }
5077 
5078 static void
5079 bfa_fcs_lport_scn_sm_sending_scr(struct bfa_fcs_lport_scn_s *scn,
5080  enum port_scn_event event)
5081 {
5082  switch (event) {
5083  case SCNSM_EVENT_SCR_SENT:
5084  bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr);
5085  break;
5086 
5088  bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5089  bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe);
5090  break;
5091 
5092  default:
5093  bfa_sm_fault(scn->port->fcs, event);
5094  }
5095 }
5096 
5097 static void
5098 bfa_fcs_lport_scn_sm_scr(struct bfa_fcs_lport_scn_s *scn,
5099  enum port_scn_event event)
5100 {
5101  struct bfa_fcs_lport_s *port = scn->port;
5102 
5103  switch (event) {
5104  case SCNSM_EVENT_RSP_OK:
5105  bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_online);
5106  break;
5107 
5108  case SCNSM_EVENT_RSP_ERROR:
5109  bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_scr_retry);
5110  bfa_timer_start(port->fcs->bfa, &scn->timer,
5111  bfa_fcs_lport_scn_timeout, scn,
5113  break;
5114 
5116  bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5117  bfa_fcxp_discard(scn->fcxp);
5118  break;
5119 
5120  default:
5121  bfa_sm_fault(port->fcs, event);
5122  }
5123 }
5124 
5125 static void
5126 bfa_fcs_lport_scn_sm_scr_retry(struct bfa_fcs_lport_scn_s *scn,
5127  enum port_scn_event event)
5128 {
5129  switch (event) {
5130  case SCNSM_EVENT_TIMEOUT:
5131  bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_sending_scr);
5132  bfa_fcs_lport_scn_send_scr(scn, NULL);
5133  break;
5134 
5136  bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5137  bfa_timer_stop(&scn->timer);
5138  break;
5139 
5140  default:
5141  bfa_sm_fault(scn->port->fcs, event);
5142  }
5143 }
5144 
5145 static void
5146 bfa_fcs_lport_scn_sm_online(struct bfa_fcs_lport_scn_s *scn,
5147  enum port_scn_event event)
5148 {
5149  switch (event) {
5151  bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5152  break;
5153 
5154  default:
5155  bfa_sm_fault(scn->port->fcs, event);
5156  }
5157 }
5158 
5159 
5160 
5161 /*
5162  * fcs_scn_private FCS SCN private functions
5163  */
5164 
5165 /*
5166  * This routine will be called to send a SCR command.
5167  */
5168 static void
5169 bfa_fcs_lport_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
5170 {
5171  struct bfa_fcs_lport_scn_s *scn = scn_cbarg;
5172  struct bfa_fcs_lport_s *port = scn->port;
5173  struct fchs_s fchs;
5174  int len;
5175  struct bfa_fcxp_s *fcxp;
5176 
5177  bfa_trc(port->fcs, port->pid);
5178  bfa_trc(port->fcs, port->port_cfg.pwwn);
5179 
5180  fcxp = fcxp_alloced ? fcxp_alloced :
5182  if (!fcxp) {
5183  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
5184  bfa_fcs_lport_scn_send_scr, scn, BFA_TRUE);
5185  return;
5186  }
5187  scn->fcxp = fcxp;
5188 
5189  /* Handle VU registrations for Base port only */
5190  if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
5191  len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5192  port->fabric->lps->brcd_switch,
5193  port->pid, 0);
5194  } else {
5195  len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5196  BFA_FALSE,
5197  port->pid, 0);
5198  }
5199 
5200  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
5201  FC_CLASS_3, len, &fchs,
5202  bfa_fcs_lport_scn_scr_response,
5203  (void *)scn, FC_MAX_PDUSZ, FC_ELS_TOV);
5204 
5206 }
5207 
5208 static void
5209 bfa_fcs_lport_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
5210  void *cbarg, bfa_status_t req_status, u32 rsp_len,
5211  u32 resid_len, struct fchs_s *rsp_fchs)
5212 {
5213  struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) cbarg;
5214  struct bfa_fcs_lport_s *port = scn->port;
5215  struct fc_els_cmd_s *els_cmd;
5216  struct fc_ls_rjt_s *ls_rjt;
5217 
5218  bfa_trc(port->fcs, port->port_cfg.pwwn);
5219 
5220  /*
5221  * Sanity Checks
5222  */
5223  if (req_status != BFA_STATUS_OK) {
5224  bfa_trc(port->fcs, req_status);
5226  return;
5227  }
5228 
5229  els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
5230 
5231  switch (els_cmd->els_code) {
5232 
5233  case FC_ELS_ACC:
5235  break;
5236 
5237  case FC_ELS_LS_RJT:
5238 
5239  ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
5240 
5241  bfa_trc(port->fcs, ls_rjt->reason_code);
5242  bfa_trc(port->fcs, ls_rjt->reason_code_expl);
5243 
5245  break;
5246 
5247  default:
5249  }
5250 }
5251 
5252 /*
5253  * Send a LS Accept
5254  */
5255 static void
5256 bfa_fcs_lport_scn_send_ls_acc(struct bfa_fcs_lport_s *port,
5257  struct fchs_s *rx_fchs)
5258 {
5259  struct fchs_s fchs;
5260  struct bfa_fcxp_s *fcxp;
5261  struct bfa_rport_s *bfa_rport = NULL;
5262  int len;
5263 
5264  bfa_trc(port->fcs, rx_fchs->s_id);
5265 
5266  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
5267  if (!fcxp)
5268  return;
5269 
5270  len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
5271  rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
5272  rx_fchs->ox_id);
5273 
5274  bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
5275  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
5276  FC_MAX_PDUSZ, 0);
5277 }
5278 
5279 /*
5280  * This routine will be called by bfa_timer on timer timeouts.
5281  *
5282  * param[in] vport - pointer to bfa_fcs_lport_t.
5283  * param[out] vport_status - pointer to return vport status in
5284  *
5285  * return
5286  * void
5287  *
5288  * Special Considerations:
5289  *
5290  * note
5291  */
5292 static void
5293 bfa_fcs_lport_scn_timeout(void *arg)
5294 {
5295  struct bfa_fcs_lport_scn_s *scn = (struct bfa_fcs_lport_scn_s *) arg;
5296 
5298 }
5299 
5300 
5301 
5302 /*
5303  * fcs_scn_public FCS state change notification public interfaces
5304  */
5305 
5306 /*
5307  * Functions called by port/fab
5308  */
5309 void
5311 {
5312  struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
5313 
5314  scn->port = port;
5315  bfa_sm_set_state(scn, bfa_fcs_lport_scn_sm_offline);
5316 }
5317 
5318 void
5320 {
5321  struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
5322 
5323  scn->port = port;
5325 }
5326 
5327 void
5329 {
5330  struct bfa_fcs_lport_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
5331 
5332  scn->port = port;
5334 }
5335 
5336 static void
5337 bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
5338 {
5339  struct bfa_fcs_rport_s *rport;
5340  struct bfa_fcs_fabric_s *fabric = port->fabric;
5341  struct bfa_fcs_vport_s *vport;
5342  struct list_head *qe;
5343 
5344  bfa_trc(port->fcs, rpid);
5345 
5346  /*
5347  * Ignore PID if it is of base port or of vports created on the
5348  * same base port. It is to avoid vports discovering base port or
5349  * other vports created on same base port as remote port
5350  */
5351  if (rpid == fabric->bport.pid)
5352  return;
5353 
5354  list_for_each(qe, &fabric->vport_q) {
5355  vport = (struct bfa_fcs_vport_s *) qe;
5356  if (vport->lport.pid == rpid)
5357  return;
5358  }
5359  /*
5360  * If this is an unknown device, then it just came online.
5361  * Otherwise let rport handle the RSCN event.
5362  */
5363  rport = bfa_fcs_lport_get_rport_by_pid(port, rpid);
5364  if (!rport)
5365  rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid);
5366 
5367  if (rport == NULL) {
5368  /*
5369  * If min cfg mode is enabled, we donot need to
5370  * discover any new rports.
5371  */
5372  if (!__fcs_min_cfg(port->fcs))
5373  rport = bfa_fcs_rport_create(port, rpid);
5374  } else
5375  bfa_fcs_rport_scn(rport);
5376 }
5377 
5378 /*
5379  * rscn format based PID comparison
5380  */
5381 #define __fc_pid_match(__c0, __c1, __fmt) \
5382  (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \
5383  (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \
5384  ((__c0)[0] == (__c1)[0])) || \
5385  (((__fmt) == FC_RSCN_FORMAT_AREA) && \
5386  ((__c0)[0] == (__c1)[0]) && \
5387  ((__c0)[1] == (__c1)[1])))
5388 
5389 static void
5390 bfa_fcs_lport_scn_multiport_rscn(struct bfa_fcs_lport_s *port,
5391  enum fc_rscn_format format,
5392  u32 rscn_pid)
5393 {
5394  struct bfa_fcs_rport_s *rport;
5395  struct list_head *qe, *qe_next;
5396  u8 *c0, *c1;
5397 
5398  bfa_trc(port->fcs, format);
5399  bfa_trc(port->fcs, rscn_pid);
5400 
5401  c0 = (u8 *) &rscn_pid;
5402 
5403  list_for_each_safe(qe, qe_next, &port->rport_q) {
5404  rport = (struct bfa_fcs_rport_s *) qe;
5405  c1 = (u8 *) &rport->pid;
5406  if (__fc_pid_match(c0, c1, format))
5407  bfa_fcs_rport_scn(rport);
5408  }
5409 }
5410 
5411 
5412 void
5414  struct fchs_s *fchs, u32 len)
5415 {
5416  struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1);
5417  int num_entries;
5418  u32 rscn_pid;
5419  bfa_boolean_t nsquery = BFA_FALSE, found;
5420  int i = 0, j;
5421 
5422  num_entries =
5423  (be16_to_cpu(rscn->payldlen) -
5424  sizeof(u32)) / sizeof(rscn->event[0]);
5425 
5426  bfa_trc(port->fcs, num_entries);
5427 
5428  port->stats.num_rscn++;
5429 
5430  bfa_fcs_lport_scn_send_ls_acc(port, fchs);
5431 
5432  for (i = 0; i < num_entries; i++) {
5433  rscn_pid = rscn->event[i].portid;
5434 
5435  bfa_trc(port->fcs, rscn->event[i].format);
5436  bfa_trc(port->fcs, rscn_pid);
5437 
5438  /* check for duplicate entries in the list */
5439  found = BFA_FALSE;
5440  for (j = 0; j < i; j++) {
5441  if (rscn->event[j].portid == rscn_pid) {
5442  found = BFA_TRUE;
5443  break;
5444  }
5445  }
5446 
5447  /* if found in down the list, pid has been already processed */
5448  if (found) {
5449  bfa_trc(port->fcs, rscn_pid);
5450  continue;
5451  }
5452 
5453  switch (rscn->event[i].format) {
5454  case FC_RSCN_FORMAT_PORTID:
5455  if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) {
5456  /*
5457  * Ignore this event.
5458  * f/w would have processed it
5459  */
5460  bfa_trc(port->fcs, rscn_pid);
5461  } else {
5462  port->stats.num_portid_rscn++;
5463  bfa_fcs_lport_scn_portid_rscn(port, rscn_pid);
5464  }
5465  break;
5466 
5467  case FC_RSCN_FORMAT_FABRIC:
5468  if (rscn->event[i].qualifier ==
5471  break;
5472  }
5473  /* !!!!!!!!! Fall Through !!!!!!!!!!!!! */
5474 
5475  case FC_RSCN_FORMAT_AREA:
5476  case FC_RSCN_FORMAT_DOMAIN:
5477  nsquery = BFA_TRUE;
5478  bfa_fcs_lport_scn_multiport_rscn(port,
5479  rscn->event[i].format,
5480  rscn_pid);
5481  break;
5482 
5483 
5484  default:
5485  WARN_ON(1);
5486  nsquery = BFA_TRUE;
5487  }
5488  }
5489 
5490  /*
5491  * If any of area, domain or fabric RSCN is received, do a fresh
5492  * discovery to find new devices.
5493  */
5494  if (nsquery)
5495  bfa_fcs_lport_ns_query(port);
5496 }
5497 
5498 /*
5499  * BFA FCS port
5500  */
5501 /*
5502  * fcs_port_api BFA FCS port API
5503  */
5504 struct bfa_fcs_lport_s *
5506 {
5507  return &fcs->fabric.bport;
5508 }
5509 
5510 wwn_t
5512  int nrports, bfa_boolean_t bwwn)
5513 {
5514  struct list_head *qh, *qe;
5515  struct bfa_fcs_rport_s *rport = NULL;
5516  int i;
5517  struct bfa_fcs_s *fcs;
5518 
5519  if (port == NULL || nrports == 0)
5520  return (wwn_t) 0;
5521 
5522  fcs = port->fcs;
5523  bfa_trc(fcs, (u32) nrports);
5524 
5525  i = 0;
5526  qh = &port->rport_q;
5527  qe = bfa_q_first(qh);
5528 
5529  while ((qe != qh) && (i < nrports)) {
5530  rport = (struct bfa_fcs_rport_s *) qe;
5531  if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
5532  qe = bfa_q_next(qe);
5533  bfa_trc(fcs, (u32) rport->pwwn);
5534  bfa_trc(fcs, rport->pid);
5535  bfa_trc(fcs, i);
5536  continue;
5537  }
5538 
5539  if (bwwn) {
5540  if (!memcmp(&wwn, &rport->pwwn, 8))
5541  break;
5542  } else {
5543  if (i == index)
5544  break;
5545  }
5546 
5547  i++;
5548  qe = bfa_q_next(qe);
5549  }
5550 
5551  bfa_trc(fcs, i);
5552  if (rport)
5553  return rport->pwwn;
5554  else
5555  return (wwn_t) 0;
5556 }
5557 
5558 void
5560  struct bfa_rport_qualifier_s rports[], int *nrports)
5561 {
5562  struct list_head *qh, *qe;
5563  struct bfa_fcs_rport_s *rport = NULL;
5564  int i;
5565  struct bfa_fcs_s *fcs;
5566 
5567  if (port == NULL || rports == NULL || *nrports == 0)
5568  return;
5569 
5570  fcs = port->fcs;
5571  bfa_trc(fcs, (u32) *nrports);
5572 
5573  i = 0;
5574  qh = &port->rport_q;
5575  qe = bfa_q_first(qh);
5576 
5577  while ((qe != qh) && (i < *nrports)) {
5578  rport = (struct bfa_fcs_rport_s *) qe;
5579  if (bfa_ntoh3b(rport->pid) > 0xFFF000) {
5580  qe = bfa_q_next(qe);
5581  bfa_trc(fcs, (u32) rport->pwwn);
5582  bfa_trc(fcs, rport->pid);
5583  bfa_trc(fcs, i);
5584  continue;
5585  }
5586 
5587  if (!rport->pwwn && !rport->pid) {
5588  qe = bfa_q_next(qe);
5589  continue;
5590  }
5591 
5592  rports[i].pwwn = rport->pwwn;
5593  rports[i].pid = rport->pid;
5594 
5595  i++;
5596  qe = bfa_q_next(qe);
5597  }
5598 
5599  bfa_trc(fcs, i);
5600  *nrports = i;
5601 }
5602 
5603 /*
5604  * Iterate's through all the rport's in the given port to
5605  * determine the maximum operating speed.
5606  *
5607  * !!!! To be used in TRL Functionality only !!!!
5608  */
5611 {
5612  struct list_head *qh, *qe;
5613  struct bfa_fcs_rport_s *rport = NULL;
5614  struct bfa_fcs_s *fcs;
5615  bfa_port_speed_t max_speed = 0;
5616  struct bfa_port_attr_s port_attr;
5617  bfa_port_speed_t port_speed, rport_speed;
5618  bfa_boolean_t trl_enabled = bfa_fcport_is_ratelim(port->fcs->bfa);
5619 
5620 
5621  if (port == NULL)
5622  return 0;
5623 
5624  fcs = port->fcs;
5625 
5626  /* Get Physical port's current speed */
5627  bfa_fcport_get_attr(port->fcs->bfa, &port_attr);
5628  port_speed = port_attr.speed;
5629  bfa_trc(fcs, port_speed);
5630 
5631  qh = &port->rport_q;
5632  qe = bfa_q_first(qh);
5633 
5634  while (qe != qh) {
5635  rport = (struct bfa_fcs_rport_s *) qe;
5636  if ((bfa_ntoh3b(rport->pid) > 0xFFF000) ||
5638  (rport->scsi_function != BFA_RPORT_TARGET)) {
5639  qe = bfa_q_next(qe);
5640  continue;
5641  }
5642 
5643  rport_speed = rport->rpf.rpsc_speed;
5644  if ((trl_enabled) && (rport_speed ==
5646  /* Use default ratelim speed setting */
5647  rport_speed =
5648  bfa_fcport_get_ratelim_speed(port->fcs->bfa);
5649  }
5650 
5651  if (rport_speed > max_speed)
5652  max_speed = rport_speed;
5653 
5654  qe = bfa_q_next(qe);
5655  }
5656 
5657  if (max_speed > port_speed)
5658  max_speed = port_speed;
5659 
5660  bfa_trc(fcs, max_speed);
5661  return max_speed;
5662 }
5663 
5664 struct bfa_fcs_lport_s *
5666 {
5667  struct bfa_fcs_vport_s *vport;
5668  bfa_fcs_vf_t *vf;
5669 
5670  WARN_ON(fcs == NULL);
5671 
5672  vf = bfa_fcs_vf_lookup(fcs, vf_id);
5673  if (vf == NULL) {
5674  bfa_trc(fcs, vf_id);
5675  return NULL;
5676  }
5677 
5678  if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
5679  return &vf->bport;
5680 
5681  vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
5682  if (vport)
5683  return &vport->lport;
5684 
5685  return NULL;
5686 }
5687 
5688 /*
5689  * API corresponding to NPIV_VPORT_GETINFO.
5690  */
5691 void
5693  struct bfa_lport_info_s *port_info)
5694 {
5695 
5696  bfa_trc(port->fcs, port->fabric->fabric_name);
5697 
5698  if (port->vport == NULL) {
5699  /*
5700  * This is a Physical port
5701  */
5702  port_info->port_type = BFA_LPORT_TYPE_PHYSICAL;
5703 
5704  /*
5705  * @todo : need to fix the state & reason
5706  */
5707  port_info->port_state = 0;
5708  port_info->offline_reason = 0;
5709 
5710  port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5711  port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5712 
5713  port_info->max_vports_supp =
5714  bfa_lps_get_max_vport(port->fcs->bfa);
5715  port_info->num_vports_inuse =
5716  port->fabric->num_vports;
5718  port_info->num_rports_inuse = port->num_rports;
5719  } else {
5720  /*
5721  * This is a virtual port
5722  */
5723  port_info->port_type = BFA_LPORT_TYPE_VIRTUAL;
5724 
5725  /*
5726  * @todo : need to fix the state & reason
5727  */
5728  port_info->port_state = 0;
5729  port_info->offline_reason = 0;
5730 
5731  port_info->port_wwn = bfa_fcs_lport_get_pwwn(port);
5732  port_info->node_wwn = bfa_fcs_lport_get_nwwn(port);
5733  }
5734 }
5735 
5736 void
5738  struct bfa_lport_stats_s *port_stats)
5739 {
5740  *port_stats = fcs_port->stats;
5741 }
5742 
5743 void
5745 {
5746  memset(&fcs_port->stats, 0, sizeof(struct bfa_lport_stats_s));
5747 }
5748 
5749 /*
5750  * Let new loop map create missing rports
5751  */
5752 void
5754 {
5755  bfa_fcs_lport_loop_online(port);
5756 }
5757 
5758 /*
5759  * FCS virtual port state machine
5760  */
5761 
5762 #define __vport_fcs(__vp) ((__vp)->lport.fcs)
5763 #define __vport_pwwn(__vp) ((__vp)->lport.port_cfg.pwwn)
5764 #define __vport_nwwn(__vp) ((__vp)->lport.port_cfg.nwwn)
5765 #define __vport_bfa(__vp) ((__vp)->lport.fcs->bfa)
5766 #define __vport_fcid(__vp) ((__vp)->lport.pid)
5767 #define __vport_fabric(__vp) ((__vp)->lport.fabric)
5768 #define __vport_vfid(__vp) ((__vp)->lport.fabric->vf_id)
5769 
5770 #define BFA_FCS_VPORT_MAX_RETRIES 5
5771 /*
5772  * Forward declarations
5773  */
5774 static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport);
5775 static void bfa_fcs_vport_timeout(void *vport_arg);
5776 static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport);
5777 static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport);
5778 
5779 /*
5780  * fcs_vport_sm FCS virtual port state machine
5781  */
5782 
5783 /*
5784  * VPort State Machine events
5785  */
5787  BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */
5788  BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */
5789  BFA_FCS_VPORT_SM_START = 3, /* vport start request */
5790  BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */
5791  BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */
5792  BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */
5793  BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */
5794  BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */
5795  BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */
5796  BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */
5797  BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */
5798  BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/
5799  BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */
5800  BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */
5801 };
5802 
5803 static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
5804  enum bfa_fcs_vport_event event);
5805 static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
5806  enum bfa_fcs_vport_event event);
5807 static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
5808  enum bfa_fcs_vport_event event);
5809 static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
5810  enum bfa_fcs_vport_event event);
5811 static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
5812  enum bfa_fcs_vport_event event);
5813 static void bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
5814  enum bfa_fcs_vport_event event);
5815 static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
5816  enum bfa_fcs_vport_event event);
5817 static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
5818  enum bfa_fcs_vport_event event);
5819 static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
5820  enum bfa_fcs_vport_event event);
5821 static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
5822  enum bfa_fcs_vport_event event);
5823 static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
5824  enum bfa_fcs_vport_event event);
5825 static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
5826  enum bfa_fcs_vport_event event);
5827 static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
5828  enum bfa_fcs_vport_event event);
5829 
5830 static struct bfa_sm_table_s vport_sm_table[] = {
5831  {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT},
5832  {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED},
5833  {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE},
5834  {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC},
5835  {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY},
5836  {BFA_SM(bfa_fcs_vport_sm_fdisc_rsp_wait), BFA_FCS_VPORT_FDISC_RSP_WAIT},
5837  {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE},
5838  {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING},
5839  {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP},
5840  {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO},
5841  {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR}
5842 };
5843 
5844 /*
5845  * Beginning state.
5846  */
5847 static void
5848 bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
5849  enum bfa_fcs_vport_event event)
5850 {
5851  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5852  bfa_trc(__vport_fcs(vport), event);
5853 
5854  switch (event) {
5856  bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
5857  bfa_fcs_fabric_addvport(__vport_fabric(vport), vport);
5858  break;
5859 
5860  default:
5861  bfa_sm_fault(__vport_fcs(vport), event);
5862  }
5863 }
5864 
5865 /*
5866  * Created state - a start event is required to start up the state machine.
5867  */
5868 static void
5869 bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
5870  enum bfa_fcs_vport_event event)
5871 {
5872  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5873  bfa_trc(__vport_fcs(vport), event);
5874 
5875  switch (event) {
5877  if (bfa_sm_cmp_state(__vport_fabric(vport),
5880  bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5881  bfa_fcs_vport_do_fdisc(vport);
5882  } else {
5883  /*
5884  * Fabric is offline or not NPIV capable, stay in
5885  * offline state.
5886  */
5887  vport->vport_stats.fab_no_npiv++;
5888  bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5889  }
5890  break;
5891 
5893  bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5894  bfa_fcs_lport_delete(&vport->lport);
5895  break;
5896 
5899  /*
5900  * Ignore ONLINE/OFFLINE events from fabric
5901  * till vport is started.
5902  */
5903  break;
5904 
5905  default:
5906  bfa_sm_fault(__vport_fcs(vport), event);
5907  }
5908 }
5909 
5910 /*
5911  * Offline state - awaiting ONLINE event from fabric SM.
5912  */
5913 static void
5914 bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
5915  enum bfa_fcs_vport_event event)
5916 {
5917  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5918  bfa_trc(__vport_fcs(vport), event);
5919 
5920  switch (event) {
5922  bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5923  bfa_fcs_lport_delete(&vport->lport);
5924  break;
5925 
5927  bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
5928  vport->fdisc_retries = 0;
5929  bfa_fcs_vport_do_fdisc(vport);
5930  break;
5931 
5932  case BFA_FCS_VPORT_SM_STOP:
5933  bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
5935  break;
5936 
5938  /*
5939  * This can happen if the vport couldn't be initialzied
5940  * due the fact that the npiv was not enabled on the switch.
5941  * In that case we will put the vport in offline state.
5942  * However, the link can go down and cause the this event to
5943  * be sent when we are already offline. Ignore it.
5944  */
5945  break;
5946 
5947  default:
5948  bfa_sm_fault(__vport_fcs(vport), event);
5949  }
5950 }
5951 
5952 
5953 /*
5954  * FDISC is sent and awaiting reply from fabric.
5955  */
5956 static void
5957 bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
5958  enum bfa_fcs_vport_event event)
5959 {
5960  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
5961  bfa_trc(__vport_fcs(vport), event);
5962 
5963  switch (event) {
5965  bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_rsp_wait);
5966  break;
5967 
5969  bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5971  break;
5972 
5974  bfa_sm_set_state(vport, bfa_fcs_vport_sm_online);
5975  bfa_fcs_lport_online(&vport->lport);
5976  break;
5977 
5979  bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry);
5980  bfa_timer_start(__vport_bfa(vport), &vport->timer,
5981  bfa_fcs_vport_timeout, vport,
5983  break;
5984 
5986  bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
5987  break;
5988 
5990  bfa_sm_set_state(vport, bfa_fcs_vport_sm_error);
5991  break;
5992 
5993  default:
5994  bfa_sm_fault(__vport_fcs(vport), event);
5995  }
5996 }
5997 
5998 /*
5999  * FDISC attempt failed - a timer is active to retry FDISC.
6000  */
6001 static void
6002 bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
6003  enum bfa_fcs_vport_event event)
6004 {
6005  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6006  bfa_trc(__vport_fcs(vport), event);
6007 
6008  switch (event) {
6010  bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6011  bfa_timer_stop(&vport->timer);
6012  bfa_fcs_lport_delete(&vport->lport);
6013  break;
6014 
6016  bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6017  bfa_timer_stop(&vport->timer);
6018  break;
6019 
6021  bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
6022  vport->vport_stats.fdisc_retries++;
6023  vport->fdisc_retries++;
6024  bfa_fcs_vport_do_fdisc(vport);
6025  break;
6026 
6027  default:
6028  bfa_sm_fault(__vport_fcs(vport), event);
6029  }
6030 }
6031 
6032 /*
6033  * FDISC is in progress and we got a vport delete request -
6034  * this is a wait state while we wait for fdisc response and
6035  * we will transition to the appropriate state - on rsp status.
6036  */
6037 static void
6038 bfa_fcs_vport_sm_fdisc_rsp_wait(struct bfa_fcs_vport_s *vport,
6039  enum bfa_fcs_vport_event event)
6040 {
6041  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6042  bfa_trc(__vport_fcs(vport), event);
6043 
6044  switch (event) {
6046  bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
6047  bfa_fcs_lport_delete(&vport->lport);
6048  break;
6049 
6051  break;
6052 
6057  bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6059  bfa_fcs_lport_delete(&vport->lport);
6060  break;
6061 
6062  default:
6063  bfa_sm_fault(__vport_fcs(vport), event);
6064  }
6065 }
6066 
6067 /*
6068  * Vport is online (FDISC is complete).
6069  */
6070 static void
6071 bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
6072  enum bfa_fcs_vport_event event)
6073 {
6074  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6075  bfa_trc(__vport_fcs(vport), event);
6076 
6077  switch (event) {
6079  bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
6080  bfa_fcs_lport_delete(&vport->lport);
6081  break;
6082 
6083  case BFA_FCS_VPORT_SM_STOP:
6084  bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping);
6086  break;
6087 
6089  bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
6091  bfa_fcs_lport_offline(&vport->lport);
6092  break;
6093 
6094  default:
6095  bfa_sm_fault(__vport_fcs(vport), event);
6096  }
6097 }
6098 
6099 /*
6100  * Vport is being stopped - awaiting lport stop completion to send
6101  * LOGO to fabric.
6102  */
6103 static void
6104 bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport,
6105  enum bfa_fcs_vport_event event)
6106 {
6107  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6108  bfa_trc(__vport_fcs(vport), event);
6109 
6110  switch (event) {
6112  bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop);
6113  bfa_fcs_vport_do_logo(vport);
6114  break;
6115 
6117  bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6118  break;
6119 
6120  default:
6121  bfa_sm_fault(__vport_fcs(vport), event);
6122  }
6123 }
6124 
6125 /*
6126  * Vport is being deleted - awaiting lport delete completion to send
6127  * LOGO to fabric.
6128  */
6129 static void
6130 bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
6131  enum bfa_fcs_vport_event event)
6132 {
6133  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6134  bfa_trc(__vport_fcs(vport), event);
6135 
6136  switch (event) {
6138  break;
6139 
6141  bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
6142  bfa_fcs_vport_do_logo(vport);
6143  break;
6144 
6146  bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6147  break;
6148 
6149  default:
6150  bfa_sm_fault(__vport_fcs(vport), event);
6151  }
6152 }
6153 
6154 /*
6155  * Error State.
6156  * This state will be set when the Vport Creation fails due
6157  * to errors like Dup WWN. In this state only operation allowed
6158  * is a Vport Delete.
6159  */
6160 static void
6161 bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
6162  enum bfa_fcs_vport_event event)
6163 {
6164  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6165  bfa_trc(__vport_fcs(vport), event);
6166 
6167  switch (event) {
6169  bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
6170  bfa_fcs_lport_delete(&vport->lport);
6171  break;
6172 
6173  default:
6174  bfa_trc(__vport_fcs(vport), event);
6175  }
6176 }
6177 
6178 /*
6179  * Lport cleanup is in progress since vport is being deleted. Fabric is
6180  * offline, so no LOGO is needed to complete vport deletion.
6181  */
6182 static void
6183 bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
6184  enum bfa_fcs_vport_event event)
6185 {
6186  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6187  bfa_trc(__vport_fcs(vport), event);
6188 
6189  switch (event) {
6191  bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
6192  bfa_fcs_vport_free(vport);
6193  break;
6194 
6196  bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
6197  break;
6198 
6200  break;
6201 
6202  default:
6203  bfa_sm_fault(__vport_fcs(vport), event);
6204  }
6205 }
6206 
6207 /*
6208  * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup
6209  * is done.
6210  */
6211 static void
6212 bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport,
6213  enum bfa_fcs_vport_event event)
6214 {
6215  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6216  bfa_trc(__vport_fcs(vport), event);
6217 
6218  switch (event) {
6221  /*
6222  * !!! fall through !!!
6223  */
6224 
6227  bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
6228  break;
6229 
6230  default:
6231  bfa_sm_fault(__vport_fcs(vport), event);
6232  }
6233 }
6234 
6235 /*
6236  * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
6237  * is done.
6238  */
6239 static void
6240 bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
6241  enum bfa_fcs_vport_event event)
6242 {
6243  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6244  bfa_trc(__vport_fcs(vport), event);
6245 
6246  switch (event) {
6249  /*
6250  * !!! fall through !!!
6251  */
6252 
6255  bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
6256  bfa_fcs_vport_free(vport);
6257  break;
6258 
6260  break;
6261 
6262  default:
6263  bfa_sm_fault(__vport_fcs(vport), event);
6264  }
6265 }
6266 
6267 
6268 
6269 /*
6270  * fcs_vport_private FCS virtual port private functions
6271  */
6272 /*
6273  * Send AEN notification
6274  */
6275 static void
6276 bfa_fcs_vport_aen_post(struct bfa_fcs_lport_s *port,
6277  enum bfa_lport_aen_event event)
6278 {
6279  struct bfad_s *bfad = (struct bfad_s *)port->fabric->fcs->bfad;
6280  struct bfa_aen_entry_s *aen_entry;
6281 
6282  bfad_get_aen_entry(bfad, aen_entry);
6283  if (!aen_entry)
6284  return;
6285 
6286  aen_entry->aen_data.lport.vf_id = port->fabric->vf_id;
6287  aen_entry->aen_data.lport.roles = port->port_cfg.roles;
6288  aen_entry->aen_data.lport.ppwwn = bfa_fcs_lport_get_pwwn(
6289  bfa_fcs_get_base_port(port->fcs));
6290  aen_entry->aen_data.lport.lpwwn = bfa_fcs_lport_get_pwwn(port);
6291 
6292  /* Send the AEN notification */
6293  bfad_im_post_vendor_event(aen_entry, bfad, ++port->fcs->fcs_aen_seq,
6294  BFA_AEN_CAT_LPORT, event);
6295 }
6296 
6297 /*
6298  * This routine will be called to send a FDISC command.
6299  */
6300 static void
6301 bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
6302 {
6303  bfa_lps_fdisc(vport->lps, vport,
6305  __vport_pwwn(vport), __vport_nwwn(vport));
6306  vport->vport_stats.fdisc_sent++;
6307 }
6308 
6309 static void
6310 bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
6311 {
6312  u8 lsrjt_rsn = vport->lps->lsrjt_rsn;
6313  u8 lsrjt_expl = vport->lps->lsrjt_expl;
6314 
6315  bfa_trc(__vport_fcs(vport), lsrjt_rsn);
6316  bfa_trc(__vport_fcs(vport), lsrjt_expl);
6317 
6318  /* For certain reason codes, we don't want to retry. */
6319  switch (vport->lps->lsrjt_expl) {
6320  case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */
6321  case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
6324  else {
6325  bfa_fcs_vport_aen_post(&vport->lport,
6328  }
6329  break;
6330 
6332  /*
6333  * This means max logins per port/switch setting on the
6334  * switch was exceeded.
6335  */
6338  else {
6339  bfa_fcs_vport_aen_post(&vport->lport,
6342  }
6343  break;
6344 
6345  default:
6346  if (vport->fdisc_retries == 0)
6347  bfa_fcs_vport_aen_post(&vport->lport,
6350  }
6351 }
6352 
6353 /*
6354  * Called to send a logout to the fabric. Used when a V-Port is
6355  * deleted/stopped.
6356  */
6357 static void
6358 bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport)
6359 {
6360  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6361 
6362  vport->vport_stats.logo_sent++;
6363  bfa_lps_fdisclogo(vport->lps);
6364 }
6365 
6366 
6367 /*
6368  * This routine will be called by bfa_timer on timer timeouts.
6369  *
6370  * param[in] vport - pointer to bfa_fcs_vport_t.
6371  * param[out] vport_status - pointer to return vport status in
6372  *
6373  * return
6374  * void
6375  *
6376  * Special Considerations:
6377  *
6378  * note
6379  */
6380 static void
6381 bfa_fcs_vport_timeout(void *vport_arg)
6382 {
6383  struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *) vport_arg;
6384 
6385  vport->vport_stats.fdisc_timeouts++;
6387 }
6388 
6389 static void
6390 bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
6391 {
6392  struct bfad_vport_s *vport_drv =
6393  (struct bfad_vport_s *)vport->vport_drv;
6394 
6395  bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
6396  bfa_lps_delete(vport->lps);
6397 
6398  if (vport_drv->comp_del) {
6399  complete(vport_drv->comp_del);
6400  return;
6401  }
6402 
6403  /*
6404  * We queue the vport delete work to the IM work_q from here.
6405  * The memory for the bfad_vport_s is freed from the FC function
6406  * template vport_delete entry point.
6407  */
6408  bfad_im_port_delete(vport_drv->drv_port.bfad, &vport_drv->drv_port);
6409 }
6410 
6411 /*
6412  * fcs_vport_public FCS virtual port public interfaces
6413  */
6414 
6415 /*
6416  * Online notification from fabric SM.
6417  */
6418 void
6420 {
6421  vport->vport_stats.fab_online++;
6424  else
6425  vport->vport_stats.fab_no_npiv++;
6426 }
6427 
6428 /*
6429  * Offline notification from fabric SM.
6430  */
6431 void
6433 {
6434  vport->vport_stats.fab_offline++;
6436 }
6437 
6438 /*
6439  * Cleanup notification from fabric SM on link timer expiry.
6440  */
6441 void
6443 {
6444  vport->vport_stats.fab_cleanup++;
6445 }
6446 
6447 /*
6448  * Stop notification from fabric SM. To be invoked from within FCS.
6449  */
6450 void
6452 {
6454 }
6455 
6456 /*
6457  * delete notification from fabric SM. To be invoked from within FCS.
6458  */
6459 void
6461 {
6463 }
6464 
6465 /*
6466  * Stop completion callback from associated lport
6467  */
6468 void
6470 {
6472 }
6473 
6474 /*
6475  * Delete completion callback from associated lport
6476  */
6477 void
6479 {
6481 }
6482 
6483 
6484 
6485 /*
6486  * fcs_vport_api Virtual port API
6487  */
6488 
6489 /*
6490  * Use this function to instantiate a new FCS vport object. This
6491  * function will not trigger any HW initialization process (which will be
6492  * done in vport_start() call)
6493  *
6494  * param[in] vport - pointer to bfa_fcs_vport_t. This space
6495  * needs to be allocated by the driver.
6496  * param[in] fcs - FCS instance
6497  * param[in] vport_cfg - vport configuration
6498  * param[in] vf_id - VF_ID if vport is created within a VF.
6499  * FC_VF_ID_NULL to specify base fabric.
6500  * param[in] vport_drv - Opaque handle back to the driver's vport
6501  * structure
6502  *
6503  * retval BFA_STATUS_OK - on success.
6504  * retval BFA_STATUS_FAILED - on failure.
6505  */
6508  u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
6509  struct bfad_vport_s *vport_drv)
6510 {
6511  if (vport_cfg->pwwn == 0)
6512  return BFA_STATUS_INVALID_WWN;
6513 
6514  if (bfa_fcs_lport_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
6515  return BFA_STATUS_VPORT_WWN_BP;
6516 
6517  if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
6518  return BFA_STATUS_VPORT_EXISTS;
6519 
6520  if (fcs->fabric.num_vports ==
6521  bfa_lps_get_max_vport(fcs->bfa))
6522  return BFA_STATUS_VPORT_MAX;
6523 
6524  vport->lps = bfa_lps_alloc(fcs->bfa);
6525  if (!vport->lps)
6526  return BFA_STATUS_VPORT_MAX;
6527 
6528  vport->vport_drv = vport_drv;
6529  vport_cfg->preboot_vp = BFA_FALSE;
6530 
6531  bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
6532  bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport);
6533  bfa_fcs_lport_init(&vport->lport, vport_cfg);
6535 
6536  return BFA_STATUS_OK;
6537 }
6538 
6539 /*
6540  * Use this function to instantiate a new FCS PBC vport object. This
6541  * function will not trigger any HW initialization process (which will be
6542  * done in vport_start() call)
6543  *
6544  * param[in] vport - pointer to bfa_fcs_vport_t. This space
6545  * needs to be allocated by the driver.
6546  * param[in] fcs - FCS instance
6547  * param[in] vport_cfg - vport configuration
6548  * param[in] vf_id - VF_ID if vport is created within a VF.
6549  * FC_VF_ID_NULL to specify base fabric.
6550  * param[in] vport_drv - Opaque handle back to the driver's vport
6551  * structure
6552  *
6553  * retval BFA_STATUS_OK - on success.
6554  * retval BFA_STATUS_FAILED - on failure.
6555  */
6558  u16 vf_id, struct bfa_lport_cfg_s *vport_cfg,
6559  struct bfad_vport_s *vport_drv)
6560 {
6561  bfa_status_t rc;
6562 
6563  rc = bfa_fcs_vport_create(vport, fcs, vf_id, vport_cfg, vport_drv);
6564  vport->lport.port_cfg.preboot_vp = BFA_TRUE;
6565 
6566  return rc;
6567 }
6568 
6569 /*
6570  * Use this function to findout if this is a pbc vport or not.
6571  *
6572  * @param[in] vport - pointer to bfa_fcs_vport_t.
6573  *
6574  * @returns None
6575  */
6578 {
6579 
6580  if (vport && (vport->lport.port_cfg.preboot_vp == BFA_TRUE))
6581  return BFA_TRUE;
6582  else
6583  return BFA_FALSE;
6584 
6585 }
6586 
6587 /*
6588  * Use this function initialize the vport.
6589  *
6590  * @param[in] vport - pointer to bfa_fcs_vport_t.
6591  *
6592  * @returns None
6593  */
6596 {
6598 
6599  return BFA_STATUS_OK;
6600 }
6601 
6602 /*
6603  * Use this function quiese the vport object. This function will return
6604  * immediately, when the vport is actually stopped, the
6605  * bfa_drv_vport_stop_cb() will be called.
6606  *
6607  * param[in] vport - pointer to bfa_fcs_vport_t.
6608  *
6609  * return None
6610  */
6613 {
6615 
6616  return BFA_STATUS_OK;
6617 }
6618 
6619 /*
6620  * Use this function to delete a vport object. Fabric object should
6621  * be stopped before this function call.
6622  *
6623  * !!!!!!! Donot invoke this from within FCS !!!!!!!
6624  *
6625  * param[in] vport - pointer to bfa_fcs_vport_t.
6626  *
6627  * return None
6628  */
6631 {
6632 
6633  if (vport->lport.port_cfg.preboot_vp)
6634  return BFA_STATUS_PBC;
6635 
6637 
6638  return BFA_STATUS_OK;
6639 }
6640 
6641 /*
6642  * Use this function to get vport's current status info.
6643  *
6644  * param[in] vport pointer to bfa_fcs_vport_t.
6645  * param[out] attr pointer to return vport attributes
6646  *
6647  * return None
6648  */
6649 void
6651  struct bfa_vport_attr_s *attr)
6652 {
6653  if (vport == NULL || attr == NULL)
6654  return;
6655 
6656  memset(attr, 0, sizeof(struct bfa_vport_attr_s));
6657 
6658  bfa_fcs_lport_get_attr(&vport->lport, &attr->port_attr);
6659  attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
6660 }
6661 
6662 
6663 /*
6664  * Lookup a virtual port. Excludes base port from lookup.
6665  */
6666 struct bfa_fcs_vport_s *
6668 {
6669  struct bfa_fcs_vport_s *vport;
6670  struct bfa_fcs_fabric_s *fabric;
6671 
6672  bfa_trc(fcs, vf_id);
6673  bfa_trc(fcs, vpwwn);
6674 
6675  fabric = bfa_fcs_vf_lookup(fcs, vf_id);
6676  if (!fabric) {
6677  bfa_trc(fcs, vf_id);
6678  return NULL;
6679  }
6680 
6681  vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn);
6682  return vport;
6683 }
6684 
6685 /*
6686  * FDISC Response
6687  */
6688 void
6690 {
6691  struct bfa_fcs_vport_s *vport = uarg;
6692 
6693  bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
6694  bfa_trc(__vport_fcs(vport), status);
6695 
6696  switch (status) {
6697  case BFA_STATUS_OK:
6698  /*
6699  * Initialize the V-Port fields
6700  */
6701  __vport_fcid(vport) = vport->lps->lp_pid;
6702  vport->vport_stats.fdisc_accepts++;
6704  break;
6705 
6707  /* Only for CNA */
6708  vport->vport_stats.fdisc_acc_bad++;
6710 
6711  break;
6712 
6713  case BFA_STATUS_EPROTOCOL:
6714  switch (vport->lps->ext_status) {
6715  case BFA_EPROTO_BAD_ACCEPT:
6716  vport->vport_stats.fdisc_acc_bad++;
6717  break;
6718 
6720  vport->vport_stats.fdisc_unknown_rsp++;
6721  break;
6722 
6723  default:
6724  break;
6725  }
6726 
6728  break;
6729 
6730  case BFA_STATUS_FABRIC_RJT:
6731  vport->vport_stats.fdisc_rejects++;
6732  bfa_fcs_vport_fdisc_rejected(vport);
6733  break;
6734 
6735  default:
6736  vport->vport_stats.fdisc_rsp_err++;
6738  }
6739 }
6740 
6741 /*
6742  * LOGO response
6743  */
6744 void
6745 bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
6746 {
6747  struct bfa_fcs_vport_s *vport = uarg;
6749 }
6750 
6751 /*
6752  * Received clear virtual link
6753  */
6754 void
6755 bfa_cb_lps_cvl_event(void *bfad, void *uarg)
6756 {
6757  struct bfa_fcs_vport_s *vport = uarg;
6758 
6759  /* Send an Offline followed by an ONLINE */
6762 }