Print this page
NEX-5717 import QLogic 16G FC drivers
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2010 QLogic Corporation.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "Copyright 2010 QLogic Corporation; ql_nx.c"
  28 
  29 /*
  30  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
  31  *
  32  * ***********************************************************************
  33  * *                                                                    **
  34  * *                            NOTICE                                  **
  35  * *            COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION              **
  36  * *                    ALL RIGHTS RESERVED                             **
  37  * *                                                                    **
  38  * ***********************************************************************
  39  *
  40  */
  41 
  42 #include <ql_apps.h>
  43 #include <ql_api.h>
  44 #include <ql_debug.h>

  45 #include <ql_mbx.h>
  46 #include <ql_nx.h>
  47 
  48 /*
  49  *  Local Function Prototypes.
  50  */
  51 static void *ql_8021_pci_base_offsetfset(ql_adapter_state_t *, uint64_t);
  52 static void ql_crb_addr_transform_setup(ql_adapter_state_t *);
  53 static void ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *, uint64_t *);
  54 static void ql_8021_wr_32(ql_adapter_state_t *, uint64_t, uint32_t);
  55 static void ql_8021_rd_32(ql_adapter_state_t *, uint64_t, uint32_t *);
  56 static int ql_8021_crb_win_lock(ql_adapter_state_t *);
  57 static void ql_8021_crb_win_unlock(ql_adapter_state_t *);
  58 static int ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *, uint64_t *);
  59 static uint32_t ql_8021_pci_mem_bound_check(ql_adapter_state_t *, uint64_t,
  60     uint32_t);
  61 static uint64_t ql_8021_pci_set_window(ql_adapter_state_t *, uint64_t);
  62 static int ql_8021_pci_is_same_window(ql_adapter_state_t *, uint64_t);
  63 static int ql_8021_pci_mem_read_direct(ql_adapter_state_t *, uint64_t, void *,
  64     uint32_t);
  65 static int ql_8021_pci_mem_write_direct(ql_adapter_state_t *, uint64_t, void *,
  66     uint32_t);
  67 static int ql_8021_pci_mem_read_2M(ql_adapter_state_t *, uint64_t, void *,
  68     uint32_t);
  69 static int ql_8021_pci_mem_write_2M(ql_adapter_state_t *, uint64_t, void *,
  70     uint32_t);
  71 static uint32_t ql_8021_decode_crb_addr(ql_adapter_state_t *, uint32_t);
  72 static int ql_8021_rom_lock(ql_adapter_state_t *);
  73 static void ql_8021_rom_unlock(ql_adapter_state_t *);
  74 static int ql_8021_wait_rom_done(ql_adapter_state_t *);
  75 static int ql_8021_wait_flash_done(ql_adapter_state_t *);
  76 static int ql_8021_do_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
  77 static int ql_8021_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
  78 static int ql_8021_do_rom_write(ql_adapter_state_t *, uint32_t, uint32_t);
  79 static int ql_8021_do_rom_erase(ql_adapter_state_t *, uint32_t);
  80 static int ql_8021_phantom_init(ql_adapter_state_t *);
  81 static int ql_8021_pinit_from_rom(ql_adapter_state_t *);
  82 static int ql_8021_load_from_flash(ql_adapter_state_t *);
  83 static int ql_8021_load_firmware(ql_adapter_state_t *);
  84 static int ql_8021_reset_hw(ql_adapter_state_t *, int);
  85 static int ql_8021_init_p3p(ql_adapter_state_t *);
  86 static int ql_8021_hw_lock(ql_adapter_state_t *, uint32_t);
  87 static void ql_8021_hw_unlock(ql_adapter_state_t *);
  88 static void ql_8021_need_reset_handler(ql_adapter_state_t *);





























  89 
  90 /*
  91  * Local Data.
  92  */
  93 static uint32_t crb_addr_xform[MAX_CRB_XFORM];
  94 static int      crb_table_initialized = 0;
  95 static int      pci_set_window_warning_count = 0;
  96 
  97 static struct legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
  98 
  99 static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
 100         {{{0, 0,         0,      0}}},                  /* 0: PCI */
 101         {{{1, 0x0100000, 0x0102000, 0x120000},          /* 1: PCIE */
 102             {1, 0x0110000, 0x0120000, 0x130000},
 103             {1, 0x0120000, 0x0122000, 0x124000},
 104             {1, 0x0130000, 0x0132000, 0x126000},
 105             {1, 0x0140000, 0x0142000, 0x128000},
 106             {1, 0x0150000, 0x0152000, 0x12a000},
 107             {1, 0x0160000, 0x0170000, 0x110000},
 108             {1, 0x0170000, 0x0172000, 0x12e000},


 306         UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
 307         UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
 308         UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
 309         UNM_HW_CRB_HUB_AGT_ADR_XDMA,
 310         UNM_HW_CRB_HUB_AGT_ADR_I2Q,
 311         UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
 312         0,
 313         UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
 314         UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
 315         UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
 316         UNM_HW_CRB_HUB_AGT_ADR_OCM0,
 317         0,
 318         UNM_HW_CRB_HUB_AGT_ADR_SMB,
 319         UNM_HW_CRB_HUB_AGT_ADR_I2C0,
 320         UNM_HW_CRB_HUB_AGT_ADR_I2C1,
 321         0,
 322         UNM_HW_CRB_HUB_AGT_ADR_PGNC,
 323         0,
 324 };
 325 
 326 static void *
 327 ql_8021_pci_base_offsetfset(ql_adapter_state_t *ha, uint64_t off)
 328 {
 329         if ((off < ha->first_page_group_end) &&
 330             (off >= ha->first_page_group_start)) {
 331                 return ((void *)(ha->nx_pcibase + off));
 332         }
 333 
 334         return (NULL);
 335 }
 336 
 337 /* ARGSUSED */
 338 static void
 339 ql_crb_addr_transform_setup(ql_adapter_state_t *ha)
 340 {
 341         crb_addr_transform(XDMA);
 342         crb_addr_transform(TIMR);
 343         crb_addr_transform(SRE);
 344         crb_addr_transform(SQN3);
 345         crb_addr_transform(SQN2);
 346         crb_addr_transform(SQN1);
 347         crb_addr_transform(SQN0);
 348         crb_addr_transform(SQS3);
 349         crb_addr_transform(SQS2);
 350         crb_addr_transform(SQS1);
 351         crb_addr_transform(SQS0);
 352         crb_addr_transform(RPMX7);
 353         crb_addr_transform(RPMX6);
 354         crb_addr_transform(RPMX5);
 355         crb_addr_transform(RPMX4);
 356         crb_addr_transform(RPMX3);


 387         crb_addr_transform(C2C1);
 388         crb_addr_transform(C2C0);
 389         crb_addr_transform(SMB);
 390         crb_addr_transform(OCM0);
 391         /*
 392          * Used only in P3 just define it for P2 also.
 393          */
 394         crb_addr_transform(I2C0);
 395 
 396         crb_table_initialized = 1;
 397 }
 398 
 399 /*
 400  * In: 'off' is offset from CRB space in 128M pci map
 401  * Out: 'off' is 2M pci map addr
 402  * side effect: lock crb window
 403  */
 404 static void
 405 ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *ha, uint64_t *off)
 406 {
 407         uint32_t        win_read;
 408 
 409         ha->crb_win = (uint32_t)CRB_HI(*off);
 410         WRT_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase, ha->crb_win);
 411 
 412         /*
 413          * Read back value to make sure write has gone through before trying
 414          * to use it.
 415          */
 416         win_read = RD_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase);
 417         if (win_read != ha->crb_win) {
 418                 EL(ha, "Written crbwin (0x%x) != Read crbwin (0x%x), "
 419                     "off=0x%llx\n", ha->crb_win, win_read, *off);
 420         }
 421         *off = (*off & MASK(16)) + CRB_INDIRECT_2M + (uintptr_t)ha->nx_pcibase;
 422 }
 423 
 424 static void
 425 ql_8021_wr_32(ql_adapter_state_t *ha, uint64_t off, uint32_t data)
 426 {
 427         int     rv;
 428 
 429         rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
 430         if (rv == -1) {
 431                 cmn_err(CE_PANIC, "ql_8021_wr_32, ql_8021_pci_get_crb_addr_"
 432                     "2M=-1\n");
 433         }
 434         if (rv == 1) {
 435                 (void) ql_8021_crb_win_lock(ha);
 436                 ql_8021_pci_set_crbwindow_2M(ha, &off);
 437         }
 438 
 439         WRT_REG_DWORD(ha, (uintptr_t)off, data);
 440 
 441         if (rv == 1) {
 442                 ql_8021_crb_win_unlock(ha);
 443         }
 444 }
 445 
 446 static void
 447 ql_8021_rd_32(ql_adapter_state_t *ha, uint64_t off, uint32_t *data)
 448 {
 449         int             rv;
 450         uint32_t        n;
 451 
 452         rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
 453         if (rv == -1) {
 454                 cmn_err(CE_PANIC, "ql_8021_rd_32, ql_8021_pci_get_crb_addr_"
 455                     "2M=-1\n");
 456         }
 457 
 458         if (rv == 1) {
 459                 (void) ql_8021_crb_win_lock(ha);
 460                 ql_8021_pci_set_crbwindow_2M(ha, &off);
 461         }
 462         n = RD_REG_DWORD(ha, (uintptr_t)off);
 463 
 464         if (data != NULL) {
 465                 *data = n;
 466         }


 473 static int
 474 ql_8021_crb_win_lock(ql_adapter_state_t *ha)
 475 {
 476         uint32_t        done = 0, timeout = 0;
 477 
 478         while (!done) {
 479                 /* acquire semaphore3 from PCI HW block */
 480                 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_LOCK), &done);
 481                 if (done == 1) {
 482                         break;
 483                 }
 484                 if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
 485                         EL(ha, "timeout\n");
 486                         return (-1);
 487                 }
 488                 timeout++;
 489 
 490                 /* Yield CPU */
 491                 delay(1);
 492         }
 493         ql_8021_wr_32(ha, UNM_CRB_WIN_LOCK_ID, ha->function_number);
 494 
 495         return (0);
 496 }
 497 
 498 static void
 499 ql_8021_crb_win_unlock(ql_adapter_state_t *ha)
 500 {
 501         ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_UNLOCK), NULL);
 502 }
 503 
 504 static int
 505 ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *ha, uint64_t *off)
 506 {
 507         crb_128M_2M_sub_block_map_t     *m;
 508 
 509         if (*off >= UNM_CRB_MAX) {
 510                 EL(ha, "%llx >= %llx\n", *off, UNM_CRB_MAX);
 511                 return (-1);
 512         }
 513 


 557             /*LINTED suspicious 0 comparison*/
 558             !QL_8021_ADDR_IN_RANGE(addr + size - 1, UNM_ADDR_DDR_NET,
 559             UNM_ADDR_DDR_NET_MAX) ||
 560             ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
 561                 return (0);
 562         }
 563 
 564         return (1);
 565 }
 566 
 567 static uint64_t
 568 ql_8021_pci_set_window(ql_adapter_state_t *ha, uint64_t addr)
 569 {
 570         uint32_t        window, win_read;
 571 
 572         /*LINTED suspicious 0 comparison*/
 573         if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
 574             UNM_ADDR_DDR_NET_MAX)) {
 575                 /* DDR network side */
 576                 window = (uint32_t)MN_WIN(addr);
 577                 ha->ddr_mn_window = window;
 578                 ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
 579                 ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
 580                     &win_read);
 581                 if ((win_read << 17) != window) {
 582                         EL(ha, "Warning, Written MNwin (0x%x) != Read MNwin "
 583                             "(0x%x)\n", window, win_read);
 584                 }
 585                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
 586         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
 587             UNM_ADDR_OCM0_MAX)) {
 588                 uint32_t        temp1;
 589 
 590                 if ((addr & 0x00ff800) == 0xff800) {
 591                         /* if bits 19:18&17:11 are on */
 592                         EL(ha, "QM access not handled\n");
 593                         addr = -1UL;
 594                 }
 595 
 596                 window = (uint32_t)OCM_WIN(addr);
 597                 ha->ddr_mn_window = window;
 598                 ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
 599                 ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
 600                     &win_read);
 601                 temp1 = ((window & 0x1FF) << 7) |
 602                     ((window & 0x0FFFE0000) >> 17);
 603                 if (win_read != temp1) {
 604                         EL(ha, "Written OCMwin (0x%x) != Read OCMwin (0x%x)\n",
 605                             temp1, win_read);
 606                 }
 607                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
 608         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
 609             NX_P3_ADDR_QDR_NET_MAX)) {
 610                 /* QDR network side */
 611                 window = (uint32_t)MS_WIN(addr);
 612                 ha->qdr_sn_window = window;
 613                 ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
 614                 ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
 615                     &win_read);
 616                 if (win_read != window) {
 617                         EL(ha, "Written MSwin (0x%x) != Read MSwin (0x%x)\n",
 618                             window, win_read);
 619                 }
 620                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
 621         } else {
 622                 /*
 623                  * peg gdb frequently accesses memory that doesn't exist,
 624                  * this limits the chit chat so debugging isn't slowed down.
 625                  */
 626                 if ((pci_set_window_warning_count++ < 8) ||
 627                     (pci_set_window_warning_count % 64 == 0)) {
 628                         EL(ha, "Unknown address range\n");
 629                 }
 630                 addr = -1UL;
 631         }
 632 
 633         return (addr);
 634 }
 635 


 667 
 668 static int
 669 ql_8021_pci_mem_read_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
 670     uint32_t size)
 671 {
 672         void            *addr;
 673         int             ret = 0;
 674         uint64_t        start;
 675 
 676         /*
 677          * If attempting to access unknown address or straddle hw windows,
 678          * do not access.
 679          */
 680         if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
 681             (ql_8021_pci_is_same_window(ha, off + size - 1) == 0)) {
 682                 EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
 683                     off);
 684                 return (-1);
 685         }
 686 
 687         addr = ql_8021_pci_base_offsetfset(ha, start);
 688         if (!addr) {
 689                 addr = (void *)((uint8_t *)ha->nx_pcibase + start);
 690         }
 691 
 692         switch (size) {
 693         case 1:
 694                 *(uint8_t  *)data = RD_REG_BYTE(ha, addr);
 695                 break;
 696         case 2:
 697                 *(uint16_t  *)data = RD_REG_WORD(ha, addr);
 698                 break;
 699         case 4:
 700                 *(uint32_t  *)data = RD_REG_DWORD(ha, addr);
 701                 break;
 702         case 8:
 703                 *(uint64_t  *)data = RD_REG_DDWORD(ha, addr);
 704                 break;
 705         default:
 706                 EL(ha, "invalid size=%x\n", size);
 707                 ret = -1;
 708                 break;
 709         }
 710 


 713 
 714 static int
 715 ql_8021_pci_mem_write_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
 716     uint32_t size)
 717 {
 718         void            *addr;
 719         int             ret = 0;
 720         uint64_t        start;
 721 
 722         /*
 723          * If attempting to access unknown address or straddle hw windows,
 724          * do not access.
 725          */
 726         if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
 727             (ql_8021_pci_is_same_window(ha, off + size -1) == 0)) {
 728                 EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
 729                     off);
 730                 return (-1);
 731         }
 732 
 733         addr = ql_8021_pci_base_offsetfset(ha, start);
 734         if (!addr) {
 735                 addr = (void *)((uint8_t *)ha->nx_pcibase + start);
 736         }
 737 
 738         switch (size) {
 739         case 1:
 740                 WRT_REG_BYTE(ha, addr, *(uint8_t *)data);
 741                 break;
 742         case 2:
 743                 WRT_REG_WORD(ha, addr, *(uint16_t *)data);
 744                 break;
 745         case 4:
 746                 WRT_REG_DWORD(ha, addr, *(uint32_t *)data);
 747                 break;
 748         case 8:
 749                 WRT_REG_DDWORD(ha, addr, *(uint64_t *)data);
 750                 break;
 751         default:
 752                 EL(ha, "invalid size=%x\n", size);
 753                 ret = -1;
 754                 break;
 755         }
 756 


 928                 tmpw = (uint64_t)(*((uint16_t *)data));
 929                 break;
 930         case 4:
 931                 tmpw = (uint64_t)(*((uint32_t *)data));
 932                 break;
 933         case 8:
 934         default:
 935                 tmpw = *((uint64_t *)data);
 936                 break;
 937         }
 938 
 939         if (p3p) {
 940                 if (sz[0] == 8) {
 941                         word[startword] = tmpw;
 942                 } else {
 943                         word[startword] &= ~((~(~0ULL << (sz[0] * 8))) <<
 944                             (off0 * 8));
 945                         word[startword] |= tmpw << (off0 * 8);
 946                 }
 947                 if (sz[1] != 0) {
 948                         word[startword+1] &= ~(~0ULL << (sz[1] * 8));
 949                         word[startword+1] |= tmpw >> (sz[0] * 8);
 950                 }
 951         } else {
 952                 word[startword] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
 953                 word[startword] |= tmpw << (off0 * 8);
 954 
 955                 if (loop == 2) {
 956                         word[1] &= ~(~0ULL << (sz[1] * 8));
 957                         word[1] |= tmpw >> (sz[0] * 8);
 958                 }
 959         }
 960 
 961         /*
 962          * don't lock here - write_wx gets the lock if each time
 963          * write_lock_irqsave(&adapter->adapter_lock, flags);
 964          * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
 965          */
 966 
 967         for (i = 0; i < loop; i++) {
 968                 temp = (uint32_t)(off8 + (i << shift_amount));
 969                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);


