1 /*
   2  * CDDL HEADER START
   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},
 136             {0, 0x0000000, 0x0000000, 0x000000},
 137             {0, 0x0000000, 0x0000000, 0x000000},
 138             {0, 0x0000000, 0x0000000, 0x000000},
 139             {0, 0x0000000, 0x0000000, 0x000000},
 140             {0, 0x0000000, 0x0000000, 0x000000},
 141             {0, 0x0000000, 0x0000000, 0x000000},
 142             {1, 0x01e0000, 0x01e0800, 0x122000},
 143             {0, 0x0000000, 0x0000000, 0x000000}}},
 144         {{{1, 0x0200000, 0x0210000, 0x180000}}},        /* 2: MN */
 145         {{{0, 0,         0,      0}}},                  /* 3: */
 146         {{{1, 0x0400000, 0x0401000, 0x169000}}},        /* 4: P2NR1 */
 147         {{{1, 0x0500000, 0x0510000, 0x140000}}},        /* 5: SRE   */
 148         {{{1, 0x0600000, 0x0610000, 0x1c0000}}},        /* 6: NIU   */
 149         {{{1, 0x0700000, 0x0704000, 0x1b8000}}},        /* 7: QM    */
 150         {{{1, 0x0800000, 0x0802000, 0x170000},          /* 8: SQM0  */
 151             {0, 0x0000000, 0x0000000, 0x000000},
 152             {0, 0x0000000, 0x0000000, 0x000000},
 153             {0, 0x0000000, 0x0000000, 0x000000},
 154             {0, 0x0000000, 0x0000000, 0x000000},
 155             {0, 0x0000000, 0x0000000, 0x000000},
 156             {0, 0x0000000, 0x0000000, 0x000000},
 157             {0, 0x0000000, 0x0000000, 0x000000},
 158             {0, 0x0000000, 0x0000000, 0x000000},
 159             {0, 0x0000000, 0x0000000, 0x000000},
 160             {0, 0x0000000, 0x0000000, 0x000000},
 161             {0, 0x0000000, 0x0000000, 0x000000},
 162             {0, 0x0000000, 0x0000000, 0x000000},
 163             {0, 0x0000000, 0x0000000, 0x000000},
 164             {0, 0x0000000, 0x0000000, 0x000000},
 165             {1, 0x08f0000, 0x08f2000, 0x172000}}},
 166         {{{1, 0x0900000, 0x0902000, 0x174000},          /* 9: SQM1 */
 167             {0, 0x0000000, 0x0000000, 0x000000},
 168             {0, 0x0000000, 0x0000000, 0x000000},
 169             {0, 0x0000000, 0x0000000, 0x000000},
 170             {0, 0x0000000, 0x0000000, 0x000000},
 171             {0, 0x0000000, 0x0000000, 0x000000},
 172             {0, 0x0000000, 0x0000000, 0x000000},
 173             {0, 0x0000000, 0x0000000, 0x000000},
 174             {0, 0x0000000, 0x0000000, 0x000000},
 175             {0, 0x0000000, 0x0000000, 0x000000},
 176             {0, 0x0000000, 0x0000000, 0x000000},
 177             {0, 0x0000000, 0x0000000, 0x000000},
 178             {0, 0x0000000, 0x0000000, 0x000000},
 179             {0, 0x0000000, 0x0000000, 0x000000},
 180             {0, 0x0000000, 0x0000000, 0x000000},
 181             {1, 0x09f0000, 0x09f2000, 0x176000}}},
 182         {{{0, 0x0a00000, 0x0a02000, 0x178000},          /* 10: SQM2 */
 183             {0, 0x0000000, 0x0000000, 0x000000},
 184             {0, 0x0000000, 0x0000000, 0x000000},
 185             {0, 0x0000000, 0x0000000, 0x000000},
 186             {0, 0x0000000, 0x0000000, 0x000000},
 187             {0, 0x0000000, 0x0000000, 0x000000},
 188             {0, 0x0000000, 0x0000000, 0x000000},
 189             {0, 0x0000000, 0x0000000, 0x000000},
 190             {0, 0x0000000, 0x0000000, 0x000000},
 191             {0, 0x0000000, 0x0000000, 0x000000},
 192             {0, 0x0000000, 0x0000000, 0x000000},
 193             {0, 0x0000000, 0x0000000, 0x000000},
 194             {0, 0x0000000, 0x0000000, 0x000000},
 195             {0, 0x0000000, 0x0000000, 0x000000},
 196             {0, 0x0000000, 0x0000000, 0x000000},
 197             {1, 0x0af0000, 0x0af2000, 0x17a000}}},
 198         {{{0, 0x0b00000, 0x0b02000, 0x17c000},          /* 11: SQM3 */
 199             {0, 0x0000000, 0x0000000, 0x000000},
 200             {0, 0x0000000, 0x0000000, 0x000000},
 201             {0, 0x0000000, 0x0000000, 0x000000},
 202             {0, 0x0000000, 0x0000000, 0x000000},
 203             {0, 0x0000000, 0x0000000, 0x000000},
 204             {0, 0x0000000, 0x0000000, 0x000000},
 205             {0, 0x0000000, 0x0000000, 0x000000},
 206             {0, 0x0000000, 0x0000000, 0x000000},
 207             {0, 0x0000000, 0x0000000, 0x000000},
 208             {0, 0x0000000, 0x0000000, 0x000000},
 209             {0, 0x0000000, 0x0000000, 0x000000},
 210             {0, 0x0000000, 0x0000000, 0x000000},
 211             {0, 0x0000000, 0x0000000, 0x000000},
 212             {0, 0x0000000, 0x0000000, 0x000000},
 213             {1, 0x0bf0000, 0x0bf2000, 0x17e000}}},
 214         {{{1, 0x0c00000, 0x0c04000, 0x1d4000}}},        /* 12: I2Q */
 215         {{{1, 0x0d00000, 0x0d04000, 0x1a4000}}},        /* 13: TMR */
 216         {{{1, 0x0e00000, 0x0e04000, 0x1a0000}}},        /* 14: ROMUSB */
 217         {{{1, 0x0f00000, 0x0f01000, 0x164000}}},        /* 15: PEG4 */
 218         {{{0, 0x1000000, 0x1004000, 0x1a8000}}},        /* 16: XDMA */
 219         {{{1, 0x1100000, 0x1101000, 0x160000}}},        /* 17: PEG0 */
 220         {{{1, 0x1200000, 0x1201000, 0x161000}}},        /* 18: PEG1 */
 221         {{{1, 0x1300000, 0x1301000, 0x162000}}},        /* 19: PEG2 */
 222         {{{1, 0x1400000, 0x1401000, 0x163000}}},        /* 20: PEG3 */
 223         {{{1, 0x1500000, 0x1501000, 0x165000}}},        /* 21: P2ND */
 224         {{{1, 0x1600000, 0x1601000, 0x166000}}},        /* 22: P2NI */
 225         {{{0, 0,         0,      0}}},                  /* 23: */
 226         {{{0, 0,         0,      0}}},                  /* 24: */
 227         {{{0, 0,         0,      0}}},                  /* 25: */
 228         {{{0, 0,         0,      0}}},                  /* 26: */
 229         {{{0, 0,         0,      0}}},                  /* 27: */
 230         {{{0, 0,         0,      0}}},                  /* 28: */
 231         {{{1, 0x1d00000, 0x1d10000, 0x190000}}},        /* 29: MS */
 232         {{{1, 0x1e00000, 0x1e01000, 0x16a000}}},        /* 30: P2NR2 */
 233         {{{1, 0x1f00000, 0x1f10000, 0x150000}}},        /* 31: EPG */
 234         {{{0}}},                                        /* 32: PCI */
 235         {{{1, 0x2100000, 0x2102000, 0x120000},          /* 33: PCIE */
 236             {1, 0x2110000, 0x2120000, 0x130000},
 237             {1, 0x2120000, 0x2122000, 0x124000},
 238             {1, 0x2130000, 0x2132000, 0x126000},
 239             {1, 0x2140000, 0x2142000, 0x128000},
 240             {1, 0x2150000, 0x2152000, 0x12a000},
 241             {1, 0x2160000, 0x2170000, 0x110000},
 242             {1, 0x2170000, 0x2172000, 0x12e000},
 243             {0, 0x0000000, 0x0000000, 0x000000},
 244             {0, 0x0000000, 0x0000000, 0x000000},
 245             {0, 0x0000000, 0x0000000, 0x000000},
 246             {0, 0x0000000, 0x0000000, 0x000000},
 247             {0, 0x0000000, 0x0000000, 0x000000},
 248             {0, 0x0000000, 0x0000000, 0x000000},
 249             {0, 0x0000000, 0x0000000, 0x000000},
 250             {0, 0x0000000, 0x0000000, 0x000000}}},
 251         {{{1, 0x2200000, 0x2204000, 0x1b0000}}},        /* 34: CAM */
 252         {{{0}}},                                        /* 35: */
 253         {{{0}}},                                        /* 36: */
 254         {{{0}}},                                        /* 37: */
 255         {{{0}}},                                        /* 38: */
 256         {{{0}}},                                        /* 39: */
 257         {{{1, 0x2800000, 0x2804000, 0x1a4000}}},        /* 40: TMR */
 258         {{{1, 0x2900000, 0x2901000, 0x16b000}}},        /* 41: P2NR3 */
 259         {{{1, 0x2a00000, 0x2a00400, 0x1ac400}}},        /* 42: RPMX1 */
 260         {{{1, 0x2b00000, 0x2b00400, 0x1ac800}}},        /* 43: RPMX2 */
 261         {{{1, 0x2c00000, 0x2c00400, 0x1acc00}}},        /* 44: RPMX3 */
 262         {{{1, 0x2d00000, 0x2d00400, 0x1ad000}}},        /* 45: RPMX4 */
 263         {{{1, 0x2e00000, 0x2e00400, 0x1ad400}}},        /* 46: RPMX5 */
 264         {{{1, 0x2f00000, 0x2f00400, 0x1ad800}}},        /* 47: RPMX6 */
 265         {{{1, 0x3000000, 0x3000400, 0x1adc00}}},        /* 48: RPMX7 */
 266         {{{0, 0x3100000, 0x3104000, 0x1a8000}}},        /* 49: XDMA */
 267         {{{1, 0x3200000, 0x3204000, 0x1d4000}}},        /* 50: I2Q */
 268         {{{1, 0x3300000, 0x3304000, 0x1a0000}}},        /* 51: ROMUSB */
 269         {{{0}}},                                        /* 52: */
 270         {{{1, 0x3500000, 0x3500400, 0x1ac000}}},        /* 53: RPMX0 */
 271         {{{1, 0x3600000, 0x3600400, 0x1ae000}}},        /* 54: RPMX8 */
 272         {{{1, 0x3700000, 0x3700400, 0x1ae400}}},        /* 55: RPMX9 */
 273         {{{1, 0x3800000, 0x3804000, 0x1d0000}}},        /* 56: OCM0 */
 274         {{{1, 0x3900000, 0x3904000, 0x1b4000}}},        /* 57: CRYPTO */
 275         {{{1, 0x3a00000, 0x3a04000, 0x1d8000}}},        /* 58: SMB */
 276         {{{0}}},                                        /* 59: I2C0 */
 277         {{{0}}},                                        /* 60: I2C1 */
 278         {{{1, 0x3d00000, 0x3d04000, 0x1dc000}}},        /* 61: LPC */
 279         {{{1, 0x3e00000, 0x3e01000, 0x167000}}},        /* 62: P2NC */
 280         {{{1, 0x3f00000, 0x3f01000, 0x168000}}}         /* 63: P2NR0 */
 281 };
 282 
 283 /*
 284  * top 12 bits of crb internal address (hub, agent)
 285  */
 286 static uint32_t crb_hub_agt[64] = {
 287         0,
 288         UNM_HW_CRB_HUB_AGT_ADR_PS,
 289         UNM_HW_CRB_HUB_AGT_ADR_MN,
 290         UNM_HW_CRB_HUB_AGT_ADR_MS,
 291         0,
 292         UNM_HW_CRB_HUB_AGT_ADR_SRE,
 293         UNM_HW_CRB_HUB_AGT_ADR_NIU,
 294         UNM_HW_CRB_HUB_AGT_ADR_QMN,
 295         UNM_HW_CRB_HUB_AGT_ADR_SQN0,
 296         UNM_HW_CRB_HUB_AGT_ADR_SQN1,
 297         UNM_HW_CRB_HUB_AGT_ADR_SQN2,
 298         UNM_HW_CRB_HUB_AGT_ADR_SQN3,
 299         UNM_HW_CRB_HUB_AGT_ADR_I2Q,
 300         UNM_HW_CRB_HUB_AGT_ADR_TIMR,
 301         UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
 302         UNM_HW_CRB_HUB_AGT_ADR_PGN4,
 303         UNM_HW_CRB_HUB_AGT_ADR_XDMA,
 304         UNM_HW_CRB_HUB_AGT_ADR_PGN0,
 305         UNM_HW_CRB_HUB_AGT_ADR_PGN1,
 306         UNM_HW_CRB_HUB_AGT_ADR_PGN2,
 307         UNM_HW_CRB_HUB_AGT_ADR_PGN3,
 308         UNM_HW_CRB_HUB_AGT_ADR_PGND,
 309         UNM_HW_CRB_HUB_AGT_ADR_PGNI,
 310         UNM_HW_CRB_HUB_AGT_ADR_PGS0,
 311         UNM_HW_CRB_HUB_AGT_ADR_PGS1,
 312         UNM_HW_CRB_HUB_AGT_ADR_PGS2,
 313         UNM_HW_CRB_HUB_AGT_ADR_PGS3,
 314         0,
 315         UNM_HW_CRB_HUB_AGT_ADR_PGSI,
 316         UNM_HW_CRB_HUB_AGT_ADR_SN,
 317         0,
 318         UNM_HW_CRB_HUB_AGT_ADR_EG,
 319         0,
 320         UNM_HW_CRB_HUB_AGT_ADR_PS,
 321         UNM_HW_CRB_HUB_AGT_ADR_CAM,
 322         0,
 323         0,
 324         0,
 325         0,
 326         0,
 327         UNM_HW_CRB_HUB_AGT_ADR_TIMR,
 328         0,
 329         UNM_HW_CRB_HUB_AGT_ADR_RPMX1,
 330         UNM_HW_CRB_HUB_AGT_ADR_RPMX2,
 331         UNM_HW_CRB_HUB_AGT_ADR_RPMX3,
 332         UNM_HW_CRB_HUB_AGT_ADR_RPMX4,
 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);
 373         crb_addr_transform(RPMX2);
 374         crb_addr_transform(RPMX1);
 375         crb_addr_transform(RPMX0);
 376         crb_addr_transform(ROMUSB);
 377         crb_addr_transform(SN);
 378         crb_addr_transform(QMN);
 379         crb_addr_transform(QMS);
 380         crb_addr_transform(PGNI);
 381         crb_addr_transform(PGND);
 382         crb_addr_transform(PGN3);
 383         crb_addr_transform(PGN2);
 384         crb_addr_transform(PGN1);
 385         crb_addr_transform(PGN0);
 386         crb_addr_transform(PGSI);
 387         crb_addr_transform(PGSD);
 388         crb_addr_transform(PGS3);
 389         crb_addr_transform(PGS2);
 390         crb_addr_transform(PGS1);
 391         crb_addr_transform(PGS0);
 392         crb_addr_transform(PS);
 393         crb_addr_transform(PH);
 394         crb_addr_transform(NIU);
 395         crb_addr_transform(I2Q);
 396         crb_addr_transform(EG);
 397         crb_addr_transform(MN);
 398         crb_addr_transform(MS);
 399         crb_addr_transform(CAS2);
 400         crb_addr_transform(CAS1);
 401         crb_addr_transform(CAS0);
 402         crb_addr_transform(CAM);
 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         }
 483 
 484         if (rv == 1) {
 485                 ql_8021_crb_win_unlock(ha);
 486         }
 487 }
 488 
 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 
 530         if (*off >= UNM_PCI_CAMQM && (*off < UNM_PCI_CAMQM_2M_END)) {
 531                 *off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
 532                     (uintptr_t)ha->nx_pcibase;
 533                 return (0);
 534         }
 535 
 536         if (*off < UNM_PCI_CRBSPACE) {
 537                 EL(ha, "%llx < %llx\n", *off, UNM_PCI_CRBSPACE);
 538                 return (-1);
 539         }
 540 
 541         *off -= UNM_PCI_CRBSPACE;
 542         /*
 543          * Try direct map
 544          */
 545 
 546         m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
 547 
 548         if (m->valid && ((uint64_t)m->start_128M <= *off) &&
 549             ((uint64_t)m->end_128M > *off)) {
 550                 *off = (uint64_t)(*off + m->start_2M - m->start_128M +
 551                     (uintptr_t)ha->nx_pcibase);
 552                 return (0);
 553         }
 554 
 555         /*
 556          * Not in direct map, use crb window
 557          */
 558         return (1);
 559 }
 560 
 561 /*
 562  * check memory access boundary.
 563  * used by test agent. support ddr access only for now
 564  */
 565 /* ARGSUSED */
 566 static uint32_t
 567 ql_8021_pci_mem_bound_check(ql_adapter_state_t *ha, uint64_t addr,
 568     uint32_t size)
 569 {
 570         /*LINTED suspicious 0 comparison*/
 571         if (!QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
 572             UNM_ADDR_DDR_NET_MAX) ||
 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 
 647 /* check if address is in the same windows as the previous access */
 648 static int
 649 ql_8021_pci_is_same_window(ql_adapter_state_t *ha, uint64_t addr)
 650 {
 651         uint32_t        window;
 652         uint64_t        qdr_max;
 653 
 654         qdr_max = NX_P3_ADDR_QDR_NET_MAX;
 655 
 656         /*LINTED suspicious 0 comparison*/
 657         if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
 658             UNM_ADDR_DDR_NET_MAX)) {
 659                 /* DDR network side */
 660                 EL(ha, "DDR network side\n");
 661                 return (0);     /* MN access can not come here */
 662         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
 663             UNM_ADDR_OCM0_MAX)) {
 664                 return (1);
 665         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM1,
 666             UNM_ADDR_OCM1_MAX)) {
 667                 return (1);
 668         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
 669                 /* QDR network side */
 670                 window = (uint32_t)(((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f);
 671                 if (ha->qdr_sn_window == window) {
 672                         return (1);
 673                 }
 674         }
 675 
 676         return (0);
 677 }
 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 
 719         return (ret);
 720 }
 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 
 762         return (ret);
 763 }
 764 
 765 static int
 766 ql_8021_pci_mem_read_2M(ql_adapter_state_t *ha, uint64_t off, void *data,
 767     uint32_t size)
 768 {
 769         int             j = 0;
 770         uint32_t        i, temp, sz[2], loop, shift_amount;
 771         uint64_t        start, end, k;
 772         uint64_t        off8, off0[2], val, mem_crb, word[2] = {0, 0};
 773 
 774         /*
 775          * If not MN, go check for MS or invalid.
 776          */
 777 
 778         if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
 779                 mem_crb = UNM_CRB_QDR_NET;
 780         } else {
 781                 mem_crb = UNM_CRB_DDR_NET;
 782                 if (ql_8021_pci_mem_bound_check(ha, off, size) == 0) {
 783                         return (ql_8021_pci_mem_read_direct(ha, off, data,
 784                             size));
 785                 }
 786         }
 787 
 788         if (NX_IS_REVISION_P3PLUS(ha->rev_id)) {
 789                 off8 = off & 0xfffffff0;
 790                 off0[0] = off & 0xf;
 791                 sz[0] = (uint32_t)(((uint64_t)size < (16 - off0[0])) ? size :
 792                     (16 - off0[0]));
 793                 shift_amount = 4;
 794         } else {
 795                 off8 = off & 0xfffffff8;
 796                 off0[0] = off & 0x7;
 797                 sz[0] = (uint32_t)(((uint64_t)size < (8 - off0[0])) ? size :
 798                     (8 - off0[0]));
 799                 shift_amount = 3;
 800         }
 801         loop = (uint32_t)(((off0[0] + size - 1) >> shift_amount) + 1);
 802         off0[1] = 0;
 803         sz[1] = size - sz[0];
 804 
 805         /*
 806          * don't lock here - write_wx gets the lock if each time
 807          * write_lock_irqsave(&adapter->adapter_lock, flags);
 808          * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
 809          */
 810 
 811         for (i = 0; i < loop; i++) {
 812                 temp = (uint32_t)(off8 + (i << shift_amount));
 813                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
 814                 temp = 0;
 815                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
 816                 temp = MIU_TA_CTL_ENABLE;
 817                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
 818                 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
 819                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
 820 
 821                 for (j = 0; j < MAX_CTL_CHECK; j++) {
 822                         ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL, &temp);
 823                         if ((temp & MIU_TA_CTL_BUSY) == 0) {
 824                                 break;
 825                         }
 826                 }
 827 
 828                 if (j >= MAX_CTL_CHECK) {
 829                         EL(ha, "failed to read through agent\n");
 830                         break;
 831                 }
 832 
 833                 start = off0[i] >> 2;
 834                 end = (off0[i] + sz[i] - 1) >> 2;
 835                 for (k = start; k <= end; k++) {
 836                         ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_RDDATA(k),
 837                             &temp);
 838                         word[i] |= ((uint64_t)temp << (32 * (k & 1)));
 839                 }
 840         }
 841 
 842         /*
 843          * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
 844          * write_unlock_irqrestore(&adapter->adapter_lock, flags);
 845          */
 846 
 847         if (j >= MAX_CTL_CHECK) {
 848                 return (-1);
 849         }
 850 
 851         if ((off0[0] & 7) == 0) {
 852                 val = word[0];
 853         } else {
 854                 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
 855                     ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
 856         }
 857 
 858         switch (size) {
 859         case 1:
 860                 *(uint8_t *)data = (uint8_t)val;
 861                 break;
 862         case 2:
 863                 *(uint16_t *)data = (uint16_t)val;
 864                 break;
 865         case 4:
 866                 *(uint32_t *)data = (uint32_t)val;
 867                 break;
 868         case 8:
 869                 *(uint64_t *)data = val;
 870                 break;
 871         }
 872 
 873         return (0);
 874 }
 875 
 876 static int
 877 ql_8021_pci_mem_write_2M(ql_adapter_state_t *ha, uint64_t off, void *data,
 878     uint32_t size)
 879 {
 880         int             j, ret = 0;
 881         uint32_t        i, temp, loop, sz[2];
 882         uint32_t        scale, shift_amount, p3p, startword;
 883         uint64_t        off8, off0, mem_crb, tmpw, word[2] = {0, 0};
 884 
 885         /*
 886          * If not MN, go check for MS or invalid.
 887          */
 888         if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
 889                 mem_crb = UNM_CRB_QDR_NET;
 890         } else {
 891                 mem_crb = UNM_CRB_DDR_NET;
 892                 if (ql_8021_pci_mem_bound_check(ha, off, size) == 0) {
 893                         return (ql_8021_pci_mem_write_direct(ha, off, data,
 894                             size));
 895                 }
 896         }
 897 
 898         off0 = off & 0x7;
 899         sz[0] = (uint32_t)(((uint64_t)size < (8 - off0)) ? size : (8 - off0));
 900         sz[1] = size - sz[0];
 901 
 902         if (NX_IS_REVISION_P3PLUS(ha->rev_id)) {
 903                 off8 = off & 0xfffffff0;
 904                 loop = (uint32_t)((((off & 0xf) + size - 1) >> 4) + 1);
 905                 shift_amount = 4;
 906                 scale = 2;
 907                 p3p = 1;
 908                 startword = (uint32_t)((off & 0xf) / 8);
 909         } else {
 910                 off8 = off & 0xfffffff8;
 911                 loop = (uint32_t)(((off0 + size - 1) >> 3) + 1);
 912                 shift_amount = 3;
 913                 scale = 1;
 914                 p3p = 0;
 915                 startword = 0;
 916         }
 917 
 918         if (p3p || (size != 8) || (off0 != 0)) {
 919                 for (i = 0; i < loop; i++) {
 920                         if (ql_8021_pci_mem_read_2M(ha, off8 +
 921                             (i << shift_amount), &word[i * scale], 8)) {
 922                                 EL(ha, "8021_pci_mem_read_2M != 0\n");
 923                                 return (-1);
 924                         }
 925                 }
 926         }
 927 
 928         switch (size) {
 929         case 1:
 930                 tmpw = (uint64_t)(*((uint8_t *)data));
 931                 break;
 932         case 2:
 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);
 975                 temp = 0;
 976                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
 977                 temp = (uint32_t)(word[i * scale] & 0xffffffff);
 978                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_LO, temp);
 979                 temp = (uint32_t)((word[i * scale] >> 32) & 0xffffffff);
 980                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_HI, temp);
 981                 if (p3p) {
 982                         temp = (uint32_t)(word[i * scale + 1] & 0xffffffff);
 983                         ql_8021_wr_32(ha,
 984                             mem_crb + MIU_TEST_AGT_WRDATA_UPPER_LO, temp);
 985                         temp = (uint32_t)((word[i * scale + 1] >> 32) &
 986                             0xffffffff);
 987                         ql_8021_wr_32(ha,
 988                             mem_crb + MIU_TEST_AGT_WRDATA_UPPER_HI, temp);
 989                 }
 990                 temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
 991                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
 992                 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
 993                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
 994 
 995                 for (j = 0; j < MAX_CTL_CHECK; j++) {
 996                         ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL, &temp);
 997                         if ((temp & MIU_TA_CTL_BUSY) == 0)
 998                                 break;
 999                 }
