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