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