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