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