1000 
1001                 if (j >= MAX_CTL_CHECK) {
1002                         EL(ha, "failed to write through agent\n");
1003                         ret = -1;
1004                         break;
1005                 }
1006         }
1007 
1008         return (ret);
1009 }
1010 
1011 static uint32_t
1012 ql_8021_decode_crb_addr(ql_adapter_state_t *ha, uint32_t addr)
1013 {
1014         int             i;
1015         uint32_t        base_addr, offset, pci_base;
1016 
1017         if (!crb_table_initialized) {
1018                 ql_crb_addr_transform_setup(ha);
1019         }
1020 
1021         pci_base = ADDR_ERROR;
1022         base_addr = addr & 0xfff00000;
1023         offset = addr & 0x000fffff;
1024 
1025         for (i = 0; i < MAX_CRB_XFORM; i++) {
1026                 if (crb_addr_xform[i] == base_addr) {
1027                         pci_base = i << 20;
1028                         break;
1029                 }
1030         }
1031         if (pci_base == ADDR_ERROR) {
1032                 return (pci_base);
1033         } else {
1034                 return (pci_base + offset);
1035         }
1036 }
1037 
1038 static int
1039 ql_8021_hw_lock(ql_adapter_state_t *ha, uint32_t timer)
1040 {
1041         uint32_t        done = 0, timeout = 0;
1042 
1043         while (!done) {
1044                 /* acquire semaphore5 from PCI HW block */
1045                 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM5_LOCK), &done);
1046                 if (done == 1) {
1047                         break;
1048                 }
1049                 if (timeout >= timer) {
1050                         EL(ha, "timeout\n");
1051                         return (-1);
1052                 }
1053                 timeout++;
1054 
1055                 /*
1056                  * Yield CPU
1057                  */
1058                 delay(1);
1059         }
1060 
1061         return (0);
1062 }
1063 
1064 static void
1065 ql_8021_hw_unlock(ql_adapter_state_t *ha)
1066 {
1067         ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM5_UNLOCK), NULL);
1068 }
1069 
1070 static int
1071 ql_8021_rom_lock(ql_adapter_state_t *ha)
1072 {
1073         uint32_t        done = 0, timeout = 0;
1074 
1075         while (!done) {
1076                 /* acquire semaphore2 from PCI HW block */
1077                 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM2_LOCK), &done);
1078                 if (done == 1) {
1079                         break;
1080                 }
1081                 if (timeout >= ROM_LOCK_TIMEOUT) {
1082                         EL(ha, "timeout\n");
1083                         return (-1);
1084                 }
1085                 timeout++;
1086 
1087                 /*
1088                  * Yield CPU
1089                  */
1090                 delay(1);
1091         }
1092         ql_8021_wr_32(ha, UNM_ROM_LOCK_ID, ROM_LOCK_DRIVER);
1093 
1094         return (0);
1095 }
1096 
1097 static void
1098 ql_8021_rom_unlock(ql_adapter_state_t *ha)
1099 {
1100         ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM2_UNLOCK), NULL);
1101 }
1102 
1103 static int
1104 ql_8021_wait_rom_done(ql_adapter_state_t *ha)
1105 {
1106         uint32_t        timeout = 0, done = 0;
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");
1197                 return (-1);
1198         }
1199 
1200         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
1201         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1202         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1203         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1204             UNM_ROMUSB_ROM_PP_INSTR);
1205         if (ql_8021_wait_rom_done(ha)) {
1206                 EL(ha, "Error waiting for rom done1\n");
1207                 return (-1);
1208         }
1209 
1210         if (ql_8021_wait_flash_done(ha)) {
1211                 EL(ha, "Error waiting for flash done\n");
1212                 return (-1);
1213         }
1214 
1215         return (0);
1216 }
1217 
1218 static int
1219 ql_8021_do_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
1220 {
1221         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1222         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1223             UNM_ROMUSB_ROM_WREN_INSTR);
1224         if (ql_8021_wait_rom_done(ha)) {
1225                 EL(ha, "Error waiting for rom done\n");
1226                 return (-1);
1227         }
1228 
1229         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1230         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1231         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1232             UNM_ROMUSB_ROM_SE_INSTR);
1233         if (ql_8021_wait_rom_done(ha)) {
1234                 EL(ha, "Error waiting for rom done1\n");
1235                 return (-1);
1236         }
1237 
1238         if (ql_8021_wait_flash_done(ha)) {
1239                 EL(ha, "Error waiting for flash done\n");
1240                 return (-1);
1241         }
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;
1326                         } else if (ql_8021_wait_flash_done(ha)) {
1327                                 EL(ha, "Error waiting for flash done\n");
1328                                 ret = QL_FUNCTION_FAILED;
1329                         }
1330                 }
1331                 ql_8021_rom_unlock(ha);
1332         }
1333 
1334         return (ret);
1335 }
1336 
1337 static int
1338 ql_8021_phantom_init(ql_adapter_state_t *ha)
1339 {
1340         uint32_t        val = 0, err = 0;
1341         int             retries = 60;
1342 
1343         do {
1344                 ql_8021_rd_32(ha, CRB_CMDPEG_STATE, &val);
1345 
1346                 switch (val) {
1347                 case PHAN_INITIALIZE_COMPLETE:
1348                 case PHAN_INITIALIZE_ACK:
1349                         EL(ha, "success=%xh\n", val);
1350                         return (0);
1351                 case PHAN_INITIALIZE_FAILED:
1352                         EL(ha, "PHAN_INITIALIZE_FAILED\n");
1353                         err = 1;
1354                         break;
1355                 default:
1356                         break;
1357                 }
1358 
1359                 if (err) {
1360                         break;
1361                 }
1362                 /* 500 msec wait */
1363                 delay(50);
1364 
1365         } while (--retries);
1366 
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++) {
1408                 if (ql_8021_rom_fast_read(ha, 8 * i + 4 * offset, &val) != 0 ||
1409                     ql_8021_rom_fast_read(ha, 8 * i + 4 * offset + 4, &addr) !=
1410                     0) {
1411                         kmem_free(buf, n * sizeof (struct crb_addr_pair));
1412                         EL(ha, "ql_8021_rom_fast_read != 0 to zalloc memory\n");
1413                         return (-1);
1414                 }
1415 
1416                 buf[i].addr = addr;
1417                 buf[i].data = val;
1418         }
1419 
1420         for (i = 0; i < n; i++) {
1421                 off = ql_8021_decode_crb_addr(ha, buf[i].addr);
1422                 if (off == ADDR_ERROR) {
1423                         EL(ha, "Err: Unknown addr: 0x%lx\n", buf[i].addr);
1424                         continue;
1425                 }
1426                 off += UNM_PCI_CRBSPACE;
1427 
1428                 if (off & 1) {
1429                         continue;
1430                 }
1431 
1432                 /* skipping cold reboot MAGIC */
1433                 if (off == UNM_RAM_COLD_BOOT) {
1434                         continue;
1435                 }
1436                 if (off == (UNM_CRB_I2C0 + 0x1c)) {
1437                         continue;
1438                 }
1439                 /* do not reset PCI */
1440                 if (off == (ROMUSB_GLB + 0xbc)) {
1441                         continue;
1442                 }
1443                 if (off == (ROMUSB_GLB + 0xa8)) {
1444                         continue;
1445                 }
1446                 if (off == (ROMUSB_GLB + 0xc8)) {       /* core clock */
1447                         continue;
1448                 }
1449                 if (off == (ROMUSB_GLB + 0x24)) {       /* MN clock */
1450                         continue;
1451                 }
1452                 if (off == (ROMUSB_GLB + 0x1c)) {       /* MS clock */
1453                         continue;
1454                 }
1455                 if ((off & 0x0ff00000) == UNM_CRB_DDR_NET) {
1456                         continue;
1457                 }
1458                 if (off == (UNM_CRB_PEG_NET_1 + 0x18) &&
1459                     !NX_IS_REVISION_P3PLUS(ha->rev_id)) {
1460                         buf[i].data = 0x1020;
1461                 }
1462                 /* skip the function enable register */
1463                 if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION)) {
1464                         continue;
1465                 }
1466                 if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION2)) {
1467                         continue;
1468                 }
1469                 if ((off & 0x0ff00000) == UNM_CRB_SMB) {
1470                         continue;
1471                 }
1472 
1473                 /* After writing this register, HW needs time for CRB */
1474                 /* to quiet down (else crb_window returns 0xffffffff) */
1475                 init_delay = 1;
1476                 if (off == UNM_ROMUSB_GLB_SW_RESET) {
1477                         init_delay = 100;       /* Sleep 1000 msecs */
1478                 }
1479 
1480                 ql_8021_wr_32(ha, off, buf[i].data);
1481 
1482                 delay(init_delay);
1483         }
1484         kmem_free(buf, n * sizeof (struct crb_addr_pair));
1485 
1486         /* disable_peg_cache_all */
1487 
1488         /* p2dn replyCount */
1489         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0xec, 0x1e);
1490         /* disable_peg_cache 0 */
1491         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0x4c, 8);
1492         /* disable_peg_cache 1 */
1493         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_I + 0x4c, 8);
1494 
1495         /* peg_clr_all */
1496         /* peg_clr 0 */
1497         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x8, 0);
1498         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0xc, 0);
1499         /* peg_clr 1 */
1500         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0x8, 0);
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) {
1646                         EL(ha, "CRB_UNM_GLB_SW_RST=%x exit\n", data);
1647                         return (-1);
1648                 }
1649                 ql_8021_wr_32(ha, UNM_RAM_COLD_BOOT, 0);
1650         }
1651         ql_8021_rd_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, &data);
1652         data |= 1;
1653         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, data);
1654 
1655         /*
1656          * ???
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 }