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