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