1102 
1103         while (done == 0) {
1104                 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_STATUS, &done);
1105                 done &= 2;
1106                 timeout++;
1107                 if (timeout >= ROM_MAX_TIMEOUT) {
1108                         EL(ha, "Timeout reached waiting for rom done\n");
1109                         return (-1);
1110                 }
1111         }
1112 
1113         return (0);
1114 }
1115 
1116 static int
1117 ql_8021_wait_flash_done(ql_adapter_state_t *ha)
1118 {
1119         clock_t         timer;
1120         uint32_t        status;
1121 
1122         for (timer = 30 * drv_usectohz(1000000); timer; timer--) {
1123                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1124                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1125                     UNM_ROMUSB_ROM_RDSR_INSTR);
1126                 if (ql_8021_wait_rom_done(ha)) {
1127                         EL(ha, "Error waiting for rom done2\n");
1128                         return (-1);
1129                 }
1130 
1131                 /* Get status. */
1132                 ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, &status);
1133                 if (!(status & BIT_0)) {
1134                         return (0);
1135                 }
1136                 delay(1);
1137         }
1138 
1139         EL(ha, "timeout status=%x\n", status);
1140         return (-1);
1141 }
1142 
1143 static int
1144 ql_8021_do_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
1145 {
1146         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1147         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
1148         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1149         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1150             UNM_ROMUSB_ROM_FAST_RD_INSTR);
1151         if (ql_8021_wait_rom_done(ha)) {
1152                 EL(ha, "Error waiting for rom done\n");
1153                 return (-1);
1154         }
1155         /* reset abyte_cnt and dummy_byte_cnt */
1156         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
1157         drv_usecwait(10);
1158         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1159 
1160         ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, valp);
1161 
1162         return (0);
1163 }
1164 
1165 int
1166 ql_8021_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
1167 {
1168         int     ret, loops = 0;
1169 
1170         while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1171                 drv_usecwait(100);
1172                 loops++;
1173         }
1174         if (loops >= 50000) {
1175                 EL(ha, "rom_lock failed\n");
1176                 return (-1);
1177         }
1178         ret = ql_8021_do_rom_fast_read(ha, addr, valp);
1179         ql_8021_rom_unlock(ha);
1180 
1181         return (ret);
1182 }
1183 
1184 static int
1185 ql_8021_do_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
1186 {
1187         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1188         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1189             UNM_ROMUSB_ROM_WREN_INSTR);
1190         if (ql_8021_wait_rom_done(ha)) {
1191                 EL(ha, "Error waiting for rom done\n");


1237 
1238         return (0);
1239 }
1240 
1241 int
1242 ql_8021_rom_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *bp)
1243 {
1244         int     ret;
1245 
1246         ret = ql_8021_rom_fast_read(ha, addr << 2, bp) == 0 ? QL_SUCCESS :
1247             QL_FUNCTION_FAILED;
1248 
1249         return (ret);
1250 }
1251 
1252 int
1253 ql_8021_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
1254 {
1255         int     ret, loops = 0;
1256 
1257         while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1258                 drv_usecwait(100);
1259                 loops++;
1260         }
1261         if (loops >= 50000) {
1262                 EL(ha, "rom_lock failed\n");
1263                 ret = QL_FUNCTION_TIMEOUT;
1264         } else {
1265                 ret = ql_8021_do_rom_write(ha, addr << 2, data) == 0 ?
1266                     QL_SUCCESS : QL_FUNCTION_FAILED;
1267                 ql_8021_rom_unlock(ha);
1268         }
1269 
1270         return (ret);
1271 }
1272 
1273 int
1274 ql_8021_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
1275 {
1276         int     ret, loops = 0;
1277 
1278         while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1279                 drv_usecwait(100);
1280                 loops++;
1281         }
1282         if (loops >= 50000) {
1283                 EL(ha, "rom_lock failed\n");
1284                 ret = QL_FUNCTION_TIMEOUT;
1285         } else {
1286                 ret = ql_8021_do_rom_erase(ha, addr << 2) == 0 ? QL_SUCCESS :
1287                     QL_FUNCTION_FAILED;
1288                 ql_8021_rom_unlock(ha);
1289         }
1290 
1291         return (ret);
1292 }
1293 
1294 int
1295 ql_8021_rom_wrsr(ql_adapter_state_t *ha, uint32_t data)
1296 {
1297         int     ret = QL_SUCCESS, loops = 0;
1298 
1299         while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1300                 drv_usecwait(100);
1301                 loops++;
1302         }
1303         if (loops >= 50000) {
1304                 EL(ha, "rom_lock failed\n");
1305                 ret = QL_FUNCTION_TIMEOUT;
1306         } else {
1307                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1308                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1309                     UNM_ROMUSB_ROM_WREN_INSTR);
1310                 if (ql_8021_wait_rom_done(ha)) {
1311                         EL(ha, "Error waiting for rom done\n");
1312                         ret = QL_FUNCTION_FAILED;
1313                 } else {
1314                         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
1315                         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1316                         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1317                             UNM_ROMUSB_ROM_WRSR_INSTR);
1318                         if (ql_8021_wait_rom_done(ha)) {
1319                                 EL(ha, "Error waiting for rom done1\n");
1320                                 ret = QL_FUNCTION_FAILED;


1362         if (!err) {
1363                 ql_8021_wr_32(ha, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
1364         }
1365 
1366         EL(ha, "firmware init failed=%x\n", val);
1367         return (-1);
1368 }
1369 
1370 static int
1371 ql_8021_pinit_from_rom(ql_adapter_state_t *ha)
1372 {
1373         int                     init_delay = 0;
1374         struct crb_addr_pair    *buf;
1375         uint32_t                offset, off, i, n, addr, val;
1376 
1377         /* Grab the lock so that no one can read flash when we reset the chip */
1378         (void) ql_8021_rom_lock(ha);
1379         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0xffffffff);
1380         /* Just in case it was held when we reset the chip */
1381         ql_8021_rom_unlock(ha);

1382 
1383         if (ql_8021_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafe ||
1384             ql_8021_rom_fast_read(ha, 4, &n) != 0) {
1385                 EL(ha, "ERROR Reading crb_init area: n: %08x\n", n);
1386                 return (-1);
1387         }
1388         offset = n & 0xffff;
1389         n = (n >> 16) & 0xffff;
1390         if (n >= 1024) {
1391                 EL(ha, "n=0x%x Error! NetXen card flash not initialized\n", n);
1392                 return (-1);
1393         }
1394 
1395         buf = kmem_zalloc(n * sizeof (struct crb_addr_pair), KM_SLEEP);
1396         if (buf == NULL) {
1397                 EL(ha, "Unable to zalloc memory\n");
1398                 return (-1);
1399         }
1400 
1401         for (i = 0; i < n; i++) {


1495         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0xc, 0);
1496         /* peg_clr 2 */
1497         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0x8, 0);
1498         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0xc, 0);
1499         /* peg_clr 3 */
1500         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0x8, 0);
1501         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0xc, 0);
1502 
1503         return (0);
1504 }
1505 
1506 static int
1507 ql_8021_load_from_flash(ql_adapter_state_t *ha)
1508 {
1509         int             i;
1510         uint32_t        flashaddr, memaddr;
1511         uint32_t        high, low, size;
1512         uint64_t        data;
1513 
1514         size = ha->bootloader_size / 2;
1515         flashaddr = ha->bootloader_addr << 2;
1516         memaddr = BOOTLD_START;
1517 
1518         for (i = 0; i < size; i++) {
1519                 if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1520                     (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1521                         EL(ha, "ql_8021_rom_fast_read != 0\n");
1522                         return (-1);
1523                 }
1524                 data = ((uint64_t)high << 32) | low;
1525                 (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);



1526                 flashaddr += 8;
1527                 memaddr += 8;





1528         }

1529 




1530         size = ha->flash_fw_size / 2;
1531         flashaddr = ha->flash_fw_addr << 2;
1532         memaddr = IMAGE_START;
1533 
1534         for (i = 0; i < size; i++) {
1535                 if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1536                     (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1537                         EL(ha, "ql_8021_rom_fast_read3 != 0\n");
1538                         return (-1);
1539                 }
1540                 data = ((uint64_t)high << 32) | low;
1541                 (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
1542                 flashaddr += 8;
1543                 memaddr += 8;
1544         }
1545 







1546         return (0);
1547 }
1548 
1549 static int
1550 ql_8021_load_firmware(ql_adapter_state_t *ha)
1551 {
1552         uint64_t        data;
1553         uint32_t        i, flashaddr, size;
1554         uint8_t         *bp, n, *dp;
1555 
1556         bp = (uint8_t *)(ha->risc_fw[0].code);
1557         dp = (uint8_t *)&size;
1558         for (n = 0; n < 4; n++) {
1559                 dp[n] = *bp++;
1560         }
1561         LITTLE_ENDIAN_32(&size);
1562         EL(ha, "signature=%x\n", size);
1563 
1564         size = (IMAGE_START - BOOTLD_START) / 8;

1565 
1566         bp = (uint8_t *)(ha->risc_fw[0].code + BOOTLD_START);
1567         flashaddr = BOOTLD_START;
1568 
1569         dp = (uint8_t *)&data;
1570         for (i = 0; i < size; i++) {
1571                 for (n = 0; n < 8; n++) {
1572                         dp[n] = *bp++;
1573                 }
1574                 LITTLE_ENDIAN_64(&data);
1575                 (void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);



1576                 flashaddr += 8;
1577         }
1578 
1579         bp = (uint8_t *)(ha->risc_fw[0].code + FW_SIZE_OFFSET);
1580         dp = (uint8_t *)&size;
1581         for (n = 0; n < 4; n++) {
1582                 dp[n] = *bp++;
1583         }
1584         LITTLE_ENDIAN_32(&size);
1585         EL(ha, "IMAGE_START size=%llx\n", size);
1586         size = (size + 7) / 8;
1587 
1588         bp = (uint8_t *)(ha->risc_fw[0].code + IMAGE_START);
1589         flashaddr = IMAGE_START;
1590 
1591         dp = (uint8_t *)&data;
1592         for (i = 0; i < size; i++) {
1593                 for (n = 0; n < 8; n++) {
1594                         dp[n] = *bp++;
1595                 }
1596                 LITTLE_ENDIAN_64(&data);
1597                 (void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);



1598                 flashaddr += 8;
1599         }
1600 
1601         return (0);
1602 }
1603 
1604 static int
1605 ql_8021_init_p3p(ql_adapter_state_t *ha)
1606 {
1607         uint32_t        data;
1608 
1609         /* ??? */
1610         ql_8021_wr_32(ha, UNM_PORT_MODE_ADDR, UNM_PORT_MODE_AUTO_NEG);
1611         delay(drv_usectohz(1000000));
1612 
1613         /* CAM RAM Cold Boot Register */
1614         ql_8021_rd_32(ha, UNM_RAM_COLD_BOOT, &data);
1615         if (data == 0x55555555) {
1616                 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &data);
1617                 if (data != 0x80000f) {


1629          * data = ha->pci_bus_addr | BIT_31;
1630          * ql_8021_wr_32(ha, UNM_BUS_DEV_NO, data);
1631          */
1632 
1633         return (0);
1634 }
1635 
1636 /* ARGSUSED */
1637 void
1638 ql_8021_reset_chip(ql_adapter_state_t *ha)
1639 {
1640         /*
1641          * Disable interrupts does not work on a per function bases
1642          * leave them enabled
1643          */
1644         ql_8021_enable_intrs(ha);
1645 
1646         ADAPTER_STATE_LOCK(ha);
1647         ha->flags |= INTERRUPTS_ENABLED;
1648         ADAPTER_STATE_UNLOCK(ha);
1649 
1650         (void) ql_stop_firmware(ha);

1651 }
1652 
1653 static int
1654 ql_8021_reset_hw(ql_adapter_state_t *ha, int type)
1655 {
1656         int             ret;
1657         uint32_t        rst;
1658 
1659         /* scrub dma mask expansion register */
1660         ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1661 
1662         /* Overwrite stale initialization register values */
1663         ql_8021_wr_32(ha, CRB_CMDPEG_STATE, 0);
1664         ql_8021_wr_32(ha, CRB_RCVPEG_STATE, 0);
1665         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0);
1666         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0);
1667 
1668         (void) ql_8021_pinit_from_rom(ha);





























1669         delay(1);
1670 







1671         /* Bring QM and CAMRAM out of reset */
1672         ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &rst);
1673         rst &= ~((1 << 28) | (1 << 24));
1674         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, rst);
1675 
1676         switch (type) {
1677         case 0:
1678                 ret = ql_8021_init_p3p(ha);
1679                 break;
1680         case 1:
1681                 ret = ql_8021_load_from_flash(ha);
1682                 break;
1683         case 2:
1684                 ret = ql_8021_load_firmware(ha);
1685                 break;
1686         }
1687         delay(1);
1688 
1689         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x18, 0x1020);
1690         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0x80001e);
1691 
1692         if (ret) {
1693                 EL(ha, "type=%d, ret=%d\n", type, ret);
1694         } else {
1695                 ret = ql_8021_phantom_init(ha);
1696         }
1697         return (ret);
1698 }
1699 
1700 int
1701 ql_8021_load_risc(ql_adapter_state_t *ha)
1702 {
1703         int             rv = 0;
1704         static int      ql_8021_fw_loaded = 0;
1705 
1706         GLOBAL_HW_LOCK();
1707         if (!ql_8021_fw_loaded) {
1708                 if (ha->risc_fw[0].code) {
1709                         EL(ha, "from driver\n");
1710                         rv = ql_8021_reset_hw(ha, 2);
1711                 } else {
1712                         /*
1713                          * BIOS method
1714                          * ql_8021_reset_hw(ha, 0)
1715                          */
1716                         EL(ha, "from flash\n");
1717                         rv = ql_8021_reset_hw(ha, 1);
1718                 }
1719                 if (rv == 0) {
1720                         ql_8021_fw_loaded = 1;
1721 
1722                         ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1723                         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0x0);
1724                         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0x0);
1725 
1726                         GLOBAL_HW_UNLOCK();
1727 
1728                         ADAPTER_STATE_LOCK(ha);
1729                         ha->flags &= ~INTERRUPTS_ENABLED;
1730                         ADAPTER_STATE_UNLOCK(ha);
1731 










1732                         (void) ql_8021_enable_intrs(ha);
1733 
1734                         ADAPTER_STATE_LOCK(ha);
1735                         ha->flags |= INTERRUPTS_ENABLED;
1736                         ADAPTER_STATE_UNLOCK(ha);
1737                 } else {
1738                         GLOBAL_HW_UNLOCK();
1739                 }
1740         } else {
1741                 GLOBAL_HW_UNLOCK();
1742                 EL(ha, "Firmware loaded by other function\n");
1743         }
1744 
1745         if (rv == 0) {
1746                 ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR, &ha->fw_major_version);
1747                 ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR, &ha->fw_minor_version);
1748                 ql_8021_rd_32(ha, UNM_FW_VERSION_SUB, &ha->fw_subminor_version);
1749                 EL(ha, "fw v%d.%02d.%02d\n", ha->fw_major_version,
1750                     ha->fw_minor_version, ha->fw_subminor_version);
1751         } else {
1752                 EL(ha, "status = -1\n");
1753                 return (QL_FUNCTION_FAILED);
1754         }
1755 
1756         return (QL_SUCCESS);
1757 }
1758 
1759 void
1760 ql_8021_clr_hw_intr(ql_adapter_state_t *ha)
1761 {
1762         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
1763         ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1764         ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1765 }
1766 
1767 void
1768 ql_8021_clr_fw_intr(ql_adapter_state_t *ha)
1769 {
1770         WRT32_IO_REG(ha, nx_risc_int, 0);
1771         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xfbff);
1772 }
1773 
1774 void
1775 ql_8021_enable_intrs(ql_adapter_state_t *ha)
1776 {
1777         GLOBAL_HW_LOCK();
1778         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
1779         GLOBAL_HW_UNLOCK();

1780         (void) ql_toggle_interrupt(ha, 1);

1781 }
1782 
1783 void
1784 ql_8021_disable_intrs(ql_adapter_state_t *ha)
1785 {
1786         (void) ql_toggle_interrupt(ha, 0);
1787         GLOBAL_HW_LOCK();
1788         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
1789         GLOBAL_HW_UNLOCK();
1790 }
1791 
1792 void
1793 ql_8021_update_crb_int_ptr(ql_adapter_state_t *ha)
1794 {
1795         struct legacy_intr_set  *nx_legacy_intr;
1796 
1797         ha->qdr_sn_window = (uint32_t)-1;
1798         ha->ddr_mn_window = (uint32_t)-1;
1799         nx_legacy_intr = &legacy_intr[ha->function_number];
1800 
1801         ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;
1802         ha->nx_legacy_intr.tgt_status_reg = nx_legacy_intr->tgt_status_reg;
1803         ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;
1804         ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
1805 }
1806 
1807 void
1808 ql_8021_set_drv_active(ql_adapter_state_t *ha)
1809 {
1810         uint32_t        val;
1811 
1812         if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1813                 return;
1814         }
1815 
1816         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1817         if (val == 0xffffffff) {
1818                 val = (1 << (ha->function_number * 4));
1819         } else {
1820                 val |= (1 << (ha->function_number * 4));
1821         }
1822         ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1823 
1824         ql_8021_hw_unlock(ha);
1825 }
1826 
1827 void
1828 ql_8021_clr_drv_active(ql_adapter_state_t *ha)
1829 {
1830         uint32_t        val;
1831 
1832         if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1833                 return;
1834         }
1835 
1836         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1837         val &= ~(1 << (ha->function_number * 4));
1838         ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1839 
1840         ql_8021_hw_unlock(ha);
1841 }
1842 
1843 static void
1844 ql_8021_need_reset_handler(ql_adapter_state_t *ha)
1845 {
1846         uint32_t        drv_state, drv_active;
1847         clock_t         timer;
1848 












1849         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1850 
1851         ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1852         drv_state |= (1 << (ha->function_number * 4));





1853         ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);





