Merge tag 'soundwire-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul...
[linux-2.6-microblaze.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                 /* !!! fall through !!! */
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                 /* !!! fall through !!! */
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         strlcpy(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
3303         case BFI_ABLK_I2H_PF_DELETE:
3304         case BFI_ABLK_I2H_PF_UPDATE:
3305         case BFI_ABLK_I2H_OPTROM_ENABLE:
3306         case BFI_ABLK_I2H_OPTROM_DISABLE:
3307                 /* No-op */
3308                 break;
3309
3310         case BFI_ABLK_I2H_PF_CREATE:
3311                 *(ablk->pcifn) = rsp->pcifn;
3312                 ablk->pcifn = NULL;
3313                 break;
3314
3315         default:
3316                 WARN_ON(1);
3317         }
3318
3319         ablk->busy = BFA_FALSE;
3320         if (ablk->cbfn) {
3321                 cbfn = ablk->cbfn;
3322                 ablk->cbfn = NULL;
3323                 cbfn(ablk->cbarg, rsp->status);
3324         }
3325 }
3326
3327 static void
3328 bfa_ablk_notify(void *cbarg, enum bfa_ioc_event_e event)
3329 {
3330         struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg;
3331
3332         bfa_trc(ablk->ioc, event);
3333
3334         switch (event) {
3335         case BFA_IOC_E_ENABLED:
3336                 WARN_ON(ablk->busy != BFA_FALSE);
3337                 break;
3338
3339         case BFA_IOC_E_DISABLED:
3340         case BFA_IOC_E_FAILED:
3341                 /* Fail any pending requests */
3342                 ablk->pcifn = NULL;
3343                 if (ablk->busy) {
3344                         if (ablk->cbfn)
3345                                 ablk->cbfn(ablk->cbarg, BFA_STATUS_FAILED);
3346                         ablk->cbfn = NULL;
3347                         ablk->busy = BFA_FALSE;
3348                 }
3349                 break;
3350
3351         default:
3352                 WARN_ON(1);
3353                 break;
3354         }
3355 }
3356
3357 u32
3358 bfa_ablk_meminfo(void)
3359 {
3360         return BFA_ROUNDUP(sizeof(struct bfa_ablk_cfg_s), BFA_DMA_ALIGN_SZ);
3361 }
3362
3363 void
3364 bfa_ablk_memclaim(struct bfa_ablk_s *ablk, u8 *dma_kva, u64 dma_pa)
3365 {
3366         ablk->dma_addr.kva = dma_kva;
3367         ablk->dma_addr.pa  = dma_pa;
3368 }
3369
3370 void
3371 bfa_ablk_attach(struct bfa_ablk_s *ablk, struct bfa_ioc_s *ioc)
3372 {
3373         ablk->ioc = ioc;
3374
3375         bfa_ioc_mbox_regisr(ablk->ioc, BFI_MC_ABLK, bfa_ablk_isr, ablk);
3376         bfa_q_qe_init(&ablk->ioc_notify);
3377         bfa_ioc_notify_init(&ablk->ioc_notify, bfa_ablk_notify, ablk);
3378         list_add_tail(&ablk->ioc_notify.qe, &ablk->ioc->notify_q);
3379 }
3380
3381 bfa_status_t
3382 bfa_ablk_query(struct bfa_ablk_s *ablk, struct bfa_ablk_cfg_s *ablk_cfg,
3383                 bfa_ablk_cbfn_t cbfn, void *cbarg)
3384 {
3385         struct bfi_ablk_h2i_query_s *m;
3386
3387         WARN_ON(!ablk_cfg);
3388
3389         if (!bfa_ioc_is_operational(ablk->ioc)) {
3390                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3391                 return BFA_STATUS_IOC_FAILURE;
3392         }
3393
3394         if (ablk->busy) {
3395                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3396                 return  BFA_STATUS_DEVBUSY;
3397         }
3398
3399         ablk->cfg = ablk_cfg;
3400         ablk->cbfn  = cbfn;
3401         ablk->cbarg = cbarg;
3402         ablk->busy  = BFA_TRUE;
3403
3404         m = (struct bfi_ablk_h2i_query_s *)ablk->mb.msg;
3405         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_QUERY,
3406                     bfa_ioc_portid(ablk->ioc));
3407         bfa_dma_be_addr_set(m->addr, ablk->dma_addr.pa);
3408         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3409
3410         return BFA_STATUS_OK;
3411 }
3412
3413 bfa_status_t
3414 bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn,
3415                 u8 port, enum bfi_pcifn_class personality,
3416                 u16 bw_min, u16 bw_max,
3417                 bfa_ablk_cbfn_t cbfn, void *cbarg)
3418 {
3419         struct bfi_ablk_h2i_pf_req_s *m;
3420
3421         if (!bfa_ioc_is_operational(ablk->ioc)) {
3422                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3423                 return BFA_STATUS_IOC_FAILURE;
3424         }
3425
3426         if (ablk->busy) {
3427                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3428                 return  BFA_STATUS_DEVBUSY;
3429         }
3430
3431         ablk->pcifn = pcifn;
3432         ablk->cbfn = cbfn;
3433         ablk->cbarg = cbarg;
3434         ablk->busy  = BFA_TRUE;
3435
3436         m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3437         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE,
3438                     bfa_ioc_portid(ablk->ioc));
3439         m->pers = cpu_to_be16((u16)personality);
3440         m->bw_min = cpu_to_be16(bw_min);
3441         m->bw_max = cpu_to_be16(bw_max);
3442         m->port = port;
3443         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3444
3445         return BFA_STATUS_OK;
3446 }
3447
3448 bfa_status_t
3449 bfa_ablk_pf_delete(struct bfa_ablk_s *ablk, int pcifn,
3450                 bfa_ablk_cbfn_t cbfn, void *cbarg)
3451 {
3452         struct bfi_ablk_h2i_pf_req_s *m;
3453
3454         if (!bfa_ioc_is_operational(ablk->ioc)) {
3455                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3456                 return BFA_STATUS_IOC_FAILURE;
3457         }
3458
3459         if (ablk->busy) {
3460                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3461                 return  BFA_STATUS_DEVBUSY;
3462         }
3463
3464         ablk->cbfn  = cbfn;
3465         ablk->cbarg = cbarg;
3466         ablk->busy  = BFA_TRUE;
3467
3468         m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3469         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_DELETE,
3470                     bfa_ioc_portid(ablk->ioc));
3471         m->pcifn = (u8)pcifn;
3472         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3473
3474         return BFA_STATUS_OK;
3475 }
3476
3477 bfa_status_t
3478 bfa_ablk_adapter_config(struct bfa_ablk_s *ablk, enum bfa_mode_s mode,
3479                 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg)
3480 {
3481         struct bfi_ablk_h2i_cfg_req_s *m;
3482
3483         if (!bfa_ioc_is_operational(ablk->ioc)) {
3484                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3485                 return BFA_STATUS_IOC_FAILURE;
3486         }
3487
3488         if (ablk->busy) {
3489                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3490                 return  BFA_STATUS_DEVBUSY;
3491         }
3492
3493         ablk->cbfn  = cbfn;
3494         ablk->cbarg = cbarg;
3495         ablk->busy  = BFA_TRUE;
3496
3497         m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg;
3498         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_ADPT_CONFIG,
3499                     bfa_ioc_portid(ablk->ioc));
3500         m->mode = (u8)mode;
3501         m->max_pf = (u8)max_pf;
3502         m->max_vf = (u8)max_vf;
3503         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3504
3505         return BFA_STATUS_OK;
3506 }
3507
3508 bfa_status_t
3509 bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port, enum bfa_mode_s mode,
3510                 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg)
3511 {
3512         struct bfi_ablk_h2i_cfg_req_s *m;
3513
3514         if (!bfa_ioc_is_operational(ablk->ioc)) {
3515                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3516                 return BFA_STATUS_IOC_FAILURE;
3517         }
3518
3519         if (ablk->busy) {
3520                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3521                 return  BFA_STATUS_DEVBUSY;
3522         }
3523
3524         ablk->cbfn  = cbfn;
3525         ablk->cbarg = cbarg;
3526         ablk->busy  = BFA_TRUE;
3527
3528         m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg;
3529         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PORT_CONFIG,
3530                 bfa_ioc_portid(ablk->ioc));
3531         m->port = (u8)port;
3532         m->mode = (u8)mode;
3533         m->max_pf = (u8)max_pf;
3534         m->max_vf = (u8)max_vf;
3535         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3536
3537         return BFA_STATUS_OK;
3538 }
3539
3540 bfa_status_t
3541 bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, u16 bw_min,
3542                    u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg)
3543 {
3544         struct bfi_ablk_h2i_pf_req_s *m;
3545
3546         if (!bfa_ioc_is_operational(ablk->ioc)) {
3547                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3548                 return BFA_STATUS_IOC_FAILURE;
3549         }
3550
3551         if (ablk->busy) {
3552                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3553                 return  BFA_STATUS_DEVBUSY;
3554         }
3555
3556         ablk->cbfn  = cbfn;
3557         ablk->cbarg = cbarg;
3558         ablk->busy  = BFA_TRUE;
3559
3560         m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3561         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE,
3562                 bfa_ioc_portid(ablk->ioc));
3563         m->pcifn = (u8)pcifn;
3564         m->bw_min = cpu_to_be16(bw_min);
3565         m->bw_max = cpu_to_be16(bw_max);
3566         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3567
3568         return BFA_STATUS_OK;
3569 }
3570
3571 bfa_status_t
3572 bfa_ablk_optrom_en(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg)
3573 {
3574         struct bfi_ablk_h2i_optrom_s *m;
3575
3576         if (!bfa_ioc_is_operational(ablk->ioc)) {
3577                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3578                 return BFA_STATUS_IOC_FAILURE;
3579         }
3580
3581         if (ablk->busy) {
3582                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3583                 return  BFA_STATUS_DEVBUSY;
3584         }
3585
3586         ablk->cbfn  = cbfn;
3587         ablk->cbarg = cbarg;
3588         ablk->busy  = BFA_TRUE;
3589
3590         m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg;
3591         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_ENABLE,
3592                 bfa_ioc_portid(ablk->ioc));
3593         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3594
3595         return BFA_STATUS_OK;
3596 }
3597
3598 bfa_status_t
3599 bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg)
3600 {
3601         struct bfi_ablk_h2i_optrom_s *m;
3602
3603         if (!bfa_ioc_is_operational(ablk->ioc)) {
3604                 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3605                 return BFA_STATUS_IOC_FAILURE;
3606         }
3607
3608         if (ablk->busy) {
3609                 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3610                 return  BFA_STATUS_DEVBUSY;
3611         }
3612
3613         ablk->cbfn  = cbfn;
3614         ablk->cbarg = cbarg;
3615         ablk->busy  = BFA_TRUE;
3616
3617         m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg;
3618         bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_DISABLE,
3619                 bfa_ioc_portid(ablk->ioc));
3620         bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3621
3622         return BFA_STATUS_OK;
3623 }
3624
3625 /*
3626  *      SFP module specific
3627  */
3628
3629 /* forward declarations */
3630 static void bfa_sfp_getdata_send(struct bfa_sfp_s *sfp);
3631 static void bfa_sfp_media_get(struct bfa_sfp_s *sfp);
3632 static bfa_status_t bfa_sfp_speed_valid(struct bfa_sfp_s *sfp,
3633                                 enum bfa_port_speed portspeed);
3634
3635 static void
3636 bfa_cb_sfp_show(struct bfa_sfp_s *sfp)
3637 {
3638         bfa_trc(sfp, sfp->lock);
3639         if (sfp->cbfn)
3640                 sfp->cbfn(sfp->cbarg, sfp->status);
3641         sfp->lock = 0;
3642         sfp->cbfn = NULL;
3643 }
3644
3645 static void
3646 bfa_cb_sfp_state_query(struct bfa_sfp_s *sfp)
3647 {
3648         bfa_trc(sfp, sfp->portspeed);
3649         if (sfp->media) {
3650                 bfa_sfp_media_get(sfp);
3651                 if (sfp->state_query_cbfn)
3652                         sfp->state_query_cbfn(sfp->state_query_cbarg,
3653                                         sfp->status);
3654                 sfp->media = NULL;
3655         }
3656
3657         if (sfp->portspeed) {
3658                 sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed);
3659                 if (sfp->state_query_cbfn)
3660                         sfp->state_query_cbfn(sfp->state_query_cbarg,
3661                                         sfp->status);
3662                 sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
3663         }
3664
3665         sfp->state_query_lock = 0;
3666         sfp->state_query_cbfn = NULL;
3667 }
3668
3669 /*
3670  *      IOC event handler.
3671  */
3672 static void
3673 bfa_sfp_notify(void *sfp_arg, enum bfa_ioc_event_e event)
3674 {
3675         struct bfa_sfp_s *sfp = sfp_arg;
3676
3677         bfa_trc(sfp, event);
3678         bfa_trc(sfp, sfp->lock);
3679         bfa_trc(sfp, sfp->state_query_lock);
3680
3681         switch (event) {
3682         case BFA_IOC_E_DISABLED:
3683         case BFA_IOC_E_FAILED:
3684                 if (sfp->lock) {
3685                         sfp->status = BFA_STATUS_IOC_FAILURE;
3686                         bfa_cb_sfp_show(sfp);
3687                 }
3688
3689                 if (sfp->state_query_lock) {
3690                         sfp->status = BFA_STATUS_IOC_FAILURE;
3691                         bfa_cb_sfp_state_query(sfp);
3692                 }
3693                 break;
3694
3695         default:
3696                 break;
3697         }
3698 }
3699
3700 /*
3701  * SFP's State Change Notification post to AEN
3702  */
3703 static void
3704 bfa_sfp_scn_aen_post(struct bfa_sfp_s *sfp, struct bfi_sfp_scn_s *rsp)
3705 {
3706         struct bfad_s *bfad = (struct bfad_s *)sfp->ioc->bfa->bfad;
3707         struct bfa_aen_entry_s  *aen_entry;
3708         enum bfa_port_aen_event aen_evt = 0;
3709
3710         bfa_trc(sfp, (((u64)rsp->pomlvl) << 16) | (((u64)rsp->sfpid) << 8) |
3711                       ((u64)rsp->event));
3712
3713         bfad_get_aen_entry(bfad, aen_entry);
3714         if (!aen_entry)
3715                 return;
3716
3717         aen_entry->aen_data.port.ioc_type = bfa_ioc_get_type(sfp->ioc);
3718         aen_entry->aen_data.port.pwwn = sfp->ioc->attr->pwwn;
3719         aen_entry->aen_data.port.mac = bfa_ioc_get_mac(sfp->ioc);
3720
3721         switch (rsp->event) {
3722         case BFA_SFP_SCN_INSERTED:
3723                 aen_evt = BFA_PORT_AEN_SFP_INSERT;
3724                 break;
3725         case BFA_SFP_SCN_REMOVED:
3726                 aen_evt = BFA_PORT_AEN_SFP_REMOVE;
3727                 break;
3728         case BFA_SFP_SCN_FAILED:
3729                 aen_evt = BFA_PORT_AEN_SFP_ACCESS_ERROR;
3730                 break;
3731         case BFA_SFP_SCN_UNSUPPORT:
3732                 aen_evt = BFA_PORT_AEN_SFP_UNSUPPORT;
3733                 break;
3734         case BFA_SFP_SCN_POM:
3735                 aen_evt = BFA_PORT_AEN_SFP_POM;
3736                 aen_entry->aen_data.port.level = rsp->pomlvl;
3737                 break;
3738         default:
3739                 bfa_trc(sfp, rsp->event);
3740                 WARN_ON(1);
3741         }
3742
3743         /* Send the AEN notification */
3744         bfad_im_post_vendor_event(aen_entry, bfad, ++sfp->ioc->ioc_aen_seq,
3745                                   BFA_AEN_CAT_PORT, aen_evt);
3746 }
3747
3748 /*
3749  *      SFP get data send
3750  */
3751 static void
3752 bfa_sfp_getdata_send(struct bfa_sfp_s *sfp)
3753 {
3754         struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
3755
3756         bfa_trc(sfp, req->memtype);
3757
3758         /* build host command */
3759         bfi_h2i_set(req->mh, BFI_MC_SFP, BFI_SFP_H2I_SHOW,
3760                         bfa_ioc_portid(sfp->ioc));
3761
3762         /* send mbox cmd */
3763         bfa_ioc_mbox_queue(sfp->ioc, &sfp->mbcmd);
3764 }
3765
3766 /*
3767  *      SFP is valid, read sfp data
3768  */
3769 static void
3770 bfa_sfp_getdata(struct bfa_sfp_s *sfp, enum bfi_sfp_mem_e memtype)
3771 {
3772         struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
3773
3774         WARN_ON(sfp->lock != 0);
3775         bfa_trc(sfp, sfp->state);
3776
3777         sfp->lock = 1;
3778         sfp->memtype = memtype;
3779         req->memtype = memtype;
3780
3781         /* Setup SG list */
3782         bfa_alen_set(&req->alen, sizeof(struct sfp_mem_s), sfp->dbuf_pa);
3783
3784         bfa_sfp_getdata_send(sfp);
3785 }
3786
3787 /*
3788  *      SFP scn handler
3789  */
3790 static void
3791 bfa_sfp_scn(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg)
3792 {
3793         struct bfi_sfp_scn_s *rsp = (struct bfi_sfp_scn_s *) msg;
3794
3795         switch (rsp->event) {
3796         case BFA_SFP_SCN_INSERTED:
3797                 sfp->state = BFA_SFP_STATE_INSERTED;
3798                 sfp->data_valid = 0;
3799                 bfa_sfp_scn_aen_post(sfp, rsp);
3800                 break;
3801         case BFA_SFP_SCN_REMOVED:
3802                 sfp->state = BFA_SFP_STATE_REMOVED;
3803                 sfp->data_valid = 0;
3804                 bfa_sfp_scn_aen_post(sfp, rsp);
3805                 break;
3806         case BFA_SFP_SCN_FAILED:
3807                 sfp->state = BFA_SFP_STATE_FAILED;
3808                 sfp->data_valid = 0;
3809                 bfa_sfp_scn_aen_post(sfp, rsp);
3810                 break;
3811         case BFA_SFP_SCN_UNSUPPORT:
3812                 sfp->state = BFA_SFP_STATE_UNSUPPORT;
3813                 bfa_sfp_scn_aen_post(sfp, rsp);
3814                 if (!sfp->lock)
3815                         bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3816                 break;
3817         case BFA_SFP_SCN_POM:
3818                 bfa_sfp_scn_aen_post(sfp, rsp);
3819                 break;
3820         case BFA_SFP_SCN_VALID:
3821                 sfp->state = BFA_SFP_STATE_VALID;
3822                 if (!sfp->lock)
3823                         bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3824                 break;
3825         default:
3826                 bfa_trc(sfp, rsp->event);
3827                 WARN_ON(1);
3828         }
3829 }
3830
3831 /*
3832  * SFP show complete
3833  */
3834 static void
3835 bfa_sfp_show_comp(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg)
3836 {
3837         struct bfi_sfp_rsp_s *rsp = (struct bfi_sfp_rsp_s *) msg;
3838
3839         if (!sfp->lock) {
3840                 /*
3841                  * receiving response after ioc failure
3842                  */
3843                 bfa_trc(sfp, sfp->lock);
3844                 return;
3845         }
3846
3847         bfa_trc(sfp, rsp->status);
3848         if (rsp->status == BFA_STATUS_OK) {
3849                 sfp->data_valid = 1;
3850                 if (sfp->state == BFA_SFP_STATE_VALID)
3851                         sfp->status = BFA_STATUS_OK;
3852                 else if (sfp->state == BFA_SFP_STATE_UNSUPPORT)
3853                         sfp->status = BFA_STATUS_SFP_UNSUPP;
3854                 else
3855                         bfa_trc(sfp, sfp->state);
3856         } else {
3857                 sfp->data_valid = 0;
3858                 sfp->status = rsp->status;
3859                 /* sfpshow shouldn't change sfp state */
3860         }
3861
3862         bfa_trc(sfp, sfp->memtype);
3863         if (sfp->memtype == BFI_SFP_MEM_DIAGEXT) {
3864                 bfa_trc(sfp, sfp->data_valid);
3865                 if (sfp->data_valid) {
3866                         u32     size = sizeof(struct sfp_mem_s);
3867                         u8 *des = (u8 *)(sfp->sfpmem);
3868                         memcpy(des, sfp->dbuf_kva, size);
3869                 }
3870                 /*
3871                  * Queue completion callback.
3872                  */
3873                 bfa_cb_sfp_show(sfp);
3874         } else
3875                 sfp->lock = 0;
3876
3877         bfa_trc(sfp, sfp->state_query_lock);
3878         if (sfp->state_query_lock) {
3879                 sfp->state = rsp->state;
3880                 /* Complete callback */
3881                 bfa_cb_sfp_state_query(sfp);
3882         }
3883 }
3884
3885 /*
3886  *      SFP query fw sfp state
3887  */
3888 static void
3889 bfa_sfp_state_query(struct bfa_sfp_s *sfp)
3890 {
3891         struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
3892
3893         /* Should not be doing query if not in _INIT state */
3894         WARN_ON(sfp->state != BFA_SFP_STATE_INIT);
3895         WARN_ON(sfp->state_query_lock != 0);
3896         bfa_trc(sfp, sfp->state);
3897
3898         sfp->state_query_lock = 1;
3899         req->memtype = 0;
3900
3901         if (!sfp->lock)
3902                 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3903 }
3904
3905 static void
3906 bfa_sfp_media_get(struct bfa_sfp_s *sfp)
3907 {
3908         enum bfa_defs_sfp_media_e *media = sfp->media;
3909
3910         *media = BFA_SFP_MEDIA_UNKNOWN;
3911
3912         if (sfp->state == BFA_SFP_STATE_UNSUPPORT)
3913                 *media = BFA_SFP_MEDIA_UNSUPPORT;
3914         else if (sfp->state == BFA_SFP_STATE_VALID) {
3915                 union sfp_xcvr_e10g_code_u e10g;
3916                 struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva;
3917                 u16 xmtr_tech = (sfpmem->srlid_base.xcvr[4] & 0x3) << 7 |
3918                                 (sfpmem->srlid_base.xcvr[5] >> 1);
3919
3920                 e10g.b = sfpmem->srlid_base.xcvr[0];
3921                 bfa_trc(sfp, e10g.b);
3922                 bfa_trc(sfp, xmtr_tech);
3923                 /* check fc transmitter tech */
3924                 if ((xmtr_tech & SFP_XMTR_TECH_CU) ||
3925                     (xmtr_tech & SFP_XMTR_TECH_CP) ||
3926                     (xmtr_tech & SFP_XMTR_TECH_CA))
3927                         *media = BFA_SFP_MEDIA_CU;
3928                 else if ((xmtr_tech & SFP_XMTR_TECH_EL_INTRA) ||
3929                          (xmtr_tech & SFP_XMTR_TECH_EL_INTER))
3930                         *media = BFA_SFP_MEDIA_EL;
3931                 else if ((xmtr_tech & SFP_XMTR_TECH_LL) ||
3932                          (xmtr_tech & SFP_XMTR_TECH_LC))
3933                         *media = BFA_SFP_MEDIA_LW;
3934                 else if ((xmtr_tech & SFP_XMTR_TECH_SL) ||
3935                          (xmtr_tech & SFP_XMTR_TECH_SN) ||
3936                          (xmtr_tech & SFP_XMTR_TECH_SA))
3937                         *media = BFA_SFP_MEDIA_SW;
3938                 /* Check 10G Ethernet Compilance code */
3939                 else if (e10g.r.e10g_sr)
3940                         *media = BFA_SFP_MEDIA_SW;
3941                 else if (e10g.r.e10g_lrm && e10g.r.e10g_lr)
3942                         *media = BFA_SFP_MEDIA_LW;
3943                 else if (e10g.r.e10g_unall)
3944                         *media = BFA_SFP_MEDIA_UNKNOWN;
3945                 else
3946                         bfa_trc(sfp, 0);
3947         } else
3948                 bfa_trc(sfp, sfp->state);
3949 }
3950
3951 static bfa_status_t
3952 bfa_sfp_speed_valid(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed)
3953 {
3954         struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva;
3955         struct sfp_xcvr_s *xcvr = (struct sfp_xcvr_s *) sfpmem->srlid_base.xcvr;
3956         union sfp_xcvr_fc3_code_u fc3 = xcvr->fc3;
3957         union sfp_xcvr_e10g_code_u e10g = xcvr->e10g;
3958
3959         if (portspeed == BFA_PORT_SPEED_10GBPS) {
3960                 if (e10g.r.e10g_sr || e10g.r.e10g_lr)
3961                         return BFA_STATUS_OK;
3962                 else {
3963                         bfa_trc(sfp, e10g.b);
3964                         return BFA_STATUS_UNSUPP_SPEED;
3965                 }
3966         }
3967         if (((portspeed & BFA_PORT_SPEED_16GBPS) && fc3.r.mb1600) ||
3968             ((portspeed & BFA_PORT_SPEED_8GBPS) && fc3.r.mb800) ||
3969             ((portspeed & BFA_PORT_SPEED_4GBPS) && fc3.r.mb400) ||
3970             ((portspeed & BFA_PORT_SPEED_2GBPS) && fc3.r.mb200) ||
3971             ((portspeed & BFA_PORT_SPEED_1GBPS) && fc3.r.mb100))
3972                 return BFA_STATUS_OK;
3973         else {
3974                 bfa_trc(sfp, portspeed);
3975                 bfa_trc(sfp, fc3.b);
3976                 bfa_trc(sfp, e10g.b);
3977                 return BFA_STATUS_UNSUPP_SPEED;
3978         }
3979 }
3980
3981 /*
3982  *      SFP hmbox handler
3983  */
3984 void
3985 bfa_sfp_intr(void *sfparg, struct bfi_mbmsg_s *msg)
3986 {
3987         struct bfa_sfp_s *sfp = sfparg;
3988
3989         switch (msg->mh.msg_id) {
3990         case BFI_SFP_I2H_SHOW:
3991                 bfa_sfp_show_comp(sfp, msg);
3992                 break;
3993
3994         case BFI_SFP_I2H_SCN:
3995                 bfa_sfp_scn(sfp, msg);
3996                 break;
3997
3998         default:
3999                 bfa_trc(sfp, msg->mh.msg_id);
4000                 WARN_ON(1);
4001         }
4002 }
4003
4004 /*
4005  *      Return DMA memory needed by sfp module.
4006  */
4007 u32
4008 bfa_sfp_meminfo(void)
4009 {
4010         return BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
4011 }
4012
4013 /*
4014  *      Attach virtual and physical memory for SFP.
4015  */
4016 void
4017 bfa_sfp_attach(struct bfa_sfp_s *sfp, struct bfa_ioc_s *ioc, void *dev,
4018                 struct bfa_trc_mod_s *trcmod)
4019 {
4020         sfp->dev = dev;
4021         sfp->ioc = ioc;
4022         sfp->trcmod = trcmod;
4023
4024         sfp->cbfn = NULL;
4025         sfp->cbarg = NULL;
4026         sfp->sfpmem = NULL;
4027         sfp->lock = 0;
4028         sfp->data_valid = 0;
4029         sfp->state = BFA_SFP_STATE_INIT;
4030         sfp->state_query_lock = 0;
4031         sfp->state_query_cbfn = NULL;
4032         sfp->state_query_cbarg = NULL;
4033         sfp->media = NULL;
4034         sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
4035         sfp->is_elb = BFA_FALSE;
4036
4037         bfa_ioc_mbox_regisr(sfp->ioc, BFI_MC_SFP, bfa_sfp_intr, sfp);
4038         bfa_q_qe_init(&sfp->ioc_notify);
4039         bfa_ioc_notify_init(&sfp->ioc_notify, bfa_sfp_notify, sfp);
4040         list_add_tail(&sfp->ioc_notify.qe, &sfp->ioc->notify_q);
4041 }
4042
4043 /*
4044  *      Claim Memory for SFP
4045  */
4046 void
4047 bfa_sfp_memclaim(struct bfa_sfp_s *sfp, u8 *dm_kva, u64 dm_pa)
4048 {
4049         sfp->dbuf_kva   = dm_kva;
4050         sfp->dbuf_pa    = dm_pa;
4051         memset(sfp->dbuf_kva, 0, sizeof(struct sfp_mem_s));
4052
4053         dm_kva += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
4054         dm_pa += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
4055 }
4056
4057 /*
4058  * Show SFP eeprom content
4059  *
4060  * @param[in] sfp   - bfa sfp module
4061  *
4062  * @param[out] sfpmem - sfp eeprom data
4063  *
4064  */
4065 bfa_status_t
4066 bfa_sfp_show(struct bfa_sfp_s *sfp, struct sfp_mem_s *sfpmem,
4067                 bfa_cb_sfp_t cbfn, void *cbarg)
4068 {
4069
4070         if (!bfa_ioc_is_operational(sfp->ioc)) {
4071                 bfa_trc(sfp, 0);
4072                 return BFA_STATUS_IOC_NON_OP;
4073         }
4074
4075         if (sfp->lock) {
4076                 bfa_trc(sfp, 0);
4077                 return BFA_STATUS_DEVBUSY;
4078         }
4079
4080         sfp->cbfn = cbfn;
4081         sfp->cbarg = cbarg;
4082         sfp->sfpmem = sfpmem;
4083
4084         bfa_sfp_getdata(sfp, BFI_SFP_MEM_DIAGEXT);
4085         return BFA_STATUS_OK;
4086 }
4087
4088 /*
4089  * Return SFP Media type
4090  *
4091  * @param[in] sfp   - bfa sfp module
4092  *
4093  * @param[out] media - port speed from user
4094  *
4095  */
4096 bfa_status_t
4097 bfa_sfp_media(struct bfa_sfp_s *sfp, enum bfa_defs_sfp_media_e *media,
4098                 bfa_cb_sfp_t cbfn, void *cbarg)
4099 {
4100         if (!bfa_ioc_is_operational(sfp->ioc)) {
4101                 bfa_trc(sfp, 0);
4102                 return BFA_STATUS_IOC_NON_OP;
4103         }
4104
4105         sfp->media = media;
4106         if (sfp->state == BFA_SFP_STATE_INIT) {
4107                 if (sfp->state_query_lock) {
4108                         bfa_trc(sfp, 0);
4109                         return BFA_STATUS_DEVBUSY;
4110                 } else {
4111                         sfp->state_query_cbfn = cbfn;
4112                         sfp->state_query_cbarg = cbarg;
4113                         bfa_sfp_state_query(sfp);
4114                         return BFA_STATUS_SFP_NOT_READY;
4115                 }
4116         }
4117
4118         bfa_sfp_media_get(sfp);
4119         return BFA_STATUS_OK;
4120 }
4121
4122 /*
4123  * Check if user set port speed is allowed by the SFP
4124  *
4125  * @param[in] sfp   - bfa sfp module
4126  * @param[in] portspeed - port speed from user
4127  *
4128  */
4129 bfa_status_t
4130 bfa_sfp_speed(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed,
4131                 bfa_cb_sfp_t cbfn, void *cbarg)
4132 {
4133         WARN_ON(portspeed == BFA_PORT_SPEED_UNKNOWN);
4134
4135         if (!bfa_ioc_is_operational(sfp->ioc))
4136                 return BFA_STATUS_IOC_NON_OP;
4137
4138         /* For Mezz card, all speed is allowed */
4139         if (bfa_mfg_is_mezz(sfp->ioc->attr->card_type))
4140                 return BFA_STATUS_OK;
4141
4142         /* Check SFP state */
4143         sfp->portspeed = portspeed;
4144         if (sfp->state == BFA_SFP_STATE_INIT) {
4145                 if (sfp->state_query_lock) {
4146                         bfa_trc(sfp, 0);
4147                         return BFA_STATUS_DEVBUSY;
4148                 } else {
4149                         sfp->state_query_cbfn = cbfn;
4150                         sfp->state_query_cbarg = cbarg;
4151                         bfa_sfp_state_query(sfp);
4152                         return BFA_STATUS_SFP_NOT_READY;
4153                 }
4154         }
4155
4156         if (sfp->state == BFA_SFP_STATE_REMOVED ||
4157             sfp->state == BFA_SFP_STATE_FAILED) {
4158                 bfa_trc(sfp, sfp->state);
4159                 return BFA_STATUS_NO_SFP_DEV;
4160         }
4161
4162         if (sfp->state == BFA_SFP_STATE_INSERTED) {
4163                 bfa_trc(sfp, sfp->state);
4164                 return BFA_STATUS_DEVBUSY;  /* sfp is reading data */
4165         }
4166
4167         /* For eloopback, all speed is allowed */
4168         if (sfp->is_elb)
4169                 return BFA_STATUS_OK;
4170
4171         return bfa_sfp_speed_valid(sfp, portspeed);
4172 }
4173
4174 /*
4175  *      Flash module specific
4176  */
4177
4178 /*
4179  * FLASH DMA buffer should be big enough to hold both MFG block and
4180  * asic block(64k) at the same time and also should be 2k aligned to
4181  * avoid write segement to cross sector boundary.
4182  */
4183 #define BFA_FLASH_SEG_SZ        2048
4184 #define BFA_FLASH_DMA_BUF_SZ    \
4185         BFA_ROUNDUP(0x010000 + sizeof(struct bfa_mfg_block_s), BFA_FLASH_SEG_SZ)
4186
4187 static void
4188 bfa_flash_aen_audit_post(struct bfa_ioc_s *ioc, enum bfa_audit_aen_event event,
4189                         int inst, int type)
4190 {
4191         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
4192         struct bfa_aen_entry_s  *aen_entry;
4193
4194         bfad_get_aen_entry(bfad, aen_entry);
4195         if (!aen_entry)
4196                 return;
4197
4198         aen_entry->aen_data.audit.pwwn = ioc->attr->pwwn;
4199         aen_entry->aen_data.audit.partition_inst = inst;
4200         aen_entry->aen_data.audit.partition_type = type;
4201
4202         /* Send the AEN notification */
4203         bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq,
4204                                   BFA_AEN_CAT_AUDIT, event);
4205 }
4206
4207 static void
4208 bfa_flash_cb(struct bfa_flash_s *flash)
4209 {
4210         flash->op_busy = 0;
4211         if (flash->cbfn)
4212                 flash->cbfn(flash->cbarg, flash->status);
4213 }
4214
4215 static void
4216 bfa_flash_notify(void *cbarg, enum bfa_ioc_event_e event)
4217 {
4218         struct bfa_flash_s      *flash = cbarg;
4219
4220         bfa_trc(flash, event);
4221         switch (event) {
4222         case BFA_IOC_E_DISABLED:
4223         case BFA_IOC_E_FAILED:
4224                 if (flash->op_busy) {
4225                         flash->status = BFA_STATUS_IOC_FAILURE;
4226                         flash->cbfn(flash->cbarg, flash->status);
4227                         flash->op_busy = 0;
4228                 }
4229                 break;
4230
4231         default:
4232                 break;
4233         }
4234 }
4235
4236 /*
4237  * Send flash attribute query request.
4238  *
4239  * @param[in] cbarg - callback argument
4240  */
4241 static void
4242 bfa_flash_query_send(void *cbarg)
4243 {
4244         struct bfa_flash_s *flash = cbarg;
4245         struct bfi_flash_query_req_s *msg =
4246                         (struct bfi_flash_query_req_s *) flash->mb.msg;
4247
4248         bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_QUERY_REQ,
4249                 bfa_ioc_portid(flash->ioc));
4250         bfa_alen_set(&msg->alen, sizeof(struct bfa_flash_attr_s),
4251                 flash->dbuf_pa);
4252         bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4253 }
4254
4255 /*
4256  * Send flash write request.
4257  *
4258  * @param[in] cbarg - callback argument
4259  */
4260 static void
4261 bfa_flash_write_send(struct bfa_flash_s *flash)
4262 {
4263         struct bfi_flash_write_req_s *msg =
4264                         (struct bfi_flash_write_req_s *) flash->mb.msg;
4265         u32     len;
4266
4267         msg->type = be32_to_cpu(flash->type);
4268         msg->instance = flash->instance;
4269         msg->offset = be32_to_cpu(flash->addr_off + flash->offset);
4270         len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ?
4271                 flash->residue : BFA_FLASH_DMA_BUF_SZ;
4272         msg->length = be32_to_cpu(len);
4273
4274         /* indicate if it's the last msg of the whole write operation */
4275         msg->last = (len == flash->residue) ? 1 : 0;
4276
4277         bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_WRITE_REQ,
4278                         bfa_ioc_portid(flash->ioc));
4279         bfa_alen_set(&msg->alen, len, flash->dbuf_pa);
4280         memcpy(flash->dbuf_kva, flash->ubuf + flash->offset, len);
4281         bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4282
4283         flash->residue -= len;
4284         flash->offset += len;
4285 }
4286
4287 /*
4288  * Send flash read request.
4289  *
4290  * @param[in] cbarg - callback argument
4291  */
4292 static void
4293 bfa_flash_read_send(void *cbarg)
4294 {
4295         struct bfa_flash_s *flash = cbarg;
4296         struct bfi_flash_read_req_s *msg =
4297                         (struct bfi_flash_read_req_s *) flash->mb.msg;
4298         u32     len;
4299
4300         msg->type = be32_to_cpu(flash->type);
4301         msg->instance = flash->instance;
4302         msg->offset = be32_to_cpu(flash->addr_off + flash->offset);
4303         len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ?
4304                         flash->residue : BFA_FLASH_DMA_BUF_SZ;
4305         msg->length = be32_to_cpu(len);
4306         bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_READ_REQ,
4307                 bfa_ioc_portid(flash->ioc));
4308         bfa_alen_set(&msg->alen, len, flash->dbuf_pa);
4309         bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4310 }
4311
4312 /*
4313  * Send flash erase request.
4314  *
4315  * @param[in] cbarg - callback argument
4316  */
4317 static void
4318 bfa_flash_erase_send(void *cbarg)
4319 {
4320         struct bfa_flash_s *flash = cbarg;
4321         struct bfi_flash_erase_req_s *msg =
4322                         (struct bfi_flash_erase_req_s *) flash->mb.msg;
4323
4324         msg->type = be32_to_cpu(flash->type);
4325         msg->instance = flash->instance;
4326         bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_ERASE_REQ,
4327                         bfa_ioc_portid(flash->ioc));
4328         bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4329 }
4330
4331 /*
4332  * Process flash response messages upon receiving interrupts.
4333  *
4334  * @param[in] flasharg - flash structure
4335  * @param[in] msg - message structure
4336  */
4337 static void
4338 bfa_flash_intr(void *flasharg, struct bfi_mbmsg_s *msg)
4339 {
4340         struct bfa_flash_s *flash = flasharg;
4341         u32     status;
4342
4343         union {
4344                 struct bfi_flash_query_rsp_s *query;
4345                 struct bfi_flash_erase_rsp_s *erase;
4346                 struct bfi_flash_write_rsp_s *write;
4347                 struct bfi_flash_read_rsp_s *read;
4348                 struct bfi_flash_event_s *event;
4349                 struct bfi_mbmsg_s   *msg;
4350         } m;
4351
4352         m.msg = msg;
4353         bfa_trc(flash, msg->mh.msg_id);
4354
4355         if (!flash->op_busy && msg->mh.msg_id != BFI_FLASH_I2H_EVENT) {
4356                 /* receiving response after ioc failure */
4357                 bfa_trc(flash, 0x9999);
4358                 return;
4359         }
4360
4361         switch (msg->mh.msg_id) {
4362         case BFI_FLASH_I2H_QUERY_RSP:
4363                 status = be32_to_cpu(m.query->status);
4364                 bfa_trc(flash, status);
4365                 if (status == BFA_STATUS_OK) {
4366                         u32     i;
4367                         struct bfa_flash_attr_s *attr, *f;
4368
4369                         attr = (struct bfa_flash_attr_s *) flash->ubuf;
4370                         f = (struct bfa_flash_attr_s *) flash->dbuf_kva;
4371                         attr->status = be32_to_cpu(f->status);
4372                         attr->npart = be32_to_cpu(f->npart);
4373                         bfa_trc(flash, attr->status);
4374                         bfa_trc(flash, attr->npart);
4375                         for (i = 0; i < attr->npart; i++) {
4376                                 attr->part[i].part_type =
4377                                         be32_to_cpu(f->part[i].part_type);
4378                                 attr->part[i].part_instance =
4379                                         be32_to_cpu(f->part[i].part_instance);
4380                                 attr->part[i].part_off =
4381                                         be32_to_cpu(f->part[i].part_off);
4382                                 attr->part[i].part_size =
4383                                         be32_to_cpu(f->part[i].part_size);
4384                                 attr->part[i].part_len =
4385                                         be32_to_cpu(f->part[i].part_len);
4386                                 attr->part[i].part_status =
4387                                         be32_to_cpu(f->part[i].part_status);
4388                         }
4389                 }
4390                 flash->status = status;
4391                 bfa_flash_cb(flash);
4392                 break;
4393         case BFI_FLASH_I2H_ERASE_RSP:
4394                 status = be32_to_cpu(m.erase->status);
4395                 bfa_trc(flash, status);
4396                 flash->status = status;
4397                 bfa_flash_cb(flash);
4398                 break;
4399         case BFI_FLASH_I2H_WRITE_RSP:
4400                 status = be32_to_cpu(m.write->status);
4401                 bfa_trc(flash, status);
4402                 if (status != BFA_STATUS_OK || flash->residue == 0) {
4403                         flash->status = status;
4404                         bfa_flash_cb(flash);
4405                 } else {
4406                         bfa_trc(flash, flash->offset);
4407                         bfa_flash_write_send(flash);
4408                 }
4409                 break;
4410         case BFI_FLASH_I2H_READ_RSP:
4411                 status = be32_to_cpu(m.read->status);
4412                 bfa_trc(flash, status);
4413                 if (status != BFA_STATUS_OK) {
4414                         flash->status = status;
4415                         bfa_flash_cb(flash);
4416                 } else {
4417                         u32 len = be32_to_cpu(m.read->length);
4418                         bfa_trc(flash, flash->offset);
4419                         bfa_trc(flash, len);
4420                         memcpy(flash->ubuf + flash->offset,
4421                                 flash->dbuf_kva, len);
4422                         flash->residue -= len;
4423                         flash->offset += len;
4424                         if (flash->residue == 0) {
4425                                 flash->status = status;
4426                                 bfa_flash_cb(flash);
4427                         } else
4428                                 bfa_flash_read_send(flash);
4429                 }
4430                 break;
4431         case BFI_FLASH_I2H_BOOT_VER_RSP:
4432                 break;
4433         case BFI_FLASH_I2H_EVENT:
4434                 status = be32_to_cpu(m.event->status);
4435                 bfa_trc(flash, status);
4436                 if (status == BFA_STATUS_BAD_FWCFG)
4437                         bfa_ioc_aen_post(flash->ioc, BFA_IOC_AEN_FWCFG_ERROR);
4438                 else if (status == BFA_STATUS_INVALID_VENDOR) {
4439                         u32 param;
4440                         param = be32_to_cpu(m.event->param);
4441                         bfa_trc(flash, param);
4442                         bfa_ioc_aen_post(flash->ioc,
4443                                 BFA_IOC_AEN_INVALID_VENDOR);
4444                 }
4445                 break;
4446
4447         default:
4448                 WARN_ON(1);
4449         }
4450 }
4451
4452 /*
4453  * Flash memory info API.
4454  *
4455  * @param[in] mincfg - minimal cfg variable
4456  */
4457 u32
4458 bfa_flash_meminfo(bfa_boolean_t mincfg)
4459 {
4460         /* min driver doesn't need flash */
4461         if (mincfg)
4462                 return 0;
4463         return BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
4464 }
4465
4466 /*
4467  * Flash attach API.
4468  *
4469  * @param[in] flash - flash structure
4470  * @param[in] ioc  - ioc structure
4471  * @param[in] dev  - device structure
4472  * @param[in] trcmod - trace module
4473  * @param[in] logmod - log module
4474  */
4475 void
4476 bfa_flash_attach(struct bfa_flash_s *flash, struct bfa_ioc_s *ioc, void *dev,
4477                 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
4478 {
4479         flash->ioc = ioc;
4480         flash->trcmod = trcmod;
4481         flash->cbfn = NULL;
4482         flash->cbarg = NULL;
4483         flash->op_busy = 0;
4484
4485         bfa_ioc_mbox_regisr(flash->ioc, BFI_MC_FLASH, bfa_flash_intr, flash);
4486         bfa_q_qe_init(&flash->ioc_notify);
4487         bfa_ioc_notify_init(&flash->ioc_notify, bfa_flash_notify, flash);
4488         list_add_tail(&flash->ioc_notify.qe, &flash->ioc->notify_q);
4489
4490         /* min driver doesn't need flash */
4491         if (mincfg) {
4492                 flash->dbuf_kva = NULL;
4493                 flash->dbuf_pa = 0;
4494         }
4495 }
4496
4497 /*
4498  * Claim memory for flash
4499  *
4500  * @param[in] flash - flash structure
4501  * @param[in] dm_kva - pointer to virtual memory address
4502  * @param[in] dm_pa - physical memory address
4503  * @param[in] mincfg - minimal cfg variable
4504  */
4505 void
4506 bfa_flash_memclaim(struct bfa_flash_s *flash, u8 *dm_kva, u64 dm_pa,
4507                 bfa_boolean_t mincfg)
4508 {
4509         if (mincfg)
4510                 return;
4511
4512         flash->dbuf_kva = dm_kva;
4513         flash->dbuf_pa = dm_pa;
4514         memset(flash->dbuf_kva, 0, BFA_FLASH_DMA_BUF_SZ);
4515         dm_kva += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
4516         dm_pa += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
4517 }
4518
4519 /*
4520  * Get flash attribute.
4521  *
4522  * @param[in] flash - flash structure
4523  * @param[in] attr - flash attribute structure
4524  * @param[in] cbfn - callback function
4525  * @param[in] cbarg - callback argument
4526  *
4527  * Return status.
4528  */
4529 bfa_status_t
4530 bfa_flash_get_attr(struct bfa_flash_s *flash, struct bfa_flash_attr_s *attr,
4531                 bfa_cb_flash_t cbfn, void *cbarg)
4532 {
4533         bfa_trc(flash, BFI_FLASH_H2I_QUERY_REQ);
4534
4535         if (!bfa_ioc_is_operational(flash->ioc))
4536                 return BFA_STATUS_IOC_NON_OP;
4537
4538         if (flash->op_busy) {
4539                 bfa_trc(flash, flash->op_busy);
4540                 return BFA_STATUS_DEVBUSY;
4541         }
4542
4543         flash->op_busy = 1;
4544         flash->cbfn = cbfn;
4545         flash->cbarg = cbarg;
4546         flash->ubuf = (u8 *) attr;
4547         bfa_flash_query_send(flash);
4548
4549         return BFA_STATUS_OK;
4550 }
4551
4552 /*
4553  * Erase flash partition.
4554  *
4555  * @param[in] flash - flash structure
4556  * @param[in] type - flash partition type
4557  * @param[in] instance - flash partition instance
4558  * @param[in] cbfn - callback function
4559  * @param[in] cbarg - callback argument
4560  *
4561  * Return status.
4562  */
4563 bfa_status_t
4564 bfa_flash_erase_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
4565                 u8 instance, bfa_cb_flash_t cbfn, void *cbarg)
4566 {
4567         bfa_trc(flash, BFI_FLASH_H2I_ERASE_REQ);
4568         bfa_trc(flash, type);
4569         bfa_trc(flash, instance);
4570
4571         if (!bfa_ioc_is_operational(flash->ioc))
4572                 return BFA_STATUS_IOC_NON_OP;
4573
4574         if (flash->op_busy) {
4575                 bfa_trc(flash, flash->op_busy);
4576                 return BFA_STATUS_DEVBUSY;
4577         }
4578
4579         flash->op_busy = 1;
4580         flash->cbfn = cbfn;
4581         flash->cbarg = cbarg;
4582         flash->type = type;
4583         flash->instance = instance;
4584
4585         bfa_flash_erase_send(flash);
4586         bfa_flash_aen_audit_post(flash->ioc, BFA_AUDIT_AEN_FLASH_ERASE,
4587                                 instance, type);
4588         return BFA_STATUS_OK;
4589 }
4590
4591 /*
4592  * Update flash partition.
4593  *
4594  * @param[in] flash - flash structure
4595  * @param[in] type - flash partition type
4596  * @param[in] instance - flash partition instance
4597  * @param[in] buf - update data buffer
4598  * @param[in] len - data buffer length
4599  * @param[in] offset - offset relative to the partition starting address
4600  * @param[in] cbfn - callback function
4601  * @param[in] cbarg - callback argument
4602  *
4603  * Return status.
4604  */
4605 bfa_status_t
4606 bfa_flash_update_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
4607                 u8 instance, void *buf, u32 len, u32 offset,
4608                 bfa_cb_flash_t cbfn, void *cbarg)
4609 {
4610         bfa_trc(flash, BFI_FLASH_H2I_WRITE_REQ);
4611         bfa_trc(flash, type);
4612         bfa_trc(flash, instance);
4613         bfa_trc(flash, len);
4614         bfa_trc(flash, offset);
4615
4616         if (!bfa_ioc_is_operational(flash->ioc))
4617                 return BFA_STATUS_IOC_NON_OP;
4618
4619         /*
4620          * 'len' must be in word (4-byte) boundary
4621          * 'offset' must be in sector (16kb) boundary
4622          */
4623         if (!len || (len & 0x03) || (offset & 0x00003FFF))
4624                 return BFA_STATUS_FLASH_BAD_LEN;
4625
4626         if (type == BFA_FLASH_PART_MFG)
4627                 return BFA_STATUS_EINVAL;
4628
4629         if (flash->op_busy) {
4630                 bfa_trc(flash, flash->op_busy);
4631                 return BFA_STATUS_DEVBUSY;
4632         }
4633
4634         flash->op_busy = 1;
4635         flash->cbfn = cbfn;
4636         flash->cbarg = cbarg;
4637         flash->type = type;
4638         flash->instance = instance;
4639         flash->residue = len;
4640         flash->offset = 0;
4641         flash->addr_off = offset;
4642         flash->ubuf = buf;
4643
4644         bfa_flash_write_send(flash);
4645         return BFA_STATUS_OK;
4646 }
4647
4648 /*
4649  * Read flash partition.
4650  *
4651  * @param[in] flash - flash structure
4652  * @param[in] type - flash partition type
4653  * @param[in] instance - flash partition instance
4654  * @param[in] buf - read data buffer
4655  * @param[in] len - data buffer length
4656  * @param[in] offset - offset relative to the partition starting address
4657  * @param[in] cbfn - callback function
4658  * @param[in] cbarg - callback argument
4659  *
4660  * Return status.
4661  */
4662 bfa_status_t
4663 bfa_flash_read_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
4664                 u8 instance, void *buf, u32 len, u32 offset,
4665                 bfa_cb_flash_t cbfn, void *cbarg)
4666 {
4667         bfa_trc(flash, BFI_FLASH_H2I_READ_REQ);
4668         bfa_trc(flash, type);
4669         bfa_trc(flash, instance);
4670         bfa_trc(flash, len);
4671         bfa_trc(flash, offset);
4672
4673         if (!bfa_ioc_is_operational(flash->ioc))
4674                 return BFA_STATUS_IOC_NON_OP;
4675
4676         /*
4677          * 'len' must be in word (4-byte) boundary
4678          * 'offset' must be in sector (16kb) boundary
4679          */
4680         if (!len || (len & 0x03) || (offset & 0x00003FFF))
4681                 return BFA_STATUS_FLASH_BAD_LEN;
4682
4683         if (flash->op_busy) {
4684                 bfa_trc(flash, flash->op_busy);
4685                 return BFA_STATUS_DEVBUSY;
4686         }
4687
4688         flash->op_busy = 1;
4689         flash->cbfn = cbfn;
4690         flash->cbarg = cbarg;
4691         flash->type = type;
4692         flash->instance = instance;
4693         flash->residue = len;
4694         flash->offset = 0;
4695         flash->addr_off = offset;
4696         flash->ubuf = buf;
4697         bfa_flash_read_send(flash);
4698
4699         return BFA_STATUS_OK;
4700 }
4701
4702 /*
4703  *      DIAG module specific
4704  */
4705
4706 #define BFA_DIAG_MEMTEST_TOV    50000   /* memtest timeout in msec */
4707 #define CT2_BFA_DIAG_MEMTEST_TOV        (9*30*1000)  /* 4.5 min */
4708
4709 /* IOC event handler */
4710 static void
4711 bfa_diag_notify(void *diag_arg, enum bfa_ioc_event_e event)
4712 {
4713         struct bfa_diag_s *diag = diag_arg;
4714
4715         bfa_trc(diag, event);
4716         bfa_trc(diag, diag->block);
4717         bfa_trc(diag, diag->fwping.lock);
4718         bfa_trc(diag, diag->tsensor.lock);
4719
4720         switch (event) {
4721         case BFA_IOC_E_DISABLED:
4722         case BFA_IOC_E_FAILED:
4723                 if (diag->fwping.lock) {
4724                         diag->fwping.status = BFA_STATUS_IOC_FAILURE;
4725                         diag->fwping.cbfn(diag->fwping.cbarg,
4726                                         diag->fwping.status);
4727                         diag->fwping.lock = 0;
4728                 }
4729
4730                 if (diag->tsensor.lock) {
4731                         diag->tsensor.status = BFA_STATUS_IOC_FAILURE;
4732                         diag->tsensor.cbfn(diag->tsensor.cbarg,
4733                                            diag->tsensor.status);
4734                         diag->tsensor.lock = 0;
4735                 }
4736
4737                 if (diag->block) {
4738                         if (diag->timer_active) {
4739                                 bfa_timer_stop(&diag->timer);
4740                                 diag->timer_active = 0;
4741                         }
4742
4743                         diag->status = BFA_STATUS_IOC_FAILURE;
4744                         diag->cbfn(diag->cbarg, diag->status);
4745                         diag->block = 0;
4746                 }
4747                 break;
4748
4749         default:
4750                 break;
4751         }
4752 }
4753
4754 static void
4755 bfa_diag_memtest_done(void *cbarg)
4756 {
4757         struct bfa_diag_s *diag = cbarg;
4758         struct bfa_ioc_s  *ioc = diag->ioc;
4759         struct bfa_diag_memtest_result *res = diag->result;
4760         u32     loff = BFI_BOOT_MEMTEST_RES_ADDR;
4761         u32     pgnum, i;
4762
4763         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
4764         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
4765
4766         for (i = 0; i < (sizeof(struct bfa_diag_memtest_result) /
4767                          sizeof(u32)); i++) {
4768                 /* read test result from smem */
4769                 *((u32 *) res + i) =
4770                         bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
4771                 loff += sizeof(u32);
4772         }
4773
4774         /* Reset IOC fwstates to BFI_IOC_UNINIT */
4775         bfa_ioc_reset_fwstate(ioc);
4776
4777         res->status = swab32(res->status);
4778         bfa_trc(diag, res->status);
4779
4780         if (res->status == BFI_BOOT_MEMTEST_RES_SIG)
4781                 diag->status = BFA_STATUS_OK;
4782         else {
4783                 diag->status = BFA_STATUS_MEMTEST_FAILED;
4784                 res->addr = swab32(res->addr);
4785                 res->exp = swab32(res->exp);
4786                 res->act = swab32(res->act);
4787                 res->err_status = swab32(res->err_status);
4788                 res->err_status1 = swab32(res->err_status1);
4789                 res->err_addr = swab32(res->err_addr);
4790                 bfa_trc(diag, res->addr);
4791                 bfa_trc(diag, res->exp);
4792                 bfa_trc(diag, res->act);
4793                 bfa_trc(diag, res->err_status);
4794                 bfa_trc(diag, res->err_status1);
4795                 bfa_trc(diag, res->err_addr);
4796         }
4797         diag->timer_active = 0;
4798         diag->cbfn(diag->cbarg, diag->status);
4799         diag->block = 0;
4800 }
4801
4802 /*
4803  * Firmware ping
4804  */
4805
4806 /*
4807  * Perform DMA test directly
4808  */
4809 static void
4810 diag_fwping_send(struct bfa_diag_s *diag)
4811 {
4812         struct bfi_diag_fwping_req_s *fwping_req;
4813         u32     i;
4814
4815         bfa_trc(diag, diag->fwping.dbuf_pa);
4816
4817         /* fill DMA area with pattern */
4818         for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++)
4819                 *((u32 *)diag->fwping.dbuf_kva + i) = diag->fwping.data;
4820
4821         /* Fill mbox msg */
4822         fwping_req = (struct bfi_diag_fwping_req_s *)diag->fwping.mbcmd.msg;
4823
4824         /* Setup SG list */
4825         bfa_alen_set(&fwping_req->alen, BFI_DIAG_DMA_BUF_SZ,
4826                         diag->fwping.dbuf_pa);
4827         /* Set up dma count */
4828         fwping_req->count = cpu_to_be32(diag->fwping.count);
4829         /* Set up data pattern */
4830         fwping_req->data = diag->fwping.data;
4831
4832         /* build host command */
4833         bfi_h2i_set(fwping_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_FWPING,
4834                 bfa_ioc_portid(diag->ioc));
4835
4836         /* send mbox cmd */
4837         bfa_ioc_mbox_queue(diag->ioc, &diag->fwping.mbcmd);
4838 }
4839
4840 static void
4841 diag_fwping_comp(struct bfa_diag_s *diag,
4842                  struct bfi_diag_fwping_rsp_s *diag_rsp)
4843 {
4844         u32     rsp_data = diag_rsp->data;
4845         u8      rsp_dma_status = diag_rsp->dma_status;
4846
4847         bfa_trc(diag, rsp_data);
4848         bfa_trc(diag, rsp_dma_status);
4849
4850         if (rsp_dma_status == BFA_STATUS_OK) {
4851                 u32     i, pat;
4852                 pat = (diag->fwping.count & 0x1) ? ~(diag->fwping.data) :
4853                         diag->fwping.data;
4854                 /* Check mbox data */
4855                 if (diag->fwping.data != rsp_data) {
4856                         bfa_trc(diag, rsp_data);
4857                         diag->fwping.result->dmastatus =
4858                                         BFA_STATUS_DATACORRUPTED;
4859                         diag->fwping.status = BFA_STATUS_DATACORRUPTED;
4860                         diag->fwping.cbfn(diag->fwping.cbarg,
4861                                         diag->fwping.status);
4862                         diag->fwping.lock = 0;
4863                         return;
4864                 }
4865                 /* Check dma pattern */
4866                 for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++) {
4867                         if (*((u32 *)diag->fwping.dbuf_kva + i) != pat) {
4868                                 bfa_trc(diag, i);
4869                                 bfa_trc(diag, pat);
4870                                 bfa_trc(diag,
4871                                         *((u32 *)diag->fwping.dbuf_kva + i));
4872                                 diag->fwping.result->dmastatus =
4873                                                 BFA_STATUS_DATACORRUPTED;
4874                                 diag->fwping.status = BFA_STATUS_DATACORRUPTED;
4875                                 diag->fwping.cbfn(diag->fwping.cbarg,
4876                                                 diag->fwping.status);
4877                                 diag->fwping.lock = 0;
4878                                 return;
4879                         }
4880                 }
4881                 diag->fwping.result->dmastatus = BFA_STATUS_OK;
4882                 diag->fwping.status = BFA_STATUS_OK;
4883                 diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status);
4884                 diag->fwping.lock = 0;
4885         } else {
4886                 diag->fwping.status = BFA_STATUS_HDMA_FAILED;
4887                 diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status);
4888                 diag->fwping.lock = 0;
4889         }
4890 }
4891
4892 /*
4893  * Temperature Sensor
4894  */
4895
4896 static void
4897 diag_tempsensor_send(struct bfa_diag_s *diag)
4898 {
4899         struct bfi_diag_ts_req_s *msg;
4900
4901         msg = (struct bfi_diag_ts_req_s *)diag->tsensor.mbcmd.msg;
4902         bfa_trc(diag, msg->temp);
4903         /* build host command */
4904         bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_TEMPSENSOR,
4905                 bfa_ioc_portid(diag->ioc));
4906         /* send mbox cmd */
4907         bfa_ioc_mbox_queue(diag->ioc, &diag->tsensor.mbcmd);
4908 }
4909
4910 static void
4911 diag_tempsensor_comp(struct bfa_diag_s *diag, bfi_diag_ts_rsp_t *rsp)
4912 {
4913         if (!diag->tsensor.lock) {
4914                 /* receiving response after ioc failure */
4915                 bfa_trc(diag, diag->tsensor.lock);
4916                 return;
4917         }
4918
4919         /*
4920          * ASIC junction tempsensor is a reg read operation
4921          * it will always return OK
4922          */
4923         diag->tsensor.temp->temp = be16_to_cpu(rsp->temp);
4924         diag->tsensor.temp->ts_junc = rsp->ts_junc;
4925         diag->tsensor.temp->ts_brd = rsp->ts_brd;
4926
4927         if (rsp->ts_brd) {
4928                 /* tsensor.temp->status is brd_temp status */
4929                 diag->tsensor.temp->status = rsp->status;
4930                 if (rsp->status == BFA_STATUS_OK) {
4931                         diag->tsensor.temp->brd_temp =
4932                                 be16_to_cpu(rsp->brd_temp);
4933                 } else
4934                         diag->tsensor.temp->brd_temp = 0;
4935         }
4936
4937         bfa_trc(diag, rsp->status);
4938         bfa_trc(diag, rsp->ts_junc);
4939         bfa_trc(diag, rsp->temp);
4940         bfa_trc(diag, rsp->ts_brd);
4941         bfa_trc(diag, rsp->brd_temp);
4942
4943         /* tsensor status is always good bcos we always have junction temp */
4944         diag->tsensor.status = BFA_STATUS_OK;
4945         diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status);
4946         diag->tsensor.lock = 0;
4947 }
4948
4949 /*
4950  *      LED Test command
4951  */
4952 static void
4953 diag_ledtest_send(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest)
4954 {
4955         struct bfi_diag_ledtest_req_s  *msg;
4956
4957         msg = (struct bfi_diag_ledtest_req_s *)diag->ledtest.mbcmd.msg;
4958         /* build host command */
4959         bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LEDTEST,
4960                         bfa_ioc_portid(diag->ioc));
4961
4962         /*
4963          * convert the freq from N blinks per 10 sec to
4964          * crossbow ontime value. We do it here because division is need
4965          */
4966         if (ledtest->freq)
4967                 ledtest->freq = 500 / ledtest->freq;
4968
4969         if (ledtest->freq == 0)
4970                 ledtest->freq = 1;
4971
4972         bfa_trc(diag, ledtest->freq);
4973         /* mcpy(&ledtest_req->req, ledtest, sizeof(bfa_diag_ledtest_t)); */
4974         msg->cmd = (u8) ledtest->cmd;
4975         msg->color = (u8) ledtest->color;
4976         msg->portid = bfa_ioc_portid(diag->ioc);
4977         msg->led = ledtest->led;
4978         msg->freq = cpu_to_be16(ledtest->freq);
4979
4980         /* send mbox cmd */
4981         bfa_ioc_mbox_queue(diag->ioc, &diag->ledtest.mbcmd);
4982 }
4983
4984 static void
4985 diag_ledtest_comp(struct bfa_diag_s *diag, struct bfi_diag_ledtest_rsp_s *msg)
4986 {
4987         bfa_trc(diag, diag->ledtest.lock);
4988         diag->ledtest.lock = BFA_FALSE;
4989         /* no bfa_cb_queue is needed because driver is not waiting */
4990 }
4991
4992 /*
4993  * Port beaconing
4994  */
4995 static void
4996 diag_portbeacon_send(struct bfa_diag_s *diag, bfa_boolean_t beacon, u32 sec)
4997 {
4998         struct bfi_diag_portbeacon_req_s *msg;
4999
5000         msg = (struct bfi_diag_portbeacon_req_s *)diag->beacon.mbcmd.msg;
5001         /* build host command */
5002         bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_PORTBEACON,
5003                 bfa_ioc_portid(diag->ioc));
5004         msg->beacon = beacon;
5005         msg->period = cpu_to_be32(sec);
5006         /* send mbox cmd */
5007         bfa_ioc_mbox_queue(diag->ioc, &diag->beacon.mbcmd);
5008 }
5009
5010 static void
5011 diag_portbeacon_comp(struct bfa_diag_s *diag)
5012 {
5013         bfa_trc(diag, diag->beacon.state);
5014         diag->beacon.state = BFA_FALSE;
5015         if (diag->cbfn_beacon)
5016                 diag->cbfn_beacon(diag->dev, BFA_FALSE, diag->beacon.link_e2e);
5017 }
5018
5019 /*
5020  *      Diag hmbox handler
5021  */
5022 static void
5023 bfa_diag_intr(void *diagarg, struct bfi_mbmsg_s *msg)
5024 {
5025         struct bfa_diag_s *diag = diagarg;
5026
5027         switch (msg->mh.msg_id) {
5028         case BFI_DIAG_I2H_PORTBEACON:
5029                 diag_portbeacon_comp(diag);
5030                 break;
5031         case BFI_DIAG_I2H_FWPING:
5032                 diag_fwping_comp(diag, (struct bfi_diag_fwping_rsp_s *) msg);
5033                 break;
5034         case BFI_DIAG_I2H_TEMPSENSOR:
5035                 diag_tempsensor_comp(diag, (bfi_diag_ts_rsp_t *) msg);
5036                 break;
5037         case BFI_DIAG_I2H_LEDTEST:
5038                 diag_ledtest_comp(diag, (struct bfi_diag_ledtest_rsp_s *) msg);
5039                 break;
5040         default:
5041                 bfa_trc(diag, msg->mh.msg_id);
5042                 WARN_ON(1);
5043         }
5044 }
5045
5046 /*
5047  * Gen RAM Test
5048  *
5049  *   @param[in] *diag           - diag data struct
5050  *   @param[in] *memtest        - mem test params input from upper layer,
5051  *   @param[in] pattern         - mem test pattern
5052  *   @param[in] *result         - mem test result
5053  *   @param[in] cbfn            - mem test callback functioin
5054  *   @param[in] cbarg           - callback functioin arg
5055  *
5056  *   @param[out]
5057  */
5058 bfa_status_t
5059 bfa_diag_memtest(struct bfa_diag_s *diag, struct bfa_diag_memtest_s *memtest,
5060                 u32 pattern, struct bfa_diag_memtest_result *result,
5061                 bfa_cb_diag_t cbfn, void *cbarg)
5062 {
5063         u32     memtest_tov;
5064
5065         bfa_trc(diag, pattern);
5066
5067         if (!bfa_ioc_adapter_is_disabled(diag->ioc))
5068                 return BFA_STATUS_ADAPTER_ENABLED;
5069
5070         /* check to see if there is another destructive diag cmd running */
5071         if (diag->block) {
5072                 bfa_trc(diag, diag->block);
5073                 return BFA_STATUS_DEVBUSY;
5074         } else
5075                 diag->block = 1;
5076
5077         diag->result = result;
5078         diag->cbfn = cbfn;
5079         diag->cbarg = cbarg;
5080
5081         /* download memtest code and take LPU0 out of reset */
5082         bfa_ioc_boot(diag->ioc, BFI_FWBOOT_TYPE_MEMTEST, BFI_FWBOOT_ENV_OS);
5083
5084         memtest_tov = (bfa_ioc_asic_gen(diag->ioc) == BFI_ASIC_GEN_CT2) ?
5085                        CT2_BFA_DIAG_MEMTEST_TOV : BFA_DIAG_MEMTEST_TOV;
5086         bfa_timer_begin(diag->ioc->timer_mod, &diag->timer,
5087                         bfa_diag_memtest_done, diag, memtest_tov);
5088         diag->timer_active = 1;
5089         return BFA_STATUS_OK;
5090 }
5091
5092 /*
5093  * DIAG firmware ping command
5094  *
5095  *   @param[in] *diag           - diag data struct
5096  *   @param[in] cnt             - dma loop count for testing PCIE
5097  *   @param[in] data            - data pattern to pass in fw
5098  *   @param[in] *result         - pt to bfa_diag_fwping_result_t data struct
5099  *   @param[in] cbfn            - callback function
5100  *   @param[in] *cbarg          - callback functioin arg
5101  *
5102  *   @param[out]
5103  */
5104 bfa_status_t
5105 bfa_diag_fwping(struct bfa_diag_s *diag, u32 cnt, u32 data,
5106                 struct bfa_diag_results_fwping *result, bfa_cb_diag_t cbfn,
5107                 void *cbarg)
5108 {
5109         bfa_trc(diag, cnt);
5110         bfa_trc(diag, data);
5111
5112         if (!bfa_ioc_is_operational(diag->ioc))
5113                 return BFA_STATUS_IOC_NON_OP;
5114
5115         if (bfa_asic_id_ct2(bfa_ioc_devid((diag->ioc))) &&
5116             ((diag->ioc)->clscode == BFI_PCIFN_CLASS_ETH))
5117                 return BFA_STATUS_CMD_NOTSUPP;
5118
5119         /* check to see if there is another destructive diag cmd running */
5120         if (diag->block || diag->fwping.lock) {
5121                 bfa_trc(diag, diag->block);
5122                 bfa_trc(diag, diag->fwping.lock);
5123                 return BFA_STATUS_DEVBUSY;
5124         }
5125
5126         /* Initialization */
5127         diag->fwping.lock = 1;
5128         diag->fwping.cbfn = cbfn;
5129         diag->fwping.cbarg = cbarg;
5130         diag->fwping.result = result;
5131         diag->fwping.data = data;
5132         diag->fwping.count = cnt;
5133
5134         /* Init test results */
5135         diag->fwping.result->data = 0;
5136         diag->fwping.result->status = BFA_STATUS_OK;
5137
5138         /* kick off the first ping */
5139         diag_fwping_send(diag);
5140         return BFA_STATUS_OK;
5141 }
5142
5143 /*
5144  * Read Temperature Sensor
5145  *
5146  *   @param[in] *diag           - diag data struct
5147  *   @param[in] *result         - pt to bfa_diag_temp_t data struct
5148  *   @param[in] cbfn            - callback function
5149  *   @param[in] *cbarg          - callback functioin arg
5150  *
5151  *   @param[out]
5152  */
5153 bfa_status_t
5154 bfa_diag_tsensor_query(struct bfa_diag_s *diag,
5155                 struct bfa_diag_results_tempsensor_s *result,
5156                 bfa_cb_diag_t cbfn, void *cbarg)
5157 {
5158         /* check to see if there is a destructive diag cmd running */
5159         if (diag->block || diag->tsensor.lock) {
5160                 bfa_trc(diag, diag->block);
5161                 bfa_trc(diag, diag->tsensor.lock);
5162                 return BFA_STATUS_DEVBUSY;
5163         }
5164
5165         if (!bfa_ioc_is_operational(diag->ioc))
5166                 return BFA_STATUS_IOC_NON_OP;
5167
5168         /* Init diag mod params */
5169         diag->tsensor.lock = 1;
5170         diag->tsensor.temp = result;
5171         diag->tsensor.cbfn = cbfn;
5172         diag->tsensor.cbarg = cbarg;
5173         diag->tsensor.status = BFA_STATUS_OK;
5174
5175         /* Send msg to fw */
5176         diag_tempsensor_send(diag);
5177
5178         return BFA_STATUS_OK;
5179 }
5180
5181 /*
5182  * LED Test command
5183  *
5184  *   @param[in] *diag           - diag data struct
5185  *   @param[in] *ledtest        - pt to ledtest data structure
5186  *
5187  *   @param[out]
5188  */
5189 bfa_status_t
5190 bfa_diag_ledtest(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest)
5191 {
5192         bfa_trc(diag, ledtest->cmd);
5193
5194         if (!bfa_ioc_is_operational(diag->ioc))
5195                 return BFA_STATUS_IOC_NON_OP;
5196
5197         if (diag->beacon.state)
5198                 return BFA_STATUS_BEACON_ON;
5199
5200         if (diag->ledtest.lock)
5201                 return BFA_STATUS_LEDTEST_OP;
5202
5203         /* Send msg to fw */
5204         diag->ledtest.lock = BFA_TRUE;
5205         diag_ledtest_send(diag, ledtest);
5206
5207         return BFA_STATUS_OK;
5208 }
5209
5210 /*
5211  * Port beaconing command
5212  *
5213  *   @param[in] *diag           - diag data struct
5214  *   @param[in] beacon          - port beaconing 1:ON   0:OFF
5215  *   @param[in] link_e2e_beacon - link beaconing 1:ON   0:OFF
5216  *   @param[in] sec             - beaconing duration in seconds
5217  *
5218  *   @param[out]
5219  */
5220 bfa_status_t
5221 bfa_diag_beacon_port(struct bfa_diag_s *diag, bfa_boolean_t beacon,
5222                 bfa_boolean_t link_e2e_beacon, uint32_t sec)
5223 {
5224         bfa_trc(diag, beacon);
5225         bfa_trc(diag, link_e2e_beacon);
5226         bfa_trc(diag, sec);
5227
5228         if (!bfa_ioc_is_operational(diag->ioc))
5229                 return BFA_STATUS_IOC_NON_OP;
5230
5231         if (diag->ledtest.lock)
5232                 return BFA_STATUS_LEDTEST_OP;
5233
5234         if (diag->beacon.state && beacon)       /* beacon alread on */
5235                 return BFA_STATUS_BEACON_ON;
5236
5237         diag->beacon.state      = beacon;
5238         diag->beacon.link_e2e   = link_e2e_beacon;
5239         if (diag->cbfn_beacon)
5240                 diag->cbfn_beacon(diag->dev, beacon, link_e2e_beacon);
5241
5242         /* Send msg to fw */
5243         diag_portbeacon_send(diag, beacon, sec);
5244
5245         return BFA_STATUS_OK;
5246 }
5247
5248 /*
5249  * Return DMA memory needed by diag module.
5250  */
5251 u32
5252 bfa_diag_meminfo(void)
5253 {
5254         return BFA_ROUNDUP(BFI_DIAG_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5255 }
5256
5257 /*
5258  *      Attach virtual and physical memory for Diag.
5259  */
5260 void
5261 bfa_diag_attach(struct bfa_diag_s *diag, struct bfa_ioc_s *ioc, void *dev,
5262         bfa_cb_diag_beacon_t cbfn_beacon, struct bfa_trc_mod_s *trcmod)
5263 {
5264         diag->dev = dev;
5265         diag->ioc = ioc;
5266         diag->trcmod = trcmod;
5267
5268         diag->block = 0;
5269         diag->cbfn = NULL;
5270         diag->cbarg = NULL;
5271         diag->result = NULL;
5272         diag->cbfn_beacon = cbfn_beacon;
5273
5274         bfa_ioc_mbox_regisr(diag->ioc, BFI_MC_DIAG, bfa_diag_intr, diag);
5275         bfa_q_qe_init(&diag->ioc_notify);
5276         bfa_ioc_notify_init(&diag->ioc_notify, bfa_diag_notify, diag);
5277         list_add_tail(&diag->ioc_notify.qe, &diag->ioc->notify_q);
5278 }
5279
5280 void
5281 bfa_diag_memclaim(struct bfa_diag_s *diag, u8 *dm_kva, u64 dm_pa)
5282 {
5283         diag->fwping.dbuf_kva = dm_kva;
5284         diag->fwping.dbuf_pa = dm_pa;
5285         memset(diag->fwping.dbuf_kva, 0, BFI_DIAG_DMA_BUF_SZ);
5286 }
5287
5288 /*
5289  *      PHY module specific
5290  */
5291 #define BFA_PHY_DMA_BUF_SZ      0x02000         /* 8k dma buffer */
5292 #define BFA_PHY_LOCK_STATUS     0x018878        /* phy semaphore status reg */
5293
5294 static void
5295 bfa_phy_ntoh32(u32 *obuf, u32 *ibuf, int sz)
5296 {
5297         int i, m = sz >> 2;
5298
5299         for (i = 0; i < m; i++)
5300                 obuf[i] = be32_to_cpu(ibuf[i]);
5301 }
5302
5303 static bfa_boolean_t
5304 bfa_phy_present(struct bfa_phy_s *phy)
5305 {
5306         return (phy->ioc->attr->card_type == BFA_MFG_TYPE_LIGHTNING);
5307 }
5308
5309 static void
5310 bfa_phy_notify(void *cbarg, enum bfa_ioc_event_e event)
5311 {
5312         struct bfa_phy_s *phy = cbarg;
5313
5314         bfa_trc(phy, event);
5315
5316         switch (event) {
5317         case BFA_IOC_E_DISABLED:
5318         case BFA_IOC_E_FAILED:
5319                 if (phy->op_busy) {
5320                         phy->status = BFA_STATUS_IOC_FAILURE;
5321                         phy->cbfn(phy->cbarg, phy->status);
5322                         phy->op_busy = 0;
5323                 }
5324                 break;
5325
5326         default:
5327                 break;
5328         }
5329 }
5330
5331 /*
5332  * Send phy attribute query request.
5333  *
5334  * @param[in] cbarg - callback argument
5335  */
5336 static void
5337 bfa_phy_query_send(void *cbarg)
5338 {
5339         struct bfa_phy_s *phy = cbarg;
5340         struct bfi_phy_query_req_s *msg =
5341                         (struct bfi_phy_query_req_s *) phy->mb.msg;
5342
5343         msg->instance = phy->instance;
5344         bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_QUERY_REQ,
5345                 bfa_ioc_portid(phy->ioc));
5346         bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_attr_s), phy->dbuf_pa);
5347         bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5348 }
5349
5350 /*
5351  * Send phy write request.
5352  *
5353  * @param[in] cbarg - callback argument
5354  */
5355 static void
5356 bfa_phy_write_send(void *cbarg)
5357 {
5358         struct bfa_phy_s *phy = cbarg;
5359         struct bfi_phy_write_req_s *msg =
5360                         (struct bfi_phy_write_req_s *) phy->mb.msg;
5361         u32     len;
5362         u16     *buf, *dbuf;
5363         int     i, sz;
5364
5365         msg->instance = phy->instance;
5366         msg->offset = cpu_to_be32(phy->addr_off + phy->offset);
5367         len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ?
5368                         phy->residue : BFA_PHY_DMA_BUF_SZ;
5369         msg->length = cpu_to_be32(len);
5370
5371         /* indicate if it's the last msg of the whole write operation */
5372         msg->last = (len == phy->residue) ? 1 : 0;
5373
5374         bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_WRITE_REQ,
5375                 bfa_ioc_portid(phy->ioc));
5376         bfa_alen_set(&msg->alen, len, phy->dbuf_pa);
5377
5378         buf = (u16 *) (phy->ubuf + phy->offset);
5379         dbuf = (u16 *)phy->dbuf_kva;
5380         sz = len >> 1;
5381         for (i = 0; i < sz; i++)
5382                 buf[i] = cpu_to_be16(dbuf[i]);
5383
5384         bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5385
5386         phy->residue -= len;
5387         phy->offset += len;
5388 }
5389
5390 /*
5391  * Send phy read request.
5392  *
5393  * @param[in] cbarg - callback argument
5394  */
5395 static void
5396 bfa_phy_read_send(void *cbarg)
5397 {
5398         struct bfa_phy_s *phy = cbarg;
5399         struct bfi_phy_read_req_s *msg =
5400                         (struct bfi_phy_read_req_s *) phy->mb.msg;
5401         u32     len;
5402
5403         msg->instance = phy->instance;
5404         msg->offset = cpu_to_be32(phy->addr_off + phy->offset);
5405         len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ?
5406                         phy->residue : BFA_PHY_DMA_BUF_SZ;
5407         msg->length = cpu_to_be32(len);
5408         bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_READ_REQ,
5409                 bfa_ioc_portid(phy->ioc));
5410         bfa_alen_set(&msg->alen, len, phy->dbuf_pa);
5411         bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5412 }
5413
5414 /*
5415  * Send phy stats request.
5416  *
5417  * @param[in] cbarg - callback argument
5418  */
5419 static void
5420 bfa_phy_stats_send(void *cbarg)
5421 {
5422         struct bfa_phy_s *phy = cbarg;
5423         struct bfi_phy_stats_req_s *msg =
5424                         (struct bfi_phy_stats_req_s *) phy->mb.msg;
5425
5426         msg->instance = phy->instance;
5427         bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_STATS_REQ,
5428                 bfa_ioc_portid(phy->ioc));
5429         bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_stats_s), phy->dbuf_pa);
5430         bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5431 }
5432
5433 /*
5434  * Flash memory info API.
5435  *
5436  * @param[in] mincfg - minimal cfg variable
5437  */
5438 u32
5439 bfa_phy_meminfo(bfa_boolean_t mincfg)
5440 {
5441         /* min driver doesn't need phy */
5442         if (mincfg)
5443                 return 0;
5444
5445         return BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5446 }
5447
5448 /*
5449  * Flash attach API.
5450  *
5451  * @param[in] phy - phy structure
5452  * @param[in] ioc  - ioc structure
5453  * @param[in] dev  - device structure
5454  * @param[in] trcmod - trace module
5455  * @param[in] logmod - log module
5456  */
5457 void
5458 bfa_phy_attach(struct bfa_phy_s *phy, struct bfa_ioc_s *ioc, void *dev,
5459                 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
5460 {
5461         phy->ioc = ioc;
5462         phy->trcmod = trcmod;
5463         phy->cbfn = NULL;
5464         phy->cbarg = NULL;
5465         phy->op_busy = 0;
5466
5467         bfa_ioc_mbox_regisr(phy->ioc, BFI_MC_PHY, bfa_phy_intr, phy);
5468         bfa_q_qe_init(&phy->ioc_notify);
5469         bfa_ioc_notify_init(&phy->ioc_notify, bfa_phy_notify, phy);
5470         list_add_tail(&phy->ioc_notify.qe, &phy->ioc->notify_q);
5471
5472         /* min driver doesn't need phy */
5473         if (mincfg) {
5474                 phy->dbuf_kva = NULL;
5475                 phy->dbuf_pa = 0;
5476         }
5477 }
5478
5479 /*
5480  * Claim memory for phy
5481  *
5482  * @param[in] phy - phy structure
5483  * @param[in] dm_kva - pointer to virtual memory address
5484  * @param[in] dm_pa - physical memory address
5485  * @param[in] mincfg - minimal cfg variable
5486  */
5487 void
5488 bfa_phy_memclaim(struct bfa_phy_s *phy, u8 *dm_kva, u64 dm_pa,
5489                 bfa_boolean_t mincfg)
5490 {
5491         if (mincfg)
5492                 return;
5493
5494         phy->dbuf_kva = dm_kva;
5495         phy->dbuf_pa = dm_pa;
5496         memset(phy->dbuf_kva, 0, BFA_PHY_DMA_BUF_SZ);
5497         dm_kva += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5498         dm_pa += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5499 }
5500
5501 bfa_boolean_t
5502 bfa_phy_busy(struct bfa_ioc_s *ioc)
5503 {
5504         void __iomem    *rb;
5505
5506         rb = bfa_ioc_bar0(ioc);
5507         return readl(rb + BFA_PHY_LOCK_STATUS);
5508 }
5509
5510 /*
5511  * Get phy attribute.
5512  *
5513  * @param[in] phy - phy structure
5514  * @param[in] attr - phy attribute structure
5515  * @param[in] cbfn - callback function
5516  * @param[in] cbarg - callback argument
5517  *
5518  * Return status.
5519  */
5520 bfa_status_t
5521 bfa_phy_get_attr(struct bfa_phy_s *phy, u8 instance,
5522                 struct bfa_phy_attr_s *attr, bfa_cb_phy_t cbfn, void *cbarg)
5523 {
5524         bfa_trc(phy, BFI_PHY_H2I_QUERY_REQ);
5525         bfa_trc(phy, instance);
5526
5527         if (!bfa_phy_present(phy))
5528                 return BFA_STATUS_PHY_NOT_PRESENT;
5529
5530         if (!bfa_ioc_is_operational(phy->ioc))
5531                 return BFA_STATUS_IOC_NON_OP;
5532
5533         if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5534                 bfa_trc(phy, phy->op_busy);
5535                 return BFA_STATUS_DEVBUSY;
5536         }
5537
5538         phy->op_busy = 1;
5539         phy->cbfn = cbfn;
5540         phy->cbarg = cbarg;
5541         phy->instance = instance;
5542         phy->ubuf = (uint8_t *) attr;
5543         bfa_phy_query_send(phy);
5544
5545         return BFA_STATUS_OK;
5546 }
5547
5548 /*
5549  * Get phy stats.
5550  *
5551  * @param[in] phy - phy structure
5552  * @param[in] instance - phy image instance
5553  * @param[in] stats - pointer to phy stats
5554  * @param[in] cbfn - callback function
5555  * @param[in] cbarg - callback argument
5556  *
5557  * Return status.
5558  */
5559 bfa_status_t
5560 bfa_phy_get_stats(struct bfa_phy_s *phy, u8 instance,
5561                 struct bfa_phy_stats_s *stats,
5562                 bfa_cb_phy_t cbfn, void *cbarg)
5563 {
5564         bfa_trc(phy, BFI_PHY_H2I_STATS_REQ);
5565         bfa_trc(phy, instance);
5566
5567         if (!bfa_phy_present(phy))
5568                 return BFA_STATUS_PHY_NOT_PRESENT;
5569
5570         if (!bfa_ioc_is_operational(phy->ioc))
5571                 return BFA_STATUS_IOC_NON_OP;
5572
5573         if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5574                 bfa_trc(phy, phy->op_busy);
5575                 return BFA_STATUS_DEVBUSY;
5576         }
5577
5578         phy->op_busy = 1;
5579         phy->cbfn = cbfn;
5580         phy->cbarg = cbarg;
5581         phy->instance = instance;
5582         phy->ubuf = (u8 *) stats;
5583         bfa_phy_stats_send(phy);
5584
5585         return BFA_STATUS_OK;
5586 }
5587
5588 /*
5589  * Update phy image.
5590  *
5591  * @param[in] phy - phy structure
5592  * @param[in] instance - phy image instance
5593  * @param[in] buf - update data buffer
5594  * @param[in] len - data buffer length
5595  * @param[in] offset - offset relative to starting address
5596  * @param[in] cbfn - callback function
5597  * @param[in] cbarg - callback argument
5598  *
5599  * Return status.
5600  */
5601 bfa_status_t
5602 bfa_phy_update(struct bfa_phy_s *phy, u8 instance,
5603                 void *buf, u32 len, u32 offset,
5604                 bfa_cb_phy_t cbfn, void *cbarg)
5605 {
5606         bfa_trc(phy, BFI_PHY_H2I_WRITE_REQ);
5607         bfa_trc(phy, instance);
5608         bfa_trc(phy, len);
5609         bfa_trc(phy, offset);
5610
5611         if (!bfa_phy_present(phy))
5612                 return BFA_STATUS_PHY_NOT_PRESENT;
5613
5614         if (!bfa_ioc_is_operational(phy->ioc))
5615                 return BFA_STATUS_IOC_NON_OP;
5616
5617         /* 'len' must be in word (4-byte) boundary */
5618         if (!len || (len & 0x03))
5619                 return BFA_STATUS_FAILED;
5620
5621         if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5622                 bfa_trc(phy, phy->op_busy);
5623                 return BFA_STATUS_DEVBUSY;
5624         }
5625
5626         phy->op_busy = 1;
5627         phy->cbfn = cbfn;
5628         phy->cbarg = cbarg;
5629         phy->instance = instance;
5630         phy->residue = len;
5631         phy->offset = 0;
5632         phy->addr_off = offset;
5633         phy->ubuf = buf;
5634
5635         bfa_phy_write_send(phy);
5636         return BFA_STATUS_OK;
5637 }
5638
5639 /*
5640  * Read phy image.
5641  *
5642  * @param[in] phy - phy structure
5643  * @param[in] instance - phy image instance
5644  * @param[in] buf - read data buffer
5645  * @param[in] len - data buffer length
5646  * @param[in] offset - offset relative to starting address
5647  * @param[in] cbfn - callback function
5648  * @param[in] cbarg - callback argument
5649  *
5650  * Return status.
5651  */
5652 bfa_status_t
5653 bfa_phy_read(struct bfa_phy_s *phy, u8 instance,
5654                 void *buf, u32 len, u32 offset,
5655                 bfa_cb_phy_t cbfn, void *cbarg)
5656 {
5657         bfa_trc(phy, BFI_PHY_H2I_READ_REQ);
5658         bfa_trc(phy, instance);
5659         bfa_trc(phy, len);
5660         bfa_trc(phy, offset);
5661
5662         if (!bfa_phy_present(phy))
5663                 return BFA_STATUS_PHY_NOT_PRESENT;
5664
5665         if (!bfa_ioc_is_operational(phy->ioc))
5666                 return BFA_STATUS_IOC_NON_OP;
5667
5668         /* 'len' must be in word (4-byte) boundary */
5669         if (!len || (len & 0x03))
5670                 return BFA_STATUS_FAILED;
5671
5672         if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5673                 bfa_trc(phy, phy->op_busy);
5674                 return BFA_STATUS_DEVBUSY;
5675         }
5676
5677         phy->op_busy = 1;
5678         phy->cbfn = cbfn;
5679         phy->cbarg = cbarg;
5680         phy->instance = instance;
5681         phy->residue = len;
5682         phy->offset = 0;
5683         phy->addr_off = offset;
5684         phy->ubuf = buf;
5685         bfa_phy_read_send(phy);
5686
5687         return BFA_STATUS_OK;
5688 }
5689
5690 /*
5691  * Process phy response messages upon receiving interrupts.
5692  *
5693  * @param[in] phyarg - phy structure
5694  * @param[in] msg - message structure
5695  */
5696 void
5697 bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg)
5698 {
5699         struct bfa_phy_s *phy = phyarg;
5700         u32     status;
5701
5702         union {
5703                 struct bfi_phy_query_rsp_s *query;
5704                 struct bfi_phy_stats_rsp_s *stats;
5705                 struct bfi_phy_write_rsp_s *write;
5706                 struct bfi_phy_read_rsp_s *read;
5707                 struct bfi_mbmsg_s   *msg;
5708         } m;
5709
5710         m.msg = msg;
5711         bfa_trc(phy, msg->mh.msg_id);
5712
5713         if (!phy->op_busy) {
5714                 /* receiving response after ioc failure */
5715                 bfa_trc(phy, 0x9999);
5716                 return;
5717         }
5718
5719         switch (msg->mh.msg_id) {
5720         case BFI_PHY_I2H_QUERY_RSP:
5721                 status = be32_to_cpu(m.query->status);
5722                 bfa_trc(phy, status);
5723
5724                 if (status == BFA_STATUS_OK) {
5725                         struct bfa_phy_attr_s *attr =
5726                                 (struct bfa_phy_attr_s *) phy->ubuf;
5727                         bfa_phy_ntoh32((u32 *)attr, (u32 *)phy->dbuf_kva,
5728                                         sizeof(struct bfa_phy_attr_s));
5729                         bfa_trc(phy, attr->status);
5730                         bfa_trc(phy, attr->length);
5731                 }
5732
5733                 phy->status = status;
5734                 phy->op_busy = 0;
5735                 if (phy->cbfn)
5736                         phy->cbfn(phy->cbarg, phy->status);
5737                 break;
5738         case BFI_PHY_I2H_STATS_RSP:
5739                 status = be32_to_cpu(m.stats->status);
5740                 bfa_trc(phy, status);
5741
5742                 if (status == BFA_STATUS_OK) {
5743                         struct bfa_phy_stats_s *stats =
5744                                 (struct bfa_phy_stats_s *) phy->ubuf;
5745                         bfa_phy_ntoh32((u32 *)stats, (u32 *)phy->dbuf_kva,
5746                                 sizeof(struct bfa_phy_stats_s));
5747                         bfa_trc(phy, stats->status);
5748                 }
5749
5750                 phy->status = status;
5751                 phy->op_busy = 0;
5752                 if (phy->cbfn)
5753                         phy->cbfn(phy->cbarg, phy->status);
5754                 break;
5755         case BFI_PHY_I2H_WRITE_RSP:
5756                 status = be32_to_cpu(m.write->status);
5757                 bfa_trc(phy, status);
5758
5759                 if (status != BFA_STATUS_OK || phy->residue == 0) {
5760                         phy->status = status;
5761                         phy->op_busy = 0;
5762                         if (phy->cbfn)
5763                                 phy->cbfn(phy->cbarg, phy->status);
5764                 } else {
5765                         bfa_trc(phy, phy->offset);
5766                         bfa_phy_write_send(phy);
5767                 }
5768                 break;
5769         case BFI_PHY_I2H_READ_RSP:
5770                 status = be32_to_cpu(m.read->status);
5771                 bfa_trc(phy, status);
5772
5773                 if (status != BFA_STATUS_OK) {
5774                         phy->status = status;
5775                         phy->op_busy = 0;
5776                         if (phy->cbfn)
5777                                 phy->cbfn(phy->cbarg, phy->status);
5778                 } else {
5779                         u32 len = be32_to_cpu(m.read->length);
5780                         u16 *buf = (u16 *)(phy->ubuf + phy->offset);
5781                         u16 *dbuf = (u16 *)phy->dbuf_kva;
5782                         int i, sz = len >> 1;
5783
5784                         bfa_trc(phy, phy->offset);
5785                         bfa_trc(phy, len);
5786
5787                         for (i = 0; i < sz; i++)
5788                                 buf[i] = be16_to_cpu(dbuf[i]);
5789
5790                         phy->residue -= len;
5791                         phy->offset += len;
5792
5793                         if (phy->residue == 0) {
5794                                 phy->status = status;
5795                                 phy->op_busy = 0;
5796                                 if (phy->cbfn)
5797                                         phy->cbfn(phy->cbarg, phy->status);
5798                         } else
5799                                 bfa_phy_read_send(phy);
5800                 }
5801                 break;
5802         default:
5803                 WARN_ON(1);
5804         }
5805 }
5806
5807 /*
5808  * DCONF state machine events
5809  */
5810 enum bfa_dconf_event {
5811         BFA_DCONF_SM_INIT               = 1,    /* dconf Init */
5812         BFA_DCONF_SM_FLASH_COMP         = 2,    /* read/write to flash */
5813         BFA_DCONF_SM_WR                 = 3,    /* binding change, map */
5814         BFA_DCONF_SM_TIMEOUT            = 4,    /* Start timer */
5815         BFA_DCONF_SM_EXIT               = 5,    /* exit dconf module */
5816         BFA_DCONF_SM_IOCDISABLE         = 6,    /* IOC disable event */
5817 };
5818
5819 /* forward declaration of DCONF state machine */
5820 static void bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf,
5821                                 enum bfa_dconf_event event);
5822 static void bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
5823                                 enum bfa_dconf_event event);
5824 static void bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf,
5825                                 enum bfa_dconf_event event);
5826 static void bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf,
5827                                 enum bfa_dconf_event event);
5828 static void bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf,
5829                                 enum bfa_dconf_event event);
5830 static void bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf,
5831                                 enum bfa_dconf_event event);
5832 static void bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf,
5833                                 enum bfa_dconf_event event);
5834
5835 static void bfa_dconf_cbfn(void *dconf, bfa_status_t status);
5836 static void bfa_dconf_timer(void *cbarg);
5837 static bfa_status_t bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf);
5838 static void bfa_dconf_init_cb(void *arg, bfa_status_t status);
5839
5840 /*
5841  * Beginning state of dconf module. Waiting for an event to start.
5842  */
5843 static void
5844 bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5845 {
5846         bfa_status_t bfa_status;
5847         bfa_trc(dconf->bfa, event);
5848
5849         switch (event) {
5850         case BFA_DCONF_SM_INIT:
5851                 if (dconf->min_cfg) {
5852                         bfa_trc(dconf->bfa, dconf->min_cfg);
5853                         bfa_fsm_send_event(&dconf->bfa->iocfc,
5854                                         IOCFC_E_DCONF_DONE);
5855                         return;
5856                 }
5857                 bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read);
5858                 bfa_timer_start(dconf->bfa, &dconf->timer,
5859                         bfa_dconf_timer, dconf, 2 * BFA_DCONF_UPDATE_TOV);
5860                 bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa),
5861                                         BFA_FLASH_PART_DRV, dconf->instance,
5862                                         dconf->dconf,
5863                                         sizeof(struct bfa_dconf_s), 0,
5864                                         bfa_dconf_init_cb, dconf->bfa);
5865                 if (bfa_status != BFA_STATUS_OK) {
5866                         bfa_timer_stop(&dconf->timer);
5867                         bfa_dconf_init_cb(dconf->bfa, BFA_STATUS_FAILED);
5868                         bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5869                         return;
5870                 }
5871                 break;
5872         case BFA_DCONF_SM_EXIT:
5873                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5874         case BFA_DCONF_SM_IOCDISABLE:
5875         case BFA_DCONF_SM_WR:
5876         case BFA_DCONF_SM_FLASH_COMP:
5877                 break;
5878         default:
5879                 bfa_sm_fault(dconf->bfa, event);
5880         }
5881 }
5882
5883 /*
5884  * Read flash for dconf entries and make a call back to the driver once done.
5885  */
5886 static void
5887 bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
5888                         enum bfa_dconf_event event)
5889 {
5890         bfa_trc(dconf->bfa, event);
5891
5892         switch (event) {
5893         case BFA_DCONF_SM_FLASH_COMP:
5894                 bfa_timer_stop(&dconf->timer);
5895                 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5896                 break;
5897         case BFA_DCONF_SM_TIMEOUT:
5898                 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5899                 bfa_ioc_suspend(&dconf->bfa->ioc);
5900                 break;
5901         case BFA_DCONF_SM_EXIT:
5902                 bfa_timer_stop(&dconf->timer);
5903                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5904                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5905                 break;
5906         case BFA_DCONF_SM_IOCDISABLE:
5907                 bfa_timer_stop(&dconf->timer);
5908                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5909                 break;
5910         default:
5911                 bfa_sm_fault(dconf->bfa, event);
5912         }
5913 }
5914
5915 /*
5916  * DCONF Module is in ready state. Has completed the initialization.
5917  */
5918 static void
5919 bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5920 {
5921         bfa_trc(dconf->bfa, event);
5922
5923         switch (event) {
5924         case BFA_DCONF_SM_WR:
5925                 bfa_timer_start(dconf->bfa, &dconf->timer,
5926                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5927                 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
5928                 break;
5929         case BFA_DCONF_SM_EXIT:
5930                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5931                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5932                 break;
5933         case BFA_DCONF_SM_INIT:
5934         case BFA_DCONF_SM_IOCDISABLE:
5935                 break;
5936         default:
5937                 bfa_sm_fault(dconf->bfa, event);
5938         }
5939 }
5940
5941 /*
5942  * entries are dirty, write back to the flash.
5943  */
5944
5945 static void
5946 bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5947 {
5948         bfa_trc(dconf->bfa, event);
5949
5950         switch (event) {
5951         case BFA_DCONF_SM_TIMEOUT:
5952                 bfa_sm_set_state(dconf, bfa_dconf_sm_sync);
5953                 bfa_dconf_flash_write(dconf);
5954                 break;
5955         case BFA_DCONF_SM_WR:
5956                 bfa_timer_stop(&dconf->timer);
5957                 bfa_timer_start(dconf->bfa, &dconf->timer,
5958                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5959                 break;
5960         case BFA_DCONF_SM_EXIT:
5961                 bfa_timer_stop(&dconf->timer);
5962                 bfa_timer_start(dconf->bfa, &dconf->timer,
5963                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5964                 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync);
5965                 bfa_dconf_flash_write(dconf);
5966                 break;
5967         case BFA_DCONF_SM_FLASH_COMP:
5968                 break;
5969         case BFA_DCONF_SM_IOCDISABLE:
5970                 bfa_timer_stop(&dconf->timer);
5971                 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty);
5972                 break;
5973         default:
5974                 bfa_sm_fault(dconf->bfa, event);
5975         }
5976 }
5977
5978 /*
5979  * Sync the dconf entries to the flash.
5980  */
5981 static void
5982 bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf,
5983                         enum bfa_dconf_event event)
5984 {
5985         bfa_trc(dconf->bfa, event);
5986
5987         switch (event) {
5988         case BFA_DCONF_SM_IOCDISABLE:
5989         case BFA_DCONF_SM_FLASH_COMP:
5990                 bfa_timer_stop(&dconf->timer);
5991                 fallthrough;
5992         case BFA_DCONF_SM_TIMEOUT:
5993                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5994                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5995                 break;
5996         default:
5997                 bfa_sm_fault(dconf->bfa, event);
5998         }
5999 }
6000
6001 static void
6002 bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
6003 {
6004         bfa_trc(dconf->bfa, event);
6005
6006         switch (event) {
6007         case BFA_DCONF_SM_FLASH_COMP:
6008                 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
6009                 break;
6010         case BFA_DCONF_SM_WR:
6011                 bfa_timer_start(dconf->bfa, &dconf->timer,
6012                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6013                 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
6014                 break;
6015         case BFA_DCONF_SM_EXIT:
6016                 bfa_timer_start(dconf->bfa, &dconf->timer,
6017                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6018                 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync);
6019                 break;
6020         case BFA_DCONF_SM_IOCDISABLE:
6021                 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty);
6022                 break;
6023         default:
6024                 bfa_sm_fault(dconf->bfa, event);
6025         }
6026 }
6027
6028 static void
6029 bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf,
6030                         enum bfa_dconf_event event)
6031 {
6032         bfa_trc(dconf->bfa, event);
6033
6034         switch (event) {
6035         case BFA_DCONF_SM_INIT:
6036                 bfa_timer_start(dconf->bfa, &dconf->timer,
6037                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6038                 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
6039                 break;
6040         case BFA_DCONF_SM_EXIT:
6041                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
6042                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
6043                 break;
6044         case BFA_DCONF_SM_IOCDISABLE:
6045                 break;
6046         default:
6047                 bfa_sm_fault(dconf->bfa, event);
6048         }
6049 }
6050
6051 /*
6052  * Compute and return memory needed by DRV_CFG module.
6053  */
6054 void
6055 bfa_dconf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
6056                   struct bfa_s *bfa)
6057 {
6058         struct bfa_mem_kva_s *dconf_kva = BFA_MEM_DCONF_KVA(bfa);
6059
6060         if (cfg->drvcfg.min_cfg)
6061                 bfa_mem_kva_setup(meminfo, dconf_kva,
6062                                 sizeof(struct bfa_dconf_hdr_s));
6063         else
6064                 bfa_mem_kva_setup(meminfo, dconf_kva,
6065                                 sizeof(struct bfa_dconf_s));
6066 }
6067
6068 void
6069 bfa_dconf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg)
6070 {
6071         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6072
6073         dconf->bfad = bfad;
6074         dconf->bfa = bfa;
6075         dconf->instance = bfa->ioc.port_id;
6076         bfa_trc(bfa, dconf->instance);
6077
6078         dconf->dconf = (struct bfa_dconf_s *) bfa_mem_kva_curp(dconf);
6079         if (cfg->drvcfg.min_cfg) {
6080                 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_hdr_s);
6081                 dconf->min_cfg = BFA_TRUE;
6082         } else {
6083                 dconf->min_cfg = BFA_FALSE;
6084                 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_s);
6085         }
6086
6087         bfa_dconf_read_data_valid(bfa) = BFA_FALSE;
6088         bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
6089 }
6090
6091 static void
6092 bfa_dconf_init_cb(void *arg, bfa_status_t status)
6093 {
6094         struct bfa_s *bfa = arg;
6095         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6096
6097         if (status == BFA_STATUS_OK) {
6098                 bfa_dconf_read_data_valid(bfa) = BFA_TRUE;
6099                 if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE)
6100                         dconf->dconf->hdr.signature = BFI_DCONF_SIGNATURE;
6101                 if (dconf->dconf->hdr.version != BFI_DCONF_VERSION)
6102                         dconf->dconf->hdr.version = BFI_DCONF_VERSION;
6103         }
6104         bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
6105         bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE);
6106 }
6107
6108 void
6109 bfa_dconf_modinit(struct bfa_s *bfa)
6110 {
6111         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6112         bfa_sm_send_event(dconf, BFA_DCONF_SM_INIT);
6113 }
6114
6115 static void bfa_dconf_timer(void *cbarg)
6116 {
6117         struct bfa_dconf_mod_s *dconf = cbarg;
6118         bfa_sm_send_event(dconf, BFA_DCONF_SM_TIMEOUT);
6119 }
6120
6121 void
6122 bfa_dconf_iocdisable(struct bfa_s *bfa)
6123 {
6124         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6125         bfa_sm_send_event(dconf, BFA_DCONF_SM_IOCDISABLE);
6126 }
6127
6128 static bfa_status_t
6129 bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf)
6130 {
6131         bfa_status_t bfa_status;
6132         bfa_trc(dconf->bfa, 0);
6133
6134         bfa_status = bfa_flash_update_part(BFA_FLASH(dconf->bfa),
6135                                 BFA_FLASH_PART_DRV, dconf->instance,
6136                                 dconf->dconf,  sizeof(struct bfa_dconf_s), 0,
6137                                 bfa_dconf_cbfn, dconf);
6138         if (bfa_status != BFA_STATUS_OK)
6139                 WARN_ON(bfa_status);
6140         bfa_trc(dconf->bfa, bfa_status);
6141
6142         return bfa_status;
6143 }
6144
6145 bfa_status_t
6146 bfa_dconf_update(struct bfa_s *bfa)
6147 {
6148         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6149         bfa_trc(dconf->bfa, 0);
6150         if (bfa_sm_cmp_state(dconf, bfa_dconf_sm_iocdown_dirty))
6151                 return BFA_STATUS_FAILED;
6152
6153         if (dconf->min_cfg) {
6154                 bfa_trc(dconf->bfa, dconf->min_cfg);
6155                 return BFA_STATUS_FAILED;
6156         }
6157
6158         bfa_sm_send_event(dconf, BFA_DCONF_SM_WR);
6159         return BFA_STATUS_OK;
6160 }
6161
6162 static void
6163 bfa_dconf_cbfn(void *arg, bfa_status_t status)
6164 {
6165         struct bfa_dconf_mod_s *dconf = arg;
6166         WARN_ON(status);
6167         bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
6168 }
6169
6170 void
6171 bfa_dconf_modexit(struct bfa_s *bfa)
6172 {
6173         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6174         bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT);
6175 }
6176
6177 /*
6178  * FRU specific functions
6179  */
6180
6181 #define BFA_FRU_DMA_BUF_SZ      0x02000         /* 8k dma buffer */
6182 #define BFA_FRU_CHINOOK_MAX_SIZE 0x10000
6183 #define BFA_FRU_LIGHTNING_MAX_SIZE 0x200
6184
6185 static void
6186 bfa_fru_notify(void *cbarg, enum bfa_ioc_event_e event)
6187 {
6188         struct bfa_fru_s *fru = cbarg;
6189
6190         bfa_trc(fru, event);
6191
6192         switch (event) {
6193         case BFA_IOC_E_DISABLED:
6194         case BFA_IOC_E_FAILED:
6195                 if (fru->op_busy) {
6196                         fru->status = BFA_STATUS_IOC_FAILURE;
6197                         fru->cbfn(fru->cbarg, fru->status);
6198                         fru->op_busy = 0;
6199                 }
6200                 break;
6201
6202         default:
6203                 break;
6204         }
6205 }
6206
6207 /*
6208  * Send fru write request.
6209  *
6210  * @param[in] cbarg - callback argument
6211  */
6212 static void
6213 bfa_fru_write_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type)
6214 {
6215         struct bfa_fru_s *fru = cbarg;
6216         struct bfi_fru_write_req_s *msg =
6217                         (struct bfi_fru_write_req_s *) fru->mb.msg;
6218         u32 len;
6219
6220         msg->offset = cpu_to_be32(fru->addr_off + fru->offset);
6221         len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ?
6222                                 fru->residue : BFA_FRU_DMA_BUF_SZ;
6223         msg->length = cpu_to_be32(len);
6224
6225         /*
6226          * indicate if it's the last msg of the whole write operation
6227          */
6228         msg->last = (len == fru->residue) ? 1 : 0;
6229
6230         msg->trfr_cmpl = (len == fru->residue) ? fru->trfr_cmpl : 0;
6231         bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
6232         bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
6233
6234         memcpy(fru->dbuf_kva, fru->ubuf + fru->offset, len);
6235         bfa_ioc_mbox_queue(fru->ioc, &fru->mb);
6236
6237         fru->residue -= len;
6238         fru->offset += len;
6239 }
6240
6241 /*
6242  * Send fru read request.
6243  *
6244  * @param[in] cbarg - callback argument
6245  */
6246 static void
6247 bfa_fru_read_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type)
6248 {
6249         struct bfa_fru_s *fru = cbarg;
6250         struct bfi_fru_read_req_s *msg =
6251                         (struct bfi_fru_read_req_s *) fru->mb.msg;
6252         u32 len;
6253
6254         msg->offset = cpu_to_be32(fru->addr_off + fru->offset);
6255         len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ?
6256                                 fru->residue : BFA_FRU_DMA_BUF_SZ;
6257         msg->length = cpu_to_be32(len);
6258         bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
6259         bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
6260         bfa_ioc_mbox_queue(fru->ioc, &fru->mb);
6261 }
6262
6263 /*
6264  * Flash memory info API.
6265  *
6266  * @param[in] mincfg - minimal cfg variable
6267  */
6268 u32
6269 bfa_fru_meminfo(bfa_boolean_t mincfg)
6270 {
6271         /* min driver doesn't need fru */
6272         if (mincfg)
6273                 return 0;
6274
6275         return BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6276 }
6277
6278 /*
6279  * Flash attach API.
6280  *
6281  * @param[in] fru - fru structure
6282  * @param[in] ioc  - ioc structure
6283  * @param[in] dev  - device structure
6284  * @param[in] trcmod - trace module
6285  * @param[in] logmod - log module
6286  */
6287 void
6288 bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, void *dev,
6289         struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
6290 {
6291         fru->ioc = ioc;
6292         fru->trcmod = trcmod;
6293         fru->cbfn = NULL;
6294         fru->cbarg = NULL;
6295         fru->op_busy = 0;
6296
6297         bfa_ioc_mbox_regisr(fru->ioc, BFI_MC_FRU, bfa_fru_intr, fru);
6298         bfa_q_qe_init(&fru->ioc_notify);
6299         bfa_ioc_notify_init(&fru->ioc_notify, bfa_fru_notify, fru);
6300         list_add_tail(&fru->ioc_notify.qe, &fru->ioc->notify_q);
6301
6302         /* min driver doesn't need fru */
6303         if (mincfg) {
6304                 fru->dbuf_kva = NULL;
6305                 fru->dbuf_pa = 0;
6306         }
6307 }
6308
6309 /*
6310  * Claim memory for fru
6311  *
6312  * @param[in] fru - fru structure
6313  * @param[in] dm_kva - pointer to virtual memory address
6314  * @param[in] dm_pa - frusical memory address
6315  * @param[in] mincfg - minimal cfg variable
6316  */
6317 void
6318 bfa_fru_memclaim(struct bfa_fru_s *fru, u8 *dm_kva, u64 dm_pa,
6319         bfa_boolean_t mincfg)
6320 {
6321         if (mincfg)
6322                 return;
6323
6324         fru->dbuf_kva = dm_kva;
6325         fru->dbuf_pa = dm_pa;
6326         memset(fru->dbuf_kva, 0, BFA_FRU_DMA_BUF_SZ);
6327         dm_kva += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6328         dm_pa += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6329 }
6330
6331 /*
6332  * Update fru vpd image.
6333  *
6334  * @param[in] fru - fru structure
6335  * @param[in] buf - update data buffer
6336  * @param[in] len - data buffer length
6337  * @param[in] offset - offset relative to starting address
6338  * @param[in] cbfn - callback function
6339  * @param[in] cbarg - callback argument
6340  *
6341  * Return status.
6342  */
6343 bfa_status_t
6344 bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6345                   bfa_cb_fru_t cbfn, void *cbarg, u8 trfr_cmpl)
6346 {
6347         bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ);
6348         bfa_trc(fru, len);
6349         bfa_trc(fru, offset);
6350
6351         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2 &&
6352                 fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2)
6353                 return BFA_STATUS_FRU_NOT_PRESENT;
6354
6355         if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK)
6356                 return BFA_STATUS_CMD_NOTSUPP;
6357
6358         if (!bfa_ioc_is_operational(fru->ioc))
6359                 return BFA_STATUS_IOC_NON_OP;
6360
6361         if (fru->op_busy) {
6362                 bfa_trc(fru, fru->op_busy);
6363                 return BFA_STATUS_DEVBUSY;
6364         }
6365
6366         fru->op_busy = 1;
6367
6368         fru->cbfn = cbfn;
6369         fru->cbarg = cbarg;
6370         fru->residue = len;
6371         fru->offset = 0;
6372         fru->addr_off = offset;
6373         fru->ubuf = buf;
6374         fru->trfr_cmpl = trfr_cmpl;
6375
6376         bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ);
6377
6378         return BFA_STATUS_OK;
6379 }
6380
6381 /*
6382  * Read fru vpd image.
6383  *
6384  * @param[in] fru - fru structure
6385  * @param[in] buf - read data buffer
6386  * @param[in] len - data buffer length
6387  * @param[in] offset - offset relative to starting address
6388  * @param[in] cbfn - callback function
6389  * @param[in] cbarg - callback argument
6390  *
6391  * Return status.
6392  */
6393 bfa_status_t
6394 bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6395                 bfa_cb_fru_t cbfn, void *cbarg)
6396 {
6397         bfa_trc(fru, BFI_FRUVPD_H2I_READ_REQ);
6398         bfa_trc(fru, len);
6399         bfa_trc(fru, offset);
6400
6401         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6402                 return BFA_STATUS_FRU_NOT_PRESENT;
6403
6404         if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK &&
6405                 fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2)
6406                 return BFA_STATUS_CMD_NOTSUPP;
6407
6408         if (!bfa_ioc_is_operational(fru->ioc))
6409                 return BFA_STATUS_IOC_NON_OP;
6410
6411         if (fru->op_busy) {
6412                 bfa_trc(fru, fru->op_busy);
6413                 return BFA_STATUS_DEVBUSY;
6414         }
6415
6416         fru->op_busy = 1;
6417
6418         fru->cbfn = cbfn;
6419         fru->cbarg = cbarg;
6420         fru->residue = len;
6421         fru->offset = 0;
6422         fru->addr_off = offset;
6423         fru->ubuf = buf;
6424         bfa_fru_read_send(fru, BFI_FRUVPD_H2I_READ_REQ);
6425
6426         return BFA_STATUS_OK;
6427 }
6428
6429 /*
6430  * Get maximum size fru vpd image.
6431  *
6432  * @param[in] fru - fru structure
6433  * @param[out] size - maximum size of fru vpd data
6434  *
6435  * Return status.
6436  */
6437 bfa_status_t
6438 bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size)
6439 {
6440         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6441                 return BFA_STATUS_FRU_NOT_PRESENT;
6442
6443         if (!bfa_ioc_is_operational(fru->ioc))
6444                 return BFA_STATUS_IOC_NON_OP;
6445
6446         if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK ||
6447                 fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK2)
6448                 *max_size = BFA_FRU_CHINOOK_MAX_SIZE;
6449         else
6450                 return BFA_STATUS_CMD_NOTSUPP;
6451         return BFA_STATUS_OK;
6452 }
6453 /*
6454  * tfru write.
6455  *
6456  * @param[in] fru - fru structure
6457  * @param[in] buf - update data buffer
6458  * @param[in] len - data buffer length
6459  * @param[in] offset - offset relative to starting address
6460  * @param[in] cbfn - callback function
6461  * @param[in] cbarg - callback argument
6462  *
6463  * Return status.
6464  */
6465 bfa_status_t
6466 bfa_tfru_write(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6467                bfa_cb_fru_t cbfn, void *cbarg)
6468 {
6469         bfa_trc(fru, BFI_TFRU_H2I_WRITE_REQ);
6470         bfa_trc(fru, len);
6471         bfa_trc(fru, offset);
6472         bfa_trc(fru, *((u8 *) buf));
6473
6474         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6475                 return BFA_STATUS_FRU_NOT_PRESENT;
6476
6477         if (!bfa_ioc_is_operational(fru->ioc))
6478                 return BFA_STATUS_IOC_NON_OP;
6479
6480         if (fru->op_busy) {
6481                 bfa_trc(fru, fru->op_busy);
6482                 return BFA_STATUS_DEVBUSY;
6483         }
6484
6485         fru->op_busy = 1;
6486
6487         fru->cbfn = cbfn;
6488         fru->cbarg = cbarg;
6489         fru->residue = len;
6490         fru->offset = 0;
6491         fru->addr_off = offset;
6492         fru->ubuf = buf;
6493
6494         bfa_fru_write_send(fru, BFI_TFRU_H2I_WRITE_REQ);
6495
6496         return BFA_STATUS_OK;
6497 }
6498
6499 /*
6500  * tfru read.
6501  *
6502  * @param[in] fru - fru structure
6503  * @param[in] buf - read data buffer
6504  * @param[in] len - data buffer length
6505  * @param[in] offset - offset relative to starting address
6506  * @param[in] cbfn - callback function
6507  * @param[in] cbarg - callback argument
6508  *
6509  * Return status.
6510  */
6511 bfa_status_t
6512 bfa_tfru_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6513               bfa_cb_fru_t cbfn, void *cbarg)
6514 {
6515         bfa_trc(fru, BFI_TFRU_H2I_READ_REQ);
6516         bfa_trc(fru, len);
6517         bfa_trc(fru, offset);
6518
6519         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6520                 return BFA_STATUS_FRU_NOT_PRESENT;
6521
6522         if (!bfa_ioc_is_operational(fru->ioc))
6523                 return BFA_STATUS_IOC_NON_OP;
6524
6525         if (fru->op_busy) {
6526                 bfa_trc(fru, fru->op_busy);
6527                 return BFA_STATUS_DEVBUSY;
6528         }
6529
6530         fru->op_busy = 1;
6531
6532         fru->cbfn = cbfn;
6533         fru->cbarg = cbarg;
6534         fru->residue = len;
6535         fru->offset = 0;
6536         fru->addr_off = offset;
6537         fru->ubuf = buf;
6538         bfa_fru_read_send(fru, BFI_TFRU_H2I_READ_REQ);
6539
6540         return BFA_STATUS_OK;
6541 }
6542
6543 /*
6544  * Process fru response messages upon receiving interrupts.
6545  *
6546  * @param[in] fruarg - fru structure
6547  * @param[in] msg - message structure
6548  */
6549 void
6550 bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg)
6551 {
6552         struct bfa_fru_s *fru = fruarg;
6553         struct bfi_fru_rsp_s *rsp = (struct bfi_fru_rsp_s *)msg;
6554         u32 status;
6555
6556         bfa_trc(fru, msg->mh.msg_id);
6557
6558         if (!fru->op_busy) {
6559                 /*
6560                  * receiving response after ioc failure
6561                  */
6562                 bfa_trc(fru, 0x9999);
6563                 return;
6564         }
6565
6566         switch (msg->mh.msg_id) {
6567         case BFI_FRUVPD_I2H_WRITE_RSP:
6568         case BFI_TFRU_I2H_WRITE_RSP:
6569                 status = be32_to_cpu(rsp->status);
6570                 bfa_trc(fru, status);
6571
6572                 if (status != BFA_STATUS_OK || fru->residue == 0) {
6573                         fru->status = status;
6574                         fru->op_busy = 0;
6575                         if (fru->cbfn)
6576                                 fru->cbfn(fru->cbarg, fru->status);
6577                 } else {
6578                         bfa_trc(fru, fru->offset);
6579                         if (msg->mh.msg_id == BFI_FRUVPD_I2H_WRITE_RSP)
6580                                 bfa_fru_write_send(fru,
6581                                         BFI_FRUVPD_H2I_WRITE_REQ);
6582                         else
6583                                 bfa_fru_write_send(fru,
6584                                         BFI_TFRU_H2I_WRITE_REQ);
6585                 }
6586                 break;
6587         case BFI_FRUVPD_I2H_READ_RSP:
6588         case BFI_TFRU_I2H_READ_RSP:
6589                 status = be32_to_cpu(rsp->status);
6590                 bfa_trc(fru, status);
6591
6592                 if (status != BFA_STATUS_OK) {
6593                         fru->status = status;
6594                         fru->op_busy = 0;
6595                         if (fru->cbfn)
6596                                 fru->cbfn(fru->cbarg, fru->status);
6597                 } else {
6598                         u32 len = be32_to_cpu(rsp->length);
6599
6600                         bfa_trc(fru, fru->offset);
6601                         bfa_trc(fru, len);
6602
6603                         memcpy(fru->ubuf + fru->offset, fru->dbuf_kva, len);
6604                         fru->residue -= len;
6605                         fru->offset += len;
6606
6607                         if (fru->residue == 0) {
6608                                 fru->status = status;
6609                                 fru->op_busy = 0;
6610                                 if (fru->cbfn)
6611                                         fru->cbfn(fru->cbarg, fru->status);
6612                         } else {
6613                                 if (msg->mh.msg_id == BFI_FRUVPD_I2H_READ_RSP)
6614                                         bfa_fru_read_send(fru,
6615                                                 BFI_FRUVPD_H2I_READ_REQ);
6616                                 else
6617                                         bfa_fru_read_send(fru,
6618                                                 BFI_TFRU_H2I_READ_REQ);
6619                         }
6620                 }
6621                 break;
6622         default:
6623                 WARN_ON(1);
6624         }
6625 }
6626
6627 /*
6628  * register definitions
6629  */
6630 #define FLI_CMD_REG                     0x0001d000
6631 #define FLI_RDDATA_REG                  0x0001d010
6632 #define FLI_ADDR_REG                    0x0001d004
6633 #define FLI_DEV_STATUS_REG              0x0001d014
6634
6635 #define BFA_FLASH_FIFO_SIZE             128     /* fifo size */
6636 #define BFA_FLASH_CHECK_MAX             10000   /* max # of status check */
6637 #define BFA_FLASH_BLOCKING_OP_MAX       1000000 /* max # of blocking op check */
6638 #define BFA_FLASH_WIP_MASK              0x01    /* write in progress bit mask */
6639
6640 enum bfa_flash_cmd {
6641         BFA_FLASH_FAST_READ     = 0x0b, /* fast read */
6642         BFA_FLASH_READ_STATUS   = 0x05, /* read status */
6643 };
6644
6645 /*
6646  * Hardware error definition
6647  */
6648 enum bfa_flash_err {
6649         BFA_FLASH_NOT_PRESENT   = -1,   /*!< flash not present */
6650         BFA_FLASH_UNINIT        = -2,   /*!< flash not initialized */
6651         BFA_FLASH_BAD           = -3,   /*!< flash bad */
6652         BFA_FLASH_BUSY          = -4,   /*!< flash busy */
6653         BFA_FLASH_ERR_CMD_ACT   = -5,   /*!< command active never cleared */
6654         BFA_FLASH_ERR_FIFO_CNT  = -6,   /*!< fifo count never cleared */
6655         BFA_FLASH_ERR_WIP       = -7,   /*!< write-in-progress never cleared */
6656         BFA_FLASH_ERR_TIMEOUT   = -8,   /*!< fli timeout */
6657         BFA_FLASH_ERR_LEN       = -9,   /*!< invalid length */
6658 };
6659
6660 /*
6661  * Flash command register data structure
6662  */
6663 union bfa_flash_cmd_reg_u {
6664         struct {
6665 #ifdef __BIG_ENDIAN
6666                 u32     act:1;
6667                 u32     rsv:1;
6668                 u32     write_cnt:9;
6669                 u32     read_cnt:9;
6670                 u32     addr_cnt:4;
6671                 u32     cmd:8;
6672 #else
6673                 u32     cmd:8;
6674                 u32     addr_cnt:4;
6675                 u32     read_cnt:9;
6676                 u32     write_cnt:9;
6677                 u32     rsv:1;
6678                 u32     act:1;
6679 #endif
6680         } r;
6681         u32     i;
6682 };
6683
6684 /*
6685  * Flash device status register data structure
6686  */
6687 union bfa_flash_dev_status_reg_u {
6688         struct {
6689 #ifdef __BIG_ENDIAN
6690                 u32     rsv:21;
6691                 u32     fifo_cnt:6;
6692                 u32     busy:1;
6693                 u32     init_status:1;
6694                 u32     present:1;
6695                 u32     bad:1;
6696                 u32     good:1;
6697 #else
6698                 u32     good:1;
6699                 u32     bad:1;
6700                 u32     present:1;
6701                 u32     init_status:1;
6702                 u32     busy:1;
6703                 u32     fifo_cnt:6;
6704                 u32     rsv:21;
6705 #endif
6706         } r;
6707         u32     i;
6708 };
6709
6710 /*
6711  * Flash address register data structure
6712  */
6713 union bfa_flash_addr_reg_u {
6714         struct {
6715 #ifdef __BIG_ENDIAN
6716                 u32     addr:24;
6717                 u32     dummy:8;
6718 #else
6719                 u32     dummy:8;
6720                 u32     addr:24;
6721 #endif
6722         } r;
6723         u32     i;
6724 };
6725
6726 /*
6727  * dg flash_raw_private Flash raw private functions
6728  */
6729 static void
6730 bfa_flash_set_cmd(void __iomem *pci_bar, u8 wr_cnt,
6731                   u8 rd_cnt, u8 ad_cnt, u8 op)
6732 {
6733         union bfa_flash_cmd_reg_u cmd;
6734
6735         cmd.i = 0;
6736         cmd.r.act = 1;
6737         cmd.r.write_cnt = wr_cnt;
6738         cmd.r.read_cnt = rd_cnt;
6739         cmd.r.addr_cnt = ad_cnt;
6740         cmd.r.cmd = op;
6741         writel(cmd.i, (pci_bar + FLI_CMD_REG));
6742 }
6743
6744 static void
6745 bfa_flash_set_addr(void __iomem *pci_bar, u32 address)
6746 {
6747         union bfa_flash_addr_reg_u addr;
6748
6749         addr.r.addr = address & 0x00ffffff;
6750         addr.r.dummy = 0;
6751         writel(addr.i, (pci_bar + FLI_ADDR_REG));
6752 }
6753
6754 static int
6755 bfa_flash_cmd_act_check(void __iomem *pci_bar)
6756 {
6757         union bfa_flash_cmd_reg_u cmd;
6758
6759         cmd.i = readl(pci_bar + FLI_CMD_REG);
6760
6761         if (cmd.r.act)
6762                 return BFA_FLASH_ERR_CMD_ACT;
6763
6764         return 0;
6765 }
6766
6767 /*
6768  * @brief
6769  * Flush FLI data fifo.
6770  *
6771  * @param[in] pci_bar - pci bar address
6772  * @param[in] dev_status - device status
6773  *
6774  * Return 0 on success, negative error number on error.
6775  */
6776 static u32
6777 bfa_flash_fifo_flush(void __iomem *pci_bar)
6778 {
6779         u32 i;
6780         union bfa_flash_dev_status_reg_u dev_status;
6781
6782         dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6783
6784         if (!dev_status.r.fifo_cnt)
6785                 return 0;
6786
6787         /* fifo counter in terms of words */
6788         for (i = 0; i < dev_status.r.fifo_cnt; i++)
6789                 readl(pci_bar + FLI_RDDATA_REG);
6790
6791         /*
6792          * Check the device status. It may take some time.
6793          */
6794         for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
6795                 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6796                 if (!dev_status.r.fifo_cnt)
6797                         break;
6798         }
6799
6800         if (dev_status.r.fifo_cnt)
6801                 return BFA_FLASH_ERR_FIFO_CNT;
6802
6803         return 0;
6804 }
6805
6806 /*
6807  * @brief
6808  * Read flash status.
6809  *
6810  * @param[in] pci_bar - pci bar address
6811  *
6812  * Return 0 on success, negative error number on error.
6813 */
6814 static u32
6815 bfa_flash_status_read(void __iomem *pci_bar)
6816 {
6817         union bfa_flash_dev_status_reg_u        dev_status;
6818         int                             status;
6819         u32                     ret_status;
6820         int                             i;
6821
6822         status = bfa_flash_fifo_flush(pci_bar);
6823         if (status < 0)
6824                 return status;
6825
6826         bfa_flash_set_cmd(pci_bar, 0, 4, 0, BFA_FLASH_READ_STATUS);
6827
6828         for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
6829                 status = bfa_flash_cmd_act_check(pci_bar);
6830                 if (!status)
6831                         break;
6832         }
6833
6834         if (status)
6835                 return status;
6836
6837         dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6838         if (!dev_status.r.fifo_cnt)
6839                 return BFA_FLASH_BUSY;
6840
6841         ret_status = readl(pci_bar + FLI_RDDATA_REG);
6842         ret_status >>= 24;
6843
6844         status = bfa_flash_fifo_flush(pci_bar);
6845         if (status < 0)
6846                 return status;
6847
6848         return ret_status;
6849 }
6850
6851 /*
6852  * @brief
6853  * Start flash read operation.
6854  *
6855  * @param[in] pci_bar - pci bar address
6856  * @param[in] offset - flash address offset
6857  * @param[in] len - read data length
6858  * @param[in] buf - read data buffer
6859  *
6860  * Return 0 on success, negative error number on error.
6861  */
6862 static u32
6863 bfa_flash_read_start(void __iomem *pci_bar, u32 offset, u32 len,
6864                          char *buf)
6865 {
6866         int status;
6867
6868         /*
6869          * len must be mutiple of 4 and not exceeding fifo size
6870          */
6871         if (len == 0 || len > BFA_FLASH_FIFO_SIZE || (len & 0x03) != 0)
6872                 return BFA_FLASH_ERR_LEN;
6873
6874         /*
6875          * check status
6876          */
6877         status = bfa_flash_status_read(pci_bar);
6878         if (status == BFA_FLASH_BUSY)
6879                 status = bfa_flash_status_read(pci_bar);
6880
6881         if (status < 0)
6882                 return status;
6883
6884         /*
6885          * check if write-in-progress bit is cleared
6886          */
6887         if (status & BFA_FLASH_WIP_MASK)
6888                 return BFA_FLASH_ERR_WIP;
6889
6890         bfa_flash_set_addr(pci_bar, offset);
6891
6892         bfa_flash_set_cmd(pci_bar, 0, (u8)len, 4, BFA_FLASH_FAST_READ);
6893
6894         return 0;
6895 }
6896
6897 /*
6898  * @brief
6899  * Check flash read operation.
6900  *
6901  * @param[in] pci_bar - pci bar address
6902  *
6903  * Return flash device status, 1 if busy, 0 if not.
6904  */
6905 static u32
6906 bfa_flash_read_check(void __iomem *pci_bar)
6907 {
6908         if (bfa_flash_cmd_act_check(pci_bar))
6909                 return 1;
6910
6911         return 0;
6912 }
6913
6914 /*
6915  * @brief
6916  * End flash read operation.
6917  *
6918  * @param[in] pci_bar - pci bar address
6919  * @param[in] len - read data length
6920  * @param[in] buf - read data buffer
6921  *
6922  */
6923 static void
6924 bfa_flash_read_end(void __iomem *pci_bar, u32 len, char *buf)
6925 {
6926
6927         u32 i;
6928
6929         /*
6930          * read data fifo up to 32 words
6931          */
6932         for (i = 0; i < len; i += 4) {
6933                 u32 w = readl(pci_bar + FLI_RDDATA_REG);
6934                 *((u32 *) (buf + i)) = swab32(w);
6935         }
6936
6937         bfa_flash_fifo_flush(pci_bar);
6938 }
6939
6940 /*
6941  * @brief
6942  * Perform flash raw read.
6943  *
6944  * @param[in] pci_bar - pci bar address
6945  * @param[in] offset - flash partition address offset
6946  * @param[in] buf - read data buffer
6947  * @param[in] len - read data length
6948  *
6949  * Return status.
6950  */
6951
6952
6953 #define FLASH_BLOCKING_OP_MAX   500
6954 #define FLASH_SEM_LOCK_REG      0x18820
6955
6956 static int
6957 bfa_raw_sem_get(void __iomem *bar)
6958 {
6959         int     locked;
6960
6961         locked = readl((bar + FLASH_SEM_LOCK_REG));
6962         return !locked;
6963
6964 }
6965
6966 static bfa_status_t
6967 bfa_flash_sem_get(void __iomem *bar)
6968 {
6969         u32 n = FLASH_BLOCKING_OP_MAX;
6970
6971         while (!bfa_raw_sem_get(bar)) {
6972                 if (--n <= 0)
6973                         return BFA_STATUS_BADFLASH;
6974                 mdelay(10);
6975         }
6976         return BFA_STATUS_OK;
6977 }
6978
6979 static void
6980 bfa_flash_sem_put(void __iomem *bar)
6981 {
6982         writel(0, (bar + FLASH_SEM_LOCK_REG));
6983 }
6984
6985 bfa_status_t
6986 bfa_flash_raw_read(void __iomem *pci_bar, u32 offset, char *buf,
6987                        u32 len)
6988 {
6989         u32 n;
6990         int status;
6991         u32 off, l, s, residue, fifo_sz;
6992
6993         residue = len;
6994         off = 0;
6995         fifo_sz = BFA_FLASH_FIFO_SIZE;
6996         status = bfa_flash_sem_get(pci_bar);
6997         if (status != BFA_STATUS_OK)
6998                 return status;
6999
7000         while (residue) {
7001                 s = offset + off;
7002                 n = s / fifo_sz;
7003                 l = (n + 1) * fifo_sz - s;
7004                 if (l > residue)
7005                         l = residue;
7006
7007                 status = bfa_flash_read_start(pci_bar, offset + off, l,
7008                                                                 &buf[off]);
7009                 if (status < 0) {
7010                         bfa_flash_sem_put(pci_bar);
7011                         return BFA_STATUS_FAILED;
7012                 }
7013
7014                 n = BFA_FLASH_BLOCKING_OP_MAX;
7015                 while (bfa_flash_read_check(pci_bar)) {
7016                         if (--n <= 0) {
7017                                 bfa_flash_sem_put(pci_bar);
7018                                 return BFA_STATUS_FAILED;
7019                         }
7020                 }
7021
7022                 bfa_flash_read_end(pci_bar, l, &buf[off]);
7023
7024                 residue -= l;
7025                 off += l;
7026         }
7027         bfa_flash_sem_put(pci_bar);
7028
7029         return BFA_STATUS_OK;
7030 }