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