1854 
1855         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);



1856 




1857         ql_8021_hw_unlock(ha);
1858 
1859         for (timer = 30; timer && drv_state != drv_active; timer--) {
1860                 delay(100);
1861 
1862                 (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1863                 ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1864                 ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
1865                 ql_8021_hw_unlock(ha);








1866         }

1867 }
1868 
1869 uint32_t
1870 ql_8021_idc_handler(ql_adapter_state_t *ha)
1871 {
1872         uint32_t        dev_state, drv_state, rval;
1873         clock_t         timer;




















1874         ql_mbx_data_t   mr;
1875         boolean_t       stalled = B_FALSE, lock = B_FALSE;

1876 
1877         /* wait for 30 seconds for device to go ready */
1878         timer = 30;
1879         while (timer) {
1880                 if (lock == B_FALSE) {
1881                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1882                         lock = B_TRUE;
1883                 }






1884                 ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);

1885 
1886                 switch (dev_state) {
1887                 case 0xffffffff:
1888                 case NX_DEV_COLD:

1889                         EL(ha, "dev_state=NX_DEV_COLD\n");

1890                         rval = NX_DEV_COLD;
1891                         ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_INITIALIZING);
1892                         ql_8021_wr_32(ha, CRB_DRV_IDC_VERSION, NX_IDC_VERSION);
1893                         (void) ql_8021_hw_unlock(ha);
1894                         if (ql_get_fw_version(ha, &mr, 2) == QL_SUCCESS &&

1895                             (mr.mb[1] | mr.mb[2] | mr.mb[3])) {
1896                                 ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR,
1897                                     &ha->fw_major_version);
1898                                 ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR,
1899                                     &ha->fw_minor_version);
1900                                 ql_8021_rd_32(ha, UNM_FW_VERSION_SUB,
1901                                     &ha->fw_subminor_version);
1902                                 rval = NX_DEV_READY;
1903                         } else if (ql_8021_load_risc(ha) == QL_SUCCESS) {
1904                                 rval = NX_DEV_READY;






1905                         }






1906                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1907                         ql_8021_wr_32(ha, CRB_DEV_STATE, rval);
1908                         break;
1909                 case NX_DEV_READY:



1910                         rval = NX_DEV_READY;
1911                         timer = 0;
1912                         break;
1913                 case NX_DEV_FAILED:

1914                         EL(ha, "dev_state=NX_DEV_FAILED\n");

1915                         rval = NX_DEV_FAILED;
1916                         timer = 0;
1917                         break;
1918 
1919                 case NX_DEV_NEED_RESET:

1920                         EL(ha, "dev_state=NX_DEV_NEED_RESET\n");

1921                         rval = NX_DEV_NEED_RESET;
1922                         (void) ql_8021_hw_unlock(ha);
1923                         lock = B_FALSE;
1924                         if (ql_stall_driver(ha, 0) == QL_SUCCESS) {
1925                                 stalled = B_TRUE;
1926                                 ql_8021_need_reset_handler(ha);









1927                         }

1928                         break;
1929 
1930                 case NX_DEV_NEED_QUIESCENT:

1931                         EL(ha, "dev_state=NX_DEV_NEED_QUIESCENT\n");
1932                         (void) ql_8021_hw_unlock(ha);
1933                         lock = B_FALSE;
1934                         rval = ql_stall_driver(ha, 0);
1935                         if (rval == QL_SUCCESS) {
1936                                 stalled = B_TRUE;
1937                                 (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1938                                 lock = B_TRUE;
1939                                 ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1940                                 drv_state |=
1941                                     (2 << (ha->function_number * 4));
1942                                 ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);








1943                         }

1944                         break;
1945 
1946                 case NX_DEV_INITIALIZING:

1947                         EL(ha, "dev_state=NX_DEV_INITIALIZING\n");


















1948                         break;
1949                 case NX_DEV_QUIESCENT:

1950                         EL(ha, "dev_state=NX_DEV_QUIESCENT\n");




1951                         break;
1952                 default:

1953                         EL(ha, "dev_state=%x, default\n", dev_state);




1954                         break;
1955                 }
1956                 if (lock == B_TRUE) {
1957                         (void) ql_8021_hw_unlock(ha);
1958                         lock = B_FALSE;
1959                 }
1960 
1961                 if (timer) {








1962                         delay(100);
1963                         timer--;
1964                 }
1965         }
1966 
1967         if (stalled) {



1968                 ql_restart_driver(ha);
1969         }
1970         return (rval);












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































