1250661Sdavidcs/* 2284982Sdavidcs * Copyright (c) 2013-2016 Qlogic Corporation 3250661Sdavidcs * All rights reserved. 4250661Sdavidcs * 5250661Sdavidcs * Redistribution and use in source and binary forms, with or without 6250661Sdavidcs * modification, are permitted provided that the following conditions 7250661Sdavidcs * are met: 8250661Sdavidcs * 9250661Sdavidcs * 1. Redistributions of source code must retain the above copyright 10250661Sdavidcs * notice, this list of conditions and the following disclaimer. 11250661Sdavidcs * 2. Redistributions in binary form must reproduce the above copyright 12250661Sdavidcs * notice, this list of conditions and the following disclaimer in the 13250661Sdavidcs * documentation and/or other materials provided with the distribution. 14250661Sdavidcs * 15250661Sdavidcs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16250661Sdavidcs * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17250661Sdavidcs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18250661Sdavidcs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19250661Sdavidcs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20250661Sdavidcs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21250661Sdavidcs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22250661Sdavidcs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23250661Sdavidcs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24250661Sdavidcs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25250661Sdavidcs * POSSIBILITY OF SUCH DAMAGE. 26250661Sdavidcs */ 27250661Sdavidcs/* 28250661Sdavidcs * File : ql_misc.c 29250661Sdavidcs * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656. 30250661Sdavidcs */ 31250661Sdavidcs 32250661Sdavidcs#include <sys/cdefs.h> 33250661Sdavidcs__FBSDID("$FreeBSD: releng/10.3/sys/dev/qlxgbe/ql_misc.c 284982 2015-06-30 20:59:07Z davidcs $"); 34250661Sdavidcs 35250661Sdavidcs#include "ql_os.h" 36250661Sdavidcs#include "ql_hw.h" 37250661Sdavidcs#include "ql_def.h" 38250661Sdavidcs#include "ql_inline.h" 39250661Sdavidcs#include "ql_glbl.h" 40250661Sdavidcs#include "ql_dbg.h" 41250661Sdavidcs#include "ql_tmplt.h" 42250661Sdavidcs 43250661Sdavidcs#define QL_FDT_OFFSET 0x3F0000 44250661Sdavidcs#define Q8_FLASH_SECTOR_SIZE 0x10000 45250661Sdavidcs 46250661Sdavidcsstatic int qla_ld_fw_init(qla_host_t *ha); 47250661Sdavidcs 48250661Sdavidcs/* 49250661Sdavidcs * structure encapsulating the value to read/write to offchip memory 50250661Sdavidcs */ 51250661Sdavidcstypedef struct _offchip_mem_val { 52250661Sdavidcs uint32_t data_lo; 53250661Sdavidcs uint32_t data_hi; 54250661Sdavidcs uint32_t data_ulo; 55250661Sdavidcs uint32_t data_uhi; 56250661Sdavidcs} offchip_mem_val_t; 57250661Sdavidcs 58250661Sdavidcs/* 59250661Sdavidcs * Name: ql_rdwr_indreg32 60250661Sdavidcs * Function: Read/Write an Indirect Register 61250661Sdavidcs */ 62250661Sdavidcsint 63250661Sdavidcsql_rdwr_indreg32(qla_host_t *ha, uint32_t addr, uint32_t *val, uint32_t rd) 64250661Sdavidcs{ 65250661Sdavidcs uint32_t wnd_reg; 66250661Sdavidcs uint32_t count = 100; 67250661Sdavidcs 68250661Sdavidcs wnd_reg = (Q8_CRB_WINDOW_PF0 | (ha->pci_func << 2)); 69250661Sdavidcs 70250661Sdavidcs WRITE_REG32(ha, wnd_reg, addr); 71250661Sdavidcs 72250661Sdavidcs while (count--) { 73250661Sdavidcs if (READ_REG32(ha, wnd_reg) == addr) 74250661Sdavidcs break; 75250661Sdavidcs qla_mdelay(__func__, 1); 76250661Sdavidcs } 77250661Sdavidcs if (!count || QL_ERR_INJECT(ha, INJCT_RDWR_INDREG_FAILURE)) { 78250661Sdavidcs device_printf(ha->pci_dev, "%s: [0x%08x, 0x%08x, %d] failed\n", 79250661Sdavidcs __func__, addr, *val, rd); 80250661Sdavidcs ha->qla_initiate_recovery = 1; 81250661Sdavidcs return -1; 82250661Sdavidcs } 83250661Sdavidcs 84250661Sdavidcs if (rd) { 85250661Sdavidcs *val = READ_REG32(ha, Q8_WILD_CARD); 86250661Sdavidcs } else { 87250661Sdavidcs WRITE_REG32(ha, Q8_WILD_CARD, *val); 88250661Sdavidcs } 89250661Sdavidcs 90250661Sdavidcs return 0; 91250661Sdavidcs} 92250661Sdavidcs 93250661Sdavidcs/* 94250661Sdavidcs * Name: ql_rdwr_offchip_mem 95250661Sdavidcs * Function: Read/Write OffChip Memory 96250661Sdavidcs */ 97250661Sdavidcsint 98250661Sdavidcsql_rdwr_offchip_mem(qla_host_t *ha, uint64_t addr, q80_offchip_mem_val_t *val, 99250661Sdavidcs uint32_t rd) 100250661Sdavidcs{ 101250661Sdavidcs uint32_t count = 100; 102250661Sdavidcs uint32_t data, step = 0; 103250661Sdavidcs 104250661Sdavidcs 105250661Sdavidcs if (QL_ERR_INJECT(ha, INJCT_RDWR_OFFCHIPMEM_FAILURE)) 106250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 107250661Sdavidcs 108250661Sdavidcs data = (uint32_t)addr; 109250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_LO, &data, 0)) { 110250661Sdavidcs step = 1; 111250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 112250661Sdavidcs } 113250661Sdavidcs 114250661Sdavidcs data = (uint32_t)(addr >> 32); 115250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_HI, &data, 0)) { 116250661Sdavidcs step = 2; 117250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 118250661Sdavidcs } 119250661Sdavidcs 120250661Sdavidcs data = BIT_1; 121250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) { 122250661Sdavidcs step = 3; 123250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 124250661Sdavidcs } 125250661Sdavidcs 126250661Sdavidcs if (!rd) { 127250661Sdavidcs data = val->data_lo; 128250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_0_31, &data, 0)) { 129250661Sdavidcs step = 4; 130250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 131250661Sdavidcs } 132250661Sdavidcs 133250661Sdavidcs data = val->data_hi; 134250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_32_63, &data, 0)) { 135250661Sdavidcs step = 5; 136250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 137250661Sdavidcs } 138250661Sdavidcs 139250661Sdavidcs data = val->data_ulo; 140250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_64_95, &data, 0)) { 141250661Sdavidcs step = 6; 142250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 143250661Sdavidcs } 144250661Sdavidcs 145250661Sdavidcs data = val->data_uhi; 146250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_96_127, &data, 0)) { 147250661Sdavidcs step = 7; 148250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 149250661Sdavidcs } 150250661Sdavidcs 151250661Sdavidcs data = (BIT_2|BIT_1|BIT_0); 152250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) { 153250661Sdavidcs step = 7; 154250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 155250661Sdavidcs } 156250661Sdavidcs } else { 157250661Sdavidcs data = (BIT_1|BIT_0); 158250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) { 159250661Sdavidcs step = 8; 160250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 161250661Sdavidcs } 162250661Sdavidcs } 163250661Sdavidcs 164250661Sdavidcs while (count--) { 165250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 1)) { 166250661Sdavidcs step = 9; 167250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 168250661Sdavidcs } 169250661Sdavidcs 170250661Sdavidcs if (!(data & BIT_3)) { 171250661Sdavidcs if (rd) { 172250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_0_31, 173250661Sdavidcs &data, 1)) { 174250661Sdavidcs step = 10; 175250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 176250661Sdavidcs } 177250661Sdavidcs val->data_lo = data; 178250661Sdavidcs 179250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_32_63, 180250661Sdavidcs &data, 1)) { 181250661Sdavidcs step = 11; 182250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 183250661Sdavidcs } 184250661Sdavidcs val->data_hi = data; 185250661Sdavidcs 186250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_64_95, 187250661Sdavidcs &data, 1)) { 188250661Sdavidcs step = 12; 189250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 190250661Sdavidcs } 191250661Sdavidcs val->data_ulo = data; 192250661Sdavidcs 193250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_96_127, 194250661Sdavidcs &data, 1)) { 195250661Sdavidcs step = 13; 196250661Sdavidcs goto exit_ql_rdwr_offchip_mem; 197250661Sdavidcs } 198250661Sdavidcs val->data_uhi = data; 199250661Sdavidcs } 200250661Sdavidcs return 0; 201250661Sdavidcs } else 202250661Sdavidcs qla_mdelay(__func__, 1); 203250661Sdavidcs } 204250661Sdavidcs 205250661Sdavidcsexit_ql_rdwr_offchip_mem: 206250661Sdavidcs 207250661Sdavidcs device_printf(ha->pci_dev, 208250661Sdavidcs "%s: [0x%08x 0x%08x : 0x%08x 0x%08x 0x%08x 0x%08x]" 209250661Sdavidcs " [%d] [%d] failed\n", __func__, (uint32_t)(addr >> 32), 210250661Sdavidcs (uint32_t)(addr), val->data_lo, val->data_hi, val->data_ulo, 211250661Sdavidcs val->data_uhi, rd, step); 212250661Sdavidcs 213250661Sdavidcs ha->qla_initiate_recovery = 1; 214250661Sdavidcs 215250661Sdavidcs return (-1); 216250661Sdavidcs} 217250661Sdavidcs 218250661Sdavidcs/* 219250661Sdavidcs * Name: ql_rd_flash32 220250661Sdavidcs * Function: Read Flash Memory 221250661Sdavidcs */ 222250661Sdavidcsint 223250661Sdavidcsql_rd_flash32(qla_host_t *ha, uint32_t addr, uint32_t *data) 224250661Sdavidcs{ 225250661Sdavidcs uint32_t data32; 226250661Sdavidcs 227250661Sdavidcs if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID, 0xABCDABCD)) { 228250661Sdavidcs device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n", 229250661Sdavidcs __func__); 230250661Sdavidcs return (-1); 231250661Sdavidcs } 232250661Sdavidcs 233250661Sdavidcs data32 = addr; 234250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_DIRECT_WINDOW, &data32, 0)) { 235250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 236250661Sdavidcs device_printf(ha->pci_dev, 237250661Sdavidcs "%s: Q8_FLASH_DIRECT_WINDOW[0x%08x] failed\n", 238250661Sdavidcs __func__, data32); 239250661Sdavidcs return (-1); 240250661Sdavidcs } 241250661Sdavidcs 242250661Sdavidcs data32 = Q8_FLASH_DIRECT_DATA | (addr & 0xFFFF); 243250661Sdavidcs if (ql_rdwr_indreg32(ha, data32, data, 1)) { 244250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 245250661Sdavidcs device_printf(ha->pci_dev, 246250661Sdavidcs "%s: data32:data [0x%08x] failed\n", 247250661Sdavidcs __func__, data32); 248250661Sdavidcs return (-1); 249250661Sdavidcs } 250250661Sdavidcs 251250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 252250661Sdavidcs return 0; 253250661Sdavidcs} 254250661Sdavidcs 255250661Sdavidcsstatic int 256250661Sdavidcsqla_get_fdt(qla_host_t *ha) 257250661Sdavidcs{ 258250661Sdavidcs uint32_t data32; 259250661Sdavidcs int count; 260250661Sdavidcs qla_hw_t *hw; 261250661Sdavidcs 262250661Sdavidcs hw = &ha->hw; 263250661Sdavidcs 264250661Sdavidcs for (count = 0; count < sizeof(qla_flash_desc_table_t); count+=4) { 265250661Sdavidcs if (ql_rd_flash32(ha, QL_FDT_OFFSET + count, 266250661Sdavidcs (uint32_t *)&hw->fdt + (count >> 2))) { 267250661Sdavidcs device_printf(ha->pci_dev, 268250661Sdavidcs "%s: Read QL_FDT_OFFSET + %d failed\n", 269250661Sdavidcs __func__, count); 270250661Sdavidcs return (-1); 271250661Sdavidcs } 272250661Sdavidcs } 273250661Sdavidcs 274250661Sdavidcs if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID, 275250661Sdavidcs Q8_FDT_LOCK_MAGIC_ID)) { 276250661Sdavidcs device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n", 277250661Sdavidcs __func__); 278250661Sdavidcs return (-1); 279250661Sdavidcs } 280250661Sdavidcs 281250661Sdavidcs data32 = Q8_FDT_FLASH_ADDR_VAL; 282250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) { 283250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 284250661Sdavidcs device_printf(ha->pci_dev, 285250661Sdavidcs "%s: Write to Q8_FLASH_ADDRESS failed\n", 286250661Sdavidcs __func__); 287250661Sdavidcs return (-1); 288250661Sdavidcs } 289250661Sdavidcs 290250661Sdavidcs data32 = Q8_FDT_FLASH_CTRL_VAL; 291250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) { 292250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 293250661Sdavidcs device_printf(ha->pci_dev, 294250661Sdavidcs "%s: Write to Q8_FLASH_CONTROL failed\n", 295250661Sdavidcs __func__); 296250661Sdavidcs return (-1); 297250661Sdavidcs } 298250661Sdavidcs 299250661Sdavidcs count = 0; 300250661Sdavidcs 301250661Sdavidcs do { 302250661Sdavidcs if (count < 1000) { 303250661Sdavidcs QLA_USEC_DELAY(10); 304250661Sdavidcs count += 10; 305250661Sdavidcs } else { 306250661Sdavidcs qla_mdelay(__func__, 1); 307250661Sdavidcs count += 1000; 308250661Sdavidcs } 309250661Sdavidcs 310250661Sdavidcs data32 = 0; 311250661Sdavidcs 312250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) { 313250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 314250661Sdavidcs device_printf(ha->pci_dev, 315250661Sdavidcs "%s: Read Q8_FLASH_STATUS failed\n", 316250661Sdavidcs __func__); 317250661Sdavidcs return (-1); 318250661Sdavidcs } 319250661Sdavidcs 320250661Sdavidcs data32 &= 0x6; 321250661Sdavidcs 322250661Sdavidcs } while ((count < 10000) && (data32 != 0x6)); 323250661Sdavidcs 324254976Sdavidcs if (data32 != 0x6) { 325250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 326250661Sdavidcs device_printf(ha->pci_dev, 327250661Sdavidcs "%s: Poll Q8_FLASH_STATUS failed\n", 328250661Sdavidcs __func__); 329250661Sdavidcs return (-1); 330250661Sdavidcs } 331250661Sdavidcs 332250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_RD_DATA, &data32, 1)) { 333250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 334250661Sdavidcs device_printf(ha->pci_dev, 335250661Sdavidcs "%s: Read Q8_FLASH_RD_DATA failed\n", 336250661Sdavidcs __func__); 337250661Sdavidcs return (-1); 338250661Sdavidcs } 339250661Sdavidcs 340250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 341250661Sdavidcs 342250661Sdavidcs data32 &= Q8_FDT_MASK_VAL; 343250661Sdavidcs if (hw->fdt.flash_manuf == data32) 344250661Sdavidcs return (0); 345250661Sdavidcs else 346250661Sdavidcs return (-1); 347250661Sdavidcs} 348250661Sdavidcs 349250661Sdavidcsstatic int 350250661Sdavidcsqla_flash_write_enable(qla_host_t *ha, int enable) 351250661Sdavidcs{ 352250661Sdavidcs uint32_t data32; 353250661Sdavidcs int count = 0; 354250661Sdavidcs 355250661Sdavidcs data32 = Q8_WR_ENABLE_FL_ADDR | ha->hw.fdt.write_statusreg_cmd; 356250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) { 357250661Sdavidcs device_printf(ha->pci_dev, 358250661Sdavidcs "%s: Write to Q8_FLASH_ADDRESS failed\n", 359250661Sdavidcs __func__); 360250661Sdavidcs return (-1); 361250661Sdavidcs } 362250661Sdavidcs 363250661Sdavidcs if (enable) 364250661Sdavidcs data32 = ha->hw.fdt.write_enable_bits; 365250661Sdavidcs else 366250661Sdavidcs data32 = ha->hw.fdt.write_disable_bits; 367250661Sdavidcs 368250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, &data32, 0)) { 369250661Sdavidcs device_printf(ha->pci_dev, 370250661Sdavidcs "%s: Write to Q8_FLASH_WR_DATA failed\n", 371250661Sdavidcs __func__); 372250661Sdavidcs return (-1); 373250661Sdavidcs } 374250661Sdavidcs 375250661Sdavidcs data32 = Q8_WR_ENABLE_FL_CTRL; 376250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) { 377250661Sdavidcs device_printf(ha->pci_dev, 378250661Sdavidcs "%s: Write to Q8_FLASH_CONTROL failed\n", 379250661Sdavidcs __func__); 380250661Sdavidcs return (-1); 381250661Sdavidcs } 382250661Sdavidcs 383250661Sdavidcs do { 384250661Sdavidcs if (count < 1000) { 385250661Sdavidcs QLA_USEC_DELAY(10); 386250661Sdavidcs count += 10; 387250661Sdavidcs } else { 388250661Sdavidcs qla_mdelay(__func__, 1); 389250661Sdavidcs count += 1000; 390250661Sdavidcs } 391250661Sdavidcs 392250661Sdavidcs data32 = 0; 393250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) { 394250661Sdavidcs device_printf(ha->pci_dev, 395250661Sdavidcs "%s: Read Q8_FLASH_STATUS failed\n", 396250661Sdavidcs __func__); 397250661Sdavidcs return (-1); 398250661Sdavidcs } 399250661Sdavidcs 400250661Sdavidcs data32 &= 0x6; 401250661Sdavidcs 402250661Sdavidcs } while ((count < 10000) && (data32 != 0x6)); 403250661Sdavidcs 404254976Sdavidcs if (data32 != 0x6) { 405250661Sdavidcs device_printf(ha->pci_dev, 406250661Sdavidcs "%s: Poll Q8_FLASH_STATUS failed\n", 407250661Sdavidcs __func__); 408250661Sdavidcs return (-1); 409250661Sdavidcs } 410250661Sdavidcs 411250661Sdavidcs return 0; 412250661Sdavidcs} 413250661Sdavidcs 414250661Sdavidcsstatic int 415250661Sdavidcsqla_erase_flash_sector(qla_host_t *ha, uint32_t start) 416250661Sdavidcs{ 417250661Sdavidcs uint32_t data32; 418250661Sdavidcs int count = 0; 419250661Sdavidcs 420250661Sdavidcs do { 421250661Sdavidcs qla_mdelay(__func__, 1); 422250661Sdavidcs 423250661Sdavidcs data32 = 0; 424250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) { 425250661Sdavidcs device_printf(ha->pci_dev, 426250661Sdavidcs "%s: Read Q8_FLASH_STATUS failed\n", 427250661Sdavidcs __func__); 428250661Sdavidcs return (-1); 429250661Sdavidcs } 430250661Sdavidcs 431250661Sdavidcs data32 &= 0x6; 432250661Sdavidcs 433250661Sdavidcs } while (((count++) < 1000) && (data32 != 0x6)); 434250661Sdavidcs 435254976Sdavidcs if (data32 != 0x6) { 436250661Sdavidcs device_printf(ha->pci_dev, 437250661Sdavidcs "%s: Poll Q8_FLASH_STATUS failed\n", 438250661Sdavidcs __func__); 439250661Sdavidcs return (-1); 440250661Sdavidcs } 441250661Sdavidcs 442250661Sdavidcs data32 = (start >> 16) & 0xFF; 443250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, &data32, 0)) { 444250661Sdavidcs device_printf(ha->pci_dev, 445250661Sdavidcs "%s: Write to Q8_FLASH_WR_DATA failed\n", 446250661Sdavidcs __func__); 447250661Sdavidcs return (-1); 448250661Sdavidcs } 449250661Sdavidcs 450250661Sdavidcs data32 = Q8_ERASE_FL_ADDR_MASK | ha->hw.fdt.erase_cmd; 451250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) { 452250661Sdavidcs device_printf(ha->pci_dev, 453250661Sdavidcs "%s: Write to Q8_FLASH_ADDRESS failed\n", 454250661Sdavidcs __func__); 455250661Sdavidcs return (-1); 456250661Sdavidcs } 457250661Sdavidcs 458250661Sdavidcs data32 = Q8_ERASE_FL_CTRL_MASK; 459250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) { 460250661Sdavidcs device_printf(ha->pci_dev, 461250661Sdavidcs "%s: Write to Q8_FLASH_CONTROL failed\n", 462250661Sdavidcs __func__); 463250661Sdavidcs return (-1); 464250661Sdavidcs } 465250661Sdavidcs 466250661Sdavidcs count = 0; 467250661Sdavidcs do { 468250661Sdavidcs qla_mdelay(__func__, 1); 469250661Sdavidcs 470250661Sdavidcs data32 = 0; 471250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) { 472250661Sdavidcs device_printf(ha->pci_dev, 473250661Sdavidcs "%s: Read Q8_FLASH_STATUS failed\n", 474250661Sdavidcs __func__); 475250661Sdavidcs return (-1); 476250661Sdavidcs } 477250661Sdavidcs 478250661Sdavidcs data32 &= 0x6; 479250661Sdavidcs 480250661Sdavidcs } while (((count++) < 1000) && (data32 != 0x6)); 481250661Sdavidcs 482254976Sdavidcs if (data32 != 0x6) { 483250661Sdavidcs device_printf(ha->pci_dev, 484250661Sdavidcs "%s: Poll Q8_FLASH_STATUS failed\n", 485250661Sdavidcs __func__); 486250661Sdavidcs return (-1); 487250661Sdavidcs } 488250661Sdavidcs 489250661Sdavidcs return 0; 490250661Sdavidcs} 491250661Sdavidcs 492250661Sdavidcsint 493250661Sdavidcsql_erase_flash(qla_host_t *ha, uint32_t off, uint32_t size) 494250661Sdavidcs{ 495250661Sdavidcs int rval = 0; 496250661Sdavidcs uint32_t start; 497250661Sdavidcs 498250661Sdavidcs if (off & (Q8_FLASH_SECTOR_SIZE -1)) 499250661Sdavidcs return (-1); 500250661Sdavidcs 501250661Sdavidcs if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID, 502250661Sdavidcs Q8_ERASE_LOCK_MAGIC_ID)) { 503250661Sdavidcs device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n", 504250661Sdavidcs __func__); 505250661Sdavidcs return (-1); 506250661Sdavidcs } 507250661Sdavidcs 508250661Sdavidcs if (qla_flash_write_enable(ha, 1) != 0) { 509250661Sdavidcs rval = -1; 510250661Sdavidcs goto ql_erase_flash_exit; 511250661Sdavidcs } 512250661Sdavidcs 513250661Sdavidcs for (start = off; start < (off + size); start = start + 514250661Sdavidcs Q8_FLASH_SECTOR_SIZE) { 515250661Sdavidcs if (qla_erase_flash_sector(ha, start)) { 516250661Sdavidcs rval = -1; 517250661Sdavidcs break; 518250661Sdavidcs } 519250661Sdavidcs } 520250661Sdavidcs 521250661Sdavidcs rval = qla_flash_write_enable(ha, 0); 522250661Sdavidcs 523250661Sdavidcsql_erase_flash_exit: 524250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 525250661Sdavidcs return (rval); 526250661Sdavidcs} 527250661Sdavidcs 528250661Sdavidcsstatic int 529250661Sdavidcsqla_wr_flash32(qla_host_t *ha, uint32_t off, uint32_t *data) 530250661Sdavidcs{ 531250661Sdavidcs uint32_t data32; 532250661Sdavidcs int count = 0; 533250661Sdavidcs 534250661Sdavidcs data32 = Q8_WR_FL_ADDR_MASK | (off >> 2); 535250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) { 536250661Sdavidcs device_printf(ha->pci_dev, 537250661Sdavidcs "%s: Write to Q8_FLASH_ADDRESS failed\n", 538250661Sdavidcs __func__); 539250661Sdavidcs return (-1); 540250661Sdavidcs } 541250661Sdavidcs 542250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, data, 0)) { 543250661Sdavidcs device_printf(ha->pci_dev, 544250661Sdavidcs "%s: Write to Q8_FLASH_WR_DATA failed\n", 545250661Sdavidcs __func__); 546250661Sdavidcs return (-1); 547250661Sdavidcs } 548250661Sdavidcs 549250661Sdavidcs data32 = Q8_WR_FL_CTRL_MASK; 550250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) { 551250661Sdavidcs device_printf(ha->pci_dev, 552250661Sdavidcs "%s: Write to Q8_FLASH_CONTROL failed\n", 553250661Sdavidcs __func__); 554250661Sdavidcs return (-1); 555250661Sdavidcs } 556250661Sdavidcs 557250661Sdavidcs do { 558250661Sdavidcs if (count < 1000) { 559250661Sdavidcs QLA_USEC_DELAY(10); 560250661Sdavidcs count += 10; 561250661Sdavidcs } else { 562250661Sdavidcs qla_mdelay(__func__, 1); 563250661Sdavidcs count += 1000; 564250661Sdavidcs } 565250661Sdavidcs 566250661Sdavidcs data32 = 0; 567250661Sdavidcs if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) { 568250661Sdavidcs device_printf(ha->pci_dev, 569250661Sdavidcs "%s: Read Q8_FLASH_STATUS failed\n", 570250661Sdavidcs __func__); 571250661Sdavidcs return (-1); 572250661Sdavidcs } 573250661Sdavidcs 574250661Sdavidcs data32 &= 0x6; 575250661Sdavidcs 576250661Sdavidcs } while ((count < 10000) && (data32 != 0x6)); 577250661Sdavidcs 578254976Sdavidcs if (data32 != 0x6) { 579250661Sdavidcs device_printf(ha->pci_dev, 580250661Sdavidcs "%s: Poll Q8_FLASH_STATUS failed\n", 581250661Sdavidcs __func__); 582250661Sdavidcs return (-1); 583250661Sdavidcs } 584250661Sdavidcs 585250661Sdavidcs return 0; 586250661Sdavidcs} 587250661Sdavidcs 588250661Sdavidcsstatic int 589250661Sdavidcsqla_flash_write_data(qla_host_t *ha, uint32_t off, uint32_t size, 590250661Sdavidcs void *data) 591250661Sdavidcs{ 592250661Sdavidcs int rval = 0; 593250661Sdavidcs uint32_t start; 594250661Sdavidcs uint32_t *data32 = data; 595250661Sdavidcs 596250661Sdavidcs if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID, 597250661Sdavidcs Q8_WR_FL_LOCK_MAGIC_ID)) { 598250661Sdavidcs device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n", 599250661Sdavidcs __func__); 600250661Sdavidcs rval = -1; 601250661Sdavidcs goto qla_flash_write_data_exit; 602250661Sdavidcs } 603250661Sdavidcs 604250661Sdavidcs if ((qla_flash_write_enable(ha, 1) != 0)) { 605250661Sdavidcs device_printf(ha->pci_dev, "%s: failed\n", 606250661Sdavidcs __func__); 607250661Sdavidcs rval = -1; 608250661Sdavidcs goto qla_flash_write_data_unlock_exit; 609250661Sdavidcs } 610250661Sdavidcs 611250661Sdavidcs for (start = off; start < (off + size); start = start + 4) { 612250661Sdavidcs if (*data32 != 0xFFFFFFFF) { 613250661Sdavidcs if (qla_wr_flash32(ha, start, data32)) { 614250661Sdavidcs rval = -1; 615250661Sdavidcs break; 616250661Sdavidcs } 617250661Sdavidcs } 618250661Sdavidcs data32++; 619250661Sdavidcs } 620250661Sdavidcs 621250661Sdavidcs rval = qla_flash_write_enable(ha, 0); 622250661Sdavidcs 623250661Sdavidcsqla_flash_write_data_unlock_exit: 624250661Sdavidcs qla_sem_unlock(ha, Q8_FLASH_UNLOCK); 625250661Sdavidcs 626250661Sdavidcsqla_flash_write_data_exit: 627250661Sdavidcs return (rval); 628250661Sdavidcs} 629250661Sdavidcs 630250661Sdavidcsint 631250661Sdavidcsql_wr_flash_buffer(qla_host_t *ha, uint32_t off, uint32_t size, void *buf) 632250661Sdavidcs{ 633250661Sdavidcs int rval = 0; 634250661Sdavidcs void *data; 635250661Sdavidcs 636250661Sdavidcs if (size == 0) 637250661Sdavidcs return 0; 638250661Sdavidcs 639250661Sdavidcs size = size << 2; 640250661Sdavidcs 641250661Sdavidcs if (buf == NULL) 642250661Sdavidcs return -1; 643250661Sdavidcs 644250661Sdavidcs if ((data = malloc(size, M_QLA83XXBUF, M_NOWAIT)) == NULL) { 645250661Sdavidcs device_printf(ha->pci_dev, "%s: malloc failed \n", __func__); 646250661Sdavidcs rval = -1; 647250661Sdavidcs goto ql_wr_flash_buffer_exit; 648250661Sdavidcs } 649250661Sdavidcs 650250661Sdavidcs if ((rval = copyin(buf, data, size))) { 651250661Sdavidcs device_printf(ha->pci_dev, "%s copyin failed\n", __func__); 652250661Sdavidcs goto ql_wr_flash_buffer_free_exit; 653250661Sdavidcs } 654250661Sdavidcs 655250661Sdavidcs rval = qla_flash_write_data(ha, off, size, data); 656250661Sdavidcs 657250661Sdavidcsql_wr_flash_buffer_free_exit: 658250661Sdavidcs free(data, M_QLA83XXBUF); 659250661Sdavidcs 660250661Sdavidcsql_wr_flash_buffer_exit: 661250661Sdavidcs return (rval); 662250661Sdavidcs} 663250661Sdavidcs 664284982Sdavidcs#ifdef QL_LDFLASH_FW 665250661Sdavidcs/* 666250661Sdavidcs * Name: qla_load_fw_from_flash 667250661Sdavidcs * Function: Reads the Bootloader from Flash and Loads into Offchip Memory 668250661Sdavidcs */ 669250661Sdavidcsstatic void 670250661Sdavidcsqla_load_fw_from_flash(qla_host_t *ha) 671250661Sdavidcs{ 672250661Sdavidcs uint32_t flash_off = 0x10000; 673250661Sdavidcs uint64_t mem_off; 674250661Sdavidcs uint32_t count, mem_size; 675250661Sdavidcs q80_offchip_mem_val_t val; 676250661Sdavidcs 677250661Sdavidcs mem_off = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR)); 678250661Sdavidcs mem_size = READ_REG32(ha, Q8_BOOTLD_SIZE); 679250661Sdavidcs 680250661Sdavidcs device_printf(ha->pci_dev, "%s: [0x%08x][0x%08x]\n", 681250661Sdavidcs __func__, (uint32_t)mem_off, mem_size); 682250661Sdavidcs 683250661Sdavidcs /* only bootloader needs to be loaded into memory */ 684250661Sdavidcs for (count = 0; count < mem_size ; ) { 685250661Sdavidcs ql_rd_flash32(ha, flash_off, &val.data_lo); 686250661Sdavidcs count = count + 4; 687250661Sdavidcs flash_off = flash_off + 4; 688250661Sdavidcs 689250661Sdavidcs ql_rd_flash32(ha, flash_off, &val.data_hi); 690250661Sdavidcs count = count + 4; 691250661Sdavidcs flash_off = flash_off + 4; 692250661Sdavidcs 693250661Sdavidcs ql_rd_flash32(ha, flash_off, &val.data_ulo); 694250661Sdavidcs count = count + 4; 695250661Sdavidcs flash_off = flash_off + 4; 696250661Sdavidcs 697250661Sdavidcs ql_rd_flash32(ha, flash_off, &val.data_uhi); 698250661Sdavidcs count = count + 4; 699250661Sdavidcs flash_off = flash_off + 4; 700250661Sdavidcs 701250661Sdavidcs ql_rdwr_offchip_mem(ha, mem_off, &val, 0); 702250661Sdavidcs 703250661Sdavidcs mem_off = mem_off + 16; 704250661Sdavidcs } 705250661Sdavidcs 706250661Sdavidcs return; 707250661Sdavidcs} 708284982Sdavidcs#endif /* #ifdef QL_LDFLASH_FW */ 709250661Sdavidcs 710250661Sdavidcs/* 711250661Sdavidcs * Name: qla_init_from_flash 712250661Sdavidcs * Function: Performs Initialization which consists of the following sequence 713250661Sdavidcs * - reset 714250661Sdavidcs * - CRB Init 715250661Sdavidcs * - Peg Init 716250661Sdavidcs * - Read the Bootloader from Flash and Load into Offchip Memory 717250661Sdavidcs * - Kick start the bootloader which loads the rest of the firmware 718250661Sdavidcs * and performs the remaining steps in the initialization process. 719250661Sdavidcs */ 720250661Sdavidcsstatic int 721250661Sdavidcsqla_init_from_flash(qla_host_t *ha) 722250661Sdavidcs{ 723250661Sdavidcs uint32_t delay = 300; 724250661Sdavidcs uint32_t data; 725250661Sdavidcs 726250661Sdavidcs qla_ld_fw_init(ha); 727250661Sdavidcs 728250661Sdavidcs do { 729250661Sdavidcs data = READ_REG32(ha, Q8_CMDPEG_STATE); 730250661Sdavidcs 731250661Sdavidcs QL_DPRINT2(ha, 732250661Sdavidcs (ha->pci_dev, "%s: func[%d] cmdpegstate 0x%08x\n", 733250661Sdavidcs __func__, ha->pci_func, data)); 734250661Sdavidcs if (data == 0xFF01) { 735250661Sdavidcs QL_DPRINT2(ha, (ha->pci_dev, 736250661Sdavidcs "%s: func[%d] init complete\n", 737250661Sdavidcs __func__, ha->pci_func)); 738250661Sdavidcs return(0); 739250661Sdavidcs } 740250661Sdavidcs qla_mdelay(__func__, 100); 741250661Sdavidcs } while (delay--); 742250661Sdavidcs 743250661Sdavidcs return (-1); 744250661Sdavidcs} 745250661Sdavidcs 746250661Sdavidcs/* 747250661Sdavidcs * Name: ql_init_hw 748250661Sdavidcs * Function: Initializes P3+ hardware. 749250661Sdavidcs */ 750250661Sdavidcsint 751250661Sdavidcsql_init_hw(qla_host_t *ha) 752250661Sdavidcs{ 753250661Sdavidcs device_t dev; 754250661Sdavidcs int ret = 0; 755250661Sdavidcs uint32_t val, delay = 300; 756250661Sdavidcs 757250661Sdavidcs dev = ha->pci_dev; 758250661Sdavidcs 759250661Sdavidcs QL_DPRINT1(ha, (dev, "%s: enter\n", __func__)); 760250661Sdavidcs 761250661Sdavidcs if (ha->pci_func & 0x1) { 762250661Sdavidcs 763250661Sdavidcs while ((ha->pci_func & 0x1) && delay--) { 764250661Sdavidcs 765250661Sdavidcs val = READ_REG32(ha, Q8_CMDPEG_STATE); 766250661Sdavidcs 767250661Sdavidcs if (val == 0xFF01) { 768250661Sdavidcs QL_DPRINT2(ha, (dev, 769250661Sdavidcs "%s: func = %d init complete\n", 770250661Sdavidcs __func__, ha->pci_func)); 771250661Sdavidcs qla_mdelay(__func__, 100); 772250661Sdavidcs goto qla_init_exit; 773250661Sdavidcs } 774250661Sdavidcs qla_mdelay(__func__, 100); 775250661Sdavidcs } 776250661Sdavidcs return (-1); 777250661Sdavidcs } 778250661Sdavidcs 779250661Sdavidcs 780250661Sdavidcs val = READ_REG32(ha, Q8_CMDPEG_STATE); 781250661Sdavidcs if (!cold || (val != 0xFF01)) { 782250661Sdavidcs ret = qla_init_from_flash(ha); 783250661Sdavidcs qla_mdelay(__func__, 100); 784250661Sdavidcs } 785250661Sdavidcs 786250661Sdavidcsqla_init_exit: 787250661Sdavidcs ha->fw_ver_major = READ_REG32(ha, Q8_FW_VER_MAJOR); 788250661Sdavidcs ha->fw_ver_minor = READ_REG32(ha, Q8_FW_VER_MINOR); 789250661Sdavidcs ha->fw_ver_sub = READ_REG32(ha, Q8_FW_VER_SUB); 790250661Sdavidcs 791250661Sdavidcs if (qla_get_fdt(ha) != 0) { 792250661Sdavidcs device_printf(dev, "%s: qla_get_fdt failed\n", __func__); 793250661Sdavidcs } else { 794250661Sdavidcs ha->hw.flags.fdt_valid = 1; 795250661Sdavidcs } 796250661Sdavidcs 797250661Sdavidcs return (ret); 798250661Sdavidcs} 799250661Sdavidcs 800250661Sdavidcsvoid 801250661Sdavidcsql_read_mac_addr(qla_host_t *ha) 802250661Sdavidcs{ 803250661Sdavidcs uint8_t *macp; 804250661Sdavidcs uint32_t mac_lo; 805250661Sdavidcs uint32_t mac_hi; 806250661Sdavidcs uint32_t flash_off; 807250661Sdavidcs 808250661Sdavidcs flash_off = Q8_BOARD_CONFIG_OFFSET + Q8_BOARD_CONFIG_MAC0_LO + 809250661Sdavidcs (ha->pci_func << 3); 810250661Sdavidcs ql_rd_flash32(ha, flash_off, &mac_lo); 811250661Sdavidcs 812250661Sdavidcs flash_off += 4; 813250661Sdavidcs ql_rd_flash32(ha, flash_off, &mac_hi); 814250661Sdavidcs 815250661Sdavidcs macp = (uint8_t *)&mac_lo; 816250661Sdavidcs ha->hw.mac_addr[5] = macp[0]; 817250661Sdavidcs ha->hw.mac_addr[4] = macp[1]; 818250661Sdavidcs ha->hw.mac_addr[3] = macp[2]; 819250661Sdavidcs ha->hw.mac_addr[2] = macp[3]; 820250661Sdavidcs 821250661Sdavidcs macp = (uint8_t *)&mac_hi; 822250661Sdavidcs ha->hw.mac_addr[1] = macp[0]; 823250661Sdavidcs ha->hw.mac_addr[0] = macp[1]; 824250661Sdavidcs 825250661Sdavidcs //device_printf(ha->pci_dev, "%s: %02x:%02x:%02x:%02x:%02x:%02x\n", 826250661Sdavidcs // __func__, ha->hw.mac_addr[0], ha->hw.mac_addr[1], 827250661Sdavidcs // ha->hw.mac_addr[2], ha->hw.mac_addr[3], 828250661Sdavidcs // ha->hw.mac_addr[4], ha->hw.mac_addr[5]); 829250661Sdavidcs 830250661Sdavidcs return; 831250661Sdavidcs} 832250661Sdavidcs 833250661Sdavidcs/* 834250661Sdavidcs * Stop/Start/Initialization Handling 835250661Sdavidcs */ 836250661Sdavidcs 837250661Sdavidcsstatic uint16_t 838250661Sdavidcsqla_tmplt_16bit_checksum(qla_host_t *ha, uint16_t *buf, uint32_t size) 839250661Sdavidcs{ 840250661Sdavidcs uint32_t sum = 0; 841250661Sdavidcs uint32_t count = size >> 1; /* size in 16 bit words */ 842250661Sdavidcs 843250661Sdavidcs while (count-- > 0) 844250661Sdavidcs sum += *buf++; 845250661Sdavidcs 846250661Sdavidcs while (sum >> 16) 847250661Sdavidcs sum = (sum & 0xFFFF) + (sum >> 16); 848250661Sdavidcs 849250661Sdavidcs return (~sum); 850250661Sdavidcs} 851250661Sdavidcs 852250661Sdavidcsstatic int 853250661Sdavidcsqla_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr) 854250661Sdavidcs{ 855250661Sdavidcs q8_wrl_e_t *wr_l; 856250661Sdavidcs int i; 857250661Sdavidcs 858250661Sdavidcs wr_l = (q8_wrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t)); 859250661Sdavidcs 860250661Sdavidcs for (i = 0; i < ce_hdr->opcount; i++, wr_l++) { 861250661Sdavidcs 862250661Sdavidcs if (ql_rdwr_indreg32(ha, wr_l->addr, &wr_l->value, 0)) { 863250661Sdavidcs device_printf(ha->pci_dev, 864250661Sdavidcs "%s: [0x%08x 0x%08x] error\n", __func__, 865250661Sdavidcs wr_l->addr, wr_l->value); 866250661Sdavidcs return -1; 867250661Sdavidcs } 868250661Sdavidcs if (ce_hdr->delay_to) { 869250661Sdavidcs DELAY(ce_hdr->delay_to); 870250661Sdavidcs } 871250661Sdavidcs } 872250661Sdavidcs return 0; 873250661Sdavidcs} 874250661Sdavidcs 875250661Sdavidcsstatic int 876250661Sdavidcsqla_rd_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr) 877250661Sdavidcs{ 878250661Sdavidcs q8_rdwrl_e_t *rd_wr_l; 879250661Sdavidcs uint32_t data; 880250661Sdavidcs int i; 881250661Sdavidcs 882250661Sdavidcs rd_wr_l = (q8_rdwrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t)); 883250661Sdavidcs 884250661Sdavidcs for (i = 0; i < ce_hdr->opcount; i++, rd_wr_l++) { 885250661Sdavidcs 886250661Sdavidcs if (ql_rdwr_indreg32(ha, rd_wr_l->rd_addr, &data, 1)) { 887250661Sdavidcs device_printf(ha->pci_dev, "%s: [0x%08x] error\n", 888250661Sdavidcs __func__, rd_wr_l->rd_addr); 889250661Sdavidcs 890250661Sdavidcs return -1; 891250661Sdavidcs } 892250661Sdavidcs 893250661Sdavidcs if (ql_rdwr_indreg32(ha, rd_wr_l->wr_addr, &data, 0)) { 894250661Sdavidcs device_printf(ha->pci_dev, 895250661Sdavidcs "%s: [0x%08x 0x%08x] error\n", __func__, 896250661Sdavidcs rd_wr_l->wr_addr, data); 897250661Sdavidcs return -1; 898250661Sdavidcs } 899250661Sdavidcs if (ce_hdr->delay_to) { 900250661Sdavidcs DELAY(ce_hdr->delay_to); 901250661Sdavidcs } 902250661Sdavidcs } 903250661Sdavidcs return 0; 904250661Sdavidcs} 905250661Sdavidcs 906250661Sdavidcsstatic int 907250661Sdavidcsqla_poll_reg(qla_host_t *ha, uint32_t addr, uint32_t ms_to, uint32_t tmask, 908250661Sdavidcs uint32_t tvalue) 909250661Sdavidcs{ 910250661Sdavidcs uint32_t data; 911250661Sdavidcs 912250661Sdavidcs while (ms_to) { 913250661Sdavidcs 914250661Sdavidcs if (ql_rdwr_indreg32(ha, addr, &data, 1)) { 915250661Sdavidcs device_printf(ha->pci_dev, "%s: [0x%08x] error\n", 916250661Sdavidcs __func__, addr); 917250661Sdavidcs return -1; 918250661Sdavidcs } 919250661Sdavidcs 920250661Sdavidcs if ((data & tmask) != tvalue) { 921250661Sdavidcs ms_to--; 922250661Sdavidcs } else 923250661Sdavidcs break; 924250661Sdavidcs 925250661Sdavidcs qla_mdelay(__func__, 1); 926250661Sdavidcs } 927250661Sdavidcs return ((ms_to ? 0: -1)); 928250661Sdavidcs} 929250661Sdavidcs 930250661Sdavidcsstatic int 931250661Sdavidcsqla_poll_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr) 932250661Sdavidcs{ 933250661Sdavidcs int i; 934250661Sdavidcs q8_poll_hdr_t *phdr; 935250661Sdavidcs q8_poll_e_t *pe; 936250661Sdavidcs uint32_t data; 937250661Sdavidcs 938250661Sdavidcs phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t)); 939250661Sdavidcs pe = (q8_poll_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t)); 940250661Sdavidcs 941250661Sdavidcs for (i = 0; i < ce_hdr->opcount; i++, pe++) { 942250661Sdavidcs if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) { 943250661Sdavidcs device_printf(ha->pci_dev, "%s: [0x%08x] error\n", 944250661Sdavidcs __func__, pe->addr); 945250661Sdavidcs return -1; 946250661Sdavidcs } 947250661Sdavidcs 948250661Sdavidcs if (ce_hdr->delay_to) { 949250661Sdavidcs if ((data & phdr->tmask) == phdr->tvalue) 950250661Sdavidcs break; 951250661Sdavidcs if (qla_poll_reg(ha, pe->addr, ce_hdr->delay_to, 952250661Sdavidcs phdr->tmask, phdr->tvalue)) { 953250661Sdavidcs 954250661Sdavidcs if (ql_rdwr_indreg32(ha, pe->to_addr, &data, 955250661Sdavidcs 1)) { 956250661Sdavidcs device_printf(ha->pci_dev, 957250661Sdavidcs "%s: [0x%08x] error\n", 958250661Sdavidcs __func__, pe->to_addr); 959250661Sdavidcs return -1; 960250661Sdavidcs } 961250661Sdavidcs 962250661Sdavidcs if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) { 963250661Sdavidcs device_printf(ha->pci_dev, 964250661Sdavidcs "%s: [0x%08x] error\n", 965250661Sdavidcs __func__, pe->addr); 966250661Sdavidcs return -1; 967250661Sdavidcs } 968250661Sdavidcs } 969250661Sdavidcs } 970250661Sdavidcs } 971250661Sdavidcs return 0; 972250661Sdavidcs} 973250661Sdavidcs 974250661Sdavidcsstatic int 975250661Sdavidcsqla_poll_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr) 976250661Sdavidcs{ 977250661Sdavidcs int i; 978250661Sdavidcs q8_poll_hdr_t *phdr; 979250661Sdavidcs q8_poll_wr_e_t *wr_e; 980250661Sdavidcs 981250661Sdavidcs phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t)); 982250661Sdavidcs wr_e = (q8_poll_wr_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t)); 983250661Sdavidcs 984250661Sdavidcs for (i = 0; i < ce_hdr->opcount; i++, wr_e++) { 985250661Sdavidcs 986250661Sdavidcs if (ql_rdwr_indreg32(ha, wr_e->dr_addr, &wr_e->dr_value, 0)) { 987250661Sdavidcs device_printf(ha->pci_dev, 988250661Sdavidcs "%s: [0x%08x 0x%08x] error\n", __func__, 989250661Sdavidcs wr_e->dr_addr, wr_e->dr_value); 990250661Sdavidcs return -1; 991250661Sdavidcs } 992250661Sdavidcs if (ql_rdwr_indreg32(ha, wr_e->ar_addr, &wr_e->ar_value, 0)) { 993250661Sdavidcs device_printf(ha->pci_dev, 994250661Sdavidcs "%s: [0x%08x 0x%08x] error\n", __func__, 995250661Sdavidcs wr_e->ar_addr, wr_e->ar_value); 996250661Sdavidcs return -1; 997250661Sdavidcs } 998250661Sdavidcs if (ce_hdr->delay_to) { 999250661Sdavidcs if (qla_poll_reg(ha, wr_e->ar_addr, ce_hdr->delay_to, 1000250661Sdavidcs phdr->tmask, phdr->tvalue)) 1001250661Sdavidcs device_printf(ha->pci_dev, "%s: " 1002250661Sdavidcs "[ar_addr, ar_value, delay, tmask," 1003250661Sdavidcs "tvalue] [0x%08x 0x%08x 0x%08x 0x%08x" 1004250661Sdavidcs " 0x%08x]\n", 1005250661Sdavidcs __func__, wr_e->ar_addr, wr_e->ar_value, 1006250661Sdavidcs ce_hdr->delay_to, phdr->tmask, 1007250661Sdavidcs phdr->tvalue); 1008250661Sdavidcs } 1009250661Sdavidcs } 1010250661Sdavidcs return 0; 1011250661Sdavidcs} 1012250661Sdavidcs 1013250661Sdavidcsstatic int 1014250661Sdavidcsqla_poll_read_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr) 1015250661Sdavidcs{ 1016250661Sdavidcs int i; 1017250661Sdavidcs q8_poll_hdr_t *phdr; 1018250661Sdavidcs q8_poll_rd_e_t *rd_e; 1019250661Sdavidcs uint32_t value; 1020250661Sdavidcs 1021250661Sdavidcs phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t)); 1022250661Sdavidcs rd_e = (q8_poll_rd_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t)); 1023250661Sdavidcs 1024250661Sdavidcs for (i = 0; i < ce_hdr->opcount; i++, rd_e++) { 1025250661Sdavidcs if (ql_rdwr_indreg32(ha, rd_e->ar_addr, &rd_e->ar_value, 0)) { 1026250661Sdavidcs device_printf(ha->pci_dev, 1027250661Sdavidcs "%s: [0x%08x 0x%08x] error\n", __func__, 1028250661Sdavidcs rd_e->ar_addr, rd_e->ar_value); 1029250661Sdavidcs return -1; 1030250661Sdavidcs } 1031250661Sdavidcs 1032250661Sdavidcs if (ce_hdr->delay_to) { 1033250661Sdavidcs if (qla_poll_reg(ha, rd_e->ar_addr, ce_hdr->delay_to, 1034250661Sdavidcs phdr->tmask, phdr->tvalue)) { 1035250661Sdavidcs return (-1); 1036250661Sdavidcs } else { 1037250661Sdavidcs if (ql_rdwr_indreg32(ha, rd_e->dr_addr, 1038250661Sdavidcs &value, 1)) { 1039250661Sdavidcs device_printf(ha->pci_dev, 1040250661Sdavidcs "%s: [0x%08x] error\n", 1041250661Sdavidcs __func__, rd_e->ar_addr); 1042250661Sdavidcs return -1; 1043250661Sdavidcs } 1044250661Sdavidcs 1045250661Sdavidcs ha->hw.rst_seq[ha->hw.rst_seq_idx++] = value; 1046250661Sdavidcs if (ha->hw.rst_seq_idx == Q8_MAX_RESET_SEQ_IDX) 1047250661Sdavidcs ha->hw.rst_seq_idx = 1; 1048250661Sdavidcs } 1049250661Sdavidcs } 1050250661Sdavidcs } 1051250661Sdavidcs return 0; 1052250661Sdavidcs} 1053250661Sdavidcs 1054250661Sdavidcsstatic int 1055250661Sdavidcsqla_rdmwr(qla_host_t *ha, uint32_t raddr, uint32_t waddr, q8_rdmwr_hdr_t *hdr) 1056250661Sdavidcs{ 1057250661Sdavidcs uint32_t value; 1058250661Sdavidcs 1059250661Sdavidcs if (hdr->index_a >= Q8_MAX_RESET_SEQ_IDX) { 1060250661Sdavidcs device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__, 1061250661Sdavidcs hdr->index_a); 1062250661Sdavidcs return -1; 1063250661Sdavidcs } 1064250661Sdavidcs 1065250661Sdavidcs if (hdr->index_a) { 1066250661Sdavidcs value = ha->hw.rst_seq[hdr->index_a]; 1067250661Sdavidcs } else { 1068250661Sdavidcs if (ql_rdwr_indreg32(ha, raddr, &value, 1)) { 1069250661Sdavidcs device_printf(ha->pci_dev, "%s: [0x%08x] error\n", 1070250661Sdavidcs __func__, raddr); 1071250661Sdavidcs return -1; 1072250661Sdavidcs } 1073250661Sdavidcs } 1074250661Sdavidcs 1075250661Sdavidcs value &= hdr->and_value; 1076250661Sdavidcs value <<= hdr->shl; 1077250661Sdavidcs value >>= hdr->shr; 1078250661Sdavidcs value |= hdr->or_value; 1079250661Sdavidcs value ^= hdr->xor_value; 1080250661Sdavidcs 1081250661Sdavidcs if (ql_rdwr_indreg32(ha, waddr, &value, 0)) { 1082250661Sdavidcs device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__, 1083250661Sdavidcs raddr); 1084250661Sdavidcs return -1; 1085250661Sdavidcs } 1086250661Sdavidcs return 0; 1087250661Sdavidcs} 1088250661Sdavidcs 1089250661Sdavidcsstatic int 1090250661Sdavidcsqla_read_modify_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr) 1091250661Sdavidcs{ 1092250661Sdavidcs int i; 1093250661Sdavidcs q8_rdmwr_hdr_t *rdmwr_hdr; 1094250661Sdavidcs q8_rdmwr_e_t *rdmwr_e; 1095250661Sdavidcs 1096250661Sdavidcs rdmwr_hdr = (q8_rdmwr_hdr_t *)((uint8_t *)ce_hdr + 1097250661Sdavidcs sizeof (q8_ce_hdr_t)); 1098250661Sdavidcs rdmwr_e = (q8_rdmwr_e_t *)((uint8_t *)rdmwr_hdr + 1099250661Sdavidcs sizeof(q8_rdmwr_hdr_t)); 1100250661Sdavidcs 1101250661Sdavidcs for (i = 0; i < ce_hdr->opcount; i++, rdmwr_e++) { 1102250661Sdavidcs 1103250661Sdavidcs if (qla_rdmwr(ha, rdmwr_e->rd_addr, rdmwr_e->wr_addr, 1104250661Sdavidcs rdmwr_hdr)) { 1105250661Sdavidcs return -1; 1106250661Sdavidcs } 1107250661Sdavidcs if (ce_hdr->delay_to) { 1108250661Sdavidcs DELAY(ce_hdr->delay_to); 1109250661Sdavidcs } 1110250661Sdavidcs } 1111250661Sdavidcs return 0; 1112250661Sdavidcs} 1113250661Sdavidcs 1114250661Sdavidcsstatic int 1115250661Sdavidcsqla_tmplt_execute(qla_host_t *ha, uint8_t *buf, int start_idx, int *end_idx, 1116250661Sdavidcs uint32_t nentries) 1117250661Sdavidcs{ 1118250661Sdavidcs int i, ret = 0, proc_end = 0; 1119250661Sdavidcs q8_ce_hdr_t *ce_hdr; 1120250661Sdavidcs 1121250661Sdavidcs for (i = start_idx; ((i < nentries) && (!proc_end)); i++) { 1122250661Sdavidcs ce_hdr = (q8_ce_hdr_t *)buf; 1123250661Sdavidcs ret = 0; 1124250661Sdavidcs 1125250661Sdavidcs switch (ce_hdr->opcode) { 1126250661Sdavidcs case Q8_CE_OPCODE_NOP: 1127250661Sdavidcs break; 1128250661Sdavidcs 1129250661Sdavidcs case Q8_CE_OPCODE_WRITE_LIST: 1130250661Sdavidcs ret = qla_wr_list(ha, ce_hdr); 1131250661Sdavidcs //printf("qla_wr_list %d\n", ret); 1132250661Sdavidcs break; 1133250661Sdavidcs 1134250661Sdavidcs case Q8_CE_OPCODE_READ_WRITE_LIST: 1135250661Sdavidcs ret = qla_rd_wr_list(ha, ce_hdr); 1136250661Sdavidcs //printf("qla_rd_wr_list %d\n", ret); 1137250661Sdavidcs break; 1138250661Sdavidcs 1139250661Sdavidcs case Q8_CE_OPCODE_POLL_LIST: 1140250661Sdavidcs ret = qla_poll_list(ha, ce_hdr); 1141250661Sdavidcs //printf("qla_poll_list %d\n", ret); 1142250661Sdavidcs break; 1143250661Sdavidcs 1144250661Sdavidcs case Q8_CE_OPCODE_POLL_WRITE_LIST: 1145250661Sdavidcs ret = qla_poll_write_list(ha, ce_hdr); 1146250661Sdavidcs //printf("qla_poll_write_list %d\n", ret); 1147250661Sdavidcs break; 1148250661Sdavidcs 1149250661Sdavidcs case Q8_CE_OPCODE_POLL_RD_LIST: 1150250661Sdavidcs ret = qla_poll_read_list(ha, ce_hdr); 1151250661Sdavidcs //printf("qla_poll_read_list %d\n", ret); 1152250661Sdavidcs break; 1153250661Sdavidcs 1154250661Sdavidcs case Q8_CE_OPCODE_READ_MODIFY_WRITE: 1155250661Sdavidcs ret = qla_read_modify_write_list(ha, ce_hdr); 1156250661Sdavidcs //printf("qla_read_modify_write_list %d\n", ret); 1157250661Sdavidcs break; 1158250661Sdavidcs 1159250661Sdavidcs case Q8_CE_OPCODE_SEQ_PAUSE: 1160250661Sdavidcs if (ce_hdr->delay_to) { 1161250661Sdavidcs qla_mdelay(__func__, ce_hdr->delay_to); 1162250661Sdavidcs } 1163250661Sdavidcs break; 1164250661Sdavidcs 1165250661Sdavidcs case Q8_CE_OPCODE_SEQ_END: 1166250661Sdavidcs proc_end = 1; 1167250661Sdavidcs break; 1168250661Sdavidcs 1169250661Sdavidcs case Q8_CE_OPCODE_TMPLT_END: 1170250661Sdavidcs *end_idx = i; 1171250661Sdavidcs return 0; 1172250661Sdavidcs } 1173250661Sdavidcs 1174250661Sdavidcs if (ret) 1175250661Sdavidcs break; 1176250661Sdavidcs 1177250661Sdavidcs buf += ce_hdr->size; 1178250661Sdavidcs } 1179250661Sdavidcs *end_idx = i; 1180250661Sdavidcs 1181250661Sdavidcs return (ret); 1182250661Sdavidcs} 1183250661Sdavidcs 1184284982Sdavidcs#ifndef QL_LDFLASH_FW 1185284982Sdavidcsstatic int 1186284982Sdavidcsqla_load_offchip_mem(qla_host_t *ha, uint64_t addr, uint32_t *data32, 1187284982Sdavidcs uint32_t len32) 1188284982Sdavidcs{ 1189284982Sdavidcs q80_offchip_mem_val_t val; 1190284982Sdavidcs int ret = 0; 1191250661Sdavidcs 1192284982Sdavidcs while (len32) { 1193284982Sdavidcs if (len32 > 4) { 1194284982Sdavidcs val.data_lo = *data32++; 1195284982Sdavidcs val.data_hi = *data32++; 1196284982Sdavidcs val.data_ulo = *data32++; 1197284982Sdavidcs val.data_uhi = *data32++; 1198284982Sdavidcs len32 -= 4; 1199284982Sdavidcs if (ql_rdwr_offchip_mem(ha, addr, &val, 0)) 1200284982Sdavidcs return -1; 1201284982Sdavidcs 1202284982Sdavidcs addr += (uint64_t)16; 1203284982Sdavidcs } else { 1204284982Sdavidcs break; 1205284982Sdavidcs } 1206284982Sdavidcs } 1207284982Sdavidcs 1208284982Sdavidcs bzero(&val, sizeof(q80_offchip_mem_val_t)); 1209284982Sdavidcs 1210284982Sdavidcs switch (len32) { 1211284982Sdavidcs case 3: 1212284982Sdavidcs val.data_lo = *data32++; 1213284982Sdavidcs val.data_hi = *data32++; 1214284982Sdavidcs val.data_ulo = *data32++; 1215284982Sdavidcs ret = ql_rdwr_offchip_mem(ha, addr, &val, 0); 1216284982Sdavidcs break; 1217284982Sdavidcs 1218284982Sdavidcs case 2: 1219284982Sdavidcs val.data_lo = *data32++; 1220284982Sdavidcs val.data_hi = *data32++; 1221284982Sdavidcs ret = ql_rdwr_offchip_mem(ha, addr, &val, 0); 1222284982Sdavidcs break; 1223284982Sdavidcs 1224284982Sdavidcs case 1: 1225284982Sdavidcs val.data_lo = *data32++; 1226284982Sdavidcs ret = ql_rdwr_offchip_mem(ha, addr, &val, 0); 1227284982Sdavidcs break; 1228284982Sdavidcs 1229284982Sdavidcs default: 1230284982Sdavidcs break; 1231284982Sdavidcs 1232284982Sdavidcs } 1233284982Sdavidcs return ret; 1234284982Sdavidcs} 1235284982Sdavidcs 1236284982Sdavidcs 1237250661Sdavidcsstatic int 1238284982Sdavidcsqla_load_bootldr(qla_host_t *ha) 1239284982Sdavidcs{ 1240284982Sdavidcs uint64_t addr; 1241284982Sdavidcs uint32_t *data32; 1242284982Sdavidcs uint32_t len32; 1243284982Sdavidcs int ret; 1244284982Sdavidcs 1245284982Sdavidcs addr = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR)); 1246284982Sdavidcs data32 = (uint32_t *)ql83xx_bootloader; 1247284982Sdavidcs len32 = ql83xx_bootloader_len >> 2; 1248284982Sdavidcs 1249284982Sdavidcs ret = qla_load_offchip_mem(ha, addr, data32, len32); 1250284982Sdavidcs 1251284982Sdavidcs return (ret); 1252284982Sdavidcs} 1253284982Sdavidcs 1254284982Sdavidcsstatic int 1255284982Sdavidcsqla_load_fwimage(qla_host_t *ha) 1256284982Sdavidcs{ 1257284982Sdavidcs uint64_t addr; 1258284982Sdavidcs uint32_t *data32; 1259284982Sdavidcs uint32_t len32; 1260284982Sdavidcs int ret; 1261284982Sdavidcs 1262284982Sdavidcs addr = (uint64_t)(READ_REG32(ha, Q8_FW_IMAGE_ADDR)); 1263284982Sdavidcs data32 = (uint32_t *)ql83xx_firmware; 1264284982Sdavidcs len32 = ql83xx_firmware_len >> 2; 1265284982Sdavidcs 1266284982Sdavidcs ret = qla_load_offchip_mem(ha, addr, data32, len32); 1267284982Sdavidcs 1268284982Sdavidcs return (ret); 1269284982Sdavidcs} 1270284982Sdavidcs#endif /* #ifndef QL_LDFLASH_FW */ 1271284982Sdavidcs 1272284982Sdavidcsstatic int 1273250661Sdavidcsqla_ld_fw_init(qla_host_t *ha) 1274250661Sdavidcs{ 1275250661Sdavidcs uint8_t *buf; 1276250661Sdavidcs uint32_t index = 0, end_idx; 1277250661Sdavidcs q8_tmplt_hdr_t *hdr; 1278250661Sdavidcs 1279250661Sdavidcs bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq)); 1280250661Sdavidcs 1281250661Sdavidcs hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq; 1282250661Sdavidcs 1283250661Sdavidcs if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq, 1284250661Sdavidcs (uint32_t)hdr->size)) { 1285250661Sdavidcs device_printf(ha->pci_dev, "%s: reset seq checksum failed\n", 1286250661Sdavidcs __func__); 1287250661Sdavidcs return -1; 1288250661Sdavidcs } 1289250661Sdavidcs 1290250661Sdavidcs 1291250661Sdavidcs buf = ql83xx_resetseq + hdr->stop_seq_off; 1292250661Sdavidcs 1293250661Sdavidcs// device_printf(ha->pci_dev, "%s: stop sequence\n", __func__); 1294250661Sdavidcs if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) { 1295250661Sdavidcs device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__); 1296250661Sdavidcs return -1; 1297250661Sdavidcs } 1298250661Sdavidcs 1299250661Sdavidcs index = end_idx; 1300250661Sdavidcs 1301250661Sdavidcs buf = ql83xx_resetseq + hdr->init_seq_off; 1302250661Sdavidcs 1303250661Sdavidcs// device_printf(ha->pci_dev, "%s: init sequence\n", __func__); 1304250661Sdavidcs if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) { 1305250661Sdavidcs device_printf(ha->pci_dev, "%s: init seq failed\n", __func__); 1306250661Sdavidcs return -1; 1307250661Sdavidcs } 1308250661Sdavidcs 1309284982Sdavidcs#ifdef QL_LDFLASH_FW 1310250661Sdavidcs qla_load_fw_from_flash(ha); 1311250661Sdavidcs WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0); 1312284982Sdavidcs#else 1313284982Sdavidcs if (qla_load_bootldr(ha)) 1314284982Sdavidcs return -1; 1315250661Sdavidcs 1316284982Sdavidcs if (qla_load_fwimage(ha)) 1317284982Sdavidcs return -1; 1318284982Sdavidcs 1319284982Sdavidcs WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678); 1320284982Sdavidcs#endif /* #ifdef QL_LDFLASH_FW */ 1321284982Sdavidcs 1322250661Sdavidcs index = end_idx; 1323250661Sdavidcs buf = ql83xx_resetseq + hdr->start_seq_off; 1324250661Sdavidcs 1325250661Sdavidcs// device_printf(ha->pci_dev, "%s: start sequence\n", __func__); 1326250661Sdavidcs if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) { 1327250661Sdavidcs device_printf(ha->pci_dev, "%s: init seq failed\n", __func__); 1328250661Sdavidcs return -1; 1329250661Sdavidcs } 1330250661Sdavidcs 1331250661Sdavidcs return 0; 1332250661Sdavidcs} 1333250661Sdavidcs 1334250661Sdavidcsint 1335250661Sdavidcsql_stop_sequence(qla_host_t *ha) 1336250661Sdavidcs{ 1337250661Sdavidcs uint8_t *buf; 1338250661Sdavidcs uint32_t index = 0, end_idx; 1339250661Sdavidcs q8_tmplt_hdr_t *hdr; 1340250661Sdavidcs 1341250661Sdavidcs bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq)); 1342250661Sdavidcs 1343250661Sdavidcs hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq; 1344250661Sdavidcs 1345250661Sdavidcs if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq, 1346250661Sdavidcs (uint32_t)hdr->size)) { 1347250661Sdavidcs device_printf(ha->pci_dev, "%s: reset seq checksum failed\n", 1348250661Sdavidcs __func__); 1349250661Sdavidcs return (-1); 1350250661Sdavidcs } 1351250661Sdavidcs 1352250661Sdavidcs buf = ql83xx_resetseq + hdr->stop_seq_off; 1353250661Sdavidcs 1354250661Sdavidcs device_printf(ha->pci_dev, "%s: stop sequence\n", __func__); 1355250661Sdavidcs if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) { 1356250661Sdavidcs device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__); 1357250661Sdavidcs return (-1); 1358250661Sdavidcs } 1359250661Sdavidcs 1360250661Sdavidcs return end_idx; 1361250661Sdavidcs} 1362250661Sdavidcs 1363250661Sdavidcsint 1364250661Sdavidcsql_start_sequence(qla_host_t *ha, uint16_t index) 1365250661Sdavidcs{ 1366250661Sdavidcs uint8_t *buf; 1367250661Sdavidcs uint32_t end_idx; 1368250661Sdavidcs q8_tmplt_hdr_t *hdr; 1369250661Sdavidcs 1370250661Sdavidcs bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq)); 1371250661Sdavidcs 1372250661Sdavidcs hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq; 1373250661Sdavidcs 1374250661Sdavidcs if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq, 1375250661Sdavidcs (uint32_t)hdr->size)) { 1376250661Sdavidcs device_printf(ha->pci_dev, "%s: reset seq checksum failed\n", 1377250661Sdavidcs __func__); 1378250661Sdavidcs return (-1); 1379250661Sdavidcs } 1380250661Sdavidcs 1381250661Sdavidcs buf = ql83xx_resetseq + hdr->init_seq_off; 1382250661Sdavidcs 1383250661Sdavidcs device_printf(ha->pci_dev, "%s: init sequence\n", __func__); 1384250661Sdavidcs if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) { 1385250661Sdavidcs device_printf(ha->pci_dev, "%s: init seq failed\n", __func__); 1386250661Sdavidcs return (-1); 1387250661Sdavidcs } 1388250661Sdavidcs 1389284982Sdavidcs#ifdef QL_LDFLASH_FW 1390250661Sdavidcs qla_load_fw_from_flash(ha); 1391250661Sdavidcs WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0); 1392284982Sdavidcs#else 1393284982Sdavidcs if (qla_load_bootldr(ha)) 1394284982Sdavidcs return -1; 1395250661Sdavidcs 1396284982Sdavidcs if (qla_load_fwimage(ha)) 1397284982Sdavidcs return -1; 1398284982Sdavidcs 1399284982Sdavidcs WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678); 1400284982Sdavidcs#endif /* #ifdef QL_LDFLASH_FW */ 1401284982Sdavidcs 1402284982Sdavidcs 1403250661Sdavidcs index = end_idx; 1404250661Sdavidcs buf = ql83xx_resetseq + hdr->start_seq_off; 1405250661Sdavidcs 1406250661Sdavidcs device_printf(ha->pci_dev, "%s: start sequence\n", __func__); 1407250661Sdavidcs if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) { 1408250661Sdavidcs device_printf(ha->pci_dev, "%s: init seq failed\n", __func__); 1409250661Sdavidcs return -1; 1410250661Sdavidcs } 1411250661Sdavidcs 1412250661Sdavidcs return (0); 1413250661Sdavidcs} 1414250661Sdavidcs 1415