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