GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / scsi / bfa / bfa_ioc.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
4  * Copyright (c) 2014- QLogic Corporation.
5  * All rights reserved
6  * www.qlogic.com
7  *
8  * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
9  */
10
11 #include "bfad_drv.h"
12 #include "bfad_im.h"
13 #include "bfa_ioc.h"
14 #include "bfi_reg.h"
15 #include "bfa_defs.h"
16 #include "bfa_defs_svc.h"
17 #include "bfi.h"
18
19 BFA_TRC_FILE(CNA, IOC);
20
21 /*
22  * IOC local definitions
23  */
24 #define BFA_IOC_TOV             3000    /* msecs */
25 #define BFA_IOC_HWSEM_TOV       500     /* msecs */
26 #define BFA_IOC_HB_TOV          500     /* msecs */
27 #define BFA_IOC_TOV_RECOVER      BFA_IOC_HB_TOV
28 #define BFA_IOC_POLL_TOV        BFA_TIMER_FREQ
29
30 #define bfa_ioc_timer_start(__ioc)                                      \
31         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
32                         bfa_ioc_timeout, (__ioc), BFA_IOC_TOV)
33 #define bfa_ioc_timer_stop(__ioc)   bfa_timer_stop(&(__ioc)->ioc_timer)
34
35 #define bfa_hb_timer_start(__ioc)                                       \
36         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->hb_timer,         \
37                         bfa_ioc_hb_check, (__ioc), BFA_IOC_HB_TOV)
38 #define bfa_hb_timer_stop(__ioc)        bfa_timer_stop(&(__ioc)->hb_timer)
39
40 #define BFA_DBG_FWTRC_OFF(_fn)  (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
41
42 #define bfa_ioc_state_disabled(__sm)            \
43         (((__sm) == BFI_IOC_UNINIT) ||          \
44         ((__sm) == BFI_IOC_INITING) ||          \
45         ((__sm) == BFI_IOC_HWINIT) ||           \
46         ((__sm) == BFI_IOC_DISABLED) ||         \
47         ((__sm) == BFI_IOC_FAIL) ||             \
48         ((__sm) == BFI_IOC_CFG_DISABLED))
49
50 /*
51  * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
52  */
53
54 #define bfa_ioc_firmware_lock(__ioc)                    \
55                         ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
56 #define bfa_ioc_firmware_unlock(__ioc)                  \
57                         ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
58 #define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
59 #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
60 #define bfa_ioc_notify_fail(__ioc)              \
61                         ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc))
62 #define bfa_ioc_sync_start(__ioc)               \
63                         ((__ioc)->ioc_hwif->ioc_sync_start(__ioc))
64 #define bfa_ioc_sync_join(__ioc)                \
65                         ((__ioc)->ioc_hwif->ioc_sync_join(__ioc))
66 #define bfa_ioc_sync_leave(__ioc)               \
67                         ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc))
68 #define bfa_ioc_sync_ack(__ioc)                 \
69                         ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc))
70 #define bfa_ioc_sync_complete(__ioc)            \
71                         ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc))
72 #define bfa_ioc_set_cur_ioc_fwstate(__ioc, __fwstate)           \
73                         ((__ioc)->ioc_hwif->ioc_set_fwstate(__ioc, __fwstate))
74 #define bfa_ioc_get_cur_ioc_fwstate(__ioc)              \
75                         ((__ioc)->ioc_hwif->ioc_get_fwstate(__ioc))
76 #define bfa_ioc_set_alt_ioc_fwstate(__ioc, __fwstate)           \
77                 ((__ioc)->ioc_hwif->ioc_set_alt_fwstate(__ioc, __fwstate))
78 #define bfa_ioc_get_alt_ioc_fwstate(__ioc)              \
79                         ((__ioc)->ioc_hwif->ioc_get_alt_fwstate(__ioc))
80
81 #define bfa_ioc_mbox_cmd_pending(__ioc)         \
82                         (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
83                         readl((__ioc)->ioc_regs.hfn_mbox_cmd))
84
85 bfa_boolean_t bfa_auto_recover = BFA_TRUE;
86
87 /*
88  * forward declarations
89  */
90 static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
91 static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
92 static void bfa_ioc_timeout(void *ioc);
93 static void bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc);
94 static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc);
95 static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc);
96 static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc);
97 static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc);
98 static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
99 static void bfa_ioc_mbox_flush(struct bfa_ioc_s *ioc);
100 static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
101 static void bfa_ioc_event_notify(struct bfa_ioc_s *ioc ,
102                                 enum bfa_ioc_event_e event);
103 static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
104 static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
105 static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc);
106 static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc);
107 static enum bfi_ioc_img_ver_cmp_e bfa_ioc_fw_ver_patch_cmp(
108                                 struct bfi_ioc_image_hdr_s *base_fwhdr,
109                                 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp);
110 static enum bfi_ioc_img_ver_cmp_e bfa_ioc_flash_fwver_cmp(
111                                 struct bfa_ioc_s *ioc,
112                                 struct bfi_ioc_image_hdr_s *base_fwhdr);
113
114 /*
115  * IOC state machine definitions/declarations
116  */
117 enum ioc_event {
118         IOC_E_RESET             = 1,    /*  IOC reset request           */
119         IOC_E_ENABLE            = 2,    /*  IOC enable request          */
120         IOC_E_DISABLE           = 3,    /*  IOC disable request */
121         IOC_E_DETACH            = 4,    /*  driver detach cleanup       */
122         IOC_E_ENABLED           = 5,    /*  f/w enabled         */
123         IOC_E_FWRSP_GETATTR     = 6,    /*  IOC get attribute response  */
124         IOC_E_DISABLED          = 7,    /*  f/w disabled                */
125         IOC_E_PFFAILED          = 8,    /*  failure notice by iocpf sm  */
126         IOC_E_HBFAIL            = 9,    /*  heartbeat failure           */
127         IOC_E_HWERROR           = 10,   /*  hardware error interrupt    */
128         IOC_E_TIMEOUT           = 11,   /*  timeout                     */
129         IOC_E_HWFAILED          = 12,   /*  PCI mapping failure notice  */
130 };
131
132 bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event);
133 bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
134 bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
135 bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
136 bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
137 bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc_s, enum ioc_event);
138 bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event);
139 bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
140 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
141 bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc_s, enum ioc_event);
142
143 static struct bfa_sm_table_s ioc_sm_table[] = {
144         {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
145         {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
146         {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING},
147         {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
148         {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
149         {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL},
150         {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
151         {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
152         {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
153         {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL},
154 };
155
156 /*
157  * IOCPF state machine definitions/declarations
158  */
159
160 #define bfa_iocpf_timer_start(__ioc)                                    \
161         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
162                         bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV)
163 #define bfa_iocpf_timer_stop(__ioc)     bfa_timer_stop(&(__ioc)->ioc_timer)
164
165 #define bfa_iocpf_poll_timer_start(__ioc)                               \
166         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
167                         bfa_iocpf_poll_timeout, (__ioc), BFA_IOC_POLL_TOV)
168
169 #define bfa_sem_timer_start(__ioc)                                      \
170         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->sem_timer,        \
171                         bfa_iocpf_sem_timeout, (__ioc), BFA_IOC_HWSEM_TOV)
172 #define bfa_sem_timer_stop(__ioc)       bfa_timer_stop(&(__ioc)->sem_timer)
173
174 /*
175  * Forward declareations for iocpf state machine
176  */
177 static void bfa_iocpf_timeout(void *ioc_arg);
178 static void bfa_iocpf_sem_timeout(void *ioc_arg);
179 static void bfa_iocpf_poll_timeout(void *ioc_arg);
180
181 /*
182  * IOCPF state machine events
183  */
184 enum iocpf_event {
185         IOCPF_E_ENABLE          = 1,    /*  IOCPF enable request        */
186         IOCPF_E_DISABLE         = 2,    /*  IOCPF disable request       */
187         IOCPF_E_STOP            = 3,    /*  stop on driver detach       */
188         IOCPF_E_FWREADY         = 4,    /*  f/w initialization done     */
189         IOCPF_E_FWRSP_ENABLE    = 5,    /*  enable f/w response */
190         IOCPF_E_FWRSP_DISABLE   = 6,    /*  disable f/w response        */
191         IOCPF_E_FAIL            = 7,    /*  failure notice by ioc sm    */
192         IOCPF_E_INITFAIL        = 8,    /*  init fail notice by ioc sm  */
193         IOCPF_E_GETATTRFAIL     = 9,    /*  init fail notice by ioc sm  */
194         IOCPF_E_SEMLOCKED       = 10,   /*  h/w semaphore is locked     */
195         IOCPF_E_TIMEOUT         = 11,   /*  f/w response timeout        */
196         IOCPF_E_SEM_ERROR       = 12,   /*  h/w sem mapping error       */
197 };
198
199 /*
200  * IOCPF states
201  */
202 enum bfa_iocpf_state {
203         BFA_IOCPF_RESET         = 1,    /*  IOC is in reset state */
204         BFA_IOCPF_SEMWAIT       = 2,    /*  Waiting for IOC h/w semaphore */
205         BFA_IOCPF_HWINIT        = 3,    /*  IOC h/w is being initialized */
206         BFA_IOCPF_READY         = 4,    /*  IOCPF is initialized */
207         BFA_IOCPF_INITFAIL      = 5,    /*  IOCPF failed */
208         BFA_IOCPF_FAIL          = 6,    /*  IOCPF failed */
209         BFA_IOCPF_DISABLING     = 7,    /*  IOCPF is being disabled */
210         BFA_IOCPF_DISABLED      = 8,    /*  IOCPF is disabled */
211         BFA_IOCPF_FWMISMATCH    = 9,    /*  IOC f/w different from drivers */
212 };
213
214 bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf_s, enum iocpf_event);
215 bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf_s, enum iocpf_event);
216 bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf_s, enum iocpf_event);
217 bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf_s, enum iocpf_event);
218 bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf_s, enum iocpf_event);
219 bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf_s, enum iocpf_event);
220 bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf_s, enum iocpf_event);
221 bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf_s,
222                                                 enum iocpf_event);
223 bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf_s, enum iocpf_event);
224 bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf_s, enum iocpf_event);
225 bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf_s, enum iocpf_event);
226 bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf_s, enum iocpf_event);
227 bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf_s,
228                                                 enum iocpf_event);
229 bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf_s, enum iocpf_event);
230
231 static struct bfa_sm_table_s iocpf_sm_table[] = {
232         {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET},
233         {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH},
234         {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH},
235         {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT},
236         {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT},
237         {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT},
238         {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY},
239         {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL},
240         {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL},
241         {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL},
242         {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL},
243         {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING},
244         {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING},
245         {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED},
246 };
247
248 /*
249  * IOC State Machine
250  */
251
252 /*
253  * Beginning state. IOC uninit state.
254  */
255
256 static void
257 bfa_ioc_sm_uninit_entry(struct bfa_ioc_s *ioc)
258 {
259 }
260
261 /*
262  * IOC is in uninit state.
263  */
264 static void
265 bfa_ioc_sm_uninit(struct bfa_ioc_s *ioc, enum ioc_event event)
266 {
267         bfa_trc(ioc, event);
268
269         switch (event) {
270         case IOC_E_RESET:
271                 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
272                 break;
273
274         default:
275                 bfa_sm_fault(ioc, event);
276         }
277 }
278 /*
279  * Reset entry actions -- initialize state machine
280  */
281 static void
282 bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc)
283 {
284         bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset);
285 }
286
287 /*
288  * IOC is in reset state.
289  */
290 static void
291 bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event)
292 {
293         bfa_trc(ioc, event);
294
295         switch (event) {
296         case IOC_E_ENABLE:
297                 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
298                 break;
299
300         case IOC_E_DISABLE:
301                 bfa_ioc_disable_comp(ioc);
302                 break;
303
304         case IOC_E_DETACH:
305                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
306                 break;
307
308         default:
309                 bfa_sm_fault(ioc, event);
310         }
311 }
312
313
314 static void
315 bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
316 {
317         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE);
318 }
319
320 /*
321  * Host IOC function is being enabled, awaiting response from firmware.
322  * Semaphore is acquired.
323  */
324 static void
325 bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
326 {
327         bfa_trc(ioc, event);
328
329         switch (event) {
330         case IOC_E_ENABLED:
331                 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
332                 break;
333
334         case IOC_E_PFFAILED:
335                 /* !!! fall through !!! */
336         case IOC_E_HWERROR:
337                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
338                 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
339                 if (event != IOC_E_PFFAILED)
340                         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
341                 break;
342
343         case IOC_E_HWFAILED:
344                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
345                 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
346                 break;
347
348         case IOC_E_DISABLE:
349                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
350                 break;
351
352         case IOC_E_DETACH:
353                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
354                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
355                 break;
356
357         case IOC_E_ENABLE:
358                 break;
359
360         default:
361                 bfa_sm_fault(ioc, event);
362         }
363 }
364
365
366 static void
367 bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc)
368 {
369         bfa_ioc_timer_start(ioc);
370         bfa_ioc_send_getattr(ioc);
371 }
372
373 /*
374  * IOC configuration in progress. Timer is active.
375  */
376 static void
377 bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
378 {
379         bfa_trc(ioc, event);
380
381         switch (event) {
382         case IOC_E_FWRSP_GETATTR:
383                 bfa_ioc_timer_stop(ioc);
384                 bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
385                 break;
386
387         case IOC_E_PFFAILED:
388         case IOC_E_HWERROR:
389                 bfa_ioc_timer_stop(ioc);
390                 fallthrough;
391         case IOC_E_TIMEOUT:
392                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
393                 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
394                 if (event != IOC_E_PFFAILED)
395                         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
396                 break;
397
398         case IOC_E_DISABLE:
399                 bfa_ioc_timer_stop(ioc);
400                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
401                 break;
402
403         case IOC_E_ENABLE:
404                 break;
405
406         default:
407                 bfa_sm_fault(ioc, event);
408         }
409 }
410
411 static void
412 bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
413 {
414         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
415
416         ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
417         bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
418         bfa_ioc_hb_monitor(ioc);
419         BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
420         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE);
421 }
422
423 static void
424 bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
425 {
426         bfa_trc(ioc, event);
427
428         switch (event) {
429         case IOC_E_ENABLE:
430                 break;
431
432         case IOC_E_DISABLE:
433                 bfa_hb_timer_stop(ioc);
434                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
435                 break;
436
437         case IOC_E_PFFAILED:
438         case IOC_E_HWERROR:
439                 bfa_hb_timer_stop(ioc);
440                 fallthrough;
441         case IOC_E_HBFAIL:
442                 if (ioc->iocpf.auto_recover)
443                         bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
444                 else
445                         bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
446
447                 bfa_ioc_fail_notify(ioc);
448
449                 if (event != IOC_E_PFFAILED)
450                         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
451                 break;
452
453         default:
454                 bfa_sm_fault(ioc, event);
455         }
456 }
457
458
459 static void
460 bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
461 {
462         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
463         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
464         BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n");
465         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_DISABLE);
466 }
467
468 /*
469  * IOC is being disabled
470  */
471 static void
472 bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
473 {
474         bfa_trc(ioc, event);
475
476         switch (event) {
477         case IOC_E_DISABLED:
478                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
479                 break;
480
481         case IOC_E_HWERROR:
482                 /*
483                  * No state change.  Will move to disabled state
484                  * after iocpf sm completes failure processing and
485                  * moves to disabled state.
486                  */
487                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
488                 break;
489
490         case IOC_E_HWFAILED:
491                 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
492                 bfa_ioc_disable_comp(ioc);
493                 break;
494
495         default:
496                 bfa_sm_fault(ioc, event);
497         }
498 }
499
500 /*
501  * IOC disable completion entry.
502  */
503 static void
504 bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc)
505 {
506         bfa_ioc_disable_comp(ioc);
507 }
508
509 static void
510 bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
511 {
512         bfa_trc(ioc, event);
513
514         switch (event) {
515         case IOC_E_ENABLE:
516                 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
517                 break;
518
519         case IOC_E_DISABLE:
520                 ioc->cbfn->disable_cbfn(ioc->bfa);
521                 break;
522
523         case IOC_E_DETACH:
524                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
525                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
526                 break;
527
528         default:
529                 bfa_sm_fault(ioc, event);
530         }
531 }
532
533
534 static void
535 bfa_ioc_sm_fail_retry_entry(struct bfa_ioc_s *ioc)
536 {
537         bfa_trc(ioc, 0);
538 }
539
540 /*
541  * Hardware initialization retry.
542  */
543 static void
544 bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event)
545 {
546         bfa_trc(ioc, event);
547
548         switch (event) {
549         case IOC_E_ENABLED:
550                 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
551                 break;
552
553         case IOC_E_PFFAILED:
554         case IOC_E_HWERROR:
555                 /*
556                  * Initialization retry failed.
557                  */
558                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
559                 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
560                 if (event != IOC_E_PFFAILED)
561                         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
562                 break;
563
564         case IOC_E_HWFAILED:
565                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
566                 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
567                 break;
568
569         case IOC_E_ENABLE:
570                 break;
571
572         case IOC_E_DISABLE:
573                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
574                 break;
575
576         case IOC_E_DETACH:
577                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
578                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
579                 break;
580
581         default:
582                 bfa_sm_fault(ioc, event);
583         }
584 }
585
586
587 static void
588 bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc)
589 {
590         bfa_trc(ioc, 0);
591 }
592
593 /*
594  * IOC failure.
595  */
596 static void
597 bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
598 {
599         bfa_trc(ioc, event);
600
601         switch (event) {
602
603         case IOC_E_ENABLE:
604                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
605                 break;
606
607         case IOC_E_DISABLE:
608                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
609                 break;
610
611         case IOC_E_DETACH:
612                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
613                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
614                 break;
615
616         case IOC_E_HWERROR:
617         case IOC_E_HWFAILED:
618                 /*
619                  * HB failure / HW error notification, ignore.
620                  */
621                 break;
622         default:
623                 bfa_sm_fault(ioc, event);
624         }
625 }
626
627 static void
628 bfa_ioc_sm_hwfail_entry(struct bfa_ioc_s *ioc)
629 {
630         bfa_trc(ioc, 0);
631 }
632
633 static void
634 bfa_ioc_sm_hwfail(struct bfa_ioc_s *ioc, enum ioc_event event)
635 {
636         bfa_trc(ioc, event);
637
638         switch (event) {
639         case IOC_E_ENABLE:
640                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
641                 break;
642
643         case IOC_E_DISABLE:
644                 ioc->cbfn->disable_cbfn(ioc->bfa);
645                 break;
646
647         case IOC_E_DETACH:
648                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
649                 break;
650
651         case IOC_E_HWERROR:
652                 /* Ignore - already in hwfail state */
653                 break;
654
655         default:
656                 bfa_sm_fault(ioc, event);
657         }
658 }
659
660 /*
661  * IOCPF State Machine
662  */
663
664 /*
665  * Reset entry actions -- initialize state machine
666  */
667 static void
668 bfa_iocpf_sm_reset_entry(struct bfa_iocpf_s *iocpf)
669 {
670         iocpf->fw_mismatch_notified = BFA_FALSE;
671         iocpf->auto_recover = bfa_auto_recover;
672 }
673
674 /*
675  * Beginning state. IOC is in reset state.
676  */
677 static void
678 bfa_iocpf_sm_reset(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
679 {
680         struct bfa_ioc_s *ioc = iocpf->ioc;
681
682         bfa_trc(ioc, event);
683
684         switch (event) {
685         case IOCPF_E_ENABLE:
686                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
687                 break;
688
689         case IOCPF_E_STOP:
690                 break;
691
692         default:
693                 bfa_sm_fault(ioc, event);
694         }
695 }
696
697 /*
698  * Semaphore should be acquired for version check.
699  */
700 static void
701 bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf)
702 {
703         struct bfi_ioc_image_hdr_s      fwhdr;
704         u32     r32, fwstate, pgnum, loff = 0;
705         int     i;
706
707         /*
708          * Spin on init semaphore to serialize.
709          */
710         r32 = readl(iocpf->ioc->ioc_regs.ioc_init_sem_reg);
711         while (r32 & 0x1) {
712                 udelay(20);
713                 r32 = readl(iocpf->ioc->ioc_regs.ioc_init_sem_reg);
714         }
715
716         /* h/w sem init */
717         fwstate = bfa_ioc_get_cur_ioc_fwstate(iocpf->ioc);
718         if (fwstate == BFI_IOC_UNINIT) {
719                 writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
720                 goto sem_get;
721         }
722
723         bfa_ioc_fwver_get(iocpf->ioc, &fwhdr);
724
725         if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) {
726                 writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
727                 goto sem_get;
728         }
729
730         /*
731          * Clear fwver hdr
732          */
733         pgnum = PSS_SMEM_PGNUM(iocpf->ioc->ioc_regs.smem_pg0, loff);
734         writel(pgnum, iocpf->ioc->ioc_regs.host_page_num_fn);
735
736         for (i = 0; i < sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32); i++) {
737                 bfa_mem_write(iocpf->ioc->ioc_regs.smem_page_start, loff, 0);
738                 loff += sizeof(u32);
739         }
740
741         bfa_trc(iocpf->ioc, fwstate);
742         bfa_trc(iocpf->ioc, swab32(fwhdr.exec));
743         bfa_ioc_set_cur_ioc_fwstate(iocpf->ioc, BFI_IOC_UNINIT);
744         bfa_ioc_set_alt_ioc_fwstate(iocpf->ioc, BFI_IOC_UNINIT);
745
746         /*
747          * Unlock the hw semaphore. Should be here only once per boot.
748          */
749         bfa_ioc_ownership_reset(iocpf->ioc);
750
751         /*
752          * unlock init semaphore.
753          */
754         writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
755
756 sem_get:
757         bfa_ioc_hw_sem_get(iocpf->ioc);
758 }
759
760 /*
761  * Awaiting h/w semaphore to continue with version check.
762  */
763 static void
764 bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
765 {
766         struct bfa_ioc_s *ioc = iocpf->ioc;
767
768         bfa_trc(ioc, event);
769
770         switch (event) {
771         case IOCPF_E_SEMLOCKED:
772                 if (bfa_ioc_firmware_lock(ioc)) {
773                         if (bfa_ioc_sync_start(ioc)) {
774                                 bfa_ioc_sync_join(ioc);
775                                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
776                         } else {
777                                 bfa_ioc_firmware_unlock(ioc);
778                                 writel(1, ioc->ioc_regs.ioc_sem_reg);
779                                 bfa_sem_timer_start(ioc);
780                         }
781                 } else {
782                         writel(1, ioc->ioc_regs.ioc_sem_reg);
783                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch);
784                 }
785                 break;
786
787         case IOCPF_E_SEM_ERROR:
788                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
789                 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
790                 break;
791
792         case IOCPF_E_DISABLE:
793                 bfa_sem_timer_stop(ioc);
794                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
795                 bfa_fsm_send_event(ioc, IOC_E_DISABLED);
796                 break;
797
798         case IOCPF_E_STOP:
799                 bfa_sem_timer_stop(ioc);
800                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
801                 break;
802
803         default:
804                 bfa_sm_fault(ioc, event);
805         }
806 }
807
808 /*
809  * Notify enable completion callback.
810  */
811 static void
812 bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf_s *iocpf)
813 {
814         /*
815          * Call only the first time sm enters fwmismatch state.
816          */
817         if (iocpf->fw_mismatch_notified == BFA_FALSE)
818                 bfa_ioc_pf_fwmismatch(iocpf->ioc);
819
820         iocpf->fw_mismatch_notified = BFA_TRUE;
821         bfa_iocpf_timer_start(iocpf->ioc);
822 }
823
824 /*
825  * Awaiting firmware version match.
826  */
827 static void
828 bfa_iocpf_sm_mismatch(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
829 {
830         struct bfa_ioc_s *ioc = iocpf->ioc;
831
832         bfa_trc(ioc, event);
833
834         switch (event) {
835         case IOCPF_E_TIMEOUT:
836                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
837                 break;
838
839         case IOCPF_E_DISABLE:
840                 bfa_iocpf_timer_stop(ioc);
841                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
842                 bfa_fsm_send_event(ioc, IOC_E_DISABLED);
843                 break;
844
845         case IOCPF_E_STOP:
846                 bfa_iocpf_timer_stop(ioc);
847                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
848                 break;
849
850         default:
851                 bfa_sm_fault(ioc, event);
852         }
853 }
854
855 /*
856  * Request for semaphore.
857  */
858 static void
859 bfa_iocpf_sm_semwait_entry(struct bfa_iocpf_s *iocpf)
860 {
861         bfa_ioc_hw_sem_get(iocpf->ioc);
862 }
863
864 /*
865  * Awaiting semaphore for h/w initialzation.
866  */
867 static void
868 bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
869 {
870         struct bfa_ioc_s *ioc = iocpf->ioc;
871
872         bfa_trc(ioc, event);
873
874         switch (event) {
875         case IOCPF_E_SEMLOCKED:
876                 if (bfa_ioc_sync_complete(ioc)) {
877                         bfa_ioc_sync_join(ioc);
878                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
879                 } else {
880                         writel(1, ioc->ioc_regs.ioc_sem_reg);
881                         bfa_sem_timer_start(ioc);
882                 }
883                 break;
884
885         case IOCPF_E_SEM_ERROR:
886                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
887                 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
888                 break;
889
890         case IOCPF_E_DISABLE:
891                 bfa_sem_timer_stop(ioc);
892                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
893                 break;
894
895         default:
896                 bfa_sm_fault(ioc, event);
897         }
898 }
899
900 static void
901 bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf)
902 {
903         iocpf->poll_time = 0;
904         bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE);
905 }
906
907 /*
908  * Hardware is being initialized. Interrupts are enabled.
909  * Holding hardware semaphore lock.
910  */
911 static void
912 bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
913 {
914         struct bfa_ioc_s *ioc = iocpf->ioc;
915
916         bfa_trc(ioc, event);
917
918         switch (event) {
919         case IOCPF_E_FWREADY:
920                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling);
921                 break;
922
923         case IOCPF_E_TIMEOUT:
924                 writel(1, ioc->ioc_regs.ioc_sem_reg);
925                 bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
926                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
927                 break;
928
929         case IOCPF_E_DISABLE:
930                 bfa_iocpf_timer_stop(ioc);
931                 bfa_ioc_sync_leave(ioc);
932                 writel(1, ioc->ioc_regs.ioc_sem_reg);
933                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
934                 break;
935
936         default:
937                 bfa_sm_fault(ioc, event);
938         }
939 }
940
941 static void
942 bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf)
943 {
944         bfa_iocpf_timer_start(iocpf->ioc);
945         /*
946          * Enable Interrupts before sending fw IOC ENABLE cmd.
947          */
948         iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa);
949         bfa_ioc_send_enable(iocpf->ioc);
950 }
951
952 /*
953  * Host IOC function is being enabled, awaiting response from firmware.
954  * Semaphore is acquired.
955  */
956 static void
957 bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
958 {
959         struct bfa_ioc_s *ioc = iocpf->ioc;
960
961         bfa_trc(ioc, event);
962
963         switch (event) {
964         case IOCPF_E_FWRSP_ENABLE:
965                 bfa_iocpf_timer_stop(ioc);
966                 writel(1, ioc->ioc_regs.ioc_sem_reg);
967                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready);
968                 break;
969
970         case IOCPF_E_INITFAIL:
971                 bfa_iocpf_timer_stop(ioc);
972                 fallthrough;
973
974         case IOCPF_E_TIMEOUT:
975                 writel(1, ioc->ioc_regs.ioc_sem_reg);
976                 if (event == IOCPF_E_TIMEOUT)
977                         bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
978                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
979                 break;
980
981         case IOCPF_E_DISABLE:
982                 bfa_iocpf_timer_stop(ioc);
983                 writel(1, ioc->ioc_regs.ioc_sem_reg);
984                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
985                 break;
986
987         default:
988                 bfa_sm_fault(ioc, event);
989         }
990 }
991
992 static void
993 bfa_iocpf_sm_ready_entry(struct bfa_iocpf_s *iocpf)
994 {
995         bfa_fsm_send_event(iocpf->ioc, IOC_E_ENABLED);
996 }
997
998 static void
999 bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1000 {
1001         struct bfa_ioc_s *ioc = iocpf->ioc;
1002
1003         bfa_trc(ioc, event);
1004
1005         switch (event) {
1006         case IOCPF_E_DISABLE:
1007                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
1008                 break;
1009
1010         case IOCPF_E_GETATTRFAIL:
1011                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
1012                 break;
1013
1014         case IOCPF_E_FAIL:
1015                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
1016                 break;
1017
1018         default:
1019                 bfa_sm_fault(ioc, event);
1020         }
1021 }
1022
1023 static void
1024 bfa_iocpf_sm_disabling_entry(struct bfa_iocpf_s *iocpf)
1025 {
1026         bfa_iocpf_timer_start(iocpf->ioc);
1027         bfa_ioc_send_disable(iocpf->ioc);
1028 }
1029
1030 /*
1031  * IOC is being disabled
1032  */
1033 static void
1034 bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1035 {
1036         struct bfa_ioc_s *ioc = iocpf->ioc;
1037
1038         bfa_trc(ioc, event);
1039
1040         switch (event) {
1041         case IOCPF_E_FWRSP_DISABLE:
1042                 bfa_iocpf_timer_stop(ioc);
1043                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1044                 break;
1045
1046         case IOCPF_E_FAIL:
1047                 bfa_iocpf_timer_stop(ioc);
1048                 fallthrough;
1049
1050         case IOCPF_E_TIMEOUT:
1051                 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
1052                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1053                 break;
1054
1055         case IOCPF_E_FWRSP_ENABLE:
1056                 break;
1057
1058         default:
1059                 bfa_sm_fault(ioc, event);
1060         }
1061 }
1062
1063 static void
1064 bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf_s *iocpf)
1065 {
1066         bfa_ioc_hw_sem_get(iocpf->ioc);
1067 }
1068
1069 /*
1070  * IOC hb ack request is being removed.
1071  */
1072 static void
1073 bfa_iocpf_sm_disabling_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1074 {
1075         struct bfa_ioc_s *ioc = iocpf->ioc;
1076
1077         bfa_trc(ioc, event);
1078
1079         switch (event) {
1080         case IOCPF_E_SEMLOCKED:
1081                 bfa_ioc_sync_leave(ioc);
1082                 writel(1, ioc->ioc_regs.ioc_sem_reg);
1083                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1084                 break;
1085
1086         case IOCPF_E_SEM_ERROR:
1087                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1088                 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1089                 break;
1090
1091         case IOCPF_E_FAIL:
1092                 break;
1093
1094         default:
1095                 bfa_sm_fault(ioc, event);
1096         }
1097 }
1098
1099 /*
1100  * IOC disable completion entry.
1101  */
1102 static void
1103 bfa_iocpf_sm_disabled_entry(struct bfa_iocpf_s *iocpf)
1104 {
1105         bfa_ioc_mbox_flush(iocpf->ioc);
1106         bfa_fsm_send_event(iocpf->ioc, IOC_E_DISABLED);
1107 }
1108
1109 static void
1110 bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1111 {
1112         struct bfa_ioc_s *ioc = iocpf->ioc;
1113
1114         bfa_trc(ioc, event);
1115
1116         switch (event) {
1117         case IOCPF_E_ENABLE:
1118                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
1119                 break;
1120
1121         case IOCPF_E_STOP:
1122                 bfa_ioc_firmware_unlock(ioc);
1123                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
1124                 break;
1125
1126         default:
1127                 bfa_sm_fault(ioc, event);
1128         }
1129 }
1130
1131 static void
1132 bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf)
1133 {
1134         bfa_ioc_debug_save_ftrc(iocpf->ioc);
1135         bfa_ioc_hw_sem_get(iocpf->ioc);
1136 }
1137
1138 /*
1139  * Hardware initialization failed.
1140  */
1141 static void
1142 bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1143 {
1144         struct bfa_ioc_s *ioc = iocpf->ioc;
1145
1146         bfa_trc(ioc, event);
1147
1148         switch (event) {
1149         case IOCPF_E_SEMLOCKED:
1150                 bfa_ioc_notify_fail(ioc);
1151                 bfa_ioc_sync_leave(ioc);
1152                 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
1153                 writel(1, ioc->ioc_regs.ioc_sem_reg);
1154                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
1155                 break;
1156
1157         case IOCPF_E_SEM_ERROR:
1158                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1159                 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1160                 break;
1161
1162         case IOCPF_E_DISABLE:
1163                 bfa_sem_timer_stop(ioc);
1164                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1165                 break;
1166
1167         case IOCPF_E_STOP:
1168                 bfa_sem_timer_stop(ioc);
1169                 bfa_ioc_firmware_unlock(ioc);
1170                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
1171                 break;
1172
1173         case IOCPF_E_FAIL:
1174                 break;
1175
1176         default:
1177                 bfa_sm_fault(ioc, event);
1178         }
1179 }
1180
1181 static void
1182 bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf)
1183 {
1184         bfa_trc(iocpf->ioc, 0);
1185 }
1186
1187 /*
1188  * Hardware initialization failed.
1189  */
1190 static void
1191 bfa_iocpf_sm_initfail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1192 {
1193         struct bfa_ioc_s *ioc = iocpf->ioc;
1194
1195         bfa_trc(ioc, event);
1196
1197         switch (event) {
1198         case IOCPF_E_DISABLE:
1199                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1200                 break;
1201
1202         case IOCPF_E_STOP:
1203                 bfa_ioc_firmware_unlock(ioc);
1204                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
1205                 break;
1206
1207         default:
1208                 bfa_sm_fault(ioc, event);
1209         }
1210 }
1211
1212 static void
1213 bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf_s *iocpf)
1214 {
1215         /*
1216          * Mark IOC as failed in hardware and stop firmware.
1217          */
1218         bfa_ioc_lpu_stop(iocpf->ioc);
1219
1220         /*
1221          * Flush any queued up mailbox requests.
1222          */
1223         bfa_ioc_mbox_flush(iocpf->ioc);
1224
1225         bfa_ioc_hw_sem_get(iocpf->ioc);
1226 }
1227
1228 static void
1229 bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1230 {
1231         struct bfa_ioc_s *ioc = iocpf->ioc;
1232
1233         bfa_trc(ioc, event);
1234
1235         switch (event) {
1236         case IOCPF_E_SEMLOCKED:
1237                 bfa_ioc_sync_ack(ioc);
1238                 bfa_ioc_notify_fail(ioc);
1239                 if (!iocpf->auto_recover) {
1240                         bfa_ioc_sync_leave(ioc);
1241                         bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
1242                         writel(1, ioc->ioc_regs.ioc_sem_reg);
1243                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1244                 } else {
1245                         if (bfa_ioc_sync_complete(ioc))
1246                                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
1247                         else {
1248                                 writel(1, ioc->ioc_regs.ioc_sem_reg);
1249                                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
1250                         }
1251                 }
1252                 break;
1253
1254         case IOCPF_E_SEM_ERROR:
1255                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1256                 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1257                 break;
1258
1259         case IOCPF_E_DISABLE:
1260                 bfa_sem_timer_stop(ioc);
1261                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1262                 break;
1263
1264         case IOCPF_E_FAIL:
1265                 break;
1266
1267         default:
1268                 bfa_sm_fault(ioc, event);
1269         }
1270 }
1271
1272 static void
1273 bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
1274 {
1275         bfa_trc(iocpf->ioc, 0);
1276 }
1277
1278 /*
1279  * IOC is in failed state.
1280  */
1281 static void
1282 bfa_iocpf_sm_fail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1283 {
1284         struct bfa_ioc_s *ioc = iocpf->ioc;
1285
1286         bfa_trc(ioc, event);
1287
1288         switch (event) {
1289         case IOCPF_E_DISABLE:
1290                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1291                 break;
1292
1293         default:
1294                 bfa_sm_fault(ioc, event);
1295         }
1296 }
1297
1298 /*
1299  *  BFA IOC private functions
1300  */
1301
1302 /*
1303  * Notify common modules registered for notification.
1304  */
1305 static void
1306 bfa_ioc_event_notify(struct bfa_ioc_s *ioc, enum bfa_ioc_event_e event)
1307 {
1308         struct bfa_ioc_notify_s *notify;
1309         struct list_head        *qe;
1310
1311         list_for_each(qe, &ioc->notify_q) {
1312                 notify = (struct bfa_ioc_notify_s *)qe;
1313                 notify->cbfn(notify->cbarg, event);
1314         }
1315 }
1316
1317 static void
1318 bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
1319 {
1320         ioc->cbfn->disable_cbfn(ioc->bfa);
1321         bfa_ioc_event_notify(ioc, BFA_IOC_E_DISABLED);
1322 }
1323
1324 bfa_boolean_t
1325 bfa_ioc_sem_get(void __iomem *sem_reg)
1326 {
1327         u32 r32;
1328         int cnt = 0;
1329 #define BFA_SEM_SPINCNT 3000
1330
1331         r32 = readl(sem_reg);
1332
1333         while ((r32 & 1) && (cnt < BFA_SEM_SPINCNT)) {
1334                 cnt++;
1335                 udelay(2);
1336                 r32 = readl(sem_reg);
1337         }
1338
1339         if (!(r32 & 1))
1340                 return BFA_TRUE;
1341
1342         return BFA_FALSE;
1343 }
1344
1345 static void
1346 bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
1347 {
1348         u32     r32;
1349
1350         /*
1351          * First read to the semaphore register will return 0, subsequent reads
1352          * will return 1. Semaphore is released by writing 1 to the register
1353          */
1354         r32 = readl(ioc->ioc_regs.ioc_sem_reg);
1355         if (r32 == ~0) {
1356                 WARN_ON(r32 == ~0);
1357                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEM_ERROR);
1358                 return;
1359         }
1360         if (!(r32 & 1)) {
1361                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED);
1362                 return;
1363         }
1364
1365         bfa_sem_timer_start(ioc);
1366 }
1367
1368 /*
1369  * Initialize LPU local memory (aka secondary memory / SRAM)
1370  */
1371 static void
1372 bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
1373 {
1374         u32     pss_ctl;
1375         int             i;
1376 #define PSS_LMEM_INIT_TIME  10000
1377
1378         pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1379         pss_ctl &= ~__PSS_LMEM_RESET;
1380         pss_ctl |= __PSS_LMEM_INIT_EN;
1381
1382         /*
1383          * i2c workaround 12.5khz clock
1384          */
1385         pss_ctl |= __PSS_I2C_CLK_DIV(3UL);
1386         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1387
1388         /*
1389          * wait for memory initialization to be complete
1390          */
1391         i = 0;
1392         do {
1393                 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1394                 i++;
1395         } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
1396
1397         /*
1398          * If memory initialization is not successful, IOC timeout will catch
1399          * such failures.
1400          */
1401         WARN_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE));
1402         bfa_trc(ioc, pss_ctl);
1403
1404         pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
1405         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1406 }
1407
1408 static void
1409 bfa_ioc_lpu_start(struct bfa_ioc_s *ioc)
1410 {
1411         u32     pss_ctl;
1412
1413         /*
1414          * Take processor out of reset.
1415          */
1416         pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1417         pss_ctl &= ~__PSS_LPU0_RESET;
1418
1419         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1420 }
1421
1422 static void
1423 bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
1424 {
1425         u32     pss_ctl;
1426
1427         /*
1428          * Put processors in reset.
1429          */
1430         pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1431         pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
1432
1433         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1434 }
1435
1436 /*
1437  * Get driver and firmware versions.
1438  */
1439 void
1440 bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
1441 {
1442         u32     pgnum;
1443         u32     loff = 0;
1444         int             i;
1445         u32     *fwsig = (u32 *) fwhdr;
1446
1447         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1448         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1449
1450         for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
1451              i++) {
1452                 fwsig[i] =
1453                         bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
1454                 loff += sizeof(u32);
1455         }
1456 }
1457
1458 /*
1459  * Returns TRUE if driver is willing to work with current smem f/w version.
1460  */
1461 bfa_boolean_t
1462 bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
1463                 struct bfi_ioc_image_hdr_s *smem_fwhdr)
1464 {
1465         struct bfi_ioc_image_hdr_s *drv_fwhdr;
1466         enum bfi_ioc_img_ver_cmp_e smem_flash_cmp, drv_smem_cmp;
1467
1468         drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
1469                 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
1470
1471         /*
1472          * If smem is incompatible or old, driver should not work with it.
1473          */
1474         drv_smem_cmp = bfa_ioc_fw_ver_patch_cmp(drv_fwhdr, smem_fwhdr);
1475         if (drv_smem_cmp == BFI_IOC_IMG_VER_INCOMP ||
1476                 drv_smem_cmp == BFI_IOC_IMG_VER_OLD) {
1477                 return BFA_FALSE;
1478         }
1479
1480         /*
1481          * IF Flash has a better F/W than smem do not work with smem.
1482          * If smem f/w == flash f/w, as smem f/w not old | incmp, work with it.
1483          * If Flash is old or incomp work with smem iff smem f/w == drv f/w.
1484          */
1485         smem_flash_cmp = bfa_ioc_flash_fwver_cmp(ioc, smem_fwhdr);
1486
1487         if (smem_flash_cmp == BFI_IOC_IMG_VER_BETTER) {
1488                 return BFA_FALSE;
1489         } else if (smem_flash_cmp == BFI_IOC_IMG_VER_SAME) {
1490                 return BFA_TRUE;
1491         } else {
1492                 return (drv_smem_cmp == BFI_IOC_IMG_VER_SAME) ?
1493                         BFA_TRUE : BFA_FALSE;
1494         }
1495 }
1496
1497 /*
1498  * Return true if current running version is valid. Firmware signature and
1499  * execution context (driver/bios) must match.
1500  */
1501 static bfa_boolean_t
1502 bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
1503 {
1504         struct bfi_ioc_image_hdr_s fwhdr;
1505
1506         bfa_ioc_fwver_get(ioc, &fwhdr);
1507
1508         if (swab32(fwhdr.bootenv) != boot_env) {
1509                 bfa_trc(ioc, fwhdr.bootenv);
1510                 bfa_trc(ioc, boot_env);
1511                 return BFA_FALSE;
1512         }
1513
1514         return bfa_ioc_fwver_cmp(ioc, &fwhdr);
1515 }
1516
1517 static bfa_boolean_t
1518 bfa_ioc_fwver_md5_check(struct bfi_ioc_image_hdr_s *fwhdr_1,
1519                                 struct bfi_ioc_image_hdr_s *fwhdr_2)
1520 {
1521         int i;
1522
1523         for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++)
1524                 if (fwhdr_1->md5sum[i] != fwhdr_2->md5sum[i])
1525                         return BFA_FALSE;
1526
1527         return BFA_TRUE;
1528 }
1529
1530 /*
1531  * Returns TRUE if major minor and maintainence are same.
1532  * If patch versions are same, check for MD5 Checksum to be same.
1533  */
1534 static bfa_boolean_t
1535 bfa_ioc_fw_ver_compatible(struct bfi_ioc_image_hdr_s *drv_fwhdr,
1536                                 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp)
1537 {
1538         if (drv_fwhdr->signature != fwhdr_to_cmp->signature)
1539                 return BFA_FALSE;
1540
1541         if (drv_fwhdr->fwver.major != fwhdr_to_cmp->fwver.major)
1542                 return BFA_FALSE;
1543
1544         if (drv_fwhdr->fwver.minor != fwhdr_to_cmp->fwver.minor)
1545                 return BFA_FALSE;
1546
1547         if (drv_fwhdr->fwver.maint != fwhdr_to_cmp->fwver.maint)
1548                 return BFA_FALSE;
1549
1550         if (drv_fwhdr->fwver.patch == fwhdr_to_cmp->fwver.patch &&
1551                 drv_fwhdr->fwver.phase == fwhdr_to_cmp->fwver.phase &&
1552                 drv_fwhdr->fwver.build == fwhdr_to_cmp->fwver.build) {
1553                 return bfa_ioc_fwver_md5_check(drv_fwhdr, fwhdr_to_cmp);
1554         }
1555
1556         return BFA_TRUE;
1557 }
1558
1559 static bfa_boolean_t
1560 bfa_ioc_flash_fwver_valid(struct bfi_ioc_image_hdr_s *flash_fwhdr)
1561 {
1562         if (flash_fwhdr->fwver.major == 0 || flash_fwhdr->fwver.major == 0xFF)
1563                 return BFA_FALSE;
1564
1565         return BFA_TRUE;
1566 }
1567
1568 static bfa_boolean_t fwhdr_is_ga(struct bfi_ioc_image_hdr_s *fwhdr)
1569 {
1570         if (fwhdr->fwver.phase == 0 &&
1571                 fwhdr->fwver.build == 0)
1572                 return BFA_TRUE;
1573
1574         return BFA_FALSE;
1575 }
1576
1577 /*
1578  * Returns TRUE if both are compatible and patch of fwhdr_to_cmp is better.
1579  */
1580 static enum bfi_ioc_img_ver_cmp_e
1581 bfa_ioc_fw_ver_patch_cmp(struct bfi_ioc_image_hdr_s *base_fwhdr,
1582                                 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp)
1583 {
1584         if (bfa_ioc_fw_ver_compatible(base_fwhdr, fwhdr_to_cmp) == BFA_FALSE)
1585                 return BFI_IOC_IMG_VER_INCOMP;
1586
1587         if (fwhdr_to_cmp->fwver.patch > base_fwhdr->fwver.patch)
1588                 return BFI_IOC_IMG_VER_BETTER;
1589
1590         else if (fwhdr_to_cmp->fwver.patch < base_fwhdr->fwver.patch)
1591                 return BFI_IOC_IMG_VER_OLD;
1592
1593         /*
1594          * GA takes priority over internal builds of the same patch stream.
1595          * At this point major minor maint and patch numbers are same.
1596          */
1597
1598         if (fwhdr_is_ga(base_fwhdr) == BFA_TRUE) {
1599                 if (fwhdr_is_ga(fwhdr_to_cmp))
1600                         return BFI_IOC_IMG_VER_SAME;
1601                 else
1602                         return BFI_IOC_IMG_VER_OLD;
1603         } else {
1604                 if (fwhdr_is_ga(fwhdr_to_cmp))
1605                         return BFI_IOC_IMG_VER_BETTER;
1606         }
1607
1608         if (fwhdr_to_cmp->fwver.phase > base_fwhdr->fwver.phase)
1609                 return BFI_IOC_IMG_VER_BETTER;
1610         else if (fwhdr_to_cmp->fwver.phase < base_fwhdr->fwver.phase)
1611                 return BFI_IOC_IMG_VER_OLD;
1612
1613         if (fwhdr_to_cmp->fwver.build > base_fwhdr->fwver.build)
1614                 return BFI_IOC_IMG_VER_BETTER;
1615         else if (fwhdr_to_cmp->fwver.build < base_fwhdr->fwver.build)
1616                 return BFI_IOC_IMG_VER_OLD;
1617
1618         /*
1619          * All Version Numbers are equal.
1620          * Md5 check to be done as a part of compatibility check.
1621          */
1622         return BFI_IOC_IMG_VER_SAME;
1623 }
1624
1625 #define BFA_FLASH_PART_FWIMG_ADDR       0x100000 /* fw image address */
1626
1627 bfa_status_t
1628 bfa_ioc_flash_img_get_chnk(struct bfa_ioc_s *ioc, u32 off,
1629                                 u32 *fwimg)
1630 {
1631         return bfa_flash_raw_read(ioc->pcidev.pci_bar_kva,
1632                         BFA_FLASH_PART_FWIMG_ADDR + (off * sizeof(u32)),
1633                         (char *)fwimg, BFI_FLASH_CHUNK_SZ);
1634 }
1635
1636 static enum bfi_ioc_img_ver_cmp_e
1637 bfa_ioc_flash_fwver_cmp(struct bfa_ioc_s *ioc,
1638                         struct bfi_ioc_image_hdr_s *base_fwhdr)
1639 {
1640         struct bfi_ioc_image_hdr_s *flash_fwhdr;
1641         bfa_status_t status;
1642         u32 fwimg[BFI_FLASH_CHUNK_SZ_WORDS];
1643
1644         status = bfa_ioc_flash_img_get_chnk(ioc, 0, fwimg);
1645         if (status != BFA_STATUS_OK)
1646                 return BFI_IOC_IMG_VER_INCOMP;
1647
1648         flash_fwhdr = (struct bfi_ioc_image_hdr_s *) fwimg;
1649         if (bfa_ioc_flash_fwver_valid(flash_fwhdr) == BFA_TRUE)
1650                 return bfa_ioc_fw_ver_patch_cmp(base_fwhdr, flash_fwhdr);
1651         else
1652                 return BFI_IOC_IMG_VER_INCOMP;
1653 }
1654
1655
1656 /*
1657  * Invalidate fwver signature
1658  */
1659 bfa_status_t
1660 bfa_ioc_fwsig_invalidate(struct bfa_ioc_s *ioc)
1661 {
1662
1663         u32     pgnum;
1664         u32     loff = 0;
1665         enum bfi_ioc_state ioc_fwstate;
1666
1667         ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
1668         if (!bfa_ioc_state_disabled(ioc_fwstate))
1669                 return BFA_STATUS_ADAPTER_ENABLED;
1670
1671         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1672         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1673         bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, BFA_IOC_FW_INV_SIGN);
1674
1675         return BFA_STATUS_OK;
1676 }
1677
1678 /*
1679  * Conditionally flush any pending message from firmware at start.
1680  */
1681 static void
1682 bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
1683 {
1684         u32     r32;
1685
1686         r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
1687         if (r32)
1688                 writel(1, ioc->ioc_regs.lpu_mbox_cmd);
1689 }
1690
1691 static void
1692 bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1693 {
1694         enum bfi_ioc_state ioc_fwstate;
1695         bfa_boolean_t fwvalid;
1696         u32 boot_type;
1697         u32 boot_env;
1698
1699         ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
1700
1701         if (force)
1702                 ioc_fwstate = BFI_IOC_UNINIT;
1703
1704         bfa_trc(ioc, ioc_fwstate);
1705
1706         boot_type = BFI_FWBOOT_TYPE_NORMAL;
1707         boot_env = BFI_FWBOOT_ENV_OS;
1708
1709         /*
1710          * check if firmware is valid
1711          */
1712         fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
1713                 BFA_FALSE : bfa_ioc_fwver_valid(ioc, boot_env);
1714
1715         if (!fwvalid) {
1716                 if (bfa_ioc_boot(ioc, boot_type, boot_env) == BFA_STATUS_OK)
1717                         bfa_ioc_poll_fwinit(ioc);
1718                 return;
1719         }
1720
1721         /*
1722          * If hardware initialization is in progress (initialized by other IOC),
1723          * just wait for an initialization completion interrupt.
1724          */
1725         if (ioc_fwstate == BFI_IOC_INITING) {
1726                 bfa_ioc_poll_fwinit(ioc);
1727                 return;
1728         }
1729
1730         /*
1731          * If IOC function is disabled and firmware version is same,
1732          * just re-enable IOC.
1733          *
1734          * If option rom, IOC must not be in operational state. With
1735          * convergence, IOC will be in operational state when 2nd driver
1736          * is loaded.
1737          */
1738         if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
1739
1740                 /*
1741                  * When using MSI-X any pending firmware ready event should
1742                  * be flushed. Otherwise MSI-X interrupts are not delivered.
1743                  */
1744                 bfa_ioc_msgflush(ioc);
1745                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
1746                 return;
1747         }
1748
1749         /*
1750          * Initialize the h/w for any other states.
1751          */
1752         if (bfa_ioc_boot(ioc, boot_type, boot_env) == BFA_STATUS_OK)
1753                 bfa_ioc_poll_fwinit(ioc);
1754 }
1755
1756 static void
1757 bfa_ioc_timeout(void *ioc_arg)
1758 {
1759         struct bfa_ioc_s  *ioc = (struct bfa_ioc_s *) ioc_arg;
1760
1761         bfa_trc(ioc, 0);
1762         bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
1763 }
1764
1765 void
1766 bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len)
1767 {
1768         u32 *msgp = (u32 *) ioc_msg;
1769         u32 i;
1770
1771         bfa_trc(ioc, msgp[0]);
1772         bfa_trc(ioc, len);
1773
1774         WARN_ON(len > BFI_IOC_MSGLEN_MAX);
1775
1776         /*
1777          * first write msg to mailbox registers
1778          */
1779         for (i = 0; i < len / sizeof(u32); i++)
1780                 writel(cpu_to_le32(msgp[i]),
1781                         ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
1782
1783         for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
1784                 writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
1785
1786         /*
1787          * write 1 to mailbox CMD to trigger LPU event
1788          */
1789         writel(1, ioc->ioc_regs.hfn_mbox_cmd);
1790         (void) readl(ioc->ioc_regs.hfn_mbox_cmd);
1791 }
1792
1793 static void
1794 bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
1795 {
1796         struct bfi_ioc_ctrl_req_s enable_req;
1797
1798         bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
1799                     bfa_ioc_portid(ioc));
1800         enable_req.clscode = cpu_to_be16(ioc->clscode);
1801         /* unsigned 32-bit time_t overflow in y2106 */
1802         enable_req.tv_sec = be32_to_cpu(ktime_get_real_seconds());
1803         bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1804 }
1805
1806 static void
1807 bfa_ioc_send_disable(struct bfa_ioc_s *ioc)
1808 {
1809         struct bfi_ioc_ctrl_req_s disable_req;
1810
1811         bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
1812                     bfa_ioc_portid(ioc));
1813         disable_req.clscode = cpu_to_be16(ioc->clscode);
1814         /* unsigned 32-bit time_t overflow in y2106 */
1815         disable_req.tv_sec = be32_to_cpu(ktime_get_real_seconds());
1816         bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1817 }
1818
1819 static void
1820 bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
1821 {
1822         struct bfi_ioc_getattr_req_s    attr_req;
1823
1824         bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
1825                     bfa_ioc_portid(ioc));
1826         bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
1827         bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
1828 }
1829
1830 static void
1831 bfa_ioc_hb_check(void *cbarg)
1832 {
1833         struct bfa_ioc_s  *ioc = cbarg;
1834         u32     hb_count;
1835
1836         hb_count = readl(ioc->ioc_regs.heartbeat);
1837         if (ioc->hb_count == hb_count) {
1838                 bfa_ioc_recover(ioc);
1839                 return;
1840         } else {
1841                 ioc->hb_count = hb_count;
1842         }
1843
1844         bfa_ioc_mbox_poll(ioc);
1845         bfa_hb_timer_start(ioc);
1846 }
1847
1848 static void
1849 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
1850 {
1851         ioc->hb_count = readl(ioc->ioc_regs.heartbeat);
1852         bfa_hb_timer_start(ioc);
1853 }
1854
1855 /*
1856  *      Initiate a full firmware download.
1857  */
1858 static bfa_status_t
1859 bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1860                     u32 boot_env)
1861 {
1862         u32 *fwimg;
1863         u32 pgnum;
1864         u32 loff = 0;
1865         u32 chunkno = 0;
1866         u32 i;
1867         u32 asicmode;
1868         u32 fwimg_size;
1869         u32 fwimg_buf[BFI_FLASH_CHUNK_SZ_WORDS];
1870         bfa_status_t status;
1871
1872         if (boot_env == BFI_FWBOOT_ENV_OS &&
1873                 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1874                 fwimg_size = BFI_FLASH_IMAGE_SZ/sizeof(u32);
1875
1876                 status = bfa_ioc_flash_img_get_chnk(ioc,
1877                         BFA_IOC_FLASH_CHUNK_ADDR(chunkno), fwimg_buf);
1878                 if (status != BFA_STATUS_OK)
1879                         return status;
1880
1881                 fwimg = fwimg_buf;
1882         } else {
1883                 fwimg_size = bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc));
1884                 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc),
1885                                         BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1886         }
1887
1888         bfa_trc(ioc, fwimg_size);
1889
1890
1891         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1892         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1893
1894         for (i = 0; i < fwimg_size; i++) {
1895
1896                 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
1897                         chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
1898
1899                         if (boot_env == BFI_FWBOOT_ENV_OS &&
1900                                 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1901                                 status = bfa_ioc_flash_img_get_chnk(ioc,
1902                                         BFA_IOC_FLASH_CHUNK_ADDR(chunkno),
1903                                         fwimg_buf);
1904                                 if (status != BFA_STATUS_OK)
1905                                         return status;
1906
1907                                 fwimg = fwimg_buf;
1908                         } else {
1909                                 fwimg = bfa_cb_image_get_chunk(
1910                                         bfa_ioc_asic_gen(ioc),
1911                                         BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1912                         }
1913                 }
1914
1915                 /*
1916                  * write smem
1917                  */
1918                 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
1919                               fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
1920
1921                 loff += sizeof(u32);
1922
1923                 /*
1924                  * handle page offset wrap around
1925                  */
1926                 loff = PSS_SMEM_PGOFF(loff);
1927                 if (loff == 0) {
1928                         pgnum++;
1929                         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1930                 }
1931         }
1932
1933         writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
1934                         ioc->ioc_regs.host_page_num_fn);
1935
1936         /*
1937          * Set boot type, env and device mode at the end.
1938          */
1939         if (boot_env == BFI_FWBOOT_ENV_OS &&
1940                 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1941                 boot_type = BFI_FWBOOT_TYPE_NORMAL;
1942         }
1943         asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode,
1944                                 ioc->port0_mode, ioc->port1_mode);
1945         bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_DEVMODE_OFF,
1946                         swab32(asicmode));
1947         bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_TYPE_OFF,
1948                         swab32(boot_type));
1949         bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_ENV_OFF,
1950                         swab32(boot_env));
1951         return BFA_STATUS_OK;
1952 }
1953
1954
1955 /*
1956  * Update BFA configuration from firmware configuration.
1957  */
1958 static void
1959 bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
1960 {
1961         struct bfi_ioc_attr_s   *attr = ioc->attr;
1962
1963         attr->adapter_prop  = be32_to_cpu(attr->adapter_prop);
1964         attr->card_type     = be32_to_cpu(attr->card_type);
1965         attr->maxfrsize     = be16_to_cpu(attr->maxfrsize);
1966         ioc->fcmode     = (attr->port_mode == BFI_PORT_MODE_FC);
1967         attr->mfg_year  = be16_to_cpu(attr->mfg_year);
1968
1969         bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
1970 }
1971
1972 /*
1973  * Attach time initialization of mbox logic.
1974  */
1975 static void
1976 bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc)
1977 {
1978         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
1979         int     mc;
1980
1981         INIT_LIST_HEAD(&mod->cmd_q);
1982         for (mc = 0; mc < BFI_MC_MAX; mc++) {
1983                 mod->mbhdlr[mc].cbfn = NULL;
1984                 mod->mbhdlr[mc].cbarg = ioc->bfa;
1985         }
1986 }
1987
1988 /*
1989  * Mbox poll timer -- restarts any pending mailbox requests.
1990  */
1991 static void
1992 bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc)
1993 {
1994         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
1995         struct bfa_mbox_cmd_s           *cmd;
1996         u32                     stat;
1997
1998         /*
1999          * If no command pending, do nothing
2000          */
2001         if (list_empty(&mod->cmd_q))
2002                 return;
2003
2004         /*
2005          * If previous command is not yet fetched by firmware, do nothing
2006          */
2007         stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
2008         if (stat)
2009                 return;
2010
2011         /*
2012          * Enqueue command to firmware.
2013          */
2014         bfa_q_deq(&mod->cmd_q, &cmd);
2015         bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
2016 }
2017
2018 /*
2019  * Cleanup any pending requests.
2020  */
2021 static void
2022 bfa_ioc_mbox_flush(struct bfa_ioc_s *ioc)
2023 {
2024         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2025         struct bfa_mbox_cmd_s           *cmd;
2026
2027         while (!list_empty(&mod->cmd_q))
2028                 bfa_q_deq(&mod->cmd_q, &cmd);
2029 }
2030
2031 /*
2032  * Read data from SMEM to host through PCI memmap
2033  *
2034  * @param[in]   ioc     memory for IOC
2035  * @param[in]   tbuf    app memory to store data from smem
2036  * @param[in]   soff    smem offset
2037  * @param[in]   sz      size of smem in bytes
2038  */
2039 static bfa_status_t
2040 bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
2041 {
2042         u32 pgnum, loff;
2043         __be32 r32;
2044         int i, len;
2045         u32 *buf = tbuf;
2046
2047         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
2048         loff = PSS_SMEM_PGOFF(soff);
2049         bfa_trc(ioc, pgnum);
2050         bfa_trc(ioc, loff);
2051         bfa_trc(ioc, sz);
2052
2053         /*
2054          *  Hold semaphore to serialize pll init and fwtrc.
2055          */
2056         if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) {
2057                 bfa_trc(ioc, 0);
2058                 return BFA_STATUS_FAILED;
2059         }
2060
2061         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2062
2063         len = sz/sizeof(u32);
2064         bfa_trc(ioc, len);
2065         for (i = 0; i < len; i++) {
2066                 r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
2067                 buf[i] = swab32(r32);
2068                 loff += sizeof(u32);
2069
2070                 /*
2071                  * handle page offset wrap around
2072                  */
2073                 loff = PSS_SMEM_PGOFF(loff);
2074                 if (loff == 0) {
2075                         pgnum++;
2076                         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2077                 }
2078         }
2079         writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
2080                         ioc->ioc_regs.host_page_num_fn);
2081         /*
2082          *  release semaphore.
2083          */
2084         readl(ioc->ioc_regs.ioc_init_sem_reg);
2085         writel(1, ioc->ioc_regs.ioc_init_sem_reg);
2086
2087         bfa_trc(ioc, pgnum);
2088         return BFA_STATUS_OK;
2089 }
2090
2091 /*
2092  * Clear SMEM data from host through PCI memmap
2093  *
2094  * @param[in]   ioc     memory for IOC
2095  * @param[in]   soff    smem offset
2096  * @param[in]   sz      size of smem in bytes
2097  */
2098 static bfa_status_t
2099 bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
2100 {
2101         int i, len;
2102         u32 pgnum, loff;
2103
2104         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
2105         loff = PSS_SMEM_PGOFF(soff);
2106         bfa_trc(ioc, pgnum);
2107         bfa_trc(ioc, loff);
2108         bfa_trc(ioc, sz);
2109
2110         /*
2111          *  Hold semaphore to serialize pll init and fwtrc.
2112          */
2113         if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) {
2114                 bfa_trc(ioc, 0);
2115                 return BFA_STATUS_FAILED;
2116         }
2117
2118         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2119
2120         len = sz/sizeof(u32); /* len in words */
2121         bfa_trc(ioc, len);
2122         for (i = 0; i < len; i++) {
2123                 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 0);
2124                 loff += sizeof(u32);
2125
2126                 /*
2127                  * handle page offset wrap around
2128                  */
2129                 loff = PSS_SMEM_PGOFF(loff);
2130                 if (loff == 0) {
2131                         pgnum++;
2132                         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2133                 }
2134         }
2135         writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
2136                         ioc->ioc_regs.host_page_num_fn);
2137
2138         /*
2139          *  release semaphore.
2140          */
2141         readl(ioc->ioc_regs.ioc_init_sem_reg);
2142         writel(1, ioc->ioc_regs.ioc_init_sem_reg);
2143         bfa_trc(ioc, pgnum);
2144         return BFA_STATUS_OK;
2145 }
2146
2147 static void
2148 bfa_ioc_fail_notify(struct bfa_ioc_s *ioc)
2149 {
2150         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
2151
2152         /*
2153          * Notify driver and common modules registered for notification.
2154          */
2155         ioc->cbfn->hbfail_cbfn(ioc->bfa);
2156         bfa_ioc_event_notify(ioc, BFA_IOC_E_FAILED);
2157
2158         bfa_ioc_debug_save_ftrc(ioc);
2159
2160         BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
2161                 "Heart Beat of IOC has failed\n");
2162         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL);
2163
2164 }
2165
2166 static void
2167 bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
2168 {
2169         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
2170         /*
2171          * Provide enable completion callback.
2172          */
2173         ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
2174         BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
2175                 "Running firmware version is incompatible "
2176                 "with the driver version\n");
2177         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH);
2178 }
2179
2180 bfa_status_t
2181 bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
2182 {
2183
2184         /*
2185          *  Hold semaphore so that nobody can access the chip during init.
2186          */
2187         bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
2188
2189         bfa_ioc_pll_init_asic(ioc);
2190
2191         ioc->pllinit = BFA_TRUE;
2192
2193         /*
2194          * Initialize LMEM
2195          */
2196         bfa_ioc_lmem_init(ioc);
2197
2198         /*
2199          *  release semaphore.
2200          */
2201         readl(ioc->ioc_regs.ioc_init_sem_reg);
2202         writel(1, ioc->ioc_regs.ioc_init_sem_reg);
2203
2204         return BFA_STATUS_OK;
2205 }
2206
2207 /*
2208  * Interface used by diag module to do firmware boot with memory test
2209  * as the entry vector.
2210  */
2211 bfa_status_t
2212 bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env)
2213 {
2214         struct bfi_ioc_image_hdr_s *drv_fwhdr;
2215         bfa_status_t status;
2216         bfa_ioc_stats(ioc, ioc_boots);
2217
2218         if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
2219                 return BFA_STATUS_FAILED;
2220
2221         if (boot_env == BFI_FWBOOT_ENV_OS &&
2222                 boot_type == BFI_FWBOOT_TYPE_NORMAL) {
2223
2224                 drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
2225                         bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
2226
2227                 /*
2228                  * Work with Flash iff flash f/w is better than driver f/w.
2229                  * Otherwise push drivers firmware.
2230                  */
2231                 if (bfa_ioc_flash_fwver_cmp(ioc, drv_fwhdr) ==
2232                                                 BFI_IOC_IMG_VER_BETTER)
2233                         boot_type = BFI_FWBOOT_TYPE_FLASH;
2234         }
2235
2236         /*
2237          * Initialize IOC state of all functions on a chip reset.
2238          */
2239         if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) {
2240                 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_MEMTEST);
2241                 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_MEMTEST);
2242         } else {
2243                 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_INITING);
2244                 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_INITING);
2245         }
2246
2247         bfa_ioc_msgflush(ioc);
2248         status = bfa_ioc_download_fw(ioc, boot_type, boot_env);
2249         if (status == BFA_STATUS_OK)
2250                 bfa_ioc_lpu_start(ioc);
2251         else {
2252                 WARN_ON(boot_type == BFI_FWBOOT_TYPE_MEMTEST);
2253                 bfa_iocpf_timeout(ioc);
2254         }
2255         return status;
2256 }
2257
2258 /*
2259  * Enable/disable IOC failure auto recovery.
2260  */
2261 void
2262 bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
2263 {
2264         bfa_auto_recover = auto_recover;
2265 }
2266
2267
2268
2269 bfa_boolean_t
2270 bfa_ioc_is_operational(struct bfa_ioc_s *ioc)
2271 {
2272         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
2273 }
2274
2275 bfa_boolean_t
2276 bfa_ioc_is_initialized(struct bfa_ioc_s *ioc)
2277 {
2278         u32 r32 = bfa_ioc_get_cur_ioc_fwstate(ioc);
2279
2280         return ((r32 != BFI_IOC_UNINIT) &&
2281                 (r32 != BFI_IOC_INITING) &&
2282                 (r32 != BFI_IOC_MEMTEST));
2283 }
2284
2285 bfa_boolean_t
2286 bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
2287 {
2288         __be32  *msgp = mbmsg;
2289         u32     r32;
2290         int             i;
2291
2292         r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
2293         if ((r32 & 1) == 0)
2294                 return BFA_FALSE;
2295
2296         /*
2297          * read the MBOX msg
2298          */
2299         for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
2300              i++) {
2301                 r32 = readl(ioc->ioc_regs.lpu_mbox +
2302                                    i * sizeof(u32));
2303                 msgp[i] = cpu_to_be32(r32);
2304         }
2305
2306         /*
2307          * turn off mailbox interrupt by clearing mailbox status
2308          */
2309         writel(1, ioc->ioc_regs.lpu_mbox_cmd);
2310         readl(ioc->ioc_regs.lpu_mbox_cmd);
2311
2312         return BFA_TRUE;
2313 }
2314
2315 void
2316 bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
2317 {
2318         union bfi_ioc_i2h_msg_u *msg;
2319         struct bfa_iocpf_s *iocpf = &ioc->iocpf;
2320
2321         msg = (union bfi_ioc_i2h_msg_u *) m;
2322
2323         bfa_ioc_stats(ioc, ioc_isrs);
2324
2325         switch (msg->mh.msg_id) {
2326         case BFI_IOC_I2H_HBEAT:
2327                 break;
2328
2329         case BFI_IOC_I2H_ENABLE_REPLY:
2330                 ioc->port_mode = ioc->port_mode_cfg =
2331                                 (enum bfa_mode_s)msg->fw_event.port_mode;
2332                 ioc->ad_cap_bm = msg->fw_event.cap_bm;
2333                 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
2334                 break;
2335
2336         case BFI_IOC_I2H_DISABLE_REPLY:
2337                 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE);
2338                 break;
2339
2340         case BFI_IOC_I2H_GETATTR_REPLY:
2341                 bfa_ioc_getattr_reply(ioc);
2342                 break;
2343
2344         default:
2345                 bfa_trc(ioc, msg->mh.msg_id);
2346                 WARN_ON(1);
2347         }
2348 }
2349
2350 /*
2351  * IOC attach time initialization and setup.
2352  *
2353  * @param[in]   ioc     memory for IOC
2354  * @param[in]   bfa     driver instance structure
2355  */
2356 void
2357 bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn,
2358                struct bfa_timer_mod_s *timer_mod)
2359 {
2360         ioc->bfa        = bfa;
2361         ioc->cbfn       = cbfn;
2362         ioc->timer_mod  = timer_mod;
2363         ioc->fcmode     = BFA_FALSE;
2364         ioc->pllinit    = BFA_FALSE;
2365         ioc->dbg_fwsave_once = BFA_TRUE;
2366         ioc->iocpf.ioc  = ioc;
2367
2368         bfa_ioc_mbox_attach(ioc);
2369         INIT_LIST_HEAD(&ioc->notify_q);
2370
2371         bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
2372         bfa_fsm_send_event(ioc, IOC_E_RESET);
2373 }
2374
2375 /*
2376  * Driver detach time IOC cleanup.
2377  */
2378 void
2379 bfa_ioc_detach(struct bfa_ioc_s *ioc)
2380 {
2381         bfa_fsm_send_event(ioc, IOC_E_DETACH);
2382         INIT_LIST_HEAD(&ioc->notify_q);
2383 }
2384
2385 /*
2386  * Setup IOC PCI properties.
2387  *
2388  * @param[in]   pcidev  PCI device information for this IOC
2389  */
2390 void
2391 bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
2392                 enum bfi_pcifn_class clscode)
2393 {
2394         ioc->clscode    = clscode;
2395         ioc->pcidev     = *pcidev;
2396
2397         /*
2398          * Initialize IOC and device personality
2399          */
2400         ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_FC;
2401         ioc->asic_mode  = BFI_ASIC_MODE_FC;
2402
2403         switch (pcidev->device_id) {
2404         case BFA_PCI_DEVICE_ID_FC_8G1P:
2405         case BFA_PCI_DEVICE_ID_FC_8G2P:
2406                 ioc->asic_gen = BFI_ASIC_GEN_CB;
2407                 ioc->fcmode = BFA_TRUE;
2408                 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2409                 ioc->ad_cap_bm = BFA_CM_HBA;
2410                 break;
2411
2412         case BFA_PCI_DEVICE_ID_CT:
2413                 ioc->asic_gen = BFI_ASIC_GEN_CT;
2414                 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
2415                 ioc->asic_mode  = BFI_ASIC_MODE_ETH;
2416                 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_CNA;
2417                 ioc->ad_cap_bm = BFA_CM_CNA;
2418                 break;
2419
2420         case BFA_PCI_DEVICE_ID_CT_FC:
2421                 ioc->asic_gen = BFI_ASIC_GEN_CT;
2422                 ioc->fcmode = BFA_TRUE;
2423                 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2424                 ioc->ad_cap_bm = BFA_CM_HBA;
2425                 break;
2426
2427         case BFA_PCI_DEVICE_ID_CT2:
2428         case BFA_PCI_DEVICE_ID_CT2_QUAD:
2429                 ioc->asic_gen = BFI_ASIC_GEN_CT2;
2430                 if (clscode == BFI_PCIFN_CLASS_FC &&
2431                     pcidev->ssid == BFA_PCI_CT2_SSID_FC) {
2432                         ioc->asic_mode  = BFI_ASIC_MODE_FC16;
2433                         ioc->fcmode = BFA_TRUE;
2434                         ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2435                         ioc->ad_cap_bm = BFA_CM_HBA;
2436                 } else {
2437                         ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
2438                         ioc->asic_mode  = BFI_ASIC_MODE_ETH;
2439                         if (pcidev->ssid == BFA_PCI_CT2_SSID_FCoE) {
2440                                 ioc->port_mode =
2441                                 ioc->port_mode_cfg = BFA_MODE_CNA;
2442                                 ioc->ad_cap_bm = BFA_CM_CNA;
2443                         } else {
2444                                 ioc->port_mode =
2445                                 ioc->port_mode_cfg = BFA_MODE_NIC;
2446                                 ioc->ad_cap_bm = BFA_CM_NIC;
2447                         }
2448                 }
2449                 break;
2450
2451         default:
2452                 WARN_ON(1);
2453         }
2454
2455         /*
2456          * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
2457          */
2458         if (ioc->asic_gen == BFI_ASIC_GEN_CB)
2459                 bfa_ioc_set_cb_hwif(ioc);
2460         else if (ioc->asic_gen == BFI_ASIC_GEN_CT)
2461                 bfa_ioc_set_ct_hwif(ioc);
2462         else {
2463                 WARN_ON(ioc->asic_gen != BFI_ASIC_GEN_CT2);
2464                 bfa_ioc_set_ct2_hwif(ioc);
2465                 bfa_ioc_ct2_poweron(ioc);
2466         }
2467
2468         bfa_ioc_map_port(ioc);
2469         bfa_ioc_reg_init(ioc);
2470 }
2471
2472 /*
2473  * Initialize IOC dma memory
2474  *
2475  * @param[in]   dm_kva  kernel virtual address of IOC dma memory
2476  * @param[in]   dm_pa   physical address of IOC dma memory
2477  */
2478 void
2479 bfa_ioc_mem_claim(struct bfa_ioc_s *ioc,  u8 *dm_kva, u64 dm_pa)
2480 {
2481         /*
2482          * dma memory for firmware attribute
2483          */
2484         ioc->attr_dma.kva = dm_kva;
2485         ioc->attr_dma.pa = dm_pa;
2486         ioc->attr = (struct bfi_ioc_attr_s *) dm_kva;
2487 }
2488
2489 void
2490 bfa_ioc_enable(struct bfa_ioc_s *ioc)
2491 {
2492         bfa_ioc_stats(ioc, ioc_enables);
2493         ioc->dbg_fwsave_once = BFA_TRUE;
2494
2495         bfa_fsm_send_event(ioc, IOC_E_ENABLE);
2496 }
2497
2498 void
2499 bfa_ioc_disable(struct bfa_ioc_s *ioc)
2500 {
2501         bfa_ioc_stats(ioc, ioc_disables);
2502         bfa_fsm_send_event(ioc, IOC_E_DISABLE);
2503 }
2504
2505 void
2506 bfa_ioc_suspend(struct bfa_ioc_s *ioc)
2507 {
2508         ioc->dbg_fwsave_once = BFA_TRUE;
2509         bfa_fsm_send_event(ioc, IOC_E_HWERROR);
2510 }
2511
2512 /*
2513  * Initialize memory for saving firmware trace. Driver must initialize
2514  * trace memory before call bfa_ioc_enable().
2515  */
2516 void
2517 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
2518 {
2519         ioc->dbg_fwsave     = dbg_fwsave;
2520         ioc->dbg_fwsave_len = BFA_DBG_FWTRC_LEN;
2521 }
2522
2523 /*
2524  * Register mailbox message handler functions
2525  *
2526  * @param[in]   ioc             IOC instance
2527  * @param[in]   mcfuncs         message class handler functions
2528  */
2529 void
2530 bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs)
2531 {
2532         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2533         int                             mc;
2534
2535         for (mc = 0; mc < BFI_MC_MAX; mc++)
2536                 mod->mbhdlr[mc].cbfn = mcfuncs[mc];
2537 }
2538
2539 /*
2540  * Register mailbox message handler function, to be called by common modules
2541  */
2542 void
2543 bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
2544                     bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
2545 {
2546         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2547
2548         mod->mbhdlr[mc].cbfn    = cbfn;
2549         mod->mbhdlr[mc].cbarg   = cbarg;
2550 }
2551
2552 /*
2553  * Queue a mailbox command request to firmware. Waits if mailbox is busy.
2554  * Responsibility of caller to serialize
2555  *
2556  * @param[in]   ioc     IOC instance
2557  * @param[i]    cmd     Mailbox command
2558  */
2559 void
2560 bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd)
2561 {
2562         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2563         u32                     stat;
2564
2565         /*
2566          * If a previous command is pending, queue new command
2567          */
2568         if (!list_empty(&mod->cmd_q)) {
2569                 list_add_tail(&cmd->qe, &mod->cmd_q);
2570                 return;
2571         }
2572
2573         /*
2574          * If mailbox is busy, queue command for poll timer
2575          */
2576         stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
2577         if (stat) {
2578                 list_add_tail(&cmd->qe, &mod->cmd_q);
2579                 return;
2580         }
2581
2582         /*
2583          * mailbox is free -- queue command to firmware
2584          */
2585         bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
2586 }
2587
2588 /*
2589  * Handle mailbox interrupts
2590  */
2591 void
2592 bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc)
2593 {
2594         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2595         struct bfi_mbmsg_s              m;
2596         int                             mc;
2597
2598         if (bfa_ioc_msgget(ioc, &m)) {
2599                 /*
2600                  * Treat IOC message class as special.
2601                  */
2602                 mc = m.mh.msg_class;
2603                 if (mc == BFI_MC_IOC) {
2604                         bfa_ioc_isr(ioc, &m);
2605                         return;
2606                 }
2607
2608                 if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
2609                         return;
2610
2611                 mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
2612         }
2613
2614         bfa_ioc_lpu_read_stat(ioc);
2615
2616         /*
2617          * Try to send pending mailbox commands
2618          */
2619         bfa_ioc_mbox_poll(ioc);
2620 }
2621
2622 void
2623 bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
2624 {
2625         bfa_ioc_stats(ioc, ioc_hbfails);
2626         ioc->stats.hb_count = ioc->hb_count;
2627         bfa_fsm_send_event(ioc, IOC_E_HWERROR);
2628 }
2629
2630 /*
2631  * return true if IOC is disabled
2632  */
2633 bfa_boolean_t
2634 bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
2635 {
2636         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) ||
2637                 bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
2638 }
2639
2640 /*
2641  * return true if IOC firmware is different.
2642  */
2643 bfa_boolean_t
2644 bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
2645 {
2646         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset) ||
2647                 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_fwcheck) ||
2648                 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_mismatch);
2649 }
2650
2651 /*
2652  * Check if adapter is disabled -- both IOCs should be in a disabled
2653  * state.
2654  */
2655 bfa_boolean_t
2656 bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
2657 {
2658         u32     ioc_state;
2659
2660         if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled))
2661                 return BFA_FALSE;
2662
2663         ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc);
2664         if (!bfa_ioc_state_disabled(ioc_state))
2665                 return BFA_FALSE;
2666
2667         if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) {
2668                 ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc);
2669                 if (!bfa_ioc_state_disabled(ioc_state))
2670                         return BFA_FALSE;
2671         }
2672
2673         return BFA_TRUE;
2674 }
2675
2676 /*
2677  * Reset IOC fwstate registers.
2678  */
2679 void
2680 bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc)
2681 {
2682         bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_UNINIT);
2683         bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_UNINIT);
2684 }
2685
2686 #define BFA_MFG_NAME "QLogic"
2687 void
2688 bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2689                          struct bfa_adapter_attr_s *ad_attr)
2690 {
2691         struct bfi_ioc_attr_s   *ioc_attr;
2692
2693         ioc_attr = ioc->attr;
2694
2695         bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
2696         bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
2697         bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
2698         bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
2699         memcpy(&ad_attr->vpd, &ioc_attr->vpd,
2700                       sizeof(struct bfa_mfg_vpd_s));
2701
2702         ad_attr->nports = bfa_ioc_get_nports(ioc);
2703         ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
2704
2705         bfa_ioc_get_adapter_model(ioc, ad_attr->model);
2706         /* For now, model descr uses same model string */
2707         bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
2708
2709         ad_attr->card_type = ioc_attr->card_type;
2710         ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type);
2711
2712         if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
2713                 ad_attr->prototype = 1;
2714         else
2715                 ad_attr->prototype = 0;
2716
2717         ad_attr->pwwn = ioc->attr->pwwn;
2718         ad_attr->mac  = bfa_ioc_get_mac(ioc);
2719
2720         ad_attr->pcie_gen = ioc_attr->pcie_gen;
2721         ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
2722         ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
2723         ad_attr->asic_rev = ioc_attr->asic_rev;
2724
2725         bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
2726
2727         ad_attr->cna_capable = bfa_ioc_is_cna(ioc);
2728         ad_attr->trunk_capable = (ad_attr->nports > 1) &&
2729                                   !bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz;
2730         ad_attr->mfg_day = ioc_attr->mfg_day;
2731         ad_attr->mfg_month = ioc_attr->mfg_month;
2732         ad_attr->mfg_year = ioc_attr->mfg_year;
2733         memcpy(ad_attr->uuid, ioc_attr->uuid, BFA_ADAPTER_UUID_LEN);
2734 }
2735
2736 enum bfa_ioc_type_e
2737 bfa_ioc_get_type(struct bfa_ioc_s *ioc)
2738 {
2739         if (ioc->clscode == BFI_PCIFN_CLASS_ETH)
2740                 return BFA_IOC_TYPE_LL;
2741
2742         WARN_ON(ioc->clscode != BFI_PCIFN_CLASS_FC);
2743
2744         return (ioc->attr->port_mode == BFI_PORT_MODE_FC)
2745                 ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE;
2746 }
2747
2748 void
2749 bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
2750 {
2751         memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
2752         memcpy((void *)serial_num,
2753                         (void *)ioc->attr->brcd_serialnum,
2754                         BFA_ADAPTER_SERIAL_NUM_LEN);
2755 }
2756
2757 void
2758 bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
2759 {
2760         memset((void *)fw_ver, 0, BFA_VERSION_LEN);
2761         memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
2762 }
2763
2764 void
2765 bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
2766 {
2767         WARN_ON(!chip_rev);
2768
2769         memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
2770
2771         chip_rev[0] = 'R';
2772         chip_rev[1] = 'e';
2773         chip_rev[2] = 'v';
2774         chip_rev[3] = '-';
2775         chip_rev[4] = ioc->attr->asic_rev;
2776         chip_rev[5] = '\0';
2777 }
2778
2779 void
2780 bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver)
2781 {
2782         memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
2783         memcpy(optrom_ver, ioc->attr->optrom_version,
2784                       BFA_VERSION_LEN);
2785 }
2786
2787 void
2788 bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
2789 {
2790         memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
2791         strscpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
2792 }
2793
2794 void
2795 bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
2796 {
2797         struct bfi_ioc_attr_s   *ioc_attr;
2798         u8 nports = bfa_ioc_get_nports(ioc);
2799
2800         WARN_ON(!model);
2801         memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
2802
2803         ioc_attr = ioc->attr;
2804
2805         if (bfa_asic_id_ct2(ioc->pcidev.device_id) &&
2806                 (!bfa_mfg_is_mezz(ioc_attr->card_type)))
2807                 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u-%u%s",
2808                         BFA_MFG_NAME, ioc_attr->card_type, nports, "p");
2809         else
2810                 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
2811                         BFA_MFG_NAME, ioc_attr->card_type);
2812 }
2813
2814 enum bfa_ioc_state
2815 bfa_ioc_get_state(struct bfa_ioc_s *ioc)
2816 {
2817         enum bfa_iocpf_state iocpf_st;
2818         enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
2819
2820         if (ioc_st == BFA_IOC_ENABLING ||
2821                 ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) {
2822
2823                 iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm);
2824
2825                 switch (iocpf_st) {
2826                 case BFA_IOCPF_SEMWAIT:
2827                         ioc_st = BFA_IOC_SEMWAIT;
2828                         break;
2829
2830                 case BFA_IOCPF_HWINIT:
2831                         ioc_st = BFA_IOC_HWINIT;
2832                         break;
2833
2834                 case BFA_IOCPF_FWMISMATCH:
2835                         ioc_st = BFA_IOC_FWMISMATCH;
2836                         break;
2837
2838                 case BFA_IOCPF_FAIL:
2839                         ioc_st = BFA_IOC_FAIL;
2840                         break;
2841
2842                 case BFA_IOCPF_INITFAIL:
2843                         ioc_st = BFA_IOC_INITFAIL;
2844                         break;
2845
2846                 default:
2847                         break;
2848                 }
2849         }
2850
2851         return ioc_st;
2852 }
2853
2854 void
2855 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
2856 {
2857         memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
2858
2859         ioc_attr->state = bfa_ioc_get_state(ioc);
2860         ioc_attr->port_id = bfa_ioc_portid(ioc);
2861         ioc_attr->port_mode = ioc->port_mode;
2862         ioc_attr->port_mode_cfg = ioc->port_mode_cfg;
2863         ioc_attr->cap_bm = ioc->ad_cap_bm;
2864
2865         ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
2866
2867         bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
2868
2869         ioc_attr->pci_attr.device_id = bfa_ioc_devid(ioc);
2870         ioc_attr->pci_attr.pcifn = bfa_ioc_pcifn(ioc);
2871         ioc_attr->def_fn = (bfa_ioc_pcifn(ioc) == bfa_ioc_portid(ioc));
2872         bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
2873 }
2874
2875 mac_t
2876 bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
2877 {
2878         /*
2879          * Check the IOC type and return the appropriate MAC
2880          */
2881         if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE)
2882                 return ioc->attr->fcoe_mac;
2883         else
2884                 return ioc->attr->mac;
2885 }
2886
2887 mac_t
2888 bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc)
2889 {
2890         mac_t   m;
2891
2892         m = ioc->attr->mfg_mac;
2893         if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type))
2894                 m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
2895         else
2896                 bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]),
2897                         bfa_ioc_pcifn(ioc));
2898
2899         return m;
2900 }
2901
2902 /*
2903  * Send AEN notification
2904  */
2905 void
2906 bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2907 {
2908         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
2909         struct bfa_aen_entry_s  *aen_entry;
2910         enum bfa_ioc_type_e ioc_type;
2911
2912         bfad_get_aen_entry(bfad, aen_entry);
2913         if (!aen_entry)
2914                 return;
2915
2916         ioc_type = bfa_ioc_get_type(ioc);
2917         switch (ioc_type) {
2918         case BFA_IOC_TYPE_FC:
2919                 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn;
2920                 break;
2921         case BFA_IOC_TYPE_FCoE:
2922                 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn;
2923                 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2924                 break;
2925         case BFA_IOC_TYPE_LL:
2926                 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2927                 break;
2928         default:
2929                 WARN_ON(ioc_type != BFA_IOC_TYPE_FC);
2930                 break;
2931         }
2932
2933         /* Send the AEN notification */
2934         aen_entry->aen_data.ioc.ioc_type = ioc_type;
2935         bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq,
2936                                   BFA_AEN_CAT_IOC, event);
2937 }
2938
2939 /*
2940  * Retrieve saved firmware trace from a prior IOC failure.
2941  */
2942 bfa_status_t
2943 bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2944 {
2945         int     tlen;
2946
2947         if (ioc->dbg_fwsave_len == 0)
2948                 return BFA_STATUS_ENOFSAVE;
2949
2950         tlen = *trclen;
2951         if (tlen > ioc->dbg_fwsave_len)
2952                 tlen = ioc->dbg_fwsave_len;
2953
2954         memcpy(trcdata, ioc->dbg_fwsave, tlen);
2955         *trclen = tlen;
2956         return BFA_STATUS_OK;
2957 }
2958
2959
2960 /*
2961  * Retrieve saved firmware trace from a prior IOC failure.
2962  */
2963 bfa_status_t
2964 bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2965 {
2966         u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc));
2967         int tlen;
2968         bfa_status_t status;
2969
2970         bfa_trc(ioc, *trclen);
2971
2972         tlen = *trclen;
2973         if (tlen > BFA_DBG_FWTRC_LEN)
2974                 tlen = BFA_DBG_FWTRC_LEN;
2975
2976         status = bfa_ioc_smem_read(ioc, trcdata, loff, tlen);
2977         *trclen = tlen;
2978         return status;
2979 }
2980
2981 static void
2982 bfa_ioc_send_fwsync(struct bfa_ioc_s *ioc)
2983 {
2984         struct bfa_mbox_cmd_s cmd;
2985         struct bfi_ioc_ctrl_req_s *req = (struct bfi_ioc_ctrl_req_s *) cmd.msg;
2986
2987         bfi_h2i_set(req->mh, BFI_MC_IOC, BFI_IOC_H2I_DBG_SYNC,
2988                     bfa_ioc_portid(ioc));
2989         req->clscode = cpu_to_be16(ioc->clscode);
2990         bfa_ioc_mbox_queue(ioc, &cmd);
2991 }
2992
2993 static void
2994 bfa_ioc_fwsync(struct bfa_ioc_s *ioc)
2995 {
2996         u32 fwsync_iter = 1000;
2997
2998         bfa_ioc_send_fwsync(ioc);
2999
3000         /*
3001          * After sending a fw sync mbox command wait for it to
3002          * take effect.  We will not wait for a response because
3003          *    1. fw_sync mbox cmd doesn't have a response.
3004          *    2. Even if we implement that,  interrupts might not
3005          *       be enabled when we call this function.
3006          * So, just keep checking if any mbox cmd is pending, and
3007          * after waiting for a reasonable amount of time, go ahead.
3008          * It is possible that fw has crashed and the mbox command
3009          * is never acknowledged.
3010          */
3011         while (bfa_ioc_mbox_cmd_pending(ioc) && fwsync_iter > 0)
3012                 fwsync_iter--;
3013 }
3014
3015 /*
3016  * Dump firmware smem
3017  */
3018 bfa_status_t
3019 bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf,
3020                                 u32 *offset, int *buflen)
3021 {
3022         u32 loff;
3023         int dlen;
3024         bfa_status_t status;
3025         u32 smem_len = BFA_IOC_FW_SMEM_SIZE(ioc);
3026
3027         if (*offset >= smem_len) {
3028                 *offset = *buflen = 0;
3029                 return BFA_STATUS_EINVAL;
3030         }
3031
3032         loff = *offset;
3033         dlen = *buflen;
3034
3035         /*
3036          * First smem read, sync smem before proceeding
3037          * No need to sync before reading every chunk.
3038          */
3039         if (loff == 0)
3040                 bfa_ioc_fwsync(ioc);
3041
3042         if ((loff + dlen) >= smem_len)
3043                 dlen = smem_len - loff;
3044
3045         status = bfa_ioc_smem_read(ioc, buf, loff, dlen);
3046
3047         if (status != BFA_STATUS_OK) {
3048                 *offset = *buflen = 0;
3049                 return status;
3050         }
3051
3052         *offset += dlen;
3053
3054         if (*offset >= smem_len)
3055                 *offset = 0;
3056
3057         *buflen = dlen;
3058
3059         return status;
3060 }
3061
3062 /*
3063  * Firmware statistics
3064  */
3065 bfa_status_t
3066 bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats)
3067 {
3068         u32 loff = BFI_IOC_FWSTATS_OFF + \
3069                 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc));
3070         int tlen;
3071         bfa_status_t status;
3072
3073         if (ioc->stats_busy) {
3074                 bfa_trc(ioc, ioc->stats_busy);
3075                 return BFA_STATUS_DEVBUSY;
3076         }
3077         ioc->stats_busy = BFA_TRUE;
3078
3079         tlen = sizeof(struct bfa_fw_stats_s);
3080         status = bfa_ioc_smem_read(ioc, stats, loff, tlen);
3081
3082         ioc->stats_busy = BFA_FALSE;
3083         return status;
3084 }
3085
3086 bfa_status_t
3087 bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc)
3088 {
3089         u32 loff = BFI_IOC_FWSTATS_OFF + \
3090                 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc));
3091         int tlen;
3092         bfa_status_t status;
3093
3094         if (ioc->stats_busy) {
3095                 bfa_trc(ioc, ioc->stats_busy);
3096                 return BFA_STATUS_DEVBUSY;
3097         }
3098         ioc->stats_busy = BFA_TRUE;
3099
3100         tlen = sizeof(struct bfa_fw_stats_s);
3101         status = bfa_ioc_smem_clr(ioc, loff, tlen);
3102
3103         ioc->stats_busy = BFA_FALSE;
3104         return status;
3105 }
3106
3107 /*
3108  * Save firmware trace if configured.
3109  */
3110 void
3111 bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc)
3112 {
3113         int             tlen;
3114
3115         if (ioc->dbg_fwsave_once) {
3116                 ioc->dbg_fwsave_once = BFA_FALSE;
3117                 if (ioc->dbg_fwsave_len) {
3118                         tlen = ioc->dbg_fwsave_len;
3119                         bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
3120                 }
3121         }
3122 }
3123
3124 /*
3125  * Firmware failure detected. Start recovery actions.
3126  */
3127 static void
3128 bfa_ioc_recover(struct bfa_ioc_s *ioc)
3129 {
3130         bfa_ioc_stats(ioc, ioc_hbfails);
3131         ioc->stats.hb_count = ioc->hb_count;
3132         bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
3133 }
3134
3135 /*
3136  *  BFA IOC PF private functions
3137  */
3138 static void
3139 bfa_iocpf_timeout(void *ioc_arg)
3140 {
3141         struct bfa_ioc_s  *ioc = (struct bfa_ioc_s *) ioc_arg;
3142
3143         bfa_trc(ioc, 0);
3144         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT);
3145 }
3146
3147 static void
3148 bfa_iocpf_sem_timeout(void *ioc_arg)
3149 {
3150         struct bfa_ioc_s  *ioc = (struct bfa_ioc_s *) ioc_arg;
3151
3152         bfa_ioc_hw_sem_get(ioc);
3153 }
3154
3155 static void
3156 bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc)
3157 {
3158         u32 fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
3159
3160         bfa_trc(ioc, fwstate);
3161
3162         if (fwstate == BFI_IOC_DISABLED) {
3163                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
3164                 return;
3165         }
3166
3167         if (ioc->iocpf.poll_time >= (3 * BFA_IOC_TOV))
3168                 bfa_iocpf_timeout(ioc);
3169         else {
3170                 ioc->iocpf.poll_time += BFA_IOC_POLL_TOV;
3171                 bfa_iocpf_poll_timer_start(ioc);
3172         }
3173 }
3174
3175 static void
3176 bfa_iocpf_poll_timeout(void *ioc_arg)
3177 {
3178         struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg;
3179
3180         bfa_ioc_poll_fwinit(ioc);
3181 }
3182
3183 /*
3184  *  bfa timer function
3185  */
3186 void
3187 bfa_timer_beat(struct bfa_timer_mod_s *mod)
3188 {
3189         struct list_head *qh = &mod->timer_q;
3190         struct list_head *qe, *qe_next;
3191         struct bfa_timer_s *elem;
3192         struct list_head timedout_q;
3193
3194         INIT_LIST_HEAD(&timedout_q);
3195
3196         qe = bfa_q_next(qh);
3197
3198         while (qe != qh) {
3199                 qe_next = bfa_q_next(qe);
3200
3201                 elem = (struct bfa_timer_s *) qe;
3202                 if (elem->timeout <= BFA_TIMER_FREQ) {
3203                         elem->timeout = 0;
3204                         list_del(&elem->qe);
3205                         list_add_tail(&elem->qe, &timedout_q);
3206                 } else {
3207                         elem->timeout -= BFA_TIMER_FREQ;
3208                 }
3209
3210                 qe = qe_next;   /* go to next elem */
3211         }
3212
3213         /*
3214          * Pop all the timeout entries
3215          */
3216         while (!list_empty(&timedout_q)) {
3217                 bfa_q_deq(&timedout_q, &elem);
3218                 elem->timercb(elem->arg);
3219         }
3220 }
3221
3222 /*
3223  * Should be called with lock protection
3224  */
3225 void
3226 bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
3227                     void (*timercb) (void *), void *arg, unsigned int timeout)
3228 {
3229
3230         WARN_ON(timercb == NULL);
3231         WARN_ON(bfa_q_is_on_q(&mod->timer_q, timer));
3232
3233         timer->timeout = timeout;
3234         timer->timercb = timercb;
3235         timer->arg = arg;
3236
3237         list_add_tail(&timer->qe, &mod->timer_q);
3238 }
3239
3240 /*
3241  * Should be called with lock protection
3242  */
3243 void
3244 bfa_timer_stop(struct bfa_timer_s *timer)
3245 {
3246         WARN_ON(list_empty(&timer->qe));
3247
3248         list_del(&timer->qe);
3249 }
3250
3251 /*
3252  *      ASIC block related
3253  */
3254 static void
3255 bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg)
3256 {
3257         struct bfa_ablk_cfg_inst_s *cfg_inst;
3258         int i, j;
3259         u16     be16;
3260
3261         for (i = 0; i < BFA_ABLK_MAX; i++) {
3262                 cfg_inst = &cfg->inst[i];
3263                 for (j = 0; j < BFA_ABLK_MAX_PFS; j++) {
3264                         be16 = cfg_inst->pf_cfg[j].pers;
3265                         cfg_inst->pf_cfg[j].pers = be16_to_cpu(be16);
3266                         be16 = cfg_inst->pf_cfg[j].num_qpairs;
3267                         cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16);
3268                         be16 = cfg_inst->pf_cfg[j].num_vectors;
3269                         cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16);
3270                         be16 = cfg_inst->pf_cfg[j].bw_min;
3271                         cfg_inst->pf_cfg[j].bw_min = be16_to_cpu(be16);
3272                         be16 = cfg_inst->pf_cfg[j].bw_max;
3273                         cfg_inst->pf_cfg[j].bw_max = be16_to_cpu(be16);
3274                 }
3275         }
3276 }
3277
3278 static void
3279 bfa_ablk_isr(void *cbarg, struct bfi_mbmsg_s *msg)
3280 {
3281         struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg;
3282         struct bfi_ablk_i2h_rsp_s *rsp = (struct bfi_ablk_i2h_rsp_s *)msg;
3283         bfa_ablk_cbfn_t cbfn;
3284
3285         WARN_ON(msg->mh.msg_class != BFI_MC_ABLK);
3286         bfa_trc(ablk->ioc, msg->mh.msg_id);
3287
3288         switch (msg->mh.msg_id) {
3289         case BFI_ABLK_I2H_QUERY:
3290                 if (rsp->status == BFA_STATUS_OK) {
3291                         memcpy(ablk->cfg, ablk->dma_addr.kva,
3292                                 sizeof(struct bfa_ablk_cfg_s));
3293                         bfa_ablk_config_swap(ablk->cfg);
3294                         ablk->cfg = NULL;
3295                 }
3296                 break;
3297
3298         case BFI_ABLK_I2H_ADPT_CONFIG:
3299         case BFI_ABLK_I2H_PORT_CONFIG:
3300                 /* update config port mode */
3301                 ablk->ioc->port_mode_cfg = rsp->port_mode;
3302                 break;
3303
3304         case BFI_ABLK_I2H_PF_DELETE:
3305         case BFI_ABLK_I2H_PF_UPDATE:
3306         case BFI_ABLK_I2H_OPTROM_ENABLE:
3307         case BFI_ABLK_I2H_OPTROM_DISABLE:
3308                 /* No-op */
3309                 break;
3310
3311         case BFI_ABLK_I2H_PF_CREATE:
3312                 *(ablk->pcifn) = rsp->pcifn;
3313                 ablk->pcifn = NULL;
3314                 break;
3315
3316         default:
3317                 WARN_ON(1);
3318         }
3319
3320         ablk->busy = BFA_FALSE;
3321         if (ablk->cbfn) {
3322                 cbfn = ablk->cbfn;
3323                 ablk->cbfn = NULL;
3324                 cbfn(ablk->cbarg, rsp->status);
3325         }
3326 }
3327
3328 static void
3329 bfa_ablk_notify(void *cbarg, enum bfa_ioc_event_e event)
3330 {
3331         struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg;
3332
3333         bfa_trc(ablk->ioc, event);
3334
3335         switch (event) {
3336         case BFA_IOC_E_ENABLED:
3337                 WARN_ON(ablk->busy != BFA_FALSE);
3338                 break;
3339
3340         case BFA_IOC_E_DISABLED:
3341         case BFA_IOC_E_FAILED:
3342                 /* Fail any pending requests */
3343                 ablk->pcifn = NULL;
3344                 if (ablk->busy) {
3345                         if (ablk->cbfn)
3346                                 ablk->cbfn(ablk->cbarg, BFA_STATUS_FAILED);
3347                         ablk->cbfn = NULL;
3348                         ablk->busy = BFA_FALSE;
3349                 }
3350                 break;
3351
3352         default:
3353                 WARN_ON(1);
3354                 break;
3355         }
3356 }
3357
3358 u32
3359 bfa_ablk_meminfo(void)
3360 {
3361         return BFA_ROUNDUP(sizeof(struct bfa_ablk_cfg_s), BFA_DMA_ALIGN_SZ);
3362 }
3363
3364 void
3365 bfa_ablk_memclaim(struct bfa_ablk_s *ablk, u8 *dma_kva, u64 dma_pa)
3366 {
3367         ablk->dma_addr.kva = dma_kva;
3368         ablk->dma_addr.pa  = dma_pa;
3369 }
3370
3371 void
3372 bfa_ablk_attach(struct bfa_ablk_s *ablk, struct bfa_ioc_s *ioc)
3373 {
3374         ablk->ioc = ioc;
3375
3376         bfa_ioc_mbox_regisr(ablk->ioc, BFI_MC_ABLK, bfa_ablk_isr, ablk);
3377         bfa_q_qe_init(&ablk->ioc_notify);
3378         bfa_ioc_notify_init(&ablk->ioc_notify, bfa_ablk_notify, ablk);
3379         list_add_tail(&ablk->ioc_notify.qe, &ablk->ioc->notify_q);
3380 }
3381
3382 bfa_status_t
3383 bfa_ablk_query(struct bfa_ablk_s *ablk, struct bfa_ablk_cfg_s *ablk_cfg,
3384                 bfa_ablk_cbfn_t cbfn, void *cbarg)
3385 {
3386         struct bfi_ablk_h2i_query_s *m;
3387
3388         WARN_ON(!ablk_cfg);
3389
3390         if (!bfa_ioc_is_operational(ablk->ioc)) {
3391                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3392                 return BFA_STATUS_IOC_FAILURE;
3393         }
3394
3395         if (ablk->busy) {
3396                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3397                 return  BFA_STATUS_DEVBUSY;
3398         }
3399
3400         ablk->cfg = ablk_cfg;
3401         ablk->cbfn  = cbfn;
3402         ablk->cbarg = cbarg;
3403         ablk->busy  = BFA_TRUE;
3404
3405         m = (struct bfi_ablk_h2i_query_s *)ablk->mb.msg;
3406         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_QUERY,
3407                     bfa_ioc_portid(ablk->ioc));
3408         bfa_dma_be_addr_set(m->addr, ablk->dma_addr.pa);
3409         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3410
3411         return BFA_STATUS_OK;
3412 }
3413
3414 bfa_status_t
3415 bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn,
3416                 u8 port, enum bfi_pcifn_class personality,
3417                 u16 bw_min, u16 bw_max,
3418                 bfa_ablk_cbfn_t cbfn, void *cbarg)
3419 {
3420         struct bfi_ablk_h2i_pf_req_s *m;
3421
3422         if (!bfa_ioc_is_operational(ablk->ioc)) {
3423                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3424                 return BFA_STATUS_IOC_FAILURE;
3425         }
3426
3427         if (ablk->busy) {
3428                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3429                 return  BFA_STATUS_DEVBUSY;
3430         }
3431
3432         ablk->pcifn = pcifn;
3433         ablk->cbfn = cbfn;
3434         ablk->cbarg = cbarg;
3435         ablk->busy  = BFA_TRUE;
3436
3437         m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3438         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE,
3439                     bfa_ioc_portid(ablk->ioc));
3440         m->pers = cpu_to_be16((u16)personality);
3441         m->bw_min = cpu_to_be16(bw_min);
3442         m->bw_max = cpu_to_be16(bw_max);
3443         m->port = port;
3444         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3445
3446         return BFA_STATUS_OK;
3447 }
3448
3449 bfa_status_t
3450 bfa_ablk_pf_delete(struct bfa_ablk_s *ablk, int pcifn,
3451                 bfa_ablk_cbfn_t cbfn, void *cbarg)
3452 {
3453         struct bfi_ablk_h2i_pf_req_s *m;
3454
3455         if (!bfa_ioc_is_operational(ablk->ioc)) {
3456                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3457                 return BFA_STATUS_IOC_FAILURE;
3458         }
3459
3460         if (ablk->busy) {
3461                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3462                 return  BFA_STATUS_DEVBUSY;
3463         }
3464
3465         ablk->cbfn  = cbfn;
3466         ablk->cbarg = cbarg;
3467         ablk->busy  = BFA_TRUE;
3468
3469         m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3470         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_DELETE,
3471                     bfa_ioc_portid(ablk->ioc));
3472         m->pcifn = (u8)pcifn;
3473         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3474
3475         return BFA_STATUS_OK;
3476 }
3477
3478 bfa_status_t
3479 bfa_ablk_adapter_config(struct bfa_ablk_s *ablk, enum bfa_mode_s mode,
3480                 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg)
3481 {
3482         struct bfi_ablk_h2i_cfg_req_s *m;
3483
3484         if (!bfa_ioc_is_operational(ablk->ioc)) {
3485                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3486                 return BFA_STATUS_IOC_FAILURE;
3487         }
3488
3489         if (ablk->busy) {
3490                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3491                 return  BFA_STATUS_DEVBUSY;
3492         }
3493
3494         ablk->cbfn  = cbfn;
3495         ablk->cbarg = cbarg;
3496         ablk->busy  = BFA_TRUE;
3497
3498         m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg;
3499         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_ADPT_CONFIG,
3500                     bfa_ioc_portid(ablk->ioc));
3501         m->mode = (u8)mode;
3502         m->max_pf = (u8)max_pf;
3503         m->max_vf = (u8)max_vf;
3504         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3505
3506         return BFA_STATUS_OK;
3507 }
3508
3509 bfa_status_t
3510 bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port, enum bfa_mode_s mode,
3511                 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg)
3512 {
3513         struct bfi_ablk_h2i_cfg_req_s *m;
3514
3515         if (!bfa_ioc_is_operational(ablk->ioc)) {
3516                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3517                 return BFA_STATUS_IOC_FAILURE;
3518         }
3519
3520         if (ablk->busy) {
3521                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3522                 return  BFA_STATUS_DEVBUSY;
3523         }
3524
3525         ablk->cbfn  = cbfn;
3526         ablk->cbarg = cbarg;
3527         ablk->busy  = BFA_TRUE;
3528
3529         m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg;
3530         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PORT_CONFIG,
3531                 bfa_ioc_portid(ablk->ioc));
3532         m->port = (u8)port;
3533         m->mode = (u8)mode;
3534         m->max_pf = (u8)max_pf;
3535         m->max_vf = (u8)max_vf;
3536         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3537
3538         return BFA_STATUS_OK;
3539 }
3540
3541 bfa_status_t
3542 bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, u16 bw_min,
3543                    u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg)
3544 {
3545         struct bfi_ablk_h2i_pf_req_s *m;
3546
3547         if (!bfa_ioc_is_operational(ablk->ioc)) {
3548                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3549                 return BFA_STATUS_IOC_FAILURE;
3550         }
3551
3552         if (ablk->busy) {
3553                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3554                 return  BFA_STATUS_DEVBUSY;
3555         }
3556
3557         ablk->cbfn  = cbfn;
3558         ablk->cbarg = cbarg;
3559         ablk->busy  = BFA_TRUE;
3560
3561         m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3562         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE,
3563                 bfa_ioc_portid(ablk->ioc));
3564         m->pcifn = (u8)pcifn;
3565         m->bw_min = cpu_to_be16(bw_min);
3566         m->bw_max = cpu_to_be16(bw_max);
3567         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3568
3569         return BFA_STATUS_OK;
3570 }
3571
3572 bfa_status_t
3573 bfa_ablk_optrom_en(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg)
3574 {
3575         struct bfi_ablk_h2i_optrom_s *m;
3576
3577         if (!bfa_ioc_is_operational(ablk->ioc)) {
3578                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3579                 return BFA_STATUS_IOC_FAILURE;
3580         }
3581
3582         if (ablk->busy) {
3583                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3584                 return  BFA_STATUS_DEVBUSY;
3585         }
3586
3587         ablk->cbfn  = cbfn;
3588         ablk->cbarg = cbarg;
3589         ablk->busy  = BFA_TRUE;
3590
3591         m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg;
3592         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_ENABLE,
3593                 bfa_ioc_portid(ablk->ioc));
3594         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3595
3596         return BFA_STATUS_OK;
3597 }
3598
3599 bfa_status_t
3600 bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg)
3601 {
3602         struct bfi_ablk_h2i_optrom_s *m;
3603
3604         if (!bfa_ioc_is_operational(ablk->ioc)) {
3605                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3606                 return BFA_STATUS_IOC_FAILURE;
3607         }
3608
3609         if (ablk->busy) {
3610                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3611                 return  BFA_STATUS_DEVBUSY;
3612         }
3613
3614         ablk->cbfn  = cbfn;
3615         ablk->cbarg = cbarg;
3616         ablk->busy  = BFA_TRUE;
3617
3618         m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg;
3619         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_DISABLE,
3620                 bfa_ioc_portid(ablk->ioc));
3621         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3622
3623         return BFA_STATUS_OK;
3624 }
3625
3626 /*
3627  *      SFP module specific
3628  */
3629
3630 /* forward declarations */
3631 static void bfa_sfp_getdata_send(struct bfa_sfp_s *sfp);
3632 static void bfa_sfp_media_get(struct bfa_sfp_s *sfp);
3633 static bfa_status_t bfa_sfp_speed_valid(struct bfa_sfp_s *sfp,
3634                                 enum bfa_port_speed portspeed);
3635
3636 static void
3637 bfa_cb_sfp_show(struct bfa_sfp_s *sfp)
3638 {
3639         bfa_trc(sfp, sfp->lock);
3640         if (sfp->cbfn)
3641                 sfp->cbfn(sfp->cbarg, sfp->status);
3642         sfp->lock = 0;
3643         sfp->cbfn = NULL;
3644 }
3645
3646 static void
3647 bfa_cb_sfp_state_query(struct bfa_sfp_s *sfp)
3648 {
3649         bfa_trc(sfp, sfp->portspeed);
3650         if (sfp->media) {
3651                 bfa_sfp_media_get(sfp);
3652                 if (sfp->state_query_cbfn)
3653                         sfp->state_query_cbfn(sfp->state_query_cbarg,
3654                                         sfp->status);
3655                 sfp->media = NULL;
3656         }
3657
3658         if (sfp->portspeed) {
3659                 sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed);
3660                 if (sfp->state_query_cbfn)
3661                         sfp->state_query_cbfn(sfp->state_query_cbarg,
3662                                         sfp->status);
3663                 sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
3664         }
3665
3666         sfp->state_query_lock = 0;
3667         sfp->state_query_cbfn = NULL;
3668 }
3669
3670 /*
3671  *      IOC event handler.
3672  */
3673 static void
3674 bfa_sfp_notify(void *sfp_arg, enum bfa_ioc_event_e event)
3675 {
3676         struct bfa_sfp_s *sfp = sfp_arg;
3677
3678         bfa_trc(sfp, event);
3679         bfa_trc(sfp, sfp->lock);
3680         bfa_trc(sfp, sfp->state_query_lock);
3681
3682         switch (event) {
3683         case BFA_IOC_E_DISABLED:
3684         case BFA_IOC_E_FAILED:
3685                 if (sfp->lock) {
3686                         sfp->status = BFA_STATUS_IOC_FAILURE;
3687                         bfa_cb_sfp_show(sfp);
3688                 }
3689
3690                 if (sfp->state_query_lock) {
3691                         sfp->status = BFA_STATUS_IOC_FAILURE;
3692                         bfa_cb_sfp_state_query(sfp);
3693                 }
3694                 break;
3695
3696         default:
3697                 break;
3698         }
3699 }
3700
3701 /*
3702  * SFP's State Change Notification post to AEN
3703  */
3704 static void
3705 bfa_sfp_scn_aen_post(struct bfa_sfp_s *sfp, struct bfi_sfp_scn_s *rsp)
3706 {
3707         struct bfad_s *bfad = (struct bfad_s *)sfp->ioc->bfa->bfad;
3708         struct bfa_aen_entry_s  *aen_entry;
3709         enum bfa_port_aen_event aen_evt = 0;
3710
3711         bfa_trc(sfp, (((u64)rsp->pomlvl) << 16) | (((u64)rsp->sfpid) << 8) |
3712                       ((u64)rsp->event));
3713
3714         bfad_get_aen_entry(bfad, aen_entry);
3715         if (!aen_entry)
3716                 return;
3717
3718         aen_entry->aen_data.port.ioc_type = bfa_ioc_get_type(sfp->ioc);
3719         aen_entry->aen_data.port.pwwn = sfp->ioc->attr->pwwn;
3720         aen_entry->aen_data.port.mac = bfa_ioc_get_mac(sfp->ioc);
3721
3722         switch (rsp->event) {
3723         case BFA_SFP_SCN_INSERTED:
3724                 aen_evt = BFA_PORT_AEN_SFP_INSERT;
3725                 break;
3726         case BFA_SFP_SCN_REMOVED:
3727                 aen_evt = BFA_PORT_AEN_SFP_REMOVE;
3728                 break;
3729         case BFA_SFP_SCN_FAILED:
3730                 aen_evt = BFA_PORT_AEN_SFP_ACCESS_ERROR;
3731                 break;
3732         case BFA_SFP_SCN_UNSUPPORT:
3733                 aen_evt = BFA_PORT_AEN_SFP_UNSUPPORT;
3734                 break;
3735         case BFA_SFP_SCN_POM:
3736                 aen_evt = BFA_PORT_AEN_SFP_POM;
3737                 aen_entry->aen_data.port.level = rsp->pomlvl;
3738                 break;
3739         default:
3740                 bfa_trc(sfp, rsp->event);
3741                 WARN_ON(1);
3742         }
3743
3744         /* Send the AEN notification */
3745         bfad_im_post_vendor_event(aen_entry, bfad, ++sfp->ioc->ioc_aen_seq,
3746                                   BFA_AEN_CAT_PORT, aen_evt);
3747 }
3748
3749 /*
3750  *      SFP get data send
3751  */
3752 static void
3753 bfa_sfp_getdata_send(struct bfa_sfp_s *sfp)
3754 {
3755         struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
3756
3757         bfa_trc(sfp, req->memtype);
3758
3759         /* build host command */
3760         bfi_h2i_set(req->mh, BFI_MC_SFP, BFI_SFP_H2I_SHOW,
3761                         bfa_ioc_portid(sfp->ioc));
3762
3763         /* send mbox cmd */
3764         bfa_ioc_mbox_queue(sfp->ioc, &sfp->mbcmd);
3765 }
3766
3767 /*
3768  *      SFP is valid, read sfp data
3769  */
3770 static void
3771 bfa_sfp_getdata(struct bfa_sfp_s *sfp, enum bfi_sfp_mem_e memtype)
3772 {
3773         struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
3774
3775         WARN_ON(sfp->lock != 0);
3776         bfa_trc(sfp, sfp->state);
3777
3778         sfp->lock = 1;
3779         sfp->memtype = memtype;
3780         req->memtype = memtype;
3781
3782         /* Setup SG list */
3783         bfa_alen_set(&req->alen, sizeof(struct sfp_mem_s), sfp->dbuf_pa);
3784
3785         bfa_sfp_getdata_send(sfp);
3786 }
3787
3788 /*
3789  *      SFP scn handler
3790  */
3791 static void
3792 bfa_sfp_scn(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg)
3793 {
3794         struct bfi_sfp_scn_s *rsp = (struct bfi_sfp_scn_s *) msg;
3795
3796         switch (rsp->event) {
3797         case BFA_SFP_SCN_INSERTED:
3798                 sfp->state = BFA_SFP_STATE_INSERTED;
3799                 sfp->data_valid = 0;
3800                 bfa_sfp_scn_aen_post(sfp, rsp);
3801                 break;
3802         case BFA_SFP_SCN_REMOVED:
3803                 sfp->state = BFA_SFP_STATE_REMOVED;
3804                 sfp->data_valid = 0;
3805                 bfa_sfp_scn_aen_post(sfp, rsp);
3806                 break;
3807         case BFA_SFP_SCN_FAILED:
3808                 sfp->state = BFA_SFP_STATE_FAILED;
3809                 sfp->data_valid = 0;
3810                 bfa_sfp_scn_aen_post(sfp, rsp);
3811                 break;
3812         case BFA_SFP_SCN_UNSUPPORT:
3813                 sfp->state = BFA_SFP_STATE_UNSUPPORT;
3814                 bfa_sfp_scn_aen_post(sfp, rsp);
3815                 if (!sfp->lock)
3816                         bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3817                 break;
3818         case BFA_SFP_SCN_POM:
3819                 bfa_sfp_scn_aen_post(sfp, rsp);
3820                 break;
3821         case BFA_SFP_SCN_VALID:
3822                 sfp->state = BFA_SFP_STATE_VALID;
3823                 if (!sfp->lock)
3824                         bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3825                 break;
3826         default:
3827                 bfa_trc(sfp, rsp->event);
3828                 WARN_ON(1);
3829         }
3830 }
3831
3832 /*
3833  * SFP show complete
3834  */
3835 static void
3836 bfa_sfp_show_comp(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg)
3837 {
3838         struct bfi_sfp_rsp_s *rsp = (struct bfi_sfp_rsp_s *) msg;
3839
3840         if (!sfp->lock) {
3841                 /*
3842                  * receiving response after ioc failure
3843                  */
3844                 bfa_trc(sfp, sfp->lock);
3845                 return;
3846         }
3847
3848         bfa_trc(sfp, rsp->status);
3849         if (rsp->status == BFA_STATUS_OK) {
3850                 sfp->data_valid = 1;
3851                 if (sfp->state == BFA_SFP_STATE_VALID)
3852                         sfp->status = BFA_STATUS_OK;
3853                 else if (sfp->state == BFA_SFP_STATE_UNSUPPORT)
3854                         sfp->status = BFA_STATUS_SFP_UNSUPP;
3855                 else
3856                         bfa_trc(sfp, sfp->state);
3857         } else {
3858                 sfp->data_valid = 0;
3859                 sfp->status = rsp->status;
3860                 /* sfpshow shouldn't change sfp state */
3861         }
3862
3863         bfa_trc(sfp, sfp->memtype);
3864         if (sfp->memtype == BFI_SFP_MEM_DIAGEXT) {
3865                 bfa_trc(sfp, sfp->data_valid);
3866                 if (sfp->data_valid) {
3867                         u32     size = sizeof(struct sfp_mem_s);
3868                         u8 *des = (u8 *)(sfp->sfpmem);
3869                         memcpy(des, sfp->dbuf_kva, size);
3870                 }
3871                 /*
3872                  * Queue completion callback.
3873                  */
3874                 bfa_cb_sfp_show(sfp);
3875         } else
3876                 sfp->lock = 0;
3877
3878         bfa_trc(sfp, sfp->state_query_lock);
3879         if (sfp->state_query_lock) {
3880                 sfp->state = rsp->state;
3881                 /* Complete callback */
3882                 bfa_cb_sfp_state_query(sfp);
3883         }
3884 }
3885
3886 /*
3887  *      SFP query fw sfp state
3888  */
3889 static void
3890 bfa_sfp_state_query(struct bfa_sfp_s *sfp)
3891 {
3892         struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
3893
3894         /* Should not be doing query if not in _INIT state */
3895         WARN_ON(sfp->state != BFA_SFP_STATE_INIT);
3896         WARN_ON(sfp->state_query_lock != 0);
3897         bfa_trc(sfp, sfp->state);
3898
3899         sfp->state_query_lock = 1;
3900         req->memtype = 0;
3901
3902         if (!sfp->lock)
3903                 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3904 }
3905
3906 static void
3907 bfa_sfp_media_get(struct bfa_sfp_s *sfp)
3908 {
3909         enum bfa_defs_sfp_media_e *media = sfp->media;
3910
3911         *media = BFA_SFP_MEDIA_UNKNOWN;
3912
3913         if (sfp->state == BFA_SFP_STATE_UNSUPPORT)
3914                 *media = BFA_SFP_MEDIA_UNSUPPORT;
3915         else if (sfp->state == BFA_SFP_STATE_VALID) {
3916                 union sfp_xcvr_e10g_code_u e10g;
3917                 struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva;
3918                 u16 xmtr_tech = (sfpmem->srlid_base.xcvr[4] & 0x3) << 7 |
3919                                 (sfpmem->srlid_base.xcvr[5] >> 1);
3920
3921                 e10g.b = sfpmem->srlid_base.xcvr[0];
3922                 bfa_trc(sfp, e10g.b);
3923                 bfa_trc(sfp, xmtr_tech);
3924                 /* check fc transmitter tech */
3925                 if ((xmtr_tech & SFP_XMTR_TECH_CU) ||
3926                     (xmtr_tech & SFP_XMTR_TECH_CP) ||
3927                     (xmtr_tech & SFP_XMTR_TECH_CA))
3928                         *media = BFA_SFP_MEDIA_CU;
3929                 else if ((xmtr_tech & SFP_XMTR_TECH_EL_INTRA) ||
3930                          (xmtr_tech & SFP_XMTR_TECH_EL_INTER))
3931                         *media = BFA_SFP_MEDIA_EL;
3932                 else if ((xmtr_tech & SFP_XMTR_TECH_LL) ||
3933                          (xmtr_tech & SFP_XMTR_TECH_LC))
3934                         *media = BFA_SFP_MEDIA_LW;
3935                 else if ((xmtr_tech & SFP_XMTR_TECH_SL) ||
3936                          (xmtr_tech & SFP_XMTR_TECH_SN) ||
3937                          (xmtr_tech & SFP_XMTR_TECH_SA))
3938                         *media = BFA_SFP_MEDIA_SW;
3939                 /* Check 10G Ethernet Compilance code */
3940                 else if (e10g.r.e10g_sr)
3941                         *media = BFA_SFP_MEDIA_SW;
3942                 else if (e10g.r.e10g_lrm && e10g.r.e10g_lr)
3943                         *media = BFA_SFP_MEDIA_LW;
3944                 else if (e10g.r.e10g_unall)
3945                         *media = BFA_SFP_MEDIA_UNKNOWN;
3946                 else
3947                         bfa_trc(sfp, 0);
3948         } else
3949                 bfa_trc(sfp, sfp->state);
3950 }
3951
3952 static bfa_status_t
3953 bfa_sfp_speed_valid(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed)
3954 {
3955         struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva;
3956         struct sfp_xcvr_s *xcvr = (struct sfp_xcvr_s *) sfpmem->srlid_base.xcvr;
3957         union sfp_xcvr_fc3_code_u fc3 = xcvr->fc3;
3958         union sfp_xcvr_e10g_code_u e10g = xcvr->e10g;
3959
3960         if (portspeed == BFA_PORT_SPEED_10GBPS) {
3961                 if (e10g.r.e10g_sr || e10g.r.e10g_lr)
3962                         return BFA_STATUS_OK;
3963                 else {
3964                         bfa_trc(sfp, e10g.b);
3965                         return BFA_STATUS_UNSUPP_SPEED;
3966                 }
3967         }
3968         if (((portspeed & BFA_PORT_SPEED_16GBPS) && fc3.r.mb1600) ||
3969             ((portspeed & BFA_PORT_SPEED_8GBPS) && fc3.r.mb800) ||
3970             ((portspeed & BFA_PORT_SPEED_4GBPS) && fc3.r.mb400) ||
3971             ((portspeed & BFA_PORT_SPEED_2GBPS) && fc3.r.mb200) ||
3972             ((portspeed & BFA_PORT_SPEED_1GBPS) && fc3.r.mb100))
3973                 return BFA_STATUS_OK;
3974         else {
3975                 bfa_trc(sfp, portspeed);
3976                 bfa_trc(sfp, fc3.b);
3977                 bfa_trc(sfp, e10g.b);
3978                 return BFA_STATUS_UNSUPP_SPEED;
3979         }
3980 }
3981
3982 /*
3983  *      SFP hmbox handler
3984  */
3985 void
3986 bfa_sfp_intr(void *sfparg, struct bfi_mbmsg_s *msg)
3987 {
3988         struct bfa_sfp_s *sfp = sfparg;
3989
3990         switch (msg->mh.msg_id) {
3991         case BFI_SFP_I2H_SHOW:
3992                 bfa_sfp_show_comp(sfp, msg);
3993                 break;
3994
3995         case BFI_SFP_I2H_SCN:
3996                 bfa_sfp_scn(sfp, msg);
3997                 break;
3998
3999         default:
4000                 bfa_trc(sfp, msg->mh.msg_id);
4001                 WARN_ON(1);
4002         }
4003 }
4004
4005 /*
4006  *      Return DMA memory needed by sfp module.
4007  */
4008 u32
4009 bfa_sfp_meminfo(void)
4010 {
4011         return BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
4012 }
4013
4014 /*
4015  *      Attach virtual and physical memory for SFP.
4016  */
4017 void
4018 bfa_sfp_attach(struct bfa_sfp_s *sfp, struct bfa_ioc_s *ioc, void *dev,
4019                 struct bfa_trc_mod_s *trcmod)
4020 {
4021         sfp->dev = dev;
4022         sfp->ioc = ioc;
4023         sfp->trcmod = trcmod;
4024
4025         sfp->cbfn = NULL;
4026         sfp->cbarg = NULL;
4027         sfp->sfpmem = NULL;
4028         sfp->lock = 0;
4029         sfp->data_valid = 0;
4030         sfp->state = BFA_SFP_STATE_INIT;
4031         sfp->state_query_lock = 0;
4032         sfp->state_query_cbfn = NULL;
4033         sfp->state_query_cbarg = NULL;
4034         sfp->media = NULL;
4035         sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
4036         sfp->is_elb = BFA_FALSE;
4037
4038         bfa_ioc_mbox_regisr(sfp->ioc, BFI_MC_SFP, bfa_sfp_intr, sfp);
4039         bfa_q_qe_init(&sfp->ioc_notify);
4040         bfa_ioc_notify_init(&sfp->ioc_notify, bfa_sfp_notify, sfp);
4041         list_add_tail(&sfp->ioc_notify.qe, &sfp->ioc->notify_q);
4042 }
4043
4044 /*
4045  *      Claim Memory for SFP
4046  */
4047 void
4048 bfa_sfp_memclaim(struct bfa_sfp_s *sfp, u8 *dm_kva, u64 dm_pa)
4049 {
4050         sfp->dbuf_kva   = dm_kva;
4051         sfp->dbuf_pa    = dm_pa;
4052         memset(sfp->dbuf_kva, 0, sizeof(struct sfp_mem_s));
4053
4054         dm_kva += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
4055         dm_pa += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
4056 }
4057
4058 /*
4059  * Show SFP eeprom content
4060  *
4061  * @param[in] sfp   - bfa sfp module
4062  *
4063  * @param[out] sfpmem - sfp eeprom data
4064  *
4065  */
4066 bfa_status_t
4067 bfa_sfp_show(struct bfa_sfp_s *sfp, struct sfp_mem_s *sfpmem,
4068                 bfa_cb_sfp_t cbfn, void *cbarg)
4069 {
4070
4071         if (!bfa_ioc_is_operational(sfp->ioc)) {
4072                 bfa_trc(sfp, 0);
4073                 return BFA_STATUS_IOC_NON_OP;
4074         }
4075
4076         if (sfp->lock) {
4077                 bfa_trc(sfp, 0);
4078                 return BFA_STATUS_DEVBUSY;
4079         }
4080
4081         sfp->cbfn = cbfn;
4082         sfp->cbarg = cbarg;
4083         sfp->sfpmem = sfpmem;
4084
4085         bfa_sfp_getdata(sfp, BFI_SFP_MEM_DIAGEXT);
4086         return BFA_STATUS_OK;
4087 }
4088
4089 /*
4090  * Return SFP Media type
4091  *
4092  * @param[in] sfp   - bfa sfp module
4093  *
4094  * @param[out] media - port speed from user
4095  *
4096  */
4097 bfa_status_t
4098 bfa_sfp_media(struct bfa_sfp_s *sfp, enum bfa_defs_sfp_media_e *media,
4099                 bfa_cb_sfp_t cbfn, void *cbarg)
4100 {
4101         if (!bfa_ioc_is_operational(sfp->ioc)) {
4102                 bfa_trc(sfp, 0);
4103                 return BFA_STATUS_IOC_NON_OP;
4104         }
4105
4106         sfp->media = media;
4107         if (sfp->state == BFA_SFP_STATE_INIT) {
4108                 if (sfp->state_query_lock) {
4109                         bfa_trc(sfp, 0);
4110                         return BFA_STATUS_DEVBUSY;
4111                 } else {
4112                         sfp->state_query_cbfn = cbfn;
4113                         sfp->state_query_cbarg = cbarg;
4114                         bfa_sfp_state_query(sfp);
4115                         return BFA_STATUS_SFP_NOT_READY;
4116                 }
4117         }
4118
4119         bfa_sfp_media_get(sfp);
4120         return BFA_STATUS_OK;
4121 }
4122
4123 /*
4124  * Check if user set port speed is allowed by the SFP
4125  *
4126  * @param[in] sfp   - bfa sfp module
4127  * @param[in] portspeed - port speed from user
4128  *
4129  */
4130 bfa_status_t
4131 bfa_sfp_speed(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed,
4132                 bfa_cb_sfp_t cbfn, void *cbarg)
4133 {
4134         WARN_ON(portspeed == BFA_PORT_SPEED_UNKNOWN);
4135
4136         if (!bfa_ioc_is_operational(sfp->ioc))
4137                 return BFA_STATUS_IOC_NON_OP;
4138
4139         /* For Mezz card, all speed is allowed */
4140         if (bfa_mfg_is_mezz(sfp->ioc->attr->card_type))
4141                 return BFA_STATUS_OK;
4142
4143         /* Check SFP state */
4144         sfp->portspeed = portspeed;
4145         if (sfp->state == BFA_SFP_STATE_INIT) {
4146                 if (sfp->state_query_lock) {
4147                         bfa_trc(sfp, 0);
4148                         return BFA_STATUS_DEVBUSY;
4149                 } else {
4150                         sfp->state_query_cbfn = cbfn;
4151                         sfp->state_query_cbarg = cbarg;
4152                         bfa_sfp_state_query(sfp);
4153                         return BFA_STATUS_SFP_NOT_READY;
4154                 }
4155         }
4156
4157         if (sfp->state == BFA_SFP_STATE_REMOVED ||
4158             sfp->state == BFA_SFP_STATE_FAILED) {
4159                 bfa_trc(sfp, sfp->state);
4160                 return BFA_STATUS_NO_SFP_DEV;
4161         }
4162
4163         if (sfp->state == BFA_SFP_STATE_INSERTED) {
4164                 bfa_trc(sfp, sfp->state);
4165                 return BFA_STATUS_DEVBUSY;  /* sfp is reading data */
4166         }
4167
4168         /* For eloopback, all speed is allowed */
4169         if (sfp->is_elb)
4170                 return BFA_STATUS_OK;
4171
4172         return bfa_sfp_speed_valid(sfp, portspeed);
4173 }
4174
4175 /*
4176  *      Flash module specific
4177  */
4178
4179 /*
4180  * FLASH DMA buffer should be big enough to hold both MFG block and
4181  * asic block(64k) at the same time and also should be 2k aligned to
4182  * avoid write segement to cross sector boundary.
4183  */
4184 #define BFA_FLASH_SEG_SZ        2048
4185 #define BFA_FLASH_DMA_BUF_SZ    \
4186         BFA_ROUNDUP(0x010000 + sizeof(struct bfa_mfg_block_s), BFA_FLASH_SEG_SZ)
4187
4188 static void
4189 bfa_flash_aen_audit_post(struct bfa_ioc_s *ioc, enum bfa_audit_aen_event event,
4190                         int inst, int type)
4191 {
4192         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
4193         struct bfa_aen_entry_s  *aen_entry;
4194
4195         bfad_get_aen_entry(bfad, aen_entry);
4196         if (!aen_entry)
4197                 return;
4198
4199         aen_entry->aen_data.audit.pwwn = ioc->attr->pwwn;
4200         aen_entry->aen_data.audit.partition_inst = inst;
4201         aen_entry->aen_data.audit.partition_type = type;
4202
4203         /* Send the AEN notification */
4204         bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq,
4205                                   BFA_AEN_CAT_AUDIT, event);
4206 }
4207
4208 static void
4209 bfa_flash_cb(struct bfa_flash_s *flash)
4210 {
4211         flash->op_busy = 0;
4212         if (flash->cbfn)
4213                 flash->cbfn(flash->cbarg, flash->status);
4214 }
4215
4216 static void
4217 bfa_flash_notify(void *cbarg, enum bfa_ioc_event_e event)
4218 {
4219         struct bfa_flash_s      *flash = cbarg;
4220
4221         bfa_trc(flash, event);
4222         switch (event) {
4223         case BFA_IOC_E_DISABLED:
4224         case BFA_IOC_E_FAILED:
4225                 if (flash->op_busy) {
4226                         flash->status = BFA_STATUS_IOC_FAILURE;
4227                         flash->cbfn(flash->cbarg, flash->status);
4228                         flash->op_busy = 0;
4229                 }
4230                 break;
4231
4232         default:
4233                 break;
4234         }
4235 }
4236
4237 /*
4238  * Send flash attribute query request.
4239  *
4240  * @param[in] cbarg - callback argument
4241  */
4242 static void
4243 bfa_flash_query_send(void *cbarg)
4244 {
4245         struct bfa_flash_s *flash = cbarg;
4246         struct bfi_flash_query_req_s *msg =
4247                         (struct bfi_flash_query_req_s *) flash->mb.msg;
4248
4249         bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_QUERY_REQ,
4250                 bfa_ioc_portid(flash->ioc));
4251         bfa_alen_set(&msg->alen, sizeof(struct bfa_flash_attr_s),
4252                 flash->dbuf_pa);
4253         bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4254 }
4255
4256 /*
4257  * Send flash write request.
4258  *
4259  * @param[in] cbarg - callback argument
4260  */
4261 static void
4262 bfa_flash_write_send(struct bfa_flash_s *flash)
4263 {
4264         struct bfi_flash_write_req_s *msg =
4265                         (struct bfi_flash_write_req_s *) flash->mb.msg;
4266         u32     len;
4267
4268         msg->type = be32_to_cpu(flash->type);
4269         msg->instance = flash->instance;
4270         msg->offset = be32_to_cpu(flash->addr_off + flash->offset);
4271         len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ?
4272                 flash->residue : BFA_FLASH_DMA_BUF_SZ;
4273         msg->length = be32_to_cpu(len);
4274
4275         /* indicate if it's the last msg of the whole write operation */
4276         msg->last = (len == flash->residue) ? 1 : 0;
4277
4278         bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_WRITE_REQ,
4279                         bfa_ioc_portid(flash->ioc));
4280         bfa_alen_set(&msg->alen, len, flash->dbuf_pa);
4281         memcpy(flash->dbuf_kva, flash->ubuf + flash->offset, len);
4282         bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4283
4284         flash->residue -= len;
4285         flash->offset += len;
4286 }
4287
4288 /*
4289  * Send flash read request.
4290  *
4291  * @param[in] cbarg - callback argument
4292  */
4293 static void
4294 bfa_flash_read_send(void *cbarg)
4295 {
4296         struct bfa_flash_s *flash = cbarg;
4297         struct bfi_flash_read_req_s *msg =
4298                         (struct bfi_flash_read_req_s *) flash->mb.msg;
4299         u32     len;
4300
4301         msg->type = be32_to_cpu(flash->type);
4302         msg->instance = flash->instance;
4303         msg->offset = be32_to_cpu(flash->addr_off + flash->offset);
4304         len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ?
4305                         flash->residue : BFA_FLASH_DMA_BUF_SZ;
4306         msg->length = be32_to_cpu(len);
4307         bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_READ_REQ,
4308                 bfa_ioc_portid(flash->ioc));
4309         bfa_alen_set(&msg->alen, len, flash->dbuf_pa);
4310         bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4311 }
4312
4313 /*
4314  * Send flash erase request.
4315  *
4316  * @param[in] cbarg - callback argument
4317  */
4318 static void
4319 bfa_flash_erase_send(void *cbarg)
4320 {
4321         struct bfa_flash_s *flash = cbarg;
4322         struct bfi_flash_erase_req_s *msg =
4323                         (struct bfi_flash_erase_req_s *) flash->mb.msg;
4324
4325         msg->type = be32_to_cpu(flash->type);
4326         msg->instance = flash->instance;
4327         bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_ERASE_REQ,
4328                         bfa_ioc_portid(flash->ioc));
4329         bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4330 }
4331
4332 /*
4333  * Process flash response messages upon receiving interrupts.
4334  *
4335  * @param[in] flasharg - flash structure
4336  * @param[in] msg - message structure
4337  */
4338 static void
4339 bfa_flash_intr(void *flasharg, struct bfi_mbmsg_s *msg)
4340 {
4341         struct bfa_flash_s *flash = flasharg;
4342         u32     status;
4343
4344         union {
4345                 struct bfi_flash_query_rsp_s *query;
4346                 struct bfi_flash_erase_rsp_s *erase;
4347                 struct bfi_flash_write_rsp_s *write;
4348                 struct bfi_flash_read_rsp_s *read;
4349                 struct bfi_flash_event_s *event;
4350                 struct bfi_mbmsg_s   *msg;
4351         } m;
4352
4353         m.msg = msg;
4354         bfa_trc(flash, msg->mh.msg_id);
4355
4356         if (!flash->op_busy && msg->mh.msg_id != BFI_FLASH_I2H_EVENT) {
4357                 /* receiving response after ioc failure */
4358                 bfa_trc(flash, 0x9999);
4359                 return;
4360         }
4361
4362         switch (msg->mh.msg_id) {
4363         case BFI_FLASH_I2H_QUERY_RSP:
4364                 status = be32_to_cpu(m.query->status);
4365                 bfa_trc(flash, status);
4366                 if (status == BFA_STATUS_OK) {
4367                         u32     i;
4368                         struct bfa_flash_attr_s *attr, *f;
4369
4370                         attr = (struct bfa_flash_attr_s *) flash->ubuf;
4371                         f = (struct bfa_flash_attr_s *) flash->dbuf_kva;
4372                         attr->status = be32_to_cpu(f->status);
4373                         attr->npart = be32_to_cpu(f->npart);
4374                         bfa_trc(flash, attr->status);
4375                         bfa_trc(flash, attr->npart);
4376                         for (i = 0; i < attr->npart; i++) {
4377                                 attr->part[i].part_type =
4378                                         be32_to_cpu(f->part[i].part_type);
4379                                 attr->part[i].part_instance =
4380                                         be32_to_cpu(f->part[i].part_instance);
4381                                 attr->part[i].part_off =
4382                                         be32_to_cpu(f->part[i].part_off);
4383                                 attr->part[i].part_size =
4384                                         be32_to_cpu(f->part[i].part_size);
4385                                 attr->part[i].part_len =
4386                                         be32_to_cpu(f->part[i].part_len);
4387                                 attr->part[i].part_status =
4388                                         be32_to_cpu(f->part[i].part_status);
4389                         }
4390                 }
4391                 flash->status = status;
4392                 bfa_flash_cb(flash);
4393                 break;
4394         case BFI_FLASH_I2H_ERASE_RSP:
4395                 status = be32_to_cpu(m.erase->status);
4396                 bfa_trc(flash, status);
4397                 flash->status = status;
4398                 bfa_flash_cb(flash);
4399                 break;
4400         case BFI_FLASH_I2H_WRITE_RSP:
4401                 status = be32_to_cpu(m.write->status);
4402                 bfa_trc(flash, status);
4403                 if (status != BFA_STATUS_OK || flash->residue == 0) {
4404                         flash->status = status;
4405                         bfa_flash_cb(flash);
4406                 } else {
4407                         bfa_trc(flash, flash->offset);
4408                         bfa_flash_write_send(flash);
4409                 }
4410                 break;
4411         case BFI_FLASH_I2H_READ_RSP:
4412                 status = be32_to_cpu(m.read->status);
4413                 bfa_trc(flash, status);
4414                 if (status != BFA_STATUS_OK) {
4415                         flash->status = status;
4416                         bfa_flash_cb(flash);
4417                 } else {
4418                         u32 len = be32_to_cpu(m.read->length);
4419                         bfa_trc(flash, flash->offset);
4420                         bfa_trc(flash, len);
4421                         memcpy(flash->ubuf + flash->offset,
4422                                 flash->dbuf_kva, len);
4423                         flash->residue -= len;
4424                         flash->offset += len;
4425                         if (flash->residue == 0) {
4426                                 flash->status = status;
4427                                 bfa_flash_cb(flash);
4428                         } else
4429                                 bfa_flash_read_send(flash);
4430                 }
4431                 break;
4432         case BFI_FLASH_I2H_BOOT_VER_RSP:
4433                 break;
4434         case BFI_FLASH_I2H_EVENT:
4435                 status = be32_to_cpu(m.event->status);
4436                 bfa_trc(flash, status);
4437                 if (status == BFA_STATUS_BAD_FWCFG)
4438                         bfa_ioc_aen_post(flash->ioc, BFA_IOC_AEN_FWCFG_ERROR);
4439                 else if (status == BFA_STATUS_INVALID_VENDOR) {
4440                         u32 param;
4441                         param = be32_to_cpu(m.event->param);
4442                         bfa_trc(flash, param);
4443                         bfa_ioc_aen_post(flash->ioc,
4444                                 BFA_IOC_AEN_INVALID_VENDOR);
4445                 }
4446                 break;
4447
4448         default:
4449                 WARN_ON(1);
4450         }
4451 }
4452
4453 /*
4454  * Flash memory info API.
4455  *
4456  * @param[in] mincfg - minimal cfg variable
4457  */
4458 u32
4459 bfa_flash_meminfo(bfa_boolean_t mincfg)
4460 {
4461         /* min driver doesn't need flash */
4462         if (mincfg)
4463                 return 0;
4464         return BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
4465 }
4466
4467 /*
4468  * Flash attach API.
4469  *
4470  * @param[in] flash - flash structure
4471  * @param[in] ioc  - ioc structure
4472  * @param[in] dev  - device structure
4473  * @param[in] trcmod - trace module
4474  * @param[in] logmod - log module
4475  */
4476 void
4477 bfa_flash_attach(struct bfa_flash_s *flash, struct bfa_ioc_s *ioc, void *dev,
4478                 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
4479 {
4480         flash->ioc = ioc;
4481         flash->trcmod = trcmod;
4482         flash->cbfn = NULL;
4483         flash->cbarg = NULL;
4484         flash->op_busy = 0;
4485
4486         bfa_ioc_mbox_regisr(flash->ioc, BFI_MC_FLASH, bfa_flash_intr, flash);
4487         bfa_q_qe_init(&flash->ioc_notify);
4488         bfa_ioc_notify_init(&flash->ioc_notify, bfa_flash_notify, flash);
4489         list_add_tail(&flash->ioc_notify.qe, &flash->ioc->notify_q);
4490
4491         /* min driver doesn't need flash */
4492         if (mincfg) {
4493                 flash->dbuf_kva = NULL;
4494                 flash->dbuf_pa = 0;
4495         }
4496 }
4497
4498 /*
4499  * Claim memory for flash
4500  *
4501  * @param[in] flash - flash structure
4502  * @param[in] dm_kva - pointer to virtual memory address
4503  * @param[in] dm_pa - physical memory address
4504  * @param[in] mincfg - minimal cfg variable
4505  */
4506 void
4507 bfa_flash_memclaim(struct bfa_flash_s *flash, u8 *dm_kva, u64 dm_pa,
4508                 bfa_boolean_t mincfg)
4509 {
4510         if (mincfg)
4511                 return;
4512
4513         flash->dbuf_kva = dm_kva;
4514         flash->dbuf_pa = dm_pa;
4515         memset(flash->dbuf_kva, 0, BFA_FLASH_DMA_BUF_SZ);
4516         dm_kva += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
4517         dm_pa += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
4518 }
4519
4520 /*
4521  * Get flash attribute.
4522  *
4523  * @param[in] flash - flash structure
4524  * @param[in] attr - flash attribute structure
4525  * @param[in] cbfn - callback function
4526  * @param[in] cbarg - callback argument
4527  *
4528  * Return status.
4529  */
4530 bfa_status_t
4531 bfa_flash_get_attr(struct bfa_flash_s *flash, struct bfa_flash_attr_s *attr,
4532                 bfa_cb_flash_t cbfn, void *cbarg)
4533 {
4534         bfa_trc(flash, BFI_FLASH_H2I_QUERY_REQ);
4535
4536         if (!bfa_ioc_is_operational(flash->ioc))
4537                 return BFA_STATUS_IOC_NON_OP;
4538
4539         if (flash->op_busy) {
4540                 bfa_trc(flash, flash->op_busy);
4541                 return BFA_STATUS_DEVBUSY;
4542         }
4543
4544         flash->op_busy = 1;
4545         flash->cbfn = cbfn;
4546         flash->cbarg = cbarg;
4547         flash->ubuf = (u8 *) attr;
4548         bfa_flash_query_send(flash);
4549
4550         return BFA_STATUS_OK;
4551 }
4552
4553 /*
4554  * Erase flash partition.
4555  *
4556  * @param[in] flash - flash structure
4557  * @param[in] type - flash partition type
4558  * @param[in] instance - flash partition instance
4559  * @param[in] cbfn - callback function
4560  * @param[in] cbarg - callback argument
4561  *
4562  * Return status.
4563  */
4564 bfa_status_t
4565 bfa_flash_erase_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
4566                 u8 instance, bfa_cb_flash_t cbfn, void *cbarg)
4567 {
4568         bfa_trc(flash, BFI_FLASH_H2I_ERASE_REQ);
4569         bfa_trc(flash, type);
4570         bfa_trc(flash, instance);
4571
4572         if (!bfa_ioc_is_operational(flash->ioc))
4573                 return BFA_STATUS_IOC_NON_OP;
4574
4575         if (flash->op_busy) {
4576                 bfa_trc(flash, flash->op_busy);
4577                 return BFA_STATUS_DEVBUSY;
4578         }
4579
4580         flash->op_busy = 1;
4581         flash->cbfn = cbfn;
4582         flash->cbarg = cbarg;
4583         flash->type = type;
4584         flash->instance = instance;
4585
4586         bfa_flash_erase_send(flash);
4587         bfa_flash_aen_audit_post(flash->ioc, BFA_AUDIT_AEN_FLASH_ERASE,
4588                                 instance, type);
4589         return BFA_STATUS_OK;
4590 }
4591
4592 /*
4593  * Update flash partition.
4594  *
4595  * @param[in] flash - flash structure
4596  * @param[in] type - flash partition type
4597  * @param[in] instance - flash partition instance
4598  * @param[in] buf - update data buffer
4599  * @param[in] len - data buffer length
4600  * @param[in] offset - offset relative to the partition starting address
4601  * @param[in] cbfn - callback function
4602  * @param[in] cbarg - callback argument
4603  *
4604  * Return status.
4605  */
4606 bfa_status_t
4607 bfa_flash_update_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
4608                 u8 instance, void *buf, u32 len, u32 offset,
4609                 bfa_cb_flash_t cbfn, void *cbarg)
4610 {
4611         bfa_trc(flash, BFI_FLASH_H2I_WRITE_REQ);
4612         bfa_trc(flash, type);
4613         bfa_trc(flash, instance);
4614         bfa_trc(flash, len);
4615         bfa_trc(flash, offset);
4616
4617         if (!bfa_ioc_is_operational(flash->ioc))
4618                 return BFA_STATUS_IOC_NON_OP;
4619
4620         /*
4621          * 'len' must be in word (4-byte) boundary
4622          * 'offset' must be in sector (16kb) boundary
4623          */
4624         if (!len || (len & 0x03) || (offset & 0x00003FFF))
4625                 return BFA_STATUS_FLASH_BAD_LEN;
4626
4627         if (type == BFA_FLASH_PART_MFG)
4628                 return BFA_STATUS_EINVAL;
4629
4630         if (flash->op_busy) {
4631                 bfa_trc(flash, flash->op_busy);
4632                 return BFA_STATUS_DEVBUSY;
4633         }
4634
4635         flash->op_busy = 1;
4636         flash->cbfn = cbfn;
4637         flash->cbarg = cbarg;
4638         flash->type = type;
4639         flash->instance = instance;
4640         flash->residue = len;
4641         flash->offset = 0;
4642         flash->addr_off = offset;
4643         flash->ubuf = buf;
4644
4645         bfa_flash_write_send(flash);
4646         return BFA_STATUS_OK;
4647 }
4648
4649 /*
4650  * Read flash partition.
4651  *
4652  * @param[in] flash - flash structure
4653  * @param[in] type - flash partition type
4654  * @param[in] instance - flash partition instance
4655  * @param[in] buf - read data buffer
4656  * @param[in] len - data buffer length
4657  * @param[in] offset - offset relative to the partition starting address
4658  * @param[in] cbfn - callback function
4659  * @param[in] cbarg - callback argument
4660  *
4661  * Return status.
4662  */
4663 bfa_status_t
4664 bfa_flash_read_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
4665                 u8 instance, void *buf, u32 len, u32 offset,
4666                 bfa_cb_flash_t cbfn, void *cbarg)
4667 {
4668         bfa_trc(flash, BFI_FLASH_H2I_READ_REQ);
4669         bfa_trc(flash, type);
4670         bfa_trc(flash, instance);
4671         bfa_trc(flash, len);
4672         bfa_trc(flash, offset);
4673
4674         if (!bfa_ioc_is_operational(flash->ioc))
4675                 return BFA_STATUS_IOC_NON_OP;
4676
4677         /*
4678          * 'len' must be in word (4-byte) boundary
4679          * 'offset' must be in sector (16kb) boundary
4680          */
4681         if (!len || (len & 0x03) || (offset & 0x00003FFF))
4682                 return BFA_STATUS_FLASH_BAD_LEN;
4683
4684         if (flash->op_busy) {
4685                 bfa_trc(flash, flash->op_busy);
4686                 return BFA_STATUS_DEVBUSY;
4687         }
4688
4689         flash->op_busy = 1;
4690         flash->cbfn = cbfn;
4691         flash->cbarg = cbarg;
4692         flash->type = type;
4693         flash->instance = instance;
4694         flash->residue = len;
4695         flash->offset = 0;
4696         flash->addr_off = offset;
4697         flash->ubuf = buf;
4698         bfa_flash_read_send(flash);
4699
4700         return BFA_STATUS_OK;
4701 }
4702
4703 /*
4704  *      DIAG module specific
4705  */
4706
4707 #define BFA_DIAG_MEMTEST_TOV    50000   /* memtest timeout in msec */
4708 #define CT2_BFA_DIAG_MEMTEST_TOV        (9*30*1000)  /* 4.5 min */
4709
4710 /* IOC event handler */
4711 static void
4712 bfa_diag_notify(void *diag_arg, enum bfa_ioc_event_e event)
4713 {
4714         struct bfa_diag_s *diag = diag_arg;
4715
4716         bfa_trc(diag, event);
4717         bfa_trc(diag, diag->block);
4718         bfa_trc(diag, diag->fwping.lock);
4719         bfa_trc(diag, diag->tsensor.lock);
4720
4721         switch (event) {
4722         case BFA_IOC_E_DISABLED:
4723         case BFA_IOC_E_FAILED:
4724                 if (diag->fwping.lock) {
4725                         diag->fwping.status = BFA_STATUS_IOC_FAILURE;
4726                         diag->fwping.cbfn(diag->fwping.cbarg,
4727                                         diag->fwping.status);
4728                         diag->fwping.lock = 0;
4729                 }
4730
4731                 if (diag->tsensor.lock) {
4732                         diag->tsensor.status = BFA_STATUS_IOC_FAILURE;
4733                         diag->tsensor.cbfn(diag->tsensor.cbarg,
4734                                            diag->tsensor.status);
4735                         diag->tsensor.lock = 0;
4736                 }
4737
4738                 if (diag->block) {
4739                         if (diag->timer_active) {
4740                                 bfa_timer_stop(&diag->timer);
4741                                 diag->timer_active = 0;
4742                         }
4743
4744                         diag->status = BFA_STATUS_IOC_FAILURE;
4745                         diag->cbfn(diag->cbarg, diag->status);
4746                         diag->block = 0;
4747                 }
4748                 break;
4749
4750         default:
4751                 break;
4752         }
4753 }
4754
4755 static void
4756 bfa_diag_memtest_done(void *cbarg)
4757 {
4758         struct bfa_diag_s *diag = cbarg;
4759         struct bfa_ioc_s  *ioc = diag->ioc;
4760         struct bfa_diag_memtest_result *res = diag->result;
4761         u32     loff = BFI_BOOT_MEMTEST_RES_ADDR;
4762         u32     pgnum, i;
4763
4764         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
4765         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
4766
4767         for (i = 0; i < (sizeof(struct bfa_diag_memtest_result) /
4768                          sizeof(u32)); i++) {
4769                 /* read test result from smem */
4770                 *((u32 *) res + i) =
4771                         bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
4772                 loff += sizeof(u32);
4773         }
4774
4775         /* Reset IOC fwstates to BFI_IOC_UNINIT */
4776         bfa_ioc_reset_fwstate(ioc);
4777
4778         res->status = swab32(res->status);
4779         bfa_trc(diag, res->status);
4780
4781         if (res->status == BFI_BOOT_MEMTEST_RES_SIG)
4782                 diag->status = BFA_STATUS_OK;
4783         else {
4784                 diag->status = BFA_STATUS_MEMTEST_FAILED;
4785                 res->addr = swab32(res->addr);
4786                 res->exp = swab32(res->exp);
4787                 res->act = swab32(res->act);
4788                 res->err_status = swab32(res->err_status);
4789                 res->err_status1 = swab32(res->err_status1);
4790                 res->err_addr = swab32(res->err_addr);
4791                 bfa_trc(diag, res->addr);
4792                 bfa_trc(diag, res->exp);
4793                 bfa_trc(diag, res->act);
4794                 bfa_trc(diag, res->err_status);
4795                 bfa_trc(diag, res->err_status1);
4796                 bfa_trc(diag, res->err_addr);
4797         }
4798         diag->timer_active = 0;
4799         diag->cbfn(diag->cbarg, diag->status);
4800         diag->block = 0;
4801 }
4802
4803 /*
4804  * Firmware ping
4805  */
4806
4807 /*
4808  * Perform DMA test directly
4809  */
4810 static void
4811 diag_fwping_send(struct bfa_diag_s *diag)
4812 {
4813         struct bfi_diag_fwping_req_s *fwping_req;
4814         u32     i;
4815
4816         bfa_trc(diag, diag->fwping.dbuf_pa);
4817
4818         /* fill DMA area with pattern */
4819         for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++)
4820                 *((u32 *)diag->fwping.dbuf_kva + i) = diag->fwping.data;
4821
4822         /* Fill mbox msg */
4823         fwping_req = (struct bfi_diag_fwping_req_s *)diag->fwping.mbcmd.msg;
4824
4825         /* Setup SG list */
4826         bfa_alen_set(&fwping_req->alen, BFI_DIAG_DMA_BUF_SZ,
4827                         diag->fwping.dbuf_pa);
4828         /* Set up dma count */
4829         fwping_req->count = cpu_to_be32(diag->fwping.count);
4830         /* Set up data pattern */
4831         fwping_req->data = diag->fwping.data;
4832
4833         /* build host command */
4834         bfi_h2i_set(fwping_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_FWPING,
4835                 bfa_ioc_portid(diag->ioc));
4836
4837         /* send mbox cmd */
4838         bfa_ioc_mbox_queue(diag->ioc, &diag->fwping.mbcmd);
4839 }
4840
4841 static void
4842 diag_fwping_comp(struct bfa_diag_s *diag,
4843                  struct bfi_diag_fwping_rsp_s *diag_rsp)
4844 {
4845         u32     rsp_data = diag_rsp->data;
4846         u8      rsp_dma_status = diag_rsp->dma_status;
4847
4848         bfa_trc(diag, rsp_data);
4849         bfa_trc(diag, rsp_dma_status);
4850
4851         if (rsp_dma_status == BFA_STATUS_OK) {
4852                 u32     i, pat;
4853                 pat = (diag->fwping.count & 0x1) ? ~(diag->fwping.data) :
4854                         diag->fwping.data;
4855                 /* Check mbox data */
4856                 if (diag->fwping.data != rsp_data) {
4857                         bfa_trc(diag, rsp_data);
4858                         diag->fwping.result->dmastatus =
4859                                         BFA_STATUS_DATACORRUPTED;
4860                         diag->fwping.status = BFA_STATUS_DATACORRUPTED;
4861                         diag->fwping.cbfn(diag->fwping.cbarg,
4862                                         diag->fwping.status);
4863                         diag->fwping.lock = 0;
4864                         return;
4865                 }
4866                 /* Check dma pattern */
4867                 for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++) {
4868                         if (*((u32 *)diag->fwping.dbuf_kva + i) != pat) {
4869                                 bfa_trc(diag, i);
4870                                 bfa_trc(diag, pat);
4871                                 bfa_trc(diag,
4872                                         *((u32 *)diag->fwping.dbuf_kva + i));
4873                                 diag->fwping.result->dmastatus =
4874                                                 BFA_STATUS_DATACORRUPTED;
4875                                 diag->fwping.status = BFA_STATUS_DATACORRUPTED;
4876                                 diag->fwping.cbfn(diag->fwping.cbarg,
4877                                                 diag->fwping.status);
4878                                 diag->fwping.lock = 0;
4879                                 return;
4880                         }
4881                 }
4882                 diag->fwping.result->dmastatus = BFA_STATUS_OK;
4883                 diag->fwping.status = BFA_STATUS_OK;
4884                 diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status);
4885                 diag->fwping.lock = 0;
4886         } else {
4887                 diag->fwping.status = BFA_STATUS_HDMA_FAILED;
4888                 diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status);
4889                 diag->fwping.lock = 0;
4890         }
4891 }
4892
4893 /*
4894  * Temperature Sensor
4895  */
4896
4897 static void
4898 diag_tempsensor_send(struct bfa_diag_s *diag)
4899 {
4900         struct bfi_diag_ts_req_s *msg;
4901
4902         msg = (struct bfi_diag_ts_req_s *)diag->tsensor.mbcmd.msg;
4903         bfa_trc(diag, msg->temp);
4904         /* build host command */
4905         bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_TEMPSENSOR,
4906                 bfa_ioc_portid(diag->ioc));
4907         /* send mbox cmd */
4908         bfa_ioc_mbox_queue(diag->ioc, &diag->tsensor.mbcmd);
4909 }
4910
4911 static void
4912 diag_tempsensor_comp(struct bfa_diag_s *diag, bfi_diag_ts_rsp_t *rsp)
4913 {
4914         if (!diag->tsensor.lock) {
4915                 /* receiving response after ioc failure */
4916                 bfa_trc(diag, diag->tsensor.lock);
4917                 return;
4918         }
4919
4920         /*
4921          * ASIC junction tempsensor is a reg read operation
4922          * it will always return OK
4923          */
4924         diag->tsensor.temp->temp = be16_to_cpu(rsp->temp);
4925         diag->tsensor.temp->ts_junc = rsp->ts_junc;
4926         diag->tsensor.temp->ts_brd = rsp->ts_brd;
4927
4928         if (rsp->ts_brd) {
4929                 /* tsensor.temp->status is brd_temp status */
4930                 diag->tsensor.temp->status = rsp->status;
4931                 if (rsp->status == BFA_STATUS_OK) {
4932                         diag->tsensor.temp->brd_temp =
4933                                 be16_to_cpu(rsp->brd_temp);
4934                 } else
4935                         diag->tsensor.temp->brd_temp = 0;
4936         }
4937
4938         bfa_trc(diag, rsp->status);
4939         bfa_trc(diag, rsp->ts_junc);
4940         bfa_trc(diag, rsp->temp);
4941         bfa_trc(diag, rsp->ts_brd);
4942         bfa_trc(diag, rsp->brd_temp);
4943
4944         /* tsensor status is always good bcos we always have junction temp */
4945         diag->tsensor.status = BFA_STATUS_OK;
4946         diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status);
4947         diag->tsensor.lock = 0;
4948 }
4949
4950 /*
4951  *      LED Test command
4952  */
4953 static void
4954 diag_ledtest_send(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest)
4955 {
4956         struct bfi_diag_ledtest_req_s  *msg;
4957
4958         msg = (struct bfi_diag_ledtest_req_s *)diag->ledtest.mbcmd.msg;
4959         /* build host command */
4960         bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LEDTEST,
4961                         bfa_ioc_portid(diag->ioc));
4962
4963         /*
4964          * convert the freq from N blinks per 10 sec to
4965          * crossbow ontime value. We do it here because division is need
4966          */
4967         if (ledtest->freq)
4968                 ledtest->freq = 500 / ledtest->freq;
4969
4970         if (ledtest->freq == 0)
4971                 ledtest->freq = 1;
4972
4973         bfa_trc(diag, ledtest->freq);
4974         /* mcpy(&ledtest_req->req, ledtest, sizeof(bfa_diag_ledtest_t)); */
4975         msg->cmd = (u8) ledtest->cmd;
4976         msg->color = (u8) ledtest->color;
4977         msg->portid = bfa_ioc_portid(diag->ioc);
4978         msg->led = ledtest->led;
4979         msg->freq = cpu_to_be16(ledtest->freq);
4980
4981         /* send mbox cmd */
4982         bfa_ioc_mbox_queue(diag->ioc, &diag->ledtest.mbcmd);
4983 }
4984
4985 static void
4986 diag_ledtest_comp(struct bfa_diag_s *diag, struct bfi_diag_ledtest_rsp_s *msg)
4987 {
4988         bfa_trc(diag, diag->ledtest.lock);
4989         diag->ledtest.lock = BFA_FALSE;
4990         /* no bfa_cb_queue is needed because driver is not waiting */
4991 }
4992
4993 /*
4994  * Port beaconing
4995  */
4996 static void
4997 diag_portbeacon_send(struct bfa_diag_s *diag, bfa_boolean_t beacon, u32 sec)
4998 {
4999         struct bfi_diag_portbeacon_req_s *msg;
5000
5001         msg = (struct bfi_diag_portbeacon_req_s *)diag->beacon.mbcmd.msg;
5002         /* build host command */
5003         bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_PORTBEACON,
5004                 bfa_ioc_portid(diag->ioc));
5005         msg->beacon = beacon;
5006         msg->period = cpu_to_be32(sec);
5007         /* send mbox cmd */
5008         bfa_ioc_mbox_queue(diag->ioc, &diag->beacon.mbcmd);
5009 }
5010
5011 static void
5012 diag_portbeacon_comp(struct bfa_diag_s *diag)
5013 {
5014         bfa_trc(diag, diag->beacon.state);
5015         diag->beacon.state = BFA_FALSE;
5016         if (diag->cbfn_beacon)
5017                 diag->cbfn_beacon(diag->dev, BFA_FALSE, diag->beacon.link_e2e);
5018 }
5019
5020 /*
5021  *      Diag hmbox handler
5022  */
5023 static void
5024 bfa_diag_intr(void *diagarg, struct bfi_mbmsg_s *msg)
5025 {
5026         struct bfa_diag_s *diag = diagarg;
5027
5028         switch (msg->mh.msg_id) {
5029         case BFI_DIAG_I2H_PORTBEACON:
5030                 diag_portbeacon_comp(diag);
5031                 break;
5032         case BFI_DIAG_I2H_FWPING:
5033                 diag_fwping_comp(diag, (struct bfi_diag_fwping_rsp_s *) msg);
5034                 break;
5035         case BFI_DIAG_I2H_TEMPSENSOR:
5036                 diag_tempsensor_comp(diag, (bfi_diag_ts_rsp_t *) msg);
5037                 break;
5038         case BFI_DIAG_I2H_LEDTEST:
5039                 diag_ledtest_comp(diag, (struct bfi_diag_ledtest_rsp_s *) msg);
5040                 break;
5041         default:
5042                 bfa_trc(diag, msg->mh.msg_id);
5043                 WARN_ON(1);
5044         }
5045 }
5046
5047 /*
5048  * Gen RAM Test
5049  *
5050  *   @param[in] *diag           - diag data struct
5051  *   @param[in] *memtest        - mem test params input from upper layer,
5052  *   @param[in] pattern         - mem test pattern
5053  *   @param[in] *result         - mem test result
5054  *   @param[in] cbfn            - mem test callback functioin
5055  *   @param[in] cbarg           - callback functioin arg
5056  *
5057  *   @param[out]
5058  */
5059 bfa_status_t
5060 bfa_diag_memtest(struct bfa_diag_s *diag, struct bfa_diag_memtest_s *memtest,
5061                 u32 pattern, struct bfa_diag_memtest_result *result,
5062                 bfa_cb_diag_t cbfn, void *cbarg)
5063 {
5064         u32     memtest_tov;
5065
5066         bfa_trc(diag, pattern);
5067
5068         if (!bfa_ioc_adapter_is_disabled(diag->ioc))
5069                 return BFA_STATUS_ADAPTER_ENABLED;
5070
5071         /* check to see if there is another destructive diag cmd running */
5072         if (diag->block) {
5073                 bfa_trc(diag, diag->block);
5074                 return BFA_STATUS_DEVBUSY;
5075         } else
5076                 diag->block = 1;
5077
5078         diag->result = result;
5079         diag->cbfn = cbfn;
5080         diag->cbarg = cbarg;
5081
5082         /* download memtest code and take LPU0 out of reset */
5083         bfa_ioc_boot(diag->ioc, BFI_FWBOOT_TYPE_MEMTEST, BFI_FWBOOT_ENV_OS);
5084
5085         memtest_tov = (bfa_ioc_asic_gen(diag->ioc) == BFI_ASIC_GEN_CT2) ?
5086                        CT2_BFA_DIAG_MEMTEST_TOV : BFA_DIAG_MEMTEST_TOV;
5087         bfa_timer_begin(diag->ioc->timer_mod, &diag->timer,
5088                         bfa_diag_memtest_done, diag, memtest_tov);
5089         diag->timer_active = 1;
5090         return BFA_STATUS_OK;
5091 }
5092
5093 /*
5094  * DIAG firmware ping command
5095  *
5096  *   @param[in] *diag           - diag data struct
5097  *   @param[in] cnt             - dma loop count for testing PCIE
5098  *   @param[in] data            - data pattern to pass in fw
5099  *   @param[in] *result         - pt to bfa_diag_fwping_result_t data struct
5100  *   @param[in] cbfn            - callback function
5101  *   @param[in] *cbarg          - callback functioin arg
5102  *
5103  *   @param[out]
5104  */
5105 bfa_status_t
5106 bfa_diag_fwping(struct bfa_diag_s *diag, u32 cnt, u32 data,
5107                 struct bfa_diag_results_fwping *result, bfa_cb_diag_t cbfn,
5108                 void *cbarg)
5109 {
5110         bfa_trc(diag, cnt);
5111         bfa_trc(diag, data);
5112
5113         if (!bfa_ioc_is_operational(diag->ioc))
5114                 return BFA_STATUS_IOC_NON_OP;
5115
5116         if (bfa_asic_id_ct2(bfa_ioc_devid((diag->ioc))) &&
5117             ((diag->ioc)->clscode == BFI_PCIFN_CLASS_ETH))
5118                 return BFA_STATUS_CMD_NOTSUPP;
5119
5120         /* check to see if there is another destructive diag cmd running */
5121         if (diag->block || diag->fwping.lock) {
5122                 bfa_trc(diag, diag->block);
5123                 bfa_trc(diag, diag->fwping.lock);
5124                 return BFA_STATUS_DEVBUSY;
5125         }
5126
5127         /* Initialization */
5128         diag->fwping.lock = 1;
5129         diag->fwping.cbfn = cbfn;
5130         diag->fwping.cbarg = cbarg;
5131         diag->fwping.result = result;
5132         diag->fwping.data = data;
5133         diag->fwping.count = cnt;
5134
5135         /* Init test results */
5136         diag->fwping.result->data = 0;
5137         diag->fwping.result->status = BFA_STATUS_OK;
5138
5139         /* kick off the first ping */
5140         diag_fwping_send(diag);
5141         return BFA_STATUS_OK;
5142 }
5143
5144 /*
5145  * Read Temperature Sensor
5146  *
5147  *   @param[in] *diag           - diag data struct
5148  *   @param[in] *result         - pt to bfa_diag_temp_t data struct
5149  *   @param[in] cbfn            - callback function
5150  *   @param[in] *cbarg          - callback functioin arg
5151  *
5152  *   @param[out]
5153  */
5154 bfa_status_t
5155 bfa_diag_tsensor_query(struct bfa_diag_s *diag,
5156                 struct bfa_diag_results_tempsensor_s *result,
5157                 bfa_cb_diag_t cbfn, void *cbarg)
5158 {
5159         /* check to see if there is a destructive diag cmd running */
5160         if (diag->block || diag->tsensor.lock) {
5161                 bfa_trc(diag, diag->block);
5162                 bfa_trc(diag, diag->tsensor.lock);
5163                 return BFA_STATUS_DEVBUSY;
5164         }
5165
5166         if (!bfa_ioc_is_operational(diag->ioc))
5167                 return BFA_STATUS_IOC_NON_OP;
5168
5169         /* Init diag mod params */
5170         diag->tsensor.lock = 1;
5171         diag->tsensor.temp = result;
5172         diag->tsensor.cbfn = cbfn;
5173         diag->tsensor.cbarg = cbarg;
5174         diag->tsensor.status = BFA_STATUS_OK;
5175
5176         /* Send msg to fw */
5177         diag_tempsensor_send(diag);
5178
5179         return BFA_STATUS_OK;
5180 }
5181
5182 /*
5183  * LED Test command
5184  *
5185  *   @param[in] *diag           - diag data struct
5186  *   @param[in] *ledtest        - pt to ledtest data structure
5187  *
5188  *   @param[out]
5189  */
5190 bfa_status_t
5191 bfa_diag_ledtest(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest)
5192 {
5193         bfa_trc(diag, ledtest->cmd);
5194
5195         if (!bfa_ioc_is_operational(diag->ioc))
5196                 return BFA_STATUS_IOC_NON_OP;
5197
5198         if (diag->beacon.state)
5199                 return BFA_STATUS_BEACON_ON;
5200
5201         if (diag->ledtest.lock)
5202                 return BFA_STATUS_LEDTEST_OP;
5203
5204         /* Send msg to fw */
5205         diag->ledtest.lock = BFA_TRUE;
5206         diag_ledtest_send(diag, ledtest);
5207
5208         return BFA_STATUS_OK;
5209 }
5210
5211 /*
5212  * Port beaconing command
5213  *
5214  *   @param[in] *diag           - diag data struct
5215  *   @param[in] beacon          - port beaconing 1:ON   0:OFF
5216  *   @param[in] link_e2e_beacon - link beaconing 1:ON   0:OFF
5217  *   @param[in] sec             - beaconing duration in seconds
5218  *
5219  *   @param[out]
5220  */
5221 bfa_status_t
5222 bfa_diag_beacon_port(struct bfa_diag_s *diag, bfa_boolean_t beacon,
5223                 bfa_boolean_t link_e2e_beacon, uint32_t sec)
5224 {
5225         bfa_trc(diag, beacon);
5226         bfa_trc(diag, link_e2e_beacon);
5227         bfa_trc(diag, sec);
5228
5229         if (!bfa_ioc_is_operational(diag->ioc))
5230                 return BFA_STATUS_IOC_NON_OP;
5231
5232         if (diag->ledtest.lock)
5233                 return BFA_STATUS_LEDTEST_OP;
5234
5235         if (diag->beacon.state && beacon)       /* beacon alread on */
5236                 return BFA_STATUS_BEACON_ON;
5237
5238         diag->beacon.state      = beacon;
5239         diag->beacon.link_e2e   = link_e2e_beacon;
5240         if (diag->cbfn_beacon)
5241                 diag->cbfn_beacon(diag->dev, beacon, link_e2e_beacon);
5242
5243         /* Send msg to fw */
5244         diag_portbeacon_send(diag, beacon, sec);
5245
5246         return BFA_STATUS_OK;
5247 }
5248
5249 /*
5250  * Return DMA memory needed by diag module.
5251  */
5252 u32
5253 bfa_diag_meminfo(void)
5254 {
5255         return BFA_ROUNDUP(BFI_DIAG_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5256 }
5257
5258 /*
5259  *      Attach virtual and physical memory for Diag.
5260  */
5261 void
5262 bfa_diag_attach(struct bfa_diag_s *diag, struct bfa_ioc_s *ioc, void *dev,
5263         bfa_cb_diag_beacon_t cbfn_beacon, struct bfa_trc_mod_s *trcmod)
5264 {
5265         diag->dev = dev;
5266         diag->ioc = ioc;
5267         diag->trcmod = trcmod;
5268
5269         diag->block = 0;
5270         diag->cbfn = NULL;
5271         diag->cbarg = NULL;
5272         diag->result = NULL;
5273         diag->cbfn_beacon = cbfn_beacon;
5274
5275         bfa_ioc_mbox_regisr(diag->ioc, BFI_MC_DIAG, bfa_diag_intr, diag);
5276         bfa_q_qe_init(&diag->ioc_notify);
5277         bfa_ioc_notify_init(&diag->ioc_notify, bfa_diag_notify, diag);
5278         list_add_tail(&diag->ioc_notify.qe, &diag->ioc->notify_q);
5279 }
5280
5281 void
5282 bfa_diag_memclaim(struct bfa_diag_s *diag, u8 *dm_kva, u64 dm_pa)
5283 {
5284         diag->fwping.dbuf_kva = dm_kva;
5285         diag->fwping.dbuf_pa = dm_pa;
5286         memset(diag->fwping.dbuf_kva, 0, BFI_DIAG_DMA_BUF_SZ);
5287 }
5288
5289 /*
5290  *      PHY module specific
5291  */
5292 #define BFA_PHY_DMA_BUF_SZ      0x02000         /* 8k dma buffer */
5293 #define BFA_PHY_LOCK_STATUS     0x018878        /* phy semaphore status reg */
5294
5295 static void
5296 bfa_phy_ntoh32(u32 *obuf, u32 *ibuf, int sz)
5297 {
5298         int i, m = sz >> 2;
5299
5300         for (i = 0; i < m; i++)
5301                 obuf[i] = be32_to_cpu(ibuf[i]);
5302 }
5303
5304 static bfa_boolean_t
5305 bfa_phy_present(struct bfa_phy_s *phy)
5306 {
5307         return (phy->ioc->attr->card_type == BFA_MFG_TYPE_LIGHTNING);
5308 }
5309
5310 static void
5311 bfa_phy_notify(void *cbarg, enum bfa_ioc_event_e event)
5312 {
5313         struct bfa_phy_s *phy = cbarg;
5314
5315         bfa_trc(phy, event);
5316
5317         switch (event) {
5318         case BFA_IOC_E_DISABLED:
5319         case BFA_IOC_E_FAILED:
5320                 if (phy->op_busy) {
5321                         phy->status = BFA_STATUS_IOC_FAILURE;
5322                         phy->cbfn(phy->cbarg, phy->status);
5323                         phy->op_busy = 0;
5324                 }
5325                 break;
5326
5327         default:
5328                 break;
5329         }
5330 }
5331
5332 /*
5333  * Send phy attribute query request.
5334  *
5335  * @param[in] cbarg - callback argument
5336  */
5337 static void
5338 bfa_phy_query_send(void *cbarg)
5339 {
5340         struct bfa_phy_s *phy = cbarg;
5341         struct bfi_phy_query_req_s *msg =
5342                         (struct bfi_phy_query_req_s *) phy->mb.msg;
5343
5344         msg->instance = phy->instance;
5345         bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_QUERY_REQ,
5346                 bfa_ioc_portid(phy->ioc));
5347         bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_attr_s), phy->dbuf_pa);
5348         bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5349 }
5350
5351 /*
5352  * Send phy write request.
5353  *
5354  * @param[in] cbarg - callback argument
5355  */
5356 static void
5357 bfa_phy_write_send(void *cbarg)
5358 {
5359         struct bfa_phy_s *phy = cbarg;
5360         struct bfi_phy_write_req_s *msg =
5361                         (struct bfi_phy_write_req_s *) phy->mb.msg;
5362         u32     len;
5363         u16     *buf, *dbuf;
5364         int     i, sz;
5365
5366         msg->instance = phy->instance;
5367         msg->offset = cpu_to_be32(phy->addr_off + phy->offset);
5368         len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ?
5369                         phy->residue : BFA_PHY_DMA_BUF_SZ;
5370         msg->length = cpu_to_be32(len);
5371
5372         /* indicate if it's the last msg of the whole write operation */
5373         msg->last = (len == phy->residue) ? 1 : 0;
5374
5375         bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_WRITE_REQ,
5376                 bfa_ioc_portid(phy->ioc));
5377         bfa_alen_set(&msg->alen, len, phy->dbuf_pa);
5378
5379         buf = (u16 *) (phy->ubuf + phy->offset);
5380         dbuf = (u16 *)phy->dbuf_kva;
5381         sz = len >> 1;
5382         for (i = 0; i < sz; i++)
5383                 buf[i] = cpu_to_be16(dbuf[i]);
5384
5385         bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5386
5387         phy->residue -= len;
5388         phy->offset += len;
5389 }
5390
5391 /*
5392  * Send phy read request.
5393  *
5394  * @param[in] cbarg - callback argument
5395  */
5396 static void
5397 bfa_phy_read_send(void *cbarg)
5398 {
5399         struct bfa_phy_s *phy = cbarg;
5400         struct bfi_phy_read_req_s *msg =
5401                         (struct bfi_phy_read_req_s *) phy->mb.msg;
5402         u32     len;
5403
5404         msg->instance = phy->instance;
5405         msg->offset = cpu_to_be32(phy->addr_off + phy->offset);
5406         len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ?
5407                         phy->residue : BFA_PHY_DMA_BUF_SZ;
5408         msg->length = cpu_to_be32(len);
5409         bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_READ_REQ,
5410                 bfa_ioc_portid(phy->ioc));
5411         bfa_alen_set(&msg->alen, len, phy->dbuf_pa);
5412         bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5413 }
5414
5415 /*
5416  * Send phy stats request.
5417  *
5418  * @param[in] cbarg - callback argument
5419  */
5420 static void
5421 bfa_phy_stats_send(void *cbarg)
5422 {
5423         struct bfa_phy_s *phy = cbarg;
5424         struct bfi_phy_stats_req_s *msg =
5425                         (struct bfi_phy_stats_req_s *) phy->mb.msg;
5426
5427         msg->instance = phy->instance;
5428         bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_STATS_REQ,
5429                 bfa_ioc_portid(phy->ioc));
5430         bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_stats_s), phy->dbuf_pa);
5431         bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5432 }
5433
5434 /*
5435  * Flash memory info API.
5436  *
5437  * @param[in] mincfg - minimal cfg variable
5438  */
5439 u32
5440 bfa_phy_meminfo(bfa_boolean_t mincfg)
5441 {
5442         /* min driver doesn't need phy */
5443         if (mincfg)
5444                 return 0;
5445
5446         return BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5447 }
5448
5449 /*
5450  * Flash attach API.
5451  *
5452  * @param[in] phy - phy structure
5453  * @param[in] ioc  - ioc structure
5454  * @param[in] dev  - device structure
5455  * @param[in] trcmod - trace module
5456  * @param[in] logmod - log module
5457  */
5458 void
5459 bfa_phy_attach(struct bfa_phy_s *phy, struct bfa_ioc_s *ioc, void *dev,
5460                 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
5461 {
5462         phy->ioc = ioc;
5463         phy->trcmod = trcmod;
5464         phy->cbfn = NULL;
5465         phy->cbarg = NULL;
5466         phy->op_busy = 0;
5467
5468         bfa_ioc_mbox_regisr(phy->ioc, BFI_MC_PHY, bfa_phy_intr, phy);
5469         bfa_q_qe_init(&phy->ioc_notify);
5470         bfa_ioc_notify_init(&phy->ioc_notify, bfa_phy_notify, phy);
5471         list_add_tail(&phy->ioc_notify.qe, &phy->ioc->notify_q);
5472
5473         /* min driver doesn't need phy */
5474         if (mincfg) {
5475                 phy->dbuf_kva = NULL;
5476                 phy->dbuf_pa = 0;
5477         }
5478 }
5479
5480 /*
5481  * Claim memory for phy
5482  *
5483  * @param[in] phy - phy structure
5484  * @param[in] dm_kva - pointer to virtual memory address
5485  * @param[in] dm_pa - physical memory address
5486  * @param[in] mincfg - minimal cfg variable
5487  */
5488 void
5489 bfa_phy_memclaim(struct bfa_phy_s *phy, u8 *dm_kva, u64 dm_pa,
5490                 bfa_boolean_t mincfg)
5491 {
5492         if (mincfg)
5493                 return;
5494
5495         phy->dbuf_kva = dm_kva;
5496         phy->dbuf_pa = dm_pa;
5497         memset(phy->dbuf_kva, 0, BFA_PHY_DMA_BUF_SZ);
5498         dm_kva += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5499         dm_pa += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5500 }
5501
5502 bfa_boolean_t
5503 bfa_phy_busy(struct bfa_ioc_s *ioc)
5504 {
5505         void __iomem    *rb;
5506
5507         rb = bfa_ioc_bar0(ioc);
5508         return readl(rb + BFA_PHY_LOCK_STATUS);
5509 }
5510
5511 /*
5512  * Get phy attribute.
5513  *
5514  * @param[in] phy - phy structure
5515  * @param[in] attr - phy attribute structure
5516  * @param[in] cbfn - callback function
5517  * @param[in] cbarg - callback argument
5518  *
5519  * Return status.
5520  */
5521 bfa_status_t
5522 bfa_phy_get_attr(struct bfa_phy_s *phy, u8 instance,
5523                 struct bfa_phy_attr_s *attr, bfa_cb_phy_t cbfn, void *cbarg)
5524 {
5525         bfa_trc(phy, BFI_PHY_H2I_QUERY_REQ);
5526         bfa_trc(phy, instance);
5527
5528         if (!bfa_phy_present(phy))
5529                 return BFA_STATUS_PHY_NOT_PRESENT;
5530
5531         if (!bfa_ioc_is_operational(phy->ioc))
5532                 return BFA_STATUS_IOC_NON_OP;
5533
5534         if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5535                 bfa_trc(phy, phy->op_busy);
5536                 return BFA_STATUS_DEVBUSY;
5537         }
5538
5539         phy->op_busy = 1;
5540         phy->cbfn = cbfn;
5541         phy->cbarg = cbarg;
5542         phy->instance = instance;
5543         phy->ubuf = (uint8_t *) attr;
5544         bfa_phy_query_send(phy);
5545
5546         return BFA_STATUS_OK;
5547 }
5548
5549 /*
5550  * Get phy stats.
5551  *
5552  * @param[in] phy - phy structure
5553  * @param[in] instance - phy image instance
5554  * @param[in] stats - pointer to phy stats
5555  * @param[in] cbfn - callback function
5556  * @param[in] cbarg - callback argument
5557  *
5558  * Return status.
5559  */
5560 bfa_status_t
5561 bfa_phy_get_stats(struct bfa_phy_s *phy, u8 instance,
5562                 struct bfa_phy_stats_s *stats,
5563                 bfa_cb_phy_t cbfn, void *cbarg)
5564 {
5565         bfa_trc(phy, BFI_PHY_H2I_STATS_REQ);
5566         bfa_trc(phy, instance);
5567
5568         if (!bfa_phy_present(phy))
5569                 return BFA_STATUS_PHY_NOT_PRESENT;
5570
5571         if (!bfa_ioc_is_operational(phy->ioc))
5572                 return BFA_STATUS_IOC_NON_OP;
5573
5574         if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5575                 bfa_trc(phy, phy->op_busy);
5576                 return BFA_STATUS_DEVBUSY;
5577         }
5578
5579         phy->op_busy = 1;
5580         phy->cbfn = cbfn;
5581         phy->cbarg = cbarg;
5582         phy->instance = instance;
5583         phy->ubuf = (u8 *) stats;
5584         bfa_phy_stats_send(phy);
5585
5586         return BFA_STATUS_OK;
5587 }
5588
5589 /*
5590  * Update phy image.
5591  *
5592  * @param[in] phy - phy structure
5593  * @param[in] instance - phy image instance
5594  * @param[in] buf - update data buffer
5595  * @param[in] len - data buffer length
5596  * @param[in] offset - offset relative to starting address
5597  * @param[in] cbfn - callback function
5598  * @param[in] cbarg - callback argument
5599  *
5600  * Return status.
5601  */
5602 bfa_status_t
5603 bfa_phy_update(struct bfa_phy_s *phy, u8 instance,
5604                 void *buf, u32 len, u32 offset,
5605                 bfa_cb_phy_t cbfn, void *cbarg)
5606 {
5607         bfa_trc(phy, BFI_PHY_H2I_WRITE_REQ);
5608         bfa_trc(phy, instance);
5609         bfa_trc(phy, len);
5610         bfa_trc(phy, offset);
5611
5612         if (!bfa_phy_present(phy))
5613                 return BFA_STATUS_PHY_NOT_PRESENT;
5614
5615         if (!bfa_ioc_is_operational(phy->ioc))
5616                 return BFA_STATUS_IOC_NON_OP;
5617
5618         /* 'len' must be in word (4-byte) boundary */
5619         if (!len || (len & 0x03))
5620                 return BFA_STATUS_FAILED;
5621
5622         if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5623                 bfa_trc(phy, phy->op_busy);
5624                 return BFA_STATUS_DEVBUSY;
5625         }
5626
5627         phy->op_busy = 1;
5628         phy->cbfn = cbfn;
5629         phy->cbarg = cbarg;
5630         phy->instance = instance;
5631         phy->residue = len;
5632         phy->offset = 0;
5633         phy->addr_off = offset;
5634         phy->ubuf = buf;
5635
5636         bfa_phy_write_send(phy);
5637         return BFA_STATUS_OK;
5638 }
5639
5640 /*
5641  * Read phy image.
5642  *
5643  * @param[in] phy - phy structure
5644  * @param[in] instance - phy image instance
5645  * @param[in] buf - read data buffer
5646  * @param[in] len - data buffer length
5647  * @param[in] offset - offset relative to starting address
5648  * @param[in] cbfn - callback function
5649  * @param[in] cbarg - callback argument
5650  *
5651  * Return status.
5652  */
5653 bfa_status_t
5654 bfa_phy_read(struct bfa_phy_s *phy, u8 instance,
5655                 void *buf, u32 len, u32 offset,
5656                 bfa_cb_phy_t cbfn, void *cbarg)
5657 {
5658         bfa_trc(phy, BFI_PHY_H2I_READ_REQ);
5659         bfa_trc(phy, instance);
5660         bfa_trc(phy, len);
5661         bfa_trc(phy, offset);
5662
5663         if (!bfa_phy_present(phy))
5664                 return BFA_STATUS_PHY_NOT_PRESENT;
5665
5666         if (!bfa_ioc_is_operational(phy->ioc))
5667                 return BFA_STATUS_IOC_NON_OP;
5668
5669         /* 'len' must be in word (4-byte) boundary */
5670         if (!len || (len & 0x03))
5671                 return BFA_STATUS_FAILED;
5672
5673         if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5674                 bfa_trc(phy, phy->op_busy);
5675                 return BFA_STATUS_DEVBUSY;
5676         }
5677
5678         phy->op_busy = 1;
5679         phy->cbfn = cbfn;
5680         phy->cbarg = cbarg;
5681         phy->instance = instance;
5682         phy->residue = len;
5683         phy->offset = 0;
5684         phy->addr_off = offset;
5685         phy->ubuf = buf;
5686         bfa_phy_read_send(phy);
5687
5688         return BFA_STATUS_OK;
5689 }
5690
5691 /*
5692  * Process phy response messages upon receiving interrupts.
5693  *
5694  * @param[in] phyarg - phy structure
5695  * @param[in] msg - message structure
5696  */
5697 void
5698 bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg)
5699 {
5700         struct bfa_phy_s *phy = phyarg;
5701         u32     status;
5702
5703         union {
5704                 struct bfi_phy_query_rsp_s *query;
5705                 struct bfi_phy_stats_rsp_s *stats;
5706                 struct bfi_phy_write_rsp_s *write;
5707                 struct bfi_phy_read_rsp_s *read;
5708                 struct bfi_mbmsg_s   *msg;
5709         } m;
5710
5711         m.msg = msg;
5712         bfa_trc(phy, msg->mh.msg_id);
5713
5714         if (!phy->op_busy) {
5715                 /* receiving response after ioc failure */
5716                 bfa_trc(phy, 0x9999);
5717                 return;
5718         }
5719
5720         switch (msg->mh.msg_id) {
5721         case BFI_PHY_I2H_QUERY_RSP:
5722                 status = be32_to_cpu(m.query->status);
5723                 bfa_trc(phy, status);
5724
5725                 if (status == BFA_STATUS_OK) {
5726                         struct bfa_phy_attr_s *attr =
5727                                 (struct bfa_phy_attr_s *) phy->ubuf;
5728                         bfa_phy_ntoh32((u32 *)attr, (u32 *)phy->dbuf_kva,
5729                                         sizeof(struct bfa_phy_attr_s));
5730                         bfa_trc(phy, attr->status);
5731                         bfa_trc(phy, attr->length);
5732                 }
5733
5734                 phy->status = status;
5735                 phy->op_busy = 0;
5736                 if (phy->cbfn)
5737                         phy->cbfn(phy->cbarg, phy->status);
5738                 break;
5739         case BFI_PHY_I2H_STATS_RSP:
5740                 status = be32_to_cpu(m.stats->status);
5741                 bfa_trc(phy, status);
5742
5743                 if (status == BFA_STATUS_OK) {
5744                         struct bfa_phy_stats_s *stats =
5745                                 (struct bfa_phy_stats_s *) phy->ubuf;
5746                         bfa_phy_ntoh32((u32 *)stats, (u32 *)phy->dbuf_kva,
5747                                 sizeof(struct bfa_phy_stats_s));
5748                         bfa_trc(phy, stats->status);
5749                 }
5750
5751                 phy->status = status;
5752                 phy->op_busy = 0;
5753                 if (phy->cbfn)
5754                         phy->cbfn(phy->cbarg, phy->status);
5755                 break;
5756         case BFI_PHY_I2H_WRITE_RSP:
5757                 status = be32_to_cpu(m.write->status);
5758                 bfa_trc(phy, status);
5759
5760                 if (status != BFA_STATUS_OK || phy->residue == 0) {
5761                         phy->status = status;
5762                         phy->op_busy = 0;
5763                         if (phy->cbfn)
5764                                 phy->cbfn(phy->cbarg, phy->status);
5765                 } else {
5766                         bfa_trc(phy, phy->offset);
5767                         bfa_phy_write_send(phy);
5768                 }
5769                 break;
5770         case BFI_PHY_I2H_READ_RSP:
5771                 status = be32_to_cpu(m.read->status);
5772                 bfa_trc(phy, status);
5773
5774                 if (status != BFA_STATUS_OK) {
5775                         phy->status = status;
5776                         phy->op_busy = 0;
5777                         if (phy->cbfn)
5778                                 phy->cbfn(phy->cbarg, phy->status);
5779                 } else {
5780                         u32 len = be32_to_cpu(m.read->length);
5781                         u16 *buf = (u16 *)(phy->ubuf + phy->offset);
5782                         u16 *dbuf = (u16 *)phy->dbuf_kva;
5783                         int i, sz = len >> 1;
5784
5785                         bfa_trc(phy, phy->offset);
5786                         bfa_trc(phy, len);
5787
5788                         for (i = 0; i < sz; i++)
5789                                 buf[i] = be16_to_cpu(dbuf[i]);
5790
5791                         phy->residue -= len;
5792                         phy->offset += len;
5793
5794                         if (phy->residue == 0) {
5795                                 phy->status = status;
5796                                 phy->op_busy = 0;
5797                                 if (phy->cbfn)
5798                                         phy->cbfn(phy->cbarg, phy->status);
5799                         } else
5800                                 bfa_phy_read_send(phy);
5801                 }
5802                 break;
5803         default:
5804                 WARN_ON(1);
5805         }
5806 }
5807
5808 /*
5809  * DCONF state machine events
5810  */
5811 enum bfa_dconf_event {
5812         BFA_DCONF_SM_INIT               = 1,    /* dconf Init */
5813         BFA_DCONF_SM_FLASH_COMP         = 2,    /* read/write to flash */
5814         BFA_DCONF_SM_WR                 = 3,    /* binding change, map */
5815         BFA_DCONF_SM_TIMEOUT            = 4,    /* Start timer */
5816         BFA_DCONF_SM_EXIT               = 5,    /* exit dconf module */
5817         BFA_DCONF_SM_IOCDISABLE         = 6,    /* IOC disable event */
5818 };
5819
5820 /* forward declaration of DCONF state machine */
5821 static void bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf,
5822                                 enum bfa_dconf_event event);
5823 static void bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
5824                                 enum bfa_dconf_event event);
5825 static void bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf,
5826                                 enum bfa_dconf_event event);
5827 static void bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf,
5828                                 enum bfa_dconf_event event);
5829 static void bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf,
5830                                 enum bfa_dconf_event event);
5831 static void bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf,
5832                                 enum bfa_dconf_event event);
5833 static void bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf,
5834                                 enum bfa_dconf_event event);
5835
5836 static void bfa_dconf_cbfn(void *dconf, bfa_status_t status);
5837 static void bfa_dconf_timer(void *cbarg);
5838 static bfa_status_t bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf);
5839 static void bfa_dconf_init_cb(void *arg, bfa_status_t status);
5840
5841 /*
5842  * Beginning state of dconf module. Waiting for an event to start.
5843  */
5844 static void
5845 bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5846 {
5847         bfa_status_t bfa_status;
5848         bfa_trc(dconf->bfa, event);
5849
5850         switch (event) {
5851         case BFA_DCONF_SM_INIT:
5852                 if (dconf->min_cfg) {
5853                         bfa_trc(dconf->bfa, dconf->min_cfg);
5854                         bfa_fsm_send_event(&dconf->bfa->iocfc,
5855                                         IOCFC_E_DCONF_DONE);
5856                         return;
5857                 }
5858                 bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read);
5859                 bfa_timer_start(dconf->bfa, &dconf->timer,
5860                         bfa_dconf_timer, dconf, 2 * BFA_DCONF_UPDATE_TOV);
5861                 bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa),
5862                                         BFA_FLASH_PART_DRV, dconf->instance,
5863                                         dconf->dconf,
5864                                         sizeof(struct bfa_dconf_s), 0,
5865                                         bfa_dconf_init_cb, dconf->bfa);
5866                 if (bfa_status != BFA_STATUS_OK) {
5867                         bfa_timer_stop(&dconf->timer);
5868                         bfa_dconf_init_cb(dconf->bfa, BFA_STATUS_FAILED);
5869                         bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5870                         return;
5871                 }
5872                 break;
5873         case BFA_DCONF_SM_EXIT:
5874                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5875                 break;
5876         case BFA_DCONF_SM_IOCDISABLE:
5877         case BFA_DCONF_SM_WR:
5878         case BFA_DCONF_SM_FLASH_COMP:
5879                 break;
5880         default:
5881                 bfa_sm_fault(dconf->bfa, event);
5882         }
5883 }
5884
5885 /*
5886  * Read flash for dconf entries and make a call back to the driver once done.
5887  */
5888 static void
5889 bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
5890                         enum bfa_dconf_event event)
5891 {
5892         bfa_trc(dconf->bfa, event);
5893
5894         switch (event) {
5895         case BFA_DCONF_SM_FLASH_COMP:
5896                 bfa_timer_stop(&dconf->timer);
5897                 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5898                 break;
5899         case BFA_DCONF_SM_TIMEOUT:
5900                 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5901                 bfa_ioc_suspend(&dconf->bfa->ioc);
5902                 break;
5903         case BFA_DCONF_SM_EXIT:
5904                 bfa_timer_stop(&dconf->timer);
5905                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5906                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5907                 break;
5908         case BFA_DCONF_SM_IOCDISABLE:
5909                 bfa_timer_stop(&dconf->timer);
5910                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5911                 break;
5912         default:
5913                 bfa_sm_fault(dconf->bfa, event);
5914         }
5915 }
5916
5917 /*
5918  * DCONF Module is in ready state. Has completed the initialization.
5919  */
5920 static void
5921 bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5922 {
5923         bfa_trc(dconf->bfa, event);
5924
5925         switch (event) {
5926         case BFA_DCONF_SM_WR:
5927                 bfa_timer_start(dconf->bfa, &dconf->timer,
5928                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5929                 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
5930                 break;
5931         case BFA_DCONF_SM_EXIT:
5932                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5933                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5934                 break;
5935         case BFA_DCONF_SM_INIT:
5936         case BFA_DCONF_SM_IOCDISABLE:
5937                 break;
5938         default:
5939                 bfa_sm_fault(dconf->bfa, event);
5940         }
5941 }
5942
5943 /*
5944  * entries are dirty, write back to the flash.
5945  */
5946
5947 static void
5948 bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5949 {
5950         bfa_trc(dconf->bfa, event);
5951
5952         switch (event) {
5953         case BFA_DCONF_SM_TIMEOUT:
5954                 bfa_sm_set_state(dconf, bfa_dconf_sm_sync);
5955                 bfa_dconf_flash_write(dconf);
5956                 break;
5957         case BFA_DCONF_SM_WR:
5958                 bfa_timer_stop(&dconf->timer);
5959                 bfa_timer_start(dconf->bfa, &dconf->timer,
5960                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5961                 break;
5962         case BFA_DCONF_SM_EXIT:
5963                 bfa_timer_stop(&dconf->timer);
5964                 bfa_timer_start(dconf->bfa, &dconf->timer,
5965                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5966                 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync);
5967                 bfa_dconf_flash_write(dconf);
5968                 break;
5969         case BFA_DCONF_SM_FLASH_COMP:
5970                 break;
5971         case BFA_DCONF_SM_IOCDISABLE:
5972                 bfa_timer_stop(&dconf->timer);
5973                 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty);
5974                 break;
5975         default:
5976                 bfa_sm_fault(dconf->bfa, event);
5977         }
5978 }
5979
5980 /*
5981  * Sync the dconf entries to the flash.
5982  */
5983 static void
5984 bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf,
5985                         enum bfa_dconf_event event)
5986 {
5987         bfa_trc(dconf->bfa, event);
5988
5989         switch (event) {
5990         case BFA_DCONF_SM_IOCDISABLE:
5991         case BFA_DCONF_SM_FLASH_COMP:
5992                 bfa_timer_stop(&dconf->timer);
5993                 fallthrough;
5994         case BFA_DCONF_SM_TIMEOUT:
5995                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5996                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5997                 break;
5998         default:
5999                 bfa_sm_fault(dconf->bfa, event);
6000         }
6001 }
6002
6003 static void
6004 bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
6005 {
6006         bfa_trc(dconf->bfa, event);
6007
6008         switch (event) {
6009         case BFA_DCONF_SM_FLASH_COMP:
6010                 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
6011                 break;
6012         case BFA_DCONF_SM_WR:
6013                 bfa_timer_start(dconf->bfa, &dconf->timer,
6014                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6015                 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
6016                 break;
6017         case BFA_DCONF_SM_EXIT:
6018                 bfa_timer_start(dconf->bfa, &dconf->timer,
6019                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6020                 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync);
6021                 break;
6022         case BFA_DCONF_SM_IOCDISABLE:
6023                 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty);
6024                 break;
6025         default:
6026                 bfa_sm_fault(dconf->bfa, event);
6027         }
6028 }
6029
6030 static void
6031 bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf,
6032                         enum bfa_dconf_event event)
6033 {
6034         bfa_trc(dconf->bfa, event);
6035
6036         switch (event) {
6037         case BFA_DCONF_SM_INIT:
6038                 bfa_timer_start(dconf->bfa, &dconf->timer,
6039                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6040                 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
6041                 break;
6042         case BFA_DCONF_SM_EXIT:
6043                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
6044                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
6045                 break;
6046         case BFA_DCONF_SM_IOCDISABLE:
6047                 break;
6048         default:
6049                 bfa_sm_fault(dconf->bfa, event);
6050         }
6051 }
6052
6053 /*
6054  * Compute and return memory needed by DRV_CFG module.
6055  */
6056 void
6057 bfa_dconf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
6058                   struct bfa_s *bfa)
6059 {
6060         struct bfa_mem_kva_s *dconf_kva = BFA_MEM_DCONF_KVA(bfa);
6061
6062         if (cfg->drvcfg.min_cfg)
6063                 bfa_mem_kva_setup(meminfo, dconf_kva,
6064                                 sizeof(struct bfa_dconf_hdr_s));
6065         else
6066                 bfa_mem_kva_setup(meminfo, dconf_kva,
6067                                 sizeof(struct bfa_dconf_s));
6068 }
6069
6070 void
6071 bfa_dconf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg)
6072 {
6073         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6074
6075         dconf->bfad = bfad;
6076         dconf->bfa = bfa;
6077         dconf->instance = bfa->ioc.port_id;
6078         bfa_trc(bfa, dconf->instance);
6079
6080         dconf->dconf = (struct bfa_dconf_s *) bfa_mem_kva_curp(dconf);
6081         if (cfg->drvcfg.min_cfg) {
6082                 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_hdr_s);
6083                 dconf->min_cfg = BFA_TRUE;
6084         } else {
6085                 dconf->min_cfg = BFA_FALSE;
6086                 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_s);
6087         }
6088
6089         bfa_dconf_read_data_valid(bfa) = BFA_FALSE;
6090         bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
6091 }
6092
6093 static void
6094 bfa_dconf_init_cb(void *arg, bfa_status_t status)
6095 {
6096         struct bfa_s *bfa = arg;
6097         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6098
6099         if (status == BFA_STATUS_OK) {
6100                 bfa_dconf_read_data_valid(bfa) = BFA_TRUE;
6101                 if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE)
6102                         dconf->dconf->hdr.signature = BFI_DCONF_SIGNATURE;
6103                 if (dconf->dconf->hdr.version != BFI_DCONF_VERSION)
6104                         dconf->dconf->hdr.version = BFI_DCONF_VERSION;
6105         }
6106         bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
6107         bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE);
6108 }
6109
6110 void
6111 bfa_dconf_modinit(struct bfa_s *bfa)
6112 {
6113         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6114         bfa_sm_send_event(dconf, BFA_DCONF_SM_INIT);
6115 }
6116
6117 static void bfa_dconf_timer(void *cbarg)
6118 {
6119         struct bfa_dconf_mod_s *dconf = cbarg;
6120         bfa_sm_send_event(dconf, BFA_DCONF_SM_TIMEOUT);
6121 }
6122
6123 void
6124 bfa_dconf_iocdisable(struct bfa_s *bfa)
6125 {
6126         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6127         bfa_sm_send_event(dconf, BFA_DCONF_SM_IOCDISABLE);
6128 }
6129
6130 static bfa_status_t
6131 bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf)
6132 {
6133         bfa_status_t bfa_status;
6134         bfa_trc(dconf->bfa, 0);
6135
6136         bfa_status = bfa_flash_update_part(BFA_FLASH(dconf->bfa),
6137                                 BFA_FLASH_PART_DRV, dconf->instance,
6138                                 dconf->dconf,  sizeof(struct bfa_dconf_s), 0,
6139                                 bfa_dconf_cbfn, dconf);
6140         if (bfa_status != BFA_STATUS_OK)
6141                 WARN_ON(bfa_status);
6142         bfa_trc(dconf->bfa, bfa_status);
6143
6144         return bfa_status;
6145 }
6146
6147 bfa_status_t
6148 bfa_dconf_update(struct bfa_s *bfa)
6149 {
6150         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6151         bfa_trc(dconf->bfa, 0);
6152         if (bfa_sm_cmp_state(dconf, bfa_dconf_sm_iocdown_dirty))
6153                 return BFA_STATUS_FAILED;
6154
6155         if (dconf->min_cfg) {
6156                 bfa_trc(dconf->bfa, dconf->min_cfg);
6157                 return BFA_STATUS_FAILED;
6158         }
6159
6160         bfa_sm_send_event(dconf, BFA_DCONF_SM_WR);
6161         return BFA_STATUS_OK;
6162 }
6163
6164 static void
6165 bfa_dconf_cbfn(void *arg, bfa_status_t status)
6166 {
6167         struct bfa_dconf_mod_s *dconf = arg;
6168         WARN_ON(status);
6169         bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
6170 }
6171
6172 void
6173 bfa_dconf_modexit(struct bfa_s *bfa)
6174 {
6175         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6176         bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT);
6177 }
6178
6179 /*
6180  * FRU specific functions
6181  */
6182
6183 #define BFA_FRU_DMA_BUF_SZ      0x02000         /* 8k dma buffer */
6184 #define BFA_FRU_CHINOOK_MAX_SIZE 0x10000
6185 #define BFA_FRU_LIGHTNING_MAX_SIZE 0x200
6186
6187 static void
6188 bfa_fru_notify(void *cbarg, enum bfa_ioc_event_e event)
6189 {
6190         struct bfa_fru_s *fru = cbarg;
6191
6192         bfa_trc(fru, event);
6193
6194         switch (event) {
6195         case BFA_IOC_E_DISABLED:
6196         case BFA_IOC_E_FAILED:
6197                 if (fru->op_busy) {
6198                         fru->status = BFA_STATUS_IOC_FAILURE;
6199                         fru->cbfn(fru->cbarg, fru->status);
6200                         fru->op_busy = 0;
6201                 }
6202                 break;
6203
6204         default:
6205                 break;
6206         }
6207 }
6208
6209 /*
6210  * Send fru write request.
6211  *
6212  * @param[in] cbarg - callback argument
6213  */
6214 static void
6215 bfa_fru_write_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type)
6216 {
6217         struct bfa_fru_s *fru = cbarg;
6218         struct bfi_fru_write_req_s *msg =
6219                         (struct bfi_fru_write_req_s *) fru->mb.msg;
6220         u32 len;
6221
6222         msg->offset = cpu_to_be32(fru->addr_off + fru->offset);
6223         len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ?
6224                                 fru->residue : BFA_FRU_DMA_BUF_SZ;
6225         msg->length = cpu_to_be32(len);
6226
6227         /*
6228          * indicate if it's the last msg of the whole write operation
6229          */
6230         msg->last = (len == fru->residue) ? 1 : 0;
6231
6232         msg->trfr_cmpl = (len == fru->residue) ? fru->trfr_cmpl : 0;
6233         bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
6234         bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
6235
6236         memcpy(fru->dbuf_kva, fru->ubuf + fru->offset, len);
6237         bfa_ioc_mbox_queue(fru->ioc, &fru->mb);
6238
6239         fru->residue -= len;
6240         fru->offset += len;
6241 }
6242
6243 /*
6244  * Send fru read request.
6245  *
6246  * @param[in] cbarg - callback argument
6247  */
6248 static void
6249 bfa_fru_read_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type)
6250 {
6251         struct bfa_fru_s *fru = cbarg;
6252         struct bfi_fru_read_req_s *msg =
6253                         (struct bfi_fru_read_req_s *) fru->mb.msg;
6254         u32 len;
6255
6256         msg->offset = cpu_to_be32(fru->addr_off + fru->offset);
6257         len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ?
6258                                 fru->residue : BFA_FRU_DMA_BUF_SZ;
6259         msg->length = cpu_to_be32(len);
6260         bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
6261         bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
6262         bfa_ioc_mbox_queue(fru->ioc, &fru->mb);
6263 }
6264
6265 /*
6266  * Flash memory info API.
6267  *
6268  * @param[in] mincfg - minimal cfg variable
6269  */
6270 u32
6271 bfa_fru_meminfo(bfa_boolean_t mincfg)
6272 {
6273         /* min driver doesn't need fru */
6274         if (mincfg)
6275                 return 0;
6276
6277         return BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6278 }
6279
6280 /*
6281  * Flash attach API.
6282  *
6283  * @param[in] fru - fru structure
6284  * @param[in] ioc  - ioc structure
6285  * @param[in] dev  - device structure
6286  * @param[in] trcmod - trace module
6287  * @param[in] logmod - log module
6288  */
6289 void
6290 bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, void *dev,
6291         struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
6292 {
6293         fru->ioc = ioc;
6294         fru->trcmod = trcmod;
6295         fru->cbfn = NULL;
6296         fru->cbarg = NULL;
6297         fru->op_busy = 0;
6298
6299         bfa_ioc_mbox_regisr(fru->ioc, BFI_MC_FRU, bfa_fru_intr, fru);
6300         bfa_q_qe_init(&fru->ioc_notify);
6301         bfa_ioc_notify_init(&fru->ioc_notify, bfa_fru_notify, fru);
6302         list_add_tail(&fru->ioc_notify.qe, &fru->ioc->notify_q);
6303
6304         /* min driver doesn't need fru */
6305         if (mincfg) {
6306                 fru->dbuf_kva = NULL;
6307                 fru->dbuf_pa = 0;
6308         }
6309 }
6310
6311 /*
6312  * Claim memory for fru
6313  *
6314  * @param[in] fru - fru structure
6315  * @param[in] dm_kva - pointer to virtual memory address
6316  * @param[in] dm_pa - frusical memory address
6317  * @param[in] mincfg - minimal cfg variable
6318  */
6319 void
6320 bfa_fru_memclaim(struct bfa_fru_s *fru, u8 *dm_kva, u64 dm_pa,
6321         bfa_boolean_t mincfg)
6322 {
6323         if (mincfg)
6324                 return;
6325
6326         fru->dbuf_kva = dm_kva;
6327         fru->dbuf_pa = dm_pa;
6328         memset(fru->dbuf_kva, 0, BFA_FRU_DMA_BUF_SZ);
6329         dm_kva += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6330         dm_pa += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6331 }
6332
6333 /*
6334  * Update fru vpd image.
6335  *
6336  * @param[in] fru - fru structure
6337  * @param[in] buf - update data buffer
6338  * @param[in] len - data buffer length
6339  * @param[in] offset - offset relative to starting address
6340  * @param[in] cbfn - callback function
6341  * @param[in] cbarg - callback argument
6342  *
6343  * Return status.
6344  */
6345 bfa_status_t
6346 bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6347                   bfa_cb_fru_t cbfn, void *cbarg, u8 trfr_cmpl)
6348 {
6349         bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ);
6350         bfa_trc(fru, len);
6351         bfa_trc(fru, offset);
6352
6353         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2 &&
6354                 fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2)
6355                 return BFA_STATUS_FRU_NOT_PRESENT;
6356
6357         if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK)
6358                 return BFA_STATUS_CMD_NOTSUPP;
6359
6360         if (!bfa_ioc_is_operational(fru->ioc))
6361                 return BFA_STATUS_IOC_NON_OP;
6362
6363         if (fru->op_busy) {
6364                 bfa_trc(fru, fru->op_busy);
6365                 return BFA_STATUS_DEVBUSY;
6366         }
6367
6368         fru->op_busy = 1;
6369
6370         fru->cbfn = cbfn;
6371         fru->cbarg = cbarg;
6372         fru->residue = len;
6373         fru->offset = 0;
6374         fru->addr_off = offset;
6375         fru->ubuf = buf;
6376         fru->trfr_cmpl = trfr_cmpl;
6377
6378         bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ);
6379
6380         return BFA_STATUS_OK;
6381 }
6382
6383 /*
6384  * Read fru vpd image.
6385  *
6386  * @param[in] fru - fru structure
6387  * @param[in] buf - read data buffer
6388  * @param[in] len - data buffer length
6389  * @param[in] offset - offset relative to starting address
6390  * @param[in] cbfn - callback function
6391  * @param[in] cbarg - callback argument
6392  *
6393  * Return status.
6394  */
6395 bfa_status_t
6396 bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6397                 bfa_cb_fru_t cbfn, void *cbarg)
6398 {
6399         bfa_trc(fru, BFI_FRUVPD_H2I_READ_REQ);
6400         bfa_trc(fru, len);
6401         bfa_trc(fru, offset);
6402
6403         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6404                 return BFA_STATUS_FRU_NOT_PRESENT;
6405
6406         if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK &&
6407                 fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2)
6408                 return BFA_STATUS_CMD_NOTSUPP;
6409
6410         if (!bfa_ioc_is_operational(fru->ioc))
6411                 return BFA_STATUS_IOC_NON_OP;
6412
6413         if (fru->op_busy) {
6414                 bfa_trc(fru, fru->op_busy);
6415                 return BFA_STATUS_DEVBUSY;
6416         }
6417
6418         fru->op_busy = 1;
6419
6420         fru->cbfn = cbfn;
6421         fru->cbarg = cbarg;
6422         fru->residue = len;
6423         fru->offset = 0;
6424         fru->addr_off = offset;
6425         fru->ubuf = buf;
6426         bfa_fru_read_send(fru, BFI_FRUVPD_H2I_READ_REQ);
6427
6428         return BFA_STATUS_OK;
6429 }
6430
6431 /*
6432  * Get maximum size fru vpd image.
6433  *
6434  * @param[in] fru - fru structure
6435  * @param[out] size - maximum size of fru vpd data
6436  *
6437  * Return status.
6438  */
6439 bfa_status_t
6440 bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size)
6441 {
6442         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6443                 return BFA_STATUS_FRU_NOT_PRESENT;
6444
6445         if (!bfa_ioc_is_operational(fru->ioc))
6446                 return BFA_STATUS_IOC_NON_OP;
6447
6448         if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK ||
6449                 fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK2)
6450                 *max_size = BFA_FRU_CHINOOK_MAX_SIZE;
6451         else
6452                 return BFA_STATUS_CMD_NOTSUPP;
6453         return BFA_STATUS_OK;
6454 }
6455 /*
6456  * tfru write.
6457  *
6458  * @param[in] fru - fru structure
6459  * @param[in] buf - update data buffer
6460  * @param[in] len - data buffer length
6461  * @param[in] offset - offset relative to starting address
6462  * @param[in] cbfn - callback function
6463  * @param[in] cbarg - callback argument
6464  *
6465  * Return status.
6466  */
6467 bfa_status_t
6468 bfa_tfru_write(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6469                bfa_cb_fru_t cbfn, void *cbarg)
6470 {
6471         bfa_trc(fru, BFI_TFRU_H2I_WRITE_REQ);
6472         bfa_trc(fru, len);
6473         bfa_trc(fru, offset);
6474         bfa_trc(fru, *((u8 *) buf));
6475
6476         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6477                 return BFA_STATUS_FRU_NOT_PRESENT;
6478
6479         if (!bfa_ioc_is_operational(fru->ioc))
6480                 return BFA_STATUS_IOC_NON_OP;
6481
6482         if (fru->op_busy) {
6483                 bfa_trc(fru, fru->op_busy);
6484                 return BFA_STATUS_DEVBUSY;
6485         }
6486
6487         fru->op_busy = 1;
6488
6489         fru->cbfn = cbfn;
6490         fru->cbarg = cbarg;
6491         fru->residue = len;
6492         fru->offset = 0;
6493         fru->addr_off = offset;
6494         fru->ubuf = buf;
6495
6496         bfa_fru_write_send(fru, BFI_TFRU_H2I_WRITE_REQ);
6497
6498         return BFA_STATUS_OK;
6499 }
6500
6501 /*
6502  * tfru read.
6503  *
6504  * @param[in] fru - fru structure
6505  * @param[in] buf - read data buffer
6506  * @param[in] len - data buffer length
6507  * @param[in] offset - offset relative to starting address
6508  * @param[in] cbfn - callback function
6509  * @param[in] cbarg - callback argument
6510  *
6511  * Return status.
6512  */
6513 bfa_status_t
6514 bfa_tfru_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6515               bfa_cb_fru_t cbfn, void *cbarg)
6516 {
6517         bfa_trc(fru, BFI_TFRU_H2I_READ_REQ);
6518         bfa_trc(fru, len);
6519         bfa_trc(fru, offset);
6520
6521         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6522                 return BFA_STATUS_FRU_NOT_PRESENT;
6523
6524         if (!bfa_ioc_is_operational(fru->ioc))
6525                 return BFA_STATUS_IOC_NON_OP;
6526
6527         if (fru->op_busy) {
6528                 bfa_trc(fru, fru->op_busy);
6529                 return BFA_STATUS_DEVBUSY;
6530         }
6531
6532         fru->op_busy = 1;
6533
6534         fru->cbfn = cbfn;
6535         fru->cbarg = cbarg;
6536         fru->residue = len;
6537         fru->offset = 0;
6538         fru->addr_off = offset;
6539         fru->ubuf = buf;
6540         bfa_fru_read_send(fru, BFI_TFRU_H2I_READ_REQ);
6541
6542         return BFA_STATUS_OK;
6543 }
6544
6545 /*
6546  * Process fru response messages upon receiving interrupts.
6547  *
6548  * @param[in] fruarg - fru structure
6549  * @param[in] msg - message structure
6550  */
6551 void
6552 bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg)
6553 {
6554         struct bfa_fru_s *fru = fruarg;
6555         struct bfi_fru_rsp_s *rsp = (struct bfi_fru_rsp_s *)msg;
6556         u32 status;
6557
6558         bfa_trc(fru, msg->mh.msg_id);
6559
6560         if (!fru->op_busy) {
6561                 /*
6562                  * receiving response after ioc failure
6563                  */
6564                 bfa_trc(fru, 0x9999);
6565                 return;
6566         }
6567
6568         switch (msg->mh.msg_id) {
6569         case BFI_FRUVPD_I2H_WRITE_RSP:
6570         case BFI_TFRU_I2H_WRITE_RSP:
6571                 status = be32_to_cpu(rsp->status);
6572                 bfa_trc(fru, status);
6573
6574                 if (status != BFA_STATUS_OK || fru->residue == 0) {
6575                         fru->status = status;
6576                         fru->op_busy = 0;
6577                         if (fru->cbfn)
6578                                 fru->cbfn(fru->cbarg, fru->status);
6579                 } else {
6580                         bfa_trc(fru, fru->offset);
6581                         if (msg->mh.msg_id == BFI_FRUVPD_I2H_WRITE_RSP)
6582                                 bfa_fru_write_send(fru,
6583                                         BFI_FRUVPD_H2I_WRITE_REQ);
6584                         else
6585                                 bfa_fru_write_send(fru,
6586                                         BFI_TFRU_H2I_WRITE_REQ);
6587                 }
6588                 break;
6589         case BFI_FRUVPD_I2H_READ_RSP:
6590         case BFI_TFRU_I2H_READ_RSP:
6591                 status = be32_to_cpu(rsp->status);
6592                 bfa_trc(fru, status);
6593
6594                 if (status != BFA_STATUS_OK) {
6595                         fru->status = status;
6596                         fru->op_busy = 0;
6597                         if (fru->cbfn)
6598                                 fru->cbfn(fru->cbarg, fru->status);
6599                 } else {
6600                         u32 len = be32_to_cpu(rsp->length);
6601
6602                         bfa_trc(fru, fru->offset);
6603                         bfa_trc(fru, len);
6604
6605                         memcpy(fru->ubuf + fru->offset, fru->dbuf_kva, len);
6606                         fru->residue -= len;
6607                         fru->offset += len;
6608
6609                         if (fru->residue == 0) {
6610                                 fru->status = status;
6611                                 fru->op_busy = 0;
6612                                 if (fru->cbfn)
6613                                         fru->cbfn(fru->cbarg, fru->status);
6614                         } else {
6615                                 if (msg->mh.msg_id == BFI_FRUVPD_I2H_READ_RSP)
6616                                         bfa_fru_read_send(fru,
6617                                                 BFI_FRUVPD_H2I_READ_REQ);
6618                                 else
6619                                         bfa_fru_read_send(fru,
6620                                                 BFI_TFRU_H2I_READ_REQ);
6621                         }
6622                 }
6623                 break;
6624         default:
6625                 WARN_ON(1);
6626         }
6627 }
6628
6629 /*
6630  * register definitions
6631  */
6632 #define FLI_CMD_REG                     0x0001d000
6633 #define FLI_RDDATA_REG                  0x0001d010
6634 #define FLI_ADDR_REG                    0x0001d004
6635 #define FLI_DEV_STATUS_REG              0x0001d014
6636
6637 #define BFA_FLASH_FIFO_SIZE             128     /* fifo size */
6638 #define BFA_FLASH_CHECK_MAX             10000   /* max # of status check */
6639 #define BFA_FLASH_BLOCKING_OP_MAX       1000000 /* max # of blocking op check */
6640 #define BFA_FLASH_WIP_MASK              0x01    /* write in progress bit mask */
6641
6642 enum bfa_flash_cmd {
6643         BFA_FLASH_FAST_READ     = 0x0b, /* fast read */
6644         BFA_FLASH_READ_STATUS   = 0x05, /* read status */
6645 };
6646
6647 /*
6648  * Hardware error definition
6649  */
6650 enum bfa_flash_err {
6651         BFA_FLASH_NOT_PRESENT   = -1,   /*!< flash not present */
6652         BFA_FLASH_UNINIT        = -2,   /*!< flash not initialized */
6653         BFA_FLASH_BAD           = -3,   /*!< flash bad */
6654         BFA_FLASH_BUSY          = -4,   /*!< flash busy */
6655         BFA_FLASH_ERR_CMD_ACT   = -5,   /*!< command active never cleared */
6656         BFA_FLASH_ERR_FIFO_CNT  = -6,   /*!< fifo count never cleared */
6657         BFA_FLASH_ERR_WIP       = -7,   /*!< write-in-progress never cleared */
6658         BFA_FLASH_ERR_TIMEOUT   = -8,   /*!< fli timeout */
6659         BFA_FLASH_ERR_LEN       = -9,   /*!< invalid length */
6660 };
6661
6662 /*
6663  * Flash command register data structure
6664  */
6665 union bfa_flash_cmd_reg_u {
6666         struct {
6667 #ifdef __BIG_ENDIAN
6668                 u32     act:1;
6669                 u32     rsv:1;
6670                 u32     write_cnt:9;
6671                 u32     read_cnt:9;
6672                 u32     addr_cnt:4;
6673                 u32     cmd:8;
6674 #else
6675                 u32     cmd:8;
6676                 u32     addr_cnt:4;
6677                 u32     read_cnt:9;
6678                 u32     write_cnt:9;
6679                 u32     rsv:1;
6680                 u32     act:1;
6681 #endif
6682         } r;
6683         u32     i;
6684 };
6685
6686 /*
6687  * Flash device status register data structure
6688  */
6689 union bfa_flash_dev_status_reg_u {
6690         struct {
6691 #ifdef __BIG_ENDIAN
6692                 u32     rsv:21;
6693                 u32     fifo_cnt:6;
6694                 u32     busy:1;
6695                 u32     init_status:1;
6696                 u32     present:1;
6697                 u32     bad:1;
6698                 u32     good:1;
6699 #else
6700                 u32     good:1;
6701                 u32     bad:1;
6702                 u32     present:1;
6703                 u32     init_status:1;
6704                 u32     busy:1;
6705                 u32     fifo_cnt:6;
6706                 u32     rsv:21;
6707 #endif
6708         } r;
6709         u32     i;
6710 };
6711
6712 /*
6713  * Flash address register data structure
6714  */
6715 union bfa_flash_addr_reg_u {
6716         struct {
6717 #ifdef __BIG_ENDIAN
6718                 u32     addr:24;
6719                 u32     dummy:8;
6720 #else
6721                 u32     dummy:8;
6722                 u32     addr:24;
6723 #endif
6724         } r;
6725         u32     i;
6726 };
6727
6728 /*
6729  * dg flash_raw_private Flash raw private functions
6730  */
6731 static void
6732 bfa_flash_set_cmd(void __iomem *pci_bar, u8 wr_cnt,
6733                   u8 rd_cnt, u8 ad_cnt, u8 op)
6734 {
6735         union bfa_flash_cmd_reg_u cmd;
6736
6737         cmd.i = 0;
6738         cmd.r.act = 1;
6739         cmd.r.write_cnt = wr_cnt;
6740         cmd.r.read_cnt = rd_cnt;
6741         cmd.r.addr_cnt = ad_cnt;
6742         cmd.r.cmd = op;
6743         writel(cmd.i, (pci_bar + FLI_CMD_REG));
6744 }
6745
6746 static void
6747 bfa_flash_set_addr(void __iomem *pci_bar, u32 address)
6748 {
6749         union bfa_flash_addr_reg_u addr;
6750
6751         addr.r.addr = address & 0x00ffffff;
6752         addr.r.dummy = 0;
6753         writel(addr.i, (pci_bar + FLI_ADDR_REG));
6754 }
6755
6756 static int
6757 bfa_flash_cmd_act_check(void __iomem *pci_bar)
6758 {
6759         union bfa_flash_cmd_reg_u cmd;
6760
6761         cmd.i = readl(pci_bar + FLI_CMD_REG);
6762
6763         if (cmd.r.act)
6764                 return BFA_FLASH_ERR_CMD_ACT;
6765
6766         return 0;
6767 }
6768
6769 /*
6770  * @brief
6771  * Flush FLI data fifo.
6772  *
6773  * @param[in] pci_bar - pci bar address
6774  * @param[in] dev_status - device status
6775  *
6776  * Return 0 on success, negative error number on error.
6777  */
6778 static u32
6779 bfa_flash_fifo_flush(void __iomem *pci_bar)
6780 {
6781         u32 i;
6782         union bfa_flash_dev_status_reg_u dev_status;
6783
6784         dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6785
6786         if (!dev_status.r.fifo_cnt)
6787                 return 0;
6788
6789         /* fifo counter in terms of words */
6790         for (i = 0; i < dev_status.r.fifo_cnt; i++)
6791                 readl(pci_bar + FLI_RDDATA_REG);
6792
6793         /*
6794          * Check the device status. It may take some time.
6795          */
6796         for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
6797                 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6798                 if (!dev_status.r.fifo_cnt)
6799                         break;
6800         }
6801
6802         if (dev_status.r.fifo_cnt)
6803                 return BFA_FLASH_ERR_FIFO_CNT;
6804
6805         return 0;
6806 }
6807
6808 /*
6809  * @brief
6810  * Read flash status.
6811  *
6812  * @param[in] pci_bar - pci bar address
6813  *
6814  * Return 0 on success, negative error number on error.
6815 */
6816 static u32
6817 bfa_flash_status_read(void __iomem *pci_bar)
6818 {
6819         union bfa_flash_dev_status_reg_u        dev_status;
6820         int                             status;
6821         u32                     ret_status;
6822         int                             i;
6823
6824         status = bfa_flash_fifo_flush(pci_bar);
6825         if (status < 0)
6826                 return status;
6827
6828         bfa_flash_set_cmd(pci_bar, 0, 4, 0, BFA_FLASH_READ_STATUS);
6829
6830         for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
6831                 status = bfa_flash_cmd_act_check(pci_bar);
6832                 if (!status)
6833                         break;
6834         }
6835
6836         if (status)
6837                 return status;
6838
6839         dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6840         if (!dev_status.r.fifo_cnt)
6841                 return BFA_FLASH_BUSY;
6842
6843         ret_status = readl(pci_bar + FLI_RDDATA_REG);
6844         ret_status >>= 24;
6845
6846         status = bfa_flash_fifo_flush(pci_bar);
6847         if (status < 0)
6848                 return status;
6849
6850         return ret_status;
6851 }
6852
6853 /*
6854  * @brief
6855  * Start flash read operation.
6856  *
6857  * @param[in] pci_bar - pci bar address
6858  * @param[in] offset - flash address offset
6859  * @param[in] len - read data length
6860  * @param[in] buf - read data buffer
6861  *
6862  * Return 0 on success, negative error number on error.
6863  */
6864 static u32
6865 bfa_flash_read_start(void __iomem *pci_bar, u32 offset, u32 len,
6866                          char *buf)
6867 {
6868         int status;
6869
6870         /*
6871          * len must be mutiple of 4 and not exceeding fifo size
6872          */
6873         if (len == 0 || len > BFA_FLASH_FIFO_SIZE || (len & 0x03) != 0)
6874                 return BFA_FLASH_ERR_LEN;
6875
6876         /*
6877          * check status
6878          */
6879         status = bfa_flash_status_read(pci_bar);
6880         if (status == BFA_FLASH_BUSY)
6881                 status = bfa_flash_status_read(pci_bar);
6882
6883         if (status < 0)
6884                 return status;
6885
6886         /*
6887          * check if write-in-progress bit is cleared
6888          */
6889         if (status & BFA_FLASH_WIP_MASK)
6890                 return BFA_FLASH_ERR_WIP;
6891
6892         bfa_flash_set_addr(pci_bar, offset);
6893
6894         bfa_flash_set_cmd(pci_bar, 0, (u8)len, 4, BFA_FLASH_FAST_READ);
6895
6896         return 0;
6897 }
6898
6899 /*
6900  * @brief
6901  * Check flash read operation.
6902  *
6903  * @param[in] pci_bar - pci bar address
6904  *
6905  * Return flash device status, 1 if busy, 0 if not.
6906  */
6907 static u32
6908 bfa_flash_read_check(void __iomem *pci_bar)
6909 {
6910         if (bfa_flash_cmd_act_check(pci_bar))
6911                 return 1;
6912
6913         return 0;
6914 }
6915
6916 /*
6917  * @brief
6918  * End flash read operation.
6919  *
6920  * @param[in] pci_bar - pci bar address
6921  * @param[in] len - read data length
6922  * @param[in] buf - read data buffer
6923  *
6924  */
6925 static void
6926 bfa_flash_read_end(void __iomem *pci_bar, u32 len, char *buf)
6927 {
6928
6929         u32 i;
6930
6931         /*
6932          * read data fifo up to 32 words
6933          */
6934         for (i = 0; i < len; i += 4) {
6935                 u32 w = readl(pci_bar + FLI_RDDATA_REG);
6936                 *((u32 *) (buf + i)) = swab32(w);
6937         }
6938
6939         bfa_flash_fifo_flush(pci_bar);
6940 }
6941
6942 /*
6943  * @brief
6944  * Perform flash raw read.
6945  *
6946  * @param[in] pci_bar - pci bar address
6947  * @param[in] offset - flash partition address offset
6948  * @param[in] buf - read data buffer
6949  * @param[in] len - read data length
6950  *
6951  * Return status.
6952  */
6953
6954
6955 #define FLASH_BLOCKING_OP_MAX   500
6956 #define FLASH_SEM_LOCK_REG      0x18820
6957
6958 static int
6959 bfa_raw_sem_get(void __iomem *bar)
6960 {
6961         int     locked;
6962
6963         locked = readl((bar + FLASH_SEM_LOCK_REG));
6964         return !locked;
6965
6966 }
6967
6968 static bfa_status_t
6969 bfa_flash_sem_get(void __iomem *bar)
6970 {
6971         u32 n = FLASH_BLOCKING_OP_MAX;
6972
6973         while (!bfa_raw_sem_get(bar)) {
6974                 if (--n <= 0)
6975                         return BFA_STATUS_BADFLASH;
6976                 mdelay(10);
6977         }
6978         return BFA_STATUS_OK;
6979 }
6980
6981 static void
6982 bfa_flash_sem_put(void __iomem *bar)
6983 {
6984         writel(0, (bar + FLASH_SEM_LOCK_REG));
6985 }
6986
6987 bfa_status_t
6988 bfa_flash_raw_read(void __iomem *pci_bar, u32 offset, char *buf,
6989                        u32 len)
6990 {
6991         u32 n;
6992         int status;
6993         u32 off, l, s, residue, fifo_sz;
6994
6995         residue = len;
6996         off = 0;
6997         fifo_sz = BFA_FLASH_FIFO_SIZE;
6998         status = bfa_flash_sem_get(pci_bar);
6999         if (status != BFA_STATUS_OK)
7000                 return status;
7001
7002         while (residue) {
7003                 s = offset + off;
7004                 n = s / fifo_sz;
7005                 l = (n + 1) * fifo_sz - s;
7006                 if (l > residue)
7007                         l = residue;
7008
7009                 status = bfa_flash_read_start(pci_bar, offset + off, l,
7010                                                                 &buf[off]);
7011                 if (status < 0) {
7012                         bfa_flash_sem_put(pci_bar);
7013                         return BFA_STATUS_FAILED;
7014                 }
7015
7016                 n = BFA_FLASH_BLOCKING_OP_MAX;
7017                 while (bfa_flash_read_check(pci_bar)) {
7018                         if (--n <= 0) {
7019                                 bfa_flash_sem_put(pci_bar);
7020                                 return BFA_STATUS_FAILED;
7021                         }
7022                 }
7023
7024                 bfa_flash_read_end(pci_bar, l, &buf[off]);
7025
7026                 residue -= l;
7027                 off += l;
7028         }
7029         bfa_flash_sem_put(pci_bar);
7030
7031         return BFA_STATUS_OK;
7032 }