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