]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/qlxgbe/ql_misc.c
MFV: r361597
[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                 QL_INITIATE_RECOVERY(ha);
83                 return -1;
84         }
85
86         if (rd) {
87                 *val = READ_REG32(ha, Q8_WILD_CARD);
88         } else {
89                 WRITE_REG32(ha, Q8_WILD_CARD, *val);
90         }
91
92         return 0;
93 }
94
95 /*
96  * Name: ql_rdwr_offchip_mem
97  * Function: Read/Write OffChip Memory
98  */
99 int
100 ql_rdwr_offchip_mem(qla_host_t *ha, uint64_t addr, q80_offchip_mem_val_t *val,
101         uint32_t rd)
102 {
103         uint32_t count = 100;
104         uint32_t data, step = 0;
105
106
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
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                 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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