xref: /freebsd/sys/dev/qlxgbe/ql_misc.c (revision d8a0fe102c0cfdfcd5b818f850eff09d8536c9bc)
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 		ha->qla_initiate_recovery = 1;
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 	ha->qla_initiate_recovery = 1;
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 		return (-1);
779 	}
780 
781 
782 	val = READ_REG32(ha, Q8_CMDPEG_STATE);
783 	if (!cold || (val != 0xFF01)) {
784         	ret = qla_init_from_flash(ha);
785 		qla_mdelay(__func__, 100);
786 	}
787 
788 qla_init_exit:
789         ha->fw_ver_major = READ_REG32(ha, Q8_FW_VER_MAJOR);
790         ha->fw_ver_minor = READ_REG32(ha, Q8_FW_VER_MINOR);
791         ha->fw_ver_sub = READ_REG32(ha, Q8_FW_VER_SUB);
792 
793 	if (qla_get_fdt(ha) != 0) {
794 		device_printf(dev, "%s: qla_get_fdt failed\n", __func__);
795 	} else {
796 		ha->hw.flags.fdt_valid = 1;
797 	}
798 
799         return (ret);
800 }
801 
802 void
803 ql_read_mac_addr(qla_host_t *ha)
804 {
805 	uint8_t *macp;
806 	uint32_t mac_lo;
807 	uint32_t mac_hi;
808 	uint32_t flash_off;
809 
810 	flash_off = Q8_BOARD_CONFIG_OFFSET + Q8_BOARD_CONFIG_MAC0_LO +
811 			(ha->pci_func << 3);
812 	ql_rd_flash32(ha, flash_off, &mac_lo);
813 
814 	flash_off += 4;
815 	ql_rd_flash32(ha, flash_off, &mac_hi);
816 
817 	macp = (uint8_t *)&mac_lo;
818 	ha->hw.mac_addr[5] = macp[0];
819 	ha->hw.mac_addr[4] = macp[1];
820 	ha->hw.mac_addr[3] = macp[2];
821 	ha->hw.mac_addr[2] = macp[3];
822 
823 	macp = (uint8_t *)&mac_hi;
824 	ha->hw.mac_addr[1] = macp[0];
825 	ha->hw.mac_addr[0] = macp[1];
826 
827 	//device_printf(ha->pci_dev, "%s: %02x:%02x:%02x:%02x:%02x:%02x\n",
828 	//	__func__, ha->hw.mac_addr[0], ha->hw.mac_addr[1],
829 	//	ha->hw.mac_addr[2], ha->hw.mac_addr[3],
830 	//	ha->hw.mac_addr[4], ha->hw.mac_addr[5]);
831 
832         return;
833 }
834 
835 /*
836  * Stop/Start/Initialization Handling
837  */
838 
839 static uint16_t
840 qla_tmplt_16bit_checksum(qla_host_t *ha, uint16_t *buf, uint32_t size)
841 {
842 	uint32_t sum = 0;
843 	uint32_t count = size >> 1; /* size in 16 bit words */
844 
845 	while (count-- > 0)
846 		sum += *buf++;
847 
848 	while (sum >> 16)
849 		sum = (sum & 0xFFFF) + (sum >> 16);
850 
851 	return (~sum);
852 }
853 
854 static int
855 qla_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
856 {
857 	q8_wrl_e_t *wr_l;
858 	int i;
859 
860 	wr_l = (q8_wrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
861 
862 	for (i = 0; i < ce_hdr->opcount; i++, wr_l++) {
863 
864 		if (ql_rdwr_indreg32(ha, wr_l->addr, &wr_l->value, 0)) {
865 			device_printf(ha->pci_dev,
866 				"%s: [0x%08x 0x%08x] error\n", __func__,
867 				wr_l->addr, wr_l->value);
868 			return -1;
869 		}
870 		if (ce_hdr->delay_to) {
871 			DELAY(ce_hdr->delay_to);
872 		}
873 	}
874 	return 0;
875 }
876 
877 static int
878 qla_rd_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
879 {
880 	q8_rdwrl_e_t *rd_wr_l;
881 	uint32_t data;
882 	int i;
883 
884 	rd_wr_l = (q8_rdwrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
885 
886 	for (i = 0; i < ce_hdr->opcount; i++, rd_wr_l++) {
887 
888 		if (ql_rdwr_indreg32(ha, rd_wr_l->rd_addr, &data, 1)) {
889 			device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
890 				__func__, rd_wr_l->rd_addr);
891 
892 			return -1;
893 		}
894 
895 		if (ql_rdwr_indreg32(ha, rd_wr_l->wr_addr, &data, 0)) {
896 			device_printf(ha->pci_dev,
897 				"%s: [0x%08x 0x%08x] error\n", __func__,
898 				rd_wr_l->wr_addr, data);
899 			return -1;
900 		}
901 		if (ce_hdr->delay_to) {
902 			DELAY(ce_hdr->delay_to);
903 		}
904 	}
905 	return 0;
906 }
907 
908 static int
909 qla_poll_reg(qla_host_t *ha, uint32_t addr, uint32_t ms_to, uint32_t tmask,
910 	uint32_t tvalue)
911 {
912 	uint32_t data;
913 
914 	while (ms_to) {
915 
916 		if (ql_rdwr_indreg32(ha, addr, &data, 1)) {
917 			device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
918 				__func__, addr);
919 			return -1;
920 		}
921 
922 		if ((data & tmask) != tvalue) {
923 			ms_to--;
924 		} else
925 			break;
926 
927 		qla_mdelay(__func__, 1);
928 	}
929 	return ((ms_to ? 0: -1));
930 }
931 
932 static int
933 qla_poll_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
934 {
935 	int		i;
936 	q8_poll_hdr_t	*phdr;
937 	q8_poll_e_t	*pe;
938 	uint32_t	data;
939 
940 	phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
941 	pe = (q8_poll_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
942 
943 	for (i = 0; i < ce_hdr->opcount; i++, pe++) {
944 		if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
945 			device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
946 				__func__, pe->addr);
947 			return -1;
948 		}
949 
950 		if (ce_hdr->delay_to)  {
951 			if ((data & phdr->tmask) == phdr->tvalue)
952 				break;
953 			if (qla_poll_reg(ha, pe->addr, ce_hdr->delay_to,
954 				phdr->tmask, phdr->tvalue)) {
955 
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 
988 		if (ql_rdwr_indreg32(ha, wr_e->dr_addr, &wr_e->dr_value, 0)) {
989 			device_printf(ha->pci_dev,
990 				"%s: [0x%08x 0x%08x] error\n", __func__,
991 				wr_e->dr_addr, wr_e->dr_value);
992 			return -1;
993 		}
994 		if (ql_rdwr_indreg32(ha, wr_e->ar_addr, &wr_e->ar_value, 0)) {
995 			device_printf(ha->pci_dev,
996 				"%s: [0x%08x 0x%08x] error\n", __func__,
997 				wr_e->ar_addr, wr_e->ar_value);
998 			return -1;
999 		}
1000 		if (ce_hdr->delay_to)  {
1001 			if (qla_poll_reg(ha, wr_e->ar_addr, ce_hdr->delay_to,
1002 				phdr->tmask, phdr->tvalue))
1003 				device_printf(ha->pci_dev, "%s: "
1004 					"[ar_addr, ar_value, delay, tmask,"
1005 					"tvalue] [0x%08x 0x%08x 0x%08x 0x%08x"
1006 					" 0x%08x]\n",
1007 					__func__, wr_e->ar_addr, wr_e->ar_value,
1008 					ce_hdr->delay_to, phdr->tmask,
1009 					phdr->tvalue);
1010 		}
1011 	}
1012 	return 0;
1013 }
1014 
1015 static int
1016 qla_poll_read_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
1017 {
1018 	int		i;
1019 	q8_poll_hdr_t	*phdr;
1020 	q8_poll_rd_e_t	*rd_e;
1021 	uint32_t	value;
1022 
1023 	phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
1024 	rd_e = (q8_poll_rd_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
1025 
1026 	for (i = 0; i < ce_hdr->opcount; i++, rd_e++) {
1027 		if (ql_rdwr_indreg32(ha, rd_e->ar_addr, &rd_e->ar_value, 0)) {
1028 			device_printf(ha->pci_dev,
1029 				"%s: [0x%08x 0x%08x] error\n", __func__,
1030 				rd_e->ar_addr, rd_e->ar_value);
1031 			return -1;
1032 		}
1033 
1034 		if (ce_hdr->delay_to)  {
1035 			if (qla_poll_reg(ha, rd_e->ar_addr, ce_hdr->delay_to,
1036 				phdr->tmask, phdr->tvalue)) {
1037 				return (-1);
1038 			} else {
1039 				if (ql_rdwr_indreg32(ha, rd_e->dr_addr,
1040 					&value, 1)) {
1041 					device_printf(ha->pci_dev,
1042 						"%s: [0x%08x] error\n",
1043 						__func__, rd_e->ar_addr);
1044 					return -1;
1045 				}
1046 
1047 				ha->hw.rst_seq[ha->hw.rst_seq_idx++] = value;
1048 				if (ha->hw.rst_seq_idx == Q8_MAX_RESET_SEQ_IDX)
1049 					ha->hw.rst_seq_idx = 1;
1050 			}
1051 		}
1052 	}
1053 	return 0;
1054 }
1055 
1056 static int
1057 qla_rdmwr(qla_host_t *ha, uint32_t raddr, uint32_t waddr, q8_rdmwr_hdr_t *hdr)
1058 {
1059 	uint32_t value;
1060 
1061 	if (hdr->index_a >= Q8_MAX_RESET_SEQ_IDX) {
1062 		device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
1063 			hdr->index_a);
1064 		return -1;
1065 	}
1066 
1067 	if (hdr->index_a) {
1068 		value = ha->hw.rst_seq[hdr->index_a];
1069 	} else {
1070 		if (ql_rdwr_indreg32(ha, raddr, &value, 1)) {
1071 			device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
1072 						__func__, raddr);
1073 			return -1;
1074 		}
1075 	}
1076 
1077 	value &= hdr->and_value;
1078 	value <<= hdr->shl;
1079 	value >>= hdr->shr;
1080 	value |= hdr->or_value;
1081 	value ^= hdr->xor_value;
1082 
1083 	if (ql_rdwr_indreg32(ha, waddr, &value, 0)) {
1084 		device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
1085 			raddr);
1086 		return -1;
1087 	}
1088 	return 0;
1089 }
1090 
1091 static int
1092 qla_read_modify_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
1093 {
1094 	int		i;
1095 	q8_rdmwr_hdr_t	*rdmwr_hdr;
1096 	q8_rdmwr_e_t	*rdmwr_e;
1097 
1098 	rdmwr_hdr = (q8_rdmwr_hdr_t *)((uint8_t *)ce_hdr +
1099 						sizeof (q8_ce_hdr_t));
1100 	rdmwr_e = (q8_rdmwr_e_t *)((uint8_t *)rdmwr_hdr +
1101 					sizeof(q8_rdmwr_hdr_t));
1102 
1103 	for (i = 0; i < ce_hdr->opcount; i++, rdmwr_e++) {
1104 
1105 		if (qla_rdmwr(ha, rdmwr_e->rd_addr, rdmwr_e->wr_addr,
1106 			rdmwr_hdr)) {
1107 			return -1;
1108 		}
1109 		if (ce_hdr->delay_to) {
1110 			DELAY(ce_hdr->delay_to);
1111 		}
1112 	}
1113 	return 0;
1114 }
1115 
1116 static int
1117 qla_tmplt_execute(qla_host_t *ha, uint8_t *buf, int start_idx, int *end_idx,
1118 	uint32_t nentries)
1119 {
1120 	int i, ret = 0, proc_end = 0;
1121 	q8_ce_hdr_t	*ce_hdr;
1122 
1123 	for (i = start_idx; ((i < nentries) && (!proc_end)); i++) {
1124 		ce_hdr = (q8_ce_hdr_t *)buf;
1125 		ret = 0;
1126 
1127 		switch (ce_hdr->opcode) {
1128 		case Q8_CE_OPCODE_NOP:
1129 			break;
1130 
1131 		case Q8_CE_OPCODE_WRITE_LIST:
1132 			ret = qla_wr_list(ha, ce_hdr);
1133 			//printf("qla_wr_list %d\n", ret);
1134 			break;
1135 
1136 		case Q8_CE_OPCODE_READ_WRITE_LIST:
1137 			ret = qla_rd_wr_list(ha, ce_hdr);
1138 			//printf("qla_rd_wr_list %d\n", ret);
1139 			break;
1140 
1141 		case Q8_CE_OPCODE_POLL_LIST:
1142 			ret = qla_poll_list(ha, ce_hdr);
1143 			//printf("qla_poll_list %d\n", ret);
1144 			break;
1145 
1146 		case Q8_CE_OPCODE_POLL_WRITE_LIST:
1147 			ret = qla_poll_write_list(ha, ce_hdr);
1148 			//printf("qla_poll_write_list %d\n", ret);
1149 			break;
1150 
1151 		case Q8_CE_OPCODE_POLL_RD_LIST:
1152 			ret = qla_poll_read_list(ha, ce_hdr);
1153 			//printf("qla_poll_read_list %d\n", ret);
1154 			break;
1155 
1156 		case Q8_CE_OPCODE_READ_MODIFY_WRITE:
1157 			ret = qla_read_modify_write_list(ha, ce_hdr);
1158 			//printf("qla_read_modify_write_list %d\n", ret);
1159 			break;
1160 
1161 		case Q8_CE_OPCODE_SEQ_PAUSE:
1162 			if (ce_hdr->delay_to) {
1163 				qla_mdelay(__func__, ce_hdr->delay_to);
1164 			}
1165 			break;
1166 
1167 		case Q8_CE_OPCODE_SEQ_END:
1168 			proc_end = 1;
1169 			break;
1170 
1171 		case Q8_CE_OPCODE_TMPLT_END:
1172 			*end_idx = i;
1173 			return 0;
1174 		}
1175 
1176 		if (ret)
1177 			break;
1178 
1179 		buf += ce_hdr->size;
1180 	}
1181 	*end_idx = i;
1182 
1183 	return (ret);
1184 }
1185 
1186 #ifndef QL_LDFLASH_FW
1187 static int
1188 qla_load_offchip_mem(qla_host_t *ha, uint64_t addr, uint32_t *data32,
1189         uint32_t len32)
1190 {
1191         q80_offchip_mem_val_t val;
1192         int             ret = 0;
1193 
1194         while (len32) {
1195                 if (len32 > 4) {
1196                         val.data_lo = *data32++;
1197                         val.data_hi = *data32++;
1198                         val.data_ulo = *data32++;
1199                         val.data_uhi = *data32++;
1200                         len32 -= 4;
1201                         if (ql_rdwr_offchip_mem(ha, addr, &val, 0))
1202                                 return -1;
1203 
1204                         addr += (uint64_t)16;
1205                 } else {
1206                         break;
1207                 }
1208         }
1209 
1210         bzero(&val, sizeof(q80_offchip_mem_val_t));
1211 
1212         switch (len32) {
1213         case 3:
1214                 val.data_lo = *data32++;
1215                 val.data_hi = *data32++;
1216                 val.data_ulo = *data32++;
1217                  ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1218                 break;
1219 
1220         case 2:
1221                 val.data_lo = *data32++;
1222                 val.data_hi = *data32++;
1223                  ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1224                 break;
1225 
1226         case 1:
1227                 val.data_lo = *data32++;
1228                 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1229                 break;
1230 
1231         default:
1232                 break;
1233 
1234         }
1235         return ret;
1236 }
1237 
1238 
1239 static int
1240 qla_load_bootldr(qla_host_t *ha)
1241 {
1242         uint64_t        addr;
1243         uint32_t        *data32;
1244         uint32_t        len32;
1245         int             ret;
1246 
1247         addr = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
1248         data32 = (uint32_t *)ql83xx_bootloader;
1249         len32 = ql83xx_bootloader_len >> 2;
1250 
1251         ret = qla_load_offchip_mem(ha, addr, data32, len32);
1252 
1253         return (ret);
1254 }
1255 
1256 static int
1257 qla_load_fwimage(qla_host_t *ha)
1258 {
1259         uint64_t        addr;
1260         uint32_t        *data32;
1261         uint32_t        len32;
1262         int             ret;
1263 
1264         addr = (uint64_t)(READ_REG32(ha, Q8_FW_IMAGE_ADDR));
1265         data32 = (uint32_t *)ql83xx_firmware;
1266         len32 = ql83xx_firmware_len >> 2;
1267 
1268         ret = qla_load_offchip_mem(ha, addr, data32, len32);
1269 
1270         return (ret);
1271 }
1272 #endif /* #ifndef QL_LDFLASH_FW */
1273 
1274 static int
1275 qla_ld_fw_init(qla_host_t *ha)
1276 {
1277 	uint8_t *buf;
1278 	uint32_t index = 0, end_idx;
1279 	q8_tmplt_hdr_t *hdr;
1280 
1281 	bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1282 
1283 	hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1284 
1285 	if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1286 		(uint32_t)hdr->size)) {
1287 		device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1288 			__func__);
1289 		return -1;
1290 	}
1291 
1292 
1293 	buf = ql83xx_resetseq + hdr->stop_seq_off;
1294 
1295 //	device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
1296 	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1297 		device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
1298 		return -1;
1299 	}
1300 
1301 	index = end_idx;
1302 
1303 	buf = ql83xx_resetseq + hdr->init_seq_off;
1304 
1305 //	device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
1306 	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1307 		device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1308 		return -1;
1309 	}
1310 
1311 #ifdef QL_LDFLASH_FW
1312 	qla_load_fw_from_flash(ha);
1313 	WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
1314 #else
1315         if (qla_load_bootldr(ha))
1316                 return -1;
1317 
1318         if (qla_load_fwimage(ha))
1319                 return -1;
1320 
1321         WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
1322 #endif /* #ifdef QL_LDFLASH_FW */
1323 
1324 	index = end_idx;
1325 	buf = ql83xx_resetseq + hdr->start_seq_off;
1326 
1327 //	device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
1328 	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1329 		device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1330 		return -1;
1331 	}
1332 
1333 	return 0;
1334 }
1335 
1336 int
1337 ql_stop_sequence(qla_host_t *ha)
1338 {
1339 	uint8_t *buf;
1340 	uint32_t index = 0, end_idx;
1341 	q8_tmplt_hdr_t *hdr;
1342 
1343 	bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1344 
1345 	hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1346 
1347 	if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1348 		(uint32_t)hdr->size)) {
1349 		device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1350 		__func__);
1351 		return (-1);
1352 	}
1353 
1354 	buf = ql83xx_resetseq + hdr->stop_seq_off;
1355 
1356 	device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
1357 	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1358 		device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
1359 		return (-1);
1360 	}
1361 
1362 	return end_idx;
1363 }
1364 
1365 int
1366 ql_start_sequence(qla_host_t *ha, uint16_t index)
1367 {
1368 	uint8_t *buf;
1369 	uint32_t end_idx;
1370 	q8_tmplt_hdr_t *hdr;
1371 
1372 	bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1373 
1374 	hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1375 
1376 	if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1377 		(uint32_t)hdr->size)) {
1378 		device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1379 		__func__);
1380 		return (-1);
1381 	}
1382 
1383 	buf = ql83xx_resetseq + hdr->init_seq_off;
1384 
1385 	device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
1386 	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1387 		device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1388 		return (-1);
1389 	}
1390 
1391 #ifdef QL_LDFLASH_FW
1392 	qla_load_fw_from_flash(ha);
1393 	WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
1394 #else
1395         if (qla_load_bootldr(ha))
1396                 return -1;
1397 
1398         if (qla_load_fwimage(ha))
1399                 return -1;
1400 
1401         WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
1402 #endif /* #ifdef QL_LDFLASH_FW */
1403 
1404 
1405 	index = end_idx;
1406 	buf = ql83xx_resetseq + hdr->start_seq_off;
1407 
1408 	device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
1409 	if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1410 		device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1411 		return -1;
1412 	}
1413 
1414 	return (0);
1415 }
1416 
1417