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