1971 }


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2015 QLogic Corporation.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "Copyright 2015 QLogic Corporation; ql_nx.c"
  28 
  29 /*
  30  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
  31  *
  32  * ***********************************************************************
  33  * *                                                                    **
  34  * *                            NOTICE                                  **
  35  * *            COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION              **
  36  * *                    ALL RIGHTS RESERVED                             **
  37  * *                                                                    **
  38  * ***********************************************************************
  39  *
  40  */
  41 
  42 #include <ql_apps.h>
  43 #include <ql_api.h>
  44 #include <ql_debug.h>
  45 #include <ql_init.h>
  46 #include <ql_mbx.h>
  47 #include <ql_nx.h>
  48 
  49 /*
  50  *  Local Function Prototypes.
  51  */

  52 static void ql_crb_addr_transform_setup(ql_adapter_state_t *);
  53 static void ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *, uint64_t *);


  54 static int ql_8021_crb_win_lock(ql_adapter_state_t *);
  55 static void ql_8021_crb_win_unlock(ql_adapter_state_t *);
  56 static int ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *, uint64_t *);
  57 static uint32_t ql_8021_pci_mem_bound_check(ql_adapter_state_t *, uint64_t,
  58     uint32_t);
  59 static uint64_t ql_8021_pci_set_window(ql_adapter_state_t *, uint64_t);
  60 static int ql_8021_pci_is_same_window(ql_adapter_state_t *, uint64_t);
  61 static int ql_8021_pci_mem_read_direct(ql_adapter_state_t *, uint64_t, void *,
  62     uint32_t);
  63 static int ql_8021_pci_mem_write_direct(ql_adapter_state_t *, uint64_t, void *,
  64     uint32_t);
  65 static int ql_8021_pci_mem_read_2M(ql_adapter_state_t *, uint64_t, void *,
  66     uint32_t);
  67 static int ql_8021_pci_mem_write_2M(ql_adapter_state_t *, uint64_t, void *,
  68     uint32_t);
  69 static uint32_t ql_8021_decode_crb_addr(ql_adapter_state_t *, uint32_t);
  70 static int ql_8021_rom_lock(ql_adapter_state_t *);
  71 static void ql_8021_rom_unlock(ql_adapter_state_t *);
  72 static int ql_8021_wait_rom_done(ql_adapter_state_t *);
  73 static int ql_8021_wait_flash_done(ql_adapter_state_t *);
  74 static int ql_8021_do_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
  75 static int ql_8021_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
  76 static int ql_8021_do_rom_write(ql_adapter_state_t *, uint32_t, uint32_t);
  77 static int ql_8021_do_rom_erase(ql_adapter_state_t *, uint32_t);
  78 static int ql_8021_phantom_init(ql_adapter_state_t *);
  79 static int ql_8021_pinit_from_rom(ql_adapter_state_t *);
  80 static int ql_8021_load_from_flash(ql_adapter_state_t *);
  81 static int ql_8021_load_firmware(ql_adapter_state_t *);
  82 static int ql_8021_reset_hw(ql_adapter_state_t *, int);
  83 static int ql_8021_init_p3p(ql_adapter_state_t *);
  84 static int ql_8021_hw_lock(ql_adapter_state_t *, uint32_t);
  85 static void ql_8021_hw_unlock(ql_adapter_state_t *);
  86 static void ql_8021_need_reset_handler(ql_adapter_state_t *);
  87 static int ql_8021_load_fw(ql_adapter_state_t *);
  88 static uint32_t ql_8021_check_fw_alive(ql_adapter_state_t *);
  89 static int ql_8021_get_fw_dump(ql_adapter_state_t *);
  90 static void ql_8021_md_parse_template(ql_adapter_state_t *, caddr_t, caddr_t,
  91     uint32_t, uint32_t);
  92 static int ql_8021_md_rdcrb(ql_adapter_state_t *, md_entry_rdcrb_t *,
  93     uint32_t *);
  94 static int ql_8021_md_L2Cache(ql_adapter_state_t *, md_entry_cache_t *,
  95     uint32_t *);
  96 static int ql_8021_md_L1Cache(ql_adapter_state_t *, md_entry_cache_t *,
  97     uint32_t *);
  98 static int ql_8021_md_rdocm(ql_adapter_state_t *, md_entry_rdocm_t *,
  99     uint32_t *);
 100 static int ql_8021_md_rdmem(ql_adapter_state_t *, md_entry_rdmem_t *,
 101     uint32_t *);
 102 static int ql_8021_md_rdrom(ql_adapter_state_t *, md_entry_rdrom_t *,
 103     uint32_t *);
 104 static int ql_8021_md_rdmux(ql_adapter_state_t *, md_entry_mux_t *,
 105     uint32_t *);
 106 static int ql_8021_md_rdqueue(ql_adapter_state_t *, md_entry_queue_t *,
 107     uint32_t *);
 108 static int ql_8021_md_cntrl(ql_adapter_state_t *, md_template_hdr_t *,
 109     md_entry_cntrl_t *);
 110 static void ql_8021_md_entry_err_chk(ql_adapter_state_t *, md_entry_t *,
 111     uint32_t, int);
 112 static uint32_t ql_8021_md_template_checksum(ql_adapter_state_t *);
 113 static uint32_t ql_8021_read_reg(ql_adapter_state_t *, uint32_t);
 114 static void ql_8021_write_reg(ql_adapter_state_t *, uint32_t, uint32_t);
 115 static uint32_t ql_8021_read_ocm(ql_adapter_state_t *, uint32_t);
 116 
 117 /*
 118  * Local Data.
 119  */
 120 static uint32_t crb_addr_xform[MAX_CRB_XFORM];
 121 static int      crb_table_initialized = 0;
 122 static int      pci_set_window_warning_count = 0;
 123 
 124 static struct legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
 125 
 126 static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
 127         {{{0, 0,         0,      0}}},                  /* 0: PCI */
 128         {{{1, 0x0100000, 0x0102000, 0x120000},          /* 1: PCIE */
 129             {1, 0x0110000, 0x0120000, 0x130000},
 130             {1, 0x0120000, 0x0122000, 0x124000},
 131             {1, 0x0130000, 0x0132000, 0x126000},
 132             {1, 0x0140000, 0x0142000, 0x128000},
 133             {1, 0x0150000, 0x0152000, 0x12a000},
 134             {1, 0x0160000, 0x0170000, 0x110000},
 135             {1, 0x0170000, 0x0172000, 0x12e000},


 333         UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
 334         UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
 335         UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
 336         UNM_HW_CRB_HUB_AGT_ADR_XDMA,
 337         UNM_HW_CRB_HUB_AGT_ADR_I2Q,
 338         UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
 339         0,
 340         UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
 341         UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
 342         UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
 343         UNM_HW_CRB_HUB_AGT_ADR_OCM0,
 344         0,
 345         UNM_HW_CRB_HUB_AGT_ADR_SMB,
 346         UNM_HW_CRB_HUB_AGT_ADR_I2C0,
 347         UNM_HW_CRB_HUB_AGT_ADR_I2C1,
 348         0,
 349         UNM_HW_CRB_HUB_AGT_ADR_PGNC,
 350         0,
 351 };
 352 











 353 /* ARGSUSED */
 354 static void
 355 ql_crb_addr_transform_setup(ql_adapter_state_t *ha)
 356 {
 357         crb_addr_transform(XDMA);
 358         crb_addr_transform(TIMR);
 359         crb_addr_transform(SRE);
 360         crb_addr_transform(SQN3);
 361         crb_addr_transform(SQN2);
 362         crb_addr_transform(SQN1);
 363         crb_addr_transform(SQN0);
 364         crb_addr_transform(SQS3);
 365         crb_addr_transform(SQS2);
 366         crb_addr_transform(SQS1);
 367         crb_addr_transform(SQS0);
 368         crb_addr_transform(RPMX7);
 369         crb_addr_transform(RPMX6);
 370         crb_addr_transform(RPMX5);
 371         crb_addr_transform(RPMX4);
 372         crb_addr_transform(RPMX3);


 403         crb_addr_transform(C2C1);
 404         crb_addr_transform(C2C0);
 405         crb_addr_transform(SMB);
 406         crb_addr_transform(OCM0);
 407         /*
 408          * Used only in P3 just define it for P2 also.
 409          */
 410         crb_addr_transform(I2C0);
 411 
 412         crb_table_initialized = 1;
 413 }
 414 
 415 /*
 416  * In: 'off' is offset from CRB space in 128M pci map
 417  * Out: 'off' is 2M pci map addr
 418  * side effect: lock crb window
 419  */
 420 static void
 421 ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *ha, uint64_t *off)
 422 {
 423         uint32_t        win_read, crb_win;
 424 
 425         crb_win = (uint32_t)CRB_HI(*off);
 426         WRT_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase, crb_win);
 427 
 428         /*
 429          * Read back value to make sure write has gone through before trying
 430          * to use it.
 431          */
 432         win_read = RD_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase);
 433         if (win_read != crb_win) {
 434                 EL(ha, "Written crbwin (0x%x) != Read crbwin (0x%x), "
 435                     "off=0x%llx\n", crb_win, win_read, *off);
 436         }
 437         *off = (*off & MASK(16)) + CRB_INDIRECT_2M + (uintptr_t)ha->nx_pcibase;
 438 }
 439 
 440 void
 441 ql_8021_wr_32(ql_adapter_state_t *ha, uint64_t off, uint32_t data)
 442 {
 443         int     rv;
 444 
 445         rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
 446         if (rv == -1) {
 447                 cmn_err(CE_PANIC, "ql_8021_wr_32, ql_8021_pci_get_crb_addr_"
 448                     "2M=-1\n");
 449         }
 450         if (rv == 1) {
 451                 (void) ql_8021_crb_win_lock(ha);
 452                 ql_8021_pci_set_crbwindow_2M(ha, &off);
 453         }
 454 
 455         WRT_REG_DWORD(ha, (uintptr_t)off, data);
 456 
 457         if (rv == 1) {
 458                 ql_8021_crb_win_unlock(ha);
 459         }
 460 }
 461 
 462 void
 463 ql_8021_rd_32(ql_adapter_state_t *ha, uint64_t off, uint32_t *data)
 464 {
 465         int             rv;
 466         uint32_t        n;
 467 
 468         rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
 469         if (rv == -1) {
 470                 cmn_err(CE_PANIC, "ql_8021_rd_32, ql_8021_pci_get_crb_addr_"
 471                     "2M=-1\n");
 472         }
 473 
 474         if (rv == 1) {
 475                 (void) ql_8021_crb_win_lock(ha);
 476                 ql_8021_pci_set_crbwindow_2M(ha, &off);
 477         }
 478         n = RD_REG_DWORD(ha, (uintptr_t)off);
 479 
 480         if (data != NULL) {
 481                 *data = n;
 482         }


 489 static int
 490 ql_8021_crb_win_lock(ql_adapter_state_t *ha)
 491 {
 492         uint32_t        done = 0, timeout = 0;
 493 
 494         while (!done) {
 495                 /* acquire semaphore3 from PCI HW block */
 496                 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_LOCK), &done);
 497                 if (done == 1) {
 498                         break;
 499                 }
 500                 if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
 501                         EL(ha, "timeout\n");
 502                         return (-1);
 503                 }
 504                 timeout++;
 505 
 506                 /* Yield CPU */
 507                 delay(1);
 508         }
 509         ql_8021_wr_32(ha, UNM_CRB_WIN_LOCK_ID, ha->pci_function_number);
 510 
 511         return (0);
 512 }
 513 
 514 static void
 515 ql_8021_crb_win_unlock(ql_adapter_state_t *ha)
 516 {
 517         ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_UNLOCK), NULL);
 518 }
 519 
 520 static int
 521 ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *ha, uint64_t *off)
 522 {
 523         crb_128M_2M_sub_block_map_t     *m;
 524 
 525         if (*off >= UNM_CRB_MAX) {
 526                 EL(ha, "%llx >= %llx\n", *off, UNM_CRB_MAX);
 527                 return (-1);
 528         }
 529 


 573             /*LINTED suspicious 0 comparison*/
 574             !QL_8021_ADDR_IN_RANGE(addr + size - 1, UNM_ADDR_DDR_NET,
 575             UNM_ADDR_DDR_NET_MAX) ||
 576             ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
 577                 return (0);
 578         }
 579 
 580         return (1);
 581 }
 582 
 583 static uint64_t
 584 ql_8021_pci_set_window(ql_adapter_state_t *ha, uint64_t addr)
 585 {
 586         uint32_t        window, win_read;
 587 
 588         /*LINTED suspicious 0 comparison*/
 589         if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
 590             UNM_ADDR_DDR_NET_MAX)) {
 591                 /* DDR network side */
 592                 window = (uint32_t)MN_WIN(addr);
 593                 ql_8021_wr_32(ha, UNM_PCI_CRBSPACE, window);
 594                 ql_8021_rd_32(ha, UNM_PCI_CRBSPACE, &win_read);


 595                 if ((win_read << 17) != window) {
 596                         EL(ha, "Warning, Written MNwin (0x%x) != Read MNwin "
 597                             "(0x%x)\n", window, win_read);
 598                 }
 599                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
 600         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
 601             UNM_ADDR_OCM0_MAX)) {
 602                 uint32_t        temp1;
 603 
 604                 if ((addr & 0x00ff800) == 0xff800) {
 605                         /* if bits 19:18&17:11 are on */
 606                         EL(ha, "QM access not handled\n");
 607                         addr = -1UL;
 608                 }
 609 
 610                 window = (uint32_t)OCM_WIN(addr);
 611                 ql_8021_wr_32(ha, UNM_PCI_CRBSPACE, window);
 612                 ql_8021_rd_32(ha, UNM_PCI_CRBSPACE, &win_read);


 613                 temp1 = ((window & 0x1FF) << 7) |
 614                     ((window & 0x0FFFE0000) >> 17);
 615                 if (win_read != temp1) {
 616                         EL(ha, "Written OCMwin (0x%x) != Read OCMwin (0x%x)\n",
 617                             temp1, win_read);
 618                 }
 619                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
 620         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
 621             NX_P3_ADDR_QDR_NET_MAX)) {
 622                 /* QDR network side */
 623                 window = (uint32_t)MS_WIN(addr);
 624                 ha->qdr_sn_window = window;
 625                 ql_8021_wr_32(ha, UNM_PCI_CRBSPACE, window);
 626                 ql_8021_rd_32(ha, UNM_PCI_CRBSPACE, &win_read);

 627                 if (win_read != window) {
 628                         EL(ha, "Written MSwin (0x%x) != Read MSwin (0x%x)\n",
 629                             window, win_read);
 630                 }
 631                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
 632         } else {
 633                 /*
 634                  * peg gdb frequently accesses memory that doesn't exist,
 635                  * this limits the chit chat so debugging isn't slowed down.
 636                  */
 637                 if ((pci_set_window_warning_count++ < 8) ||
 638                     (pci_set_window_warning_count % 64 == 0)) {
 639                         EL(ha, "Unknown address range\n");
 640                 }
 641                 addr = -1UL;
 642         }
 643 
 644         return (addr);
 645 }
 646 


 678 
 679 static int
 680 ql_8021_pci_mem_read_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
 681     uint32_t size)
 682 {
 683         void            *addr;
 684         int             ret = 0;
 685         uint64_t        start;
 686 
 687         /*
 688          * If attempting to access unknown address or straddle hw windows,
 689          * do not access.
 690          */
 691         if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
 692             (ql_8021_pci_is_same_window(ha, off + size - 1) == 0)) {
 693                 EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
 694                     off);
 695                 return (-1);
 696         }
 697 


 698         addr = (void *)((uint8_t *)ha->nx_pcibase + start);

 699 
 700         switch (size) {
 701         case 1:
 702                 *(uint8_t *)data = RD_REG_BYTE(ha, addr);
 703                 break;
 704         case 2:
 705                 *(uint16_t *)data = RD_REG_WORD(ha, addr);
 706                 break;
 707         case 4:
 708                 *(uint32_t *)data = RD_REG_DWORD(ha, addr);
 709                 break;
 710         case 8:
 711                 *(uint64_t *)data = RD_REG_DDWORD(ha, addr);
 712                 break;
 713         default:
 714                 EL(ha, "invalid size=%x\n", size);
 715                 ret = -1;
 716                 break;
 717         }
 718 


 721 
 722 static int
 723 ql_8021_pci_mem_write_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
 724     uint32_t size)
 725 {
 726         void            *addr;
 727         int             ret = 0;
 728         uint64_t        start;
 729 
 730         /*
 731          * If attempting to access unknown address or straddle hw windows,
 732          * do not access.
 733          */
 734         if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
 735             (ql_8021_pci_is_same_window(ha, off + size -1) == 0)) {
 736                 EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
 737                     off);
 738                 return (-1);
 739         }
 740 


 741         addr = (void *)((uint8_t *)ha->nx_pcibase + start);

 742 
 743         switch (size) {
 744         case 1:
 745                 WRT_REG_BYTE(ha, addr, *(uint8_t *)data);
 746                 break;
 747         case 2:
 748                 WRT_REG_WORD(ha, addr, *(uint16_t *)data);
 749                 break;
 750         case 4:
 751                 WRT_REG_DWORD(ha, addr, *(uint32_t *)data);
 752                 break;
 753         case 8:
 754                 WRT_REG_DDWORD(ha, addr, *(uint64_t *)data);
 755                 break;
 756         default:
 757                 EL(ha, "invalid size=%x\n", size);
 758                 ret = -1;
 759                 break;
 760         }
 761 


 933                 tmpw = (uint64_t)(*((uint16_t *)data));
 934                 break;
 935         case 4:
 936                 tmpw = (uint64_t)(*((uint32_t *)data));
 937                 break;
 938         case 8:
 939         default:
 940                 tmpw = *((uint64_t *)data);
 941                 break;
 942         }
 943 
 944         if (p3p) {
 945                 if (sz[0] == 8) {
 946                         word[startword] = tmpw;
 947                 } else {
 948                         word[startword] &= ~((~(~0ULL << (sz[0] * 8))) <<
 949                             (off0 * 8));
 950                         word[startword] |= tmpw << (off0 * 8);
 951                 }
 952                 if (sz[1] != 0) {
 953                         word[startword + 1] &= ~(~0ULL << (sz[1] * 8));
 954                         word[startword + 1] |= tmpw >> (sz[0] * 8);
 955                 }
 956         } else {
 957                 word[startword] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
 958                 word[startword] |= tmpw << (off0 * 8);
 959 
 960                 if (loop == 2) {
 961                         word[1] &= ~(~0ULL << (sz[1] * 8));
 962                         word[1] |= tmpw >> (sz[0] * 8);
 963                 }
 964         }
 965 
 966         /*
 967          * don't lock here - write_wx gets the lock if each time
 968          * write_lock_irqsave(&adapter->adapter_lock, flags);
 969          * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
 970          */
 971 
 972         for (i = 0; i < loop; i++) {
 973                 temp = (uint32_t)(off8 + (i << shift_amount));
 974                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);


1107 
1108         while (done == 0) {
1109                 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_STATUS, &done);
1110                 done &= 2;
1111                 timeout++;
1112                 if (timeout >= ROM_MAX_TIMEOUT) {
1113                         EL(ha, "Timeout reached waiting for rom done\n");
1114                         return (-1);
1115                 }
1116         }
1117 
1118         return (0);
1119 }
1120 
1121 static int
1122 ql_8021_wait_flash_done(ql_adapter_state_t *ha)
1123 {
1124         clock_t         timer;
1125         uint32_t        status;
1126 
1127         for (timer = 500000; timer; timer--) {
1128                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1129                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1130                     UNM_ROMUSB_ROM_RDSR_INSTR);
1131                 if (ql_8021_wait_rom_done(ha)) {
1132                         EL(ha, "Error waiting for rom done2\n");
1133                         return (-1);
1134                 }
1135 
1136                 /* Get status. */
1137                 ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, &status);
1138                 if (!(status & BIT_0)) {
1139                         return (0);
1140                 }
1141                 drv_usecwait(10);
1142         }
1143 
1144         EL(ha, "timeout status=%x\n", status);
1145         return (-1);
1146 }
1147 
1148 static int
1149 ql_8021_do_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
1150 {
1151         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1152         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
1153         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1154         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1155             UNM_ROMUSB_ROM_FAST_RD_INSTR);
1156         if (ql_8021_wait_rom_done(ha)) {
1157                 EL(ha, "Error waiting for rom done\n");
1158                 return (-1);
1159         }
1160         /* reset abyte_cnt and dummy_byte_cnt */
1161         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
1162         drv_usecwait(10);
1163         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1164 
1165         ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, valp);
1166 
1167         return (0);
1168 }
1169 
1170 int
1171 ql_8021_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
1172 {
1173         int     ret, loops = 0;
1174 
1175         while ((ql_8021_rom_lock(ha) != 0) && (loops < 500000)) {
1176                 drv_usecwait(10);
1177                 loops++;
1178         }
1179         if (loops >= 50000) {
1180                 EL(ha, "rom_lock failed\n");
1181                 return (-1);
1182         }
1183         ret = ql_8021_do_rom_fast_read(ha, addr, valp);
1184         ql_8021_rom_unlock(ha);
1185 
1186         return (ret);
1187 }
1188 
1189 static int
1190 ql_8021_do_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
1191 {
1192         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1193         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1194             UNM_ROMUSB_ROM_WREN_INSTR);
1195         if (ql_8021_wait_rom_done(ha)) {
1196                 EL(ha, "Error waiting for rom done\n");


1242 
1243         return (0);
1244 }
1245 
1246 int
1247 ql_8021_rom_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *bp)
1248 {
1249         int     ret;
1250 
1251         ret = ql_8021_rom_fast_read(ha, addr << 2, bp) == 0 ? QL_SUCCESS :
1252             QL_FUNCTION_FAILED;
1253 
1254         return (ret);
1255 }
1256 
1257 int
1258 ql_8021_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
1259 {
1260         int     ret, loops = 0;
1261 
1262         while ((ql_8021_rom_lock(ha) != 0) && (loops < 500000)) {
1263                 drv_usecwait(10);
1264                 loops++;
1265         }
1266         if (loops >= 50000) {
1267                 EL(ha, "rom_lock failed\n");
1268                 ret = QL_FUNCTION_TIMEOUT;
1269         } else {
1270                 ret = ql_8021_do_rom_write(ha, addr << 2, data) == 0 ?
1271                     QL_SUCCESS : QL_FUNCTION_FAILED;
1272                 ql_8021_rom_unlock(ha);
1273         }
1274 
1275         return (ret);
1276 }
1277 
1278 int
1279 ql_8021_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
1280 {
1281         int     ret, loops = 0;
1282 
1283         while ((ql_8021_rom_lock(ha) != 0) && (loops < 500000)) {
1284                 drv_usecwait(10);
1285                 loops++;
1286         }
1287         if (loops >= 50000) {
1288                 EL(ha, "rom_lock failed\n");
1289                 ret = QL_FUNCTION_TIMEOUT;
1290         } else {
1291                 ret = ql_8021_do_rom_erase(ha, addr << 2) == 0 ? QL_SUCCESS :
1292                     QL_FUNCTION_FAILED;
1293                 ql_8021_rom_unlock(ha);
1294         }
1295 
1296         return (ret);
1297 }
1298 
1299 int
1300 ql_8021_rom_wrsr(ql_adapter_state_t *ha, uint32_t data)
1301 {
1302         int     ret = QL_SUCCESS, loops = 0;
1303 
1304         while ((ql_8021_rom_lock(ha) != 0) && (loops < 500000)) {
1305                 drv_usecwait(10);
1306                 loops++;
1307         }
1308         if (loops >= 50000) {
1309                 EL(ha, "rom_lock failed\n");
1310                 ret = QL_FUNCTION_TIMEOUT;
1311         } else {
1312                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1313                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1314                     UNM_ROMUSB_ROM_WREN_INSTR);
1315                 if (ql_8021_wait_rom_done(ha)) {
1316                         EL(ha, "Error waiting for rom done\n");
1317                         ret = QL_FUNCTION_FAILED;
1318                 } else {
1319                         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
1320                         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1321                         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1322                             UNM_ROMUSB_ROM_WRSR_INSTR);
1323                         if (ql_8021_wait_rom_done(ha)) {
1324                                 EL(ha, "Error waiting for rom done1\n");
1325                                 ret = QL_FUNCTION_FAILED;


1367         if (!err) {
1368                 ql_8021_wr_32(ha, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
1369         }
1370 
1371         EL(ha, "firmware init failed=%x\n", val);
1372         return (-1);
1373 }
1374 
1375 static int
1376 ql_8021_pinit_from_rom(ql_adapter_state_t *ha)
1377 {
1378         int                     init_delay = 0;
1379         struct crb_addr_pair    *buf;
1380         uint32_t                offset, off, i, n, addr, val;
1381 
1382         /* Grab the lock so that no one can read flash when we reset the chip */
1383         (void) ql_8021_rom_lock(ha);
1384         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0xffffffff);
1385         /* Just in case it was held when we reset the chip */
1386         ql_8021_rom_unlock(ha);
1387         delay(100);
1388 
1389         if (ql_8021_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafe ||
1390             ql_8021_rom_fast_read(ha, 4, &n) != 0) {
1391                 EL(ha, "ERROR Reading crb_init area: n: %08x\n", n);
1392                 return (-1);
1393         }
1394         offset = n & 0xffff;
1395         n = (n >> 16) & 0xffff;
1396         if (n >= 1024) {
1397                 EL(ha, "n=0x%x Error! NetXen card flash not initialized\n", n);
1398                 return (-1);
1399         }
1400 
1401         buf = kmem_zalloc(n * sizeof (struct crb_addr_pair), KM_SLEEP);
1402         if (buf == NULL) {
1403                 EL(ha, "Unable to zalloc memory\n");
1404                 return (-1);
1405         }
1406 
1407         for (i = 0; i < n; i++) {


1501         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0xc, 0);
1502         /* peg_clr 2 */
1503         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0x8, 0);
1504         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0xc, 0);
1505         /* peg_clr 3 */
1506         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0x8, 0);
1507         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0xc, 0);
1508 
1509         return (0);
1510 }
1511 
1512 static int
1513 ql_8021_load_from_flash(ql_adapter_state_t *ha)
1514 {
1515         int             i;
1516         uint32_t        flashaddr, memaddr;
1517         uint32_t        high, low, size;
1518         uint64_t        data;
1519 
1520         size = ha->bootloader_size / 2;
1521         memaddr = flashaddr = ha->bootloader_addr << 2;

1522 
1523         for (i = 0; i < size; i++) {
1524                 if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1525                     (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1526                         EL(ha, "ql_8021_rom_fast_read != 0\n");
1527                         return (-1);
1528                 }
1529                 data = ((uint64_t)high << 32) | low;
1530                 if (ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8)) {
1531                         EL(ha, "qla_fc_8021_pci_mem_write_2M != 0\n");
1532                         return (-1);
1533                 }
1534                 flashaddr += 8;
1535                 memaddr += 8;
1536 
1537                 /* Allow other system activity. */
1538                 if (i % 0x1000 == 0) {
1539                         /* Delay for 1 tick (10ms). */
1540                         delay(1);
1541                 }
1542         }
1543 
1544 #if 0
1545         /* Allow other system activity, delay for 1 tick (10ms). */
1546         delay(1);
1547 
1548         size = ha->flash_fw_size / 2;
1549         memaddr = flashaddr = ha->flash_fw_addr << 2;

