]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/qlxgbe/ql_misc.c
Merge llvm trunk r321414 to contrib/llvm.
[FreeBSD/FreeBSD.git] / sys / dev / qlxgbe / ql_misc.c
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                 ha->qla_initiate_recovery = 1;
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
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         ha->qla_initiate_recovery = 1;
216
217         return (-1);
218 }
219
220 /*
221  * Name: ql_rd_flash32
222  * Function: Read Flash Memory
223  */
224 int
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 
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
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
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
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
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
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
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
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
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
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                 return (-1);
779         }
780
781         
782         val = READ_REG32(ha, Q8_CMDPEG_STATE);
783         if (!cold || (val != 0xFF01)) {
784                 ret = qla_init_from_flash(ha);
785                 qla_mdelay(__func__, 100);
786         }
787
788 qla_init_exit:
789         ha->fw_ver_major = READ_REG32(ha, Q8_FW_VER_MAJOR);
790         ha->fw_ver_minor = READ_REG32(ha, Q8_FW_VER_MINOR);
791         ha->fw_ver_sub = READ_REG32(ha, Q8_FW_VER_SUB);
792
793         if (qla_get_fdt(ha) != 0) {
794                 device_printf(dev, "%s: qla_get_fdt failed\n", __func__);
795         } else {
796                 ha->hw.flags.fdt_valid = 1;
797         }
798
799         return (ret);
800 }
801
802 void
803 ql_read_mac_addr(qla_host_t *ha)
804 {
805         uint8_t *macp;
806         uint32_t mac_lo;
807         uint32_t mac_hi;
808         uint32_t flash_off;
809
810         flash_off = Q8_BOARD_CONFIG_OFFSET + Q8_BOARD_CONFIG_MAC0_LO +
811                         (ha->pci_func << 3);
812         ql_rd_flash32(ha, flash_off, &mac_lo);
813
814         flash_off += 4;
815         ql_rd_flash32(ha, flash_off, &mac_hi);
816
817         macp = (uint8_t *)&mac_lo;
818         ha->hw.mac_addr[5] = macp[0];
819         ha->hw.mac_addr[4] = macp[1];
820         ha->hw.mac_addr[3] = macp[2];
821         ha->hw.mac_addr[2] = macp[3];
822  
823         macp = (uint8_t *)&mac_hi;
824         ha->hw.mac_addr[1] = macp[0];
825         ha->hw.mac_addr[0] = macp[1];
826
827         //device_printf(ha->pci_dev, "%s: %02x:%02x:%02x:%02x:%02x:%02x\n",
828         //      __func__, ha->hw.mac_addr[0], ha->hw.mac_addr[1],
829         //      ha->hw.mac_addr[2], ha->hw.mac_addr[3],
830         //      ha->hw.mac_addr[4], ha->hw.mac_addr[5]);
831
832         return;
833 }
834
835 /*
836  * Stop/Start/Initialization Handling
837  */
838
839 static uint16_t
840 qla_tmplt_16bit_checksum(qla_host_t *ha, uint16_t *buf, uint32_t size)
841 {
842         uint32_t sum = 0;
843         uint32_t count = size >> 1; /* size in 16 bit words */
844
845         while (count-- > 0) 
846                 sum += *buf++;
847
848         while (sum >> 16) 
849                 sum = (sum & 0xFFFF) + (sum >> 16);
850
851         return (~sum);
852 }
853
854 static int
855 qla_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
856 {
857         q8_wrl_e_t *wr_l;
858         int i;
859
860         wr_l = (q8_wrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
861
862         for (i = 0; i < ce_hdr->opcount; i++, wr_l++) {
863
864                 if (ql_rdwr_indreg32(ha, wr_l->addr, &wr_l->value, 0)) {
865                         device_printf(ha->pci_dev,
866                                 "%s: [0x%08x 0x%08x] error\n", __func__,
867                                 wr_l->addr, wr_l->value);
868                         return -1;
869                 }
870                 if (ce_hdr->delay_to) {
871                         DELAY(ce_hdr->delay_to);
872                 }
873         }
874         return 0;
875 }
876
877 static int
878 qla_rd_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
879 {
880         q8_rdwrl_e_t *rd_wr_l;
881         uint32_t data;
882         int i;
883
884         rd_wr_l = (q8_rdwrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
885
886         for (i = 0; i < ce_hdr->opcount; i++, rd_wr_l++) {
887
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
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
916                 if (ql_rdwr_indreg32(ha, addr, &data, 1)) {
917                         device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
918                                 __func__, addr);
919                         return -1;
920                 }
921
922                 if ((data & tmask) != tvalue) {
923                         ms_to--;
924                 } else 
925                         break;
926
927                 qla_mdelay(__func__, 1);
928         }
929         return ((ms_to ? 0: -1));
930 }
931
932 static int
933 qla_poll_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
934 {
935         int             i;
936         q8_poll_hdr_t   *phdr;
937         q8_poll_e_t     *pe;
938         uint32_t        data;
939
940         phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
941         pe = (q8_poll_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
942
943         for (i = 0; i < ce_hdr->opcount; i++, pe++) {
944                 if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
945                         device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
946                                 __func__, pe->addr);
947                         return -1;
948                 }
949
950                 if (ce_hdr->delay_to)  {
951                         if ((data & phdr->tmask) == phdr->tvalue)
952                                 break;
953                         if (qla_poll_reg(ha, pe->addr, ce_hdr->delay_to,
954                                 phdr->tmask, phdr->tvalue)) {
955
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
988                 if (ql_rdwr_indreg32(ha, wr_e->dr_addr, &wr_e->dr_value, 0)) {
989                         device_printf(ha->pci_dev,
990                                 "%s: [0x%08x 0x%08x] error\n", __func__,
991                                 wr_e->dr_addr, wr_e->dr_value);
992                         return -1;
993                 }
994                 if (ql_rdwr_indreg32(ha, wr_e->ar_addr, &wr_e->ar_value, 0)) {
995                         device_printf(ha->pci_dev,
996                                 "%s: [0x%08x 0x%08x] error\n", __func__,
997                                 wr_e->ar_addr, wr_e->ar_value);
998                         return -1;
999                 }
1000                 if (ce_hdr->delay_to)  {
1001                         if (qla_poll_reg(ha, wr_e->ar_addr, ce_hdr->delay_to,
1002                                 phdr->tmask, phdr->tvalue))
1003                                 device_printf(ha->pci_dev, "%s: "
1004                                         "[ar_addr, ar_value, delay, tmask,"
1005                                         "tvalue] [0x%08x 0x%08x 0x%08x 0x%08x"
1006                                         " 0x%08x]\n",
1007                                         __func__, wr_e->ar_addr, wr_e->ar_value,
1008                                         ce_hdr->delay_to, phdr->tmask,
1009                                         phdr->tvalue);
1010                 }
1011         }
1012         return 0;
1013 }
1014
1015 static int
1016 qla_poll_read_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
1017 {
1018         int             i;
1019         q8_poll_hdr_t   *phdr;
1020         q8_poll_rd_e_t  *rd_e;
1021         uint32_t        value;
1022
1023         phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
1024         rd_e = (q8_poll_rd_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
1025
1026         for (i = 0; i < ce_hdr->opcount; i++, rd_e++) {
1027                 if (ql_rdwr_indreg32(ha, rd_e->ar_addr, &rd_e->ar_value, 0)) {
1028                         device_printf(ha->pci_dev,
1029                                 "%s: [0x%08x 0x%08x] error\n", __func__,
1030                                 rd_e->ar_addr, rd_e->ar_value);
1031                         return -1;
1032                 }
1033
1034                 if (ce_hdr->delay_to)  {
1035                         if (qla_poll_reg(ha, rd_e->ar_addr, ce_hdr->delay_to,
1036                                 phdr->tmask, phdr->tvalue)) {
1037                                 return (-1);
1038                         } else {
1039                                 if (ql_rdwr_indreg32(ha, rd_e->dr_addr,
1040                                         &value, 1)) {
1041                                         device_printf(ha->pci_dev,
1042                                                 "%s: [0x%08x] error\n",
1043                                                 __func__, rd_e->ar_addr);
1044                                         return -1;
1045                                 }
1046
1047                                 ha->hw.rst_seq[ha->hw.rst_seq_idx++] = value;
1048                                 if (ha->hw.rst_seq_idx == Q8_MAX_RESET_SEQ_IDX)
1049                                         ha->hw.rst_seq_idx = 1;
1050                         }
1051                 }
1052         }
1053         return 0;
1054 }
1055
1056 static int
1057 qla_rdmwr(qla_host_t *ha, uint32_t raddr, uint32_t waddr, q8_rdmwr_hdr_t *hdr)
1058 {
1059         uint32_t value;
1060
1061         if (hdr->index_a >= Q8_MAX_RESET_SEQ_IDX) {
1062                 device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
1063                         hdr->index_a);
1064                 return -1;
1065         }
1066
1067         if (hdr->index_a) {
1068                 value = ha->hw.rst_seq[hdr->index_a];
1069         } else {
1070                 if (ql_rdwr_indreg32(ha, raddr, &value, 1)) {
1071                         device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
1072                                                 __func__, raddr);
1073                         return -1;
1074                 }
1075         }
1076
1077         value &= hdr->and_value;
1078         value <<= hdr->shl;
1079         value >>= hdr->shr;
1080         value |= hdr->or_value;
1081         value ^= hdr->xor_value;
1082
1083         if (ql_rdwr_indreg32(ha, waddr, &value, 0)) {
1084                 device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
1085                         raddr);
1086                 return -1;
1087         }
1088         return 0;
1089 }
1090
1091 static int
1092 qla_read_modify_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
1093 {
1094         int             i;
1095         q8_rdmwr_hdr_t  *rdmwr_hdr;
1096         q8_rdmwr_e_t    *rdmwr_e;
1097
1098         rdmwr_hdr = (q8_rdmwr_hdr_t *)((uint8_t *)ce_hdr +
1099                                                 sizeof (q8_ce_hdr_t));
1100         rdmwr_e = (q8_rdmwr_e_t *)((uint8_t *)rdmwr_hdr +
1101                                         sizeof(q8_rdmwr_hdr_t));
1102
1103         for (i = 0; i < ce_hdr->opcount; i++, rdmwr_e++) {
1104
1105                 if (qla_rdmwr(ha, rdmwr_e->rd_addr, rdmwr_e->wr_addr,
1106                         rdmwr_hdr)) {
1107                         return -1;
1108                 }
1109                 if (ce_hdr->delay_to) {
1110                         DELAY(ce_hdr->delay_to);
1111                 }
1112         }
1113         return 0;
1114 }
1115
1116 static int
1117 qla_tmplt_execute(qla_host_t *ha, uint8_t *buf, int start_idx, int *end_idx,
1118         uint32_t nentries)
1119 {
1120         int i, ret = 0, proc_end = 0;
1121         q8_ce_hdr_t     *ce_hdr;
1122
1123         for (i = start_idx; ((i < nentries) && (!proc_end)); i++) {
1124                 ce_hdr = (q8_ce_hdr_t *)buf;
1125                 ret = 0;
1126
1127                 switch (ce_hdr->opcode) {
1128                 case Q8_CE_OPCODE_NOP:
1129                         break;
1130
1131                 case Q8_CE_OPCODE_WRITE_LIST:
1132                         ret = qla_wr_list(ha, ce_hdr);
1133                         //printf("qla_wr_list %d\n", ret);
1134                         break;
1135
1136                 case Q8_CE_OPCODE_READ_WRITE_LIST:
1137                         ret = qla_rd_wr_list(ha, ce_hdr);
1138                         //printf("qla_rd_wr_list %d\n", ret);
1139                         break;
1140
1141                 case Q8_CE_OPCODE_POLL_LIST:
1142                         ret = qla_poll_list(ha, ce_hdr);
1143                         //printf("qla_poll_list %d\n", ret);
1144                         break;
1145
1146                 case Q8_CE_OPCODE_POLL_WRITE_LIST:
1147                         ret = qla_poll_write_list(ha, ce_hdr);
1148                         //printf("qla_poll_write_list %d\n", ret);
1149                         break;
1150
1151                 case Q8_CE_OPCODE_POLL_RD_LIST:
1152                         ret = qla_poll_read_list(ha, ce_hdr);
1153                         //printf("qla_poll_read_list %d\n", ret);
1154                         break;
1155
1156                 case Q8_CE_OPCODE_READ_MODIFY_WRITE:
1157                         ret = qla_read_modify_write_list(ha, ce_hdr);
1158                         //printf("qla_read_modify_write_list %d\n", ret);
1159                         break;
1160
1161                 case Q8_CE_OPCODE_SEQ_PAUSE:
1162                         if (ce_hdr->delay_to) {
1163                                 qla_mdelay(__func__, ce_hdr->delay_to);
1164                         }
1165                         break;
1166
1167                 case Q8_CE_OPCODE_SEQ_END:
1168                         proc_end = 1;
1169                         break;
1170
1171                 case Q8_CE_OPCODE_TMPLT_END:
1172                         *end_idx = i;
1173                         return 0;
1174                 }
1175
1176                 if (ret)
1177                         break;
1178
1179                 buf += ce_hdr->size;
1180         }
1181         *end_idx = i;
1182
1183         return (ret);
1184 }
1185
1186 #ifndef QL_LDFLASH_FW
1187 static int
1188 qla_load_offchip_mem(qla_host_t *ha, uint64_t addr, uint32_t *data32,
1189         uint32_t len32)
1190 {
1191         q80_offchip_mem_val_t val;
1192         int             ret = 0;
1193
1194         while (len32) {
1195                 if (len32 > 4) {
1196                         val.data_lo = *data32++;
1197                         val.data_hi = *data32++;
1198                         val.data_ulo = *data32++;
1199                         val.data_uhi = *data32++;
1200                         len32 -= 4;
1201                         if (ql_rdwr_offchip_mem(ha, addr, &val, 0))
1202                                 return -1;
1203
1204                         addr += (uint64_t)16;
1205                 } else {
1206                         break;
1207                 }
1208         }
1209
1210         bzero(&val, sizeof(q80_offchip_mem_val_t));
1211
1212         switch (len32) {
1213         case 3:
1214                 val.data_lo = *data32++;
1215                 val.data_hi = *data32++;
1216                 val.data_ulo = *data32++;
1217                  ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1218                 break;
1219
1220         case 2:
1221                 val.data_lo = *data32++;
1222                 val.data_hi = *data32++;
1223                  ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1224                 break;
1225
1226         case 1:
1227                 val.data_lo = *data32++;
1228                 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1229                 break;
1230
1231         default:
1232                 break;
1233
1234         }
1235         return ret;
1236 }
1237
1238
1239 static int
1240 qla_load_bootldr(qla_host_t *ha)
1241 {
1242         uint64_t        addr;
1243         uint32_t        *data32;
1244         uint32_t        len32;
1245         int             ret;
1246
1247         addr = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
1248         data32 = (uint32_t *)ql83xx_bootloader;
1249         len32 = ql83xx_bootloader_len >> 2;
1250
1251         ret = qla_load_offchip_mem(ha, addr, data32, len32);
1252
1253         return (ret);
1254 }
1255
1256 static int
1257 qla_load_fwimage(qla_host_t *ha)
1258 {
1259         uint64_t        addr;
1260         uint32_t        *data32;
1261         uint32_t        len32;
1262         int             ret;
1263
1264         addr = (uint64_t)(READ_REG32(ha, Q8_FW_IMAGE_ADDR));
1265         data32 = (uint32_t *)ql83xx_firmware;
1266         len32 = ql83xx_firmware_len >> 2;
1267
1268         ret = qla_load_offchip_mem(ha, addr, data32, len32);
1269
1270         return (ret);
1271 }
1272 #endif /* #ifndef QL_LDFLASH_FW */
1273
1274 static int
1275 qla_ld_fw_init(qla_host_t *ha)
1276 {
1277         uint8_t *buf;
1278         uint32_t index = 0, end_idx;
1279         q8_tmplt_hdr_t *hdr;
1280
1281         bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1282
1283         hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1284
1285         if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1286                 (uint32_t)hdr->size)) {
1287                 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1288                         __func__);
1289                 return -1;
1290         }
1291         
1292
1293         buf = ql83xx_resetseq + hdr->stop_seq_off;
1294
1295 //      device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
1296         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1297                 device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
1298                 return -1;
1299         }
1300
1301         index = end_idx;
1302
1303         buf = ql83xx_resetseq + hdr->init_seq_off;
1304
1305 //      device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
1306         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1307                 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1308                 return -1;
1309         }
1310
1311 #ifdef QL_LDFLASH_FW
1312         qla_load_fw_from_flash(ha);
1313         WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
1314 #else
1315         if (qla_load_bootldr(ha))
1316                 return -1;
1317
1318         if (qla_load_fwimage(ha))
1319                 return -1;
1320
1321         WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
1322 #endif /* #ifdef QL_LDFLASH_FW */
1323
1324         index = end_idx;
1325         buf = ql83xx_resetseq + hdr->start_seq_off;
1326
1327 //      device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
1328         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1329                 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1330                 return -1;
1331         }
1332
1333         return 0;
1334 }
1335
1336 int
1337 ql_stop_sequence(qla_host_t *ha)
1338 {
1339         uint8_t *buf;
1340         uint32_t index = 0, end_idx;
1341         q8_tmplt_hdr_t *hdr;
1342
1343         bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1344
1345         hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1346
1347         if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1348                 (uint32_t)hdr->size)) {
1349                 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1350                 __func__);
1351                 return (-1);
1352         }
1353
1354         buf = ql83xx_resetseq + hdr->stop_seq_off;
1355
1356         device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
1357         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1358                 device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
1359                 return (-1);
1360         }
1361
1362         return end_idx;
1363 }
1364
1365 int
1366 ql_start_sequence(qla_host_t *ha, uint16_t index)
1367 {
1368         uint8_t *buf;
1369         uint32_t end_idx;
1370         q8_tmplt_hdr_t *hdr;
1371
1372         bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1373
1374         hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1375
1376         if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1377                 (uint32_t)hdr->size)) {
1378                 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1379                 __func__);
1380                 return (-1);
1381         }
1382
1383         buf = ql83xx_resetseq + hdr->init_seq_off;
1384
1385         device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
1386         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1387                 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1388                 return (-1);
1389         }
1390
1391 #ifdef QL_LDFLASH_FW
1392         qla_load_fw_from_flash(ha);
1393         WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
1394 #else
1395         if (qla_load_bootldr(ha))
1396                 return -1;
1397
1398         if (qla_load_fwimage(ha))
1399                 return -1;
1400
1401         WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
1402 #endif /* #ifdef QL_LDFLASH_FW */
1403
1404
1405         index = end_idx;
1406         buf = ql83xx_resetseq + hdr->start_seq_off;
1407
1408         device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
1409         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1410                 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1411                 return -1;
1412         }
1413
1414         return (0);
1415 }
1416