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.
23 #include "bfa_fcbuild.h"
26 BFA_TRC_FILE(FCS, RPORT);
29 bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
32 * forward declarations
34 static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(
35 struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid);
36 static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
37 static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
38 static void bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport);
39 static void bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport);
40 static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
41 struct fc_logi_s *plogi);
42 static void bfa_fcs_rport_timeout(void *arg);
43 static void bfa_fcs_rport_send_plogi(void *rport_cbarg,
44 struct bfa_fcxp_s *fcxp_alloced);
45 static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
46 struct bfa_fcxp_s *fcxp_alloced);
47 static void bfa_fcs_rport_plogi_response(void *fcsarg,
48 struct bfa_fcxp_s *fcxp, void *cbarg,
49 bfa_status_t req_status, u32 rsp_len,
50 u32 resid_len, struct fchs_s *rsp_fchs);
51 static void bfa_fcs_rport_send_adisc(void *rport_cbarg,
52 struct bfa_fcxp_s *fcxp_alloced);
53 static void bfa_fcs_rport_adisc_response(void *fcsarg,
54 struct bfa_fcxp_s *fcxp, void *cbarg,
55 bfa_status_t req_status, u32 rsp_len,
56 u32 resid_len, struct fchs_s *rsp_fchs);
57 static void bfa_fcs_rport_send_nsdisc(void *rport_cbarg,
58 struct bfa_fcxp_s *fcxp_alloced);
59 static void bfa_fcs_rport_gidpn_response(void *fcsarg,
60 struct bfa_fcxp_s *fcxp, void *cbarg,
61 bfa_status_t req_status, u32 rsp_len,
62 u32 resid_len, struct fchs_s *rsp_fchs);
63 static void bfa_fcs_rport_gpnid_response(void *fcsarg,
64 struct bfa_fcxp_s *fcxp, void *cbarg,
65 bfa_status_t req_status, u32 rsp_len,
66 u32 resid_len, struct fchs_s *rsp_fchs);
67 static void bfa_fcs_rport_send_logo(void *rport_cbarg,
68 struct bfa_fcxp_s *fcxp_alloced);
69 static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
70 static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
71 struct fchs_s *rx_fchs, u16 len);
72 static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
73 struct fchs_s *rx_fchs, u8 reason_code,
75 static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
76 struct fchs_s *rx_fchs, u16 len);
77 static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
79 * fcs_rport_sm FCS rport state machine events
83 RPSM_EVENT_PLOGI_SEND = 1, /* new rport; start with PLOGI */
84 RPSM_EVENT_PLOGI_RCVD = 2, /* Inbound PLOGI from remote port */
85 RPSM_EVENT_PLOGI_COMP = 3, /* PLOGI completed to rport */
86 RPSM_EVENT_LOGO_RCVD = 4, /* LOGO from remote device */
87 RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */
88 RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */
89 RPSM_EVENT_DELETE = 7, /* RPORT delete request */
90 RPSM_EVENT_SCN = 8, /* state change notification */
91 RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */
92 RPSM_EVENT_FAILED = 10, /* Request to rport failed. */
93 RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */
94 RPSM_EVENT_HCB_ONLINE = 12, /* BFA rport online callback */
95 RPSM_EVENT_HCB_OFFLINE = 13, /* BFA rport offline callback */
96 RPSM_EVENT_FC4_OFFLINE = 14, /* FC-4 offline complete */
97 RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */
98 RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */
99 RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */
100 RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continously */
103 static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
104 enum rport_event event);
105 static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
106 enum rport_event event);
107 static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
108 enum rport_event event);
109 static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
110 enum rport_event event);
111 static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
112 enum rport_event event);
113 static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
114 enum rport_event event);
115 static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
116 enum rport_event event);
117 static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
118 enum rport_event event);
119 static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
120 enum rport_event event);
121 static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
122 enum rport_event event);
123 static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport,
124 enum rport_event event);
125 static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
126 enum rport_event event);
127 static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
128 enum rport_event event);
129 static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
130 enum rport_event event);
131 static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
132 enum rport_event event);
133 static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
134 enum rport_event event);
135 static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
136 enum rport_event event);
137 static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
138 enum rport_event event);
139 static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
140 enum rport_event event);
141 static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
142 enum rport_event event);
143 static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
144 enum rport_event event);
145 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
146 enum rport_event event);
147 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
148 enum rport_event event);
150 static struct bfa_sm_table_s rport_sm_table[] = {
151 {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
152 {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
153 {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
154 {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
155 {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
156 {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
157 {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
158 {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
159 {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
160 {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC},
161 {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC},
162 {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
163 {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
164 {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
165 {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
166 {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
167 {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
168 {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
169 {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
170 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
171 {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
172 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
179 bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
181 bfa_trc(rport->fcs, rport->pwwn);
182 bfa_trc(rport->fcs, rport->pid);
183 bfa_trc(rport->fcs, event);
186 case RPSM_EVENT_PLOGI_SEND:
187 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
188 rport->plogi_retries = 0;
189 bfa_fcs_rport_send_plogi(rport, NULL);
192 case RPSM_EVENT_PLOGI_RCVD:
193 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
194 bfa_fcs_rport_send_plogiacc(rport, NULL);
197 case RPSM_EVENT_PLOGI_COMP:
198 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
199 bfa_fcs_rport_hal_online(rport);
202 case RPSM_EVENT_ADDRESS_CHANGE:
203 case RPSM_EVENT_ADDRESS_DISC:
204 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
205 rport->ns_retries = 0;
206 bfa_fcs_rport_send_nsdisc(rport, NULL);
209 bfa_sm_fault(rport->fcs, event);
214 * PLOGI is being sent.
217 bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
218 enum rport_event event)
220 bfa_trc(rport->fcs, rport->pwwn);
221 bfa_trc(rport->fcs, rport->pid);
222 bfa_trc(rport->fcs, event);
225 case RPSM_EVENT_FCXP_SENT:
226 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
229 case RPSM_EVENT_DELETE:
230 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
231 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
232 bfa_fcs_rport_free(rport);
235 case RPSM_EVENT_PLOGI_RCVD:
236 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
237 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
238 bfa_fcs_rport_send_plogiacc(rport, NULL);
241 case RPSM_EVENT_ADDRESS_CHANGE:
244 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
245 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
246 rport->ns_retries = 0;
247 bfa_fcs_rport_send_nsdisc(rport, NULL);
250 case RPSM_EVENT_LOGO_IMP:
252 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
253 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
254 bfa_timer_start(rport->fcs->bfa, &rport->timer,
255 bfa_fcs_rport_timeout, rport,
256 bfa_fcs_rport_del_timeout);
261 bfa_sm_fault(rport->fcs, event);
266 * PLOGI is being sent.
269 bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
270 enum rport_event event)
272 bfa_trc(rport->fcs, rport->pwwn);
273 bfa_trc(rport->fcs, rport->pid);
274 bfa_trc(rport->fcs, event);
277 case RPSM_EVENT_FCXP_SENT:
278 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
279 bfa_fcs_rport_hal_online(rport);
282 case RPSM_EVENT_DELETE:
283 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
284 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
285 bfa_fcs_rport_free(rport);
288 case RPSM_EVENT_PLOGI_RCVD:
291 * Ignore, SCN is possibly online notification.
295 case RPSM_EVENT_ADDRESS_CHANGE:
296 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
297 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
298 rport->ns_retries = 0;
299 bfa_fcs_rport_send_nsdisc(rport, NULL);
302 case RPSM_EVENT_LOGO_IMP:
304 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
305 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
306 bfa_timer_start(rport->fcs->bfa, &rport->timer,
307 bfa_fcs_rport_timeout, rport,
308 bfa_fcs_rport_del_timeout);
311 case RPSM_EVENT_HCB_OFFLINE:
313 * Ignore BFA callback, on a PLOGI receive we call bfa offline.
318 bfa_sm_fault(rport->fcs, event);
326 bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
327 enum rport_event event)
329 bfa_trc(rport->fcs, rport->pwwn);
330 bfa_trc(rport->fcs, rport->pid);
331 bfa_trc(rport->fcs, event);
334 case RPSM_EVENT_TIMEOUT:
335 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
336 bfa_fcs_rport_send_plogi(rport, NULL);
339 case RPSM_EVENT_DELETE:
340 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
341 bfa_timer_stop(&rport->timer);
342 bfa_fcs_rport_free(rport);
345 case RPSM_EVENT_PRLO_RCVD:
346 case RPSM_EVENT_LOGO_RCVD:
349 case RPSM_EVENT_PLOGI_RCVD:
350 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
351 bfa_timer_stop(&rport->timer);
352 bfa_fcs_rport_send_plogiacc(rport, NULL);
355 case RPSM_EVENT_ADDRESS_CHANGE:
357 bfa_timer_stop(&rport->timer);
358 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
359 rport->ns_retries = 0;
360 bfa_fcs_rport_send_nsdisc(rport, NULL);
363 case RPSM_EVENT_LOGO_IMP:
365 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
366 bfa_timer_stop(&rport->timer);
367 bfa_timer_start(rport->fcs->bfa, &rport->timer,
368 bfa_fcs_rport_timeout, rport,
369 bfa_fcs_rport_del_timeout);
372 case RPSM_EVENT_PLOGI_COMP:
373 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
374 bfa_timer_stop(&rport->timer);
375 bfa_fcs_rport_hal_online(rport);
379 bfa_sm_fault(rport->fcs, event);
387 bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
389 bfa_trc(rport->fcs, rport->pwwn);
390 bfa_trc(rport->fcs, rport->pid);
391 bfa_trc(rport->fcs, event);
394 case RPSM_EVENT_ACCEPTED:
395 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
396 rport->plogi_retries = 0;
397 bfa_fcs_rport_hal_online(rport);
400 case RPSM_EVENT_LOGO_RCVD:
401 bfa_fcs_rport_send_logo_acc(rport);
405 case RPSM_EVENT_PRLO_RCVD:
406 if (rport->prlo == BFA_TRUE)
407 bfa_fcs_rport_send_prlo_acc(rport);
409 bfa_fcxp_discard(rport->fcxp);
413 case RPSM_EVENT_FAILED:
414 if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
415 rport->plogi_retries++;
416 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
417 bfa_timer_start(rport->fcs->bfa, &rport->timer,
418 bfa_fcs_rport_timeout, rport,
419 BFA_FCS_RETRY_TIMEOUT);
421 bfa_stats(rport->port, rport_del_max_plogi_retry);
423 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
424 bfa_timer_start(rport->fcs->bfa, &rport->timer,
425 bfa_fcs_rport_timeout, rport,
426 bfa_fcs_rport_del_timeout);
430 case RPSM_EVENT_PLOGI_RETRY:
431 rport->plogi_retries = 0;
432 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
433 bfa_timer_start(rport->fcs->bfa, &rport->timer,
434 bfa_fcs_rport_timeout, rport,
438 case RPSM_EVENT_LOGO_IMP:
440 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
441 bfa_fcxp_discard(rport->fcxp);
442 bfa_timer_start(rport->fcs->bfa, &rport->timer,
443 bfa_fcs_rport_timeout, rport,
444 bfa_fcs_rport_del_timeout);
447 case RPSM_EVENT_ADDRESS_CHANGE:
449 bfa_fcxp_discard(rport->fcxp);
450 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
451 rport->ns_retries = 0;
452 bfa_fcs_rport_send_nsdisc(rport, NULL);
455 case RPSM_EVENT_PLOGI_RCVD:
456 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
457 bfa_fcxp_discard(rport->fcxp);
458 bfa_fcs_rport_send_plogiacc(rport, NULL);
461 case RPSM_EVENT_DELETE:
462 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
463 bfa_fcxp_discard(rport->fcxp);
464 bfa_fcs_rport_free(rport);
467 case RPSM_EVENT_PLOGI_COMP:
468 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
469 bfa_fcxp_discard(rport->fcxp);
470 bfa_fcs_rport_hal_online(rport);
474 bfa_sm_fault(rport->fcs, event);
479 * PLOGI is complete. Awaiting BFA rport online callback. FC-4s
483 bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
484 enum rport_event event)
486 bfa_trc(rport->fcs, rport->pwwn);
487 bfa_trc(rport->fcs, rport->pid);
488 bfa_trc(rport->fcs, event);
491 case RPSM_EVENT_HCB_ONLINE:
492 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
493 bfa_fcs_rport_online_action(rport);
496 case RPSM_EVENT_PRLO_RCVD:
499 case RPSM_EVENT_LOGO_RCVD:
500 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
501 bfa_rport_offline(rport->bfa_rport);
504 case RPSM_EVENT_LOGO_IMP:
505 case RPSM_EVENT_ADDRESS_CHANGE:
506 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
507 bfa_rport_offline(rport->bfa_rport);
510 case RPSM_EVENT_PLOGI_RCVD:
511 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
512 bfa_rport_offline(rport->bfa_rport);
513 bfa_fcs_rport_send_plogiacc(rport, NULL);
516 case RPSM_EVENT_DELETE:
517 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
518 bfa_rport_offline(rport->bfa_rport);
524 * Ignore SCN - PLOGI just completed, FC-4 login should detect
530 bfa_sm_fault(rport->fcs, event);
535 * Rport is ONLINE. FC-4s active.
538 bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
540 bfa_trc(rport->fcs, rport->pwwn);
541 bfa_trc(rport->fcs, rport->pid);
542 bfa_trc(rport->fcs, event);
546 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
547 bfa_sm_set_state(rport,
548 bfa_fcs_rport_sm_nsquery_sending);
549 rport->ns_retries = 0;
550 bfa_fcs_rport_send_nsdisc(rport, NULL);
552 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
553 bfa_fcs_rport_send_adisc(rport, NULL);
557 case RPSM_EVENT_PLOGI_RCVD:
558 case RPSM_EVENT_LOGO_IMP:
559 case RPSM_EVENT_ADDRESS_CHANGE:
560 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
561 bfa_fcs_rport_offline_action(rport);
564 case RPSM_EVENT_DELETE:
565 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
566 bfa_fcs_rport_offline_action(rport);
569 case RPSM_EVENT_LOGO_RCVD:
570 case RPSM_EVENT_PRLO_RCVD:
571 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
572 bfa_fcs_rport_offline_action(rport);
575 case RPSM_EVENT_PLOGI_COMP:
579 bfa_sm_fault(rport->fcs, event);
584 * An SCN event is received in ONLINE state. NS query is being sent
585 * prior to ADISC authentication with rport. FC-4s are paused.
588 bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
589 enum rport_event event)
591 bfa_trc(rport->fcs, rport->pwwn);
592 bfa_trc(rport->fcs, rport->pid);
593 bfa_trc(rport->fcs, event);
596 case RPSM_EVENT_FCXP_SENT:
597 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
600 case RPSM_EVENT_DELETE:
601 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
602 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
603 bfa_fcs_rport_offline_action(rport);
608 * ignore SCN, wait for response to query itself
612 case RPSM_EVENT_LOGO_RCVD:
613 case RPSM_EVENT_PRLO_RCVD:
614 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
615 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
616 bfa_fcs_rport_offline_action(rport);
619 case RPSM_EVENT_LOGO_IMP:
621 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
622 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
623 bfa_timer_start(rport->fcs->bfa, &rport->timer,
624 bfa_fcs_rport_timeout, rport,
625 bfa_fcs_rport_del_timeout);
628 case RPSM_EVENT_PLOGI_RCVD:
629 case RPSM_EVENT_ADDRESS_CHANGE:
630 case RPSM_EVENT_PLOGI_COMP:
631 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
632 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
633 bfa_fcs_rport_offline_action(rport);
637 bfa_sm_fault(rport->fcs, event);
642 * An SCN event is received in ONLINE state. NS query is sent to rport.
646 bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
648 bfa_trc(rport->fcs, rport->pwwn);
649 bfa_trc(rport->fcs, rport->pid);
650 bfa_trc(rport->fcs, event);
653 case RPSM_EVENT_ACCEPTED:
654 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
655 bfa_fcs_rport_send_adisc(rport, NULL);
658 case RPSM_EVENT_FAILED:
660 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
661 bfa_sm_set_state(rport,
662 bfa_fcs_rport_sm_nsquery_sending);
663 bfa_fcs_rport_send_nsdisc(rport, NULL);
665 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
666 bfa_fcs_rport_offline_action(rport);
670 case RPSM_EVENT_DELETE:
671 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
672 bfa_fcxp_discard(rport->fcxp);
673 bfa_fcs_rport_offline_action(rport);
679 case RPSM_EVENT_LOGO_RCVD:
680 case RPSM_EVENT_PRLO_RCVD:
681 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
682 bfa_fcxp_discard(rport->fcxp);
683 bfa_fcs_rport_offline_action(rport);
686 case RPSM_EVENT_PLOGI_COMP:
687 case RPSM_EVENT_ADDRESS_CHANGE:
688 case RPSM_EVENT_PLOGI_RCVD:
689 case RPSM_EVENT_LOGO_IMP:
690 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
691 bfa_fcxp_discard(rport->fcxp);
692 bfa_fcs_rport_offline_action(rport);
696 bfa_sm_fault(rport->fcs, event);
701 * An SCN event is received in ONLINE state. ADISC is being sent for
702 * authenticating with rport. FC-4s are paused.
705 bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
706 enum rport_event event)
708 bfa_trc(rport->fcs, rport->pwwn);
709 bfa_trc(rport->fcs, rport->pid);
710 bfa_trc(rport->fcs, event);
713 case RPSM_EVENT_FCXP_SENT:
714 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc);
717 case RPSM_EVENT_DELETE:
718 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
719 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
720 bfa_fcs_rport_offline_action(rport);
723 case RPSM_EVENT_LOGO_IMP:
724 case RPSM_EVENT_ADDRESS_CHANGE:
725 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
726 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
727 bfa_fcs_rport_offline_action(rport);
730 case RPSM_EVENT_LOGO_RCVD:
731 case RPSM_EVENT_PRLO_RCVD:
732 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
733 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
734 bfa_fcs_rport_offline_action(rport);
740 case RPSM_EVENT_PLOGI_RCVD:
741 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
742 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
743 bfa_fcs_rport_offline_action(rport);
747 bfa_sm_fault(rport->fcs, event);
752 * An SCN event is received in ONLINE state. ADISC is to rport.
756 bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
758 bfa_trc(rport->fcs, rport->pwwn);
759 bfa_trc(rport->fcs, rport->pid);
760 bfa_trc(rport->fcs, event);
763 case RPSM_EVENT_ACCEPTED:
764 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
767 case RPSM_EVENT_PLOGI_RCVD:
769 * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
770 * At least go offline when a PLOGI is received.
772 bfa_fcxp_discard(rport->fcxp);
774 * !!! fall through !!!
777 case RPSM_EVENT_FAILED:
778 case RPSM_EVENT_ADDRESS_CHANGE:
779 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
780 bfa_fcs_rport_offline_action(rport);
783 case RPSM_EVENT_DELETE:
784 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
785 bfa_fcxp_discard(rport->fcxp);
786 bfa_fcs_rport_offline_action(rport);
791 * already processing RSCN
795 case RPSM_EVENT_LOGO_IMP:
796 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
797 bfa_fcxp_discard(rport->fcxp);
798 bfa_fcs_rport_offline_action(rport);
801 case RPSM_EVENT_LOGO_RCVD:
802 case RPSM_EVENT_PRLO_RCVD:
803 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
804 bfa_fcxp_discard(rport->fcxp);
805 bfa_fcs_rport_offline_action(rport);
809 bfa_sm_fault(rport->fcs, event);
814 * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
817 bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
818 enum rport_event event)
820 bfa_trc(rport->fcs, rport->pwwn);
821 bfa_trc(rport->fcs, rport->pid);
822 bfa_trc(rport->fcs, event);
825 case RPSM_EVENT_FC4_OFFLINE:
826 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
827 bfa_rport_offline(rport->bfa_rport);
830 case RPSM_EVENT_DELETE:
831 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
834 case RPSM_EVENT_LOGO_RCVD:
835 case RPSM_EVENT_PRLO_RCVD:
836 case RPSM_EVENT_ADDRESS_CHANGE:
840 bfa_sm_fault(rport->fcs, event);
845 * LOGO needs to be sent to rport. Awaiting FC-4 offline completion
849 bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
850 enum rport_event event)
852 bfa_trc(rport->fcs, rport->pwwn);
853 bfa_trc(rport->fcs, rport->pid);
854 bfa_trc(rport->fcs, event);
857 case RPSM_EVENT_FC4_OFFLINE:
858 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
859 bfa_rport_offline(rport->bfa_rport);
863 bfa_sm_fault(rport->fcs, event);
868 * Rport is going offline. Awaiting FC-4 offline completion callback.
871 bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
872 enum rport_event event)
874 bfa_trc(rport->fcs, rport->pwwn);
875 bfa_trc(rport->fcs, rport->pid);
876 bfa_trc(rport->fcs, event);
879 case RPSM_EVENT_FC4_OFFLINE:
880 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
881 bfa_rport_offline(rport->bfa_rport);
885 case RPSM_EVENT_LOGO_IMP:
886 case RPSM_EVENT_LOGO_RCVD:
887 case RPSM_EVENT_PRLO_RCVD:
888 case RPSM_EVENT_ADDRESS_CHANGE:
890 * rport is already going offline.
891 * SCN - ignore and wait till transitioning to offline state
895 case RPSM_EVENT_DELETE:
896 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
900 bfa_sm_fault(rport->fcs, event);
905 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
909 bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
910 enum rport_event event)
912 bfa_trc(rport->fcs, rport->pwwn);
913 bfa_trc(rport->fcs, rport->pid);
914 bfa_trc(rport->fcs, event);
917 case RPSM_EVENT_HCB_OFFLINE:
918 case RPSM_EVENT_ADDRESS_CHANGE:
919 if (bfa_fcs_lport_is_online(rport->port)) {
920 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
921 bfa_sm_set_state(rport,
922 bfa_fcs_rport_sm_nsdisc_sending);
923 rport->ns_retries = 0;
924 bfa_fcs_rport_send_nsdisc(rport, NULL);
926 bfa_sm_set_state(rport,
927 bfa_fcs_rport_sm_plogi_sending);
928 rport->plogi_retries = 0;
929 bfa_fcs_rport_send_plogi(rport, NULL);
933 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
934 bfa_timer_start(rport->fcs->bfa, &rport->timer,
935 bfa_fcs_rport_timeout, rport,
936 bfa_fcs_rport_del_timeout);
940 case RPSM_EVENT_DELETE:
941 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
942 bfa_fcs_rport_free(rport);
946 case RPSM_EVENT_LOGO_RCVD:
947 case RPSM_EVENT_PRLO_RCVD:
949 * Ignore, already offline.
954 bfa_sm_fault(rport->fcs, event);
959 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
960 * callback to send LOGO accept.
963 bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
964 enum rport_event event)
966 bfa_trc(rport->fcs, rport->pwwn);
967 bfa_trc(rport->fcs, rport->pid);
968 bfa_trc(rport->fcs, event);
971 case RPSM_EVENT_HCB_OFFLINE:
972 case RPSM_EVENT_ADDRESS_CHANGE:
973 if (rport->pid && (rport->prlo == BFA_TRUE))
974 bfa_fcs_rport_send_prlo_acc(rport);
975 if (rport->pid && (rport->prlo == BFA_FALSE))
976 bfa_fcs_rport_send_logo_acc(rport);
978 * If the lport is online and if the rport is not a well
979 * known address port,
980 * we try to re-discover the r-port.
982 if (bfa_fcs_lport_is_online(rport->port) &&
983 (!BFA_FCS_PID_IS_WKA(rport->pid))) {
984 bfa_sm_set_state(rport,
985 bfa_fcs_rport_sm_nsdisc_sending);
986 rport->ns_retries = 0;
987 bfa_fcs_rport_send_nsdisc(rport, NULL);
990 * if it is not a well known address, reset the
993 if (!BFA_FCS_PID_IS_WKA(rport->pid))
995 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
996 bfa_timer_start(rport->fcs->bfa, &rport->timer,
997 bfa_fcs_rport_timeout, rport,
998 bfa_fcs_rport_del_timeout);
1002 case RPSM_EVENT_DELETE:
1003 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
1006 case RPSM_EVENT_LOGO_IMP:
1007 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1010 case RPSM_EVENT_LOGO_RCVD:
1011 case RPSM_EVENT_PRLO_RCVD:
1013 * Ignore - already processing a LOGO.
1018 bfa_sm_fault(rport->fcs, event);
1023 * Rport is being deleted. FC-4s are offline.
1024 * Awaiting BFA rport offline
1025 * callback to send LOGO.
1028 bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1029 enum rport_event event)
1031 bfa_trc(rport->fcs, rport->pwwn);
1032 bfa_trc(rport->fcs, rport->pid);
1033 bfa_trc(rport->fcs, event);
1036 case RPSM_EVENT_HCB_OFFLINE:
1037 bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
1038 bfa_fcs_rport_send_logo(rport, NULL);
1041 case RPSM_EVENT_LOGO_RCVD:
1042 case RPSM_EVENT_PRLO_RCVD:
1043 case RPSM_EVENT_ADDRESS_CHANGE:
1047 bfa_sm_fault(rport->fcs, event);
1052 * Rport is being deleted. FC-4s are offline. LOGO is being sent.
1055 bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1056 enum rport_event event)
1058 bfa_trc(rport->fcs, rport->pwwn);
1059 bfa_trc(rport->fcs, rport->pid);
1060 bfa_trc(rport->fcs, event);
1063 case RPSM_EVENT_FCXP_SENT:
1064 /* Once LOGO is sent, we donot wait for the response */
1065 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1066 bfa_fcs_rport_free(rport);
1069 case RPSM_EVENT_SCN:
1070 case RPSM_EVENT_ADDRESS_CHANGE:
1073 case RPSM_EVENT_LOGO_RCVD:
1074 case RPSM_EVENT_PRLO_RCVD:
1075 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1076 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1077 bfa_fcs_rport_free(rport);
1081 bfa_sm_fault(rport->fcs, event);
1086 * Rport is offline. FC-4s are offline. BFA rport is offline.
1087 * Timer active to delete stale rport.
1090 bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1092 bfa_trc(rport->fcs, rport->pwwn);
1093 bfa_trc(rport->fcs, rport->pid);
1094 bfa_trc(rport->fcs, event);
1097 case RPSM_EVENT_TIMEOUT:
1098 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1099 bfa_fcs_rport_free(rport);
1102 case RPSM_EVENT_SCN:
1103 case RPSM_EVENT_ADDRESS_CHANGE:
1104 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1105 bfa_timer_stop(&rport->timer);
1106 rport->ns_retries = 0;
1107 bfa_fcs_rport_send_nsdisc(rport, NULL);
1110 case RPSM_EVENT_DELETE:
1111 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1112 bfa_timer_stop(&rport->timer);
1113 bfa_fcs_rport_free(rport);
1116 case RPSM_EVENT_PLOGI_RCVD:
1117 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1118 bfa_timer_stop(&rport->timer);
1119 bfa_fcs_rport_send_plogiacc(rport, NULL);
1122 case RPSM_EVENT_LOGO_RCVD:
1123 case RPSM_EVENT_PRLO_RCVD:
1124 case RPSM_EVENT_LOGO_IMP:
1127 case RPSM_EVENT_PLOGI_COMP:
1128 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1129 bfa_timer_stop(&rport->timer);
1130 bfa_fcs_rport_hal_online(rport);
1133 case RPSM_EVENT_PLOGI_SEND:
1134 bfa_timer_stop(&rport->timer);
1135 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1136 rport->plogi_retries = 0;
1137 bfa_fcs_rport_send_plogi(rport, NULL);
1141 bfa_sm_fault(rport->fcs, event);
1146 * Rport address has changed. Nameserver discovery request is being sent.
1149 bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1150 enum rport_event event)
1152 bfa_trc(rport->fcs, rport->pwwn);
1153 bfa_trc(rport->fcs, rport->pid);
1154 bfa_trc(rport->fcs, event);
1157 case RPSM_EVENT_FCXP_SENT:
1158 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent);
1161 case RPSM_EVENT_DELETE:
1162 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1163 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1164 bfa_fcs_rport_free(rport);
1167 case RPSM_EVENT_PLOGI_RCVD:
1168 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1169 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1170 bfa_fcs_rport_send_plogiacc(rport, NULL);
1173 case RPSM_EVENT_SCN:
1174 case RPSM_EVENT_LOGO_RCVD:
1175 case RPSM_EVENT_PRLO_RCVD:
1176 case RPSM_EVENT_PLOGI_SEND:
1179 case RPSM_EVENT_ADDRESS_CHANGE:
1180 rport->ns_retries = 0; /* reset the retry count */
1183 case RPSM_EVENT_LOGO_IMP:
1184 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1185 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1186 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1187 bfa_fcs_rport_timeout, rport,
1188 bfa_fcs_rport_del_timeout);
1191 case RPSM_EVENT_PLOGI_COMP:
1192 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1193 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1194 bfa_fcs_rport_hal_online(rport);
1198 bfa_sm_fault(rport->fcs, event);
1203 * Nameserver discovery failed. Waiting for timeout to retry.
1206 bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1207 enum rport_event event)
1209 bfa_trc(rport->fcs, rport->pwwn);
1210 bfa_trc(rport->fcs, rport->pid);
1211 bfa_trc(rport->fcs, event);
1214 case RPSM_EVENT_TIMEOUT:
1215 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1216 bfa_fcs_rport_send_nsdisc(rport, NULL);
1219 case RPSM_EVENT_SCN:
1220 case RPSM_EVENT_ADDRESS_CHANGE:
1221 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1222 bfa_timer_stop(&rport->timer);
1223 rport->ns_retries = 0;
1224 bfa_fcs_rport_send_nsdisc(rport, NULL);
1227 case RPSM_EVENT_DELETE:
1228 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1229 bfa_timer_stop(&rport->timer);
1230 bfa_fcs_rport_free(rport);
1233 case RPSM_EVENT_PLOGI_RCVD:
1234 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1235 bfa_timer_stop(&rport->timer);
1236 bfa_fcs_rport_send_plogiacc(rport, NULL);
1239 case RPSM_EVENT_LOGO_IMP:
1241 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1242 bfa_timer_stop(&rport->timer);
1243 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1244 bfa_fcs_rport_timeout, rport,
1245 bfa_fcs_rport_del_timeout);
1248 case RPSM_EVENT_LOGO_RCVD:
1249 bfa_fcs_rport_send_logo_acc(rport);
1251 case RPSM_EVENT_PRLO_RCVD:
1252 bfa_fcs_rport_send_prlo_acc(rport);
1255 case RPSM_EVENT_PLOGI_COMP:
1256 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1257 bfa_timer_stop(&rport->timer);
1258 bfa_fcs_rport_hal_online(rport);
1262 bfa_sm_fault(rport->fcs, event);
1267 * Rport address has changed. Nameserver discovery request is sent.
1270 bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1271 enum rport_event event)
1273 bfa_trc(rport->fcs, rport->pwwn);
1274 bfa_trc(rport->fcs, rport->pid);
1275 bfa_trc(rport->fcs, event);
1278 case RPSM_EVENT_ACCEPTED:
1279 case RPSM_EVENT_ADDRESS_CHANGE:
1281 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1282 bfa_fcs_rport_send_plogi(rport, NULL);
1284 bfa_sm_set_state(rport,
1285 bfa_fcs_rport_sm_nsdisc_sending);
1286 rport->ns_retries = 0;
1287 bfa_fcs_rport_send_nsdisc(rport, NULL);
1291 case RPSM_EVENT_FAILED:
1292 rport->ns_retries++;
1293 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
1294 bfa_sm_set_state(rport,
1295 bfa_fcs_rport_sm_nsdisc_sending);
1296 bfa_fcs_rport_send_nsdisc(rport, NULL);
1299 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1300 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1301 bfa_fcs_rport_timeout, rport,
1302 bfa_fcs_rport_del_timeout);
1306 case RPSM_EVENT_DELETE:
1307 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1308 bfa_fcxp_discard(rport->fcxp);
1309 bfa_fcs_rport_free(rport);
1312 case RPSM_EVENT_PLOGI_RCVD:
1313 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1314 bfa_fcxp_discard(rport->fcxp);
1315 bfa_fcs_rport_send_plogiacc(rport, NULL);
1318 case RPSM_EVENT_LOGO_IMP:
1320 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1321 bfa_fcxp_discard(rport->fcxp);
1322 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1323 bfa_fcs_rport_timeout, rport,
1324 bfa_fcs_rport_del_timeout);
1328 case RPSM_EVENT_PRLO_RCVD:
1329 bfa_fcs_rport_send_prlo_acc(rport);
1331 case RPSM_EVENT_SCN:
1333 * ignore, wait for NS query response
1337 case RPSM_EVENT_LOGO_RCVD:
1339 * Not logged-in yet. Accept LOGO.
1341 bfa_fcs_rport_send_logo_acc(rport);
1344 case RPSM_EVENT_PLOGI_COMP:
1345 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1346 bfa_fcxp_discard(rport->fcxp);
1347 bfa_fcs_rport_hal_online(rport);
1351 bfa_sm_fault(rport->fcs, event);
1358 * fcs_rport_private FCS RPORT provate functions
1362 bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1364 struct bfa_fcs_rport_s *rport = rport_cbarg;
1365 struct bfa_fcs_lport_s *port = rport->port;
1368 struct bfa_fcxp_s *fcxp;
1370 bfa_trc(rport->fcs, rport->pwwn);
1372 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1374 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1375 bfa_fcs_rport_send_plogi, rport);
1380 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1381 bfa_fcs_lport_get_fcid(port), 0,
1382 port->port_cfg.pwwn, port->port_cfg.nwwn,
1383 bfa_fcport_get_maxfrsize(port->fcs->bfa));
1385 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1386 FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
1387 (void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1389 rport->stats.plogis++;
1390 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1394 bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1395 bfa_status_t req_status, u32 rsp_len,
1396 u32 resid_len, struct fchs_s *rsp_fchs)
1398 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1399 struct fc_logi_s *plogi_rsp;
1400 struct fc_ls_rjt_s *ls_rjt;
1401 struct bfa_fcs_rport_s *twin;
1402 struct list_head *qe;
1404 bfa_trc(rport->fcs, rport->pwwn);
1409 if (req_status != BFA_STATUS_OK) {
1410 bfa_trc(rport->fcs, req_status);
1411 rport->stats.plogi_failed++;
1412 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1416 plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
1419 * Check for failure first.
1421 if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
1422 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
1424 bfa_trc(rport->fcs, ls_rjt->reason_code);
1425 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1427 if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) &&
1428 (ls_rjt->reason_code_expl == FC_LS_RJT_EXP_INSUFF_RES)) {
1429 rport->stats.rjt_insuff_res++;
1430 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RETRY);
1434 rport->stats.plogi_rejects++;
1435 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1440 * PLOGI is complete. Make sure this device is not one of the known
1441 * device with a new FC port address.
1443 list_for_each(qe, &rport->port->rport_q) {
1444 twin = (struct bfa_fcs_rport_s *) qe;
1447 if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
1448 bfa_trc(rport->fcs, twin->pid);
1449 bfa_trc(rport->fcs, rport->pid);
1451 /* Update plogi stats in twin */
1452 twin->stats.plogis += rport->stats.plogis;
1453 twin->stats.plogi_rejects +=
1454 rport->stats.plogi_rejects;
1455 twin->stats.plogi_timeouts +=
1456 rport->stats.plogi_timeouts;
1457 twin->stats.plogi_failed +=
1458 rport->stats.plogi_failed;
1459 twin->stats.plogi_rcvd += rport->stats.plogi_rcvd;
1460 twin->stats.plogi_accs++;
1462 bfa_fcs_rport_delete(rport);
1464 bfa_fcs_rport_update(twin, plogi_rsp);
1465 twin->pid = rsp_fchs->s_id;
1466 bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP);
1472 * Normal login path -- no evil twins.
1474 rport->stats.plogi_accs++;
1475 bfa_fcs_rport_update(rport, plogi_rsp);
1476 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1480 bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1482 struct bfa_fcs_rport_s *rport = rport_cbarg;
1483 struct bfa_fcs_lport_s *port = rport->port;
1486 struct bfa_fcxp_s *fcxp;
1488 bfa_trc(rport->fcs, rport->pwwn);
1489 bfa_trc(rport->fcs, rport->reply_oxid);
1491 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1493 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1494 bfa_fcs_rport_send_plogiacc, rport);
1499 len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1500 rport->pid, bfa_fcs_lport_get_fcid(port),
1501 rport->reply_oxid, port->port_cfg.pwwn,
1502 port->port_cfg.nwwn,
1503 bfa_fcport_get_maxfrsize(port->fcs->bfa));
1505 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1506 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1508 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1512 bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1514 struct bfa_fcs_rport_s *rport = rport_cbarg;
1515 struct bfa_fcs_lport_s *port = rport->port;
1518 struct bfa_fcxp_s *fcxp;
1520 bfa_trc(rport->fcs, rport->pwwn);
1522 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1524 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1525 bfa_fcs_rport_send_adisc, rport);
1530 len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1531 bfa_fcs_lport_get_fcid(port), 0,
1532 port->port_cfg.pwwn, port->port_cfg.nwwn);
1534 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1535 FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
1536 rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1538 rport->stats.adisc_sent++;
1539 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1543 bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1544 bfa_status_t req_status, u32 rsp_len,
1545 u32 resid_len, struct fchs_s *rsp_fchs)
1547 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1548 void *pld = bfa_fcxp_get_rspbuf(fcxp);
1549 struct fc_ls_rjt_s *ls_rjt;
1551 if (req_status != BFA_STATUS_OK) {
1552 bfa_trc(rport->fcs, req_status);
1553 rport->stats.adisc_failed++;
1554 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1558 if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
1559 rport->nwwn) == FC_PARSE_OK) {
1560 rport->stats.adisc_accs++;
1561 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1565 rport->stats.adisc_rejects++;
1567 bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
1568 bfa_trc(rport->fcs, ls_rjt->reason_code);
1569 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1570 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1574 bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1576 struct bfa_fcs_rport_s *rport = rport_cbarg;
1577 struct bfa_fcs_lport_s *port = rport->port;
1579 struct bfa_fcxp_s *fcxp;
1581 bfa_cb_fcxp_send_t cbfn;
1583 bfa_trc(rport->fcs, rport->pid);
1585 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1587 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1588 bfa_fcs_rport_send_nsdisc, rport);
1594 len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1595 bfa_fcs_lport_get_fcid(port), 0, rport->pwwn);
1596 cbfn = bfa_fcs_rport_gidpn_response;
1598 len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1599 bfa_fcs_lport_get_fcid(port), 0, rport->pid);
1600 cbfn = bfa_fcs_rport_gpnid_response;
1603 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1604 FC_CLASS_3, len, &fchs, cbfn,
1605 (void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV);
1607 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1611 bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1612 bfa_status_t req_status, u32 rsp_len,
1613 u32 resid_len, struct fchs_s *rsp_fchs)
1615 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1616 struct ct_hdr_s *cthdr;
1617 struct fcgs_gidpn_resp_s *gidpn_rsp;
1618 struct bfa_fcs_rport_s *twin;
1619 struct list_head *qe;
1621 bfa_trc(rport->fcs, rport->pwwn);
1623 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1624 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1626 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1627 /* Check if the pid is the same as before. */
1628 gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
1630 if (gidpn_rsp->dap == rport->pid) {
1631 /* Device is online */
1632 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1635 * Device's PID has changed. We need to cleanup
1636 * and re-login. If there is another device with
1637 * the the newly discovered pid, send an scn notice
1638 * so that its new pid can be discovered.
1640 list_for_each(qe, &rport->port->rport_q) {
1641 twin = (struct bfa_fcs_rport_s *) qe;
1644 if (gidpn_rsp->dap == twin->pid) {
1645 bfa_trc(rport->fcs, twin->pid);
1646 bfa_trc(rport->fcs, rport->pid);
1649 bfa_sm_send_event(twin,
1650 RPSM_EVENT_ADDRESS_CHANGE);
1653 rport->pid = gidpn_rsp->dap;
1654 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE);
1662 switch (cthdr->reason_code) {
1663 case CT_RSN_LOGICAL_BUSY:
1667 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1670 case CT_RSN_UNABLE_TO_PERF:
1672 * device doesn't exist : Start timer to cleanup this later.
1674 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1678 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1684 bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1685 bfa_status_t req_status, u32 rsp_len,
1686 u32 resid_len, struct fchs_s *rsp_fchs)
1688 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1689 struct ct_hdr_s *cthdr;
1691 bfa_trc(rport->fcs, rport->pwwn);
1693 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1694 cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1696 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1697 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1704 switch (cthdr->reason_code) {
1705 case CT_RSN_LOGICAL_BUSY:
1709 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1712 case CT_RSN_UNABLE_TO_PERF:
1714 * device doesn't exist : Start timer to cleanup this later.
1716 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1720 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1726 * Called to send a logout to the rport.
1729 bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1731 struct bfa_fcs_rport_s *rport = rport_cbarg;
1732 struct bfa_fcs_lport_s *port;
1734 struct bfa_fcxp_s *fcxp;
1737 bfa_trc(rport->fcs, rport->pid);
1741 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1743 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1744 bfa_fcs_rport_send_logo, rport);
1749 len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1750 bfa_fcs_lport_get_fcid(port), 0,
1751 bfa_fcs_lport_get_pwwn(port));
1753 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1754 FC_CLASS_3, len, &fchs, NULL,
1755 rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1757 rport->stats.logos++;
1758 bfa_fcxp_discard(rport->fcxp);
1759 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1763 * Send ACC for a LOGO received.
1766 bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
1768 struct bfa_fcs_rport_s *rport = rport_cbarg;
1769 struct bfa_fcs_lport_s *port;
1771 struct bfa_fcxp_s *fcxp;
1774 bfa_trc(rport->fcs, rport->pid);
1778 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1782 rport->stats.logo_rcvd++;
1783 len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1784 rport->pid, bfa_fcs_lport_get_fcid(port),
1787 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1788 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1793 * This routine will be called by bfa_timer on timer timeouts.
1795 * param[in] rport - pointer to bfa_fcs_lport_ns_t.
1796 * param[out] rport_status - pointer to return vport status in
1801 * Special Considerations:
1806 bfa_fcs_rport_timeout(void *arg)
1808 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg;
1810 rport->stats.plogi_timeouts++;
1811 bfa_stats(rport->port, rport_plogi_timeouts);
1812 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1816 bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
1817 struct fchs_s *rx_fchs, u16 len)
1819 struct bfa_fcxp_s *fcxp;
1821 struct bfa_fcs_lport_s *port = rport->port;
1822 struct fc_prli_s *prli;
1824 bfa_trc(port->fcs, rx_fchs->s_id);
1825 bfa_trc(port->fcs, rx_fchs->d_id);
1827 rport->stats.prli_rcvd++;
1830 * We are in Initiator Mode
1832 prli = (struct fc_prli_s *) (rx_fchs + 1);
1834 if (prli->parampage.servparams.target) {
1836 * PRLI from a target ?
1838 * PRLI sent by us will be used to transition the IT nexus,
1839 * once the response is received from the target.
1841 bfa_trc(port->fcs, rx_fchs->s_id);
1842 rport->scsi_function = BFA_RPORT_TARGET;
1844 bfa_trc(rport->fcs, prli->parampage.type);
1845 rport->scsi_function = BFA_RPORT_INITIATOR;
1846 bfa_fcs_itnim_is_initiator(rport->itnim);
1849 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1853 len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1854 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
1855 rx_fchs->ox_id, port->port_cfg.roles);
1857 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1858 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1862 bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
1863 struct fchs_s *rx_fchs, u16 len)
1865 struct bfa_fcxp_s *fcxp;
1867 struct bfa_fcs_lport_s *port = rport->port;
1868 struct fc_rpsc_speed_info_s speeds;
1869 struct bfa_port_attr_s pport_attr;
1871 bfa_trc(port->fcs, rx_fchs->s_id);
1872 bfa_trc(port->fcs, rx_fchs->d_id);
1874 rport->stats.rpsc_rcvd++;
1875 speeds.port_speed_cap =
1876 RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G |
1880 * get curent speed from pport attributes from BFA
1882 bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
1884 speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
1886 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1890 len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1891 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
1892 rx_fchs->ox_id, &speeds);
1894 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1895 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1899 bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
1900 struct fchs_s *rx_fchs, u16 len)
1902 struct bfa_fcxp_s *fcxp;
1904 struct bfa_fcs_lport_s *port = rport->port;
1905 struct fc_adisc_s *adisc;
1907 bfa_trc(port->fcs, rx_fchs->s_id);
1908 bfa_trc(port->fcs, rx_fchs->d_id);
1910 rport->stats.adisc_rcvd++;
1912 adisc = (struct fc_adisc_s *) (rx_fchs + 1);
1915 * Accept if the itnim for this rport is online.
1916 * Else reject the ADISC.
1918 if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
1920 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1924 len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1925 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
1926 rx_fchs->ox_id, port->port_cfg.pwwn,
1927 port->port_cfg.nwwn);
1929 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
1930 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
1933 rport->stats.adisc_rejected++;
1934 bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
1935 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
1936 FC_LS_RJT_EXP_LOGIN_REQUIRED);
1941 bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
1943 struct bfa_fcs_lport_s *port = rport->port;
1944 struct bfa_rport_info_s rport_info;
1946 rport_info.pid = rport->pid;
1947 rport_info.local_pid = port->pid;
1948 rport_info.lp_tag = port->lp_tag;
1949 rport_info.vf_id = port->fabric->vf_id;
1950 rport_info.vf_en = port->fabric->is_vf;
1951 rport_info.fc_class = rport->fc_cos;
1952 rport_info.cisc = rport->cisc;
1953 rport_info.max_frmsz = rport->maxfrsize;
1954 bfa_rport_online(rport->bfa_rport, &rport_info);
1957 static struct bfa_fcs_rport_s *
1958 bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
1960 struct bfa_fcs_s *fcs = port->fcs;
1961 struct bfa_fcs_rport_s *rport;
1962 struct bfad_rport_s *rport_drv;
1967 if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
1978 rport->rp_drv = rport_drv;
1983 * allocate BFA rport
1985 rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport);
1986 if (!rport->bfa_rport) {
1995 bfa_assert(bfa_fcs_lport_is_initiator(port));
1997 if (bfa_fcs_lport_is_initiator(port)) {
1998 rport->itnim = bfa_fcs_itnim_create(rport);
1999 if (!rport->itnim) {
2001 bfa_rport_delete(rport->bfa_rport);
2007 bfa_fcs_lport_add_rport(port, rport);
2009 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
2011 /* Initialize the Rport Features(RPF) Sub Module */
2012 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2013 bfa_fcs_rpf_init(rport);
2020 bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
2022 struct bfa_fcs_lport_s *port = rport->port;
2026 * - delete BFA rport
2027 * - remove from queue of rports
2029 if (bfa_fcs_lport_is_initiator(port)) {
2030 bfa_fcs_itnim_delete(rport->itnim);
2031 if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid))
2032 bfa_fcs_rpf_rport_offline(rport);
2035 bfa_rport_delete(rport->bfa_rport);
2036 bfa_fcs_lport_del_rport(port, rport);
2037 kfree(rport->rp_drv);
2041 bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
2043 struct bfa_fcs_lport_s *port = rport->port;
2044 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2045 char lpwwn_buf[BFA_STRING_32];
2046 char rpwwn_buf[BFA_STRING_32];
2048 rport->stats.onlines++;
2050 if (bfa_fcs_lport_is_initiator(port)) {
2051 bfa_fcs_itnim_rport_online(rport->itnim);
2052 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2053 bfa_fcs_rpf_rport_online(rport);
2056 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2057 wwn2str(rpwwn_buf, rport->pwwn);
2058 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2059 BFA_LOG(KERN_INFO, bfad, log_level,
2060 "Remote port (WWN = %s) online for logical port (WWN = %s)\n",
2061 rpwwn_buf, lpwwn_buf);
2065 bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
2067 struct bfa_fcs_lport_s *port = rport->port;
2068 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2069 char lpwwn_buf[BFA_STRING_32];
2070 char rpwwn_buf[BFA_STRING_32];
2072 rport->stats.offlines++;
2074 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2075 wwn2str(rpwwn_buf, rport->pwwn);
2076 if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2077 if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE)
2078 BFA_LOG(KERN_ERR, bfad, log_level,
2079 "Remote port (WWN = %s) connectivity lost for "
2080 "logical port (WWN = %s)\n",
2081 rpwwn_buf, lpwwn_buf);
2083 BFA_LOG(KERN_INFO, bfad, log_level,
2084 "Remote port (WWN = %s) offlined by "
2085 "logical port (WWN = %s)\n",
2086 rpwwn_buf, lpwwn_buf);
2089 if (bfa_fcs_lport_is_initiator(port)) {
2090 bfa_fcs_itnim_rport_offline(rport->itnim);
2091 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2092 bfa_fcs_rpf_rport_offline(rport);
2097 * Update rport parameters from PLOGI or PLOGI accept.
2100 bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2102 bfa_fcs_lport_t *port = rport->port;
2108 rport->pwwn = plogi->port_name;
2109 rport->nwwn = plogi->node_name;
2112 * - class of service
2115 if (plogi->class3.class_valid)
2116 rport->fc_cos = FC_CLASS_3;
2118 if (plogi->class2.class_valid)
2119 rport->fc_cos |= FC_CLASS_2;
2123 * - MAX receive frame size
2125 rport->cisc = plogi->csp.cisc;
2126 rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz);
2128 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2129 bfa_trc(port->fcs, port->fabric->bb_credit);
2131 * Direct Attach P2P mode :
2132 * This is to handle a bug (233476) in IBM targets in Direct Attach
2133 * Mode. Basically, in FLOGI Accept the target would have
2134 * erroneously set the BB Credit to the value used in the FLOGI
2135 * sent by the HBA. It uses the correct value (its own BB credit)
2138 if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
2139 (be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
2141 bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2142 bfa_trc(port->fcs, port->fabric->bb_credit);
2144 port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
2145 bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
2146 port->fabric->bb_credit);
2152 * Called to handle LOGO received from an existing remote port.
2155 bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
2157 rport->reply_oxid = fchs->ox_id;
2158 bfa_trc(rport->fcs, rport->reply_oxid);
2160 rport->prlo = BFA_FALSE;
2161 rport->stats.logo_rcvd++;
2162 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
2168 * fcs_rport_public FCS rport public interfaces
2172 * Called by bport/vport to create a remote port instance for a discovered
2175 * @param[in] port - base port or vport
2176 * @param[in] rpid - remote port ID
2180 struct bfa_fcs_rport_s *
2181 bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid)
2183 struct bfa_fcs_rport_s *rport;
2185 bfa_trc(port->fcs, rpid);
2186 rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
2190 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2195 * Called to create a rport for which only the wwn is known.
2197 * @param[in] port - base port
2198 * @param[in] rpwwn - remote port wwn
2202 struct bfa_fcs_rport_s *
2203 bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2205 struct bfa_fcs_rport_s *rport;
2206 bfa_trc(port->fcs, rpwwn);
2207 rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
2211 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
2215 * Called by bport in private loop topology to indicate that a
2216 * rport has been discovered and plogi has been completed.
2218 * @param[in] port - base port or vport
2219 * @param[in] rpid - remote port ID
2222 bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2223 struct fc_logi_s *plogi)
2225 struct bfa_fcs_rport_s *rport;
2227 rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
2231 bfa_fcs_rport_update(rport, plogi);
2233 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
2237 * Called by bport/vport to handle PLOGI received from a new remote port.
2238 * If an existing rport does a plogi, it will be handled separately.
2241 bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2242 struct fc_logi_s *plogi)
2244 struct bfa_fcs_rport_s *rport;
2246 rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
2250 bfa_fcs_rport_update(rport, plogi);
2252 rport->reply_oxid = fchs->ox_id;
2253 bfa_trc(rport->fcs, rport->reply_oxid);
2255 rport->stats.plogi_rcvd++;
2256 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2260 wwn_compare(wwn_t wwn1, wwn_t wwn2)
2262 u8 *b1 = (u8 *) &wwn1;
2263 u8 *b2 = (u8 *) &wwn2;
2266 for (i = 0; i < sizeof(wwn_t); i++) {
2276 * Called by bport/vport to handle PLOGI received from an existing
2280 bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2281 struct fc_logi_s *plogi)
2284 * @todo Handle P2P and initiator-initiator.
2287 bfa_fcs_rport_update(rport, plogi);
2289 rport->reply_oxid = rx_fchs->ox_id;
2290 bfa_trc(rport->fcs, rport->reply_oxid);
2293 * In Switched fabric topology,
2294 * PLOGI to each other. If our pwwn is smaller, ignore it,
2295 * if it is not a well known address.
2296 * If the link topology is N2N,
2297 * this Plogi should be accepted.
2299 if ((wwn_compare(rport->port->port_cfg.pwwn, rport->pwwn) == -1) &&
2300 (bfa_fcs_fabric_is_switched(rport->port->fabric)) &&
2301 (!BFA_FCS_PID_IS_WKA(rport->pid))) {
2302 bfa_trc(rport->fcs, rport->pid);
2306 rport->stats.plogi_rcvd++;
2307 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2311 * Called by bport/vport to delete a remote port instance.
2313 * Rport delete is called under the following conditions:
2314 * - vport is deleted
2316 * - explicit request from OS to delete rport
2319 bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport)
2321 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
2325 * Called by bport/vport to when a target goes offline.
2329 bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport)
2331 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
2335 * Called by bport in n2n when a target (attached port) becomes online.
2339 bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport)
2341 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2344 * Called by bport/vport to notify SCN for the remote port
2347 bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
2349 rport->stats.rscns++;
2350 bfa_sm_send_event(rport, RPSM_EVENT_SCN);
2354 * Called by fcpim to notify that the ITN cleanup is done.
2357 bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport)
2359 bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
2363 * Called by fcptm to notify that the ITN cleanup is done.
2366 bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport)
2368 bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
2373 * This routine BFA callback for bfa_rport_online() call.
2375 * param[in] cb_arg - rport struct.
2380 * Special Considerations:
2385 bfa_cb_rport_online(void *cbarg)
2388 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2390 bfa_trc(rport->fcs, rport->pwwn);
2391 bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
2396 * This routine BFA callback for bfa_rport_offline() call.
2403 * Special Considerations:
2408 bfa_cb_rport_offline(void *cbarg)
2410 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2412 bfa_trc(rport->fcs, rport->pwwn);
2413 bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
2418 * This routine is a static BFA callback when there is a QoS flow_id
2419 * change notification
2426 * Special Considerations:
2431 bfa_cb_rport_qos_scn_flowid(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;
2437 bfa_trc(rport->fcs, rport->pwwn);
2442 * This routine is a static BFA callback when there is a QoS priority
2443 * change notification
2450 * Special Considerations:
2455 bfa_cb_rport_qos_scn_prio(void *cbarg,
2456 struct bfa_rport_qos_attr_s old_qos_attr,
2457 struct bfa_rport_qos_attr_s new_qos_attr)
2459 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2461 bfa_trc(rport->fcs, rport->pwwn);
2465 * Called to process any unsolicted frames from this remote port
2468 bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport)
2470 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
2474 * Called to process any unsolicted frames from this remote port
2477 bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
2478 struct fchs_s *fchs, u16 len)
2480 struct bfa_fcs_lport_s *port = rport->port;
2481 struct fc_els_cmd_s *els_cmd;
2483 bfa_trc(rport->fcs, fchs->s_id);
2484 bfa_trc(rport->fcs, fchs->d_id);
2485 bfa_trc(rport->fcs, fchs->type);
2487 if (fchs->type != FC_TYPE_ELS)
2490 els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
2492 bfa_trc(rport->fcs, els_cmd->els_code);
2494 switch (els_cmd->els_code) {
2496 bfa_stats(port, plogi_rcvd);
2497 bfa_fcs_rport_process_logo(rport, fchs);
2501 bfa_stats(port, adisc_rcvd);
2502 bfa_fcs_rport_process_adisc(rport, fchs, len);
2506 bfa_stats(port, prlo_rcvd);
2507 if (bfa_fcs_lport_is_initiator(port))
2508 bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
2512 bfa_stats(port, prli_rcvd);
2513 bfa_fcs_rport_process_prli(rport, fchs, len);
2517 bfa_stats(port, rpsc_rcvd);
2518 bfa_fcs_rport_process_rpsc(rport, fchs, len);
2522 bfa_stats(port, un_handled_els_rcvd);
2523 bfa_fcs_rport_send_ls_rjt(rport, fchs,
2524 FC_LS_RJT_RSN_CMD_NOT_SUPP,
2525 FC_LS_RJT_EXP_NO_ADDL_INFO);
2530 /* send best case acc to prlo */
2532 bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
2534 struct bfa_fcs_lport_s *port = rport->port;
2536 struct bfa_fcxp_s *fcxp;
2539 bfa_trc(rport->fcs, rport->pid);
2541 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
2544 len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2545 rport->pid, bfa_fcs_lport_get_fcid(port),
2546 rport->reply_oxid, 0);
2548 bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id,
2549 port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs,
2550 NULL, NULL, FC_MAX_PDUSZ, 0);
2557 bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2558 u8 reason_code, u8 reason_code_expl)
2560 struct bfa_fcs_lport_s *port = rport->port;
2562 struct bfa_fcxp_s *fcxp;
2565 bfa_trc(rport->fcs, rx_fchs->s_id);
2567 fcxp = bfa_fcs_fcxp_alloc(rport->fcs);
2571 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2572 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2573 rx_fchs->ox_id, reason_code, reason_code_expl);
2575 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2576 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2581 * Return state of rport.
2584 bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
2586 return bfa_sm_to_state(rport_sm_table, rport->sm);
2591 * Called by the Driver to set rport delete/ageout timeout
2593 * param[in] rport timeout value in seconds.
2598 bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
2600 /* convert to Millisecs */
2602 bfa_fcs_rport_del_timeout = rport_tmo * 1000;
2605 bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, u16 ox_id)
2607 bfa_trc(rport->fcs, rport->pid);
2609 rport->prlo = BFA_TRUE;
2610 rport->reply_oxid = ox_id;
2611 bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD);
2617 * Remote port implementation.
2621 * fcs_rport_api FCS rport API.
2625 * Direct API to add a target by port wwn. This interface is used, for
2626 * example, by bios when target pwwn is known from boot lun configuration.
2629 bfa_fcs_rport_add(struct bfa_fcs_lport_s *port, wwn_t *pwwn,
2630 struct bfa_fcs_rport_s *rport, struct bfad_rport_s *rport_drv)
2632 bfa_trc(port->fcs, *pwwn);
2634 return BFA_STATUS_OK;
2638 * Direct API to remove a target and its associated resources. This
2639 * interface is used, for example, by driver to remove target
2640 * ports from the target list for a VM.
2643 bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport_in)
2646 struct bfa_fcs_rport_s *rport;
2648 bfa_trc(rport_in->fcs, rport_in->pwwn);
2650 rport = bfa_fcs_lport_get_rport_by_pwwn(rport_in->port, rport_in->pwwn);
2651 if (rport == NULL) {
2653 * TBD Error handling
2655 bfa_trc(rport_in->fcs, rport_in->pid);
2656 return BFA_STATUS_UNKNOWN_RWWN;
2660 * TBD if this remote port is online, send a logo
2662 return BFA_STATUS_OK;
2667 * Remote device status for display/debug.
2670 bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
2671 struct bfa_rport_attr_s *rport_attr)
2673 struct bfa_rport_qos_attr_s qos_attr;
2674 bfa_fcs_lport_t *port = rport->port;
2675 bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
2677 memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
2679 rport_attr->pid = rport->pid;
2680 rport_attr->pwwn = rport->pwwn;
2681 rport_attr->nwwn = rport->nwwn;
2682 rport_attr->cos_supported = rport->fc_cos;
2683 rport_attr->df_sz = rport->maxfrsize;
2684 rport_attr->state = bfa_fcs_rport_get_state(rport);
2685 rport_attr->fc_cos = rport->fc_cos;
2686 rport_attr->cisc = rport->cisc;
2687 rport_attr->scsi_function = rport->scsi_function;
2688 rport_attr->curr_speed = rport->rpf.rpsc_speed;
2689 rport_attr->assigned_speed = rport->rpf.assigned_speed;
2691 bfa_rport_get_qos_attr(rport->bfa_rport, &qos_attr);
2692 rport_attr->qos_attr = qos_attr;
2694 rport_attr->trl_enforced = BFA_FALSE;
2695 if (bfa_fcport_is_ratelim(port->fcs->bfa)) {
2696 if (rport_speed == BFA_PORT_SPEED_UNKNOWN) {
2697 /* Use default ratelim speed setting */
2699 bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
2702 if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port))
2703 rport_attr->trl_enforced = BFA_TRUE;
2708 * Per remote device statistics.
2711 bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
2712 struct bfa_rport_stats_s *stats)
2714 *stats = rport->stats;
2718 bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport)
2720 memset((char *)&rport->stats, 0,
2721 sizeof(struct bfa_rport_stats_s));
2724 struct bfa_fcs_rport_s *
2725 bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2727 struct bfa_fcs_rport_s *rport;
2729 rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
2730 if (rport == NULL) {
2732 * TBD Error handling
2739 struct bfa_fcs_rport_s *
2740 bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn)
2742 struct bfa_fcs_rport_s *rport;
2744 rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn);
2745 if (rport == NULL) {
2747 * TBD Error handling
2755 * This API is to set the Rport's speed. Should be used when RPSC is not
2756 * supported by the rport.
2759 bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport, bfa_port_speed_t speed)
2761 rport->rpf.assigned_speed = speed;
2763 /* Set this speed in f/w only if the RPSC speed is not available */
2764 if (rport->rpf.rpsc_speed == BFA_PORT_SPEED_UNKNOWN)
2765 bfa_rport_speed(rport->bfa_rport, speed);
2771 * Remote port features (RPF) implementation.
2774 #define BFA_FCS_RPF_RETRIES (3)
2775 #define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */
2777 static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
2778 struct bfa_fcxp_s *fcxp_alloced);
2779 static void bfa_fcs_rpf_rpsc2_response(void *fcsarg,
2780 struct bfa_fcxp_s *fcxp,
2782 bfa_status_t req_status,
2785 struct fchs_s *rsp_fchs);
2787 static void bfa_fcs_rpf_timeout(void *arg);
2790 * fcs_rport_ftrs_sm FCS rport state machine events
2794 RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */
2795 RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */
2796 RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */
2797 RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */
2798 RPFSM_EVENT_RPSC_COMP = 5,
2799 RPFSM_EVENT_RPSC_FAIL = 6,
2800 RPFSM_EVENT_RPSC_ERROR = 7,
2803 static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
2804 enum rpf_event event);
2805 static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
2806 enum rpf_event event);
2807 static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
2808 enum rpf_event event);
2809 static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
2810 enum rpf_event event);
2811 static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
2812 enum rpf_event event);
2813 static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
2814 enum rpf_event event);
2817 bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2819 struct bfa_fcs_rport_s *rport = rpf->rport;
2820 struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric;
2822 bfa_trc(rport->fcs, rport->pwwn);
2823 bfa_trc(rport->fcs, rport->pid);
2824 bfa_trc(rport->fcs, event);
2827 case RPFSM_EVENT_RPORT_ONLINE:
2828 /* Send RPSC2 to a Brocade fabric only. */
2829 if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
2830 ((bfa_lps_is_brcd_fabric(rport->port->fabric->lps)) ||
2831 (bfa_fcs_fabric_get_switch_oui(fabric) ==
2832 BFA_FCS_BRCD_SWITCH_OUI))) {
2833 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
2834 rpf->rpsc_retries = 0;
2835 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
2839 case RPFSM_EVENT_RPORT_OFFLINE:
2843 bfa_sm_fault(rport->fcs, event);
2848 bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2850 struct bfa_fcs_rport_s *rport = rpf->rport;
2852 bfa_trc(rport->fcs, event);
2855 case RPFSM_EVENT_FCXP_SENT:
2856 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
2859 case RPFSM_EVENT_RPORT_OFFLINE:
2860 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2861 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
2862 rpf->rpsc_retries = 0;
2866 bfa_sm_fault(rport->fcs, event);
2871 bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2873 struct bfa_fcs_rport_s *rport = rpf->rport;
2875 bfa_trc(rport->fcs, rport->pid);
2876 bfa_trc(rport->fcs, event);
2879 case RPFSM_EVENT_RPSC_COMP:
2880 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
2881 /* Update speed info in f/w via BFA */
2882 if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN)
2883 bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
2884 else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN)
2885 bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
2888 case RPFSM_EVENT_RPSC_FAIL:
2889 /* RPSC not supported by rport */
2890 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
2893 case RPFSM_EVENT_RPSC_ERROR:
2894 /* need to retry...delayed a bit. */
2895 if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
2896 bfa_timer_start(rport->fcs->bfa, &rpf->timer,
2897 bfa_fcs_rpf_timeout, rpf,
2898 BFA_FCS_RPF_RETRY_TIMEOUT);
2899 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
2901 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
2905 case RPFSM_EVENT_RPORT_OFFLINE:
2906 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2907 bfa_fcxp_discard(rpf->fcxp);
2908 rpf->rpsc_retries = 0;
2912 bfa_sm_fault(rport->fcs, event);
2917 bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2919 struct bfa_fcs_rport_s *rport = rpf->rport;
2921 bfa_trc(rport->fcs, rport->pid);
2922 bfa_trc(rport->fcs, event);
2925 case RPFSM_EVENT_TIMEOUT:
2926 /* re-send the RPSC */
2927 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
2928 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
2931 case RPFSM_EVENT_RPORT_OFFLINE:
2932 bfa_timer_stop(&rpf->timer);
2933 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2934 rpf->rpsc_retries = 0;
2938 bfa_sm_fault(rport->fcs, event);
2943 bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2945 struct bfa_fcs_rport_s *rport = rpf->rport;
2947 bfa_trc(rport->fcs, rport->pwwn);
2948 bfa_trc(rport->fcs, rport->pid);
2949 bfa_trc(rport->fcs, event);
2952 case RPFSM_EVENT_RPORT_OFFLINE:
2953 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2954 rpf->rpsc_retries = 0;
2958 bfa_sm_fault(rport->fcs, event);
2963 bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2965 struct bfa_fcs_rport_s *rport = rpf->rport;
2967 bfa_trc(rport->fcs, rport->pwwn);
2968 bfa_trc(rport->fcs, rport->pid);
2969 bfa_trc(rport->fcs, event);
2972 case RPFSM_EVENT_RPORT_ONLINE:
2973 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
2974 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
2977 case RPFSM_EVENT_RPORT_OFFLINE:
2981 bfa_sm_fault(rport->fcs, event);
2985 * Called when Rport is created.
2988 bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
2990 struct bfa_fcs_rpf_s *rpf = &rport->rpf;
2992 bfa_trc(rport->fcs, rport->pid);
2995 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
2999 * Called when Rport becomes online
3002 bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
3004 bfa_trc(rport->fcs, rport->pid);
3006 if (__fcs_min_cfg(rport->port->fcs))
3009 if (bfa_fcs_fabric_is_switched(rport->port->fabric))
3010 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
3014 * Called when Rport becomes offline
3017 bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
3019 bfa_trc(rport->fcs, rport->pid);
3021 if (__fcs_min_cfg(rport->port->fcs))
3024 rport->rpf.rpsc_speed = 0;
3025 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
3029 bfa_fcs_rpf_timeout(void *arg)
3031 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
3032 struct bfa_fcs_rport_s *rport = rpf->rport;
3034 bfa_trc(rport->fcs, rport->pid);
3035 bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT);
3039 bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3041 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
3042 struct bfa_fcs_rport_s *rport = rpf->rport;
3043 struct bfa_fcs_lport_s *port = rport->port;
3046 struct bfa_fcxp_s *fcxp;
3048 bfa_trc(rport->fcs, rport->pwwn);
3050 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3052 bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
3053 bfa_fcs_rpf_send_rpsc2, rpf);
3058 len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
3059 bfa_fcs_lport_get_fcid(port), &rport->pid, 1);
3061 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3062 FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
3063 rpf, FC_MAX_PDUSZ, FC_ELS_TOV);
3064 rport->stats.rpsc_sent++;
3065 bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
3070 bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
3071 bfa_status_t req_status, u32 rsp_len,
3072 u32 resid_len, struct fchs_s *rsp_fchs)
3074 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
3075 struct bfa_fcs_rport_s *rport = rpf->rport;
3076 struct fc_ls_rjt_s *ls_rjt;
3077 struct fc_rpsc2_acc_s *rpsc2_acc;
3080 bfa_trc(rport->fcs, req_status);
3082 if (req_status != BFA_STATUS_OK) {
3083 bfa_trc(rport->fcs, req_status);
3084 if (req_status == BFA_STATUS_ETIMER)
3085 rport->stats.rpsc_failed++;
3086 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3090 rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
3091 if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
3092 rport->stats.rpsc_accs++;
3093 num_ents = be16_to_cpu(rpsc2_acc->num_pids);
3094 bfa_trc(rport->fcs, num_ents);
3096 bfa_assert(rpsc2_acc->port_info[0].pid != rport->pid);
3098 be16_to_cpu(rpsc2_acc->port_info[0].pid));
3100 be16_to_cpu(rpsc2_acc->port_info[0].speed));
3102 be16_to_cpu(rpsc2_acc->port_info[0].index));
3104 rpsc2_acc->port_info[0].type);
3106 if (rpsc2_acc->port_info[0].speed == 0) {
3107 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3111 rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
3112 be16_to_cpu(rpsc2_acc->port_info[0].speed));
3114 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
3117 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3118 bfa_trc(rport->fcs, ls_rjt->reason_code);
3119 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
3120 rport->stats.rpsc_rejects++;
3121 if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
3122 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
3124 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);