1550 
1551         for (i = 0; i < size; i++) {
1552                 if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1553                     (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1554                         EL(ha, "ql_8021_rom_fast_read3 != 0\n");
1555                         return (-1);
1556                 }
1557                 data = ((uint64_t)high << 32) | low;
1558                 (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
1559                 flashaddr += 8;
1560                 memaddr += 8;

1561 
1562                 /* Allow other system activity. */
1563                 if (i % 0x1000 == 0) {
1564                         /* Delay for 1 tick (10ms). */
1565                         delay(1);
1566                 }
1567         }
1568 #endif
1569         return (0);
1570 }
1571 
1572 static int
1573 ql_8021_load_firmware(ql_adapter_state_t *ha)
1574 {
1575         uint64_t        data;
1576         uint32_t        i, flashaddr, size;
1577         uint8_t         *bp, n, *dp;
1578 
1579         bp = (uint8_t *)(ha->risc_fw[0].code);
1580         dp = (uint8_t *)&size;
1581         for (n = 0; n < 4; n++) {
1582                 dp[n] = *bp++;
1583         }
1584         LITTLE_ENDIAN_32(&size);
1585         EL(ha, "signature=%x\n", size);
1586 
1587         size = ha->bootloader_size / 2;
1588         flashaddr = ha->bootloader_addr << 2;
1589 
1590         bp = (uint8_t *)(ha->risc_fw[0].code + flashaddr);


1591         dp = (uint8_t *)&data;
1592         for (i = 0; i < size; i++) {
1593                 for (n = 0; n < 8; n++) {
1594                         dp[n] = *bp++;
1595                 }
1596                 LITTLE_ENDIAN_64(&data);
1597                 if (ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8)) {
1598                         EL(ha, "qla_fc_8021_pci_mem_write_2M != 0\n");
1599                         return (-1);
1600                 }
1601                 flashaddr += 8;
1602         }
1603 
1604         bp = (uint8_t *)(ha->risc_fw[0].code + FW_SIZE_OFFSET);
1605         dp = (uint8_t *)&size;
1606         for (n = 0; n < 4; n++) {
1607                 dp[n] = *bp++;
1608         }
1609         LITTLE_ENDIAN_32(&size);
1610         EL(ha, "IMAGE_START size=%llx\n", size);
1611         size = (size + 7) / 8;
1612 
1613         flashaddr = ha->flash_fw_addr << 2;
1614         bp = (uint8_t *)(ha->risc_fw[0].code + flashaddr);
1615 
1616         dp = (uint8_t *)&data;
1617         for (i = 0; i < size; i++) {
1618                 for (n = 0; n < 8; n++) {
1619                         dp[n] = *bp++;
1620                 }
1621                 LITTLE_ENDIAN_64(&data);
1622                 if (ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8)) {
1623                         EL(ha, "qla_fc_8021_pci_mem_write_2M != 0\n");
1624                         return (-1);
1625                 }
1626                 flashaddr += 8;
1627         }
1628 
1629         return (0);
1630 }
1631 
1632 static int
1633 ql_8021_init_p3p(ql_adapter_state_t *ha)
1634 {
1635         uint32_t        data;
1636 
1637         /* ??? */
1638         ql_8021_wr_32(ha, UNM_PORT_MODE_ADDR, UNM_PORT_MODE_AUTO_NEG);
1639         delay(drv_usectohz(1000000));
1640 
1641         /* CAM RAM Cold Boot Register */
1642         ql_8021_rd_32(ha, UNM_RAM_COLD_BOOT, &data);
1643         if (data == 0x55555555) {
1644                 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &data);
1645                 if (data != 0x80000f) {


1657          * data = ha->pci_bus_addr | BIT_31;
1658          * ql_8021_wr_32(ha, UNM_BUS_DEV_NO, data);
1659          */
1660 
1661         return (0);
1662 }
1663 
1664 /* ARGSUSED */
1665 void
1666 ql_8021_reset_chip(ql_adapter_state_t *ha)
1667 {
1668         /*
1669          * Disable interrupts does not work on a per function bases
1670          * leave them enabled
1671          */
1672         ql_8021_enable_intrs(ha);
1673 
1674         ADAPTER_STATE_LOCK(ha);
1675         ha->flags |= INTERRUPTS_ENABLED;
1676         ADAPTER_STATE_UNLOCK(ha);
1677         if (!(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
1678                 (void) ql_stop_firmware(ha);
1679         }
1680 }
1681 
1682 static int
1683 ql_8021_reset_hw(ql_adapter_state_t *ha, int type)
1684 {
1685         int             ret;
1686         uint32_t        rst;
1687 
1688         /* scrub dma mask expansion register */
1689         ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1690 
1691         /* Overwrite stale initialization register values */
1692         ql_8021_wr_32(ha, CRB_CMDPEG_STATE, 0);
1693         ql_8021_wr_32(ha, CRB_RCVPEG_STATE, 0);
1694         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0);
1695         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0);
1696 
1697         /*
1698          * This reset sequence is to provide a graceful shutdown of the
1699          * different hardware blocks prior to performing an ASIC Reset,
1700          * has to be done before writing 0xffffffff to ASIC_RESET.
1701          */
1702         ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x10, 0);
1703         ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x14, 0);
1704         ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x18, 0);
1705         ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x1c, 0);
1706         ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x20, 0);
1707         ql_8021_wr_32(ha, UNM_CRB_I2Q + 0x24, 0);
1708         ql_8021_wr_32(ha, UNM_CRB_NIU + 0x40, 0xff);
1709         ql_8021_wr_32(ha, UNM_CRB_NIU + 0x70000, 0x0);
1710         ql_8021_wr_32(ha, UNM_CRB_NIU + 0x80000, 0x0);
1711         ql_8021_wr_32(ha, UNM_CRB_NIU + 0x90000, 0x0);
1712         ql_8021_wr_32(ha, UNM_CRB_NIU + 0xa0000, 0x0);
1713         ql_8021_wr_32(ha, UNM_CRB_NIU + 0xb0000, 0x0);
1714         ql_8021_wr_32(ha, UNM_CRB_SRE + 0x1000, 0x28ff000c);
1715         ql_8021_wr_32(ha, UNM_CRB_EPG + 0x1300, 0x1);
1716         ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x0, 0x0);
1717         ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x8, 0x0);
1718         ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x10, 0x0);
1719         ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x18, 0x0);
1720         ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x100, 0x0);
1721         ql_8021_wr_32(ha, UNM_CRB_TIMER + 0x200, 0x0);
1722         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x3C, 0x1);
1723         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0x3C, 0x1);
1724         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0x3C, 0x1);
1725         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0x3C, 0x1);
1726         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_4 + 0x3C, 0x1);
1727         delay(1);
1728 
1729         ret = ql_8021_pinit_from_rom(ha);
1730         if (ret) {
1731                 EL(ha, "pinit_from_rom ret=%d\n", ret);
1732                 return (ret);
1733         }
1734         delay(1);
1735 
1736         /* Bring QM and CAMRAM out of reset */
1737         ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &rst);
1738         rst &= ~((1 << 28) | (1 << 24));
1739         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, rst);
1740 
1741         switch (type) {
1742         case 0:
1743                 ret = ql_8021_init_p3p(ha);
1744                 break;
1745         case 1:
1746                 ret = ql_8021_load_from_flash(ha);
1747                 break;
1748         case 2:
1749                 ret = ql_8021_load_firmware(ha);
1750                 break;
1751         }
1752         delay(1);
1753 
1754         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x18, 0x1020);
1755         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0x80001e);
1756 
1757         if (ret) {
1758                 EL(ha, "type=%d, ret=%d\n", type, ret);
1759         } else {
1760                 ret = ql_8021_phantom_init(ha);
1761         }
1762         return (ret);
1763 }
1764 
1765 static int
1766 ql_8021_load_fw(ql_adapter_state_t *ha)
1767 {
1768         int     rv = 0;

1769 
1770         GLOBAL_HW_LOCK();

1771         if (ha->risc_fw[0].code) {
1772                 EL(ha, "from driver\n");
1773                 rv = ql_8021_reset_hw(ha, 2);
1774         } else {
1775                 /*
1776                  * BIOS method
1777                  * ql_8021_reset_hw(ha, 0)
1778                  */
1779                 EL(ha, "from flash\n");
1780                 rv = ql_8021_reset_hw(ha, 1);
1781         }
1782         if (rv == 0) {


1783                 ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1784                 ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0x0);
1785                 ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0x0);
1786 
1787                 GLOBAL_HW_UNLOCK();
1788 
1789                 ADAPTER_STATE_LOCK(ha);
1790                 ha->flags &= ~INTERRUPTS_ENABLED;
1791                 ADAPTER_STATE_UNLOCK(ha);
1792 
1793                 /* clear the mailbox command pointer. */
1794                 INTR_LOCK(ha);
1795                 ha->mcp = NULL;
1796                 INTR_UNLOCK(ha);
1797 
1798                 MBX_REGISTER_LOCK(ha);
1799                 ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
1800                     ~(MBX_BUSY_FLG | MBX_WANT_FLG | MBX_ABORT | MBX_INTERRUPT));
1801                 MBX_REGISTER_UNLOCK(ha);
1802 
1803                 (void) ql_8021_enable_intrs(ha);
1804 
1805                 ADAPTER_STATE_LOCK(ha);
1806                 ha->flags |= INTERRUPTS_ENABLED;
1807                 ADAPTER_STATE_UNLOCK(ha);
1808         } else {
1809                 GLOBAL_HW_UNLOCK();
1810         }




1811 
1812         if (rv == 0) {
1813                 ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR, &ha->fw_major_version);
1814                 ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR, &ha->fw_minor_version);
1815                 ql_8021_rd_32(ha, UNM_FW_VERSION_SUB, &ha->fw_subminor_version);
1816                 EL(ha, "fw v%d.%02d.%02d\n", ha->fw_major_version,
1817                     ha->fw_minor_version, ha->fw_subminor_version);
1818         } else {
1819                 EL(ha, "status = -1\n");

1820         }
1821 
1822         return (rv);
1823 }
1824 
1825 void
1826 ql_8021_clr_hw_intr(ql_adapter_state_t *ha)
1827 {
1828         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
1829         ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1830         ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1831 }
1832 
1833 void
1834 ql_8021_clr_fw_intr(ql_adapter_state_t *ha)
1835 {
1836         WRT32_IO_REG(ha, nx_risc_int, 0);
1837         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xfbff);
1838 }
1839 
1840 void
1841 ql_8021_enable_intrs(ql_adapter_state_t *ha)
1842 {
1843         GLOBAL_HW_LOCK();
1844         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
1845         GLOBAL_HW_UNLOCK();
1846         if (!(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
1847                 (void) ql_toggle_interrupt(ha, 1);
1848         }
1849 }
1850 
1851 void
1852 ql_8021_disable_intrs(ql_adapter_state_t *ha)
1853 {
1854         (void) ql_toggle_interrupt(ha, 0);
1855         GLOBAL_HW_LOCK();
1856         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
1857         GLOBAL_HW_UNLOCK();
1858 }
1859 
1860 void
1861 ql_8021_update_crb_int_ptr(ql_adapter_state_t *ha)
1862 {
1863         struct legacy_intr_set  *nx_legacy_intr;
1864 
1865         ha->qdr_sn_window = (uint32_t)-1;
1866         nx_legacy_intr = &legacy_intr[ha->pci_function_number];

1867 
1868         ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;
1869         ha->nx_legacy_intr.tgt_status_reg = nx_legacy_intr->tgt_status_reg;
1870         ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;
1871         ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
1872 }
1873 
1874 void
1875 ql_8021_set_drv_active(ql_adapter_state_t *ha)
1876 {
1877         uint32_t        val;
1878 
1879         if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1880                 return;
1881         }
1882 
1883         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1884         if (val == 0xffffffff) {
1885                 val = (1 << (ha->pci_function_number * 4));
1886         } else {
1887                 val |= (1 << (ha->pci_function_number * 4));
1888         }
1889         ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1890 
1891         ql_8021_hw_unlock(ha);
1892 }
1893 
1894 void
1895 ql_8021_clr_drv_active(ql_adapter_state_t *ha)
1896 {
1897         uint32_t        val;
1898 
1899         if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1900                 return;
1901         }
1902 
1903         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1904         val &= ~(1 << (ha->pci_function_number * 4));
1905         ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1906 
1907         ql_8021_hw_unlock(ha);
1908 }
1909 
1910 static void
1911 ql_8021_need_reset_handler(ql_adapter_state_t *ha)
1912 {
1913         uint32_t        drv_state, drv_active, cnt;

1914 
1915         ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1916         if (drv_state == 0xffffffff) {
1917                 drv_state = 0;
1918         }
1919         if (!(ha->ql_dump_state & QL_DUMPING)) {
1920                 drv_state |= (1 << (ha->pci_function_number * 4));
1921         }
1922         ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1923 
1924         for (cnt = 60; cnt; cnt--) {
1925                 ql_8021_hw_unlock(ha);
1926                 delay(100);
1927                 (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1928 
1929                 ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1930                 ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
1931                 if (ha->ql_dump_state & QL_DUMPING) {
1932                         drv_state |= (1 << (ha->pci_function_number * 4));
1933                 }
1934                 if (drv_state == drv_active) {
1935                         if (ha->ql_dump_state & QL_DUMPING) {
1936                                 ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1937                         }
1938                         break;
1939                 }
1940         }
1941 }
1942 
1943 int
1944 ql_8021_fw_reload(ql_adapter_state_t *ha)
1945 {
1946         int     rval;
1947 
1948         (void) ql_stall_driver(ha, BIT_0);
1949 
1950         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1951         ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_INITIALIZING);
1952         ql_8021_hw_unlock(ha);
1953 
1954         rval = ql_8021_load_fw(ha) == 0 ? NX_DEV_READY : NX_DEV_FAILED;

1955 
1956         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1957         ql_8021_wr_32(ha, CRB_DEV_STATE, rval);

1958         ql_8021_hw_unlock(ha);
1959 
1960         TASK_DAEMON_LOCK(ha);
1961         ha->task_daemon_flags &= ~(TASK_DAEMON_STALLED_FLG | DRIVER_STALL);
1962         TASK_DAEMON_UNLOCK(ha);
1963 
1964         if (rval != NX_DEV_READY) {
1965                 EL(ha, "status=%xh\n", QL_FUNCTION_FAILED);
1966                 return (QL_FUNCTION_FAILED);
1967         }
1968         return (QL_SUCCESS);
1969 }
1970 
1971 void
1972 ql_8021_idc_poll(ql_adapter_state_t *ha)
1973 {
1974         uint32_t        new_state;
1975 
1976         if (ha->ql_dump_state & QL_DUMPING) {
1977                 return;
1978         }
1979         new_state = ql_8021_check_fw_alive(ha);
1980 
1981         if (new_state == NX_DEV_NEED_RESET &&
1982             !(ha->ql_dump_state & QL_DUMPING ||
1983             (ha->ql_dump_state & QL_DUMP_VALID &&
1984             !(ha->ql_dump_state & QL_DUMP_UPLOADED)))) {
1985                 (void) ql_dump_firmware(ha);
1986         } else {
1987                 (void) ql_8021_idc_handler(ha, new_state);
1988         }
1989 }
1990 
1991 int
1992 ql_8021_idc_handler(ql_adapter_state_t *ha, uint32_t new_state)
1993 {
1994         int             rval;
1995         uint32_t        dev_state, drv_state, loop;
1996         ql_mbx_data_t   mr;
1997         boolean_t       stalled = B_FALSE, reset_needed = B_FALSE;
1998         boolean_t       force_load = B_FALSE;
1999 




2000         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
2001 
2002         /* wait for 180 seconds for device to go ready */
2003         for (loop = 180; loop; loop--) {
2004                 if (new_state != NX_DEV_POLL) {
2005                         ql_8021_wr_32(ha, CRB_DEV_STATE, new_state);
2006                         dev_state = new_state;
2007                         new_state = NX_DEV_POLL;
2008                 } else {
2009                         ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
2010                 }
2011 
2012                 switch (dev_state) {
2013                 case 0xffffffff:
2014                 case NX_DEV_COLD:
2015                         if (ha->dev_state != dev_state) {
2016                                 EL(ha, "dev_state=NX_DEV_COLD\n");
2017                         }
2018                         rval = NX_DEV_COLD;
2019                         ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_INITIALIZING);
2020                         ql_8021_wr_32(ha, CRB_DRV_IDC_VERSION, NX_IDC_VERSION);
2021                         ql_8021_hw_unlock(ha);
2022                         if (!force_load &&
2023                             ql_get_fw_version(ha, &mr, 2) == QL_SUCCESS &&
2024                             (mr.mb[1] | mr.mb[2] | mr.mb[3])) {
2025                                 ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR,
2026                                     &ha->fw_major_version);
2027                                 ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR,
2028                                     &ha->fw_minor_version);
2029                                 ql_8021_rd_32(ha, UNM_FW_VERSION_SUB,
2030                                     &ha->fw_subminor_version);
2031                                 rval = NX_DEV_READY;
2032                         } else {
2033                                 if (!stalled) {
2034                                         TASK_DAEMON_LOCK(ha);
2035                                         ha->task_daemon_flags |=
2036                                             TASK_DAEMON_STALLED_FLG;
2037                                         TASK_DAEMON_UNLOCK(ha);
2038                                         ql_abort_queues(ha);
2039                                         stalled = B_TRUE;
2040                                 }
2041                                 if (ha->ql_dump_state & QL_DUMPING) {
2042                                         (void) ql_8021_get_fw_dump(ha);
2043                                 }
2044                                 rval = ql_8021_load_fw(ha) == 0 ?
2045                                     NX_DEV_READY : NX_DEV_FAILED;
2046                         }
2047                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
2048                         ql_8021_wr_32(ha, CRB_DEV_STATE, rval);
2049                         break;
2050                 case NX_DEV_READY:
2051                         if (ha->dev_state != dev_state) {
2052                                 EL(ha, "dev_state=NX_DEV_READY\n");
2053                         }
2054                         rval = NX_DEV_READY;
2055                         loop = 1;
2056                         break;
2057                 case NX_DEV_FAILED:
2058                         if (ha->dev_state != dev_state) {
2059                                 EL(ha, "dev_state=NX_DEV_FAILED\n");
2060                         }
2061                         rval = NX_DEV_FAILED;
2062                         loop = 1;
2063                         break;

