treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / scsi / bfa / bfa_ioc.c
blob93471d7c61d05d840caf40acff379906058861d4
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
4 * Copyright (c) 2014- QLogic Corporation.
5 * All rights reserved
6 * www.qlogic.com
8 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
9 */
11 #include "bfad_drv.h"
12 #include "bfad_im.h"
13 #include "bfa_ioc.h"
14 #include "bfi_reg.h"
15 #include "bfa_defs.h"
16 #include "bfa_defs_svc.h"
17 #include "bfi.h"
19 BFA_TRC_FILE(CNA, IOC);
22 * IOC local definitions
24 #define BFA_IOC_TOV 3000 /* msecs */
25 #define BFA_IOC_HWSEM_TOV 500 /* msecs */
26 #define BFA_IOC_HB_TOV 500 /* msecs */
27 #define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV
28 #define BFA_IOC_POLL_TOV BFA_TIMER_FREQ
30 #define bfa_ioc_timer_start(__ioc) \
31 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \
32 bfa_ioc_timeout, (__ioc), BFA_IOC_TOV)
33 #define bfa_ioc_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer)
35 #define bfa_hb_timer_start(__ioc) \
36 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->hb_timer, \
37 bfa_ioc_hb_check, (__ioc), BFA_IOC_HB_TOV)
38 #define bfa_hb_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->hb_timer)
40 #define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
42 #define bfa_ioc_state_disabled(__sm) \
43 (((__sm) == BFI_IOC_UNINIT) || \
44 ((__sm) == BFI_IOC_INITING) || \
45 ((__sm) == BFI_IOC_HWINIT) || \
46 ((__sm) == BFI_IOC_DISABLED) || \
47 ((__sm) == BFI_IOC_FAIL) || \
48 ((__sm) == BFI_IOC_CFG_DISABLED))
51 * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
54 #define bfa_ioc_firmware_lock(__ioc) \
55 ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
56 #define bfa_ioc_firmware_unlock(__ioc) \
57 ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
58 #define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
59 #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
60 #define bfa_ioc_notify_fail(__ioc) \
61 ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc))
62 #define bfa_ioc_sync_start(__ioc) \
63 ((__ioc)->ioc_hwif->ioc_sync_start(__ioc))
64 #define bfa_ioc_sync_join(__ioc) \
65 ((__ioc)->ioc_hwif->ioc_sync_join(__ioc))
66 #define bfa_ioc_sync_leave(__ioc) \
67 ((__ioc)->ioc_hwif->ioc_sync_leave(__ioc))
68 #define bfa_ioc_sync_ack(__ioc) \
69 ((__ioc)->ioc_hwif->ioc_sync_ack(__ioc))
70 #define bfa_ioc_sync_complete(__ioc) \
71 ((__ioc)->ioc_hwif->ioc_sync_complete(__ioc))
72 #define bfa_ioc_set_cur_ioc_fwstate(__ioc, __fwstate) \
73 ((__ioc)->ioc_hwif->ioc_set_fwstate(__ioc, __fwstate))
74 #define bfa_ioc_get_cur_ioc_fwstate(__ioc) \
75 ((__ioc)->ioc_hwif->ioc_get_fwstate(__ioc))
76 #define bfa_ioc_set_alt_ioc_fwstate(__ioc, __fwstate) \
77 ((__ioc)->ioc_hwif->ioc_set_alt_fwstate(__ioc, __fwstate))
78 #define bfa_ioc_get_alt_ioc_fwstate(__ioc) \
79 ((__ioc)->ioc_hwif->ioc_get_alt_fwstate(__ioc))
81 #define bfa_ioc_mbox_cmd_pending(__ioc) \
82 (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
83 readl((__ioc)->ioc_regs.hfn_mbox_cmd))
85 bfa_boolean_t bfa_auto_recover = BFA_TRUE;
88 * forward declarations
90 static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
91 static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
92 static void bfa_ioc_timeout(void *ioc);
93 static void bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc);
94 static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc);
95 static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc);
96 static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc);
97 static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc);
98 static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
99 static void bfa_ioc_mbox_flush(struct bfa_ioc_s *ioc);
100 static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
101 static void bfa_ioc_event_notify(struct bfa_ioc_s *ioc ,
102 enum bfa_ioc_event_e event);
103 static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
104 static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
105 static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc);
106 static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc);
107 static enum bfi_ioc_img_ver_cmp_e bfa_ioc_fw_ver_patch_cmp(
108 struct bfi_ioc_image_hdr_s *base_fwhdr,
109 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp);
110 static enum bfi_ioc_img_ver_cmp_e bfa_ioc_flash_fwver_cmp(
111 struct bfa_ioc_s *ioc,
112 struct bfi_ioc_image_hdr_s *base_fwhdr);
115 * IOC state machine definitions/declarations
117 enum ioc_event {
118 IOC_E_RESET = 1, /* IOC reset request */
119 IOC_E_ENABLE = 2, /* IOC enable request */
120 IOC_E_DISABLE = 3, /* IOC disable request */
121 IOC_E_DETACH = 4, /* driver detach cleanup */
122 IOC_E_ENABLED = 5, /* f/w enabled */
123 IOC_E_FWRSP_GETATTR = 6, /* IOC get attribute response */
124 IOC_E_DISABLED = 7, /* f/w disabled */
125 IOC_E_PFFAILED = 8, /* failure notice by iocpf sm */
126 IOC_E_HBFAIL = 9, /* heartbeat failure */
127 IOC_E_HWERROR = 10, /* hardware error interrupt */
128 IOC_E_TIMEOUT = 11, /* timeout */
129 IOC_E_HWFAILED = 12, /* PCI mapping failure notice */
132 bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event);
133 bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
134 bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
135 bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
136 bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
137 bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc_s, enum ioc_event);
138 bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event);
139 bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
140 bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
141 bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc_s, enum ioc_event);
143 static struct bfa_sm_table_s ioc_sm_table[] = {
144 {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT},
145 {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
146 {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING},
147 {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
148 {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
149 {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL},
150 {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
151 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
152 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
153 {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL},
157 * IOCPF state machine definitions/declarations
160 #define bfa_iocpf_timer_start(__ioc) \
161 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \
162 bfa_iocpf_timeout, (__ioc), BFA_IOC_TOV)
163 #define bfa_iocpf_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer)
165 #define bfa_iocpf_poll_timer_start(__ioc) \
166 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \
167 bfa_iocpf_poll_timeout, (__ioc), BFA_IOC_POLL_TOV)
169 #define bfa_sem_timer_start(__ioc) \
170 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->sem_timer, \
171 bfa_iocpf_sem_timeout, (__ioc), BFA_IOC_HWSEM_TOV)
172 #define bfa_sem_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->sem_timer)
175 * Forward declareations for iocpf state machine
177 static void bfa_iocpf_timeout(void *ioc_arg);
178 static void bfa_iocpf_sem_timeout(void *ioc_arg);
179 static void bfa_iocpf_poll_timeout(void *ioc_arg);
182 * IOCPF state machine events
184 enum iocpf_event {
185 IOCPF_E_ENABLE = 1, /* IOCPF enable request */
186 IOCPF_E_DISABLE = 2, /* IOCPF disable request */
187 IOCPF_E_STOP = 3, /* stop on driver detach */
188 IOCPF_E_FWREADY = 4, /* f/w initialization done */
189 IOCPF_E_FWRSP_ENABLE = 5, /* enable f/w response */
190 IOCPF_E_FWRSP_DISABLE = 6, /* disable f/w response */
191 IOCPF_E_FAIL = 7, /* failure notice by ioc sm */
192 IOCPF_E_INITFAIL = 8, /* init fail notice by ioc sm */
193 IOCPF_E_GETATTRFAIL = 9, /* init fail notice by ioc sm */
194 IOCPF_E_SEMLOCKED = 10, /* h/w semaphore is locked */
195 IOCPF_E_TIMEOUT = 11, /* f/w response timeout */
196 IOCPF_E_SEM_ERROR = 12, /* h/w sem mapping error */
200 * IOCPF states
202 enum bfa_iocpf_state {
203 BFA_IOCPF_RESET = 1, /* IOC is in reset state */
204 BFA_IOCPF_SEMWAIT = 2, /* Waiting for IOC h/w semaphore */
205 BFA_IOCPF_HWINIT = 3, /* IOC h/w is being initialized */
206 BFA_IOCPF_READY = 4, /* IOCPF is initialized */
207 BFA_IOCPF_INITFAIL = 5, /* IOCPF failed */
208 BFA_IOCPF_FAIL = 6, /* IOCPF failed */
209 BFA_IOCPF_DISABLING = 7, /* IOCPF is being disabled */
210 BFA_IOCPF_DISABLED = 8, /* IOCPF is disabled */
211 BFA_IOCPF_FWMISMATCH = 9, /* IOC f/w different from drivers */
214 bfa_fsm_state_decl(bfa_iocpf, reset, struct bfa_iocpf_s, enum iocpf_event);
215 bfa_fsm_state_decl(bfa_iocpf, fwcheck, struct bfa_iocpf_s, enum iocpf_event);
216 bfa_fsm_state_decl(bfa_iocpf, mismatch, struct bfa_iocpf_s, enum iocpf_event);
217 bfa_fsm_state_decl(bfa_iocpf, semwait, struct bfa_iocpf_s, enum iocpf_event);
218 bfa_fsm_state_decl(bfa_iocpf, hwinit, struct bfa_iocpf_s, enum iocpf_event);
219 bfa_fsm_state_decl(bfa_iocpf, enabling, struct bfa_iocpf_s, enum iocpf_event);
220 bfa_fsm_state_decl(bfa_iocpf, ready, struct bfa_iocpf_s, enum iocpf_event);
221 bfa_fsm_state_decl(bfa_iocpf, initfail_sync, struct bfa_iocpf_s,
222 enum iocpf_event);
223 bfa_fsm_state_decl(bfa_iocpf, initfail, struct bfa_iocpf_s, enum iocpf_event);
224 bfa_fsm_state_decl(bfa_iocpf, fail_sync, struct bfa_iocpf_s, enum iocpf_event);
225 bfa_fsm_state_decl(bfa_iocpf, fail, struct bfa_iocpf_s, enum iocpf_event);
226 bfa_fsm_state_decl(bfa_iocpf, disabling, struct bfa_iocpf_s, enum iocpf_event);
227 bfa_fsm_state_decl(bfa_iocpf, disabling_sync, struct bfa_iocpf_s,
228 enum iocpf_event);
229 bfa_fsm_state_decl(bfa_iocpf, disabled, struct bfa_iocpf_s, enum iocpf_event);
231 static struct bfa_sm_table_s iocpf_sm_table[] = {
232 {BFA_SM(bfa_iocpf_sm_reset), BFA_IOCPF_RESET},
233 {BFA_SM(bfa_iocpf_sm_fwcheck), BFA_IOCPF_FWMISMATCH},
234 {BFA_SM(bfa_iocpf_sm_mismatch), BFA_IOCPF_FWMISMATCH},
235 {BFA_SM(bfa_iocpf_sm_semwait), BFA_IOCPF_SEMWAIT},
236 {BFA_SM(bfa_iocpf_sm_hwinit), BFA_IOCPF_HWINIT},
237 {BFA_SM(bfa_iocpf_sm_enabling), BFA_IOCPF_HWINIT},
238 {BFA_SM(bfa_iocpf_sm_ready), BFA_IOCPF_READY},
239 {BFA_SM(bfa_iocpf_sm_initfail_sync), BFA_IOCPF_INITFAIL},
240 {BFA_SM(bfa_iocpf_sm_initfail), BFA_IOCPF_INITFAIL},
241 {BFA_SM(bfa_iocpf_sm_fail_sync), BFA_IOCPF_FAIL},
242 {BFA_SM(bfa_iocpf_sm_fail), BFA_IOCPF_FAIL},
243 {BFA_SM(bfa_iocpf_sm_disabling), BFA_IOCPF_DISABLING},
244 {BFA_SM(bfa_iocpf_sm_disabling_sync), BFA_IOCPF_DISABLING},
245 {BFA_SM(bfa_iocpf_sm_disabled), BFA_IOCPF_DISABLED},
249 * IOC State Machine
253 * Beginning state. IOC uninit state.
256 static void
257 bfa_ioc_sm_uninit_entry(struct bfa_ioc_s *ioc)
262 * IOC is in uninit state.
264 static void
265 bfa_ioc_sm_uninit(struct bfa_ioc_s *ioc, enum ioc_event event)
267 bfa_trc(ioc, event);
269 switch (event) {
270 case IOC_E_RESET:
271 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
272 break;
274 default:
275 bfa_sm_fault(ioc, event);
279 * Reset entry actions -- initialize state machine
281 static void
282 bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc)
284 bfa_fsm_set_state(&ioc->iocpf, bfa_iocpf_sm_reset);
288 * IOC is in reset state.
290 static void
291 bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event)
293 bfa_trc(ioc, event);
295 switch (event) {
296 case IOC_E_ENABLE:
297 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
298 break;
300 case IOC_E_DISABLE:
301 bfa_ioc_disable_comp(ioc);
302 break;
304 case IOC_E_DETACH:
305 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
306 break;
308 default:
309 bfa_sm_fault(ioc, event);
314 static void
315 bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
317 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_ENABLE);
321 * Host IOC function is being enabled, awaiting response from firmware.
322 * Semaphore is acquired.
324 static void
325 bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
327 bfa_trc(ioc, event);
329 switch (event) {
330 case IOC_E_ENABLED:
331 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
332 break;
334 case IOC_E_PFFAILED:
335 /* !!! fall through !!! */
336 case IOC_E_HWERROR:
337 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
338 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
339 if (event != IOC_E_PFFAILED)
340 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
341 break;
343 case IOC_E_HWFAILED:
344 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
345 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
346 break;
348 case IOC_E_DISABLE:
349 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
350 break;
352 case IOC_E_DETACH:
353 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
354 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
355 break;
357 case IOC_E_ENABLE:
358 break;
360 default:
361 bfa_sm_fault(ioc, event);
366 static void
367 bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc)
369 bfa_ioc_timer_start(ioc);
370 bfa_ioc_send_getattr(ioc);
374 * IOC configuration in progress. Timer is active.
376 static void
377 bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
379 bfa_trc(ioc, event);
381 switch (event) {
382 case IOC_E_FWRSP_GETATTR:
383 bfa_ioc_timer_stop(ioc);
384 bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
385 break;
387 case IOC_E_PFFAILED:
388 case IOC_E_HWERROR:
389 bfa_ioc_timer_stop(ioc);
390 /* !!! fall through !!! */
391 case IOC_E_TIMEOUT:
392 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
393 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
394 if (event != IOC_E_PFFAILED)
395 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
396 break;
398 case IOC_E_DISABLE:
399 bfa_ioc_timer_stop(ioc);
400 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
401 break;
403 case IOC_E_ENABLE:
404 break;
406 default:
407 bfa_sm_fault(ioc, event);
411 static void
412 bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
414 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
416 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
417 bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
418 bfa_ioc_hb_monitor(ioc);
419 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
420 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE);
423 static void
424 bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
426 bfa_trc(ioc, event);
428 switch (event) {
429 case IOC_E_ENABLE:
430 break;
432 case IOC_E_DISABLE:
433 bfa_hb_timer_stop(ioc);
434 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
435 break;
437 case IOC_E_PFFAILED:
438 case IOC_E_HWERROR:
439 bfa_hb_timer_stop(ioc);
440 /* !!! fall through !!! */
441 case IOC_E_HBFAIL:
442 if (ioc->iocpf.auto_recover)
443 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
444 else
445 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
447 bfa_ioc_fail_notify(ioc);
449 if (event != IOC_E_PFFAILED)
450 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
451 break;
453 default:
454 bfa_sm_fault(ioc, event);
459 static void
460 bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
462 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
463 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_DISABLE);
464 BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n");
465 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_DISABLE);
469 * IOC is being disabled
471 static void
472 bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
474 bfa_trc(ioc, event);
476 switch (event) {
477 case IOC_E_DISABLED:
478 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
479 break;
481 case IOC_E_HWERROR:
483 * No state change. Will move to disabled state
484 * after iocpf sm completes failure processing and
485 * moves to disabled state.
487 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
488 break;
490 case IOC_E_HWFAILED:
491 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
492 bfa_ioc_disable_comp(ioc);
493 break;
495 default:
496 bfa_sm_fault(ioc, event);
501 * IOC disable completion entry.
503 static void
504 bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc)
506 bfa_ioc_disable_comp(ioc);
509 static void
510 bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
512 bfa_trc(ioc, event);
514 switch (event) {
515 case IOC_E_ENABLE:
516 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
517 break;
519 case IOC_E_DISABLE:
520 ioc->cbfn->disable_cbfn(ioc->bfa);
521 break;
523 case IOC_E_DETACH:
524 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
525 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
526 break;
528 default:
529 bfa_sm_fault(ioc, event);
534 static void
535 bfa_ioc_sm_fail_retry_entry(struct bfa_ioc_s *ioc)
537 bfa_trc(ioc, 0);
541 * Hardware initialization retry.
543 static void
544 bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event)
546 bfa_trc(ioc, event);
548 switch (event) {
549 case IOC_E_ENABLED:
550 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
551 break;
553 case IOC_E_PFFAILED:
554 case IOC_E_HWERROR:
556 * Initialization retry failed.
558 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
559 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
560 if (event != IOC_E_PFFAILED)
561 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
562 break;
564 case IOC_E_HWFAILED:
565 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
566 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwfail);
567 break;
569 case IOC_E_ENABLE:
570 break;
572 case IOC_E_DISABLE:
573 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
574 break;
576 case IOC_E_DETACH:
577 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
578 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
579 break;
581 default:
582 bfa_sm_fault(ioc, event);
587 static void
588 bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc)
590 bfa_trc(ioc, 0);
594 * IOC failure.
596 static void
597 bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
599 bfa_trc(ioc, event);
601 switch (event) {
603 case IOC_E_ENABLE:
604 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
605 break;
607 case IOC_E_DISABLE:
608 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
609 break;
611 case IOC_E_DETACH:
612 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
613 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_STOP);
614 break;
616 case IOC_E_HWERROR:
617 case IOC_E_HWFAILED:
619 * HB failure / HW error notification, ignore.
621 break;
622 default:
623 bfa_sm_fault(ioc, event);
627 static void
628 bfa_ioc_sm_hwfail_entry(struct bfa_ioc_s *ioc)
630 bfa_trc(ioc, 0);
633 static void
634 bfa_ioc_sm_hwfail(struct bfa_ioc_s *ioc, enum ioc_event event)
636 bfa_trc(ioc, event);
638 switch (event) {
639 case IOC_E_ENABLE:
640 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
641 break;
643 case IOC_E_DISABLE:
644 ioc->cbfn->disable_cbfn(ioc->bfa);
645 break;
647 case IOC_E_DETACH:
648 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
649 break;
651 case IOC_E_HWERROR:
652 /* Ignore - already in hwfail state */
653 break;
655 default:
656 bfa_sm_fault(ioc, event);
661 * IOCPF State Machine
665 * Reset entry actions -- initialize state machine
667 static void
668 bfa_iocpf_sm_reset_entry(struct bfa_iocpf_s *iocpf)
670 iocpf->fw_mismatch_notified = BFA_FALSE;
671 iocpf->auto_recover = bfa_auto_recover;
675 * Beginning state. IOC is in reset state.
677 static void
678 bfa_iocpf_sm_reset(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
680 struct bfa_ioc_s *ioc = iocpf->ioc;
682 bfa_trc(ioc, event);
684 switch (event) {
685 case IOCPF_E_ENABLE:
686 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
687 break;
689 case IOCPF_E_STOP:
690 break;
692 default:
693 bfa_sm_fault(ioc, event);
698 * Semaphore should be acquired for version check.
700 static void
701 bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf)
703 struct bfi_ioc_image_hdr_s fwhdr;
704 u32 r32, fwstate, pgnum, pgoff, loff = 0;
705 int i;
708 * Spin on init semaphore to serialize.
710 r32 = readl(iocpf->ioc->ioc_regs.ioc_init_sem_reg);
711 while (r32 & 0x1) {
712 udelay(20);
713 r32 = readl(iocpf->ioc->ioc_regs.ioc_init_sem_reg);
716 /* h/w sem init */
717 fwstate = bfa_ioc_get_cur_ioc_fwstate(iocpf->ioc);
718 if (fwstate == BFI_IOC_UNINIT) {
719 writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
720 goto sem_get;
723 bfa_ioc_fwver_get(iocpf->ioc, &fwhdr);
725 if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) {
726 writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
727 goto sem_get;
731 * Clear fwver hdr
733 pgnum = PSS_SMEM_PGNUM(iocpf->ioc->ioc_regs.smem_pg0, loff);
734 pgoff = PSS_SMEM_PGOFF(loff);
735 writel(pgnum, iocpf->ioc->ioc_regs.host_page_num_fn);
737 for (i = 0; i < sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32); i++) {
738 bfa_mem_write(iocpf->ioc->ioc_regs.smem_page_start, loff, 0);
739 loff += sizeof(u32);
742 bfa_trc(iocpf->ioc, fwstate);
743 bfa_trc(iocpf->ioc, swab32(fwhdr.exec));
744 bfa_ioc_set_cur_ioc_fwstate(iocpf->ioc, BFI_IOC_UNINIT);
745 bfa_ioc_set_alt_ioc_fwstate(iocpf->ioc, BFI_IOC_UNINIT);
748 * Unlock the hw semaphore. Should be here only once per boot.
750 bfa_ioc_ownership_reset(iocpf->ioc);
753 * unlock init semaphore.
755 writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
757 sem_get:
758 bfa_ioc_hw_sem_get(iocpf->ioc);
762 * Awaiting h/w semaphore to continue with version check.
764 static void
765 bfa_iocpf_sm_fwcheck(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
767 struct bfa_ioc_s *ioc = iocpf->ioc;
769 bfa_trc(ioc, event);
771 switch (event) {
772 case IOCPF_E_SEMLOCKED:
773 if (bfa_ioc_firmware_lock(ioc)) {
774 if (bfa_ioc_sync_start(ioc)) {
775 bfa_ioc_sync_join(ioc);
776 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
777 } else {
778 bfa_ioc_firmware_unlock(ioc);
779 writel(1, ioc->ioc_regs.ioc_sem_reg);
780 bfa_sem_timer_start(ioc);
782 } else {
783 writel(1, ioc->ioc_regs.ioc_sem_reg);
784 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_mismatch);
786 break;
788 case IOCPF_E_SEM_ERROR:
789 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
790 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
791 break;
793 case IOCPF_E_DISABLE:
794 bfa_sem_timer_stop(ioc);
795 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
796 bfa_fsm_send_event(ioc, IOC_E_DISABLED);
797 break;
799 case IOCPF_E_STOP:
800 bfa_sem_timer_stop(ioc);
801 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
802 break;
804 default:
805 bfa_sm_fault(ioc, event);
810 * Notify enable completion callback.
812 static void
813 bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf_s *iocpf)
816 * Call only the first time sm enters fwmismatch state.
818 if (iocpf->fw_mismatch_notified == BFA_FALSE)
819 bfa_ioc_pf_fwmismatch(iocpf->ioc);
821 iocpf->fw_mismatch_notified = BFA_TRUE;
822 bfa_iocpf_timer_start(iocpf->ioc);
826 * Awaiting firmware version match.
828 static void
829 bfa_iocpf_sm_mismatch(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
831 struct bfa_ioc_s *ioc = iocpf->ioc;
833 bfa_trc(ioc, event);
835 switch (event) {
836 case IOCPF_E_TIMEOUT:
837 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fwcheck);
838 break;
840 case IOCPF_E_DISABLE:
841 bfa_iocpf_timer_stop(ioc);
842 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
843 bfa_fsm_send_event(ioc, IOC_E_DISABLED);
844 break;
846 case IOCPF_E_STOP:
847 bfa_iocpf_timer_stop(ioc);
848 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
849 break;
851 default:
852 bfa_sm_fault(ioc, event);
857 * Request for semaphore.
859 static void
860 bfa_iocpf_sm_semwait_entry(struct bfa_iocpf_s *iocpf)
862 bfa_ioc_hw_sem_get(iocpf->ioc);
866 * Awaiting semaphore for h/w initialzation.
868 static void
869 bfa_iocpf_sm_semwait(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
871 struct bfa_ioc_s *ioc = iocpf->ioc;
873 bfa_trc(ioc, event);
875 switch (event) {
876 case IOCPF_E_SEMLOCKED:
877 if (bfa_ioc_sync_complete(ioc)) {
878 bfa_ioc_sync_join(ioc);
879 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
880 } else {
881 writel(1, ioc->ioc_regs.ioc_sem_reg);
882 bfa_sem_timer_start(ioc);
884 break;
886 case IOCPF_E_SEM_ERROR:
887 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
888 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
889 break;
891 case IOCPF_E_DISABLE:
892 bfa_sem_timer_stop(ioc);
893 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
894 break;
896 default:
897 bfa_sm_fault(ioc, event);
901 static void
902 bfa_iocpf_sm_hwinit_entry(struct bfa_iocpf_s *iocpf)
904 iocpf->poll_time = 0;
905 bfa_ioc_hwinit(iocpf->ioc, BFA_FALSE);
909 * Hardware is being initialized. Interrupts are enabled.
910 * Holding hardware semaphore lock.
912 static void
913 bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
915 struct bfa_ioc_s *ioc = iocpf->ioc;
917 bfa_trc(ioc, event);
919 switch (event) {
920 case IOCPF_E_FWREADY:
921 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_enabling);
922 break;
924 case IOCPF_E_TIMEOUT:
925 writel(1, ioc->ioc_regs.ioc_sem_reg);
926 bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
927 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
928 break;
930 case IOCPF_E_DISABLE:
931 bfa_iocpf_timer_stop(ioc);
932 bfa_ioc_sync_leave(ioc);
933 writel(1, ioc->ioc_regs.ioc_sem_reg);
934 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
935 break;
937 default:
938 bfa_sm_fault(ioc, event);
942 static void
943 bfa_iocpf_sm_enabling_entry(struct bfa_iocpf_s *iocpf)
945 bfa_iocpf_timer_start(iocpf->ioc);
947 * Enable Interrupts before sending fw IOC ENABLE cmd.
949 iocpf->ioc->cbfn->reset_cbfn(iocpf->ioc->bfa);
950 bfa_ioc_send_enable(iocpf->ioc);
954 * Host IOC function is being enabled, awaiting response from firmware.
955 * Semaphore is acquired.
957 static void
958 bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
960 struct bfa_ioc_s *ioc = iocpf->ioc;
962 bfa_trc(ioc, event);
964 switch (event) {
965 case IOCPF_E_FWRSP_ENABLE:
966 bfa_iocpf_timer_stop(ioc);
967 writel(1, ioc->ioc_regs.ioc_sem_reg);
968 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_ready);
969 break;
971 case IOCPF_E_INITFAIL:
972 bfa_iocpf_timer_stop(ioc);
973 /* fall through */
975 case IOCPF_E_TIMEOUT:
976 writel(1, ioc->ioc_regs.ioc_sem_reg);
977 if (event == IOCPF_E_TIMEOUT)
978 bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
979 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
980 break;
982 case IOCPF_E_DISABLE:
983 bfa_iocpf_timer_stop(ioc);
984 writel(1, ioc->ioc_regs.ioc_sem_reg);
985 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
986 break;
988 default:
989 bfa_sm_fault(ioc, event);
993 static void
994 bfa_iocpf_sm_ready_entry(struct bfa_iocpf_s *iocpf)
996 bfa_fsm_send_event(iocpf->ioc, IOC_E_ENABLED);
999 static void
1000 bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1002 struct bfa_ioc_s *ioc = iocpf->ioc;
1004 bfa_trc(ioc, event);
1006 switch (event) {
1007 case IOCPF_E_DISABLE:
1008 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling);
1009 break;
1011 case IOCPF_E_GETATTRFAIL:
1012 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail_sync);
1013 break;
1015 case IOCPF_E_FAIL:
1016 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail_sync);
1017 break;
1019 default:
1020 bfa_sm_fault(ioc, event);
1024 static void
1025 bfa_iocpf_sm_disabling_entry(struct bfa_iocpf_s *iocpf)
1027 bfa_iocpf_timer_start(iocpf->ioc);
1028 bfa_ioc_send_disable(iocpf->ioc);
1032 * IOC is being disabled
1034 static void
1035 bfa_iocpf_sm_disabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1037 struct bfa_ioc_s *ioc = iocpf->ioc;
1039 bfa_trc(ioc, event);
1041 switch (event) {
1042 case IOCPF_E_FWRSP_DISABLE:
1043 bfa_iocpf_timer_stop(ioc);
1044 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1045 break;
1047 case IOCPF_E_FAIL:
1048 bfa_iocpf_timer_stop(ioc);
1049 /* fall through */
1051 case IOCPF_E_TIMEOUT:
1052 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
1053 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1054 break;
1056 case IOCPF_E_FWRSP_ENABLE:
1057 break;
1059 default:
1060 bfa_sm_fault(ioc, event);
1064 static void
1065 bfa_iocpf_sm_disabling_sync_entry(struct bfa_iocpf_s *iocpf)
1067 bfa_ioc_hw_sem_get(iocpf->ioc);
1071 * IOC hb ack request is being removed.
1073 static void
1074 bfa_iocpf_sm_disabling_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1076 struct bfa_ioc_s *ioc = iocpf->ioc;
1078 bfa_trc(ioc, event);
1080 switch (event) {
1081 case IOCPF_E_SEMLOCKED:
1082 bfa_ioc_sync_leave(ioc);
1083 writel(1, ioc->ioc_regs.ioc_sem_reg);
1084 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1085 break;
1087 case IOCPF_E_SEM_ERROR:
1088 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1089 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1090 break;
1092 case IOCPF_E_FAIL:
1093 break;
1095 default:
1096 bfa_sm_fault(ioc, event);
1101 * IOC disable completion entry.
1103 static void
1104 bfa_iocpf_sm_disabled_entry(struct bfa_iocpf_s *iocpf)
1106 bfa_ioc_mbox_flush(iocpf->ioc);
1107 bfa_fsm_send_event(iocpf->ioc, IOC_E_DISABLED);
1110 static void
1111 bfa_iocpf_sm_disabled(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1113 struct bfa_ioc_s *ioc = iocpf->ioc;
1115 bfa_trc(ioc, event);
1117 switch (event) {
1118 case IOCPF_E_ENABLE:
1119 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
1120 break;
1122 case IOCPF_E_STOP:
1123 bfa_ioc_firmware_unlock(ioc);
1124 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
1125 break;
1127 default:
1128 bfa_sm_fault(ioc, event);
1132 static void
1133 bfa_iocpf_sm_initfail_sync_entry(struct bfa_iocpf_s *iocpf)
1135 bfa_ioc_debug_save_ftrc(iocpf->ioc);
1136 bfa_ioc_hw_sem_get(iocpf->ioc);
1140 * Hardware initialization failed.
1142 static void
1143 bfa_iocpf_sm_initfail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1145 struct bfa_ioc_s *ioc = iocpf->ioc;
1147 bfa_trc(ioc, event);
1149 switch (event) {
1150 case IOCPF_E_SEMLOCKED:
1151 bfa_ioc_notify_fail(ioc);
1152 bfa_ioc_sync_leave(ioc);
1153 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
1154 writel(1, ioc->ioc_regs.ioc_sem_reg);
1155 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
1156 break;
1158 case IOCPF_E_SEM_ERROR:
1159 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1160 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1161 break;
1163 case IOCPF_E_DISABLE:
1164 bfa_sem_timer_stop(ioc);
1165 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1166 break;
1168 case IOCPF_E_STOP:
1169 bfa_sem_timer_stop(ioc);
1170 bfa_ioc_firmware_unlock(ioc);
1171 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
1172 break;
1174 case IOCPF_E_FAIL:
1175 break;
1177 default:
1178 bfa_sm_fault(ioc, event);
1182 static void
1183 bfa_iocpf_sm_initfail_entry(struct bfa_iocpf_s *iocpf)
1185 bfa_trc(iocpf->ioc, 0);
1189 * Hardware initialization failed.
1191 static void
1192 bfa_iocpf_sm_initfail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1194 struct bfa_ioc_s *ioc = iocpf->ioc;
1196 bfa_trc(ioc, event);
1198 switch (event) {
1199 case IOCPF_E_DISABLE:
1200 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1201 break;
1203 case IOCPF_E_STOP:
1204 bfa_ioc_firmware_unlock(ioc);
1205 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_reset);
1206 break;
1208 default:
1209 bfa_sm_fault(ioc, event);
1213 static void
1214 bfa_iocpf_sm_fail_sync_entry(struct bfa_iocpf_s *iocpf)
1217 * Mark IOC as failed in hardware and stop firmware.
1219 bfa_ioc_lpu_stop(iocpf->ioc);
1222 * Flush any queued up mailbox requests.
1224 bfa_ioc_mbox_flush(iocpf->ioc);
1226 bfa_ioc_hw_sem_get(iocpf->ioc);
1229 static void
1230 bfa_iocpf_sm_fail_sync(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1232 struct bfa_ioc_s *ioc = iocpf->ioc;
1234 bfa_trc(ioc, event);
1236 switch (event) {
1237 case IOCPF_E_SEMLOCKED:
1238 bfa_ioc_sync_ack(ioc);
1239 bfa_ioc_notify_fail(ioc);
1240 if (!iocpf->auto_recover) {
1241 bfa_ioc_sync_leave(ioc);
1242 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
1243 writel(1, ioc->ioc_regs.ioc_sem_reg);
1244 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1245 } else {
1246 if (bfa_ioc_sync_complete(ioc))
1247 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
1248 else {
1249 writel(1, ioc->ioc_regs.ioc_sem_reg);
1250 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_semwait);
1253 break;
1255 case IOCPF_E_SEM_ERROR:
1256 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
1257 bfa_fsm_send_event(ioc, IOC_E_HWFAILED);
1258 break;
1260 case IOCPF_E_DISABLE:
1261 bfa_sem_timer_stop(ioc);
1262 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
1263 break;
1265 case IOCPF_E_FAIL:
1266 break;
1268 default:
1269 bfa_sm_fault(ioc, event);
1273 static void
1274 bfa_iocpf_sm_fail_entry(struct bfa_iocpf_s *iocpf)
1276 bfa_trc(iocpf->ioc, 0);
1280 * IOC is in failed state.
1282 static void
1283 bfa_iocpf_sm_fail(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
1285 struct bfa_ioc_s *ioc = iocpf->ioc;
1287 bfa_trc(ioc, event);
1289 switch (event) {
1290 case IOCPF_E_DISABLE:
1291 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabled);
1292 break;
1294 default:
1295 bfa_sm_fault(ioc, event);
1300 * BFA IOC private functions
1304 * Notify common modules registered for notification.
1306 static void
1307 bfa_ioc_event_notify(struct bfa_ioc_s *ioc, enum bfa_ioc_event_e event)
1309 struct bfa_ioc_notify_s *notify;
1310 struct list_head *qe;
1312 list_for_each(qe, &ioc->notify_q) {
1313 notify = (struct bfa_ioc_notify_s *)qe;
1314 notify->cbfn(notify->cbarg, event);
1318 static void
1319 bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
1321 ioc->cbfn->disable_cbfn(ioc->bfa);
1322 bfa_ioc_event_notify(ioc, BFA_IOC_E_DISABLED);
1325 bfa_boolean_t
1326 bfa_ioc_sem_get(void __iomem *sem_reg)
1328 u32 r32;
1329 int cnt = 0;
1330 #define BFA_SEM_SPINCNT 3000
1332 r32 = readl(sem_reg);
1334 while ((r32 & 1) && (cnt < BFA_SEM_SPINCNT)) {
1335 cnt++;
1336 udelay(2);
1337 r32 = readl(sem_reg);
1340 if (!(r32 & 1))
1341 return BFA_TRUE;
1343 return BFA_FALSE;
1346 static void
1347 bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
1349 u32 r32;
1352 * First read to the semaphore register will return 0, subsequent reads
1353 * will return 1. Semaphore is released by writing 1 to the register
1355 r32 = readl(ioc->ioc_regs.ioc_sem_reg);
1356 if (r32 == ~0) {
1357 WARN_ON(r32 == ~0);
1358 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEM_ERROR);
1359 return;
1361 if (!(r32 & 1)) {
1362 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_SEMLOCKED);
1363 return;
1366 bfa_sem_timer_start(ioc);
1370 * Initialize LPU local memory (aka secondary memory / SRAM)
1372 static void
1373 bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
1375 u32 pss_ctl;
1376 int i;
1377 #define PSS_LMEM_INIT_TIME 10000
1379 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1380 pss_ctl &= ~__PSS_LMEM_RESET;
1381 pss_ctl |= __PSS_LMEM_INIT_EN;
1384 * i2c workaround 12.5khz clock
1386 pss_ctl |= __PSS_I2C_CLK_DIV(3UL);
1387 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1390 * wait for memory initialization to be complete
1392 i = 0;
1393 do {
1394 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1395 i++;
1396 } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
1399 * If memory initialization is not successful, IOC timeout will catch
1400 * such failures.
1402 WARN_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE));
1403 bfa_trc(ioc, pss_ctl);
1405 pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
1406 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1409 static void
1410 bfa_ioc_lpu_start(struct bfa_ioc_s *ioc)
1412 u32 pss_ctl;
1415 * Take processor out of reset.
1417 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1418 pss_ctl &= ~__PSS_LPU0_RESET;
1420 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1423 static void
1424 bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
1426 u32 pss_ctl;
1429 * Put processors in reset.
1431 pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg);
1432 pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
1434 writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg);
1438 * Get driver and firmware versions.
1440 void
1441 bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
1443 u32 pgnum, pgoff;
1444 u32 loff = 0;
1445 int i;
1446 u32 *fwsig = (u32 *) fwhdr;
1448 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1449 pgoff = PSS_SMEM_PGOFF(loff);
1450 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1452 for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
1453 i++) {
1454 fwsig[i] =
1455 bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
1456 loff += sizeof(u32);
1461 * Returns TRUE if driver is willing to work with current smem f/w version.
1463 bfa_boolean_t
1464 bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
1465 struct bfi_ioc_image_hdr_s *smem_fwhdr)
1467 struct bfi_ioc_image_hdr_s *drv_fwhdr;
1468 enum bfi_ioc_img_ver_cmp_e smem_flash_cmp, drv_smem_cmp;
1470 drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
1471 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
1474 * If smem is incompatible or old, driver should not work with it.
1476 drv_smem_cmp = bfa_ioc_fw_ver_patch_cmp(drv_fwhdr, smem_fwhdr);
1477 if (drv_smem_cmp == BFI_IOC_IMG_VER_INCOMP ||
1478 drv_smem_cmp == BFI_IOC_IMG_VER_OLD) {
1479 return BFA_FALSE;
1483 * IF Flash has a better F/W than smem do not work with smem.
1484 * If smem f/w == flash f/w, as smem f/w not old | incmp, work with it.
1485 * If Flash is old or incomp work with smem iff smem f/w == drv f/w.
1487 smem_flash_cmp = bfa_ioc_flash_fwver_cmp(ioc, smem_fwhdr);
1489 if (smem_flash_cmp == BFI_IOC_IMG_VER_BETTER) {
1490 return BFA_FALSE;
1491 } else if (smem_flash_cmp == BFI_IOC_IMG_VER_SAME) {
1492 return BFA_TRUE;
1493 } else {
1494 return (drv_smem_cmp == BFI_IOC_IMG_VER_SAME) ?
1495 BFA_TRUE : BFA_FALSE;
1500 * Return true if current running version is valid. Firmware signature and
1501 * execution context (driver/bios) must match.
1503 static bfa_boolean_t
1504 bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
1506 struct bfi_ioc_image_hdr_s fwhdr;
1508 bfa_ioc_fwver_get(ioc, &fwhdr);
1510 if (swab32(fwhdr.bootenv) != boot_env) {
1511 bfa_trc(ioc, fwhdr.bootenv);
1512 bfa_trc(ioc, boot_env);
1513 return BFA_FALSE;
1516 return bfa_ioc_fwver_cmp(ioc, &fwhdr);
1519 static bfa_boolean_t
1520 bfa_ioc_fwver_md5_check(struct bfi_ioc_image_hdr_s *fwhdr_1,
1521 struct bfi_ioc_image_hdr_s *fwhdr_2)
1523 int i;
1525 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++)
1526 if (fwhdr_1->md5sum[i] != fwhdr_2->md5sum[i])
1527 return BFA_FALSE;
1529 return BFA_TRUE;
1533 * Returns TRUE if major minor and maintainence are same.
1534 * If patch versions are same, check for MD5 Checksum to be same.
1536 static bfa_boolean_t
1537 bfa_ioc_fw_ver_compatible(struct bfi_ioc_image_hdr_s *drv_fwhdr,
1538 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp)
1540 if (drv_fwhdr->signature != fwhdr_to_cmp->signature)
1541 return BFA_FALSE;
1543 if (drv_fwhdr->fwver.major != fwhdr_to_cmp->fwver.major)
1544 return BFA_FALSE;
1546 if (drv_fwhdr->fwver.minor != fwhdr_to_cmp->fwver.minor)
1547 return BFA_FALSE;
1549 if (drv_fwhdr->fwver.maint != fwhdr_to_cmp->fwver.maint)
1550 return BFA_FALSE;
1552 if (drv_fwhdr->fwver.patch == fwhdr_to_cmp->fwver.patch &&
1553 drv_fwhdr->fwver.phase == fwhdr_to_cmp->fwver.phase &&
1554 drv_fwhdr->fwver.build == fwhdr_to_cmp->fwver.build) {
1555 return bfa_ioc_fwver_md5_check(drv_fwhdr, fwhdr_to_cmp);
1558 return BFA_TRUE;
1561 static bfa_boolean_t
1562 bfa_ioc_flash_fwver_valid(struct bfi_ioc_image_hdr_s *flash_fwhdr)
1564 if (flash_fwhdr->fwver.major == 0 || flash_fwhdr->fwver.major == 0xFF)
1565 return BFA_FALSE;
1567 return BFA_TRUE;
1570 static bfa_boolean_t fwhdr_is_ga(struct bfi_ioc_image_hdr_s *fwhdr)
1572 if (fwhdr->fwver.phase == 0 &&
1573 fwhdr->fwver.build == 0)
1574 return BFA_TRUE;
1576 return BFA_FALSE;
1580 * Returns TRUE if both are compatible and patch of fwhdr_to_cmp is better.
1582 static enum bfi_ioc_img_ver_cmp_e
1583 bfa_ioc_fw_ver_patch_cmp(struct bfi_ioc_image_hdr_s *base_fwhdr,
1584 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp)
1586 if (bfa_ioc_fw_ver_compatible(base_fwhdr, fwhdr_to_cmp) == BFA_FALSE)
1587 return BFI_IOC_IMG_VER_INCOMP;
1589 if (fwhdr_to_cmp->fwver.patch > base_fwhdr->fwver.patch)
1590 return BFI_IOC_IMG_VER_BETTER;
1592 else if (fwhdr_to_cmp->fwver.patch < base_fwhdr->fwver.patch)
1593 return BFI_IOC_IMG_VER_OLD;
1596 * GA takes priority over internal builds of the same patch stream.
1597 * At this point major minor maint and patch numbers are same.
1600 if (fwhdr_is_ga(base_fwhdr) == BFA_TRUE) {
1601 if (fwhdr_is_ga(fwhdr_to_cmp))
1602 return BFI_IOC_IMG_VER_SAME;
1603 else
1604 return BFI_IOC_IMG_VER_OLD;
1605 } else {
1606 if (fwhdr_is_ga(fwhdr_to_cmp))
1607 return BFI_IOC_IMG_VER_BETTER;
1610 if (fwhdr_to_cmp->fwver.phase > base_fwhdr->fwver.phase)
1611 return BFI_IOC_IMG_VER_BETTER;
1612 else if (fwhdr_to_cmp->fwver.phase < base_fwhdr->fwver.phase)
1613 return BFI_IOC_IMG_VER_OLD;
1615 if (fwhdr_to_cmp->fwver.build > base_fwhdr->fwver.build)
1616 return BFI_IOC_IMG_VER_BETTER;
1617 else if (fwhdr_to_cmp->fwver.build < base_fwhdr->fwver.build)
1618 return BFI_IOC_IMG_VER_OLD;
1621 * All Version Numbers are equal.
1622 * Md5 check to be done as a part of compatibility check.
1624 return BFI_IOC_IMG_VER_SAME;
1627 #define BFA_FLASH_PART_FWIMG_ADDR 0x100000 /* fw image address */
1629 bfa_status_t
1630 bfa_ioc_flash_img_get_chnk(struct bfa_ioc_s *ioc, u32 off,
1631 u32 *fwimg)
1633 return bfa_flash_raw_read(ioc->pcidev.pci_bar_kva,
1634 BFA_FLASH_PART_FWIMG_ADDR + (off * sizeof(u32)),
1635 (char *)fwimg, BFI_FLASH_CHUNK_SZ);
1638 static enum bfi_ioc_img_ver_cmp_e
1639 bfa_ioc_flash_fwver_cmp(struct bfa_ioc_s *ioc,
1640 struct bfi_ioc_image_hdr_s *base_fwhdr)
1642 struct bfi_ioc_image_hdr_s *flash_fwhdr;
1643 bfa_status_t status;
1644 u32 fwimg[BFI_FLASH_CHUNK_SZ_WORDS];
1646 status = bfa_ioc_flash_img_get_chnk(ioc, 0, fwimg);
1647 if (status != BFA_STATUS_OK)
1648 return BFI_IOC_IMG_VER_INCOMP;
1650 flash_fwhdr = (struct bfi_ioc_image_hdr_s *) fwimg;
1651 if (bfa_ioc_flash_fwver_valid(flash_fwhdr) == BFA_TRUE)
1652 return bfa_ioc_fw_ver_patch_cmp(base_fwhdr, flash_fwhdr);
1653 else
1654 return BFI_IOC_IMG_VER_INCOMP;
1659 * Invalidate fwver signature
1661 bfa_status_t
1662 bfa_ioc_fwsig_invalidate(struct bfa_ioc_s *ioc)
1665 u32 pgnum, pgoff;
1666 u32 loff = 0;
1667 enum bfi_ioc_state ioc_fwstate;
1669 ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
1670 if (!bfa_ioc_state_disabled(ioc_fwstate))
1671 return BFA_STATUS_ADAPTER_ENABLED;
1673 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1674 pgoff = PSS_SMEM_PGOFF(loff);
1675 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1676 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, BFA_IOC_FW_INV_SIGN);
1678 return BFA_STATUS_OK;
1682 * Conditionally flush any pending message from firmware at start.
1684 static void
1685 bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
1687 u32 r32;
1689 r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
1690 if (r32)
1691 writel(1, ioc->ioc_regs.lpu_mbox_cmd);
1694 static void
1695 bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1697 enum bfi_ioc_state ioc_fwstate;
1698 bfa_boolean_t fwvalid;
1699 u32 boot_type;
1700 u32 boot_env;
1702 ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
1704 if (force)
1705 ioc_fwstate = BFI_IOC_UNINIT;
1707 bfa_trc(ioc, ioc_fwstate);
1709 boot_type = BFI_FWBOOT_TYPE_NORMAL;
1710 boot_env = BFI_FWBOOT_ENV_OS;
1713 * check if firmware is valid
1715 fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
1716 BFA_FALSE : bfa_ioc_fwver_valid(ioc, boot_env);
1718 if (!fwvalid) {
1719 if (bfa_ioc_boot(ioc, boot_type, boot_env) == BFA_STATUS_OK)
1720 bfa_ioc_poll_fwinit(ioc);
1721 return;
1725 * If hardware initialization is in progress (initialized by other IOC),
1726 * just wait for an initialization completion interrupt.
1728 if (ioc_fwstate == BFI_IOC_INITING) {
1729 bfa_ioc_poll_fwinit(ioc);
1730 return;
1734 * If IOC function is disabled and firmware version is same,
1735 * just re-enable IOC.
1737 * If option rom, IOC must not be in operational state. With
1738 * convergence, IOC will be in operational state when 2nd driver
1739 * is loaded.
1741 if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
1744 * When using MSI-X any pending firmware ready event should
1745 * be flushed. Otherwise MSI-X interrupts are not delivered.
1747 bfa_ioc_msgflush(ioc);
1748 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
1749 return;
1753 * Initialize the h/w for any other states.
1755 if (bfa_ioc_boot(ioc, boot_type, boot_env) == BFA_STATUS_OK)
1756 bfa_ioc_poll_fwinit(ioc);
1759 static void
1760 bfa_ioc_timeout(void *ioc_arg)
1762 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg;
1764 bfa_trc(ioc, 0);
1765 bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
1768 void
1769 bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len)
1771 u32 *msgp = (u32 *) ioc_msg;
1772 u32 i;
1774 bfa_trc(ioc, msgp[0]);
1775 bfa_trc(ioc, len);
1777 WARN_ON(len > BFI_IOC_MSGLEN_MAX);
1780 * first write msg to mailbox registers
1782 for (i = 0; i < len / sizeof(u32); i++)
1783 writel(cpu_to_le32(msgp[i]),
1784 ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
1786 for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
1787 writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32));
1790 * write 1 to mailbox CMD to trigger LPU event
1792 writel(1, ioc->ioc_regs.hfn_mbox_cmd);
1793 (void) readl(ioc->ioc_regs.hfn_mbox_cmd);
1796 static void
1797 bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
1799 struct bfi_ioc_ctrl_req_s enable_req;
1801 bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
1802 bfa_ioc_portid(ioc));
1803 enable_req.clscode = cpu_to_be16(ioc->clscode);
1804 /* unsigned 32-bit time_t overflow in y2106 */
1805 enable_req.tv_sec = be32_to_cpu(ktime_get_real_seconds());
1806 bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1809 static void
1810 bfa_ioc_send_disable(struct bfa_ioc_s *ioc)
1812 struct bfi_ioc_ctrl_req_s disable_req;
1814 bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
1815 bfa_ioc_portid(ioc));
1816 disable_req.clscode = cpu_to_be16(ioc->clscode);
1817 /* unsigned 32-bit time_t overflow in y2106 */
1818 disable_req.tv_sec = be32_to_cpu(ktime_get_real_seconds());
1819 bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1822 static void
1823 bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
1825 struct bfi_ioc_getattr_req_s attr_req;
1827 bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
1828 bfa_ioc_portid(ioc));
1829 bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
1830 bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
1833 static void
1834 bfa_ioc_hb_check(void *cbarg)
1836 struct bfa_ioc_s *ioc = cbarg;
1837 u32 hb_count;
1839 hb_count = readl(ioc->ioc_regs.heartbeat);
1840 if (ioc->hb_count == hb_count) {
1841 bfa_ioc_recover(ioc);
1842 return;
1843 } else {
1844 ioc->hb_count = hb_count;
1847 bfa_ioc_mbox_poll(ioc);
1848 bfa_hb_timer_start(ioc);
1851 static void
1852 bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
1854 ioc->hb_count = readl(ioc->ioc_regs.heartbeat);
1855 bfa_hb_timer_start(ioc);
1859 * Initiate a full firmware download.
1861 static bfa_status_t
1862 bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1863 u32 boot_env)
1865 u32 *fwimg;
1866 u32 pgnum, pgoff;
1867 u32 loff = 0;
1868 u32 chunkno = 0;
1869 u32 i;
1870 u32 asicmode;
1871 u32 fwimg_size;
1872 u32 fwimg_buf[BFI_FLASH_CHUNK_SZ_WORDS];
1873 bfa_status_t status;
1875 if (boot_env == BFI_FWBOOT_ENV_OS &&
1876 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1877 fwimg_size = BFI_FLASH_IMAGE_SZ/sizeof(u32);
1879 status = bfa_ioc_flash_img_get_chnk(ioc,
1880 BFA_IOC_FLASH_CHUNK_ADDR(chunkno), fwimg_buf);
1881 if (status != BFA_STATUS_OK)
1882 return status;
1884 fwimg = fwimg_buf;
1885 } else {
1886 fwimg_size = bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc));
1887 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc),
1888 BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1891 bfa_trc(ioc, fwimg_size);
1894 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1895 pgoff = PSS_SMEM_PGOFF(loff);
1897 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1899 for (i = 0; i < fwimg_size; i++) {
1901 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
1902 chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
1904 if (boot_env == BFI_FWBOOT_ENV_OS &&
1905 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1906 status = bfa_ioc_flash_img_get_chnk(ioc,
1907 BFA_IOC_FLASH_CHUNK_ADDR(chunkno),
1908 fwimg_buf);
1909 if (status != BFA_STATUS_OK)
1910 return status;
1912 fwimg = fwimg_buf;
1913 } else {
1914 fwimg = bfa_cb_image_get_chunk(
1915 bfa_ioc_asic_gen(ioc),
1916 BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1921 * write smem
1923 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
1924 fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
1926 loff += sizeof(u32);
1929 * handle page offset wrap around
1931 loff = PSS_SMEM_PGOFF(loff);
1932 if (loff == 0) {
1933 pgnum++;
1934 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1938 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
1939 ioc->ioc_regs.host_page_num_fn);
1942 * Set boot type, env and device mode at the end.
1944 if (boot_env == BFI_FWBOOT_ENV_OS &&
1945 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1946 boot_type = BFI_FWBOOT_TYPE_NORMAL;
1948 asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode,
1949 ioc->port0_mode, ioc->port1_mode);
1950 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_DEVMODE_OFF,
1951 swab32(asicmode));
1952 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_TYPE_OFF,
1953 swab32(boot_type));
1954 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_ENV_OFF,
1955 swab32(boot_env));
1956 return BFA_STATUS_OK;
1961 * Update BFA configuration from firmware configuration.
1963 static void
1964 bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
1966 struct bfi_ioc_attr_s *attr = ioc->attr;
1968 attr->adapter_prop = be32_to_cpu(attr->adapter_prop);
1969 attr->card_type = be32_to_cpu(attr->card_type);
1970 attr->maxfrsize = be16_to_cpu(attr->maxfrsize);
1971 ioc->fcmode = (attr->port_mode == BFI_PORT_MODE_FC);
1972 attr->mfg_year = be16_to_cpu(attr->mfg_year);
1974 bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
1978 * Attach time initialization of mbox logic.
1980 static void
1981 bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc)
1983 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1984 int mc;
1986 INIT_LIST_HEAD(&mod->cmd_q);
1987 for (mc = 0; mc < BFI_MC_MAX; mc++) {
1988 mod->mbhdlr[mc].cbfn = NULL;
1989 mod->mbhdlr[mc].cbarg = ioc->bfa;
1994 * Mbox poll timer -- restarts any pending mailbox requests.
1996 static void
1997 bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc)
1999 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
2000 struct bfa_mbox_cmd_s *cmd;
2001 u32 stat;
2004 * If no command pending, do nothing
2006 if (list_empty(&mod->cmd_q))
2007 return;
2010 * If previous command is not yet fetched by firmware, do nothing
2012 stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
2013 if (stat)
2014 return;
2017 * Enqueue command to firmware.
2019 bfa_q_deq(&mod->cmd_q, &cmd);
2020 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
2024 * Cleanup any pending requests.
2026 static void
2027 bfa_ioc_mbox_flush(struct bfa_ioc_s *ioc)
2029 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
2030 struct bfa_mbox_cmd_s *cmd;
2032 while (!list_empty(&mod->cmd_q))
2033 bfa_q_deq(&mod->cmd_q, &cmd);
2037 * Read data from SMEM to host through PCI memmap
2039 * @param[in] ioc memory for IOC
2040 * @param[in] tbuf app memory to store data from smem
2041 * @param[in] soff smem offset
2042 * @param[in] sz size of smem in bytes
2044 static bfa_status_t
2045 bfa_ioc_smem_read(struct bfa_ioc_s *ioc, void *tbuf, u32 soff, u32 sz)
2047 u32 pgnum, loff;
2048 __be32 r32;
2049 int i, len;
2050 u32 *buf = tbuf;
2052 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
2053 loff = PSS_SMEM_PGOFF(soff);
2054 bfa_trc(ioc, pgnum);
2055 bfa_trc(ioc, loff);
2056 bfa_trc(ioc, sz);
2059 * Hold semaphore to serialize pll init and fwtrc.
2061 if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) {
2062 bfa_trc(ioc, 0);
2063 return BFA_STATUS_FAILED;
2066 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2068 len = sz/sizeof(u32);
2069 bfa_trc(ioc, len);
2070 for (i = 0; i < len; i++) {
2071 r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
2072 buf[i] = swab32(r32);
2073 loff += sizeof(u32);
2076 * handle page offset wrap around
2078 loff = PSS_SMEM_PGOFF(loff);
2079 if (loff == 0) {
2080 pgnum++;
2081 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2084 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
2085 ioc->ioc_regs.host_page_num_fn);
2087 * release semaphore.
2089 readl(ioc->ioc_regs.ioc_init_sem_reg);
2090 writel(1, ioc->ioc_regs.ioc_init_sem_reg);
2092 bfa_trc(ioc, pgnum);
2093 return BFA_STATUS_OK;
2097 * Clear SMEM data from host through PCI memmap
2099 * @param[in] ioc memory for IOC
2100 * @param[in] soff smem offset
2101 * @param[in] sz size of smem in bytes
2103 static bfa_status_t
2104 bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
2106 int i, len;
2107 u32 pgnum, loff;
2109 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, soff);
2110 loff = PSS_SMEM_PGOFF(soff);
2111 bfa_trc(ioc, pgnum);
2112 bfa_trc(ioc, loff);
2113 bfa_trc(ioc, sz);
2116 * Hold semaphore to serialize pll init and fwtrc.
2118 if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) {
2119 bfa_trc(ioc, 0);
2120 return BFA_STATUS_FAILED;
2123 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2125 len = sz/sizeof(u32); /* len in words */
2126 bfa_trc(ioc, len);
2127 for (i = 0; i < len; i++) {
2128 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 0);
2129 loff += sizeof(u32);
2132 * handle page offset wrap around
2134 loff = PSS_SMEM_PGOFF(loff);
2135 if (loff == 0) {
2136 pgnum++;
2137 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
2140 writel(PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, 0),
2141 ioc->ioc_regs.host_page_num_fn);
2144 * release semaphore.
2146 readl(ioc->ioc_regs.ioc_init_sem_reg);
2147 writel(1, ioc->ioc_regs.ioc_init_sem_reg);
2148 bfa_trc(ioc, pgnum);
2149 return BFA_STATUS_OK;
2152 static void
2153 bfa_ioc_fail_notify(struct bfa_ioc_s *ioc)
2155 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
2158 * Notify driver and common modules registered for notification.
2160 ioc->cbfn->hbfail_cbfn(ioc->bfa);
2161 bfa_ioc_event_notify(ioc, BFA_IOC_E_FAILED);
2163 bfa_ioc_debug_save_ftrc(ioc);
2165 BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
2166 "Heart Beat of IOC has failed\n");
2167 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL);
2171 static void
2172 bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
2174 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
2176 * Provide enable completion callback.
2178 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
2179 BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
2180 "Running firmware version is incompatible "
2181 "with the driver version\n");
2182 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH);
2185 bfa_status_t
2186 bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
2190 * Hold semaphore so that nobody can access the chip during init.
2192 bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
2194 bfa_ioc_pll_init_asic(ioc);
2196 ioc->pllinit = BFA_TRUE;
2199 * Initialize LMEM
2201 bfa_ioc_lmem_init(ioc);
2204 * release semaphore.
2206 readl(ioc->ioc_regs.ioc_init_sem_reg);
2207 writel(1, ioc->ioc_regs.ioc_init_sem_reg);
2209 return BFA_STATUS_OK;
2213 * Interface used by diag module to do firmware boot with memory test
2214 * as the entry vector.
2216 bfa_status_t
2217 bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env)
2219 struct bfi_ioc_image_hdr_s *drv_fwhdr;
2220 bfa_status_t status;
2221 bfa_ioc_stats(ioc, ioc_boots);
2223 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
2224 return BFA_STATUS_FAILED;
2226 if (boot_env == BFI_FWBOOT_ENV_OS &&
2227 boot_type == BFI_FWBOOT_TYPE_NORMAL) {
2229 drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
2230 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
2233 * Work with Flash iff flash f/w is better than driver f/w.
2234 * Otherwise push drivers firmware.
2236 if (bfa_ioc_flash_fwver_cmp(ioc, drv_fwhdr) ==
2237 BFI_IOC_IMG_VER_BETTER)
2238 boot_type = BFI_FWBOOT_TYPE_FLASH;
2242 * Initialize IOC state of all functions on a chip reset.
2244 if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) {
2245 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_MEMTEST);
2246 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_MEMTEST);
2247 } else {
2248 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_INITING);
2249 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_INITING);
2252 bfa_ioc_msgflush(ioc);
2253 status = bfa_ioc_download_fw(ioc, boot_type, boot_env);
2254 if (status == BFA_STATUS_OK)
2255 bfa_ioc_lpu_start(ioc);
2256 else {
2257 WARN_ON(boot_type == BFI_FWBOOT_TYPE_MEMTEST);
2258 bfa_iocpf_timeout(ioc);
2260 return status;
2264 * Enable/disable IOC failure auto recovery.
2266 void
2267 bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
2269 bfa_auto_recover = auto_recover;
2274 bfa_boolean_t
2275 bfa_ioc_is_operational(struct bfa_ioc_s *ioc)
2277 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
2280 bfa_boolean_t
2281 bfa_ioc_is_initialized(struct bfa_ioc_s *ioc)
2283 u32 r32 = bfa_ioc_get_cur_ioc_fwstate(ioc);
2285 return ((r32 != BFI_IOC_UNINIT) &&
2286 (r32 != BFI_IOC_INITING) &&
2287 (r32 != BFI_IOC_MEMTEST));
2290 bfa_boolean_t
2291 bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
2293 __be32 *msgp = mbmsg;
2294 u32 r32;
2295 int i;
2297 r32 = readl(ioc->ioc_regs.lpu_mbox_cmd);
2298 if ((r32 & 1) == 0)
2299 return BFA_FALSE;
2302 * read the MBOX msg
2304 for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
2305 i++) {
2306 r32 = readl(ioc->ioc_regs.lpu_mbox +
2307 i * sizeof(u32));
2308 msgp[i] = cpu_to_be32(r32);
2312 * turn off mailbox interrupt by clearing mailbox status
2314 writel(1, ioc->ioc_regs.lpu_mbox_cmd);
2315 readl(ioc->ioc_regs.lpu_mbox_cmd);
2317 return BFA_TRUE;
2320 void
2321 bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
2323 union bfi_ioc_i2h_msg_u *msg;
2324 struct bfa_iocpf_s *iocpf = &ioc->iocpf;
2326 msg = (union bfi_ioc_i2h_msg_u *) m;
2328 bfa_ioc_stats(ioc, ioc_isrs);
2330 switch (msg->mh.msg_id) {
2331 case BFI_IOC_I2H_HBEAT:
2332 break;
2334 case BFI_IOC_I2H_ENABLE_REPLY:
2335 ioc->port_mode = ioc->port_mode_cfg =
2336 (enum bfa_mode_s)msg->fw_event.port_mode;
2337 ioc->ad_cap_bm = msg->fw_event.cap_bm;
2338 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_ENABLE);
2339 break;
2341 case BFI_IOC_I2H_DISABLE_REPLY:
2342 bfa_fsm_send_event(iocpf, IOCPF_E_FWRSP_DISABLE);
2343 break;
2345 case BFI_IOC_I2H_GETATTR_REPLY:
2346 bfa_ioc_getattr_reply(ioc);
2347 break;
2349 default:
2350 bfa_trc(ioc, msg->mh.msg_id);
2351 WARN_ON(1);
2356 * IOC attach time initialization and setup.
2358 * @param[in] ioc memory for IOC
2359 * @param[in] bfa driver instance structure
2361 void
2362 bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn,
2363 struct bfa_timer_mod_s *timer_mod)
2365 ioc->bfa = bfa;
2366 ioc->cbfn = cbfn;
2367 ioc->timer_mod = timer_mod;
2368 ioc->fcmode = BFA_FALSE;
2369 ioc->pllinit = BFA_FALSE;
2370 ioc->dbg_fwsave_once = BFA_TRUE;
2371 ioc->iocpf.ioc = ioc;
2373 bfa_ioc_mbox_attach(ioc);
2374 INIT_LIST_HEAD(&ioc->notify_q);
2376 bfa_fsm_set_state(ioc, bfa_ioc_sm_uninit);
2377 bfa_fsm_send_event(ioc, IOC_E_RESET);
2381 * Driver detach time IOC cleanup.
2383 void
2384 bfa_ioc_detach(struct bfa_ioc_s *ioc)
2386 bfa_fsm_send_event(ioc, IOC_E_DETACH);
2387 INIT_LIST_HEAD(&ioc->notify_q);
2391 * Setup IOC PCI properties.
2393 * @param[in] pcidev PCI device information for this IOC
2395 void
2396 bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
2397 enum bfi_pcifn_class clscode)
2399 ioc->clscode = clscode;
2400 ioc->pcidev = *pcidev;
2403 * Initialize IOC and device personality
2405 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_FC;
2406 ioc->asic_mode = BFI_ASIC_MODE_FC;
2408 switch (pcidev->device_id) {
2409 case BFA_PCI_DEVICE_ID_FC_8G1P:
2410 case BFA_PCI_DEVICE_ID_FC_8G2P:
2411 ioc->asic_gen = BFI_ASIC_GEN_CB;
2412 ioc->fcmode = BFA_TRUE;
2413 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2414 ioc->ad_cap_bm = BFA_CM_HBA;
2415 break;
2417 case BFA_PCI_DEVICE_ID_CT:
2418 ioc->asic_gen = BFI_ASIC_GEN_CT;
2419 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
2420 ioc->asic_mode = BFI_ASIC_MODE_ETH;
2421 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_CNA;
2422 ioc->ad_cap_bm = BFA_CM_CNA;
2423 break;
2425 case BFA_PCI_DEVICE_ID_CT_FC:
2426 ioc->asic_gen = BFI_ASIC_GEN_CT;
2427 ioc->fcmode = BFA_TRUE;
2428 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2429 ioc->ad_cap_bm = BFA_CM_HBA;
2430 break;
2432 case BFA_PCI_DEVICE_ID_CT2:
2433 case BFA_PCI_DEVICE_ID_CT2_QUAD:
2434 ioc->asic_gen = BFI_ASIC_GEN_CT2;
2435 if (clscode == BFI_PCIFN_CLASS_FC &&
2436 pcidev->ssid == BFA_PCI_CT2_SSID_FC) {
2437 ioc->asic_mode = BFI_ASIC_MODE_FC16;
2438 ioc->fcmode = BFA_TRUE;
2439 ioc->port_mode = ioc->port_mode_cfg = BFA_MODE_HBA;
2440 ioc->ad_cap_bm = BFA_CM_HBA;
2441 } else {
2442 ioc->port0_mode = ioc->port1_mode = BFI_PORT_MODE_ETH;
2443 ioc->asic_mode = BFI_ASIC_MODE_ETH;
2444 if (pcidev->ssid == BFA_PCI_CT2_SSID_FCoE) {
2445 ioc->port_mode =
2446 ioc->port_mode_cfg = BFA_MODE_CNA;
2447 ioc->ad_cap_bm = BFA_CM_CNA;
2448 } else {
2449 ioc->port_mode =
2450 ioc->port_mode_cfg = BFA_MODE_NIC;
2451 ioc->ad_cap_bm = BFA_CM_NIC;
2454 break;
2456 default:
2457 WARN_ON(1);
2461 * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c
2463 if (ioc->asic_gen == BFI_ASIC_GEN_CB)
2464 bfa_ioc_set_cb_hwif(ioc);
2465 else if (ioc->asic_gen == BFI_ASIC_GEN_CT)
2466 bfa_ioc_set_ct_hwif(ioc);
2467 else {
2468 WARN_ON(ioc->asic_gen != BFI_ASIC_GEN_CT2);
2469 bfa_ioc_set_ct2_hwif(ioc);
2470 bfa_ioc_ct2_poweron(ioc);
2473 bfa_ioc_map_port(ioc);
2474 bfa_ioc_reg_init(ioc);
2478 * Initialize IOC dma memory
2480 * @param[in] dm_kva kernel virtual address of IOC dma memory
2481 * @param[in] dm_pa physical address of IOC dma memory
2483 void
2484 bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa)
2487 * dma memory for firmware attribute
2489 ioc->attr_dma.kva = dm_kva;
2490 ioc->attr_dma.pa = dm_pa;
2491 ioc->attr = (struct bfi_ioc_attr_s *) dm_kva;
2494 void
2495 bfa_ioc_enable(struct bfa_ioc_s *ioc)
2497 bfa_ioc_stats(ioc, ioc_enables);
2498 ioc->dbg_fwsave_once = BFA_TRUE;
2500 bfa_fsm_send_event(ioc, IOC_E_ENABLE);
2503 void
2504 bfa_ioc_disable(struct bfa_ioc_s *ioc)
2506 bfa_ioc_stats(ioc, ioc_disables);
2507 bfa_fsm_send_event(ioc, IOC_E_DISABLE);
2510 void
2511 bfa_ioc_suspend(struct bfa_ioc_s *ioc)
2513 ioc->dbg_fwsave_once = BFA_TRUE;
2514 bfa_fsm_send_event(ioc, IOC_E_HWERROR);
2518 * Initialize memory for saving firmware trace. Driver must initialize
2519 * trace memory before call bfa_ioc_enable().
2521 void
2522 bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
2524 ioc->dbg_fwsave = dbg_fwsave;
2525 ioc->dbg_fwsave_len = BFA_DBG_FWTRC_LEN;
2529 * Register mailbox message handler functions
2531 * @param[in] ioc IOC instance
2532 * @param[in] mcfuncs message class handler functions
2534 void
2535 bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs)
2537 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
2538 int mc;
2540 for (mc = 0; mc < BFI_MC_MAX; mc++)
2541 mod->mbhdlr[mc].cbfn = mcfuncs[mc];
2545 * Register mailbox message handler function, to be called by common modules
2547 void
2548 bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
2549 bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
2551 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
2553 mod->mbhdlr[mc].cbfn = cbfn;
2554 mod->mbhdlr[mc].cbarg = cbarg;
2558 * Queue a mailbox command request to firmware. Waits if mailbox is busy.
2559 * Responsibility of caller to serialize
2561 * @param[in] ioc IOC instance
2562 * @param[i] cmd Mailbox command
2564 void
2565 bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd)
2567 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
2568 u32 stat;
2571 * If a previous command is pending, queue new command
2573 if (!list_empty(&mod->cmd_q)) {
2574 list_add_tail(&cmd->qe, &mod->cmd_q);
2575 return;
2579 * If mailbox is busy, queue command for poll timer
2581 stat = readl(ioc->ioc_regs.hfn_mbox_cmd);
2582 if (stat) {
2583 list_add_tail(&cmd->qe, &mod->cmd_q);
2584 return;
2588 * mailbox is free -- queue command to firmware
2590 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
2594 * Handle mailbox interrupts
2596 void
2597 bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc)
2599 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
2600 struct bfi_mbmsg_s m;
2601 int mc;
2603 if (bfa_ioc_msgget(ioc, &m)) {
2605 * Treat IOC message class as special.
2607 mc = m.mh.msg_class;
2608 if (mc == BFI_MC_IOC) {
2609 bfa_ioc_isr(ioc, &m);
2610 return;
2613 if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
2614 return;
2616 mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
2619 bfa_ioc_lpu_read_stat(ioc);
2622 * Try to send pending mailbox commands
2624 bfa_ioc_mbox_poll(ioc);
2627 void
2628 bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
2630 bfa_ioc_stats(ioc, ioc_hbfails);
2631 ioc->stats.hb_count = ioc->hb_count;
2632 bfa_fsm_send_event(ioc, IOC_E_HWERROR);
2636 * return true if IOC is disabled
2638 bfa_boolean_t
2639 bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
2641 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) ||
2642 bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled);
2646 * return true if IOC firmware is different.
2648 bfa_boolean_t
2649 bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
2651 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset) ||
2652 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_fwcheck) ||
2653 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_mismatch);
2657 * Check if adapter is disabled -- both IOCs should be in a disabled
2658 * state.
2660 bfa_boolean_t
2661 bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
2663 u32 ioc_state;
2665 if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled))
2666 return BFA_FALSE;
2668 ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc);
2669 if (!bfa_ioc_state_disabled(ioc_state))
2670 return BFA_FALSE;
2672 if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) {
2673 ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc);
2674 if (!bfa_ioc_state_disabled(ioc_state))
2675 return BFA_FALSE;
2678 return BFA_TRUE;
2682 * Reset IOC fwstate registers.
2684 void
2685 bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc)
2687 bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_UNINIT);
2688 bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_UNINIT);
2691 #define BFA_MFG_NAME "QLogic"
2692 void
2693 bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2694 struct bfa_adapter_attr_s *ad_attr)
2696 struct bfi_ioc_attr_s *ioc_attr;
2698 ioc_attr = ioc->attr;
2700 bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num);
2701 bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver);
2702 bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver);
2703 bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer);
2704 memcpy(&ad_attr->vpd, &ioc_attr->vpd,
2705 sizeof(struct bfa_mfg_vpd_s));
2707 ad_attr->nports = bfa_ioc_get_nports(ioc);
2708 ad_attr->max_speed = bfa_ioc_speed_sup(ioc);
2710 bfa_ioc_get_adapter_model(ioc, ad_attr->model);
2711 /* For now, model descr uses same model string */
2712 bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
2714 ad_attr->card_type = ioc_attr->card_type;
2715 ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type);
2717 if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
2718 ad_attr->prototype = 1;
2719 else
2720 ad_attr->prototype = 0;
2722 ad_attr->pwwn = ioc->attr->pwwn;
2723 ad_attr->mac = bfa_ioc_get_mac(ioc);
2725 ad_attr->pcie_gen = ioc_attr->pcie_gen;
2726 ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
2727 ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
2728 ad_attr->asic_rev = ioc_attr->asic_rev;
2730 bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
2732 ad_attr->cna_capable = bfa_ioc_is_cna(ioc);
2733 ad_attr->trunk_capable = (ad_attr->nports > 1) &&
2734 !bfa_ioc_is_cna(ioc) && !ad_attr->is_mezz;
2735 ad_attr->mfg_day = ioc_attr->mfg_day;
2736 ad_attr->mfg_month = ioc_attr->mfg_month;
2737 ad_attr->mfg_year = ioc_attr->mfg_year;
2738 memcpy(ad_attr->uuid, ioc_attr->uuid, BFA_ADAPTER_UUID_LEN);
2741 enum bfa_ioc_type_e
2742 bfa_ioc_get_type(struct bfa_ioc_s *ioc)
2744 if (ioc->clscode == BFI_PCIFN_CLASS_ETH)
2745 return BFA_IOC_TYPE_LL;
2747 WARN_ON(ioc->clscode != BFI_PCIFN_CLASS_FC);
2749 return (ioc->attr->port_mode == BFI_PORT_MODE_FC)
2750 ? BFA_IOC_TYPE_FC : BFA_IOC_TYPE_FCoE;
2753 void
2754 bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num)
2756 memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN);
2757 memcpy((void *)serial_num,
2758 (void *)ioc->attr->brcd_serialnum,
2759 BFA_ADAPTER_SERIAL_NUM_LEN);
2762 void
2763 bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver)
2765 memset((void *)fw_ver, 0, BFA_VERSION_LEN);
2766 memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN);
2769 void
2770 bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev)
2772 WARN_ON(!chip_rev);
2774 memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN);
2776 chip_rev[0] = 'R';
2777 chip_rev[1] = 'e';
2778 chip_rev[2] = 'v';
2779 chip_rev[3] = '-';
2780 chip_rev[4] = ioc->attr->asic_rev;
2781 chip_rev[5] = '\0';
2784 void
2785 bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver)
2787 memset((void *)optrom_ver, 0, BFA_VERSION_LEN);
2788 memcpy(optrom_ver, ioc->attr->optrom_version,
2789 BFA_VERSION_LEN);
2792 void
2793 bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
2795 memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
2796 strlcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
2799 void
2800 bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
2802 struct bfi_ioc_attr_s *ioc_attr;
2803 u8 nports = bfa_ioc_get_nports(ioc);
2805 WARN_ON(!model);
2806 memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
2808 ioc_attr = ioc->attr;
2810 if (bfa_asic_id_ct2(ioc->pcidev.device_id) &&
2811 (!bfa_mfg_is_mezz(ioc_attr->card_type)))
2812 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u-%u%s",
2813 BFA_MFG_NAME, ioc_attr->card_type, nports, "p");
2814 else
2815 snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
2816 BFA_MFG_NAME, ioc_attr->card_type);
2819 enum bfa_ioc_state
2820 bfa_ioc_get_state(struct bfa_ioc_s *ioc)
2822 enum bfa_iocpf_state iocpf_st;
2823 enum bfa_ioc_state ioc_st = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
2825 if (ioc_st == BFA_IOC_ENABLING ||
2826 ioc_st == BFA_IOC_FAIL || ioc_st == BFA_IOC_INITFAIL) {
2828 iocpf_st = bfa_sm_to_state(iocpf_sm_table, ioc->iocpf.fsm);
2830 switch (iocpf_st) {
2831 case BFA_IOCPF_SEMWAIT:
2832 ioc_st = BFA_IOC_SEMWAIT;
2833 break;
2835 case BFA_IOCPF_HWINIT:
2836 ioc_st = BFA_IOC_HWINIT;
2837 break;
2839 case BFA_IOCPF_FWMISMATCH:
2840 ioc_st = BFA_IOC_FWMISMATCH;
2841 break;
2843 case BFA_IOCPF_FAIL:
2844 ioc_st = BFA_IOC_FAIL;
2845 break;
2847 case BFA_IOCPF_INITFAIL:
2848 ioc_st = BFA_IOC_INITFAIL;
2849 break;
2851 default:
2852 break;
2856 return ioc_st;
2859 void
2860 bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
2862 memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
2864 ioc_attr->state = bfa_ioc_get_state(ioc);
2865 ioc_attr->port_id = bfa_ioc_portid(ioc);
2866 ioc_attr->port_mode = ioc->port_mode;
2867 ioc_attr->port_mode_cfg = ioc->port_mode_cfg;
2868 ioc_attr->cap_bm = ioc->ad_cap_bm;
2870 ioc_attr->ioc_type = bfa_ioc_get_type(ioc);
2872 bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
2874 ioc_attr->pci_attr.device_id = bfa_ioc_devid(ioc);
2875 ioc_attr->pci_attr.pcifn = bfa_ioc_pcifn(ioc);
2876 ioc_attr->def_fn = (bfa_ioc_pcifn(ioc) == bfa_ioc_portid(ioc));
2877 bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
2880 mac_t
2881 bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
2884 * Check the IOC type and return the appropriate MAC
2886 if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE)
2887 return ioc->attr->fcoe_mac;
2888 else
2889 return ioc->attr->mac;
2892 mac_t
2893 bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc)
2895 mac_t m;
2897 m = ioc->attr->mfg_mac;
2898 if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type))
2899 m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
2900 else
2901 bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]),
2902 bfa_ioc_pcifn(ioc));
2904 return m;
2908 * Send AEN notification
2910 void
2911 bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2913 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
2914 struct bfa_aen_entry_s *aen_entry;
2915 enum bfa_ioc_type_e ioc_type;
2917 bfad_get_aen_entry(bfad, aen_entry);
2918 if (!aen_entry)
2919 return;
2921 ioc_type = bfa_ioc_get_type(ioc);
2922 switch (ioc_type) {
2923 case BFA_IOC_TYPE_FC:
2924 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn;
2925 break;
2926 case BFA_IOC_TYPE_FCoE:
2927 aen_entry->aen_data.ioc.pwwn = ioc->attr->pwwn;
2928 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2929 break;
2930 case BFA_IOC_TYPE_LL:
2931 aen_entry->aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2932 break;
2933 default:
2934 WARN_ON(ioc_type != BFA_IOC_TYPE_FC);
2935 break;
2938 /* Send the AEN notification */
2939 aen_entry->aen_data.ioc.ioc_type = ioc_type;
2940 bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq,
2941 BFA_AEN_CAT_IOC, event);
2945 * Retrieve saved firmware trace from a prior IOC failure.
2947 bfa_status_t
2948 bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2950 int tlen;
2952 if (ioc->dbg_fwsave_len == 0)
2953 return BFA_STATUS_ENOFSAVE;
2955 tlen = *trclen;
2956 if (tlen > ioc->dbg_fwsave_len)
2957 tlen = ioc->dbg_fwsave_len;
2959 memcpy(trcdata, ioc->dbg_fwsave, tlen);
2960 *trclen = tlen;
2961 return BFA_STATUS_OK;
2966 * Retrieve saved firmware trace from a prior IOC failure.
2968 bfa_status_t
2969 bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2971 u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc));
2972 int tlen;
2973 bfa_status_t status;
2975 bfa_trc(ioc, *trclen);
2977 tlen = *trclen;
2978 if (tlen > BFA_DBG_FWTRC_LEN)
2979 tlen = BFA_DBG_FWTRC_LEN;
2981 status = bfa_ioc_smem_read(ioc, trcdata, loff, tlen);
2982 *trclen = tlen;
2983 return status;
2986 static void
2987 bfa_ioc_send_fwsync(struct bfa_ioc_s *ioc)
2989 struct bfa_mbox_cmd_s cmd;
2990 struct bfi_ioc_ctrl_req_s *req = (struct bfi_ioc_ctrl_req_s *) cmd.msg;
2992 bfi_h2i_set(req->mh, BFI_MC_IOC, BFI_IOC_H2I_DBG_SYNC,
2993 bfa_ioc_portid(ioc));
2994 req->clscode = cpu_to_be16(ioc->clscode);
2995 bfa_ioc_mbox_queue(ioc, &cmd);
2998 static void
2999 bfa_ioc_fwsync(struct bfa_ioc_s *ioc)
3001 u32 fwsync_iter = 1000;
3003 bfa_ioc_send_fwsync(ioc);
3006 * After sending a fw sync mbox command wait for it to
3007 * take effect. We will not wait for a response because
3008 * 1. fw_sync mbox cmd doesn't have a response.
3009 * 2. Even if we implement that, interrupts might not
3010 * be enabled when we call this function.
3011 * So, just keep checking if any mbox cmd is pending, and
3012 * after waiting for a reasonable amount of time, go ahead.
3013 * It is possible that fw has crashed and the mbox command
3014 * is never acknowledged.
3016 while (bfa_ioc_mbox_cmd_pending(ioc) && fwsync_iter > 0)
3017 fwsync_iter--;
3021 * Dump firmware smem
3023 bfa_status_t
3024 bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf,
3025 u32 *offset, int *buflen)
3027 u32 loff;
3028 int dlen;
3029 bfa_status_t status;
3030 u32 smem_len = BFA_IOC_FW_SMEM_SIZE(ioc);
3032 if (*offset >= smem_len) {
3033 *offset = *buflen = 0;
3034 return BFA_STATUS_EINVAL;
3037 loff = *offset;
3038 dlen = *buflen;
3041 * First smem read, sync smem before proceeding
3042 * No need to sync before reading every chunk.
3044 if (loff == 0)
3045 bfa_ioc_fwsync(ioc);
3047 if ((loff + dlen) >= smem_len)
3048 dlen = smem_len - loff;
3050 status = bfa_ioc_smem_read(ioc, buf, loff, dlen);
3052 if (status != BFA_STATUS_OK) {
3053 *offset = *buflen = 0;
3054 return status;
3057 *offset += dlen;
3059 if (*offset >= smem_len)
3060 *offset = 0;
3062 *buflen = dlen;
3064 return status;
3068 * Firmware statistics
3070 bfa_status_t
3071 bfa_ioc_fw_stats_get(struct bfa_ioc_s *ioc, void *stats)
3073 u32 loff = BFI_IOC_FWSTATS_OFF + \
3074 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc));
3075 int tlen;
3076 bfa_status_t status;
3078 if (ioc->stats_busy) {
3079 bfa_trc(ioc, ioc->stats_busy);
3080 return BFA_STATUS_DEVBUSY;
3082 ioc->stats_busy = BFA_TRUE;
3084 tlen = sizeof(struct bfa_fw_stats_s);
3085 status = bfa_ioc_smem_read(ioc, stats, loff, tlen);
3087 ioc->stats_busy = BFA_FALSE;
3088 return status;
3091 bfa_status_t
3092 bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc)
3094 u32 loff = BFI_IOC_FWSTATS_OFF + \
3095 BFI_IOC_FWSTATS_SZ * (bfa_ioc_portid(ioc));
3096 int tlen;
3097 bfa_status_t status;
3099 if (ioc->stats_busy) {
3100 bfa_trc(ioc, ioc->stats_busy);
3101 return BFA_STATUS_DEVBUSY;
3103 ioc->stats_busy = BFA_TRUE;
3105 tlen = sizeof(struct bfa_fw_stats_s);
3106 status = bfa_ioc_smem_clr(ioc, loff, tlen);
3108 ioc->stats_busy = BFA_FALSE;
3109 return status;
3113 * Save firmware trace if configured.
3115 void
3116 bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc)
3118 int tlen;
3120 if (ioc->dbg_fwsave_once) {
3121 ioc->dbg_fwsave_once = BFA_FALSE;
3122 if (ioc->dbg_fwsave_len) {
3123 tlen = ioc->dbg_fwsave_len;
3124 bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
3130 * Firmware failure detected. Start recovery actions.
3132 static void
3133 bfa_ioc_recover(struct bfa_ioc_s *ioc)
3135 bfa_ioc_stats(ioc, ioc_hbfails);
3136 ioc->stats.hb_count = ioc->hb_count;
3137 bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
3141 * BFA IOC PF private functions
3143 static void
3144 bfa_iocpf_timeout(void *ioc_arg)
3146 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg;
3148 bfa_trc(ioc, 0);
3149 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_TIMEOUT);
3152 static void
3153 bfa_iocpf_sem_timeout(void *ioc_arg)
3155 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg;
3157 bfa_ioc_hw_sem_get(ioc);
3160 static void
3161 bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc)
3163 u32 fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
3165 bfa_trc(ioc, fwstate);
3167 if (fwstate == BFI_IOC_DISABLED) {
3168 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FWREADY);
3169 return;
3172 if (ioc->iocpf.poll_time >= (3 * BFA_IOC_TOV))
3173 bfa_iocpf_timeout(ioc);
3174 else {
3175 ioc->iocpf.poll_time += BFA_IOC_POLL_TOV;
3176 bfa_iocpf_poll_timer_start(ioc);
3180 static void
3181 bfa_iocpf_poll_timeout(void *ioc_arg)
3183 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *) ioc_arg;
3185 bfa_ioc_poll_fwinit(ioc);
3189 * bfa timer function
3191 void
3192 bfa_timer_beat(struct bfa_timer_mod_s *mod)
3194 struct list_head *qh = &mod->timer_q;
3195 struct list_head *qe, *qe_next;
3196 struct bfa_timer_s *elem;
3197 struct list_head timedout_q;
3199 INIT_LIST_HEAD(&timedout_q);
3201 qe = bfa_q_next(qh);
3203 while (qe != qh) {
3204 qe_next = bfa_q_next(qe);
3206 elem = (struct bfa_timer_s *) qe;
3207 if (elem->timeout <= BFA_TIMER_FREQ) {
3208 elem->timeout = 0;
3209 list_del(&elem->qe);
3210 list_add_tail(&elem->qe, &timedout_q);
3211 } else {
3212 elem->timeout -= BFA_TIMER_FREQ;
3215 qe = qe_next; /* go to next elem */
3219 * Pop all the timeout entries
3221 while (!list_empty(&timedout_q)) {
3222 bfa_q_deq(&timedout_q, &elem);
3223 elem->timercb(elem->arg);
3228 * Should be called with lock protection
3230 void
3231 bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
3232 void (*timercb) (void *), void *arg, unsigned int timeout)
3235 WARN_ON(timercb == NULL);
3236 WARN_ON(bfa_q_is_on_q(&mod->timer_q, timer));
3238 timer->timeout = timeout;
3239 timer->timercb = timercb;
3240 timer->arg = arg;
3242 list_add_tail(&timer->qe, &mod->timer_q);
3246 * Should be called with lock protection
3248 void
3249 bfa_timer_stop(struct bfa_timer_s *timer)
3251 WARN_ON(list_empty(&timer->qe));
3253 list_del(&timer->qe);
3257 * ASIC block related
3259 static void
3260 bfa_ablk_config_swap(struct bfa_ablk_cfg_s *cfg)
3262 struct bfa_ablk_cfg_inst_s *cfg_inst;
3263 int i, j;
3264 u16 be16;
3266 for (i = 0; i < BFA_ABLK_MAX; i++) {
3267 cfg_inst = &cfg->inst[i];
3268 for (j = 0; j < BFA_ABLK_MAX_PFS; j++) {
3269 be16 = cfg_inst->pf_cfg[j].pers;
3270 cfg_inst->pf_cfg[j].pers = be16_to_cpu(be16);
3271 be16 = cfg_inst->pf_cfg[j].num_qpairs;
3272 cfg_inst->pf_cfg[j].num_qpairs = be16_to_cpu(be16);
3273 be16 = cfg_inst->pf_cfg[j].num_vectors;
3274 cfg_inst->pf_cfg[j].num_vectors = be16_to_cpu(be16);
3275 be16 = cfg_inst->pf_cfg[j].bw_min;
3276 cfg_inst->pf_cfg[j].bw_min = be16_to_cpu(be16);
3277 be16 = cfg_inst->pf_cfg[j].bw_max;
3278 cfg_inst->pf_cfg[j].bw_max = be16_to_cpu(be16);
3283 static void
3284 bfa_ablk_isr(void *cbarg, struct bfi_mbmsg_s *msg)
3286 struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg;
3287 struct bfi_ablk_i2h_rsp_s *rsp = (struct bfi_ablk_i2h_rsp_s *)msg;
3288 bfa_ablk_cbfn_t cbfn;
3290 WARN_ON(msg->mh.msg_class != BFI_MC_ABLK);
3291 bfa_trc(ablk->ioc, msg->mh.msg_id);
3293 switch (msg->mh.msg_id) {
3294 case BFI_ABLK_I2H_QUERY:
3295 if (rsp->status == BFA_STATUS_OK) {
3296 memcpy(ablk->cfg, ablk->dma_addr.kva,
3297 sizeof(struct bfa_ablk_cfg_s));
3298 bfa_ablk_config_swap(ablk->cfg);
3299 ablk->cfg = NULL;
3301 break;
3303 case BFI_ABLK_I2H_ADPT_CONFIG:
3304 case BFI_ABLK_I2H_PORT_CONFIG:
3305 /* update config port mode */
3306 ablk->ioc->port_mode_cfg = rsp->port_mode;
3308 case BFI_ABLK_I2H_PF_DELETE:
3309 case BFI_ABLK_I2H_PF_UPDATE:
3310 case BFI_ABLK_I2H_OPTROM_ENABLE:
3311 case BFI_ABLK_I2H_OPTROM_DISABLE:
3312 /* No-op */
3313 break;
3315 case BFI_ABLK_I2H_PF_CREATE:
3316 *(ablk->pcifn) = rsp->pcifn;
3317 ablk->pcifn = NULL;
3318 break;
3320 default:
3321 WARN_ON(1);
3324 ablk->busy = BFA_FALSE;
3325 if (ablk->cbfn) {
3326 cbfn = ablk->cbfn;
3327 ablk->cbfn = NULL;
3328 cbfn(ablk->cbarg, rsp->status);
3332 static void
3333 bfa_ablk_notify(void *cbarg, enum bfa_ioc_event_e event)
3335 struct bfa_ablk_s *ablk = (struct bfa_ablk_s *)cbarg;
3337 bfa_trc(ablk->ioc, event);
3339 switch (event) {
3340 case BFA_IOC_E_ENABLED:
3341 WARN_ON(ablk->busy != BFA_FALSE);
3342 break;
3344 case BFA_IOC_E_DISABLED:
3345 case BFA_IOC_E_FAILED:
3346 /* Fail any pending requests */
3347 ablk->pcifn = NULL;
3348 if (ablk->busy) {
3349 if (ablk->cbfn)
3350 ablk->cbfn(ablk->cbarg, BFA_STATUS_FAILED);
3351 ablk->cbfn = NULL;
3352 ablk->busy = BFA_FALSE;
3354 break;
3356 default:
3357 WARN_ON(1);
3358 break;
3363 bfa_ablk_meminfo(void)
3365 return BFA_ROUNDUP(sizeof(struct bfa_ablk_cfg_s), BFA_DMA_ALIGN_SZ);
3368 void
3369 bfa_ablk_memclaim(struct bfa_ablk_s *ablk, u8 *dma_kva, u64 dma_pa)
3371 ablk->dma_addr.kva = dma_kva;
3372 ablk->dma_addr.pa = dma_pa;
3375 void
3376 bfa_ablk_attach(struct bfa_ablk_s *ablk, struct bfa_ioc_s *ioc)
3378 ablk->ioc = ioc;
3380 bfa_ioc_mbox_regisr(ablk->ioc, BFI_MC_ABLK, bfa_ablk_isr, ablk);
3381 bfa_q_qe_init(&ablk->ioc_notify);
3382 bfa_ioc_notify_init(&ablk->ioc_notify, bfa_ablk_notify, ablk);
3383 list_add_tail(&ablk->ioc_notify.qe, &ablk->ioc->notify_q);
3386 bfa_status_t
3387 bfa_ablk_query(struct bfa_ablk_s *ablk, struct bfa_ablk_cfg_s *ablk_cfg,
3388 bfa_ablk_cbfn_t cbfn, void *cbarg)
3390 struct bfi_ablk_h2i_query_s *m;
3392 WARN_ON(!ablk_cfg);
3394 if (!bfa_ioc_is_operational(ablk->ioc)) {
3395 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3396 return BFA_STATUS_IOC_FAILURE;
3399 if (ablk->busy) {
3400 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3401 return BFA_STATUS_DEVBUSY;
3404 ablk->cfg = ablk_cfg;
3405 ablk->cbfn = cbfn;
3406 ablk->cbarg = cbarg;
3407 ablk->busy = BFA_TRUE;
3409 m = (struct bfi_ablk_h2i_query_s *)ablk->mb.msg;
3410 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_QUERY,
3411 bfa_ioc_portid(ablk->ioc));
3412 bfa_dma_be_addr_set(m->addr, ablk->dma_addr.pa);
3413 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3415 return BFA_STATUS_OK;
3418 bfa_status_t
3419 bfa_ablk_pf_create(struct bfa_ablk_s *ablk, u16 *pcifn,
3420 u8 port, enum bfi_pcifn_class personality,
3421 u16 bw_min, u16 bw_max,
3422 bfa_ablk_cbfn_t cbfn, void *cbarg)
3424 struct bfi_ablk_h2i_pf_req_s *m;
3426 if (!bfa_ioc_is_operational(ablk->ioc)) {
3427 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3428 return BFA_STATUS_IOC_FAILURE;
3431 if (ablk->busy) {
3432 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3433 return BFA_STATUS_DEVBUSY;
3436 ablk->pcifn = pcifn;
3437 ablk->cbfn = cbfn;
3438 ablk->cbarg = cbarg;
3439 ablk->busy = BFA_TRUE;
3441 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3442 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_CREATE,
3443 bfa_ioc_portid(ablk->ioc));
3444 m->pers = cpu_to_be16((u16)personality);
3445 m->bw_min = cpu_to_be16(bw_min);
3446 m->bw_max = cpu_to_be16(bw_max);
3447 m->port = port;
3448 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3450 return BFA_STATUS_OK;
3453 bfa_status_t
3454 bfa_ablk_pf_delete(struct bfa_ablk_s *ablk, int pcifn,
3455 bfa_ablk_cbfn_t cbfn, void *cbarg)
3457 struct bfi_ablk_h2i_pf_req_s *m;
3459 if (!bfa_ioc_is_operational(ablk->ioc)) {
3460 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3461 return BFA_STATUS_IOC_FAILURE;
3464 if (ablk->busy) {
3465 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3466 return BFA_STATUS_DEVBUSY;
3469 ablk->cbfn = cbfn;
3470 ablk->cbarg = cbarg;
3471 ablk->busy = BFA_TRUE;
3473 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3474 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_DELETE,
3475 bfa_ioc_portid(ablk->ioc));
3476 m->pcifn = (u8)pcifn;
3477 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3479 return BFA_STATUS_OK;
3482 bfa_status_t
3483 bfa_ablk_adapter_config(struct bfa_ablk_s *ablk, enum bfa_mode_s mode,
3484 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg)
3486 struct bfi_ablk_h2i_cfg_req_s *m;
3488 if (!bfa_ioc_is_operational(ablk->ioc)) {
3489 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3490 return BFA_STATUS_IOC_FAILURE;
3493 if (ablk->busy) {
3494 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3495 return BFA_STATUS_DEVBUSY;
3498 ablk->cbfn = cbfn;
3499 ablk->cbarg = cbarg;
3500 ablk->busy = BFA_TRUE;
3502 m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg;
3503 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_ADPT_CONFIG,
3504 bfa_ioc_portid(ablk->ioc));
3505 m->mode = (u8)mode;
3506 m->max_pf = (u8)max_pf;
3507 m->max_vf = (u8)max_vf;
3508 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3510 return BFA_STATUS_OK;
3513 bfa_status_t
3514 bfa_ablk_port_config(struct bfa_ablk_s *ablk, int port, enum bfa_mode_s mode,
3515 int max_pf, int max_vf, bfa_ablk_cbfn_t cbfn, void *cbarg)
3517 struct bfi_ablk_h2i_cfg_req_s *m;
3519 if (!bfa_ioc_is_operational(ablk->ioc)) {
3520 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3521 return BFA_STATUS_IOC_FAILURE;
3524 if (ablk->busy) {
3525 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3526 return BFA_STATUS_DEVBUSY;
3529 ablk->cbfn = cbfn;
3530 ablk->cbarg = cbarg;
3531 ablk->busy = BFA_TRUE;
3533 m = (struct bfi_ablk_h2i_cfg_req_s *)ablk->mb.msg;
3534 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PORT_CONFIG,
3535 bfa_ioc_portid(ablk->ioc));
3536 m->port = (u8)port;
3537 m->mode = (u8)mode;
3538 m->max_pf = (u8)max_pf;
3539 m->max_vf = (u8)max_vf;
3540 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3542 return BFA_STATUS_OK;
3545 bfa_status_t
3546 bfa_ablk_pf_update(struct bfa_ablk_s *ablk, int pcifn, u16 bw_min,
3547 u16 bw_max, bfa_ablk_cbfn_t cbfn, void *cbarg)
3549 struct bfi_ablk_h2i_pf_req_s *m;
3551 if (!bfa_ioc_is_operational(ablk->ioc)) {
3552 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3553 return BFA_STATUS_IOC_FAILURE;
3556 if (ablk->busy) {
3557 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3558 return BFA_STATUS_DEVBUSY;
3561 ablk->cbfn = cbfn;
3562 ablk->cbarg = cbarg;
3563 ablk->busy = BFA_TRUE;
3565 m = (struct bfi_ablk_h2i_pf_req_s *)ablk->mb.msg;
3566 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_PF_UPDATE,
3567 bfa_ioc_portid(ablk->ioc));
3568 m->pcifn = (u8)pcifn;
3569 m->bw_min = cpu_to_be16(bw_min);
3570 m->bw_max = cpu_to_be16(bw_max);
3571 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3573 return BFA_STATUS_OK;
3576 bfa_status_t
3577 bfa_ablk_optrom_en(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg)
3579 struct bfi_ablk_h2i_optrom_s *m;
3581 if (!bfa_ioc_is_operational(ablk->ioc)) {
3582 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3583 return BFA_STATUS_IOC_FAILURE;
3586 if (ablk->busy) {
3587 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3588 return BFA_STATUS_DEVBUSY;
3591 ablk->cbfn = cbfn;
3592 ablk->cbarg = cbarg;
3593 ablk->busy = BFA_TRUE;
3595 m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg;
3596 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_ENABLE,
3597 bfa_ioc_portid(ablk->ioc));
3598 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3600 return BFA_STATUS_OK;
3603 bfa_status_t
3604 bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk, bfa_ablk_cbfn_t cbfn, void *cbarg)
3606 struct bfi_ablk_h2i_optrom_s *m;
3608 if (!bfa_ioc_is_operational(ablk->ioc)) {
3609 bfa_trc(ablk->ioc, BFA_STATUS_IOC_FAILURE);
3610 return BFA_STATUS_IOC_FAILURE;
3613 if (ablk->busy) {
3614 bfa_trc(ablk->ioc, BFA_STATUS_DEVBUSY);
3615 return BFA_STATUS_DEVBUSY;
3618 ablk->cbfn = cbfn;
3619 ablk->cbarg = cbarg;
3620 ablk->busy = BFA_TRUE;
3622 m = (struct bfi_ablk_h2i_optrom_s *)ablk->mb.msg;
3623 bfi_h2i_set(m->mh, BFI_MC_ABLK, BFI_ABLK_H2I_OPTROM_DISABLE,
3624 bfa_ioc_portid(ablk->ioc));
3625 bfa_ioc_mbox_queue(ablk->ioc, &ablk->mb);
3627 return BFA_STATUS_OK;
3631 * SFP module specific
3634 /* forward declarations */
3635 static void bfa_sfp_getdata_send(struct bfa_sfp_s *sfp);
3636 static void bfa_sfp_media_get(struct bfa_sfp_s *sfp);
3637 static bfa_status_t bfa_sfp_speed_valid(struct bfa_sfp_s *sfp,
3638 enum bfa_port_speed portspeed);
3640 static void
3641 bfa_cb_sfp_show(struct bfa_sfp_s *sfp)
3643 bfa_trc(sfp, sfp->lock);
3644 if (sfp->cbfn)
3645 sfp->cbfn(sfp->cbarg, sfp->status);
3646 sfp->lock = 0;
3647 sfp->cbfn = NULL;
3650 static void
3651 bfa_cb_sfp_state_query(struct bfa_sfp_s *sfp)
3653 bfa_trc(sfp, sfp->portspeed);
3654 if (sfp->media) {
3655 bfa_sfp_media_get(sfp);
3656 if (sfp->state_query_cbfn)
3657 sfp->state_query_cbfn(sfp->state_query_cbarg,
3658 sfp->status);
3659 sfp->media = NULL;
3662 if (sfp->portspeed) {
3663 sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed);
3664 if (sfp->state_query_cbfn)
3665 sfp->state_query_cbfn(sfp->state_query_cbarg,
3666 sfp->status);
3667 sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
3670 sfp->state_query_lock = 0;
3671 sfp->state_query_cbfn = NULL;
3675 * IOC event handler.
3677 static void
3678 bfa_sfp_notify(void *sfp_arg, enum bfa_ioc_event_e event)
3680 struct bfa_sfp_s *sfp = sfp_arg;
3682 bfa_trc(sfp, event);
3683 bfa_trc(sfp, sfp->lock);
3684 bfa_trc(sfp, sfp->state_query_lock);
3686 switch (event) {
3687 case BFA_IOC_E_DISABLED:
3688 case BFA_IOC_E_FAILED:
3689 if (sfp->lock) {
3690 sfp->status = BFA_STATUS_IOC_FAILURE;
3691 bfa_cb_sfp_show(sfp);
3694 if (sfp->state_query_lock) {
3695 sfp->status = BFA_STATUS_IOC_FAILURE;
3696 bfa_cb_sfp_state_query(sfp);
3698 break;
3700 default:
3701 break;
3706 * SFP's State Change Notification post to AEN
3708 static void
3709 bfa_sfp_scn_aen_post(struct bfa_sfp_s *sfp, struct bfi_sfp_scn_s *rsp)
3711 struct bfad_s *bfad = (struct bfad_s *)sfp->ioc->bfa->bfad;
3712 struct bfa_aen_entry_s *aen_entry;
3713 enum bfa_port_aen_event aen_evt = 0;
3715 bfa_trc(sfp, (((u64)rsp->pomlvl) << 16) | (((u64)rsp->sfpid) << 8) |
3716 ((u64)rsp->event));
3718 bfad_get_aen_entry(bfad, aen_entry);
3719 if (!aen_entry)
3720 return;
3722 aen_entry->aen_data.port.ioc_type = bfa_ioc_get_type(sfp->ioc);
3723 aen_entry->aen_data.port.pwwn = sfp->ioc->attr->pwwn;
3724 aen_entry->aen_data.port.mac = bfa_ioc_get_mac(sfp->ioc);
3726 switch (rsp->event) {
3727 case BFA_SFP_SCN_INSERTED:
3728 aen_evt = BFA_PORT_AEN_SFP_INSERT;
3729 break;
3730 case BFA_SFP_SCN_REMOVED:
3731 aen_evt = BFA_PORT_AEN_SFP_REMOVE;
3732 break;
3733 case BFA_SFP_SCN_FAILED:
3734 aen_evt = BFA_PORT_AEN_SFP_ACCESS_ERROR;
3735 break;
3736 case BFA_SFP_SCN_UNSUPPORT:
3737 aen_evt = BFA_PORT_AEN_SFP_UNSUPPORT;
3738 break;
3739 case BFA_SFP_SCN_POM:
3740 aen_evt = BFA_PORT_AEN_SFP_POM;
3741 aen_entry->aen_data.port.level = rsp->pomlvl;
3742 break;
3743 default:
3744 bfa_trc(sfp, rsp->event);
3745 WARN_ON(1);
3748 /* Send the AEN notification */
3749 bfad_im_post_vendor_event(aen_entry, bfad, ++sfp->ioc->ioc_aen_seq,
3750 BFA_AEN_CAT_PORT, aen_evt);
3754 * SFP get data send
3756 static void
3757 bfa_sfp_getdata_send(struct bfa_sfp_s *sfp)
3759 struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
3761 bfa_trc(sfp, req->memtype);
3763 /* build host command */
3764 bfi_h2i_set(req->mh, BFI_MC_SFP, BFI_SFP_H2I_SHOW,
3765 bfa_ioc_portid(sfp->ioc));
3767 /* send mbox cmd */
3768 bfa_ioc_mbox_queue(sfp->ioc, &sfp->mbcmd);
3772 * SFP is valid, read sfp data
3774 static void
3775 bfa_sfp_getdata(struct bfa_sfp_s *sfp, enum bfi_sfp_mem_e memtype)
3777 struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
3779 WARN_ON(sfp->lock != 0);
3780 bfa_trc(sfp, sfp->state);
3782 sfp->lock = 1;
3783 sfp->memtype = memtype;
3784 req->memtype = memtype;
3786 /* Setup SG list */
3787 bfa_alen_set(&req->alen, sizeof(struct sfp_mem_s), sfp->dbuf_pa);
3789 bfa_sfp_getdata_send(sfp);
3793 * SFP scn handler
3795 static void
3796 bfa_sfp_scn(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg)
3798 struct bfi_sfp_scn_s *rsp = (struct bfi_sfp_scn_s *) msg;
3800 switch (rsp->event) {
3801 case BFA_SFP_SCN_INSERTED:
3802 sfp->state = BFA_SFP_STATE_INSERTED;
3803 sfp->data_valid = 0;
3804 bfa_sfp_scn_aen_post(sfp, rsp);
3805 break;
3806 case BFA_SFP_SCN_REMOVED:
3807 sfp->state = BFA_SFP_STATE_REMOVED;
3808 sfp->data_valid = 0;
3809 bfa_sfp_scn_aen_post(sfp, rsp);
3810 break;
3811 case BFA_SFP_SCN_FAILED:
3812 sfp->state = BFA_SFP_STATE_FAILED;
3813 sfp->data_valid = 0;
3814 bfa_sfp_scn_aen_post(sfp, rsp);
3815 break;
3816 case BFA_SFP_SCN_UNSUPPORT:
3817 sfp->state = BFA_SFP_STATE_UNSUPPORT;
3818 bfa_sfp_scn_aen_post(sfp, rsp);
3819 if (!sfp->lock)
3820 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3821 break;
3822 case BFA_SFP_SCN_POM:
3823 bfa_sfp_scn_aen_post(sfp, rsp);
3824 break;
3825 case BFA_SFP_SCN_VALID:
3826 sfp->state = BFA_SFP_STATE_VALID;
3827 if (!sfp->lock)
3828 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3829 break;
3830 default:
3831 bfa_trc(sfp, rsp->event);
3832 WARN_ON(1);
3837 * SFP show complete
3839 static void
3840 bfa_sfp_show_comp(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg)
3842 struct bfi_sfp_rsp_s *rsp = (struct bfi_sfp_rsp_s *) msg;
3844 if (!sfp->lock) {
3846 * receiving response after ioc failure
3848 bfa_trc(sfp, sfp->lock);
3849 return;
3852 bfa_trc(sfp, rsp->status);
3853 if (rsp->status == BFA_STATUS_OK) {
3854 sfp->data_valid = 1;
3855 if (sfp->state == BFA_SFP_STATE_VALID)
3856 sfp->status = BFA_STATUS_OK;
3857 else if (sfp->state == BFA_SFP_STATE_UNSUPPORT)
3858 sfp->status = BFA_STATUS_SFP_UNSUPP;
3859 else
3860 bfa_trc(sfp, sfp->state);
3861 } else {
3862 sfp->data_valid = 0;
3863 sfp->status = rsp->status;
3864 /* sfpshow shouldn't change sfp state */
3867 bfa_trc(sfp, sfp->memtype);
3868 if (sfp->memtype == BFI_SFP_MEM_DIAGEXT) {
3869 bfa_trc(sfp, sfp->data_valid);
3870 if (sfp->data_valid) {
3871 u32 size = sizeof(struct sfp_mem_s);
3872 u8 *des = (u8 *)(sfp->sfpmem);
3873 memcpy(des, sfp->dbuf_kva, size);
3876 * Queue completion callback.
3878 bfa_cb_sfp_show(sfp);
3879 } else
3880 sfp->lock = 0;
3882 bfa_trc(sfp, sfp->state_query_lock);
3883 if (sfp->state_query_lock) {
3884 sfp->state = rsp->state;
3885 /* Complete callback */
3886 bfa_cb_sfp_state_query(sfp);
3891 * SFP query fw sfp state
3893 static void
3894 bfa_sfp_state_query(struct bfa_sfp_s *sfp)
3896 struct bfi_sfp_req_s *req = (struct bfi_sfp_req_s *)sfp->mbcmd.msg;
3898 /* Should not be doing query if not in _INIT state */
3899 WARN_ON(sfp->state != BFA_SFP_STATE_INIT);
3900 WARN_ON(sfp->state_query_lock != 0);
3901 bfa_trc(sfp, sfp->state);
3903 sfp->state_query_lock = 1;
3904 req->memtype = 0;
3906 if (!sfp->lock)
3907 bfa_sfp_getdata(sfp, BFI_SFP_MEM_ALL);
3910 static void
3911 bfa_sfp_media_get(struct bfa_sfp_s *sfp)
3913 enum bfa_defs_sfp_media_e *media = sfp->media;
3915 *media = BFA_SFP_MEDIA_UNKNOWN;
3917 if (sfp->state == BFA_SFP_STATE_UNSUPPORT)
3918 *media = BFA_SFP_MEDIA_UNSUPPORT;
3919 else if (sfp->state == BFA_SFP_STATE_VALID) {
3920 union sfp_xcvr_e10g_code_u e10g;
3921 struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva;
3922 u16 xmtr_tech = (sfpmem->srlid_base.xcvr[4] & 0x3) << 7 |
3923 (sfpmem->srlid_base.xcvr[5] >> 1);
3925 e10g.b = sfpmem->srlid_base.xcvr[0];
3926 bfa_trc(sfp, e10g.b);
3927 bfa_trc(sfp, xmtr_tech);
3928 /* check fc transmitter tech */
3929 if ((xmtr_tech & SFP_XMTR_TECH_CU) ||
3930 (xmtr_tech & SFP_XMTR_TECH_CP) ||
3931 (xmtr_tech & SFP_XMTR_TECH_CA))
3932 *media = BFA_SFP_MEDIA_CU;
3933 else if ((xmtr_tech & SFP_XMTR_TECH_EL_INTRA) ||
3934 (xmtr_tech & SFP_XMTR_TECH_EL_INTER))
3935 *media = BFA_SFP_MEDIA_EL;
3936 else if ((xmtr_tech & SFP_XMTR_TECH_LL) ||
3937 (xmtr_tech & SFP_XMTR_TECH_LC))
3938 *media = BFA_SFP_MEDIA_LW;
3939 else if ((xmtr_tech & SFP_XMTR_TECH_SL) ||
3940 (xmtr_tech & SFP_XMTR_TECH_SN) ||
3941 (xmtr_tech & SFP_XMTR_TECH_SA))
3942 *media = BFA_SFP_MEDIA_SW;
3943 /* Check 10G Ethernet Compilance code */
3944 else if (e10g.r.e10g_sr)
3945 *media = BFA_SFP_MEDIA_SW;
3946 else if (e10g.r.e10g_lrm && e10g.r.e10g_lr)
3947 *media = BFA_SFP_MEDIA_LW;
3948 else if (e10g.r.e10g_unall)
3949 *media = BFA_SFP_MEDIA_UNKNOWN;
3950 else
3951 bfa_trc(sfp, 0);
3952 } else
3953 bfa_trc(sfp, sfp->state);
3956 static bfa_status_t
3957 bfa_sfp_speed_valid(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed)
3959 struct sfp_mem_s *sfpmem = (struct sfp_mem_s *)sfp->dbuf_kva;
3960 struct sfp_xcvr_s *xcvr = (struct sfp_xcvr_s *) sfpmem->srlid_base.xcvr;
3961 union sfp_xcvr_fc3_code_u fc3 = xcvr->fc3;
3962 union sfp_xcvr_e10g_code_u e10g = xcvr->e10g;
3964 if (portspeed == BFA_PORT_SPEED_10GBPS) {
3965 if (e10g.r.e10g_sr || e10g.r.e10g_lr)
3966 return BFA_STATUS_OK;
3967 else {
3968 bfa_trc(sfp, e10g.b);
3969 return BFA_STATUS_UNSUPP_SPEED;
3972 if (((portspeed & BFA_PORT_SPEED_16GBPS) && fc3.r.mb1600) ||
3973 ((portspeed & BFA_PORT_SPEED_8GBPS) && fc3.r.mb800) ||
3974 ((portspeed & BFA_PORT_SPEED_4GBPS) && fc3.r.mb400) ||
3975 ((portspeed & BFA_PORT_SPEED_2GBPS) && fc3.r.mb200) ||
3976 ((portspeed & BFA_PORT_SPEED_1GBPS) && fc3.r.mb100))
3977 return BFA_STATUS_OK;
3978 else {
3979 bfa_trc(sfp, portspeed);
3980 bfa_trc(sfp, fc3.b);
3981 bfa_trc(sfp, e10g.b);
3982 return BFA_STATUS_UNSUPP_SPEED;
3987 * SFP hmbox handler
3989 void
3990 bfa_sfp_intr(void *sfparg, struct bfi_mbmsg_s *msg)
3992 struct bfa_sfp_s *sfp = sfparg;
3994 switch (msg->mh.msg_id) {
3995 case BFI_SFP_I2H_SHOW:
3996 bfa_sfp_show_comp(sfp, msg);
3997 break;
3999 case BFI_SFP_I2H_SCN:
4000 bfa_sfp_scn(sfp, msg);
4001 break;
4003 default:
4004 bfa_trc(sfp, msg->mh.msg_id);
4005 WARN_ON(1);
4010 * Return DMA memory needed by sfp module.
4013 bfa_sfp_meminfo(void)
4015 return BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
4019 * Attach virtual and physical memory for SFP.
4021 void
4022 bfa_sfp_attach(struct bfa_sfp_s *sfp, struct bfa_ioc_s *ioc, void *dev,
4023 struct bfa_trc_mod_s *trcmod)
4025 sfp->dev = dev;
4026 sfp->ioc = ioc;
4027 sfp->trcmod = trcmod;
4029 sfp->cbfn = NULL;
4030 sfp->cbarg = NULL;
4031 sfp->sfpmem = NULL;
4032 sfp->lock = 0;
4033 sfp->data_valid = 0;
4034 sfp->state = BFA_SFP_STATE_INIT;
4035 sfp->state_query_lock = 0;
4036 sfp->state_query_cbfn = NULL;
4037 sfp->state_query_cbarg = NULL;
4038 sfp->media = NULL;
4039 sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
4040 sfp->is_elb = BFA_FALSE;
4042 bfa_ioc_mbox_regisr(sfp->ioc, BFI_MC_SFP, bfa_sfp_intr, sfp);
4043 bfa_q_qe_init(&sfp->ioc_notify);
4044 bfa_ioc_notify_init(&sfp->ioc_notify, bfa_sfp_notify, sfp);
4045 list_add_tail(&sfp->ioc_notify.qe, &sfp->ioc->notify_q);
4049 * Claim Memory for SFP
4051 void
4052 bfa_sfp_memclaim(struct bfa_sfp_s *sfp, u8 *dm_kva, u64 dm_pa)
4054 sfp->dbuf_kva = dm_kva;
4055 sfp->dbuf_pa = dm_pa;
4056 memset(sfp->dbuf_kva, 0, sizeof(struct sfp_mem_s));
4058 dm_kva += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
4059 dm_pa += BFA_ROUNDUP(sizeof(struct sfp_mem_s), BFA_DMA_ALIGN_SZ);
4063 * Show SFP eeprom content
4065 * @param[in] sfp - bfa sfp module
4067 * @param[out] sfpmem - sfp eeprom data
4070 bfa_status_t
4071 bfa_sfp_show(struct bfa_sfp_s *sfp, struct sfp_mem_s *sfpmem,
4072 bfa_cb_sfp_t cbfn, void *cbarg)
4075 if (!bfa_ioc_is_operational(sfp->ioc)) {
4076 bfa_trc(sfp, 0);
4077 return BFA_STATUS_IOC_NON_OP;
4080 if (sfp->lock) {
4081 bfa_trc(sfp, 0);
4082 return BFA_STATUS_DEVBUSY;
4085 sfp->cbfn = cbfn;
4086 sfp->cbarg = cbarg;
4087 sfp->sfpmem = sfpmem;
4089 bfa_sfp_getdata(sfp, BFI_SFP_MEM_DIAGEXT);
4090 return BFA_STATUS_OK;
4094 * Return SFP Media type
4096 * @param[in] sfp - bfa sfp module
4098 * @param[out] media - port speed from user
4101 bfa_status_t
4102 bfa_sfp_media(struct bfa_sfp_s *sfp, enum bfa_defs_sfp_media_e *media,
4103 bfa_cb_sfp_t cbfn, void *cbarg)
4105 if (!bfa_ioc_is_operational(sfp->ioc)) {
4106 bfa_trc(sfp, 0);
4107 return BFA_STATUS_IOC_NON_OP;
4110 sfp->media = media;
4111 if (sfp->state == BFA_SFP_STATE_INIT) {
4112 if (sfp->state_query_lock) {
4113 bfa_trc(sfp, 0);
4114 return BFA_STATUS_DEVBUSY;
4115 } else {
4116 sfp->state_query_cbfn = cbfn;
4117 sfp->state_query_cbarg = cbarg;
4118 bfa_sfp_state_query(sfp);
4119 return BFA_STATUS_SFP_NOT_READY;
4123 bfa_sfp_media_get(sfp);
4124 return BFA_STATUS_OK;
4128 * Check if user set port speed is allowed by the SFP
4130 * @param[in] sfp - bfa sfp module
4131 * @param[in] portspeed - port speed from user
4134 bfa_status_t
4135 bfa_sfp_speed(struct bfa_sfp_s *sfp, enum bfa_port_speed portspeed,
4136 bfa_cb_sfp_t cbfn, void *cbarg)
4138 WARN_ON(portspeed == BFA_PORT_SPEED_UNKNOWN);
4140 if (!bfa_ioc_is_operational(sfp->ioc))
4141 return BFA_STATUS_IOC_NON_OP;
4143 /* For Mezz card, all speed is allowed */
4144 if (bfa_mfg_is_mezz(sfp->ioc->attr->card_type))
4145 return BFA_STATUS_OK;
4147 /* Check SFP state */
4148 sfp->portspeed = portspeed;
4149 if (sfp->state == BFA_SFP_STATE_INIT) {
4150 if (sfp->state_query_lock) {
4151 bfa_trc(sfp, 0);
4152 return BFA_STATUS_DEVBUSY;
4153 } else {
4154 sfp->state_query_cbfn = cbfn;
4155 sfp->state_query_cbarg = cbarg;
4156 bfa_sfp_state_query(sfp);
4157 return BFA_STATUS_SFP_NOT_READY;
4161 if (sfp->state == BFA_SFP_STATE_REMOVED ||
4162 sfp->state == BFA_SFP_STATE_FAILED) {
4163 bfa_trc(sfp, sfp->state);
4164 return BFA_STATUS_NO_SFP_DEV;
4167 if (sfp->state == BFA_SFP_STATE_INSERTED) {
4168 bfa_trc(sfp, sfp->state);
4169 return BFA_STATUS_DEVBUSY; /* sfp is reading data */
4172 /* For eloopback, all speed is allowed */
4173 if (sfp->is_elb)
4174 return BFA_STATUS_OK;
4176 return bfa_sfp_speed_valid(sfp, portspeed);
4180 * Flash module specific
4184 * FLASH DMA buffer should be big enough to hold both MFG block and
4185 * asic block(64k) at the same time and also should be 2k aligned to
4186 * avoid write segement to cross sector boundary.
4188 #define BFA_FLASH_SEG_SZ 2048
4189 #define BFA_FLASH_DMA_BUF_SZ \
4190 BFA_ROUNDUP(0x010000 + sizeof(struct bfa_mfg_block_s), BFA_FLASH_SEG_SZ)
4192 static void
4193 bfa_flash_aen_audit_post(struct bfa_ioc_s *ioc, enum bfa_audit_aen_event event,
4194 int inst, int type)
4196 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
4197 struct bfa_aen_entry_s *aen_entry;
4199 bfad_get_aen_entry(bfad, aen_entry);
4200 if (!aen_entry)
4201 return;
4203 aen_entry->aen_data.audit.pwwn = ioc->attr->pwwn;
4204 aen_entry->aen_data.audit.partition_inst = inst;
4205 aen_entry->aen_data.audit.partition_type = type;
4207 /* Send the AEN notification */
4208 bfad_im_post_vendor_event(aen_entry, bfad, ++ioc->ioc_aen_seq,
4209 BFA_AEN_CAT_AUDIT, event);
4212 static void
4213 bfa_flash_cb(struct bfa_flash_s *flash)
4215 flash->op_busy = 0;
4216 if (flash->cbfn)
4217 flash->cbfn(flash->cbarg, flash->status);
4220 static void
4221 bfa_flash_notify(void *cbarg, enum bfa_ioc_event_e event)
4223 struct bfa_flash_s *flash = cbarg;
4225 bfa_trc(flash, event);
4226 switch (event) {
4227 case BFA_IOC_E_DISABLED:
4228 case BFA_IOC_E_FAILED:
4229 if (flash->op_busy) {
4230 flash->status = BFA_STATUS_IOC_FAILURE;
4231 flash->cbfn(flash->cbarg, flash->status);
4232 flash->op_busy = 0;
4234 break;
4236 default:
4237 break;
4242 * Send flash attribute query request.
4244 * @param[in] cbarg - callback argument
4246 static void
4247 bfa_flash_query_send(void *cbarg)
4249 struct bfa_flash_s *flash = cbarg;
4250 struct bfi_flash_query_req_s *msg =
4251 (struct bfi_flash_query_req_s *) flash->mb.msg;
4253 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_QUERY_REQ,
4254 bfa_ioc_portid(flash->ioc));
4255 bfa_alen_set(&msg->alen, sizeof(struct bfa_flash_attr_s),
4256 flash->dbuf_pa);
4257 bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4261 * Send flash write request.
4263 * @param[in] cbarg - callback argument
4265 static void
4266 bfa_flash_write_send(struct bfa_flash_s *flash)
4268 struct bfi_flash_write_req_s *msg =
4269 (struct bfi_flash_write_req_s *) flash->mb.msg;
4270 u32 len;
4272 msg->type = be32_to_cpu(flash->type);
4273 msg->instance = flash->instance;
4274 msg->offset = be32_to_cpu(flash->addr_off + flash->offset);
4275 len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ?
4276 flash->residue : BFA_FLASH_DMA_BUF_SZ;
4277 msg->length = be32_to_cpu(len);
4279 /* indicate if it's the last msg of the whole write operation */
4280 msg->last = (len == flash->residue) ? 1 : 0;
4282 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_WRITE_REQ,
4283 bfa_ioc_portid(flash->ioc));
4284 bfa_alen_set(&msg->alen, len, flash->dbuf_pa);
4285 memcpy(flash->dbuf_kva, flash->ubuf + flash->offset, len);
4286 bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4288 flash->residue -= len;
4289 flash->offset += len;
4293 * Send flash read request.
4295 * @param[in] cbarg - callback argument
4297 static void
4298 bfa_flash_read_send(void *cbarg)
4300 struct bfa_flash_s *flash = cbarg;
4301 struct bfi_flash_read_req_s *msg =
4302 (struct bfi_flash_read_req_s *) flash->mb.msg;
4303 u32 len;
4305 msg->type = be32_to_cpu(flash->type);
4306 msg->instance = flash->instance;
4307 msg->offset = be32_to_cpu(flash->addr_off + flash->offset);
4308 len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ?
4309 flash->residue : BFA_FLASH_DMA_BUF_SZ;
4310 msg->length = be32_to_cpu(len);
4311 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_READ_REQ,
4312 bfa_ioc_portid(flash->ioc));
4313 bfa_alen_set(&msg->alen, len, flash->dbuf_pa);
4314 bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4318 * Send flash erase request.
4320 * @param[in] cbarg - callback argument
4322 static void
4323 bfa_flash_erase_send(void *cbarg)
4325 struct bfa_flash_s *flash = cbarg;
4326 struct bfi_flash_erase_req_s *msg =
4327 (struct bfi_flash_erase_req_s *) flash->mb.msg;
4329 msg->type = be32_to_cpu(flash->type);
4330 msg->instance = flash->instance;
4331 bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_ERASE_REQ,
4332 bfa_ioc_portid(flash->ioc));
4333 bfa_ioc_mbox_queue(flash->ioc, &flash->mb);
4337 * Process flash response messages upon receiving interrupts.
4339 * @param[in] flasharg - flash structure
4340 * @param[in] msg - message structure
4342 static void
4343 bfa_flash_intr(void *flasharg, struct bfi_mbmsg_s *msg)
4345 struct bfa_flash_s *flash = flasharg;
4346 u32 status;
4348 union {
4349 struct bfi_flash_query_rsp_s *query;
4350 struct bfi_flash_erase_rsp_s *erase;
4351 struct bfi_flash_write_rsp_s *write;
4352 struct bfi_flash_read_rsp_s *read;
4353 struct bfi_flash_event_s *event;
4354 struct bfi_mbmsg_s *msg;
4355 } m;
4357 m.msg = msg;
4358 bfa_trc(flash, msg->mh.msg_id);
4360 if (!flash->op_busy && msg->mh.msg_id != BFI_FLASH_I2H_EVENT) {
4361 /* receiving response after ioc failure */
4362 bfa_trc(flash, 0x9999);
4363 return;
4366 switch (msg->mh.msg_id) {
4367 case BFI_FLASH_I2H_QUERY_RSP:
4368 status = be32_to_cpu(m.query->status);
4369 bfa_trc(flash, status);
4370 if (status == BFA_STATUS_OK) {
4371 u32 i;
4372 struct bfa_flash_attr_s *attr, *f;
4374 attr = (struct bfa_flash_attr_s *) flash->ubuf;
4375 f = (struct bfa_flash_attr_s *) flash->dbuf_kva;
4376 attr->status = be32_to_cpu(f->status);
4377 attr->npart = be32_to_cpu(f->npart);
4378 bfa_trc(flash, attr->status);
4379 bfa_trc(flash, attr->npart);
4380 for (i = 0; i < attr->npart; i++) {
4381 attr->part[i].part_type =
4382 be32_to_cpu(f->part[i].part_type);
4383 attr->part[i].part_instance =
4384 be32_to_cpu(f->part[i].part_instance);
4385 attr->part[i].part_off =
4386 be32_to_cpu(f->part[i].part_off);
4387 attr->part[i].part_size =
4388 be32_to_cpu(f->part[i].part_size);
4389 attr->part[i].part_len =
4390 be32_to_cpu(f->part[i].part_len);
4391 attr->part[i].part_status =
4392 be32_to_cpu(f->part[i].part_status);
4395 flash->status = status;
4396 bfa_flash_cb(flash);
4397 break;
4398 case BFI_FLASH_I2H_ERASE_RSP:
4399 status = be32_to_cpu(m.erase->status);
4400 bfa_trc(flash, status);
4401 flash->status = status;
4402 bfa_flash_cb(flash);
4403 break;
4404 case BFI_FLASH_I2H_WRITE_RSP:
4405 status = be32_to_cpu(m.write->status);
4406 bfa_trc(flash, status);
4407 if (status != BFA_STATUS_OK || flash->residue == 0) {
4408 flash->status = status;
4409 bfa_flash_cb(flash);
4410 } else {
4411 bfa_trc(flash, flash->offset);
4412 bfa_flash_write_send(flash);
4414 break;
4415 case BFI_FLASH_I2H_READ_RSP:
4416 status = be32_to_cpu(m.read->status);
4417 bfa_trc(flash, status);
4418 if (status != BFA_STATUS_OK) {
4419 flash->status = status;
4420 bfa_flash_cb(flash);
4421 } else {
4422 u32 len = be32_to_cpu(m.read->length);
4423 bfa_trc(flash, flash->offset);
4424 bfa_trc(flash, len);
4425 memcpy(flash->ubuf + flash->offset,
4426 flash->dbuf_kva, len);
4427 flash->residue -= len;
4428 flash->offset += len;
4429 if (flash->residue == 0) {
4430 flash->status = status;
4431 bfa_flash_cb(flash);
4432 } else
4433 bfa_flash_read_send(flash);
4435 break;
4436 case BFI_FLASH_I2H_BOOT_VER_RSP:
4437 break;
4438 case BFI_FLASH_I2H_EVENT:
4439 status = be32_to_cpu(m.event->status);
4440 bfa_trc(flash, status);
4441 if (status == BFA_STATUS_BAD_FWCFG)
4442 bfa_ioc_aen_post(flash->ioc, BFA_IOC_AEN_FWCFG_ERROR);
4443 else if (status == BFA_STATUS_INVALID_VENDOR) {
4444 u32 param;
4445 param = be32_to_cpu(m.event->param);
4446 bfa_trc(flash, param);
4447 bfa_ioc_aen_post(flash->ioc,
4448 BFA_IOC_AEN_INVALID_VENDOR);
4450 break;
4452 default:
4453 WARN_ON(1);
4458 * Flash memory info API.
4460 * @param[in] mincfg - minimal cfg variable
4463 bfa_flash_meminfo(bfa_boolean_t mincfg)
4465 /* min driver doesn't need flash */
4466 if (mincfg)
4467 return 0;
4468 return BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
4472 * Flash attach API.
4474 * @param[in] flash - flash structure
4475 * @param[in] ioc - ioc structure
4476 * @param[in] dev - device structure
4477 * @param[in] trcmod - trace module
4478 * @param[in] logmod - log module
4480 void
4481 bfa_flash_attach(struct bfa_flash_s *flash, struct bfa_ioc_s *ioc, void *dev,
4482 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
4484 flash->ioc = ioc;
4485 flash->trcmod = trcmod;
4486 flash->cbfn = NULL;
4487 flash->cbarg = NULL;
4488 flash->op_busy = 0;
4490 bfa_ioc_mbox_regisr(flash->ioc, BFI_MC_FLASH, bfa_flash_intr, flash);
4491 bfa_q_qe_init(&flash->ioc_notify);
4492 bfa_ioc_notify_init(&flash->ioc_notify, bfa_flash_notify, flash);
4493 list_add_tail(&flash->ioc_notify.qe, &flash->ioc->notify_q);
4495 /* min driver doesn't need flash */
4496 if (mincfg) {
4497 flash->dbuf_kva = NULL;
4498 flash->dbuf_pa = 0;
4503 * Claim memory for flash
4505 * @param[in] flash - flash structure
4506 * @param[in] dm_kva - pointer to virtual memory address
4507 * @param[in] dm_pa - physical memory address
4508 * @param[in] mincfg - minimal cfg variable
4510 void
4511 bfa_flash_memclaim(struct bfa_flash_s *flash, u8 *dm_kva, u64 dm_pa,
4512 bfa_boolean_t mincfg)
4514 if (mincfg)
4515 return;
4517 flash->dbuf_kva = dm_kva;
4518 flash->dbuf_pa = dm_pa;
4519 memset(flash->dbuf_kva, 0, BFA_FLASH_DMA_BUF_SZ);
4520 dm_kva += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
4521 dm_pa += BFA_ROUNDUP(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
4525 * Get flash attribute.
4527 * @param[in] flash - flash structure
4528 * @param[in] attr - flash attribute structure
4529 * @param[in] cbfn - callback function
4530 * @param[in] cbarg - callback argument
4532 * Return status.
4534 bfa_status_t
4535 bfa_flash_get_attr(struct bfa_flash_s *flash, struct bfa_flash_attr_s *attr,
4536 bfa_cb_flash_t cbfn, void *cbarg)
4538 bfa_trc(flash, BFI_FLASH_H2I_QUERY_REQ);
4540 if (!bfa_ioc_is_operational(flash->ioc))
4541 return BFA_STATUS_IOC_NON_OP;
4543 if (flash->op_busy) {
4544 bfa_trc(flash, flash->op_busy);
4545 return BFA_STATUS_DEVBUSY;
4548 flash->op_busy = 1;
4549 flash->cbfn = cbfn;
4550 flash->cbarg = cbarg;
4551 flash->ubuf = (u8 *) attr;
4552 bfa_flash_query_send(flash);
4554 return BFA_STATUS_OK;
4558 * Erase flash partition.
4560 * @param[in] flash - flash structure
4561 * @param[in] type - flash partition type
4562 * @param[in] instance - flash partition instance
4563 * @param[in] cbfn - callback function
4564 * @param[in] cbarg - callback argument
4566 * Return status.
4568 bfa_status_t
4569 bfa_flash_erase_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
4570 u8 instance, bfa_cb_flash_t cbfn, void *cbarg)
4572 bfa_trc(flash, BFI_FLASH_H2I_ERASE_REQ);
4573 bfa_trc(flash, type);
4574 bfa_trc(flash, instance);
4576 if (!bfa_ioc_is_operational(flash->ioc))
4577 return BFA_STATUS_IOC_NON_OP;
4579 if (flash->op_busy) {
4580 bfa_trc(flash, flash->op_busy);
4581 return BFA_STATUS_DEVBUSY;
4584 flash->op_busy = 1;
4585 flash->cbfn = cbfn;
4586 flash->cbarg = cbarg;
4587 flash->type = type;
4588 flash->instance = instance;
4590 bfa_flash_erase_send(flash);
4591 bfa_flash_aen_audit_post(flash->ioc, BFA_AUDIT_AEN_FLASH_ERASE,
4592 instance, type);
4593 return BFA_STATUS_OK;
4597 * Update flash partition.
4599 * @param[in] flash - flash structure
4600 * @param[in] type - flash partition type
4601 * @param[in] instance - flash partition instance
4602 * @param[in] buf - update data buffer
4603 * @param[in] len - data buffer length
4604 * @param[in] offset - offset relative to the partition starting address
4605 * @param[in] cbfn - callback function
4606 * @param[in] cbarg - callback argument
4608 * Return status.
4610 bfa_status_t
4611 bfa_flash_update_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
4612 u8 instance, void *buf, u32 len, u32 offset,
4613 bfa_cb_flash_t cbfn, void *cbarg)
4615 bfa_trc(flash, BFI_FLASH_H2I_WRITE_REQ);
4616 bfa_trc(flash, type);
4617 bfa_trc(flash, instance);
4618 bfa_trc(flash, len);
4619 bfa_trc(flash, offset);
4621 if (!bfa_ioc_is_operational(flash->ioc))
4622 return BFA_STATUS_IOC_NON_OP;
4625 * 'len' must be in word (4-byte) boundary
4626 * 'offset' must be in sector (16kb) boundary
4628 if (!len || (len & 0x03) || (offset & 0x00003FFF))
4629 return BFA_STATUS_FLASH_BAD_LEN;
4631 if (type == BFA_FLASH_PART_MFG)
4632 return BFA_STATUS_EINVAL;
4634 if (flash->op_busy) {
4635 bfa_trc(flash, flash->op_busy);
4636 return BFA_STATUS_DEVBUSY;
4639 flash->op_busy = 1;
4640 flash->cbfn = cbfn;
4641 flash->cbarg = cbarg;
4642 flash->type = type;
4643 flash->instance = instance;
4644 flash->residue = len;
4645 flash->offset = 0;
4646 flash->addr_off = offset;
4647 flash->ubuf = buf;
4649 bfa_flash_write_send(flash);
4650 return BFA_STATUS_OK;
4654 * Read flash partition.
4656 * @param[in] flash - flash structure
4657 * @param[in] type - flash partition type
4658 * @param[in] instance - flash partition instance
4659 * @param[in] buf - read data buffer
4660 * @param[in] len - data buffer length
4661 * @param[in] offset - offset relative to the partition starting address
4662 * @param[in] cbfn - callback function
4663 * @param[in] cbarg - callback argument
4665 * Return status.
4667 bfa_status_t
4668 bfa_flash_read_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type,
4669 u8 instance, void *buf, u32 len, u32 offset,
4670 bfa_cb_flash_t cbfn, void *cbarg)
4672 bfa_trc(flash, BFI_FLASH_H2I_READ_REQ);
4673 bfa_trc(flash, type);
4674 bfa_trc(flash, instance);
4675 bfa_trc(flash, len);
4676 bfa_trc(flash, offset);
4678 if (!bfa_ioc_is_operational(flash->ioc))
4679 return BFA_STATUS_IOC_NON_OP;
4682 * 'len' must be in word (4-byte) boundary
4683 * 'offset' must be in sector (16kb) boundary
4685 if (!len || (len & 0x03) || (offset & 0x00003FFF))
4686 return BFA_STATUS_FLASH_BAD_LEN;
4688 if (flash->op_busy) {
4689 bfa_trc(flash, flash->op_busy);
4690 return BFA_STATUS_DEVBUSY;
4693 flash->op_busy = 1;
4694 flash->cbfn = cbfn;
4695 flash->cbarg = cbarg;
4696 flash->type = type;
4697 flash->instance = instance;
4698 flash->residue = len;
4699 flash->offset = 0;
4700 flash->addr_off = offset;
4701 flash->ubuf = buf;
4702 bfa_flash_read_send(flash);
4704 return BFA_STATUS_OK;
4708 * DIAG module specific
4711 #define BFA_DIAG_MEMTEST_TOV 50000 /* memtest timeout in msec */
4712 #define CT2_BFA_DIAG_MEMTEST_TOV (9*30*1000) /* 4.5 min */
4714 /* IOC event handler */
4715 static void
4716 bfa_diag_notify(void *diag_arg, enum bfa_ioc_event_e event)
4718 struct bfa_diag_s *diag = diag_arg;
4720 bfa_trc(diag, event);
4721 bfa_trc(diag, diag->block);
4722 bfa_trc(diag, diag->fwping.lock);
4723 bfa_trc(diag, diag->tsensor.lock);
4725 switch (event) {
4726 case BFA_IOC_E_DISABLED:
4727 case BFA_IOC_E_FAILED:
4728 if (diag->fwping.lock) {
4729 diag->fwping.status = BFA_STATUS_IOC_FAILURE;
4730 diag->fwping.cbfn(diag->fwping.cbarg,
4731 diag->fwping.status);
4732 diag->fwping.lock = 0;
4735 if (diag->tsensor.lock) {
4736 diag->tsensor.status = BFA_STATUS_IOC_FAILURE;
4737 diag->tsensor.cbfn(diag->tsensor.cbarg,
4738 diag->tsensor.status);
4739 diag->tsensor.lock = 0;
4742 if (diag->block) {
4743 if (diag->timer_active) {
4744 bfa_timer_stop(&diag->timer);
4745 diag->timer_active = 0;
4748 diag->status = BFA_STATUS_IOC_FAILURE;
4749 diag->cbfn(diag->cbarg, diag->status);
4750 diag->block = 0;
4752 break;
4754 default:
4755 break;
4759 static void
4760 bfa_diag_memtest_done(void *cbarg)
4762 struct bfa_diag_s *diag = cbarg;
4763 struct bfa_ioc_s *ioc = diag->ioc;
4764 struct bfa_diag_memtest_result *res = diag->result;
4765 u32 loff = BFI_BOOT_MEMTEST_RES_ADDR;
4766 u32 pgnum, pgoff, i;
4768 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
4769 pgoff = PSS_SMEM_PGOFF(loff);
4771 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
4773 for (i = 0; i < (sizeof(struct bfa_diag_memtest_result) /
4774 sizeof(u32)); i++) {
4775 /* read test result from smem */
4776 *((u32 *) res + i) =
4777 bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
4778 loff += sizeof(u32);
4781 /* Reset IOC fwstates to BFI_IOC_UNINIT */
4782 bfa_ioc_reset_fwstate(ioc);
4784 res->status = swab32(res->status);
4785 bfa_trc(diag, res->status);
4787 if (res->status == BFI_BOOT_MEMTEST_RES_SIG)
4788 diag->status = BFA_STATUS_OK;
4789 else {
4790 diag->status = BFA_STATUS_MEMTEST_FAILED;
4791 res->addr = swab32(res->addr);
4792 res->exp = swab32(res->exp);
4793 res->act = swab32(res->act);
4794 res->err_status = swab32(res->err_status);
4795 res->err_status1 = swab32(res->err_status1);
4796 res->err_addr = swab32(res->err_addr);
4797 bfa_trc(diag, res->addr);
4798 bfa_trc(diag, res->exp);
4799 bfa_trc(diag, res->act);
4800 bfa_trc(diag, res->err_status);
4801 bfa_trc(diag, res->err_status1);
4802 bfa_trc(diag, res->err_addr);
4804 diag->timer_active = 0;
4805 diag->cbfn(diag->cbarg, diag->status);
4806 diag->block = 0;
4810 * Firmware ping
4814 * Perform DMA test directly
4816 static void
4817 diag_fwping_send(struct bfa_diag_s *diag)
4819 struct bfi_diag_fwping_req_s *fwping_req;
4820 u32 i;
4822 bfa_trc(diag, diag->fwping.dbuf_pa);
4824 /* fill DMA area with pattern */
4825 for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++)
4826 *((u32 *)diag->fwping.dbuf_kva + i) = diag->fwping.data;
4828 /* Fill mbox msg */
4829 fwping_req = (struct bfi_diag_fwping_req_s *)diag->fwping.mbcmd.msg;
4831 /* Setup SG list */
4832 bfa_alen_set(&fwping_req->alen, BFI_DIAG_DMA_BUF_SZ,
4833 diag->fwping.dbuf_pa);
4834 /* Set up dma count */
4835 fwping_req->count = cpu_to_be32(diag->fwping.count);
4836 /* Set up data pattern */
4837 fwping_req->data = diag->fwping.data;
4839 /* build host command */
4840 bfi_h2i_set(fwping_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_FWPING,
4841 bfa_ioc_portid(diag->ioc));
4843 /* send mbox cmd */
4844 bfa_ioc_mbox_queue(diag->ioc, &diag->fwping.mbcmd);
4847 static void
4848 diag_fwping_comp(struct bfa_diag_s *diag,
4849 struct bfi_diag_fwping_rsp_s *diag_rsp)
4851 u32 rsp_data = diag_rsp->data;
4852 u8 rsp_dma_status = diag_rsp->dma_status;
4854 bfa_trc(diag, rsp_data);
4855 bfa_trc(diag, rsp_dma_status);
4857 if (rsp_dma_status == BFA_STATUS_OK) {
4858 u32 i, pat;
4859 pat = (diag->fwping.count & 0x1) ? ~(diag->fwping.data) :
4860 diag->fwping.data;
4861 /* Check mbox data */
4862 if (diag->fwping.data != rsp_data) {
4863 bfa_trc(diag, rsp_data);
4864 diag->fwping.result->dmastatus =
4865 BFA_STATUS_DATACORRUPTED;
4866 diag->fwping.status = BFA_STATUS_DATACORRUPTED;
4867 diag->fwping.cbfn(diag->fwping.cbarg,
4868 diag->fwping.status);
4869 diag->fwping.lock = 0;
4870 return;
4872 /* Check dma pattern */
4873 for (i = 0; i < (BFI_DIAG_DMA_BUF_SZ >> 2); i++) {
4874 if (*((u32 *)diag->fwping.dbuf_kva + i) != pat) {
4875 bfa_trc(diag, i);
4876 bfa_trc(diag, pat);
4877 bfa_trc(diag,
4878 *((u32 *)diag->fwping.dbuf_kva + i));
4879 diag->fwping.result->dmastatus =
4880 BFA_STATUS_DATACORRUPTED;
4881 diag->fwping.status = BFA_STATUS_DATACORRUPTED;
4882 diag->fwping.cbfn(diag->fwping.cbarg,
4883 diag->fwping.status);
4884 diag->fwping.lock = 0;
4885 return;
4888 diag->fwping.result->dmastatus = BFA_STATUS_OK;
4889 diag->fwping.status = BFA_STATUS_OK;
4890 diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status);
4891 diag->fwping.lock = 0;
4892 } else {
4893 diag->fwping.status = BFA_STATUS_HDMA_FAILED;
4894 diag->fwping.cbfn(diag->fwping.cbarg, diag->fwping.status);
4895 diag->fwping.lock = 0;
4900 * Temperature Sensor
4903 static void
4904 diag_tempsensor_send(struct bfa_diag_s *diag)
4906 struct bfi_diag_ts_req_s *msg;
4908 msg = (struct bfi_diag_ts_req_s *)diag->tsensor.mbcmd.msg;
4909 bfa_trc(diag, msg->temp);
4910 /* build host command */
4911 bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_TEMPSENSOR,
4912 bfa_ioc_portid(diag->ioc));
4913 /* send mbox cmd */
4914 bfa_ioc_mbox_queue(diag->ioc, &diag->tsensor.mbcmd);
4917 static void
4918 diag_tempsensor_comp(struct bfa_diag_s *diag, bfi_diag_ts_rsp_t *rsp)
4920 if (!diag->tsensor.lock) {
4921 /* receiving response after ioc failure */
4922 bfa_trc(diag, diag->tsensor.lock);
4923 return;
4927 * ASIC junction tempsensor is a reg read operation
4928 * it will always return OK
4930 diag->tsensor.temp->temp = be16_to_cpu(rsp->temp);
4931 diag->tsensor.temp->ts_junc = rsp->ts_junc;
4932 diag->tsensor.temp->ts_brd = rsp->ts_brd;
4934 if (rsp->ts_brd) {
4935 /* tsensor.temp->status is brd_temp status */
4936 diag->tsensor.temp->status = rsp->status;
4937 if (rsp->status == BFA_STATUS_OK) {
4938 diag->tsensor.temp->brd_temp =
4939 be16_to_cpu(rsp->brd_temp);
4940 } else
4941 diag->tsensor.temp->brd_temp = 0;
4944 bfa_trc(diag, rsp->status);
4945 bfa_trc(diag, rsp->ts_junc);
4946 bfa_trc(diag, rsp->temp);
4947 bfa_trc(diag, rsp->ts_brd);
4948 bfa_trc(diag, rsp->brd_temp);
4950 /* tsensor status is always good bcos we always have junction temp */
4951 diag->tsensor.status = BFA_STATUS_OK;
4952 diag->tsensor.cbfn(diag->tsensor.cbarg, diag->tsensor.status);
4953 diag->tsensor.lock = 0;
4957 * LED Test command
4959 static void
4960 diag_ledtest_send(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest)
4962 struct bfi_diag_ledtest_req_s *msg;
4964 msg = (struct bfi_diag_ledtest_req_s *)diag->ledtest.mbcmd.msg;
4965 /* build host command */
4966 bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LEDTEST,
4967 bfa_ioc_portid(diag->ioc));
4970 * convert the freq from N blinks per 10 sec to
4971 * crossbow ontime value. We do it here because division is need
4973 if (ledtest->freq)
4974 ledtest->freq = 500 / ledtest->freq;
4976 if (ledtest->freq == 0)
4977 ledtest->freq = 1;
4979 bfa_trc(diag, ledtest->freq);
4980 /* mcpy(&ledtest_req->req, ledtest, sizeof(bfa_diag_ledtest_t)); */
4981 msg->cmd = (u8) ledtest->cmd;
4982 msg->color = (u8) ledtest->color;
4983 msg->portid = bfa_ioc_portid(diag->ioc);
4984 msg->led = ledtest->led;
4985 msg->freq = cpu_to_be16(ledtest->freq);
4987 /* send mbox cmd */
4988 bfa_ioc_mbox_queue(diag->ioc, &diag->ledtest.mbcmd);
4991 static void
4992 diag_ledtest_comp(struct bfa_diag_s *diag, struct bfi_diag_ledtest_rsp_s *msg)
4994 bfa_trc(diag, diag->ledtest.lock);
4995 diag->ledtest.lock = BFA_FALSE;
4996 /* no bfa_cb_queue is needed because driver is not waiting */
5000 * Port beaconing
5002 static void
5003 diag_portbeacon_send(struct bfa_diag_s *diag, bfa_boolean_t beacon, u32 sec)
5005 struct bfi_diag_portbeacon_req_s *msg;
5007 msg = (struct bfi_diag_portbeacon_req_s *)diag->beacon.mbcmd.msg;
5008 /* build host command */
5009 bfi_h2i_set(msg->mh, BFI_MC_DIAG, BFI_DIAG_H2I_PORTBEACON,
5010 bfa_ioc_portid(diag->ioc));
5011 msg->beacon = beacon;
5012 msg->period = cpu_to_be32(sec);
5013 /* send mbox cmd */
5014 bfa_ioc_mbox_queue(diag->ioc, &diag->beacon.mbcmd);
5017 static void
5018 diag_portbeacon_comp(struct bfa_diag_s *diag)
5020 bfa_trc(diag, diag->beacon.state);
5021 diag->beacon.state = BFA_FALSE;
5022 if (diag->cbfn_beacon)
5023 diag->cbfn_beacon(diag->dev, BFA_FALSE, diag->beacon.link_e2e);
5027 * Diag hmbox handler
5029 void
5030 bfa_diag_intr(void *diagarg, struct bfi_mbmsg_s *msg)
5032 struct bfa_diag_s *diag = diagarg;
5034 switch (msg->mh.msg_id) {
5035 case BFI_DIAG_I2H_PORTBEACON:
5036 diag_portbeacon_comp(diag);
5037 break;
5038 case BFI_DIAG_I2H_FWPING:
5039 diag_fwping_comp(diag, (struct bfi_diag_fwping_rsp_s *) msg);
5040 break;
5041 case BFI_DIAG_I2H_TEMPSENSOR:
5042 diag_tempsensor_comp(diag, (bfi_diag_ts_rsp_t *) msg);
5043 break;
5044 case BFI_DIAG_I2H_LEDTEST:
5045 diag_ledtest_comp(diag, (struct bfi_diag_ledtest_rsp_s *) msg);
5046 break;
5047 default:
5048 bfa_trc(diag, msg->mh.msg_id);
5049 WARN_ON(1);
5054 * Gen RAM Test
5056 * @param[in] *diag - diag data struct
5057 * @param[in] *memtest - mem test params input from upper layer,
5058 * @param[in] pattern - mem test pattern
5059 * @param[in] *result - mem test result
5060 * @param[in] cbfn - mem test callback functioin
5061 * @param[in] cbarg - callback functioin arg
5063 * @param[out]
5065 bfa_status_t
5066 bfa_diag_memtest(struct bfa_diag_s *diag, struct bfa_diag_memtest_s *memtest,
5067 u32 pattern, struct bfa_diag_memtest_result *result,
5068 bfa_cb_diag_t cbfn, void *cbarg)
5070 u32 memtest_tov;
5072 bfa_trc(diag, pattern);
5074 if (!bfa_ioc_adapter_is_disabled(diag->ioc))
5075 return BFA_STATUS_ADAPTER_ENABLED;
5077 /* check to see if there is another destructive diag cmd running */
5078 if (diag->block) {
5079 bfa_trc(diag, diag->block);
5080 return BFA_STATUS_DEVBUSY;
5081 } else
5082 diag->block = 1;
5084 diag->result = result;
5085 diag->cbfn = cbfn;
5086 diag->cbarg = cbarg;
5088 /* download memtest code and take LPU0 out of reset */
5089 bfa_ioc_boot(diag->ioc, BFI_FWBOOT_TYPE_MEMTEST, BFI_FWBOOT_ENV_OS);
5091 memtest_tov = (bfa_ioc_asic_gen(diag->ioc) == BFI_ASIC_GEN_CT2) ?
5092 CT2_BFA_DIAG_MEMTEST_TOV : BFA_DIAG_MEMTEST_TOV;
5093 bfa_timer_begin(diag->ioc->timer_mod, &diag->timer,
5094 bfa_diag_memtest_done, diag, memtest_tov);
5095 diag->timer_active = 1;
5096 return BFA_STATUS_OK;
5100 * DIAG firmware ping command
5102 * @param[in] *diag - diag data struct
5103 * @param[in] cnt - dma loop count for testing PCIE
5104 * @param[in] data - data pattern to pass in fw
5105 * @param[in] *result - pt to bfa_diag_fwping_result_t data struct
5106 * @param[in] cbfn - callback function
5107 * @param[in] *cbarg - callback functioin arg
5109 * @param[out]
5111 bfa_status_t
5112 bfa_diag_fwping(struct bfa_diag_s *diag, u32 cnt, u32 data,
5113 struct bfa_diag_results_fwping *result, bfa_cb_diag_t cbfn,
5114 void *cbarg)
5116 bfa_trc(diag, cnt);
5117 bfa_trc(diag, data);
5119 if (!bfa_ioc_is_operational(diag->ioc))
5120 return BFA_STATUS_IOC_NON_OP;
5122 if (bfa_asic_id_ct2(bfa_ioc_devid((diag->ioc))) &&
5123 ((diag->ioc)->clscode == BFI_PCIFN_CLASS_ETH))
5124 return BFA_STATUS_CMD_NOTSUPP;
5126 /* check to see if there is another destructive diag cmd running */
5127 if (diag->block || diag->fwping.lock) {
5128 bfa_trc(diag, diag->block);
5129 bfa_trc(diag, diag->fwping.lock);
5130 return BFA_STATUS_DEVBUSY;
5133 /* Initialization */
5134 diag->fwping.lock = 1;
5135 diag->fwping.cbfn = cbfn;
5136 diag->fwping.cbarg = cbarg;
5137 diag->fwping.result = result;
5138 diag->fwping.data = data;
5139 diag->fwping.count = cnt;
5141 /* Init test results */
5142 diag->fwping.result->data = 0;
5143 diag->fwping.result->status = BFA_STATUS_OK;
5145 /* kick off the first ping */
5146 diag_fwping_send(diag);
5147 return BFA_STATUS_OK;
5151 * Read Temperature Sensor
5153 * @param[in] *diag - diag data struct
5154 * @param[in] *result - pt to bfa_diag_temp_t data struct
5155 * @param[in] cbfn - callback function
5156 * @param[in] *cbarg - callback functioin arg
5158 * @param[out]
5160 bfa_status_t
5161 bfa_diag_tsensor_query(struct bfa_diag_s *diag,
5162 struct bfa_diag_results_tempsensor_s *result,
5163 bfa_cb_diag_t cbfn, void *cbarg)
5165 /* check to see if there is a destructive diag cmd running */
5166 if (diag->block || diag->tsensor.lock) {
5167 bfa_trc(diag, diag->block);
5168 bfa_trc(diag, diag->tsensor.lock);
5169 return BFA_STATUS_DEVBUSY;
5172 if (!bfa_ioc_is_operational(diag->ioc))
5173 return BFA_STATUS_IOC_NON_OP;
5175 /* Init diag mod params */
5176 diag->tsensor.lock = 1;
5177 diag->tsensor.temp = result;
5178 diag->tsensor.cbfn = cbfn;
5179 diag->tsensor.cbarg = cbarg;
5180 diag->tsensor.status = BFA_STATUS_OK;
5182 /* Send msg to fw */
5183 diag_tempsensor_send(diag);
5185 return BFA_STATUS_OK;
5189 * LED Test command
5191 * @param[in] *diag - diag data struct
5192 * @param[in] *ledtest - pt to ledtest data structure
5194 * @param[out]
5196 bfa_status_t
5197 bfa_diag_ledtest(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest)
5199 bfa_trc(diag, ledtest->cmd);
5201 if (!bfa_ioc_is_operational(diag->ioc))
5202 return BFA_STATUS_IOC_NON_OP;
5204 if (diag->beacon.state)
5205 return BFA_STATUS_BEACON_ON;
5207 if (diag->ledtest.lock)
5208 return BFA_STATUS_LEDTEST_OP;
5210 /* Send msg to fw */
5211 diag->ledtest.lock = BFA_TRUE;
5212 diag_ledtest_send(diag, ledtest);
5214 return BFA_STATUS_OK;
5218 * Port beaconing command
5220 * @param[in] *diag - diag data struct
5221 * @param[in] beacon - port beaconing 1:ON 0:OFF
5222 * @param[in] link_e2e_beacon - link beaconing 1:ON 0:OFF
5223 * @param[in] sec - beaconing duration in seconds
5225 * @param[out]
5227 bfa_status_t
5228 bfa_diag_beacon_port(struct bfa_diag_s *diag, bfa_boolean_t beacon,
5229 bfa_boolean_t link_e2e_beacon, uint32_t sec)
5231 bfa_trc(diag, beacon);
5232 bfa_trc(diag, link_e2e_beacon);
5233 bfa_trc(diag, sec);
5235 if (!bfa_ioc_is_operational(diag->ioc))
5236 return BFA_STATUS_IOC_NON_OP;
5238 if (diag->ledtest.lock)
5239 return BFA_STATUS_LEDTEST_OP;
5241 if (diag->beacon.state && beacon) /* beacon alread on */
5242 return BFA_STATUS_BEACON_ON;
5244 diag->beacon.state = beacon;
5245 diag->beacon.link_e2e = link_e2e_beacon;
5246 if (diag->cbfn_beacon)
5247 diag->cbfn_beacon(diag->dev, beacon, link_e2e_beacon);
5249 /* Send msg to fw */
5250 diag_portbeacon_send(diag, beacon, sec);
5252 return BFA_STATUS_OK;
5256 * Return DMA memory needed by diag module.
5259 bfa_diag_meminfo(void)
5261 return BFA_ROUNDUP(BFI_DIAG_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5265 * Attach virtual and physical memory for Diag.
5267 void
5268 bfa_diag_attach(struct bfa_diag_s *diag, struct bfa_ioc_s *ioc, void *dev,
5269 bfa_cb_diag_beacon_t cbfn_beacon, struct bfa_trc_mod_s *trcmod)
5271 diag->dev = dev;
5272 diag->ioc = ioc;
5273 diag->trcmod = trcmod;
5275 diag->block = 0;
5276 diag->cbfn = NULL;
5277 diag->cbarg = NULL;
5278 diag->result = NULL;
5279 diag->cbfn_beacon = cbfn_beacon;
5281 bfa_ioc_mbox_regisr(diag->ioc, BFI_MC_DIAG, bfa_diag_intr, diag);
5282 bfa_q_qe_init(&diag->ioc_notify);
5283 bfa_ioc_notify_init(&diag->ioc_notify, bfa_diag_notify, diag);
5284 list_add_tail(&diag->ioc_notify.qe, &diag->ioc->notify_q);
5287 void
5288 bfa_diag_memclaim(struct bfa_diag_s *diag, u8 *dm_kva, u64 dm_pa)
5290 diag->fwping.dbuf_kva = dm_kva;
5291 diag->fwping.dbuf_pa = dm_pa;
5292 memset(diag->fwping.dbuf_kva, 0, BFI_DIAG_DMA_BUF_SZ);
5296 * PHY module specific
5298 #define BFA_PHY_DMA_BUF_SZ 0x02000 /* 8k dma buffer */
5299 #define BFA_PHY_LOCK_STATUS 0x018878 /* phy semaphore status reg */
5301 static void
5302 bfa_phy_ntoh32(u32 *obuf, u32 *ibuf, int sz)
5304 int i, m = sz >> 2;
5306 for (i = 0; i < m; i++)
5307 obuf[i] = be32_to_cpu(ibuf[i]);
5310 static bfa_boolean_t
5311 bfa_phy_present(struct bfa_phy_s *phy)
5313 return (phy->ioc->attr->card_type == BFA_MFG_TYPE_LIGHTNING);
5316 static void
5317 bfa_phy_notify(void *cbarg, enum bfa_ioc_event_e event)
5319 struct bfa_phy_s *phy = cbarg;
5321 bfa_trc(phy, event);
5323 switch (event) {
5324 case BFA_IOC_E_DISABLED:
5325 case BFA_IOC_E_FAILED:
5326 if (phy->op_busy) {
5327 phy->status = BFA_STATUS_IOC_FAILURE;
5328 phy->cbfn(phy->cbarg, phy->status);
5329 phy->op_busy = 0;
5331 break;
5333 default:
5334 break;
5339 * Send phy attribute query request.
5341 * @param[in] cbarg - callback argument
5343 static void
5344 bfa_phy_query_send(void *cbarg)
5346 struct bfa_phy_s *phy = cbarg;
5347 struct bfi_phy_query_req_s *msg =
5348 (struct bfi_phy_query_req_s *) phy->mb.msg;
5350 msg->instance = phy->instance;
5351 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_QUERY_REQ,
5352 bfa_ioc_portid(phy->ioc));
5353 bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_attr_s), phy->dbuf_pa);
5354 bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5358 * Send phy write request.
5360 * @param[in] cbarg - callback argument
5362 static void
5363 bfa_phy_write_send(void *cbarg)
5365 struct bfa_phy_s *phy = cbarg;
5366 struct bfi_phy_write_req_s *msg =
5367 (struct bfi_phy_write_req_s *) phy->mb.msg;
5368 u32 len;
5369 u16 *buf, *dbuf;
5370 int i, sz;
5372 msg->instance = phy->instance;
5373 msg->offset = cpu_to_be32(phy->addr_off + phy->offset);
5374 len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ?
5375 phy->residue : BFA_PHY_DMA_BUF_SZ;
5376 msg->length = cpu_to_be32(len);
5378 /* indicate if it's the last msg of the whole write operation */
5379 msg->last = (len == phy->residue) ? 1 : 0;
5381 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_WRITE_REQ,
5382 bfa_ioc_portid(phy->ioc));
5383 bfa_alen_set(&msg->alen, len, phy->dbuf_pa);
5385 buf = (u16 *) (phy->ubuf + phy->offset);
5386 dbuf = (u16 *)phy->dbuf_kva;
5387 sz = len >> 1;
5388 for (i = 0; i < sz; i++)
5389 buf[i] = cpu_to_be16(dbuf[i]);
5391 bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5393 phy->residue -= len;
5394 phy->offset += len;
5398 * Send phy read request.
5400 * @param[in] cbarg - callback argument
5402 static void
5403 bfa_phy_read_send(void *cbarg)
5405 struct bfa_phy_s *phy = cbarg;
5406 struct bfi_phy_read_req_s *msg =
5407 (struct bfi_phy_read_req_s *) phy->mb.msg;
5408 u32 len;
5410 msg->instance = phy->instance;
5411 msg->offset = cpu_to_be32(phy->addr_off + phy->offset);
5412 len = (phy->residue < BFA_PHY_DMA_BUF_SZ) ?
5413 phy->residue : BFA_PHY_DMA_BUF_SZ;
5414 msg->length = cpu_to_be32(len);
5415 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_READ_REQ,
5416 bfa_ioc_portid(phy->ioc));
5417 bfa_alen_set(&msg->alen, len, phy->dbuf_pa);
5418 bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5422 * Send phy stats request.
5424 * @param[in] cbarg - callback argument
5426 static void
5427 bfa_phy_stats_send(void *cbarg)
5429 struct bfa_phy_s *phy = cbarg;
5430 struct bfi_phy_stats_req_s *msg =
5431 (struct bfi_phy_stats_req_s *) phy->mb.msg;
5433 msg->instance = phy->instance;
5434 bfi_h2i_set(msg->mh, BFI_MC_PHY, BFI_PHY_H2I_STATS_REQ,
5435 bfa_ioc_portid(phy->ioc));
5436 bfa_alen_set(&msg->alen, sizeof(struct bfa_phy_stats_s), phy->dbuf_pa);
5437 bfa_ioc_mbox_queue(phy->ioc, &phy->mb);
5441 * Flash memory info API.
5443 * @param[in] mincfg - minimal cfg variable
5446 bfa_phy_meminfo(bfa_boolean_t mincfg)
5448 /* min driver doesn't need phy */
5449 if (mincfg)
5450 return 0;
5452 return BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5456 * Flash attach API.
5458 * @param[in] phy - phy structure
5459 * @param[in] ioc - ioc structure
5460 * @param[in] dev - device structure
5461 * @param[in] trcmod - trace module
5462 * @param[in] logmod - log module
5464 void
5465 bfa_phy_attach(struct bfa_phy_s *phy, struct bfa_ioc_s *ioc, void *dev,
5466 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
5468 phy->ioc = ioc;
5469 phy->trcmod = trcmod;
5470 phy->cbfn = NULL;
5471 phy->cbarg = NULL;
5472 phy->op_busy = 0;
5474 bfa_ioc_mbox_regisr(phy->ioc, BFI_MC_PHY, bfa_phy_intr, phy);
5475 bfa_q_qe_init(&phy->ioc_notify);
5476 bfa_ioc_notify_init(&phy->ioc_notify, bfa_phy_notify, phy);
5477 list_add_tail(&phy->ioc_notify.qe, &phy->ioc->notify_q);
5479 /* min driver doesn't need phy */
5480 if (mincfg) {
5481 phy->dbuf_kva = NULL;
5482 phy->dbuf_pa = 0;
5487 * Claim memory for phy
5489 * @param[in] phy - phy structure
5490 * @param[in] dm_kva - pointer to virtual memory address
5491 * @param[in] dm_pa - physical memory address
5492 * @param[in] mincfg - minimal cfg variable
5494 void
5495 bfa_phy_memclaim(struct bfa_phy_s *phy, u8 *dm_kva, u64 dm_pa,
5496 bfa_boolean_t mincfg)
5498 if (mincfg)
5499 return;
5501 phy->dbuf_kva = dm_kva;
5502 phy->dbuf_pa = dm_pa;
5503 memset(phy->dbuf_kva, 0, BFA_PHY_DMA_BUF_SZ);
5504 dm_kva += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5505 dm_pa += BFA_ROUNDUP(BFA_PHY_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
5508 bfa_boolean_t
5509 bfa_phy_busy(struct bfa_ioc_s *ioc)
5511 void __iomem *rb;
5513 rb = bfa_ioc_bar0(ioc);
5514 return readl(rb + BFA_PHY_LOCK_STATUS);
5518 * Get phy attribute.
5520 * @param[in] phy - phy structure
5521 * @param[in] attr - phy attribute structure
5522 * @param[in] cbfn - callback function
5523 * @param[in] cbarg - callback argument
5525 * Return status.
5527 bfa_status_t
5528 bfa_phy_get_attr(struct bfa_phy_s *phy, u8 instance,
5529 struct bfa_phy_attr_s *attr, bfa_cb_phy_t cbfn, void *cbarg)
5531 bfa_trc(phy, BFI_PHY_H2I_QUERY_REQ);
5532 bfa_trc(phy, instance);
5534 if (!bfa_phy_present(phy))
5535 return BFA_STATUS_PHY_NOT_PRESENT;
5537 if (!bfa_ioc_is_operational(phy->ioc))
5538 return BFA_STATUS_IOC_NON_OP;
5540 if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5541 bfa_trc(phy, phy->op_busy);
5542 return BFA_STATUS_DEVBUSY;
5545 phy->op_busy = 1;
5546 phy->cbfn = cbfn;
5547 phy->cbarg = cbarg;
5548 phy->instance = instance;
5549 phy->ubuf = (uint8_t *) attr;
5550 bfa_phy_query_send(phy);
5552 return BFA_STATUS_OK;
5556 * Get phy stats.
5558 * @param[in] phy - phy structure
5559 * @param[in] instance - phy image instance
5560 * @param[in] stats - pointer to phy stats
5561 * @param[in] cbfn - callback function
5562 * @param[in] cbarg - callback argument
5564 * Return status.
5566 bfa_status_t
5567 bfa_phy_get_stats(struct bfa_phy_s *phy, u8 instance,
5568 struct bfa_phy_stats_s *stats,
5569 bfa_cb_phy_t cbfn, void *cbarg)
5571 bfa_trc(phy, BFI_PHY_H2I_STATS_REQ);
5572 bfa_trc(phy, instance);
5574 if (!bfa_phy_present(phy))
5575 return BFA_STATUS_PHY_NOT_PRESENT;
5577 if (!bfa_ioc_is_operational(phy->ioc))
5578 return BFA_STATUS_IOC_NON_OP;
5580 if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5581 bfa_trc(phy, phy->op_busy);
5582 return BFA_STATUS_DEVBUSY;
5585 phy->op_busy = 1;
5586 phy->cbfn = cbfn;
5587 phy->cbarg = cbarg;
5588 phy->instance = instance;
5589 phy->ubuf = (u8 *) stats;
5590 bfa_phy_stats_send(phy);
5592 return BFA_STATUS_OK;
5596 * Update phy image.
5598 * @param[in] phy - phy structure
5599 * @param[in] instance - phy image instance
5600 * @param[in] buf - update data buffer
5601 * @param[in] len - data buffer length
5602 * @param[in] offset - offset relative to starting address
5603 * @param[in] cbfn - callback function
5604 * @param[in] cbarg - callback argument
5606 * Return status.
5608 bfa_status_t
5609 bfa_phy_update(struct bfa_phy_s *phy, u8 instance,
5610 void *buf, u32 len, u32 offset,
5611 bfa_cb_phy_t cbfn, void *cbarg)
5613 bfa_trc(phy, BFI_PHY_H2I_WRITE_REQ);
5614 bfa_trc(phy, instance);
5615 bfa_trc(phy, len);
5616 bfa_trc(phy, offset);
5618 if (!bfa_phy_present(phy))
5619 return BFA_STATUS_PHY_NOT_PRESENT;
5621 if (!bfa_ioc_is_operational(phy->ioc))
5622 return BFA_STATUS_IOC_NON_OP;
5624 /* 'len' must be in word (4-byte) boundary */
5625 if (!len || (len & 0x03))
5626 return BFA_STATUS_FAILED;
5628 if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5629 bfa_trc(phy, phy->op_busy);
5630 return BFA_STATUS_DEVBUSY;
5633 phy->op_busy = 1;
5634 phy->cbfn = cbfn;
5635 phy->cbarg = cbarg;
5636 phy->instance = instance;
5637 phy->residue = len;
5638 phy->offset = 0;
5639 phy->addr_off = offset;
5640 phy->ubuf = buf;
5642 bfa_phy_write_send(phy);
5643 return BFA_STATUS_OK;
5647 * Read phy image.
5649 * @param[in] phy - phy structure
5650 * @param[in] instance - phy image instance
5651 * @param[in] buf - read data buffer
5652 * @param[in] len - data buffer length
5653 * @param[in] offset - offset relative to starting address
5654 * @param[in] cbfn - callback function
5655 * @param[in] cbarg - callback argument
5657 * Return status.
5659 bfa_status_t
5660 bfa_phy_read(struct bfa_phy_s *phy, u8 instance,
5661 void *buf, u32 len, u32 offset,
5662 bfa_cb_phy_t cbfn, void *cbarg)
5664 bfa_trc(phy, BFI_PHY_H2I_READ_REQ);
5665 bfa_trc(phy, instance);
5666 bfa_trc(phy, len);
5667 bfa_trc(phy, offset);
5669 if (!bfa_phy_present(phy))
5670 return BFA_STATUS_PHY_NOT_PRESENT;
5672 if (!bfa_ioc_is_operational(phy->ioc))
5673 return BFA_STATUS_IOC_NON_OP;
5675 /* 'len' must be in word (4-byte) boundary */
5676 if (!len || (len & 0x03))
5677 return BFA_STATUS_FAILED;
5679 if (phy->op_busy || bfa_phy_busy(phy->ioc)) {
5680 bfa_trc(phy, phy->op_busy);
5681 return BFA_STATUS_DEVBUSY;
5684 phy->op_busy = 1;
5685 phy->cbfn = cbfn;
5686 phy->cbarg = cbarg;
5687 phy->instance = instance;
5688 phy->residue = len;
5689 phy->offset = 0;
5690 phy->addr_off = offset;
5691 phy->ubuf = buf;
5692 bfa_phy_read_send(phy);
5694 return BFA_STATUS_OK;
5698 * Process phy response messages upon receiving interrupts.
5700 * @param[in] phyarg - phy structure
5701 * @param[in] msg - message structure
5703 void
5704 bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg)
5706 struct bfa_phy_s *phy = phyarg;
5707 u32 status;
5709 union {
5710 struct bfi_phy_query_rsp_s *query;
5711 struct bfi_phy_stats_rsp_s *stats;
5712 struct bfi_phy_write_rsp_s *write;
5713 struct bfi_phy_read_rsp_s *read;
5714 struct bfi_mbmsg_s *msg;
5715 } m;
5717 m.msg = msg;
5718 bfa_trc(phy, msg->mh.msg_id);
5720 if (!phy->op_busy) {
5721 /* receiving response after ioc failure */
5722 bfa_trc(phy, 0x9999);
5723 return;
5726 switch (msg->mh.msg_id) {
5727 case BFI_PHY_I2H_QUERY_RSP:
5728 status = be32_to_cpu(m.query->status);
5729 bfa_trc(phy, status);
5731 if (status == BFA_STATUS_OK) {
5732 struct bfa_phy_attr_s *attr =
5733 (struct bfa_phy_attr_s *) phy->ubuf;
5734 bfa_phy_ntoh32((u32 *)attr, (u32 *)phy->dbuf_kva,
5735 sizeof(struct bfa_phy_attr_s));
5736 bfa_trc(phy, attr->status);
5737 bfa_trc(phy, attr->length);
5740 phy->status = status;
5741 phy->op_busy = 0;
5742 if (phy->cbfn)
5743 phy->cbfn(phy->cbarg, phy->status);
5744 break;
5745 case BFI_PHY_I2H_STATS_RSP:
5746 status = be32_to_cpu(m.stats->status);
5747 bfa_trc(phy, status);
5749 if (status == BFA_STATUS_OK) {
5750 struct bfa_phy_stats_s *stats =
5751 (struct bfa_phy_stats_s *) phy->ubuf;
5752 bfa_phy_ntoh32((u32 *)stats, (u32 *)phy->dbuf_kva,
5753 sizeof(struct bfa_phy_stats_s));
5754 bfa_trc(phy, stats->status);
5757 phy->status = status;
5758 phy->op_busy = 0;
5759 if (phy->cbfn)
5760 phy->cbfn(phy->cbarg, phy->status);
5761 break;
5762 case BFI_PHY_I2H_WRITE_RSP:
5763 status = be32_to_cpu(m.write->status);
5764 bfa_trc(phy, status);
5766 if (status != BFA_STATUS_OK || phy->residue == 0) {
5767 phy->status = status;
5768 phy->op_busy = 0;
5769 if (phy->cbfn)
5770 phy->cbfn(phy->cbarg, phy->status);
5771 } else {
5772 bfa_trc(phy, phy->offset);
5773 bfa_phy_write_send(phy);
5775 break;
5776 case BFI_PHY_I2H_READ_RSP:
5777 status = be32_to_cpu(m.read->status);
5778 bfa_trc(phy, status);
5780 if (status != BFA_STATUS_OK) {
5781 phy->status = status;
5782 phy->op_busy = 0;
5783 if (phy->cbfn)
5784 phy->cbfn(phy->cbarg, phy->status);
5785 } else {
5786 u32 len = be32_to_cpu(m.read->length);
5787 u16 *buf = (u16 *)(phy->ubuf + phy->offset);
5788 u16 *dbuf = (u16 *)phy->dbuf_kva;
5789 int i, sz = len >> 1;
5791 bfa_trc(phy, phy->offset);
5792 bfa_trc(phy, len);
5794 for (i = 0; i < sz; i++)
5795 buf[i] = be16_to_cpu(dbuf[i]);
5797 phy->residue -= len;
5798 phy->offset += len;
5800 if (phy->residue == 0) {
5801 phy->status = status;
5802 phy->op_busy = 0;
5803 if (phy->cbfn)
5804 phy->cbfn(phy->cbarg, phy->status);
5805 } else
5806 bfa_phy_read_send(phy);
5808 break;
5809 default:
5810 WARN_ON(1);
5815 * DCONF state machine events
5817 enum bfa_dconf_event {
5818 BFA_DCONF_SM_INIT = 1, /* dconf Init */
5819 BFA_DCONF_SM_FLASH_COMP = 2, /* read/write to flash */
5820 BFA_DCONF_SM_WR = 3, /* binding change, map */
5821 BFA_DCONF_SM_TIMEOUT = 4, /* Start timer */
5822 BFA_DCONF_SM_EXIT = 5, /* exit dconf module */
5823 BFA_DCONF_SM_IOCDISABLE = 6, /* IOC disable event */
5826 /* forward declaration of DCONF state machine */
5827 static void bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf,
5828 enum bfa_dconf_event event);
5829 static void bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
5830 enum bfa_dconf_event event);
5831 static void bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf,
5832 enum bfa_dconf_event event);
5833 static void bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf,
5834 enum bfa_dconf_event event);
5835 static void bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf,
5836 enum bfa_dconf_event event);
5837 static void bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf,
5838 enum bfa_dconf_event event);
5839 static void bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf,
5840 enum bfa_dconf_event event);
5842 static void bfa_dconf_cbfn(void *dconf, bfa_status_t status);
5843 static void bfa_dconf_timer(void *cbarg);
5844 static bfa_status_t bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf);
5845 static void bfa_dconf_init_cb(void *arg, bfa_status_t status);
5848 * Beginning state of dconf module. Waiting for an event to start.
5850 static void
5851 bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5853 bfa_status_t bfa_status;
5854 bfa_trc(dconf->bfa, event);
5856 switch (event) {
5857 case BFA_DCONF_SM_INIT:
5858 if (dconf->min_cfg) {
5859 bfa_trc(dconf->bfa, dconf->min_cfg);
5860 bfa_fsm_send_event(&dconf->bfa->iocfc,
5861 IOCFC_E_DCONF_DONE);
5862 return;
5864 bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read);
5865 bfa_timer_start(dconf->bfa, &dconf->timer,
5866 bfa_dconf_timer, dconf, 2 * BFA_DCONF_UPDATE_TOV);
5867 bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa),
5868 BFA_FLASH_PART_DRV, dconf->instance,
5869 dconf->dconf,
5870 sizeof(struct bfa_dconf_s), 0,
5871 bfa_dconf_init_cb, dconf->bfa);
5872 if (bfa_status != BFA_STATUS_OK) {
5873 bfa_timer_stop(&dconf->timer);
5874 bfa_dconf_init_cb(dconf->bfa, BFA_STATUS_FAILED);
5875 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5876 return;
5878 break;
5879 case BFA_DCONF_SM_EXIT:
5880 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5881 case BFA_DCONF_SM_IOCDISABLE:
5882 case BFA_DCONF_SM_WR:
5883 case BFA_DCONF_SM_FLASH_COMP:
5884 break;
5885 default:
5886 bfa_sm_fault(dconf->bfa, event);
5891 * Read flash for dconf entries and make a call back to the driver once done.
5893 static void
5894 bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf,
5895 enum bfa_dconf_event event)
5897 bfa_trc(dconf->bfa, event);
5899 switch (event) {
5900 case BFA_DCONF_SM_FLASH_COMP:
5901 bfa_timer_stop(&dconf->timer);
5902 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5903 break;
5904 case BFA_DCONF_SM_TIMEOUT:
5905 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
5906 bfa_ioc_suspend(&dconf->bfa->ioc);
5907 break;
5908 case BFA_DCONF_SM_EXIT:
5909 bfa_timer_stop(&dconf->timer);
5910 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5911 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5912 break;
5913 case BFA_DCONF_SM_IOCDISABLE:
5914 bfa_timer_stop(&dconf->timer);
5915 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5916 break;
5917 default:
5918 bfa_sm_fault(dconf->bfa, event);
5923 * DCONF Module is in ready state. Has completed the initialization.
5925 static void
5926 bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5928 bfa_trc(dconf->bfa, event);
5930 switch (event) {
5931 case BFA_DCONF_SM_WR:
5932 bfa_timer_start(dconf->bfa, &dconf->timer,
5933 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5934 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
5935 break;
5936 case BFA_DCONF_SM_EXIT:
5937 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
5938 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
5939 break;
5940 case BFA_DCONF_SM_INIT:
5941 case BFA_DCONF_SM_IOCDISABLE:
5942 break;
5943 default:
5944 bfa_sm_fault(dconf->bfa, event);
5949 * entries are dirty, write back to the flash.
5952 static void
5953 bfa_dconf_sm_dirty(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
5955 bfa_trc(dconf->bfa, event);
5957 switch (event) {
5958 case BFA_DCONF_SM_TIMEOUT:
5959 bfa_sm_set_state(dconf, bfa_dconf_sm_sync);
5960 bfa_dconf_flash_write(dconf);
5961 break;
5962 case BFA_DCONF_SM_WR:
5963 bfa_timer_stop(&dconf->timer);
5964 bfa_timer_start(dconf->bfa, &dconf->timer,
5965 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5966 break;
5967 case BFA_DCONF_SM_EXIT:
5968 bfa_timer_stop(&dconf->timer);
5969 bfa_timer_start(dconf->bfa, &dconf->timer,
5970 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
5971 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync);
5972 bfa_dconf_flash_write(dconf);
5973 break;
5974 case BFA_DCONF_SM_FLASH_COMP:
5975 break;
5976 case BFA_DCONF_SM_IOCDISABLE:
5977 bfa_timer_stop(&dconf->timer);
5978 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty);
5979 break;
5980 default:
5981 bfa_sm_fault(dconf->bfa, event);
5986 * Sync the dconf entries to the flash.
5988 static void
5989 bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf,
5990 enum bfa_dconf_event event)
5992 bfa_trc(dconf->bfa, event);
5994 switch (event) {
5995 case BFA_DCONF_SM_IOCDISABLE:
5996 case BFA_DCONF_SM_FLASH_COMP:
5997 bfa_timer_stop(&dconf->timer);
5998 /* fall through */
5999 case BFA_DCONF_SM_TIMEOUT:
6000 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
6001 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
6002 break;
6003 default:
6004 bfa_sm_fault(dconf->bfa, event);
6008 static void
6009 bfa_dconf_sm_sync(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event)
6011 bfa_trc(dconf->bfa, event);
6013 switch (event) {
6014 case BFA_DCONF_SM_FLASH_COMP:
6015 bfa_sm_set_state(dconf, bfa_dconf_sm_ready);
6016 break;
6017 case BFA_DCONF_SM_WR:
6018 bfa_timer_start(dconf->bfa, &dconf->timer,
6019 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6020 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
6021 break;
6022 case BFA_DCONF_SM_EXIT:
6023 bfa_timer_start(dconf->bfa, &dconf->timer,
6024 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6025 bfa_sm_set_state(dconf, bfa_dconf_sm_final_sync);
6026 break;
6027 case BFA_DCONF_SM_IOCDISABLE:
6028 bfa_sm_set_state(dconf, bfa_dconf_sm_iocdown_dirty);
6029 break;
6030 default:
6031 bfa_sm_fault(dconf->bfa, event);
6035 static void
6036 bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf,
6037 enum bfa_dconf_event event)
6039 bfa_trc(dconf->bfa, event);
6041 switch (event) {
6042 case BFA_DCONF_SM_INIT:
6043 bfa_timer_start(dconf->bfa, &dconf->timer,
6044 bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV);
6045 bfa_sm_set_state(dconf, bfa_dconf_sm_dirty);
6046 break;
6047 case BFA_DCONF_SM_EXIT:
6048 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
6049 bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE);
6050 break;
6051 case BFA_DCONF_SM_IOCDISABLE:
6052 break;
6053 default:
6054 bfa_sm_fault(dconf->bfa, event);
6059 * Compute and return memory needed by DRV_CFG module.
6061 void
6062 bfa_dconf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
6063 struct bfa_s *bfa)
6065 struct bfa_mem_kva_s *dconf_kva = BFA_MEM_DCONF_KVA(bfa);
6067 if (cfg->drvcfg.min_cfg)
6068 bfa_mem_kva_setup(meminfo, dconf_kva,
6069 sizeof(struct bfa_dconf_hdr_s));
6070 else
6071 bfa_mem_kva_setup(meminfo, dconf_kva,
6072 sizeof(struct bfa_dconf_s));
6075 void
6076 bfa_dconf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg)
6078 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6080 dconf->bfad = bfad;
6081 dconf->bfa = bfa;
6082 dconf->instance = bfa->ioc.port_id;
6083 bfa_trc(bfa, dconf->instance);
6085 dconf->dconf = (struct bfa_dconf_s *) bfa_mem_kva_curp(dconf);
6086 if (cfg->drvcfg.min_cfg) {
6087 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_hdr_s);
6088 dconf->min_cfg = BFA_TRUE;
6089 } else {
6090 dconf->min_cfg = BFA_FALSE;
6091 bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_s);
6094 bfa_dconf_read_data_valid(bfa) = BFA_FALSE;
6095 bfa_sm_set_state(dconf, bfa_dconf_sm_uninit);
6098 static void
6099 bfa_dconf_init_cb(void *arg, bfa_status_t status)
6101 struct bfa_s *bfa = arg;
6102 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6104 if (status == BFA_STATUS_OK) {
6105 bfa_dconf_read_data_valid(bfa) = BFA_TRUE;
6106 if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE)
6107 dconf->dconf->hdr.signature = BFI_DCONF_SIGNATURE;
6108 if (dconf->dconf->hdr.version != BFI_DCONF_VERSION)
6109 dconf->dconf->hdr.version = BFI_DCONF_VERSION;
6111 bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
6112 bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE);
6115 void
6116 bfa_dconf_modinit(struct bfa_s *bfa)
6118 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6119 bfa_sm_send_event(dconf, BFA_DCONF_SM_INIT);
6122 static void bfa_dconf_timer(void *cbarg)
6124 struct bfa_dconf_mod_s *dconf = cbarg;
6125 bfa_sm_send_event(dconf, BFA_DCONF_SM_TIMEOUT);
6128 void
6129 bfa_dconf_iocdisable(struct bfa_s *bfa)
6131 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6132 bfa_sm_send_event(dconf, BFA_DCONF_SM_IOCDISABLE);
6135 static bfa_status_t
6136 bfa_dconf_flash_write(struct bfa_dconf_mod_s *dconf)
6138 bfa_status_t bfa_status;
6139 bfa_trc(dconf->bfa, 0);
6141 bfa_status = bfa_flash_update_part(BFA_FLASH(dconf->bfa),
6142 BFA_FLASH_PART_DRV, dconf->instance,
6143 dconf->dconf, sizeof(struct bfa_dconf_s), 0,
6144 bfa_dconf_cbfn, dconf);
6145 if (bfa_status != BFA_STATUS_OK)
6146 WARN_ON(bfa_status);
6147 bfa_trc(dconf->bfa, bfa_status);
6149 return bfa_status;
6152 bfa_status_t
6153 bfa_dconf_update(struct bfa_s *bfa)
6155 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6156 bfa_trc(dconf->bfa, 0);
6157 if (bfa_sm_cmp_state(dconf, bfa_dconf_sm_iocdown_dirty))
6158 return BFA_STATUS_FAILED;
6160 if (dconf->min_cfg) {
6161 bfa_trc(dconf->bfa, dconf->min_cfg);
6162 return BFA_STATUS_FAILED;
6165 bfa_sm_send_event(dconf, BFA_DCONF_SM_WR);
6166 return BFA_STATUS_OK;
6169 static void
6170 bfa_dconf_cbfn(void *arg, bfa_status_t status)
6172 struct bfa_dconf_mod_s *dconf = arg;
6173 WARN_ON(status);
6174 bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP);
6177 void
6178 bfa_dconf_modexit(struct bfa_s *bfa)
6180 struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa);
6181 bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT);
6185 * FRU specific functions
6188 #define BFA_FRU_DMA_BUF_SZ 0x02000 /* 8k dma buffer */
6189 #define BFA_FRU_CHINOOK_MAX_SIZE 0x10000
6190 #define BFA_FRU_LIGHTNING_MAX_SIZE 0x200
6192 static void
6193 bfa_fru_notify(void *cbarg, enum bfa_ioc_event_e event)
6195 struct bfa_fru_s *fru = cbarg;
6197 bfa_trc(fru, event);
6199 switch (event) {
6200 case BFA_IOC_E_DISABLED:
6201 case BFA_IOC_E_FAILED:
6202 if (fru->op_busy) {
6203 fru->status = BFA_STATUS_IOC_FAILURE;
6204 fru->cbfn(fru->cbarg, fru->status);
6205 fru->op_busy = 0;
6207 break;
6209 default:
6210 break;
6215 * Send fru write request.
6217 * @param[in] cbarg - callback argument
6219 static void
6220 bfa_fru_write_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type)
6222 struct bfa_fru_s *fru = cbarg;
6223 struct bfi_fru_write_req_s *msg =
6224 (struct bfi_fru_write_req_s *) fru->mb.msg;
6225 u32 len;
6227 msg->offset = cpu_to_be32(fru->addr_off + fru->offset);
6228 len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ?
6229 fru->residue : BFA_FRU_DMA_BUF_SZ;
6230 msg->length = cpu_to_be32(len);
6233 * indicate if it's the last msg of the whole write operation
6235 msg->last = (len == fru->residue) ? 1 : 0;
6237 msg->trfr_cmpl = (len == fru->residue) ? fru->trfr_cmpl : 0;
6238 bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
6239 bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
6241 memcpy(fru->dbuf_kva, fru->ubuf + fru->offset, len);
6242 bfa_ioc_mbox_queue(fru->ioc, &fru->mb);
6244 fru->residue -= len;
6245 fru->offset += len;
6249 * Send fru read request.
6251 * @param[in] cbarg - callback argument
6253 static void
6254 bfa_fru_read_send(void *cbarg, enum bfi_fru_h2i_msgs msg_type)
6256 struct bfa_fru_s *fru = cbarg;
6257 struct bfi_fru_read_req_s *msg =
6258 (struct bfi_fru_read_req_s *) fru->mb.msg;
6259 u32 len;
6261 msg->offset = cpu_to_be32(fru->addr_off + fru->offset);
6262 len = (fru->residue < BFA_FRU_DMA_BUF_SZ) ?
6263 fru->residue : BFA_FRU_DMA_BUF_SZ;
6264 msg->length = cpu_to_be32(len);
6265 bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
6266 bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
6267 bfa_ioc_mbox_queue(fru->ioc, &fru->mb);
6271 * Flash memory info API.
6273 * @param[in] mincfg - minimal cfg variable
6276 bfa_fru_meminfo(bfa_boolean_t mincfg)
6278 /* min driver doesn't need fru */
6279 if (mincfg)
6280 return 0;
6282 return BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6286 * Flash attach API.
6288 * @param[in] fru - fru structure
6289 * @param[in] ioc - ioc structure
6290 * @param[in] dev - device structure
6291 * @param[in] trcmod - trace module
6292 * @param[in] logmod - log module
6294 void
6295 bfa_fru_attach(struct bfa_fru_s *fru, struct bfa_ioc_s *ioc, void *dev,
6296 struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg)
6298 fru->ioc = ioc;
6299 fru->trcmod = trcmod;
6300 fru->cbfn = NULL;
6301 fru->cbarg = NULL;
6302 fru->op_busy = 0;
6304 bfa_ioc_mbox_regisr(fru->ioc, BFI_MC_FRU, bfa_fru_intr, fru);
6305 bfa_q_qe_init(&fru->ioc_notify);
6306 bfa_ioc_notify_init(&fru->ioc_notify, bfa_fru_notify, fru);
6307 list_add_tail(&fru->ioc_notify.qe, &fru->ioc->notify_q);
6309 /* min driver doesn't need fru */
6310 if (mincfg) {
6311 fru->dbuf_kva = NULL;
6312 fru->dbuf_pa = 0;
6317 * Claim memory for fru
6319 * @param[in] fru - fru structure
6320 * @param[in] dm_kva - pointer to virtual memory address
6321 * @param[in] dm_pa - frusical memory address
6322 * @param[in] mincfg - minimal cfg variable
6324 void
6325 bfa_fru_memclaim(struct bfa_fru_s *fru, u8 *dm_kva, u64 dm_pa,
6326 bfa_boolean_t mincfg)
6328 if (mincfg)
6329 return;
6331 fru->dbuf_kva = dm_kva;
6332 fru->dbuf_pa = dm_pa;
6333 memset(fru->dbuf_kva, 0, BFA_FRU_DMA_BUF_SZ);
6334 dm_kva += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6335 dm_pa += BFA_ROUNDUP(BFA_FRU_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ);
6339 * Update fru vpd image.
6341 * @param[in] fru - fru structure
6342 * @param[in] buf - update data buffer
6343 * @param[in] len - data buffer length
6344 * @param[in] offset - offset relative to starting address
6345 * @param[in] cbfn - callback function
6346 * @param[in] cbarg - callback argument
6348 * Return status.
6350 bfa_status_t
6351 bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6352 bfa_cb_fru_t cbfn, void *cbarg, u8 trfr_cmpl)
6354 bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ);
6355 bfa_trc(fru, len);
6356 bfa_trc(fru, offset);
6358 if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2 &&
6359 fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2)
6360 return BFA_STATUS_FRU_NOT_PRESENT;
6362 if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK)
6363 return BFA_STATUS_CMD_NOTSUPP;
6365 if (!bfa_ioc_is_operational(fru->ioc))
6366 return BFA_STATUS_IOC_NON_OP;
6368 if (fru->op_busy) {
6369 bfa_trc(fru, fru->op_busy);
6370 return BFA_STATUS_DEVBUSY;
6373 fru->op_busy = 1;
6375 fru->cbfn = cbfn;
6376 fru->cbarg = cbarg;
6377 fru->residue = len;
6378 fru->offset = 0;
6379 fru->addr_off = offset;
6380 fru->ubuf = buf;
6381 fru->trfr_cmpl = trfr_cmpl;
6383 bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ);
6385 return BFA_STATUS_OK;
6389 * Read fru vpd image.
6391 * @param[in] fru - fru structure
6392 * @param[in] buf - read data buffer
6393 * @param[in] len - data buffer length
6394 * @param[in] offset - offset relative to starting address
6395 * @param[in] cbfn - callback function
6396 * @param[in] cbarg - callback argument
6398 * Return status.
6400 bfa_status_t
6401 bfa_fruvpd_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6402 bfa_cb_fru_t cbfn, void *cbarg)
6404 bfa_trc(fru, BFI_FRUVPD_H2I_READ_REQ);
6405 bfa_trc(fru, len);
6406 bfa_trc(fru, offset);
6408 if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6409 return BFA_STATUS_FRU_NOT_PRESENT;
6411 if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK &&
6412 fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2)
6413 return BFA_STATUS_CMD_NOTSUPP;
6415 if (!bfa_ioc_is_operational(fru->ioc))
6416 return BFA_STATUS_IOC_NON_OP;
6418 if (fru->op_busy) {
6419 bfa_trc(fru, fru->op_busy);
6420 return BFA_STATUS_DEVBUSY;
6423 fru->op_busy = 1;
6425 fru->cbfn = cbfn;
6426 fru->cbarg = cbarg;
6427 fru->residue = len;
6428 fru->offset = 0;
6429 fru->addr_off = offset;
6430 fru->ubuf = buf;
6431 bfa_fru_read_send(fru, BFI_FRUVPD_H2I_READ_REQ);
6433 return BFA_STATUS_OK;
6437 * Get maximum size fru vpd image.
6439 * @param[in] fru - fru structure
6440 * @param[out] size - maximum size of fru vpd data
6442 * Return status.
6444 bfa_status_t
6445 bfa_fruvpd_get_max_size(struct bfa_fru_s *fru, u32 *max_size)
6447 if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6448 return BFA_STATUS_FRU_NOT_PRESENT;
6450 if (!bfa_ioc_is_operational(fru->ioc))
6451 return BFA_STATUS_IOC_NON_OP;
6453 if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK ||
6454 fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK2)
6455 *max_size = BFA_FRU_CHINOOK_MAX_SIZE;
6456 else
6457 return BFA_STATUS_CMD_NOTSUPP;
6458 return BFA_STATUS_OK;
6461 * tfru write.
6463 * @param[in] fru - fru structure
6464 * @param[in] buf - update data buffer
6465 * @param[in] len - data buffer length
6466 * @param[in] offset - offset relative to starting address
6467 * @param[in] cbfn - callback function
6468 * @param[in] cbarg - callback argument
6470 * Return status.
6472 bfa_status_t
6473 bfa_tfru_write(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6474 bfa_cb_fru_t cbfn, void *cbarg)
6476 bfa_trc(fru, BFI_TFRU_H2I_WRITE_REQ);
6477 bfa_trc(fru, len);
6478 bfa_trc(fru, offset);
6479 bfa_trc(fru, *((u8 *) buf));
6481 if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6482 return BFA_STATUS_FRU_NOT_PRESENT;
6484 if (!bfa_ioc_is_operational(fru->ioc))
6485 return BFA_STATUS_IOC_NON_OP;
6487 if (fru->op_busy) {
6488 bfa_trc(fru, fru->op_busy);
6489 return BFA_STATUS_DEVBUSY;
6492 fru->op_busy = 1;
6494 fru->cbfn = cbfn;
6495 fru->cbarg = cbarg;
6496 fru->residue = len;
6497 fru->offset = 0;
6498 fru->addr_off = offset;
6499 fru->ubuf = buf;
6501 bfa_fru_write_send(fru, BFI_TFRU_H2I_WRITE_REQ);
6503 return BFA_STATUS_OK;
6507 * tfru read.
6509 * @param[in] fru - fru structure
6510 * @param[in] buf - read data buffer
6511 * @param[in] len - data buffer length
6512 * @param[in] offset - offset relative to starting address
6513 * @param[in] cbfn - callback function
6514 * @param[in] cbarg - callback argument
6516 * Return status.
6518 bfa_status_t
6519 bfa_tfru_read(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
6520 bfa_cb_fru_t cbfn, void *cbarg)
6522 bfa_trc(fru, BFI_TFRU_H2I_READ_REQ);
6523 bfa_trc(fru, len);
6524 bfa_trc(fru, offset);
6526 if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
6527 return BFA_STATUS_FRU_NOT_PRESENT;
6529 if (!bfa_ioc_is_operational(fru->ioc))
6530 return BFA_STATUS_IOC_NON_OP;
6532 if (fru->op_busy) {
6533 bfa_trc(fru, fru->op_busy);
6534 return BFA_STATUS_DEVBUSY;
6537 fru->op_busy = 1;
6539 fru->cbfn = cbfn;
6540 fru->cbarg = cbarg;
6541 fru->residue = len;
6542 fru->offset = 0;
6543 fru->addr_off = offset;
6544 fru->ubuf = buf;
6545 bfa_fru_read_send(fru, BFI_TFRU_H2I_READ_REQ);
6547 return BFA_STATUS_OK;
6551 * Process fru response messages upon receiving interrupts.
6553 * @param[in] fruarg - fru structure
6554 * @param[in] msg - message structure
6556 void
6557 bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg)
6559 struct bfa_fru_s *fru = fruarg;
6560 struct bfi_fru_rsp_s *rsp = (struct bfi_fru_rsp_s *)msg;
6561 u32 status;
6563 bfa_trc(fru, msg->mh.msg_id);
6565 if (!fru->op_busy) {
6567 * receiving response after ioc failure
6569 bfa_trc(fru, 0x9999);
6570 return;
6573 switch (msg->mh.msg_id) {
6574 case BFI_FRUVPD_I2H_WRITE_RSP:
6575 case BFI_TFRU_I2H_WRITE_RSP:
6576 status = be32_to_cpu(rsp->status);
6577 bfa_trc(fru, status);
6579 if (status != BFA_STATUS_OK || fru->residue == 0) {
6580 fru->status = status;
6581 fru->op_busy = 0;
6582 if (fru->cbfn)
6583 fru->cbfn(fru->cbarg, fru->status);
6584 } else {
6585 bfa_trc(fru, fru->offset);
6586 if (msg->mh.msg_id == BFI_FRUVPD_I2H_WRITE_RSP)
6587 bfa_fru_write_send(fru,
6588 BFI_FRUVPD_H2I_WRITE_REQ);
6589 else
6590 bfa_fru_write_send(fru,
6591 BFI_TFRU_H2I_WRITE_REQ);
6593 break;
6594 case BFI_FRUVPD_I2H_READ_RSP:
6595 case BFI_TFRU_I2H_READ_RSP:
6596 status = be32_to_cpu(rsp->status);
6597 bfa_trc(fru, status);
6599 if (status != BFA_STATUS_OK) {
6600 fru->status = status;
6601 fru->op_busy = 0;
6602 if (fru->cbfn)
6603 fru->cbfn(fru->cbarg, fru->status);
6604 } else {
6605 u32 len = be32_to_cpu(rsp->length);
6607 bfa_trc(fru, fru->offset);
6608 bfa_trc(fru, len);
6610 memcpy(fru->ubuf + fru->offset, fru->dbuf_kva, len);
6611 fru->residue -= len;
6612 fru->offset += len;
6614 if (fru->residue == 0) {
6615 fru->status = status;
6616 fru->op_busy = 0;
6617 if (fru->cbfn)
6618 fru->cbfn(fru->cbarg, fru->status);
6619 } else {
6620 if (msg->mh.msg_id == BFI_FRUVPD_I2H_READ_RSP)
6621 bfa_fru_read_send(fru,
6622 BFI_FRUVPD_H2I_READ_REQ);
6623 else
6624 bfa_fru_read_send(fru,
6625 BFI_TFRU_H2I_READ_REQ);
6628 break;
6629 default:
6630 WARN_ON(1);
6635 * register definitions
6637 #define FLI_CMD_REG 0x0001d000
6638 #define FLI_RDDATA_REG 0x0001d010
6639 #define FLI_ADDR_REG 0x0001d004
6640 #define FLI_DEV_STATUS_REG 0x0001d014
6642 #define BFA_FLASH_FIFO_SIZE 128 /* fifo size */
6643 #define BFA_FLASH_CHECK_MAX 10000 /* max # of status check */
6644 #define BFA_FLASH_BLOCKING_OP_MAX 1000000 /* max # of blocking op check */
6645 #define BFA_FLASH_WIP_MASK 0x01 /* write in progress bit mask */
6647 enum bfa_flash_cmd {
6648 BFA_FLASH_FAST_READ = 0x0b, /* fast read */
6649 BFA_FLASH_READ_STATUS = 0x05, /* read status */
6653 * @brief hardware error definition
6655 enum bfa_flash_err {
6656 BFA_FLASH_NOT_PRESENT = -1, /*!< flash not present */
6657 BFA_FLASH_UNINIT = -2, /*!< flash not initialized */
6658 BFA_FLASH_BAD = -3, /*!< flash bad */
6659 BFA_FLASH_BUSY = -4, /*!< flash busy */
6660 BFA_FLASH_ERR_CMD_ACT = -5, /*!< command active never cleared */
6661 BFA_FLASH_ERR_FIFO_CNT = -6, /*!< fifo count never cleared */
6662 BFA_FLASH_ERR_WIP = -7, /*!< write-in-progress never cleared */
6663 BFA_FLASH_ERR_TIMEOUT = -8, /*!< fli timeout */
6664 BFA_FLASH_ERR_LEN = -9, /*!< invalid length */
6668 * @brief flash command register data structure
6670 union bfa_flash_cmd_reg_u {
6671 struct {
6672 #ifdef __BIG_ENDIAN
6673 u32 act:1;
6674 u32 rsv:1;
6675 u32 write_cnt:9;
6676 u32 read_cnt:9;
6677 u32 addr_cnt:4;
6678 u32 cmd:8;
6679 #else
6680 u32 cmd:8;
6681 u32 addr_cnt:4;
6682 u32 read_cnt:9;
6683 u32 write_cnt:9;
6684 u32 rsv:1;
6685 u32 act:1;
6686 #endif
6687 } r;
6688 u32 i;
6692 * @brief flash device status register data structure
6694 union bfa_flash_dev_status_reg_u {
6695 struct {
6696 #ifdef __BIG_ENDIAN
6697 u32 rsv:21;
6698 u32 fifo_cnt:6;
6699 u32 busy:1;
6700 u32 init_status:1;
6701 u32 present:1;
6702 u32 bad:1;
6703 u32 good:1;
6704 #else
6705 u32 good:1;
6706 u32 bad:1;
6707 u32 present:1;
6708 u32 init_status:1;
6709 u32 busy:1;
6710 u32 fifo_cnt:6;
6711 u32 rsv:21;
6712 #endif
6713 } r;
6714 u32 i;
6718 * @brief flash address register data structure
6720 union bfa_flash_addr_reg_u {
6721 struct {
6722 #ifdef __BIG_ENDIAN
6723 u32 addr:24;
6724 u32 dummy:8;
6725 #else
6726 u32 dummy:8;
6727 u32 addr:24;
6728 #endif
6729 } r;
6730 u32 i;
6734 * dg flash_raw_private Flash raw private functions
6736 static void
6737 bfa_flash_set_cmd(void __iomem *pci_bar, u8 wr_cnt,
6738 u8 rd_cnt, u8 ad_cnt, u8 op)
6740 union bfa_flash_cmd_reg_u cmd;
6742 cmd.i = 0;
6743 cmd.r.act = 1;
6744 cmd.r.write_cnt = wr_cnt;
6745 cmd.r.read_cnt = rd_cnt;
6746 cmd.r.addr_cnt = ad_cnt;
6747 cmd.r.cmd = op;
6748 writel(cmd.i, (pci_bar + FLI_CMD_REG));
6751 static void
6752 bfa_flash_set_addr(void __iomem *pci_bar, u32 address)
6754 union bfa_flash_addr_reg_u addr;
6756 addr.r.addr = address & 0x00ffffff;
6757 addr.r.dummy = 0;
6758 writel(addr.i, (pci_bar + FLI_ADDR_REG));
6761 static int
6762 bfa_flash_cmd_act_check(void __iomem *pci_bar)
6764 union bfa_flash_cmd_reg_u cmd;
6766 cmd.i = readl(pci_bar + FLI_CMD_REG);
6768 if (cmd.r.act)
6769 return BFA_FLASH_ERR_CMD_ACT;
6771 return 0;
6775 * @brief
6776 * Flush FLI data fifo.
6778 * @param[in] pci_bar - pci bar address
6779 * @param[in] dev_status - device status
6781 * Return 0 on success, negative error number on error.
6783 static u32
6784 bfa_flash_fifo_flush(void __iomem *pci_bar)
6786 u32 i;
6787 u32 t;
6788 union bfa_flash_dev_status_reg_u dev_status;
6790 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6792 if (!dev_status.r.fifo_cnt)
6793 return 0;
6795 /* fifo counter in terms of words */
6796 for (i = 0; i < dev_status.r.fifo_cnt; i++)
6797 t = readl(pci_bar + FLI_RDDATA_REG);
6800 * Check the device status. It may take some time.
6802 for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
6803 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6804 if (!dev_status.r.fifo_cnt)
6805 break;
6808 if (dev_status.r.fifo_cnt)
6809 return BFA_FLASH_ERR_FIFO_CNT;
6811 return 0;
6815 * @brief
6816 * Read flash status.
6818 * @param[in] pci_bar - pci bar address
6820 * Return 0 on success, negative error number on error.
6822 static u32
6823 bfa_flash_status_read(void __iomem *pci_bar)
6825 union bfa_flash_dev_status_reg_u dev_status;
6826 int status;
6827 u32 ret_status;
6828 int i;
6830 status = bfa_flash_fifo_flush(pci_bar);
6831 if (status < 0)
6832 return status;
6834 bfa_flash_set_cmd(pci_bar, 0, 4, 0, BFA_FLASH_READ_STATUS);
6836 for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
6837 status = bfa_flash_cmd_act_check(pci_bar);
6838 if (!status)
6839 break;
6842 if (status)
6843 return status;
6845 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6846 if (!dev_status.r.fifo_cnt)
6847 return BFA_FLASH_BUSY;
6849 ret_status = readl(pci_bar + FLI_RDDATA_REG);
6850 ret_status >>= 24;
6852 status = bfa_flash_fifo_flush(pci_bar);
6853 if (status < 0)
6854 return status;
6856 return ret_status;
6860 * @brief
6861 * Start flash read operation.
6863 * @param[in] pci_bar - pci bar address
6864 * @param[in] offset - flash address offset
6865 * @param[in] len - read data length
6866 * @param[in] buf - read data buffer
6868 * Return 0 on success, negative error number on error.
6870 static u32
6871 bfa_flash_read_start(void __iomem *pci_bar, u32 offset, u32 len,
6872 char *buf)
6874 int status;
6877 * len must be mutiple of 4 and not exceeding fifo size
6879 if (len == 0 || len > BFA_FLASH_FIFO_SIZE || (len & 0x03) != 0)
6880 return BFA_FLASH_ERR_LEN;
6883 * check status
6885 status = bfa_flash_status_read(pci_bar);
6886 if (status == BFA_FLASH_BUSY)
6887 status = bfa_flash_status_read(pci_bar);
6889 if (status < 0)
6890 return status;
6893 * check if write-in-progress bit is cleared
6895 if (status & BFA_FLASH_WIP_MASK)
6896 return BFA_FLASH_ERR_WIP;
6898 bfa_flash_set_addr(pci_bar, offset);
6900 bfa_flash_set_cmd(pci_bar, 0, (u8)len, 4, BFA_FLASH_FAST_READ);
6902 return 0;
6906 * @brief
6907 * Check flash read operation.
6909 * @param[in] pci_bar - pci bar address
6911 * Return flash device status, 1 if busy, 0 if not.
6913 static u32
6914 bfa_flash_read_check(void __iomem *pci_bar)
6916 if (bfa_flash_cmd_act_check(pci_bar))
6917 return 1;
6919 return 0;
6922 * @brief
6923 * End flash read operation.
6925 * @param[in] pci_bar - pci bar address
6926 * @param[in] len - read data length
6927 * @param[in] buf - read data buffer
6930 static void
6931 bfa_flash_read_end(void __iomem *pci_bar, u32 len, char *buf)
6934 u32 i;
6937 * read data fifo up to 32 words
6939 for (i = 0; i < len; i += 4) {
6940 u32 w = readl(pci_bar + FLI_RDDATA_REG);
6941 *((u32 *) (buf + i)) = swab32(w);
6944 bfa_flash_fifo_flush(pci_bar);
6948 * @brief
6949 * Perform flash raw read.
6951 * @param[in] pci_bar - pci bar address
6952 * @param[in] offset - flash partition address offset
6953 * @param[in] buf - read data buffer
6954 * @param[in] len - read data length
6956 * Return status.
6960 #define FLASH_BLOCKING_OP_MAX 500
6961 #define FLASH_SEM_LOCK_REG 0x18820
6963 static int
6964 bfa_raw_sem_get(void __iomem *bar)
6966 int locked;
6968 locked = readl((bar + FLASH_SEM_LOCK_REG));
6969 return !locked;
6973 bfa_status_t
6974 bfa_flash_sem_get(void __iomem *bar)
6976 u32 n = FLASH_BLOCKING_OP_MAX;
6978 while (!bfa_raw_sem_get(bar)) {
6979 if (--n <= 0)
6980 return BFA_STATUS_BADFLASH;
6981 mdelay(10);
6983 return BFA_STATUS_OK;
6986 void
6987 bfa_flash_sem_put(void __iomem *bar)
6989 writel(0, (bar + FLASH_SEM_LOCK_REG));
6992 bfa_status_t
6993 bfa_flash_raw_read(void __iomem *pci_bar, u32 offset, char *buf,
6994 u32 len)
6996 u32 n;
6997 int status;
6998 u32 off, l, s, residue, fifo_sz;
7000 residue = len;
7001 off = 0;
7002 fifo_sz = BFA_FLASH_FIFO_SIZE;
7003 status = bfa_flash_sem_get(pci_bar);
7004 if (status != BFA_STATUS_OK)
7005 return status;
7007 while (residue) {
7008 s = offset + off;
7009 n = s / fifo_sz;
7010 l = (n + 1) * fifo_sz - s;
7011 if (l > residue)
7012 l = residue;
7014 status = bfa_flash_read_start(pci_bar, offset + off, l,
7015 &buf[off]);
7016 if (status < 0) {
7017 bfa_flash_sem_put(pci_bar);
7018 return BFA_STATUS_FAILED;
7021 n = BFA_FLASH_BLOCKING_OP_MAX;
7022 while (bfa_flash_read_check(pci_bar)) {
7023 if (--n <= 0) {
7024 bfa_flash_sem_put(pci_bar);
7025 return BFA_STATUS_FAILED;
7029 bfa_flash_read_end(pci_bar, l, &buf[off]);
7031 residue -= l;
7032 off += l;
7034 bfa_flash_sem_put(pci_bar);
7036 return BFA_STATUS_OK;