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 2010 QLogic Corporation.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "Copyright 2010 QLogic Corporation; ql_nx.c"
  28 
  29 /*
  30  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
  31  *
  32  * ***********************************************************************
  33  * *                                                                    **
  34  * *                            NOTICE                                  **
  35  * *            COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION              **
  36  * *                    ALL RIGHTS RESERVED                             **
  37  * *                                                                    **
  38  * ***********************************************************************
  39  *
  40  */
  41 
  42 #include <ql_apps.h>
  43 #include <ql_api.h>
  44 #include <ql_debug.h>
  45 #include <ql_mbx.h>
  46 #include <ql_nx.h>
  47 
  48 /*
  49  *  Local Function Prototypes.
  50  */
  51 static void *ql_8021_pci_base_offsetfset(ql_adapter_state_t *, uint64_t);
  52 static void ql_crb_addr_transform_setup(ql_adapter_state_t *);
  53 static void ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *, uint64_t *);
  54 static void ql_8021_wr_32(ql_adapter_state_t *, uint64_t, uint32_t);
  55 static void ql_8021_rd_32(ql_adapter_state_t *, uint64_t, uint32_t *);
  56 static int ql_8021_crb_win_lock(ql_adapter_state_t *);
  57 static void ql_8021_crb_win_unlock(ql_adapter_state_t *);
  58 static int ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *, uint64_t *);
  59 static uint32_t ql_8021_pci_mem_bound_check(ql_adapter_state_t *, uint64_t,
  60     uint32_t);
  61 static uint64_t ql_8021_pci_set_window(ql_adapter_state_t *, uint64_t);
  62 static int ql_8021_pci_is_same_window(ql_adapter_state_t *, uint64_t);
  63 static int ql_8021_pci_mem_read_direct(ql_adapter_state_t *, uint64_t, void *,
  64     uint32_t);
  65 static int ql_8021_pci_mem_write_direct(ql_adapter_state_t *, uint64_t, void *,
  66     uint32_t);
  67 static int ql_8021_pci_mem_read_2M(ql_adapter_state_t *, uint64_t, void *,
  68     uint32_t);
  69 static int ql_8021_pci_mem_write_2M(ql_adapter_state_t *, uint64_t, void *,
  70     uint32_t);
  71 static uint32_t ql_8021_decode_crb_addr(ql_adapter_state_t *, uint32_t);
  72 static int ql_8021_rom_lock(ql_adapter_state_t *);
  73 static void ql_8021_rom_unlock(ql_adapter_state_t *);
  74 static int ql_8021_wait_rom_done(ql_adapter_state_t *);
  75 static int ql_8021_wait_flash_done(ql_adapter_state_t *);
  76 static int ql_8021_do_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
  77 static int ql_8021_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
  78 static int ql_8021_do_rom_write(ql_adapter_state_t *, uint32_t, uint32_t);
  79 static int ql_8021_do_rom_erase(ql_adapter_state_t *, uint32_t);
  80 static int ql_8021_phantom_init(ql_adapter_state_t *);
  81 static int ql_8021_pinit_from_rom(ql_adapter_state_t *);
  82 static int ql_8021_load_from_flash(ql_adapter_state_t *);
  83 static int ql_8021_load_firmware(ql_adapter_state_t *);
  84 static int ql_8021_reset_hw(ql_adapter_state_t *, int);
  85 static int ql_8021_init_p3p(ql_adapter_state_t *);
  86 static int ql_8021_hw_lock(ql_adapter_state_t *, uint32_t);
  87 static void ql_8021_hw_unlock(ql_adapter_state_t *);
  88 static void ql_8021_need_reset_handler(ql_adapter_state_t *);
  89 
  90 /*
  91  * Local Data.
  92  */
  93 static uint32_t crb_addr_xform[MAX_CRB_XFORM];
  94 static int      crb_table_initialized = 0;
  95 static int      pci_set_window_warning_count = 0;
  96 
  97 static struct legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
  98 
  99 static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
 100         {{{0, 0,         0,      0}}},                  /* 0: PCI */
 101         {{{1, 0x0100000, 0x0102000, 0x120000},          /* 1: PCIE */
 102             {1, 0x0110000, 0x0120000, 0x130000},
 103             {1, 0x0120000, 0x0122000, 0x124000},
 104             {1, 0x0130000, 0x0132000, 0x126000},
 105             {1, 0x0140000, 0x0142000, 0x128000},
 106             {1, 0x0150000, 0x0152000, 0x12a000},
 107             {1, 0x0160000, 0x0170000, 0x110000},
 108             {1, 0x0170000, 0x0172000, 0x12e000},
 109             {0, 0x0000000, 0x0000000, 0x000000},
 110             {0, 0x0000000, 0x0000000, 0x000000},
 111             {0, 0x0000000, 0x0000000, 0x000000},
 112             {0, 0x0000000, 0x0000000, 0x000000},
 113             {0, 0x0000000, 0x0000000, 0x000000},
 114             {0, 0x0000000, 0x0000000, 0x000000},
 115             {1, 0x01e0000, 0x01e0800, 0x122000},
 116             {0, 0x0000000, 0x0000000, 0x000000}}},
 117         {{{1, 0x0200000, 0x0210000, 0x180000}}},        /* 2: MN */
 118         {{{0, 0,         0,      0}}},                  /* 3: */
 119         {{{1, 0x0400000, 0x0401000, 0x169000}}},        /* 4: P2NR1 */
 120         {{{1, 0x0500000, 0x0510000, 0x140000}}},        /* 5: SRE   */
 121         {{{1, 0x0600000, 0x0610000, 0x1c0000}}},        /* 6: NIU   */
 122         {{{1, 0x0700000, 0x0704000, 0x1b8000}}},        /* 7: QM    */
 123         {{{1, 0x0800000, 0x0802000, 0x170000},          /* 8: SQM0  */
 124             {0, 0x0000000, 0x0000000, 0x000000},
 125             {0, 0x0000000, 0x0000000, 0x000000},
 126             {0, 0x0000000, 0x0000000, 0x000000},
 127             {0, 0x0000000, 0x0000000, 0x000000},
 128             {0, 0x0000000, 0x0000000, 0x000000},
 129             {0, 0x0000000, 0x0000000, 0x000000},
 130             {0, 0x0000000, 0x0000000, 0x000000},
 131             {0, 0x0000000, 0x0000000, 0x000000},
 132             {0, 0x0000000, 0x0000000, 0x000000},
 133             {0, 0x0000000, 0x0000000, 0x000000},
 134             {0, 0x0000000, 0x0000000, 0x000000},
 135             {0, 0x0000000, 0x0000000, 0x000000},
 136             {0, 0x0000000, 0x0000000, 0x000000},
 137             {0, 0x0000000, 0x0000000, 0x000000},
 138             {1, 0x08f0000, 0x08f2000, 0x172000}}},
 139         {{{1, 0x0900000, 0x0902000, 0x174000},          /* 9: SQM1 */
 140             {0, 0x0000000, 0x0000000, 0x000000},
 141             {0, 0x0000000, 0x0000000, 0x000000},
 142             {0, 0x0000000, 0x0000000, 0x000000},
 143             {0, 0x0000000, 0x0000000, 0x000000},
 144             {0, 0x0000000, 0x0000000, 0x000000},
 145             {0, 0x0000000, 0x0000000, 0x000000},
 146             {0, 0x0000000, 0x0000000, 0x000000},
 147             {0, 0x0000000, 0x0000000, 0x000000},
 148             {0, 0x0000000, 0x0000000, 0x000000},
 149             {0, 0x0000000, 0x0000000, 0x000000},
 150             {0, 0x0000000, 0x0000000, 0x000000},
 151             {0, 0x0000000, 0x0000000, 0x000000},
 152             {0, 0x0000000, 0x0000000, 0x000000},
 153             {0, 0x0000000, 0x0000000, 0x000000},
 154             {1, 0x09f0000, 0x09f2000, 0x176000}}},
 155         {{{0, 0x0a00000, 0x0a02000, 0x178000},          /* 10: SQM2 */
 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             {0, 0x0000000, 0x0000000, 0x000000},
 166             {0, 0x0000000, 0x0000000, 0x000000},
 167             {0, 0x0000000, 0x0000000, 0x000000},
 168             {0, 0x0000000, 0x0000000, 0x000000},
 169             {0, 0x0000000, 0x0000000, 0x000000},
 170             {1, 0x0af0000, 0x0af2000, 0x17a000}}},
 171         {{{0, 0x0b00000, 0x0b02000, 0x17c000},          /* 11: SQM3 */
 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             {0, 0x0000000, 0x0000000, 0x000000},
 182             {0, 0x0000000, 0x0000000, 0x000000},
 183             {0, 0x0000000, 0x0000000, 0x000000},
 184             {0, 0x0000000, 0x0000000, 0x000000},
 185             {0, 0x0000000, 0x0000000, 0x000000},
 186             {1, 0x0bf0000, 0x0bf2000, 0x17e000}}},
 187         {{{1, 0x0c00000, 0x0c04000, 0x1d4000}}},        /* 12: I2Q */
 188         {{{1, 0x0d00000, 0x0d04000, 0x1a4000}}},        /* 13: TMR */
 189         {{{1, 0x0e00000, 0x0e04000, 0x1a0000}}},        /* 14: ROMUSB */
 190         {{{1, 0x0f00000, 0x0f01000, 0x164000}}},        /* 15: PEG4 */
 191         {{{0, 0x1000000, 0x1004000, 0x1a8000}}},        /* 16: XDMA */
 192         {{{1, 0x1100000, 0x1101000, 0x160000}}},        /* 17: PEG0 */
 193         {{{1, 0x1200000, 0x1201000, 0x161000}}},        /* 18: PEG1 */
 194         {{{1, 0x1300000, 0x1301000, 0x162000}}},        /* 19: PEG2 */
 195         {{{1, 0x1400000, 0x1401000, 0x163000}}},        /* 20: PEG3 */
 196         {{{1, 0x1500000, 0x1501000, 0x165000}}},        /* 21: P2ND */
 197         {{{1, 0x1600000, 0x1601000, 0x166000}}},        /* 22: P2NI */
 198         {{{0, 0,         0,      0}}},                  /* 23: */
 199         {{{0, 0,         0,      0}}},                  /* 24: */
 200         {{{0, 0,         0,      0}}},                  /* 25: */
 201         {{{0, 0,         0,      0}}},                  /* 26: */
 202         {{{0, 0,         0,      0}}},                  /* 27: */
 203         {{{0, 0,         0,      0}}},                  /* 28: */
 204         {{{1, 0x1d00000, 0x1d10000, 0x190000}}},        /* 29: MS */
 205         {{{1, 0x1e00000, 0x1e01000, 0x16a000}}},        /* 30: P2NR2 */
 206         {{{1, 0x1f00000, 0x1f10000, 0x150000}}},        /* 31: EPG */
 207         {{{0}}},                                        /* 32: PCI */
 208         {{{1, 0x2100000, 0x2102000, 0x120000},          /* 33: PCIE */
 209             {1, 0x2110000, 0x2120000, 0x130000},
 210             {1, 0x2120000, 0x2122000, 0x124000},
 211             {1, 0x2130000, 0x2132000, 0x126000},
 212             {1, 0x2140000, 0x2142000, 0x128000},
 213             {1, 0x2150000, 0x2152000, 0x12a000},
 214             {1, 0x2160000, 0x2170000, 0x110000},
 215             {1, 0x2170000, 0x2172000, 0x12e000},
 216             {0, 0x0000000, 0x0000000, 0x000000},
 217             {0, 0x0000000, 0x0000000, 0x000000},
 218             {0, 0x0000000, 0x0000000, 0x000000},
 219             {0, 0x0000000, 0x0000000, 0x000000},
 220             {0, 0x0000000, 0x0000000, 0x000000},
 221             {0, 0x0000000, 0x0000000, 0x000000},
 222             {0, 0x0000000, 0x0000000, 0x000000},
 223             {0, 0x0000000, 0x0000000, 0x000000}}},
 224         {{{1, 0x2200000, 0x2204000, 0x1b0000}}},        /* 34: CAM */
 225         {{{0}}},                                        /* 35: */
 226         {{{0}}},                                        /* 36: */
 227         {{{0}}},                                        /* 37: */
 228         {{{0}}},                                        /* 38: */
 229         {{{0}}},                                        /* 39: */
 230         {{{1, 0x2800000, 0x2804000, 0x1a4000}}},        /* 40: TMR */
 231         {{{1, 0x2900000, 0x2901000, 0x16b000}}},        /* 41: P2NR3 */
 232         {{{1, 0x2a00000, 0x2a00400, 0x1ac400}}},        /* 42: RPMX1 */
 233         {{{1, 0x2b00000, 0x2b00400, 0x1ac800}}},        /* 43: RPMX2 */
 234         {{{1, 0x2c00000, 0x2c00400, 0x1acc00}}},        /* 44: RPMX3 */
 235         {{{1, 0x2d00000, 0x2d00400, 0x1ad000}}},        /* 45: RPMX4 */
 236         {{{1, 0x2e00000, 0x2e00400, 0x1ad400}}},        /* 46: RPMX5 */
 237         {{{1, 0x2f00000, 0x2f00400, 0x1ad800}}},        /* 47: RPMX6 */
 238         {{{1, 0x3000000, 0x3000400, 0x1adc00}}},        /* 48: RPMX7 */
 239         {{{0, 0x3100000, 0x3104000, 0x1a8000}}},        /* 49: XDMA */
 240         {{{1, 0x3200000, 0x3204000, 0x1d4000}}},        /* 50: I2Q */
 241         {{{1, 0x3300000, 0x3304000, 0x1a0000}}},        /* 51: ROMUSB */
 242         {{{0}}},                                        /* 52: */
 243         {{{1, 0x3500000, 0x3500400, 0x1ac000}}},        /* 53: RPMX0 */
 244         {{{1, 0x3600000, 0x3600400, 0x1ae000}}},        /* 54: RPMX8 */
 245         {{{1, 0x3700000, 0x3700400, 0x1ae400}}},        /* 55: RPMX9 */
 246         {{{1, 0x3800000, 0x3804000, 0x1d0000}}},        /* 56: OCM0 */
 247         {{{1, 0x3900000, 0x3904000, 0x1b4000}}},        /* 57: CRYPTO */
 248         {{{1, 0x3a00000, 0x3a04000, 0x1d8000}}},        /* 58: SMB */
 249         {{{0}}},                                        /* 59: I2C0 */
 250         {{{0}}},                                        /* 60: I2C1 */
 251         {{{1, 0x3d00000, 0x3d04000, 0x1dc000}}},        /* 61: LPC */
 252         {{{1, 0x3e00000, 0x3e01000, 0x167000}}},        /* 62: P2NC */
 253         {{{1, 0x3f00000, 0x3f01000, 0x168000}}}         /* 63: P2NR0 */
 254 };
 255 
 256 /*
 257  * top 12 bits of crb internal address (hub, agent)
 258  */
 259 static uint32_t crb_hub_agt[64] = {
 260         0,
 261         UNM_HW_CRB_HUB_AGT_ADR_PS,
 262         UNM_HW_CRB_HUB_AGT_ADR_MN,
 263         UNM_HW_CRB_HUB_AGT_ADR_MS,
 264         0,
 265         UNM_HW_CRB_HUB_AGT_ADR_SRE,
 266         UNM_HW_CRB_HUB_AGT_ADR_NIU,
 267         UNM_HW_CRB_HUB_AGT_ADR_QMN,
 268         UNM_HW_CRB_HUB_AGT_ADR_SQN0,
 269         UNM_HW_CRB_HUB_AGT_ADR_SQN1,
 270         UNM_HW_CRB_HUB_AGT_ADR_SQN2,
 271         UNM_HW_CRB_HUB_AGT_ADR_SQN3,
 272         UNM_HW_CRB_HUB_AGT_ADR_I2Q,
 273         UNM_HW_CRB_HUB_AGT_ADR_TIMR,
 274         UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
 275         UNM_HW_CRB_HUB_AGT_ADR_PGN4,
 276         UNM_HW_CRB_HUB_AGT_ADR_XDMA,
 277         UNM_HW_CRB_HUB_AGT_ADR_PGN0,
 278         UNM_HW_CRB_HUB_AGT_ADR_PGN1,
 279         UNM_HW_CRB_HUB_AGT_ADR_PGN2,
 280         UNM_HW_CRB_HUB_AGT_ADR_PGN3,
 281         UNM_HW_CRB_HUB_AGT_ADR_PGND,
 282         UNM_HW_CRB_HUB_AGT_ADR_PGNI,
 283         UNM_HW_CRB_HUB_AGT_ADR_PGS0,
 284         UNM_HW_CRB_HUB_AGT_ADR_PGS1,
 285         UNM_HW_CRB_HUB_AGT_ADR_PGS2,
 286         UNM_HW_CRB_HUB_AGT_ADR_PGS3,
 287         0,
 288         UNM_HW_CRB_HUB_AGT_ADR_PGSI,
 289         UNM_HW_CRB_HUB_AGT_ADR_SN,
 290         0,
 291         UNM_HW_CRB_HUB_AGT_ADR_EG,
 292         0,
 293         UNM_HW_CRB_HUB_AGT_ADR_PS,
 294         UNM_HW_CRB_HUB_AGT_ADR_CAM,
 295         0,
 296         0,
 297         0,
 298         0,
 299         0,
 300         UNM_HW_CRB_HUB_AGT_ADR_TIMR,
 301         0,
 302         UNM_HW_CRB_HUB_AGT_ADR_RPMX1,
 303         UNM_HW_CRB_HUB_AGT_ADR_RPMX2,
 304         UNM_HW_CRB_HUB_AGT_ADR_RPMX3,
 305         UNM_HW_CRB_HUB_AGT_ADR_RPMX4,
 306         UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
 307         UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
 308         UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
 309         UNM_HW_CRB_HUB_AGT_ADR_XDMA,
 310         UNM_HW_CRB_HUB_AGT_ADR_I2Q,
 311         UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
 312         0,
 313         UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
 314         UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
 315         UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
 316         UNM_HW_CRB_HUB_AGT_ADR_OCM0,
 317         0,
 318         UNM_HW_CRB_HUB_AGT_ADR_SMB,
 319         UNM_HW_CRB_HUB_AGT_ADR_I2C0,
 320         UNM_HW_CRB_HUB_AGT_ADR_I2C1,
 321         0,
 322         UNM_HW_CRB_HUB_AGT_ADR_PGNC,
 323         0,
 324 };
 325 
 326 static void *
 327 ql_8021_pci_base_offsetfset(ql_adapter_state_t *ha, uint64_t off)
 328 {
 329         if ((off < ha->first_page_group_end) &&
 330             (off >= ha->first_page_group_start)) {
 331                 return ((void *)(ha->nx_pcibase + off));
 332         }
 333 
 334         return (NULL);
 335 }
 336 
 337 /* ARGSUSED */
 338 static void
 339 ql_crb_addr_transform_setup(ql_adapter_state_t *ha)
 340 {
 341         crb_addr_transform(XDMA);
 342         crb_addr_transform(TIMR);
 343         crb_addr_transform(SRE);
 344         crb_addr_transform(SQN3);
 345         crb_addr_transform(SQN2);
 346         crb_addr_transform(SQN1);
 347         crb_addr_transform(SQN0);
 348         crb_addr_transform(SQS3);
 349         crb_addr_transform(SQS2);
 350         crb_addr_transform(SQS1);
 351         crb_addr_transform(SQS0);
 352         crb_addr_transform(RPMX7);
 353         crb_addr_transform(RPMX6);
 354         crb_addr_transform(RPMX5);
 355         crb_addr_transform(RPMX4);
 356         crb_addr_transform(RPMX3);
 357         crb_addr_transform(RPMX2);
 358         crb_addr_transform(RPMX1);
 359         crb_addr_transform(RPMX0);
 360         crb_addr_transform(ROMUSB);
 361         crb_addr_transform(SN);
 362         crb_addr_transform(QMN);
 363         crb_addr_transform(QMS);
 364         crb_addr_transform(PGNI);
 365         crb_addr_transform(PGND);
 366         crb_addr_transform(PGN3);
 367         crb_addr_transform(PGN2);
 368         crb_addr_transform(PGN1);
 369         crb_addr_transform(PGN0);
 370         crb_addr_transform(PGSI);
 371         crb_addr_transform(PGSD);
 372         crb_addr_transform(PGS3);
 373         crb_addr_transform(PGS2);
 374         crb_addr_transform(PGS1);
 375         crb_addr_transform(PGS0);
 376         crb_addr_transform(PS);
 377         crb_addr_transform(PH);
 378         crb_addr_transform(NIU);
 379         crb_addr_transform(I2Q);
 380         crb_addr_transform(EG);
 381         crb_addr_transform(MN);
 382         crb_addr_transform(MS);
 383         crb_addr_transform(CAS2);
 384         crb_addr_transform(CAS1);
 385         crb_addr_transform(CAS0);
 386         crb_addr_transform(CAM);
 387         crb_addr_transform(C2C1);
 388         crb_addr_transform(C2C0);
 389         crb_addr_transform(SMB);
 390         crb_addr_transform(OCM0);
 391         /*
 392          * Used only in P3 just define it for P2 also.
 393          */
 394         crb_addr_transform(I2C0);
 395 
 396         crb_table_initialized = 1;
 397 }
 398 
 399 /*
 400  * In: 'off' is offset from CRB space in 128M pci map
 401  * Out: 'off' is 2M pci map addr
 402  * side effect: lock crb window
 403  */
 404 static void
 405 ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *ha, uint64_t *off)
 406 {
 407         uint32_t        win_read;
 408 
 409         ha->crb_win = (uint32_t)CRB_HI(*off);
 410         WRT_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase, ha->crb_win);
 411 
 412         /*
 413          * Read back value to make sure write has gone through before trying
 414          * to use it.
 415          */
 416         win_read = RD_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase);
 417         if (win_read != ha->crb_win) {
 418                 EL(ha, "Written crbwin (0x%x) != Read crbwin (0x%x), "
 419                     "off=0x%llx\n", ha->crb_win, win_read, *off);
 420         }
 421         *off = (*off & MASK(16)) + CRB_INDIRECT_2M + (uintptr_t)ha->nx_pcibase;
 422 }
 423 
 424 static void
 425 ql_8021_wr_32(ql_adapter_state_t *ha, uint64_t off, uint32_t data)
 426 {
 427         int     rv;
 428 
 429         rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
 430         if (rv == -1) {
 431                 cmn_err(CE_PANIC, "ql_8021_wr_32, ql_8021_pci_get_crb_addr_"
 432                     "2M=-1\n");
 433         }
 434         if (rv == 1) {
 435                 (void) ql_8021_crb_win_lock(ha);
 436                 ql_8021_pci_set_crbwindow_2M(ha, &off);
 437         }
 438 
 439         WRT_REG_DWORD(ha, (uintptr_t)off, data);
 440 
 441         if (rv == 1) {
 442                 ql_8021_crb_win_unlock(ha);
 443         }
 444 }
 445 
 446 static void
 447 ql_8021_rd_32(ql_adapter_state_t *ha, uint64_t off, uint32_t *data)
 448 {
 449         int             rv;
 450         uint32_t        n;
 451 
 452         rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
 453         if (rv == -1) {
 454                 cmn_err(CE_PANIC, "ql_8021_rd_32, ql_8021_pci_get_crb_addr_"
 455                     "2M=-1\n");
 456         }
 457 
 458         if (rv == 1) {
 459                 (void) ql_8021_crb_win_lock(ha);
 460                 ql_8021_pci_set_crbwindow_2M(ha, &off);
 461         }
 462         n = RD_REG_DWORD(ha, (uintptr_t)off);
 463 
 464         if (data != NULL) {
 465                 *data = n;
 466         }
 467 
 468         if (rv == 1) {
 469                 ql_8021_crb_win_unlock(ha);
 470         }
 471 }
 472 
 473 static int
 474 ql_8021_crb_win_lock(ql_adapter_state_t *ha)
 475 {
 476         uint32_t        done = 0, timeout = 0;
 477 
 478         while (!done) {
 479                 /* acquire semaphore3 from PCI HW block */
 480                 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_LOCK), &done);
 481                 if (done == 1) {
 482                         break;
 483                 }
 484                 if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
 485                         EL(ha, "timeout\n");
 486                         return (-1);
 487                 }
 488                 timeout++;
 489 
 490                 /* Yield CPU */
 491                 delay(1);
 492         }
 493         ql_8021_wr_32(ha, UNM_CRB_WIN_LOCK_ID, ha->function_number);
 494 
 495         return (0);
 496 }
 497 
 498 static void
 499 ql_8021_crb_win_unlock(ql_adapter_state_t *ha)
 500 {
 501         ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_UNLOCK), NULL);
 502 }
 503 
 504 static int
 505 ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *ha, uint64_t *off)
 506 {
 507         crb_128M_2M_sub_block_map_t     *m;
 508 
 509         if (*off >= UNM_CRB_MAX) {
 510                 EL(ha, "%llx >= %llx\n", *off, UNM_CRB_MAX);
 511                 return (-1);
 512         }
 513 
 514         if (*off >= UNM_PCI_CAMQM && (*off < UNM_PCI_CAMQM_2M_END)) {
 515                 *off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
 516                     (uintptr_t)ha->nx_pcibase;
 517                 return (0);
 518         }
 519 
 520         if (*off < UNM_PCI_CRBSPACE) {
 521                 EL(ha, "%llx < %llx\n", *off, UNM_PCI_CRBSPACE);
 522                 return (-1);
 523         }
 524 
 525         *off -= UNM_PCI_CRBSPACE;
 526         /*
 527          * Try direct map
 528          */
 529 
 530         m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
 531 
 532         if (m->valid && ((uint64_t)m->start_128M <= *off) &&
 533             ((uint64_t)m->end_128M > *off)) {
 534                 *off = (uint64_t)(*off + m->start_2M - m->start_128M +
 535                     (uintptr_t)ha->nx_pcibase);
 536                 return (0);
 537         }
 538 
 539         /*
 540          * Not in direct map, use crb window
 541          */
 542         return (1);
 543 }
 544 
 545 /*
 546  * check memory access boundary.
 547  * used by test agent. support ddr access only for now
 548  */
 549 /* ARGSUSED */
 550 static uint32_t
 551 ql_8021_pci_mem_bound_check(ql_adapter_state_t *ha, uint64_t addr,
 552     uint32_t size)
 553 {
 554         /*LINTED suspicious 0 comparison*/
 555         if (!QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
 556             UNM_ADDR_DDR_NET_MAX) ||
 557             /*LINTED suspicious 0 comparison*/
 558             !QL_8021_ADDR_IN_RANGE(addr + size - 1, UNM_ADDR_DDR_NET,
 559             UNM_ADDR_DDR_NET_MAX) ||
 560             ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
 561                 return (0);
 562         }
 563 
 564         return (1);
 565 }
 566 
 567 static uint64_t
 568 ql_8021_pci_set_window(ql_adapter_state_t *ha, uint64_t addr)
 569 {
 570         uint32_t        window, win_read;
 571 
 572         /*LINTED suspicious 0 comparison*/
 573         if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
 574             UNM_ADDR_DDR_NET_MAX)) {
 575                 /* DDR network side */
 576                 window = (uint32_t)MN_WIN(addr);
 577                 ha->ddr_mn_window = window;
 578                 ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
 579                 ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
 580                     &win_read);
 581                 if ((win_read << 17) != window) {
 582                         EL(ha, "Warning, Written MNwin (0x%x) != Read MNwin "
 583                             "(0x%x)\n", window, win_read);
 584                 }
 585                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
 586         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
 587             UNM_ADDR_OCM0_MAX)) {
 588                 uint32_t        temp1;
 589 
 590                 if ((addr & 0x00ff800) == 0xff800) {
 591                         /* if bits 19:18&17:11 are on */
 592                         EL(ha, "QM access not handled\n");
 593                         addr = -1UL;
 594                 }
 595 
 596                 window = (uint32_t)OCM_WIN(addr);
 597                 ha->ddr_mn_window = window;
 598                 ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
 599                 ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
 600                     &win_read);
 601                 temp1 = ((window & 0x1FF) << 7) |
 602                     ((window & 0x0FFFE0000) >> 17);
 603                 if (win_read != temp1) {
 604                         EL(ha, "Written OCMwin (0x%x) != Read OCMwin (0x%x)\n",
 605                             temp1, win_read);
 606                 }
 607                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
 608         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
 609             NX_P3_ADDR_QDR_NET_MAX)) {
 610                 /* QDR network side */
 611                 window = (uint32_t)MS_WIN(addr);
 612                 ha->qdr_sn_window = window;
 613                 ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
 614                 ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
 615                     &win_read);
 616                 if (win_read != window) {
 617                         EL(ha, "Written MSwin (0x%x) != Read MSwin (0x%x)\n",
 618                             window, win_read);
 619                 }
 620                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
 621         } else {
 622                 /*
 623                  * peg gdb frequently accesses memory that doesn't exist,
 624                  * this limits the chit chat so debugging isn't slowed down.
 625                  */
 626                 if ((pci_set_window_warning_count++ < 8) ||
 627                     (pci_set_window_warning_count % 64 == 0)) {
 628                         EL(ha, "Unknown address range\n");
 629                 }
 630                 addr = -1UL;
 631         }
 632 
 633         return (addr);
 634 }
 635 
 636 /* check if address is in the same windows as the previous access */
 637 static int
 638 ql_8021_pci_is_same_window(ql_adapter_state_t *ha, uint64_t addr)
 639 {
 640         uint32_t        window;
 641         uint64_t        qdr_max;
 642 
 643         qdr_max = NX_P3_ADDR_QDR_NET_MAX;
 644 
 645         /*LINTED suspicious 0 comparison*/
 646         if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
 647             UNM_ADDR_DDR_NET_MAX)) {
 648                 /* DDR network side */
 649                 EL(ha, "DDR network side\n");
 650                 return (0);     /* MN access can not come here */
 651         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
 652             UNM_ADDR_OCM0_MAX)) {
 653                 return (1);
 654         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM1,
 655             UNM_ADDR_OCM1_MAX)) {
 656                 return (1);
 657         } else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
 658                 /* QDR network side */
 659                 window = (uint32_t)(((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f);
 660                 if (ha->qdr_sn_window == window) {
 661                         return (1);
 662                 }
 663         }
 664 
 665         return (0);
 666 }
 667 
 668 static int
 669 ql_8021_pci_mem_read_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
 670     uint32_t size)
 671 {
 672         void            *addr;
 673         int             ret = 0;
 674         uint64_t        start;
 675 
 676         /*
 677          * If attempting to access unknown address or straddle hw windows,
 678          * do not access.
 679          */
 680         if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
 681             (ql_8021_pci_is_same_window(ha, off + size - 1) == 0)) {
 682                 EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
 683                     off);
 684                 return (-1);
 685         }
 686 
 687         addr = ql_8021_pci_base_offsetfset(ha, start);
 688         if (!addr) {
 689                 addr = (void *)((uint8_t *)ha->nx_pcibase + start);
 690         }
 691 
 692         switch (size) {
 693         case 1:
 694                 *(uint8_t  *)data = RD_REG_BYTE(ha, addr);
 695                 break;
 696         case 2:
 697                 *(uint16_t  *)data = RD_REG_WORD(ha, addr);
 698                 break;
 699         case 4:
 700                 *(uint32_t  *)data = RD_REG_DWORD(ha, addr);
 701                 break;
 702         case 8:
 703                 *(uint64_t  *)data = RD_REG_DDWORD(ha, addr);
 704                 break;
 705         default:
 706                 EL(ha, "invalid size=%x\n", size);
 707                 ret = -1;
 708                 break;
 709         }
 710 
 711         return (ret);
 712 }
 713 
 714 static int
 715 ql_8021_pci_mem_write_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
 716     uint32_t size)
 717 {
 718         void            *addr;
 719         int             ret = 0;
 720         uint64_t        start;
 721 
 722         /*
 723          * If attempting to access unknown address or straddle hw windows,
 724          * do not access.
 725          */
 726         if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
 727             (ql_8021_pci_is_same_window(ha, off + size -1) == 0)) {
 728                 EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
 729                     off);
 730                 return (-1);
 731         }
 732 
 733         addr = ql_8021_pci_base_offsetfset(ha, start);
 734         if (!addr) {
 735                 addr = (void *)((uint8_t *)ha->nx_pcibase + start);
 736         }
 737 
 738         switch (size) {
 739         case 1:
 740                 WRT_REG_BYTE(ha, addr, *(uint8_t *)data);
 741                 break;
 742         case 2:
 743                 WRT_REG_WORD(ha, addr, *(uint16_t *)data);
 744                 break;
 745         case 4:
 746                 WRT_REG_DWORD(ha, addr, *(uint32_t *)data);
 747                 break;
 748         case 8:
 749                 WRT_REG_DDWORD(ha, addr, *(uint64_t *)data);
 750                 break;
 751         default:
 752                 EL(ha, "invalid size=%x\n", size);
 753                 ret = -1;
 754                 break;
 755         }
 756 
 757         return (ret);
 758 }
 759 
 760 static int
 761 ql_8021_pci_mem_read_2M(ql_adapter_state_t *ha, uint64_t off, void *data,
 762     uint32_t size)
 763 {
 764         int             j = 0;
 765         uint32_t        i, temp, sz[2], loop, shift_amount;
 766         uint64_t        start, end, k;
 767         uint64_t        off8, off0[2], val, mem_crb, word[2] = {0, 0};
 768 
 769         /*
 770          * If not MN, go check for MS or invalid.
 771          */
 772 
 773         if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
 774                 mem_crb = UNM_CRB_QDR_NET;
 775         } else {
 776                 mem_crb = UNM_CRB_DDR_NET;
 777                 if (ql_8021_pci_mem_bound_check(ha, off, size) == 0) {
 778                         return (ql_8021_pci_mem_read_direct(ha, off, data,
 779                             size));
 780                 }
 781         }
 782 
 783         if (NX_IS_REVISION_P3PLUS(ha->rev_id)) {
 784                 off8 = off & 0xfffffff0;
 785                 off0[0] = off & 0xf;
 786                 sz[0] = (uint32_t)(((uint64_t)size < (16 - off0[0])) ? size :
 787                     (16 - off0[0]));
 788                 shift_amount = 4;
 789         } else {
 790                 off8 = off & 0xfffffff8;
 791                 off0[0] = off & 0x7;
 792                 sz[0] = (uint32_t)(((uint64_t)size < (8 - off0[0])) ? size :
 793                     (8 - off0[0]));
 794                 shift_amount = 3;
 795         }
 796         loop = (uint32_t)(((off0[0] + size - 1) >> shift_amount) + 1);
 797         off0[1] = 0;
 798         sz[1] = size - sz[0];
 799 
 800         /*
 801          * don't lock here - write_wx gets the lock if each time
 802          * write_lock_irqsave(&adapter->adapter_lock, flags);
 803          * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
 804          */
 805 
 806         for (i = 0; i < loop; i++) {
 807                 temp = (uint32_t)(off8 + (i << shift_amount));
 808                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
 809                 temp = 0;
 810                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
 811                 temp = MIU_TA_CTL_ENABLE;
 812                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
 813                 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
 814                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
 815 
 816                 for (j = 0; j < MAX_CTL_CHECK; j++) {
 817                         ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL, &temp);
 818                         if ((temp & MIU_TA_CTL_BUSY) == 0) {
 819                                 break;
 820                         }
 821                 }
 822 
 823                 if (j >= MAX_CTL_CHECK) {
 824                         EL(ha, "failed to read through agent\n");
 825                         break;
 826                 }
 827 
 828                 start = off0[i] >> 2;
 829                 end = (off0[i] + sz[i] - 1) >> 2;
 830                 for (k = start; k <= end; k++) {
 831                         ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_RDDATA(k),
 832                             &temp);
 833                         word[i] |= ((uint64_t)temp << (32 * (k & 1)));
 834                 }
 835         }
 836 
 837         /*
 838          * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
 839          * write_unlock_irqrestore(&adapter->adapter_lock, flags);
 840          */
 841 
 842         if (j >= MAX_CTL_CHECK) {
 843                 return (-1);
 844         }
 845 
 846         if ((off0[0] & 7) == 0) {
 847                 val = word[0];
 848         } else {
 849                 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
 850                     ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
 851         }
 852 
 853         switch (size) {
 854         case 1:
 855                 *(uint8_t *)data = (uint8_t)val;
 856                 break;
 857         case 2:
 858                 *(uint16_t *)data = (uint16_t)val;
 859                 break;
 860         case 4:
 861                 *(uint32_t *)data = (uint32_t)val;
 862                 break;
 863         case 8:
 864                 *(uint64_t *)data = val;
 865                 break;
 866         }
 867 
 868         return (0);
 869 }
 870 
 871 static int
 872 ql_8021_pci_mem_write_2M(ql_adapter_state_t *ha, uint64_t off, void *data,
 873     uint32_t size)
 874 {
 875         int             j, ret = 0;
 876         uint32_t        i, temp, loop, sz[2];
 877         uint32_t        scale, shift_amount, p3p, startword;
 878         uint64_t        off8, off0, mem_crb, tmpw, word[2] = {0, 0};
 879 
 880         /*
 881          * If not MN, go check for MS or invalid.
 882          */
 883         if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
 884                 mem_crb = UNM_CRB_QDR_NET;
 885         } else {
 886                 mem_crb = UNM_CRB_DDR_NET;
 887                 if (ql_8021_pci_mem_bound_check(ha, off, size) == 0) {
 888                         return (ql_8021_pci_mem_write_direct(ha, off, data,
 889                             size));
 890                 }
 891         }
 892 
 893         off0 = off & 0x7;
 894         sz[0] = (uint32_t)(((uint64_t)size < (8 - off0)) ? size : (8 - off0));
 895         sz[1] = size - sz[0];
 896 
 897         if (NX_IS_REVISION_P3PLUS(ha->rev_id)) {
 898                 off8 = off & 0xfffffff0;
 899                 loop = (uint32_t)((((off & 0xf) + size - 1) >> 4) + 1);
 900                 shift_amount = 4;
 901                 scale = 2;
 902                 p3p = 1;
 903                 startword = (uint32_t)((off & 0xf) / 8);
 904         } else {
 905                 off8 = off & 0xfffffff8;
 906                 loop = (uint32_t)(((off0 + size - 1) >> 3) + 1);
 907                 shift_amount = 3;
 908                 scale = 1;
 909                 p3p = 0;
 910                 startword = 0;
 911         }
 912 
 913         if (p3p || (size != 8) || (off0 != 0)) {
 914                 for (i = 0; i < loop; i++) {
 915                         if (ql_8021_pci_mem_read_2M(ha, off8 +
 916                             (i << shift_amount), &word[i * scale], 8)) {
 917                                 EL(ha, "8021_pci_mem_read_2M != 0\n");
 918                                 return (-1);
 919                         }
 920                 }
 921         }
 922 
 923         switch (size) {
 924         case 1:
 925                 tmpw = (uint64_t)(*((uint8_t *)data));
 926                 break;
 927         case 2:
 928                 tmpw = (uint64_t)(*((uint16_t *)data));
 929                 break;
 930         case 4:
 931                 tmpw = (uint64_t)(*((uint32_t *)data));
 932                 break;
 933         case 8:
 934         default:
 935                 tmpw = *((uint64_t *)data);
 936                 break;
 937         }
 938 
 939         if (p3p) {
 940                 if (sz[0] == 8) {
 941                         word[startword] = tmpw;
 942                 } else {
 943                         word[startword] &= ~((~(~0ULL << (sz[0] * 8))) <<
 944                             (off0 * 8));
 945                         word[startword] |= tmpw << (off0 * 8);
 946                 }
 947                 if (sz[1] != 0) {
 948                         word[startword+1] &= ~(~0ULL << (sz[1] * 8));
 949                         word[startword+1] |= tmpw >> (sz[0] * 8);
 950                 }
 951         } else {
 952                 word[startword] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
 953                 word[startword] |= tmpw << (off0 * 8);
 954 
 955                 if (loop == 2) {
 956                         word[1] &= ~(~0ULL << (sz[1] * 8));
 957                         word[1] |= tmpw >> (sz[0] * 8);
 958                 }
 959         }
 960 
 961         /*
 962          * don't lock here - write_wx gets the lock if each time
 963          * write_lock_irqsave(&adapter->adapter_lock, flags);
 964          * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
 965          */
 966 
 967         for (i = 0; i < loop; i++) {
 968                 temp = (uint32_t)(off8 + (i << shift_amount));
 969                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
 970                 temp = 0;
 971                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
 972                 temp = (uint32_t)(word[i * scale] & 0xffffffff);
 973                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_LO, temp);
 974                 temp = (uint32_t)((word[i * scale] >> 32) & 0xffffffff);
 975                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_HI, temp);
 976                 if (p3p) {
 977                         temp = (uint32_t)(word[i * scale + 1] & 0xffffffff);
 978                         ql_8021_wr_32(ha,
 979                             mem_crb + MIU_TEST_AGT_WRDATA_UPPER_LO, temp);
 980                         temp = (uint32_t)((word[i * scale + 1] >> 32) &
 981                             0xffffffff);
 982                         ql_8021_wr_32(ha,
 983                             mem_crb + MIU_TEST_AGT_WRDATA_UPPER_HI, temp);
 984                 }
 985                 temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
 986                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
 987                 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
 988                 ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
 989 
 990                 for (j = 0; j < MAX_CTL_CHECK; j++) {
 991                         ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL, &temp);
 992                         if ((temp & MIU_TA_CTL_BUSY) == 0)
 993                                 break;
 994                 }
 995 
 996                 if (j >= MAX_CTL_CHECK) {
 997                         EL(ha, "failed to write through agent\n");
 998                         ret = -1;
 999                         break;
1000                 }
1001         }
1002 
1003         return (ret);
1004 }
1005 
1006 static uint32_t
1007 ql_8021_decode_crb_addr(ql_adapter_state_t *ha, uint32_t addr)
1008 {
1009         int             i;
1010         uint32_t        base_addr, offset, pci_base;
1011 
1012         if (!crb_table_initialized) {
1013                 ql_crb_addr_transform_setup(ha);
1014         }
1015 
1016         pci_base = ADDR_ERROR;
1017         base_addr = addr & 0xfff00000;
1018         offset = addr & 0x000fffff;
1019 
1020         for (i = 0; i < MAX_CRB_XFORM; i++) {
1021                 if (crb_addr_xform[i] == base_addr) {
1022                         pci_base = i << 20;
1023                         break;
1024                 }
1025         }
1026         if (pci_base == ADDR_ERROR) {
1027                 return (pci_base);
1028         } else {
1029                 return (pci_base + offset);
1030         }
1031 }
1032 
1033 static int
1034 ql_8021_hw_lock(ql_adapter_state_t *ha, uint32_t timer)
1035 {
1036         uint32_t        done = 0, timeout = 0;
1037 
1038         while (!done) {
1039                 /* acquire semaphore5 from PCI HW block */
1040                 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM5_LOCK), &done);
1041                 if (done == 1) {
1042                         break;
1043                 }
1044                 if (timeout >= timer) {
1045                         EL(ha, "timeout\n");
1046                         return (-1);
1047                 }
1048                 timeout++;
1049 
1050                 /*
1051                  * Yield CPU
1052                  */
1053                 delay(1);
1054         }
1055 
1056         return (0);
1057 }
1058 
1059 static void
1060 ql_8021_hw_unlock(ql_adapter_state_t *ha)
1061 {
1062         ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM5_UNLOCK), NULL);
1063 }
1064 
1065 static int
1066 ql_8021_rom_lock(ql_adapter_state_t *ha)
1067 {
1068         uint32_t        done = 0, timeout = 0;
1069 
1070         while (!done) {
1071                 /* acquire semaphore2 from PCI HW block */
1072                 ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM2_LOCK), &done);
1073                 if (done == 1) {
1074                         break;
1075                 }
1076                 if (timeout >= ROM_LOCK_TIMEOUT) {
1077                         EL(ha, "timeout\n");
1078                         return (-1);
1079                 }
1080                 timeout++;
1081 
1082                 /*
1083                  * Yield CPU
1084                  */
1085                 delay(1);
1086         }
1087         ql_8021_wr_32(ha, UNM_ROM_LOCK_ID, ROM_LOCK_DRIVER);
1088 
1089         return (0);
1090 }
1091 
1092 static void
1093 ql_8021_rom_unlock(ql_adapter_state_t *ha)
1094 {
1095         ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM2_UNLOCK), NULL);
1096 }
1097 
1098 static int
1099 ql_8021_wait_rom_done(ql_adapter_state_t *ha)
1100 {
1101         uint32_t        timeout = 0, done = 0;
1102 
1103         while (done == 0) {
1104                 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_STATUS, &done);
1105                 done &= 2;
1106                 timeout++;
1107                 if (timeout >= ROM_MAX_TIMEOUT) {
1108                         EL(ha, "Timeout reached waiting for rom done\n");
1109                         return (-1);
1110                 }
1111         }
1112 
1113         return (0);
1114 }
1115 
1116 static int
1117 ql_8021_wait_flash_done(ql_adapter_state_t *ha)
1118 {
1119         clock_t         timer;
1120         uint32_t        status;
1121 
1122         for (timer = 30 * drv_usectohz(1000000); timer; timer--) {
1123                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1124                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1125                     UNM_ROMUSB_ROM_RDSR_INSTR);
1126                 if (ql_8021_wait_rom_done(ha)) {
1127                         EL(ha, "Error waiting for rom done2\n");
1128                         return (-1);
1129                 }
1130 
1131                 /* Get status. */
1132                 ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, &status);
1133                 if (!(status & BIT_0)) {
1134                         return (0);
1135                 }
1136                 delay(1);
1137         }
1138 
1139         EL(ha, "timeout status=%x\n", status);
1140         return (-1);
1141 }
1142 
1143 static int
1144 ql_8021_do_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
1145 {
1146         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1147         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
1148         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1149         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1150             UNM_ROMUSB_ROM_FAST_RD_INSTR);
1151         if (ql_8021_wait_rom_done(ha)) {
1152                 EL(ha, "Error waiting for rom done\n");
1153                 return (-1);
1154         }
1155         /* reset abyte_cnt and dummy_byte_cnt */
1156         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
1157         drv_usecwait(10);
1158         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1159 
1160         ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, valp);
1161 
1162         return (0);
1163 }
1164 
1165 int
1166 ql_8021_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
1167 {
1168         int     ret, loops = 0;
1169 
1170         while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1171                 drv_usecwait(100);
1172                 loops++;
1173         }
1174         if (loops >= 50000) {
1175                 EL(ha, "rom_lock failed\n");
1176                 return (-1);
1177         }
1178         ret = ql_8021_do_rom_fast_read(ha, addr, valp);
1179         ql_8021_rom_unlock(ha);
1180 
1181         return (ret);
1182 }
1183 
1184 static int
1185 ql_8021_do_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
1186 {
1187         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1188         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1189             UNM_ROMUSB_ROM_WREN_INSTR);
1190         if (ql_8021_wait_rom_done(ha)) {
1191                 EL(ha, "Error waiting for rom done\n");
1192                 return (-1);
1193         }
1194 
1195         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
1196         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1197         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1198         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1199             UNM_ROMUSB_ROM_PP_INSTR);
1200         if (ql_8021_wait_rom_done(ha)) {
1201                 EL(ha, "Error waiting for rom done1\n");
1202                 return (-1);
1203         }
1204 
1205         if (ql_8021_wait_flash_done(ha)) {
1206                 EL(ha, "Error waiting for flash done\n");
1207                 return (-1);
1208         }
1209 
1210         return (0);
1211 }
1212 
1213 static int
1214 ql_8021_do_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
1215 {
1216         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1217         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1218             UNM_ROMUSB_ROM_WREN_INSTR);
1219         if (ql_8021_wait_rom_done(ha)) {
1220                 EL(ha, "Error waiting for rom done\n");
1221                 return (-1);
1222         }
1223 
1224         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1225         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1226         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1227             UNM_ROMUSB_ROM_SE_INSTR);
1228         if (ql_8021_wait_rom_done(ha)) {
1229                 EL(ha, "Error waiting for rom done1\n");
1230                 return (-1);
1231         }
1232 
1233         if (ql_8021_wait_flash_done(ha)) {
1234                 EL(ha, "Error waiting for flash done\n");
1235                 return (-1);
1236         }
1237 
1238         return (0);
1239 }
1240 
1241 int
1242 ql_8021_rom_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *bp)
1243 {
1244         int     ret;
1245 
1246         ret = ql_8021_rom_fast_read(ha, addr << 2, bp) == 0 ? QL_SUCCESS :
1247             QL_FUNCTION_FAILED;
1248 
1249         return (ret);
1250 }
1251 
1252 int
1253 ql_8021_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
1254 {
1255         int     ret, loops = 0;
1256 
1257         while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1258                 drv_usecwait(100);
1259                 loops++;
1260         }
1261         if (loops >= 50000) {
1262                 EL(ha, "rom_lock failed\n");
1263                 ret = QL_FUNCTION_TIMEOUT;
1264         } else {
1265                 ret = ql_8021_do_rom_write(ha, addr << 2, data) == 0 ?
1266                     QL_SUCCESS : QL_FUNCTION_FAILED;
1267                 ql_8021_rom_unlock(ha);
1268         }
1269 
1270         return (ret);
1271 }
1272 
1273 int
1274 ql_8021_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
1275 {
1276         int     ret, loops = 0;
1277 
1278         while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1279                 drv_usecwait(100);
1280                 loops++;
1281         }
1282         if (loops >= 50000) {
1283                 EL(ha, "rom_lock failed\n");
1284                 ret = QL_FUNCTION_TIMEOUT;
1285         } else {
1286                 ret = ql_8021_do_rom_erase(ha, addr << 2) == 0 ? QL_SUCCESS :
1287                     QL_FUNCTION_FAILED;
1288                 ql_8021_rom_unlock(ha);
1289         }
1290 
1291         return (ret);
1292 }
1293 
1294 int
1295 ql_8021_rom_wrsr(ql_adapter_state_t *ha, uint32_t data)
1296 {
1297         int     ret = QL_SUCCESS, loops = 0;
1298 
1299         while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1300                 drv_usecwait(100);
1301                 loops++;
1302         }
1303         if (loops >= 50000) {
1304                 EL(ha, "rom_lock failed\n");
1305                 ret = QL_FUNCTION_TIMEOUT;
1306         } else {
1307                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1308                 ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1309                     UNM_ROMUSB_ROM_WREN_INSTR);
1310                 if (ql_8021_wait_rom_done(ha)) {
1311                         EL(ha, "Error waiting for rom done\n");
1312                         ret = QL_FUNCTION_FAILED;
1313                 } else {
1314                         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
1315                         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1316                         ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1317                             UNM_ROMUSB_ROM_WRSR_INSTR);
1318                         if (ql_8021_wait_rom_done(ha)) {
1319                                 EL(ha, "Error waiting for rom done1\n");
1320                                 ret = QL_FUNCTION_FAILED;
1321                         } else if (ql_8021_wait_flash_done(ha)) {
1322                                 EL(ha, "Error waiting for flash done\n");
1323                                 ret = QL_FUNCTION_FAILED;
1324                         }
1325                 }
1326                 ql_8021_rom_unlock(ha);
1327         }
1328 
1329         return (ret);
1330 }
1331 
1332 static int
1333 ql_8021_phantom_init(ql_adapter_state_t *ha)
1334 {
1335         uint32_t        val = 0, err = 0;
1336         int             retries = 60;
1337 
1338         do {
1339                 ql_8021_rd_32(ha, CRB_CMDPEG_STATE, &val);
1340 
1341                 switch (val) {
1342                 case PHAN_INITIALIZE_COMPLETE:
1343                 case PHAN_INITIALIZE_ACK:
1344                         EL(ha, "success=%xh\n", val);
1345                         return (0);
1346                 case PHAN_INITIALIZE_FAILED:
1347                         EL(ha, "PHAN_INITIALIZE_FAILED\n");
1348                         err = 1;
1349                         break;
1350                 default:
1351                         break;
1352                 }
1353 
1354                 if (err) {
1355                         break;
1356                 }
1357                 /* 500 msec wait */
1358                 delay(50);
1359 
1360         } while (--retries);
1361 
1362         if (!err) {
1363                 ql_8021_wr_32(ha, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
1364         }
1365 
1366         EL(ha, "firmware init failed=%x\n", val);
1367         return (-1);
1368 }
1369 
1370 static int
1371 ql_8021_pinit_from_rom(ql_adapter_state_t *ha)
1372 {
1373         int                     init_delay = 0;
1374         struct crb_addr_pair    *buf;
1375         uint32_t                offset, off, i, n, addr, val;
1376 
1377         /* Grab the lock so that no one can read flash when we reset the chip */
1378         (void) ql_8021_rom_lock(ha);
1379         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0xffffffff);
1380         /* Just in case it was held when we reset the chip */
1381         ql_8021_rom_unlock(ha);
1382 
1383         if (ql_8021_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafe ||
1384             ql_8021_rom_fast_read(ha, 4, &n) != 0) {
1385                 EL(ha, "ERROR Reading crb_init area: n: %08x\n", n);
1386                 return (-1);
1387         }
1388         offset = n & 0xffff;
1389         n = (n >> 16) & 0xffff;
1390         if (n >= 1024) {
1391                 EL(ha, "n=0x%x Error! NetXen card flash not initialized\n", n);
1392                 return (-1);
1393         }
1394 
1395         buf = kmem_zalloc(n * sizeof (struct crb_addr_pair), KM_SLEEP);
1396 
1397         for (i = 0; i < n; i++) {
1398                 if (ql_8021_rom_fast_read(ha, 8 * i + 4 * offset, &val) != 0 ||
1399                     ql_8021_rom_fast_read(ha, 8 * i + 4 * offset + 4, &addr) !=
1400                     0) {
1401                         kmem_free(buf, n * sizeof (struct crb_addr_pair));
1402                         EL(ha, "ql_8021_rom_fast_read != 0 to zalloc memory\n");
1403                         return (-1);
1404                 }
1405 
1406                 buf[i].addr = addr;
1407                 buf[i].data = val;
1408         }
1409 
1410         for (i = 0; i < n; i++) {
1411                 off = ql_8021_decode_crb_addr(ha, buf[i].addr);
1412                 if (off == ADDR_ERROR) {
1413                         EL(ha, "Err: Unknown addr: 0x%lx\n", buf[i].addr);
1414                         continue;
1415                 }
1416                 off += UNM_PCI_CRBSPACE;
1417 
1418                 if (off & 1) {
1419                         continue;
1420                 }
1421 
1422                 /* skipping cold reboot MAGIC */
1423                 if (off == UNM_RAM_COLD_BOOT) {
1424                         continue;
1425                 }
1426                 if (off == (UNM_CRB_I2C0 + 0x1c)) {
1427                         continue;
1428                 }
1429                 /* do not reset PCI */
1430                 if (off == (ROMUSB_GLB + 0xbc)) {
1431                         continue;
1432                 }
1433                 if (off == (ROMUSB_GLB + 0xa8)) {
1434                         continue;
1435                 }
1436                 if (off == (ROMUSB_GLB + 0xc8)) {       /* core clock */
1437                         continue;
1438                 }
1439                 if (off == (ROMUSB_GLB + 0x24)) {       /* MN clock */
1440                         continue;
1441                 }
1442                 if (off == (ROMUSB_GLB + 0x1c)) {       /* MS clock */
1443                         continue;
1444                 }
1445                 if ((off & 0x0ff00000) == UNM_CRB_DDR_NET) {
1446                         continue;
1447                 }
1448                 if (off == (UNM_CRB_PEG_NET_1 + 0x18) &&
1449                     !NX_IS_REVISION_P3PLUS(ha->rev_id)) {
1450                         buf[i].data = 0x1020;
1451                 }
1452                 /* skip the function enable register */
1453                 if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION)) {
1454                         continue;
1455                 }
1456                 if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION2)) {
1457                         continue;
1458                 }
1459                 if ((off & 0x0ff00000) == UNM_CRB_SMB) {
1460                         continue;
1461                 }
1462 
1463                 /* After writing this register, HW needs time for CRB */
1464                 /* to quiet down (else crb_window returns 0xffffffff) */
1465                 init_delay = 1;
1466                 if (off == UNM_ROMUSB_GLB_SW_RESET) {
1467                         init_delay = 100;       /* Sleep 1000 msecs */
1468                 }
1469 
1470                 ql_8021_wr_32(ha, off, buf[i].data);
1471 
1472                 delay(init_delay);
1473         }
1474         kmem_free(buf, n * sizeof (struct crb_addr_pair));
1475 
1476         /* disable_peg_cache_all */
1477 
1478         /* p2dn replyCount */
1479         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0xec, 0x1e);
1480         /* disable_peg_cache 0 */
1481         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0x4c, 8);
1482         /* disable_peg_cache 1 */
1483         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_I + 0x4c, 8);
1484 
1485         /* peg_clr_all */
1486         /* peg_clr 0 */
1487         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x8, 0);
1488         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0xc, 0);
1489         /* peg_clr 1 */
1490         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0x8, 0);
1491         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0xc, 0);
1492         /* peg_clr 2 */
1493         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0x8, 0);
1494         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0xc, 0);
1495         /* peg_clr 3 */
1496         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0x8, 0);
1497         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0xc, 0);
1498 
1499         return (0);
1500 }
1501 
1502 static int
1503 ql_8021_load_from_flash(ql_adapter_state_t *ha)
1504 {
1505         int             i;
1506         uint32_t        flashaddr, memaddr;
1507         uint32_t        high, low, size;
1508         uint64_t        data;
1509 
1510         size = ha->bootloader_size / 2;
1511         flashaddr = ha->bootloader_addr << 2;
1512         memaddr = BOOTLD_START;
1513 
1514         for (i = 0; i < size; i++) {
1515                 if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1516                     (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1517                         EL(ha, "ql_8021_rom_fast_read != 0\n");
1518                         return (-1);
1519                 }
1520                 data = ((uint64_t)high << 32) | low;
1521                 (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
1522                 flashaddr += 8;
1523                 memaddr += 8;
1524         }
1525 
1526         size = ha->flash_fw_size / 2;
1527         flashaddr = ha->flash_fw_addr << 2;
1528         memaddr = IMAGE_START;
1529 
1530         for (i = 0; i < size; i++) {
1531                 if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1532                     (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1533                         EL(ha, "ql_8021_rom_fast_read3 != 0\n");
1534                         return (-1);
1535                 }
1536                 data = ((uint64_t)high << 32) | low;
1537                 (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
1538                 flashaddr += 8;
1539                 memaddr += 8;
1540         }
1541 
1542         return (0);
1543 }
1544 
1545 static int
1546 ql_8021_load_firmware(ql_adapter_state_t *ha)
1547 {
1548         uint64_t        data;
1549         uint32_t        i, flashaddr, size;
1550         uint8_t         *bp, n, *dp;
1551 
1552         bp = (uint8_t *)(ha->risc_fw[0].code);
1553         dp = (uint8_t *)&size;
1554         for (n = 0; n < 4; n++) {
1555                 dp[n] = *bp++;
1556         }
1557         LITTLE_ENDIAN_32(&size);
1558         EL(ha, "signature=%x\n", size);
1559 
1560         size = (IMAGE_START - BOOTLD_START) / 8;
1561 
1562         bp = (uint8_t *)(ha->risc_fw[0].code + BOOTLD_START);
1563         flashaddr = BOOTLD_START;
1564 
1565         dp = (uint8_t *)&data;
1566         for (i = 0; i < size; i++) {
1567                 for (n = 0; n < 8; n++) {
1568                         dp[n] = *bp++;
1569                 }
1570                 LITTLE_ENDIAN_64(&data);
1571                 (void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);
1572                 flashaddr += 8;
1573         }
1574 
1575         bp = (uint8_t *)(ha->risc_fw[0].code + FW_SIZE_OFFSET);
1576         dp = (uint8_t *)&size;
1577         for (n = 0; n < 4; n++) {
1578                 dp[n] = *bp++;
1579         }
1580         LITTLE_ENDIAN_32(&size);
1581         EL(ha, "IMAGE_START size=%llx\n", size);
1582         size = (size + 7) / 8;
1583 
1584         bp = (uint8_t *)(ha->risc_fw[0].code + IMAGE_START);
1585         flashaddr = IMAGE_START;
1586 
1587         dp = (uint8_t *)&data;
1588         for (i = 0; i < size; i++) {
1589                 for (n = 0; n < 8; n++) {
1590                         dp[n] = *bp++;
1591                 }
1592                 LITTLE_ENDIAN_64(&data);
1593                 (void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);
1594                 flashaddr += 8;
1595         }
1596 
1597         return (0);
1598 }
1599 
1600 static int
1601 ql_8021_init_p3p(ql_adapter_state_t *ha)
1602 {
1603         uint32_t        data;
1604 
1605         /* ??? */
1606         ql_8021_wr_32(ha, UNM_PORT_MODE_ADDR, UNM_PORT_MODE_AUTO_NEG);
1607         delay(drv_usectohz(1000000));
1608 
1609         /* CAM RAM Cold Boot Register */
1610         ql_8021_rd_32(ha, UNM_RAM_COLD_BOOT, &data);
1611         if (data == 0x55555555) {
1612                 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &data);
1613                 if (data != 0x80000f) {
1614                         EL(ha, "CRB_UNM_GLB_SW_RST=%x exit\n", data);
1615                         return (-1);
1616                 }
1617                 ql_8021_wr_32(ha, UNM_RAM_COLD_BOOT, 0);
1618         }
1619         ql_8021_rd_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, &data);
1620         data |= 1;
1621         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, data);
1622 
1623         /*
1624          * ???
1625          * data = ha->pci_bus_addr | BIT_31;
1626          * ql_8021_wr_32(ha, UNM_BUS_DEV_NO, data);
1627          */
1628 
1629         return (0);
1630 }
1631 
1632 /* ARGSUSED */
1633 void
1634 ql_8021_reset_chip(ql_adapter_state_t *ha)
1635 {
1636         /*
1637          * Disable interrupts does not work on a per function bases
1638          * leave them enabled
1639          */
1640         ql_8021_enable_intrs(ha);
1641 
1642         ADAPTER_STATE_LOCK(ha);
1643         ha->flags |= INTERRUPTS_ENABLED;
1644         ADAPTER_STATE_UNLOCK(ha);
1645 
1646         (void) ql_stop_firmware(ha);
1647 }
1648 
1649 static int
1650 ql_8021_reset_hw(ql_adapter_state_t *ha, int type)
1651 {
1652         int             ret;
1653         uint32_t        rst;
1654 
1655         /* scrub dma mask expansion register */
1656         ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1657 
1658         /* Overwrite stale initialization register values */
1659         ql_8021_wr_32(ha, CRB_CMDPEG_STATE, 0);
1660         ql_8021_wr_32(ha, CRB_RCVPEG_STATE, 0);
1661         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0);
1662         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0);
1663 
1664         (void) ql_8021_pinit_from_rom(ha);
1665         delay(1);
1666 
1667         /* Bring QM and CAMRAM out of reset */
1668         ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &rst);
1669         rst &= ~((1 << 28) | (1 << 24));
1670         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, rst);
1671 
1672         switch (type) {
1673         case 0:
1674                 ret = ql_8021_init_p3p(ha);
1675                 break;
1676         case 1:
1677                 ret = ql_8021_load_from_flash(ha);
1678                 break;
1679         case 2:
1680                 ret = ql_8021_load_firmware(ha);
1681                 break;
1682         }
1683         delay(1);
1684 
1685         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x18, 0x1020);
1686         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0x80001e);
1687 
1688         if (ret) {
1689                 EL(ha, "type=%d, ret=%d\n", type, ret);
1690         } else {
1691                 ret = ql_8021_phantom_init(ha);
1692         }
1693         return (ret);
1694 }
1695 
1696 int
1697 ql_8021_load_risc(ql_adapter_state_t *ha)
1698 {
1699         int             rv = 0;
1700         static int      ql_8021_fw_loaded = 0;
1701 
1702         GLOBAL_HW_LOCK();
1703         if (!ql_8021_fw_loaded) {
1704                 if (ha->risc_fw[0].code) {
1705                         EL(ha, "from driver\n");
1706                         rv = ql_8021_reset_hw(ha, 2);
1707                 } else {
1708                         /*
1709                          * BIOS method
1710                          * ql_8021_reset_hw(ha, 0)
1711                          */
1712                         EL(ha, "from flash\n");
1713                         rv = ql_8021_reset_hw(ha, 1);
1714                 }
1715                 if (rv == 0) {
1716                         ql_8021_fw_loaded = 1;
1717 
1718                         ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1719                         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0x0);
1720                         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0x0);
1721 
1722                         GLOBAL_HW_UNLOCK();
1723 
1724                         ADAPTER_STATE_LOCK(ha);
1725                         ha->flags &= ~INTERRUPTS_ENABLED;
1726                         ADAPTER_STATE_UNLOCK(ha);
1727 
1728                         (void) ql_8021_enable_intrs(ha);
1729 
1730                         ADAPTER_STATE_LOCK(ha);
1731                         ha->flags |= INTERRUPTS_ENABLED;
1732                         ADAPTER_STATE_UNLOCK(ha);
1733                 } else {
1734                         GLOBAL_HW_UNLOCK();
1735                 }
1736         } else {
1737                 GLOBAL_HW_UNLOCK();
1738                 EL(ha, "Firmware loaded by other function\n");
1739         }
1740 
1741         if (rv == 0) {
1742                 ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR, &ha->fw_major_version);
1743                 ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR, &ha->fw_minor_version);
1744                 ql_8021_rd_32(ha, UNM_FW_VERSION_SUB, &ha->fw_subminor_version);
1745                 EL(ha, "fw v%d.%02d.%02d\n", ha->fw_major_version,
1746                     ha->fw_minor_version, ha->fw_subminor_version);
1747         } else {
1748                 EL(ha, "status = -1\n");
1749                 return (QL_FUNCTION_FAILED);
1750         }
1751 
1752         return (QL_SUCCESS);
1753 }
1754 
1755 void
1756 ql_8021_clr_hw_intr(ql_adapter_state_t *ha)
1757 {
1758         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
1759         ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1760         ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1761 }
1762 
1763 void
1764 ql_8021_clr_fw_intr(ql_adapter_state_t *ha)
1765 {
1766         WRT32_IO_REG(ha, nx_risc_int, 0);
1767         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xfbff);
1768 }
1769 
1770 void
1771 ql_8021_enable_intrs(ql_adapter_state_t *ha)
1772 {
1773         GLOBAL_HW_LOCK();
1774         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
1775         GLOBAL_HW_UNLOCK();
1776         (void) ql_toggle_interrupt(ha, 1);
1777 }
1778 
1779 void
1780 ql_8021_disable_intrs(ql_adapter_state_t *ha)
1781 {
1782         (void) ql_toggle_interrupt(ha, 0);
1783         GLOBAL_HW_LOCK();
1784         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
1785         GLOBAL_HW_UNLOCK();
1786 }
1787 
1788 void
1789 ql_8021_update_crb_int_ptr(ql_adapter_state_t *ha)
1790 {
1791         struct legacy_intr_set  *nx_legacy_intr;
1792 
1793         ha->qdr_sn_window = (uint32_t)-1;
1794         ha->ddr_mn_window = (uint32_t)-1;
1795         nx_legacy_intr = &legacy_intr[ha->function_number];
1796 
1797         ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;
1798         ha->nx_legacy_intr.tgt_status_reg = nx_legacy_intr->tgt_status_reg;
1799         ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;
1800         ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
1801 }
1802 
1803 void
1804 ql_8021_set_drv_active(ql_adapter_state_t *ha)
1805 {
1806         uint32_t        val;
1807 
1808         if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1809                 return;
1810         }
1811 
1812         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1813         if (val == 0xffffffff) {
1814                 val = (1 << (ha->function_number * 4));
1815         } else {
1816                 val |= (1 << (ha->function_number * 4));
1817         }
1818         ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1819 
1820         ql_8021_hw_unlock(ha);
1821 }
1822 
1823 void
1824 ql_8021_clr_drv_active(ql_adapter_state_t *ha)
1825 {
1826         uint32_t        val;
1827 
1828         if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1829                 return;
1830         }
1831 
1832         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1833         val &= ~(1 << (ha->function_number * 4));
1834         ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1835 
1836         ql_8021_hw_unlock(ha);
1837 }
1838 
1839 static void
1840 ql_8021_need_reset_handler(ql_adapter_state_t *ha)
1841 {
1842         uint32_t        drv_state, drv_active;
1843         clock_t         timer;
1844 
1845         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1846 
1847         ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1848         drv_state |= (1 << (ha->function_number * 4));
1849         ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1850 
1851         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
1852 
1853         ql_8021_hw_unlock(ha);
1854 
1855         for (timer = 30; timer && drv_state != drv_active; timer--) {
1856                 delay(100);
1857 
1858                 (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1859                 ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1860                 ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
1861                 ql_8021_hw_unlock(ha);
1862         }
1863 }
1864 
1865 uint32_t
1866 ql_8021_idc_handler(ql_adapter_state_t *ha)
1867 {
1868         uint32_t        dev_state, drv_state, rval;
1869         clock_t         timer;
1870         ql_mbx_data_t   mr;
1871         boolean_t       stalled = B_FALSE, lock = B_FALSE;
1872 
1873         /* wait for 30 seconds for device to go ready */
1874         timer = 30;
1875         while (timer) {
1876                 if (lock == B_FALSE) {
1877                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1878                         lock = B_TRUE;
1879                 }
1880                 ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
1881 
1882                 switch (dev_state) {
1883                 case 0xffffffff:
1884                 case NX_DEV_COLD:
1885                         EL(ha, "dev_state=NX_DEV_COLD\n");
1886                         rval = NX_DEV_COLD;
1887                         ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_INITIALIZING);
1888                         ql_8021_wr_32(ha, CRB_DRV_IDC_VERSION, NX_IDC_VERSION);
1889                         (void) ql_8021_hw_unlock(ha);
1890                         if (ql_get_fw_version(ha, &mr, 2) == QL_SUCCESS &&
1891                             (mr.mb[1] | mr.mb[2] | mr.mb[3])) {
1892                                 ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR,
1893                                     &ha->fw_major_version);
1894                                 ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR,
1895                                     &ha->fw_minor_version);
1896                                 ql_8021_rd_32(ha, UNM_FW_VERSION_SUB,
1897                                     &ha->fw_subminor_version);
1898                                 rval = NX_DEV_READY;
1899                         } else if (ql_8021_load_risc(ha) == QL_SUCCESS) {
1900                                 rval = NX_DEV_READY;
1901                         }
1902                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1903                         ql_8021_wr_32(ha, CRB_DEV_STATE, rval);
1904                         break;
1905                 case NX_DEV_READY:
1906                         rval = NX_DEV_READY;
1907                         timer = 0;
1908                         break;
1909                 case NX_DEV_FAILED:
1910                         EL(ha, "dev_state=NX_DEV_FAILED\n");
1911                         rval = NX_DEV_FAILED;
1912                         timer = 0;
1913                         break;
1914 
1915                 case NX_DEV_NEED_RESET:
1916                         EL(ha, "dev_state=NX_DEV_NEED_RESET\n");
1917                         rval = NX_DEV_NEED_RESET;
1918                         (void) ql_8021_hw_unlock(ha);
1919                         lock = B_FALSE;
1920                         if (ql_stall_driver(ha, 0) == QL_SUCCESS) {
1921                                 stalled = B_TRUE;
1922                                 ql_8021_need_reset_handler(ha);
1923                         }
1924                         break;
1925 
1926                 case NX_DEV_NEED_QUIESCENT:
1927                         EL(ha, "dev_state=NX_DEV_NEED_QUIESCENT\n");
1928                         (void) ql_8021_hw_unlock(ha);
1929                         lock = B_FALSE;
1930                         rval = ql_stall_driver(ha, 0);
1931                         if (rval == QL_SUCCESS) {
1932                                 stalled = B_TRUE;
1933                                 (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1934                                 lock = B_TRUE;
1935                                 ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1936                                 drv_state |=
1937                                     (2 << (ha->function_number * 4));
1938                                 ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1939                         }
1940                         break;
1941 
1942                 case NX_DEV_INITIALIZING:
1943                         EL(ha, "dev_state=NX_DEV_INITIALIZING\n");
1944                         break;
1945                 case NX_DEV_QUIESCENT:
1946                         EL(ha, "dev_state=NX_DEV_QUIESCENT\n");
1947                         break;
1948                 default:
1949                         EL(ha, "dev_state=%x, default\n", dev_state);
1950                         break;
1951                 }
1952                 if (lock == B_TRUE) {
1953                         (void) ql_8021_hw_unlock(ha);
1954                         lock = B_FALSE;
1955                 }
1956 
1957                 if (timer) {
1958                         delay(100);
1959                         timer--;
1960                 }
1961         }
1962 
1963         if (stalled) {
1964                 ql_restart_driver(ha);
1965         }
1966         return (rval);
1967 }