2064                 case NX_DEV_NEED_RESET:
2065                         if (ha->dev_state != dev_state) {
2066                                 EL(ha, "dev_state=NX_DEV_NEED_RESET\n");
2067                         }
2068                         rval = NX_DEV_NEED_RESET;




2069                         ql_8021_need_reset_handler(ha);
2070                         /*
2071                          * Force to DEV_COLD unless someone else is starting
2072                          * a reset
2073                          */
2074                         ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
2075                         if (dev_state == NX_DEV_NEED_RESET) {
2076                                 EL(ha, "HW State: COLD/RE-INIT\n");
2077                                 ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_COLD);
2078                                 force_load = B_TRUE;
2079                         }
2080                         reset_needed = B_TRUE;
2081                         break;

2082                 case NX_DEV_NEED_QUIESCENT:
2083                         if (ha->dev_state != dev_state) {
2084                                 EL(ha, "dev_state=NX_DEV_NEED_QUIESCENT\n");
2085                         }






2086                         ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
2087                         drv_state |= (2 << (ha->pci_function_number * 4));

2088                         ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
2089                         ql_8021_hw_unlock(ha);
2090                         if (!stalled) {
2091                                 TASK_DAEMON_LOCK(ha);
2092                                 ha->task_daemon_flags |=
2093                                     TASK_DAEMON_STALLED_FLG;
2094                                 TASK_DAEMON_UNLOCK(ha);
2095                                 (void) ql_stall_driver(ha, BIT_0);
2096                                 stalled = B_TRUE;
2097                         }
2098                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
2099                         break;

2100                 case NX_DEV_INITIALIZING:
2101                         if (ha->dev_state != dev_state) {
2102                                 EL(ha, "dev_state=NX_DEV_INITIALIZING\n");
2103                         }
2104                         ql_8021_hw_unlock(ha);
2105                         if (!stalled) {
2106                                 TASK_DAEMON_LOCK(ha);
2107                                 ha->task_daemon_flags |=
2108                                     TASK_DAEMON_STALLED_FLG;
2109                                 TASK_DAEMON_UNLOCK(ha);
2110                                 ql_awaken_task_daemon(ha, NULL,
2111                                     DRIVER_STALL, 0);
2112                                 stalled = B_TRUE;
2113                                 ql_requeue_all_cmds(ha);
2114                                 ADAPTER_STATE_LOCK(ha);
2115                                 ha->flags &= ~INTERRUPTS_ENABLED;
2116                                 ADAPTER_STATE_UNLOCK(ha);
2117                         }
2118                         delay(100);
2119                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
2120                         reset_needed = B_TRUE;
2121                         break;
2122                 case NX_DEV_QUIESCENT:
2123                         if (ha->dev_state != dev_state) {
2124                                 EL(ha, "dev_state=NX_DEV_QUIESCENT\n");
2125                         }
2126                         ql_8021_hw_unlock(ha);
2127                         delay(100);
2128                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
2129                         break;
2130                 default:
2131                         if (ha->dev_state != dev_state) {
2132                                 EL(ha, "dev_state=%x, default\n", dev_state);
2133                         }
2134                         ql_8021_hw_unlock(ha);
2135                         delay(100);
2136                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
2137                         break;
2138                 }
2139                 ha->dev_state = dev_state;


2140         }
2141 
2142         /* Clear reset ready and quiescent flags. */
2143         ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
2144         drv_state &= ~(1 << (ha->pci_function_number * 4));
2145         drv_state &= ~(2 << (ha->pci_function_number * 4));
2146         ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
2147 
2148         ql_8021_hw_unlock(ha);
2149         if (reset_needed && ha->flags & ONLINE &&
2150             !(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
2151                 delay(100);
2152                 ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, 0);
2153         }


