1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2013-2016 Qlogic Corporation
5 * All rights reserved.
6 *
7 *  Redistribution and use in source and binary forms, with or without
8 *  modification, are permitted provided that the following conditions
9 *  are met:
10 *
11 *  1. Redistributions of source code must retain the above copyright
12 *     notice, this list of conditions and the following disclaimer.
13 *  2. Redistributions in binary form must reproduce the above copyright
14 *     notice, this list of conditions and the following disclaimer in the
15 *     documentation and/or other materials provided with the distribution.
16 *
17 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 *  POSSIBILITY OF SUCH DAMAGE.
28 */
29/*
30 * File : ql_misc.c
31 * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
32 */
33
34#include <sys/cdefs.h>
35#include "ql_os.h"
36#include "ql_hw.h"
37#include "ql_def.h"
38#include "ql_inline.h"
39#include "ql_glbl.h"
40#include "ql_dbg.h"
41#include "ql_tmplt.h"
42
43#define	QL_FDT_OFFSET		0x3F0000
44#define Q8_FLASH_SECTOR_SIZE	0x10000
45
46static int qla_ld_fw_init(qla_host_t *ha);
47
48/*
49 * structure encapsulating the value to read/write to offchip memory
50 */
51typedef struct _offchip_mem_val {
52        uint32_t data_lo;
53        uint32_t data_hi;
54        uint32_t data_ulo;
55        uint32_t data_uhi;
56} offchip_mem_val_t;
57
58/*
59 * Name: ql_rdwr_indreg32
60 * Function: Read/Write an Indirect Register
61 */
62int
63ql_rdwr_indreg32(qla_host_t *ha, uint32_t addr, uint32_t *val, uint32_t rd)
64{
65	uint32_t wnd_reg;
66	uint32_t count = 100;
67
68	wnd_reg = (Q8_CRB_WINDOW_PF0 | (ha->pci_func << 2));
69
70	WRITE_REG32(ha, wnd_reg, addr);
71
72	while (count--) {
73		if (READ_REG32(ha, wnd_reg) == addr)
74			break;
75		qla_mdelay(__func__, 1);
76	}
77	if (!count || QL_ERR_INJECT(ha, INJCT_RDWR_INDREG_FAILURE)) {
78		device_printf(ha->pci_dev, "%s: [0x%08x, 0x%08x, %d] failed\n",
79			__func__, addr, *val, rd);
80		QL_INITIATE_RECOVERY(ha);
81		return -1;
82	}
83
84	if (rd) {
85		*val = READ_REG32(ha, Q8_WILD_CARD);
86	} else {
87		WRITE_REG32(ha, Q8_WILD_CARD, *val);
88	}
89
90	return 0;
91}
92
93/*
94 * Name: ql_rdwr_offchip_mem
95 * Function: Read/Write OffChip Memory
96 */
97int
98ql_rdwr_offchip_mem(qla_host_t *ha, uint64_t addr, q80_offchip_mem_val_t *val,
99	uint32_t rd)
100{
101	uint32_t count = 100;
102	uint32_t data, step = 0;
103
104	if (QL_ERR_INJECT(ha, INJCT_RDWR_OFFCHIPMEM_FAILURE))
105		goto exit_ql_rdwr_offchip_mem;
106
107	data = (uint32_t)addr;
108	if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_LO, &data, 0)) {
109		step = 1;
110		goto exit_ql_rdwr_offchip_mem;
111	}
112
113	data = (uint32_t)(addr >> 32);
114	if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_HI, &data, 0)) {
115		step = 2;
116		goto exit_ql_rdwr_offchip_mem;
117	}
118
119	data = BIT_1;
120	if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
121		step = 3;
122		goto exit_ql_rdwr_offchip_mem;
123	}
124
125	if (!rd) {
126		data = val->data_lo;
127		if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_0_31, &data, 0)) {
128			step = 4;
129			goto exit_ql_rdwr_offchip_mem;
130		}
131
132		data = val->data_hi;
133		if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_32_63, &data, 0)) {
134			step = 5;
135			goto exit_ql_rdwr_offchip_mem;
136		}
137
138		data = val->data_ulo;
139		if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_64_95, &data, 0)) {
140			step = 6;
141			goto exit_ql_rdwr_offchip_mem;
142		}
143
144		data = val->data_uhi;
145		if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_96_127, &data, 0)) {
146			step = 7;
147			goto exit_ql_rdwr_offchip_mem;
148		}
149
150		data = (BIT_2|BIT_1|BIT_0);
151		if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
152			step = 7;
153			goto exit_ql_rdwr_offchip_mem;
154		}
155	} else {
156		data = (BIT_1|BIT_0);
157		if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
158			step = 8;
159			goto exit_ql_rdwr_offchip_mem;
160		}
161	}
162
163	while (count--) {
164		if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 1)) {
165			step = 9;
166			goto exit_ql_rdwr_offchip_mem;
167		}
168
169		if (!(data & BIT_3)) {
170			if (rd) {
171				if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_0_31,
172					&data, 1)) {
173					step = 10;
174					goto exit_ql_rdwr_offchip_mem;
175				}
176				val->data_lo = data;
177
178				if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_32_63,
179					&data, 1)) {
180					step = 11;
181					goto exit_ql_rdwr_offchip_mem;
182				}
183				val->data_hi = data;
184
185				if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_64_95,
186					&data, 1)) {
187					step = 12;
188					goto exit_ql_rdwr_offchip_mem;
189				}
190				val->data_ulo = data;
191
192				if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_96_127,
193					&data, 1)) {
194					step = 13;
195					goto exit_ql_rdwr_offchip_mem;
196				}
197				val->data_uhi = data;
198			}
199			return 0;
200		} else
201			qla_mdelay(__func__, 1);
202	}
203
204exit_ql_rdwr_offchip_mem:
205
206	device_printf(ha->pci_dev,
207		"%s: [0x%08x 0x%08x : 0x%08x 0x%08x 0x%08x 0x%08x]"
208		" [%d] [%d] failed\n", __func__, (uint32_t)(addr >> 32),
209		(uint32_t)(addr), val->data_lo, val->data_hi, val->data_ulo,
210		val->data_uhi, rd, step);
211
212	QL_INITIATE_RECOVERY(ha);
213
214	return (-1);
215}
216
217/*
218 * Name: ql_rd_flash32
219 * Function: Read Flash Memory
220 */
221int
222ql_rd_flash32(qla_host_t *ha, uint32_t addr, uint32_t *data)
223{
224	uint32_t data32;
225
226	if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID, 0xABCDABCD)) {
227		device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
228			__func__);
229		return (-1);
230	}
231
232	data32 = addr;
233	if (ql_rdwr_indreg32(ha, Q8_FLASH_DIRECT_WINDOW, &data32, 0)) {
234		qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
235		device_printf(ha->pci_dev,
236			"%s: Q8_FLASH_DIRECT_WINDOW[0x%08x] failed\n",
237			__func__, data32);
238		return (-1);
239	}
240
241	data32 = Q8_FLASH_DIRECT_DATA | (addr & 0xFFFF);
242	if (ql_rdwr_indreg32(ha, data32, data, 1)) {
243		qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
244		device_printf(ha->pci_dev,
245			"%s: data32:data [0x%08x] failed\n",
246			__func__, data32);
247		return (-1);
248	}
249
250	qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
251	return 0;
252}
253
254static int
255qla_get_fdt(qla_host_t *ha)
256{
257	uint32_t data32;
258	int count;
259	qla_hw_t *hw;
260
261	hw = &ha->hw;
262
263	for (count = 0; count < sizeof(qla_flash_desc_table_t); count+=4) {
264		if (ql_rd_flash32(ha, QL_FDT_OFFSET + count,
265			(uint32_t *)&hw->fdt + (count >> 2))) {
266				device_printf(ha->pci_dev,
267					"%s: Read QL_FDT_OFFSET + %d failed\n",
268					__func__, count);
269				return (-1);
270		}
271	}
272
273	if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID,
274		Q8_FDT_LOCK_MAGIC_ID)) {
275		device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
276			__func__);
277		return (-1);
278	}
279
280	data32 = Q8_FDT_FLASH_ADDR_VAL;
281	if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
282		qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
283		device_printf(ha->pci_dev,
284			"%s: Write to Q8_FLASH_ADDRESS failed\n",
285			__func__);
286		return (-1);
287	}
288
289	data32 = Q8_FDT_FLASH_CTRL_VAL;
290	if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
291		qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
292		device_printf(ha->pci_dev,
293			"%s: Write to Q8_FLASH_CONTROL failed\n",
294			__func__);
295		return (-1);
296	}
297
298	count = 0;
299
300	do {
301		if (count < 1000) {
302			QLA_USEC_DELAY(10);
303			count += 10;
304		} else {
305			qla_mdelay(__func__, 1);
306			count += 1000;
307		}
308
309		data32 = 0;
310
311		if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
312			qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
313			device_printf(ha->pci_dev,
314				"%s: Read Q8_FLASH_STATUS failed\n",
315				__func__);
316			return (-1);
317		}
318
319		data32 &= 0x6;
320
321	} while ((count < 10000) && (data32 != 0x6));
322
323	if (data32 != 0x6) {
324		qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
325		device_printf(ha->pci_dev,
326			"%s: Poll Q8_FLASH_STATUS failed\n",
327			__func__);
328		return (-1);
329	}
330
331	if (ql_rdwr_indreg32(ha, Q8_FLASH_RD_DATA, &data32, 1)) {
332		qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
333		device_printf(ha->pci_dev,
334			"%s: Read Q8_FLASH_RD_DATA failed\n",
335			__func__);
336		return (-1);
337	}
338
339	qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
340
341	data32 &= Q8_FDT_MASK_VAL;
342	if (hw->fdt.flash_manuf == data32)
343		return (0);
344	else
345		return (-1);
346}
347
348static int
349qla_flash_write_enable(qla_host_t *ha, int enable)
350{
351	uint32_t data32;
352	int count = 0;
353
354	data32 = Q8_WR_ENABLE_FL_ADDR | ha->hw.fdt.write_statusreg_cmd;
355	if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
356		device_printf(ha->pci_dev,
357			"%s: Write to Q8_FLASH_ADDRESS failed\n",
358			__func__);
359		return (-1);
360	}
361
362	if (enable)
363		data32 = ha->hw.fdt.write_enable_bits;
364	else
365		data32 = ha->hw.fdt.write_disable_bits;
366
367	if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, &data32, 0)) {
368		device_printf(ha->pci_dev,
369			"%s: Write to Q8_FLASH_WR_DATA failed\n",
370			__func__);
371		return (-1);
372	}
373
374	data32 = Q8_WR_ENABLE_FL_CTRL;
375	if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
376		device_printf(ha->pci_dev,
377			"%s: Write to Q8_FLASH_CONTROL failed\n",
378			__func__);
379		return (-1);
380	}
381
382	do {
383		if (count < 1000) {
384			QLA_USEC_DELAY(10);
385			count += 10;
386		} else {
387			qla_mdelay(__func__, 1);
388			count += 1000;
389		}
390
391		data32 = 0;
392		if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
393			device_printf(ha->pci_dev,
394				"%s: Read Q8_FLASH_STATUS failed\n",
395				__func__);
396			return (-1);
397		}
398
399		data32 &= 0x6;
400
401	} while ((count < 10000) && (data32 != 0x6));
402
403	if (data32 != 0x6) {
404		device_printf(ha->pci_dev,
405			"%s: Poll Q8_FLASH_STATUS failed\n",
406			__func__);
407		return (-1);
408	}
409
410	return 0;
411}
412
413static int
414qla_erase_flash_sector(qla_host_t *ha, uint32_t start)
415{
416	uint32_t data32;
417	int count = 0;
418
419	do {
420		qla_mdelay(__func__, 1);
421
422		data32 = 0;
423		if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
424			device_printf(ha->pci_dev,
425				"%s: Read Q8_FLASH_STATUS failed\n",
426				__func__);
427			return (-1);
428		}
429
430		data32 &= 0x6;
431
432	} while (((count++) < 1000) && (data32 != 0x6));
433
434	if (data32 != 0x6) {
435		device_printf(ha->pci_dev,
436			"%s: Poll Q8_FLASH_STATUS failed\n",
437			__func__);
438		return (-1);
439	}
440
441	data32 = (start >> 16) & 0xFF;
442	if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, &data32, 0)) {
443		device_printf(ha->pci_dev,
444			"%s: Write to Q8_FLASH_WR_DATA failed\n",
445			__func__);
446		return (-1);
447	}
448
449	data32 = Q8_ERASE_FL_ADDR_MASK | ha->hw.fdt.erase_cmd;
450	if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
451		device_printf(ha->pci_dev,
452			"%s: Write to Q8_FLASH_ADDRESS failed\n",
453			__func__);
454		return (-1);
455	}
456
457	data32 = Q8_ERASE_FL_CTRL_MASK;
458	if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
459		device_printf(ha->pci_dev,
460			"%s: Write to Q8_FLASH_CONTROL failed\n",
461			__func__);
462		return (-1);
463	}
464
465	count = 0;
466	do {
467		qla_mdelay(__func__, 1);
468
469		data32 = 0;
470		if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
471			device_printf(ha->pci_dev,
472				"%s: Read Q8_FLASH_STATUS failed\n",
473				__func__);
474			return (-1);
475		}
476
477		data32 &= 0x6;
478
479	} while (((count++) < 1000) && (data32 != 0x6));
480
481	if (data32 != 0x6) {
482		device_printf(ha->pci_dev,
483			"%s: Poll Q8_FLASH_STATUS failed\n",
484			__func__);
485		return (-1);
486	}
487
488	return 0;
489}
490
491int
492ql_erase_flash(qla_host_t *ha, uint32_t off, uint32_t size)
493{
494	int rval = 0;
495	uint32_t start;
496
497	if (off & (Q8_FLASH_SECTOR_SIZE -1))
498		return (-1);
499
500	if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID,
501		Q8_ERASE_LOCK_MAGIC_ID)) {
502		device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
503			__func__);
504		return (-1);
505	}
506
507	if (qla_flash_write_enable(ha, 1) != 0) {
508		rval = -1;
509		goto ql_erase_flash_exit;
510	}
511
512	for (start = off; start < (off + size); start = start +
513		Q8_FLASH_SECTOR_SIZE) {
514			if (qla_erase_flash_sector(ha, start)) {
515				rval = -1;
516				break;
517			}
518	}
519
520	rval = qla_flash_write_enable(ha, 0);
521
522ql_erase_flash_exit:
523	qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
524	return (rval);
525}
526
527static int
528qla_wr_flash32(qla_host_t *ha, uint32_t off, uint32_t *data)
529{
530	uint32_t data32;
531	int count = 0;
532
533	data32 = Q8_WR_FL_ADDR_MASK | (off >> 2);
534	if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
535		device_printf(ha->pci_dev,
536			"%s: Write to Q8_FLASH_ADDRESS failed\n",
537			__func__);
538		return (-1);
539	}
540
541	if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, data, 0)) {
542		device_printf(ha->pci_dev,
543			"%s: Write to Q8_FLASH_WR_DATA failed\n",
544			__func__);
545		return (-1);
546	}
547
548	data32 = Q8_WR_FL_CTRL_MASK;
549	if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
550		device_printf(ha->pci_dev,
551			"%s: Write to Q8_FLASH_CONTROL failed\n",
552			__func__);
553		return (-1);
554	}
555
556	do {
557		if (count < 1000) {
558			QLA_USEC_DELAY(10);
559			count += 10;
560		} else {
561			qla_mdelay(__func__, 1);
562			count += 1000;
563		}
564
565		data32 = 0;
566		if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
567			device_printf(ha->pci_dev,
568				"%s: Read Q8_FLASH_STATUS failed\n",
569				__func__);
570			return (-1);
571		}
572
573		data32 &= 0x6;
574
575	} while ((count < 10000) && (data32 != 0x6));
576
577	if (data32 != 0x6) {
578		device_printf(ha->pci_dev,
579			"%s: Poll Q8_FLASH_STATUS failed\n",
580			__func__);
581		return (-1);
582	}
583
584	return 0;
585}
586
587static int
588qla_flash_write_data(qla_host_t *ha, uint32_t off, uint32_t size,
589        void *data)
590{
591	int rval = 0;
592	uint32_t start;
593	uint32_t *data32 = data;
594
595	if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID,
596		Q8_WR_FL_LOCK_MAGIC_ID)) {
597			device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
598				__func__);
599			rval = -1;
600			goto qla_flash_write_data_exit;
601	}
602
603	if ((qla_flash_write_enable(ha, 1) != 0)) {
604		device_printf(ha->pci_dev, "%s: failed\n",
605			__func__);
606		rval = -1;
607		goto qla_flash_write_data_unlock_exit;
608	}
609
610	for (start = off; start < (off + size); start = start + 4) {
611		if (*data32 != 0xFFFFFFFF) {
612			if (qla_wr_flash32(ha, start, data32)) {
613				rval = -1;
614				break;
615			}
616		}
617		data32++;
618	}
619
620	rval = qla_flash_write_enable(ha, 0);
621
622qla_flash_write_data_unlock_exit:
623	qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
624
625qla_flash_write_data_exit:
626	return (rval);
627}
628
629int
630ql_wr_flash_buffer(qla_host_t *ha, uint32_t off, uint32_t size, void *buf)
631{
632	int rval = 0;
633	void *data;
634
635	if (size == 0)
636		return 0;
637
638	size = size << 2;
639
640	if (buf == NULL)
641		return -1;
642
643	if ((data = malloc(size, M_QLA83XXBUF, M_NOWAIT)) == NULL) {
644		device_printf(ha->pci_dev, "%s: malloc failed \n", __func__);
645		rval = -1;
646		goto ql_wr_flash_buffer_exit;
647	}
648
649	if ((rval = copyin(buf, data, size))) {
650		device_printf(ha->pci_dev, "%s copyin failed\n", __func__);
651		goto ql_wr_flash_buffer_free_exit;
652	}
653
654	rval = qla_flash_write_data(ha, off, size, data);
655
656ql_wr_flash_buffer_free_exit:
657	free(data, M_QLA83XXBUF);
658
659ql_wr_flash_buffer_exit:
660	return (rval);
661}
662
663#ifdef QL_LDFLASH_FW
664/*
665 * Name: qla_load_fw_from_flash
666 * Function: Reads the Bootloader from Flash and Loads into Offchip Memory
667 */
668static void
669qla_load_fw_from_flash(qla_host_t *ha)
670{
671	uint32_t flash_off	= 0x10000;
672	uint64_t mem_off;
673	uint32_t count, mem_size;
674	q80_offchip_mem_val_t val;
675
676	mem_off = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
677	mem_size = READ_REG32(ha, Q8_BOOTLD_SIZE);
678
679	device_printf(ha->pci_dev, "%s: [0x%08x][0x%08x]\n",
680		__func__, (uint32_t)mem_off, mem_size);
681
682	/* only bootloader needs to be loaded into memory */
683	for (count = 0; count < mem_size ; ) {
684		ql_rd_flash32(ha, flash_off, &val.data_lo);
685		count = count + 4;
686		flash_off = flash_off + 4;
687
688		ql_rd_flash32(ha, flash_off, &val.data_hi);
689		count = count + 4;
690		flash_off = flash_off + 4;
691
692		ql_rd_flash32(ha, flash_off, &val.data_ulo);
693		count = count + 4;
694		flash_off = flash_off + 4;
695
696		ql_rd_flash32(ha, flash_off, &val.data_uhi);
697		count = count + 4;
698		flash_off = flash_off + 4;
699
700		ql_rdwr_offchip_mem(ha, mem_off, &val, 0);
701
702		mem_off = mem_off + 16;
703	}
704
705	return;
706}
707#endif /* #ifdef QL_LDFLASH_FW */
708
709/*
710 * Name: qla_init_from_flash
711 * Function: Performs Initialization which consists of the following sequence
712 *	- reset
713 *	- CRB Init
714 *	- Peg Init
715 *	- Read the Bootloader from Flash and Load into Offchip Memory
716 *	- Kick start the bootloader which loads the rest of the firmware
717 *		and performs the remaining steps in the initialization process.
718 */
719static int
720qla_init_from_flash(qla_host_t *ha)
721{
722	uint32_t delay = 300;
723	uint32_t data;
724
725	qla_ld_fw_init(ha);
726
727	do {
728		data = READ_REG32(ha, Q8_CMDPEG_STATE);
729
730		QL_DPRINT2(ha,
731			(ha->pci_dev, "%s: func[%d] cmdpegstate 0x%08x\n",
732				__func__, ha->pci_func, data));
733		if (data == 0xFF01) {
734			QL_DPRINT2(ha, (ha->pci_dev,
735				"%s: func[%d] init complete\n",
736				__func__, ha->pci_func));
737			return(0);
738		}
739		qla_mdelay(__func__, 100);
740	} while (delay--);
741
742	return (-1);
743}
744
745/*
746 * Name: ql_init_hw
747 * Function: Initializes P3+ hardware.
748 */
749int
750ql_init_hw(qla_host_t *ha)
751{
752        device_t dev;
753        int ret = 0;
754        uint32_t val, delay = 300;
755
756        dev = ha->pci_dev;
757
758        QL_DPRINT1(ha, (dev, "%s: enter\n", __func__));
759
760	if (ha->pci_func & 0x1) {
761        	while ((ha->pci_func & 0x1) && delay--) {
762			val = READ_REG32(ha, Q8_CMDPEG_STATE);
763
764			if (val == 0xFF01) {
765				QL_DPRINT2(ha, (dev,
766					"%s: func = %d init complete\n",
767					__func__, ha->pci_func));
768				qla_mdelay(__func__, 100);
769				goto qla_init_exit;
770			}
771			qla_mdelay(__func__, 100);
772		}
773		ret = -1;
774		goto ql_init_hw_exit;
775	}
776
777	val = READ_REG32(ha, Q8_CMDPEG_STATE);
778	if (!cold || (val != 0xFF01) || ha->qla_initiate_recovery) {
779        	ret = qla_init_from_flash(ha);
780		qla_mdelay(__func__, 100);
781	}
782
783qla_init_exit:
784        ha->fw_ver_major = READ_REG32(ha, Q8_FW_VER_MAJOR);
785        ha->fw_ver_minor = READ_REG32(ha, Q8_FW_VER_MINOR);
786        ha->fw_ver_sub = READ_REG32(ha, Q8_FW_VER_SUB);
787
788	if (qla_get_fdt(ha) != 0) {
789		device_printf(dev, "%s: qla_get_fdt failed\n", __func__);
790	} else {
791		ha->hw.flags.fdt_valid = 1;
792	}
793
794ql_init_hw_exit:
795
796	if (ret) {
797		if (ha->hw.sp_log_stop_events & Q8_SP_LOG_STOP_HW_INIT_FAILURE)
798			ha->hw.sp_log_stop = -1;
799	}
800
801        return (ret);
802}
803
804void
805ql_read_mac_addr(qla_host_t *ha)
806{
807	uint8_t *macp;
808	uint32_t mac_lo;
809	uint32_t mac_hi;
810	uint32_t flash_off;
811
812	flash_off = Q8_BOARD_CONFIG_OFFSET + Q8_BOARD_CONFIG_MAC0_LO +
813			(ha->pci_func << 3);
814	ql_rd_flash32(ha, flash_off, &mac_lo);
815
816	flash_off += 4;
817	ql_rd_flash32(ha, flash_off, &mac_hi);
818
819	macp = (uint8_t *)&mac_lo;
820	ha->hw.mac_addr[5] = macp[0];
821	ha->hw.mac_addr[4] = macp[1];
822	ha->hw.mac_addr[3] = macp[2];
823	ha->hw.mac_addr[2] = macp[3];
824
825	macp = (uint8_t *)&mac_hi;
826	ha->hw.mac_addr[1] = macp[0];
827	ha->hw.mac_addr[0] = macp[1];
828
829	//device_printf(ha->pci_dev, "%s: %02x:%02x:%02x:%02x:%02x:%02x\n",
830	//	__func__, ha->hw.mac_addr[0], ha->hw.mac_addr[1],
831	//	ha->hw.mac_addr[2], ha->hw.mac_addr[3],
832	//	ha->hw.mac_addr[4], ha->hw.mac_addr[5]);
833
834        return;
835}
836
837/*
838 * Stop/Start/Initialization Handling
839 */
840
841static uint16_t
842qla_tmplt_16bit_checksum(qla_host_t *ha, uint16_t *buf, uint32_t size)
843{
844	uint32_t sum = 0;
845	uint32_t count = size >> 1; /* size in 16 bit words */
846
847	while (count-- > 0)
848		sum += *buf++;
849
850	while (sum >> 16)
851		sum = (sum & 0xFFFF) + (sum >> 16);
852
853	return (~sum);
854}
855
856static int
857qla_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
858{
859	q8_wrl_e_t *wr_l;
860	int i;
861
862	wr_l = (q8_wrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
863
864	for (i = 0; i < ce_hdr->opcount; i++, wr_l++) {
865		if (ql_rdwr_indreg32(ha, wr_l->addr, &wr_l->value, 0)) {
866			device_printf(ha->pci_dev,
867				"%s: [0x%08x 0x%08x] error\n", __func__,
868				wr_l->addr, wr_l->value);
869			return -1;
870		}
871		if (ce_hdr->delay_to) {
872			DELAY(ce_hdr->delay_to);
873		}
874	}
875	return 0;
876}
877
878static int
879qla_rd_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
880{
881	q8_rdwrl_e_t *rd_wr_l;
882	uint32_t data;
883	int i;
884
885	rd_wr_l = (q8_rdwrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
886
887	for (i = 0; i < ce_hdr->opcount; i++, rd_wr_l++) {
888		if (ql_rdwr_indreg32(ha, rd_wr_l->rd_addr, &data, 1)) {
889			device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
890				__func__, rd_wr_l->rd_addr);
891
892			return -1;
893		}
894
895		if (ql_rdwr_indreg32(ha, rd_wr_l->wr_addr, &data, 0)) {
896			device_printf(ha->pci_dev,
897				"%s: [0x%08x 0x%08x] error\n", __func__,
898				rd_wr_l->wr_addr, data);
899			return -1;
900		}
901		if (ce_hdr->delay_to) {
902			DELAY(ce_hdr->delay_to);
903		}
904	}
905	return 0;
906}
907
908static int
909qla_poll_reg(qla_host_t *ha, uint32_t addr, uint32_t ms_to, uint32_t tmask,
910	uint32_t tvalue)
911{
912	uint32_t data;
913
914	while (ms_to) {
915		if (ql_rdwr_indreg32(ha, addr, &data, 1)) {
916			device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
917				__func__, addr);
918			return -1;
919		}
920
921		if ((data & tmask) != tvalue) {
922			ms_to--;
923		} else
924			break;
925
926		qla_mdelay(__func__, 1);
927	}
928	return ((ms_to ? 0: -1));
929}
930
931static int
932qla_poll_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
933{
934	int		i;
935	q8_poll_hdr_t	*phdr;
936	q8_poll_e_t	*pe;
937	uint32_t	data;
938
939	phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
940	pe = (q8_poll_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
941
942	for (i = 0; i < ce_hdr->opcount; i++, pe++) {
943		if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
944			device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
945				__func__, pe->addr);
946			return -1;
947		}
948
949		if (ce_hdr->delay_to)  {
950			if ((data & phdr->tmask) == phdr->tvalue)
951				break;
952			if (qla_poll_reg(ha, pe->addr, ce_hdr->delay_to,
953				phdr->tmask, phdr->tvalue)) {
954				if (ql_rdwr_indreg32(ha, pe->to_addr, &data,
955					1)) {
956					device_printf(ha->pci_dev,
957						"%s: [0x%08x] error\n",
958						__func__, pe->to_addr);
959					return -1;
960				}
961
962				if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
963					device_printf(ha->pci_dev,
964						"%s: [0x%08x] error\n",
965						__func__, pe->addr);
966					return -1;
967				}
968			}
969		}
970	}
971	return 0;
972}
973
974static int
975qla_poll_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
976{
977	int		i;
978	q8_poll_hdr_t	*phdr;
979	q8_poll_wr_e_t	*wr_e;
980
981	phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
982	wr_e = (q8_poll_wr_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
983
984	for (i = 0; i < ce_hdr->opcount; i++, wr_e++) {
985		if (ql_rdwr_indreg32(ha, wr_e->dr_addr, &wr_e->dr_value, 0)) {
986			device_printf(ha->pci_dev,
987				"%s: [0x%08x 0x%08x] error\n", __func__,
988				wr_e->dr_addr, wr_e->dr_value);
989			return -1;
990		}
991		if (ql_rdwr_indreg32(ha, wr_e->ar_addr, &wr_e->ar_value, 0)) {
992			device_printf(ha->pci_dev,
993				"%s: [0x%08x 0x%08x] error\n", __func__,
994				wr_e->ar_addr, wr_e->ar_value);
995			return -1;
996		}
997		if (ce_hdr->delay_to)  {
998			if (qla_poll_reg(ha, wr_e->ar_addr, ce_hdr->delay_to,
999				phdr->tmask, phdr->tvalue))
1000				device_printf(ha->pci_dev, "%s: "
1001					"[ar_addr, ar_value, delay, tmask,"
1002					"tvalue] [0x%08x 0x%08x 0x%08x 0x%08x"
1003					" 0x%08x]\n",
1004					__func__, wr_e->ar_addr, wr_e->ar_value,
1005					ce_hdr->delay_to, phdr->tmask,
1006					phdr->tvalue);
1007		}
1008	}
1009	return 0;
1010}
1011
1012static int
1013qla_poll_read_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
1014{
1015	int		i;
1016	q8_poll_hdr_t	*phdr;
1017	q8_poll_rd_e_t	*rd_e;
1018	uint32_t	value;
1019
1020	phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
1021	rd_e = (q8_poll_rd_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
1022
1023	for (i = 0; i < ce_hdr->opcount; i++, rd_e++) {
1024		if (ql_rdwr_indreg32(ha, rd_e->ar_addr, &rd_e->ar_value, 0)) {
1025			device_printf(ha->pci_dev,
1026				"%s: [0x%08x 0x%08x] error\n", __func__,
1027				rd_e->ar_addr, rd_e->ar_value);
1028			return -1;
1029		}
1030
1031		if (ce_hdr->delay_to)  {
1032			if (qla_poll_reg(ha, rd_e->ar_addr, ce_hdr->delay_to,
1033				phdr->tmask, phdr->tvalue)) {
1034				return (-1);
1035			} else {
1036				if (ql_rdwr_indreg32(ha, rd_e->dr_addr,
1037					&value, 1)) {
1038					device_printf(ha->pci_dev,
1039						"%s: [0x%08x] error\n",
1040						__func__, rd_e->ar_addr);
1041					return -1;
1042				}
1043
1044				ha->hw.rst_seq[ha->hw.rst_seq_idx++] = value;
1045				if (ha->hw.rst_seq_idx == Q8_MAX_RESET_SEQ_IDX)
1046					ha->hw.rst_seq_idx = 1;
1047			}
1048		}
1049	}
1050	return 0;
1051}
1052
1053static int
1054qla_rdmwr(qla_host_t *ha, uint32_t raddr, uint32_t waddr, q8_rdmwr_hdr_t *hdr)
1055{
1056	uint32_t value;
1057
1058	if (hdr->index_a >= Q8_MAX_RESET_SEQ_IDX) {
1059		device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
1060			hdr->index_a);
1061		return -1;
1062	}
1063
1064	if (hdr->index_a) {
1065		value = ha->hw.rst_seq[hdr->index_a];
1066	} else {
1067		if (ql_rdwr_indreg32(ha, raddr, &value, 1)) {
1068			device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
1069						__func__, raddr);
1070			return -1;
1071		}
1072	}
1073
1074	value &= hdr->and_value;
1075	value <<= hdr->shl;
1076	value >>= hdr->shr;
1077	value |= hdr->or_value;
1078	value ^= hdr->xor_value;
1079
1080	if (ql_rdwr_indreg32(ha, waddr, &value, 0)) {
1081		device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
1082			raddr);
1083		return -1;
1084	}
1085	return 0;
1086}
1087
1088static int
1089qla_read_modify_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
1090{
1091	int		i;
1092	q8_rdmwr_hdr_t	*rdmwr_hdr;
1093	q8_rdmwr_e_t	*rdmwr_e;
1094
1095	rdmwr_hdr = (q8_rdmwr_hdr_t *)((uint8_t *)ce_hdr +
1096						sizeof (q8_ce_hdr_t));
1097	rdmwr_e = (q8_rdmwr_e_t *)((uint8_t *)rdmwr_hdr +
1098					sizeof(q8_rdmwr_hdr_t));
1099
1100	for (i = 0; i < ce_hdr->opcount; i++, rdmwr_e++) {
1101		if (qla_rdmwr(ha, rdmwr_e->rd_addr, rdmwr_e->wr_addr,
1102			rdmwr_hdr)) {
1103			return -1;
1104		}
1105		if (ce_hdr->delay_to) {
1106			DELAY(ce_hdr->delay_to);
1107		}
1108	}
1109	return 0;
1110}
1111
1112static int
1113qla_tmplt_execute(qla_host_t *ha, uint8_t *buf, int start_idx, int *end_idx,
1114	uint32_t nentries)
1115{
1116	int i, ret = 0, proc_end = 0;
1117	q8_ce_hdr_t	*ce_hdr;
1118
1119	for (i = start_idx; ((i < nentries) && (!proc_end)); i++) {
1120		ce_hdr = (q8_ce_hdr_t *)buf;
1121		ret = 0;
1122
1123		switch (ce_hdr->opcode) {
1124		case Q8_CE_OPCODE_NOP:
1125			break;
1126
1127		case Q8_CE_OPCODE_WRITE_LIST:
1128			ret = qla_wr_list(ha, ce_hdr);
1129			//printf("qla_wr_list %d\n", ret);
1130			break;
1131
1132		case Q8_CE_OPCODE_READ_WRITE_LIST:
1133			ret = qla_rd_wr_list(ha, ce_hdr);
1134			//printf("qla_rd_wr_list %d\n", ret);
1135			break;
1136
1137		case Q8_CE_OPCODE_POLL_LIST:
1138			ret = qla_poll_list(ha, ce_hdr);
1139			//printf("qla_poll_list %d\n", ret);
1140			break;
1141
1142		case Q8_CE_OPCODE_POLL_WRITE_LIST:
1143			ret = qla_poll_write_list(ha, ce_hdr);
1144			//printf("qla_poll_write_list %d\n", ret);
1145			break;
1146
1147		case Q8_CE_OPCODE_POLL_RD_LIST:
1148			ret = qla_poll_read_list(ha, ce_hdr);
1149			//printf("qla_poll_read_list %d\n", ret);
1150			break;
1151
1152		case Q8_CE_OPCODE_READ_MODIFY_WRITE:
1153			ret = qla_read_modify_write_list(ha, ce_hdr);
1154			//printf("qla_read_modify_write_list %d\n", ret);
1155			break;
1156
1157		case Q8_CE_OPCODE_SEQ_PAUSE:
1158			if (ce_hdr->delay_to) {
1159				qla_mdelay(__func__, ce_hdr->delay_to);
1160			}
1161			break;
1162
1163		case Q8_CE_OPCODE_SEQ_END:
1164			proc_end = 1;
1165			break;
1166
1167		case Q8_CE_OPCODE_TMPLT_END:
1168			*end_idx = i;
1169			return 0;
1170		}
1171
1172		if (ret)
1173			break;
1174
1175		buf += ce_hdr->size;
1176	}
1177	*end_idx = i;
1178
1179	return (ret);
1180}
1181
1182#ifndef QL_LDFLASH_FW
1183static int
1184qla_load_offchip_mem(qla_host_t *ha, uint64_t addr, uint32_t *data32,
1185        uint32_t len32)
1186{
1187        q80_offchip_mem_val_t val;
1188        int             ret = 0;
1189
1190        while (len32) {
1191                if (len32 > 4) {
1192                        val.data_lo = *data32++;
1193                        val.data_hi = *data32++;
1194                        val.data_ulo = *data32++;
1195                        val.data_uhi = *data32++;
1196                        len32 -= 4;
1197                        if (ql_rdwr_offchip_mem(ha, addr, &val, 0))
1198                                return -1;
1199
1200                        addr += (uint64_t)16;
1201                } else {
1202                        break;
1203                }
1204        }
1205
1206        bzero(&val, sizeof(q80_offchip_mem_val_t));
1207
1208        switch (len32) {
1209        case 3:
1210                val.data_lo = *data32++;
1211                val.data_hi = *data32++;
1212                val.data_ulo = *data32++;
1213                 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1214                break;
1215
1216        case 2:
1217                val.data_lo = *data32++;
1218                val.data_hi = *data32++;
1219                 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1220                break;
1221
1222        case 1:
1223                val.data_lo = *data32++;
1224                ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1225                break;
1226
1227        default:
1228                break;
1229        }
1230        return ret;
1231}
1232
1233static int
1234qla_load_bootldr(qla_host_t *ha)
1235{
1236        uint64_t        addr;
1237        uint32_t        *data32;
1238        uint32_t        len32;
1239        int             ret;
1240
1241        addr = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
1242        data32 = (uint32_t *)ql83xx_bootloader;
1243        len32 = ql83xx_bootloader_len >> 2;
1244
1245        ret = qla_load_offchip_mem(ha, addr, data32, len32);
1246
1247        return (ret);
1248}
1249
1250static int
1251qla_load_fwimage(qla_host_t *ha)
1252{
1253        uint64_t        addr;
1254        uint32_t        *data32;
1255        uint32_t        len32;
1256        int             ret;
1257
1258        addr = (uint64_t)(READ_REG32(ha, Q8_FW_IMAGE_ADDR));
1259        data32 = (uint32_t *)ql83xx_firmware;
1260        len32 = ql83xx_firmware_len >> 2;
1261
1262        ret = qla_load_offchip_mem(ha, addr, data32, len32);
1263
1264        return (ret);
1265}
1266#endif /* #ifndef QL_LDFLASH_FW */
1267
1268static int
1269qla_ld_fw_init(qla_host_t *ha)
1270{
1271	uint8_t *buf;
1272	uint32_t index = 0, end_idx;
1273	q8_tmplt_hdr_t *hdr;
1274
1275	bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1276
1277	hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1278
1279	device_printf(ha->pci_dev, "%s: reset sequence\n", __func__);
1280	if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1281		(uint32_t)hdr->size)) {
1282		device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1283			__func__);
1284		return -1;
1285	}
1286
1287	buf = ql83xx_resetseq + hdr->stop_seq_off;
1288
1289	device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
1290	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1291		device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
1292		return -1;
1293	}
1294
1295	index = end_idx;
1296
1297	buf = ql83xx_resetseq + hdr->init_seq_off;
1298
1299	device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
1300	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1301		device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1302		return -1;
1303	}
1304
1305#ifdef QL_LDFLASH_FW
1306	qla_load_fw_from_flash(ha);
1307	WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
1308#else
1309        if (qla_load_bootldr(ha))
1310                return -1;
1311
1312        if (qla_load_fwimage(ha))
1313                return -1;
1314
1315        WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
1316#endif /* #ifdef QL_LDFLASH_FW */
1317
1318	index = end_idx;
1319	buf = ql83xx_resetseq + hdr->start_seq_off;
1320
1321	device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
1322	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1323		device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1324		return -1;
1325	}
1326
1327	return 0;
1328}
1329
1330int
1331ql_stop_sequence(qla_host_t *ha)
1332{
1333	uint8_t *buf;
1334	uint32_t index = 0, end_idx;
1335	q8_tmplt_hdr_t *hdr;
1336
1337	bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1338
1339	hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1340
1341	if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1342		(uint32_t)hdr->size)) {
1343		device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1344		__func__);
1345		return (-1);
1346	}
1347
1348	buf = ql83xx_resetseq + hdr->stop_seq_off;
1349
1350	device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
1351	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1352		device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
1353		return (-1);
1354	}
1355
1356	return end_idx;
1357}
1358
1359int
1360ql_start_sequence(qla_host_t *ha, uint16_t index)
1361{
1362	uint8_t *buf;
1363	uint32_t end_idx;
1364	q8_tmplt_hdr_t *hdr;
1365
1366	bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1367
1368	hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1369
1370	if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1371		(uint32_t)hdr->size)) {
1372		device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1373		__func__);
1374		return (-1);
1375	}
1376
1377	buf = ql83xx_resetseq + hdr->init_seq_off;
1378
1379	device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
1380	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1381		device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1382		return (-1);
1383	}
1384
1385#ifdef QL_LDFLASH_FW
1386	qla_load_fw_from_flash(ha);
1387	WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
1388#else
1389        if (qla_load_bootldr(ha))
1390                return -1;
1391
1392        if (qla_load_fwimage(ha))
1393                return -1;
1394
1395        WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
1396#endif /* #ifdef QL_LDFLASH_FW */
1397
1398	index = end_idx;
1399	buf = ql83xx_resetseq + hdr->start_seq_off;
1400
1401	device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
1402	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1403		device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1404		return -1;
1405	}
1406
1407	return (0);
1408}
1409