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