2 * Copyright (c) 2013-2016 Qlogic Corporation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
38 #include "ql_inline.h"
43 #define QL_FDT_OFFSET 0x3F0000
44 #define Q8_FLASH_SECTOR_SIZE 0x10000
46 static int qla_ld_fw_init(qla_host_t *ha);
49 * structure encapsulating the value to read/write to offchip memory
51 typedef struct _offchip_mem_val {
59 * Name: ql_rdwr_indreg32
60 * Function: Read/Write an Indirect Register
63 ql_rdwr_indreg32(qla_host_t *ha, uint32_t addr, uint32_t *val, uint32_t rd)
68 wnd_reg = (Q8_CRB_WINDOW_PF0 | (ha->pci_func << 2));
70 WRITE_REG32(ha, wnd_reg, addr);
73 if (READ_REG32(ha, wnd_reg) == addr)
75 qla_mdelay(__func__, 1);
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 ha->qla_initiate_recovery = 1;
85 *val = READ_REG32(ha, Q8_WILD_CARD);
87 WRITE_REG32(ha, Q8_WILD_CARD, *val);
94 * Name: ql_rdwr_offchip_mem
95 * Function: Read/Write OffChip Memory
98 ql_rdwr_offchip_mem(qla_host_t *ha, uint64_t addr, q80_offchip_mem_val_t *val,
101 uint32_t count = 100;
102 uint32_t data, step = 0;
105 if (QL_ERR_INJECT(ha, INJCT_RDWR_OFFCHIPMEM_FAILURE))
106 goto exit_ql_rdwr_offchip_mem;
108 data = (uint32_t)addr;
109 if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_LO, &data, 0)) {
111 goto exit_ql_rdwr_offchip_mem;
114 data = (uint32_t)(addr >> 32);
115 if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_HI, &data, 0)) {
117 goto exit_ql_rdwr_offchip_mem;
121 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
123 goto exit_ql_rdwr_offchip_mem;
128 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_0_31, &data, 0)) {
130 goto exit_ql_rdwr_offchip_mem;
134 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_32_63, &data, 0)) {
136 goto exit_ql_rdwr_offchip_mem;
139 data = val->data_ulo;
140 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_64_95, &data, 0)) {
142 goto exit_ql_rdwr_offchip_mem;
145 data = val->data_uhi;
146 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_96_127, &data, 0)) {
148 goto exit_ql_rdwr_offchip_mem;
151 data = (BIT_2|BIT_1|BIT_0);
152 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
154 goto exit_ql_rdwr_offchip_mem;
157 data = (BIT_1|BIT_0);
158 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
160 goto exit_ql_rdwr_offchip_mem;
165 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 1)) {
167 goto exit_ql_rdwr_offchip_mem;
170 if (!(data & BIT_3)) {
172 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_0_31,
175 goto exit_ql_rdwr_offchip_mem;
179 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_32_63,
182 goto exit_ql_rdwr_offchip_mem;
186 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_64_95,
189 goto exit_ql_rdwr_offchip_mem;
191 val->data_ulo = data;
193 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_96_127,
196 goto exit_ql_rdwr_offchip_mem;
198 val->data_uhi = data;
202 qla_mdelay(__func__, 1);
205 exit_ql_rdwr_offchip_mem:
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);
213 ha->qla_initiate_recovery = 1;
219 * Name: ql_rd_flash32
220 * Function: Read Flash Memory
223 ql_rd_flash32(qla_host_t *ha, uint32_t addr, uint32_t *data)
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",
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",
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",
251 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
256 qla_get_fdt(qla_host_t *ha)
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",
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",
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",
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",
306 qla_mdelay(__func__, 1);
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",
322 } while ((count < 10000) && (data32 != 0x6));
325 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
326 device_printf(ha->pci_dev,
327 "%s: Poll Q8_FLASH_STATUS failed\n",
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",
340 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
342 data32 &= Q8_FDT_MASK_VAL;
343 if (hw->fdt.flash_manuf == data32)
350 qla_flash_write_enable(qla_host_t *ha, int enable)
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",
364 data32 = ha->hw.fdt.write_enable_bits;
366 data32 = ha->hw.fdt.write_disable_bits;
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",
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",
388 qla_mdelay(__func__, 1);
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",
402 } while ((count < 10000) && (data32 != 0x6));
405 device_printf(ha->pci_dev,
406 "%s: Poll Q8_FLASH_STATUS failed\n",
415 qla_erase_flash_sector(qla_host_t *ha, uint32_t start)
421 qla_mdelay(__func__, 1);
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",
433 } while (((count++) < 1000) && (data32 != 0x6));
436 device_printf(ha->pci_dev,
437 "%s: Poll Q8_FLASH_STATUS failed\n",
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",
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",
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",
468 qla_mdelay(__func__, 1);
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",
480 } while (((count++) < 1000) && (data32 != 0x6));
483 device_printf(ha->pci_dev,
484 "%s: Poll Q8_FLASH_STATUS failed\n",
493 ql_erase_flash(qla_host_t *ha, uint32_t off, uint32_t size)
498 if (off & (Q8_FLASH_SECTOR_SIZE -1))
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",
508 if (qla_flash_write_enable(ha, 1) != 0) {
510 goto ql_erase_flash_exit;
513 for (start = off; start < (off + size); start = start +
514 Q8_FLASH_SECTOR_SIZE) {
515 if (qla_erase_flash_sector(ha, start)) {
521 rval = qla_flash_write_enable(ha, 0);
524 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
529 qla_wr_flash32(qla_host_t *ha, uint32_t off, uint32_t *data)
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",
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",
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",
562 qla_mdelay(__func__, 1);
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",
576 } while ((count < 10000) && (data32 != 0x6));
579 device_printf(ha->pci_dev,
580 "%s: Poll Q8_FLASH_STATUS failed\n",
589 qla_flash_write_data(qla_host_t *ha, uint32_t off, uint32_t size,
594 uint32_t *data32 = data;
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",
601 goto qla_flash_write_data_exit;
604 if ((qla_flash_write_enable(ha, 1) != 0)) {
605 device_printf(ha->pci_dev, "%s: failed\n",
608 goto qla_flash_write_data_unlock_exit;
611 for (start = off; start < (off + size); start = start + 4) {
612 if (*data32 != 0xFFFFFFFF) {
613 if (qla_wr_flash32(ha, start, data32)) {
621 rval = qla_flash_write_enable(ha, 0);
623 qla_flash_write_data_unlock_exit:
624 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
626 qla_flash_write_data_exit:
631 ql_wr_flash_buffer(qla_host_t *ha, uint32_t off, uint32_t size, void *buf)
644 if ((data = malloc(size, M_QLA83XXBUF, M_NOWAIT)) == NULL) {
645 device_printf(ha->pci_dev, "%s: malloc failed \n", __func__);
647 goto ql_wr_flash_buffer_exit;
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;
655 rval = qla_flash_write_data(ha, off, size, data);
657 ql_wr_flash_buffer_free_exit:
658 free(data, M_QLA83XXBUF);
660 ql_wr_flash_buffer_exit:
666 * Name: qla_load_fw_from_flash
667 * Function: Reads the Bootloader from Flash and Loads into Offchip Memory
670 qla_load_fw_from_flash(qla_host_t *ha)
672 uint32_t flash_off = 0x10000;
674 uint32_t count, mem_size;
675 q80_offchip_mem_val_t val;
677 mem_off = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
678 mem_size = READ_REG32(ha, Q8_BOOTLD_SIZE);
680 device_printf(ha->pci_dev, "%s: [0x%08x][0x%08x]\n",
681 __func__, (uint32_t)mem_off, mem_size);
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);
687 flash_off = flash_off + 4;
689 ql_rd_flash32(ha, flash_off, &val.data_hi);
691 flash_off = flash_off + 4;
693 ql_rd_flash32(ha, flash_off, &val.data_ulo);
695 flash_off = flash_off + 4;
697 ql_rd_flash32(ha, flash_off, &val.data_uhi);
699 flash_off = flash_off + 4;
701 ql_rdwr_offchip_mem(ha, mem_off, &val, 0);
703 mem_off = mem_off + 16;
708 #endif /* #ifdef QL_LDFLASH_FW */
711 * Name: qla_init_from_flash
712 * Function: Performs Initialization which consists of the following sequence
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.
721 qla_init_from_flash(qla_host_t *ha)
723 uint32_t delay = 300;
729 data = READ_REG32(ha, Q8_CMDPEG_STATE);
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));
740 qla_mdelay(__func__, 100);
748 * Function: Initializes P3+ hardware.
751 ql_init_hw(qla_host_t *ha)
755 uint32_t val, delay = 300;
759 QL_DPRINT1(ha, (dev, "%s: enter\n", __func__));
761 if (ha->pci_func & 0x1) {
763 while ((ha->pci_func & 0x1) && delay--) {
765 val = READ_REG32(ha, Q8_CMDPEG_STATE);
769 "%s: func = %d init complete\n",
770 __func__, ha->pci_func));
771 qla_mdelay(__func__, 100);
774 qla_mdelay(__func__, 100);
780 val = READ_REG32(ha, Q8_CMDPEG_STATE);
781 if (!cold || (val != 0xFF01)) {
782 ret = qla_init_from_flash(ha);
783 qla_mdelay(__func__, 100);
787 ha->fw_ver_major = READ_REG32(ha, Q8_FW_VER_MAJOR);
788 ha->fw_ver_minor = READ_REG32(ha, Q8_FW_VER_MINOR);
789 ha->fw_ver_sub = READ_REG32(ha, Q8_FW_VER_SUB);
791 if (qla_get_fdt(ha) != 0) {
792 device_printf(dev, "%s: qla_get_fdt failed\n", __func__);
794 ha->hw.flags.fdt_valid = 1;
801 ql_read_mac_addr(qla_host_t *ha)
808 flash_off = Q8_BOARD_CONFIG_OFFSET + Q8_BOARD_CONFIG_MAC0_LO +
810 ql_rd_flash32(ha, flash_off, &mac_lo);
813 ql_rd_flash32(ha, flash_off, &mac_hi);
815 macp = (uint8_t *)&mac_lo;
816 ha->hw.mac_addr[5] = macp[0];
817 ha->hw.mac_addr[4] = macp[1];
818 ha->hw.mac_addr[3] = macp[2];
819 ha->hw.mac_addr[2] = macp[3];
821 macp = (uint8_t *)&mac_hi;
822 ha->hw.mac_addr[1] = macp[0];
823 ha->hw.mac_addr[0] = macp[1];
825 //device_printf(ha->pci_dev, "%s: %02x:%02x:%02x:%02x:%02x:%02x\n",
826 // __func__, ha->hw.mac_addr[0], ha->hw.mac_addr[1],
827 // ha->hw.mac_addr[2], ha->hw.mac_addr[3],
828 // ha->hw.mac_addr[4], ha->hw.mac_addr[5]);
834 * Stop/Start/Initialization Handling
838 qla_tmplt_16bit_checksum(qla_host_t *ha, uint16_t *buf, uint32_t size)
841 uint32_t count = size >> 1; /* size in 16 bit words */
847 sum = (sum & 0xFFFF) + (sum >> 16);
853 qla_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
858 wr_l = (q8_wrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
860 for (i = 0; i < ce_hdr->opcount; i++, wr_l++) {
862 if (ql_rdwr_indreg32(ha, wr_l->addr, &wr_l->value, 0)) {
863 device_printf(ha->pci_dev,
864 "%s: [0x%08x 0x%08x] error\n", __func__,
865 wr_l->addr, wr_l->value);
868 if (ce_hdr->delay_to) {
869 DELAY(ce_hdr->delay_to);
876 qla_rd_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
878 q8_rdwrl_e_t *rd_wr_l;
882 rd_wr_l = (q8_rdwrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
884 for (i = 0; i < ce_hdr->opcount; i++, rd_wr_l++) {
886 if (ql_rdwr_indreg32(ha, rd_wr_l->rd_addr, &data, 1)) {
887 device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
888 __func__, rd_wr_l->rd_addr);
893 if (ql_rdwr_indreg32(ha, rd_wr_l->wr_addr, &data, 0)) {
894 device_printf(ha->pci_dev,
895 "%s: [0x%08x 0x%08x] error\n", __func__,
896 rd_wr_l->wr_addr, data);
899 if (ce_hdr->delay_to) {
900 DELAY(ce_hdr->delay_to);
907 qla_poll_reg(qla_host_t *ha, uint32_t addr, uint32_t ms_to, uint32_t tmask,
914 if (ql_rdwr_indreg32(ha, addr, &data, 1)) {
915 device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
920 if ((data & tmask) != tvalue) {
925 qla_mdelay(__func__, 1);
927 return ((ms_to ? 0: -1));
931 qla_poll_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
938 phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
939 pe = (q8_poll_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
941 for (i = 0; i < ce_hdr->opcount; i++, pe++) {
942 if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
943 device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
948 if (ce_hdr->delay_to) {
949 if ((data & phdr->tmask) == phdr->tvalue)
951 if (qla_poll_reg(ha, pe->addr, ce_hdr->delay_to,
952 phdr->tmask, phdr->tvalue)) {
954 if (ql_rdwr_indreg32(ha, pe->to_addr, &data,
956 device_printf(ha->pci_dev,
957 "%s: [0x%08x] error\n",
958 __func__, pe->to_addr);
962 if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
963 device_printf(ha->pci_dev,
964 "%s: [0x%08x] error\n",
975 qla_poll_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
979 q8_poll_wr_e_t *wr_e;
981 phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
982 wr_e = (q8_poll_wr_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
984 for (i = 0; i < ce_hdr->opcount; i++, wr_e++) {
986 if (ql_rdwr_indreg32(ha, wr_e->dr_addr, &wr_e->dr_value, 0)) {
987 device_printf(ha->pci_dev,
988 "%s: [0x%08x 0x%08x] error\n", __func__,
989 wr_e->dr_addr, wr_e->dr_value);
992 if (ql_rdwr_indreg32(ha, wr_e->ar_addr, &wr_e->ar_value, 0)) {
993 device_printf(ha->pci_dev,
994 "%s: [0x%08x 0x%08x] error\n", __func__,
995 wr_e->ar_addr, wr_e->ar_value);
998 if (ce_hdr->delay_to) {
999 if (qla_poll_reg(ha, wr_e->ar_addr, ce_hdr->delay_to,
1000 phdr->tmask, phdr->tvalue))
1001 device_printf(ha->pci_dev, "%s: "
1002 "[ar_addr, ar_value, delay, tmask,"
1003 "tvalue] [0x%08x 0x%08x 0x%08x 0x%08x"
1005 __func__, wr_e->ar_addr, wr_e->ar_value,
1006 ce_hdr->delay_to, phdr->tmask,
1014 qla_poll_read_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
1017 q8_poll_hdr_t *phdr;
1018 q8_poll_rd_e_t *rd_e;
1021 phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
1022 rd_e = (q8_poll_rd_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
1024 for (i = 0; i < ce_hdr->opcount; i++, rd_e++) {
1025 if (ql_rdwr_indreg32(ha, rd_e->ar_addr, &rd_e->ar_value, 0)) {
1026 device_printf(ha->pci_dev,
1027 "%s: [0x%08x 0x%08x] error\n", __func__,
1028 rd_e->ar_addr, rd_e->ar_value);
1032 if (ce_hdr->delay_to) {
1033 if (qla_poll_reg(ha, rd_e->ar_addr, ce_hdr->delay_to,
1034 phdr->tmask, phdr->tvalue)) {
1037 if (ql_rdwr_indreg32(ha, rd_e->dr_addr,
1039 device_printf(ha->pci_dev,
1040 "%s: [0x%08x] error\n",
1041 __func__, rd_e->ar_addr);
1045 ha->hw.rst_seq[ha->hw.rst_seq_idx++] = value;
1046 if (ha->hw.rst_seq_idx == Q8_MAX_RESET_SEQ_IDX)
1047 ha->hw.rst_seq_idx = 1;
1055 qla_rdmwr(qla_host_t *ha, uint32_t raddr, uint32_t waddr, q8_rdmwr_hdr_t *hdr)
1059 if (hdr->index_a >= Q8_MAX_RESET_SEQ_IDX) {
1060 device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
1066 value = ha->hw.rst_seq[hdr->index_a];
1068 if (ql_rdwr_indreg32(ha, raddr, &value, 1)) {
1069 device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
1075 value &= hdr->and_value;
1078 value |= hdr->or_value;
1079 value ^= hdr->xor_value;
1081 if (ql_rdwr_indreg32(ha, waddr, &value, 0)) {
1082 device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
1090 qla_read_modify_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
1093 q8_rdmwr_hdr_t *rdmwr_hdr;
1094 q8_rdmwr_e_t *rdmwr_e;
1096 rdmwr_hdr = (q8_rdmwr_hdr_t *)((uint8_t *)ce_hdr +
1097 sizeof (q8_ce_hdr_t));
1098 rdmwr_e = (q8_rdmwr_e_t *)((uint8_t *)rdmwr_hdr +
1099 sizeof(q8_rdmwr_hdr_t));
1101 for (i = 0; i < ce_hdr->opcount; i++, rdmwr_e++) {
1103 if (qla_rdmwr(ha, rdmwr_e->rd_addr, rdmwr_e->wr_addr,
1107 if (ce_hdr->delay_to) {
1108 DELAY(ce_hdr->delay_to);
1115 qla_tmplt_execute(qla_host_t *ha, uint8_t *buf, int start_idx, int *end_idx,
1118 int i, ret = 0, proc_end = 0;
1119 q8_ce_hdr_t *ce_hdr;
1121 for (i = start_idx; ((i < nentries) && (!proc_end)); i++) {
1122 ce_hdr = (q8_ce_hdr_t *)buf;
1125 switch (ce_hdr->opcode) {
1126 case Q8_CE_OPCODE_NOP:
1129 case Q8_CE_OPCODE_WRITE_LIST:
1130 ret = qla_wr_list(ha, ce_hdr);
1131 //printf("qla_wr_list %d\n", ret);
1134 case Q8_CE_OPCODE_READ_WRITE_LIST:
1135 ret = qla_rd_wr_list(ha, ce_hdr);
1136 //printf("qla_rd_wr_list %d\n", ret);
1139 case Q8_CE_OPCODE_POLL_LIST:
1140 ret = qla_poll_list(ha, ce_hdr);
1141 //printf("qla_poll_list %d\n", ret);
1144 case Q8_CE_OPCODE_POLL_WRITE_LIST:
1145 ret = qla_poll_write_list(ha, ce_hdr);
1146 //printf("qla_poll_write_list %d\n", ret);
1149 case Q8_CE_OPCODE_POLL_RD_LIST:
1150 ret = qla_poll_read_list(ha, ce_hdr);
1151 //printf("qla_poll_read_list %d\n", ret);
1154 case Q8_CE_OPCODE_READ_MODIFY_WRITE:
1155 ret = qla_read_modify_write_list(ha, ce_hdr);
1156 //printf("qla_read_modify_write_list %d\n", ret);
1159 case Q8_CE_OPCODE_SEQ_PAUSE:
1160 if (ce_hdr->delay_to) {
1161 qla_mdelay(__func__, ce_hdr->delay_to);
1165 case Q8_CE_OPCODE_SEQ_END:
1169 case Q8_CE_OPCODE_TMPLT_END:
1177 buf += ce_hdr->size;
1184 #ifndef QL_LDFLASH_FW
1186 qla_load_offchip_mem(qla_host_t *ha, uint64_t addr, uint32_t *data32,
1189 q80_offchip_mem_val_t val;
1194 val.data_lo = *data32++;
1195 val.data_hi = *data32++;
1196 val.data_ulo = *data32++;
1197 val.data_uhi = *data32++;
1199 if (ql_rdwr_offchip_mem(ha, addr, &val, 0))
1202 addr += (uint64_t)16;
1208 bzero(&val, sizeof(q80_offchip_mem_val_t));
1212 val.data_lo = *data32++;
1213 val.data_hi = *data32++;
1214 val.data_ulo = *data32++;
1215 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1219 val.data_lo = *data32++;
1220 val.data_hi = *data32++;
1221 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1225 val.data_lo = *data32++;
1226 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1238 qla_load_bootldr(qla_host_t *ha)
1245 addr = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
1246 data32 = (uint32_t *)ql83xx_bootloader;
1247 len32 = ql83xx_bootloader_len >> 2;
1249 ret = qla_load_offchip_mem(ha, addr, data32, len32);
1255 qla_load_fwimage(qla_host_t *ha)
1262 addr = (uint64_t)(READ_REG32(ha, Q8_FW_IMAGE_ADDR));
1263 data32 = (uint32_t *)ql83xx_firmware;
1264 len32 = ql83xx_firmware_len >> 2;
1266 ret = qla_load_offchip_mem(ha, addr, data32, len32);
1270 #endif /* #ifndef QL_LDFLASH_FW */
1273 qla_ld_fw_init(qla_host_t *ha)
1276 uint32_t index = 0, end_idx;
1277 q8_tmplt_hdr_t *hdr;
1279 bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1281 hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1283 if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1284 (uint32_t)hdr->size)) {
1285 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1291 buf = ql83xx_resetseq + hdr->stop_seq_off;
1293 // device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
1294 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1295 device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
1301 buf = ql83xx_resetseq + hdr->init_seq_off;
1303 // device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
1304 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1305 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1309 #ifdef QL_LDFLASH_FW
1310 qla_load_fw_from_flash(ha);
1311 WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
1313 if (qla_load_bootldr(ha))
1316 if (qla_load_fwimage(ha))
1319 WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
1320 #endif /* #ifdef QL_LDFLASH_FW */
1323 buf = ql83xx_resetseq + hdr->start_seq_off;
1325 // device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
1326 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1327 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1335 ql_stop_sequence(qla_host_t *ha)
1338 uint32_t index = 0, end_idx;
1339 q8_tmplt_hdr_t *hdr;
1341 bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1343 hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1345 if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1346 (uint32_t)hdr->size)) {
1347 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1352 buf = ql83xx_resetseq + hdr->stop_seq_off;
1354 device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
1355 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1356 device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
1364 ql_start_sequence(qla_host_t *ha, uint16_t index)
1368 q8_tmplt_hdr_t *hdr;
1370 bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1372 hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1374 if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1375 (uint32_t)hdr->size)) {
1376 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1381 buf = ql83xx_resetseq + hdr->init_seq_off;
1383 device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
1384 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1385 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1389 #ifdef QL_LDFLASH_FW
1390 qla_load_fw_from_flash(ha);
1391 WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
1393 if (qla_load_bootldr(ha))
1396 if (qla_load_fwimage(ha))
1399 WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
1400 #endif /* #ifdef QL_LDFLASH_FW */
1404 buf = ql83xx_resetseq + hdr->start_seq_off;
1406 device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
1407 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1408 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);