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