2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2013-2016 Qlogic Corporation
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
31 * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
40 #include "ql_inline.h"
45 #define QL_FDT_OFFSET 0x3F0000
46 #define Q8_FLASH_SECTOR_SIZE 0x10000
48 static int qla_ld_fw_init(qla_host_t *ha);
51 * structure encapsulating the value to read/write to offchip memory
53 typedef struct _offchip_mem_val {
61 * Name: ql_rdwr_indreg32
62 * Function: Read/Write an Indirect Register
65 ql_rdwr_indreg32(qla_host_t *ha, uint32_t addr, uint32_t *val, uint32_t rd)
70 wnd_reg = (Q8_CRB_WINDOW_PF0 | (ha->pci_func << 2));
72 WRITE_REG32(ha, wnd_reg, addr);
75 if (READ_REG32(ha, wnd_reg) == addr)
77 qla_mdelay(__func__, 1);
79 if (!count || QL_ERR_INJECT(ha, INJCT_RDWR_INDREG_FAILURE)) {
80 device_printf(ha->pci_dev, "%s: [0x%08x, 0x%08x, %d] failed\n",
81 __func__, addr, *val, rd);
82 ha->qla_initiate_recovery = 1;
87 *val = READ_REG32(ha, Q8_WILD_CARD);
89 WRITE_REG32(ha, Q8_WILD_CARD, *val);
96 * Name: ql_rdwr_offchip_mem
97 * Function: Read/Write OffChip Memory
100 ql_rdwr_offchip_mem(qla_host_t *ha, uint64_t addr, q80_offchip_mem_val_t *val,
103 uint32_t count = 100;
104 uint32_t data, step = 0;
107 if (QL_ERR_INJECT(ha, INJCT_RDWR_OFFCHIPMEM_FAILURE))
108 goto exit_ql_rdwr_offchip_mem;
110 data = (uint32_t)addr;
111 if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_LO, &data, 0)) {
113 goto exit_ql_rdwr_offchip_mem;
116 data = (uint32_t)(addr >> 32);
117 if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_HI, &data, 0)) {
119 goto exit_ql_rdwr_offchip_mem;
123 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
125 goto exit_ql_rdwr_offchip_mem;
130 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_0_31, &data, 0)) {
132 goto exit_ql_rdwr_offchip_mem;
136 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_32_63, &data, 0)) {
138 goto exit_ql_rdwr_offchip_mem;
141 data = val->data_ulo;
142 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_64_95, &data, 0)) {
144 goto exit_ql_rdwr_offchip_mem;
147 data = val->data_uhi;
148 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_96_127, &data, 0)) {
150 goto exit_ql_rdwr_offchip_mem;
153 data = (BIT_2|BIT_1|BIT_0);
154 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
156 goto exit_ql_rdwr_offchip_mem;
159 data = (BIT_1|BIT_0);
160 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
162 goto exit_ql_rdwr_offchip_mem;
167 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 1)) {
169 goto exit_ql_rdwr_offchip_mem;
172 if (!(data & BIT_3)) {
174 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_0_31,
177 goto exit_ql_rdwr_offchip_mem;
181 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_32_63,
184 goto exit_ql_rdwr_offchip_mem;
188 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_64_95,
191 goto exit_ql_rdwr_offchip_mem;
193 val->data_ulo = data;
195 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_96_127,
198 goto exit_ql_rdwr_offchip_mem;
200 val->data_uhi = data;
204 qla_mdelay(__func__, 1);
207 exit_ql_rdwr_offchip_mem:
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);
215 ha->qla_initiate_recovery = 1;
221 * Name: ql_rd_flash32
222 * Function: Read Flash Memory
225 ql_rd_flash32(qla_host_t *ha, uint32_t addr, uint32_t *data)
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",
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",
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",
253 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
258 qla_get_fdt(qla_host_t *ha)
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",
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",
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",
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",
308 qla_mdelay(__func__, 1);
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",
324 } while ((count < 10000) && (data32 != 0x6));
327 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
328 device_printf(ha->pci_dev,
329 "%s: Poll Q8_FLASH_STATUS failed\n",
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",
342 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
344 data32 &= Q8_FDT_MASK_VAL;
345 if (hw->fdt.flash_manuf == data32)
352 qla_flash_write_enable(qla_host_t *ha, int enable)
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",
366 data32 = ha->hw.fdt.write_enable_bits;
368 data32 = ha->hw.fdt.write_disable_bits;
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",
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",
390 qla_mdelay(__func__, 1);
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",
404 } while ((count < 10000) && (data32 != 0x6));
407 device_printf(ha->pci_dev,
408 "%s: Poll Q8_FLASH_STATUS failed\n",
417 qla_erase_flash_sector(qla_host_t *ha, uint32_t start)
423 qla_mdelay(__func__, 1);
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",
435 } while (((count++) < 1000) && (data32 != 0x6));
438 device_printf(ha->pci_dev,
439 "%s: Poll Q8_FLASH_STATUS failed\n",
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",
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",
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",
470 qla_mdelay(__func__, 1);
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",
482 } while (((count++) < 1000) && (data32 != 0x6));
485 device_printf(ha->pci_dev,
486 "%s: Poll Q8_FLASH_STATUS failed\n",
495 ql_erase_flash(qla_host_t *ha, uint32_t off, uint32_t size)
500 if (off & (Q8_FLASH_SECTOR_SIZE -1))
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",
510 if (qla_flash_write_enable(ha, 1) != 0) {
512 goto ql_erase_flash_exit;
515 for (start = off; start < (off + size); start = start +
516 Q8_FLASH_SECTOR_SIZE) {
517 if (qla_erase_flash_sector(ha, start)) {
523 rval = qla_flash_write_enable(ha, 0);
526 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
531 qla_wr_flash32(qla_host_t *ha, uint32_t off, uint32_t *data)
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",
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",
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",
564 qla_mdelay(__func__, 1);
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",
578 } while ((count < 10000) && (data32 != 0x6));
581 device_printf(ha->pci_dev,
582 "%s: Poll Q8_FLASH_STATUS failed\n",
591 qla_flash_write_data(qla_host_t *ha, uint32_t off, uint32_t size,
596 uint32_t *data32 = data;
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",
603 goto qla_flash_write_data_exit;
606 if ((qla_flash_write_enable(ha, 1) != 0)) {
607 device_printf(ha->pci_dev, "%s: failed\n",
610 goto qla_flash_write_data_unlock_exit;
613 for (start = off; start < (off + size); start = start + 4) {
614 if (*data32 != 0xFFFFFFFF) {
615 if (qla_wr_flash32(ha, start, data32)) {
623 rval = qla_flash_write_enable(ha, 0);
625 qla_flash_write_data_unlock_exit:
626 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
628 qla_flash_write_data_exit:
633 ql_wr_flash_buffer(qla_host_t *ha, uint32_t off, uint32_t size, void *buf)
646 if ((data = malloc(size, M_QLA83XXBUF, M_NOWAIT)) == NULL) {
647 device_printf(ha->pci_dev, "%s: malloc failed \n", __func__);
649 goto ql_wr_flash_buffer_exit;
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;
657 rval = qla_flash_write_data(ha, off, size, data);
659 ql_wr_flash_buffer_free_exit:
660 free(data, M_QLA83XXBUF);
662 ql_wr_flash_buffer_exit:
668 * Name: qla_load_fw_from_flash
669 * Function: Reads the Bootloader from Flash and Loads into Offchip Memory
672 qla_load_fw_from_flash(qla_host_t *ha)
674 uint32_t flash_off = 0x10000;
676 uint32_t count, mem_size;
677 q80_offchip_mem_val_t val;
679 mem_off = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
680 mem_size = READ_REG32(ha, Q8_BOOTLD_SIZE);
682 device_printf(ha->pci_dev, "%s: [0x%08x][0x%08x]\n",
683 __func__, (uint32_t)mem_off, mem_size);
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);
689 flash_off = flash_off + 4;
691 ql_rd_flash32(ha, flash_off, &val.data_hi);
693 flash_off = flash_off + 4;
695 ql_rd_flash32(ha, flash_off, &val.data_ulo);
697 flash_off = flash_off + 4;
699 ql_rd_flash32(ha, flash_off, &val.data_uhi);
701 flash_off = flash_off + 4;
703 ql_rdwr_offchip_mem(ha, mem_off, &val, 0);
705 mem_off = mem_off + 16;
710 #endif /* #ifdef QL_LDFLASH_FW */
713 * Name: qla_init_from_flash
714 * Function: Performs Initialization which consists of the following sequence
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.
723 qla_init_from_flash(qla_host_t *ha)
725 uint32_t delay = 300;
731 data = READ_REG32(ha, Q8_CMDPEG_STATE);
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));
742 qla_mdelay(__func__, 100);
750 * Function: Initializes P3+ hardware.
753 ql_init_hw(qla_host_t *ha)
757 uint32_t val, delay = 300;
761 QL_DPRINT1(ha, (dev, "%s: enter\n", __func__));
763 if (ha->pci_func & 0x1) {
765 while ((ha->pci_func & 0x1) && delay--) {
767 val = READ_REG32(ha, Q8_CMDPEG_STATE);
771 "%s: func = %d init complete\n",
772 __func__, ha->pci_func));
773 qla_mdelay(__func__, 100);
776 qla_mdelay(__func__, 100);
782 val = READ_REG32(ha, Q8_CMDPEG_STATE);
783 if (!cold || (val != 0xFF01)) {
784 ret = qla_init_from_flash(ha);
785 qla_mdelay(__func__, 100);
789 ha->fw_ver_major = READ_REG32(ha, Q8_FW_VER_MAJOR);
790 ha->fw_ver_minor = READ_REG32(ha, Q8_FW_VER_MINOR);
791 ha->fw_ver_sub = READ_REG32(ha, Q8_FW_VER_SUB);
793 if (qla_get_fdt(ha) != 0) {
794 device_printf(dev, "%s: qla_get_fdt failed\n", __func__);
796 ha->hw.flags.fdt_valid = 1;
803 ql_read_mac_addr(qla_host_t *ha)
810 flash_off = Q8_BOARD_CONFIG_OFFSET + Q8_BOARD_CONFIG_MAC0_LO +
812 ql_rd_flash32(ha, flash_off, &mac_lo);
815 ql_rd_flash32(ha, flash_off, &mac_hi);
817 macp = (uint8_t *)&mac_lo;
818 ha->hw.mac_addr[5] = macp[0];
819 ha->hw.mac_addr[4] = macp[1];
820 ha->hw.mac_addr[3] = macp[2];
821 ha->hw.mac_addr[2] = macp[3];
823 macp = (uint8_t *)&mac_hi;
824 ha->hw.mac_addr[1] = macp[0];
825 ha->hw.mac_addr[0] = macp[1];
827 //device_printf(ha->pci_dev, "%s: %02x:%02x:%02x:%02x:%02x:%02x\n",
828 // __func__, ha->hw.mac_addr[0], ha->hw.mac_addr[1],
829 // ha->hw.mac_addr[2], ha->hw.mac_addr[3],
830 // ha->hw.mac_addr[4], ha->hw.mac_addr[5]);
836 * Stop/Start/Initialization Handling
840 qla_tmplt_16bit_checksum(qla_host_t *ha, uint16_t *buf, uint32_t size)
843 uint32_t count = size >> 1; /* size in 16 bit words */
849 sum = (sum & 0xFFFF) + (sum >> 16);
855 qla_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
860 wr_l = (q8_wrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
862 for (i = 0; i < ce_hdr->opcount; i++, wr_l++) {
864 if (ql_rdwr_indreg32(ha, wr_l->addr, &wr_l->value, 0)) {
865 device_printf(ha->pci_dev,
866 "%s: [0x%08x 0x%08x] error\n", __func__,
867 wr_l->addr, wr_l->value);
870 if (ce_hdr->delay_to) {
871 DELAY(ce_hdr->delay_to);
878 qla_rd_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
880 q8_rdwrl_e_t *rd_wr_l;
884 rd_wr_l = (q8_rdwrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
886 for (i = 0; i < ce_hdr->opcount; i++, rd_wr_l++) {
888 if (ql_rdwr_indreg32(ha, rd_wr_l->rd_addr, &data, 1)) {
889 device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
890 __func__, rd_wr_l->rd_addr);
895 if (ql_rdwr_indreg32(ha, rd_wr_l->wr_addr, &data, 0)) {
896 device_printf(ha->pci_dev,
897 "%s: [0x%08x 0x%08x] error\n", __func__,
898 rd_wr_l->wr_addr, data);
901 if (ce_hdr->delay_to) {
902 DELAY(ce_hdr->delay_to);
909 qla_poll_reg(qla_host_t *ha, uint32_t addr, uint32_t ms_to, uint32_t tmask,
916 if (ql_rdwr_indreg32(ha, addr, &data, 1)) {
917 device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
922 if ((data & tmask) != tvalue) {
927 qla_mdelay(__func__, 1);
929 return ((ms_to ? 0: -1));
933 qla_poll_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
940 phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
941 pe = (q8_poll_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
943 for (i = 0; i < ce_hdr->opcount; i++, pe++) {
944 if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
945 device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
950 if (ce_hdr->delay_to) {
951 if ((data & phdr->tmask) == phdr->tvalue)
953 if (qla_poll_reg(ha, pe->addr, ce_hdr->delay_to,
954 phdr->tmask, phdr->tvalue)) {
956 if (ql_rdwr_indreg32(ha, pe->to_addr, &data,
958 device_printf(ha->pci_dev,
959 "%s: [0x%08x] error\n",
960 __func__, pe->to_addr);
964 if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
965 device_printf(ha->pci_dev,
966 "%s: [0x%08x] error\n",
977 qla_poll_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
981 q8_poll_wr_e_t *wr_e;
983 phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
984 wr_e = (q8_poll_wr_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
986 for (i = 0; i < ce_hdr->opcount; i++, wr_e++) {
988 if (ql_rdwr_indreg32(ha, wr_e->dr_addr, &wr_e->dr_value, 0)) {
989 device_printf(ha->pci_dev,
990 "%s: [0x%08x 0x%08x] error\n", __func__,
991 wr_e->dr_addr, wr_e->dr_value);
994 if (ql_rdwr_indreg32(ha, wr_e->ar_addr, &wr_e->ar_value, 0)) {
995 device_printf(ha->pci_dev,
996 "%s: [0x%08x 0x%08x] error\n", __func__,
997 wr_e->ar_addr, wr_e->ar_value);
1000 if (ce_hdr->delay_to) {
1001 if (qla_poll_reg(ha, wr_e->ar_addr, ce_hdr->delay_to,
1002 phdr->tmask, phdr->tvalue))
1003 device_printf(ha->pci_dev, "%s: "
1004 "[ar_addr, ar_value, delay, tmask,"
1005 "tvalue] [0x%08x 0x%08x 0x%08x 0x%08x"
1007 __func__, wr_e->ar_addr, wr_e->ar_value,
1008 ce_hdr->delay_to, phdr->tmask,
1016 qla_poll_read_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
1019 q8_poll_hdr_t *phdr;
1020 q8_poll_rd_e_t *rd_e;
1023 phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
1024 rd_e = (q8_poll_rd_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
1026 for (i = 0; i < ce_hdr->opcount; i++, rd_e++) {
1027 if (ql_rdwr_indreg32(ha, rd_e->ar_addr, &rd_e->ar_value, 0)) {
1028 device_printf(ha->pci_dev,
1029 "%s: [0x%08x 0x%08x] error\n", __func__,
1030 rd_e->ar_addr, rd_e->ar_value);
1034 if (ce_hdr->delay_to) {
1035 if (qla_poll_reg(ha, rd_e->ar_addr, ce_hdr->delay_to,
1036 phdr->tmask, phdr->tvalue)) {
1039 if (ql_rdwr_indreg32(ha, rd_e->dr_addr,
1041 device_printf(ha->pci_dev,
1042 "%s: [0x%08x] error\n",
1043 __func__, rd_e->ar_addr);
1047 ha->hw.rst_seq[ha->hw.rst_seq_idx++] = value;
1048 if (ha->hw.rst_seq_idx == Q8_MAX_RESET_SEQ_IDX)
1049 ha->hw.rst_seq_idx = 1;
1057 qla_rdmwr(qla_host_t *ha, uint32_t raddr, uint32_t waddr, q8_rdmwr_hdr_t *hdr)
1061 if (hdr->index_a >= Q8_MAX_RESET_SEQ_IDX) {
1062 device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
1068 value = ha->hw.rst_seq[hdr->index_a];
1070 if (ql_rdwr_indreg32(ha, raddr, &value, 1)) {
1071 device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
1077 value &= hdr->and_value;
1080 value |= hdr->or_value;
1081 value ^= hdr->xor_value;
1083 if (ql_rdwr_indreg32(ha, waddr, &value, 0)) {
1084 device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
1092 qla_read_modify_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
1095 q8_rdmwr_hdr_t *rdmwr_hdr;
1096 q8_rdmwr_e_t *rdmwr_e;
1098 rdmwr_hdr = (q8_rdmwr_hdr_t *)((uint8_t *)ce_hdr +
1099 sizeof (q8_ce_hdr_t));
1100 rdmwr_e = (q8_rdmwr_e_t *)((uint8_t *)rdmwr_hdr +
1101 sizeof(q8_rdmwr_hdr_t));
1103 for (i = 0; i < ce_hdr->opcount; i++, rdmwr_e++) {
1105 if (qla_rdmwr(ha, rdmwr_e->rd_addr, rdmwr_e->wr_addr,
1109 if (ce_hdr->delay_to) {
1110 DELAY(ce_hdr->delay_to);
1117 qla_tmplt_execute(qla_host_t *ha, uint8_t *buf, int start_idx, int *end_idx,
1120 int i, ret = 0, proc_end = 0;
1121 q8_ce_hdr_t *ce_hdr;
1123 for (i = start_idx; ((i < nentries) && (!proc_end)); i++) {
1124 ce_hdr = (q8_ce_hdr_t *)buf;
1127 switch (ce_hdr->opcode) {
1128 case Q8_CE_OPCODE_NOP:
1131 case Q8_CE_OPCODE_WRITE_LIST:
1132 ret = qla_wr_list(ha, ce_hdr);
1133 //printf("qla_wr_list %d\n", ret);
1136 case Q8_CE_OPCODE_READ_WRITE_LIST:
1137 ret = qla_rd_wr_list(ha, ce_hdr);
1138 //printf("qla_rd_wr_list %d\n", ret);
1141 case Q8_CE_OPCODE_POLL_LIST:
1142 ret = qla_poll_list(ha, ce_hdr);
1143 //printf("qla_poll_list %d\n", ret);
1146 case Q8_CE_OPCODE_POLL_WRITE_LIST:
1147 ret = qla_poll_write_list(ha, ce_hdr);
1148 //printf("qla_poll_write_list %d\n", ret);
1151 case Q8_CE_OPCODE_POLL_RD_LIST:
1152 ret = qla_poll_read_list(ha, ce_hdr);
1153 //printf("qla_poll_read_list %d\n", ret);
1156 case Q8_CE_OPCODE_READ_MODIFY_WRITE:
1157 ret = qla_read_modify_write_list(ha, ce_hdr);
1158 //printf("qla_read_modify_write_list %d\n", ret);
1161 case Q8_CE_OPCODE_SEQ_PAUSE:
1162 if (ce_hdr->delay_to) {
1163 qla_mdelay(__func__, ce_hdr->delay_to);
1167 case Q8_CE_OPCODE_SEQ_END:
1171 case Q8_CE_OPCODE_TMPLT_END:
1179 buf += ce_hdr->size;
1186 #ifndef QL_LDFLASH_FW
1188 qla_load_offchip_mem(qla_host_t *ha, uint64_t addr, uint32_t *data32,
1191 q80_offchip_mem_val_t val;
1196 val.data_lo = *data32++;
1197 val.data_hi = *data32++;
1198 val.data_ulo = *data32++;
1199 val.data_uhi = *data32++;
1201 if (ql_rdwr_offchip_mem(ha, addr, &val, 0))
1204 addr += (uint64_t)16;
1210 bzero(&val, sizeof(q80_offchip_mem_val_t));
1214 val.data_lo = *data32++;
1215 val.data_hi = *data32++;
1216 val.data_ulo = *data32++;
1217 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1221 val.data_lo = *data32++;
1222 val.data_hi = *data32++;
1223 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1227 val.data_lo = *data32++;
1228 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
1240 qla_load_bootldr(qla_host_t *ha)
1247 addr = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
1248 data32 = (uint32_t *)ql83xx_bootloader;
1249 len32 = ql83xx_bootloader_len >> 2;
1251 ret = qla_load_offchip_mem(ha, addr, data32, len32);
1257 qla_load_fwimage(qla_host_t *ha)
1264 addr = (uint64_t)(READ_REG32(ha, Q8_FW_IMAGE_ADDR));
1265 data32 = (uint32_t *)ql83xx_firmware;
1266 len32 = ql83xx_firmware_len >> 2;
1268 ret = qla_load_offchip_mem(ha, addr, data32, len32);
1272 #endif /* #ifndef QL_LDFLASH_FW */
1275 qla_ld_fw_init(qla_host_t *ha)
1278 uint32_t index = 0, end_idx;
1279 q8_tmplt_hdr_t *hdr;
1281 bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1283 hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1285 if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1286 (uint32_t)hdr->size)) {
1287 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1293 buf = ql83xx_resetseq + hdr->stop_seq_off;
1295 // device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
1296 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1297 device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
1303 buf = ql83xx_resetseq + hdr->init_seq_off;
1305 // device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
1306 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1307 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1311 #ifdef QL_LDFLASH_FW
1312 qla_load_fw_from_flash(ha);
1313 WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
1315 if (qla_load_bootldr(ha))
1318 if (qla_load_fwimage(ha))
1321 WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
1322 #endif /* #ifdef QL_LDFLASH_FW */
1325 buf = ql83xx_resetseq + hdr->start_seq_off;
1327 // device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
1328 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1329 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1337 ql_stop_sequence(qla_host_t *ha)
1340 uint32_t index = 0, end_idx;
1341 q8_tmplt_hdr_t *hdr;
1343 bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1345 hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1347 if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1348 (uint32_t)hdr->size)) {
1349 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1354 buf = ql83xx_resetseq + hdr->stop_seq_off;
1356 device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
1357 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1358 device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
1366 ql_start_sequence(qla_host_t *ha, uint16_t index)
1370 q8_tmplt_hdr_t *hdr;
1372 bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
1374 hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
1376 if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
1377 (uint32_t)hdr->size)) {
1378 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
1383 buf = ql83xx_resetseq + hdr->init_seq_off;
1385 device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
1386 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1387 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
1391 #ifdef QL_LDFLASH_FW
1392 qla_load_fw_from_flash(ha);
1393 WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
1395 if (qla_load_bootldr(ha))
1398 if (qla_load_fwimage(ha))
1401 WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
1402 #endif /* #ifdef QL_LDFLASH_FW */
1406 buf = ql83xx_resetseq + hdr->start_seq_off;
1408 device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
1409 if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
1410 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);