[SCSI] bfa: remove all OS wrappers
[pandora-kernel.git] / drivers / scsi / bfa / bfa_ioc.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 #include "bfad_drv.h"
19 #include "bfa_ioc.h"
20 #include "bfi_ctreg.h"
21 #include "bfa_defs.h"
22 #include "bfa_defs_svc.h"
23
24 BFA_TRC_FILE(CNA, IOC);
25
26 /*
27  * IOC local definitions
28  */
29 #define BFA_IOC_TOV             3000    /* msecs */
30 #define BFA_IOC_HWSEM_TOV       500     /* msecs */
31 #define BFA_IOC_HB_TOV          500     /* msecs */
32 #define BFA_IOC_HWINIT_MAX      2
33 #define BFA_IOC_TOV_RECOVER      BFA_IOC_HB_TOV
34
35 #define bfa_ioc_timer_start(__ioc)                                      \
36         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
37                         bfa_ioc_timeout, (__ioc), BFA_IOC_TOV)
38 #define bfa_ioc_timer_stop(__ioc)   bfa_timer_stop(&(__ioc)->ioc_timer)
39
40 #define bfa_hb_timer_start(__ioc)                                       \
41         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->hb_timer,         \
42                         bfa_ioc_hb_check, (__ioc), BFA_IOC_HB_TOV)
43 #define bfa_hb_timer_stop(__ioc)        bfa_timer_stop(&(__ioc)->hb_timer)
44
45 #define BFA_DBG_FWTRC_OFF(_fn)  (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
46
47 /*
48  * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
49  */
50
51 #define bfa_ioc_firmware_lock(__ioc)                    \
52                         ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
53 #define bfa_ioc_firmware_unlock(__ioc)                  \
54                         ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
55 #define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
56 #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
57 #define bfa_ioc_notify_hbfail(__ioc)                    \
58                         ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
59
60 #ifdef BFA_IOC_IS_UEFI
61 #define bfa_ioc_is_bios_optrom(__ioc) (0)
62 #define bfa_ioc_is_uefi(__ioc) BFA_IOC_IS_UEFI
63 #else
64 #define bfa_ioc_is_bios_optrom(__ioc)   \
65         (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ)
66 #define bfa_ioc_is_uefi(__ioc) (0)
67 #endif
68
69 #define bfa_ioc_mbox_cmd_pending(__ioc)         \
70                         (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
71                         readl((__ioc)->ioc_regs.hfn_mbox_cmd))
72
73 bfa_boolean_t bfa_auto_recover = BFA_TRUE;
74
75 /*
76  * forward declarations
77  */
78 static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
79 static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
80 static void bfa_ioc_timeout(void *ioc);
81 static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc);
82 static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc);
83 static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc);
84 static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc);
85 static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
86 static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
87 static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
88 static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc);
89 static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
90 static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
91 static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc);
92
93
94 /*
95  * IOC state machine definitions/declarations
96  */
97 enum ioc_event {
98         IOC_E_RESET             = 1,    /*  IOC reset request           */
99         IOC_E_ENABLE            = 2,    /*  IOC enable request          */
100         IOC_E_DISABLE           = 3,    /*  IOC disable request */
101         IOC_E_DETACH            = 4,    /*  driver detach cleanup       */
102         IOC_E_ENABLED           = 5,    /*  f/w enabled         */
103         IOC_E_FWRSP_GETATTR     = 6,    /*  IOC get attribute response  */
104         IOC_E_DISABLED          = 7,    /*  f/w disabled                */
105         IOC_E_FAILED            = 8,    /*  failure notice by iocpf sm  */
106         IOC_E_HBFAIL            = 9,    /*  heartbeat failure           */
107         IOC_E_HWERROR           = 10,   /*  hardware error interrupt    */
108         IOC_E_TIMEOUT           = 11,   /*  timeout                     */
109 };
110
111 bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event);
112 bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
113 bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
114 bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
115 bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
116 bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc_s, enum ioc_event);
117 bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event);
118 bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
119 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
120
121 static struct bfa_sm_table_s ioc_sm_table[] = {
122         {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
123         {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
124         {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING},
125         {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
126         {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
127         {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL},
128         {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
129         {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
130         {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
131 };
132
133 /*
134  * IOCPF state machine definitions/declarations
135  */
136
137 #define bfa_iocpf_timer_start(__ioc)                                    \
138         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
139                         bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV)
140 #define bfa_iocpf_timer_stop(__ioc)     bfa_timer_stop(&(__ioc)->ioc_timer)
141
142 #define bfa_iocpf_recovery_timer_start(__ioc)                           \
143         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
144                         bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV_RECOVER)
145
146 #define bfa_sem_timer_start(__ioc)                                      \
147         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->sem_timer,        \
148                         bfa_iocpf_sem_timeout, (__ioc), BFA_IOC_HWSEM_TOV)
149 #define bfa_sem_timer_stop(__ioc)       bfa_timer_stop(&(__ioc)->sem_timer)
150
151 /*
152  * Forward declareations for iocpf state machine
153  */
154 static void bfa_iocpf_timeout(void *ioc_arg);
155 static void bfa_iocpf_sem_timeout(void *ioc_arg);
156
157 /*
158  * IOCPF state machine events
159  */
160 enum iocpf_event {
161         IOCPF_E_ENABLE          = 1,    /*  IOCPF enable request        */
162         IOCPF_E_DISABLE         = 2,    /*  IOCPF disable request       */
163         IOCPF_E_STOP            = 3,    /*  stop on driver detach       */
164         IOCPF_E_FWREADY         = 4,    /*  f/w initialization done     */
165         IOCPF_E_FWRSP_ENABLE    = 5,    /*  enable f/w response */
166         IOCPF_E_FWRSP_DISABLE   = 6,    /*  disable f/w response        */
167         IOCPF_E_FAIL            = 7,    /*  failure notice by ioc sm    */
168         IOCPF_E_INITFAIL        = 8,    /*  init fail notice by ioc sm  */
169         IOCPF_E_GETATTRFAIL     = 9,    /*  init fail notice by ioc sm  */
170         IOCPF_E_SEMLOCKED       = 10,   /*  h/w semaphore is locked     */
171         IOCPF_E_TIMEOUT         = 11,   /*  f/w response timeout        */
172 };
173
174 /*
175  * IOCPF states
176  */
177 enum bfa_iocpf_state {
178         BFA_IOCPF_RESET         = 1,    /*  IOC is in reset state */
179         BFA_IOCPF_SEMWAIT       = 2,    /*  Waiting for IOC h/w semaphore */
180         BFA_IOCPF_HWINIT        = 3,    /*  IOC h/w is being initialized */
181         BFA_IOCPF_READY         = 4,    /*  IOCPF is initialized */
182         BFA_IOCPF_INITFAIL      = 5,    /*  IOCPF failed */
183         BFA_IOCPF_FAIL          = 6,    /*  IOCPF failed */
184         BFA_IOCPF_DISABLING     = 7,    /*  IOCPF is being disabled */
185         BFA_IOCPF_DISABLED      = 8,    /*  IOCPF is disabled */
186         BFA_IOCPF_FWMISMATCH    = 9,    /*  IOC f/w different from drivers */
187 };
188
189 bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf_s, enum iocpf_event);
190 bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf_s, enum iocpf_event);
191 bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf_s, enum iocpf_event);
192 bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf_s, enum iocpf_event);
193 bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf_s, enum iocpf_event);
194 bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf_s, enum iocpf_event);
195 bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf_s, enum iocpf_event);
196 bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf_s, enum iocpf_event);
197 bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf_s, enum iocpf_event);
198 bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf_s, enum iocpf_event);
199 bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf_s, enum iocpf_event);
200
201 static struct bfa_sm_table_s iocpf_sm_table[] = {
202         {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET},
203         {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH},
204         {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH},
205         {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT},
206         {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT},
207         {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT},
208         {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY},
209         {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL},
210         {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL},
211         {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING},
212         {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED},
213 };
214
215 /*
216  * IOC State Machine
217  */
218
219 /*
220  * Beginning state. IOC uninit state.
221  */
222
223 static void
224 bfa_ioc_sm_uninit_entry(struct bfa_ioc_s *ioc)
225 {
226 }
227
228 /*
229  * IOC is in uninit state.
230  */
231 static void
232 bfa_ioc_sm_uninit(struct bfa_ioc_s *ioc, enum ioc_event event)
233 {
234         bfa_trc(ioc, event);
235
236         switch (event) {
237         case IOC_E_RESET:
238                 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
239                 break;
240
241         default:
242                 bfa_sm_fault(ioc, event);
243         }
244 }
245 /*
246  * Reset entry actions -- initialize state machine
247  */
248 static void
249 bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc)
250 {
251         bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset);
252 }
253
254 /*
255  * IOC is in reset state.
256  */
257 static void
258 bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event)
259 {
260         bfa_trc(ioc, event);
261
262         switch (event) {
263         case IOC_E_ENABLE:
264                 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
265                 break;
266
267         case IOC_E_DISABLE:
268                 bfa_ioc_disable_comp(ioc);
269                 break;
270
271         case IOC_E_DETACH:
272                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
273                 break;
274
275         default:
276                 bfa_sm_fault(ioc, event);
277         }
278 }
279
280
281 static void
282 bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
283 {
284         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE);
285 }
286
287 /*
288  * Host IOC function is being enabled, awaiting response from firmware.
289  * Semaphore is acquired.
290  */
291 static void
292 bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
293 {
294         bfa_trc(ioc, event);
295
296         switch (event) {
297         case IOC_E_ENABLED:
298                 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
299                 break;
300
301         case IOC_E_FAILED:
302                 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
303                 break;
304
305         case IOC_E_HWERROR:
306                 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
307                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
308                 break;
309
310         case IOC_E_DISABLE:
311                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
312                 break;
313
314         case IOC_E_DETACH:
315                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
316                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
317                 break;
318
319         case IOC_E_ENABLE:
320                 break;
321
322         default:
323                 bfa_sm_fault(ioc, event);
324         }
325 }
326
327
328 static void
329 bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc)
330 {
331         bfa_ioc_timer_start(ioc);
332         bfa_ioc_send_getattr(ioc);
333 }
334
335 /*
336  * IOC configuration in progress. Timer is active.
337  */
338 static void
339 bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
340 {
341         bfa_trc(ioc, event);
342
343         switch (event) {
344         case IOC_E_FWRSP_GETATTR:
345                 bfa_ioc_timer_stop(ioc);
346                 bfa_ioc_check_attr_wwns(ioc);
347                 bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
348                 break;
349
350         case IOC_E_FAILED:
351                 bfa_ioc_timer_stop(ioc);
352                 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
353                 break;
354
355         case IOC_E_HWERROR:
356                 bfa_ioc_timer_stop(ioc);
357                 /* fall through */
358
359         case IOC_E_TIMEOUT:
360                 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
361                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
362                 break;
363
364         case IOC_E_DISABLE:
365                 bfa_ioc_timer_stop(ioc);
366                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
367                 break;
368
369         case IOC_E_ENABLE:
370                 break;
371
372         default:
373                 bfa_sm_fault(ioc, event);
374         }
375 }
376
377
378 static void
379 bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
380 {
381         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
382
383         ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
384         bfa_ioc_hb_monitor(ioc);
385         BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
386 }
387
388 static void
389 bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
390 {
391         bfa_trc(ioc, event);
392
393         switch (event) {
394         case IOC_E_ENABLE:
395                 break;
396
397         case IOC_E_DISABLE:
398                 bfa_hb_timer_stop(ioc);
399                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
400                 break;
401
402         case IOC_E_FAILED:
403                 bfa_hb_timer_stop(ioc);
404                 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
405                 break;
406
407         case IOC_E_HWERROR:
408                 bfa_hb_timer_stop(ioc);
409                 /* !!! fall through !!! */
410
411         case IOC_E_HBFAIL:
412                 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
413                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
414                 break;
415
416         default:
417                 bfa_sm_fault(ioc, event);
418         }
419 }
420
421
422 static void
423 bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
424 {
425         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
426         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
427         BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n");
428 }
429
430 /*
431  * IOC is being disabled
432  */
433 static void
434 bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
435 {
436         bfa_trc(ioc, event);
437
438         switch (event) {
439         case IOC_E_DISABLED:
440                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
441                 break;
442
443         case IOC_E_HWERROR:
444                 /*
445                  * No state change.  Will move to disabled state
446                  * after iocpf sm completes failure processing and
447                  * moves to disabled state.
448                  */
449                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
450                 break;
451
452         default:
453                 bfa_sm_fault(ioc, event);
454         }
455 }
456
457 /*
458  * IOC disable completion entry.
459  */
460 static void
461 bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc)
462 {
463         bfa_ioc_disable_comp(ioc);
464 }
465
466 static void
467 bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
468 {
469         bfa_trc(ioc, event);
470
471         switch (event) {
472         case IOC_E_ENABLE:
473                 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
474                 break;
475
476         case IOC_E_DISABLE:
477                 ioc->cbfn->disable_cbfn(ioc->bfa);
478                 break;
479
480         case IOC_E_DETACH:
481                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
482                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
483                 break;
484
485         default:
486                 bfa_sm_fault(ioc, event);
487         }
488 }
489
490
491 static void
492 bfa_ioc_sm_initfail_entry(struct bfa_ioc_s *ioc)
493 {
494         ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
495 }
496
497 /*
498  * Hardware initialization failed.
499  */
500 static void
501 bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
502 {
503         bfa_trc(ioc, event);
504
505         switch (event) {
506         case IOC_E_ENABLED:
507                 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
508                 break;
509
510         case IOC_E_FAILED:
511                 /*
512                  * Initialization failure during iocpf init retry.
513                  */
514                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
515                 break;
516
517         case IOC_E_DISABLE:
518                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
519                 break;
520
521         case IOC_E_DETACH:
522                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
523                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
524                 break;
525
526         default:
527                 bfa_sm_fault(ioc, event);
528         }
529 }
530
531
532 static void
533 bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc)
534 {
535         struct list_head                        *qe;
536         struct bfa_ioc_hbfail_notify_s  *notify;
537         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
538
539         /*
540          * Notify driver and common modules registered for notification.
541          */
542         ioc->cbfn->hbfail_cbfn(ioc->bfa);
543         list_for_each(qe, &ioc->hb_notify_q) {
544                 notify = (struct bfa_ioc_hbfail_notify_s *) qe;
545                 notify->cbfn(notify->cbarg);
546         }
547
548         BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
549                 "Heart Beat of IOC has failed\n");
550 }
551
552 /*
553  * IOC failure.
554  */
555 static void
556 bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
557 {
558         bfa_trc(ioc, event);
559
560         switch (event) {
561
562         case IOC_E_FAILED:
563                 /*
564                  * Initialization failure during iocpf recovery.
565                  * !!! Fall through !!!
566                  */
567         case IOC_E_ENABLE:
568                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
569                 break;
570
571         case IOC_E_ENABLED:
572                 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
573                 break;
574
575         case IOC_E_DISABLE:
576                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
577                 break;
578
579         case IOC_E_HWERROR:
580                 /*
581                  * HB failure notification, ignore.
582                  */
583                 break;
584         default:
585                 bfa_sm_fault(ioc, event);
586         }
587 }
588
589
590
591 /*
592  * IOCPF State Machine
593  */
594
595
596 /*
597  * Reset entry actions -- initialize state machine
598  */
599 static void
600 bfa_iocpf_sm_reset_entry(struct bfa_iocpf_s *iocpf)
601 {
602         iocpf->retry_count = 0;
603         iocpf->auto_recover = bfa_auto_recover;
604 }
605
606 /*
607  * Beginning state. IOC is in reset state.
608  */
609 static void
610 bfa_iocpf_sm_reset(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
611 {
612         struct bfa_ioc_s *ioc = iocpf->ioc;
613
614         bfa_trc(ioc, event);
615
616         switch (event) {
617         case IOCPF_E_ENABLE:
618                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
619                 break;
620
621         case IOCPF_E_STOP:
622                 break;
623
624         default:
625                 bfa_sm_fault(ioc, event);
626         }
627 }
628
629 /*
630  * Semaphore should be acquired for version check.
631  */
632 static void
633 bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf)
634 {
635         bfa_ioc_hw_sem_get(iocpf->ioc);
636 }
637
638 /*
639  * Awaiting h/w semaphore to continue with version check.
640  */
641 static void
642 bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
643 {
644         struct bfa_ioc_s *ioc = iocpf->ioc;
645
646         bfa_trc(ioc, event);
647
648         switch (event) {
649         case IOCPF_E_SEMLOCKED:
650                 if (bfa_ioc_firmware_lock(ioc)) {
651                         iocpf->retry_count = 0;
652                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
653                 } else {
654                         writel(1, ioc->ioc_regs.ioc_sem_reg);
655                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch);
656                 }
657                 break;
658
659         case IOCPF_E_DISABLE:
660                 bfa_sem_timer_stop(ioc);
661                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
662                 bfa_fsm_send_event(ioc, IOC_E_DISABLED);
663                 break;
664
665         case IOCPF_E_STOP:
666                 bfa_sem_timer_stop(ioc);
667                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
668                 break;
669
670         default:
671                 bfa_sm_fault(ioc, event);
672         }
673 }
674
675 /*
676  * Notify enable completion callback.
677  */
678 static void
679 bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf_s *iocpf)
680 {
681         /*
682          * Call only the first time sm enters fwmismatch state.
683          */
684         if (iocpf->retry_count == 0)
685                 bfa_ioc_pf_fwmismatch(iocpf->ioc);
686
687         iocpf->retry_count++;
688         bfa_iocpf_timer_start(iocpf->ioc);
689 }
690
691 /*
692  * Awaiting firmware version match.
693  */
694 static void
695 bfa_iocpf_sm_mismatch(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
696 {
697         struct bfa_ioc_s *ioc = iocpf->ioc;
698
699         bfa_trc(ioc, event);
700
701         switch (event) {
702         case IOCPF_E_TIMEOUT:
703                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
704                 break;
705
706         case IOCPF_E_DISABLE:
707                 bfa_iocpf_timer_stop(ioc);
708                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
709                 bfa_fsm_send_event(ioc, IOC_E_DISABLED);
710                 break;
711
712         case IOCPF_E_STOP:
713                 bfa_iocpf_timer_stop(ioc);
714                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
715                 break;
716
717         default:
718                 bfa_sm_fault(ioc, event);
719         }
720 }
721
722 /*
723  * Request for semaphore.
724  */
725 static void
726 bfa_iocpf_sm_semwait_entry(struct bfa_iocpf_s *iocpf)
727 {
728         bfa_ioc_hw_sem_get(iocpf->ioc);
729 }
730
731 /*
732  * Awaiting semaphore for h/w initialzation.
733  */
734 static void
735 bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
736 {
737         struct bfa_ioc_s *ioc = iocpf->ioc;
738
739         bfa_trc(ioc, event);
740
741         switch (event) {
742         case IOCPF_E_SEMLOCKED:
743                 iocpf->retry_count = 0;
744                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
745                 break;
746
747         case IOCPF_E_DISABLE:
748                 bfa_sem_timer_stop(ioc);
749                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
750                 break;
751
752         default:
753                 bfa_sm_fault(ioc, event);
754         }
755 }
756
757
758 static void
759 bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf)
760 {
761         bfa_iocpf_timer_start(iocpf->ioc);
762         bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE);
763 }
764
765 /*
766  * Hardware is being initialized. Interrupts are enabled.
767  * Holding hardware semaphore lock.
768  */
769 static void
770 bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
771 {
772         struct bfa_ioc_s *ioc = iocpf->ioc;
773
774         bfa_trc(ioc, event);
775
776         switch (event) {
777         case IOCPF_E_FWREADY:
778                 bfa_iocpf_timer_stop(ioc);
779                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling);
780                 break;
781
782         case IOCPF_E_INITFAIL:
783                 bfa_iocpf_timer_stop(ioc);
784                 /*
785                  * !!! fall through !!!
786                  */
787
788         case IOCPF_E_TIMEOUT:
789                 iocpf->retry_count++;
790                 if (iocpf->retry_count < BFA_IOC_HWINIT_MAX) {
791                         bfa_iocpf_timer_start(ioc);
792                         bfa_ioc_hwinit(ioc, BFA_TRUE);
793                         break;
794                 }
795
796                 writel(1, ioc->ioc_regs.ioc_sem_reg);
797                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
798
799                 if (event == IOCPF_E_TIMEOUT)
800                         bfa_fsm_send_event(ioc, IOC_E_FAILED);
801                 break;
802
803         case IOCPF_E_DISABLE:
804                 writel(1, ioc->ioc_regs.ioc_sem_reg);
805                 bfa_iocpf_timer_stop(ioc);
806                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
807                 break;
808
809         default:
810                 bfa_sm_fault(ioc, event);
811         }
812 }
813
814
815 static void
816 bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf)
817 {
818         bfa_iocpf_timer_start(iocpf->ioc);
819         bfa_ioc_send_enable(iocpf->ioc);
820 }
821
822 /*
823  * Host IOC function is being enabled, awaiting response from firmware.
824  * Semaphore is acquired.
825  */
826 static void
827 bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
828 {
829         struct bfa_ioc_s *ioc = iocpf->ioc;
830
831         bfa_trc(ioc, event);
832
833         switch (event) {
834         case IOCPF_E_FWRSP_ENABLE:
835                 bfa_iocpf_timer_stop(ioc);
836                 writel(1, ioc->ioc_regs.ioc_sem_reg);
837                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready);
838                 break;
839
840         case IOCPF_E_INITFAIL:
841                 bfa_iocpf_timer_stop(ioc);
842                 /*
843                  * !!! fall through !!!
844                  */
845
846         case IOCPF_E_TIMEOUT:
847                 iocpf->retry_count++;
848                 if (iocpf->retry_count < BFA_IOC_HWINIT_MAX) {
849                         writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
850                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
851                         break;
852                 }
853
854                 writel(1, ioc->ioc_regs.ioc_sem_reg);
855                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
856
857                 if (event == IOCPF_E_TIMEOUT)
858                         bfa_fsm_send_event(ioc, IOC_E_FAILED);
859                 break;
860
861         case IOCPF_E_DISABLE:
862                 bfa_iocpf_timer_stop(ioc);
863                 writel(1, ioc->ioc_regs.ioc_sem_reg);
864                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
865                 break;
866
867         case IOCPF_E_FWREADY:
868                 bfa_ioc_send_enable(ioc);
869                 break;
870
871         default:
872                 bfa_sm_fault(ioc, event);
873         }
874 }
875
876
877
878 static void
879 bfa_iocpf_sm_ready_entry(struct bfa_iocpf_s *iocpf)
880 {
881         bfa_fsm_send_event(iocpf->ioc, IOC_E_ENABLED);
882 }
883
884 static void
885 bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
886 {
887         struct bfa_ioc_s *ioc = iocpf->ioc;
888
889         bfa_trc(ioc, event);
890
891         switch (event) {
892         case IOCPF_E_DISABLE:
893                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
894                 break;
895
896         case IOCPF_E_GETATTRFAIL:
897                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
898                 break;
899
900         case IOCPF_E_FAIL:
901                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
902                 break;
903
904         case IOCPF_E_FWREADY:
905                 if (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op))
906                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
907                 else
908                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
909
910                 bfa_fsm_send_event(ioc, IOC_E_FAILED);
911                 break;
912
913         default:
914                 bfa_sm_fault(ioc, event);
915         }
916 }
917
918
919 static void
920 bfa_iocpf_sm_disabling_entry(struct bfa_iocpf_s *iocpf)
921 {
922         bfa_iocpf_timer_start(iocpf->ioc);
923         bfa_ioc_send_disable(iocpf->ioc);
924 }
925
926 /*
927  * IOC is being disabled
928  */
929 static void
930 bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
931 {
932         struct bfa_ioc_s *ioc = iocpf->ioc;
933
934         bfa_trc(ioc, event);
935
936         switch (event) {
937         case IOCPF_E_FWRSP_DISABLE:
938         case IOCPF_E_FWREADY:
939                 bfa_iocpf_timer_stop(ioc);
940                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
941                 break;
942
943         case IOCPF_E_FAIL:
944                 bfa_iocpf_timer_stop(ioc);
945                 /*
946                  * !!! fall through !!!
947                  */
948
949         case IOCPF_E_TIMEOUT:
950                 writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
951                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
952                 break;
953
954         case IOCPF_E_FWRSP_ENABLE:
955                 break;
956
957         default:
958                 bfa_sm_fault(ioc, event);
959         }
960 }
961
962 /*
963  * IOC disable completion entry.
964  */
965 static void
966 bfa_iocpf_sm_disabled_entry(struct bfa_iocpf_s *iocpf)
967 {
968         bfa_fsm_send_event(iocpf->ioc, IOC_E_DISABLED);
969 }
970
971 static void
972 bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
973 {
974         struct bfa_ioc_s *ioc = iocpf->ioc;
975
976         bfa_trc(ioc, event);
977
978         switch (event) {
979         case IOCPF_E_ENABLE:
980                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
981                 break;
982
983         case IOCPF_E_STOP:
984                 bfa_ioc_firmware_unlock(ioc);
985                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
986                 break;
987
988         default:
989                 bfa_sm_fault(ioc, event);
990         }
991 }
992
993
994 static void
995 bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf)
996 {
997         bfa_iocpf_timer_start(iocpf->ioc);
998 }
999
1000 /*
1001  * Hardware initialization failed.
1002  */
1003 static void
1004 bfa_iocpf_sm_initfail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1005 {
1006         struct bfa_ioc_s *ioc = iocpf->ioc;
1007
1008         bfa_trc(ioc, event);
1009
1010         switch (event) {
1011         case IOCPF_E_DISABLE:
1012                 bfa_iocpf_timer_stop(ioc);
1013                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1014                 break;
1015
1016         case IOCPF_E_STOP:
1017                 bfa_iocpf_timer_stop(ioc);
1018                 bfa_ioc_firmware_unlock(ioc);
1019                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
1020                 break;
1021
1022         case IOCPF_E_TIMEOUT:
1023                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
1024                 break;
1025
1026         default:
1027                 bfa_sm_fault(ioc, event);
1028         }
1029 }
1030
1031
1032 static void
1033 bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
1034 {
1035         /*
1036          * Mark IOC as failed in hardware and stop firmware.
1037          */
1038         bfa_ioc_lpu_stop(iocpf->ioc);
1039         writel(BFI_IOC_FAIL, iocpf->ioc->ioc_regs.ioc_fwstate);
1040
1041         /*
1042          * Notify other functions on HB failure.
1043          */
1044         bfa_ioc_notify_hbfail(iocpf->ioc);
1045
1046         /*
1047          * Flush any queued up mailbox requests.
1048          */
1049         bfa_ioc_mbox_hbfail(iocpf->ioc);
1050
1051         if (iocpf->auto_recover)
1052                 bfa_iocpf_recovery_timer_start(iocpf->ioc);
1053 }
1054
1055 /*
1056  * IOC is in failed state.
1057  */
1058 static void
1059 bfa_iocpf_sm_fail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1060 {
1061         struct bfa_ioc_s *ioc = iocpf->ioc;
1062
1063         bfa_trc(ioc, event);
1064
1065         switch (event) {
1066         case IOCPF_E_DISABLE:
1067                 if (iocpf->auto_recover)
1068                         bfa_iocpf_timer_stop(ioc);
1069                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1070                 break;
1071
1072         case IOCPF_E_TIMEOUT:
1073                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
1074                 break;
1075
1076         default:
1077                 bfa_sm_fault(ioc, event);
1078         }
1079 }
1080
1081
1082
1083 /*
1084  *  BFA IOC private functions
1085  */
1086
1087 static void
1088 bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
1089 {
1090         struct list_head                        *qe;
1091         struct bfa_ioc_hbfail_notify_s  *notify;
1092
1093         ioc->cbfn->disable_cbfn(ioc->bfa);
1094
1095         /*
1096          * Notify common modules registered for notification.
1097          */
1098         list_for_each(qe, &ioc->hb_notify_q) {
1099                 notify = (struct bfa_ioc_hbfail_notify_s *) qe;
1100                 notify->cbfn(notify->cbarg);
1101         }
1102 }
1103
1104 bfa_boolean_t
1105 bfa_ioc_sem_get(void __iomem *sem_reg)
1106 {
1107         u32 r32;
1108         int cnt = 0;
1109 #define BFA_SEM_SPINCNT 3000
1110
1111         r32 = readl(sem_reg);
1112
1113         while (r32 && (cnt < BFA_SEM_SPINCNT)) {
1114                 cnt++;
1115                 udelay(2);
1116                 r32 = readl(sem_reg);
1117         }
1118
1119         if (r32 == 0)
1120                 return BFA_TRUE;
1121
1122         bfa_assert(cnt < BFA_SEM_SPINCNT);
1123         return BFA_FALSE;
1124 }
1125
1126
1127 static void
1128 bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
1129 {
1130         u32     r32;
1131
1132         /*
1133          * First read to the semaphore register will return 0, subsequent reads
1134          * will return 1. Semaphore is released by writing 1 to the register
1135          */
1136         r32 = readl(ioc->ioc_regs.ioc_sem_reg);
1137         if (r32 == 0) {
1138                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED);
1139                 return;
1140         }
1141
1142         bfa_sem_timer_start(ioc);
1143 }
1144
1145 /*
1146  * Initialize LPU local memory (aka secondary memory / SRAM)
1147  */
1148 static void
1149 bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
1150 {
1151         u32     pss_ctl;
1152         int             i;
1153 #define PSS_LMEM_INIT_TIME  10000
1154
1155         pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1156         pss_ctl &= ~__PSS_LMEM_RESET;
1157         pss_ctl |= __PSS_LMEM_INIT_EN;
1158
1159         /*
1160          * i2c workaround 12.5khz clock
1161          */
1162         pss_ctl |= __PSS_I2C_CLK_DIV(3UL);
1163         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1164
1165         /*
1166          * wait for memory initialization to be complete
1167          */
1168         i = 0;
1169         do {
1170                 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1171                 i++;
1172         } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
1173
1174         /*
1175          * If memory initialization is not successful, IOC timeout will catch
1176          * such failures.
1177          */
1178         bfa_assert(pss_ctl & __PSS_LMEM_INIT_DONE);
1179         bfa_trc(ioc, pss_ctl);
1180
1181         pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
1182         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1183 }
1184
1185 static void
1186 bfa_ioc_lpu_start(struct bfa_ioc_s *ioc)
1187 {
1188         u32     pss_ctl;
1189
1190         /*
1191          * Take processor out of reset.
1192          */
1193         pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1194         pss_ctl &= ~__PSS_LPU0_RESET;
1195
1196         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1197 }
1198
1199 static void
1200 bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
1201 {
1202         u32     pss_ctl;
1203
1204         /*
1205          * Put processors in reset.
1206          */
1207         pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1208         pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
1209
1210         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1211 }
1212
1213 /*
1214  * Get driver and firmware versions.
1215  */
1216 void
1217 bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
1218 {
1219         u32     pgnum, pgoff;
1220         u32     loff = 0;
1221         int             i;
1222         u32     *fwsig = (u32 *) fwhdr;
1223
1224         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1225         pgoff = PSS_SMEM_PGOFF(loff);
1226         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1227
1228         for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
1229              i++) {
1230                 fwsig[i] =
1231                         bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
1232                 loff += sizeof(u32);
1233         }
1234 }
1235
1236 /*
1237  * Returns TRUE if same.
1238  */
1239 bfa_boolean_t
1240 bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
1241 {
1242         struct bfi_ioc_image_hdr_s *drv_fwhdr;
1243         int i;
1244
1245         drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
1246                 bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
1247
1248         for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
1249                 if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) {
1250                         bfa_trc(ioc, i);
1251                         bfa_trc(ioc, fwhdr->md5sum[i]);
1252                         bfa_trc(ioc, drv_fwhdr->md5sum[i]);
1253                         return BFA_FALSE;
1254                 }
1255         }
1256
1257         bfa_trc(ioc, fwhdr->md5sum[0]);
1258         return BFA_TRUE;
1259 }
1260
1261 /*
1262  * Return true if current running version is valid. Firmware signature and
1263  * execution context (driver/bios) must match.
1264  */
1265 static bfa_boolean_t
1266 bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
1267 {
1268         struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr;
1269
1270         /*
1271          * If bios/efi boot (flash based) -- return true
1272          */
1273         if (bfa_ioc_is_bios_optrom(ioc))
1274                 return BFA_TRUE;
1275
1276         bfa_ioc_fwver_get(ioc, &fwhdr);
1277         drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
1278                 bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
1279
1280         if (fwhdr.signature != drv_fwhdr->signature) {
1281                 bfa_trc(ioc, fwhdr.signature);
1282                 bfa_trc(ioc, drv_fwhdr->signature);
1283                 return BFA_FALSE;
1284         }
1285
1286         if (swab32(fwhdr.param) != boot_env) {
1287                 bfa_trc(ioc, fwhdr.param);
1288                 bfa_trc(ioc, boot_env);
1289                 return BFA_FALSE;
1290         }
1291
1292         return bfa_ioc_fwver_cmp(ioc, &fwhdr);
1293 }
1294
1295 /*
1296  * Conditionally flush any pending message from firmware at start.
1297  */
1298 static void
1299 bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
1300 {
1301         u32     r32;
1302
1303         r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
1304         if (r32)
1305                 writel(1, ioc->ioc_regs.lpu_mbox_cmd);
1306 }
1307
1308
1309 static void
1310 bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1311 {
1312         enum bfi_ioc_state ioc_fwstate;
1313         bfa_boolean_t fwvalid;
1314         u32 boot_type;
1315         u32 boot_env;
1316
1317         ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
1318
1319         if (force)
1320                 ioc_fwstate = BFI_IOC_UNINIT;
1321
1322         bfa_trc(ioc, ioc_fwstate);
1323
1324         boot_type = BFI_BOOT_TYPE_NORMAL;
1325         boot_env = BFI_BOOT_LOADER_OS;
1326
1327         /*
1328          * Flash based firmware boot BIOS env.
1329          */
1330         if (bfa_ioc_is_bios_optrom(ioc)) {
1331                 boot_type = BFI_BOOT_TYPE_FLASH;
1332                 boot_env = BFI_BOOT_LOADER_BIOS;
1333         }
1334
1335         /*
1336          * Flash based firmware boot UEFI env.
1337          */
1338         if (bfa_ioc_is_uefi(ioc)) {
1339                 boot_type = BFI_BOOT_TYPE_FLASH;
1340                 boot_env = BFI_BOOT_LOADER_UEFI;
1341         }
1342
1343         /*
1344          * check if firmware is valid
1345          */
1346         fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
1347                 BFA_FALSE : bfa_ioc_fwver_valid(ioc, boot_env);
1348
1349         if (!fwvalid) {
1350                 bfa_ioc_boot(ioc, boot_type, boot_env);
1351                 return;
1352         }
1353
1354         /*
1355          * If hardware initialization is in progress (initialized by other IOC),
1356          * just wait for an initialization completion interrupt.
1357          */
1358         if (ioc_fwstate == BFI_IOC_INITING) {
1359                 ioc->cbfn->reset_cbfn(ioc->bfa);
1360                 return;
1361         }
1362
1363         /*
1364          * If IOC function is disabled and firmware version is same,
1365          * just re-enable IOC.
1366          *
1367          * If option rom, IOC must not be in operational state. With
1368          * convergence, IOC will be in operational state when 2nd driver
1369          * is loaded.
1370          */
1371         if (ioc_fwstate == BFI_IOC_DISABLED ||
1372             (!bfa_ioc_is_bios_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) {
1373
1374                 /*
1375                  * When using MSI-X any pending firmware ready event should
1376                  * be flushed. Otherwise MSI-X interrupts are not delivered.
1377                  */
1378                 bfa_ioc_msgflush(ioc);
1379                 ioc->cbfn->reset_cbfn(ioc->bfa);
1380                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
1381                 return;
1382         }
1383
1384         /*
1385          * Initialize the h/w for any other states.
1386          */
1387         bfa_ioc_boot(ioc, boot_type, boot_env);
1388 }
1389
1390 static void
1391 bfa_ioc_timeout(void *ioc_arg)
1392 {
1393         struct bfa_ioc_s  *ioc = (struct bfa_ioc_s *) ioc_arg;
1394
1395         bfa_trc(ioc, 0);
1396         bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
1397 }
1398
1399 void
1400 bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len)
1401 {
1402         u32 *msgp = (u32 *) ioc_msg;
1403         u32 i;
1404
1405         bfa_trc(ioc, msgp[0]);
1406         bfa_trc(ioc, len);
1407
1408         bfa_assert(len <= BFI_IOC_MSGLEN_MAX);
1409
1410         /*
1411          * first write msg to mailbox registers
1412          */
1413         for (i = 0; i < len / sizeof(u32); i++)
1414                 writel(cpu_to_le32(msgp[i]),
1415                         ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
1416
1417         for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
1418                 writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
1419
1420         /*
1421          * write 1 to mailbox CMD to trigger LPU event
1422          */
1423         writel(1, ioc->ioc_regs.hfn_mbox_cmd);
1424         (void) readl(ioc->ioc_regs.hfn_mbox_cmd);
1425 }
1426
1427 static void
1428 bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
1429 {
1430         struct bfi_ioc_ctrl_req_s enable_req;
1431         struct timeval tv;
1432
1433         bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
1434                     bfa_ioc_portid(ioc));
1435         enable_req.ioc_class = ioc->ioc_mc;
1436         do_gettimeofday(&tv);
1437         enable_req.tv_sec = be32_to_cpu(tv.tv_sec);
1438         bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1439 }
1440
1441 static void
1442 bfa_ioc_send_disable(struct bfa_ioc_s *ioc)
1443 {
1444         struct bfi_ioc_ctrl_req_s disable_req;
1445
1446         bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
1447                     bfa_ioc_portid(ioc));
1448         bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1449 }
1450
1451 static void
1452 bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
1453 {
1454         struct bfi_ioc_getattr_req_s    attr_req;
1455
1456         bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
1457                     bfa_ioc_portid(ioc));
1458         bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
1459         bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
1460 }
1461
1462 static void
1463 bfa_ioc_hb_check(void *cbarg)
1464 {
1465         struct bfa_ioc_s  *ioc = cbarg;
1466         u32     hb_count;
1467
1468         hb_count = readl(ioc->ioc_regs.heartbeat);
1469         if (ioc->hb_count == hb_count) {
1470                 printk(KERN_CRIT "Firmware heartbeat failure at %d", hb_count);
1471                 bfa_ioc_recover(ioc);
1472                 return;
1473         } else {
1474                 ioc->hb_count = hb_count;
1475         }
1476
1477         bfa_ioc_mbox_poll(ioc);
1478         bfa_hb_timer_start(ioc);
1479 }
1480
1481 static void
1482 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
1483 {
1484         ioc->hb_count = readl(ioc->ioc_regs.heartbeat);
1485         bfa_hb_timer_start(ioc);
1486 }
1487
1488 /*
1489  *      Initiate a full firmware download.
1490  */
1491 static void
1492 bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1493                     u32 boot_env)
1494 {
1495         u32 *fwimg;
1496         u32 pgnum, pgoff;
1497         u32 loff = 0;
1498         u32 chunkno = 0;
1499         u32 i;
1500
1501         /*
1502          * Initialize LMEM first before code download
1503          */
1504         bfa_ioc_lmem_init(ioc);
1505
1506         bfa_trc(ioc, bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)));
1507         fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno);
1508
1509         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1510         pgoff = PSS_SMEM_PGOFF(loff);
1511
1512         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1513
1514         for (i = 0; i < bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) {
1515
1516                 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
1517                         chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
1518                         fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc),
1519                                         BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1520                 }
1521
1522                 /*
1523                  * write smem
1524                  */
1525                 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
1526                               fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
1527
1528                 loff += sizeof(u32);
1529
1530                 /*
1531                  * handle page offset wrap around
1532                  */
1533                 loff = PSS_SMEM_PGOFF(loff);
1534                 if (loff == 0) {
1535                         pgnum++;
1536                         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1537                 }
1538         }
1539
1540         writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
1541                         ioc->ioc_regs.host_page_num_fn);
1542
1543         /*
1544          * Set boot type and boot param at the end.
1545         */
1546         bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF,
1547                         swab32(boot_type));
1548         bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_LOADER_OFF,
1549                         swab32(boot_env));
1550 }
1551
1552
1553 /*
1554  * Update BFA configuration from firmware configuration.
1555  */
1556 static void
1557 bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
1558 {
1559         struct bfi_ioc_attr_s   *attr = ioc->attr;
1560
1561         attr->adapter_prop  = be32_to_cpu(attr->adapter_prop);
1562         attr->card_type     = be32_to_cpu(attr->card_type);
1563         attr->maxfrsize     = be16_to_cpu(attr->maxfrsize);
1564
1565         bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
1566 }
1567
1568 /*
1569  * Attach time initialization of mbox logic.
1570  */
1571 static void
1572 bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc)
1573 {
1574         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
1575         int     mc;
1576
1577         INIT_LIST_HEAD(&mod->cmd_q);
1578         for (mc = 0; mc < BFI_MC_MAX; mc++) {
1579                 mod->mbhdlr[mc].cbfn = NULL;
1580                 mod->mbhdlr[mc].cbarg = ioc->bfa;
1581         }
1582 }
1583
1584 /*
1585  * Mbox poll timer -- restarts any pending mailbox requests.
1586  */
1587 static void
1588 bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc)
1589 {
1590         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
1591         struct bfa_mbox_cmd_s           *cmd;
1592         u32                     stat;
1593
1594         /*
1595          * If no command pending, do nothing
1596          */
1597         if (list_empty(&mod->cmd_q))
1598                 return;
1599
1600         /*
1601          * If previous command is not yet fetched by firmware, do nothing
1602          */
1603         stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
1604         if (stat)
1605                 return;
1606
1607         /*
1608          * Enqueue command to firmware.
1609          */
1610         bfa_q_deq(&mod->cmd_q, &cmd);
1611         bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
1612 }
1613
1614 /*
1615  * Cleanup any pending requests.
1616  */
1617 static void
1618 bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
1619 {
1620         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
1621         struct bfa_mbox_cmd_s           *cmd;
1622
1623         while (!list_empty(&mod->cmd_q))
1624                 bfa_q_deq(&mod->cmd_q, &cmd);
1625 }
1626
1627 /*
1628  * Read data from SMEM to host through PCI memmap
1629  *
1630  * @param[in]   ioc     memory for IOC
1631  * @param[in]   tbuf    app memory to store data from smem
1632  * @param[in]   soff    smem offset
1633  * @param[in]   sz      size of smem in bytes
1634  */
1635 static bfa_status_t
1636 bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
1637 {
1638         u32 pgnum, loff;
1639         __be32 r32;
1640         int i, len;
1641         u32 *buf = tbuf;
1642
1643         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
1644         loff = PSS_SMEM_PGOFF(soff);
1645         bfa_trc(ioc, pgnum);
1646         bfa_trc(ioc, loff);
1647         bfa_trc(ioc, sz);
1648
1649         /*
1650          *  Hold semaphore to serialize pll init and fwtrc.
1651          */
1652         if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) {
1653                 bfa_trc(ioc, 0);
1654                 return BFA_STATUS_FAILED;
1655         }
1656
1657         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1658
1659         len = sz/sizeof(u32);
1660         bfa_trc(ioc, len);
1661         for (i = 0; i < len; i++) {
1662                 r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
1663                 buf[i] = be32_to_cpu(r32);
1664                 loff += sizeof(u32);
1665
1666                 /*
1667                  * handle page offset wrap around
1668                  */
1669                 loff = PSS_SMEM_PGOFF(loff);
1670                 if (loff == 0) {
1671                         pgnum++;
1672                         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1673                 }
1674         }
1675         writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
1676                         ioc->ioc_regs.host_page_num_fn);
1677         /*
1678          *  release semaphore.
1679          */
1680         writel(1, ioc->ioc_regs.ioc_init_sem_reg);
1681
1682         bfa_trc(ioc, pgnum);
1683         return BFA_STATUS_OK;
1684 }
1685
1686 /*
1687  * Clear SMEM data from host through PCI memmap
1688  *
1689  * @param[in]   ioc     memory for IOC
1690  * @param[in]   soff    smem offset
1691  * @param[in]   sz      size of smem in bytes
1692  */
1693 static bfa_status_t
1694 bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
1695 {
1696         int i, len;
1697         u32 pgnum, loff;
1698
1699         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
1700         loff = PSS_SMEM_PGOFF(soff);
1701         bfa_trc(ioc, pgnum);
1702         bfa_trc(ioc, loff);
1703         bfa_trc(ioc, sz);
1704
1705         /*
1706          *  Hold semaphore to serialize pll init and fwtrc.
1707          */
1708         if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) {
1709                 bfa_trc(ioc, 0);
1710                 return BFA_STATUS_FAILED;
1711         }
1712
1713         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1714
1715         len = sz/sizeof(u32); /* len in words */
1716         bfa_trc(ioc, len);
1717         for (i = 0; i < len; i++) {
1718                 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 0);
1719                 loff += sizeof(u32);
1720
1721                 /*
1722                  * handle page offset wrap around
1723                  */
1724                 loff = PSS_SMEM_PGOFF(loff);
1725                 if (loff == 0) {
1726                         pgnum++;
1727                         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1728                 }
1729         }
1730         writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
1731                         ioc->ioc_regs.host_page_num_fn);
1732
1733         /*
1734          *  release semaphore.
1735          */
1736         writel(1, ioc->ioc_regs.ioc_init_sem_reg);
1737         bfa_trc(ioc, pgnum);
1738         return BFA_STATUS_OK;
1739 }
1740
1741
1742 static void
1743 bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
1744 {
1745         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
1746         /*
1747          * Provide enable completion callback.
1748          */
1749         ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
1750         BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
1751                 "Running firmware version is incompatible "
1752                 "with the driver version\n");
1753 }
1754
1755
1756 bfa_status_t
1757 bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
1758 {
1759
1760         /*
1761          *  Hold semaphore so that nobody can access the chip during init.
1762          */
1763         bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
1764
1765         bfa_ioc_pll_init_asic(ioc);
1766
1767         ioc->pllinit = BFA_TRUE;
1768         /*
1769          *  release semaphore.
1770          */
1771         writel(1, ioc->ioc_regs.ioc_init_sem_reg);
1772
1773         return BFA_STATUS_OK;
1774 }
1775
1776 /*
1777  * Interface used by diag module to do firmware boot with memory test
1778  * as the entry vector.
1779  */
1780 void
1781 bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env)
1782 {
1783         void __iomem *rb;
1784
1785         bfa_ioc_stats(ioc, ioc_boots);
1786
1787         if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
1788                 return;
1789
1790         /*
1791          * Initialize IOC state of all functions on a chip reset.
1792          */
1793         rb = ioc->pcidev.pci_bar_kva;
1794         if (boot_type == BFI_BOOT_TYPE_MEMTEST) {
1795                 writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG));
1796                 writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG));
1797         } else {
1798                 writel(BFI_IOC_INITING, (rb + BFA_IOC0_STATE_REG));
1799                 writel(BFI_IOC_INITING, (rb + BFA_IOC1_STATE_REG));
1800         }
1801
1802         bfa_ioc_msgflush(ioc);
1803         bfa_ioc_download_fw(ioc, boot_type, boot_env);
1804
1805         /*
1806          * Enable interrupts just before starting LPU
1807          */
1808         ioc->cbfn->reset_cbfn(ioc->bfa);
1809         bfa_ioc_lpu_start(ioc);
1810 }
1811
1812 /*
1813  * Enable/disable IOC failure auto recovery.
1814  */
1815 void
1816 bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
1817 {
1818         bfa_auto_recover = auto_recover;
1819 }
1820
1821
1822
1823 bfa_boolean_t
1824 bfa_ioc_is_operational(struct bfa_ioc_s *ioc)
1825 {
1826         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
1827 }
1828
1829 bfa_boolean_t
1830 bfa_ioc_is_initialized(struct bfa_ioc_s *ioc)
1831 {
1832         u32 r32 = readl(ioc->ioc_regs.ioc_fwstate);
1833
1834         return ((r32 != BFI_IOC_UNINIT) &&
1835                 (r32 != BFI_IOC_INITING) &&
1836                 (r32 != BFI_IOC_MEMTEST));
1837 }
1838
1839 void
1840 bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
1841 {
1842         __be32  *msgp = mbmsg;
1843         u32     r32;
1844         int             i;
1845
1846         /*
1847          * read the MBOX msg
1848          */
1849         for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
1850              i++) {
1851                 r32 = readl(ioc->ioc_regs.lpu_mbox +
1852                                    i * sizeof(u32));
1853                 msgp[i] = cpu_to_be32(r32);
1854         }
1855
1856         /*
1857          * turn off mailbox interrupt by clearing mailbox status
1858          */
1859         writel(1, ioc->ioc_regs.lpu_mbox_cmd);
1860         readl(ioc->ioc_regs.lpu_mbox_cmd);
1861 }
1862
1863 void
1864 bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
1865 {
1866         union bfi_ioc_i2h_msg_u *msg;
1867         struct bfa_iocpf_s *iocpf = &ioc->iocpf;
1868
1869         msg = (union bfi_ioc_i2h_msg_u *) m;
1870
1871         bfa_ioc_stats(ioc, ioc_isrs);
1872
1873         switch (msg->mh.msg_id) {
1874         case BFI_IOC_I2H_HBEAT:
1875                 break;
1876
1877         case BFI_IOC_I2H_READY_EVENT:
1878                 bfa_fsm_send_event(iocpf, IOCPF_E_FWREADY);
1879                 break;
1880
1881         case BFI_IOC_I2H_ENABLE_REPLY:
1882                 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
1883                 break;
1884
1885         case BFI_IOC_I2H_DISABLE_REPLY:
1886                 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE);
1887                 break;
1888
1889         case BFI_IOC_I2H_GETATTR_REPLY:
1890                 bfa_ioc_getattr_reply(ioc);
1891                 break;
1892
1893         default:
1894                 bfa_trc(ioc, msg->mh.msg_id);
1895                 bfa_assert(0);
1896         }
1897 }
1898
1899 /*
1900  * IOC attach time initialization and setup.
1901  *
1902  * @param[in]   ioc     memory for IOC
1903  * @param[in]   bfa     driver instance structure
1904  */
1905 void
1906 bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn,
1907                struct bfa_timer_mod_s *timer_mod)
1908 {
1909         ioc->bfa        = bfa;
1910         ioc->cbfn       = cbfn;
1911         ioc->timer_mod  = timer_mod;
1912         ioc->fcmode     = BFA_FALSE;
1913         ioc->pllinit    = BFA_FALSE;
1914         ioc->dbg_fwsave_once = BFA_TRUE;
1915         ioc->iocpf.ioc  = ioc;
1916
1917         bfa_ioc_mbox_attach(ioc);
1918         INIT_LIST_HEAD(&ioc->hb_notify_q);
1919
1920         bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
1921         bfa_fsm_send_event(ioc, IOC_E_RESET);
1922 }
1923
1924 /*
1925  * Driver detach time IOC cleanup.
1926  */
1927 void
1928 bfa_ioc_detach(struct bfa_ioc_s *ioc)
1929 {
1930         bfa_fsm_send_event(ioc, IOC_E_DETACH);
1931 }
1932
1933 /*
1934  * Setup IOC PCI properties.
1935  *
1936  * @param[in]   pcidev  PCI device information for this IOC
1937  */
1938 void
1939 bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
1940                  enum bfi_mclass mc)
1941 {
1942         ioc->ioc_mc     = mc;
1943         ioc->pcidev     = *pcidev;
1944         ioc->ctdev      = bfa_asic_id_ct(ioc->pcidev.device_id);
1945         ioc->cna        = ioc->ctdev && !ioc->fcmode;
1946
1947         /*
1948          * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
1949          */
1950         if (ioc->ctdev)
1951                 bfa_ioc_set_ct_hwif(ioc);
1952         else
1953                 bfa_ioc_set_cb_hwif(ioc);
1954
1955         bfa_ioc_map_port(ioc);
1956         bfa_ioc_reg_init(ioc);
1957 }
1958
1959 /*
1960  * Initialize IOC dma memory
1961  *
1962  * @param[in]   dm_kva  kernel virtual address of IOC dma memory
1963  * @param[in]   dm_pa   physical address of IOC dma memory
1964  */
1965 void
1966 bfa_ioc_mem_claim(struct bfa_ioc_s *ioc,  u8 *dm_kva, u64 dm_pa)
1967 {
1968         /*
1969          * dma memory for firmware attribute
1970          */
1971         ioc->attr_dma.kva = dm_kva;
1972         ioc->attr_dma.pa = dm_pa;
1973         ioc->attr = (struct bfi_ioc_attr_s *) dm_kva;
1974 }
1975
1976 void
1977 bfa_ioc_enable(struct bfa_ioc_s *ioc)
1978 {
1979         bfa_ioc_stats(ioc, ioc_enables);
1980         ioc->dbg_fwsave_once = BFA_TRUE;
1981
1982         bfa_fsm_send_event(ioc, IOC_E_ENABLE);
1983 }
1984
1985 void
1986 bfa_ioc_disable(struct bfa_ioc_s *ioc)
1987 {
1988         bfa_ioc_stats(ioc, ioc_disables);
1989         bfa_fsm_send_event(ioc, IOC_E_DISABLE);
1990 }
1991
1992
1993 /*
1994  * Initialize memory for saving firmware trace. Driver must initialize
1995  * trace memory before call bfa_ioc_enable().
1996  */
1997 void
1998 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
1999 {
2000         ioc->dbg_fwsave     = dbg_fwsave;
2001         ioc->dbg_fwsave_len = (ioc->iocpf.auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
2002 }
2003
2004 /*
2005  * Register mailbox message handler functions
2006  *
2007  * @param[in]   ioc             IOC instance
2008  * @param[in]   mcfuncs         message class handler functions
2009  */
2010 void
2011 bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs)
2012 {
2013         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2014         int                             mc;
2015
2016         for (mc = 0; mc < BFI_MC_MAX; mc++)
2017                 mod->mbhdlr[mc].cbfn = mcfuncs[mc];
2018 }
2019
2020 /*
2021  * Register mailbox message handler function, to be called by common modules
2022  */
2023 void
2024 bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
2025                     bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
2026 {
2027         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2028
2029         mod->mbhdlr[mc].cbfn    = cbfn;
2030         mod->mbhdlr[mc].cbarg   = cbarg;
2031 }
2032
2033 /*
2034  * Queue a mailbox command request to firmware. Waits if mailbox is busy.
2035  * Responsibility of caller to serialize
2036  *
2037  * @param[in]   ioc     IOC instance
2038  * @param[i]    cmd     Mailbox command
2039  */
2040 void
2041 bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd)
2042 {
2043         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2044         u32                     stat;
2045
2046         /*
2047          * If a previous command is pending, queue new command
2048          */
2049         if (!list_empty(&mod->cmd_q)) {
2050                 list_add_tail(&cmd->qe, &mod->cmd_q);
2051                 return;
2052         }
2053
2054         /*
2055          * If mailbox is busy, queue command for poll timer
2056          */
2057         stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
2058         if (stat) {
2059                 list_add_tail(&cmd->qe, &mod->cmd_q);
2060                 return;
2061         }
2062
2063         /*
2064          * mailbox is free -- queue command to firmware
2065          */
2066         bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
2067 }
2068
2069 /*
2070  * Handle mailbox interrupts
2071  */
2072 void
2073 bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc)
2074 {
2075         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2076         struct bfi_mbmsg_s              m;
2077         int                             mc;
2078
2079         bfa_ioc_msgget(ioc, &m);
2080
2081         /*
2082          * Treat IOC message class as special.
2083          */
2084         mc = m.mh.msg_class;
2085         if (mc == BFI_MC_IOC) {
2086                 bfa_ioc_isr(ioc, &m);
2087                 return;
2088         }
2089
2090         if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
2091                 return;
2092
2093         mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
2094 }
2095
2096 void
2097 bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
2098 {
2099         bfa_fsm_send_event(ioc, IOC_E_HWERROR);
2100 }
2101
2102 void
2103 bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc)
2104 {
2105         ioc->fcmode  = BFA_TRUE;
2106         ioc->port_id = bfa_ioc_pcifn(ioc);
2107 }
2108
2109 /*
2110  * return true if IOC is disabled
2111  */
2112 bfa_boolean_t
2113 bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
2114 {
2115         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) ||
2116                 bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
2117 }
2118
2119 /*
2120  * return true if IOC firmware is different.
2121  */
2122 bfa_boolean_t
2123 bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
2124 {
2125         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset) ||
2126                 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_fwcheck) ||
2127                 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_mismatch);
2128 }
2129
2130 #define bfa_ioc_state_disabled(__sm)            \
2131         (((__sm) == BFI_IOC_UNINIT) ||          \
2132          ((__sm) == BFI_IOC_INITING) ||         \
2133          ((__sm) == BFI_IOC_HWINIT) ||          \
2134          ((__sm) == BFI_IOC_DISABLED) ||        \
2135          ((__sm) == BFI_IOC_FAIL) ||            \
2136          ((__sm) == BFI_IOC_CFG_DISABLED))
2137
2138 /*
2139  * Check if adapter is disabled -- both IOCs should be in a disabled
2140  * state.
2141  */
2142 bfa_boolean_t
2143 bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
2144 {
2145         u32     ioc_state;
2146         void __iomem *rb = ioc->pcidev.pci_bar_kva;
2147
2148         if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled))
2149                 return BFA_FALSE;
2150
2151         ioc_state = readl(rb + BFA_IOC0_STATE_REG);
2152         if (!bfa_ioc_state_disabled(ioc_state))
2153                 return BFA_FALSE;
2154
2155         if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) {
2156                 ioc_state = readl(rb + BFA_IOC1_STATE_REG);
2157                 if (!bfa_ioc_state_disabled(ioc_state))
2158                         return BFA_FALSE;
2159         }
2160
2161         return BFA_TRUE;
2162 }
2163
2164 #define BFA_MFG_NAME "Brocade"
2165 void
2166 bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2167                          struct bfa_adapter_attr_s *ad_attr)
2168 {
2169         struct bfi_ioc_attr_s   *ioc_attr;
2170
2171         ioc_attr = ioc->attr;
2172
2173         bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
2174         bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
2175         bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
2176         bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
2177         memcpy(&ad_attr->vpd, &ioc_attr->vpd,
2178                       sizeof(struct bfa_mfg_vpd_s));
2179
2180         ad_attr->nports = bfa_ioc_get_nports(ioc);
2181         ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
2182
2183         bfa_ioc_get_adapter_model(ioc, ad_attr->model);
2184         /* For now, model descr uses same model string */
2185         bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
2186
2187         ad_attr->card_type = ioc_attr->card_type;
2188         ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type);
2189
2190         if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
2191                 ad_attr->prototype = 1;
2192         else
2193                 ad_attr->prototype = 0;
2194
2195         ad_attr->pwwn = ioc->attr->pwwn;
2196         ad_attr->mac  = bfa_ioc_get_mac(ioc);
2197
2198         ad_attr->pcie_gen = ioc_attr->pcie_gen;
2199         ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
2200         ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
2201         ad_attr->asic_rev = ioc_attr->asic_rev;
2202
2203         bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
2204
2205         ad_attr->cna_capable = ioc->cna;
2206         ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna;
2207 }
2208
2209 enum bfa_ioc_type_e
2210 bfa_ioc_get_type(struct bfa_ioc_s *ioc)
2211 {
2212         if (!ioc->ctdev || ioc->fcmode)
2213                 return BFA_IOC_TYPE_FC;
2214         else if (ioc->ioc_mc == BFI_MC_IOCFC)
2215                 return BFA_IOC_TYPE_FCoE;
2216         else if (ioc->ioc_mc == BFI_MC_LL)
2217                 return BFA_IOC_TYPE_LL;
2218         else {
2219                 bfa_assert(ioc->ioc_mc == BFI_MC_LL);
2220                 return BFA_IOC_TYPE_LL;
2221         }
2222 }
2223
2224 void
2225 bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
2226 {
2227         memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
2228         memcpy((void *)serial_num,
2229                         (void *)ioc->attr->brcd_serialnum,
2230                         BFA_ADAPTER_SERIAL_NUM_LEN);
2231 }
2232
2233 void
2234 bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
2235 {
2236         memset((void *)fw_ver, 0, BFA_VERSION_LEN);
2237         memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
2238 }
2239
2240 void
2241 bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
2242 {
2243         bfa_assert(chip_rev);
2244
2245         memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
2246
2247         chip_rev[0] = 'R';
2248         chip_rev[1] = 'e';
2249         chip_rev[2] = 'v';
2250         chip_rev[3] = '-';
2251         chip_rev[4] = ioc->attr->asic_rev;
2252         chip_rev[5] = '\0';
2253 }
2254
2255 void
2256 bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver)
2257 {
2258         memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
2259         memcpy(optrom_ver, ioc->attr->optrom_version,
2260                       BFA_VERSION_LEN);
2261 }
2262
2263 void
2264 bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
2265 {
2266         memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
2267         memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
2268 }
2269
2270 void
2271 bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
2272 {
2273         struct bfi_ioc_attr_s   *ioc_attr;
2274
2275         bfa_assert(model);
2276         memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
2277
2278         ioc_attr = ioc->attr;
2279
2280         /*
2281          * model name
2282          */
2283         snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
2284                 BFA_MFG_NAME, ioc_attr->card_type);
2285 }
2286
2287 enum bfa_ioc_state
2288 bfa_ioc_get_state(struct bfa_ioc_s *ioc)
2289 {
2290         enum bfa_iocpf_state iocpf_st;
2291         enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
2292
2293         if (ioc_st == BFA_IOC_ENABLING ||
2294                 ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) {
2295
2296                 iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm);
2297
2298                 switch (iocpf_st) {
2299                 case BFA_IOCPF_SEMWAIT:
2300                         ioc_st = BFA_IOC_SEMWAIT;
2301                         break;
2302
2303                 case BFA_IOCPF_HWINIT:
2304                         ioc_st = BFA_IOC_HWINIT;
2305                         break;
2306
2307                 case BFA_IOCPF_FWMISMATCH:
2308                         ioc_st = BFA_IOC_FWMISMATCH;
2309                         break;
2310
2311                 case BFA_IOCPF_FAIL:
2312                         ioc_st = BFA_IOC_FAIL;
2313                         break;
2314
2315                 case BFA_IOCPF_INITFAIL:
2316                         ioc_st = BFA_IOC_INITFAIL;
2317                         break;
2318
2319                 default:
2320                         break;
2321                 }
2322         }
2323
2324         return ioc_st;
2325 }
2326
2327 void
2328 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
2329 {
2330         memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
2331
2332         ioc_attr->state = bfa_ioc_get_state(ioc);
2333         ioc_attr->port_id = ioc->port_id;
2334
2335         ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
2336
2337         bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
2338
2339         ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
2340         ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
2341         bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
2342 }
2343
2344 mac_t
2345 bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
2346 {
2347         /*
2348          * Check the IOC type and return the appropriate MAC
2349          */
2350         if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE)
2351                 return ioc->attr->fcoe_mac;
2352         else
2353                 return ioc->attr->mac;
2354 }
2355
2356 mac_t
2357 bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc)
2358 {
2359         mac_t   m;
2360
2361         m = ioc->attr->mfg_mac;
2362         if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type))
2363                 m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
2364         else
2365                 bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]),
2366                         bfa_ioc_pcifn(ioc));
2367
2368         return m;
2369 }
2370
2371 bfa_boolean_t
2372 bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
2373 {
2374         return ioc->fcmode || !bfa_asic_id_ct(ioc->pcidev.device_id);
2375 }
2376
2377 /*
2378  * Retrieve saved firmware trace from a prior IOC failure.
2379  */
2380 bfa_status_t
2381 bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2382 {
2383         int     tlen;
2384
2385         if (ioc->dbg_fwsave_len == 0)
2386                 return BFA_STATUS_ENOFSAVE;
2387
2388         tlen = *trclen;
2389         if (tlen > ioc->dbg_fwsave_len)
2390                 tlen = ioc->dbg_fwsave_len;
2391
2392         memcpy(trcdata, ioc->dbg_fwsave, tlen);
2393         *trclen = tlen;
2394         return BFA_STATUS_OK;
2395 }
2396
2397
2398 /*
2399  * Retrieve saved firmware trace from a prior IOC failure.
2400  */
2401 bfa_status_t
2402 bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2403 {
2404         u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc));
2405         int tlen;
2406         bfa_status_t status;
2407
2408         bfa_trc(ioc, *trclen);
2409
2410         tlen = *trclen;
2411         if (tlen > BFA_DBG_FWTRC_LEN)
2412                 tlen = BFA_DBG_FWTRC_LEN;
2413
2414         status = bfa_ioc_smem_read(ioc, trcdata, loff, tlen);
2415         *trclen = tlen;
2416         return status;
2417 }
2418
2419 static void
2420 bfa_ioc_send_fwsync(struct bfa_ioc_s *ioc)
2421 {
2422         struct bfa_mbox_cmd_s cmd;
2423         struct bfi_ioc_ctrl_req_s *req = (struct bfi_ioc_ctrl_req_s *) cmd.msg;
2424
2425         bfi_h2i_set(req->mh, BFI_MC_IOC, BFI_IOC_H2I_DBG_SYNC,
2426                     bfa_ioc_portid(ioc));
2427         req->ioc_class = ioc->ioc_mc;
2428         bfa_ioc_mbox_queue(ioc, &cmd);
2429 }
2430
2431 static void
2432 bfa_ioc_fwsync(struct bfa_ioc_s *ioc)
2433 {
2434         u32 fwsync_iter = 1000;
2435
2436         bfa_ioc_send_fwsync(ioc);
2437
2438         /*
2439          * After sending a fw sync mbox command wait for it to
2440          * take effect.  We will not wait for a response because
2441          *    1. fw_sync mbox cmd doesn't have a response.
2442          *    2. Even if we implement that,  interrupts might not
2443          *       be enabled when we call this function.
2444          * So, just keep checking if any mbox cmd is pending, and
2445          * after waiting for a reasonable amount of time, go ahead.
2446          * It is possible that fw has crashed and the mbox command
2447          * is never acknowledged.
2448          */
2449         while (bfa_ioc_mbox_cmd_pending(ioc) && fwsync_iter > 0)
2450                 fwsync_iter--;
2451 }
2452
2453 /*
2454  * Dump firmware smem
2455  */
2456 bfa_status_t
2457 bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf,
2458                                 u32 *offset, int *buflen)
2459 {
2460         u32 loff;
2461         int dlen;
2462         bfa_status_t status;
2463         u32 smem_len = BFA_IOC_FW_SMEM_SIZE(ioc);
2464
2465         if (*offset >= smem_len) {
2466                 *offset = *buflen = 0;
2467                 return BFA_STATUS_EINVAL;
2468         }
2469
2470         loff = *offset;
2471         dlen = *buflen;
2472
2473         /*
2474          * First smem read, sync smem before proceeding
2475          * No need to sync before reading every chunk.
2476          */
2477         if (loff == 0)
2478                 bfa_ioc_fwsync(ioc);
2479
2480         if ((loff + dlen) >= smem_len)
2481                 dlen = smem_len - loff;
2482
2483         status = bfa_ioc_smem_read(ioc, buf, loff, dlen);
2484
2485         if (status != BFA_STATUS_OK) {
2486                 *offset = *buflen = 0;
2487                 return status;
2488         }
2489
2490         *offset += dlen;
2491
2492         if (*offset >= smem_len)
2493                 *offset = 0;
2494
2495         *buflen = dlen;
2496
2497         return status;
2498 }
2499
2500 /*
2501  * Firmware statistics
2502  */
2503 bfa_status_t
2504 bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats)
2505 {
2506         u32 loff = BFI_IOC_FWSTATS_OFF + \
2507                 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc));
2508         int tlen;
2509         bfa_status_t status;
2510
2511         if (ioc->stats_busy) {
2512                 bfa_trc(ioc, ioc->stats_busy);
2513                 return BFA_STATUS_DEVBUSY;
2514         }
2515         ioc->stats_busy = BFA_TRUE;
2516
2517         tlen = sizeof(struct bfa_fw_stats_s);
2518         status = bfa_ioc_smem_read(ioc, stats, loff, tlen);
2519
2520         ioc->stats_busy = BFA_FALSE;
2521         return status;
2522 }
2523
2524 bfa_status_t
2525 bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc)
2526 {
2527         u32 loff = BFI_IOC_FWSTATS_OFF + \
2528                 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc));
2529         int tlen;
2530         bfa_status_t status;
2531
2532         if (ioc->stats_busy) {
2533                 bfa_trc(ioc, ioc->stats_busy);
2534                 return BFA_STATUS_DEVBUSY;
2535         }
2536         ioc->stats_busy = BFA_TRUE;
2537
2538         tlen = sizeof(struct bfa_fw_stats_s);
2539         status = bfa_ioc_smem_clr(ioc, loff, tlen);
2540
2541         ioc->stats_busy = BFA_FALSE;
2542         return status;
2543 }
2544
2545 /*
2546  * Save firmware trace if configured.
2547  */
2548 static void
2549 bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
2550 {
2551         int             tlen;
2552
2553         if (ioc->dbg_fwsave_len) {
2554                 tlen = ioc->dbg_fwsave_len;
2555                 bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
2556         }
2557 }
2558
2559 /*
2560  * Firmware failure detected. Start recovery actions.
2561  */
2562 static void
2563 bfa_ioc_recover(struct bfa_ioc_s *ioc)
2564 {
2565         if (ioc->dbg_fwsave_once) {
2566                 ioc->dbg_fwsave_once = BFA_FALSE;
2567                 bfa_ioc_debug_save(ioc);
2568         }
2569
2570         bfa_ioc_stats(ioc, ioc_hbfails);
2571         bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
2572 }
2573
2574 static void
2575 bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc)
2576 {
2577         if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
2578                 return;
2579 }
2580
2581 /*
2582  *  BFA IOC PF private functions
2583  */
2584 static void
2585 bfa_iocpf_timeout(void *ioc_arg)
2586 {
2587         struct bfa_ioc_s  *ioc = (struct bfa_ioc_s *) ioc_arg;
2588
2589         bfa_trc(ioc, 0);
2590         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT);
2591 }
2592
2593 static void
2594 bfa_iocpf_sem_timeout(void *ioc_arg)
2595 {
2596         struct bfa_ioc_s  *ioc = (struct bfa_ioc_s *) ioc_arg;
2597
2598         bfa_ioc_hw_sem_get(ioc);
2599 }
2600
2601 /*
2602  *  bfa timer function
2603  */
2604 void
2605 bfa_timer_beat(struct bfa_timer_mod_s *mod)
2606 {
2607         struct list_head *qh = &mod->timer_q;
2608         struct list_head *qe, *qe_next;
2609         struct bfa_timer_s *elem;
2610         struct list_head timedout_q;
2611
2612         INIT_LIST_HEAD(&timedout_q);
2613
2614         qe = bfa_q_next(qh);
2615
2616         while (qe != qh) {
2617                 qe_next = bfa_q_next(qe);
2618
2619                 elem = (struct bfa_timer_s *) qe;
2620                 if (elem->timeout <= BFA_TIMER_FREQ) {
2621                         elem->timeout = 0;
2622                         list_del(&elem->qe);
2623                         list_add_tail(&elem->qe, &timedout_q);
2624                 } else {
2625                         elem->timeout -= BFA_TIMER_FREQ;
2626                 }
2627
2628                 qe = qe_next;   /* go to next elem */
2629         }
2630
2631         /*
2632          * Pop all the timeout entries
2633          */
2634         while (!list_empty(&timedout_q)) {
2635                 bfa_q_deq(&timedout_q, &elem);
2636                 elem->timercb(elem->arg);
2637         }
2638 }
2639
2640 /*
2641  * Should be called with lock protection
2642  */
2643 void
2644 bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
2645                     void (*timercb) (void *), void *arg, unsigned int timeout)
2646 {
2647
2648         bfa_assert(timercb != NULL);
2649         bfa_assert(!bfa_q_is_on_q(&mod->timer_q, timer));
2650
2651         timer->timeout = timeout;
2652         timer->timercb = timercb;
2653         timer->arg = arg;
2654
2655         list_add_tail(&timer->qe, &mod->timer_q);
2656 }
2657
2658 /*
2659  * Should be called with lock protection
2660  */
2661 void
2662 bfa_timer_stop(struct bfa_timer_s *timer)
2663 {
2664         bfa_assert(!list_empty(&timer->qe));
2665
2666         list_del(&timer->qe);
2667 }