Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bfa_fcs_rport.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 /*
19  * rport.c Remote port implementation.
20  */
21 
22 #include "bfad_drv.h"
23 #include "bfad_im.h"
24 #include "bfa_fcs.h"
25 #include "bfa_fcbuild.h"
26 
27 BFA_TRC_FILE(FCS, RPORT);
28 
29 static u32
30 bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
31  /* In millisecs */
32 /*
33  * bfa_fcs_rport_max_logins is max count of bfa_fcs_rports
34  * whereas DEF_CFG_NUM_RPORTS is max count of bfa_rports
35  */
36 static u32 bfa_fcs_rport_max_logins = BFA_FCS_MAX_RPORT_LOGINS;
37 
38 /*
39  * forward declarations
40  */
41 static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(
42  struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid);
43 static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
44 static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
45 static void bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport);
46 static void bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport);
47 static void bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport);
48 static void bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport);
49 static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
50  struct fc_logi_s *plogi);
51 static void bfa_fcs_rport_timeout(void *arg);
52 static void bfa_fcs_rport_send_plogi(void *rport_cbarg,
53  struct bfa_fcxp_s *fcxp_alloced);
54 static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
55  struct bfa_fcxp_s *fcxp_alloced);
56 static void bfa_fcs_rport_plogi_response(void *fcsarg,
57  struct bfa_fcxp_s *fcxp, void *cbarg,
58  bfa_status_t req_status, u32 rsp_len,
59  u32 resid_len, struct fchs_s *rsp_fchs);
60 static void bfa_fcs_rport_send_adisc(void *rport_cbarg,
61  struct bfa_fcxp_s *fcxp_alloced);
62 static void bfa_fcs_rport_adisc_response(void *fcsarg,
63  struct bfa_fcxp_s *fcxp, void *cbarg,
64  bfa_status_t req_status, u32 rsp_len,
65  u32 resid_len, struct fchs_s *rsp_fchs);
66 static void bfa_fcs_rport_send_nsdisc(void *rport_cbarg,
67  struct bfa_fcxp_s *fcxp_alloced);
68 static void bfa_fcs_rport_gidpn_response(void *fcsarg,
69  struct bfa_fcxp_s *fcxp, void *cbarg,
70  bfa_status_t req_status, u32 rsp_len,
71  u32 resid_len, struct fchs_s *rsp_fchs);
72 static void bfa_fcs_rport_gpnid_response(void *fcsarg,
73  struct bfa_fcxp_s *fcxp, void *cbarg,
74  bfa_status_t req_status, u32 rsp_len,
75  u32 resid_len, struct fchs_s *rsp_fchs);
76 static void bfa_fcs_rport_send_logo(void *rport_cbarg,
77  struct bfa_fcxp_s *fcxp_alloced);
78 static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
79 static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
80  struct fchs_s *rx_fchs, u16 len);
81 static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
82  struct fchs_s *rx_fchs, u8 reason_code,
83  u8 reason_code_expl);
84 static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
85  struct fchs_s *rx_fchs, u16 len);
86 static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
87 static void bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport);
88 
89 static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
90  enum rport_event event);
91 static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
92  enum rport_event event);
93 static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
94  enum rport_event event);
95 static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
96  enum rport_event event);
97 static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
98  enum rport_event event);
99 static void bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
100  enum rport_event event);
101 static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
102  enum rport_event event);
103 static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
104  enum rport_event event);
105 static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
106  enum rport_event event);
107 static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
108  enum rport_event event);
109 static void bfa_fcs_rport_sm_adisc_online_sending(
110  struct bfa_fcs_rport_s *rport, enum rport_event event);
111 static void bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
112  enum rport_event event);
113 static void bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s
114  *rport, enum rport_event event);
115 static void bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
116  enum rport_event event);
117 static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
118  enum rport_event event);
119 static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
120  enum rport_event event);
121 static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
122  enum rport_event event);
123 static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
124  enum rport_event event);
125 static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
126  enum rport_event event);
127 static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
128  enum rport_event event);
129 static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
130  enum rport_event event);
131 static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
132  enum rport_event event);
133 static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
134  enum rport_event event);
135 static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
136  enum rport_event event);
137 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
138  enum rport_event event);
139 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
140  enum rport_event event);
141 static void bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
142  enum rport_event event);
143 static void bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
144  enum rport_event event);
145 
146 static struct bfa_sm_table_s rport_sm_table[] = {
147  {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
148  {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
149  {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
150  {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
151  {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
152  {BFA_SM(bfa_fcs_rport_sm_fc4_fcs_online), BFA_RPORT_ONLINE},
153  {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
154  {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
155  {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
156  {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
157  {BFA_SM(bfa_fcs_rport_sm_adisc_online_sending), BFA_RPORT_ADISC},
158  {BFA_SM(bfa_fcs_rport_sm_adisc_online), BFA_RPORT_ADISC},
159  {BFA_SM(bfa_fcs_rport_sm_adisc_offline_sending), BFA_RPORT_ADISC},
160  {BFA_SM(bfa_fcs_rport_sm_adisc_offline), BFA_RPORT_ADISC},
161  {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
162  {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
163  {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
164  {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
165  {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
166  {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
167  {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
168  {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
169  {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
170  {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
171  {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
172 };
173 
174 /*
175  * Beginning state.
176  */
177 static void
178 bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
179 {
180  bfa_trc(rport->fcs, rport->pwwn);
181  bfa_trc(rport->fcs, rport->pid);
182  bfa_trc(rport->fcs, event);
183 
184  switch (event) {
186  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
187  rport->plogi_retries = 0;
188  bfa_fcs_rport_send_plogi(rport, NULL);
189  break;
190 
192  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
193  bfa_fcs_rport_fcs_online_action(rport);
194  break;
195 
197  bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
198  bfa_fcs_rport_hal_online(rport);
199  break;
200 
203  bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
204  rport->ns_retries = 0;
205  bfa_fcs_rport_send_nsdisc(rport, NULL);
206  break;
207  default:
208  bfa_sm_fault(rport->fcs, event);
209  }
210 }
211 
212 /*
213  * PLOGI is being sent.
214  */
215 static void
216 bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
217  enum rport_event event)
218 {
219  bfa_trc(rport->fcs, rport->pwwn);
220  bfa_trc(rport->fcs, rport->pid);
221  bfa_trc(rport->fcs, event);
222 
223  switch (event) {
225  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
226  break;
227 
228  case RPSM_EVENT_DELETE:
229  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
230  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
231  bfa_fcs_rport_free(rport);
232  break;
233 
235  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
236  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
237  bfa_fcs_rport_send_plogiacc(rport, NULL);
238  break;
239 
241  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
242  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
243  bfa_timer_start(rport->fcs->bfa, &rport->timer,
244  bfa_fcs_rport_timeout, rport,
245  bfa_fcs_rport_del_timeout);
246  break;
248  case RPSM_EVENT_FAB_SCN:
249  /* query the NS */
250  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
251  WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
253  bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
254  rport->ns_retries = 0;
255  bfa_fcs_rport_send_nsdisc(rport, NULL);
256  break;
257 
258  case RPSM_EVENT_LOGO_IMP:
259  rport->pid = 0;
260  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
261  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
262  bfa_timer_start(rport->fcs->bfa, &rport->timer,
263  bfa_fcs_rport_timeout, rport,
264  bfa_fcs_rport_del_timeout);
265  break;
266 
267 
268  default:
269  bfa_sm_fault(rport->fcs, event);
270  }
271 }
272 
273 /*
274  * PLOGI is being sent.
275  */
276 static void
277 bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
278  enum rport_event event)
279 {
280  bfa_trc(rport->fcs, rport->pwwn);
281  bfa_trc(rport->fcs, rport->pid);
282  bfa_trc(rport->fcs, event);
283 
284  switch (event) {
286  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
287  bfa_fcs_rport_fcs_online_action(rport);
288  break;
289 
290  case RPSM_EVENT_DELETE:
291  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
292  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
293  bfa_fcs_rport_free(rport);
294  break;
295 
298  case RPSM_EVENT_FAB_SCN:
299  /*
300  * Ignore, SCN is possibly online notification.
301  */
302  break;
303 
305  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
306  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
307  bfa_timer_start(rport->fcs->bfa, &rport->timer,
308  bfa_fcs_rport_timeout, rport,
309  bfa_fcs_rport_del_timeout);
310  break;
311 
313  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
314  bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
315  rport->ns_retries = 0;
316  bfa_fcs_rport_send_nsdisc(rport, NULL);
317  break;
318 
319  case RPSM_EVENT_LOGO_IMP:
320  rport->pid = 0;
321  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
322  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
323  bfa_timer_start(rport->fcs->bfa, &rport->timer,
324  bfa_fcs_rport_timeout, rport,
325  bfa_fcs_rport_del_timeout);
326  break;
327 
329  /*
330  * Ignore BFA callback, on a PLOGI receive we call bfa offline.
331  */
332  break;
333 
334  default:
335  bfa_sm_fault(rport->fcs, event);
336  }
337 }
338 
339 /*
340  * PLOGI is sent.
341  */
342 static void
343 bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
344  enum rport_event event)
345 {
346  bfa_trc(rport->fcs, rport->pwwn);
347  bfa_trc(rport->fcs, rport->pid);
348  bfa_trc(rport->fcs, event);
349 
350  switch (event) {
351  case RPSM_EVENT_TIMEOUT:
352  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
353  bfa_fcs_rport_send_plogi(rport, NULL);
354  break;
355 
356  case RPSM_EVENT_DELETE:
357  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
358  bfa_timer_stop(&rport->timer);
359  bfa_fcs_rport_free(rport);
360  break;
361 
364  break;
365 
367  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
368  bfa_timer_stop(&rport->timer);
369  bfa_fcs_rport_send_plogiacc(rport, NULL);
370  break;
371 
373  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
374  bfa_timer_stop(&rport->timer);
375  bfa_timer_start(rport->fcs->bfa, &rport->timer,
376  bfa_fcs_rport_timeout, rport,
377  bfa_fcs_rport_del_timeout);
378  break;
379 
381  case RPSM_EVENT_FAB_SCN:
382  bfa_timer_stop(&rport->timer);
383  WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
385  bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
386  rport->ns_retries = 0;
387  bfa_fcs_rport_send_nsdisc(rport, NULL);
388  break;
389 
390  case RPSM_EVENT_LOGO_IMP:
391  rport->pid = 0;
392  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
393  bfa_timer_stop(&rport->timer);
394  bfa_timer_start(rport->fcs->bfa, &rport->timer,
395  bfa_fcs_rport_timeout, rport,
396  bfa_fcs_rport_del_timeout);
397  break;
398 
400  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
401  bfa_timer_stop(&rport->timer);
402  bfa_fcs_rport_fcs_online_action(rport);
403  break;
404 
405  default:
406  bfa_sm_fault(rport->fcs, event);
407  }
408 }
409 
410 /*
411  * PLOGI is sent.
412  */
413 static void
414 bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
415 {
416  bfa_trc(rport->fcs, rport->pwwn);
417  bfa_trc(rport->fcs, rport->pid);
418  bfa_trc(rport->fcs, event);
419 
420  switch (event) {
421  case RPSM_EVENT_ACCEPTED:
422  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
423  rport->plogi_retries = 0;
424  bfa_fcs_rport_fcs_online_action(rport);
425  break;
426 
428  bfa_fcs_rport_send_logo_acc(rport);
429  /*
430  * !! fall through !!
431  */
433  if (rport->prlo == BFA_TRUE)
434  bfa_fcs_rport_send_prlo_acc(rport);
435 
436  bfa_fcxp_discard(rport->fcxp);
437  /*
438  * !! fall through !!
439  */
440  case RPSM_EVENT_FAILED:
442  rport->plogi_retries++;
443  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
444  bfa_timer_start(rport->fcs->bfa, &rport->timer,
445  bfa_fcs_rport_timeout, rport,
447  } else {
448  bfa_stats(rport->port, rport_del_max_plogi_retry);
449  rport->old_pid = rport->pid;
450  rport->pid = 0;
451  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
452  bfa_timer_start(rport->fcs->bfa, &rport->timer,
453  bfa_fcs_rport_timeout, rport,
454  bfa_fcs_rport_del_timeout);
455  }
456  break;
457 
459  break;
460 
462  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
463  bfa_fcxp_discard(rport->fcxp);
464  bfa_timer_start(rport->fcs->bfa, &rport->timer,
465  bfa_fcs_rport_timeout, rport,
466  bfa_fcs_rport_del_timeout);
467  break;
468 
470  rport->plogi_retries = 0;
471  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
472  bfa_timer_start(rport->fcs->bfa, &rport->timer,
473  bfa_fcs_rport_timeout, rport,
474  (FC_RA_TOV * 1000));
475  break;
476 
477  case RPSM_EVENT_LOGO_IMP:
478  rport->pid = 0;
479  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
480  bfa_fcxp_discard(rport->fcxp);
481  bfa_timer_start(rport->fcs->bfa, &rport->timer,
482  bfa_fcs_rport_timeout, rport,
483  bfa_fcs_rport_del_timeout);
484  break;
485 
487  case RPSM_EVENT_FAB_SCN:
488  bfa_fcxp_discard(rport->fcxp);
489  WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
491  bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
492  rport->ns_retries = 0;
493  bfa_fcs_rport_send_nsdisc(rport, NULL);
494  break;
495 
497  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
498  bfa_fcxp_discard(rport->fcxp);
499  bfa_fcs_rport_send_plogiacc(rport, NULL);
500  break;
501 
502  case RPSM_EVENT_DELETE:
503  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
504  bfa_fcxp_discard(rport->fcxp);
505  bfa_fcs_rport_free(rport);
506  break;
507 
509  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
510  bfa_fcxp_discard(rport->fcxp);
511  bfa_fcs_rport_fcs_online_action(rport);
512  break;
513 
514  default:
515  bfa_sm_fault(rport->fcs, event);
516  }
517 }
518 
519 /*
520  * PLOGI is done. Await bfa_fcs_itnim to ascertain the scsi function
521  */
522 static void
523 bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
524  enum rport_event event)
525 {
526  bfa_trc(rport->fcs, rport->pwwn);
527  bfa_trc(rport->fcs, rport->pid);
528  bfa_trc(rport->fcs, event);
529 
530  switch (event) {
532  if (rport->scsi_function == BFA_RPORT_INITIATOR) {
533  if (!BFA_FCS_PID_IS_WKA(rport->pid))
535  bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
536  break;
537  }
538 
539  if (!rport->bfa_rport)
540  rport->bfa_rport =
541  bfa_rport_create(rport->fcs->bfa, rport);
542 
543  if (rport->bfa_rport) {
544  bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
545  bfa_fcs_rport_hal_online(rport);
546  } else {
547  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
548  bfa_fcs_rport_fcs_offline_action(rport);
549  }
550  break;
551 
553  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
554  rport->plogi_pending = BFA_TRUE;
555  bfa_fcs_rport_fcs_offline_action(rport);
556  break;
557 
559  case RPSM_EVENT_LOGO_IMP:
561  case RPSM_EVENT_FAB_SCN:
563  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
564  bfa_fcs_rport_fcs_offline_action(rport);
565  break;
566 
569  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
570  bfa_fcs_rport_fcs_offline_action(rport);
571  break;
572 
573  case RPSM_EVENT_DELETE:
574  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
575  bfa_fcs_rport_fcs_offline_action(rport);
576  break;
577 
578  default:
579  bfa_sm_fault(rport->fcs, event);
580  break;
581  }
582 }
583 
584 /*
585  * PLOGI is complete. Awaiting BFA rport online callback. FC-4s
586  * are offline.
587  */
588 static void
589 bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
590  enum rport_event event)
591 {
592  bfa_trc(rport->fcs, rport->pwwn);
593  bfa_trc(rport->fcs, rport->pid);
594  bfa_trc(rport->fcs, event);
595 
596  switch (event) {
598  bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
599  bfa_fcs_rport_hal_online_action(rport);
600  break;
601 
603  break;
604 
607  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
608  bfa_fcs_rport_fcs_offline_action(rport);
609  break;
610 
611  case RPSM_EVENT_FAB_SCN:
612  case RPSM_EVENT_LOGO_IMP:
615  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
616  bfa_fcs_rport_fcs_offline_action(rport);
617  break;
618 
620  rport->plogi_pending = BFA_TRUE;
621  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
622  bfa_fcs_rport_fcs_offline_action(rport);
623  break;
624 
625  case RPSM_EVENT_DELETE:
626  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
627  bfa_fcs_rport_fcs_offline_action(rport);
628  break;
629 
630  default:
631  bfa_sm_fault(rport->fcs, event);
632  }
633 }
634 
635 /*
636  * Rport is ONLINE. FC-4s active.
637  */
638 static void
639 bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
640 {
641  bfa_trc(rport->fcs, rport->pwwn);
642  bfa_trc(rport->fcs, rport->pid);
643  bfa_trc(rport->fcs, event);
644 
645  switch (event) {
646  case RPSM_EVENT_FAB_SCN:
647  if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
648  bfa_sm_set_state(rport,
649  bfa_fcs_rport_sm_nsquery_sending);
650  rport->ns_retries = 0;
651  bfa_fcs_rport_send_nsdisc(rport, NULL);
652  } else {
653  bfa_sm_set_state(rport,
654  bfa_fcs_rport_sm_adisc_online_sending);
655  bfa_fcs_rport_send_adisc(rport, NULL);
656  }
657  break;
658 
660  case RPSM_EVENT_LOGO_IMP:
663  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
664  bfa_fcs_rport_hal_offline_action(rport);
665  break;
666 
667  case RPSM_EVENT_DELETE:
668  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
669  bfa_fcs_rport_hal_offline_action(rport);
670  break;
671 
674  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
675  bfa_fcs_rport_hal_offline_action(rport);
676  break;
677 
680  break;
681 
682  default:
683  bfa_sm_fault(rport->fcs, event);
684  }
685 }
686 
687 /*
688  * An SCN event is received in ONLINE state. NS query is being sent
689  * prior to ADISC authentication with rport. FC-4s are paused.
690  */
691 static void
692 bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
693  enum rport_event event)
694 {
695  bfa_trc(rport->fcs, rport->pwwn);
696  bfa_trc(rport->fcs, rport->pid);
697  bfa_trc(rport->fcs, event);
698 
699  switch (event) {
701  bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
702  break;
703 
704  case RPSM_EVENT_DELETE:
705  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
706  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
707  bfa_fcs_rport_hal_offline_action(rport);
708  break;
709 
710  case RPSM_EVENT_FAB_SCN:
711  /*
712  * ignore SCN, wait for response to query itself
713  */
714  break;
715 
718  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
719  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
720  bfa_fcs_rport_hal_offline_action(rport);
721  break;
722 
723  case RPSM_EVENT_LOGO_IMP:
727  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
728  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
729  bfa_fcs_rport_hal_offline_action(rport);
730  break;
731 
732  default:
733  bfa_sm_fault(rport->fcs, event);
734  }
735 }
736 
737 /*
738  * An SCN event is received in ONLINE state. NS query is sent to rport.
739  * FC-4s are paused.
740  */
741 static void
742 bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
743 {
744  bfa_trc(rport->fcs, rport->pwwn);
745  bfa_trc(rport->fcs, rport->pid);
746  bfa_trc(rport->fcs, event);
747 
748  switch (event) {
749  case RPSM_EVENT_ACCEPTED:
750  bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online_sending);
751  bfa_fcs_rport_send_adisc(rport, NULL);
752  break;
753 
754  case RPSM_EVENT_FAILED:
755  rport->ns_retries++;
756  if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
757  bfa_sm_set_state(rport,
758  bfa_fcs_rport_sm_nsquery_sending);
759  bfa_fcs_rport_send_nsdisc(rport, NULL);
760  } else {
761  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
762  bfa_fcs_rport_hal_offline_action(rport);
763  }
764  break;
765 
766  case RPSM_EVENT_DELETE:
767  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
768  bfa_fcxp_discard(rport->fcxp);
769  bfa_fcs_rport_hal_offline_action(rport);
770  break;
771 
772  case RPSM_EVENT_FAB_SCN:
773  break;
774 
777  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
778  bfa_fcxp_discard(rport->fcxp);
779  bfa_fcs_rport_hal_offline_action(rport);
780  break;
781 
785  case RPSM_EVENT_LOGO_IMP:
786  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
787  bfa_fcxp_discard(rport->fcxp);
788  bfa_fcs_rport_hal_offline_action(rport);
789  break;
790 
791  default:
792  bfa_sm_fault(rport->fcs, event);
793  }
794 }
795 
796 /*
797  * An SCN event is received in ONLINE state. ADISC is being sent for
798  * authenticating with rport. FC-4s are paused.
799  */
800 static void
801 bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s *rport,
802  enum rport_event event)
803 {
804  bfa_trc(rport->fcs, rport->pwwn);
805  bfa_trc(rport->fcs, rport->pid);
806  bfa_trc(rport->fcs, event);
807 
808  switch (event) {
810  bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online);
811  break;
812 
813  case RPSM_EVENT_DELETE:
814  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
815  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
816  bfa_fcs_rport_hal_offline_action(rport);
817  break;
818 
819  case RPSM_EVENT_LOGO_IMP:
821  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
822  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
823  bfa_fcs_rport_hal_offline_action(rport);
824  break;
825 
828  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
829  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
830  bfa_fcs_rport_hal_offline_action(rport);
831  break;
832 
833  case RPSM_EVENT_FAB_SCN:
834  break;
835 
837  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
838  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
839  bfa_fcs_rport_hal_offline_action(rport);
840  break;
841 
842  default:
843  bfa_sm_fault(rport->fcs, event);
844  }
845 }
846 
847 /*
848  * An SCN event is received in ONLINE state. ADISC is to rport.
849  * FC-4s are paused.
850  */
851 static void
852 bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
853  enum rport_event event)
854 {
855  bfa_trc(rport->fcs, rport->pwwn);
856  bfa_trc(rport->fcs, rport->pid);
857  bfa_trc(rport->fcs, event);
858 
859  switch (event) {
860  case RPSM_EVENT_ACCEPTED:
861  bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
862  break;
863 
865  /*
866  * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
867  * At least go offline when a PLOGI is received.
868  */
869  bfa_fcxp_discard(rport->fcxp);
870  /*
871  * !!! fall through !!!
872  */
873 
874  case RPSM_EVENT_FAILED:
876  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
877  bfa_fcs_rport_hal_offline_action(rport);
878  break;
879 
880  case RPSM_EVENT_DELETE:
881  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
882  bfa_fcxp_discard(rport->fcxp);
883  bfa_fcs_rport_hal_offline_action(rport);
884  break;
885 
886  case RPSM_EVENT_FAB_SCN:
887  /*
888  * already processing RSCN
889  */
890  break;
891 
892  case RPSM_EVENT_LOGO_IMP:
893  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
894  bfa_fcxp_discard(rport->fcxp);
895  bfa_fcs_rport_hal_offline_action(rport);
896  break;
897 
900  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
901  bfa_fcxp_discard(rport->fcxp);
902  bfa_fcs_rport_hal_offline_action(rport);
903  break;
904 
905  default:
906  bfa_sm_fault(rport->fcs, event);
907  }
908 }
909 
910 /*
911  * ADISC is being sent for authenticating with rport
912  * Already did offline actions.
913  */
914 static void
915 bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s *rport,
916  enum rport_event event)
917 {
918  bfa_trc(rport->fcs, rport->pwwn);
919  bfa_trc(rport->fcs, rport->pid);
920  bfa_trc(rport->fcs, event);
921 
922  switch (event) {
924  bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_offline);
925  break;
926 
927  case RPSM_EVENT_DELETE:
929  case RPSM_EVENT_LOGO_IMP:
932  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
933  bfa_fcxp_walloc_cancel(rport->fcs->bfa,
934  &rport->fcxp_wqe);
935  bfa_timer_start(rport->fcs->bfa, &rport->timer,
936  bfa_fcs_rport_timeout, rport,
937  bfa_fcs_rport_del_timeout);
938  break;
939 
941  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
942  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
943  bfa_fcs_rport_send_plogiacc(rport, NULL);
944  break;
945 
946  default:
947  bfa_sm_fault(rport->fcs, event);
948  }
949 }
950 
951 /*
952  * ADISC to rport
953  * Already did offline actions
954  */
955 static void
956 bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
957  enum rport_event event)
958 {
959  bfa_trc(rport->fcs, rport->pwwn);
960  bfa_trc(rport->fcs, rport->pid);
961  bfa_trc(rport->fcs, event);
962 
963  switch (event) {
964  case RPSM_EVENT_ACCEPTED:
965  bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
966  bfa_fcs_rport_hal_online(rport);
967  break;
968 
970  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
971  bfa_fcxp_discard(rport->fcxp);
972  bfa_fcs_rport_send_plogiacc(rport, NULL);
973  break;
974 
975  case RPSM_EVENT_FAILED:
976  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
977  bfa_timer_start(rport->fcs->bfa, &rport->timer,
978  bfa_fcs_rport_timeout, rport,
979  bfa_fcs_rport_del_timeout);
980  break;
981 
982  case RPSM_EVENT_DELETE:
984  case RPSM_EVENT_LOGO_IMP:
987  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
988  bfa_fcxp_discard(rport->fcxp);
989  bfa_timer_start(rport->fcs->bfa, &rport->timer,
990  bfa_fcs_rport_timeout, rport,
991  bfa_fcs_rport_del_timeout);
992  break;
993 
994  default:
995  bfa_sm_fault(rport->fcs, event);
996  }
997 }
998 
999 /*
1000  * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
1001  */
1002 static void
1003 bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
1004  enum rport_event event)
1005 {
1006  bfa_trc(rport->fcs, rport->pwwn);
1007  bfa_trc(rport->fcs, rport->pid);
1008  bfa_trc(rport->fcs, event);
1009 
1010  switch (event) {
1012  bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
1013  bfa_fcs_rport_hal_offline(rport);
1014  break;
1015 
1016  case RPSM_EVENT_DELETE:
1017  if (rport->pid && (rport->prlo == BFA_TRUE))
1018  bfa_fcs_rport_send_prlo_acc(rport);
1019  if (rport->pid && (rport->prlo == BFA_FALSE))
1020  bfa_fcs_rport_send_logo_acc(rport);
1021 
1022  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
1023  break;
1024 
1025  case RPSM_EVENT_SCN_ONLINE:
1027  case RPSM_EVENT_HCB_ONLINE:
1028  case RPSM_EVENT_LOGO_RCVD:
1029  case RPSM_EVENT_PRLO_RCVD:
1031  break;
1032 
1033  default:
1034  bfa_sm_fault(rport->fcs, event);
1035  }
1036 }
1037 
1038 /*
1039  * LOGO needs to be sent to rport. Awaiting FC-4 offline completion
1040  * callback.
1041  */
1042 static void
1043 bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
1044  enum rport_event event)
1045 {
1046  bfa_trc(rport->fcs, rport->pwwn);
1047  bfa_trc(rport->fcs, rport->pid);
1048  bfa_trc(rport->fcs, event);
1049 
1050  switch (event) {
1052  bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
1053  bfa_fcs_rport_hal_offline(rport);
1054  break;
1055 
1056  case RPSM_EVENT_LOGO_RCVD:
1057  bfa_fcs_rport_send_logo_acc(rport);
1058  case RPSM_EVENT_PRLO_RCVD:
1059  if (rport->prlo == BFA_TRUE)
1060  bfa_fcs_rport_send_prlo_acc(rport);
1061  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
1062  break;
1063 
1064  case RPSM_EVENT_HCB_ONLINE:
1065  case RPSM_EVENT_DELETE:
1066  /* Rport is being deleted */
1067  break;
1068 
1069  default:
1070  bfa_sm_fault(rport->fcs, event);
1071  }
1072 }
1073 
1074 /*
1075  * Rport is going offline. Awaiting FC-4 offline completion callback.
1076  */
1077 static void
1078 bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
1079  enum rport_event event)
1080 {
1081  bfa_trc(rport->fcs, rport->pwwn);
1082  bfa_trc(rport->fcs, rport->pid);
1083  bfa_trc(rport->fcs, event);
1084 
1085  switch (event) {
1087  bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1088  bfa_fcs_rport_hal_offline(rport);
1089  break;
1090 
1091  case RPSM_EVENT_SCN_ONLINE:
1092  break;
1093  case RPSM_EVENT_LOGO_RCVD:
1094  /*
1095  * Rport is going offline. Just ack the logo
1096  */
1097  bfa_fcs_rport_send_logo_acc(rport);
1098  break;
1099 
1100  case RPSM_EVENT_PRLO_RCVD:
1101  bfa_fcs_rport_send_prlo_acc(rport);
1102  break;
1103 
1105  case RPSM_EVENT_HCB_ONLINE:
1106  case RPSM_EVENT_FAB_SCN:
1107  case RPSM_EVENT_LOGO_IMP:
1109  /*
1110  * rport is already going offline.
1111  * SCN - ignore and wait till transitioning to offline state
1112  */
1113  break;
1114 
1115  case RPSM_EVENT_DELETE:
1116  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
1117  break;
1118 
1119  default:
1120  bfa_sm_fault(rport->fcs, event);
1121  }
1122 }
1123 
1124 /*
1125  * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
1126  * callback.
1127  */
1128 static void
1129 bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
1130  enum rport_event event)
1131 {
1132  bfa_trc(rport->fcs, rport->pwwn);
1133  bfa_trc(rport->fcs, rport->pid);
1134  bfa_trc(rport->fcs, event);
1135 
1136  switch (event) {
1138  if (bfa_fcs_lport_is_online(rport->port) &&
1139  (rport->plogi_pending)) {
1140  rport->plogi_pending = BFA_FALSE;
1141  bfa_sm_set_state(rport,
1142  bfa_fcs_rport_sm_plogiacc_sending);
1143  bfa_fcs_rport_send_plogiacc(rport, NULL);
1144  break;
1145  }
1146  /*
1147  * !! fall through !!
1148  */
1149 
1151  if (!bfa_fcs_lport_is_online(rport->port)) {
1152  rport->pid = 0;
1153  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1154  bfa_timer_start(rport->fcs->bfa, &rport->timer,
1155  bfa_fcs_rport_timeout, rport,
1156  bfa_fcs_rport_del_timeout);
1157  break;
1158  }
1159  if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
1160  bfa_sm_set_state(rport,
1161  bfa_fcs_rport_sm_nsdisc_sending);
1162  rport->ns_retries = 0;
1163  bfa_fcs_rport_send_nsdisc(rport, NULL);
1164  } else if (bfa_fcport_get_topology(rport->port->fcs->bfa) ==
1166  if (rport->scn_online) {
1167  bfa_sm_set_state(rport,
1168  bfa_fcs_rport_sm_adisc_offline_sending);
1169  bfa_fcs_rport_send_adisc(rport, NULL);
1170  } else {
1171  bfa_sm_set_state(rport,
1172  bfa_fcs_rport_sm_offline);
1173  bfa_timer_start(rport->fcs->bfa, &rport->timer,
1174  bfa_fcs_rport_timeout, rport,
1175  bfa_fcs_rport_del_timeout);
1176  }
1177  } else {
1178  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1179  rport->plogi_retries = 0;
1180  bfa_fcs_rport_send_plogi(rport, NULL);
1181  }
1182  break;
1183 
1184  case RPSM_EVENT_DELETE:
1185  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1186  bfa_fcs_rport_free(rport);
1187  break;
1188 
1189  case RPSM_EVENT_SCN_ONLINE:
1191  case RPSM_EVENT_FAB_SCN:
1192  case RPSM_EVENT_LOGO_RCVD:
1193  case RPSM_EVENT_PRLO_RCVD:
1194  case RPSM_EVENT_PLOGI_RCVD:
1195  case RPSM_EVENT_LOGO_IMP:
1196  /*
1197  * Ignore, already offline.
1198  */
1199  break;
1200 
1201  default:
1202  bfa_sm_fault(rport->fcs, event);
1203  }
1204 }
1205 
1206 /*
1207  * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
1208  * callback to send LOGO accept.
1209  */
1210 static void
1211 bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
1212  enum rport_event event)
1213 {
1214  bfa_trc(rport->fcs, rport->pwwn);
1215  bfa_trc(rport->fcs, rport->pid);
1216  bfa_trc(rport->fcs, event);
1217 
1218  switch (event) {
1221  if (rport->pid && (rport->prlo == BFA_TRUE))
1222  bfa_fcs_rport_send_prlo_acc(rport);
1223  if (rport->pid && (rport->prlo == BFA_FALSE))
1224  bfa_fcs_rport_send_logo_acc(rport);
1225  /*
1226  * If the lport is online and if the rport is not a well
1227  * known address port,
1228  * we try to re-discover the r-port.
1229  */
1230  if (bfa_fcs_lport_is_online(rport->port) &&
1231  (!BFA_FCS_PID_IS_WKA(rport->pid))) {
1232  if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
1233  bfa_sm_set_state(rport,
1234  bfa_fcs_rport_sm_nsdisc_sending);
1235  rport->ns_retries = 0;
1236  bfa_fcs_rport_send_nsdisc(rport, NULL);
1237  } else {
1238  /* For N2N Direct Attach, try to re-login */
1239  bfa_sm_set_state(rport,
1240  bfa_fcs_rport_sm_plogi_sending);
1241  rport->plogi_retries = 0;
1242  bfa_fcs_rport_send_plogi(rport, NULL);
1243  }
1244  } else {
1245  /*
1246  * if it is not a well known address, reset the
1247  * pid to 0.
1248  */
1249  if (!BFA_FCS_PID_IS_WKA(rport->pid))
1250  rport->pid = 0;
1251  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1252  bfa_timer_start(rport->fcs->bfa, &rport->timer,
1253  bfa_fcs_rport_timeout, rport,
1254  bfa_fcs_rport_del_timeout);
1255  }
1256  break;
1257 
1258  case RPSM_EVENT_DELETE:
1259  bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
1260  if (rport->pid && (rport->prlo == BFA_TRUE))
1261  bfa_fcs_rport_send_prlo_acc(rport);
1262  if (rport->pid && (rport->prlo == BFA_FALSE))
1263  bfa_fcs_rport_send_logo_acc(rport);
1264  break;
1265 
1266  case RPSM_EVENT_LOGO_IMP:
1267  bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1268  break;
1269 
1270  case RPSM_EVENT_SCN_ONLINE:
1272  case RPSM_EVENT_LOGO_RCVD:
1273  case RPSM_EVENT_PRLO_RCVD:
1274  /*
1275  * Ignore - already processing a LOGO.
1276  */
1277  break;
1278 
1279  default:
1280  bfa_sm_fault(rport->fcs, event);
1281  }
1282 }
1283 
1284 /*
1285  * Rport is being deleted. FC-4s are offline.
1286  * Awaiting BFA rport offline
1287  * callback to send LOGO.
1288  */
1289 static void
1290 bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1291  enum rport_event event)
1292 {
1293  bfa_trc(rport->fcs, rport->pwwn);
1294  bfa_trc(rport->fcs, rport->pid);
1295  bfa_trc(rport->fcs, event);
1296 
1297  switch (event) {
1299  bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
1300  bfa_fcs_rport_send_logo(rport, NULL);
1301  break;
1302 
1303  case RPSM_EVENT_LOGO_RCVD:
1304  bfa_fcs_rport_send_logo_acc(rport);
1305  case RPSM_EVENT_PRLO_RCVD:
1306  if (rport->prlo == BFA_TRUE)
1307  bfa_fcs_rport_send_prlo_acc(rport);
1308 
1309  bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
1310  break;
1311 
1312  case RPSM_EVENT_SCN_ONLINE:
1315  break;
1316 
1317  default:
1318  bfa_sm_fault(rport->fcs, event);
1319  }
1320 }
1321 
1322 /*
1323  * Rport is being deleted. FC-4s are offline. LOGO is being sent.
1324  */
1325 static void
1326 bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1327  enum rport_event event)
1328 {
1329  bfa_trc(rport->fcs, rport->pwwn);
1330  bfa_trc(rport->fcs, rport->pid);
1331  bfa_trc(rport->fcs, event);
1332 
1333  switch (event) {
1334  case RPSM_EVENT_FCXP_SENT:
1335  /* Once LOGO is sent, we donot wait for the response */
1336  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1337  bfa_fcs_rport_free(rport);
1338  break;
1339 
1340  case RPSM_EVENT_SCN_ONLINE:
1342  case RPSM_EVENT_FAB_SCN:
1344  break;
1345 
1346  case RPSM_EVENT_LOGO_RCVD:
1347  bfa_fcs_rport_send_logo_acc(rport);
1348  case RPSM_EVENT_PRLO_RCVD:
1349  if (rport->prlo == BFA_TRUE)
1350  bfa_fcs_rport_send_prlo_acc(rport);
1351 
1352  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1353  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1354  bfa_fcs_rport_free(rport);
1355  break;
1356 
1357  default:
1358  bfa_sm_fault(rport->fcs, event);
1359  }
1360 }
1361 
1362 /*
1363  * Rport is offline. FC-4s are offline. BFA rport is offline.
1364  * Timer active to delete stale rport.
1365  */
1366 static void
1367 bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1368 {
1369  bfa_trc(rport->fcs, rport->pwwn);
1370  bfa_trc(rport->fcs, rport->pid);
1371  bfa_trc(rport->fcs, event);
1372 
1373  switch (event) {
1374  case RPSM_EVENT_TIMEOUT:
1375  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1376  bfa_fcs_rport_free(rport);
1377  break;
1378 
1379  case RPSM_EVENT_FAB_SCN:
1381  bfa_timer_stop(&rport->timer);
1382  WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
1384  bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1385  rport->ns_retries = 0;
1386  bfa_fcs_rport_send_nsdisc(rport, NULL);
1387  break;
1388 
1389  case RPSM_EVENT_DELETE:
1390  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1391  bfa_timer_stop(&rport->timer);
1392  bfa_fcs_rport_free(rport);
1393  break;
1394 
1395  case RPSM_EVENT_PLOGI_RCVD:
1396  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1397  bfa_timer_stop(&rport->timer);
1398  bfa_fcs_rport_send_plogiacc(rport, NULL);
1399  break;
1400 
1401  case RPSM_EVENT_LOGO_RCVD:
1402  case RPSM_EVENT_PRLO_RCVD:
1403  case RPSM_EVENT_LOGO_IMP:
1405  break;
1406 
1407  case RPSM_EVENT_PLOGI_COMP:
1408  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1409  bfa_timer_stop(&rport->timer);
1410  bfa_fcs_rport_fcs_online_action(rport);
1411  break;
1412 
1413  case RPSM_EVENT_SCN_ONLINE:
1414  bfa_timer_stop(&rport->timer);
1415  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1416  bfa_fcs_rport_send_plogi(rport, NULL);
1417  break;
1418 
1419  case RPSM_EVENT_PLOGI_SEND:
1420  bfa_timer_stop(&rport->timer);
1421  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1422  rport->plogi_retries = 0;
1423  bfa_fcs_rport_send_plogi(rport, NULL);
1424  break;
1425 
1426  default:
1427  bfa_sm_fault(rport->fcs, event);
1428  }
1429 }
1430 
1431 /*
1432  * Rport address has changed. Nameserver discovery request is being sent.
1433  */
1434 static void
1435 bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1436  enum rport_event event)
1437 {
1438  bfa_trc(rport->fcs, rport->pwwn);
1439  bfa_trc(rport->fcs, rport->pid);
1440  bfa_trc(rport->fcs, event);
1441 
1442  switch (event) {
1443  case RPSM_EVENT_FCXP_SENT:
1444  bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent);
1445  break;
1446 
1447  case RPSM_EVENT_DELETE:
1448  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1449  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1450  bfa_fcs_rport_free(rport);
1451  break;
1452 
1453  case RPSM_EVENT_PLOGI_RCVD:
1454  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1455  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1456  bfa_fcs_rport_send_plogiacc(rport, NULL);
1457  break;
1458 
1459  case RPSM_EVENT_FAB_SCN:
1460  case RPSM_EVENT_LOGO_RCVD:
1461  case RPSM_EVENT_PRLO_RCVD:
1462  case RPSM_EVENT_PLOGI_SEND:
1463  break;
1464 
1466  rport->ns_retries = 0; /* reset the retry count */
1467  break;
1468 
1469  case RPSM_EVENT_LOGO_IMP:
1470  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1471  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1472  bfa_timer_start(rport->fcs->bfa, &rport->timer,
1473  bfa_fcs_rport_timeout, rport,
1474  bfa_fcs_rport_del_timeout);
1475  break;
1476 
1477  case RPSM_EVENT_PLOGI_COMP:
1478  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1479  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1480  bfa_fcs_rport_fcs_online_action(rport);
1481  break;
1482 
1483  default:
1484  bfa_sm_fault(rport->fcs, event);
1485  }
1486 }
1487 
1488 /*
1489  * Nameserver discovery failed. Waiting for timeout to retry.
1490  */
1491 static void
1492 bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1493  enum rport_event event)
1494 {
1495  bfa_trc(rport->fcs, rport->pwwn);
1496  bfa_trc(rport->fcs, rport->pid);
1497  bfa_trc(rport->fcs, event);
1498 
1499  switch (event) {
1500  case RPSM_EVENT_TIMEOUT:
1501  bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1502  bfa_fcs_rport_send_nsdisc(rport, NULL);
1503  break;
1504 
1505  case RPSM_EVENT_FAB_SCN:
1507  bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1508  bfa_timer_stop(&rport->timer);
1509  rport->ns_retries = 0;
1510  bfa_fcs_rport_send_nsdisc(rport, NULL);
1511  break;
1512 
1513  case RPSM_EVENT_DELETE:
1514  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1515  bfa_timer_stop(&rport->timer);
1516  bfa_fcs_rport_free(rport);
1517  break;
1518 
1519  case RPSM_EVENT_PLOGI_RCVD:
1520  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1521  bfa_timer_stop(&rport->timer);
1522  bfa_fcs_rport_send_plogiacc(rport, NULL);
1523  break;
1524 
1525  case RPSM_EVENT_LOGO_IMP:
1526  rport->pid = 0;
1527  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1528  bfa_timer_stop(&rport->timer);
1529  bfa_timer_start(rport->fcs->bfa, &rport->timer,
1530  bfa_fcs_rport_timeout, rport,
1531  bfa_fcs_rport_del_timeout);
1532  break;
1533 
1534  case RPSM_EVENT_LOGO_RCVD:
1535  bfa_fcs_rport_send_logo_acc(rport);
1536  break;
1537  case RPSM_EVENT_PRLO_RCVD:
1538  bfa_fcs_rport_send_prlo_acc(rport);
1539  break;
1540 
1541  case RPSM_EVENT_PLOGI_COMP:
1542  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1543  bfa_timer_stop(&rport->timer);
1544  bfa_fcs_rport_fcs_online_action(rport);
1545  break;
1546 
1547  default:
1548  bfa_sm_fault(rport->fcs, event);
1549  }
1550 }
1551 
1552 /*
1553  * Rport address has changed. Nameserver discovery request is sent.
1554  */
1555 static void
1556 bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1557  enum rport_event event)
1558 {
1559  bfa_trc(rport->fcs, rport->pwwn);
1560  bfa_trc(rport->fcs, rport->pid);
1561  bfa_trc(rport->fcs, event);
1562 
1563  switch (event) {
1564  case RPSM_EVENT_ACCEPTED:
1566  if (rport->pid) {
1567  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1568  bfa_fcs_rport_send_plogi(rport, NULL);
1569  } else {
1570  bfa_sm_set_state(rport,
1571  bfa_fcs_rport_sm_nsdisc_sending);
1572  rport->ns_retries = 0;
1573  bfa_fcs_rport_send_nsdisc(rport, NULL);
1574  }
1575  break;
1576 
1577  case RPSM_EVENT_FAILED:
1578  rport->ns_retries++;
1579  if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
1580  bfa_sm_set_state(rport,
1581  bfa_fcs_rport_sm_nsdisc_sending);
1582  bfa_fcs_rport_send_nsdisc(rport, NULL);
1583  } else {
1584  rport->old_pid = rport->pid;
1585  rport->pid = 0;
1586  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1587  bfa_timer_start(rport->fcs->bfa, &rport->timer,
1588  bfa_fcs_rport_timeout, rport,
1589  bfa_fcs_rport_del_timeout);
1590  };
1591  break;
1592 
1593  case RPSM_EVENT_DELETE:
1594  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1595  bfa_fcxp_discard(rport->fcxp);
1596  bfa_fcs_rport_free(rport);
1597  break;
1598 
1599  case RPSM_EVENT_PLOGI_RCVD:
1600  bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1601  bfa_fcxp_discard(rport->fcxp);
1602  bfa_fcs_rport_send_plogiacc(rport, NULL);
1603  break;
1604 
1605  case RPSM_EVENT_LOGO_IMP:
1606  rport->pid = 0;
1607  bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1608  bfa_fcxp_discard(rport->fcxp);
1609  bfa_timer_start(rport->fcs->bfa, &rport->timer,
1610  bfa_fcs_rport_timeout, rport,
1611  bfa_fcs_rport_del_timeout);
1612  break;
1613 
1614 
1615  case RPSM_EVENT_PRLO_RCVD:
1616  bfa_fcs_rport_send_prlo_acc(rport);
1617  break;
1618  case RPSM_EVENT_FAB_SCN:
1619  /*
1620  * ignore, wait for NS query response
1621  */
1622  break;
1623 
1624  case RPSM_EVENT_LOGO_RCVD:
1625  /*
1626  * Not logged-in yet. Accept LOGO.
1627  */
1628  bfa_fcs_rport_send_logo_acc(rport);
1629  break;
1630 
1631  case RPSM_EVENT_PLOGI_COMP:
1632  bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1633  bfa_fcxp_discard(rport->fcxp);
1634  bfa_fcs_rport_fcs_online_action(rport);
1635  break;
1636 
1637  default:
1638  bfa_sm_fault(rport->fcs, event);
1639  }
1640 }
1641 
1642 /*
1643  * Rport needs to be deleted
1644  * waiting for ITNIM clean up to finish
1645  */
1646 static void
1647 bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
1648  enum rport_event event)
1649 {
1650  bfa_trc(rport->fcs, rport->pwwn);
1651  bfa_trc(rport->fcs, rport->pid);
1652  bfa_trc(rport->fcs, event);
1653 
1654  switch (event) {
1656  bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
1657  bfa_fcs_rport_hal_offline(rport);
1658  break;
1659 
1660  case RPSM_EVENT_DELETE:
1661  case RPSM_EVENT_PLOGI_RCVD:
1662  /* Ignore these events */
1663  break;
1664 
1665  default:
1666  bfa_sm_fault(rport->fcs, event);
1667  break;
1668  }
1669 }
1670 
1671 /*
1672  * RPort needs to be deleted
1673  * waiting for BFA/FW to finish current processing
1674  */
1675 static void
1676 bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
1677  enum rport_event event)
1678 {
1679  bfa_trc(rport->fcs, rport->pwwn);
1680  bfa_trc(rport->fcs, rport->pid);
1681  bfa_trc(rport->fcs, event);
1682 
1683  switch (event) {
1685  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1686  bfa_fcs_rport_free(rport);
1687  break;
1688 
1689  case RPSM_EVENT_DELETE:
1690  case RPSM_EVENT_LOGO_IMP:
1691  case RPSM_EVENT_PLOGI_RCVD:
1692  /* Ignore these events */
1693  break;
1694 
1695  default:
1696  bfa_sm_fault(rport->fcs, event);
1697  }
1698 }
1699 
1700 /*
1701  * fcs_rport_private FCS RPORT provate functions
1702  */
1703 
1704 static void
1705 bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1706 {
1707  struct bfa_fcs_rport_s *rport = rport_cbarg;
1708  struct bfa_fcs_lport_s *port = rport->port;
1709  struct fchs_s fchs;
1710  int len;
1711  struct bfa_fcxp_s *fcxp;
1712 
1713  bfa_trc(rport->fcs, rport->pwwn);
1714 
1715  fcxp = fcxp_alloced ? fcxp_alloced :
1717  if (!fcxp) {
1718  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1719  bfa_fcs_rport_send_plogi, rport, BFA_TRUE);
1720  return;
1721  }
1722  rport->fcxp = fcxp;
1723 
1724  len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1725  bfa_fcs_lport_get_fcid(port), 0,
1726  port->port_cfg.pwwn, port->port_cfg.nwwn,
1727  bfa_fcport_get_maxfrsize(port->fcs->bfa),
1728  bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1729 
1730  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1731  FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
1732  (void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1733 
1734  rport->stats.plogis++;
1736 }
1737 
1738 static void
1739 bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1740  bfa_status_t req_status, u32 rsp_len,
1741  u32 resid_len, struct fchs_s *rsp_fchs)
1742 {
1743  struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1744  struct fc_logi_s *plogi_rsp;
1745  struct fc_ls_rjt_s *ls_rjt;
1746  struct bfa_fcs_rport_s *twin;
1747  struct list_head *qe;
1748 
1749  bfa_trc(rport->fcs, rport->pwwn);
1750 
1751  /*
1752  * Sanity Checks
1753  */
1754  if (req_status != BFA_STATUS_OK) {
1755  bfa_trc(rport->fcs, req_status);
1756  rport->stats.plogi_failed++;
1758  return;
1759  }
1760 
1761  plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
1762 
1763  /*
1764  * Check for failure first.
1765  */
1766  if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
1767  ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
1768 
1769  bfa_trc(rport->fcs, ls_rjt->reason_code);
1770  bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1771 
1772  if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) &&
1774  rport->stats.rjt_insuff_res++;
1776  return;
1777  }
1778 
1779  rport->stats.plogi_rejects++;
1781  return;
1782  }
1783 
1784  /*
1785  * PLOGI is complete. Make sure this device is not one of the known
1786  * device with a new FC port address.
1787  */
1788  list_for_each(qe, &rport->port->rport_q) {
1789  twin = (struct bfa_fcs_rport_s *) qe;
1790  if (twin == rport)
1791  continue;
1792  if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
1793  bfa_trc(rport->fcs, twin->pid);
1794  bfa_trc(rport->fcs, rport->pid);
1795 
1796  /* Update plogi stats in twin */
1797  twin->stats.plogis += rport->stats.plogis;
1798  twin->stats.plogi_rejects +=
1799  rport->stats.plogi_rejects;
1800  twin->stats.plogi_timeouts +=
1801  rport->stats.plogi_timeouts;
1802  twin->stats.plogi_failed +=
1803  rport->stats.plogi_failed;
1804  twin->stats.plogi_rcvd += rport->stats.plogi_rcvd;
1805  twin->stats.plogi_accs++;
1806 
1808 
1809  bfa_fcs_rport_update(twin, plogi_rsp);
1810  twin->pid = rsp_fchs->s_id;
1812  return;
1813  }
1814  }
1815 
1816  /*
1817  * Normal login path -- no evil twins.
1818  */
1819  rport->stats.plogi_accs++;
1820  bfa_fcs_rport_update(rport, plogi_rsp);
1822 }
1823 
1824 static void
1825 bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1826 {
1827  struct bfa_fcs_rport_s *rport = rport_cbarg;
1828  struct bfa_fcs_lport_s *port = rport->port;
1829  struct fchs_s fchs;
1830  int len;
1831  struct bfa_fcxp_s *fcxp;
1832 
1833  bfa_trc(rport->fcs, rport->pwwn);
1834  bfa_trc(rport->fcs, rport->reply_oxid);
1835 
1836  fcxp = fcxp_alloced ? fcxp_alloced :
1838  if (!fcxp) {
1839  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1840  bfa_fcs_rport_send_plogiacc, rport, BFA_FALSE);
1841  return;
1842  }
1843  rport->fcxp = fcxp;
1844 
1845  len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1846  rport->pid, bfa_fcs_lport_get_fcid(port),
1847  rport->reply_oxid, port->port_cfg.pwwn,
1848  port->port_cfg.nwwn,
1849  bfa_fcport_get_maxfrsize(port->fcs->bfa),
1850  bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1851 
1852  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1853  FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1854 
1856 }
1857 
1858 static void
1859 bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1860 {
1861  struct bfa_fcs_rport_s *rport = rport_cbarg;
1862  struct bfa_fcs_lport_s *port = rport->port;
1863  struct fchs_s fchs;
1864  int len;
1865  struct bfa_fcxp_s *fcxp;
1866 
1867  bfa_trc(rport->fcs, rport->pwwn);
1868 
1869  fcxp = fcxp_alloced ? fcxp_alloced :
1871  if (!fcxp) {
1872  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1873  bfa_fcs_rport_send_adisc, rport, BFA_TRUE);
1874  return;
1875  }
1876  rport->fcxp = fcxp;
1877 
1878  len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1879  bfa_fcs_lport_get_fcid(port), 0,
1880  port->port_cfg.pwwn, port->port_cfg.nwwn);
1881 
1882  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1883  FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
1884  rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1885 
1886  rport->stats.adisc_sent++;
1888 }
1889 
1890 static void
1891 bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1892  bfa_status_t req_status, u32 rsp_len,
1893  u32 resid_len, struct fchs_s *rsp_fchs)
1894 {
1895  struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1896  void *pld = bfa_fcxp_get_rspbuf(fcxp);
1897  struct fc_ls_rjt_s *ls_rjt;
1898 
1899  if (req_status != BFA_STATUS_OK) {
1900  bfa_trc(rport->fcs, req_status);
1901  rport->stats.adisc_failed++;
1903  return;
1904  }
1905 
1906  if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
1907  rport->nwwn) == FC_PARSE_OK) {
1908  rport->stats.adisc_accs++;
1910  return;
1911  }
1912 
1913  rport->stats.adisc_rejects++;
1914  ls_rjt = pld;
1915  bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
1916  bfa_trc(rport->fcs, ls_rjt->reason_code);
1917  bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1919 }
1920 
1921 static void
1922 bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1923 {
1924  struct bfa_fcs_rport_s *rport = rport_cbarg;
1925  struct bfa_fcs_lport_s *port = rport->port;
1926  struct fchs_s fchs;
1927  struct bfa_fcxp_s *fcxp;
1928  int len;
1929  bfa_cb_fcxp_send_t cbfn;
1930 
1931  bfa_trc(rport->fcs, rport->pid);
1932 
1933  fcxp = fcxp_alloced ? fcxp_alloced :
1935  if (!fcxp) {
1936  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1937  bfa_fcs_rport_send_nsdisc, rport, BFA_TRUE);
1938  return;
1939  }
1940  rport->fcxp = fcxp;
1941 
1942  if (rport->pwwn) {
1943  len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1944  bfa_fcs_lport_get_fcid(port), 0, rport->pwwn);
1945  cbfn = bfa_fcs_rport_gidpn_response;
1946  } else {
1947  len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1948  bfa_fcs_lport_get_fcid(port), 0, rport->pid);
1949  cbfn = bfa_fcs_rport_gpnid_response;
1950  }
1951 
1952  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1953  FC_CLASS_3, len, &fchs, cbfn,
1954  (void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV);
1955 
1957 }
1958 
1959 static void
1960 bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1961  bfa_status_t req_status, u32 rsp_len,
1962  u32 resid_len, struct fchs_s *rsp_fchs)
1963 {
1964  struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1965  struct ct_hdr_s *cthdr;
1966  struct fcgs_gidpn_resp_s *gidpn_rsp;
1967  struct bfa_fcs_rport_s *twin;
1968  struct list_head *qe;
1969 
1970  bfa_trc(rport->fcs, rport->pwwn);
1971 
1972  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1973  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1974 
1975  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1976  /* Check if the pid is the same as before. */
1977  gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
1978 
1979  if (gidpn_rsp->dap == rport->pid) {
1980  /* Device is online */
1982  } else {
1983  /*
1984  * Device's PID has changed. We need to cleanup
1985  * and re-login. If there is another device with
1986  * the the newly discovered pid, send an scn notice
1987  * so that its new pid can be discovered.
1988  */
1989  list_for_each(qe, &rport->port->rport_q) {
1990  twin = (struct bfa_fcs_rport_s *) qe;
1991  if (twin == rport)
1992  continue;
1993  if (gidpn_rsp->dap == twin->pid) {
1994  bfa_trc(rport->fcs, twin->pid);
1995  bfa_trc(rport->fcs, rport->pid);
1996 
1997  twin->pid = 0;
1998  bfa_sm_send_event(twin,
2000  }
2001  }
2002  rport->pid = gidpn_rsp->dap;
2004  }
2005  return;
2006  }
2007 
2008  /*
2009  * Reject Response
2010  */
2011  switch (cthdr->reason_code) {
2012  case CT_RSN_LOGICAL_BUSY:
2013  /*
2014  * Need to retry
2015  */
2017  break;
2018 
2019  case CT_RSN_UNABLE_TO_PERF:
2020  /*
2021  * device doesn't exist : Start timer to cleanup this later.
2022  */
2024  break;
2025 
2026  default:
2028  break;
2029  }
2030 }
2031 
2032 static void
2033 bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
2034  bfa_status_t req_status, u32 rsp_len,
2035  u32 resid_len, struct fchs_s *rsp_fchs)
2036 {
2037  struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2038  struct ct_hdr_s *cthdr;
2039 
2040  bfa_trc(rport->fcs, rport->pwwn);
2041 
2042  cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2043  cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2044 
2045  if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2047  return;
2048  }
2049 
2050  /*
2051  * Reject Response
2052  */
2053  switch (cthdr->reason_code) {
2054  case CT_RSN_LOGICAL_BUSY:
2055  /*
2056  * Need to retry
2057  */
2059  break;
2060 
2061  case CT_RSN_UNABLE_TO_PERF:
2062  /*
2063  * device doesn't exist : Start timer to cleanup this later.
2064  */
2066  break;
2067 
2068  default:
2070  break;
2071  }
2072 }
2073 
2074 /*
2075  * Called to send a logout to the rport.
2076  */
2077 static void
2078 bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2079 {
2080  struct bfa_fcs_rport_s *rport = rport_cbarg;
2081  struct bfa_fcs_lport_s *port;
2082  struct fchs_s fchs;
2083  struct bfa_fcxp_s *fcxp;
2084  u16 len;
2085 
2086  bfa_trc(rport->fcs, rport->pid);
2087 
2088  port = rport->port;
2089 
2090  fcxp = fcxp_alloced ? fcxp_alloced :
2092  if (!fcxp) {
2093  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
2094  bfa_fcs_rport_send_logo, rport, BFA_FALSE);
2095  return;
2096  }
2097  rport->fcxp = fcxp;
2098 
2099  len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
2100  bfa_fcs_lport_get_fcid(port), 0,
2101  bfa_fcs_lport_get_pwwn(port));
2102 
2103  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2104  FC_CLASS_3, len, &fchs, NULL,
2105  rport, FC_MAX_PDUSZ, FC_ELS_TOV);
2106 
2107  rport->stats.logos++;
2108  bfa_fcxp_discard(rport->fcxp);
2110 }
2111 
2112 /*
2113  * Send ACC for a LOGO received.
2114  */
2115 static void
2116 bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
2117 {
2118  struct bfa_fcs_rport_s *rport = rport_cbarg;
2119  struct bfa_fcs_lport_s *port;
2120  struct fchs_s fchs;
2121  struct bfa_fcxp_s *fcxp;
2122  u16 len;
2123 
2124  bfa_trc(rport->fcs, rport->pid);
2125 
2126  port = rport->port;
2127 
2128  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2129  if (!fcxp)
2130  return;
2131 
2132  rport->stats.logo_rcvd++;
2133  len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2134  rport->pid, bfa_fcs_lport_get_fcid(port),
2135  rport->reply_oxid);
2136 
2137  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2138  FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2139 }
2140 
2141 /*
2142  * brief
2143  * This routine will be called by bfa_timer on timer timeouts.
2144  *
2145  * param[in] rport - pointer to bfa_fcs_lport_ns_t.
2146  * param[out] rport_status - pointer to return vport status in
2147  *
2148  * return
2149  * void
2150  *
2151  * Special Considerations:
2152  *
2153  * note
2154  */
2155 static void
2156 bfa_fcs_rport_timeout(void *arg)
2157 {
2158  struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg;
2159 
2160  rport->stats.plogi_timeouts++;
2161  bfa_stats(rport->port, rport_plogi_timeouts);
2163 }
2164 
2165 static void
2166 bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
2167  struct fchs_s *rx_fchs, u16 len)
2168 {
2169  struct bfa_fcxp_s *fcxp;
2170  struct fchs_s fchs;
2171  struct bfa_fcs_lport_s *port = rport->port;
2172  struct fc_prli_s *prli;
2173 
2174  bfa_trc(port->fcs, rx_fchs->s_id);
2175  bfa_trc(port->fcs, rx_fchs->d_id);
2176 
2177  rport->stats.prli_rcvd++;
2178 
2179  /*
2180  * We are in Initiator Mode
2181  */
2182  prli = (struct fc_prli_s *) (rx_fchs + 1);
2183 
2184  if (prli->parampage.servparams.target) {
2185  /*
2186  * PRLI from a target ?
2187  * Send the Acc.
2188  * PRLI sent by us will be used to transition the IT nexus,
2189  * once the response is received from the target.
2190  */
2191  bfa_trc(port->fcs, rx_fchs->s_id);
2193  } else {
2194  bfa_trc(rport->fcs, prli->parampage.type);
2197  }
2198 
2199  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2200  if (!fcxp)
2201  return;
2202 
2203  len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2204  rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2205  rx_fchs->ox_id, port->port_cfg.roles);
2206 
2207  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2208  FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2209 }
2210 
2211 static void
2212 bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
2213  struct fchs_s *rx_fchs, u16 len)
2214 {
2215  struct bfa_fcxp_s *fcxp;
2216  struct fchs_s fchs;
2217  struct bfa_fcs_lport_s *port = rport->port;
2218  struct fc_rpsc_speed_info_s speeds;
2219  struct bfa_port_attr_s pport_attr;
2220 
2221  bfa_trc(port->fcs, rx_fchs->s_id);
2222  bfa_trc(port->fcs, rx_fchs->d_id);
2223 
2224  rport->stats.rpsc_rcvd++;
2225  speeds.port_speed_cap =
2228 
2229  /*
2230  * get curent speed from pport attributes from BFA
2231  */
2232  bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2233 
2234  speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
2235 
2236  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2237  if (!fcxp)
2238  return;
2239 
2240  len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2241  rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2242  rx_fchs->ox_id, &speeds);
2243 
2244  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2245  FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2246 }
2247 
2248 static void
2249 bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
2250  struct fchs_s *rx_fchs, u16 len)
2251 {
2252  struct bfa_fcxp_s *fcxp;
2253  struct fchs_s fchs;
2254  struct bfa_fcs_lport_s *port = rport->port;
2255  struct fc_adisc_s *adisc;
2256 
2257  bfa_trc(port->fcs, rx_fchs->s_id);
2258  bfa_trc(port->fcs, rx_fchs->d_id);
2259 
2260  rport->stats.adisc_rcvd++;
2261 
2262  adisc = (struct fc_adisc_s *) (rx_fchs + 1);
2263 
2264  /*
2265  * Accept if the itnim for this rport is online.
2266  * Else reject the ADISC.
2267  */
2269 
2270  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2271  if (!fcxp)
2272  return;
2273 
2274  len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2275  rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2276  rx_fchs->ox_id, port->port_cfg.pwwn,
2277  port->port_cfg.nwwn);
2278 
2279  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2280  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2281  FC_MAX_PDUSZ, 0);
2282  } else {
2283  rport->stats.adisc_rejected++;
2284  bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
2287  }
2288 }
2289 
2290 static void
2291 bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
2292 {
2293  struct bfa_fcs_lport_s *port = rport->port;
2294  struct bfa_rport_info_s rport_info;
2295 
2296  rport_info.pid = rport->pid;
2297  rport_info.local_pid = port->pid;
2298  rport_info.lp_tag = port->lp_tag;
2299  rport_info.vf_id = port->fabric->vf_id;
2300  rport_info.vf_en = port->fabric->is_vf;
2301  rport_info.fc_class = rport->fc_cos;
2302  rport_info.cisc = rport->cisc;
2303  rport_info.max_frmsz = rport->maxfrsize;
2304  bfa_rport_online(rport->bfa_rport, &rport_info);
2305 }
2306 
2307 static void
2308 bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport)
2309 {
2310  if (rport->bfa_rport)
2312  else
2313  bfa_cb_rport_offline(rport);
2314 }
2315 
2316 static struct bfa_fcs_rport_s *
2317 bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
2318 {
2319  struct bfa_fcs_s *fcs = port->fcs;
2320  struct bfa_fcs_rport_s *rport;
2321  struct bfad_rport_s *rport_drv;
2322 
2323  /*
2324  * allocate rport
2325  */
2326  if (fcs->num_rport_logins >= bfa_fcs_rport_max_logins) {
2327  bfa_trc(fcs, rpid);
2328  return NULL;
2329  }
2330 
2331  if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
2332  != BFA_STATUS_OK) {
2333  bfa_trc(fcs, rpid);
2334  return NULL;
2335  }
2336 
2337  /*
2338  * Initialize r-port
2339  */
2340  rport->port = port;
2341  rport->fcs = fcs;
2342  rport->rp_drv = rport_drv;
2343  rport->pid = rpid;
2344  rport->pwwn = pwwn;
2345  rport->old_pid = 0;
2346 
2347  rport->bfa_rport = NULL;
2348 
2349  /*
2350  * allocate FC-4s
2351  */
2353 
2354  if (bfa_fcs_lport_is_initiator(port)) {
2355  rport->itnim = bfa_fcs_itnim_create(rport);
2356  if (!rport->itnim) {
2357  bfa_trc(fcs, rpid);
2358  kfree(rport_drv);
2359  return NULL;
2360  }
2361  }
2362 
2363  bfa_fcs_lport_add_rport(port, rport);
2364  fcs->num_rport_logins++;
2365 
2366  bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
2367 
2368  /* Initialize the Rport Features(RPF) Sub Module */
2369  if (!BFA_FCS_PID_IS_WKA(rport->pid))
2370  bfa_fcs_rpf_init(rport);
2371 
2372  return rport;
2373 }
2374 
2375 
2376 static void
2377 bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
2378 {
2379  struct bfa_fcs_lport_s *port = rport->port;
2380  struct bfa_fcs_s *fcs = port->fcs;
2381 
2382  /*
2383  * - delete FC-4s
2384  * - delete BFA rport
2385  * - remove from queue of rports
2386  */
2387  rport->plogi_pending = BFA_FALSE;
2388 
2389  if (bfa_fcs_lport_is_initiator(port)) {
2390  bfa_fcs_itnim_delete(rport->itnim);
2391  if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid))
2393  }
2394 
2395  if (rport->bfa_rport) {
2397  rport->bfa_rport = NULL;
2398  }
2399 
2400  bfa_fcs_lport_del_rport(port, rport);
2401  fcs->num_rport_logins--;
2402  kfree(rport->rp_drv);
2403 }
2404 
2405 static void
2406 bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
2407  enum bfa_rport_aen_event event,
2408  struct bfa_rport_aen_data_s *data)
2409 {
2410  struct bfa_fcs_lport_s *port = rport->port;
2411  struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2412  struct bfa_aen_entry_s *aen_entry;
2413 
2414  bfad_get_aen_entry(bfad, aen_entry);
2415  if (!aen_entry)
2416  return;
2417 
2418  if (event == BFA_RPORT_AEN_QOS_PRIO)
2419  aen_entry->aen_data.rport.priv.qos = data->priv.qos;
2420  else if (event == BFA_RPORT_AEN_QOS_FLOWID)
2421  aen_entry->aen_data.rport.priv.qos = data->priv.qos;
2422 
2423  aen_entry->aen_data.rport.vf_id = rport->port->fabric->vf_id;
2424  aen_entry->aen_data.rport.ppwwn = bfa_fcs_lport_get_pwwn(
2425  bfa_fcs_get_base_port(rport->fcs));
2426  aen_entry->aen_data.rport.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
2427  aen_entry->aen_data.rport.rpwwn = rport->pwwn;
2428 
2429  /* Send the AEN notification */
2430  bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
2431  BFA_AEN_CAT_RPORT, event);
2432 }
2433 
2434 static void
2435 bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport)
2436 {
2437  if ((!rport->pid) || (!rport->pwwn)) {
2438  bfa_trc(rport->fcs, rport->pid);
2439  bfa_sm_fault(rport->fcs, rport->pid);
2440  }
2441 
2443 }
2444 
2445 static void
2446 bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport)
2447 {
2448  struct bfa_fcs_lport_s *port = rport->port;
2449  struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2450  char lpwwn_buf[BFA_STRING_32];
2451  char rpwwn_buf[BFA_STRING_32];
2452 
2453  rport->stats.onlines++;
2454 
2455  if ((!rport->pid) || (!rport->pwwn)) {
2456  bfa_trc(rport->fcs, rport->pid);
2457  bfa_sm_fault(rport->fcs, rport->pid);
2458  }
2459 
2460  if (bfa_fcs_lport_is_initiator(port)) {
2462  if (!BFA_FCS_PID_IS_WKA(rport->pid))
2463  bfa_fcs_rpf_rport_online(rport);
2464  };
2465 
2466  wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2467  wwn2str(rpwwn_buf, rport->pwwn);
2468  if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2470  "Remote port (WWN = %s) online for logical port (WWN = %s)\n",
2471  rpwwn_buf, lpwwn_buf);
2472  bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
2473  }
2474 }
2475 
2476 static void
2477 bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport)
2478 {
2479  if (!BFA_FCS_PID_IS_WKA(rport->pid))
2481 
2483 }
2484 
2485 static void
2486 bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport)
2487 {
2488  struct bfa_fcs_lport_s *port = rport->port;
2489  struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2490  char lpwwn_buf[BFA_STRING_32];
2491  char rpwwn_buf[BFA_STRING_32];
2492 
2493  if (!rport->bfa_rport) {
2494  bfa_fcs_rport_fcs_offline_action(rport);
2495  return;
2496  }
2497 
2498  rport->stats.offlines++;
2499 
2500  wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2501  wwn2str(rpwwn_buf, rport->pwwn);
2502  if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2503  if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) {
2505  "Remote port (WWN = %s) connectivity lost for "
2506  "logical port (WWN = %s)\n",
2507  rpwwn_buf, lpwwn_buf);
2508  bfa_fcs_rport_aen_post(rport,
2510  } else {
2512  "Remote port (WWN = %s) offlined by "
2513  "logical port (WWN = %s)\n",
2514  rpwwn_buf, lpwwn_buf);
2515  bfa_fcs_rport_aen_post(rport,
2517  }
2518  }
2519 
2520  if (bfa_fcs_lport_is_initiator(port)) {
2522  if (!BFA_FCS_PID_IS_WKA(rport->pid))
2524  }
2525 }
2526 
2527 /*
2528  * Update rport parameters from PLOGI or PLOGI accept.
2529  */
2530 static void
2531 bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2532 {
2533  bfa_fcs_lport_t *port = rport->port;
2534 
2535  /*
2536  * - port name
2537  * - node name
2538  */
2539  rport->pwwn = plogi->port_name;
2540  rport->nwwn = plogi->node_name;
2541 
2542  /*
2543  * - class of service
2544  */
2545  rport->fc_cos = 0;
2546  if (plogi->class3.class_valid)
2547  rport->fc_cos = FC_CLASS_3;
2548 
2549  if (plogi->class2.class_valid)
2550  rport->fc_cos |= FC_CLASS_2;
2551 
2552  /*
2553  * - CISC
2554  * - MAX receive frame size
2555  */
2556  rport->cisc = plogi->csp.cisc;
2557  if (be16_to_cpu(plogi->class3.rxsz) < be16_to_cpu(plogi->csp.rxsz))
2558  rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz);
2559  else
2560  rport->maxfrsize = be16_to_cpu(plogi->csp.rxsz);
2561 
2562  bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2563  bfa_trc(port->fcs, port->fabric->bb_credit);
2564  /*
2565  * Direct Attach P2P mode :
2566  * This is to handle a bug (233476) in IBM targets in Direct Attach
2567  * Mode. Basically, in FLOGI Accept the target would have
2568  * erroneously set the BB Credit to the value used in the FLOGI
2569  * sent by the HBA. It uses the correct value (its own BB credit)
2570  * in PLOGI.
2571  */
2572  if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
2573  (be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
2574 
2575  bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2576  bfa_trc(port->fcs, port->fabric->bb_credit);
2577 
2578  port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
2579  bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
2580  port->fabric->bb_credit, 0);
2581  }
2582 
2583 }
2584 
2585 /*
2586  * Called to handle LOGO received from an existing remote port.
2587  */
2588 static void
2589 bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
2590 {
2591  rport->reply_oxid = fchs->ox_id;
2592  bfa_trc(rport->fcs, rport->reply_oxid);
2593 
2594  rport->prlo = BFA_FALSE;
2595  rport->stats.logo_rcvd++;
2597 }
2598 
2599 
2600 
2601 /*
2602  * fcs_rport_public FCS rport public interfaces
2603  */
2604 
2605 /*
2606  * Called by bport/vport to create a remote port instance for a discovered
2607  * remote device.
2608  *
2609  * @param[in] port - base port or vport
2610  * @param[in] rpid - remote port ID
2611  *
2612  * @return None
2613  */
2614 struct bfa_fcs_rport_s *
2616 {
2617  struct bfa_fcs_rport_s *rport;
2618 
2619  bfa_trc(port->fcs, rpid);
2620  rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
2621  if (!rport)
2622  return NULL;
2623 
2625  return rport;
2626 }
2627 
2628 /*
2629  * Called to create a rport for which only the wwn is known.
2630  *
2631  * @param[in] port - base port
2632  * @param[in] rpwwn - remote port wwn
2633  *
2634  * @return None
2635  */
2636 struct bfa_fcs_rport_s *
2638 {
2639  struct bfa_fcs_rport_s *rport;
2640  bfa_trc(port->fcs, rpwwn);
2641  rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
2642  if (!rport)
2643  return NULL;
2644 
2646  return rport;
2647 }
2648 /*
2649  * Called by bport in private loop topology to indicate that a
2650  * rport has been discovered and plogi has been completed.
2651  *
2652  * @param[in] port - base port or vport
2653  * @param[in] rpid - remote port ID
2654  */
2655 void
2656 bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2657  struct fc_logi_s *plogi)
2658 {
2659  struct bfa_fcs_rport_s *rport;
2660 
2661  rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
2662  if (!rport)
2663  return;
2664 
2665  bfa_fcs_rport_update(rport, plogi);
2666 
2668 }
2669 
2670 /*
2671  * Called by bport/vport to handle PLOGI received from a new remote port.
2672  * If an existing rport does a plogi, it will be handled separately.
2673  */
2674 void
2676  struct fc_logi_s *plogi)
2677 {
2678  struct bfa_fcs_rport_s *rport;
2679 
2680  rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
2681  if (!rport)
2682  return;
2683 
2684  bfa_fcs_rport_update(rport, plogi);
2685 
2686  rport->reply_oxid = fchs->ox_id;
2687  bfa_trc(rport->fcs, rport->reply_oxid);
2688 
2689  rport->stats.plogi_rcvd++;
2691 }
2692 
2693 /*
2694  * Called by bport/vport to handle PLOGI received from an existing
2695  * remote port.
2696  */
2697 void
2698 bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2699  struct fc_logi_s *plogi)
2700 {
2701  /*
2702  * @todo Handle P2P and initiator-initiator.
2703  */
2704 
2705  bfa_fcs_rport_update(rport, plogi);
2706 
2707  rport->reply_oxid = rx_fchs->ox_id;
2708  bfa_trc(rport->fcs, rport->reply_oxid);
2709 
2710  rport->pid = rx_fchs->s_id;
2711  bfa_trc(rport->fcs, rport->pid);
2712 
2713  rport->stats.plogi_rcvd++;
2715 }
2716 
2717 
2718 /*
2719  * Called by bport/vport to notify SCN for the remote port
2720  */
2721 void
2723 {
2724  rport->stats.rscns++;
2726 }
2727 
2728 /*
2729  * brief
2730  * This routine BFA callback for bfa_rport_online() call.
2731  *
2732  * param[in] cb_arg - rport struct.
2733  *
2734  * return
2735  * void
2736  *
2737  * Special Considerations:
2738  *
2739  * note
2740  */
2741 void
2743 {
2744 
2745  struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2746 
2747  bfa_trc(rport->fcs, rport->pwwn);
2749 }
2750 
2751 /*
2752  * brief
2753  * This routine BFA callback for bfa_rport_offline() call.
2754  *
2755  * param[in] rport -
2756  *
2757  * return
2758  * void
2759  *
2760  * Special Considerations:
2761  *
2762  * note
2763  */
2764 void
2766 {
2767  struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2768 
2769  bfa_trc(rport->fcs, rport->pwwn);
2771 }
2772 
2773 /*
2774  * brief
2775  * This routine is a static BFA callback when there is a QoS flow_id
2776  * change notification
2777  *
2778  * param[in] rport -
2779  *
2780  * return
2781  * void
2782  *
2783  * Special Considerations:
2784  *
2785  * note
2786  */
2787 void
2789  struct bfa_rport_qos_attr_s old_qos_attr,
2790  struct bfa_rport_qos_attr_s new_qos_attr)
2791 {
2792  struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2793  struct bfa_rport_aen_data_s aen_data;
2794 
2795  bfa_trc(rport->fcs, rport->pwwn);
2796  aen_data.priv.qos = new_qos_attr;
2797  bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
2798 }
2799 
2800 void
2802 {
2803  struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
2804  struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
2805  struct bfa_fcs_rport_s *rp;
2806  struct list_head *qe;
2807 
2808  list_for_each(qe, &port->rport_q) {
2809  rp = (struct bfa_fcs_rport_s *) qe;
2811  rp->scn_online = BFA_TRUE;
2812  }
2813 
2814  if (bfa_fcs_lport_is_online(port))
2816 }
2817 
2818 void
2820 {
2821  struct bfa_fcs_rport_s *rp = rport;
2822 
2824  rp->scn_online = BFA_FALSE;
2825 }
2826 
2827 void
2829 {
2830  struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
2831  struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
2832  struct bfa_fcs_rport_s *rp;
2833  struct list_head *qe;
2834 
2835  list_for_each(qe, &port->rport_q) {
2836  rp = (struct bfa_fcs_rport_s *) qe;
2838  rp->scn_online = BFA_FALSE;
2839  }
2840 }
2841 
2842 /*
2843  * brief
2844  * This routine is a static BFA callback when there is a QoS priority
2845  * change notification
2846  *
2847  * param[in] rport -
2848  *
2849  * return
2850  * void
2851  *
2852  * Special Considerations:
2853  *
2854  * note
2855  */
2856 void
2858  struct bfa_rport_qos_attr_s old_qos_attr,
2859  struct bfa_rport_qos_attr_s new_qos_attr)
2860 {
2861  struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2862  struct bfa_rport_aen_data_s aen_data;
2863 
2864  bfa_trc(rport->fcs, rport->pwwn);
2865  aen_data.priv.qos = new_qos_attr;
2866  bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data);
2867 }
2868 
2869 /*
2870  * Called to process any unsolicted frames from this remote port
2871  */
2872 void
2874  struct fchs_s *fchs, u16 len)
2875 {
2876  struct bfa_fcs_lport_s *port = rport->port;
2877  struct fc_els_cmd_s *els_cmd;
2878 
2879  bfa_trc(rport->fcs, fchs->s_id);
2880  bfa_trc(rport->fcs, fchs->d_id);
2881  bfa_trc(rport->fcs, fchs->type);
2882 
2883  if (fchs->type != FC_TYPE_ELS)
2884  return;
2885 
2886  els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
2887 
2888  bfa_trc(rport->fcs, els_cmd->els_code);
2889 
2890  switch (els_cmd->els_code) {
2891  case FC_ELS_LOGO:
2892  bfa_stats(port, plogi_rcvd);
2893  bfa_fcs_rport_process_logo(rport, fchs);
2894  break;
2895 
2896  case FC_ELS_ADISC:
2897  bfa_stats(port, adisc_rcvd);
2898  bfa_fcs_rport_process_adisc(rport, fchs, len);
2899  break;
2900 
2901  case FC_ELS_PRLO:
2902  bfa_stats(port, prlo_rcvd);
2903  if (bfa_fcs_lport_is_initiator(port))
2904  bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
2905  break;
2906 
2907  case FC_ELS_PRLI:
2908  bfa_stats(port, prli_rcvd);
2909  bfa_fcs_rport_process_prli(rport, fchs, len);
2910  break;
2911 
2912  case FC_ELS_RPSC:
2913  bfa_stats(port, rpsc_rcvd);
2914  bfa_fcs_rport_process_rpsc(rport, fchs, len);
2915  break;
2916 
2917  default:
2918  bfa_stats(port, un_handled_els_rcvd);
2919  bfa_fcs_rport_send_ls_rjt(rport, fchs,
2922  break;
2923  }
2924 }
2925 
2926 /* send best case acc to prlo */
2927 static void
2928 bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
2929 {
2930  struct bfa_fcs_lport_s *port = rport->port;
2931  struct fchs_s fchs;
2932  struct bfa_fcxp_s *fcxp;
2933  int len;
2934 
2935  bfa_trc(rport->fcs, rport->pid);
2936 
2937  fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2938  if (!fcxp)
2939  return;
2940  len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2941  rport->pid, bfa_fcs_lport_get_fcid(port),
2942  rport->reply_oxid, 0);
2943 
2944  bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id,
2945  port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs,
2946  NULL, NULL, FC_MAX_PDUSZ, 0);
2947 }
2948 
2949 /*
2950  * Send a LS reject
2951  */
2952 static void
2953 bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2954  u8 reason_code, u8 reason_code_expl)
2955 {
2956  struct bfa_fcs_lport_s *port = rport->port;
2957  struct fchs_s fchs;
2958  struct bfa_fcxp_s *fcxp;
2959  int len;
2960 
2961  bfa_trc(rport->fcs, rx_fchs->s_id);
2962 
2963  fcxp = bfa_fcs_fcxp_alloc(rport->fcs, BFA_FALSE);
2964  if (!fcxp)
2965  return;
2966 
2967  len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2968  rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2969  rx_fchs->ox_id, reason_code, reason_code_expl);
2970 
2971  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2972  BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2973  FC_MAX_PDUSZ, 0);
2974 }
2975 
2976 /*
2977  * Return state of rport.
2978  */
2979 int
2981 {
2982  return bfa_sm_to_state(rport_sm_table, rport->sm);
2983 }
2984 
2985 
2986 /*
2987  * brief
2988  * Called by the Driver to set rport delete/ageout timeout
2989  *
2990  * param[in] rport timeout value in seconds.
2991  *
2992  * return None
2993  */
2994 void
2996 {
2997  /* convert to Millisecs */
2998  if (rport_tmo > 0)
2999  bfa_fcs_rport_del_timeout = rport_tmo * 1000;
3000 }
3001 void
3003 {
3004  bfa_trc(rport->fcs, rport->pid);
3005 
3006  rport->prlo = BFA_TRUE;
3007  rport->reply_oxid = ox_id;
3009 }
3010 
3011 /*
3012  * Called by BFAD to set the max limit on number of bfa_fcs_rport allocation
3013  * which limits number of concurrent logins to remote ports
3014  */
3015 void
3017 {
3018  if (max_logins > 0)
3019  bfa_fcs_rport_max_logins = max_logins;
3020 }
3021 
3022 void
3024  struct bfa_rport_attr_s *rport_attr)
3025 {
3026  struct bfa_rport_qos_attr_s qos_attr;
3027  struct bfa_fcs_lport_s *port = rport->port;
3028  bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
3029  struct bfa_port_attr_s port_attr;
3030 
3031  bfa_fcport_get_attr(rport->fcs->bfa, &port_attr);
3032 
3033  memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
3034  memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s));
3035 
3036  rport_attr->pid = rport->pid;
3037  rport_attr->pwwn = rport->pwwn;
3038  rport_attr->nwwn = rport->nwwn;
3039  rport_attr->cos_supported = rport->fc_cos;
3040  rport_attr->df_sz = rport->maxfrsize;
3041  rport_attr->state = bfa_fcs_rport_get_state(rport);
3042  rport_attr->fc_cos = rport->fc_cos;
3043  rport_attr->cisc = rport->cisc;
3044  rport_attr->scsi_function = rport->scsi_function;
3045  rport_attr->curr_speed = rport->rpf.rpsc_speed;
3046  rport_attr->assigned_speed = rport->rpf.assigned_speed;
3047 
3048  if (rport->bfa_rport) {
3049  qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority;
3050  qos_attr.qos_flow_id =
3051  cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id);
3052  }
3053  rport_attr->qos_attr = qos_attr;
3054 
3055  rport_attr->trl_enforced = BFA_FALSE;
3056  if (bfa_fcport_is_ratelim(port->fcs->bfa) &&
3057  (rport->scsi_function == BFA_RPORT_TARGET)) {
3058  if (rport_speed == BFA_PORT_SPEED_UNKNOWN)
3059  rport_speed =
3060  bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
3061 
3062  if ((bfa_fcs_lport_get_rport_max_speed(port) !=
3063  BFA_PORT_SPEED_UNKNOWN) && (rport_speed < port_attr.speed))
3064  rport_attr->trl_enforced = BFA_TRUE;
3065  }
3066 }
3067 
3068 /*
3069  * Remote port implementation.
3070  */
3071 
3072 /*
3073  * fcs_rport_api FCS rport API.
3074  */
3075 
3076 struct bfa_fcs_rport_s *
3078 {
3079  struct bfa_fcs_rport_s *rport;
3080 
3081  rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
3082  if (rport == NULL) {
3083  /*
3084  * TBD Error handling
3085  */
3086  }
3087 
3088  return rport;
3089 }
3090 
3091 struct bfa_fcs_rport_s *
3093 {
3094  struct bfa_fcs_rport_s *rport;
3095 
3096  rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn);
3097  if (rport == NULL) {
3098  /*
3099  * TBD Error handling
3100  */
3101  }
3102 
3103  return rport;
3104 }
3105 
3106 /*
3107  * Remote port features (RPF) implementation.
3108  */
3109 
3110 #define BFA_FCS_RPF_RETRIES (3)
3111 #define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */
3112 
3113 static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
3114  struct bfa_fcxp_s *fcxp_alloced);
3115 static void bfa_fcs_rpf_rpsc2_response(void *fcsarg,
3116  struct bfa_fcxp_s *fcxp,
3117  void *cbarg,
3118  bfa_status_t req_status,
3119  u32 rsp_len,
3120  u32 resid_len,
3121  struct fchs_s *rsp_fchs);
3122 
3123 static void bfa_fcs_rpf_timeout(void *arg);
3124 
3125 /*
3126  * fcs_rport_ftrs_sm FCS rport state machine events
3127  */
3128 
3130  RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */
3131  RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */
3132  RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */
3133  RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */
3137 };
3138 
3139 static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
3140  enum rpf_event event);
3141 static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
3142  enum rpf_event event);
3143 static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
3144  enum rpf_event event);
3145 static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
3146  enum rpf_event event);
3147 static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
3148  enum rpf_event event);
3149 static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
3150  enum rpf_event event);
3151 
3152 static void
3153 bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3154 {
3155  struct bfa_fcs_rport_s *rport = rpf->rport;
3156  struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric;
3157 
3158  bfa_trc(rport->fcs, rport->pwwn);
3159  bfa_trc(rport->fcs, rport->pid);
3160  bfa_trc(rport->fcs, event);
3161 
3162  switch (event) {
3164  /* Send RPSC2 to a Brocade fabric only. */
3165  if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
3166  ((rport->port->fabric->lps->brcd_switch) ||
3167  (bfa_fcs_fabric_get_switch_oui(fabric) ==
3169  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3170  rpf->rpsc_retries = 0;
3171  bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3172  }
3173  break;
3174 
3176  break;
3177 
3178  default:
3179  bfa_sm_fault(rport->fcs, event);
3180  }
3181 }
3182 
3183 static void
3184 bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3185 {
3186  struct bfa_fcs_rport_s *rport = rpf->rport;
3187 
3188  bfa_trc(rport->fcs, event);
3189 
3190  switch (event) {
3191  case RPFSM_EVENT_FCXP_SENT:
3192  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
3193  break;
3194 
3196  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3197  bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
3198  rpf->rpsc_retries = 0;
3199  break;
3200 
3201  default:
3202  bfa_sm_fault(rport->fcs, event);
3203  }
3204 }
3205 
3206 static void
3207 bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3208 {
3209  struct bfa_fcs_rport_s *rport = rpf->rport;
3210 
3211  bfa_trc(rport->fcs, rport->pid);
3212  bfa_trc(rport->fcs, event);
3213 
3214  switch (event) {
3215  case RPFSM_EVENT_RPSC_COMP:
3216  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3217  /* Update speed info in f/w via BFA */
3218  if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN)
3219  bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
3220  else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN)
3222  break;
3223 
3224  case RPFSM_EVENT_RPSC_FAIL:
3225  /* RPSC not supported by rport */
3226  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3227  break;
3228 
3230  /* need to retry...delayed a bit. */
3231  if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
3232  bfa_timer_start(rport->fcs->bfa, &rpf->timer,
3233  bfa_fcs_rpf_timeout, rpf,
3235  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
3236  } else {
3237  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3238  }
3239  break;
3240 
3242  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3243  bfa_fcxp_discard(rpf->fcxp);
3244  rpf->rpsc_retries = 0;
3245  break;
3246 
3247  default:
3248  bfa_sm_fault(rport->fcs, event);
3249  }
3250 }
3251 
3252 static void
3253 bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3254 {
3255  struct bfa_fcs_rport_s *rport = rpf->rport;
3256 
3257  bfa_trc(rport->fcs, rport->pid);
3258  bfa_trc(rport->fcs, event);
3259 
3260  switch (event) {
3261  case RPFSM_EVENT_TIMEOUT:
3262  /* re-send the RPSC */
3263  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3264  bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3265  break;
3266 
3268  bfa_timer_stop(&rpf->timer);
3269  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3270  rpf->rpsc_retries = 0;
3271  break;
3272 
3273  default:
3274  bfa_sm_fault(rport->fcs, event);
3275  }
3276 }
3277 
3278 static void
3279 bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3280 {
3281  struct bfa_fcs_rport_s *rport = rpf->rport;
3282 
3283  bfa_trc(rport->fcs, rport->pwwn);
3284  bfa_trc(rport->fcs, rport->pid);
3285  bfa_trc(rport->fcs, event);
3286 
3287  switch (event) {
3289  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3290  rpf->rpsc_retries = 0;
3291  break;
3292 
3293  default:
3294  bfa_sm_fault(rport->fcs, event);
3295  }
3296 }
3297 
3298 static void
3299 bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3300 {
3301  struct bfa_fcs_rport_s *rport = rpf->rport;
3302 
3303  bfa_trc(rport->fcs, rport->pwwn);
3304  bfa_trc(rport->fcs, rport->pid);
3305  bfa_trc(rport->fcs, event);
3306 
3307  switch (event) {
3309  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3310  bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3311  break;
3312 
3314  break;
3315 
3316  default:
3317  bfa_sm_fault(rport->fcs, event);
3318  }
3319 }
3320 /*
3321  * Called when Rport is created.
3322  */
3323 void
3325 {
3326  struct bfa_fcs_rpf_s *rpf = &rport->rpf;
3327 
3328  bfa_trc(rport->fcs, rport->pid);
3329  rpf->rport = rport;
3330 
3331  bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
3332 }
3333 
3334 /*
3335  * Called when Rport becomes online
3336  */
3337 void
3339 {
3340  bfa_trc(rport->fcs, rport->pid);
3341 
3342  if (__fcs_min_cfg(rport->port->fcs))
3343  return;
3344 
3345  if (bfa_fcs_fabric_is_switched(rport->port->fabric))
3347 }
3348 
3349 /*
3350  * Called when Rport becomes offline
3351  */
3352 void
3354 {
3355  bfa_trc(rport->fcs, rport->pid);
3356 
3357  if (__fcs_min_cfg(rport->port->fcs))
3358  return;
3359 
3360  rport->rpf.rpsc_speed = 0;
3362 }
3363 
3364 static void
3365 bfa_fcs_rpf_timeout(void *arg)
3366 {
3367  struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
3368  struct bfa_fcs_rport_s *rport = rpf->rport;
3369 
3370  bfa_trc(rport->fcs, rport->pid);
3372 }
3373 
3374 static void
3375 bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3376 {
3377  struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
3378  struct bfa_fcs_rport_s *rport = rpf->rport;
3379  struct bfa_fcs_lport_s *port = rport->port;
3380  struct fchs_s fchs;
3381  int len;
3382  struct bfa_fcxp_s *fcxp;
3383 
3384  bfa_trc(rport->fcs, rport->pwwn);
3385 
3386  fcxp = fcxp_alloced ? fcxp_alloced :
3388  if (!fcxp) {
3389  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
3390  bfa_fcs_rpf_send_rpsc2, rpf, BFA_TRUE);
3391  return;
3392  }
3393  rpf->fcxp = fcxp;
3394 
3395  len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
3396  bfa_fcs_lport_get_fcid(port), &rport->pid, 1);
3397 
3398  bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3399  FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
3400  rpf, FC_MAX_PDUSZ, FC_ELS_TOV);
3401  rport->stats.rpsc_sent++;
3403 
3404 }
3405 
3406 static void
3407 bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
3408  bfa_status_t req_status, u32 rsp_len,
3409  u32 resid_len, struct fchs_s *rsp_fchs)
3410 {
3411  struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
3412  struct bfa_fcs_rport_s *rport = rpf->rport;
3413  struct fc_ls_rjt_s *ls_rjt;
3414  struct fc_rpsc2_acc_s *rpsc2_acc;
3415  u16 num_ents;
3416 
3417  bfa_trc(rport->fcs, req_status);
3418 
3419  if (req_status != BFA_STATUS_OK) {
3420  bfa_trc(rport->fcs, req_status);
3421  if (req_status == BFA_STATUS_ETIMER)
3422  rport->stats.rpsc_failed++;
3424  return;
3425  }
3426 
3427  rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
3428  if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
3429  rport->stats.rpsc_accs++;
3430  num_ents = be16_to_cpu(rpsc2_acc->num_pids);
3431  bfa_trc(rport->fcs, num_ents);
3432  if (num_ents > 0) {
3433  WARN_ON(rpsc2_acc->port_info[0].pid == rport->pid);
3434  bfa_trc(rport->fcs,
3435  be16_to_cpu(rpsc2_acc->port_info[0].pid));
3436  bfa_trc(rport->fcs,
3437  be16_to_cpu(rpsc2_acc->port_info[0].speed));
3438  bfa_trc(rport->fcs,
3439  be16_to_cpu(rpsc2_acc->port_info[0].index));
3440  bfa_trc(rport->fcs,
3441  rpsc2_acc->port_info[0].type);
3442 
3443  if (rpsc2_acc->port_info[0].speed == 0) {
3445  return;
3446  }
3447 
3448  rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
3449  be16_to_cpu(rpsc2_acc->port_info[0].speed));
3450 
3452  }
3453  } else {
3454  ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3455  bfa_trc(rport->fcs, ls_rjt->reason_code);
3456  bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
3457  rport->stats.rpsc_rejects++;
3458  if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
3460  else
3462  }
3463 }