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