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