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 * bfa_fcs_rport_max_logins is max count of bfa_fcs_rports
34 * whereas DEF_CFG_NUM_RPORTS is max count of bfa_rports
36 static u32 bfa_fcs_rport_max_logins
= BFA_FCS_MAX_RPORT_LOGINS
;
39 * forward declarations
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
,
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
);
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
);
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
},
178 bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
180 bfa_trc(rport
->fcs
, rport
->pwwn
);
181 bfa_trc(rport
->fcs
, rport
->pid
);
182 bfa_trc(rport
->fcs
, event
);
185 case RPSM_EVENT_PLOGI_SEND
:
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
);
191 case RPSM_EVENT_PLOGI_RCVD
:
192 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogiacc_sending
);
193 bfa_fcs_rport_send_plogiacc(rport
, NULL
);
196 case RPSM_EVENT_PLOGI_COMP
:
197 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
198 bfa_fcs_rport_hal_online(rport
);
201 case RPSM_EVENT_ADDRESS_CHANGE
:
202 case RPSM_EVENT_ADDRESS_DISC
:
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
);
208 bfa_sm_fault(rport
->fcs
, event
);
213 * PLOGI is being sent.
216 bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s
*rport
,
217 enum rport_event event
)
219 bfa_trc(rport
->fcs
, rport
->pwwn
);
220 bfa_trc(rport
->fcs
, rport
->pid
);
221 bfa_trc(rport
->fcs
, event
);
224 case RPSM_EVENT_FCXP_SENT
:
225 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogi
);
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
);
234 case RPSM_EVENT_PLOGI_RCVD
:
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
);
240 case RPSM_EVENT_SCN_OFFLINE
:
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
);
247 case RPSM_EVENT_ADDRESS_CHANGE
:
248 case RPSM_EVENT_FAB_SCN
:
250 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
, &rport
->fcxp_wqe
);
251 WARN_ON(!(bfa_fcport_get_topology(rport
->port
->fcs
->bfa
) !=
252 BFA_PORT_TOPOLOGY_LOOP
));
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
);
258 case RPSM_EVENT_LOGO_IMP
:
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
);
269 bfa_sm_fault(rport
->fcs
, event
);
274 * PLOGI is being sent.
277 bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s
*rport
,
278 enum rport_event event
)
280 bfa_trc(rport
->fcs
, rport
->pwwn
);
281 bfa_trc(rport
->fcs
, rport
->pid
);
282 bfa_trc(rport
->fcs
, event
);
285 case RPSM_EVENT_FCXP_SENT
:
286 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_fcs_online
);
287 bfa_fcs_rport_fcs_online_action(rport
);
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
);
296 case RPSM_EVENT_PLOGI_RCVD
:
297 case RPSM_EVENT_PLOGI_COMP
:
298 case RPSM_EVENT_FAB_SCN
:
300 * Ignore, SCN is possibly online notification.
304 case RPSM_EVENT_SCN_OFFLINE
:
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
);
312 case RPSM_EVENT_ADDRESS_CHANGE
:
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
);
319 case RPSM_EVENT_LOGO_IMP
:
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
);
328 case RPSM_EVENT_HCB_OFFLINE
:
330 * Ignore BFA callback, on a PLOGI receive we call bfa offline.
335 bfa_sm_fault(rport
->fcs
, event
);
343 bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s
*rport
,
344 enum rport_event event
)
346 bfa_trc(rport
->fcs
, rport
->pwwn
);
347 bfa_trc(rport
->fcs
, rport
->pid
);
348 bfa_trc(rport
->fcs
, 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
);
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
);
362 case RPSM_EVENT_PRLO_RCVD
:
363 case RPSM_EVENT_LOGO_RCVD
:
366 case RPSM_EVENT_PLOGI_RCVD
:
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
);
372 case RPSM_EVENT_SCN_OFFLINE
:
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
);
380 case RPSM_EVENT_ADDRESS_CHANGE
:
381 case RPSM_EVENT_FAB_SCN
:
382 bfa_timer_stop(&rport
->timer
);
383 WARN_ON(!(bfa_fcport_get_topology(rport
->port
->fcs
->bfa
) !=
384 BFA_PORT_TOPOLOGY_LOOP
));
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
);
390 case RPSM_EVENT_LOGO_IMP
:
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
);
399 case RPSM_EVENT_PLOGI_COMP
:
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
);
406 bfa_sm_fault(rport
->fcs
, event
);
414 bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
416 bfa_trc(rport
->fcs
, rport
->pwwn
);
417 bfa_trc(rport
->fcs
, rport
->pid
);
418 bfa_trc(rport
->fcs
, 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
);
427 case RPSM_EVENT_LOGO_RCVD
:
428 bfa_fcs_rport_send_logo_acc(rport
);
432 case RPSM_EVENT_PRLO_RCVD
:
433 if (rport
->prlo
== BFA_TRUE
)
434 bfa_fcs_rport_send_prlo_acc(rport
);
436 bfa_fcxp_discard(rport
->fcxp
);
440 case RPSM_EVENT_FAILED
:
441 if (rport
->plogi_retries
< BFA_FCS_RPORT_MAX_RETRIES
) {
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
,
446 BFA_FCS_RETRY_TIMEOUT
);
448 bfa_stats(rport
->port
, rport_del_max_plogi_retry
);
449 rport
->old_pid
= rport
->pid
;
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
);
458 case RPSM_EVENT_SCN_ONLINE
:
461 case RPSM_EVENT_SCN_OFFLINE
:
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
);
469 case RPSM_EVENT_PLOGI_RETRY
:
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
,
477 case RPSM_EVENT_LOGO_IMP
:
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
);
486 case RPSM_EVENT_ADDRESS_CHANGE
:
487 case RPSM_EVENT_FAB_SCN
:
488 bfa_fcxp_discard(rport
->fcxp
);
489 WARN_ON(!(bfa_fcport_get_topology(rport
->port
->fcs
->bfa
) !=
490 BFA_PORT_TOPOLOGY_LOOP
));
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
);
496 case RPSM_EVENT_PLOGI_RCVD
:
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
);
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
);
508 case RPSM_EVENT_PLOGI_COMP
:
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
);
515 bfa_sm_fault(rport
->fcs
, event
);
520 * PLOGI is done. Await bfa_fcs_itnim to ascertain the scsi function
523 bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s
*rport
,
524 enum rport_event event
)
526 bfa_trc(rport
->fcs
, rport
->pwwn
);
527 bfa_trc(rport
->fcs
, rport
->pid
);
528 bfa_trc(rport
->fcs
, event
);
531 case RPSM_EVENT_FC4_FCS_ONLINE
:
532 if (rport
->scsi_function
== BFA_RPORT_INITIATOR
) {
533 if (!BFA_FCS_PID_IS_WKA(rport
->pid
))
534 bfa_fcs_rpf_rport_online(rport
);
535 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_online
);
539 if (!rport
->bfa_rport
)
541 bfa_rport_create(rport
->fcs
->bfa
, rport
);
543 if (rport
->bfa_rport
) {
544 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
545 bfa_fcs_rport_hal_online(rport
);
547 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logosend
);
548 bfa_fcs_rport_fcs_offline_action(rport
);
552 case RPSM_EVENT_PLOGI_RCVD
:
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
);
558 case RPSM_EVENT_PLOGI_COMP
:
559 case RPSM_EVENT_LOGO_IMP
:
560 case RPSM_EVENT_ADDRESS_CHANGE
:
561 case RPSM_EVENT_FAB_SCN
:
562 case RPSM_EVENT_SCN_OFFLINE
:
563 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
564 bfa_fcs_rport_fcs_offline_action(rport
);
567 case RPSM_EVENT_LOGO_RCVD
:
568 case RPSM_EVENT_PRLO_RCVD
:
569 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logorcv
);
570 bfa_fcs_rport_fcs_offline_action(rport
);
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
);
579 bfa_sm_fault(rport
->fcs
, event
);
585 * PLOGI is complete. Awaiting BFA rport online callback. FC-4s
589 bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s
*rport
,
590 enum rport_event event
)
592 bfa_trc(rport
->fcs
, rport
->pwwn
);
593 bfa_trc(rport
->fcs
, rport
->pid
);
594 bfa_trc(rport
->fcs
, event
);
597 case RPSM_EVENT_HCB_ONLINE
:
598 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_online
);
599 bfa_fcs_rport_hal_online_action(rport
);
602 case RPSM_EVENT_PLOGI_COMP
:
605 case RPSM_EVENT_PRLO_RCVD
:
606 case RPSM_EVENT_LOGO_RCVD
:
607 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logorcv
);
608 bfa_fcs_rport_fcs_offline_action(rport
);
611 case RPSM_EVENT_FAB_SCN
:
612 case RPSM_EVENT_LOGO_IMP
:
613 case RPSM_EVENT_ADDRESS_CHANGE
:
614 case RPSM_EVENT_SCN_OFFLINE
:
615 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
616 bfa_fcs_rport_fcs_offline_action(rport
);
619 case RPSM_EVENT_PLOGI_RCVD
:
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
);
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
);
631 bfa_sm_fault(rport
->fcs
, event
);
636 * Rport is ONLINE. FC-4s active.
639 bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
641 bfa_trc(rport
->fcs
, rport
->pwwn
);
642 bfa_trc(rport
->fcs
, rport
->pid
);
643 bfa_trc(rport
->fcs
, 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
);
653 bfa_sm_set_state(rport
,
654 bfa_fcs_rport_sm_adisc_online_sending
);
655 bfa_fcs_rport_send_adisc(rport
, NULL
);
659 case RPSM_EVENT_PLOGI_RCVD
:
660 case RPSM_EVENT_LOGO_IMP
:
661 case RPSM_EVENT_ADDRESS_CHANGE
:
662 case RPSM_EVENT_SCN_OFFLINE
:
663 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
664 bfa_fcs_rport_hal_offline_action(rport
);
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
);
672 case RPSM_EVENT_LOGO_RCVD
:
673 case RPSM_EVENT_PRLO_RCVD
:
674 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logorcv
);
675 bfa_fcs_rport_hal_offline_action(rport
);
678 case RPSM_EVENT_SCN_ONLINE
:
679 case RPSM_EVENT_PLOGI_COMP
:
683 bfa_sm_fault(rport
->fcs
, event
);
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.
692 bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s
*rport
,
693 enum rport_event event
)
695 bfa_trc(rport
->fcs
, rport
->pwwn
);
696 bfa_trc(rport
->fcs
, rport
->pid
);
697 bfa_trc(rport
->fcs
, event
);
700 case RPSM_EVENT_FCXP_SENT
:
701 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsquery
);
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
);
710 case RPSM_EVENT_FAB_SCN
:
712 * ignore SCN, wait for response to query itself
716 case RPSM_EVENT_LOGO_RCVD
:
717 case RPSM_EVENT_PRLO_RCVD
:
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
);
723 case RPSM_EVENT_LOGO_IMP
:
724 case RPSM_EVENT_PLOGI_RCVD
:
725 case RPSM_EVENT_ADDRESS_CHANGE
:
726 case RPSM_EVENT_PLOGI_COMP
:
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
);
733 bfa_sm_fault(rport
->fcs
, event
);
738 * An SCN event is received in ONLINE state. NS query is sent to rport.
742 bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
744 bfa_trc(rport
->fcs
, rport
->pwwn
);
745 bfa_trc(rport
->fcs
, rport
->pid
);
746 bfa_trc(rport
->fcs
, 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
);
754 case RPSM_EVENT_FAILED
:
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
);
761 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
762 bfa_fcs_rport_hal_offline_action(rport
);
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
);
772 case RPSM_EVENT_FAB_SCN
:
775 case RPSM_EVENT_LOGO_RCVD
:
776 case RPSM_EVENT_PRLO_RCVD
:
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
);
782 case RPSM_EVENT_PLOGI_COMP
:
783 case RPSM_EVENT_ADDRESS_CHANGE
:
784 case RPSM_EVENT_PLOGI_RCVD
:
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
);
792 bfa_sm_fault(rport
->fcs
, event
);
797 * An SCN event is received in ONLINE state. ADISC is being sent for
798 * authenticating with rport. FC-4s are paused.
801 bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s
*rport
,
802 enum rport_event event
)
804 bfa_trc(rport
->fcs
, rport
->pwwn
);
805 bfa_trc(rport
->fcs
, rport
->pid
);
806 bfa_trc(rport
->fcs
, event
);
809 case RPSM_EVENT_FCXP_SENT
:
810 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_adisc_online
);
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
);
819 case RPSM_EVENT_LOGO_IMP
:
820 case RPSM_EVENT_ADDRESS_CHANGE
:
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
);
826 case RPSM_EVENT_LOGO_RCVD
:
827 case RPSM_EVENT_PRLO_RCVD
:
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
);
833 case RPSM_EVENT_FAB_SCN
:
836 case RPSM_EVENT_PLOGI_RCVD
:
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
);
843 bfa_sm_fault(rport
->fcs
, event
);
848 * An SCN event is received in ONLINE state. ADISC is to rport.
852 bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s
*rport
,
853 enum rport_event event
)
855 bfa_trc(rport
->fcs
, rport
->pwwn
);
856 bfa_trc(rport
->fcs
, rport
->pid
);
857 bfa_trc(rport
->fcs
, event
);
860 case RPSM_EVENT_ACCEPTED
:
861 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_online
);
864 case RPSM_EVENT_PLOGI_RCVD
:
866 * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
867 * At least go offline when a PLOGI is received.
869 bfa_fcxp_discard(rport
->fcxp
);
871 * !!! fall through !!!
874 case RPSM_EVENT_FAILED
:
875 case RPSM_EVENT_ADDRESS_CHANGE
:
876 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_offline
);
877 bfa_fcs_rport_hal_offline_action(rport
);
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
);
886 case RPSM_EVENT_FAB_SCN
:
888 * already processing RSCN
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
);
898 case RPSM_EVENT_LOGO_RCVD
:
899 case RPSM_EVENT_PRLO_RCVD
:
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
);
906 bfa_sm_fault(rport
->fcs
, event
);
911 * ADISC is being sent for authenticating with rport
912 * Already did offline actions.
915 bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s
*rport
,
916 enum rport_event event
)
918 bfa_trc(rport
->fcs
, rport
->pwwn
);
919 bfa_trc(rport
->fcs
, rport
->pid
);
920 bfa_trc(rport
->fcs
, event
);
923 case RPSM_EVENT_FCXP_SENT
:
924 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_adisc_offline
);
927 case RPSM_EVENT_DELETE
:
928 case RPSM_EVENT_SCN_OFFLINE
:
929 case RPSM_EVENT_LOGO_IMP
:
930 case RPSM_EVENT_LOGO_RCVD
:
931 case RPSM_EVENT_PRLO_RCVD
:
932 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_offline
);
933 bfa_fcxp_walloc_cancel(rport
->fcs
->bfa
,
935 bfa_timer_start(rport
->fcs
->bfa
, &rport
->timer
,
936 bfa_fcs_rport_timeout
, rport
,
937 bfa_fcs_rport_del_timeout
);
940 case RPSM_EVENT_PLOGI_RCVD
:
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
);
947 bfa_sm_fault(rport
->fcs
, event
);
953 * Already did offline actions
956 bfa_fcs_rport_sm_adisc_offline(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_ACCEPTED
:
965 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hal_online
);
966 bfa_fcs_rport_hal_online(rport
);
969 case RPSM_EVENT_PLOGI_RCVD
:
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
);
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
);
982 case RPSM_EVENT_DELETE
:
983 case RPSM_EVENT_SCN_OFFLINE
:
984 case RPSM_EVENT_LOGO_IMP
:
985 case RPSM_EVENT_LOGO_RCVD
:
986 case RPSM_EVENT_PRLO_RCVD
:
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
);
995 bfa_sm_fault(rport
->fcs
, event
);
1000 * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
1003 bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s
*rport
,
1004 enum rport_event event
)
1006 bfa_trc(rport
->fcs
, rport
->pwwn
);
1007 bfa_trc(rport
->fcs
, rport
->pid
);
1008 bfa_trc(rport
->fcs
, event
);
1011 case RPSM_EVENT_FC4_OFFLINE
:
1012 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_logorcv
);
1013 bfa_fcs_rport_hal_offline(rport
);
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
);
1022 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_off_delete
);
1025 case RPSM_EVENT_SCN_ONLINE
:
1026 case RPSM_EVENT_SCN_OFFLINE
:
1027 case RPSM_EVENT_HCB_ONLINE
:
1028 case RPSM_EVENT_LOGO_RCVD
:
1029 case RPSM_EVENT_PRLO_RCVD
:
1030 case RPSM_EVENT_ADDRESS_CHANGE
:
1034 bfa_sm_fault(rport
->fcs
, event
);
1039 * LOGO needs to be sent to rport. Awaiting FC-4 offline completion
1043 bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s
*rport
,
1044 enum rport_event event
)
1046 bfa_trc(rport
->fcs
, rport
->pwwn
);
1047 bfa_trc(rport
->fcs
, rport
->pid
);
1048 bfa_trc(rport
->fcs
, event
);
1051 case RPSM_EVENT_FC4_OFFLINE
:
1052 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_logosend
);
1053 bfa_fcs_rport_hal_offline(rport
);
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
);
1064 case RPSM_EVENT_HCB_ONLINE
:
1065 case RPSM_EVENT_DELETE
:
1066 /* Rport is being deleted */
1070 bfa_sm_fault(rport
->fcs
, event
);
1075 * Rport is going offline. Awaiting FC-4 offline completion callback.
1078 bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s
*rport
,
1079 enum rport_event event
)
1081 bfa_trc(rport
->fcs
, rport
->pwwn
);
1082 bfa_trc(rport
->fcs
, rport
->pid
);
1083 bfa_trc(rport
->fcs
, event
);
1086 case RPSM_EVENT_FC4_OFFLINE
:
1087 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_offline
);
1088 bfa_fcs_rport_hal_offline(rport
);
1091 case RPSM_EVENT_SCN_ONLINE
:
1093 case RPSM_EVENT_LOGO_RCVD
:
1095 * Rport is going offline. Just ack the logo
1097 bfa_fcs_rport_send_logo_acc(rport
);
1100 case RPSM_EVENT_PRLO_RCVD
:
1101 bfa_fcs_rport_send_prlo_acc(rport
);
1104 case RPSM_EVENT_SCN_OFFLINE
:
1105 case RPSM_EVENT_HCB_ONLINE
:
1106 case RPSM_EVENT_FAB_SCN
:
1107 case RPSM_EVENT_LOGO_IMP
:
1108 case RPSM_EVENT_ADDRESS_CHANGE
:
1110 * rport is already going offline.
1111 * SCN - ignore and wait till transitioning to offline state
1115 case RPSM_EVENT_DELETE
:
1116 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_fc4_logosend
);
1120 bfa_sm_fault(rport
->fcs
, event
);
1125 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
1129 bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s
*rport
,
1130 enum rport_event event
)
1132 bfa_trc(rport
->fcs
, rport
->pwwn
);
1133 bfa_trc(rport
->fcs
, rport
->pid
);
1134 bfa_trc(rport
->fcs
, event
);
1137 case RPSM_EVENT_HCB_OFFLINE
:
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
);
1147 * !! fall through !!
1150 case RPSM_EVENT_ADDRESS_CHANGE
:
1151 if (!bfa_fcs_lport_is_online(rport
->port
)) {
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
);
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
) ==
1165 BFA_PORT_TOPOLOGY_LOOP
) {
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
);
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
);
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
);
1184 case RPSM_EVENT_DELETE
:
1185 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
1186 bfa_fcs_rport_free(rport
);
1189 case RPSM_EVENT_SCN_ONLINE
:
1190 case RPSM_EVENT_SCN_OFFLINE
:
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
:
1197 * Ignore, already offline.
1202 bfa_sm_fault(rport
->fcs
, event
);
1207 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
1208 * callback to send LOGO accept.
1211 bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s
*rport
,
1212 enum rport_event event
)
1214 bfa_trc(rport
->fcs
, rport
->pwwn
);
1215 bfa_trc(rport
->fcs
, rport
->pid
);
1216 bfa_trc(rport
->fcs
, event
);
1219 case RPSM_EVENT_HCB_OFFLINE
:
1220 case RPSM_EVENT_ADDRESS_CHANGE
:
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
);
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.
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
);
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
);
1246 * if it is not a well known address, reset the
1249 if (!BFA_FCS_PID_IS_WKA(rport
->pid
))
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
);
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
);
1266 case RPSM_EVENT_LOGO_IMP
:
1267 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_hcb_offline
);
1270 case RPSM_EVENT_SCN_ONLINE
:
1271 case RPSM_EVENT_SCN_OFFLINE
:
1272 case RPSM_EVENT_LOGO_RCVD
:
1273 case RPSM_EVENT_PRLO_RCVD
:
1275 * Ignore - already processing a LOGO.
1280 bfa_sm_fault(rport
->fcs
, event
);
1285 * Rport is being deleted. FC-4s are offline.
1286 * Awaiting BFA rport offline
1287 * callback to send LOGO.
1290 bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s
*rport
,
1291 enum rport_event event
)
1293 bfa_trc(rport
->fcs
, rport
->pwwn
);
1294 bfa_trc(rport
->fcs
, rport
->pid
);
1295 bfa_trc(rport
->fcs
, event
);
1298 case RPSM_EVENT_HCB_OFFLINE
:
1299 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_logo_sending
);
1300 bfa_fcs_rport_send_logo(rport
, NULL
);
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
);
1309 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_delete_pending
);
1312 case RPSM_EVENT_SCN_ONLINE
:
1313 case RPSM_EVENT_SCN_OFFLINE
:
1314 case RPSM_EVENT_ADDRESS_CHANGE
:
1318 bfa_sm_fault(rport
->fcs
, event
);
1323 * Rport is being deleted. FC-4s are offline. LOGO is being sent.
1326 bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s
*rport
,
1327 enum rport_event event
)
1329 bfa_trc(rport
->fcs
, rport
->pwwn
);
1330 bfa_trc(rport
->fcs
, rport
->pid
);
1331 bfa_trc(rport
->fcs
, 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
);
1340 case RPSM_EVENT_SCN_ONLINE
:
1341 case RPSM_EVENT_SCN_OFFLINE
:
1342 case RPSM_EVENT_FAB_SCN
:
1343 case RPSM_EVENT_ADDRESS_CHANGE
:
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
);
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
);
1358 bfa_sm_fault(rport
->fcs
, event
);
1363 * Rport is offline. FC-4s are offline. BFA rport is offline.
1364 * Timer active to delete stale rport.
1367 bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s
*rport
, enum rport_event event
)
1369 bfa_trc(rport
->fcs
, rport
->pwwn
);
1370 bfa_trc(rport
->fcs
, rport
->pid
);
1371 bfa_trc(rport
->fcs
, event
);
1374 case RPSM_EVENT_TIMEOUT
:
1375 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
1376 bfa_fcs_rport_free(rport
);
1379 case RPSM_EVENT_FAB_SCN
:
1380 case RPSM_EVENT_ADDRESS_CHANGE
:
1381 bfa_timer_stop(&rport
->timer
);
1382 WARN_ON(!(bfa_fcport_get_topology(rport
->port
->fcs
->bfa
) !=
1383 BFA_PORT_TOPOLOGY_LOOP
));
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
);
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
);
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
);
1401 case RPSM_EVENT_LOGO_RCVD
:
1402 case RPSM_EVENT_PRLO_RCVD
:
1403 case RPSM_EVENT_LOGO_IMP
:
1404 case RPSM_EVENT_SCN_OFFLINE
:
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
);
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
);
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
);
1427 bfa_sm_fault(rport
->fcs
, event
);
1432 * Rport address has changed. Nameserver discovery request is being sent.
1435 bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s
*rport
,
1436 enum rport_event event
)
1438 bfa_trc(rport
->fcs
, rport
->pwwn
);
1439 bfa_trc(rport
->fcs
, rport
->pid
);
1440 bfa_trc(rport
->fcs
, event
);
1443 case RPSM_EVENT_FCXP_SENT
:
1444 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_nsdisc_sent
);
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
);
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
);
1459 case RPSM_EVENT_FAB_SCN
:
1460 case RPSM_EVENT_LOGO_RCVD
:
1461 case RPSM_EVENT_PRLO_RCVD
:
1462 case RPSM_EVENT_PLOGI_SEND
:
1465 case RPSM_EVENT_ADDRESS_CHANGE
:
1466 rport
->ns_retries
= 0; /* reset the retry count */
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
);
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
);
1484 bfa_sm_fault(rport
->fcs
, event
);
1489 * Nameserver discovery failed. Waiting for timeout to retry.
1492 bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s
*rport
,
1493 enum rport_event event
)
1495 bfa_trc(rport
->fcs
, rport
->pwwn
);
1496 bfa_trc(rport
->fcs
, rport
->pid
);
1497 bfa_trc(rport
->fcs
, 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
);
1505 case RPSM_EVENT_FAB_SCN
:
1506 case RPSM_EVENT_ADDRESS_CHANGE
:
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
);
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
);
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
);
1525 case RPSM_EVENT_LOGO_IMP
:
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
);
1534 case RPSM_EVENT_LOGO_RCVD
:
1535 bfa_fcs_rport_send_logo_acc(rport
);
1537 case RPSM_EVENT_PRLO_RCVD
:
1538 bfa_fcs_rport_send_prlo_acc(rport
);
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
);
1548 bfa_sm_fault(rport
->fcs
, event
);
1553 * Rport address has changed. Nameserver discovery request is sent.
1556 bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s
*rport
,
1557 enum rport_event event
)
1559 bfa_trc(rport
->fcs
, rport
->pwwn
);
1560 bfa_trc(rport
->fcs
, rport
->pid
);
1561 bfa_trc(rport
->fcs
, event
);
1564 case RPSM_EVENT_ACCEPTED
:
1565 case RPSM_EVENT_ADDRESS_CHANGE
:
1567 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_plogi_sending
);
1568 bfa_fcs_rport_send_plogi(rport
, NULL
);
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
);
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
);
1584 rport
->old_pid
= rport
->pid
;
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
);
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
);
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
);
1605 case RPSM_EVENT_LOGO_IMP
:
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
);
1615 case RPSM_EVENT_PRLO_RCVD
:
1616 bfa_fcs_rport_send_prlo_acc(rport
);
1618 case RPSM_EVENT_FAB_SCN
:
1620 * ignore, wait for NS query response
1624 case RPSM_EVENT_LOGO_RCVD
:
1626 * Not logged-in yet. Accept LOGO.
1628 bfa_fcs_rport_send_logo_acc(rport
);
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
);
1638 bfa_sm_fault(rport
->fcs
, event
);
1643 * Rport needs to be deleted
1644 * waiting for ITNIM clean up to finish
1647 bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s
*rport
,
1648 enum rport_event event
)
1650 bfa_trc(rport
->fcs
, rport
->pwwn
);
1651 bfa_trc(rport
->fcs
, rport
->pid
);
1652 bfa_trc(rport
->fcs
, event
);
1655 case RPSM_EVENT_FC4_OFFLINE
:
1656 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_delete_pending
);
1657 bfa_fcs_rport_hal_offline(rport
);
1660 case RPSM_EVENT_DELETE
:
1661 case RPSM_EVENT_PLOGI_RCVD
:
1662 /* Ignore these events */
1666 bfa_sm_fault(rport
->fcs
, event
);
1672 * RPort needs to be deleted
1673 * waiting for BFA/FW to finish current processing
1676 bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s
*rport
,
1677 enum rport_event event
)
1679 bfa_trc(rport
->fcs
, rport
->pwwn
);
1680 bfa_trc(rport
->fcs
, rport
->pid
);
1681 bfa_trc(rport
->fcs
, event
);
1684 case RPSM_EVENT_HCB_OFFLINE
:
1685 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
1686 bfa_fcs_rport_free(rport
);
1689 case RPSM_EVENT_DELETE
:
1690 case RPSM_EVENT_LOGO_IMP
:
1691 case RPSM_EVENT_PLOGI_RCVD
:
1692 /* Ignore these events */
1696 bfa_sm_fault(rport
->fcs
, event
);
1701 * fcs_rport_private FCS RPORT provate functions
1705 bfa_fcs_rport_send_plogi(void *rport_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1707 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
1708 struct bfa_fcs_lport_s
*port
= rport
->port
;
1711 struct bfa_fcxp_s
*fcxp
;
1713 bfa_trc(rport
->fcs
, rport
->pwwn
);
1715 fcxp
= fcxp_alloced
? fcxp_alloced
:
1716 bfa_fcs_fcxp_alloc(port
->fcs
, BFA_TRUE
);
1718 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rport
->fcxp_wqe
,
1719 bfa_fcs_rport_send_plogi
, rport
, BFA_TRUE
);
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
));
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
);
1734 rport
->stats
.plogis
++;
1735 bfa_sm_send_event(rport
, RPSM_EVENT_FCXP_SENT
);
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
)
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
;
1749 bfa_trc(rport
->fcs
, rport
->pwwn
);
1754 if (req_status
!= BFA_STATUS_OK
) {
1755 bfa_trc(rport
->fcs
, req_status
);
1756 rport
->stats
.plogi_failed
++;
1757 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1761 plogi_rsp
= (struct fc_logi_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1764 * Check for failure first.
1766 if (plogi_rsp
->els_cmd
.els_code
!= FC_ELS_ACC
) {
1767 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1769 bfa_trc(rport
->fcs
, ls_rjt
->reason_code
);
1770 bfa_trc(rport
->fcs
, ls_rjt
->reason_code_expl
);
1772 if ((ls_rjt
->reason_code
== FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD
) &&
1773 (ls_rjt
->reason_code_expl
== FC_LS_RJT_EXP_INSUFF_RES
)) {
1774 rport
->stats
.rjt_insuff_res
++;
1775 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_RETRY
);
1779 rport
->stats
.plogi_rejects
++;
1780 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1785 * PLOGI is complete. Make sure this device is not one of the known
1786 * device with a new FC port address.
1788 list_for_each(qe
, &rport
->port
->rport_q
) {
1789 twin
= (struct bfa_fcs_rport_s
*) qe
;
1792 if (!rport
->pwwn
&& (plogi_rsp
->port_name
== twin
->pwwn
)) {
1793 bfa_trc(rport
->fcs
, twin
->pid
);
1794 bfa_trc(rport
->fcs
, rport
->pid
);
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
++;
1807 bfa_sm_send_event(rport
, RPSM_EVENT_DELETE
);
1809 bfa_fcs_rport_update(twin
, plogi_rsp
);
1810 twin
->pid
= rsp_fchs
->s_id
;
1811 bfa_sm_send_event(twin
, RPSM_EVENT_PLOGI_COMP
);
1817 * Normal login path -- no evil twins.
1819 rport
->stats
.plogi_accs
++;
1820 bfa_fcs_rport_update(rport
, plogi_rsp
);
1821 bfa_sm_send_event(rport
, RPSM_EVENT_ACCEPTED
);
1825 bfa_fcs_rport_send_plogiacc(void *rport_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1827 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
1828 struct bfa_fcs_lport_s
*port
= rport
->port
;
1831 struct bfa_fcxp_s
*fcxp
;
1833 bfa_trc(rport
->fcs
, rport
->pwwn
);
1834 bfa_trc(rport
->fcs
, rport
->reply_oxid
);
1836 fcxp
= fcxp_alloced
? fcxp_alloced
:
1837 bfa_fcs_fcxp_alloc(port
->fcs
, BFA_FALSE
);
1839 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rport
->fcxp_wqe
,
1840 bfa_fcs_rport_send_plogiacc
, rport
, BFA_FALSE
);
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
));
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);
1855 bfa_sm_send_event(rport
, RPSM_EVENT_FCXP_SENT
);
1859 bfa_fcs_rport_send_adisc(void *rport_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1861 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
1862 struct bfa_fcs_lport_s
*port
= rport
->port
;
1865 struct bfa_fcxp_s
*fcxp
;
1867 bfa_trc(rport
->fcs
, rport
->pwwn
);
1869 fcxp
= fcxp_alloced
? fcxp_alloced
:
1870 bfa_fcs_fcxp_alloc(port
->fcs
, BFA_TRUE
);
1872 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rport
->fcxp_wqe
,
1873 bfa_fcs_rport_send_adisc
, rport
, BFA_TRUE
);
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
);
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
);
1886 rport
->stats
.adisc_sent
++;
1887 bfa_sm_send_event(rport
, RPSM_EVENT_FCXP_SENT
);
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
)
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
;
1899 if (req_status
!= BFA_STATUS_OK
) {
1900 bfa_trc(rport
->fcs
, req_status
);
1901 rport
->stats
.adisc_failed
++;
1902 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
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
++;
1909 bfa_sm_send_event(rport
, RPSM_EVENT_ACCEPTED
);
1913 rport
->stats
.adisc_rejects
++;
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
);
1918 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
1922 bfa_fcs_rport_send_nsdisc(void *rport_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
1924 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
1925 struct bfa_fcs_lport_s
*port
= rport
->port
;
1927 struct bfa_fcxp_s
*fcxp
;
1929 bfa_cb_fcxp_send_t cbfn
;
1931 bfa_trc(rport
->fcs
, rport
->pid
);
1933 fcxp
= fcxp_alloced
? fcxp_alloced
:
1934 bfa_fcs_fcxp_alloc(port
->fcs
, BFA_TRUE
);
1936 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rport
->fcxp_wqe
,
1937 bfa_fcs_rport_send_nsdisc
, rport
, BFA_TRUE
);
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
;
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
;
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
);
1956 bfa_sm_send_event(rport
, RPSM_EVENT_FCXP_SENT
);
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
)
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
;
1970 bfa_trc(rport
->fcs
, rport
->pwwn
);
1972 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
1973 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
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);
1979 if (gidpn_rsp
->dap
== rport
->pid
) {
1980 /* Device is online */
1981 bfa_sm_send_event(rport
, RPSM_EVENT_ACCEPTED
);
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.
1989 list_for_each(qe
, &rport
->port
->rport_q
) {
1990 twin
= (struct bfa_fcs_rport_s
*) qe
;
1993 if (gidpn_rsp
->dap
== twin
->pid
) {
1994 bfa_trc(rport
->fcs
, twin
->pid
);
1995 bfa_trc(rport
->fcs
, rport
->pid
);
1998 bfa_sm_send_event(twin
,
1999 RPSM_EVENT_ADDRESS_CHANGE
);
2002 rport
->pid
= gidpn_rsp
->dap
;
2003 bfa_sm_send_event(rport
, RPSM_EVENT_ADDRESS_CHANGE
);
2011 switch (cthdr
->reason_code
) {
2012 case CT_RSN_LOGICAL_BUSY
:
2016 bfa_sm_send_event(rport
, RPSM_EVENT_TIMEOUT
);
2019 case CT_RSN_UNABLE_TO_PERF
:
2021 * device doesn't exist : Start timer to cleanup this later.
2023 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
2027 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
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
)
2037 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
2038 struct ct_hdr_s
*cthdr
;
2040 bfa_trc(rport
->fcs
, rport
->pwwn
);
2042 cthdr
= (struct ct_hdr_s
*) BFA_FCXP_RSP_PLD(fcxp
);
2043 cthdr
->cmd_rsp_code
= be16_to_cpu(cthdr
->cmd_rsp_code
);
2045 if (cthdr
->cmd_rsp_code
== CT_RSP_ACCEPT
) {
2046 bfa_sm_send_event(rport
, RPSM_EVENT_ACCEPTED
);
2053 switch (cthdr
->reason_code
) {
2054 case CT_RSN_LOGICAL_BUSY
:
2058 bfa_sm_send_event(rport
, RPSM_EVENT_TIMEOUT
);
2061 case CT_RSN_UNABLE_TO_PERF
:
2063 * device doesn't exist : Start timer to cleanup this later.
2065 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
2069 bfa_sm_send_event(rport
, RPSM_EVENT_FAILED
);
2075 * Called to send a logout to the rport.
2078 bfa_fcs_rport_send_logo(void *rport_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
2080 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
2081 struct bfa_fcs_lport_s
*port
;
2083 struct bfa_fcxp_s
*fcxp
;
2086 bfa_trc(rport
->fcs
, rport
->pid
);
2090 fcxp
= fcxp_alloced
? fcxp_alloced
:
2091 bfa_fcs_fcxp_alloc(port
->fcs
, BFA_FALSE
);
2093 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rport
->fcxp_wqe
,
2094 bfa_fcs_rport_send_logo
, rport
, BFA_FALSE
);
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
));
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
);
2107 rport
->stats
.logos
++;
2108 bfa_fcxp_discard(rport
->fcxp
);
2109 bfa_sm_send_event(rport
, RPSM_EVENT_FCXP_SENT
);
2113 * Send ACC for a LOGO received.
2116 bfa_fcs_rport_send_logo_acc(void *rport_cbarg
)
2118 struct bfa_fcs_rport_s
*rport
= rport_cbarg
;
2119 struct bfa_fcs_lport_s
*port
;
2121 struct bfa_fcxp_s
*fcxp
;
2124 bfa_trc(rport
->fcs
, rport
->pid
);
2128 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
, BFA_FALSE
);
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
),
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);
2143 * This routine will be called by bfa_timer on timer timeouts.
2145 * param[in] rport - pointer to bfa_fcs_lport_ns_t.
2146 * param[out] rport_status - pointer to return vport status in
2151 * Special Considerations:
2156 bfa_fcs_rport_timeout(void *arg
)
2158 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) arg
;
2160 rport
->stats
.plogi_timeouts
++;
2161 bfa_stats(rport
->port
, rport_plogi_timeouts
);
2162 bfa_sm_send_event(rport
, RPSM_EVENT_TIMEOUT
);
2166 bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s
*rport
,
2167 struct fchs_s
*rx_fchs
, u16 len
)
2169 struct bfa_fcxp_s
*fcxp
;
2171 struct bfa_fcs_lport_s
*port
= rport
->port
;
2172 struct fc_prli_s
*prli
;
2174 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
2175 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
2177 rport
->stats
.prli_rcvd
++;
2180 * We are in Initiator Mode
2182 prli
= (struct fc_prli_s
*) (rx_fchs
+ 1);
2184 if (prli
->parampage
.servparams
.target
) {
2186 * PRLI from a target ?
2188 * PRLI sent by us will be used to transition the IT nexus,
2189 * once the response is received from the target.
2191 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
2192 rport
->scsi_function
= BFA_RPORT_TARGET
;
2194 bfa_trc(rport
->fcs
, prli
->parampage
.type
);
2195 rport
->scsi_function
= BFA_RPORT_INITIATOR
;
2196 bfa_fcs_itnim_is_initiator(rport
->itnim
);
2199 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
, BFA_FALSE
);
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
);
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);
2212 bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s
*rport
,
2213 struct fchs_s
*rx_fchs
, u16 len
)
2215 struct bfa_fcxp_s
*fcxp
;
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
;
2221 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
2222 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
2224 rport
->stats
.rpsc_rcvd
++;
2225 speeds
.port_speed_cap
=
2226 RPSC_SPEED_CAP_1G
| RPSC_SPEED_CAP_2G
| RPSC_SPEED_CAP_4G
|
2230 * get curent speed from pport attributes from BFA
2232 bfa_fcport_get_attr(port
->fcs
->bfa
, &pport_attr
);
2234 speeds
.port_op_speed
= fc_bfa_speed_to_rpsc_operspeed(pport_attr
.speed
);
2236 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
, BFA_FALSE
);
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
);
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);
2249 bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s
*rport
,
2250 struct fchs_s
*rx_fchs
, u16 len
)
2252 struct bfa_fcxp_s
*fcxp
;
2254 struct bfa_fcs_lport_s
*port
= rport
->port
;
2255 struct fc_adisc_s
*adisc
;
2257 bfa_trc(port
->fcs
, rx_fchs
->s_id
);
2258 bfa_trc(port
->fcs
, rx_fchs
->d_id
);
2260 rport
->stats
.adisc_rcvd
++;
2262 adisc
= (struct fc_adisc_s
*) (rx_fchs
+ 1);
2265 * Accept if the itnim for this rport is online.
2266 * Else reject the ADISC.
2268 if (bfa_fcs_itnim_get_online_state(rport
->itnim
) == BFA_STATUS_OK
) {
2270 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
, BFA_FALSE
);
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
);
2279 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
,
2280 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
2283 rport
->stats
.adisc_rejected
++;
2284 bfa_fcs_rport_send_ls_rjt(rport
, rx_fchs
,
2285 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD
,
2286 FC_LS_RJT_EXP_LOGIN_REQUIRED
);
2291 bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s
*rport
)
2293 struct bfa_fcs_lport_s
*port
= rport
->port
;
2294 struct bfa_rport_info_s rport_info
;
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
);
2308 bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s
*rport
)
2310 if (rport
->bfa_rport
)
2311 bfa_sm_send_event(rport
->bfa_rport
, BFA_RPORT_SM_OFFLINE
);
2313 bfa_cb_rport_offline(rport
);
2316 static struct bfa_fcs_rport_s
*
2317 bfa_fcs_rport_alloc(struct bfa_fcs_lport_s
*port
, wwn_t pwwn
, u32 rpid
)
2319 struct bfa_fcs_s
*fcs
= port
->fcs
;
2320 struct bfa_fcs_rport_s
*rport
;
2321 struct bfad_rport_s
*rport_drv
;
2326 if (fcs
->num_rport_logins
>= bfa_fcs_rport_max_logins
) {
2331 if (bfa_fcb_rport_alloc(fcs
->bfad
, &rport
, &rport_drv
)
2342 rport
->rp_drv
= rport_drv
;
2347 rport
->bfa_rport
= NULL
;
2352 WARN_ON(!bfa_fcs_lport_is_initiator(port
));
2354 if (bfa_fcs_lport_is_initiator(port
)) {
2355 rport
->itnim
= bfa_fcs_itnim_create(rport
);
2356 if (!rport
->itnim
) {
2363 bfa_fcs_lport_add_rport(port
, rport
);
2364 fcs
->num_rport_logins
++;
2366 bfa_sm_set_state(rport
, bfa_fcs_rport_sm_uninit
);
2368 /* Initialize the Rport Features(RPF) Sub Module */
2369 if (!BFA_FCS_PID_IS_WKA(rport
->pid
))
2370 bfa_fcs_rpf_init(rport
);
2377 bfa_fcs_rport_free(struct bfa_fcs_rport_s
*rport
)
2379 struct bfa_fcs_lport_s
*port
= rport
->port
;
2380 struct bfa_fcs_s
*fcs
= port
->fcs
;
2384 * - delete BFA rport
2385 * - remove from queue of rports
2387 rport
->plogi_pending
= BFA_FALSE
;
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
))
2392 bfa_fcs_rpf_rport_offline(rport
);
2395 if (rport
->bfa_rport
) {
2396 bfa_sm_send_event(rport
->bfa_rport
, BFA_RPORT_SM_DELETE
);
2397 rport
->bfa_rport
= NULL
;
2400 bfa_fcs_lport_del_rport(port
, rport
);
2401 fcs
->num_rport_logins
--;
2402 kfree(rport
->rp_drv
);
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
)
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
;
2414 bfad_get_aen_entry(bfad
, aen_entry
);
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
;
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
;
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
);
2435 bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s
*rport
)
2437 if ((!rport
->pid
) || (!rport
->pwwn
)) {
2438 bfa_trc(rport
->fcs
, rport
->pid
);
2439 bfa_sm_fault(rport
->fcs
, rport
->pid
);
2442 bfa_sm_send_event(rport
->itnim
, BFA_FCS_ITNIM_SM_FCS_ONLINE
);
2446 bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s
*rport
)
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
];
2453 rport
->stats
.onlines
++;
2455 if ((!rport
->pid
) || (!rport
->pwwn
)) {
2456 bfa_trc(rport
->fcs
, rport
->pid
);
2457 bfa_sm_fault(rport
->fcs
, rport
->pid
);
2460 if (bfa_fcs_lport_is_initiator(port
)) {
2461 bfa_fcs_itnim_brp_online(rport
->itnim
);
2462 if (!BFA_FCS_PID_IS_WKA(rport
->pid
))
2463 bfa_fcs_rpf_rport_online(rport
);
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
)) {
2469 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
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
);
2477 bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s
*rport
)
2479 if (!BFA_FCS_PID_IS_WKA(rport
->pid
))
2480 bfa_fcs_rpf_rport_offline(rport
);
2482 bfa_fcs_itnim_rport_offline(rport
->itnim
);
2486 bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s
*rport
)
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
];
2493 if (!rport
->bfa_rport
) {
2494 bfa_fcs_rport_fcs_offline_action(rport
);
2498 rport
->stats
.offlines
++;
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
) {
2504 BFA_LOG(KERN_ERR
, bfad
, bfa_log_level
,
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
,
2509 BFA_RPORT_AEN_DISCONNECT
, NULL
);
2511 BFA_LOG(KERN_INFO
, bfad
, bfa_log_level
,
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
,
2516 BFA_RPORT_AEN_OFFLINE
, NULL
);
2520 if (bfa_fcs_lport_is_initiator(port
)) {
2521 bfa_fcs_itnim_rport_offline(rport
->itnim
);
2522 if (!BFA_FCS_PID_IS_WKA(rport
->pid
))
2523 bfa_fcs_rpf_rport_offline(rport
);
2528 * Update rport parameters from PLOGI or PLOGI accept.
2531 bfa_fcs_rport_update(struct bfa_fcs_rport_s
*rport
, struct fc_logi_s
*plogi
)
2533 bfa_fcs_lport_t
*port
= rport
->port
;
2539 rport
->pwwn
= plogi
->port_name
;
2540 rport
->nwwn
= plogi
->node_name
;
2543 * - class of service
2546 if (plogi
->class3
.class_valid
)
2547 rport
->fc_cos
= FC_CLASS_3
;
2549 if (plogi
->class2
.class_valid
)
2550 rport
->fc_cos
|= FC_CLASS_2
;
2554 * - MAX receive frame size
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
);
2560 rport
->maxfrsize
= be16_to_cpu(plogi
->csp
.rxsz
);
2562 bfa_trc(port
->fcs
, be16_to_cpu(plogi
->csp
.bbcred
));
2563 bfa_trc(port
->fcs
, port
->fabric
->bb_credit
);
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)
2572 if ((!bfa_fcs_fabric_is_switched(port
->fabric
)) &&
2573 (be16_to_cpu(plogi
->csp
.bbcred
) < port
->fabric
->bb_credit
)) {
2575 bfa_trc(port
->fcs
, be16_to_cpu(plogi
->csp
.bbcred
));
2576 bfa_trc(port
->fcs
, port
->fabric
->bb_credit
);
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
);
2586 * Called to handle LOGO received from an existing remote port.
2589 bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s
*rport
, struct fchs_s
*fchs
)
2591 rport
->reply_oxid
= fchs
->ox_id
;
2592 bfa_trc(rport
->fcs
, rport
->reply_oxid
);
2594 rport
->prlo
= BFA_FALSE
;
2595 rport
->stats
.logo_rcvd
++;
2596 bfa_sm_send_event(rport
, RPSM_EVENT_LOGO_RCVD
);
2602 * fcs_rport_public FCS rport public interfaces
2606 * Called by bport/vport to create a remote port instance for a discovered
2609 * @param[in] port - base port or vport
2610 * @param[in] rpid - remote port ID
2614 struct bfa_fcs_rport_s
*
2615 bfa_fcs_rport_create(struct bfa_fcs_lport_s
*port
, u32 rpid
)
2617 struct bfa_fcs_rport_s
*rport
;
2619 bfa_trc(port
->fcs
, rpid
);
2620 rport
= bfa_fcs_rport_alloc(port
, WWN_NULL
, rpid
);
2624 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_SEND
);
2629 * Called to create a rport for which only the wwn is known.
2631 * @param[in] port - base port
2632 * @param[in] rpwwn - remote port wwn
2636 struct bfa_fcs_rport_s
*
2637 bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s
*port
, wwn_t rpwwn
)
2639 struct bfa_fcs_rport_s
*rport
;
2640 bfa_trc(port
->fcs
, rpwwn
);
2641 rport
= bfa_fcs_rport_alloc(port
, rpwwn
, 0);
2645 bfa_sm_send_event(rport
, RPSM_EVENT_ADDRESS_DISC
);
2649 * Called by bport in private loop topology to indicate that a
2650 * rport has been discovered and plogi has been completed.
2652 * @param[in] port - base port or vport
2653 * @param[in] rpid - remote port ID
2656 bfa_fcs_rport_start(struct bfa_fcs_lport_s
*port
, struct fchs_s
*fchs
,
2657 struct fc_logi_s
*plogi
)
2659 struct bfa_fcs_rport_s
*rport
;
2661 rport
= bfa_fcs_rport_alloc(port
, WWN_NULL
, fchs
->s_id
);
2665 bfa_fcs_rport_update(rport
, plogi
);
2667 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_COMP
);
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.
2675 bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s
*port
, struct fchs_s
*fchs
,
2676 struct fc_logi_s
*plogi
)
2678 struct bfa_fcs_rport_s
*rport
;
2680 rport
= bfa_fcs_rport_alloc(port
, plogi
->port_name
, fchs
->s_id
);
2684 bfa_fcs_rport_update(rport
, plogi
);
2686 rport
->reply_oxid
= fchs
->ox_id
;
2687 bfa_trc(rport
->fcs
, rport
->reply_oxid
);
2689 rport
->stats
.plogi_rcvd
++;
2690 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_RCVD
);
2694 * Called by bport/vport to handle PLOGI received from an existing
2698 bfa_fcs_rport_plogi(struct bfa_fcs_rport_s
*rport
, struct fchs_s
*rx_fchs
,
2699 struct fc_logi_s
*plogi
)
2702 * @todo Handle P2P and initiator-initiator.
2705 bfa_fcs_rport_update(rport
, plogi
);
2707 rport
->reply_oxid
= rx_fchs
->ox_id
;
2708 bfa_trc(rport
->fcs
, rport
->reply_oxid
);
2710 rport
->pid
= rx_fchs
->s_id
;
2711 bfa_trc(rport
->fcs
, rport
->pid
);
2713 rport
->stats
.plogi_rcvd
++;
2714 bfa_sm_send_event(rport
, RPSM_EVENT_PLOGI_RCVD
);
2719 * Called by bport/vport to notify SCN for the remote port
2722 bfa_fcs_rport_scn(struct bfa_fcs_rport_s
*rport
)
2724 rport
->stats
.rscns
++;
2725 bfa_sm_send_event(rport
, RPSM_EVENT_FAB_SCN
);
2730 * This routine BFA callback for bfa_rport_online() call.
2732 * param[in] cb_arg - rport struct.
2737 * Special Considerations:
2742 bfa_cb_rport_online(void *cbarg
)
2745 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
2747 bfa_trc(rport
->fcs
, rport
->pwwn
);
2748 bfa_sm_send_event(rport
, RPSM_EVENT_HCB_ONLINE
);
2753 * This routine BFA callback for bfa_rport_offline() call.
2760 * Special Considerations:
2765 bfa_cb_rport_offline(void *cbarg
)
2767 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
2769 bfa_trc(rport
->fcs
, rport
->pwwn
);
2770 bfa_sm_send_event(rport
, RPSM_EVENT_HCB_OFFLINE
);
2775 * This routine is a static BFA callback when there is a QoS flow_id
2776 * change notification
2783 * Special Considerations:
2788 bfa_cb_rport_qos_scn_flowid(void *cbarg
,
2789 struct bfa_rport_qos_attr_s old_qos_attr
,
2790 struct bfa_rport_qos_attr_s new_qos_attr
)
2792 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
2793 struct bfa_rport_aen_data_s aen_data
;
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
);
2801 bfa_cb_rport_scn_online(struct bfa_s
*bfa
)
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
;
2808 list_for_each(qe
, &port
->rport_q
) {
2809 rp
= (struct bfa_fcs_rport_s
*) qe
;
2810 bfa_sm_send_event(rp
, RPSM_EVENT_SCN_ONLINE
);
2811 rp
->scn_online
= BFA_TRUE
;
2814 if (bfa_fcs_lport_is_online(port
))
2815 bfa_fcs_lport_lip_scn_online(port
);
2819 bfa_cb_rport_scn_no_dev(void *rport
)
2821 struct bfa_fcs_rport_s
*rp
= rport
;
2823 bfa_sm_send_event(rp
, RPSM_EVENT_SCN_OFFLINE
);
2824 rp
->scn_online
= BFA_FALSE
;
2828 bfa_cb_rport_scn_offline(struct bfa_s
*bfa
)
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
;
2835 list_for_each(qe
, &port
->rport_q
) {
2836 rp
= (struct bfa_fcs_rport_s
*) qe
;
2837 bfa_sm_send_event(rp
, RPSM_EVENT_SCN_OFFLINE
);
2838 rp
->scn_online
= BFA_FALSE
;
2844 * This routine is a static BFA callback when there is a QoS priority
2845 * change notification
2852 * Special Considerations:
2857 bfa_cb_rport_qos_scn_prio(void *cbarg
,
2858 struct bfa_rport_qos_attr_s old_qos_attr
,
2859 struct bfa_rport_qos_attr_s new_qos_attr
)
2861 struct bfa_fcs_rport_s
*rport
= (struct bfa_fcs_rport_s
*) cbarg
;
2862 struct bfa_rport_aen_data_s aen_data
;
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
);
2870 * Called to process any unsolicted frames from this remote port
2873 bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s
*rport
,
2874 struct fchs_s
*fchs
, u16 len
)
2876 struct bfa_fcs_lport_s
*port
= rport
->port
;
2877 struct fc_els_cmd_s
*els_cmd
;
2879 bfa_trc(rport
->fcs
, fchs
->s_id
);
2880 bfa_trc(rport
->fcs
, fchs
->d_id
);
2881 bfa_trc(rport
->fcs
, fchs
->type
);
2883 if (fchs
->type
!= FC_TYPE_ELS
)
2886 els_cmd
= (struct fc_els_cmd_s
*) (fchs
+ 1);
2888 bfa_trc(rport
->fcs
, els_cmd
->els_code
);
2890 switch (els_cmd
->els_code
) {
2892 bfa_stats(port
, plogi_rcvd
);
2893 bfa_fcs_rport_process_logo(rport
, fchs
);
2897 bfa_stats(port
, adisc_rcvd
);
2898 bfa_fcs_rport_process_adisc(rport
, fchs
, len
);
2902 bfa_stats(port
, prlo_rcvd
);
2903 if (bfa_fcs_lport_is_initiator(port
))
2904 bfa_fcs_fcpim_uf_recv(rport
->itnim
, fchs
, len
);
2908 bfa_stats(port
, prli_rcvd
);
2909 bfa_fcs_rport_process_prli(rport
, fchs
, len
);
2913 bfa_stats(port
, rpsc_rcvd
);
2914 bfa_fcs_rport_process_rpsc(rport
, fchs
, len
);
2918 bfa_stats(port
, un_handled_els_rcvd
);
2919 bfa_fcs_rport_send_ls_rjt(rport
, fchs
,
2920 FC_LS_RJT_RSN_CMD_NOT_SUPP
,
2921 FC_LS_RJT_EXP_NO_ADDL_INFO
);
2926 /* send best case acc to prlo */
2928 bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s
*rport
)
2930 struct bfa_fcs_lport_s
*port
= rport
->port
;
2932 struct bfa_fcxp_s
*fcxp
;
2935 bfa_trc(rport
->fcs
, rport
->pid
);
2937 fcxp
= bfa_fcs_fcxp_alloc(port
->fcs
, BFA_FALSE
);
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);
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);
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
)
2956 struct bfa_fcs_lport_s
*port
= rport
->port
;
2958 struct bfa_fcxp_s
*fcxp
;
2961 bfa_trc(rport
->fcs
, rx_fchs
->s_id
);
2963 fcxp
= bfa_fcs_fcxp_alloc(rport
->fcs
, BFA_FALSE
);
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
);
2971 bfa_fcxp_send(fcxp
, NULL
, port
->fabric
->vf_id
, port
->lp_tag
,
2972 BFA_FALSE
, FC_CLASS_3
, len
, &fchs
, NULL
, NULL
,
2977 * Return state of rport.
2980 bfa_fcs_rport_get_state(struct bfa_fcs_rport_s
*rport
)
2982 return bfa_sm_to_state(rport_sm_table
, rport
->sm
);
2988 * Called by the Driver to set rport delete/ageout timeout
2990 * param[in] rport timeout value in seconds.
2995 bfa_fcs_rport_set_del_timeout(u8 rport_tmo
)
2997 /* convert to Millisecs */
2999 bfa_fcs_rport_del_timeout
= rport_tmo
* 1000;
3002 bfa_fcs_rport_prlo(struct bfa_fcs_rport_s
*rport
, __be16 ox_id
)
3004 bfa_trc(rport
->fcs
, rport
->pid
);
3006 rport
->prlo
= BFA_TRUE
;
3007 rport
->reply_oxid
= ox_id
;
3008 bfa_sm_send_event(rport
, RPSM_EVENT_PRLO_RCVD
);
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
3016 bfa_fcs_rport_set_max_logins(u32 max_logins
)
3019 bfa_fcs_rport_max_logins
= max_logins
;
3023 bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s
*rport
,
3024 struct bfa_rport_attr_s
*rport_attr
)
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
;
3031 bfa_fcport_get_attr(rport
->fcs
->bfa
, &port_attr
);
3033 memset(rport_attr
, 0, sizeof(struct bfa_rport_attr_s
));
3034 memset(&qos_attr
, 0, sizeof(struct bfa_rport_qos_attr_s
));
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
;
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
);
3053 rport_attr
->qos_attr
= qos_attr
;
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
)
3060 bfa_fcport_get_ratelim_speed(rport
->fcs
->bfa
);
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
;
3069 * Remote port implementation.
3073 * fcs_rport_api FCS rport API.
3076 struct bfa_fcs_rport_s
*
3077 bfa_fcs_rport_lookup(struct bfa_fcs_lport_s
*port
, wwn_t rpwwn
)
3079 struct bfa_fcs_rport_s
*rport
;
3081 rport
= bfa_fcs_lport_get_rport_by_pwwn(port
, rpwwn
);
3082 if (rport
== NULL
) {
3084 * TBD Error handling
3091 struct bfa_fcs_rport_s
*
3092 bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s
*port
, wwn_t rnwwn
)
3094 struct bfa_fcs_rport_s
*rport
;
3096 rport
= bfa_fcs_lport_get_rport_by_nwwn(port
, rnwwn
);
3097 if (rport
== NULL
) {
3099 * TBD Error handling
3107 * Remote port features (RPF) implementation.
3110 #define BFA_FCS_RPF_RETRIES (3)
3111 #define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */
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
,
3118 bfa_status_t req_status
,
3121 struct fchs_s
*rsp_fchs
);
3123 static void bfa_fcs_rpf_timeout(void *arg
);
3126 * fcs_rport_ftrs_sm FCS rport state machine events
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 */
3134 RPFSM_EVENT_RPSC_COMP
= 5,
3135 RPFSM_EVENT_RPSC_FAIL
= 6,
3136 RPFSM_EVENT_RPSC_ERROR
= 7,
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
);
3153 bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
3155 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
3156 struct bfa_fcs_fabric_s
*fabric
= &rport
->fcs
->fabric
;
3158 bfa_trc(rport
->fcs
, rport
->pwwn
);
3159 bfa_trc(rport
->fcs
, rport
->pid
);
3160 bfa_trc(rport
->fcs
, event
);
3163 case RPFSM_EVENT_RPORT_ONLINE
:
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
) ==
3168 BFA_FCS_BRCD_SWITCH_OUI
))) {
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
);
3175 case RPFSM_EVENT_RPORT_OFFLINE
:
3179 bfa_sm_fault(rport
->fcs
, event
);
3184 bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
3186 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
3188 bfa_trc(rport
->fcs
, event
);
3191 case RPFSM_EVENT_FCXP_SENT
:
3192 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_rpsc
);
3195 case RPFSM_EVENT_RPORT_OFFLINE
:
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;
3202 bfa_sm_fault(rport
->fcs
, event
);
3207 bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
3209 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
3211 bfa_trc(rport
->fcs
, rport
->pid
);
3212 bfa_trc(rport
->fcs
, 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
)
3221 bfa_rport_speed(rport
->bfa_rport
, rpf
->assigned_speed
);
3224 case RPFSM_EVENT_RPSC_FAIL
:
3225 /* RPSC not supported by rport */
3226 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_online
);
3229 case RPFSM_EVENT_RPSC_ERROR
:
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
,
3234 BFA_FCS_RPF_RETRY_TIMEOUT
);
3235 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_rpsc_retry
);
3237 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_online
);
3241 case RPFSM_EVENT_RPORT_OFFLINE
:
3242 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_offline
);
3243 bfa_fcxp_discard(rpf
->fcxp
);
3244 rpf
->rpsc_retries
= 0;
3248 bfa_sm_fault(rport
->fcs
, event
);
3253 bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
3255 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
3257 bfa_trc(rport
->fcs
, rport
->pid
);
3258 bfa_trc(rport
->fcs
, 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
);
3267 case RPFSM_EVENT_RPORT_OFFLINE
:
3268 bfa_timer_stop(&rpf
->timer
);
3269 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_offline
);
3270 rpf
->rpsc_retries
= 0;
3274 bfa_sm_fault(rport
->fcs
, event
);
3279 bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
3281 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
3283 bfa_trc(rport
->fcs
, rport
->pwwn
);
3284 bfa_trc(rport
->fcs
, rport
->pid
);
3285 bfa_trc(rport
->fcs
, event
);
3288 case RPFSM_EVENT_RPORT_OFFLINE
:
3289 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_offline
);
3290 rpf
->rpsc_retries
= 0;
3294 bfa_sm_fault(rport
->fcs
, event
);
3299 bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s
*rpf
, enum rpf_event event
)
3301 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
3303 bfa_trc(rport
->fcs
, rport
->pwwn
);
3304 bfa_trc(rport
->fcs
, rport
->pid
);
3305 bfa_trc(rport
->fcs
, event
);
3308 case RPFSM_EVENT_RPORT_ONLINE
:
3309 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_rpsc_sending
);
3310 bfa_fcs_rpf_send_rpsc2(rpf
, NULL
);
3313 case RPFSM_EVENT_RPORT_OFFLINE
:
3317 bfa_sm_fault(rport
->fcs
, event
);
3321 * Called when Rport is created.
3324 bfa_fcs_rpf_init(struct bfa_fcs_rport_s
*rport
)
3326 struct bfa_fcs_rpf_s
*rpf
= &rport
->rpf
;
3328 bfa_trc(rport
->fcs
, rport
->pid
);
3331 bfa_sm_set_state(rpf
, bfa_fcs_rpf_sm_uninit
);
3335 * Called when Rport becomes online
3338 bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s
*rport
)
3340 bfa_trc(rport
->fcs
, rport
->pid
);
3342 if (__fcs_min_cfg(rport
->port
->fcs
))
3345 if (bfa_fcs_fabric_is_switched(rport
->port
->fabric
))
3346 bfa_sm_send_event(&rport
->rpf
, RPFSM_EVENT_RPORT_ONLINE
);
3350 * Called when Rport becomes offline
3353 bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s
*rport
)
3355 bfa_trc(rport
->fcs
, rport
->pid
);
3357 if (__fcs_min_cfg(rport
->port
->fcs
))
3360 rport
->rpf
.rpsc_speed
= 0;
3361 bfa_sm_send_event(&rport
->rpf
, RPFSM_EVENT_RPORT_OFFLINE
);
3365 bfa_fcs_rpf_timeout(void *arg
)
3367 struct bfa_fcs_rpf_s
*rpf
= (struct bfa_fcs_rpf_s
*) arg
;
3368 struct bfa_fcs_rport_s
*rport
= rpf
->rport
;
3370 bfa_trc(rport
->fcs
, rport
->pid
);
3371 bfa_sm_send_event(rpf
, RPFSM_EVENT_TIMEOUT
);
3375 bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg
, struct bfa_fcxp_s
*fcxp_alloced
)
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
;
3382 struct bfa_fcxp_s
*fcxp
;
3384 bfa_trc(rport
->fcs
, rport
->pwwn
);
3386 fcxp
= fcxp_alloced
? fcxp_alloced
:
3387 bfa_fcs_fcxp_alloc(port
->fcs
, BFA_TRUE
);
3389 bfa_fcs_fcxp_alloc_wait(port
->fcs
->bfa
, &rpf
->fcxp_wqe
,
3390 bfa_fcs_rpf_send_rpsc2
, rpf
, BFA_TRUE
);
3395 len
= fc_rpsc2_build(&fchs
, bfa_fcxp_get_reqbuf(fcxp
), rport
->pid
,
3396 bfa_fcs_lport_get_fcid(port
), &rport
->pid
, 1);
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
++;
3402 bfa_sm_send_event(rpf
, RPFSM_EVENT_FCXP_SENT
);
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
)
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
;
3417 bfa_trc(rport
->fcs
, req_status
);
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
++;
3423 bfa_sm_send_event(rpf
, RPFSM_EVENT_RPSC_ERROR
);
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
);
3433 WARN_ON(be32_to_cpu(rpsc2_acc
->port_info
[0].pid
) !=
3434 bfa_ntoh3b(rport
->pid
));
3436 be32_to_cpu(rpsc2_acc
->port_info
[0].pid
));
3438 be16_to_cpu(rpsc2_acc
->port_info
[0].speed
));
3440 be16_to_cpu(rpsc2_acc
->port_info
[0].index
));
3442 rpsc2_acc
->port_info
[0].type
);
3444 if (rpsc2_acc
->port_info
[0].speed
== 0) {
3445 bfa_sm_send_event(rpf
, RPFSM_EVENT_RPSC_ERROR
);
3449 rpf
->rpsc_speed
= fc_rpsc_operspeed_to_bfa_speed(
3450 be16_to_cpu(rpsc2_acc
->port_info
[0].speed
));
3452 bfa_sm_send_event(rpf
, RPFSM_EVENT_RPSC_COMP
);
3455 ls_rjt
= (struct fc_ls_rjt_s
*) BFA_FCXP_RSP_PLD(fcxp
);
3456 bfa_trc(rport
->fcs
, ls_rjt
->reason_code
);
3457 bfa_trc(rport
->fcs
, ls_rjt
->reason_code_expl
);
3458 rport
->stats
.rpsc_rejects
++;
3459 if (ls_rjt
->reason_code
== FC_LS_RJT_RSN_CMD_NOT_SUPP
)
3460 bfa_sm_send_event(rpf
, RPFSM_EVENT_RPSC_FAIL
);
3462 bfa_sm_send_event(rpf
, RPFSM_EVENT_RPSC_ERROR
);