Merge tag 'trace-v6.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux...
[sfrench/cifs-2.6.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 bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event);
118 bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
119 bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
120 bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
121 bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
122 bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc_s, enum ioc_event);
123 bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event);
124 bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
125 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
126 bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc_s, enum ioc_event);
127
128 struct bfa_ioc_sm_table {
129         bfa_ioc_sm_t    sm;             /*  state machine function      */
130         enum bfa_ioc_state state;       /*  state machine encoding      */
131         char            *name;          /*  state name for display      */
132 };
133
134 static struct bfa_ioc_sm_table ioc_sm_table[] = {
135         {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
136         {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
137         {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING},
138         {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
139         {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
140         {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL},
141         {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
142         {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
143         {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
144         {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL},
145 };
146
147 static inline enum bfa_ioc_state
148 bfa_ioc_sm_to_state(struct bfa_ioc_sm_table *smt, bfa_ioc_sm_t sm)
149 {
150         int     i = 0;
151
152         while (smt[i].sm && smt[i].sm != sm)
153                 i++;
154         return smt[i].state;
155 }
156
157 /*
158  * IOCPF state machine definitions/declarations
159  */
160
161 #define bfa_iocpf_timer_start(__ioc)                                    \
162         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
163                         bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV)
164 #define bfa_iocpf_timer_stop(__ioc)     bfa_timer_stop(&(__ioc)->ioc_timer)
165
166 #define bfa_iocpf_poll_timer_start(__ioc)                               \
167         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer,        \
168                         bfa_iocpf_poll_timeout, (__ioc), BFA_IOC_POLL_TOV)
169
170 #define bfa_sem_timer_start(__ioc)                                      \
171         bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->sem_timer,        \
172                         bfa_iocpf_sem_timeout, (__ioc), BFA_IOC_HWSEM_TOV)
173 #define bfa_sem_timer_stop(__ioc)       bfa_timer_stop(&(__ioc)->sem_timer)
174
175 /*
176  * Forward declareations for iocpf state machine
177  */
178 static void bfa_iocpf_timeout(void *ioc_arg);
179 static void bfa_iocpf_sem_timeout(void *ioc_arg);
180 static void bfa_iocpf_poll_timeout(void *ioc_arg);
181
182 /*
183  * IOCPF states
184  */
185 enum bfa_iocpf_state {
186         BFA_IOCPF_RESET         = 1,    /*  IOC is in reset state */
187         BFA_IOCPF_SEMWAIT       = 2,    /*  Waiting for IOC h/w semaphore */
188         BFA_IOCPF_HWINIT        = 3,    /*  IOC h/w is being initialized */
189         BFA_IOCPF_READY         = 4,    /*  IOCPF is initialized */
190         BFA_IOCPF_INITFAIL      = 5,    /*  IOCPF failed */
191         BFA_IOCPF_FAIL          = 6,    /*  IOCPF failed */
192         BFA_IOCPF_DISABLING     = 7,    /*  IOCPF is being disabled */
193         BFA_IOCPF_DISABLED      = 8,    /*  IOCPF is disabled */
194         BFA_IOCPF_FWMISMATCH    = 9,    /*  IOC f/w different from drivers */
195 };
196
197 bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf_s, enum iocpf_event);
198 bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf_s, enum iocpf_event);
199 bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf_s, enum iocpf_event);
200 bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf_s, enum iocpf_event);
201 bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf_s, enum iocpf_event);
202 bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf_s, enum iocpf_event);
203 bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf_s, enum iocpf_event);
204 bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf_s,
205                                                 enum iocpf_event);
206 bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf_s, enum iocpf_event);
207 bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf_s, enum iocpf_event);
208 bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf_s, enum iocpf_event);
209 bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf_s, enum iocpf_event);
210 bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf_s,
211                                                 enum iocpf_event);
212 bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf_s, enum iocpf_event);
213
214 struct bfa_iocpf_sm_table {
215         bfa_iocpf_sm_t  sm;             /*  state machine function      */
216         enum bfa_iocpf_state state;     /*  state machine encoding      */
217         char            *name;          /*  state name for display      */
218 };
219
220 static inline enum bfa_iocpf_state
221 bfa_iocpf_sm_to_state(struct bfa_iocpf_sm_table *smt, bfa_iocpf_sm_t sm)
222 {
223         int     i = 0;
224
225         while (smt[i].sm && smt[i].sm != sm)
226                 i++;
227         return smt[i].state;
228 }
229
230 static struct bfa_iocpf_sm_table iocpf_sm_table[] = {
231         {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET},
232         {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH},
233         {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH},
234         {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT},
235         {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT},
236         {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT},
237         {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY},
238         {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL},
239         {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL},
240         {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL},
241         {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL},
242         {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING},
243         {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING},
244         {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED},
245 };
246
247 /*
248  * IOC State Machine
249  */
250
251 /*
252  * Beginning state. IOC uninit state.
253  */
254
255 static void
256 bfa_ioc_sm_uninit_entry(struct bfa_ioc_s *ioc)
257 {
258 }
259
260 /*
261  * IOC is in uninit state.
262  */
263 static void
264 bfa_ioc_sm_uninit(struct bfa_ioc_s *ioc, enum ioc_event event)
265 {
266         bfa_trc(ioc, event);
267
268         switch (event) {
269         case IOC_E_RESET:
270                 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
271                 break;
272
273         default:
274                 bfa_sm_fault(ioc, event);
275         }
276 }
277 /*
278  * Reset entry actions -- initialize state machine
279  */
280 static void
281 bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc)
282 {
283         bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset);
284 }
285
286 /*
287  * IOC is in reset state.
288  */
289 static void
290 bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event)
291 {
292         bfa_trc(ioc, event);
293
294         switch (event) {
295         case IOC_E_ENABLE:
296                 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
297                 break;
298
299         case IOC_E_DISABLE:
300                 bfa_ioc_disable_comp(ioc);
301                 break;
302
303         case IOC_E_DETACH:
304                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
305                 break;
306
307         default:
308                 bfa_sm_fault(ioc, event);
309         }
310 }
311
312
313 static void
314 bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
315 {
316         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE);
317 }
318
319 /*
320  * Host IOC function is being enabled, awaiting response from firmware.
321  * Semaphore is acquired.
322  */
323 static void
324 bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
325 {
326         bfa_trc(ioc, event);
327
328         switch (event) {
329         case IOC_E_ENABLED:
330                 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
331                 break;
332
333         case IOC_E_PFFAILED:
334                 /* !!! fall through !!! */
335         case IOC_E_HWERROR:
336                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
337                 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
338                 if (event != IOC_E_PFFAILED)
339                         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
340                 break;
341
342         case IOC_E_HWFAILED:
343                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
344                 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
345                 break;
346
347         case IOC_E_DISABLE:
348                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
349                 break;
350
351         case IOC_E_DETACH:
352                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
353                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
354                 break;
355
356         case IOC_E_ENABLE:
357                 break;
358
359         default:
360                 bfa_sm_fault(ioc, event);
361         }
362 }
363
364
365 static void
366 bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc)
367 {
368         bfa_ioc_timer_start(ioc);
369         bfa_ioc_send_getattr(ioc);
370 }
371
372 /*
373  * IOC configuration in progress. Timer is active.
374  */
375 static void
376 bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
377 {
378         bfa_trc(ioc, event);
379
380         switch (event) {
381         case IOC_E_FWRSP_GETATTR:
382                 bfa_ioc_timer_stop(ioc);
383                 bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
384                 break;
385
386         case IOC_E_PFFAILED:
387         case IOC_E_HWERROR:
388                 bfa_ioc_timer_stop(ioc);
389                 fallthrough;
390         case IOC_E_TIMEOUT:
391                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
392                 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
393                 if (event != IOC_E_PFFAILED)
394                         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
395                 break;
396
397         case IOC_E_DISABLE:
398                 bfa_ioc_timer_stop(ioc);
399                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
400                 break;
401
402         case IOC_E_ENABLE:
403                 break;
404
405         default:
406                 bfa_sm_fault(ioc, event);
407         }
408 }
409
410 static void
411 bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
412 {
413         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
414
415         ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
416         bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
417         bfa_ioc_hb_monitor(ioc);
418         BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
419         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE);
420 }
421
422 static void
423 bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
424 {
425         bfa_trc(ioc, event);
426
427         switch (event) {
428         case IOC_E_ENABLE:
429                 break;
430
431         case IOC_E_DISABLE:
432                 bfa_hb_timer_stop(ioc);
433                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
434                 break;
435
436         case IOC_E_PFFAILED:
437         case IOC_E_HWERROR:
438                 bfa_hb_timer_stop(ioc);
439                 fallthrough;
440         case IOC_E_HBFAIL:
441                 if (ioc->iocpf.auto_recover)
442                         bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
443                 else
444                         bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
445
446                 bfa_ioc_fail_notify(ioc);
447
448                 if (event != IOC_E_PFFAILED)
449                         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
450                 break;
451
452         default:
453                 bfa_sm_fault(ioc, event);
454         }
455 }
456
457
458 static void
459 bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
460 {
461         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
462         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
463         BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n");
464         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_DISABLE);
465 }
466
467 /*
468  * IOC is being disabled
469  */
470 static void
471 bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
472 {
473         bfa_trc(ioc, event);
474
475         switch (event) {
476         case IOC_E_DISABLED:
477                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
478                 break;
479
480         case IOC_E_HWERROR:
481                 /*
482                  * No state change.  Will move to disabled state
483                  * after iocpf sm completes failure processing and
484                  * moves to disabled state.
485                  */
486                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
487                 break;
488
489         case IOC_E_HWFAILED:
490                 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
491                 bfa_ioc_disable_comp(ioc);
492                 break;
493
494         default:
495                 bfa_sm_fault(ioc, event);
496         }
497 }
498
499 /*
500  * IOC disable completion entry.
501  */
502 static void
503 bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc)
504 {
505         bfa_ioc_disable_comp(ioc);
506 }
507
508 static void
509 bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
510 {
511         bfa_trc(ioc, event);
512
513         switch (event) {
514         case IOC_E_ENABLE:
515                 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
516                 break;
517
518         case IOC_E_DISABLE:
519                 ioc->cbfn->disable_cbfn(ioc->bfa);
520                 break;
521
522         case IOC_E_DETACH:
523                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
524                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
525                 break;
526
527         default:
528                 bfa_sm_fault(ioc, event);
529         }
530 }
531
532
533 static void
534 bfa_ioc_sm_fail_retry_entry(struct bfa_ioc_s *ioc)
535 {
536         bfa_trc(ioc, 0);
537 }
538
539 /*
540  * Hardware initialization retry.
541  */
542 static void
543 bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event)
544 {
545         bfa_trc(ioc, event);
546
547         switch (event) {
548         case IOC_E_ENABLED:
549                 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
550                 break;
551
552         case IOC_E_PFFAILED:
553         case IOC_E_HWERROR:
554                 /*
555                  * Initialization retry failed.
556                  */
557                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
558                 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
559                 if (event != IOC_E_PFFAILED)
560                         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
561                 break;
562
563         case IOC_E_HWFAILED:
564                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
565                 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
566                 break;
567
568         case IOC_E_ENABLE:
569                 break;
570
571         case IOC_E_DISABLE:
572                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
573                 break;
574
575         case IOC_E_DETACH:
576                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
577                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
578                 break;
579
580         default:
581                 bfa_sm_fault(ioc, event);
582         }
583 }
584
585
586 static void
587 bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc)
588 {
589         bfa_trc(ioc, 0);
590 }
591
592 /*
593  * IOC failure.
594  */
595 static void
596 bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
597 {
598         bfa_trc(ioc, event);
599
600         switch (event) {
601
602         case IOC_E_ENABLE:
603                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
604                 break;
605
606         case IOC_E_DISABLE:
607                 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
608                 break;
609
610         case IOC_E_DETACH:
611                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
612                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
613                 break;
614
615         case IOC_E_HWERROR:
616         case IOC_E_HWFAILED:
617                 /*
618                  * HB failure / HW error notification, ignore.
619                  */
620                 break;
621         default:
622                 bfa_sm_fault(ioc, event);
623         }
624 }
625
626 static void
627 bfa_ioc_sm_hwfail_entry(struct bfa_ioc_s *ioc)
628 {
629         bfa_trc(ioc, 0);
630 }
631
632 static void
633 bfa_ioc_sm_hwfail(struct bfa_ioc_s *ioc, enum ioc_event event)
634 {
635         bfa_trc(ioc, event);
636
637         switch (event) {
638         case IOC_E_ENABLE:
639                 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
640                 break;
641
642         case IOC_E_DISABLE:
643                 ioc->cbfn->disable_cbfn(ioc->bfa);
644                 break;
645
646         case IOC_E_DETACH:
647                 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
648                 break;
649
650         case IOC_E_HWERROR:
651                 /* Ignore - already in hwfail state */
652                 break;
653
654         default:
655                 bfa_sm_fault(ioc, event);
656         }
657 }
658
659 /*
660  * IOCPF State Machine
661  */
662
663 /*
664  * Reset entry actions -- initialize state machine
665  */
666 static void
667 bfa_iocpf_sm_reset_entry(struct bfa_iocpf_s *iocpf)
668 {
669         iocpf->fw_mismatch_notified = BFA_FALSE;
670         iocpf->auto_recover = bfa_auto_recover;
671 }
672
673 /*
674  * Beginning state. IOC is in reset state.
675  */
676 static void
677 bfa_iocpf_sm_reset(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
678 {
679         struct bfa_ioc_s *ioc = iocpf->ioc;
680
681         bfa_trc(ioc, event);
682
683         switch (event) {
684         case IOCPF_E_ENABLE:
685                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
686                 break;
687
688         case IOCPF_E_STOP:
689                 break;
690
691         default:
692                 bfa_sm_fault(ioc, event);
693         }
694 }
695
696 /*
697  * Semaphore should be acquired for version check.
698  */
699 static void
700 bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf)
701 {
702         struct bfi_ioc_image_hdr_s      fwhdr;
703         u32     r32, fwstate, pgnum, loff = 0;
704         int     i;
705
706         /*
707          * Spin on init semaphore to serialize.
708          */
709         r32 = readl(iocpf->ioc->ioc_regs.ioc_init_sem_reg);
710         while (r32 & 0x1) {
711                 udelay(20);
712                 r32 = readl(iocpf->ioc->ioc_regs.ioc_init_sem_reg);
713         }
714
715         /* h/w sem init */
716         fwstate = bfa_ioc_get_cur_ioc_fwstate(iocpf->ioc);
717         if (fwstate == BFI_IOC_UNINIT) {
718                 writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
719                 goto sem_get;
720         }
721
722         bfa_ioc_fwver_get(iocpf->ioc, &fwhdr);
723
724         if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) {
725                 writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
726                 goto sem_get;
727         }
728
729         /*
730          * Clear fwver hdr
731          */
732         pgnum = PSS_SMEM_PGNUM(iocpf->ioc->ioc_regs.smem_pg0, loff);
733         writel(pgnum, iocpf->ioc->ioc_regs.host_page_num_fn);
734
735         for (i = 0; i < sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32); i++) {
736                 bfa_mem_write(iocpf->ioc->ioc_regs.smem_page_start, loff, 0);
737                 loff += sizeof(u32);
738         }
739
740         bfa_trc(iocpf->ioc, fwstate);
741         bfa_trc(iocpf->ioc, swab32(fwhdr.exec));
742         bfa_ioc_set_cur_ioc_fwstate(iocpf->ioc, BFI_IOC_UNINIT);
743         bfa_ioc_set_alt_ioc_fwstate(iocpf->ioc, BFI_IOC_UNINIT);
744
745         /*
746          * Unlock the hw semaphore. Should be here only once per boot.
747          */
748         bfa_ioc_ownership_reset(iocpf->ioc);
749
750         /*
751          * unlock init semaphore.
752          */
753         writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
754
755 sem_get:
756         bfa_ioc_hw_sem_get(iocpf->ioc);
757 }
758
759 /*
760  * Awaiting h/w semaphore to continue with version check.
761  */
762 static void
763 bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
764 {
765         struct bfa_ioc_s *ioc = iocpf->ioc;
766
767         bfa_trc(ioc, event);
768
769         switch (event) {
770         case IOCPF_E_SEMLOCKED:
771                 if (bfa_ioc_firmware_lock(ioc)) {
772                         if (bfa_ioc_sync_start(ioc)) {
773                                 bfa_ioc_sync_join(ioc);
774                                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
775                         } else {
776                                 bfa_ioc_firmware_unlock(ioc);
777                                 writel(1, ioc->ioc_regs.ioc_sem_reg);
778                                 bfa_sem_timer_start(ioc);
779                         }
780                 } else {
781                         writel(1, ioc->ioc_regs.ioc_sem_reg);
782                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch);
783                 }
784                 break;
785
786         case IOCPF_E_SEM_ERROR:
787                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
788                 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
789                 break;
790
791         case IOCPF_E_DISABLE:
792                 bfa_sem_timer_stop(ioc);
793                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
794                 bfa_fsm_send_event(ioc, IOC_E_DISABLED);
795                 break;
796
797         case IOCPF_E_STOP:
798                 bfa_sem_timer_stop(ioc);
799                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
800                 break;
801
802         default:
803                 bfa_sm_fault(ioc, event);
804         }
805 }
806
807 /*
808  * Notify enable completion callback.
809  */
810 static void
811 bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf_s *iocpf)
812 {
813         /*
814          * Call only the first time sm enters fwmismatch state.
815          */
816         if (iocpf->fw_mismatch_notified == BFA_FALSE)
817                 bfa_ioc_pf_fwmismatch(iocpf->ioc);
818
819         iocpf->fw_mismatch_notified = BFA_TRUE;
820         bfa_iocpf_timer_start(iocpf->ioc);
821 }
822
823 /*
824  * Awaiting firmware version match.
825  */
826 static void
827 bfa_iocpf_sm_mismatch(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
828 {
829         struct bfa_ioc_s *ioc = iocpf->ioc;
830
831         bfa_trc(ioc, event);
832
833         switch (event) {
834         case IOCPF_E_TIMEOUT:
835                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
836                 break;
837
838         case IOCPF_E_DISABLE:
839                 bfa_iocpf_timer_stop(ioc);
840                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
841                 bfa_fsm_send_event(ioc, IOC_E_DISABLED);
842                 break;
843
844         case IOCPF_E_STOP:
845                 bfa_iocpf_timer_stop(ioc);
846                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
847                 break;
848
849         default:
850                 bfa_sm_fault(ioc, event);
851         }
852 }
853
854 /*
855  * Request for semaphore.
856  */
857 static void
858 bfa_iocpf_sm_semwait_entry(struct bfa_iocpf_s *iocpf)
859 {
860         bfa_ioc_hw_sem_get(iocpf->ioc);
861 }
862
863 /*
864  * Awaiting semaphore for h/w initialzation.
865  */
866 static void
867 bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
868 {
869         struct bfa_ioc_s *ioc = iocpf->ioc;
870
871         bfa_trc(ioc, event);
872
873         switch (event) {
874         case IOCPF_E_SEMLOCKED:
875                 if (bfa_ioc_sync_complete(ioc)) {
876                         bfa_ioc_sync_join(ioc);
877                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
878                 } else {
879                         writel(1, ioc->ioc_regs.ioc_sem_reg);
880                         bfa_sem_timer_start(ioc);
881                 }
882                 break;
883
884         case IOCPF_E_SEM_ERROR:
885                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
886                 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
887                 break;
888
889         case IOCPF_E_DISABLE:
890                 bfa_sem_timer_stop(ioc);
891                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
892                 break;
893
894         default:
895                 bfa_sm_fault(ioc, event);
896         }
897 }
898
899 static void
900 bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf)
901 {
902         iocpf->poll_time = 0;
903         bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE);
904 }
905
906 /*
907  * Hardware is being initialized. Interrupts are enabled.
908  * Holding hardware semaphore lock.
909  */
910 static void
911 bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
912 {
913         struct bfa_ioc_s *ioc = iocpf->ioc;
914
915         bfa_trc(ioc, event);
916
917         switch (event) {
918         case IOCPF_E_FWREADY:
919                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling);
920                 break;
921
922         case IOCPF_E_TIMEOUT:
923                 writel(1, ioc->ioc_regs.ioc_sem_reg);
924                 bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
925                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
926                 break;
927
928         case IOCPF_E_DISABLE:
929                 bfa_iocpf_timer_stop(ioc);
930                 bfa_ioc_sync_leave(ioc);
931                 writel(1, ioc->ioc_regs.ioc_sem_reg);
932                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
933                 break;
934
935         default:
936                 bfa_sm_fault(ioc, event);
937         }
938 }
939
940 static void
941 bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf)
942 {
943         bfa_iocpf_timer_start(iocpf->ioc);
944         /*
945          * Enable Interrupts before sending fw IOC ENABLE cmd.
946          */
947         iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa);
948         bfa_ioc_send_enable(iocpf->ioc);
949 }
950
951 /*
952  * Host IOC function is being enabled, awaiting response from firmware.
953  * Semaphore is acquired.
954  */
955 static void
956 bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
957 {
958         struct bfa_ioc_s *ioc = iocpf->ioc;
959
960         bfa_trc(ioc, event);
961
962         switch (event) {
963         case IOCPF_E_FWRSP_ENABLE:
964                 bfa_iocpf_timer_stop(ioc);
965                 writel(1, ioc->ioc_regs.ioc_sem_reg);
966                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready);
967                 break;
968
969         case IOCPF_E_INITFAIL:
970                 bfa_iocpf_timer_stop(ioc);
971                 fallthrough;
972
973         case IOCPF_E_TIMEOUT:
974                 writel(1, ioc->ioc_regs.ioc_sem_reg);
975                 if (event == IOCPF_E_TIMEOUT)
976                         bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
977                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
978                 break;
979
980         case IOCPF_E_DISABLE:
981                 bfa_iocpf_timer_stop(ioc);
982                 writel(1, ioc->ioc_regs.ioc_sem_reg);
983                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
984                 break;
985
986         default:
987                 bfa_sm_fault(ioc, event);
988         }
989 }
990
991 static void
992 bfa_iocpf_sm_ready_entry(struct bfa_iocpf_s *iocpf)
993 {
994         bfa_fsm_send_event(iocpf->ioc, IOC_E_ENABLED);
995 }
996
997 static void
998 bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
999 {
1000         struct bfa_ioc_s *ioc = iocpf->ioc;
1001
1002         bfa_trc(ioc, event);
1003
1004         switch (event) {
1005         case IOCPF_E_DISABLE:
1006                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
1007                 break;
1008
1009         case IOCPF_E_GETATTRFAIL:
1010                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
1011                 break;
1012
1013         case IOCPF_E_FAIL:
1014                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
1015                 break;
1016
1017         default:
1018                 bfa_sm_fault(ioc, event);
1019         }
1020 }
1021
1022 static void
1023 bfa_iocpf_sm_disabling_entry(struct bfa_iocpf_s *iocpf)
1024 {
1025         bfa_iocpf_timer_start(iocpf->ioc);
1026         bfa_ioc_send_disable(iocpf->ioc);
1027 }
1028
1029 /*
1030  * IOC is being disabled
1031  */
1032 static void
1033 bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1034 {
1035         struct bfa_ioc_s *ioc = iocpf->ioc;
1036
1037         bfa_trc(ioc, event);
1038
1039         switch (event) {
1040         case IOCPF_E_FWRSP_DISABLE:
1041                 bfa_iocpf_timer_stop(ioc);
1042                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1043                 break;
1044
1045         case IOCPF_E_FAIL:
1046                 bfa_iocpf_timer_stop(ioc);
1047                 fallthrough;
1048
1049         case IOCPF_E_TIMEOUT:
1050                 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
1051                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1052                 break;
1053
1054         case IOCPF_E_FWRSP_ENABLE:
1055                 break;
1056
1057         default:
1058                 bfa_sm_fault(ioc, event);
1059         }
1060 }
1061
1062 static void
1063 bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf_s *iocpf)
1064 {
1065         bfa_ioc_hw_sem_get(iocpf->ioc);
1066 }
1067
1068 /*
1069  * IOC hb ack request is being removed.
1070  */
1071 static void
1072 bfa_iocpf_sm_disabling_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1073 {
1074         struct bfa_ioc_s *ioc = iocpf->ioc;
1075
1076         bfa_trc(ioc, event);
1077
1078         switch (event) {
1079         case IOCPF_E_SEMLOCKED:
1080                 bfa_ioc_sync_leave(ioc);
1081                 writel(1, ioc->ioc_regs.ioc_sem_reg);
1082                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1083                 break;
1084
1085         case IOCPF_E_SEM_ERROR:
1086                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1087                 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1088                 break;
1089
1090         case IOCPF_E_FAIL:
1091                 break;
1092
1093         default:
1094                 bfa_sm_fault(ioc, event);
1095         }
1096 }
1097
1098 /*
1099  * IOC disable completion entry.
1100  */
1101 static void
1102 bfa_iocpf_sm_disabled_entry(struct bfa_iocpf_s *iocpf)
1103 {
1104         bfa_ioc_mbox_flush(iocpf->ioc);
1105         bfa_fsm_send_event(iocpf->ioc, IOC_E_DISABLED);
1106 }
1107
1108 static void
1109 bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1110 {
1111         struct bfa_ioc_s *ioc = iocpf->ioc;
1112
1113         bfa_trc(ioc, event);
1114
1115         switch (event) {
1116         case IOCPF_E_ENABLE:
1117                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
1118                 break;
1119
1120         case IOCPF_E_STOP:
1121                 bfa_ioc_firmware_unlock(ioc);
1122                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
1123                 break;
1124
1125         default:
1126                 bfa_sm_fault(ioc, event);
1127         }
1128 }
1129
1130 static void
1131 bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf)
1132 {
1133         bfa_ioc_debug_save_ftrc(iocpf->ioc);
1134         bfa_ioc_hw_sem_get(iocpf->ioc);
1135 }
1136
1137 /*
1138  * Hardware initialization failed.
1139  */
1140 static void
1141 bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1142 {
1143         struct bfa_ioc_s *ioc = iocpf->ioc;
1144
1145         bfa_trc(ioc, event);
1146
1147         switch (event) {
1148         case IOCPF_E_SEMLOCKED:
1149                 bfa_ioc_notify_fail(ioc);
1150                 bfa_ioc_sync_leave(ioc);
1151                 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
1152                 writel(1, ioc->ioc_regs.ioc_sem_reg);
1153                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
1154                 break;
1155
1156         case IOCPF_E_SEM_ERROR:
1157                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1158                 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1159                 break;
1160
1161         case IOCPF_E_DISABLE:
1162                 bfa_sem_timer_stop(ioc);
1163                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1164                 break;
1165
1166         case IOCPF_E_STOP:
1167                 bfa_sem_timer_stop(ioc);
1168                 bfa_ioc_firmware_unlock(ioc);
1169                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
1170                 break;
1171
1172         case IOCPF_E_FAIL:
1173                 break;
1174
1175         default:
1176                 bfa_sm_fault(ioc, event);
1177         }
1178 }
1179
1180 static void
1181 bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf)
1182 {
1183         bfa_trc(iocpf->ioc, 0);
1184 }
1185
1186 /*
1187  * Hardware initialization failed.
1188  */
1189 static void
1190 bfa_iocpf_sm_initfail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1191 {
1192         struct bfa_ioc_s *ioc = iocpf->ioc;
1193
1194         bfa_trc(ioc, event);
1195
1196         switch (event) {
1197         case IOCPF_E_DISABLE:
1198                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1199                 break;
1200
1201         case IOCPF_E_STOP:
1202                 bfa_ioc_firmware_unlock(ioc);
1203                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
1204                 break;
1205
1206         default:
1207                 bfa_sm_fault(ioc, event);
1208         }
1209 }
1210
1211 static void
1212 bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf_s *iocpf)
1213 {
1214         /*
1215          * Mark IOC as failed in hardware and stop firmware.
1216          */
1217         bfa_ioc_lpu_stop(iocpf->ioc);
1218
1219         /*
1220          * Flush any queued up mailbox requests.
1221          */
1222         bfa_ioc_mbox_flush(iocpf->ioc);
1223
1224         bfa_ioc_hw_sem_get(iocpf->ioc);
1225 }
1226
1227 static void
1228 bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1229 {
1230         struct bfa_ioc_s *ioc = iocpf->ioc;
1231
1232         bfa_trc(ioc, event);
1233
1234         switch (event) {
1235         case IOCPF_E_SEMLOCKED:
1236                 bfa_ioc_sync_ack(ioc);
1237                 bfa_ioc_notify_fail(ioc);
1238                 if (!iocpf->auto_recover) {
1239                         bfa_ioc_sync_leave(ioc);
1240                         bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
1241                         writel(1, ioc->ioc_regs.ioc_sem_reg);
1242                         bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1243                 } else {
1244                         if (bfa_ioc_sync_complete(ioc))
1245                                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
1246                         else {
1247                                 writel(1, ioc->ioc_regs.ioc_sem_reg);
1248                                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
1249                         }
1250                 }
1251                 break;
1252
1253         case IOCPF_E_SEM_ERROR:
1254                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1255                 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1256                 break;
1257
1258         case IOCPF_E_DISABLE:
1259                 bfa_sem_timer_stop(ioc);
1260                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1261                 break;
1262
1263         case IOCPF_E_FAIL:
1264                 break;
1265
1266         default:
1267                 bfa_sm_fault(ioc, event);
1268         }
1269 }
1270
1271 static void
1272 bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
1273 {
1274         bfa_trc(iocpf->ioc, 0);
1275 }
1276
1277 /*
1278  * IOC is in failed state.
1279  */
1280 static void
1281 bfa_iocpf_sm_fail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1282 {
1283         struct bfa_ioc_s *ioc = iocpf->ioc;
1284
1285         bfa_trc(ioc, event);
1286
1287         switch (event) {
1288         case IOCPF_E_DISABLE:
1289                 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1290                 break;
1291
1292         default:
1293                 bfa_sm_fault(ioc, event);
1294         }
1295 }
1296
1297 /*
1298  *  BFA IOC private functions
1299  */
1300
1301 /*
1302  * Notify common modules registered for notification.
1303  */
1304 static void
1305 bfa_ioc_event_notify(struct bfa_ioc_s *ioc, enum bfa_ioc_event_e event)
1306 {
1307         struct bfa_ioc_notify_s *notify;
1308         struct list_head        *qe;
1309
1310         list_for_each(qe, &ioc->notify_q) {
1311                 notify = (struct bfa_ioc_notify_s *)qe;
1312                 notify->cbfn(notify->cbarg, event);
1313         }
1314 }
1315
1316 static void
1317 bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
1318 {
1319         ioc->cbfn->disable_cbfn(ioc->bfa);
1320         bfa_ioc_event_notify(ioc, BFA_IOC_E_DISABLED);
1321 }
1322
1323 bfa_boolean_t
1324 bfa_ioc_sem_get(void __iomem *sem_reg)
1325 {
1326         u32 r32;
1327         int cnt = 0;
1328 #define BFA_SEM_SPINCNT 3000
1329
1330         r32 = readl(sem_reg);
1331
1332         while ((r32 & 1) && (cnt < BFA_SEM_SPINCNT)) {
1333                 cnt++;
1334                 udelay(2);
1335                 r32 = readl(sem_reg);
1336         }
1337
1338         if (!(r32 & 1))
1339                 return BFA_TRUE;
1340
1341         return BFA_FALSE;
1342 }
1343
1344 static void
1345 bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
1346 {
1347         u32     r32;
1348
1349         /*
1350          * First read to the semaphore register will return 0, subsequent reads
1351          * will return 1. Semaphore is released by writing 1 to the register
1352          */
1353         r32 = readl(ioc->ioc_regs.ioc_sem_reg);
1354         if (r32 == ~0) {
1355                 WARN_ON(r32 == ~0);
1356                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEM_ERROR);
1357                 return;
1358         }
1359         if (!(r32 & 1)) {
1360                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED);
1361                 return;
1362         }
1363
1364         bfa_sem_timer_start(ioc);
1365 }
1366
1367 /*
1368  * Initialize LPU local memory (aka secondary memory / SRAM)
1369  */
1370 static void
1371 bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
1372 {
1373         u32     pss_ctl;
1374         int             i;
1375 #define PSS_LMEM_INIT_TIME  10000
1376
1377         pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1378         pss_ctl &= ~__PSS_LMEM_RESET;
1379         pss_ctl |= __PSS_LMEM_INIT_EN;
1380
1381         /*
1382          * i2c workaround 12.5khz clock
1383          */
1384         pss_ctl |= __PSS_I2C_CLK_DIV(3UL);
1385         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1386
1387         /*
1388          * wait for memory initialization to be complete
1389          */
1390         i = 0;
1391         do {
1392                 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1393                 i++;
1394         } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
1395
1396         /*
1397          * If memory initialization is not successful, IOC timeout will catch
1398          * such failures.
1399          */
1400         WARN_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE));
1401         bfa_trc(ioc, pss_ctl);
1402
1403         pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
1404         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1405 }
1406
1407 static void
1408 bfa_ioc_lpu_start(struct bfa_ioc_s *ioc)
1409 {
1410         u32     pss_ctl;
1411
1412         /*
1413          * Take processor out of reset.
1414          */
1415         pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1416         pss_ctl &= ~__PSS_LPU0_RESET;
1417
1418         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1419 }
1420
1421 static void
1422 bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
1423 {
1424         u32     pss_ctl;
1425
1426         /*
1427          * Put processors in reset.
1428          */
1429         pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1430         pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
1431
1432         writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1433 }
1434
1435 /*
1436  * Get driver and firmware versions.
1437  */
1438 void
1439 bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
1440 {
1441         u32     pgnum;
1442         u32     loff = 0;
1443         int             i;
1444         u32     *fwsig = (u32 *) fwhdr;
1445
1446         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1447         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1448
1449         for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
1450              i++) {
1451                 fwsig[i] =
1452                         bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
1453                 loff += sizeof(u32);
1454         }
1455 }
1456
1457 /*
1458  * Returns TRUE if driver is willing to work with current smem f/w version.
1459  */
1460 bfa_boolean_t
1461 bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
1462                 struct bfi_ioc_image_hdr_s *smem_fwhdr)
1463 {
1464         struct bfi_ioc_image_hdr_s *drv_fwhdr;
1465         enum bfi_ioc_img_ver_cmp_e smem_flash_cmp, drv_smem_cmp;
1466
1467         drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
1468                 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
1469
1470         /*
1471          * If smem is incompatible or old, driver should not work with it.
1472          */
1473         drv_smem_cmp = bfa_ioc_fw_ver_patch_cmp(drv_fwhdr, smem_fwhdr);
1474         if (drv_smem_cmp == BFI_IOC_IMG_VER_INCOMP ||
1475                 drv_smem_cmp == BFI_IOC_IMG_VER_OLD) {
1476                 return BFA_FALSE;
1477         }
1478
1479         /*
1480          * IF Flash has a better F/W than smem do not work with smem.
1481          * If smem f/w == flash f/w, as smem f/w not old | incmp, work with it.
1482          * If Flash is old or incomp work with smem iff smem f/w == drv f/w.
1483          */
1484         smem_flash_cmp = bfa_ioc_flash_fwver_cmp(ioc, smem_fwhdr);
1485
1486         if (smem_flash_cmp == BFI_IOC_IMG_VER_BETTER) {
1487                 return BFA_FALSE;
1488         } else if (smem_flash_cmp == BFI_IOC_IMG_VER_SAME) {
1489                 return BFA_TRUE;
1490         } else {
1491                 return (drv_smem_cmp == BFI_IOC_IMG_VER_SAME) ?
1492                         BFA_TRUE : BFA_FALSE;
1493         }
1494 }
1495
1496 /*
1497  * Return true if current running version is valid. Firmware signature and
1498  * execution context (driver/bios) must match.
1499  */
1500 static bfa_boolean_t
1501 bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
1502 {
1503         struct bfi_ioc_image_hdr_s fwhdr;
1504
1505         bfa_ioc_fwver_get(ioc, &fwhdr);
1506
1507         if (swab32(fwhdr.bootenv) != boot_env) {
1508                 bfa_trc(ioc, fwhdr.bootenv);
1509                 bfa_trc(ioc, boot_env);
1510                 return BFA_FALSE;
1511         }
1512
1513         return bfa_ioc_fwver_cmp(ioc, &fwhdr);
1514 }
1515
1516 static bfa_boolean_t
1517 bfa_ioc_fwver_md5_check(struct bfi_ioc_image_hdr_s *fwhdr_1,
1518                                 struct bfi_ioc_image_hdr_s *fwhdr_2)
1519 {
1520         int i;
1521
1522         for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++)
1523                 if (fwhdr_1->md5sum[i] != fwhdr_2->md5sum[i])
1524                         return BFA_FALSE;
1525
1526         return BFA_TRUE;
1527 }
1528
1529 /*
1530  * Returns TRUE if major minor and maintainence are same.
1531  * If patch versions are same, check for MD5 Checksum to be same.
1532  */
1533 static bfa_boolean_t
1534 bfa_ioc_fw_ver_compatible(struct bfi_ioc_image_hdr_s *drv_fwhdr,
1535                                 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp)
1536 {
1537         if (drv_fwhdr->signature != fwhdr_to_cmp->signature)
1538                 return BFA_FALSE;
1539
1540         if (drv_fwhdr->fwver.major != fwhdr_to_cmp->fwver.major)
1541                 return BFA_FALSE;
1542
1543         if (drv_fwhdr->fwver.minor != fwhdr_to_cmp->fwver.minor)
1544                 return BFA_FALSE;
1545
1546         if (drv_fwhdr->fwver.maint != fwhdr_to_cmp->fwver.maint)
1547                 return BFA_FALSE;
1548
1549         if (drv_fwhdr->fwver.patch == fwhdr_to_cmp->fwver.patch &&
1550                 drv_fwhdr->fwver.phase == fwhdr_to_cmp->fwver.phase &&
1551                 drv_fwhdr->fwver.build == fwhdr_to_cmp->fwver.build) {
1552                 return bfa_ioc_fwver_md5_check(drv_fwhdr, fwhdr_to_cmp);
1553         }
1554
1555         return BFA_TRUE;
1556 }
1557
1558 static bfa_boolean_t
1559 bfa_ioc_flash_fwver_valid(struct bfi_ioc_image_hdr_s *flash_fwhdr)
1560 {
1561         if (flash_fwhdr->fwver.major == 0 || flash_fwhdr->fwver.major == 0xFF)
1562                 return BFA_FALSE;
1563
1564         return BFA_TRUE;
1565 }
1566
1567 static bfa_boolean_t fwhdr_is_ga(struct bfi_ioc_image_hdr_s *fwhdr)
1568 {
1569         if (fwhdr->fwver.phase == 0 &&
1570                 fwhdr->fwver.build == 0)
1571                 return BFA_TRUE;
1572
1573         return BFA_FALSE;
1574 }
1575
1576 /*
1577  * Returns TRUE if both are compatible and patch of fwhdr_to_cmp is better.
1578  */
1579 static enum bfi_ioc_img_ver_cmp_e
1580 bfa_ioc_fw_ver_patch_cmp(struct bfi_ioc_image_hdr_s *base_fwhdr,
1581                                 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp)
1582 {
1583         if (bfa_ioc_fw_ver_compatible(base_fwhdr, fwhdr_to_cmp) == BFA_FALSE)
1584                 return BFI_IOC_IMG_VER_INCOMP;
1585
1586         if (fwhdr_to_cmp->fwver.patch > base_fwhdr->fwver.patch)
1587                 return BFI_IOC_IMG_VER_BETTER;
1588
1589         else if (fwhdr_to_cmp->fwver.patch < base_fwhdr->fwver.patch)
1590                 return BFI_IOC_IMG_VER_OLD;
1591
1592         /*
1593          * GA takes priority over internal builds of the same patch stream.
1594          * At this point major minor maint and patch numbers are same.
1595          */
1596
1597         if (fwhdr_is_ga(base_fwhdr) == BFA_TRUE) {
1598                 if (fwhdr_is_ga(fwhdr_to_cmp))
1599                         return BFI_IOC_IMG_VER_SAME;
1600                 else
1601                         return BFI_IOC_IMG_VER_OLD;
1602         } else {
1603                 if (fwhdr_is_ga(fwhdr_to_cmp))
1604                         return BFI_IOC_IMG_VER_BETTER;
1605         }
1606
1607         if (fwhdr_to_cmp->fwver.phase > base_fwhdr->fwver.phase)
1608                 return BFI_IOC_IMG_VER_BETTER;
1609         else if (fwhdr_to_cmp->fwver.phase < base_fwhdr->fwver.phase)
1610                 return BFI_IOC_IMG_VER_OLD;
1611
1612         if (fwhdr_to_cmp->fwver.build > base_fwhdr->fwver.build)
1613                 return BFI_IOC_IMG_VER_BETTER;
1614         else if (fwhdr_to_cmp->fwver.build < base_fwhdr->fwver.build)
1615                 return BFI_IOC_IMG_VER_OLD;
1616
1617         /*
1618          * All Version Numbers are equal.
1619          * Md5 check to be done as a part of compatibility check.
1620          */
1621         return BFI_IOC_IMG_VER_SAME;
1622 }
1623
1624 #define BFA_FLASH_PART_FWIMG_ADDR       0x100000 /* fw image address */
1625
1626 bfa_status_t
1627 bfa_ioc_flash_img_get_chnk(struct bfa_ioc_s *ioc, u32 off,
1628                                 u32 *fwimg)
1629 {
1630         return bfa_flash_raw_read(ioc->pcidev.pci_bar_kva,
1631                         BFA_FLASH_PART_FWIMG_ADDR + (off * sizeof(u32)),
1632                         (char *)fwimg, BFI_FLASH_CHUNK_SZ);
1633 }
1634
1635 static enum bfi_ioc_img_ver_cmp_e
1636 bfa_ioc_flash_fwver_cmp(struct bfa_ioc_s *ioc,
1637                         struct bfi_ioc_image_hdr_s *base_fwhdr)
1638 {
1639         struct bfi_ioc_image_hdr_s *flash_fwhdr;
1640         bfa_status_t status;
1641         u32 fwimg[BFI_FLASH_CHUNK_SZ_WORDS];
1642
1643         status = bfa_ioc_flash_img_get_chnk(ioc, 0, fwimg);
1644         if (status != BFA_STATUS_OK)
1645                 return BFI_IOC_IMG_VER_INCOMP;
1646
1647         flash_fwhdr = (struct bfi_ioc_image_hdr_s *) fwimg;
1648         if (bfa_ioc_flash_fwver_valid(flash_fwhdr) == BFA_TRUE)
1649                 return bfa_ioc_fw_ver_patch_cmp(base_fwhdr, flash_fwhdr);
1650         else
1651                 return BFI_IOC_IMG_VER_INCOMP;
1652 }
1653
1654
1655 /*
1656  * Invalidate fwver signature
1657  */
1658 bfa_status_t
1659 bfa_ioc_fwsig_invalidate(struct bfa_ioc_s *ioc)
1660 {
1661
1662         u32     pgnum;
1663         u32     loff = 0;
1664         enum bfi_ioc_state ioc_fwstate;
1665
1666         ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
1667         if (!bfa_ioc_state_disabled(ioc_fwstate))
1668                 return BFA_STATUS_ADAPTER_ENABLED;
1669
1670         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1671         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1672         bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, BFA_IOC_FW_INV_SIGN);
1673
1674         return BFA_STATUS_OK;
1675 }
1676
1677 /*
1678  * Conditionally flush any pending message from firmware at start.
1679  */
1680 static void
1681 bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
1682 {
1683         u32     r32;
1684
1685         r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
1686         if (r32)
1687                 writel(1, ioc->ioc_regs.lpu_mbox_cmd);
1688 }
1689
1690 static void
1691 bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1692 {
1693         enum bfi_ioc_state ioc_fwstate;
1694         bfa_boolean_t fwvalid;
1695         u32 boot_type;
1696         u32 boot_env;
1697
1698         ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
1699
1700         if (force)
1701                 ioc_fwstate = BFI_IOC_UNINIT;
1702
1703         bfa_trc(ioc, ioc_fwstate);
1704
1705         boot_type = BFI_FWBOOT_TYPE_NORMAL;
1706         boot_env = BFI_FWBOOT_ENV_OS;
1707
1708         /*
1709          * check if firmware is valid
1710          */
1711         fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
1712                 BFA_FALSE : bfa_ioc_fwver_valid(ioc, boot_env);
1713
1714         if (!fwvalid) {
1715                 if (bfa_ioc_boot(ioc, boot_type, boot_env) == BFA_STATUS_OK)
1716                         bfa_ioc_poll_fwinit(ioc);
1717                 return;
1718         }
1719
1720         /*
1721          * If hardware initialization is in progress (initialized by other IOC),
1722          * just wait for an initialization completion interrupt.
1723          */
1724         if (ioc_fwstate == BFI_IOC_INITING) {
1725                 bfa_ioc_poll_fwinit(ioc);
1726                 return;
1727         }
1728
1729         /*
1730          * If IOC function is disabled and firmware version is same,
1731          * just re-enable IOC.
1732          *
1733          * If option rom, IOC must not be in operational state. With
1734          * convergence, IOC will be in operational state when 2nd driver
1735          * is loaded.
1736          */
1737         if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
1738
1739                 /*
1740                  * When using MSI-X any pending firmware ready event should
1741                  * be flushed. Otherwise MSI-X interrupts are not delivered.
1742                  */
1743                 bfa_ioc_msgflush(ioc);
1744                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
1745                 return;
1746         }
1747
1748         /*
1749          * Initialize the h/w for any other states.
1750          */
1751         if (bfa_ioc_boot(ioc, boot_type, boot_env) == BFA_STATUS_OK)
1752                 bfa_ioc_poll_fwinit(ioc);
1753 }
1754
1755 static void
1756 bfa_ioc_timeout(void *ioc_arg)
1757 {
1758         struct bfa_ioc_s  *ioc = (struct bfa_ioc_s *) ioc_arg;
1759
1760         bfa_trc(ioc, 0);
1761         bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
1762 }
1763
1764 void
1765 bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len)
1766 {
1767         u32 *msgp = (u32 *) ioc_msg;
1768         u32 i;
1769
1770         bfa_trc(ioc, msgp[0]);
1771         bfa_trc(ioc, len);
1772
1773         WARN_ON(len > BFI_IOC_MSGLEN_MAX);
1774
1775         /*
1776          * first write msg to mailbox registers
1777          */
1778         for (i = 0; i < len / sizeof(u32); i++)
1779                 writel(cpu_to_le32(msgp[i]),
1780                         ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
1781
1782         for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
1783                 writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
1784
1785         /*
1786          * write 1 to mailbox CMD to trigger LPU event
1787          */
1788         writel(1, ioc->ioc_regs.hfn_mbox_cmd);
1789         (void) readl(ioc->ioc_regs.hfn_mbox_cmd);
1790 }
1791
1792 static void
1793 bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
1794 {
1795         struct bfi_ioc_ctrl_req_s enable_req;
1796
1797         bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
1798                     bfa_ioc_portid(ioc));
1799         enable_req.clscode = cpu_to_be16(ioc->clscode);
1800         /* unsigned 32-bit time_t overflow in y2106 */
1801         enable_req.tv_sec = be32_to_cpu(ktime_get_real_seconds());
1802         bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1803 }
1804
1805 static void
1806 bfa_ioc_send_disable(struct bfa_ioc_s *ioc)
1807 {
1808         struct bfi_ioc_ctrl_req_s disable_req;
1809
1810         bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
1811                     bfa_ioc_portid(ioc));
1812         disable_req.clscode = cpu_to_be16(ioc->clscode);
1813         /* unsigned 32-bit time_t overflow in y2106 */
1814         disable_req.tv_sec = be32_to_cpu(ktime_get_real_seconds());
1815         bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1816 }
1817
1818 static void
1819 bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
1820 {
1821         struct bfi_ioc_getattr_req_s    attr_req;
1822
1823         bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
1824                     bfa_ioc_portid(ioc));
1825         bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
1826         bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
1827 }
1828
1829 static void
1830 bfa_ioc_hb_check(void *cbarg)
1831 {
1832         struct bfa_ioc_s  *ioc = cbarg;
1833         u32     hb_count;
1834
1835         hb_count = readl(ioc->ioc_regs.heartbeat);
1836         if (ioc->hb_count == hb_count) {
1837                 bfa_ioc_recover(ioc);
1838                 return;
1839         } else {
1840                 ioc->hb_count = hb_count;
1841         }
1842
1843         bfa_ioc_mbox_poll(ioc);
1844         bfa_hb_timer_start(ioc);
1845 }
1846
1847 static void
1848 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
1849 {
1850         ioc->hb_count = readl(ioc->ioc_regs.heartbeat);
1851         bfa_hb_timer_start(ioc);
1852 }
1853
1854 /*
1855  *      Initiate a full firmware download.
1856  */
1857 static bfa_status_t
1858 bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1859                     u32 boot_env)
1860 {
1861         u32 *fwimg;
1862         u32 pgnum;
1863         u32 loff = 0;
1864         u32 chunkno = 0;
1865         u32 i;
1866         u32 asicmode;
1867         u32 fwimg_size;
1868         u32 fwimg_buf[BFI_FLASH_CHUNK_SZ_WORDS];
1869         bfa_status_t status;
1870
1871         if (boot_env == BFI_FWBOOT_ENV_OS &&
1872                 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1873                 fwimg_size = BFI_FLASH_IMAGE_SZ/sizeof(u32);
1874
1875                 status = bfa_ioc_flash_img_get_chnk(ioc,
1876                         BFA_IOC_FLASH_CHUNK_ADDR(chunkno), fwimg_buf);
1877                 if (status != BFA_STATUS_OK)
1878                         return status;
1879
1880                 fwimg = fwimg_buf;
1881         } else {
1882                 fwimg_size = bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc));
1883                 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc),
1884                                         BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1885         }
1886
1887         bfa_trc(ioc, fwimg_size);
1888
1889
1890         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1891         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1892
1893         for (i = 0; i < fwimg_size; i++) {
1894
1895                 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
1896                         chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
1897
1898                         if (boot_env == BFI_FWBOOT_ENV_OS &&
1899                                 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1900                                 status = bfa_ioc_flash_img_get_chnk(ioc,
1901                                         BFA_IOC_FLASH_CHUNK_ADDR(chunkno),
1902                                         fwimg_buf);
1903                                 if (status != BFA_STATUS_OK)
1904                                         return status;
1905
1906                                 fwimg = fwimg_buf;
1907                         } else {
1908                                 fwimg = bfa_cb_image_get_chunk(
1909                                         bfa_ioc_asic_gen(ioc),
1910                                         BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1911                         }
1912                 }
1913
1914                 /*
1915                  * write smem
1916                  */
1917                 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
1918                               fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
1919
1920                 loff += sizeof(u32);
1921
1922                 /*
1923                  * handle page offset wrap around
1924                  */
1925                 loff = PSS_SMEM_PGOFF(loff);
1926                 if (loff == 0) {
1927                         pgnum++;
1928                         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1929                 }
1930         }
1931
1932         writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
1933                         ioc->ioc_regs.host_page_num_fn);
1934
1935         /*
1936          * Set boot type, env and device mode at the end.
1937          */
1938         if (boot_env == BFI_FWBOOT_ENV_OS &&
1939                 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1940                 boot_type = BFI_FWBOOT_TYPE_NORMAL;
1941         }
1942         asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode,
1943                                 ioc->port0_mode, ioc->port1_mode);
1944         bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_DEVMODE_OFF,
1945                         swab32(asicmode));
1946         bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_TYPE_OFF,
1947                         swab32(boot_type));
1948         bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_ENV_OFF,
1949                         swab32(boot_env));
1950         return BFA_STATUS_OK;
1951 }
1952
1953
1954 /*
1955  * Update BFA configuration from firmware configuration.
1956  */
1957 static void
1958 bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
1959 {
1960         struct bfi_ioc_attr_s   *attr = ioc->attr;
1961
1962         attr->adapter_prop  = be32_to_cpu(attr->adapter_prop);
1963         attr->card_type     = be32_to_cpu(attr->card_type);
1964         attr->maxfrsize     = be16_to_cpu(attr->maxfrsize);
1965         ioc->fcmode     = (attr->port_mode == BFI_PORT_MODE_FC);
1966         attr->mfg_year  = be16_to_cpu(attr->mfg_year);
1967
1968         bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
1969 }
1970
1971 /*
1972  * Attach time initialization of mbox logic.
1973  */
1974 static void
1975 bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc)
1976 {
1977         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
1978         int     mc;
1979
1980         INIT_LIST_HEAD(&mod->cmd_q);
1981         for (mc = 0; mc < BFI_MC_MAX; mc++) {
1982                 mod->mbhdlr[mc].cbfn = NULL;
1983                 mod->mbhdlr[mc].cbarg = ioc->bfa;
1984         }
1985 }
1986
1987 /*
1988  * Mbox poll timer -- restarts any pending mailbox requests.
1989  */
1990 static void
1991 bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc)
1992 {
1993         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
1994         struct bfa_mbox_cmd_s           *cmd;
1995         u32                     stat;
1996
1997         /*
1998          * If no command pending, do nothing
1999          */
2000         if (list_empty(&mod->cmd_q))
2001                 return;
2002
2003         /*
2004          * If previous command is not yet fetched by firmware, do nothing
2005          */
2006         stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
2007         if (stat)
2008                 return;
2009
2010         /*
2011          * Enqueue command to firmware.
2012          */
2013         bfa_q_deq(&mod->cmd_q, &cmd);
2014         bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
2015 }
2016
2017 /*
2018  * Cleanup any pending requests.
2019  */
2020 static void
2021 bfa_ioc_mbox_flush(struct bfa_ioc_s *ioc)
2022 {
2023         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2024         struct bfa_mbox_cmd_s           *cmd;
2025
2026         while (!list_empty(&mod->cmd_q))
2027                 bfa_q_deq(&mod->cmd_q, &cmd);
2028 }
2029
2030 /*
2031  * Read data from SMEM to host through PCI memmap
2032  *
2033  * @param[in]   ioc     memory for IOC
2034  * @param[in]   tbuf    app memory to store data from smem
2035  * @param[in]   soff    smem offset
2036  * @param[in]   sz      size of smem in bytes
2037  */
2038 static bfa_status_t
2039 bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
2040 {
2041         u32 pgnum, loff;
2042         __be32 r32;
2043         int i, len;
2044         u32 *buf = tbuf;
2045
2046         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
2047         loff = PSS_SMEM_PGOFF(soff);
2048         bfa_trc(ioc, pgnum);
2049         bfa_trc(ioc, loff);
2050         bfa_trc(ioc, sz);
2051
2052         /*
2053          *  Hold semaphore to serialize pll init and fwtrc.
2054          */
2055         if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) {
2056                 bfa_trc(ioc, 0);
2057                 return BFA_STATUS_FAILED;
2058         }
2059
2060         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2061
2062         len = sz/sizeof(u32);
2063         bfa_trc(ioc, len);
2064         for (i = 0; i < len; i++) {
2065                 r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
2066                 buf[i] = swab32(r32);
2067                 loff += sizeof(u32);
2068
2069                 /*
2070                  * handle page offset wrap around
2071                  */
2072                 loff = PSS_SMEM_PGOFF(loff);
2073                 if (loff == 0) {
2074                         pgnum++;
2075                         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2076                 }
2077         }
2078         writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
2079                         ioc->ioc_regs.host_page_num_fn);
2080         /*
2081          *  release semaphore.
2082          */
2083         readl(ioc->ioc_regs.ioc_init_sem_reg);
2084         writel(1, ioc->ioc_regs.ioc_init_sem_reg);
2085
2086         bfa_trc(ioc, pgnum);
2087         return BFA_STATUS_OK;
2088 }
2089
2090 /*
2091  * Clear SMEM data from host through PCI memmap
2092  *
2093  * @param[in]   ioc     memory for IOC
2094  * @param[in]   soff    smem offset
2095  * @param[in]   sz      size of smem in bytes
2096  */
2097 static bfa_status_t
2098 bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
2099 {
2100         int i, len;
2101         u32 pgnum, loff;
2102
2103         pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
2104         loff = PSS_SMEM_PGOFF(soff);
2105         bfa_trc(ioc, pgnum);
2106         bfa_trc(ioc, loff);
2107         bfa_trc(ioc, sz);
2108
2109         /*
2110          *  Hold semaphore to serialize pll init and fwtrc.
2111          */
2112         if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) {
2113                 bfa_trc(ioc, 0);
2114                 return BFA_STATUS_FAILED;
2115         }
2116
2117         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2118
2119         len = sz/sizeof(u32); /* len in words */
2120         bfa_trc(ioc, len);
2121         for (i = 0; i < len; i++) {
2122                 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 0);
2123                 loff += sizeof(u32);
2124
2125                 /*
2126                  * handle page offset wrap around
2127                  */
2128                 loff = PSS_SMEM_PGOFF(loff);
2129                 if (loff == 0) {
2130                         pgnum++;
2131                         writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2132                 }
2133         }
2134         writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
2135                         ioc->ioc_regs.host_page_num_fn);
2136
2137         /*
2138          *  release semaphore.
2139          */
2140         readl(ioc->ioc_regs.ioc_init_sem_reg);
2141         writel(1, ioc->ioc_regs.ioc_init_sem_reg);
2142         bfa_trc(ioc, pgnum);
2143         return BFA_STATUS_OK;
2144 }
2145
2146 static void
2147 bfa_ioc_fail_notify(struct bfa_ioc_s *ioc)
2148 {
2149         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
2150
2151         /*
2152          * Notify driver and common modules registered for notification.
2153          */
2154         ioc->cbfn->hbfail_cbfn(ioc->bfa);
2155         bfa_ioc_event_notify(ioc, BFA_IOC_E_FAILED);
2156
2157         bfa_ioc_debug_save_ftrc(ioc);
2158
2159         BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
2160                 "Heart Beat of IOC has failed\n");
2161         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL);
2162
2163 }
2164
2165 static void
2166 bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
2167 {
2168         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
2169         /*
2170          * Provide enable completion callback.
2171          */
2172         ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
2173         BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
2174                 "Running firmware version is incompatible "
2175                 "with the driver version\n");
2176         bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH);
2177 }
2178
2179 bfa_status_t
2180 bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
2181 {
2182
2183         /*
2184          *  Hold semaphore so that nobody can access the chip during init.
2185          */
2186         bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
2187
2188         bfa_ioc_pll_init_asic(ioc);
2189
2190         ioc->pllinit = BFA_TRUE;
2191
2192         /*
2193          * Initialize LMEM
2194          */
2195         bfa_ioc_lmem_init(ioc);
2196
2197         /*
2198          *  release semaphore.
2199          */
2200         readl(ioc->ioc_regs.ioc_init_sem_reg);
2201         writel(1, ioc->ioc_regs.ioc_init_sem_reg);
2202
2203         return BFA_STATUS_OK;
2204 }
2205
2206 /*
2207  * Interface used by diag module to do firmware boot with memory test
2208  * as the entry vector.
2209  */
2210 bfa_status_t
2211 bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env)
2212 {
2213         struct bfi_ioc_image_hdr_s *drv_fwhdr;
2214         bfa_status_t status;
2215         bfa_ioc_stats(ioc, ioc_boots);
2216
2217         if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
2218                 return BFA_STATUS_FAILED;
2219
2220         if (boot_env == BFI_FWBOOT_ENV_OS &&
2221                 boot_type == BFI_FWBOOT_TYPE_NORMAL) {
2222
2223                 drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
2224                         bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
2225
2226                 /*
2227                  * Work with Flash iff flash f/w is better than driver f/w.
2228                  * Otherwise push drivers firmware.
2229                  */
2230                 if (bfa_ioc_flash_fwver_cmp(ioc, drv_fwhdr) ==
2231                                                 BFI_IOC_IMG_VER_BETTER)
2232                         boot_type = BFI_FWBOOT_TYPE_FLASH;
2233         }
2234
2235         /*
2236          * Initialize IOC state of all functions on a chip reset.
2237          */
2238         if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) {
2239                 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_MEMTEST);
2240                 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_MEMTEST);
2241         } else {
2242                 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_INITING);
2243                 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_INITING);
2244         }
2245
2246         bfa_ioc_msgflush(ioc);
2247         status = bfa_ioc_download_fw(ioc, boot_type, boot_env);
2248         if (status == BFA_STATUS_OK)
2249                 bfa_ioc_lpu_start(ioc);
2250         else {
2251                 WARN_ON(boot_type == BFI_FWBOOT_TYPE_MEMTEST);
2252                 bfa_iocpf_timeout(ioc);
2253         }
2254         return status;
2255 }
2256
2257 /*
2258  * Enable/disable IOC failure auto recovery.
2259  */
2260 void
2261 bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
2262 {
2263         bfa_auto_recover = auto_recover;
2264 }
2265
2266
2267
2268 bfa_boolean_t
2269 bfa_ioc_is_operational(struct bfa_ioc_s *ioc)
2270 {
2271         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
2272 }
2273
2274 bfa_boolean_t
2275 bfa_ioc_is_initialized(struct bfa_ioc_s *ioc)
2276 {
2277         u32 r32 = bfa_ioc_get_cur_ioc_fwstate(ioc);
2278
2279         return ((r32 != BFI_IOC_UNINIT) &&
2280                 (r32 != BFI_IOC_INITING) &&
2281                 (r32 != BFI_IOC_MEMTEST));
2282 }
2283
2284 bfa_boolean_t
2285 bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
2286 {
2287         __be32  *msgp = mbmsg;
2288         u32     r32;
2289         int             i;
2290
2291         r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
2292         if ((r32 & 1) == 0)
2293                 return BFA_FALSE;
2294
2295         /*
2296          * read the MBOX msg
2297          */
2298         for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
2299              i++) {
2300                 r32 = readl(ioc->ioc_regs.lpu_mbox +
2301                                    i * sizeof(u32));
2302                 msgp[i] = cpu_to_be32(r32);
2303         }
2304
2305         /*
2306          * turn off mailbox interrupt by clearing mailbox status
2307          */
2308         writel(1, ioc->ioc_regs.lpu_mbox_cmd);
2309         readl(ioc->ioc_regs.lpu_mbox_cmd);
2310
2311         return BFA_TRUE;
2312 }
2313
2314 void
2315 bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
2316 {
2317         union bfi_ioc_i2h_msg_u *msg;
2318         struct bfa_iocpf_s *iocpf = &ioc->iocpf;
2319
2320         msg = (union bfi_ioc_i2h_msg_u *) m;
2321
2322         bfa_ioc_stats(ioc, ioc_isrs);
2323
2324         switch (msg->mh.msg_id) {
2325         case BFI_IOC_I2H_HBEAT:
2326                 break;
2327
2328         case BFI_IOC_I2H_ENABLE_REPLY:
2329                 ioc->port_mode = ioc->port_mode_cfg =
2330                                 (enum bfa_mode_s)msg->fw_event.port_mode;
2331                 ioc->ad_cap_bm = msg->fw_event.cap_bm;
2332                 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
2333                 break;
2334
2335         case BFI_IOC_I2H_DISABLE_REPLY:
2336                 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE);
2337                 break;
2338
2339         case BFI_IOC_I2H_GETATTR_REPLY:
2340                 bfa_ioc_getattr_reply(ioc);
2341                 break;
2342
2343         default:
2344                 bfa_trc(ioc, msg->mh.msg_id);
2345                 WARN_ON(1);
2346         }
2347 }
2348
2349 /*
2350  * IOC attach time initialization and setup.
2351  *
2352  * @param[in]   ioc     memory for IOC
2353  * @param[in]   bfa     driver instance structure
2354  */
2355 void
2356 bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn,
2357                struct bfa_timer_mod_s *timer_mod)
2358 {
2359         ioc->bfa        = bfa;
2360         ioc->cbfn       = cbfn;
2361         ioc->timer_mod  = timer_mod;
2362         ioc->fcmode     = BFA_FALSE;
2363         ioc->pllinit    = BFA_FALSE;
2364         ioc->dbg_fwsave_once = BFA_TRUE;
2365         ioc->iocpf.ioc  = ioc;
2366
2367         bfa_ioc_mbox_attach(ioc);
2368         INIT_LIST_HEAD(&ioc->notify_q);
2369
2370         bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
2371         bfa_fsm_send_event(ioc, IOC_E_RESET);
2372 }
2373
2374 /*
2375  * Driver detach time IOC cleanup.
2376  */
2377 void
2378 bfa_ioc_detach(struct bfa_ioc_s *ioc)
2379 {
2380         bfa_fsm_send_event(ioc, IOC_E_DETACH);
2381         INIT_LIST_HEAD(&ioc->notify_q);
2382 }
2383
2384 /*
2385  * Setup IOC PCI properties.
2386  *
2387  * @param[in]   pcidev  PCI device information for this IOC
2388  */
2389 void
2390 bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
2391                 enum bfi_pcifn_class clscode)
2392 {
2393         ioc->clscode    = clscode;
2394         ioc->pcidev     = *pcidev;
2395
2396         /*
2397          * Initialize IOC and device personality
2398          */
2399         ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_FC;
2400         ioc->asic_mode  = BFI_ASIC_MODE_FC;
2401
2402         switch (pcidev->device_id) {
2403         case BFA_PCI_DEVICE_ID_FC_8G1P:
2404         case BFA_PCI_DEVICE_ID_FC_8G2P:
2405                 ioc->asic_gen = BFI_ASIC_GEN_CB;
2406                 ioc->fcmode = BFA_TRUE;
2407                 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2408                 ioc->ad_cap_bm = BFA_CM_HBA;
2409                 break;
2410
2411         case BFA_PCI_DEVICE_ID_CT:
2412                 ioc->asic_gen = BFI_ASIC_GEN_CT;
2413                 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
2414                 ioc->asic_mode  = BFI_ASIC_MODE_ETH;
2415                 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_CNA;
2416                 ioc->ad_cap_bm = BFA_CM_CNA;
2417                 break;
2418
2419         case BFA_PCI_DEVICE_ID_CT_FC:
2420                 ioc->asic_gen = BFI_ASIC_GEN_CT;
2421                 ioc->fcmode = BFA_TRUE;
2422                 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2423                 ioc->ad_cap_bm = BFA_CM_HBA;
2424                 break;
2425
2426         case BFA_PCI_DEVICE_ID_CT2:
2427         case BFA_PCI_DEVICE_ID_CT2_QUAD:
2428                 ioc->asic_gen = BFI_ASIC_GEN_CT2;
2429                 if (clscode == BFI_PCIFN_CLASS_FC &&
2430                     pcidev->ssid == BFA_PCI_CT2_SSID_FC) {
2431                         ioc->asic_mode  = BFI_ASIC_MODE_FC16;
2432                         ioc->fcmode = BFA_TRUE;
2433                         ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2434                         ioc->ad_cap_bm = BFA_CM_HBA;
2435                 } else {
2436                         ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
2437                         ioc->asic_mode  = BFI_ASIC_MODE_ETH;
2438                         if (pcidev->ssid == BFA_PCI_CT2_SSID_FCoE) {
2439                                 ioc->port_mode =
2440                                 ioc->port_mode_cfg = BFA_MODE_CNA;
2441                                 ioc->ad_cap_bm = BFA_CM_CNA;
2442                         } else {
2443                                 ioc->port_mode =
2444                                 ioc->port_mode_cfg = BFA_MODE_NIC;
2445                                 ioc->ad_cap_bm = BFA_CM_NIC;
2446                         }
2447                 }
2448                 break;
2449
2450         default:
2451                 WARN_ON(1);
2452         }
2453
2454         /*
2455          * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
2456          */
2457         if (ioc->asic_gen == BFI_ASIC_GEN_CB)
2458                 bfa_ioc_set_cb_hwif(ioc);
2459         else if (ioc->asic_gen == BFI_ASIC_GEN_CT)
2460                 bfa_ioc_set_ct_hwif(ioc);
2461         else {
2462                 WARN_ON(ioc->asic_gen != BFI_ASIC_GEN_CT2);
2463                 bfa_ioc_set_ct2_hwif(ioc);
2464                 bfa_ioc_ct2_poweron(ioc);
2465         }
2466
2467         bfa_ioc_map_port(ioc);
2468         bfa_ioc_reg_init(ioc);
2469 }
2470
2471 /*
2472  * Initialize IOC dma memory
2473  *
2474  * @param[in]   dm_kva  kernel virtual address of IOC dma memory
2475  * @param[in]   dm_pa   physical address of IOC dma memory
2476  */
2477 void
2478 bfa_ioc_mem_claim(struct bfa_ioc_s *ioc,  u8 *dm_kva, u64 dm_pa)
2479 {
2480         /*
2481          * dma memory for firmware attribute
2482          */
2483         ioc->attr_dma.kva = dm_kva;
2484         ioc->attr_dma.pa = dm_pa;
2485         ioc->attr = (struct bfi_ioc_attr_s *) dm_kva;
2486 }
2487
2488 void
2489 bfa_ioc_enable(struct bfa_ioc_s *ioc)
2490 {
2491         bfa_ioc_stats(ioc, ioc_enables);
2492         ioc->dbg_fwsave_once = BFA_TRUE;
2493
2494         bfa_fsm_send_event(ioc, IOC_E_ENABLE);
2495 }
2496
2497 void
2498 bfa_ioc_disable(struct bfa_ioc_s *ioc)
2499 {
2500         bfa_ioc_stats(ioc, ioc_disables);
2501         bfa_fsm_send_event(ioc, IOC_E_DISABLE);
2502 }
2503
2504 void
2505 bfa_ioc_suspend(struct bfa_ioc_s *ioc)
2506 {
2507         ioc->dbg_fwsave_once = BFA_TRUE;
2508         bfa_fsm_send_event(ioc, IOC_E_HWERROR);
2509 }
2510
2511 /*
2512  * Initialize memory for saving firmware trace. Driver must initialize
2513  * trace memory before call bfa_ioc_enable().
2514  */
2515 void
2516 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
2517 {
2518         ioc->dbg_fwsave     = dbg_fwsave;
2519         ioc->dbg_fwsave_len = BFA_DBG_FWTRC_LEN;
2520 }
2521
2522 /*
2523  * Register mailbox message handler functions
2524  *
2525  * @param[in]   ioc             IOC instance
2526  * @param[in]   mcfuncs         message class handler functions
2527  */
2528 void
2529 bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs)
2530 {
2531         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2532         int                             mc;
2533
2534         for (mc = 0; mc < BFI_MC_MAX; mc++)
2535                 mod->mbhdlr[mc].cbfn = mcfuncs[mc];
2536 }
2537
2538 /*
2539  * Register mailbox message handler function, to be called by common modules
2540  */
2541 void
2542 bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
2543                     bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
2544 {
2545         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2546
2547         mod->mbhdlr[mc].cbfn    = cbfn;
2548         mod->mbhdlr[mc].cbarg   = cbarg;
2549 }
2550
2551 /*
2552  * Queue a mailbox command request to firmware. Waits if mailbox is busy.
2553  * Responsibility of caller to serialize
2554  *
2555  * @param[in]   ioc     IOC instance
2556  * @param[i]    cmd     Mailbox command
2557  */
2558 void
2559 bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd)
2560 {
2561         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2562         u32                     stat;
2563
2564         /*
2565          * If a previous command is pending, queue new command
2566          */
2567         if (!list_empty(&mod->cmd_q)) {
2568                 list_add_tail(&cmd->qe, &mod->cmd_q);
2569                 return;
2570         }
2571
2572         /*
2573          * If mailbox is busy, queue command for poll timer
2574          */
2575         stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
2576         if (stat) {
2577                 list_add_tail(&cmd->qe, &mod->cmd_q);
2578                 return;
2579         }
2580
2581         /*
2582          * mailbox is free -- queue command to firmware
2583          */
2584         bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
2585 }
2586
2587 /*
2588  * Handle mailbox interrupts
2589  */
2590 void
2591 bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc)
2592 {
2593         struct bfa_ioc_mbox_mod_s       *mod = &ioc->mbox_mod;
2594         struct bfi_mbmsg_s              m;
2595         int                             mc;
2596
2597         if (bfa_ioc_msgget(ioc, &m)) {
2598                 /*
2599                  * Treat IOC message class as special.
2600                  */
2601                 mc = m.mh.msg_class;
2602                 if (mc == BFI_MC_IOC) {
2603                         bfa_ioc_isr(ioc, &m);
2604                         return;
2605                 }
2606
2607                 if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
2608                         return;
2609
2610                 mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
2611         }
2612
2613         bfa_ioc_lpu_read_stat(ioc);
2614
2615         /*
2616          * Try to send pending mailbox commands
2617          */
2618         bfa_ioc_mbox_poll(ioc);
2619 }
2620
2621 void
2622 bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
2623 {
2624         bfa_ioc_stats(ioc, ioc_hbfails);
2625         ioc->stats.hb_count = ioc->hb_count;
2626         bfa_fsm_send_event(ioc, IOC_E_HWERROR);
2627 }
2628
2629 /*
2630  * return true if IOC is disabled
2631  */
2632 bfa_boolean_t
2633 bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
2634 {
2635         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) ||
2636                 bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
2637 }
2638
2639 /*
2640  * return true if IOC firmware is different.
2641  */
2642 bfa_boolean_t
2643 bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
2644 {
2645         return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset) ||
2646                 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_fwcheck) ||
2647                 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_mismatch);
2648 }
2649
2650 /*
2651  * Check if adapter is disabled -- both IOCs should be in a disabled
2652  * state.
2653  */
2654 bfa_boolean_t
2655 bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
2656 {
2657         u32     ioc_state;
2658
2659         if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled))
2660                 return BFA_FALSE;
2661
2662         ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc);
2663         if (!bfa_ioc_state_disabled(ioc_state))
2664                 return BFA_FALSE;
2665
2666         if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) {
2667                 ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc);
2668                 if (!bfa_ioc_state_disabled(ioc_state))
2669                         return BFA_FALSE;
2670         }
2671
2672         return BFA_TRUE;
2673 }
2674
2675 /*
2676  * Reset IOC fwstate registers.
2677  */
2678 void
2679 bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc)
2680 {
2681         bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_UNINIT);
2682         bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_UNINIT);
2683 }
2684
2685 #define BFA_MFG_NAME "QLogic"
2686 void
2687 bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2688                          struct bfa_adapter_attr_s *ad_attr)
2689 {
2690         struct bfi_ioc_attr_s   *ioc_attr;
2691
2692         ioc_attr = ioc->attr;
2693
2694         bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
2695         bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
2696         bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
2697         bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
2698         memcpy(&ad_attr->vpd, &ioc_attr->vpd,
2699                       sizeof(struct bfa_mfg_vpd_s));
2700
2701         ad_attr->nports = bfa_ioc_get_nports(ioc);
2702         ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
2703
2704         bfa_ioc_get_adapter_model(ioc, ad_attr->model);
2705         /* For now, model descr uses same model string */
2706         bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
2707
2708         ad_attr->card_type = ioc_attr->card_type;
2709         ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type);
2710
2711         if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
2712                 ad_attr->prototype = 1;
2713         else
2714                 ad_attr->prototype = 0;
2715
2716         ad_attr->pwwn = ioc->attr->pwwn;
2717         ad_attr->mac  = bfa_ioc_get_mac(ioc);
2718
2719         ad_attr->pcie_gen = ioc_attr->pcie_gen;
2720         ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
2721         ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
2722         ad_attr->asic_rev = ioc_attr->asic_rev;
2723
2724         bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
2725
2726         ad_attr->cna_capable = bfa_ioc_is_cna(ioc);
2727         ad_attr->trunk_capable = (ad_attr->nports > 1) &&
2728                                   !bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz;
2729         ad_attr->mfg_day = ioc_attr->mfg_day;
2730         ad_attr->mfg_month = ioc_attr->mfg_month;
2731         ad_attr->mfg_year = ioc_attr->mfg_year;
2732         memcpy(ad_attr->uuid, ioc_attr->uuid, BFA_ADAPTER_UUID_LEN);
2733 }
2734
2735 enum bfa_ioc_type_e
2736 bfa_ioc_get_type(struct bfa_ioc_s *ioc)
2737 {
2738         if (ioc->clscode == BFI_PCIFN_CLASS_ETH)
2739                 return BFA_IOC_TYPE_LL;
2740
2741         WARN_ON(ioc->clscode != BFI_PCIFN_CLASS_FC);
2742
2743         return (ioc->attr->port_mode == BFI_PORT_MODE_FC)
2744                 ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE;
2745 }
2746
2747 void
2748 bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
2749 {
2750         memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
2751         memcpy((void *)serial_num,
2752                         (void *)ioc->attr->brcd_serialnum,
2753                         BFA_ADAPTER_SERIAL_NUM_LEN);
2754 }
2755
2756 void
2757 bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
2758 {
2759         memset((void *)fw_ver, 0, BFA_VERSION_LEN);
2760         memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
2761 }
2762
2763 void
2764 bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
2765 {
2766         WARN_ON(!chip_rev);
2767
2768         memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
2769
2770         chip_rev[0] = 'R';
2771         chip_rev[1] = 'e';
2772         chip_rev[2] = 'v';
2773         chip_rev[3] = '-';
2774         chip_rev[4] = ioc->attr->asic_rev;
2775         chip_rev[5] = '\0';
2776 }
2777
2778 void
2779 bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver)
2780 {
2781         memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
2782         memcpy(optrom_ver, ioc->attr->optrom_version,
2783                       BFA_VERSION_LEN);
2784 }
2785
2786 void
2787 bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
2788 {
2789         memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
2790         strscpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
2791 }
2792
2793 void
2794 bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
2795 {
2796         struct bfi_ioc_attr_s   *ioc_attr;
2797         u8 nports = bfa_ioc_get_nports(ioc);
2798
2799         WARN_ON(!model);
2800         memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
2801
2802         ioc_attr = ioc->attr;
2803
2804         if (bfa_asic_id_ct2(ioc->pcidev.device_id) &&
2805                 (!bfa_mfg_is_mezz(ioc_attr->card_type)))
2806                 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u-%u%s",
2807                         BFA_MFG_NAME, ioc_attr->card_type, nports, "p");
2808         else
2809                 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
2810                         BFA_MFG_NAME, ioc_attr->card_type);
2811 }
2812
2813 enum bfa_ioc_state
2814 bfa_ioc_get_state(struct bfa_ioc_s *ioc)
2815 {
2816         enum bfa_iocpf_state iocpf_st;
2817         enum bfa_ioc_state ioc_st = bfa_ioc_sm_to_state(ioc_sm_table, ioc->fsm);
2818
2819         if (ioc_st == BFA_IOC_ENABLING ||
2820                 ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) {
2821
2822                 iocpf_st = bfa_iocpf_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm);
2823
2824                 switch (iocpf_st) {
2825                 case BFA_IOCPF_SEMWAIT:
2826                         ioc_st = BFA_IOC_SEMWAIT;
2827                         break;
2828
2829                 case BFA_IOCPF_HWINIT:
2830                         ioc_st = BFA_IOC_HWINIT;
2831                         break;
2832
2833                 case BFA_IOCPF_FWMISMATCH:
2834                         ioc_st = BFA_IOC_FWMISMATCH;
2835                         break;
2836
2837                 case BFA_IOCPF_FAIL:
2838                         ioc_st = BFA_IOC_FAIL;
2839                         break;
2840
2841                 case BFA_IOCPF_INITFAIL:
2842                         ioc_st = BFA_IOC_INITFAIL;
2843                         break;
2844
2845                 default:
2846                         break;
2847                 }
2848         }
2849
2850         return ioc_st;
2851 }
2852
2853 void
2854 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
2855 {
2856         memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
2857
2858         ioc_attr->state = bfa_ioc_get_state(ioc);
2859         ioc_attr->port_id = bfa_ioc_portid(ioc);
2860         ioc_attr->port_mode = ioc->port_mode;
2861         ioc_attr->port_mode_cfg = ioc->port_mode_cfg;
2862         ioc_attr->cap_bm = ioc->ad_cap_bm;
2863
2864         ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
2865
2866         bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
2867
2868         ioc_attr->pci_attr.device_id = bfa_ioc_devid(ioc);
2869         ioc_attr->pci_attr.pcifn = bfa_ioc_pcifn(ioc);
2870         ioc_attr->def_fn = (bfa_ioc_pcifn(ioc) == bfa_ioc_portid(ioc));
2871         bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
2872 }
2873
2874 mac_t
2875 bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
2876 {
2877         /*
2878          * Check the IOC type and return the appropriate MAC
2879          */
2880         if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE)
2881                 return ioc->attr->fcoe_mac;
2882         else
2883                 return ioc->attr->mac;
2884 }
2885
2886 mac_t
2887 bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc)
2888 {
2889         mac_t   m;
2890
2891         m = ioc->attr->mfg_mac;
2892         if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type))
2893                 m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
2894         else
2895                 bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]),
2896                         bfa_ioc_pcifn(ioc));
2897
2898         return m;
2899 }
2900
2901 /*
2902  * Send AEN notification
2903  */
2904 void
2905 bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2906 {
2907         struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
2908         struct bfa_aen_entry_s  *aen_entry;
2909         enum bfa_ioc_type_e ioc_type;
2910
2911         bfad_get_aen_entry(bfad, aen_entry);
2912         if (!aen_entry)
2913                 return;
2914
2915         ioc_type = bfa_ioc_get_type(ioc);
2916         switch (ioc_type) {
2917         case BFA_IOC_TYPE_FC:
2918                 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn;
2919                 break;
2920         case BFA_IOC_TYPE_FCoE:
2921                 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn;
2922                 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2923                 break;
2924         case BFA_IOC_TYPE_LL:
2925                 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2926                 break;
2927         default:
2928                 WARN_ON(ioc_type != BFA_IOC_TYPE_FC);
2929                 break;
2930         }
2931
2932         /* Send the AEN notification */
2933         aen_entry->aen_data.ioc.ioc_type = ioc_type;
2934         bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq,
2935                                   BFA_AEN_CAT_IOC, event);
2936 }
2937
2938 /*
2939  * Retrieve saved firmware trace from a prior IOC failure.
2940  */
2941 bfa_status_t
2942 bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2943 {
2944         int     tlen;
2945
2946         if (ioc->dbg_fwsave_len == 0)
2947                 return BFA_STATUS_ENOFSAVE;
2948
2949         tlen = *trclen;
2950         if (tlen > ioc->dbg_fwsave_len)
2951                 tlen = ioc->dbg_fwsave_len;
2952
2953         memcpy(trcdata, ioc->dbg_fwsave, tlen);
2954         *trclen = tlen;
2955         return BFA_STATUS_OK;
2956 }
2957
2958
2959 /*
2960  * Retrieve saved firmware trace from a prior IOC failure.
2961  */
2962 bfa_status_t
2963 bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2964 {
2965         u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc));
2966         int tlen;
2967         bfa_status_t status;
2968
2969         bfa_trc(ioc, *trclen);
2970
2971         tlen = *trclen;
2972         if (tlen > BFA_DBG_FWTRC_LEN)
2973                 tlen = BFA_DBG_FWTRC_LEN;
2974
2975         status = bfa_ioc_smem_read(ioc, trcdata, loff, tlen);
2976         *trclen = tlen;
2977         return status;
2978 }
2979
2980 static void
2981 bfa_ioc_send_fwsync(struct bfa_ioc_s *ioc)
2982 {
2983         struct bfa_mbox_cmd_s cmd;
2984         struct bfi_ioc_ctrl_req_s *req = (struct bfi_ioc_ctrl_req_s *) cmd.msg;
2985
2986         bfi_h2i_set(req->mh, BFI_MC_IOC, BFI_IOC_H2I_DBG_SYNC,
2987                     bfa_ioc_portid(ioc));
2988         req->clscode = cpu_to_be16(ioc->clscode);
2989         bfa_ioc_mbox_queue(ioc, &cmd);
2990 }
2991
2992 static void
2993 bfa_ioc_fwsync(struct bfa_ioc_s *ioc)
2994 {
2995         u32 fwsync_iter = 1000;
2996
2997         bfa_ioc_send_fwsync(ioc);
2998
2999         /*
3000          * After sending a fw sync mbox command wait for it to
3001          * take effect.  We will not wait for a response because
3002          *    1. fw_sync mbox cmd doesn't have a response.
3003          *    2. Even if we implement that,  interrupts might not
3004          *       be enabled when we call this function.
3005          * So, just keep checking if any mbox cmd is pending, and
3006          * after waiting for a reasonable amount of time, go ahead.
3007          * It is possible that fw has crashed and the mbox command
3008          * is never acknowledged.
3009          */
3010         while (bfa_ioc_mbox_cmd_pending(ioc) && fwsync_iter > 0)
3011                 fwsync_iter--;
3012 }
3013
3014 /*
3015  * Dump firmware smem
3016  */
3017 bfa_status_t
3018 bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf,
3019                                 u32 *offset, int *buflen)
3020 {
3021         u32 loff;
3022         int dlen;
3023         bfa_status_t status;
3024         u32 smem_len = BFA_IOC_FW_SMEM_SIZE(ioc);
3025
3026         if (*offset >= smem_len) {
3027                 *offset = *buflen = 0;
3028                 return BFA_STATUS_EINVAL;
3029         }
3030
3031         loff = *offset;
3032         dlen = *buflen;
3033
3034         /*
3035          * First smem read, sync smem before proceeding
3036          * No need to sync before reading every chunk.
3037          */
3038         if (loff == 0)
3039                 bfa_ioc_fwsync(ioc);
3040
3041         if ((loff + dlen) >= smem_len)
3042                 dlen = smem_len - loff;
3043
3044         status = bfa_ioc_smem_read(ioc, buf, loff, dlen);
3045
3046         if (status != BFA_STATUS_OK) {
3047                 *offset = *buflen = 0;
3048                 return status;
3049         }
3050
3051         *offset += dlen;
3052
3053         if (*offset >= smem_len)
3054                 *offset = 0;
3055
3056         *buflen = dlen;
3057
3058         return status;
3059 }
3060
3061 /*
3062  * Firmware statistics
3063  */
3064 bfa_status_t
3065 bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats)
3066 {
3067         u32 loff = BFI_IOC_FWSTATS_OFF + \
3068                 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc));
3069         int tlen;
3070         bfa_status_t status;
3071
3072         if (ioc->stats_busy) {
3073                 bfa_trc(ioc, ioc->stats_busy);
3074                 return BFA_STATUS_DEVBUSY;
3075         }
3076         ioc->stats_busy = BFA_TRUE;
3077
3078         tlen = sizeof(struct bfa_fw_stats_s);
3079         status = bfa_ioc_smem_read(ioc, stats, loff, tlen);
3080
3081         ioc->stats_busy = BFA_FALSE;
3082         return status;
3083 }
3084
3085 bfa_status_t
3086 bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc)
3087 {
3088         u32 loff = BFI_IOC_FWSTATS_OFF + \
3089                 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc));
3090         int tlen;
3091         bfa_status_t status;
3092
3093         if (ioc->stats_busy) {
3094                 bfa_trc(ioc, ioc->stats_busy);
3095                 return BFA_STATUS_DEVBUSY;
3096         }
3097         ioc->stats_busy = BFA_TRUE;
3098
3099         tlen = sizeof(struct bfa_fw_stats_s);
3100         status = bfa_ioc_smem_clr(ioc, loff, tlen);
3101
3102         ioc->stats_busy = BFA_FALSE;
3103         return status;
3104 }
3105
3106 /*
3107  * Save firmware trace if configured.
3108  */
3109 void
3110 bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc)
3111 {
3112         int             tlen;
3113
3114         if (ioc->dbg_fwsave_once) {
3115                 ioc->dbg_fwsave_once = BFA_FALSE;
3116                 if (ioc->dbg_fwsave_len) {
3117                         tlen = ioc->dbg_fwsave_len;
3118                         bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
3119                 }
3120         }
3121 }
3122
3123 /*
3124  * Firmware failure detected. Start recovery actions.
3125  */
3126 static void
3127 bfa_ioc_recover(struct bfa_ioc_s *ioc)
3128 {
3129         bfa_ioc_stats(ioc, ioc_hbfails);
3130         ioc->stats.hb_count = ioc->hb_count;
3131         bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
3132 }
3133
3134 /*
3135  *  BFA IOC PF private functions
3136  */
3137 static void
3138 bfa_iocpf_timeout(void *ioc_arg)
3139 {
3140         struct bfa_ioc_s  *ioc = (struct bfa_ioc_s *) ioc_arg;
3141
3142         bfa_trc(ioc, 0);
3143         bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT);
3144 }
3145
3146 static void
3147 bfa_iocpf_sem_timeout(void *ioc_arg)
3148 {
3149         struct bfa_ioc_s  *ioc = (struct bfa_ioc_s *) ioc_arg;
3150
3151         bfa_ioc_hw_sem_get(ioc);
3152 }
3153
3154 static void
3155 bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc)
3156 {
3157         u32 fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
3158
3159         bfa_trc(ioc, fwstate);
3160
3161         if (fwstate == BFI_IOC_DISABLED) {
3162                 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
3163                 return;
3164         }
3165
3166         if (ioc->iocpf.poll_time >= (3 * BFA_IOC_TOV))
3167                 bfa_iocpf_timeout(ioc);
3168         else {
3169                 ioc->iocpf.poll_time += BFA_IOC_POLL_TOV;
3170                 bfa_iocpf_poll_timer_start(ioc);
3171         }
3172 }
3173
3174 static void
3175 bfa_iocpf_poll_timeout(void *ioc_arg)
3176 {
3177         struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg;
3178
3179         bfa_ioc_poll_fwinit(ioc);
3180 }
3181
3182 /*
3183  *  bfa timer function
3184  */
3185 void
3186 bfa_timer_beat(struct bfa_timer_mod_s *mod)
3187 {
3188         struct list_head *qh = &mod->timer_q;
3189         struct list_head *qe, *qe_next;
3190         struct bfa_timer_s *elem;
3191         struct list_head timedout_q;
3192
3193         INIT_LIST_HEAD(&timedout_q);
3194
3195         qe = bfa_q_next(qh);
3196
3197         while (qe != qh) {
3198                 qe_next = bfa_q_next(qe);
3199
3200                 elem = (struct bfa_timer_s *) qe;
3201                 if (elem->timeout <= BFA_TIMER_FREQ) {
3202                         elem->timeout = 0;
3203                         list_del(&elem->qe);
3204                         list_add_tail(&elem->qe, &timedout_q);
3205                 } else {
3206                         elem->timeout -= BFA_TIMER_FREQ;
3207                 }
3208
3209                 qe = qe_next;   /* go to next elem */
3210         }
3211
3212         /*
3213          * Pop all the timeout entries
3214          */
3215         while (!list_empty(&timedout_q)) {
3216                 bfa_q_deq(&timedout_q, &elem);
3217                 elem->timercb(elem->arg);
3218         }
3219 }
3220
3221 /*
3222  * Should be called with lock protection
3223  */
3224 void
3225 bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
3226                     void (*timercb) (void *), void *arg, unsigned int timeout)
3227 {
3228
3229         WARN_ON(timercb == NULL);
3230         WARN_ON(bfa_q_is_on_q(&mod->timer_q, timer));
3231
3232         timer->timeout = timeout;
3233         timer->timercb = timercb;
3234         timer->arg = arg;
3235
3236         list_add_tail(&timer->qe, &mod->timer_q);
3237 }
3238
3239 /*
3240  * Should be called with lock protection
3241  */
3242 void
3243 bfa_timer_stop(struct bfa_timer_s *timer)
3244 {
3245         WARN_ON(list_empty(&timer->qe));
3246
3247         list_del(&timer->qe);
3248 }
3249
3250 /*
3251  *      ASIC block related
3252  */
3253 static void
3254 bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg)
3255 {
3256         struct bfa_ablk_cfg_inst_s *cfg_inst;
3257         int i, j;
3258         u16     be16;
3259
3260         for (i = 0; i < BFA_ABLK_MAX; i++) {
3261                 cfg_inst = &cfg->inst[i];
3262                 for (j = 0; j < BFA_ABLK_MAX_PFS; j++) {
3263                         be16 = cfg_inst->pf_cfg[j].pers;
3264                         cfg_inst->pf_cfg[j].pers = be16_to_cpu(be16);
3265                         be16 = cfg_inst->pf_cfg[j].num_qpairs;
3266                         cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16);
3267                         be16 = cfg_inst->pf_cfg[j].num_vectors;
3268                         cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16);
3269                         be16 = cfg_inst->pf_cfg[j].bw_min;
3270                         cfg_inst->pf_cfg[j].bw_min = be16_to_cpu(be16);
3271                         be16 = cfg_inst->pf_cfg[j].bw_max;
3272                         cfg_inst->pf_cfg[j].bw_max = be16_to_cpu(be16);
3273                 }
3274         }
3275 }
3276
3277 static void
3278 bfa_ablk_isr(void *cbarg, struct bfi_mbmsg_s *msg)
3279 {
3280         struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg;
3281         struct bfi_ablk_i2h_rsp_s *rsp = (struct bfi_ablk_i2h_rsp_s *)msg;
3282         bfa_ablk_cbfn_t cbfn;
3283
3284         WARN_ON(msg->mh.msg_class != BFI_MC_ABLK);
3285         bfa_trc(ablk->ioc, msg->mh.msg_id);
3286
3287         switch (msg->mh.msg_id) {
3288         case BFI_ABLK_I2H_QUERY:
3289                 if (rsp->status == BFA_STATUS_OK) {
3290                         memcpy(ablk->cfg, ablk->dma_addr.kva,
3291                                 sizeof(struct bfa_ablk_cfg_s));
3292                         bfa_ablk_config_swap(ablk->cfg);
3293                         ablk->cfg = NULL;
3294                 }
3295                 break;
3296
3297         case BFI_ABLK_I2H_ADPT_CONFIG:
3298         case BFI_ABLK_I2H_PORT_CONFIG:
3299                 /* update config port mode */
3300                 ablk->ioc->port_mode_cfg = rsp->port_mode;
3301                 break;
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 /* forward declaration of DCONF state machine */
5808 static void bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf,
5809                                 enum bfa_dconf_event event);
5810 static void bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
5811                                 enum bfa_dconf_event event);
5812 static void bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf,
5813                                 enum bfa_dconf_event event);
5814 static void bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf,
5815                                 enum bfa_dconf_event event);
5816 static void bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf,
5817                                 enum bfa_dconf_event event);
5818 static void bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf,
5819                                 enum bfa_dconf_event event);
5820 static void bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf,
5821                                 enum bfa_dconf_event event);
5822
5823 static void bfa_dconf_cbfn(void *dconf, bfa_status_t status);
5824 static void bfa_dconf_timer(void *cbarg);
5825 static bfa_status_t bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf);
5826 static void bfa_dconf_init_cb(void *arg, bfa_status_t status);
5827
5828 /*
5829  * Beginning state of dconf module. Waiting for an event to start.
5830  */
5831 static void
5832 bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5833 {
5834         bfa_status_t bfa_status;
5835         bfa_trc(dconf->bfa, event);
5836
5837         switch (event) {
5838         case BFA_DCONF_SM_INIT:
5839                 if (dconf->min_cfg) {
5840                         bfa_trc(dconf->bfa, dconf->min_cfg);
5841                         bfa_fsm_send_event(&dconf->bfa->iocfc,
5842                                         IOCFC_E_DCONF_DONE);
5843                         return;
5844                 }
5845                 bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read);
5846                 bfa_timer_start(dconf->bfa, &dconf->timer,
5847                         bfa_dconf_timer, dconf, 2 * BFA_DCONF_UPDATE_TOV);
5848                 bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa),
5849                                         BFA_FLASH_PART_DRV, dconf->instance,
5850                                         dconf->dconf,
5851                                         sizeof(struct bfa_dconf_s), 0,
5852                                         bfa_dconf_init_cb, dconf->bfa);
5853                 if (bfa_status != BFA_STATUS_OK) {
5854                         bfa_timer_stop(&dconf->timer);
5855                         bfa_dconf_init_cb(dconf->bfa, BFA_STATUS_FAILED);
5856                         bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5857                         return;
5858                 }
5859                 break;
5860         case BFA_DCONF_SM_EXIT:
5861                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5862                 break;
5863         case BFA_DCONF_SM_IOCDISABLE:
5864         case BFA_DCONF_SM_WR:
5865         case BFA_DCONF_SM_FLASH_COMP:
5866                 break;
5867         default:
5868                 bfa_sm_fault(dconf->bfa, event);
5869         }
5870 }
5871
5872 /*
5873  * Read flash for dconf entries and make a call back to the driver once done.
5874  */
5875 static void
5876 bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
5877                         enum bfa_dconf_event event)
5878 {
5879         bfa_trc(dconf->bfa, event);
5880
5881         switch (event) {
5882         case BFA_DCONF_SM_FLASH_COMP:
5883                 bfa_timer_stop(&dconf->timer);
5884                 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5885                 break;
5886         case BFA_DCONF_SM_TIMEOUT:
5887                 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5888                 bfa_ioc_suspend(&dconf->bfa->ioc);
5889                 break;
5890         case BFA_DCONF_SM_EXIT:
5891                 bfa_timer_stop(&dconf->timer);
5892                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5893                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5894                 break;
5895         case BFA_DCONF_SM_IOCDISABLE:
5896                 bfa_timer_stop(&dconf->timer);
5897                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5898                 break;
5899         default:
5900                 bfa_sm_fault(dconf->bfa, event);
5901         }
5902 }
5903
5904 /*
5905  * DCONF Module is in ready state. Has completed the initialization.
5906  */
5907 static void
5908 bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5909 {
5910         bfa_trc(dconf->bfa, event);
5911
5912         switch (event) {
5913         case BFA_DCONF_SM_WR:
5914                 bfa_timer_start(dconf->bfa, &dconf->timer,
5915                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5916                 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
5917                 break;
5918         case BFA_DCONF_SM_EXIT:
5919                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5920                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5921                 break;
5922         case BFA_DCONF_SM_INIT:
5923         case BFA_DCONF_SM_IOCDISABLE:
5924                 break;
5925         default:
5926                 bfa_sm_fault(dconf->bfa, event);
5927         }
5928 }
5929
5930 /*
5931  * entries are dirty, write back to the flash.
5932  */
5933
5934 static void
5935 bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5936 {
5937         bfa_trc(dconf->bfa, event);
5938
5939         switch (event) {
5940         case BFA_DCONF_SM_TIMEOUT:
5941                 bfa_sm_set_state(dconf, bfa_dconf_sm_sync);
5942                 bfa_dconf_flash_write(dconf);
5943                 break;
5944         case BFA_DCONF_SM_WR:
5945                 bfa_timer_stop(&dconf->timer);
5946                 bfa_timer_start(dconf->bfa, &dconf->timer,
5947                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5948                 break;
5949         case BFA_DCONF_SM_EXIT:
5950                 bfa_timer_stop(&dconf->timer);
5951                 bfa_timer_start(dconf->bfa, &dconf->timer,
5952                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5953                 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync);
5954                 bfa_dconf_flash_write(dconf);
5955                 break;
5956         case BFA_DCONF_SM_FLASH_COMP:
5957                 break;
5958         case BFA_DCONF_SM_IOCDISABLE:
5959                 bfa_timer_stop(&dconf->timer);
5960                 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty);
5961                 break;
5962         default:
5963                 bfa_sm_fault(dconf->bfa, event);
5964         }
5965 }
5966
5967 /*
5968  * Sync the dconf entries to the flash.
5969  */
5970 static void
5971 bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf,
5972                         enum bfa_dconf_event event)
5973 {
5974         bfa_trc(dconf->bfa, event);
5975
5976         switch (event) {
5977         case BFA_DCONF_SM_IOCDISABLE:
5978         case BFA_DCONF_SM_FLASH_COMP:
5979                 bfa_timer_stop(&dconf->timer);
5980                 fallthrough;
5981         case BFA_DCONF_SM_TIMEOUT:
5982                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5983                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5984                 break;
5985         default:
5986                 bfa_sm_fault(dconf->bfa, event);
5987         }
5988 }
5989
5990 static void
5991 bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5992 {
5993         bfa_trc(dconf->bfa, event);
5994
5995         switch (event) {
5996         case BFA_DCONF_SM_FLASH_COMP:
5997                 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5998                 break;
5999         case BFA_DCONF_SM_WR:
6000                 bfa_timer_start(dconf->bfa, &dconf->timer,
6001                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6002                 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
6003                 break;
6004         case BFA_DCONF_SM_EXIT:
6005                 bfa_timer_start(dconf->bfa, &dconf->timer,
6006                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6007                 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync);
6008                 break;
6009         case BFA_DCONF_SM_IOCDISABLE:
6010                 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty);
6011                 break;
6012         default:
6013                 bfa_sm_fault(dconf->bfa, event);
6014         }
6015 }
6016
6017 static void
6018 bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf,
6019                         enum bfa_dconf_event event)
6020 {
6021         bfa_trc(dconf->bfa, event);
6022
6023         switch (event) {
6024         case BFA_DCONF_SM_INIT:
6025                 bfa_timer_start(dconf->bfa, &dconf->timer,
6026                         bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6027                 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
6028                 break;
6029         case BFA_DCONF_SM_EXIT:
6030                 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
6031                 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
6032                 break;
6033         case BFA_DCONF_SM_IOCDISABLE:
6034                 break;
6035         default:
6036                 bfa_sm_fault(dconf->bfa, event);
6037         }
6038 }
6039
6040 /*
6041  * Compute and return memory needed by DRV_CFG module.
6042  */
6043 void
6044 bfa_dconf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
6045                   struct bfa_s *bfa)
6046 {
6047         struct bfa_mem_kva_s *dconf_kva = BFA_MEM_DCONF_KVA(bfa);
6048
6049         if (cfg->drvcfg.min_cfg)
6050                 bfa_mem_kva_setup(meminfo, dconf_kva,
6051                                 sizeof(struct bfa_dconf_hdr_s));
6052         else
6053                 bfa_mem_kva_setup(meminfo, dconf_kva,
6054                                 sizeof(struct bfa_dconf_s));
6055 }
6056
6057 void
6058 bfa_dconf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg)
6059 {
6060         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6061
6062         dconf->bfad = bfad;
6063         dconf->bfa = bfa;
6064         dconf->instance = bfa->ioc.port_id;
6065         bfa_trc(bfa, dconf->instance);
6066
6067         dconf->dconf = (struct bfa_dconf_s *) bfa_mem_kva_curp(dconf);
6068         if (cfg->drvcfg.min_cfg) {
6069                 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_hdr_s);
6070                 dconf->min_cfg = BFA_TRUE;
6071         } else {
6072                 dconf->min_cfg = BFA_FALSE;
6073                 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_s);
6074         }
6075
6076         bfa_dconf_read_data_valid(bfa) = BFA_FALSE;
6077         bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
6078 }
6079
6080 static void
6081 bfa_dconf_init_cb(void *arg, bfa_status_t status)
6082 {
6083         struct bfa_s *bfa = arg;
6084         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6085
6086         if (status == BFA_STATUS_OK) {
6087                 bfa_dconf_read_data_valid(bfa) = BFA_TRUE;
6088                 if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE)
6089                         dconf->dconf->hdr.signature = BFI_DCONF_SIGNATURE;
6090                 if (dconf->dconf->hdr.version != BFI_DCONF_VERSION)
6091                         dconf->dconf->hdr.version = BFI_DCONF_VERSION;
6092         }
6093         bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
6094         bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE);
6095 }
6096
6097 void
6098 bfa_dconf_modinit(struct bfa_s *bfa)
6099 {
6100         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6101         bfa_sm_send_event(dconf, BFA_DCONF_SM_INIT);
6102 }
6103
6104 static void bfa_dconf_timer(void *cbarg)
6105 {
6106         struct bfa_dconf_mod_s *dconf = cbarg;
6107         bfa_sm_send_event(dconf, BFA_DCONF_SM_TIMEOUT);
6108 }
6109
6110 void
6111 bfa_dconf_iocdisable(struct bfa_s *bfa)
6112 {
6113         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6114         bfa_sm_send_event(dconf, BFA_DCONF_SM_IOCDISABLE);
6115 }
6116
6117 static bfa_status_t
6118 bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf)
6119 {
6120         bfa_status_t bfa_status;
6121         bfa_trc(dconf->bfa, 0);
6122
6123         bfa_status = bfa_flash_update_part(BFA_FLASH(dconf->bfa),
6124                                 BFA_FLASH_PART_DRV, dconf->instance,
6125                                 dconf->dconf,  sizeof(struct bfa_dconf_s), 0,
6126                                 bfa_dconf_cbfn, dconf);
6127         if (bfa_status != BFA_STATUS_OK)
6128                 WARN_ON(bfa_status);
6129         bfa_trc(dconf->bfa, bfa_status);
6130
6131         return bfa_status;
6132 }
6133
6134 bfa_status_t
6135 bfa_dconf_update(struct bfa_s *bfa)
6136 {
6137         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6138         bfa_trc(dconf->bfa, 0);
6139         if (bfa_sm_cmp_state(dconf, bfa_dconf_sm_iocdown_dirty))
6140                 return BFA_STATUS_FAILED;
6141
6142         if (dconf->min_cfg) {
6143                 bfa_trc(dconf->bfa, dconf->min_cfg);
6144                 return BFA_STATUS_FAILED;
6145         }
6146
6147         bfa_sm_send_event(dconf, BFA_DCONF_SM_WR);
6148         return BFA_STATUS_OK;
6149 }
6150
6151 static void
6152 bfa_dconf_cbfn(void *arg, bfa_status_t status)
6153 {
6154         struct bfa_dconf_mod_s *dconf = arg;
6155         WARN_ON(status);
6156         bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
6157 }
6158
6159 void
6160 bfa_dconf_modexit(struct bfa_s *bfa)
6161 {
6162         struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6163         bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT);
6164 }
6165
6166 /*
6167  * FRU specific functions
6168  */
6169
6170 #define BFA_FRU_DMA_BUF_SZ      0x02000         /* 8k dma buffer */
6171 #define BFA_FRU_CHINOOK_MAX_SIZE 0x10000
6172 #define BFA_FRU_LIGHTNING_MAX_SIZE 0x200
6173
6174 static void
6175 bfa_fru_notify(void *cbarg, enum bfa_ioc_event_e event)
6176 {
6177         struct bfa_fru_s *fru = cbarg;
6178
6179         bfa_trc(fru, event);
6180
6181         switch (event) {
6182         case BFA_IOC_E_DISABLED:
6183         case BFA_IOC_E_FAILED:
6184                 if (fru->op_busy) {
6185                         fru->status = BFA_STATUS_IOC_FAILURE;
6186                         fru->cbfn(fru->cbarg, fru->status);
6187                         fru->op_busy = 0;
6188                 }
6189                 break;
6190
6191         default:
6192                 break;
6193         }
6194 }
6195
6196 /*
6197  * Send fru write request.
6198  *
6199  * @param[in] cbarg - callback argument
6200  */
6201 static void
6202 bfa_fru_write_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type)
6203 {
6204         struct bfa_fru_s *fru = cbarg;
6205         struct bfi_fru_write_req_s *msg =
6206                         (struct bfi_fru_write_req_s *) fru->mb.msg;
6207         u32 len;
6208
6209         msg->offset = cpu_to_be32(fru->addr_off + fru->offset);
6210         len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ?
6211                                 fru->residue : BFA_FRU_DMA_BUF_SZ;
6212         msg->length = cpu_to_be32(len);
6213
6214         /*
6215          * indicate if it's the last msg of the whole write operation
6216          */
6217         msg->last = (len == fru->residue) ? 1 : 0;
6218
6219         msg->trfr_cmpl = (len == fru->residue) ? fru->trfr_cmpl : 0;
6220         bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
6221         bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
6222
6223         memcpy(fru->dbuf_kva, fru->ubuf + fru->offset, len);
6224         bfa_ioc_mbox_queue(fru->ioc, &fru->mb);
6225
6226         fru->residue -= len;
6227         fru->offset += len;
6228 }
6229
6230 /*
6231  * Send fru read request.
6232  *
6233  * @param[in] cbarg - callback argument
6234  */
6235 static void
6236 bfa_fru_read_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type)
6237 {
6238         struct bfa_fru_s *fru = cbarg;
6239         struct bfi_fru_read_req_s *msg =
6240                         (struct bfi_fru_read_req_s *) fru->mb.msg;
6241         u32 len;
6242
6243         msg->offset = cpu_to_be32(fru->addr_off + fru->offset);
6244         len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ?
6245                                 fru->residue : BFA_FRU_DMA_BUF_SZ;
6246         msg->length = cpu_to_be32(len);
6247         bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
6248         bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
6249         bfa_ioc_mbox_queue(fru->ioc, &fru->mb);
6250 }
6251
6252 /*
6253  * Flash memory info API.
6254  *
6255  * @param[in] mincfg - minimal cfg variable
6256  */
6257 u32
6258 bfa_fru_meminfo(bfa_boolean_t mincfg)
6259 {
6260         /* min driver doesn't need fru */
6261         if (mincfg)
6262                 return 0;
6263
6264         return BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6265 }
6266
6267 /*
6268  * Flash attach API.
6269  *
6270  * @param[in] fru - fru structure
6271  * @param[in] ioc  - ioc structure
6272  * @param[in] dev  - device structure
6273  * @param[in] trcmod - trace module
6274  * @param[in] logmod - log module
6275  */
6276 void
6277 bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, void *dev,
6278         struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
6279 {
6280         fru->ioc = ioc;
6281         fru->trcmod = trcmod;
6282         fru->cbfn = NULL;
6283         fru->cbarg = NULL;
6284         fru->op_busy = 0;
6285
6286         bfa_ioc_mbox_regisr(fru->ioc, BFI_MC_FRU, bfa_fru_intr, fru);
6287         bfa_q_qe_init(&fru->ioc_notify);
6288         bfa_ioc_notify_init(&fru->ioc_notify, bfa_fru_notify, fru);
6289         list_add_tail(&fru->ioc_notify.qe, &fru->ioc->notify_q);
6290
6291         /* min driver doesn't need fru */
6292         if (mincfg) {
6293                 fru->dbuf_kva = NULL;
6294                 fru->dbuf_pa = 0;
6295         }
6296 }
6297
6298 /*
6299  * Claim memory for fru
6300  *
6301  * @param[in] fru - fru structure
6302  * @param[in] dm_kva - pointer to virtual memory address
6303  * @param[in] dm_pa - frusical memory address
6304  * @param[in] mincfg - minimal cfg variable
6305  */
6306 void
6307 bfa_fru_memclaim(struct bfa_fru_s *fru, u8 *dm_kva, u64 dm_pa,
6308         bfa_boolean_t mincfg)
6309 {
6310         if (mincfg)
6311                 return;
6312
6313         fru->dbuf_kva = dm_kva;
6314         fru->dbuf_pa = dm_pa;
6315         memset(fru->dbuf_kva, 0, BFA_FRU_DMA_BUF_SZ);
6316         dm_kva += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6317         dm_pa += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6318 }
6319
6320 /*
6321  * Update fru vpd image.
6322  *
6323  * @param[in] fru - fru structure
6324  * @param[in] buf - update data buffer
6325  * @param[in] len - data buffer length
6326  * @param[in] offset - offset relative to starting address
6327  * @param[in] cbfn - callback function
6328  * @param[in] cbarg - callback argument
6329  *
6330  * Return status.
6331  */
6332 bfa_status_t
6333 bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6334                   bfa_cb_fru_t cbfn, void *cbarg, u8 trfr_cmpl)
6335 {
6336         bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ);
6337         bfa_trc(fru, len);
6338         bfa_trc(fru, offset);
6339
6340         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2 &&
6341                 fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2)
6342                 return BFA_STATUS_FRU_NOT_PRESENT;
6343
6344         if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK)
6345                 return BFA_STATUS_CMD_NOTSUPP;
6346
6347         if (!bfa_ioc_is_operational(fru->ioc))
6348                 return BFA_STATUS_IOC_NON_OP;
6349
6350         if (fru->op_busy) {
6351                 bfa_trc(fru, fru->op_busy);
6352                 return BFA_STATUS_DEVBUSY;
6353         }
6354
6355         fru->op_busy = 1;
6356
6357         fru->cbfn = cbfn;
6358         fru->cbarg = cbarg;
6359         fru->residue = len;
6360         fru->offset = 0;
6361         fru->addr_off = offset;
6362         fru->ubuf = buf;
6363         fru->trfr_cmpl = trfr_cmpl;
6364
6365         bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ);
6366
6367         return BFA_STATUS_OK;
6368 }
6369
6370 /*
6371  * Read fru vpd image.
6372  *
6373  * @param[in] fru - fru structure
6374  * @param[in] buf - read data buffer
6375  * @param[in] len - data buffer length
6376  * @param[in] offset - offset relative to starting address
6377  * @param[in] cbfn - callback function
6378  * @param[in] cbarg - callback argument
6379  *
6380  * Return status.
6381  */
6382 bfa_status_t
6383 bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6384                 bfa_cb_fru_t cbfn, void *cbarg)
6385 {
6386         bfa_trc(fru, BFI_FRUVPD_H2I_READ_REQ);
6387         bfa_trc(fru, len);
6388         bfa_trc(fru, offset);
6389
6390         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6391                 return BFA_STATUS_FRU_NOT_PRESENT;
6392
6393         if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK &&
6394                 fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2)
6395                 return BFA_STATUS_CMD_NOTSUPP;
6396
6397         if (!bfa_ioc_is_operational(fru->ioc))
6398                 return BFA_STATUS_IOC_NON_OP;
6399
6400         if (fru->op_busy) {
6401                 bfa_trc(fru, fru->op_busy);
6402                 return BFA_STATUS_DEVBUSY;
6403         }
6404
6405         fru->op_busy = 1;
6406
6407         fru->cbfn = cbfn;
6408         fru->cbarg = cbarg;
6409         fru->residue = len;
6410         fru->offset = 0;
6411         fru->addr_off = offset;
6412         fru->ubuf = buf;
6413         bfa_fru_read_send(fru, BFI_FRUVPD_H2I_READ_REQ);
6414
6415         return BFA_STATUS_OK;
6416 }
6417
6418 /*
6419  * Get maximum size fru vpd image.
6420  *
6421  * @param[in] fru - fru structure
6422  * @param[out] size - maximum size of fru vpd data
6423  *
6424  * Return status.
6425  */
6426 bfa_status_t
6427 bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size)
6428 {
6429         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6430                 return BFA_STATUS_FRU_NOT_PRESENT;
6431
6432         if (!bfa_ioc_is_operational(fru->ioc))
6433                 return BFA_STATUS_IOC_NON_OP;
6434
6435         if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK ||
6436                 fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK2)
6437                 *max_size = BFA_FRU_CHINOOK_MAX_SIZE;
6438         else
6439                 return BFA_STATUS_CMD_NOTSUPP;
6440         return BFA_STATUS_OK;
6441 }
6442 /*
6443  * tfru write.
6444  *
6445  * @param[in] fru - fru structure
6446  * @param[in] buf - update data buffer
6447  * @param[in] len - data buffer length
6448  * @param[in] offset - offset relative to starting address
6449  * @param[in] cbfn - callback function
6450  * @param[in] cbarg - callback argument
6451  *
6452  * Return status.
6453  */
6454 bfa_status_t
6455 bfa_tfru_write(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6456                bfa_cb_fru_t cbfn, void *cbarg)
6457 {
6458         bfa_trc(fru, BFI_TFRU_H2I_WRITE_REQ);
6459         bfa_trc(fru, len);
6460         bfa_trc(fru, offset);
6461         bfa_trc(fru, *((u8 *) buf));
6462
6463         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6464                 return BFA_STATUS_FRU_NOT_PRESENT;
6465
6466         if (!bfa_ioc_is_operational(fru->ioc))
6467                 return BFA_STATUS_IOC_NON_OP;
6468
6469         if (fru->op_busy) {
6470                 bfa_trc(fru, fru->op_busy);
6471                 return BFA_STATUS_DEVBUSY;
6472         }
6473
6474         fru->op_busy = 1;
6475
6476         fru->cbfn = cbfn;
6477         fru->cbarg = cbarg;
6478         fru->residue = len;
6479         fru->offset = 0;
6480         fru->addr_off = offset;
6481         fru->ubuf = buf;
6482
6483         bfa_fru_write_send(fru, BFI_TFRU_H2I_WRITE_REQ);
6484
6485         return BFA_STATUS_OK;
6486 }
6487
6488 /*
6489  * tfru read.
6490  *
6491  * @param[in] fru - fru structure
6492  * @param[in] buf - read data buffer
6493  * @param[in] len - data buffer length
6494  * @param[in] offset - offset relative to starting address
6495  * @param[in] cbfn - callback function
6496  * @param[in] cbarg - callback argument
6497  *
6498  * Return status.
6499  */
6500 bfa_status_t
6501 bfa_tfru_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6502               bfa_cb_fru_t cbfn, void *cbarg)
6503 {
6504         bfa_trc(fru, BFI_TFRU_H2I_READ_REQ);
6505         bfa_trc(fru, len);
6506         bfa_trc(fru, offset);
6507
6508         if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6509                 return BFA_STATUS_FRU_NOT_PRESENT;
6510
6511         if (!bfa_ioc_is_operational(fru->ioc))
6512                 return BFA_STATUS_IOC_NON_OP;
6513
6514         if (fru->op_busy) {
6515                 bfa_trc(fru, fru->op_busy);
6516                 return BFA_STATUS_DEVBUSY;
6517         }
6518
6519         fru->op_busy = 1;
6520
6521         fru->cbfn = cbfn;
6522         fru->cbarg = cbarg;
6523         fru->residue = len;
6524         fru->offset = 0;
6525         fru->addr_off = offset;
6526         fru->ubuf = buf;
6527         bfa_fru_read_send(fru, BFI_TFRU_H2I_READ_REQ);
6528
6529         return BFA_STATUS_OK;
6530 }
6531
6532 /*
6533  * Process fru response messages upon receiving interrupts.
6534  *
6535  * @param[in] fruarg - fru structure
6536  * @param[in] msg - message structure
6537  */
6538 void
6539 bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg)
6540 {
6541         struct bfa_fru_s *fru = fruarg;
6542         struct bfi_fru_rsp_s *rsp = (struct bfi_fru_rsp_s *)msg;
6543         u32 status;
6544
6545         bfa_trc(fru, msg->mh.msg_id);
6546
6547         if (!fru->op_busy) {
6548                 /*
6549                  * receiving response after ioc failure
6550                  */
6551                 bfa_trc(fru, 0x9999);
6552                 return;
6553         }
6554
6555         switch (msg->mh.msg_id) {
6556         case BFI_FRUVPD_I2H_WRITE_RSP:
6557         case BFI_TFRU_I2H_WRITE_RSP:
6558                 status = be32_to_cpu(rsp->status);
6559                 bfa_trc(fru, status);
6560
6561                 if (status != BFA_STATUS_OK || fru->residue == 0) {
6562                         fru->status = status;
6563                         fru->op_busy = 0;
6564                         if (fru->cbfn)
6565                                 fru->cbfn(fru->cbarg, fru->status);
6566                 } else {
6567                         bfa_trc(fru, fru->offset);
6568                         if (msg->mh.msg_id == BFI_FRUVPD_I2H_WRITE_RSP)
6569                                 bfa_fru_write_send(fru,
6570                                         BFI_FRUVPD_H2I_WRITE_REQ);
6571                         else
6572                                 bfa_fru_write_send(fru,
6573                                         BFI_TFRU_H2I_WRITE_REQ);
6574                 }
6575                 break;
6576         case BFI_FRUVPD_I2H_READ_RSP:
6577         case BFI_TFRU_I2H_READ_RSP:
6578                 status = be32_to_cpu(rsp->status);
6579                 bfa_trc(fru, status);
6580
6581                 if (status != BFA_STATUS_OK) {
6582                         fru->status = status;
6583                         fru->op_busy = 0;
6584                         if (fru->cbfn)
6585                                 fru->cbfn(fru->cbarg, fru->status);
6586                 } else {
6587                         u32 len = be32_to_cpu(rsp->length);
6588
6589                         bfa_trc(fru, fru->offset);
6590                         bfa_trc(fru, len);
6591
6592                         memcpy(fru->ubuf + fru->offset, fru->dbuf_kva, len);
6593                         fru->residue -= len;
6594                         fru->offset += len;
6595
6596                         if (fru->residue == 0) {
6597                                 fru->status = status;
6598                                 fru->op_busy = 0;
6599                                 if (fru->cbfn)
6600                                         fru->cbfn(fru->cbarg, fru->status);
6601                         } else {
6602                                 if (msg->mh.msg_id == BFI_FRUVPD_I2H_READ_RSP)
6603                                         bfa_fru_read_send(fru,
6604                                                 BFI_FRUVPD_H2I_READ_REQ);
6605                                 else
6606                                         bfa_fru_read_send(fru,
6607                                                 BFI_TFRU_H2I_READ_REQ);
6608                         }
6609                 }
6610                 break;
6611         default:
6612                 WARN_ON(1);
6613         }
6614 }
6615
6616 /*
6617  * register definitions
6618  */
6619 #define FLI_CMD_REG                     0x0001d000
6620 #define FLI_RDDATA_REG                  0x0001d010
6621 #define FLI_ADDR_REG                    0x0001d004
6622 #define FLI_DEV_STATUS_REG              0x0001d014
6623
6624 #define BFA_FLASH_FIFO_SIZE             128     /* fifo size */
6625 #define BFA_FLASH_CHECK_MAX             10000   /* max # of status check */
6626 #define BFA_FLASH_BLOCKING_OP_MAX       1000000 /* max # of blocking op check */
6627 #define BFA_FLASH_WIP_MASK              0x01    /* write in progress bit mask */
6628
6629 enum bfa_flash_cmd {
6630         BFA_FLASH_FAST_READ     = 0x0b, /* fast read */
6631         BFA_FLASH_READ_STATUS   = 0x05, /* read status */
6632 };
6633
6634 /*
6635  * Hardware error definition
6636  */
6637 enum bfa_flash_err {
6638         BFA_FLASH_NOT_PRESENT   = -1,   /*!< flash not present */
6639         BFA_FLASH_UNINIT        = -2,   /*!< flash not initialized */
6640         BFA_FLASH_BAD           = -3,   /*!< flash bad */
6641         BFA_FLASH_BUSY          = -4,   /*!< flash busy */
6642         BFA_FLASH_ERR_CMD_ACT   = -5,   /*!< command active never cleared */
6643         BFA_FLASH_ERR_FIFO_CNT  = -6,   /*!< fifo count never cleared */
6644         BFA_FLASH_ERR_WIP       = -7,   /*!< write-in-progress never cleared */
6645         BFA_FLASH_ERR_TIMEOUT   = -8,   /*!< fli timeout */
6646         BFA_FLASH_ERR_LEN       = -9,   /*!< invalid length */
6647 };
6648
6649 /*
6650  * Flash command register data structure
6651  */
6652 union bfa_flash_cmd_reg_u {
6653         struct {
6654 #ifdef __BIG_ENDIAN
6655                 u32     act:1;
6656                 u32     rsv:1;
6657                 u32     write_cnt:9;
6658                 u32     read_cnt:9;
6659                 u32     addr_cnt:4;
6660                 u32     cmd:8;
6661 #else
6662                 u32     cmd:8;
6663                 u32     addr_cnt:4;
6664                 u32     read_cnt:9;
6665                 u32     write_cnt:9;
6666                 u32     rsv:1;
6667                 u32     act:1;
6668 #endif
6669         } r;
6670         u32     i;
6671 };
6672
6673 /*
6674  * Flash device status register data structure
6675  */
6676 union bfa_flash_dev_status_reg_u {
6677         struct {
6678 #ifdef __BIG_ENDIAN
6679                 u32     rsv:21;
6680                 u32     fifo_cnt:6;
6681                 u32     busy:1;
6682                 u32     init_status:1;
6683                 u32     present:1;
6684                 u32     bad:1;
6685                 u32     good:1;
6686 #else
6687                 u32     good:1;
6688                 u32     bad:1;
6689                 u32     present:1;
6690                 u32     init_status:1;
6691                 u32     busy:1;
6692                 u32     fifo_cnt:6;
6693                 u32     rsv:21;
6694 #endif
6695         } r;
6696         u32     i;
6697 };
6698
6699 /*
6700  * Flash address register data structure
6701  */
6702 union bfa_flash_addr_reg_u {
6703         struct {
6704 #ifdef __BIG_ENDIAN
6705                 u32     addr:24;
6706                 u32     dummy:8;
6707 #else
6708                 u32     dummy:8;
6709                 u32     addr:24;
6710 #endif
6711         } r;
6712         u32     i;
6713 };
6714
6715 /*
6716  * dg flash_raw_private Flash raw private functions
6717  */
6718 static void
6719 bfa_flash_set_cmd(void __iomem *pci_bar, u8 wr_cnt,
6720                   u8 rd_cnt, u8 ad_cnt, u8 op)
6721 {
6722         union bfa_flash_cmd_reg_u cmd;
6723
6724         cmd.i = 0;
6725         cmd.r.act = 1;
6726         cmd.r.write_cnt = wr_cnt;
6727         cmd.r.read_cnt = rd_cnt;
6728         cmd.r.addr_cnt = ad_cnt;
6729         cmd.r.cmd = op;
6730         writel(cmd.i, (pci_bar + FLI_CMD_REG));
6731 }
6732
6733 static void
6734 bfa_flash_set_addr(void __iomem *pci_bar, u32 address)
6735 {
6736         union bfa_flash_addr_reg_u addr;
6737
6738         addr.r.addr = address & 0x00ffffff;
6739         addr.r.dummy = 0;
6740         writel(addr.i, (pci_bar + FLI_ADDR_REG));
6741 }
6742
6743 static int
6744 bfa_flash_cmd_act_check(void __iomem *pci_bar)
6745 {
6746         union bfa_flash_cmd_reg_u cmd;
6747
6748         cmd.i = readl(pci_bar + FLI_CMD_REG);
6749
6750         if (cmd.r.act)
6751                 return BFA_FLASH_ERR_CMD_ACT;
6752
6753         return 0;
6754 }
6755
6756 /*
6757  * @brief
6758  * Flush FLI data fifo.
6759  *
6760  * @param[in] pci_bar - pci bar address
6761  * @param[in] dev_status - device status
6762  *
6763  * Return 0 on success, negative error number on error.
6764  */
6765 static u32
6766 bfa_flash_fifo_flush(void __iomem *pci_bar)
6767 {
6768         u32 i;
6769         union bfa_flash_dev_status_reg_u dev_status;
6770
6771         dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6772
6773         if (!dev_status.r.fifo_cnt)
6774                 return 0;
6775
6776         /* fifo counter in terms of words */
6777         for (i = 0; i < dev_status.r.fifo_cnt; i++)
6778                 readl(pci_bar + FLI_RDDATA_REG);
6779
6780         /*
6781          * Check the device status. It may take some time.
6782          */
6783         for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
6784                 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6785                 if (!dev_status.r.fifo_cnt)
6786                         break;
6787         }
6788
6789         if (dev_status.r.fifo_cnt)
6790                 return BFA_FLASH_ERR_FIFO_CNT;
6791
6792         return 0;
6793 }
6794
6795 /*
6796  * @brief
6797  * Read flash status.
6798  *
6799  * @param[in] pci_bar - pci bar address
6800  *
6801  * Return 0 on success, negative error number on error.
6802 */
6803 static u32
6804 bfa_flash_status_read(void __iomem *pci_bar)
6805 {
6806         union bfa_flash_dev_status_reg_u        dev_status;
6807         int                             status;
6808         u32                     ret_status;
6809         int                             i;
6810
6811         status = bfa_flash_fifo_flush(pci_bar);
6812         if (status < 0)
6813                 return status;
6814
6815         bfa_flash_set_cmd(pci_bar, 0, 4, 0, BFA_FLASH_READ_STATUS);
6816
6817         for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
6818                 status = bfa_flash_cmd_act_check(pci_bar);
6819                 if (!status)
6820                         break;
6821         }
6822
6823         if (status)
6824                 return status;
6825
6826         dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6827         if (!dev_status.r.fifo_cnt)
6828                 return BFA_FLASH_BUSY;
6829
6830         ret_status = readl(pci_bar + FLI_RDDATA_REG);
6831         ret_status >>= 24;
6832
6833         status = bfa_flash_fifo_flush(pci_bar);
6834         if (status < 0)
6835                 return status;
6836
6837         return ret_status;
6838 }
6839
6840 /*
6841  * @brief
6842  * Start flash read operation.
6843  *
6844  * @param[in] pci_bar - pci bar address
6845  * @param[in] offset - flash address offset
6846  * @param[in] len - read data length
6847  * @param[in] buf - read data buffer
6848  *
6849  * Return 0 on success, negative error number on error.
6850  */
6851 static u32
6852 bfa_flash_read_start(void __iomem *pci_bar, u32 offset, u32 len,
6853                          char *buf)
6854 {
6855         int status;
6856
6857         /*
6858          * len must be mutiple of 4 and not exceeding fifo size
6859          */
6860         if (len == 0 || len > BFA_FLASH_FIFO_SIZE || (len & 0x03) != 0)
6861                 return BFA_FLASH_ERR_LEN;
6862
6863         /*
6864          * check status
6865          */
6866         status = bfa_flash_status_read(pci_bar);
6867         if (status == BFA_FLASH_BUSY)
6868                 status = bfa_flash_status_read(pci_bar);
6869
6870         if (status < 0)
6871                 return status;
6872
6873         /*
6874          * check if write-in-progress bit is cleared
6875          */
6876         if (status & BFA_FLASH_WIP_MASK)
6877                 return BFA_FLASH_ERR_WIP;
6878
6879         bfa_flash_set_addr(pci_bar, offset);
6880
6881         bfa_flash_set_cmd(pci_bar, 0, (u8)len, 4, BFA_FLASH_FAST_READ);
6882
6883         return 0;
6884 }
6885
6886 /*
6887  * @brief
6888  * Check flash read operation.
6889  *
6890  * @param[in] pci_bar - pci bar address
6891  *
6892  * Return flash device status, 1 if busy, 0 if not.
6893  */
6894 static u32
6895 bfa_flash_read_check(void __iomem *pci_bar)
6896 {
6897         if (bfa_flash_cmd_act_check(pci_bar))
6898                 return 1;
6899
6900         return 0;
6901 }
6902
6903 /*
6904  * @brief
6905  * End flash read operation.
6906  *
6907  * @param[in] pci_bar - pci bar address
6908  * @param[in] len - read data length
6909  * @param[in] buf - read data buffer
6910  *
6911  */
6912 static void
6913 bfa_flash_read_end(void __iomem *pci_bar, u32 len, char *buf)
6914 {
6915
6916         u32 i;
6917
6918         /*
6919          * read data fifo up to 32 words
6920          */
6921         for (i = 0; i < len; i += 4) {
6922                 u32 w = readl(pci_bar + FLI_RDDATA_REG);
6923                 *((u32 *) (buf + i)) = swab32(w);
6924         }
6925
6926         bfa_flash_fifo_flush(pci_bar);
6927 }
6928
6929 /*
6930  * @brief
6931  * Perform flash raw read.
6932  *
6933  * @param[in] pci_bar - pci bar address
6934  * @param[in] offset - flash partition address offset
6935  * @param[in] buf - read data buffer
6936  * @param[in] len - read data length
6937  *
6938  * Return status.
6939  */
6940
6941
6942 #define FLASH_BLOCKING_OP_MAX   500
6943 #define FLASH_SEM_LOCK_REG      0x18820
6944
6945 static int
6946 bfa_raw_sem_get(void __iomem *bar)
6947 {
6948         int     locked;
6949
6950         locked = readl((bar + FLASH_SEM_LOCK_REG));
6951         return !locked;
6952
6953 }
6954
6955 static bfa_status_t
6956 bfa_flash_sem_get(void __iomem *bar)
6957 {
6958         u32 n = FLASH_BLOCKING_OP_MAX;
6959
6960         while (!bfa_raw_sem_get(bar)) {
6961                 if (--n <= 0)
6962                         return BFA_STATUS_BADFLASH;
6963                 mdelay(10);
6964         }
6965         return BFA_STATUS_OK;
6966 }
6967
6968 static void
6969 bfa_flash_sem_put(void __iomem *bar)
6970 {
6971         writel(0, (bar + FLASH_SEM_LOCK_REG));
6972 }
6973
6974 bfa_status_t
6975 bfa_flash_raw_read(void __iomem *pci_bar, u32 offset, char *buf,
6976                        u32 len)
6977 {
6978         u32 n;
6979         int status;
6980         u32 off, l, s, residue, fifo_sz;
6981
6982         residue = len;
6983         off = 0;
6984         fifo_sz = BFA_FLASH_FIFO_SIZE;
6985         status = bfa_flash_sem_get(pci_bar);
6986         if (status != BFA_STATUS_OK)
6987                 return status;
6988
6989         while (residue) {
6990                 s = offset + off;
6991                 n = s / fifo_sz;
6992                 l = (n + 1) * fifo_sz - s;
6993                 if (l > residue)
6994                         l = residue;
6995
6996                 status = bfa_flash_read_start(pci_bar, offset + off, l,
6997                                                                 &buf[off]);
6998                 if (status < 0) {
6999                         bfa_flash_sem_put(pci_bar);
7000                         return BFA_STATUS_FAILED;
7001                 }
7002
7003                 n = BFA_FLASH_BLOCKING_OP_MAX;
7004                 while (bfa_flash_read_check(pci_bar)) {
7005                         if (--n <= 0) {
7006                                 bfa_flash_sem_put(pci_bar);
7007                                 return BFA_STATUS_FAILED;
7008                         }
7009                 }
7010
7011                 bfa_flash_read_end(pci_bar, l, &buf[off]);
7012
7013                 residue -= l;
7014                 off += l;
7015         }
7016         bfa_flash_sem_put(pci_bar);
7017
7018         return BFA_STATUS_OK;
7019 }