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