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