[SCSI] bfa: Brocade BFA FC SCSI driver
[linux-2.6-block.git] / drivers / scsi / bfa / bfa_rport.c
1 /*
2  * Copyright (c) 2005-2009 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 #include <bfa.h>
19 #include <bfa_svc.h>
20 #include <cs/bfa_debug.h>
21 #include <bfi/bfi_rport.h>
22 #include "bfa_intr_priv.h"
23
24 BFA_TRC_FILE(HAL, RPORT);
25 BFA_MODULE(rport);
26
27 #define bfa_rport_offline_cb(__rp) do {                         \
28         if ((__rp)->bfa->fcs)                                           \
29                 bfa_cb_rport_offline((__rp)->rport_drv);      \
30         else {                                                          \
31                 bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe,              \
32                                 __bfa_cb_rport_offline, (__rp));      \
33         }                                                               \
34 } while (0)
35
36 #define bfa_rport_online_cb(__rp) do {                          \
37         if ((__rp)->bfa->fcs)                                           \
38                 bfa_cb_rport_online((__rp)->rport_drv);      \
39         else {                                                          \
40                 bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe,              \
41                                   __bfa_cb_rport_online, (__rp));      \
42                 }                                                       \
43 } while (0)
44
45 /*
46  * forward declarations
47  */
48 static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod);
49 static void bfa_rport_free(struct bfa_rport_s *rport);
50 static bfa_boolean_t bfa_rport_send_fwcreate(struct bfa_rport_s *rp);
51 static bfa_boolean_t bfa_rport_send_fwdelete(struct bfa_rport_s *rp);
52 static bfa_boolean_t bfa_rport_send_fwspeed(struct bfa_rport_s *rp);
53 static void __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete);
54 static void __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete);
55
56 /**
57  *  bfa_rport_sm BFA rport state machine
58  */
59
60
61 enum bfa_rport_event {
62         BFA_RPORT_SM_CREATE     = 1,    /*  rport create event          */
63         BFA_RPORT_SM_DELETE     = 2,    /*  deleting an existing rport */
64         BFA_RPORT_SM_ONLINE     = 3,    /*  rport is online             */
65         BFA_RPORT_SM_OFFLINE    = 4,    /*  rport is offline            */
66         BFA_RPORT_SM_FWRSP      = 5,    /*  firmware response           */
67         BFA_RPORT_SM_HWFAIL     = 6,    /*  IOC h/w failure             */
68         BFA_RPORT_SM_QOS_SCN    = 7,    /*  QoS SCN from firmware       */
69         BFA_RPORT_SM_SET_SPEED  = 8,    /*  Set Rport Speed             */
70         BFA_RPORT_SM_QRESUME    = 9,    /*  space in requeue queue      */
71 };
72
73 static void     bfa_rport_sm_uninit(struct bfa_rport_s *rp,
74                                         enum bfa_rport_event event);
75 static void     bfa_rport_sm_created(struct bfa_rport_s *rp,
76                                          enum bfa_rport_event event);
77 static void     bfa_rport_sm_fwcreate(struct bfa_rport_s *rp,
78                                           enum bfa_rport_event event);
79 static void     bfa_rport_sm_online(struct bfa_rport_s *rp,
80                                         enum bfa_rport_event event);
81 static void     bfa_rport_sm_fwdelete(struct bfa_rport_s *rp,
82                                           enum bfa_rport_event event);
83 static void     bfa_rport_sm_offline(struct bfa_rport_s *rp,
84                                          enum bfa_rport_event event);
85 static void     bfa_rport_sm_deleting(struct bfa_rport_s *rp,
86                                           enum bfa_rport_event event);
87 static void     bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
88                                           enum bfa_rport_event event);
89 static void     bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
90                                           enum bfa_rport_event event);
91 static void     bfa_rport_sm_iocdisable(struct bfa_rport_s *rp,
92                                             enum bfa_rport_event event);
93 static void     bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp,
94                                           enum bfa_rport_event event);
95 static void     bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp,
96                                           enum bfa_rport_event event);
97 static void     bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp,
98                                           enum bfa_rport_event event);
99
100 /**
101  * Beginning state, only online event expected.
102  */
103 static void
104 bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event)
105 {
106         bfa_trc(rp->bfa, rp->rport_tag);
107         bfa_trc(rp->bfa, event);
108
109         switch (event) {
110         case BFA_RPORT_SM_CREATE:
111                 bfa_stats(rp, sm_un_cr);
112                 bfa_sm_set_state(rp, bfa_rport_sm_created);
113                 break;
114
115         default:
116                 bfa_stats(rp, sm_un_unexp);
117                 bfa_assert(0);
118         }
119 }
120
121 static void
122 bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
123 {
124         bfa_trc(rp->bfa, rp->rport_tag);
125         bfa_trc(rp->bfa, event);
126
127         switch (event) {
128         case BFA_RPORT_SM_ONLINE:
129                 bfa_stats(rp, sm_cr_on);
130                 if (bfa_rport_send_fwcreate(rp))
131                         bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
132                 else
133                         bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
134                 break;
135
136         case BFA_RPORT_SM_DELETE:
137                 bfa_stats(rp, sm_cr_del);
138                 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
139                 bfa_rport_free(rp);
140                 break;
141
142         case BFA_RPORT_SM_HWFAIL:
143                 bfa_stats(rp, sm_cr_hwf);
144                 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
145                 break;
146
147         default:
148                 bfa_stats(rp, sm_cr_unexp);
149                 bfa_assert(0);
150         }
151 }
152
153 /**
154  * Waiting for rport create response from firmware.
155  */
156 static void
157 bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
158 {
159         bfa_trc(rp->bfa, rp->rport_tag);
160         bfa_trc(rp->bfa, event);
161
162         switch (event) {
163         case BFA_RPORT_SM_FWRSP:
164                 bfa_stats(rp, sm_fwc_rsp);
165                 bfa_sm_set_state(rp, bfa_rport_sm_online);
166                 bfa_rport_online_cb(rp);
167                 break;
168
169         case BFA_RPORT_SM_DELETE:
170                 bfa_stats(rp, sm_fwc_del);
171                 bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
172                 break;
173
174         case BFA_RPORT_SM_OFFLINE:
175                 bfa_stats(rp, sm_fwc_off);
176                 bfa_sm_set_state(rp, bfa_rport_sm_offline_pending);
177                 break;
178
179         case BFA_RPORT_SM_HWFAIL:
180                 bfa_stats(rp, sm_fwc_hwf);
181                 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
182                 break;
183
184         default:
185                 bfa_stats(rp, sm_fwc_unexp);
186                 bfa_assert(0);
187         }
188 }
189
190 /**
191  * Request queue is full, awaiting queue resume to send create request.
192  */
193 static void
194 bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
195 {
196         bfa_trc(rp->bfa, rp->rport_tag);
197         bfa_trc(rp->bfa, event);
198
199         switch (event) {
200         case BFA_RPORT_SM_QRESUME:
201                 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
202                 bfa_rport_send_fwcreate(rp);
203                 break;
204
205         case BFA_RPORT_SM_DELETE:
206                 bfa_stats(rp, sm_fwc_del);
207                 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
208                 bfa_reqq_wcancel(&rp->reqq_wait);
209                 bfa_rport_free(rp);
210                 break;
211
212         case BFA_RPORT_SM_OFFLINE:
213                 bfa_stats(rp, sm_fwc_off);
214                 bfa_sm_set_state(rp, bfa_rport_sm_offline);
215                 bfa_reqq_wcancel(&rp->reqq_wait);
216                 bfa_rport_offline_cb(rp);
217                 break;
218
219         case BFA_RPORT_SM_HWFAIL:
220                 bfa_stats(rp, sm_fwc_hwf);
221                 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
222                 bfa_reqq_wcancel(&rp->reqq_wait);
223                 break;
224
225         default:
226                 bfa_stats(rp, sm_fwc_unexp);
227                 bfa_assert(0);
228         }
229 }
230
231 /**
232  * Online state - normal parking state.
233  */
234 static void
235 bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
236 {
237         struct bfi_rport_qos_scn_s *qos_scn;
238
239         bfa_trc(rp->bfa, rp->rport_tag);
240         bfa_trc(rp->bfa, event);
241
242         switch (event) {
243         case BFA_RPORT_SM_OFFLINE:
244                 bfa_stats(rp, sm_on_off);
245                 if (bfa_rport_send_fwdelete(rp))
246                         bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
247                 else
248                         bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
249                 break;
250
251         case BFA_RPORT_SM_DELETE:
252                 bfa_stats(rp, sm_on_del);
253                 if (bfa_rport_send_fwdelete(rp))
254                         bfa_sm_set_state(rp, bfa_rport_sm_deleting);
255                 else
256                         bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
257                 break;
258
259         case BFA_RPORT_SM_HWFAIL:
260                 bfa_stats(rp, sm_on_hwf);
261                 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
262                 break;
263
264         case BFA_RPORT_SM_SET_SPEED:
265                 bfa_rport_send_fwspeed(rp);
266                 break;
267
268         case BFA_RPORT_SM_QOS_SCN:
269                 qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg;
270                 rp->qos_attr = qos_scn->new_qos_attr;
271                 bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id);
272                 bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id);
273                 bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority);
274                 bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority);
275
276                 qos_scn->old_qos_attr.qos_flow_id  =
277                         bfa_os_ntohl(qos_scn->old_qos_attr.qos_flow_id);
278                 qos_scn->new_qos_attr.qos_flow_id  =
279                         bfa_os_ntohl(qos_scn->new_qos_attr.qos_flow_id);
280                 qos_scn->old_qos_attr.qos_priority =
281                         bfa_os_ntohl(qos_scn->old_qos_attr.qos_priority);
282                 qos_scn->new_qos_attr.qos_priority =
283                         bfa_os_ntohl(qos_scn->new_qos_attr.qos_priority);
284
285                 if (qos_scn->old_qos_attr.qos_flow_id !=
286                         qos_scn->new_qos_attr.qos_flow_id)
287                         bfa_cb_rport_qos_scn_flowid(rp->rport_drv,
288                                                     qos_scn->old_qos_attr,
289                                                     qos_scn->new_qos_attr);
290                 if (qos_scn->old_qos_attr.qos_priority !=
291                         qos_scn->new_qos_attr.qos_priority)
292                         bfa_cb_rport_qos_scn_prio(rp->rport_drv,
293                                                   qos_scn->old_qos_attr,
294                                                   qos_scn->new_qos_attr);
295                 break;
296
297         default:
298                 bfa_stats(rp, sm_on_unexp);
299                 bfa_assert(0);
300         }
301 }
302
303 /**
304  * Firmware rport is being deleted - awaiting f/w response.
305  */
306 static void
307 bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event)
308 {
309         bfa_trc(rp->bfa, rp->rport_tag);
310         bfa_trc(rp->bfa, event);
311
312         switch (event) {
313         case BFA_RPORT_SM_FWRSP:
314                 bfa_stats(rp, sm_fwd_rsp);
315                 bfa_sm_set_state(rp, bfa_rport_sm_offline);
316                 bfa_rport_offline_cb(rp);
317                 break;
318
319         case BFA_RPORT_SM_DELETE:
320                 bfa_stats(rp, sm_fwd_del);
321                 bfa_sm_set_state(rp, bfa_rport_sm_deleting);
322                 break;
323
324         case BFA_RPORT_SM_HWFAIL:
325                 bfa_stats(rp, sm_fwd_hwf);
326                 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
327                 bfa_rport_offline_cb(rp);
328                 break;
329
330         default:
331                 bfa_stats(rp, sm_fwd_unexp);
332                 bfa_assert(0);
333         }
334 }
335
336 static void
337 bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
338 {
339         bfa_trc(rp->bfa, rp->rport_tag);
340         bfa_trc(rp->bfa, event);
341
342         switch (event) {
343         case BFA_RPORT_SM_QRESUME:
344                 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
345                 bfa_rport_send_fwdelete(rp);
346                 break;
347
348         case BFA_RPORT_SM_DELETE:
349                 bfa_stats(rp, sm_fwd_del);
350                 bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
351                 break;
352
353         case BFA_RPORT_SM_HWFAIL:
354                 bfa_stats(rp, sm_fwd_hwf);
355                 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
356                 bfa_reqq_wcancel(&rp->reqq_wait);
357                 bfa_rport_offline_cb(rp);
358                 break;
359
360         default:
361                 bfa_stats(rp, sm_fwd_unexp);
362                 bfa_assert(0);
363         }
364 }
365
366 /**
367  * Offline state.
368  */
369 static void
370 bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
371 {
372         bfa_trc(rp->bfa, rp->rport_tag);
373         bfa_trc(rp->bfa, event);
374
375         switch (event) {
376         case BFA_RPORT_SM_DELETE:
377                 bfa_stats(rp, sm_off_del);
378                 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
379                 bfa_rport_free(rp);
380                 break;
381
382         case BFA_RPORT_SM_ONLINE:
383                 bfa_stats(rp, sm_off_on);
384                 if (bfa_rport_send_fwcreate(rp))
385                         bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
386                 else
387                         bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
388                 break;
389
390         case BFA_RPORT_SM_HWFAIL:
391                 bfa_stats(rp, sm_off_hwf);
392                 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
393                 break;
394
395         default:
396                 bfa_stats(rp, sm_off_unexp);
397                 bfa_assert(0);
398         }
399 }
400
401 /**
402  * Rport is deleted, waiting for firmware response to delete.
403  */
404 static void
405 bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event)
406 {
407         bfa_trc(rp->bfa, rp->rport_tag);
408         bfa_trc(rp->bfa, event);
409
410         switch (event) {
411         case BFA_RPORT_SM_FWRSP:
412                 bfa_stats(rp, sm_del_fwrsp);
413                 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
414                 bfa_rport_free(rp);
415                 break;
416
417         case BFA_RPORT_SM_HWFAIL:
418                 bfa_stats(rp, sm_del_hwf);
419                 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
420                 bfa_rport_free(rp);
421                 break;
422
423         default:
424                 bfa_assert(0);
425         }
426 }
427
428 static void
429 bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
430 {
431         bfa_trc(rp->bfa, rp->rport_tag);
432         bfa_trc(rp->bfa, event);
433
434         switch (event) {
435         case BFA_RPORT_SM_QRESUME:
436                 bfa_stats(rp, sm_del_fwrsp);
437                 bfa_sm_set_state(rp, bfa_rport_sm_deleting);
438                 bfa_rport_send_fwdelete(rp);
439                 break;
440
441         case BFA_RPORT_SM_HWFAIL:
442                 bfa_stats(rp, sm_del_hwf);
443                 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
444                 bfa_reqq_wcancel(&rp->reqq_wait);
445                 bfa_rport_free(rp);
446                 break;
447
448         default:
449                 bfa_assert(0);
450         }
451 }
452
453 /**
454  * Waiting for rport create response from firmware. A delete is pending.
455  */
456 static void
457 bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
458                                 enum bfa_rport_event event)
459 {
460         bfa_trc(rp->bfa, rp->rport_tag);
461         bfa_trc(rp->bfa, event);
462
463         switch (event) {
464         case BFA_RPORT_SM_FWRSP:
465                 bfa_stats(rp, sm_delp_fwrsp);
466                 if (bfa_rport_send_fwdelete(rp))
467                         bfa_sm_set_state(rp, bfa_rport_sm_deleting);
468                 else
469                         bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
470                 break;
471
472         case BFA_RPORT_SM_HWFAIL:
473                 bfa_stats(rp, sm_delp_hwf);
474                 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
475                 bfa_rport_free(rp);
476                 break;
477
478         default:
479                 bfa_stats(rp, sm_delp_unexp);
480                 bfa_assert(0);
481         }
482 }
483
484 /**
485  * Waiting for rport create response from firmware. Rport offline is pending.
486  */
487 static void
488 bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
489                                  enum bfa_rport_event event)
490 {
491         bfa_trc(rp->bfa, rp->rport_tag);
492         bfa_trc(rp->bfa, event);
493
494         switch (event) {
495         case BFA_RPORT_SM_FWRSP:
496                 bfa_stats(rp, sm_offp_fwrsp);
497                 if (bfa_rport_send_fwdelete(rp))
498                         bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
499                 else
500                         bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
501                 break;
502
503         case BFA_RPORT_SM_DELETE:
504                 bfa_stats(rp, sm_offp_del);
505                 bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
506                 break;
507
508         case BFA_RPORT_SM_HWFAIL:
509                 bfa_stats(rp, sm_offp_hwf);
510                 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
511                 break;
512
513         default:
514                 bfa_stats(rp, sm_offp_unexp);
515                 bfa_assert(0);
516         }
517 }
518
519 /**
520  * IOC h/w failed.
521  */
522 static void
523 bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
524 {
525         bfa_trc(rp->bfa, rp->rport_tag);
526         bfa_trc(rp->bfa, event);
527
528         switch (event) {
529         case BFA_RPORT_SM_OFFLINE:
530                 bfa_stats(rp, sm_iocd_off);
531                 bfa_rport_offline_cb(rp);
532                 break;
533
534         case BFA_RPORT_SM_DELETE:
535                 bfa_stats(rp, sm_iocd_del);
536                 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
537                 bfa_rport_free(rp);
538                 break;
539
540         case BFA_RPORT_SM_ONLINE:
541                 bfa_stats(rp, sm_iocd_on);
542                 if (bfa_rport_send_fwcreate(rp))
543                         bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
544                 else
545                         bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
546                 break;
547
548         case BFA_RPORT_SM_HWFAIL:
549                 break;
550
551         default:
552                 bfa_stats(rp, sm_iocd_unexp);
553                 bfa_assert(0);
554         }
555 }
556
557
558
559 /**
560  *  bfa_rport_private BFA rport private functions
561  */
562
563 static void
564 __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete)
565 {
566         struct bfa_rport_s *rp = cbarg;
567
568         if (complete)
569                 bfa_cb_rport_online(rp->rport_drv);
570 }
571
572 static void
573 __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete)
574 {
575         struct bfa_rport_s *rp = cbarg;
576
577         if (complete)
578                 bfa_cb_rport_offline(rp->rport_drv);
579 }
580
581 static void
582 bfa_rport_qresume(void *cbarg)
583 {
584         struct bfa_rport_s      *rp = cbarg;
585
586         bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME);
587 }
588
589 static void
590 bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
591                 u32 *dm_len)
592 {
593         if (cfg->fwcfg.num_rports < BFA_RPORT_MIN)
594                 cfg->fwcfg.num_rports = BFA_RPORT_MIN;
595
596         *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s);
597 }
598
599 static void
600 bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
601                      struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
602 {
603         struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
604         struct bfa_rport_s *rp;
605         u16        i;
606
607         INIT_LIST_HEAD(&mod->rp_free_q);
608         INIT_LIST_HEAD(&mod->rp_active_q);
609
610         rp = (struct bfa_rport_s *) bfa_meminfo_kva(meminfo);
611         mod->rps_list = rp;
612         mod->num_rports = cfg->fwcfg.num_rports;
613
614         bfa_assert(mod->num_rports
615                    && !(mod->num_rports & (mod->num_rports - 1)));
616
617         for (i = 0; i < mod->num_rports; i++, rp++) {
618                 bfa_os_memset(rp, 0, sizeof(struct bfa_rport_s));
619                 rp->bfa = bfa;
620                 rp->rport_tag = i;
621                 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
622
623                 /**
624                  *  - is unused
625                  */
626                 if (i)
627                         list_add_tail(&rp->qe, &mod->rp_free_q);
628
629                 bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp);
630         }
631
632         /**
633          * consume memory
634          */
635         bfa_meminfo_kva(meminfo) = (u8 *) rp;
636 }
637
638 static void
639 bfa_rport_initdone(struct bfa_s *bfa)
640 {
641 }
642
643 static void
644 bfa_rport_detach(struct bfa_s *bfa)
645 {
646 }
647
648 static void
649 bfa_rport_start(struct bfa_s *bfa)
650 {
651 }
652
653 static void
654 bfa_rport_stop(struct bfa_s *bfa)
655 {
656 }
657
658 static void
659 bfa_rport_iocdisable(struct bfa_s *bfa)
660 {
661         struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
662         struct bfa_rport_s *rport;
663         struct list_head        *qe, *qen;
664
665         list_for_each_safe(qe, qen, &mod->rp_active_q) {
666                 rport = (struct bfa_rport_s *) qe;
667                 bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL);
668         }
669 }
670
671 static struct bfa_rport_s *
672 bfa_rport_alloc(struct bfa_rport_mod_s *mod)
673 {
674         struct bfa_rport_s *rport;
675
676         bfa_q_deq(&mod->rp_free_q, &rport);
677         if (rport)
678                 list_add_tail(&rport->qe, &mod->rp_active_q);
679
680         return (rport);
681 }
682
683 static void
684 bfa_rport_free(struct bfa_rport_s *rport)
685 {
686         struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa);
687
688         bfa_assert(bfa_q_is_on_q(&mod->rp_active_q, rport));
689         list_del(&rport->qe);
690         list_add_tail(&rport->qe, &mod->rp_free_q);
691 }
692
693 static bfa_boolean_t
694 bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
695 {
696         struct bfi_rport_create_req_s *m;
697
698         /**
699          * check for room in queue to send request now
700          */
701         m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
702         if (!m) {
703                 bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
704                 return BFA_FALSE;
705         }
706
707         bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ,
708                         bfa_lpuid(rp->bfa));
709         m->bfa_handle = rp->rport_tag;
710         m->max_frmsz = bfa_os_htons(rp->rport_info.max_frmsz);
711         m->pid = rp->rport_info.pid;
712         m->lp_tag = rp->rport_info.lp_tag;
713         m->local_pid = rp->rport_info.local_pid;
714         m->fc_class = rp->rport_info.fc_class;
715         m->vf_en = rp->rport_info.vf_en;
716         m->vf_id = rp->rport_info.vf_id;
717         m->cisc = rp->rport_info.cisc;
718
719         /**
720          * queue I/O message to firmware
721          */
722         bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
723         return BFA_TRUE;
724 }
725
726 static bfa_boolean_t
727 bfa_rport_send_fwdelete(struct bfa_rport_s *rp)
728 {
729         struct bfi_rport_delete_req_s *m;
730
731         /**
732          * check for room in queue to send request now
733          */
734         m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
735         if (!m) {
736                 bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
737                 return BFA_FALSE;
738         }
739
740         bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ,
741                         bfa_lpuid(rp->bfa));
742         m->fw_handle = rp->fw_handle;
743
744         /**
745          * queue I/O message to firmware
746          */
747         bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
748         return BFA_TRUE;
749 }
750
751 static bfa_boolean_t
752 bfa_rport_send_fwspeed(struct bfa_rport_s *rp)
753 {
754         struct bfa_rport_speed_req_s *m;
755
756         /**
757          * check for room in queue to send request now
758          */
759         m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
760         if (!m) {
761                 bfa_trc(rp->bfa, rp->rport_info.speed);
762                 return BFA_FALSE;
763         }
764
765         bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ,
766                         bfa_lpuid(rp->bfa));
767         m->fw_handle = rp->fw_handle;
768         m->speed = (u8)rp->rport_info.speed;
769
770         /**
771          * queue I/O message to firmware
772          */
773         bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
774         return BFA_TRUE;
775 }
776
777
778
779 /**
780  *  bfa_rport_public
781  */
782
783 /**
784  *              Rport interrupt processing.
785  */
786 void
787 bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
788 {
789         union bfi_rport_i2h_msg_u msg;
790         struct bfa_rport_s *rp;
791
792         bfa_trc(bfa, m->mhdr.msg_id);
793
794         msg.msg = m;
795
796         switch (m->mhdr.msg_id) {
797         case BFI_RPORT_I2H_CREATE_RSP:
798                 rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle);
799                 rp->fw_handle = msg.create_rsp->fw_handle;
800                 rp->qos_attr = msg.create_rsp->qos_attr;
801                 bfa_assert(msg.create_rsp->status == BFA_STATUS_OK);
802                 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
803                 break;
804
805         case BFI_RPORT_I2H_DELETE_RSP:
806                 rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle);
807                 bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK);
808                 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
809                 break;
810
811         case BFI_RPORT_I2H_QOS_SCN:
812                 rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle);
813                 rp->event_arg.fw_msg = msg.qos_scn_evt;
814                 bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN);
815                 break;
816
817         default:
818                 bfa_trc(bfa, m->mhdr.msg_id);
819                 bfa_assert(0);
820         }
821 }
822
823
824
825 /**
826  *  bfa_rport_api
827  */
828
829 struct bfa_rport_s *
830 bfa_rport_create(struct bfa_s *bfa, void *rport_drv)
831 {
832         struct bfa_rport_s *rp;
833
834         rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa));
835
836         if (rp == NULL)
837                 return (NULL);
838
839         rp->bfa = bfa;
840         rp->rport_drv = rport_drv;
841         bfa_rport_clear_stats(rp);
842
843         bfa_assert(bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
844         bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE);
845
846         return (rp);
847 }
848
849 void
850 bfa_rport_delete(struct bfa_rport_s *rport)
851 {
852         bfa_sm_send_event(rport, BFA_RPORT_SM_DELETE);
853 }
854
855 void
856 bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
857 {
858         bfa_assert(rport_info->max_frmsz != 0);
859
860         /**
861          * Some JBODs are seen to be not setting PDU size correctly in PLOGI
862          * responses. Default to minimum size.
863          */
864         if (rport_info->max_frmsz == 0) {
865                 bfa_trc(rport->bfa, rport->rport_tag);
866                 rport_info->max_frmsz = FC_MIN_PDUSZ;
867         }
868
869         bfa_os_assign(rport->rport_info, *rport_info);
870         bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE);
871 }
872
873 void
874 bfa_rport_offline(struct bfa_rport_s *rport)
875 {
876         bfa_sm_send_event(rport, BFA_RPORT_SM_OFFLINE);
877 }
878
879 void
880 bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_pport_speed speed)
881 {
882         bfa_assert(speed != 0);
883         bfa_assert(speed != BFA_PPORT_SPEED_AUTO);
884
885         rport->rport_info.speed = speed;
886         bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
887 }
888
889 void
890 bfa_rport_get_stats(struct bfa_rport_s *rport,
891         struct bfa_rport_hal_stats_s *stats)
892 {
893         *stats = rport->stats;
894 }
895
896 void
897 bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
898                                         struct bfa_rport_qos_attr_s *qos_attr)
899 {
900         qos_attr->qos_priority  = bfa_os_ntohl(rport->qos_attr.qos_priority);
901         qos_attr->qos_flow_id  = bfa_os_ntohl(rport->qos_attr.qos_flow_id);
902
903 }
904
905 void
906 bfa_rport_clear_stats(struct bfa_rport_s *rport)
907 {
908         bfa_os_memset(&rport->stats, 0, sizeof(rport->stats));
909 }
910
911