2154         if (stalled) {
2155                 TASK_DAEMON_LOCK(ha);
2156                 ha->task_daemon_flags &= ~TASK_DAEMON_STALLED_FLG;
2157                 TASK_DAEMON_UNLOCK(ha);
2158                 ql_restart_driver(ha);
2159         }
2160         return (rval);
2161 }
2162 
2163 void
2164 ql_8021_wr_req_in(ql_adapter_state_t *ha, uint32_t index)
2165 {
2166         index = index << 16 | ha->pci_function_number << 5 | 4;
2167 
2168         if (NX_IS_REVISION_P3PLUS_B0(ha->rev_id)) {
2169                 uint64_t        addr;
2170 
2171                 addr = ha->function_number ? (uint64_t)CRB_PORT_1_REQIN :
2172                     (uint64_t)CRB_PORT_0_REQIN;
2173                 ql_8021_wr_32(ha, addr, index);
2174         } else {
2175                 do {
2176                         ddi_put32(ha->db_dev_handle, ha->nx_req_in, index);
2177                 } while (RD_REG_DWORD(ha, ha->db_read) != index);
2178         }
2179 }
2180 
2181 /* Called every 2 seconds */
2182 static uint32_t
2183 ql_8021_check_fw_alive(ql_adapter_state_t *ha)
2184 {
2185         uint32_t        dev_state, fw_heartbeat_counter, cnt, data[7];
2186         uint32_t        new_state = NX_DEV_POLL;
2187 
2188         ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
2189         if (dev_state != NX_DEV_READY) {
2190                 return (new_state);
2191         }
2192 
2193         ql_8021_rd_32(ha, UNM_PEG_ALIVE_COUNTER, &fw_heartbeat_counter);
2194 
2195         if (ha->fw_heartbeat_counter == fw_heartbeat_counter) {
2196                 ha->seconds_since_last_heartbeat++;
2197                 /* FW not alive after 6 seconds */
2198                 if (ha->seconds_since_last_heartbeat == 3) {
2199                         ha->seconds_since_last_heartbeat = 0;
2200                         /* FW not alive after 5 milliseconds */
2201                         for (cnt = 5; cnt; cnt--) {
2202                                 ql_8021_rd_32(ha, UNM_PEG_ALIVE_COUNTER,
2203                                     &fw_heartbeat_counter);
2204                                 if (ha->fw_heartbeat_counter !=
2205                                     fw_heartbeat_counter) {
2206                                         break;
2207                                 }
2208                                 drv_usecwait(1000);
2209                         }
2210                         if (ha->fw_heartbeat_counter == fw_heartbeat_counter) {
2211                                 EL(ha, "nx_dev_need_reset\n");
2212                                 ql_8021_rd_32(ha, UNM_PEG_HALT_STATUS1,
2213                                     &data[0]);
2214                                 ql_8021_rd_32(ha, UNM_PEG_HALT_STATUS2,
2215                                     &data[1]);
2216                                 ql_8021_rd_32(ha, UNM_CRB_PEG_NET_0 + 0x3C,
2217                                     &data[2]);
2218                                 ql_8021_rd_32(ha, UNM_CRB_PEG_NET_1 + 0x3C,
2219                                     &data[3]);
2220                                 ql_8021_rd_32(ha, UNM_CRB_PEG_NET_2 + 0x3C,
2221                                     &data[4]);
2222                                 ql_8021_rd_32(ha, UNM_CRB_PEG_NET_3 + 0x3C,
2223                                     &data[5]);
2224                                 ql_8021_rd_32(ha, UNM_CRB_PEG_NET_4 + 0x3C,
2225                                     &data[6]);
2226                                 EL(ha, "halt_status1=%xh, halt_status2=%xh,\n"
2227                                     "peg_pc0=%xh, peg_pc1=%xh, peg_pc2=%xh, "
2228                                     "peg_pc3=%xh, peg_pc4=%xh\n", data[0],
2229                                     data[1], data[2], data[3], data[4],
2230                                     data[5], data[6]);
2231                                 new_state = NX_DEV_NEED_RESET;
2232                         }
2233                 }
2234         } else {
2235                 ha->seconds_since_last_heartbeat = 0;
2236         }
2237 
2238         ha->fw_heartbeat_counter = fw_heartbeat_counter;
2239         return (new_state);
2240 }
2241 
2242 int
2243 ql_8021_reset_fw(ql_adapter_state_t *ha)
2244 {
2245         return (ql_8021_idc_handler(ha, NX_DEV_NEED_RESET));
2246 }
2247 
2248 int
2249 ql_8021_fw_chk(ql_adapter_state_t *ha)
2250 {
2251         uint32_t        dev_state, new_state = NX_DEV_POLL;
2252         int             rval;
2253         ql_mbx_data_t   mr;
2254 
2255         ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
2256         switch (dev_state) {
2257         case 0xffffffff:
2258         case NX_DEV_COLD:
2259         case NX_DEV_NEED_RESET:
2260         case NX_DEV_NEED_QUIESCENT:
2261         case NX_DEV_INITIALIZING:
2262         case NX_DEV_QUIESCENT:
2263         case NX_DEV_BADOBADO:
2264                 break;
2265         case NX_DEV_READY:
2266                 if (ql_get_fw_version(ha, &mr, 2) != QL_SUCCESS ||
2267                     (mr.mb[1] | mr.mb[2] | mr.mb[3]) == 0) {
2268                         EL(ha, "version check needs reset\n", dev_state);
2269                         new_state = NX_DEV_NEED_RESET;
2270                 }
2271                 break;
2272         case NX_DEV_FAILED:
2273                 EL(ha, "device needs reset\n");
2274                 new_state = NX_DEV_NEED_RESET;
2275                 break;
2276         default:
2277                 EL(ha, "state=%xh needs reset\n", dev_state);
2278                 new_state = NX_DEV_COLD;
2279                 break;
2280         }
2281 
2282         /* Test for firmware running. */
2283         rval = ql_8021_idc_handler(ha, new_state) == NX_DEV_READY ?
2284             QL_SUCCESS : QL_FUNCTION_FAILED;
2285 
2286         return (rval);
2287 }
2288 
2289 /* ****************************************************************** */
2290 /* ***************** NetXen MiniDump Functions ********************** */
2291 /* ****************************************************************** */
2292 
2293 /*
2294  * ql_8021_get_fw_dump
2295  *
2296  * Input:
2297  *      pi:     FC port info pointer.
2298  *
2299  * Returns:
2300  *      qla driver local function return status codes
2301  *
2302  * Context:
2303  *      Interrupt or Kernel context, no mailbox commands allowed.
2304  */
2305 static int
2306 ql_8021_get_fw_dump(ql_adapter_state_t *ha)
2307 {
2308         uint32_t        tsize, cnt, *dp, *bp;
2309 
2310         QL_PRINT_10(ha, "started\n");
2311 
2312         tsize = ha->dmp_template.size;
2313         cnt = (uint32_t)(tsize / sizeof (uint32_t));
2314         dp = (uint32_t *)ha->ql_dump_ptr;
2315         bp = (uint32_t *)ha->dmp_template.bp;
2316         while (cnt--) {
2317                 *dp++ = ddi_get32(ha->dmp_template.acc_handle, bp++);
2318         }
2319         ql_8021_md_parse_template(ha, ha->ql_dump_ptr, (caddr_t)dp,
2320             ha->md_capture_size - tsize, ha->md_capture_mask);
2321 
2322 #ifdef _BIG_ENDIAN
2323         cnt = (uint32_t)(ha->ql_dump_size / sizeof (uint32_t));
2324         dp = (uint32_t *)ha->ql_dump_ptr;
2325         while (cnt--) {
2326                 ql_chg_endian((uint8_t *)dp, 4);
2327                 dp++;
2328         }
2329 #endif
2330         QL_PRINT_10(ha, "done\n");
2331         return (QL_SUCCESS);
2332 }
2333 
2334 /*
2335  * ql_8021_get_md_template
2336  *      Get mini-dump template
2337  *
2338  * Input:
2339  *      ha:     adapter state pointer.
2340  *
2341  * Returns:
2342  *      ql local function return status code.
2343  *
2344  * Context:
2345  *      Kernel context.
2346  */
2347 int
2348 ql_8021_get_md_template(ql_adapter_state_t *ha)
2349 {
2350         ql_mbx_data_t   mr;
2351         uint32_t        tsize, chksum;
2352         int             rval;
2353 
2354         rval = ql_get_md_template(ha, NULL, &mr, 0, GTO_TEMPLATE_SIZE);
2355         if (rval != QL_SUCCESS ||
2356             (tsize = SHORT_TO_LONG(mr.mb[2], mr.mb[3])) == 0) {
2357                 EL(ha, "size=%xh status=%xh\n", tsize, rval);
2358                 ha->md_capture_size = 0;
2359                 ql_free_phys(ha, &ha->dmp_template);
2360                 return (rval);
2361         }
2362         if (ha->dmp_template.dma_handle && ha->dmp_template.size != tsize) {
2363                 ql_free_phys(ha, &ha->dmp_template);
2364         }
2365         ha->md_capture_mask = 0x1f;
2366         ha->md_capture_size = SHORT_TO_LONG(mr.mb[4], mr.mb[5]) +
2367             SHORT_TO_LONG(mr.mb[6], mr.mb[7]) +
2368             SHORT_TO_LONG(mr.mb[8], mr.mb[9]) +
2369             SHORT_TO_LONG(mr.mb[10], mr.mb[11]) + tsize;
2370         /*
2371          * Determine ascii dump file size
2372          * 2 ascii bytes per binary byte + a space and
2373          * a newline every 16 binary bytes
2374          */
2375         ha->risc_dump_size = ha->md_capture_size << 1;
2376         ha->risc_dump_size += ha->md_capture_size;
2377         ha->risc_dump_size += ha->md_capture_size / 16 + 1;
2378 
2379         /* Allocate template buffer. */
2380         if (ha->dmp_template.dma_handle == NULL) {
2381                 rval = ql_get_dma_mem(ha, &ha->dmp_template, tsize,
2382                     LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN);
2383                 if (rval != QL_SUCCESS) {
2384                         EL(ha, "unable to allocate template buffer, "
2385                             "status=%xh\n", rval);
2386                         ha->md_capture_size = 0;
2387                         ql_free_phys(ha, &ha->dmp_template);
2388                         return (rval);
2389                 }
2390         }
2391         rval = ql_get_md_template(ha, &ha->dmp_template, &mr, 0, GTO_TEMPLATE);
2392         if (rval != QL_SUCCESS ||
2393             (chksum = ql_8021_md_template_checksum(ha))) {
2394                 EL(ha, "status=%xh, chksum=%xh\n", rval, chksum);
2395                 if (rval == QL_SUCCESS) {
2396                         rval = QL_FUNCTION_FAILED;
2397                 }
2398                 ql_free_phys(ha, &ha->dmp_template);
2399                 ha->md_capture_size = 0;
2400         }
2401 
2402         return (rval);
2403 }
2404 
2405 static void
2406 ql_8021_md_parse_template(ql_adapter_state_t *ha, caddr_t template_buff,
2407     caddr_t dump_buff, uint32_t buff_size, uint32_t capture_mask)
2408 {
2409         int                     e_cnt, buff_level, esize;
2410         uint32_t                num_of_entries;
2411         time_t                  time;
2412         caddr_t                 dbuff;
2413         int                     sane_start = 0, sane_end = 0;
2414         md_template_hdr_t       *template_hdr;
2415         md_entry_t              *entry;
2416 
2417         if ((capture_mask & 0x3) != 0x3) {
2418                 EL(ha, "capture mask %02xh below minimum needed for valid "
2419                     "dump\n", capture_mask);
2420                 return;
2421         }
2422         /* Setup parameters */
2423         template_hdr = (md_template_hdr_t *)template_buff;
2424         if (template_hdr->entry_type == TLHDR) {
2425                 sane_start = 1;
2426         }
2427         (void) drv_getparm(TIME, &time);
2428         template_hdr->driver_timestamp = LSD(time);
2429         template_hdr->driver_capture_mask = capture_mask;
2430         num_of_entries = template_hdr->num_of_entries;
2431         entry = (md_entry_t *)((caddr_t)template_buff +
2432             template_hdr->first_entry_offset);
2433         for (buff_level = 0, e_cnt = 0; e_cnt < num_of_entries; e_cnt++) {
2434                 /*
2435                  * If the capture_mask of the entry does not match capture mask
2436                  * skip the entry after marking the driver_flags indicator.
2437                  */
2438                 if (!(entry->h.a.ecw.entry_capture_mask & capture_mask)) {
2439                         entry->h.a.ecw.driver_flags = (uint8_t)
2440                             (entry->h.a.ecw.driver_flags |
2441                             QL_DBG_SKIPPED_FLAG);
2442                         entry = (md_entry_t *)((char *)entry +
2443                             entry->h.entry_size);
2444                         continue;
2445                 }
2446                 /*
2447                  * This is ONLY needed in implementations where
2448                  * the capture buffer allocated is too small to capture
2449                  * all of the required entries for a given capture mask.
2450                  * We need to empty the buffer contents to a file
2451                  * if possible, before processing the next entry
2452                  * If the buff_full_flag is set, no further capture will
2453                  * happen and all remaining non-control entries will be
2454                  * skipped.
2455                  */
2456                 if (entry->h.entry_capture_size != 0) {
2457                         if ((buff_level + entry->h.entry_capture_size) >
2458                             buff_size) {
2459                                 entry = (md_entry_t *)((char *)entry +
2460                                     entry->h.entry_size);
2461                                 continue;
2462                         }
2463                 }
2464                 /*
2465                  * Decode the entry type and process it accordingly
2466                  */
2467                 switch (entry->h.entry_type) {
2468                 case RDNOP:
2469                         break;
2470                 case RDEND:
2471                         sane_end += 1;
2472                         break;
2473                 case RDCRB:
2474                         dbuff = dump_buff + buff_level;
2475                         esize = ql_8021_md_rdcrb(ha, (void *)entry,
2476                             (void *)dbuff);
2477                         ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2478                         buff_level += esize;
2479                         break;
2480                 case L2ITG:
2481                 case L2DTG:
2482                 case L2DAT:
2483                 case L2INS:
2484                         dbuff = dump_buff + buff_level;
2485                         esize = ql_8021_md_L2Cache(ha, (void *)entry,
2486                             (void *)dbuff);
2487                         if (esize == -1) {
2488                                 entry->h.a.ecw.driver_flags = (uint8_t)
2489                                     (entry->h.a.ecw.driver_flags |
2490                                     QL_DBG_SKIPPED_FLAG);
2491                         } else {
2492                                 ql_8021_md_entry_err_chk(ha, entry, esize,
2493                                     e_cnt);
2494                                 buff_level += esize;
2495                         }
2496                         break;
2497                 case L1DAT:
2498                 case L1INS:
2499                         dbuff = dump_buff + buff_level;
2500                         esize = ql_8021_md_L1Cache(ha, (void *)entry,
2501                             (void *)dbuff);
2502                         ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2503                         buff_level += esize;
2504                         break;
2505                 case RDOCM:
2506                         dbuff = dump_buff + buff_level;
2507                         esize = ql_8021_md_rdocm(ha, (void *)entry,
2508                             (void *)dbuff);
2509                         ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2510                         buff_level += esize;
2511                         break;
2512                 case RDMEM:
2513                         dbuff = dump_buff + buff_level;
2514                         esize = ql_8021_md_rdmem(ha, (void *)entry,
2515                             (void *)dbuff);
2516                         ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2517                         buff_level += esize;
2518                         break;
2519                 case BOARD:
2520                 case RDROM:
2521                         dbuff = dump_buff + buff_level;
2522                         esize = ql_8021_md_rdrom(ha, (void *)entry,
2523                             (void *)dbuff);
2524                         ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2525                         buff_level += esize;
2526                         break;
2527                 case RDMUX:
2528                         dbuff = dump_buff + buff_level;
2529                         esize = ql_8021_md_rdmux(ha, (void *)entry,
2530                             (void *)dbuff);
2531                         ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2532                         buff_level += esize;
2533                         break;
2534                 case QUEUE:
2535                         dbuff = dump_buff + buff_level;
2536                         esize = ql_8021_md_rdqueue(ha, (void *)entry,
2537                             (void *)dbuff);
2538                         ql_8021_md_entry_err_chk(ha, entry, esize, e_cnt);
2539                         buff_level += esize;
2540                         break;
2541                 case CNTRL:
2542                         if (ql_8021_md_cntrl(ha, template_hdr,
2543                             (void *)entry)) {
2544                                 entry->h.a.ecw.driver_flags = (uint8_t)
2545                                     (entry->h.a.ecw.driver_flags |
2546                                     QL_DBG_SKIPPED_FLAG);
2547                                 EL(ha, "Entry ID=%d, entry_type=%d non zero "
2548                                     "status\n", e_cnt, entry->h.entry_type);
2549                         }
2550                         break;
2551                 default:
2552                         entry->h.a.ecw.driver_flags = (uint8_t)
2553                             (entry->h.a.ecw.driver_flags |
2554                             QL_DBG_SKIPPED_FLAG);
2555                         EL(ha, "Entry ID=%d, entry_type=%d unknown\n", e_cnt,
2556                             entry->h.entry_type);
2557                         break;
2558                 }
2559                 /* next entry in the template */
2560                 entry = (md_entry_t *)((caddr_t)entry + entry->h.entry_size);
2561         }
2562         if (!sane_start || (sane_end > 1)) {
2563                 EL(ha, "Template configuration error. Check Template\n");
2564         }
2565         QL_PRINT_10(ha, "Minidump num of entries=%d\n",
2566             template_hdr->num_of_entries);
2567 }
2568 
2569 /*
2570  * Read CRB operation.
2571  */
2572 static int
2573 ql_8021_md_rdcrb(ql_adapter_state_t *ha, md_entry_rdcrb_t *crbEntry,
2574     uint32_t *data_buff)
2575 {
2576         uint32_t        loop_cnt, op_count, addr, stride, value;
2577         int             i;
2578 
2579         addr = crbEntry->addr;
2580         op_count = crbEntry->op_count;
2581         stride = crbEntry->a.ac.addr_stride;
2582 
2583         for (loop_cnt = 0; loop_cnt < op_count; loop_cnt++) {
2584                 value = ql_8021_read_reg(ha, addr);
2585                 *data_buff++ = addr;
2586                 *data_buff++ = value;
2587                 addr = addr + stride;
2588         }
2589 
2590         /*
2591          * for testing purpose we return amount of data written
2592          */
2593         i = (int)(loop_cnt * (2 * sizeof (uint32_t)));
2594 
2595         return (i);
2596 }
2597 
2598 /*
2599  * Handle L2 Cache.
2600  */
2601 static int
2602 ql_8021_md_L2Cache(ql_adapter_state_t *ha, md_entry_cache_t *cacheEntry,
2603     uint32_t *data_buff)
2604 {
2605         int                     i, k, tflag;
2606         uint32_t                read_value, loop_cnt, read_cnt;
2607         uint32_t                addr, read_addr, cntrl_addr, tag_reg_addr;
2608         uint32_t                cntl_value_w, tag_value, tag_value_stride;
2609         volatile uint8_t        cntl_value_r;
2610         clock_t                 timeout, elapsed;
2611 
2612         read_addr = cacheEntry->read_addr;
2613         loop_cnt = cacheEntry->op_count;
2614         cntrl_addr = cacheEntry->control_addr;
2615         cntl_value_w = CHAR_TO_SHORT(cacheEntry->b.cv.write_value[0],
2616             cacheEntry->b.cv.write_value[1]);
2617         tag_reg_addr = cacheEntry->tag_reg_addr;
2618         tag_value = CHAR_TO_SHORT(cacheEntry->a.sac.init_tag_value[0],
2619             cacheEntry->a.sac.init_tag_value[1]);
2620         tag_value_stride = CHAR_TO_SHORT(cacheEntry->a.sac.tag_value_stride[0],
2621             cacheEntry->a.sac.tag_value_stride[1]);
2622         read_cnt = cacheEntry->c.rac.read_addr_cnt;
2623 
2624         for (i = 0; i < loop_cnt; i++) {
2625                 ql_8021_write_reg(ha, tag_value, tag_reg_addr);
2626                 if (cntl_value_w) {
2627                         ql_8021_write_reg(ha, cntl_value_w, cntrl_addr);
2628                 }
2629                 if (cacheEntry->b.cv.poll_wait) {
2630                         (void) drv_getparm(LBOLT, &timeout);
2631                         timeout += drv_usectohz(cacheEntry->b.cv.poll_wait *
2632                             1000) + 1;
2633                         cntl_value_r = (uint8_t)ql_8021_read_reg(ha,
2634                             cntrl_addr);
2635                         tflag = 0;
2636                         while (!tflag && ((cntl_value_r &
2637                             cacheEntry->b.cv.poll_mask) != 0)) {
2638                                 (void) drv_getparm(LBOLT, &elapsed);
2639                                 if (elapsed > timeout) {
2640                                         tflag = 1;
2641                                 }
2642                                 cntl_value_r = (uint8_t)ql_8021_read_reg(ha,
2643                                     cntrl_addr);
2644                         }
2645                         if (tflag) {
2646                                 /*
2647                                  *  Report timeout error.  core dump capture
2648                                  *  failed
2649                                  *  Skip remaining entries. Write buffer out
2650                                  *  to file
2651                                  *  Use driver specific fields in template
2652                                  *  header
2653                                  *  to report this error.
2654                                  */
2655                                 EL(ha, "timeout\n");
2656                                 return (-1);
2657                         }
2658                 }
2659                 addr = read_addr;
2660                 for (k = 0; k < read_cnt; k++) {
2661                         read_value = ql_8021_read_reg(ha, addr);
2662                         *data_buff++ = read_value;
2663                         addr += cacheEntry->c.rac.read_addr_stride;
2664                 }
2665                 tag_value += tag_value_stride;
2666         }
2667         i = (int)(read_cnt * loop_cnt * sizeof (uint32_t));
2668 
2669         return (i);
2670 }
2671 
2672 /*
2673  * Handle L1 Cache.
2674  */
2675 static int
2676 ql_8021_md_L1Cache(ql_adapter_state_t *ha, md_entry_cache_t *cacheEntry,
2677     uint32_t *data_buff)
2678 {
2679         int                     i, k;
2680         uint32_t                read_value, tag_value, tag_value_stride;
2681         uint32_t                read_cnt, loop_cnt;
2682         uint32_t                addr, read_addr, cntrl_addr, tag_reg_addr;
2683         volatile uint32_t       cntl_value_w;
2684 
2685         read_addr = cacheEntry->read_addr;
2686         loop_cnt = cacheEntry->op_count;
2687         cntrl_addr = cacheEntry->control_addr;
2688         cntl_value_w = CHAR_TO_SHORT(cacheEntry->b.cv.write_value[0],
2689             cacheEntry->b.cv.write_value[1]);
2690         tag_reg_addr = cacheEntry->tag_reg_addr;
2691         tag_value = CHAR_TO_SHORT(cacheEntry->a.sac.init_tag_value[0],
2692             cacheEntry->a.sac.init_tag_value[1]);
2693         tag_value_stride = CHAR_TO_SHORT(cacheEntry->a.sac.tag_value_stride[0],
2694             cacheEntry->a.sac.tag_value_stride[1]);
2695         read_cnt = cacheEntry->c.rac.read_addr_cnt;
2696 
2697         for (i = 0; i < loop_cnt; i++) {
2698                 ql_8021_write_reg(ha, tag_value, tag_reg_addr);
2699                 ql_8021_write_reg(ha, cntl_value_w, cntrl_addr);
2700                 addr = read_addr;
2701                 for (k = 0; k < read_cnt; k++) {
2702                         read_value = ql_8021_read_reg(ha, addr);
2703                         *data_buff++ = read_value;
2704                         addr += cacheEntry->c.rac.read_addr_stride;
2705                 }
2706                 tag_value += tag_value_stride;
2707         }
2708         i = (int)(read_cnt * loop_cnt * sizeof (uint32_t));
2709 
2710         return (i);
2711 }
2712 
2713 /*
2714  * Reading OCM memory
2715  */
2716 static int
2717 ql_8021_md_rdocm(ql_adapter_state_t *ha, md_entry_rdocm_t *ocmEntry,
2718     uint32_t *data_buff)
2719 {
2720         int             i;
2721         uint32_t        addr, value, loop_cnt;
2722 
2723         addr = ocmEntry->read_addr;
2724         loop_cnt = ocmEntry->op_count;
2725 
2726         for (i = 0; i < loop_cnt; i++) {
2727                 value = ql_8021_read_ocm(ha, addr);
2728                 *data_buff++ = value;
2729                 addr += ocmEntry->read_addr_stride;
2730         }
2731         i = (int)(loop_cnt * sizeof (value));
2732 
2733         return (i);
2734 }
2735 
2736 /*
2737  * Read memory
2738  */
2739 static int
2740 ql_8021_md_rdmem(ql_adapter_state_t *ha, md_entry_rdmem_t *memEntry,
2741     uint32_t *data_buff)
2742 {
2743         int             i, k;
2744         uint32_t        addr, value, loop_cnt;
2745 
2746         addr = memEntry->read_addr;
2747         loop_cnt = (uint32_t)(memEntry->read_data_size /
2748             (sizeof (uint32_t) * 4));           /* size in bytes / 16 */
2749 
2750         ql_8021_write_reg(ha, 0, MD_MIU_TEST_AGT_ADDR_HI);
2751         for (i = 0; i < loop_cnt; i++) {
2752                 /*
2753                  * Write address
2754                  */
2755                 ql_8021_write_reg(ha, addr, MD_MIU_TEST_AGT_ADDR_LO);
2756                 ql_8021_write_reg(ha, MD_TA_CTL_ENABLE,
2757                     MD_MIU_TEST_AGT_CTRL);
2758                 ql_8021_write_reg(ha, (MD_TA_CTL_START | MD_TA_CTL_ENABLE),
2759                     MD_MIU_TEST_AGT_CTRL);
2760                 /*
2761                  * Check busy bit.
2762                  */
2763                 for (k = 0; k < MD_TA_CTL_CHECK; k++) {
2764                         value = ql_8021_read_reg(ha, MD_MIU_TEST_AGT_CTRL);
2765                         if ((value & MD_TA_CTL_BUSY) == 0) {
2766                                 break;
2767                         }
2768                 }
2769                 if (k == MD_TA_CTL_CHECK) {
2770                         i = (int)((uint_t)i * (sizeof (uint32_t) * 4));
2771                         EL(ha, "failed to read=xh\n", i);
2772                         return (i);
2773                 }
2774                 /*
2775                  * Read data
2776                  */
2777                 value = ql_8021_read_reg(ha, MD_MIU_TEST_AGT_RDDATA_0_31);
2778                 *data_buff++ = value;
2779                 value = ql_8021_read_reg(ha, MD_MIU_TEST_AGT_RDDATA_32_63);
2780                 *data_buff++ = value;
2781                 value = ql_8021_read_reg(ha, MD_MIU_TEST_AGT_RDDATA_64_95);
2782                 *data_buff++ = value;
2783                 value = ql_8021_read_reg(ha, MD_MIU_TEST_AGT_RDDATA_96_127);
2784                 *data_buff++ = value;
2785                 /*
2786                  *  next address to read
2787                  */
2788                 addr = (uint32_t)(addr + (sizeof (uint32_t) * 4));
2789         }
2790         i = (int)(loop_cnt * (sizeof (uint32_t) * 4));
2791 
2792         return (i);
2793 }
2794 
2795 /*
2796  * Read Rom
2797  */
2798 static int
2799 ql_8021_md_rdrom(ql_adapter_state_t *ha, md_entry_rdrom_t *romEntry,
2800     uint32_t *data_buff)
2801 {
2802         int             i;
2803         uint32_t        addr, waddr, raddr, value, loop_cnt;
2804 
2805         addr = romEntry->read_addr;
2806         loop_cnt = romEntry->read_data_size; /* This is size in bytes */
2807         loop_cnt = (uint32_t)(loop_cnt / sizeof (value));
2808 
2809         for (i = 0; i < loop_cnt; i++) {
2810                 waddr = addr & 0xFFFF0000;
2811                 (void) ql_8021_rom_lock(ha);
2812                 ql_8021_write_reg(ha, waddr, MD_DIRECT_ROM_WINDOW);
2813                 raddr = MD_DIRECT_ROM_READ_BASE + (addr & 0x0000FFFF);
2814                 value = ql_8021_read_reg(ha, raddr);
2815                 ql_8021_rom_unlock(ha);
2816                 *data_buff++ = value;
2817                 addr = (uint32_t)(addr + sizeof (value));
2818         }
2819         i = (int)(loop_cnt * sizeof (value));
2820 
2821         return (i);
2822 }
2823 
2824 /*
2825  * Read MUX data
2826  */
2827 static int
2828 ql_8021_md_rdmux(ql_adapter_state_t *ha, md_entry_mux_t *muxEntry,
2829     uint32_t *data_buff)
2830 {
2831         uint32_t        read_value, sel_value, loop_cnt;
2832         uint32_t        read_addr, select_addr;
2833         int             i;
2834 
2835         select_addr = muxEntry->select_addr;
2836         sel_value = muxEntry->select_value;
2837         read_addr = muxEntry->read_addr;
2838 
2839         for (loop_cnt = 0; loop_cnt < muxEntry->op_count; loop_cnt++) {
2840                 ql_8021_write_reg(ha, sel_value, select_addr);
2841                 read_value = ql_8021_read_reg(ha, read_addr);
2842                 *data_buff++ = sel_value;
2843                 *data_buff++ = read_value;
2844                 sel_value += muxEntry->select_value_stride;
2845         }
2846         i = (int)(loop_cnt * (2 * sizeof (uint32_t)));
2847 
2848         return (i);
2849 }
2850 
2851 /*
2852  * Handling Queue State Reads.
2853  */
2854 static int
2855 ql_8021_md_rdqueue(ql_adapter_state_t *ha, md_entry_queue_t *queueEntry,
2856     uint32_t *data_buff)
2857 {
2858         int             k;
2859         uint32_t        read_value, read_addr, read_stride, select_addr;
2860         uint32_t        queue_id, loop_cnt, read_cnt;
2861 
2862         read_cnt = queueEntry->b.rac.read_addr_cnt;
2863         read_stride = queueEntry->b.rac.read_addr_stride;
2864         select_addr = queueEntry->select_addr;
2865 
2866         for (loop_cnt = 0, queue_id = 0; loop_cnt < queueEntry->op_count;
2867             loop_cnt++) {
2868                 ql_8021_write_reg(ha, queue_id, select_addr);
2869                 read_addr = queueEntry->read_addr;
2870                 for (k = 0; k < read_cnt; k++) {
2871                         read_value = ql_8021_read_reg(ha, read_addr);
2872                         *data_buff++ = read_value;
2873                         read_addr += read_stride;
2874                 }
2875                 queue_id += CHAR_TO_SHORT(queueEntry->a.sac.queue_id_stride[0],
2876                     queueEntry->a.sac.queue_id_stride[1]);
2877         }
2878         k = (int)(loop_cnt * (read_cnt * sizeof (uint32_t)));
2879 
2880         return (k);
2881 }
2882 
2883 /*
2884  * Handling control entries.
2885  */
2886 static int
2887 ql_8021_md_cntrl(ql_adapter_state_t *ha, md_template_hdr_t *template_hdr,
2888     md_entry_cntrl_t *crbEntry)
2889 {
2890         int             tflag;
2891         uint32_t        opcode, read_value, addr, entry_addr, loop_cnt;
2892         clock_t         timeout, elapsed;
2893 
2894         entry_addr = crbEntry->addr;
2895 
2896         for (loop_cnt = 0; loop_cnt < crbEntry->op_count; loop_cnt++) {
2897                 opcode = crbEntry->b.cv.opcode;
2898                 if (opcode & QL_DBG_OPCODE_WR) {
2899                         ql_8021_write_reg(ha, crbEntry->value_1, entry_addr);
2900                         opcode &= ~QL_DBG_OPCODE_WR;
2901                 }
2902                 if (opcode & QL_DBG_OPCODE_RW) {
2903                         read_value = ql_8021_read_reg(ha, entry_addr);
2904                         ql_8021_write_reg(ha, read_value, entry_addr);
2905                         opcode &= ~QL_DBG_OPCODE_RW;
2906                 }
2907                 if (opcode & QL_DBG_OPCODE_AND) {
2908                         read_value = ql_8021_read_reg(ha, entry_addr);
2909                         read_value &= crbEntry->value_2;
2910                         opcode &= ~QL_DBG_OPCODE_AND;
2911 
2912                         /* Checking for OR here to avoid extra register write */
2913                         if (opcode & QL_DBG_OPCODE_OR) {
2914                                 read_value |= crbEntry->value_3;
2915                                 opcode &= ~QL_DBG_OPCODE_OR;
2916                         }
2917                         ql_8021_write_reg(ha, read_value, entry_addr);
2918                 }
2919                 if (opcode & QL_DBG_OPCODE_OR) {
2920                         read_value = ql_8021_read_reg(ha, entry_addr);
2921                         read_value |= crbEntry->value_3;
2922                         ql_8021_write_reg(ha, read_value, entry_addr);
2923                         opcode &= ~QL_DBG_OPCODE_OR;
2924                 }
2925                 if (opcode & QL_DBG_OPCODE_POLL) {
2926                         opcode &= ~QL_DBG_OPCODE_POLL;
2927                         (void) drv_getparm(LBOLT, &timeout);
2928                         timeout += drv_usectohz(
2929                             CHAR_TO_SHORT(crbEntry->a.ac.poll_timeout[0],
2930                             crbEntry->a.ac.poll_timeout[1]) * 1000) + 1;
2931                         addr = entry_addr;
2932                         read_value = ql_8021_read_reg(ha, addr);
2933                         tflag = 0;
2934                         while (!tflag && ((read_value & crbEntry->value_2) !=
2935                             crbEntry->value_1)) {
2936                                 (void) drv_getparm(LBOLT, &elapsed);
2937                                 if (elapsed > timeout) {
2938                                         tflag = 1;
2939                                 }
2940                                 read_value = ql_8021_read_reg(ha, addr);
2941                         }
2942                         if (tflag) {
2943                                 /*
2944                                  *  Report timeout error.  core dump capture
2945                                  *  failed Skip remaining entries. Write buffer
2946                                  *  out to file Use driver specific fields in
2947                                  *  template header to report this error.
2948                                  */
2949                                 EL(ha, "timeout\n");
2950                                 return (-1);
2951                         }
2952                 }
2953                 if (opcode & QL_DBG_OPCODE_RDSTATE) {
2954                         /*
2955                          * decide which address to use.
2956                          */
2957                         if (crbEntry->a.ac.state_index_a) {
2958                                 addr = template_hdr->saved_state_array[
2959                                     crbEntry->a.ac.state_index_a];
2960                         } else {
2961                                 addr = entry_addr;
2962                         }
2963                         read_value = ql_8021_read_reg(ha, addr);
2964                         template_hdr->saved_state_array[
2965                             crbEntry->b.cv.state_index_v] = read_value;
2966                         opcode &= ~QL_DBG_OPCODE_RDSTATE;
2967                 }
2968                 if (opcode & QL_DBG_OPCODE_WRSTATE) {
2969                         /*
2970                          * decide which value to use.
2971                          */
2972                         if (crbEntry->b.cv.state_index_v) {
2973                                 read_value = template_hdr->saved_state_array[
2974                                     crbEntry->b.cv.state_index_v];
2975                         } else {
2976                                 read_value = crbEntry->value_1;
2977                         }
2978                         /*
2979                          * decide which address to use.
2980                          */
2981                         if (crbEntry->a.ac.state_index_a) {
2982                                 addr = template_hdr->saved_state_array[
2983                                     crbEntry->a.ac.state_index_a];
2984                         } else {
2985                                 addr = entry_addr;
2986                         }
2987                         ql_8021_write_reg(ha, read_value, addr);
2988                         opcode &= ~QL_DBG_OPCODE_WRSTATE;
2989                 }
2990                 if (opcode & QL_DBG_OPCODE_MDSTATE) {
2991                         /* Read value from saved state using index */
2992                         read_value = template_hdr->saved_state_array[
2993                             crbEntry->b.cv.state_index_v];
2994                         /* Shift left operation */
2995                         read_value <<= crbEntry->b.cv.shl;
2996                         /* Shift right operation */
2997                         read_value >>= crbEntry->b.cv.shr;
2998                         /* check if AND mask is provided */
2999                         if (crbEntry->value_2) {
3000                                 read_value &= crbEntry->value_2;
3001                         }
3002                         read_value |= crbEntry->value_3; /* OR operation */
3003                         read_value += crbEntry->value_1; /* inc operation */
3004                         /* Write value back to state area. */
3005                         template_hdr->saved_state_array[
3006                             crbEntry->b.cv.state_index_v] = read_value;
3007                         opcode &= ~QL_DBG_OPCODE_MDSTATE;
3008                 }
3009                 entry_addr += crbEntry->a.ac.addr_stride;
3010         }
3011 
3012         return (0);
3013 }
3014 
3015 /*
3016  * Error Checking routines for template consistency.
3017  *
3018  * We catch an error where driver does not read
3019  * as much data as we expect from the entry.
3020  */
3021 static void
3022 ql_8021_md_entry_err_chk(ql_adapter_state_t *ha, md_entry_t *entry,
3023     uint32_t esize, int e_cnt)
3024 {
3025         if (esize != entry->h.entry_capture_size) {
3026                 EL(ha, "%d %04x Dump write count = %d did not match entry "
3027                     "capture size = %d entry_count = %d\n", entry->h.entry_type,
3028                     entry->h.a.ecw.entry_capture_mask, esize,
3029                     entry->h.entry_capture_size, e_cnt);
3030                 entry->h.entry_capture_size = esize;
3031                 entry->h.a.ecw.driver_flags = (uint8_t)
3032                     (entry->h.a.ecw.driver_flags | QL_DBG_SKIPPED_FLAG);
3033         }
3034 }
3035 
3036 static uint32_t
3037 ql_8021_md_template_checksum(ql_adapter_state_t *ha)
3038 {
3039         uint64_t        sum = 0;
3040         uint32_t        cnt, *bp;
3041 
3042         cnt = (uint32_t)(ha->dmp_template.size / sizeof (uint32_t));
3043         bp = ha->dmp_template.bp;
3044         while (cnt-- > 0) {
3045                 sum += ddi_get32(ha->dmp_template.acc_handle, bp++);
3046         }
3047         while (sum >> 32) {
3048                 sum = (sum & 0xFFFFFFFF) + (sum >> 32);
3049         }
3050         cnt = (uint32_t)~sum;
3051 
3052         return (cnt);
3053 }
3054 
3055 static uint32_t
3056 ql_8021_read_reg(ql_adapter_state_t *ha, uint32_t addr)
3057 {
3058         uint32_t        addr0, addr1, value;
3059 
3060         (void) ql_8021_crb_win_lock(ha);
3061 
3062         addr0 = addr & 0xFFFF0000;
3063         WRT_REG_DWORD(ha, (ha->nx_pcibase + 0x00130060), addr0);
3064         /* PCI posting read */
3065         (void) RD_REG_DWORD(ha, (ha->nx_pcibase + 0x00130060));
3066         addr1 = addr & 0x0000FFFF;
3067         value = RD_REG_DWORD(ha, (ha->nx_pcibase + 0x001E0000 + addr1));
3068 
3069         ql_8021_crb_win_unlock(ha);
3070 
3071         return (value);
3072 }
3073 
3074 static void
3075 ql_8021_write_reg(ql_adapter_state_t *ha, uint32_t value, uint32_t addr)
3076 {
3077         uint32_t        addr0, addr1;
3078 
3079         (void) ql_8021_crb_win_lock(ha);
3080 
3081         addr0 = addr & 0xFFFF0000;
3082         WRT_REG_DWORD(ha, (ha->nx_pcibase + 0x00130060), addr0);
3083         /* PCI posting read */
3084         (void) RD_REG_DWORD(ha, (ha->nx_pcibase + 0x00130060));
3085         addr1 = addr & 0x0000FFFF;
3086         WRT_REG_DWORD(ha, (ha->nx_pcibase + 0x001E0000 + addr1), value);
3087         /* PCI posting read */
3088         (void) RD_REG_DWORD(ha, (ha->nx_pcibase + 0x001E0000 + addr1));
3089 
3090         ql_8021_crb_win_unlock(ha);
3091 }
3092 
3093 static uint32_t
3094 ql_8021_read_ocm(ql_adapter_state_t *ha, uint32_t addr)
3095 {
3096         uint32_t        value;
3097 
3098         value = RD_REG_DWORD(ha, (ha->nx_pcibase + addr));
3099 
3100         return (value);
3101 }