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