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