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 = drv_sectohz(30); 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         if (buf == NULL) {
1397                 EL(ha, "Unable to zalloc memory\n");
1398                 return (-1);
1399         }
1400 
1401         for (i = 0; i < n; i++) {
1402                 if (ql_8021_rom_fast_read(ha, 8 * i + 4 * offset, &val) != 0 ||
1403                     ql_8021_rom_fast_read(ha, 8 * i + 4 * offset + 4, &addr) !=
1404                     0) {
1405                         kmem_free(buf, n * sizeof (struct crb_addr_pair));
1406                         EL(ha, "ql_8021_rom_fast_read != 0 to zalloc memory\n");
1407                         return (-1);
1408                 }
1409 
1410                 buf[i].addr = addr;
1411                 buf[i].data = val;
1412         }
1413 
1414         for (i = 0; i < n; i++) {
1415                 off = ql_8021_decode_crb_addr(ha, buf[i].addr);
1416                 if (off == ADDR_ERROR) {
1417                         EL(ha, "Err: Unknown addr: 0x%lx\n", buf[i].addr);
1418                         continue;
1419                 }
1420                 off += UNM_PCI_CRBSPACE;
1421 
1422                 if (off & 1) {
1423                         continue;
1424                 }
1425 
1426                 /* skipping cold reboot MAGIC */
1427                 if (off == UNM_RAM_COLD_BOOT) {
1428                         continue;
1429                 }
1430                 if (off == (UNM_CRB_I2C0 + 0x1c)) {
1431                         continue;
1432                 }
1433                 /* do not reset PCI */
1434                 if (off == (ROMUSB_GLB + 0xbc)) {
1435                         continue;
1436                 }
1437                 if (off == (ROMUSB_GLB + 0xa8)) {
1438                         continue;
1439                 }
1440                 if (off == (ROMUSB_GLB + 0xc8)) {       /* core clock */
1441                         continue;
1442                 }
1443                 if (off == (ROMUSB_GLB + 0x24)) {       /* MN clock */
1444                         continue;
1445                 }
1446                 if (off == (ROMUSB_GLB + 0x1c)) {       /* MS clock */
1447                         continue;
1448                 }
1449                 if ((off & 0x0ff00000) == UNM_CRB_DDR_NET) {
1450                         continue;
1451                 }
1452                 if (off == (UNM_CRB_PEG_NET_1 + 0x18) &&
1453                     !NX_IS_REVISION_P3PLUS(ha->rev_id)) {
1454                         buf[i].data = 0x1020;
1455                 }
1456                 /* skip the function enable register */
1457                 if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION)) {
1458                         continue;
1459                 }
1460                 if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION2)) {
1461                         continue;
1462                 }
1463                 if ((off & 0x0ff00000) == UNM_CRB_SMB) {
1464                         continue;
1465                 }
1466 
1467                 /* After writing this register, HW needs time for CRB */
1468                 /* to quiet down (else crb_window returns 0xffffffff) */
1469                 init_delay = 1;
1470                 if (off == UNM_ROMUSB_GLB_SW_RESET) {
1471                         init_delay = 100;       /* Sleep 1000 msecs */
1472                 }
1473 
1474                 ql_8021_wr_32(ha, off, buf[i].data);
1475 
1476                 delay(init_delay);
1477         }
1478         kmem_free(buf, n * sizeof (struct crb_addr_pair));
1479 
1480         /* disable_peg_cache_all */
1481 
1482         /* p2dn replyCount */
1483         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0xec, 0x1e);
1484         /* disable_peg_cache 0 */
1485         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0x4c, 8);
1486         /* disable_peg_cache 1 */
1487         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_I + 0x4c, 8);
1488 
1489         /* peg_clr_all */
1490         /* peg_clr 0 */
1491         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x8, 0);
1492         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0xc, 0);
1493         /* peg_clr 1 */
1494         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0x8, 0);
1495         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0xc, 0);
1496         /* peg_clr 2 */
1497         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0x8, 0);
1498         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0xc, 0);
1499         /* peg_clr 3 */
1500         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0x8, 0);
1501         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0xc, 0);
1502 
1503         return (0);
1504 }
1505 
1506 static int
1507 ql_8021_load_from_flash(ql_adapter_state_t *ha)
1508 {
1509         int             i;
1510         uint32_t        flashaddr, memaddr;
1511         uint32_t        high, low, size;
1512         uint64_t        data;
1513 
1514         size = ha->bootloader_size / 2;
1515         flashaddr = ha->bootloader_addr << 2;
1516         memaddr = BOOTLD_START;
1517 
1518         for (i = 0; i < size; i++) {
1519                 if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1520                     (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1521                         EL(ha, "ql_8021_rom_fast_read != 0\n");
1522                         return (-1);
1523                 }
1524                 data = ((uint64_t)high << 32) | low;
1525                 (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
1526                 flashaddr += 8;
1527                 memaddr += 8;
1528         }
1529 
1530         size = ha->flash_fw_size / 2;
1531         flashaddr = ha->flash_fw_addr << 2;
1532         memaddr = IMAGE_START;
1533 
1534         for (i = 0; i < size; i++) {
1535                 if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1536                     (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1537                         EL(ha, "ql_8021_rom_fast_read3 != 0\n");
1538                         return (-1);
1539                 }
1540                 data = ((uint64_t)high << 32) | low;
1541                 (void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
1542                 flashaddr += 8;
1543                 memaddr += 8;
1544         }
1545 
1546         return (0);
1547 }
1548 
1549 static int
1550 ql_8021_load_firmware(ql_adapter_state_t *ha)
1551 {
1552         uint64_t        data;
1553         uint32_t        i, flashaddr, size;
1554         uint8_t         *bp, n, *dp;
1555 
1556         bp = (uint8_t *)(ha->risc_fw[0].code);
1557         dp = (uint8_t *)&size;
1558         for (n = 0; n < 4; n++) {
1559                 dp[n] = *bp++;
1560         }
1561         LITTLE_ENDIAN_32(&size);
1562         EL(ha, "signature=%x\n", size);
1563 
1564         size = (IMAGE_START - BOOTLD_START) / 8;
1565 
1566         bp = (uint8_t *)(ha->risc_fw[0].code + BOOTLD_START);
1567         flashaddr = BOOTLD_START;
1568 
1569         dp = (uint8_t *)&data;
1570         for (i = 0; i < size; i++) {
1571                 for (n = 0; n < 8; n++) {
1572                         dp[n] = *bp++;
1573                 }
1574                 LITTLE_ENDIAN_64(&data);
1575                 (void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);
1576                 flashaddr += 8;
1577         }
1578 
1579         bp = (uint8_t *)(ha->risc_fw[0].code + FW_SIZE_OFFSET);
1580         dp = (uint8_t *)&size;
1581         for (n = 0; n < 4; n++) {
1582                 dp[n] = *bp++;
1583         }
1584         LITTLE_ENDIAN_32(&size);
1585         EL(ha, "IMAGE_START size=%llx\n", size);
1586         size = (size + 7) / 8;
1587 
1588         bp = (uint8_t *)(ha->risc_fw[0].code + IMAGE_START);
1589         flashaddr = IMAGE_START;
1590 
1591         dp = (uint8_t *)&data;
1592         for (i = 0; i < size; i++) {
1593                 for (n = 0; n < 8; n++) {
1594                         dp[n] = *bp++;
1595                 }
1596                 LITTLE_ENDIAN_64(&data);
1597                 (void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);
1598                 flashaddr += 8;
1599         }
1600 
1601         return (0);
1602 }
1603 
1604 static int
1605 ql_8021_init_p3p(ql_adapter_state_t *ha)
1606 {
1607         uint32_t        data;
1608 
1609         /* ??? */
1610         ql_8021_wr_32(ha, UNM_PORT_MODE_ADDR, UNM_PORT_MODE_AUTO_NEG);
1611         delay(drv_sectohz(1));
1612 
1613         /* CAM RAM Cold Boot Register */
1614         ql_8021_rd_32(ha, UNM_RAM_COLD_BOOT, &data);
1615         if (data == 0x55555555) {
1616                 ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &data);
1617                 if (data != 0x80000f) {
1618                         EL(ha, "CRB_UNM_GLB_SW_RST=%x exit\n", data);
1619                         return (-1);
1620                 }
1621                 ql_8021_wr_32(ha, UNM_RAM_COLD_BOOT, 0);
1622         }
1623         ql_8021_rd_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, &data);
1624         data |= 1;
1625         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, data);
1626 
1627         /*
1628          * ???
1629          * data = ha->pci_bus_addr | BIT_31;
1630          * ql_8021_wr_32(ha, UNM_BUS_DEV_NO, data);
1631          */
1632 
1633         return (0);
1634 }
1635 
1636 /* ARGSUSED */
1637 void
1638 ql_8021_reset_chip(ql_adapter_state_t *ha)
1639 {
1640         /*
1641          * Disable interrupts does not work on a per function bases
1642          * leave them enabled
1643          */
1644         ql_8021_enable_intrs(ha);
1645 
1646         ADAPTER_STATE_LOCK(ha);
1647         ha->flags |= INTERRUPTS_ENABLED;
1648         ADAPTER_STATE_UNLOCK(ha);
1649 
1650         (void) ql_stop_firmware(ha);
1651 }
1652 
1653 static int
1654 ql_8021_reset_hw(ql_adapter_state_t *ha, int type)
1655 {
1656         int             ret;
1657         uint32_t        rst;
1658 
1659         /* scrub dma mask expansion register */
1660         ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1661 
1662         /* Overwrite stale initialization register values */
1663         ql_8021_wr_32(ha, CRB_CMDPEG_STATE, 0);
1664         ql_8021_wr_32(ha, CRB_RCVPEG_STATE, 0);
1665         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0);
1666         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0);
1667 
1668         (void) ql_8021_pinit_from_rom(ha);
1669         delay(1);
1670 
1671         /* Bring QM and CAMRAM out of reset */
1672         ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &rst);
1673         rst &= ~((1 << 28) | (1 << 24));
1674         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, rst);
1675 
1676         switch (type) {
1677         case 0:
1678                 ret = ql_8021_init_p3p(ha);
1679                 break;
1680         case 1:
1681                 ret = ql_8021_load_from_flash(ha);
1682                 break;
1683         case 2:
1684                 ret = ql_8021_load_firmware(ha);
1685                 break;
1686         }
1687         delay(1);
1688 
1689         ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x18, 0x1020);
1690         ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0x80001e);
1691 
1692         if (ret) {
1693                 EL(ha, "type=%d, ret=%d\n", type, ret);
1694         } else {
1695                 ret = ql_8021_phantom_init(ha);
1696         }
1697         return (ret);
1698 }
1699 
1700 int
1701 ql_8021_load_risc(ql_adapter_state_t *ha)
1702 {
1703         int             rv = 0;
1704         static int      ql_8021_fw_loaded = 0;
1705 
1706         GLOBAL_HW_LOCK();
1707         if (!ql_8021_fw_loaded) {
1708                 if (ha->risc_fw[0].code) {
1709                         EL(ha, "from driver\n");
1710                         rv = ql_8021_reset_hw(ha, 2);
1711                 } else {
1712                         /*
1713                          * BIOS method
1714                          * ql_8021_reset_hw(ha, 0)
1715                          */
1716                         EL(ha, "from flash\n");
1717                         rv = ql_8021_reset_hw(ha, 1);
1718                 }
1719                 if (rv == 0) {
1720                         ql_8021_fw_loaded = 1;
1721 
1722                         ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1723                         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0x0);
1724                         ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0x0);
1725 
1726                         GLOBAL_HW_UNLOCK();
1727 
1728                         ADAPTER_STATE_LOCK(ha);
1729                         ha->flags &= ~INTERRUPTS_ENABLED;
1730                         ADAPTER_STATE_UNLOCK(ha);
1731 
1732                         (void) ql_8021_enable_intrs(ha);
1733 
1734                         ADAPTER_STATE_LOCK(ha);
1735                         ha->flags |= INTERRUPTS_ENABLED;
1736                         ADAPTER_STATE_UNLOCK(ha);
1737                 } else {
1738                         GLOBAL_HW_UNLOCK();
1739                 }
1740         } else {
1741                 GLOBAL_HW_UNLOCK();
1742                 EL(ha, "Firmware loaded by other function\n");
1743         }
1744 
1745         if (rv == 0) {
1746                 ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR, &ha->fw_major_version);
1747                 ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR, &ha->fw_minor_version);
1748                 ql_8021_rd_32(ha, UNM_FW_VERSION_SUB, &ha->fw_subminor_version);
1749                 EL(ha, "fw v%d.%02d.%02d\n", ha->fw_major_version,
1750                     ha->fw_minor_version, ha->fw_subminor_version);
1751         } else {
1752                 EL(ha, "status = -1\n");
1753                 return (QL_FUNCTION_FAILED);
1754         }
1755 
1756         return (QL_SUCCESS);
1757 }
1758 
1759 void
1760 ql_8021_clr_hw_intr(ql_adapter_state_t *ha)
1761 {
1762         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
1763         ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1764         ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1765 }
1766 
1767 void
1768 ql_8021_clr_fw_intr(ql_adapter_state_t *ha)
1769 {
1770         WRT32_IO_REG(ha, nx_risc_int, 0);
1771         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xfbff);
1772 }
1773 
1774 void
1775 ql_8021_enable_intrs(ql_adapter_state_t *ha)
1776 {
1777         GLOBAL_HW_LOCK();
1778         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
1779         GLOBAL_HW_UNLOCK();
1780         (void) ql_toggle_interrupt(ha, 1);
1781 }
1782 
1783 void
1784 ql_8021_disable_intrs(ql_adapter_state_t *ha)
1785 {
1786         (void) ql_toggle_interrupt(ha, 0);
1787         GLOBAL_HW_LOCK();
1788         ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
1789         GLOBAL_HW_UNLOCK();
1790 }
1791 
1792 void
1793 ql_8021_update_crb_int_ptr(ql_adapter_state_t *ha)
1794 {
1795         struct legacy_intr_set  *nx_legacy_intr;
1796 
1797         ha->qdr_sn_window = (uint32_t)-1;
1798         ha->ddr_mn_window = (uint32_t)-1;
1799         nx_legacy_intr = &legacy_intr[ha->function_number];
1800 
1801         ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;
1802         ha->nx_legacy_intr.tgt_status_reg = nx_legacy_intr->tgt_status_reg;
1803         ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;
1804         ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
1805 }
1806 
1807 void
1808 ql_8021_set_drv_active(ql_adapter_state_t *ha)
1809 {
1810         uint32_t        val;
1811 
1812         if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1813                 return;
1814         }
1815 
1816         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1817         if (val == 0xffffffff) {
1818                 val = (1 << (ha->function_number * 4));
1819         } else {
1820                 val |= (1 << (ha->function_number * 4));
1821         }
1822         ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1823 
1824         ql_8021_hw_unlock(ha);
1825 }
1826 
1827 void
1828 ql_8021_clr_drv_active(ql_adapter_state_t *ha)
1829 {
1830         uint32_t        val;
1831 
1832         if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1833                 return;
1834         }
1835 
1836         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1837         val &= ~(1 << (ha->function_number * 4));
1838         ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1839 
1840         ql_8021_hw_unlock(ha);
1841 }
1842 
1843 static void
1844 ql_8021_need_reset_handler(ql_adapter_state_t *ha)
1845 {
1846         uint32_t        drv_state, drv_active;
1847         clock_t         timer;
1848 
1849         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1850 
1851         ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1852         drv_state |= (1 << (ha->function_number * 4));
1853         ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1854 
1855         ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
1856 
1857         ql_8021_hw_unlock(ha);
1858 
1859         for (timer = 30; timer && drv_state != drv_active; timer--) {
1860                 delay(100);
1861 
1862                 (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1863                 ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1864                 ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
1865                 ql_8021_hw_unlock(ha);
1866         }
1867 }
1868 
1869 uint32_t
1870 ql_8021_idc_handler(ql_adapter_state_t *ha)
1871 {
1872         uint32_t        dev_state, drv_state, rval;
1873         clock_t         timer;
1874         ql_mbx_data_t   mr;
1875         boolean_t       stalled = B_FALSE, lock = B_FALSE;
1876 
1877         /* wait for 30 seconds for device to go ready */
1878         timer = 30;
1879         while (timer) {
1880                 if (lock == B_FALSE) {
1881                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1882                         lock = B_TRUE;
1883                 }
1884                 ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
1885 
1886                 switch (dev_state) {
1887                 case 0xffffffff:
1888                 case NX_DEV_COLD:
1889                         EL(ha, "dev_state=NX_DEV_COLD\n");
1890                         rval = NX_DEV_COLD;
1891                         ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_INITIALIZING);
1892                         ql_8021_wr_32(ha, CRB_DRV_IDC_VERSION, NX_IDC_VERSION);
1893                         (void) ql_8021_hw_unlock(ha);
1894                         if (ql_get_fw_version(ha, &mr, 2) == QL_SUCCESS &&
1895                             (mr.mb[1] | mr.mb[2] | mr.mb[3])) {
1896                                 ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR,
1897                                     &ha->fw_major_version);
1898                                 ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR,
1899                                     &ha->fw_minor_version);
1900                                 ql_8021_rd_32(ha, UNM_FW_VERSION_SUB,
1901                                     &ha->fw_subminor_version);
1902                                 rval = NX_DEV_READY;
1903                         } else if (ql_8021_load_risc(ha) == QL_SUCCESS) {
1904                                 rval = NX_DEV_READY;
1905                         }
1906                         (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1907                         ql_8021_wr_32(ha, CRB_DEV_STATE, rval);
1908                         break;
1909                 case NX_DEV_READY:
1910                         rval = NX_DEV_READY;
1911                         timer = 0;
1912                         break;
1913                 case NX_DEV_FAILED:
1914                         EL(ha, "dev_state=NX_DEV_FAILED\n");
1915                         rval = NX_DEV_FAILED;
1916                         timer = 0;
1917                         break;
1918 
1919                 case NX_DEV_NEED_RESET:
1920                         EL(ha, "dev_state=NX_DEV_NEED_RESET\n");
1921                         rval = NX_DEV_NEED_RESET;
1922                         (void) ql_8021_hw_unlock(ha);
1923                         lock = B_FALSE;
1924                         if (ql_stall_driver(ha, 0) == QL_SUCCESS) {
1925                                 stalled = B_TRUE;
1926                                 ql_8021_need_reset_handler(ha);
1927                         }
1928                         break;
1929 
1930                 case NX_DEV_NEED_QUIESCENT:
1931                         EL(ha, "dev_state=NX_DEV_NEED_QUIESCENT\n");
1932                         (void) ql_8021_hw_unlock(ha);
1933                         lock = B_FALSE;
1934                         rval = ql_stall_driver(ha, 0);
1935                         if (rval == QL_SUCCESS) {
1936                                 stalled = B_TRUE;
1937                                 (void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1938                                 lock = B_TRUE;
1939                                 ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1940                                 drv_state |=
1941                                     (2 << (ha->function_number * 4));
1942                                 ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1943                         }
1944                         break;
1945 
1946                 case NX_DEV_INITIALIZING:
1947                         EL(ha, "dev_state=NX_DEV_INITIALIZING\n");
1948                         break;
1949                 case NX_DEV_QUIESCENT:
1950                         EL(ha, "dev_state=NX_DEV_QUIESCENT\n");
1951                         break;
1952                 default:
1953                         EL(ha, "dev_state=%x, default\n", dev_state);
1954                         break;
1955                 }
1956                 if (lock == B_TRUE) {
1957                         (void) ql_8021_hw_unlock(ha);
1958                         lock = B_FALSE;
1959                 }
1960 
1961                 if (timer) {
1962                         delay(100);
1963                         timer--;
1964                 }
1965         }
1966 
1967         if (stalled) {
1968                 ql_restart_driver(ha);
1969         }
1970         return (rval);
1971 }