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