2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
19 * rport.c Remote port implementation.
25 #include "bfa_fcbuild.h"
27 BFA_TRC_FILE(FCS
, RPORT
);
30 bfa_fcs_rport_del_timeout
= BFA_FCS_RPORT_DEF_DEL_TIMEOUT
* 1000;
33 * forward declarations
35 static struct bfa_fcs_rport_s
*bfa_fcs_rport_alloc(
36 struct bfa_fcs_lport_s
*port
, wwn_t pwwn
, u32 rpid
);
37 static void bfa_fcs_rport_free(struct bfa_fcs_rport_s
*rport
);
38 static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s
*rport
);
39 static void bfa_fcs_rport_online_action(struct bfa_fcs_rport_s
*rport
);
40 static void bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s
*rport
);
41 static void bfa_fcs_rport_update(struct bfa_fcs_rport_s
*rport
,
42 struct fc_logi_s
*plogi
);
43 static void bfa_fcs_rport_timeout(void *arg
);
44 static void bfa_fcs_rport_send_plogi(void *rport_cbarg
,
45 struct bfa_fcxp_s
*fcxp_alloced
);
46 static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg
,
47 struct bfa_fcxp_s
*fcxp_alloced
);
48 static void bfa_fcs_rport_plogi_response(void *fcsarg
,
49 struct bfa_fcxp_s
*fcxp
, void *cbarg
,
50 bfa_status_t req_status
, u32 rsp_len
,
51 u32 resid_len
, struct fchs_s
*rsp_fchs
);
52 static void bfa_fcs_rport_send_adisc(void *rport_cbarg
,
53 struct bfa_fcxp_s
*fcxp_alloced
);
54 static void bfa_fcs_rport_adisc_response(void *fcsarg
,
55 struct bfa_fcxp_s
*fcxp
, void *cbarg
,
56 bfa_status_t req_status
, u32 rsp_len
,
57 u32 resid_len
, struct fchs_s
*rsp_fchs
);
58 static void bfa_fcs_rport_send_nsdisc(void *rport_cbarg
,
59 struct bfa_fcxp_s
*fcxp_alloced
);
60 static void bfa_fcs_rport_gidpn_response(void *fcsarg
,
61 struct bfa_fcxp_s
*fcxp
, void *cbarg
,
62 bfa_status_t req_status
, u32 rsp_len
,
63 u32 resid_len
, struct fchs_s
*rsp_fchs
);
64 static void bfa_fcs_rport_gpnid_response(void *fcsarg
,
65 struct bfa_fcxp_s
*fcxp
, void *cbarg
,
66 bfa_status_t req_status
, u32 rsp_len
,
67 u32 resid_len
, struct fchs_s
*rsp_fchs
);
68 static void bfa_fcs_rport_send_logo(void *rport_cbarg
,
69 struct bfa_fcxp_s
*fcxp_alloced
);
70 static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg
);
71 static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s
*rport
,
72 struct fchs_s
*rx_fchs
, u16 len
);
73 static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s
*rport
,
74 struct fchs_s
*rx_fchs
, u8 reason_code
,
76 static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s
*rport
,
77 struct fchs_s
*rx_fchs
, u16 len
);
78 static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s
*rport
);
80 static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s
*rport
,
81 enum rport_event event
);
82 static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s
*rport
,
83 enum rport_event event
);
84 static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s
*rport
,
85 enum rport_event event
);
86 static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s
*rport
,
87 enum rport_event event
);
88 static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s
*rport
,
89 enum rport_event event
);
90 static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s
*rport
,
91 enum rport_event event
);
92 static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s
*rport
,
93 enum rport_event event
);
94 static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s
*rport
,
95 enum rport_event event
);
96 static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s
*rport
,
97 enum rport_event event
);
98 static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s
*rport
,
99 enum rport_event event
);
100 static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s
*rport
,
101 enum rport_event event
);
102 static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s
*rport
,
103 enum rport_event event
);
104 static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s
*rport
,
105 enum rport_event event
);
106 static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s
*rport
,
107 enum rport_event event
);
108 static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s
*rport
,
109 enum rport_event event
);
110 static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s
*rport
,
111 enum rport_event event
);
112 static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s
*rport
,
113 enum rport_event event
);
114 static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s
*rport
,
115 enum rport_event event
);
116 static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s
*rport
,
117 enum rport_event event
);
118 static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s
*rport
,
119 enum rport_event event
);
120 static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s
*rport
,
121 enum rport_event event
);
122 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s
*rport
,
123 enum rport_event event
);
124 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s
*rport
,
125 enum rport_event event
);
127 static struct bfa_sm_table_s rport_sm_table
[] = {
128 {BFA_SM(bfa_fcs_rport_sm_uninit
), BFA_RPORT_UNINIT
},
129 {BFA_SM(bfa_fcs_rport_sm_plogi_sending
), BFA_RPORT_PLOGI
},
130 {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending
), BFA_RPORT_ONLINE
},
131 {BFA_SM(bfa_fcs_rport_sm_plogi_retry
), BFA_RPORT_PLOGI_RETRY
},
132 {BFA_SM(bfa_fcs_rport_sm_plogi
), BFA_RPORT_PLOGI
},
133 {BFA_SM(bfa_fcs_rport_sm_hal_online
), BFA_RPORT_ONLINE
},
134 {BFA_SM(bfa_fcs_rport_sm_online
), BFA_RPORT_ONLINE
},
135 {BFA_SM(bfa_fcs_rport_sm_nsquery_sending
), BFA_RPORT_NSQUERY
},
136 {BFA_SM(bfa_fcs_rport_sm_nsquery
), BFA_RPORT_NSQUERY
},
137 {BFA_SM(bfa_fcs_rport_sm_adisc_sending
), BFA_RPORT_ADISC
},
138 {BFA_SM(bfa_fcs_rport_sm_adisc
), BFA_RPORT_ADISC
},
139 {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv
), BFA_RPORT_LOGORCV
},
140 {BFA_SM(bfa_fcs_rport_sm_fc4_logosend
), BFA_RPORT_LOGO
},
141 {BFA_SM(bfa_fcs_rport_sm_fc4_offline
), BFA_RPORT_OFFLINE
},
142 {BFA_SM(bfa_fcs_rport_sm_hcb_offline
), BFA_RPORT_OFFLINE
},
143 {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv
), BFA_RPORT_LOGORCV
},
144 {BFA_SM(bfa_fcs_rport_sm_hcb_logosend
), BFA_RPORT_LOGO
},
145 {BFA_SM(bfa_fcs_rport_sm_logo_sending
), BFA_RPORT_LOGO
},
146 {BFA_SM(bfa_fcs_rport_sm_offline
), BFA_RPORT_OFFLINE
},
147 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending
), BFA_RPORT_NSDISC
},
148 {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry
), BFA_RPORT_NSDISC
},
149 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent
), BFA_RPORT_NSDISC
},
156 bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
158 bfa_trc(rport
->fcs
, rport
->pwwn
);
159 bfa_trc(rport
->fcs
, rport
->pid
);
160 bfa_trc(rport
->fcs
, event
);
163 case RPSM_EVENT_PLOGI_SEND
:
164 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogi_sending
);
165 rport
->plogi_retries
= 0;
166 bfa_fcs_rport_send_plogi(rport
, NULL
);
169 case RPSM_EVENT_PLOGI_RCVD
:
170 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogiacc_sending
);
171 bfa_fcs_rport_send_plogiacc(rport
, NULL
);
174 case RPSM_EVENT_PLOGI_COMP
:
175 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
176 bfa_fcs_rport_hal_online(rport
);
179 case RPSM_EVENT_ADDRESS_CHANGE
:
180 case RPSM_EVENT_ADDRESS_DISC
:
181 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsdisc_sending
);
182 rport
->ns_retries
= 0;
183 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
186 bfa_sm_fault(rport
->fcs
, event
);
191 * PLOGI is being sent.
194 bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s
*rport
,
195 enum rport_event event
)
197 bfa_trc(rport
->fcs
, rport
->pwwn
);
198 bfa_trc(rport
->fcs
, rport
->pid
);
199 bfa_trc(rport
->fcs
, event
);
202 case RPSM_EVENT_FCXP_SENT
:
203 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogi
);
206 case RPSM_EVENT_DELETE
:
207 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
208 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
209 bfa_fcs_rport_free(rport
);
212 case RPSM_EVENT_PLOGI_RCVD
:
213 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogiacc_sending
);
214 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
215 bfa_fcs_rport_send_plogiacc(rport
, NULL
);
218 case RPSM_EVENT_ADDRESS_CHANGE
:
221 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
222 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsdisc_sending
);
223 rport
->ns_retries
= 0;
224 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
227 case RPSM_EVENT_LOGO_IMP
:
229 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
230 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
231 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
232 bfa_fcs_rport_timeout
, rport
,
233 bfa_fcs_rport_del_timeout
);
238 bfa_sm_fault(rport
->fcs
, event
);
243 * PLOGI is being sent.
246 bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s
*rport
,
247 enum rport_event event
)
249 bfa_trc(rport
->fcs
, rport
->pwwn
);
250 bfa_trc(rport
->fcs
, rport
->pid
);
251 bfa_trc(rport
->fcs
, event
);
254 case RPSM_EVENT_FCXP_SENT
:
255 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
256 bfa_fcs_rport_hal_online(rport
);
259 case RPSM_EVENT_DELETE
:
260 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
261 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
262 bfa_fcs_rport_free(rport
);
265 case RPSM_EVENT_PLOGI_RCVD
:
266 case RPSM_EVENT_PLOGI_COMP
:
269 * Ignore, SCN is possibly online notification.
273 case RPSM_EVENT_ADDRESS_CHANGE
:
274 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
275 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsdisc_sending
);
276 rport
->ns_retries
= 0;
277 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
280 case RPSM_EVENT_LOGO_IMP
:
282 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
283 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
284 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
285 bfa_fcs_rport_timeout
, rport
,
286 bfa_fcs_rport_del_timeout
);
289 case RPSM_EVENT_HCB_OFFLINE
:
291 * Ignore BFA callback, on a PLOGI receive we call bfa offline.
296 bfa_sm_fault(rport
->fcs
, event
);
304 bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s
*rport
,
305 enum rport_event event
)
307 bfa_trc(rport
->fcs
, rport
->pwwn
);
308 bfa_trc(rport
->fcs
, rport
->pid
);
309 bfa_trc(rport
->fcs
, event
);
312 case RPSM_EVENT_TIMEOUT
:
313 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogi_sending
);
314 bfa_fcs_rport_send_plogi(rport
, NULL
);
317 case RPSM_EVENT_DELETE
:
318 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
319 bfa_timer_stop(&rport
->timer
);
320 bfa_fcs_rport_free(rport
);
323 case RPSM_EVENT_PRLO_RCVD
:
324 case RPSM_EVENT_LOGO_RCVD
:
327 case RPSM_EVENT_PLOGI_RCVD
:
328 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogiacc_sending
);
329 bfa_timer_stop(&rport
->timer
);
330 bfa_fcs_rport_send_plogiacc(rport
, NULL
);
333 case RPSM_EVENT_ADDRESS_CHANGE
:
335 bfa_timer_stop(&rport
->timer
);
336 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsdisc_sending
);
337 rport
->ns_retries
= 0;
338 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
341 case RPSM_EVENT_LOGO_IMP
:
343 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
344 bfa_timer_stop(&rport
->timer
);
345 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
346 bfa_fcs_rport_timeout
, rport
,
347 bfa_fcs_rport_del_timeout
);
350 case RPSM_EVENT_PLOGI_COMP
:
351 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
352 bfa_timer_stop(&rport
->timer
);
353 bfa_fcs_rport_hal_online(rport
);
357 bfa_sm_fault(rport
->fcs
, event
);
365 bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
367 bfa_trc(rport
->fcs
, rport
->pwwn
);
368 bfa_trc(rport
->fcs
, rport
->pid
);
369 bfa_trc(rport
->fcs
, event
);
372 case RPSM_EVENT_ACCEPTED
:
373 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
374 rport
->plogi_retries
= 0;
375 bfa_fcs_rport_hal_online(rport
);
378 case RPSM_EVENT_LOGO_RCVD
:
379 bfa_fcs_rport_send_logo_acc(rport
);
383 case RPSM_EVENT_PRLO_RCVD
:
384 if (rport
->prlo
== BFA_TRUE
)
385 bfa_fcs_rport_send_prlo_acc(rport
);
387 bfa_fcxp_discard(rport
->fcxp
);
391 case RPSM_EVENT_FAILED
:
392 if (rport
->plogi_retries
< BFA_FCS_RPORT_MAX_RETRIES
) {
393 rport
->plogi_retries
++;
394 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogi_retry
);
395 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
396 bfa_fcs_rport_timeout
, rport
,
397 BFA_FCS_RETRY_TIMEOUT
);
399 bfa_stats(rport
->port
, rport_del_max_plogi_retry
);
401 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
402 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
403 bfa_fcs_rport_timeout
, rport
,
404 bfa_fcs_rport_del_timeout
);
408 case RPSM_EVENT_PLOGI_RETRY
:
409 rport
->plogi_retries
= 0;
410 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogi_retry
);
411 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
412 bfa_fcs_rport_timeout
, rport
,
416 case RPSM_EVENT_LOGO_IMP
:
418 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
419 bfa_fcxp_discard(rport
->fcxp
);
420 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
421 bfa_fcs_rport_timeout
, rport
,
422 bfa_fcs_rport_del_timeout
);
425 case RPSM_EVENT_ADDRESS_CHANGE
:
427 bfa_fcxp_discard(rport
->fcxp
);
428 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsdisc_sending
);
429 rport
->ns_retries
= 0;
430 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
433 case RPSM_EVENT_PLOGI_RCVD
:
434 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogiacc_sending
);
435 bfa_fcxp_discard(rport
->fcxp
);
436 bfa_fcs_rport_send_plogiacc(rport
, NULL
);
439 case RPSM_EVENT_DELETE
:
440 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
441 bfa_fcxp_discard(rport
->fcxp
);
442 bfa_fcs_rport_free(rport
);
445 case RPSM_EVENT_PLOGI_COMP
:
446 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
447 bfa_fcxp_discard(rport
->fcxp
);
448 bfa_fcs_rport_hal_online(rport
);
452 bfa_sm_fault(rport
->fcs
, event
);
457 * PLOGI is complete. Awaiting BFA rport online callback. FC-4s
461 bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s
*rport
,
462 enum rport_event event
)
464 bfa_trc(rport
->fcs
, rport
->pwwn
);
465 bfa_trc(rport
->fcs
, rport
->pid
);
466 bfa_trc(rport
->fcs
, event
);
469 case RPSM_EVENT_HCB_ONLINE
:
470 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_online
);
471 bfa_fcs_rport_online_action(rport
);
474 case RPSM_EVENT_PRLO_RCVD
:
475 case RPSM_EVENT_PLOGI_COMP
:
478 case RPSM_EVENT_LOGO_RCVD
:
479 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_logorcv
);
480 bfa_sm_send_event(rport
->bfa_rport
, BFA_RPORT_SM_OFFLINE
);
483 case RPSM_EVENT_LOGO_IMP
:
484 case RPSM_EVENT_ADDRESS_CHANGE
:
485 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_offline
);
486 bfa_sm_send_event(rport
->bfa_rport
, BFA_RPORT_SM_OFFLINE
);
489 case RPSM_EVENT_PLOGI_RCVD
:
490 rport
->plogi_pending
= BFA_TRUE
;
491 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_offline
);
492 bfa_sm_send_event(rport
->bfa_rport
, BFA_RPORT_SM_OFFLINE
);
495 case RPSM_EVENT_DELETE
:
496 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_logosend
);
497 bfa_sm_send_event(rport
->bfa_rport
, BFA_RPORT_SM_OFFLINE
);
503 * Ignore SCN - PLOGI just completed, FC-4 login should detect
509 bfa_sm_fault(rport
->fcs
, event
);
514 * Rport is ONLINE. FC-4s active.
517 bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
519 bfa_trc(rport
->fcs
, rport
->pwwn
);
520 bfa_trc(rport
->fcs
, rport
->pid
);
521 bfa_trc(rport
->fcs
, event
);
525 if (bfa_fcs_fabric_is_switched(rport
->port
->fabric
)) {
526 bfa_sm_set_state(rport
,
527 bfa_fcs_rport_sm_nsquery_sending
);
528 rport
->ns_retries
= 0;
529 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
531 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_adisc_sending
);
532 bfa_fcs_rport_send_adisc(rport
, NULL
);
536 case RPSM_EVENT_PLOGI_RCVD
:
537 case RPSM_EVENT_LOGO_IMP
:
538 case RPSM_EVENT_ADDRESS_CHANGE
:
539 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
540 bfa_fcs_rport_offline_action(rport
);
543 case RPSM_EVENT_DELETE
:
544 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logosend
);
545 bfa_fcs_rport_offline_action(rport
);
548 case RPSM_EVENT_LOGO_RCVD
:
549 case RPSM_EVENT_PRLO_RCVD
:
550 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logorcv
);
551 bfa_fcs_rport_offline_action(rport
);
554 case RPSM_EVENT_PLOGI_COMP
:
558 bfa_sm_fault(rport
->fcs
, event
);
563 * An SCN event is received in ONLINE state. NS query is being sent
564 * prior to ADISC authentication with rport. FC-4s are paused.
567 bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s
*rport
,
568 enum rport_event event
)
570 bfa_trc(rport
->fcs
, rport
->pwwn
);
571 bfa_trc(rport
->fcs
, rport
->pid
);
572 bfa_trc(rport
->fcs
, event
);
575 case RPSM_EVENT_FCXP_SENT
:
576 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsquery
);
579 case RPSM_EVENT_DELETE
:
580 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logosend
);
581 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
582 bfa_fcs_rport_offline_action(rport
);
587 * ignore SCN, wait for response to query itself
591 case RPSM_EVENT_LOGO_RCVD
:
592 case RPSM_EVENT_PRLO_RCVD
:
593 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logorcv
);
594 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
595 bfa_fcs_rport_offline_action(rport
);
598 case RPSM_EVENT_LOGO_IMP
:
600 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
601 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
602 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
603 bfa_fcs_rport_timeout
, rport
,
604 bfa_fcs_rport_del_timeout
);
607 case RPSM_EVENT_PLOGI_RCVD
:
608 case RPSM_EVENT_ADDRESS_CHANGE
:
609 case RPSM_EVENT_PLOGI_COMP
:
610 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
611 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
612 bfa_fcs_rport_offline_action(rport
);
616 bfa_sm_fault(rport
->fcs
, event
);
621 * An SCN event is received in ONLINE state. NS query is sent to rport.
625 bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
627 bfa_trc(rport
->fcs
, rport
->pwwn
);
628 bfa_trc(rport
->fcs
, rport
->pid
);
629 bfa_trc(rport
->fcs
, event
);
632 case RPSM_EVENT_ACCEPTED
:
633 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_adisc_sending
);
634 bfa_fcs_rport_send_adisc(rport
, NULL
);
637 case RPSM_EVENT_FAILED
:
639 if (rport
->ns_retries
< BFA_FCS_RPORT_MAX_RETRIES
) {
640 bfa_sm_set_state(rport
,
641 bfa_fcs_rport_sm_nsquery_sending
);
642 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
644 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
645 bfa_fcs_rport_offline_action(rport
);
649 case RPSM_EVENT_DELETE
:
650 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logosend
);
651 bfa_fcxp_discard(rport
->fcxp
);
652 bfa_fcs_rport_offline_action(rport
);
658 case RPSM_EVENT_LOGO_RCVD
:
659 case RPSM_EVENT_PRLO_RCVD
:
660 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logorcv
);
661 bfa_fcxp_discard(rport
->fcxp
);
662 bfa_fcs_rport_offline_action(rport
);
665 case RPSM_EVENT_PLOGI_COMP
:
666 case RPSM_EVENT_ADDRESS_CHANGE
:
667 case RPSM_EVENT_PLOGI_RCVD
:
668 case RPSM_EVENT_LOGO_IMP
:
669 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
670 bfa_fcxp_discard(rport
->fcxp
);
671 bfa_fcs_rport_offline_action(rport
);
675 bfa_sm_fault(rport
->fcs
, event
);
680 * An SCN event is received in ONLINE state. ADISC is being sent for
681 * authenticating with rport. FC-4s are paused.
684 bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s
*rport
,
685 enum rport_event event
)
687 bfa_trc(rport
->fcs
, rport
->pwwn
);
688 bfa_trc(rport
->fcs
, rport
->pid
);
689 bfa_trc(rport
->fcs
, event
);
692 case RPSM_EVENT_FCXP_SENT
:
693 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_adisc
);
696 case RPSM_EVENT_DELETE
:
697 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logosend
);
698 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
699 bfa_fcs_rport_offline_action(rport
);
702 case RPSM_EVENT_LOGO_IMP
:
703 case RPSM_EVENT_ADDRESS_CHANGE
:
704 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
705 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
706 bfa_fcs_rport_offline_action(rport
);
709 case RPSM_EVENT_LOGO_RCVD
:
710 case RPSM_EVENT_PRLO_RCVD
:
711 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logorcv
);
712 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
713 bfa_fcs_rport_offline_action(rport
);
719 case RPSM_EVENT_PLOGI_RCVD
:
720 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
721 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
722 bfa_fcs_rport_offline_action(rport
);
726 bfa_sm_fault(rport
->fcs
, event
);
731 * An SCN event is received in ONLINE state. ADISC is to rport.
735 bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
737 bfa_trc(rport
->fcs
, rport
->pwwn
);
738 bfa_trc(rport
->fcs
, rport
->pid
);
739 bfa_trc(rport
->fcs
, event
);
742 case RPSM_EVENT_ACCEPTED
:
743 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_online
);
746 case RPSM_EVENT_PLOGI_RCVD
:
748 * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
749 * At least go offline when a PLOGI is received.
751 bfa_fcxp_discard(rport
->fcxp
);
753 * !!! fall through !!!
756 case RPSM_EVENT_FAILED
:
757 case RPSM_EVENT_ADDRESS_CHANGE
:
758 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
759 bfa_fcs_rport_offline_action(rport
);
762 case RPSM_EVENT_DELETE
:
763 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logosend
);
764 bfa_fcxp_discard(rport
->fcxp
);
765 bfa_fcs_rport_offline_action(rport
);
770 * already processing RSCN
774 case RPSM_EVENT_LOGO_IMP
:
775 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
776 bfa_fcxp_discard(rport
->fcxp
);
777 bfa_fcs_rport_offline_action(rport
);
780 case RPSM_EVENT_LOGO_RCVD
:
781 case RPSM_EVENT_PRLO_RCVD
:
782 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logorcv
);
783 bfa_fcxp_discard(rport
->fcxp
);
784 bfa_fcs_rport_offline_action(rport
);
788 bfa_sm_fault(rport
->fcs
, event
);
793 * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
796 bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s
*rport
,
797 enum rport_event event
)
799 bfa_trc(rport
->fcs
, rport
->pwwn
);
800 bfa_trc(rport
->fcs
, rport
->pid
);
801 bfa_trc(rport
->fcs
, event
);
804 case RPSM_EVENT_FC4_OFFLINE
:
805 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_logorcv
);
806 bfa_sm_send_event(rport
->bfa_rport
, BFA_RPORT_SM_OFFLINE
);
809 case RPSM_EVENT_DELETE
:
810 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logosend
);
813 case RPSM_EVENT_LOGO_RCVD
:
814 case RPSM_EVENT_PRLO_RCVD
:
815 case RPSM_EVENT_ADDRESS_CHANGE
:
819 bfa_sm_fault(rport
->fcs
, event
);
824 * LOGO needs to be sent to rport. Awaiting FC-4 offline completion
828 bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s
*rport
,
829 enum rport_event event
)
831 bfa_trc(rport
->fcs
, rport
->pwwn
);
832 bfa_trc(rport
->fcs
, rport
->pid
);
833 bfa_trc(rport
->fcs
, event
);
836 case RPSM_EVENT_FC4_OFFLINE
:
837 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_logosend
);
838 bfa_sm_send_event(rport
->bfa_rport
, BFA_RPORT_SM_OFFLINE
);
842 bfa_sm_fault(rport
->fcs
, event
);
847 * Rport is going offline. Awaiting FC-4 offline completion callback.
850 bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s
*rport
,
851 enum rport_event event
)
853 bfa_trc(rport
->fcs
, rport
->pwwn
);
854 bfa_trc(rport
->fcs
, rport
->pid
);
855 bfa_trc(rport
->fcs
, event
);
858 case RPSM_EVENT_FC4_OFFLINE
:
859 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_offline
);
860 bfa_sm_send_event(rport
->bfa_rport
, BFA_RPORT_SM_OFFLINE
);
864 case RPSM_EVENT_LOGO_IMP
:
865 case RPSM_EVENT_LOGO_RCVD
:
866 case RPSM_EVENT_PRLO_RCVD
:
867 case RPSM_EVENT_ADDRESS_CHANGE
:
869 * rport is already going offline.
870 * SCN - ignore and wait till transitioning to offline state
874 case RPSM_EVENT_DELETE
:
875 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logosend
);
879 bfa_sm_fault(rport
->fcs
, event
);
884 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
888 bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s
*rport
,
889 enum rport_event event
)
891 bfa_trc(rport
->fcs
, rport
->pwwn
);
892 bfa_trc(rport
->fcs
, rport
->pid
);
893 bfa_trc(rport
->fcs
, event
);
896 case RPSM_EVENT_HCB_OFFLINE
:
897 if (bfa_fcs_lport_is_online(rport
->port
) &&
898 (rport
->plogi_pending
)) {
899 rport
->plogi_pending
= BFA_FALSE
;
900 bfa_sm_set_state(rport
,
901 bfa_fcs_rport_sm_plogiacc_sending
);
902 bfa_fcs_rport_send_plogiacc(rport
, NULL
);
909 case RPSM_EVENT_ADDRESS_CHANGE
:
910 if (bfa_fcs_lport_is_online(rport
->port
)) {
911 if (bfa_fcs_fabric_is_switched(rport
->port
->fabric
)) {
912 bfa_sm_set_state(rport
,
913 bfa_fcs_rport_sm_nsdisc_sending
);
914 rport
->ns_retries
= 0;
915 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
917 bfa_sm_set_state(rport
,
918 bfa_fcs_rport_sm_plogi_sending
);
919 rport
->plogi_retries
= 0;
920 bfa_fcs_rport_send_plogi(rport
, NULL
);
924 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
925 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
926 bfa_fcs_rport_timeout
, rport
,
927 bfa_fcs_rport_del_timeout
);
931 case RPSM_EVENT_DELETE
:
932 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
933 bfa_fcs_rport_free(rport
);
937 case RPSM_EVENT_LOGO_RCVD
:
938 case RPSM_EVENT_PRLO_RCVD
:
939 case RPSM_EVENT_PLOGI_RCVD
:
940 case RPSM_EVENT_LOGO_IMP
:
942 * Ignore, already offline.
947 bfa_sm_fault(rport
->fcs
, event
);
952 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
953 * callback to send LOGO accept.
956 bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s
*rport
,
957 enum rport_event event
)
959 bfa_trc(rport
->fcs
, rport
->pwwn
);
960 bfa_trc(rport
->fcs
, rport
->pid
);
961 bfa_trc(rport
->fcs
, event
);
964 case RPSM_EVENT_HCB_OFFLINE
:
965 case RPSM_EVENT_ADDRESS_CHANGE
:
966 if (rport
->pid
&& (rport
->prlo
== BFA_TRUE
))
967 bfa_fcs_rport_send_prlo_acc(rport
);
968 if (rport
->pid
&& (rport
->prlo
== BFA_FALSE
))
969 bfa_fcs_rport_send_logo_acc(rport
);
971 * If the lport is online and if the rport is not a well
972 * known address port,
973 * we try to re-discover the r-port.
975 if (bfa_fcs_lport_is_online(rport
->port
) &&
976 (!BFA_FCS_PID_IS_WKA(rport
->pid
))) {
977 if (bfa_fcs_fabric_is_switched(rport
->port
->fabric
)) {
978 bfa_sm_set_state(rport
,
979 bfa_fcs_rport_sm_nsdisc_sending
);
980 rport
->ns_retries
= 0;
981 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
983 /* For N2N Direct Attach, try to re-login */
984 bfa_sm_set_state(rport
,
985 bfa_fcs_rport_sm_plogi_sending
);
986 rport
->plogi_retries
= 0;
987 bfa_fcs_rport_send_plogi(rport
, NULL
);
991 * if it is not a well known address, reset the
994 if (!BFA_FCS_PID_IS_WKA(rport
->pid
))
996 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
997 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
998 bfa_fcs_rport_timeout
, rport
,
999 bfa_fcs_rport_del_timeout
);
1003 case RPSM_EVENT_DELETE
:
1004 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_logosend
);
1007 case RPSM_EVENT_LOGO_IMP
:
1008 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_offline
);
1011 case RPSM_EVENT_LOGO_RCVD
:
1012 case RPSM_EVENT_PRLO_RCVD
:
1014 * Ignore - already processing a LOGO.
1019 bfa_sm_fault(rport
->fcs
, event
);
1024 * Rport is being deleted. FC-4s are offline.
1025 * Awaiting BFA rport offline
1026 * callback to send LOGO.
1029 bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s
*rport
,
1030 enum rport_event event
)
1032 bfa_trc(rport
->fcs
, rport
->pwwn
);
1033 bfa_trc(rport
->fcs
, rport
->pid
);
1034 bfa_trc(rport
->fcs
, event
);
1037 case RPSM_EVENT_HCB_OFFLINE
:
1038 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_logo_sending
);
1039 bfa_fcs_rport_send_logo(rport
, NULL
);
1042 case RPSM_EVENT_LOGO_RCVD
:
1043 case RPSM_EVENT_PRLO_RCVD
:
1044 case RPSM_EVENT_ADDRESS_CHANGE
:
1048 bfa_sm_fault(rport
->fcs
, event
);
1053 * Rport is being deleted. FC-4s are offline. LOGO is being sent.
1056 bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s
*rport
,
1057 enum rport_event event
)
1059 bfa_trc(rport
->fcs
, rport
->pwwn
);
1060 bfa_trc(rport
->fcs
, rport
->pid
);
1061 bfa_trc(rport
->fcs
, event
);
1064 case RPSM_EVENT_FCXP_SENT
:
1065 /* Once LOGO is sent, we donot wait for the response */
1066 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
1067 bfa_fcs_rport_free(rport
);
1070 case RPSM_EVENT_SCN
:
1071 case RPSM_EVENT_ADDRESS_CHANGE
:
1074 case RPSM_EVENT_LOGO_RCVD
:
1075 case RPSM_EVENT_PRLO_RCVD
:
1076 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
1077 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
1078 bfa_fcs_rport_free(rport
);
1082 bfa_sm_fault(rport
->fcs
, event
);
1087 * Rport is offline. FC-4s are offline. BFA rport is offline.
1088 * Timer active to delete stale rport.
1091 bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
1093 bfa_trc(rport
->fcs
, rport
->pwwn
);
1094 bfa_trc(rport
->fcs
, rport
->pid
);
1095 bfa_trc(rport
->fcs
, event
);
1098 case RPSM_EVENT_TIMEOUT
:
1099 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
1100 bfa_fcs_rport_free(rport
);
1103 case RPSM_EVENT_SCN
:
1104 case RPSM_EVENT_ADDRESS_CHANGE
:
1105 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsdisc_sending
);
1106 bfa_timer_stop(&rport
->timer
);
1107 rport
->ns_retries
= 0;
1108 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
1111 case RPSM_EVENT_DELETE
:
1112 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
1113 bfa_timer_stop(&rport
->timer
);
1114 bfa_fcs_rport_free(rport
);
1117 case RPSM_EVENT_PLOGI_RCVD
:
1118 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogiacc_sending
);
1119 bfa_timer_stop(&rport
->timer
);
1120 bfa_fcs_rport_send_plogiacc(rport
, NULL
);
1123 case RPSM_EVENT_LOGO_RCVD
:
1124 case RPSM_EVENT_PRLO_RCVD
:
1125 case RPSM_EVENT_LOGO_IMP
:
1128 case RPSM_EVENT_PLOGI_COMP
:
1129 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
1130 bfa_timer_stop(&rport
->timer
);
1131 bfa_fcs_rport_hal_online(rport
);
1134 case RPSM_EVENT_PLOGI_SEND
:
1135 bfa_timer_stop(&rport
->timer
);
1136 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogi_sending
);
1137 rport
->plogi_retries
= 0;
1138 bfa_fcs_rport_send_plogi(rport
, NULL
);
1142 bfa_sm_fault(rport
->fcs
, event
);
1147 * Rport address has changed. Nameserver discovery request is being sent.
1150 bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s
*rport
,
1151 enum rport_event event
)
1153 bfa_trc(rport
->fcs
, rport
->pwwn
);
1154 bfa_trc(rport
->fcs
, rport
->pid
);
1155 bfa_trc(rport
->fcs
, event
);
1158 case RPSM_EVENT_FCXP_SENT
:
1159 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsdisc_sent
);
1162 case RPSM_EVENT_DELETE
:
1163 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
1164 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
1165 bfa_fcs_rport_free(rport
);
1168 case RPSM_EVENT_PLOGI_RCVD
:
1169 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogiacc_sending
);
1170 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
1171 bfa_fcs_rport_send_plogiacc(rport
, NULL
);
1174 case RPSM_EVENT_SCN
:
1175 case RPSM_EVENT_LOGO_RCVD
:
1176 case RPSM_EVENT_PRLO_RCVD
:
1177 case RPSM_EVENT_PLOGI_SEND
:
1180 case RPSM_EVENT_ADDRESS_CHANGE
:
1181 rport
->ns_retries
= 0; /* reset the retry count */
1184 case RPSM_EVENT_LOGO_IMP
:
1185 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
1186 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
1187 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
1188 bfa_fcs_rport_timeout
, rport
,
1189 bfa_fcs_rport_del_timeout
);
1192 case RPSM_EVENT_PLOGI_COMP
:
1193 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
1194 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
1195 bfa_fcs_rport_hal_online(rport
);
1199 bfa_sm_fault(rport
->fcs
, event
);
1204 * Nameserver discovery failed. Waiting for timeout to retry.
1207 bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s
*rport
,
1208 enum rport_event event
)
1210 bfa_trc(rport
->fcs
, rport
->pwwn
);
1211 bfa_trc(rport
->fcs
, rport
->pid
);
1212 bfa_trc(rport
->fcs
, event
);
1215 case RPSM_EVENT_TIMEOUT
:
1216 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsdisc_sending
);
1217 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
1220 case RPSM_EVENT_SCN
:
1221 case RPSM_EVENT_ADDRESS_CHANGE
:
1222 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsdisc_sending
);
1223 bfa_timer_stop(&rport
->timer
);
1224 rport
->ns_retries
= 0;
1225 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
1228 case RPSM_EVENT_DELETE
:
1229 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
1230 bfa_timer_stop(&rport
->timer
);
1231 bfa_fcs_rport_free(rport
);
1234 case RPSM_EVENT_PLOGI_RCVD
:
1235 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogiacc_sending
);
1236 bfa_timer_stop(&rport
->timer
);
1237 bfa_fcs_rport_send_plogiacc(rport
, NULL
);
1240 case RPSM_EVENT_LOGO_IMP
:
1242 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
1243 bfa_timer_stop(&rport
->timer
);
1244 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
1245 bfa_fcs_rport_timeout
, rport
,
1246 bfa_fcs_rport_del_timeout
);
1249 case RPSM_EVENT_LOGO_RCVD
:
1250 bfa_fcs_rport_send_logo_acc(rport
);
1252 case RPSM_EVENT_PRLO_RCVD
:
1253 bfa_fcs_rport_send_prlo_acc(rport
);
1256 case RPSM_EVENT_PLOGI_COMP
:
1257 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
1258 bfa_timer_stop(&rport
->timer
);
1259 bfa_fcs_rport_hal_online(rport
);
1263 bfa_sm_fault(rport
->fcs
, event
);
1268 * Rport address has changed. Nameserver discovery request is sent.
1271 bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s
*rport
,
1272 enum rport_event event
)
1274 bfa_trc(rport
->fcs
, rport
->pwwn
);
1275 bfa_trc(rport
->fcs
, rport
->pid
);
1276 bfa_trc(rport
->fcs
, event
);
1279 case RPSM_EVENT_ACCEPTED
:
1280 case RPSM_EVENT_ADDRESS_CHANGE
:
1282 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogi_sending
);
1283 bfa_fcs_rport_send_plogi(rport
, NULL
);
1285 bfa_sm_set_state(rport
,
1286 bfa_fcs_rport_sm_nsdisc_sending
);
1287 rport
->ns_retries
= 0;
1288 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
1292 case RPSM_EVENT_FAILED
:
1293 rport
->ns_retries
++;
1294 if (rport
->ns_retries
< BFA_FCS_RPORT_MAX_RETRIES
) {
1295 bfa_sm_set_state(rport
,
1296 bfa_fcs_rport_sm_nsdisc_sending
);
1297 bfa_fcs_rport_send_nsdisc(rport
, NULL
);
1300 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
1301 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
1302 bfa_fcs_rport_timeout
, rport
,
1303 bfa_fcs_rport_del_timeout
);
1307 case RPSM_EVENT_DELETE
:
1308 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
1309 bfa_fcxp_discard(rport
->fcxp
);
1310 bfa_fcs_rport_free(rport
);
1313 case RPSM_EVENT_PLOGI_RCVD
:
1314 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogiacc_sending
);
1315 bfa_fcxp_discard(rport
->fcxp
);
1316 bfa_fcs_rport_send_plogiacc(rport
, NULL
);
1319 case RPSM_EVENT_LOGO_IMP
:
1321 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
1322 bfa_fcxp_discard(rport
->fcxp
);
1323 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
1324 bfa_fcs_rport_timeout
, rport
,
1325 bfa_fcs_rport_del_timeout
);
1329 case RPSM_EVENT_PRLO_RCVD
:
1330 bfa_fcs_rport_send_prlo_acc(rport
);
1332 case RPSM_EVENT_SCN
:
1334 * ignore, wait for NS query response
1338 case RPSM_EVENT_LOGO_RCVD
:
1340 * Not logged-in yet. Accept LOGO.
1342 bfa_fcs_rport_send_logo_acc(rport
);
1345 case RPSM_EVENT_PLOGI_COMP
:
1346 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
1347 bfa_fcxp_discard(rport
->fcxp
);
1348 bfa_fcs_rport_hal_online(rport
);
1352 bfa_sm_fault(rport
->fcs
, event
);
1359 * fcs_rport_private FCS RPORT provate functions
1363 bfa_fcs_rport_send_plogi(void *rport_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1365 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
1366 struct bfa_fcs_lport_s
*port
= rport
->port
;
1369 struct bfa_fcxp_s
*fcxp
;
1371 bfa_trc(rport
->fcs
, rport
->pwwn
);
1373 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1375 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rport
->fcxp_wqe
,
1376 bfa_fcs_rport_send_plogi
, rport
);
1381 len
= fc_plogi_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
), rport
->pid
,
1382 bfa_fcs_lport_get_fcid(port
), 0,
1383 port
->port_cfg
.pwwn
, port
->port_cfg
.nwwn
,
1384 bfa_fcport_get_maxfrsize(port
->fcs
->bfa
),
1385 bfa_fcport_get_rx_bbcredit(port
->fcs
->bfa
));
1387 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1388 FC_CLASS_3
, len
, &fchs
, bfa_fcs_rport_plogi_response
,
1389 (void *)rport
, FC_MAX_PDUSZ
, FC_ELS_TOV
);
1391 rport
->stats
.plogis
++;
1392 bfa_sm_send_event(rport
, RPSM_EVENT_FCXP_SENT
);
1396 bfa_fcs_rport_plogi_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
, void *cbarg
,
1397 bfa_status_t req_status
, u32 rsp_len
,
1398 u32 resid_len
, struct fchs_s
*rsp_fchs
)
1400 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
1401 struct fc_logi_s
*plogi_rsp
;
1402 struct fc_ls_rjt_s
*ls_rjt
;
1403 struct bfa_fcs_rport_s
*twin
;
1404 struct list_head
*qe
;
1406 bfa_trc(rport
->fcs
, rport
->pwwn
);
1411 if (req_status
!= BFA_STATUS_OK
) {
1412 bfa_trc(rport
->fcs
, req_status
);
1413 rport
->stats
.plogi_failed
++;
1414 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1418 plogi_rsp
= (struct fc_logi_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1421 * Check for failure first.
1423 if (plogi_rsp
->els_cmd
.els_code
!= FC_ELS_ACC
) {
1424 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1426 bfa_trc(rport
->fcs
, ls_rjt
->reason_code
);
1427 bfa_trc(rport
->fcs
, ls_rjt
->reason_code_expl
);
1429 if ((ls_rjt
->reason_code
== FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD
) &&
1430 (ls_rjt
->reason_code_expl
== FC_LS_RJT_EXP_INSUFF_RES
)) {
1431 rport
->stats
.rjt_insuff_res
++;
1432 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_RETRY
);
1436 rport
->stats
.plogi_rejects
++;
1437 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1442 * PLOGI is complete. Make sure this device is not one of the known
1443 * device with a new FC port address.
1445 list_for_each(qe
, &rport
->port
->rport_q
) {
1446 twin
= (struct bfa_fcs_rport_s
*) qe
;
1449 if (!rport
->pwwn
&& (plogi_rsp
->port_name
== twin
->pwwn
)) {
1450 bfa_trc(rport
->fcs
, twin
->pid
);
1451 bfa_trc(rport
->fcs
, rport
->pid
);
1453 /* Update plogi stats in twin */
1454 twin
->stats
.plogis
+= rport
->stats
.plogis
;
1455 twin
->stats
.plogi_rejects
+=
1456 rport
->stats
.plogi_rejects
;
1457 twin
->stats
.plogi_timeouts
+=
1458 rport
->stats
.plogi_timeouts
;
1459 twin
->stats
.plogi_failed
+=
1460 rport
->stats
.plogi_failed
;
1461 twin
->stats
.plogi_rcvd
+= rport
->stats
.plogi_rcvd
;
1462 twin
->stats
.plogi_accs
++;
1464 bfa_sm_send_event(rport
, RPSM_EVENT_DELETE
);
1466 bfa_fcs_rport_update(twin
, plogi_rsp
);
1467 twin
->pid
= rsp_fchs
->s_id
;
1468 bfa_sm_send_event(twin
, RPSM_EVENT_PLOGI_COMP
);
1474 * Normal login path -- no evil twins.
1476 rport
->stats
.plogi_accs
++;
1477 bfa_fcs_rport_update(rport
, plogi_rsp
);
1478 bfa_sm_send_event(rport
, RPSM_EVENT_ACCEPTED
);
1482 bfa_fcs_rport_send_plogiacc(void *rport_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1484 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
1485 struct bfa_fcs_lport_s
*port
= rport
->port
;
1488 struct bfa_fcxp_s
*fcxp
;
1490 bfa_trc(rport
->fcs
, rport
->pwwn
);
1491 bfa_trc(rport
->fcs
, rport
->reply_oxid
);
1493 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1495 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rport
->fcxp_wqe
,
1496 bfa_fcs_rport_send_plogiacc
, rport
);
1501 len
= fc_plogi_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
1502 rport
->pid
, bfa_fcs_lport_get_fcid(port
),
1503 rport
->reply_oxid
, port
->port_cfg
.pwwn
,
1504 port
->port_cfg
.nwwn
,
1505 bfa_fcport_get_maxfrsize(port
->fcs
->bfa
),
1506 bfa_fcport_get_rx_bbcredit(port
->fcs
->bfa
));
1508 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1509 FC_CLASS_3
, len
, &fchs
, NULL
, NULL
, FC_MAX_PDUSZ
, 0);
1511 bfa_sm_send_event(rport
, RPSM_EVENT_FCXP_SENT
);
1515 bfa_fcs_rport_send_adisc(void *rport_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1517 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
1518 struct bfa_fcs_lport_s
*port
= rport
->port
;
1521 struct bfa_fcxp_s
*fcxp
;
1523 bfa_trc(rport
->fcs
, rport
->pwwn
);
1525 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1527 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rport
->fcxp_wqe
,
1528 bfa_fcs_rport_send_adisc
, rport
);
1533 len
= fc_adisc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
), rport
->pid
,
1534 bfa_fcs_lport_get_fcid(port
), 0,
1535 port
->port_cfg
.pwwn
, port
->port_cfg
.nwwn
);
1537 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1538 FC_CLASS_3
, len
, &fchs
, bfa_fcs_rport_adisc_response
,
1539 rport
, FC_MAX_PDUSZ
, FC_ELS_TOV
);
1541 rport
->stats
.adisc_sent
++;
1542 bfa_sm_send_event(rport
, RPSM_EVENT_FCXP_SENT
);
1546 bfa_fcs_rport_adisc_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
, void *cbarg
,
1547 bfa_status_t req_status
, u32 rsp_len
,
1548 u32 resid_len
, struct fchs_s
*rsp_fchs
)
1550 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
1551 void *pld
= bfa_fcxp_get_rspbuf(fcxp
);
1552 struct fc_ls_rjt_s
*ls_rjt
;
1554 if (req_status
!= BFA_STATUS_OK
) {
1555 bfa_trc(rport
->fcs
, req_status
);
1556 rport
->stats
.adisc_failed
++;
1557 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1561 if (fc_adisc_rsp_parse((struct fc_adisc_s
*)pld
, rsp_len
, rport
->pwwn
,
1562 rport
->nwwn
) == FC_PARSE_OK
) {
1563 rport
->stats
.adisc_accs
++;
1564 bfa_sm_send_event(rport
, RPSM_EVENT_ACCEPTED
);
1568 rport
->stats
.adisc_rejects
++;
1570 bfa_trc(rport
->fcs
, ls_rjt
->els_cmd
.els_code
);
1571 bfa_trc(rport
->fcs
, ls_rjt
->reason_code
);
1572 bfa_trc(rport
->fcs
, ls_rjt
->reason_code_expl
);
1573 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1577 bfa_fcs_rport_send_nsdisc(void *rport_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1579 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
1580 struct bfa_fcs_lport_s
*port
= rport
->port
;
1582 struct bfa_fcxp_s
*fcxp
;
1584 bfa_cb_fcxp_send_t cbfn
;
1586 bfa_trc(rport
->fcs
, rport
->pid
);
1588 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1590 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rport
->fcxp_wqe
,
1591 bfa_fcs_rport_send_nsdisc
, rport
);
1597 len
= fc_gidpn_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
1598 bfa_fcs_lport_get_fcid(port
), 0, rport
->pwwn
);
1599 cbfn
= bfa_fcs_rport_gidpn_response
;
1601 len
= fc_gpnid_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
1602 bfa_fcs_lport_get_fcid(port
), 0, rport
->pid
);
1603 cbfn
= bfa_fcs_rport_gpnid_response
;
1606 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1607 FC_CLASS_3
, len
, &fchs
, cbfn
,
1608 (void *)rport
, FC_MAX_PDUSZ
, FC_FCCT_TOV
);
1610 bfa_sm_send_event(rport
, RPSM_EVENT_FCXP_SENT
);
1614 bfa_fcs_rport_gidpn_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
, void *cbarg
,
1615 bfa_status_t req_status
, u32 rsp_len
,
1616 u32 resid_len
, struct fchs_s
*rsp_fchs
)
1618 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
1619 struct ct_hdr_s
*cthdr
;
1620 struct fcgs_gidpn_resp_s
*gidpn_rsp
;
1621 struct bfa_fcs_rport_s
*twin
;
1622 struct list_head
*qe
;
1624 bfa_trc(rport
->fcs
, rport
->pwwn
);
1626 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1627 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
1629 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
1630 /* Check if the pid is the same as before. */
1631 gidpn_rsp
= (struct fcgs_gidpn_resp_s
*) (cthdr
+ 1);
1633 if (gidpn_rsp
->dap
== rport
->pid
) {
1634 /* Device is online */
1635 bfa_sm_send_event(rport
, RPSM_EVENT_ACCEPTED
);
1638 * Device's PID has changed. We need to cleanup
1639 * and re-login. If there is another device with
1640 * the the newly discovered pid, send an scn notice
1641 * so that its new pid can be discovered.
1643 list_for_each(qe
, &rport
->port
->rport_q
) {
1644 twin
= (struct bfa_fcs_rport_s
*) qe
;
1647 if (gidpn_rsp
->dap
== twin
->pid
) {
1648 bfa_trc(rport
->fcs
, twin
->pid
);
1649 bfa_trc(rport
->fcs
, rport
->pid
);
1652 bfa_sm_send_event(twin
,
1653 RPSM_EVENT_ADDRESS_CHANGE
);
1656 rport
->pid
= gidpn_rsp
->dap
;
1657 bfa_sm_send_event(rport
, RPSM_EVENT_ADDRESS_CHANGE
);
1665 switch (cthdr
->reason_code
) {
1666 case CT_RSN_LOGICAL_BUSY
:
1670 bfa_sm_send_event(rport
, RPSM_EVENT_TIMEOUT
);
1673 case CT_RSN_UNABLE_TO_PERF
:
1675 * device doesn't exist : Start timer to cleanup this later.
1677 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1681 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1687 bfa_fcs_rport_gpnid_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
, void *cbarg
,
1688 bfa_status_t req_status
, u32 rsp_len
,
1689 u32 resid_len
, struct fchs_s
*rsp_fchs
)
1691 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
1692 struct ct_hdr_s
*cthdr
;
1694 bfa_trc(rport
->fcs
, rport
->pwwn
);
1696 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1697 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
1699 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
1700 bfa_sm_send_event(rport
, RPSM_EVENT_ACCEPTED
);
1707 switch (cthdr
->reason_code
) {
1708 case CT_RSN_LOGICAL_BUSY
:
1712 bfa_sm_send_event(rport
, RPSM_EVENT_TIMEOUT
);
1715 case CT_RSN_UNABLE_TO_PERF
:
1717 * device doesn't exist : Start timer to cleanup this later.
1719 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1723 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1729 * Called to send a logout to the rport.
1732 bfa_fcs_rport_send_logo(void *rport_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1734 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
1735 struct bfa_fcs_lport_s
*port
;
1737 struct bfa_fcxp_s
*fcxp
;
1740 bfa_trc(rport
->fcs
, rport
->pid
);
1744 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
1746 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rport
->fcxp_wqe
,
1747 bfa_fcs_rport_send_logo
, rport
);
1752 len
= fc_logo_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
), rport
->pid
,
1753 bfa_fcs_lport_get_fcid(port
), 0,
1754 bfa_fcs_lport_get_pwwn(port
));
1756 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1757 FC_CLASS_3
, len
, &fchs
, NULL
,
1758 rport
, FC_MAX_PDUSZ
, FC_ELS_TOV
);
1760 rport
->stats
.logos
++;
1761 bfa_fcxp_discard(rport
->fcxp
);
1762 bfa_sm_send_event(rport
, RPSM_EVENT_FCXP_SENT
);
1766 * Send ACC for a LOGO received.
1769 bfa_fcs_rport_send_logo_acc(void *rport_cbarg
)
1771 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
1772 struct bfa_fcs_lport_s
*port
;
1774 struct bfa_fcxp_s
*fcxp
;
1777 bfa_trc(rport
->fcs
, rport
->pid
);
1781 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
1785 rport
->stats
.logo_rcvd
++;
1786 len
= fc_logo_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
1787 rport
->pid
, bfa_fcs_lport_get_fcid(port
),
1790 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1791 FC_CLASS_3
, len
, &fchs
, NULL
, NULL
, FC_MAX_PDUSZ
, 0);
1796 * This routine will be called by bfa_timer on timer timeouts.
1798 * param[in] rport - pointer to bfa_fcs_lport_ns_t.
1799 * param[out] rport_status - pointer to return vport status in
1804 * Special Considerations:
1809 bfa_fcs_rport_timeout(void *arg
)
1811 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) arg
;
1813 rport
->stats
.plogi_timeouts
++;
1814 bfa_stats(rport
->port
, rport_plogi_timeouts
);
1815 bfa_sm_send_event(rport
, RPSM_EVENT_TIMEOUT
);
1819 bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s
*rport
,
1820 struct fchs_s
*rx_fchs
, u16 len
)
1822 struct bfa_fcxp_s
*fcxp
;
1824 struct bfa_fcs_lport_s
*port
= rport
->port
;
1825 struct fc_prli_s
*prli
;
1827 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
1828 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
1830 rport
->stats
.prli_rcvd
++;
1833 * We are in Initiator Mode
1835 prli
= (struct fc_prli_s
*) (rx_fchs
+ 1);
1837 if (prli
->parampage
.servparams
.target
) {
1839 * PRLI from a target ?
1841 * PRLI sent by us will be used to transition the IT nexus,
1842 * once the response is received from the target.
1844 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
1845 rport
->scsi_function
= BFA_RPORT_TARGET
;
1847 bfa_trc(rport
->fcs
, prli
->parampage
.type
);
1848 rport
->scsi_function
= BFA_RPORT_INITIATOR
;
1849 bfa_fcs_itnim_is_initiator(rport
->itnim
);
1852 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
1856 len
= fc_prli_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
1857 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
1858 rx_fchs
->ox_id
, port
->port_cfg
.roles
);
1860 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1861 FC_CLASS_3
, len
, &fchs
, NULL
, NULL
, FC_MAX_PDUSZ
, 0);
1865 bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s
*rport
,
1866 struct fchs_s
*rx_fchs
, u16 len
)
1868 struct bfa_fcxp_s
*fcxp
;
1870 struct bfa_fcs_lport_s
*port
= rport
->port
;
1871 struct fc_rpsc_speed_info_s speeds
;
1872 struct bfa_port_attr_s pport_attr
;
1874 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
1875 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
1877 rport
->stats
.rpsc_rcvd
++;
1878 speeds
.port_speed_cap
=
1879 RPSC_SPEED_CAP_1G
| RPSC_SPEED_CAP_2G
| RPSC_SPEED_CAP_4G
|
1883 * get curent speed from pport attributes from BFA
1885 bfa_fcport_get_attr(port
->fcs
->bfa
, &pport_attr
);
1887 speeds
.port_op_speed
= fc_bfa_speed_to_rpsc_operspeed(pport_attr
.speed
);
1889 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
1893 len
= fc_rpsc_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
1894 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
1895 rx_fchs
->ox_id
, &speeds
);
1897 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
1898 FC_CLASS_3
, len
, &fchs
, NULL
, NULL
, FC_MAX_PDUSZ
, 0);
1902 bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s
*rport
,
1903 struct fchs_s
*rx_fchs
, u16 len
)
1905 struct bfa_fcxp_s
*fcxp
;
1907 struct bfa_fcs_lport_s
*port
= rport
->port
;
1908 struct fc_adisc_s
*adisc
;
1910 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
1911 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
1913 rport
->stats
.adisc_rcvd
++;
1915 adisc
= (struct fc_adisc_s
*) (rx_fchs
+ 1);
1918 * Accept if the itnim for this rport is online.
1919 * Else reject the ADISC.
1921 if (bfa_fcs_itnim_get_online_state(rport
->itnim
) == BFA_STATUS_OK
) {
1923 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
1927 len
= fc_adisc_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
1928 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
1929 rx_fchs
->ox_id
, port
->port_cfg
.pwwn
,
1930 port
->port_cfg
.nwwn
);
1932 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
,
1933 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
1936 rport
->stats
.adisc_rejected
++;
1937 bfa_fcs_rport_send_ls_rjt(rport
, rx_fchs
,
1938 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD
,
1939 FC_LS_RJT_EXP_LOGIN_REQUIRED
);
1944 bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s
*rport
)
1946 struct bfa_fcs_lport_s
*port
= rport
->port
;
1947 struct bfa_rport_info_s rport_info
;
1949 rport_info
.pid
= rport
->pid
;
1950 rport_info
.local_pid
= port
->pid
;
1951 rport_info
.lp_tag
= port
->lp_tag
;
1952 rport_info
.vf_id
= port
->fabric
->vf_id
;
1953 rport_info
.vf_en
= port
->fabric
->is_vf
;
1954 rport_info
.fc_class
= rport
->fc_cos
;
1955 rport_info
.cisc
= rport
->cisc
;
1956 rport_info
.max_frmsz
= rport
->maxfrsize
;
1957 bfa_rport_online(rport
->bfa_rport
, &rport_info
);
1960 static struct bfa_fcs_rport_s
*
1961 bfa_fcs_rport_alloc(struct bfa_fcs_lport_s
*port
, wwn_t pwwn
, u32 rpid
)
1963 struct bfa_fcs_s
*fcs
= port
->fcs
;
1964 struct bfa_fcs_rport_s
*rport
;
1965 struct bfad_rport_s
*rport_drv
;
1970 if (bfa_fcb_rport_alloc(fcs
->bfad
, &rport
, &rport_drv
)
1981 rport
->rp_drv
= rport_drv
;
1986 * allocate BFA rport
1988 rport
->bfa_rport
= bfa_rport_create(port
->fcs
->bfa
, rport
);
1989 if (!rport
->bfa_rport
) {
1998 WARN_ON(!bfa_fcs_lport_is_initiator(port
));
2000 if (bfa_fcs_lport_is_initiator(port
)) {
2001 rport
->itnim
= bfa_fcs_itnim_create(rport
);
2002 if (!rport
->itnim
) {
2004 bfa_sm_send_event(rport
->bfa_rport
,
2005 BFA_RPORT_SM_DELETE
);
2011 bfa_fcs_lport_add_rport(port
, rport
);
2013 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
2015 /* Initialize the Rport Features(RPF) Sub Module */
2016 if (!BFA_FCS_PID_IS_WKA(rport
->pid
))
2017 bfa_fcs_rpf_init(rport
);
2024 bfa_fcs_rport_free(struct bfa_fcs_rport_s
*rport
)
2026 struct bfa_fcs_lport_s
*port
= rport
->port
;
2030 * - delete BFA rport
2031 * - remove from queue of rports
2033 if (bfa_fcs_lport_is_initiator(port
)) {
2034 bfa_fcs_itnim_delete(rport
->itnim
);
2035 if (rport
->pid
!= 0 && !BFA_FCS_PID_IS_WKA(rport
->pid
))
2036 bfa_fcs_rpf_rport_offline(rport
);
2039 bfa_sm_send_event(rport
->bfa_rport
, BFA_RPORT_SM_DELETE
);
2040 bfa_fcs_lport_del_rport(port
, rport
);
2041 kfree(rport
->rp_drv
);
2045 bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s
*rport
,
2046 enum bfa_rport_aen_event event
,
2047 struct bfa_rport_aen_data_s
*data
)
2049 struct bfa_fcs_lport_s
*port
= rport
->port
;
2050 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fcs
->bfad
;
2051 struct bfa_aen_entry_s
*aen_entry
;
2053 bfad_get_aen_entry(bfad
, aen_entry
);
2057 if (event
== BFA_RPORT_AEN_QOS_PRIO
)
2058 aen_entry
->aen_data
.rport
.priv
.qos
= data
->priv
.qos
;
2059 else if (event
== BFA_RPORT_AEN_QOS_FLOWID
)
2060 aen_entry
->aen_data
.rport
.priv
.qos
= data
->priv
.qos
;
2062 aen_entry
->aen_data
.rport
.vf_id
= rport
->port
->fabric
->vf_id
;
2063 aen_entry
->aen_data
.rport
.ppwwn
= bfa_fcs_lport_get_pwwn(
2064 bfa_fcs_get_base_port(rport
->fcs
));
2065 aen_entry
->aen_data
.rport
.lpwwn
= bfa_fcs_lport_get_pwwn(rport
->port
);
2066 aen_entry
->aen_data
.rport
.rpwwn
= rport
->pwwn
;
2068 /* Send the AEN notification */
2069 bfad_im_post_vendor_event(aen_entry
, bfad
, ++rport
->fcs
->fcs_aen_seq
,
2070 BFA_AEN_CAT_RPORT
, event
);
2074 bfa_fcs_rport_online_action(struct bfa_fcs_rport_s
*rport
)
2076 struct bfa_fcs_lport_s
*port
= rport
->port
;
2077 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fcs
->bfad
;
2078 char lpwwn_buf
[BFA_STRING_32
];
2079 char rpwwn_buf
[BFA_STRING_32
];
2081 rport
->stats
.onlines
++;
2083 if ((!rport
->pid
) || (!rport
->pwwn
)) {
2084 bfa_trc(rport
->fcs
, rport
->pid
);
2085 bfa_sm_fault(rport
->fcs
, rport
->pid
);
2088 if (bfa_fcs_lport_is_initiator(port
)) {
2089 bfa_fcs_itnim_rport_online(rport
->itnim
);
2090 if (!BFA_FCS_PID_IS_WKA(rport
->pid
))
2091 bfa_fcs_rpf_rport_online(rport
);
2094 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(port
));
2095 wwn2str(rpwwn_buf
, rport
->pwwn
);
2096 if (!BFA_FCS_PID_IS_WKA(rport
->pid
)) {
2097 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
2098 "Remote port (WWN = %s) online for logical port (WWN = %s)\n",
2099 rpwwn_buf
, lpwwn_buf
);
2100 bfa_fcs_rport_aen_post(rport
, BFA_RPORT_AEN_ONLINE
, NULL
);
2105 bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s
*rport
)
2107 struct bfa_fcs_lport_s
*port
= rport
->port
;
2108 struct bfad_s
*bfad
= (struct bfad_s
*)port
->fcs
->bfad
;
2109 char lpwwn_buf
[BFA_STRING_32
];
2110 char rpwwn_buf
[BFA_STRING_32
];
2112 rport
->stats
.offlines
++;
2113 rport
->plogi_pending
= BFA_FALSE
;
2115 wwn2str(lpwwn_buf
, bfa_fcs_lport_get_pwwn(port
));
2116 wwn2str(rpwwn_buf
, rport
->pwwn
);
2117 if (!BFA_FCS_PID_IS_WKA(rport
->pid
)) {
2118 if (bfa_fcs_lport_is_online(rport
->port
) == BFA_TRUE
) {
2119 BFA_LOG(KERN_ERR
, bfad
, bfa_log_level
,
2120 "Remote port (WWN = %s) connectivity lost for "
2121 "logical port (WWN = %s)\n",
2122 rpwwn_buf
, lpwwn_buf
);
2123 bfa_fcs_rport_aen_post(rport
,
2124 BFA_RPORT_AEN_DISCONNECT
, NULL
);
2126 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
2127 "Remote port (WWN = %s) offlined by "
2128 "logical port (WWN = %s)\n",
2129 rpwwn_buf
, lpwwn_buf
);
2130 bfa_fcs_rport_aen_post(rport
,
2131 BFA_RPORT_AEN_OFFLINE
, NULL
);
2135 if (bfa_fcs_lport_is_initiator(port
)) {
2136 bfa_fcs_itnim_rport_offline(rport
->itnim
);
2137 if (!BFA_FCS_PID_IS_WKA(rport
->pid
))
2138 bfa_fcs_rpf_rport_offline(rport
);
2143 * Update rport parameters from PLOGI or PLOGI accept.
2146 bfa_fcs_rport_update(struct bfa_fcs_rport_s
*rport
, struct fc_logi_s
*plogi
)
2148 bfa_fcs_lport_t
*port
= rport
->port
;
2154 rport
->pwwn
= plogi
->port_name
;
2155 rport
->nwwn
= plogi
->node_name
;
2158 * - class of service
2161 if (plogi
->class3
.class_valid
)
2162 rport
->fc_cos
= FC_CLASS_3
;
2164 if (plogi
->class2
.class_valid
)
2165 rport
->fc_cos
|= FC_CLASS_2
;
2169 * - MAX receive frame size
2171 rport
->cisc
= plogi
->csp
.cisc
;
2172 if (be16_to_cpu(plogi
->class3
.rxsz
) < be16_to_cpu(plogi
->csp
.rxsz
))
2173 rport
->maxfrsize
= be16_to_cpu(plogi
->class3
.rxsz
);
2175 rport
->maxfrsize
= be16_to_cpu(plogi
->csp
.rxsz
);
2177 bfa_trc(port
->fcs
, be16_to_cpu(plogi
->csp
.bbcred
));
2178 bfa_trc(port
->fcs
, port
->fabric
->bb_credit
);
2180 * Direct Attach P2P mode :
2181 * This is to handle a bug (233476) in IBM targets in Direct Attach
2182 * Mode. Basically, in FLOGI Accept the target would have
2183 * erroneously set the BB Credit to the value used in the FLOGI
2184 * sent by the HBA. It uses the correct value (its own BB credit)
2187 if ((!bfa_fcs_fabric_is_switched(port
->fabric
)) &&
2188 (be16_to_cpu(plogi
->csp
.bbcred
) < port
->fabric
->bb_credit
)) {
2190 bfa_trc(port
->fcs
, be16_to_cpu(plogi
->csp
.bbcred
));
2191 bfa_trc(port
->fcs
, port
->fabric
->bb_credit
);
2193 port
->fabric
->bb_credit
= be16_to_cpu(plogi
->csp
.bbcred
);
2194 bfa_fcport_set_tx_bbcredit(port
->fcs
->bfa
,
2195 port
->fabric
->bb_credit
, 0);
2201 * Called to handle LOGO received from an existing remote port.
2204 bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s
*rport
, struct fchs_s
*fchs
)
2206 rport
->reply_oxid
= fchs
->ox_id
;
2207 bfa_trc(rport
->fcs
, rport
->reply_oxid
);
2209 rport
->prlo
= BFA_FALSE
;
2210 rport
->stats
.logo_rcvd
++;
2211 bfa_sm_send_event(rport
, RPSM_EVENT_LOGO_RCVD
);
2217 * fcs_rport_public FCS rport public interfaces
2221 * Called by bport/vport to create a remote port instance for a discovered
2224 * @param[in] port - base port or vport
2225 * @param[in] rpid - remote port ID
2229 struct bfa_fcs_rport_s
*
2230 bfa_fcs_rport_create(struct bfa_fcs_lport_s
*port
, u32 rpid
)
2232 struct bfa_fcs_rport_s
*rport
;
2234 bfa_trc(port
->fcs
, rpid
);
2235 rport
= bfa_fcs_rport_alloc(port
, WWN_NULL
, rpid
);
2239 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_SEND
);
2244 * Called to create a rport for which only the wwn is known.
2246 * @param[in] port - base port
2247 * @param[in] rpwwn - remote port wwn
2251 struct bfa_fcs_rport_s
*
2252 bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s
*port
, wwn_t rpwwn
)
2254 struct bfa_fcs_rport_s
*rport
;
2255 bfa_trc(port
->fcs
, rpwwn
);
2256 rport
= bfa_fcs_rport_alloc(port
, rpwwn
, 0);
2260 bfa_sm_send_event(rport
, RPSM_EVENT_ADDRESS_DISC
);
2264 * Called by bport in private loop topology to indicate that a
2265 * rport has been discovered and plogi has been completed.
2267 * @param[in] port - base port or vport
2268 * @param[in] rpid - remote port ID
2271 bfa_fcs_rport_start(struct bfa_fcs_lport_s
*port
, struct fchs_s
*fchs
,
2272 struct fc_logi_s
*plogi
)
2274 struct bfa_fcs_rport_s
*rport
;
2276 rport
= bfa_fcs_rport_alloc(port
, WWN_NULL
, fchs
->s_id
);
2280 bfa_fcs_rport_update(rport
, plogi
);
2282 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_COMP
);
2286 * Called by bport/vport to handle PLOGI received from a new remote port.
2287 * If an existing rport does a plogi, it will be handled separately.
2290 bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s
*port
, struct fchs_s
*fchs
,
2291 struct fc_logi_s
*plogi
)
2293 struct bfa_fcs_rport_s
*rport
;
2295 rport
= bfa_fcs_rport_alloc(port
, plogi
->port_name
, fchs
->s_id
);
2299 bfa_fcs_rport_update(rport
, plogi
);
2301 rport
->reply_oxid
= fchs
->ox_id
;
2302 bfa_trc(rport
->fcs
, rport
->reply_oxid
);
2304 rport
->stats
.plogi_rcvd
++;
2305 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_RCVD
);
2309 * Called by bport/vport to handle PLOGI received from an existing
2313 bfa_fcs_rport_plogi(struct bfa_fcs_rport_s
*rport
, struct fchs_s
*rx_fchs
,
2314 struct fc_logi_s
*plogi
)
2317 * @todo Handle P2P and initiator-initiator.
2320 bfa_fcs_rport_update(rport
, plogi
);
2322 rport
->reply_oxid
= rx_fchs
->ox_id
;
2323 bfa_trc(rport
->fcs
, rport
->reply_oxid
);
2325 rport
->pid
= rx_fchs
->s_id
;
2326 bfa_trc(rport
->fcs
, rport
->pid
);
2328 rport
->stats
.plogi_rcvd
++;
2329 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_RCVD
);
2334 * Called by bport/vport to notify SCN for the remote port
2337 bfa_fcs_rport_scn(struct bfa_fcs_rport_s
*rport
)
2339 rport
->stats
.rscns
++;
2340 bfa_sm_send_event(rport
, RPSM_EVENT_SCN
);
2346 * This routine BFA callback for bfa_rport_online() call.
2348 * param[in] cb_arg - rport struct.
2353 * Special Considerations:
2358 bfa_cb_rport_online(void *cbarg
)
2361 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
2363 bfa_trc(rport
->fcs
, rport
->pwwn
);
2364 bfa_sm_send_event(rport
, RPSM_EVENT_HCB_ONLINE
);
2369 * This routine BFA callback for bfa_rport_offline() call.
2376 * Special Considerations:
2381 bfa_cb_rport_offline(void *cbarg
)
2383 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
2385 bfa_trc(rport
->fcs
, rport
->pwwn
);
2386 bfa_sm_send_event(rport
, RPSM_EVENT_HCB_OFFLINE
);
2391 * This routine is a static BFA callback when there is a QoS flow_id
2392 * change notification
2399 * Special Considerations:
2404 bfa_cb_rport_qos_scn_flowid(void *cbarg
,
2405 struct bfa_rport_qos_attr_s old_qos_attr
,
2406 struct bfa_rport_qos_attr_s new_qos_attr
)
2408 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
2409 struct bfa_rport_aen_data_s aen_data
;
2411 bfa_trc(rport
->fcs
, rport
->pwwn
);
2412 aen_data
.priv
.qos
= new_qos_attr
;
2413 bfa_fcs_rport_aen_post(rport
, BFA_RPORT_AEN_QOS_FLOWID
, &aen_data
);
2418 * This routine is a static BFA callback when there is a QoS priority
2419 * change notification
2426 * Special Considerations:
2431 bfa_cb_rport_qos_scn_prio(void *cbarg
,
2432 struct bfa_rport_qos_attr_s old_qos_attr
,
2433 struct bfa_rport_qos_attr_s new_qos_attr
)
2435 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
2436 struct bfa_rport_aen_data_s aen_data
;
2438 bfa_trc(rport
->fcs
, rport
->pwwn
);
2439 aen_data
.priv
.qos
= new_qos_attr
;
2440 bfa_fcs_rport_aen_post(rport
, BFA_RPORT_AEN_QOS_PRIO
, &aen_data
);
2444 * Called to process any unsolicted frames from this remote port
2447 bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s
*rport
,
2448 struct fchs_s
*fchs
, u16 len
)
2450 struct bfa_fcs_lport_s
*port
= rport
->port
;
2451 struct fc_els_cmd_s
*els_cmd
;
2453 bfa_trc(rport
->fcs
, fchs
->s_id
);
2454 bfa_trc(rport
->fcs
, fchs
->d_id
);
2455 bfa_trc(rport
->fcs
, fchs
->type
);
2457 if (fchs
->type
!= FC_TYPE_ELS
)
2460 els_cmd
= (struct fc_els_cmd_s
*) (fchs
+ 1);
2462 bfa_trc(rport
->fcs
, els_cmd
->els_code
);
2464 switch (els_cmd
->els_code
) {
2466 bfa_stats(port
, plogi_rcvd
);
2467 bfa_fcs_rport_process_logo(rport
, fchs
);
2471 bfa_stats(port
, adisc_rcvd
);
2472 bfa_fcs_rport_process_adisc(rport
, fchs
, len
);
2476 bfa_stats(port
, prlo_rcvd
);
2477 if (bfa_fcs_lport_is_initiator(port
))
2478 bfa_fcs_fcpim_uf_recv(rport
->itnim
, fchs
, len
);
2482 bfa_stats(port
, prli_rcvd
);
2483 bfa_fcs_rport_process_prli(rport
, fchs
, len
);
2487 bfa_stats(port
, rpsc_rcvd
);
2488 bfa_fcs_rport_process_rpsc(rport
, fchs
, len
);
2492 bfa_stats(port
, un_handled_els_rcvd
);
2493 bfa_fcs_rport_send_ls_rjt(rport
, fchs
,
2494 FC_LS_RJT_RSN_CMD_NOT_SUPP
,
2495 FC_LS_RJT_EXP_NO_ADDL_INFO
);
2500 /* send best case acc to prlo */
2502 bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s
*rport
)
2504 struct bfa_fcs_lport_s
*port
= rport
->port
;
2506 struct bfa_fcxp_s
*fcxp
;
2509 bfa_trc(rport
->fcs
, rport
->pid
);
2511 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
);
2514 len
= fc_prlo_acc_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
2515 rport
->pid
, bfa_fcs_lport_get_fcid(port
),
2516 rport
->reply_oxid
, 0);
2518 bfa_fcxp_send(fcxp
, rport
->bfa_rport
, port
->fabric
->vf_id
,
2519 port
->lp_tag
, BFA_FALSE
, FC_CLASS_3
, len
, &fchs
,
2520 NULL
, NULL
, FC_MAX_PDUSZ
, 0);
2527 bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s
*rport
, struct fchs_s
*rx_fchs
,
2528 u8 reason_code
, u8 reason_code_expl
)
2530 struct bfa_fcs_lport_s
*port
= rport
->port
;
2532 struct bfa_fcxp_s
*fcxp
;
2535 bfa_trc(rport
->fcs
, rx_fchs
->s_id
);
2537 fcxp
= bfa_fcs_fcxp_alloc(rport
->fcs
);
2541 len
= fc_ls_rjt_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
),
2542 rx_fchs
->s_id
, bfa_fcs_lport_get_fcid(port
),
2543 rx_fchs
->ox_id
, reason_code
, reason_code_expl
);
2545 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
,
2546 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
2551 * Return state of rport.
2554 bfa_fcs_rport_get_state(struct bfa_fcs_rport_s
*rport
)
2556 return bfa_sm_to_state(rport_sm_table
, rport
->sm
);
2562 * Called by the Driver to set rport delete/ageout timeout
2564 * param[in] rport timeout value in seconds.
2569 bfa_fcs_rport_set_del_timeout(u8 rport_tmo
)
2571 /* convert to Millisecs */
2573 bfa_fcs_rport_del_timeout
= rport_tmo
* 1000;
2576 bfa_fcs_rport_prlo(struct bfa_fcs_rport_s
*rport
, __be16 ox_id
)
2578 bfa_trc(rport
->fcs
, rport
->pid
);
2580 rport
->prlo
= BFA_TRUE
;
2581 rport
->reply_oxid
= ox_id
;
2582 bfa_sm_send_event(rport
, RPSM_EVENT_PRLO_RCVD
);
2586 bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s
*rport
,
2587 struct bfa_rport_attr_s
*rport_attr
)
2589 struct bfa_rport_qos_attr_s qos_attr
;
2590 struct bfa_fcs_lport_s
*port
= rport
->port
;
2591 bfa_port_speed_t rport_speed
= rport
->rpf
.rpsc_speed
;
2593 memset(rport_attr
, 0, sizeof(struct bfa_rport_attr_s
));
2594 memset(&qos_attr
, 0, sizeof(struct bfa_rport_qos_attr_s
));
2596 rport_attr
->pid
= rport
->pid
;
2597 rport_attr
->pwwn
= rport
->pwwn
;
2598 rport_attr
->nwwn
= rport
->nwwn
;
2599 rport_attr
->cos_supported
= rport
->fc_cos
;
2600 rport_attr
->df_sz
= rport
->maxfrsize
;
2601 rport_attr
->state
= bfa_fcs_rport_get_state(rport
);
2602 rport_attr
->fc_cos
= rport
->fc_cos
;
2603 rport_attr
->cisc
= rport
->cisc
;
2604 rport_attr
->scsi_function
= rport
->scsi_function
;
2605 rport_attr
->curr_speed
= rport
->rpf
.rpsc_speed
;
2606 rport_attr
->assigned_speed
= rport
->rpf
.assigned_speed
;
2608 qos_attr
.qos_priority
= rport
->bfa_rport
->qos_attr
.qos_priority
;
2609 qos_attr
.qos_flow_id
=
2610 cpu_to_be32(rport
->bfa_rport
->qos_attr
.qos_flow_id
);
2611 rport_attr
->qos_attr
= qos_attr
;
2613 rport_attr
->trl_enforced
= BFA_FALSE
;
2614 if (bfa_fcport_is_ratelim(port
->fcs
->bfa
) &&
2615 (rport
->scsi_function
== BFA_RPORT_TARGET
)) {
2616 if (rport_speed
== BFA_PORT_SPEED_UNKNOWN
)
2618 bfa_fcport_get_ratelim_speed(rport
->fcs
->bfa
);
2620 if (rport_speed
< bfa_fcs_lport_get_rport_max_speed(port
))
2621 rport_attr
->trl_enforced
= BFA_TRUE
;
2626 * Remote port implementation.
2630 * fcs_rport_api FCS rport API.
2633 struct bfa_fcs_rport_s
*
2634 bfa_fcs_rport_lookup(struct bfa_fcs_lport_s
*port
, wwn_t rpwwn
)
2636 struct bfa_fcs_rport_s
*rport
;
2638 rport
= bfa_fcs_lport_get_rport_by_pwwn(port
, rpwwn
);
2639 if (rport
== NULL
) {
2641 * TBD Error handling
2648 struct bfa_fcs_rport_s
*
2649 bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s
*port
, wwn_t rnwwn
)
2651 struct bfa_fcs_rport_s
*rport
;
2653 rport
= bfa_fcs_lport_get_rport_by_nwwn(port
, rnwwn
);
2654 if (rport
== NULL
) {
2656 * TBD Error handling
2664 * Remote port features (RPF) implementation.
2667 #define BFA_FCS_RPF_RETRIES (3)
2668 #define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */
2670 static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg
,
2671 struct bfa_fcxp_s
*fcxp_alloced
);
2672 static void bfa_fcs_rpf_rpsc2_response(void *fcsarg
,
2673 struct bfa_fcxp_s
*fcxp
,
2675 bfa_status_t req_status
,
2678 struct fchs_s
*rsp_fchs
);
2680 static void bfa_fcs_rpf_timeout(void *arg
);
2683 * fcs_rport_ftrs_sm FCS rport state machine events
2687 RPFSM_EVENT_RPORT_OFFLINE
= 1, /* Rport offline */
2688 RPFSM_EVENT_RPORT_ONLINE
= 2, /* Rport online */
2689 RPFSM_EVENT_FCXP_SENT
= 3, /* Frame from has been sent */
2690 RPFSM_EVENT_TIMEOUT
= 4, /* Rport SM timeout event */
2691 RPFSM_EVENT_RPSC_COMP
= 5,
2692 RPFSM_EVENT_RPSC_FAIL
= 6,
2693 RPFSM_EVENT_RPSC_ERROR
= 7,
2696 static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s
*rpf
,
2697 enum rpf_event event
);
2698 static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s
*rpf
,
2699 enum rpf_event event
);
2700 static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s
*rpf
,
2701 enum rpf_event event
);
2702 static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s
*rpf
,
2703 enum rpf_event event
);
2704 static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s
*rpf
,
2705 enum rpf_event event
);
2706 static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s
*rpf
,
2707 enum rpf_event event
);
2710 bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
2712 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
2713 struct bfa_fcs_fabric_s
*fabric
= &rport
->fcs
->fabric
;
2715 bfa_trc(rport
->fcs
, rport
->pwwn
);
2716 bfa_trc(rport
->fcs
, rport
->pid
);
2717 bfa_trc(rport
->fcs
, event
);
2720 case RPFSM_EVENT_RPORT_ONLINE
:
2721 /* Send RPSC2 to a Brocade fabric only. */
2722 if ((!BFA_FCS_PID_IS_WKA(rport
->pid
)) &&
2723 ((rport
->port
->fabric
->lps
->brcd_switch
) ||
2724 (bfa_fcs_fabric_get_switch_oui(fabric
) ==
2725 BFA_FCS_BRCD_SWITCH_OUI
))) {
2726 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_rpsc_sending
);
2727 rpf
->rpsc_retries
= 0;
2728 bfa_fcs_rpf_send_rpsc2(rpf
, NULL
);
2732 case RPFSM_EVENT_RPORT_OFFLINE
:
2736 bfa_sm_fault(rport
->fcs
, event
);
2741 bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
2743 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
2745 bfa_trc(rport
->fcs
, event
);
2748 case RPFSM_EVENT_FCXP_SENT
:
2749 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_rpsc
);
2752 case RPFSM_EVENT_RPORT_OFFLINE
:
2753 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_offline
);
2754 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rpf
->fcxp_wqe
);
2755 rpf
->rpsc_retries
= 0;
2759 bfa_sm_fault(rport
->fcs
, event
);
2764 bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
2766 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
2768 bfa_trc(rport
->fcs
, rport
->pid
);
2769 bfa_trc(rport
->fcs
, event
);
2772 case RPFSM_EVENT_RPSC_COMP
:
2773 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_online
);
2774 /* Update speed info in f/w via BFA */
2775 if (rpf
->rpsc_speed
!= BFA_PORT_SPEED_UNKNOWN
)
2776 bfa_rport_speed(rport
->bfa_rport
, rpf
->rpsc_speed
);
2777 else if (rpf
->assigned_speed
!= BFA_PORT_SPEED_UNKNOWN
)
2778 bfa_rport_speed(rport
->bfa_rport
, rpf
->assigned_speed
);
2781 case RPFSM_EVENT_RPSC_FAIL
:
2782 /* RPSC not supported by rport */
2783 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_online
);
2786 case RPFSM_EVENT_RPSC_ERROR
:
2787 /* need to retry...delayed a bit. */
2788 if (rpf
->rpsc_retries
++ < BFA_FCS_RPF_RETRIES
) {
2789 bfa_timer_start(rport
->fcs
->bfa
, &rpf
->timer
,
2790 bfa_fcs_rpf_timeout
, rpf
,
2791 BFA_FCS_RPF_RETRY_TIMEOUT
);
2792 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_rpsc_retry
);
2794 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_online
);
2798 case RPFSM_EVENT_RPORT_OFFLINE
:
2799 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_offline
);
2800 bfa_fcxp_discard(rpf
->fcxp
);
2801 rpf
->rpsc_retries
= 0;
2805 bfa_sm_fault(rport
->fcs
, event
);
2810 bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
2812 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
2814 bfa_trc(rport
->fcs
, rport
->pid
);
2815 bfa_trc(rport
->fcs
, event
);
2818 case RPFSM_EVENT_TIMEOUT
:
2819 /* re-send the RPSC */
2820 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_rpsc_sending
);
2821 bfa_fcs_rpf_send_rpsc2(rpf
, NULL
);
2824 case RPFSM_EVENT_RPORT_OFFLINE
:
2825 bfa_timer_stop(&rpf
->timer
);
2826 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_offline
);
2827 rpf
->rpsc_retries
= 0;
2831 bfa_sm_fault(rport
->fcs
, event
);
2836 bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
2838 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
2840 bfa_trc(rport
->fcs
, rport
->pwwn
);
2841 bfa_trc(rport
->fcs
, rport
->pid
);
2842 bfa_trc(rport
->fcs
, event
);
2845 case RPFSM_EVENT_RPORT_OFFLINE
:
2846 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_offline
);
2847 rpf
->rpsc_retries
= 0;
2851 bfa_sm_fault(rport
->fcs
, event
);
2856 bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
2858 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
2860 bfa_trc(rport
->fcs
, rport
->pwwn
);
2861 bfa_trc(rport
->fcs
, rport
->pid
);
2862 bfa_trc(rport
->fcs
, event
);
2865 case RPFSM_EVENT_RPORT_ONLINE
:
2866 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_rpsc_sending
);
2867 bfa_fcs_rpf_send_rpsc2(rpf
, NULL
);
2870 case RPFSM_EVENT_RPORT_OFFLINE
:
2874 bfa_sm_fault(rport
->fcs
, event
);
2878 * Called when Rport is created.
2881 bfa_fcs_rpf_init(struct bfa_fcs_rport_s
*rport
)
2883 struct bfa_fcs_rpf_s
*rpf
= &rport
->rpf
;
2885 bfa_trc(rport
->fcs
, rport
->pid
);
2888 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_uninit
);
2892 * Called when Rport becomes online
2895 bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s
*rport
)
2897 bfa_trc(rport
->fcs
, rport
->pid
);
2899 if (__fcs_min_cfg(rport
->port
->fcs
))
2902 if (bfa_fcs_fabric_is_switched(rport
->port
->fabric
))
2903 bfa_sm_send_event(&rport
->rpf
, RPFSM_EVENT_RPORT_ONLINE
);
2907 * Called when Rport becomes offline
2910 bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s
*rport
)
2912 bfa_trc(rport
->fcs
, rport
->pid
);
2914 if (__fcs_min_cfg(rport
->port
->fcs
))
2917 rport
->rpf
.rpsc_speed
= 0;
2918 bfa_sm_send_event(&rport
->rpf
, RPFSM_EVENT_RPORT_OFFLINE
);
2922 bfa_fcs_rpf_timeout(void *arg
)
2924 struct bfa_fcs_rpf_s
*rpf
= (struct bfa_fcs_rpf_s
*) arg
;
2925 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
2927 bfa_trc(rport
->fcs
, rport
->pid
);
2928 bfa_sm_send_event(rpf
, RPFSM_EVENT_TIMEOUT
);
2932 bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
2934 struct bfa_fcs_rpf_s
*rpf
= (struct bfa_fcs_rpf_s
*)rpf_cbarg
;
2935 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
2936 struct bfa_fcs_lport_s
*port
= rport
->port
;
2939 struct bfa_fcxp_s
*fcxp
;
2941 bfa_trc(rport
->fcs
, rport
->pwwn
);
2943 fcxp
= fcxp_alloced
? fcxp_alloced
: bfa_fcs_fcxp_alloc(port
->fcs
);
2945 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rpf
->fcxp_wqe
,
2946 bfa_fcs_rpf_send_rpsc2
, rpf
);
2951 len
= fc_rpsc2_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
), rport
->pid
,
2952 bfa_fcs_lport_get_fcid(port
), &rport
->pid
, 1);
2954 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
, BFA_FALSE
,
2955 FC_CLASS_3
, len
, &fchs
, bfa_fcs_rpf_rpsc2_response
,
2956 rpf
, FC_MAX_PDUSZ
, FC_ELS_TOV
);
2957 rport
->stats
.rpsc_sent
++;
2958 bfa_sm_send_event(rpf
, RPFSM_EVENT_FCXP_SENT
);
2963 bfa_fcs_rpf_rpsc2_response(void *fcsarg
, struct bfa_fcxp_s
*fcxp
, void *cbarg
,
2964 bfa_status_t req_status
, u32 rsp_len
,
2965 u32 resid_len
, struct fchs_s
*rsp_fchs
)
2967 struct bfa_fcs_rpf_s
*rpf
= (struct bfa_fcs_rpf_s
*) cbarg
;
2968 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
2969 struct fc_ls_rjt_s
*ls_rjt
;
2970 struct fc_rpsc2_acc_s
*rpsc2_acc
;
2973 bfa_trc(rport
->fcs
, req_status
);
2975 if (req_status
!= BFA_STATUS_OK
) {
2976 bfa_trc(rport
->fcs
, req_status
);
2977 if (req_status
== BFA_STATUS_ETIMER
)
2978 rport
->stats
.rpsc_failed
++;
2979 bfa_sm_send_event(rpf
, RPFSM_EVENT_RPSC_ERROR
);
2983 rpsc2_acc
= (struct fc_rpsc2_acc_s
*) BFA_FCXP_RSP_PLD(fcxp
);
2984 if (rpsc2_acc
->els_cmd
== FC_ELS_ACC
) {
2985 rport
->stats
.rpsc_accs
++;
2986 num_ents
= be16_to_cpu(rpsc2_acc
->num_pids
);
2987 bfa_trc(rport
->fcs
, num_ents
);
2989 WARN_ON(rpsc2_acc
->port_info
[0].pid
== rport
->pid
);
2991 be16_to_cpu(rpsc2_acc
->port_info
[0].pid
));
2993 be16_to_cpu(rpsc2_acc
->port_info
[0].speed
));
2995 be16_to_cpu(rpsc2_acc
->port_info
[0].index
));
2997 rpsc2_acc
->port_info
[0].type
);
2999 if (rpsc2_acc
->port_info
[0].speed
== 0) {
3000 bfa_sm_send_event(rpf
, RPFSM_EVENT_RPSC_ERROR
);
3004 rpf
->rpsc_speed
= fc_rpsc_operspeed_to_bfa_speed(
3005 be16_to_cpu(rpsc2_acc
->port_info
[0].speed
));
3007 bfa_sm_send_event(rpf
, RPFSM_EVENT_RPSC_COMP
);
3010 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3011 bfa_trc(rport
->fcs
, ls_rjt
->reason_code
);
3012 bfa_trc(rport
->fcs
, ls_rjt
->reason_code_expl
);
3013 rport
->stats
.rpsc_rejects
++;
3014 if (ls_rjt
->reason_code
== FC_LS_RJT_RSN_CMD_NOT_SUPP
)
3015 bfa_sm_send_event(rpf
, RPFSM_EVENT_RPSC_FAIL
);
3017 bfa_sm_send_event(rpf
, RPFSM_EVENT_RPSC_ERROR
);