xref: /freebsd/sys/dev/qlxgbe/ql_misc.c (revision ab40f58ccfe6c07ebefddc72f4661a52fe746353)
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 
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 
207 exit_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  */
224 int
225 ql_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 
257 static int
258 qla_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 
351 static int
352 qla_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 
416 static int
417 qla_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 
494 int
495 ql_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 
525 ql_erase_flash_exit:
526 	qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
527 	return (rval);
528 }
529 
530 static int
531 qla_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 
590 static int
591 qla_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 
625 qla_flash_write_data_unlock_exit:
626 	qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
627 
628 qla_flash_write_data_exit:
629 	return (rval);
630 }
631 
632 int
633 ql_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 
659 ql_wr_flash_buffer_free_exit:
660 	free(data, M_QLA83XXBUF);
661 
662 ql_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  */
671 static void
672 qla_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  */
722 static int
723 qla_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  */
752 int
753 ql_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 
789 qla_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 
800 ql_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 
810 void
811 ql_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 
847 static uint16_t
848 qla_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 
862 static int
863 qla_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 
885 static int
886 qla_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 
916 static int
917 qla_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 
940 static int
941 qla_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 
984 static int
985 qla_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 
1023 static int
1024 qla_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 
1064 static int
1065 qla_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 
1099 static int
1100 qla_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 
1124 static int
1125 qla_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
1195 static int
1196 qla_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 
1247 static int
1248 qla_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 
1264 static int
1265 qla_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 
1282 static int
1283 qla_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 
1345 int
1346 ql_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 
1374 int
1375 ql_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