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 2008 NetXen, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2019 Joyent, Inc.
  29  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/conf.h>
  33 #include <sys/debug.h>
  34 #include <sys/stropts.h>
  35 #include <sys/stream.h>
  36 #include <sys/strlog.h>
  37 #include <sys/kmem.h>
  38 #include <sys/stat.h>
  39 #include <sys/kstat.h>
  40 #include <sys/vtrace.h>
  41 #include <sys/dlpi.h>
  42 #include <sys/strsun.h>
  43 #include <sys/ethernet.h>
  44 #include <sys/modctl.h>
  45 #include <sys/errno.h>
  46 #include <sys/dditypes.h>
  47 #include <sys/ddi.h>
  48 #include <sys/sunddi.h>
  49 #include <sys/sysmacros.h>
  50 
  51 #include <sys/pci.h>
  52 
  53 #include "unm_nic.h"
  54 #include "unm_nic_hw.h"
  55 #include "nic_cmn.h"
  56 #include "unm_brdcfg.h"
  57 #include "driver_info.h"
  58 
  59 long unm_niu_gbe_phy_read(struct unm_adapter_s *,
  60                 long reg, unm_crbword_t *readval);
  61 
  62 #define MASK(n)                 ((1ULL<<(n))-1)
  63 #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
  64 #define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) |    \
  65                 ((addr >> 25) & 0x3ff)) // 64K?
  66 #define MS_WIN(addr) (addr & 0x0ffc0000)
  67 #define UNM_PCI_MN_2M   (0)
  68 #define UNM_PCI_MS_2M   (0x80000)
  69 #define UNM_PCI_OCM0_2M (0xc0000)
  70 #define VALID_OCM_ADDR(addr) (((addr) & 0x3f800) != 0x3f800)
  71 #define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
  72 
  73 #define CRB_BLK(off)    ((off >> 20) & 0x3f)
  74 #define CRB_SUBBLK(off) ((off >> 16) & 0xf)
  75 #define CRB_WINDOW_2M   (0x130060)
  76 #define UNM_PCI_CAMQM_2M_END    (0x04800800UL)
  77 #define CRB_HI(off)     ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
  78 #define UNM_PCI_CAMQM_2M_BASE   (0x000ff800UL)
  79 #define CRB_INDIRECT_2M (0x1e0000UL)
  80 
  81 static crb_128M_2M_block_map_t  crb_128M_2M_map[64] = {
  82             {{{0, 0, 0, 0}}}, /* 0: PCI */
  83             {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */
  84             {1, 0x0110000, 0x0120000, 0x130000},
  85             {1, 0x0120000, 0x0122000, 0x124000},
  86             {1, 0x0130000, 0x0132000, 0x126000},
  87             {1, 0x0140000, 0x0142000, 0x128000},
  88             {1, 0x0150000, 0x0152000, 0x12a000},
  89             {1, 0x0160000, 0x0170000, 0x110000},
  90             {1, 0x0170000, 0x0172000, 0x12e000},
  91             {0, 0x0000000, 0x0000000, 0x000000},
  92             {0, 0x0000000, 0x0000000, 0x000000},
  93             {0, 0x0000000, 0x0000000, 0x000000},
  94             {0, 0x0000000, 0x0000000, 0x000000},
  95             {0, 0x0000000, 0x0000000, 0x000000},
  96             {0, 0x0000000, 0x0000000, 0x000000},
  97             {1, 0x01e0000, 0x01e0800, 0x122000},
  98             {0, 0x0000000, 0x0000000, 0x000000}}},
  99             {{{1, 0x0200000, 0x0210000, 0x180000}}}, /* 2: MN */
 100             {{{0, 0, 0, 0}}}, /* 3: */
 101             {{{1, 0x0400000, 0x0401000, 0x169000}}}, /* 4: P2NR1 */
 102             {{{1, 0x0500000, 0x0510000, 0x140000}}}, /* 5: SRE   */
 103             {{{1, 0x0600000, 0x0610000, 0x1c0000}}}, /* 6: NIU   */
 104             {{{1, 0x0700000, 0x0704000, 0x1b8000}}}, /* 7: QM    */
 105             {{{1, 0x0800000, 0x0802000, 0x170000}, /* 8: SQM0  */
 106             {0, 0x0000000, 0x0000000, 0x000000},
 107             {0, 0x0000000, 0x0000000, 0x000000},
 108             {0, 0x0000000, 0x0000000, 0x000000},
 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             {0, 0x0000000, 0x0000000, 0x000000},
 116             {0, 0x0000000, 0x0000000, 0x000000},
 117             {0, 0x0000000, 0x0000000, 0x000000},
 118             {0, 0x0000000, 0x0000000, 0x000000},
 119             {0, 0x0000000, 0x0000000, 0x000000},
 120             {1, 0x08f0000, 0x08f2000, 0x172000}}},
 121             {{{1, 0x0900000, 0x0902000, 0x174000}, /* 9: SQM1 */
 122             {0, 0x0000000, 0x0000000, 0x000000},
 123             {0, 0x0000000, 0x0000000, 0x000000},
 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             {1, 0x09f0000, 0x09f2000, 0x176000}}},
 137             {{{0, 0x0a00000, 0x0a02000, 0x178000}, /* 10: SQM2 */
 138             {0, 0x0000000, 0x0000000, 0x000000},
 139             {0, 0x0000000, 0x0000000, 0x000000},
 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             {1, 0x0af0000, 0x0af2000, 0x17a000}}},
 153             {{{0, 0x0b00000, 0x0b02000, 0x17c000}, /* 11: SQM3 */
 154             {0, 0x0000000, 0x0000000, 0x000000},
 155             {0, 0x0000000, 0x0000000, 0x000000},
 156             {0, 0x0000000, 0x0000000, 0x000000},
 157             {0, 0x0000000, 0x0000000, 0x000000},
 158             {0, 0x0000000, 0x0000000, 0x000000},
 159             {0, 0x0000000, 0x0000000, 0x000000},
 160             {0, 0x0000000, 0x0000000, 0x000000},
 161             {0, 0x0000000, 0x0000000, 0x000000},
 162             {0, 0x0000000, 0x0000000, 0x000000},
 163             {0, 0x0000000, 0x0000000, 0x000000},
 164             {0, 0x0000000, 0x0000000, 0x000000},
 165             {0, 0x0000000, 0x0000000, 0x000000},
 166             {0, 0x0000000, 0x0000000, 0x000000},
 167             {0, 0x0000000, 0x0000000, 0x000000},
 168             {1, 0x0bf0000, 0x0bf2000, 0x17e000}}},
 169             {{{1, 0x0c00000, 0x0c04000, 0x1d4000}}}, /* 12: I2Q */
 170             {{{1, 0x0d00000, 0x0d04000, 0x1a4000}}}, /* 13: TMR */
 171             {{{1, 0x0e00000, 0x0e04000, 0x1a0000}}}, /* 14: ROMUSB */
 172             {{{1, 0x0f00000, 0x0f01000, 0x164000}}}, /* 15: PEG4 */
 173             {{{0, 0x1000000, 0x1004000, 0x1a8000}}}, /* 16: XDMA */
 174             {{{1, 0x1100000, 0x1101000, 0x160000}}}, /* 17: PEG0 */
 175             {{{1, 0x1200000, 0x1201000, 0x161000}}}, /* 18: PEG1 */
 176             {{{1, 0x1300000, 0x1301000, 0x162000}}}, /* 19: PEG2 */
 177             {{{1, 0x1400000, 0x1401000, 0x163000}}}, /* 20: PEG3 */
 178             {{{1, 0x1500000, 0x1501000, 0x165000}}}, /* 21: P2ND */
 179             {{{1, 0x1600000, 0x1601000, 0x166000}}}, /* 22: P2NI */
 180             {{{0, 0, 0, 0}}}, /* 23: */
 181             {{{0, 0, 0, 0}}}, /* 24: */
 182             {{{0, 0, 0, 0}}}, /* 25: */
 183             {{{0, 0, 0, 0}}}, /* 26: */
 184             {{{0, 0, 0, 0}}}, /* 27: */
 185             {{{0, 0, 0, 0}}}, /* 28: */
 186             {{{1, 0x1d00000, 0x1d10000, 0x190000}}}, /* 29: MS */
 187             {{{1, 0x1e00000, 0x1e01000, 0x16a000}}}, /* 30: P2NR2 */
 188             {{{1, 0x1f00000, 0x1f10000, 0x150000}}}, /* 31: EPG */
 189             {{{0}}}, /* 32: PCI */
 190             {{{1, 0x2100000, 0x2102000, 0x120000}, /* 33: PCIE */
 191             {1, 0x2110000, 0x2120000, 0x130000},
 192             {1, 0x2120000, 0x2122000, 0x124000},
 193             {1, 0x2130000, 0x2132000, 0x126000},
 194             {1, 0x2140000, 0x2142000, 0x128000},
 195             {1, 0x2150000, 0x2152000, 0x12a000},
 196             {1, 0x2160000, 0x2170000, 0x110000},
 197             {1, 0x2170000, 0x2172000, 0x12e000},
 198             {0, 0x0000000, 0x0000000, 0x000000},
 199             {0, 0x0000000, 0x0000000, 0x000000},
 200             {0, 0x0000000, 0x0000000, 0x000000},
 201             {0, 0x0000000, 0x0000000, 0x000000},
 202             {0, 0x0000000, 0x0000000, 0x000000},
 203             {0, 0x0000000, 0x0000000, 0x000000},
 204             {0, 0x0000000, 0x0000000, 0x000000},
 205             {0, 0x0000000, 0x0000000, 0x000000}}},
 206             {{{1, 0x2200000, 0x2204000, 0x1b0000}}}, /* 34: CAM */
 207             {{{0}}}, /* 35: */
 208             {{{0}}}, /* 36: */
 209             {{{0}}}, /* 37: */
 210             {{{0}}}, /* 38: */
 211             {{{0}}}, /* 39: */
 212             {{{1, 0x2800000, 0x2804000, 0x1a4000}}}, /* 40: TMR */
 213             {{{1, 0x2900000, 0x2901000, 0x16b000}}}, /* 41: P2NR3 */
 214             {{{1, 0x2a00000, 0x2a00400, 0x1ac400}}}, /* 42: RPMX1 */
 215             {{{1, 0x2b00000, 0x2b00400, 0x1ac800}}}, /* 43: RPMX2 */
 216             {{{1, 0x2c00000, 0x2c00400, 0x1acc00}}}, /* 44: RPMX3 */
 217             {{{1, 0x2d00000, 0x2d00400, 0x1ad000}}}, /* 45: RPMX4 */
 218             {{{1, 0x2e00000, 0x2e00400, 0x1ad400}}}, /* 46: RPMX5 */
 219             {{{1, 0x2f00000, 0x2f00400, 0x1ad800}}}, /* 47: RPMX6 */
 220             {{{1, 0x3000000, 0x3000400, 0x1adc00}}}, /* 48: RPMX7 */
 221             {{{0, 0x3100000, 0x3104000, 0x1a8000}}}, /* 49: XDMA */
 222             {{{1, 0x3200000, 0x3204000, 0x1d4000}}}, /* 50: I2Q */
 223             {{{1, 0x3300000, 0x3304000, 0x1a0000}}}, /* 51: ROMUSB */
 224             {{{0}}}, /* 52: */
 225             {{{1, 0x3500000, 0x3500400, 0x1ac000}}}, /* 53: RPMX0 */
 226             {{{1, 0x3600000, 0x3600400, 0x1ae000}}}, /* 54: RPMX8 */
 227             {{{1, 0x3700000, 0x3700400, 0x1ae400}}}, /* 55: RPMX9 */
 228             {{{1, 0x3800000, 0x3804000, 0x1d0000}}}, /* 56: OCM0 */
 229             {{{1, 0x3900000, 0x3904000, 0x1b4000}}}, /* 57: CRYPTO */
 230             {{{1, 0x3a00000, 0x3a04000, 0x1d8000}}}, /* 58: SMB */
 231             {{{0}}}, /* 59: I2C0 */
 232             {{{0}}}, /* 60: I2C1 */
 233             {{{1, 0x3d00000, 0x3d04000, 0x1d8000}}}, /* 61: LPC */
 234             {{{1, 0x3e00000, 0x3e01000, 0x167000}}}, /* 62: P2NC */
 235             {{{1, 0x3f00000, 0x3f01000, 0x168000}}} /* 63: P2NR0 */
 236 };
 237 
 238 /*
 239  * top 12 bits of crb internal address (hub, agent)
 240  */
 241 static unsigned crb_hub_agt[64] = {
 242         0,
 243         UNM_HW_CRB_HUB_AGT_ADR_PS,
 244         UNM_HW_CRB_HUB_AGT_ADR_MN,
 245         UNM_HW_CRB_HUB_AGT_ADR_MS,
 246         0,
 247         UNM_HW_CRB_HUB_AGT_ADR_SRE,
 248         UNM_HW_CRB_HUB_AGT_ADR_NIU,
 249         UNM_HW_CRB_HUB_AGT_ADR_QMN,
 250         UNM_HW_CRB_HUB_AGT_ADR_SQN0,
 251         UNM_HW_CRB_HUB_AGT_ADR_SQN1,
 252         UNM_HW_CRB_HUB_AGT_ADR_SQN2,
 253         UNM_HW_CRB_HUB_AGT_ADR_SQN3,
 254         UNM_HW_CRB_HUB_AGT_ADR_I2Q,
 255         UNM_HW_CRB_HUB_AGT_ADR_TIMR,
 256         UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
 257         UNM_HW_CRB_HUB_AGT_ADR_PGN4,
 258         UNM_HW_CRB_HUB_AGT_ADR_XDMA,
 259         UNM_HW_CRB_HUB_AGT_ADR_PGN0,
 260         UNM_HW_CRB_HUB_AGT_ADR_PGN1,
 261         UNM_HW_CRB_HUB_AGT_ADR_PGN2,
 262         UNM_HW_CRB_HUB_AGT_ADR_PGN3,
 263         UNM_HW_CRB_HUB_AGT_ADR_PGND,
 264         UNM_HW_CRB_HUB_AGT_ADR_PGNI,
 265         UNM_HW_CRB_HUB_AGT_ADR_PGS0,
 266         UNM_HW_CRB_HUB_AGT_ADR_PGS1,
 267         UNM_HW_CRB_HUB_AGT_ADR_PGS2,
 268         UNM_HW_CRB_HUB_AGT_ADR_PGS3,
 269         0,
 270         UNM_HW_CRB_HUB_AGT_ADR_PGSI,
 271         UNM_HW_CRB_HUB_AGT_ADR_SN,
 272         0,
 273         UNM_HW_CRB_HUB_AGT_ADR_EG,
 274         0,
 275         UNM_HW_CRB_HUB_AGT_ADR_PS,
 276         UNM_HW_CRB_HUB_AGT_ADR_CAM,
 277         0,
 278         0,
 279         0,
 280         0,
 281         0,
 282         UNM_HW_CRB_HUB_AGT_ADR_TIMR,
 283         0,
 284         UNM_HW_CRB_HUB_AGT_ADR_RPMX1,
 285         UNM_HW_CRB_HUB_AGT_ADR_RPMX2,
 286         UNM_HW_CRB_HUB_AGT_ADR_RPMX3,
 287         UNM_HW_CRB_HUB_AGT_ADR_RPMX4,
 288         UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
 289         UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
 290         UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
 291         UNM_HW_CRB_HUB_AGT_ADR_XDMA,
 292         UNM_HW_CRB_HUB_AGT_ADR_I2Q,
 293         UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
 294         0,
 295         UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
 296         UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
 297         UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
 298         UNM_HW_CRB_HUB_AGT_ADR_OCM0,
 299         0,
 300         UNM_HW_CRB_HUB_AGT_ADR_SMB,
 301         UNM_HW_CRB_HUB_AGT_ADR_I2C0,
 302         UNM_HW_CRB_HUB_AGT_ADR_I2C1,
 303         0,
 304         UNM_HW_CRB_HUB_AGT_ADR_PGNC,
 305         0,
 306 };
 307 
 308 #define CRB_WIN_LOCK_TIMEOUT 100000000
 309 
 310 static void
 311 crb_win_lock(struct unm_adapter_s *adapter)
 312 {
 313         int i;
 314         int done = 0, timeout = 0;
 315 
 316         while (!done) {
 317                 /* acquire semaphore3 from PCI HW block */
 318                 adapter->unm_nic_hw_read_wx(adapter,
 319                     UNM_PCIE_REG(PCIE_SEM7_LOCK), &done, 4);
 320                 if (done == 1)
 321                         break;
 322                 if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
 323                         cmn_err(CE_WARN, "%s%d: crb_win_lock timed out\n",
 324                             adapter->name, adapter->instance);
 325                         return;
 326                 }
 327                 timeout++;
 328                 /*
 329                  *  Yield CPU
 330                  */
 331                 for (i = 0; i < 20; i++)
 332                         ;
 333         }
 334         adapter->unm_crb_writelit_adapter(adapter, UNM_CRB_WIN_LOCK_ID,
 335             adapter->portnum);
 336 }
 337 
 338 static void
 339 crb_win_unlock(struct unm_adapter_s *adapter)
 340 {
 341         int     val;
 342 
 343         adapter->unm_nic_hw_read_wx(adapter, UNM_PCIE_REG(PCIE_SEM7_UNLOCK),
 344             &val, 4);
 345 }
 346 
 347 /*
 348  * Changes the CRB window to the specified window.
 349  */
 350 void
 351 unm_nic_pci_change_crbwindow_128M(unm_adapter *adapter, uint32_t wndw)
 352 {
 353         unm_pcix_crb_window_t   window;
 354         unsigned long                   offset;
 355         uint32_t                                tmp;
 356 
 357         if (adapter->curr_window == wndw) {
 358                 return;
 359         }
 360 
 361         /*
 362          * Move the CRB window.
 363          * We need to write to the "direct access" region of PCI
 364          * to avoid a race condition where the window register has
 365          * not been successfully written across CRB before the target
 366          * register address is received by PCI. The direct region bypasses
 367          * the CRB bus.
 368          */
 369         offset = PCI_OFFSET_SECOND_RANGE(adapter,
 370             UNM_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(adapter->ahw.pci_func)));
 371 
 372         *(unm_crbword_t *)&window = 0;
 373         window.addrbit = wndw;
 374         UNM_NIC_PCI_WRITE_32(*(unsigned int *)&window, (void*) (offset));
 375         /* MUST make sure window is set before we forge on... */
 376         while ((tmp = UNM_NIC_PCI_READ_32((void*) offset)) !=
 377             *(uint32_t *)&window) {
 378                 cmn_err(CE_WARN, "%s: %s WARNING: CRB window value not "
 379                     "registered properly: 0x%08x.\n",
 380                     unm_nic_driver_name, __FUNCTION__, tmp);
 381         }
 382 
 383         adapter->curr_window = wndw;
 384 }
 385 
 386 
 387 /*
 388  * Changes the CRB window to the specified window.
 389  */
 390 /* ARGSUSED */
 391 void
 392 unm_nic_pci_change_crbwindow_2M(unm_adapter *adapter, uint32_t wndw)
 393 {
 394 }
 395 
 396 
 397 uint32_t
 398 unm_nic_get_crbwindow(unm_adapter *adapter)
 399 {
 400         return (adapter->curr_window);
 401 }
 402 
 403 /*
 404  * Return -1 if off is not valid,
 405  *       1 if window access is needed. 'off' is set to offset from
 406  *         CRB space in 128M pci map
 407  *       0 if no window access is needed. 'off' is set to 2M addr
 408  * In: 'off' is offset from base in 128M pci map
 409  */
 410 int
 411 unm_nic_pci_get_crb_addr_2M(unm_adapter *adapter, u64 *off, int len)
 412 {
 413         unsigned long end = *off + len;
 414         crb_128M_2M_sub_block_map_t *m;
 415 
 416 
 417         if (*off >= UNM_CRB_MAX)
 418                 return (-1);
 419 
 420         if (*off >= UNM_PCI_CAMQM && (end <= UNM_PCI_CAMQM_2M_END)) {
 421                 *off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
 422                     adapter->ahw.pci_base0;
 423                 return (0);
 424         }
 425 
 426         if (*off < UNM_PCI_CRBSPACE)
 427                 return (-1);
 428 
 429         *off -= UNM_PCI_CRBSPACE;
 430         end = *off + len;
 431         /*
 432          * Try direct map
 433          */
 434 
 435         m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
 436 
 437         if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) {
 438                 *off = *off + m->start_2M - m->start_128M +
 439                     adapter->ahw.pci_base0;
 440                 return (0);
 441         }
 442 
 443         /*
 444          * Not in direct map, use crb window
 445          */
 446         return (1);
 447 }
 448 /*
 449  * In: 'off' is offset from CRB space in 128M pci map
 450  * Out: 'off' is 2M pci map addr
 451  * side effect: lock crb window
 452  */
 453 static void
 454 unm_nic_pci_set_crbwindow_2M(unm_adapter *adapter, u64 *off)
 455 {
 456         u32 win_read;
 457 
 458         adapter->crb_win = CRB_HI(*off);
 459         UNM_NIC_PCI_WRITE_32(adapter->crb_win, (void *) (CRB_WINDOW_2M +
 460             adapter->ahw.pci_base0));
 461         /*
 462          * Read back value to make sure write has gone through before trying
 463          * to use it.
 464          */
 465         win_read = UNM_NIC_PCI_READ_32((void *)
 466             (CRB_WINDOW_2M + adapter->ahw.pci_base0));
 467         if (win_read != adapter->crb_win) {
 468                 cmn_err(CE_WARN, "%s: Written crbwin (0x%x) != Read crbwin "
 469                     "(0x%x), off=0x%llx\n", __FUNCTION__, adapter->crb_win,
 470                     win_read, *off);
 471         }
 472         *off = (*off & MASK(16)) + CRB_INDIRECT_2M +
 473             adapter->ahw.pci_base0;
 474 }
 475 
 476 int
 477 unm_nic_hw_write_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
 478 {
 479         void            *addr;
 480         u64             offset = off;
 481 
 482         if (ADDR_IN_WINDOW1(off)) { // Window 1
 483                 addr = CRB_NORMALIZE(adapter, off);
 484                 if (!addr) {
 485                         offset = CRB_NORMAL(off);
 486                         if (adapter->ahw.pci_len0 == 0)
 487                                 offset -= UNM_PCI_CRBSPACE;
 488                         addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
 489                             offset);
 490                 }
 491                 UNM_READ_LOCK(&adapter->adapter_lock);
 492         } else {// Window 0
 493                 addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
 494                 if (!addr) {
 495                         offset = off;
 496                         addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
 497                             offset);
 498                 }
 499                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
 500                 unm_nic_pci_change_crbwindow_128M(adapter, 0);
 501         }
 502 
 503         switch (len) {
 504                 case 1:
 505                         UNM_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
 506                         break;
 507                 case 2:
 508                         UNM_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
 509                         break;
 510                 case 4:
 511                         UNM_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
 512                         break;
 513                 case 8:
 514                         UNM_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
 515                         break;
 516                 default:
 517 #if !defined(NDEBUG)
 518                 if ((len & 0x7) != 0)
 519                         cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
 520                             unm_nic_driver_name, __FUNCTION__, len);
 521 #endif
 522                 UNM_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
 523                 break;
 524         }
 525         if (ADDR_IN_WINDOW1(off)) {// Window 1
 526                 UNM_READ_UNLOCK(&adapter->adapter_lock);
 527         } else {// Window 0
 528                 unm_nic_pci_change_crbwindow_128M(adapter, 1);
 529                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 530         }
 531 
 532         return (0);
 533 }
 534 
 535 /*
 536  * Note : 'len' argument should be either 1, 2, 4, or a multiple of 8.
 537  */
 538 int
 539 unm_nic_hw_write_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
 540 {
 541         /*
 542          * This is modified from _unm_nic_hw_write().
 543          * unm_nic_hw_write does not exist now.
 544          */
 545 
 546         void *addr;
 547 
 548         if (ADDR_IN_WINDOW1(off)) {// Window 1
 549                 addr = CRB_NORMALIZE(adapter, off);
 550                 UNM_READ_LOCK(&adapter->adapter_lock);
 551         } else {// Window 0
 552                 addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
 553                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
 554                 unm_nic_pci_change_crbwindow_128M(adapter, 0);
 555         }
 556 
 557 
 558         if (!addr) {
 559                 if (ADDR_IN_WINDOW1(off)) {// Window 1
 560                         UNM_READ_UNLOCK(&adapter->adapter_lock);
 561                 } else {// Window 0
 562                         unm_nic_pci_change_crbwindow_128M(adapter, 1);
 563                         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 564                 }
 565                 return (1);
 566         }
 567 
 568         switch (len) {
 569                 case 1:
 570                         UNM_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
 571                         break;
 572                 case 2:
 573                         UNM_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
 574                         break;
 575                 case 4:
 576                         UNM_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
 577                         break;
 578                 case 8:
 579                         UNM_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
 580                         break;
 581                 default:
 582 #if !defined(NDEBUG)
 583                         if ((len & 0x7) != 0)
 584                                 cmn_err(CE_WARN,
 585                                     "%s: %s  len(%d) not multiple of 8.\n",
 586                                     unm_nic_driver_name, __FUNCTION__, len);
 587 #endif
 588                         UNM_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
 589                         break;
 590         }
 591         if (ADDR_IN_WINDOW1(off)) {// Window 1
 592                 UNM_READ_UNLOCK(&adapter->adapter_lock);
 593         } else {// Window 0
 594                 unm_nic_pci_change_crbwindow_128M(adapter, 1);
 595                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 596         }
 597 
 598         return (0);
 599 }
 600 
 601 /*
 602  * Note : only 32-bit writes!
 603  */
 604 void
 605 unm_nic_pci_write_normalize_128M(unm_adapter *adapter, u64 off, u32 data)
 606 {
 607         UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
 608 }
 609 
 610 /*
 611  * Note : only 32-bit reads!
 612  */
 613 u32
 614 unm_nic_pci_read_normalize_128M(unm_adapter *adapter, u64 off)
 615 {
 616         return (UNM_NIC_PCI_READ_32(CRB_NORMALIZE(adapter, off)));
 617 }
 618 
 619 /*
 620  * Note : only 32-bit writes!
 621  */
 622 int
 623 unm_nic_pci_write_immediate_128M(unm_adapter *adapter, u64 off, u32 *data)
 624 {
 625         UNM_NIC_PCI_WRITE_32(*data,
 626             (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
 627         return (0);
 628 }
 629 
 630 /*
 631  * Note : only 32-bit reads!
 632  */
 633 int
 634 unm_nic_pci_read_immediate_128M(unm_adapter *adapter, u64 off, u32 *data)
 635 {
 636         *data = UNM_NIC_PCI_READ_32((void *)
 637             (uptr_t)(pci_base_offset(adapter, off)));
 638         return (0);
 639 }
 640 
 641 /*
 642  * Note : only 32-bit writes!
 643  */
 644 void
 645 unm_nic_pci_write_normalize_2M(unm_adapter *adapter, u64 off, u32 data)
 646 {
 647         u32 temp = data;
 648 
 649         adapter->unm_nic_hw_write_wx(adapter, off, &temp, 4);
 650 }
 651 
 652 /*
 653  * Note : only 32-bit reads!
 654  */
 655 u32
 656 unm_nic_pci_read_normalize_2M(unm_adapter *adapter, u64 off)
 657 {
 658         u32 temp;
 659 
 660         adapter->unm_nic_hw_read_wx(adapter, off, &temp, 4);
 661 
 662         return (temp);
 663 }
 664 
 665 /*
 666  * Note : only 32-bit writes!
 667  */
 668 int
 669 unm_nic_pci_write_immediate_2M(unm_adapter *adapter, u64 off, u32 *data)
 670 {
 671         u32 temp = *data;
 672 
 673         adapter->unm_nic_hw_write_wx(adapter, off, &temp, 4);
 674 
 675         return (0);
 676 }
 677 
 678 /*
 679  * Note : only 32-bit reads!
 680  */
 681 int
 682 unm_nic_pci_read_immediate_2M(unm_adapter *adapter, u64 off, u32 *data)
 683 {
 684         u32 temp;
 685 
 686         adapter->unm_nic_hw_read_wx(adapter, off, &temp, 4);
 687 
 688         *data = temp;
 689 
 690         return (0);
 691 }
 692 
 693 /*
 694  * write cross hw window boundary is not supported
 695  * 'len' should be either 1, 2, 4, or multiple of 8
 696  */
 697 int
 698 unm_nic_hw_write_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
 699 {
 700         int rv;
 701 
 702         rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
 703 
 704         if (rv == -1) {
 705                 cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
 706                     __FUNCTION__, off);
 707         }
 708 
 709         if (rv == 1) {
 710                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
 711                 crb_win_lock(adapter);
 712                 unm_nic_pci_set_crbwindow_2M(adapter, &off);
 713         }
 714 
 715         switch (len) {
 716         case 1:
 717                 UNM_NIC_PCI_WRITE_8(*(__uint8_t *)data, (void *) (uptr_t)off);
 718                 break;
 719         case 2:
 720                 UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, (void *) (uptr_t)off);
 721                 break;
 722         case 4:
 723                 UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, (void *) (uptr_t)off);
 724                 break;
 725         case 8:
 726                 UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, (void *) (uptr_t)off);
 727                 break;
 728         default:
 729 #if !defined(NDEBUG)
 730                 if ((len & 0x7) != 0)
 731                         cmn_err(CE_WARN, "%s: %s  len(%d) not multiple of 8.\n",
 732                             unm_nic_driver_name, __FUNCTION__, len);
 733 #endif
 734                 UNM_NIC_HW_BLOCK_WRITE_64(data, (uptr_t)off, (len>>3));
 735                 break;
 736         }
 737         if (rv == 1) {
 738                 crb_win_unlock(adapter);
 739                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 740         }
 741 
 742         return (0);
 743 }
 744 
 745 int
 746 unm_nic_hw_read_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
 747 {
 748         void            *addr;
 749         u64             offset;
 750 
 751         if (ADDR_IN_WINDOW1(off)) {// Window 1
 752                 addr = CRB_NORMALIZE(adapter, off);
 753                 if (!addr) {
 754                         offset = CRB_NORMAL(off);
 755                         if (adapter->ahw.pci_len0 == 0)
 756                                 offset -= UNM_PCI_CRBSPACE;
 757                         addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
 758                             offset);
 759                 }
 760                 UNM_READ_LOCK(&adapter->adapter_lock);
 761         } else {// Window 0
 762                 addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
 763                 if (!addr) {
 764                         offset = off;
 765                         addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
 766                             offset);
 767                 }
 768                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
 769                 unm_nic_pci_change_crbwindow_128M(adapter, 0);
 770         }
 771 
 772         switch (len) {
 773         case 1:
 774                 *(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
 775                 break;
 776         case 2:
 777                 *(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
 778                 break;
 779         case 4:
 780                 *(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
 781                 break;
 782         case 8:
 783                 *(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
 784                 break;
 785         default:
 786 #if !defined(NDEBUG)
 787                 if ((len & 0x7) != 0)
 788                         cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
 789                             unm_nic_driver_name, __FUNCTION__, len);
 790 #endif
 791                 UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
 792                 break;
 793         }
 794 
 795         if (ADDR_IN_WINDOW1(off)) {// Window 1
 796                 UNM_READ_UNLOCK(&adapter->adapter_lock);
 797         } else {// Window 0
 798                 unm_nic_pci_change_crbwindow_128M(adapter, 1);
 799                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 800         }
 801 
 802         return (0);
 803 }
 804 
 805 int
 806 unm_nic_hw_read_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
 807 {
 808         int rv;
 809 
 810         rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
 811 
 812         if (rv == -1) {
 813                 cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
 814                     __FUNCTION__, off);
 815         }
 816 
 817         if (rv == 1) {
 818                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
 819                 crb_win_lock(adapter);
 820                 unm_nic_pci_set_crbwindow_2M(adapter, &off);
 821         }
 822 
 823         switch (len) {
 824         case 1:
 825                 *(__uint8_t  *)data = UNM_NIC_PCI_READ_8((void *) (uptr_t)off);
 826                 break;
 827         case 2:
 828                 *(__uint16_t *)data = UNM_NIC_PCI_READ_16((void *) (uptr_t)off);
 829                 break;
 830         case 4:
 831                 *(__uint32_t *)data = UNM_NIC_PCI_READ_32((void *) (uptr_t)off);
 832                 break;
 833         case 8:
 834                 *(__uint64_t *)data = UNM_NIC_PCI_READ_64((void *) (uptr_t)off);
 835                 break;
 836         default:
 837 #if !defined(NDEBUG)
 838                 if ((len & 0x7) != 0)
 839                         cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
 840                             unm_nic_driver_name, __FUNCTION__, len);
 841 #endif
 842                 UNM_NIC_HW_BLOCK_READ_64(data, (void *) (uptr_t)off, (len>>3));
 843                 break;
 844         }
 845 
 846         if (rv == 1) {
 847                 crb_win_unlock(adapter);
 848                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 849         }
 850 
 851         return (0);
 852 }
 853 
 854 int
 855 unm_nic_hw_read_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
 856 {
 857         void *addr;
 858 
 859         if (ADDR_IN_WINDOW1(off)) {
 860                 // Window 1
 861                 addr = CRB_NORMALIZE(adapter, off);
 862                 UNM_READ_LOCK(&adapter->adapter_lock);
 863         } else {// Window 0
 864                 addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
 865                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
 866                 unm_nic_pci_change_crbwindow_128M(adapter, 0);
 867         }
 868 
 869         if (!addr) {
 870                 if (ADDR_IN_WINDOW1(off)) {// Window 1
 871                         UNM_READ_UNLOCK(&adapter->adapter_lock);
 872                 } else {// Window 0
 873                         unm_nic_pci_change_crbwindow_128M(adapter, 1);
 874                         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 875                 }
 876                 return (1);
 877         }
 878 
 879         switch (len) {
 880                 case 1:
 881                         *(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
 882                         break;
 883                 case 2:
 884                         *(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
 885                         break;
 886                 case 4:
 887                         *(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
 888                         break;
 889                 case 8:
 890                         *(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
 891                         break;
 892                 default:
 893 #if !defined(NDEBUG)
 894                         if ((len & 0x7) != 0)
 895                                 cmn_err(CE_WARN,
 896                                     "%s: %s len(%d) not multiple of 8.\n",
 897                                     unm_nic_driver_name, __FUNCTION__, len);
 898 #endif
 899                         UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
 900                         break;
 901         }
 902 
 903         if (ADDR_IN_WINDOW1(off)) {// Window 1
 904                 UNM_READ_UNLOCK(&adapter->adapter_lock);
 905         } else {// Window 0
 906                 unm_nic_pci_change_crbwindow_128M(adapter, 1);
 907                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 908         }
 909 
 910         return (0);
 911 }
 912 
 913 /*  PCI Windowing for DDR regions.  */
 914 #define ADDR_IN_RANGE(addr, low, high)      \
 915         (((addr) <= (high)) && ((low) ? ((addr) >= (low)) : 1))
 916 
 917 /*
 918  * check memory access boundary.
 919  * used by test agent. support ddr access only for now
 920  */
 921 /* ARGSUSED */
 922 static unsigned long
 923 unm_nic_pci_mem_bound_check(struct unm_adapter_s *adapter,
 924     unsigned long long addr, int size)
 925 {
 926         if (!ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX) ||
 927             !ADDR_IN_RANGE(addr + size -1, UNM_ADDR_DDR_NET,
 928             UNM_ADDR_DDR_NET_MAX) || ((size != 1) && (size != 2) &&
 929             (size != 4) && (size != 8)))
 930                 return (0);
 931 
 932         return (1);
 933 }
 934 
 935 int unm_pci_set_window_warning_count = 0;
 936 
 937 unsigned long long
 938 unm_nic_pci_set_window_128M(struct unm_adapter_s *adapter,
 939     unsigned long long addr)
 940 {
 941         int             window;
 942         unsigned long long      qdr_max;
 943 
 944         if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 945                 qdr_max = NX_P2_ADDR_QDR_NET_MAX;
 946         } else {
 947                 qdr_max = NX_P3_ADDR_QDR_NET_MAX;
 948         }
 949 
 950         if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
 951                 /* DDR network side */
 952                 /* MN access should never come here */
 953                 cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
 954         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
 955                 addr -= UNM_ADDR_OCM0;
 956                 addr += UNM_PCI_OCM0;
 957         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
 958                 addr -= UNM_ADDR_OCM1;
 959                 addr += UNM_PCI_OCM1;
 960         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
 961                 /* QDR network side */
 962                 addr -= UNM_ADDR_QDR_NET;
 963                 window = (addr >> 22) & 0x3f;
 964                 if (adapter->ahw.qdr_sn_window != window) {
 965                         adapter->ahw.qdr_sn_window = window;
 966                         UNM_NIC_PCI_WRITE_32((window << 22),
 967                             (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
 968                             UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
 969                             adapter->ahw.pci_func)))));
 970                         /* MUST make sure window is set before we forge on... */
 971                         (void) UNM_NIC_PCI_READ_32((void *)
 972                             (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
 973                             UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
 974                             adapter->ahw.pci_func)))));
 975                 }
 976                 addr -= (window * 0x400000);
 977                 addr += UNM_PCI_QDR_NET;
 978         } else {
 979                 /*
 980                  * peg gdb frequently accesses memory that doesn't exist,
 981                  * this limits the chit chat so debugging isn't slowed down.
 982                  */
 983                 if ((unm_pci_set_window_warning_count++ < 8) ||
 984                     (unm_pci_set_window_warning_count%64 == 0)) {
 985                         cmn_err(CE_WARN, "%s: Warning:unm_nic_pci_set_window() "
 986                             "Unknown address range!\n", unm_nic_driver_name);
 987                 }
 988                 addr = -1ULL;
 989         }
 990         return (addr);
 991 }
 992 
 993 unsigned long long
 994 unm_nic_pci_set_window_2M(struct unm_adapter_s *adapter,
 995     unsigned long long addr)
 996 {
 997         int window;
 998         u32 win_read;
 999 
1000         if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
1001                 /* DDR network side */
1002                 window = MN_WIN(addr);
1003                 adapter->ahw.ddr_mn_window = window;
1004                 adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
1005                     UNM_PCI_CRBSPACE, &window, 4);
1006                 adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
1007                     UNM_PCI_CRBSPACE, &win_read, 4);
1008                 if ((win_read << 17) != window) {
1009                         cmn_err(CE_WARN,
1010                             "%s: Written MNwin (0x%x) != Read MNwin (0x%x)\n",
1011                             __FUNCTION__, window, win_read);
1012                 }
1013                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
1014         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
1015                 unsigned int temp1;
1016 // OCM: pci_addr[20:18] == 011 && pci_addr[17:11] != 7f
1017                 if ((addr & 0x00ff800) == 0xff800) {
1018                         // if bits 19:18&17:11 are on
1019                         cmn_err(CE_WARN, "%s: QM access not handled.\n",
1020                             __FUNCTION__);
1021                         addr = -1ULL;
1022                 }
1023 
1024                 window = OCM_WIN(addr);
1025                 adapter->ahw.ddr_mn_window = window;
1026                 adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
1027                     UNM_PCI_CRBSPACE, &window, 4);
1028                 adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
1029                     UNM_PCI_CRBSPACE, &win_read, 4);
1030                 temp1 = ((window & 0x1FF) << 7) |
1031                     ((window & 0x0FFFE0000) >> 17);
1032                 if (win_read != temp1) {
1033                         cmn_err(CE_WARN,
1034                             "%s: Written OCMwin(0x%x) != Read OCMwin(0x%x)\n",
1035                             __FUNCTION__, temp1, win_read);
1036                 }
1037                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
1038 
1039         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
1040             NX_P3_ADDR_QDR_NET_MAX)) {
1041                 /* QDR network side */
1042                 window = MS_WIN(addr);
1043                 adapter->ahw.qdr_sn_window = window;
1044                 adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.ms_win_crb |
1045                     UNM_PCI_CRBSPACE, &window, 4);
1046                 adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.ms_win_crb |
1047                     UNM_PCI_CRBSPACE, &win_read, 4);
1048                 if (win_read != window) {
1049                         cmn_err(CE_WARN,
1050                             "%s: Written MSwin (0x%x) != Read MSwin (0x%x)\n",
1051                             __FUNCTION__, window, win_read);
1052                 }
1053                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
1054 
1055         } else {
1056                 /*
1057                  * peg gdb frequently accesses memory that doesn't exist,
1058                  * this limits the chit chat so debugging isn't slowed down.
1059                  */
1060                 if ((unm_pci_set_window_warning_count++ < 8) ||
1061                     (unm_pci_set_window_warning_count%64 == 0)) {
1062                         cmn_err(CE_WARN, "%s%d: %s Unknown address range!\n",
1063                             adapter->name, adapter->instance, __FUNCTION__);
1064                 }
1065                 addr = -1ULL;
1066         }
1067         return (addr);
1068 }
1069 
1070 /* check if address is in the same windows as the previous access */
1071 static unsigned long
1072 unm_nic_pci_is_same_window(struct unm_adapter_s *adapter,
1073     unsigned long long addr)
1074 {
1075         int                     window;
1076         unsigned long long      qdr_max;
1077 
1078         if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1079                 qdr_max = NX_P2_ADDR_QDR_NET_MAX;
1080         } else {
1081                 qdr_max = NX_P3_ADDR_QDR_NET_MAX;
1082         }
1083 
1084         if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
1085                 /* DDR network side */
1086                 /* MN access can not come here */
1087                 cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
1088 #if 0
1089                 window = ((addr - UNM_ADDR_DDR_NET) >> 25) & 0x3ff;
1090                 if (adapter->ahw.ddr_mn_window == window) {
1091                         return (1);
1092                 }
1093 #endif
1094         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
1095                 return (1);
1096         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
1097                 return (1);
1098         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
1099                 /* QDR network side */
1100                 window = ((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f;
1101                 if (adapter->ahw.qdr_sn_window == window) {
1102                         return (1);
1103                 }
1104         }
1105 
1106         return (0);
1107 }
1108 
1109 static int
1110 unm_nic_pci_mem_read_direct(struct unm_adapter_s *adapter,
1111     u64 off, void *data, int size)
1112 {
1113         void                    *addr;
1114         int                             ret = 0;
1115         u64                             start;
1116 
1117 #if 0
1118         /*
1119          * This check can not be currently executed, since phanmon findq
1120          * command breaks this check whereby 8 byte reads are being attempted
1121          * on "aligned-by-4" addresses on x86. Reason this works is our version
1122          * breaks up the access into 2 consecutive 4 byte writes; on other
1123          * architectures, this might require "aligned-by-8" addresses and we
1124          * will run into trouble.
1125          *
1126          * Check alignment for expected sizes of 1, 2, 4, 8. Other size
1127          * values will not trigger access.
1128          */
1129         if ((off & (size - 1)) != 0)
1130                 return (-1);
1131 #endif
1132 
1133         UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1134 
1135         /*
1136          * If attempting to access unknown address or straddle hw windows,
1137          * do not access.
1138          */
1139         if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
1140             (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
1141                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1142                 cmn_err(CE_WARN, "%s out of bound pci memory access. "
1143                     "offset is 0x%llx\n", unm_nic_driver_name, off);
1144                 return (-1);
1145         }
1146 
1147         addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
1148         if (!addr)
1149                 addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
1150 
1151         switch (size) {
1152                 case 1:
1153                         *(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
1154                         break;
1155                 case 2:
1156                         *(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
1157                         break;
1158                 case 4:
1159                         *(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
1160                         break;
1161                 case 8:
1162                         *(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
1163                         break;
1164                 default:
1165                         ret = -1;
1166                         break;
1167         }
1168 
1169         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1170         return (ret);
1171 }
1172 
1173 static int
1174 unm_nic_pci_mem_write_direct(struct unm_adapter_s *adapter, u64 off,
1175     void *data, int size)
1176 {
1177         void    *addr;
1178         int             ret = 0;
1179         u64             start;
1180 
1181 #if 0
1182         /*
1183          * This check can not be currently executed, since firmware load
1184          * breaks this check whereby 8 byte writes are being attempted on
1185          * "aligned-by-4" addresses on x86. Reason this works is our version
1186          * breaks up the access into 2 consecutive 4 byte writes; on other
1187          * architectures, this might require "aligned-by-8" addresses and we
1188          * will run into trouble.
1189          *
1190          * Check alignment for expected sizes of 1, 2, 4, 8. Other size
1191          * values will not trigger access.
1192          */
1193         if ((off & (size - 1)) != 0)
1194                 return (-1);
1195 #endif
1196 
1197         UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1198 
1199         /*
1200          * If attempting to access unknown address or straddle hw windows,
1201          * do not access.
1202          */
1203         if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
1204             (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
1205                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1206                 cmn_err(CE_WARN, "%s out of bound pci memory access. "
1207                     "offset is 0x%llx\n", unm_nic_driver_name, off);
1208                 return (-1);
1209         }
1210 
1211         addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
1212         if (!addr)
1213                 addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
1214 
1215         switch (size) {
1216                 case 1:
1217                         UNM_NIC_PCI_WRITE_8(*(__uint8_t  *)data, addr);
1218                         break;
1219                 case 2:
1220                         UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, addr);
1221                         break;
1222                 case 4:
1223                         UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, addr);
1224                         break;
1225                 case 8:
1226                         UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, addr);
1227                         break;
1228                 default:
1229                         ret = -1;
1230                         break;
1231         }
1232         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1233         return (ret);
1234 }
1235 
1236 
1237 int
1238 unm_nic_pci_mem_write_128M(struct unm_adapter_s *adapter, u64 off, void *data,
1239     int size)
1240 {
1241         int             i, j, ret = 0, loop, sz[2], off0;
1242         __uint32_t              temp;
1243         __uint64_t              off8, mem_crb, tmpw, word[2] = {0, 0};
1244 #define MAX_CTL_CHECK   1000
1245 
1246         /*
1247          * If not MN, go check for MS or invalid.
1248          */
1249         if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1250                 return (unm_nic_pci_mem_write_direct(adapter, off, data, size));
1251 
1252         off8 = off & 0xfffffff8;
1253         off0 = off & 0x7;
1254         sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1255         sz[1] = size - sz[0];
1256         loop = ((off0 + size - 1) >> 3) + 1;
1257         /* LINTED: E_FALSE_LOGICAL_EXPR */
1258         mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
1259 
1260         if ((size != 8) || (off0 != 0))  {
1261                 for (i = 0; i < loop; i++) {
1262                         if (adapter->unm_nic_pci_mem_read(adapter,
1263                             off8 + (i << 3), &word[i], 8))
1264                                 return (-1);
1265                 }
1266         }
1267 
1268         switch (size) {
1269                 case 1:
1270                         tmpw = *((__uint8_t *)data);
1271                         break;
1272                 case 2:
1273                         tmpw = *((__uint16_t *)data);
1274                         break;
1275                 case 4:
1276                         tmpw = *((__uint32_t *)data);
1277                         break;
1278                 case 8:
1279                 default:
1280                         tmpw = *((__uint64_t *)data);
1281                         break;
1282         }
1283         word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1284         word[0] |= tmpw << (off0 * 8);
1285 
1286         if (loop == 2) {
1287                 word[1] &= ~(~0ULL << (sz[1] * 8));
1288                 word[1] |= tmpw >> (sz[0] * 8);
1289         }
1290 
1291         UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1292         unm_nic_pci_change_crbwindow_128M(adapter, 0);
1293 
1294         for (i = 0; i < loop; i++) {
1295                 UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
1296                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
1297                 UNM_NIC_PCI_WRITE_32(0,
1298                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
1299                 UNM_NIC_PCI_WRITE_32(word[i] & 0xffffffff,
1300                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_LO));
1301                 UNM_NIC_PCI_WRITE_32((word[i] >> 32) & 0xffffffff,
1302                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_HI));
1303                 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
1304                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1305                 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE |
1306                     MIU_TA_CTL_WRITE,
1307                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1308 
1309                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1310                         temp = UNM_NIC_PCI_READ_32((void *)
1311                             (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1312                         if ((temp & MIU_TA_CTL_BUSY) == 0) {
1313                                 break;
1314                         }
1315                 }
1316 
1317                 if (j >= MAX_CTL_CHECK) {
1318                         cmn_err(CE_WARN, "%s: %s Fail to write thru agent\n",
1319                             __FUNCTION__, unm_nic_driver_name);
1320                         ret = -1;
1321                         break;
1322                 }
1323         }
1324 
1325         unm_nic_pci_change_crbwindow_128M(adapter, 1);
1326         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1327         return (ret);
1328 }
1329 
1330 int
1331 unm_nic_pci_mem_read_128M(struct unm_adapter_s *adapter, u64 off, void *data,
1332     int size)
1333 {
1334         int             i, j = 0, k, start, end, loop, sz[2], off0[2];
1335         __uint32_t              temp;
1336         __uint64_t              off8, val, mem_crb, word[2] = {0, 0};
1337 #define MAX_CTL_CHECK   1000
1338 
1339         /*
1340          * If not MN, go check for MS or invalid.
1341          */
1342         if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1343                 return (unm_nic_pci_mem_read_direct(adapter, off, data, size));
1344 
1345         off8 = off & 0xfffffff8;
1346         off0[0] = off & 0x7;
1347         off0[1] = 0;
1348         sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1349         sz[1] = size - sz[0];
1350         loop = ((off0[0] + size - 1) >> 3) + 1;
1351         /* LINTED: E_FALSE_LOGICAL_EXPR */
1352         mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
1353 
1354         UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1355         unm_nic_pci_change_crbwindow_128M(adapter, 0);
1356 
1357         for (i = 0; i < loop; i++) {
1358                 UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
1359                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
1360                 UNM_NIC_PCI_WRITE_32(0,
1361                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
1362                 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE,
1363                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1364                 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
1365                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1366 
1367                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1368                         temp = UNM_NIC_PCI_READ_32((void *)
1369                             (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1370                         if ((temp & MIU_TA_CTL_BUSY) == 0) {
1371                                 break;
1372                         }
1373                 }
1374 
1375                 if (j >= MAX_CTL_CHECK) {
1376                         cmn_err(CE_WARN, "%s: %s Fail to read through agent\n",
1377                             __FUNCTION__, unm_nic_driver_name);
1378                         break;
1379                 }
1380 
1381                 start = off0[i] >> 2;
1382                 end   = (off0[i] + sz[i] - 1) >> 2;
1383                 word[i] = 0;
1384                 for (k = start; k <= end; k++) {
1385                         word[i] |= ((__uint64_t)UNM_NIC_PCI_READ_32(
1386                             (void *) (uptr_t)(mem_crb +
1387                             MIU_TEST_AGT_RDDATA(k))) << (32*k));
1388                 }
1389         }
1390 
1391         unm_nic_pci_change_crbwindow_128M(adapter, 1);
1392         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1393 
1394         if (j >= MAX_CTL_CHECK)
1395                 return (-1);
1396 
1397         if (sz[0] == 8) {
1398                 val = word[0];
1399         } else {
1400                 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1401                     ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1402         }
1403 
1404         switch (size) {
1405         case 1:
1406                 *(__uint8_t  *)data = val;
1407                 break;
1408         case 2:
1409                 *(__uint16_t *)data = val;
1410                 break;
1411         case 4:
1412                 *(__uint32_t *)data = val;
1413                 break;
1414         case 8:
1415                 *(__uint64_t *)data = val;
1416                 break;
1417         }
1418         return (0);
1419 }
1420 
1421 
1422 
1423 int
1424 unm_nic_pci_mem_write_2M(struct unm_adapter_s *adapter, u64 off, void *data,
1425     int size)
1426 {
1427         int     i, j, ret = 0, loop, sz[2], off0;
1428         __uint32_t      temp;
1429         __uint64_t      off8, mem_crb, tmpw, word[2] = {0, 0};
1430 #define MAX_CTL_CHECK   1000
1431 
1432         /*
1433          * If not MN, go check for MS or invalid.
1434          */
1435         if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
1436                 mem_crb = UNM_CRB_QDR_NET;
1437         } else {
1438                 mem_crb = UNM_CRB_DDR_NET;
1439                 if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1440                         return (unm_nic_pci_mem_write_direct(adapter,
1441                             off, data, size));
1442         }
1443 
1444         off8 = off & 0xfffffff8;
1445         off0 = off & 0x7;
1446         sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1447         sz[1] = size - sz[0];
1448         loop = ((off0 + size - 1) >> 3) + 1;
1449 
1450         if ((size != 8) || (off0 != 0)) {
1451                 for (i = 0; i < loop; i++) {
1452                         if (adapter->unm_nic_pci_mem_read(adapter,
1453                             off8 + (i << 3), &word[i], 8))
1454                                 return (-1);
1455                 }
1456         }
1457 
1458         switch (size) {
1459                 case 1:
1460                         tmpw = *((__uint8_t *)data);
1461                         break;
1462                 case 2:
1463                         tmpw = *((__uint16_t *)data);
1464                         break;
1465                 case 4:
1466                         tmpw = *((__uint32_t *)data);
1467                         break;
1468                 case 8:
1469                 default:
1470                         tmpw = *((__uint64_t *)data);
1471                         break;
1472         }
1473 
1474         word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1475         word[0] |= tmpw << (off0 * 8);
1476 
1477         if (loop == 2) {
1478                 word[1] &= ~(~0ULL << (sz[1] * 8));
1479                 word[1] |= tmpw >> (sz[0] * 8);
1480         }
1481 
1482 // don't lock here - write_wx gets the lock if each time
1483 // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1484 // unm_nic_pci_change_crbwindow_128M(adapter, 0);
1485 
1486         for (i = 0; i < loop; i++) {
1487                 temp = off8 + (i << 3);
1488                 adapter->unm_nic_hw_write_wx(adapter,
1489                     mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
1490                 temp = 0;
1491                 adapter->unm_nic_hw_write_wx(adapter,
1492                     mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
1493                 temp = word[i] & 0xffffffff;
1494                 adapter->unm_nic_hw_write_wx(adapter,
1495                     mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
1496                 temp = (word[i] >> 32) & 0xffffffff;
1497                 adapter->unm_nic_hw_write_wx(adapter,
1498                     mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
1499                 temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
1500                 adapter->unm_nic_hw_write_wx(adapter,
1501                     mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
1502                 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
1503                 adapter->unm_nic_hw_write_wx(adapter,
1504                     mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
1505 
1506                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1507                         adapter->unm_nic_hw_read_wx(adapter,
1508                             mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1509                         if ((temp & MIU_TA_CTL_BUSY) == 0) {
1510                                 break;
1511                         }
1512                 }
1513 
1514                 if (j >= MAX_CTL_CHECK) {
1515                         cmn_err(CE_WARN, "%s: Fail to write through agent\n",
1516                             unm_nic_driver_name);
1517                         ret = -1;
1518                         break;
1519                 }
1520         }
1521 
1522 //  unm_nic_pci_change_crbwindow_128M(adapter, 1);
1523 //  UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1524         return (ret);
1525 }
1526 
1527 int
1528 unm_nic_pci_mem_read_2M(struct unm_adapter_s *adapter, u64 off, void *data,
1529     int size)
1530 {
1531 // unsigned long   flags;
1532         int             i, j = 0, k, start, end, loop, sz[2], off0[2];
1533         __uint32_t      temp;
1534         __uint64_t      off8, val, mem_crb, word[2] = {0, 0};
1535 #define MAX_CTL_CHECK   1000
1536 
1537         /*
1538          * If not MN, go check for MS or invalid.
1539          */
1540 
1541         if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
1542                 mem_crb = UNM_CRB_QDR_NET;
1543         } else {
1544                 mem_crb = UNM_CRB_DDR_NET;
1545                 if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1546                         return (unm_nic_pci_mem_read_direct(adapter,
1547                             off, data, size));
1548         }
1549 
1550         off8 = off & 0xfffffff8;
1551         off0[0] = off & 0x7;
1552         off0[1] = 0;
1553         sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1554         sz[1] = size - sz[0];
1555         loop = ((off0[0] + size - 1) >> 3) + 1;
1556 
1557 // don't get lock - write_wx will get it
1558 // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1559 // unm_nic_pci_change_crbwindow_128M(adapter, 0);
1560 
1561         for (i = 0; i < loop; i++) {
1562                 temp = off8 + (i << 3);
1563                 adapter->unm_nic_hw_write_wx(adapter,
1564                     mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
1565                 temp = 0;
1566                 adapter->unm_nic_hw_write_wx(adapter,
1567                     mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
1568                 temp = MIU_TA_CTL_ENABLE;
1569                 adapter->unm_nic_hw_write_wx(adapter,
1570                     mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1571                 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
1572                 adapter->unm_nic_hw_write_wx(adapter,
1573                     mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1574 
1575                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1576                         adapter->unm_nic_hw_read_wx(adapter,
1577                             mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1578                         if ((temp & MIU_TA_CTL_BUSY) == 0) {
1579                                 break;
1580                         }
1581                 }
1582 
1583                 if (j >= MAX_CTL_CHECK) {
1584                         cmn_err(CE_WARN, "%s: Fail to read through agent\n",
1585                             unm_nic_driver_name);
1586                         break;
1587                 }
1588 
1589                 start = off0[i] >> 2;
1590                 end   = (off0[i] + sz[i] - 1) >> 2;
1591                 for (k = start; k <= end; k++) {
1592                         adapter->unm_nic_hw_read_wx(adapter,
1593                             mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
1594                         word[i] |= ((__uint64_t)temp << (32 * k));
1595                 }
1596         }
1597 
1598 // unm_nic_pci_change_crbwindow_128M(adapter, 1);
1599 // UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1600 
1601         if (j >= MAX_CTL_CHECK)
1602                 return (-1);
1603 
1604         if (sz[0] == 8) {
1605                 val = word[0];
1606         } else {
1607                 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1608                     ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1609         }
1610 
1611         switch (size) {
1612                 case 1:
1613                         *(__uint8_t  *)data = val;
1614                         break;
1615                 case 2:
1616                         *(__uint16_t *)data = val;
1617                         break;
1618                 case 4:
1619                         *(__uint32_t *)data = val;
1620                         break;
1621                 case 8:
1622                         *(__uint64_t *)data = val;
1623                         break;
1624         }
1625         return (0);
1626 }
1627 
1628 int
1629 unm_crb_writelit_adapter_2M(struct unm_adapter_s *adapter, unsigned long off,
1630     int data)
1631 {
1632         return (unm_nic_hw_write_wx_2M(adapter, off, &data, 4));
1633 }
1634 
1635 int
1636 unm_crb_writelit_adapter_128M(struct unm_adapter_s *adapter, unsigned long off,
1637     int data)
1638 {
1639         void *addr;
1640 
1641         if (ADDR_IN_WINDOW1(off)) {
1642                 UNM_READ_LOCK(&adapter->adapter_lock);
1643                 UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
1644                 UNM_READ_UNLOCK(&adapter->adapter_lock);
1645         } else {
1646                 // unm_nic_write_w0 (adapter, off, data);
1647                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1648                 unm_nic_pci_change_crbwindow_128M(adapter, 0);
1649                 addr = (void *) (pci_base_offset(adapter, off));
1650                 UNM_NIC_PCI_WRITE_32(data, addr);
1651                 unm_nic_pci_change_crbwindow_128M(adapter, 1);
1652                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1653         }
1654 
1655         return (0);
1656 }
1657 
1658 int
1659 unm_nic_get_board_info(struct unm_adapter_s *adapter)
1660 {
1661         int     rv = 0;
1662         unm_board_info_t  *boardinfo;
1663         int             i;
1664         int             addr = BRDCFG_START;
1665         uint32_t          *ptr32;
1666         uint32_t        gpioval;
1667 
1668         boardinfo = &adapter->ahw.boardcfg;
1669         ptr32 = (uint32_t *)boardinfo;
1670 
1671         for (i = 0; i < sizeof (unm_board_info_t) / sizeof (uint32_t); i++) {
1672                 if (rom_fast_read(adapter, addr, (int *)ptr32) == -1) {
1673                         return (-1);
1674                 }
1675                 DPRINTF(1, (CE_WARN, "ROM(%d): %x\n", i, *ptr32));
1676                 ptr32++;
1677                 addr += sizeof (uint32_t);
1678         }
1679 
1680         if (boardinfo->magic != UNM_BDINFO_MAGIC) {
1681                 DPRINTF(1, (CE_WARN, "%s: ERROR reading board config."
1682                     " Read %x, expected %x\n", unm_nic_driver_name,
1683                     boardinfo->magic, UNM_BDINFO_MAGIC));
1684                 rv = -1;
1685         }
1686 
1687         if (boardinfo->header_version != UNM_BDINFO_VERSION) {
1688                 DPRINTF(1, (CE_WARN, "%s: Unknown board config version."
1689                     " Read %x, expected %x\n", unm_nic_driver_name,
1690                     boardinfo->header_version, UNM_BDINFO_VERSION));
1691                 rv = -1;
1692         }
1693 
1694         if (boardinfo->board_type == UNM_BRDTYPE_P3_4_GB_MM) {
1695                 gpioval = UNM_CRB_READ_VAL_ADAPTER(UNM_ROMUSB_GLB_PAD_GPIO_I,
1696                     adapter);
1697                 if ((gpioval & 0x8000) == 0)
1698                         boardinfo->board_type = UNM_BRDTYPE_P3_10G_TRP;
1699         }
1700 
1701         DPRINTF(0, (CE_WARN, "Discovered board type:0x%x  ",
1702             boardinfo->board_type));
1703 
1704         switch ((unm_brdtype_t)boardinfo->board_type) {
1705         case UNM_BRDTYPE_P2_SB35_4G:
1706                 adapter->ahw.board_type = UNM_NIC_GBE;
1707                 break;
1708         case UNM_BRDTYPE_P2_SB31_10G:
1709         case UNM_BRDTYPE_P2_SB31_10G_IMEZ:
1710         case UNM_BRDTYPE_P2_SB31_10G_HMEZ:
1711         case UNM_BRDTYPE_P2_SB31_10G_CX4:
1712         case UNM_BRDTYPE_P3_HMEZ:
1713         case UNM_BRDTYPE_P3_XG_LOM:
1714         case UNM_BRDTYPE_P3_10G_CX4:
1715         case UNM_BRDTYPE_P3_10G_CX4_LP:
1716         case UNM_BRDTYPE_P3_IMEZ:
1717         case UNM_BRDTYPE_P3_10G_SFP_PLUS:
1718         case UNM_BRDTYPE_P3_10G_XFP:
1719         case UNM_BRDTYPE_P3_10000_BASE_T:
1720                 adapter->ahw.board_type = UNM_NIC_XGBE;
1721                 break;
1722         case UNM_BRDTYPE_P3_REF_QG:
1723         case UNM_BRDTYPE_P3_4_GB:
1724         case UNM_BRDTYPE_P3_4_GB_MM:
1725                 adapter->ahw.board_type = UNM_NIC_GBE;
1726                 break;
1727         case UNM_BRDTYPE_P1_BD:
1728         case UNM_BRDTYPE_P1_SB:
1729         case UNM_BRDTYPE_P1_SMAX:
1730         case UNM_BRDTYPE_P1_SOCK:
1731                 adapter->ahw.board_type = UNM_NIC_GBE;
1732                 break;
1733         case UNM_BRDTYPE_P3_10G_TRP:
1734                 if (adapter->portnum < 2)
1735                         adapter->ahw.board_type = UNM_NIC_XGBE;
1736                 else
1737                         adapter->ahw.board_type = UNM_NIC_GBE;
1738                 break;
1739         default:
1740                 DPRINTF(1, (CE_WARN, "%s: Unknown(%x)\n", unm_nic_driver_name,
1741                     boardinfo->board_type));
1742                 break;
1743         }
1744 
1745         return (rv);
1746 }
1747 
1748 /* NIU access sections */
1749 
1750 int
1751 unm_nic_macaddr_set(struct unm_adapter_s *adapter, __uint8_t *addr)
1752 {
1753         int             ret = 0, i, retry_count = 10;
1754         unsigned char           mac_addr[MAX_ADDR_LEN];
1755 
1756         /* For P3, we should not set MAC in HW any more */
1757         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
1758                 return (0);
1759 
1760         switch (adapter->ahw.board_type) {
1761                 case UNM_NIC_GBE:
1762         /*
1763          * Flaky Mac address registers on qgig require several writes.
1764          */
1765                         for (i = 0; i < retry_count; ++i) {
1766                                 if (unm_niu_macaddr_set(adapter, addr) != 0)
1767                                         return (-1);
1768 
1769                                 (void) unm_niu_macaddr_get(adapter,
1770                                     (unsigned char *)mac_addr);
1771                                 if (memcmp(mac_addr, addr, 6) == 0)
1772                                         return (0);
1773                         }
1774                         cmn_err(CE_WARN, "%s: Flaky MAC addr registers\n",
1775                             unm_nic_driver_name);
1776                         break;
1777 
1778                 case UNM_NIC_XGBE:
1779                         ret = unm_niu_xg_macaddr_set(adapter, addr);
1780                         break;
1781 
1782                 default:
1783                         cmn_err(CE_WARN,  "\r\nUnknown board type encountered"
1784                             " while setting the MAC address.\n");
1785                         return (-1);
1786         }
1787         return (ret);
1788 }
1789 
1790 #define MTU_FUDGE_FACTOR 100
1791 int
1792 unm_nic_set_mtu(struct unm_adapter_s *adapter, int new_mtu)
1793 {
1794         long            port = adapter->physical_port;
1795         int                     ret = 0;
1796         u32                     port_mode = 0;
1797 
1798         if (adapter->ahw.revision_id >= NX_P3_A2)
1799                 return (nx_fw_cmd_set_mtu(adapter, new_mtu));
1800 
1801         new_mtu += MTU_FUDGE_FACTOR; /* so that MAC accepts frames > MTU */
1802         switch (adapter->ahw.board_type) {
1803                 case UNM_NIC_GBE:
1804                         unm_nic_write_w0(adapter,
1805                             UNM_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
1806                             new_mtu);
1807 
1808                         break;
1809 
1810                 case UNM_NIC_XGBE:
1811                         adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
1812                             &port_mode, 4);
1813                         if (port_mode == UNM_PORT_MODE_802_3_AP) {
1814                                 unm_nic_write_w0(adapter,
1815                                     UNM_NIU_AP_MAX_FRAME_SIZE(port), new_mtu);
1816                         } else {
1817                                 if (adapter->physical_port == 0) {
1818                                         unm_nic_write_w0(adapter,
1819                                             UNM_NIU_XGE_MAX_FRAME_SIZE,
1820                                             new_mtu);
1821                                 } else {
1822                                         unm_nic_write_w0(adapter,
1823                                             UNM_NIU_XG1_MAX_FRAME_SIZE,
1824                                             new_mtu);
1825                                 }
1826                         }
1827                         break;
1828 
1829                 default:
1830                         cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1831                             unm_nic_driver_name);
1832         }
1833 
1834         return (ret);
1835 }
1836 
1837 int
1838 unm_nic_set_promisc_mode(struct unm_adapter_s *adapter)
1839 {
1840         int             ret;
1841 
1842         if (adapter->promisc)
1843                 return (0);
1844 
1845         switch (adapter->ahw.board_type) {
1846                 case UNM_NIC_GBE:
1847                         ret = unm_niu_set_promiscuous_mode(adapter,
1848                             UNM_NIU_PROMISCOUS_MODE);
1849                         break;
1850 
1851                 case UNM_NIC_XGBE:
1852                         ret = unm_niu_xg_set_promiscuous_mode(adapter,
1853                             UNM_NIU_PROMISCOUS_MODE);
1854                         break;
1855 
1856                 default:
1857                         cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1858                             unm_nic_driver_name);
1859                         ret = -1;
1860                         break;
1861         }
1862 
1863         if (!ret)
1864                 adapter->promisc = 1;
1865 
1866         return (ret);
1867 }
1868 
1869 int
1870 unm_nic_unset_promisc_mode(struct unm_adapter_s *adapter)
1871 {
1872         int     ret = 0;
1873 
1874         /*
1875          * P3 does not unset promiscous mode. Why?
1876          */
1877         if (adapter->ahw.revision_id >= NX_P3_A2) {
1878                 return (0);
1879         }
1880 
1881         if (!adapter->promisc)
1882                 return (0);
1883 
1884         switch (adapter->ahw.board_type) {
1885                 case UNM_NIC_GBE:
1886                         ret = unm_niu_set_promiscuous_mode(adapter,
1887                             UNM_NIU_NON_PROMISCOUS_MODE);
1888                         break;
1889 
1890                 case UNM_NIC_XGBE:
1891                         ret = unm_niu_xg_set_promiscuous_mode(adapter,
1892                             UNM_NIU_NON_PROMISCOUS_MODE);
1893                         break;
1894 
1895                 default:
1896                         cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1897                             unm_nic_driver_name);
1898                         ret = -1;
1899                         break;
1900         }
1901 
1902         if (!ret)
1903                 adapter->promisc = 0;
1904 
1905         return (ret);
1906 }
1907 
1908 long
1909 unm_nic_phy_read(unm_adapter *adapter, long reg, __uint32_t *readval)
1910 {
1911         long    ret = 0;
1912 
1913         switch (adapter->ahw.board_type) {
1914         case UNM_NIC_GBE:
1915                 ret = unm_niu_gbe_phy_read(adapter, reg, readval);
1916                 break;
1917 
1918         case UNM_NIC_XGBE:
1919                 DPRINTF(1, (CE_WARN,
1920                     "%s: Function %s is not implemented for XG\n",
1921                     unm_nic_driver_name, __FUNCTION__));
1922                 break;
1923 
1924         default:
1925                 DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1926                     unm_nic_driver_name));
1927         }
1928 
1929         return (ret);
1930 }
1931 
1932 long
1933 unm_nic_init_port(struct unm_adapter_s *adapter)
1934 {
1935         long    portnum = adapter->physical_port;
1936         long    ret = 0;
1937         long    reg = 0;
1938         u32                     port_mode = 0;
1939 
1940         unm_nic_set_link_parameters(adapter);
1941 
1942         switch (adapter->ahw.board_type) {
1943         case UNM_NIC_GBE:
1944                 ret = unm_niu_enable_gbe_port(adapter);
1945                 break;
1946 
1947         case UNM_NIC_XGBE:
1948                 adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
1949                     &port_mode, 4);
1950                 if (port_mode == UNM_PORT_MODE_802_3_AP) {
1951                         ret = unm_niu_enable_gbe_port(adapter);
1952                 } else {
1953                         adapter->unm_crb_writelit_adapter(adapter,
1954                             UNM_NIU_XGE_CONFIG_0 + (0x10000 * portnum), 0x5);
1955                         UNM_CRB_READ_CHECK_ADAPTER(UNM_NIU_XGE_CONFIG_1 +
1956                             (0x10000 * portnum), &reg, adapter);
1957                         if (adapter->ahw.revision_id < NX_P3_A2)
1958                                 reg = (reg & ~0x2000UL);
1959                         adapter->unm_crb_writelit_adapter(adapter,
1960                             UNM_NIU_XGE_CONFIG_1 + (0x10000 * portnum), reg);
1961                 }
1962                 break;
1963 
1964         default:
1965                 DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1966                     unm_nic_driver_name));
1967         }
1968 
1969         return (ret);
1970 }
1971 
1972 void
1973 unm_nic_stop_port(struct unm_adapter_s *adapter)
1974 {
1975 
1976         (void) mac_unregister(adapter->mach);
1977 
1978         switch (adapter->ahw.board_type) {
1979         case UNM_NIC_GBE:
1980                 (void) unm_niu_disable_gbe_port(adapter);
1981                 break;
1982 
1983         case UNM_NIC_XGBE:
1984                 (void) unm_niu_disable_xg_port(adapter);
1985                 break;
1986 
1987         default:
1988                 DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1989                     unm_nic_driver_name));
1990         }
1991 }
1992 
1993 void
1994 unm_crb_write_adapter(unsigned long off, void *data,
1995     struct unm_adapter_s *adapter)
1996 {
1997         (void) adapter->unm_nic_hw_write_wx(adapter, off, data, 4);
1998 }
1999 
2000 int
2001 unm_crb_read_adapter(unsigned long off, void *data,
2002     struct unm_adapter_s *adapter)
2003 {
2004         return (adapter->unm_nic_hw_read_wx(adapter, off, data, 4));
2005 }
2006 
2007 int
2008 unm_crb_read_val_adapter(unsigned long off, struct unm_adapter_s *adapter)
2009 {
2010         int data;
2011 
2012         adapter->unm_nic_hw_read_wx(adapter, off, &data, 4);
2013         return (data);
2014 }
2015 
2016 void
2017 unm_nic_set_link_parameters(struct unm_adapter_s *adapter)
2018 {
2019         unm_niu_phy_status_t status;
2020         uint16_t defval = (uint16_t)-1;
2021         unm_niu_control_t mode;
2022         u32 port_mode = 0;
2023 
2024         unm_nic_read_w0(adapter, UNM_NIU_MODE, (uint32_t *)&mode);
2025         if (mode.enable_ge) { // Gb 10/100/1000 Mbps mode
2026                 adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
2027                     &port_mode, 4);
2028                 if (port_mode == UNM_PORT_MODE_802_3_AP) {
2029                         adapter->link_speed = MBPS_1000;
2030                         adapter->link_duplex = LINK_DUPLEX_FULL;
2031                 } else {
2032                 if (unm_nic_phy_read(adapter,
2033                     UNM_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
2034                     (unm_crbword_t *)&status) == 0) {
2035                         if (status.link) {
2036                                 switch (status.speed) {
2037                                 case 0: adapter->link_speed = MBPS_10;
2038                                         break;
2039                                 case 1: adapter->link_speed = MBPS_100;
2040                                         break;
2041                                 case 2: adapter->link_speed = MBPS_1000;
2042                                         break;
2043                                 default:
2044                                         adapter->link_speed = defval;
2045                                         break;
2046                                 }
2047                                 switch (status.duplex) {
2048                                 case 0: adapter->link_duplex = LINK_DUPLEX_HALF;
2049                                         break;
2050                                 case 1: adapter->link_duplex = LINK_DUPLEX_FULL;
2051                                         break;
2052                                 default:
2053                                         adapter->link_duplex = defval;
2054                                         break;
2055                                 }
2056                         } else {
2057                                 adapter->link_speed = defval;
2058                                 adapter->link_duplex = defval;
2059                         }
2060                 } else {
2061                         adapter->link_speed = defval;
2062                         adapter->link_duplex = defval;
2063                 }
2064                 }
2065         }
2066 }
2067 
2068 void
2069 unm_nic_flash_print(struct unm_adapter_s *adapter)
2070 {
2071         int valid = 1;
2072         unm_board_info_t *board_info = &(adapter->ahw.boardcfg);
2073 
2074         if (board_info->magic != UNM_BDINFO_MAGIC) {
2075                 cmn_err(CE_WARN, "%s UNM Unknown board config, Read 0x%x "
2076                     "expected as 0x%x\n", unm_nic_driver_name,
2077                     board_info->magic, UNM_BDINFO_MAGIC);
2078                 valid = 0;
2079         }
2080         if (board_info->header_version != UNM_BDINFO_VERSION) {
2081                 cmn_err(CE_WARN, "%s UNM Unknown board config version."
2082                     " Read %x, expected %x\n", unm_nic_driver_name,
2083                     board_info->header_version, UNM_BDINFO_VERSION);
2084                 valid = 0;
2085         }
2086         if (valid) {
2087                 unm_user_info_t  user_info;
2088                 int     i;
2089                 int     addr = USER_START;
2090                 int     *ptr32;
2091 
2092                 ptr32 = (int *)&user_info;
2093                 for (i = 0; i < sizeof (unm_user_info_t) / sizeof (uint32_t);
2094                     i++) {
2095                         if (rom_fast_read(adapter, addr, ptr32) == -1) {
2096                                 cmn_err(CE_WARN,
2097                                     "%s: ERROR reading %s board userarea.\n",
2098                                     unm_nic_driver_name, unm_nic_driver_name);
2099                                 return;
2100                         }
2101                         ptr32++;
2102                         addr += sizeof (uint32_t);
2103                 }
2104                 if (verbmsg != 0) {
2105                         char    *brd_name;
2106                         GET_BRD_NAME_BY_TYPE(board_info->board_type, brd_name);
2107                         cmn_err(CE_NOTE, "%s %s Board S/N %s  Chip id 0x%x\n",
2108                             unm_nic_driver_name, brd_name, user_info.serial_num,
2109                             board_info->chip_id);
2110                 }
2111         }
2112 }
2113 
2114 static int
2115 nx_nic_send_cmd_descs(unm_adapter *adapter, cmdDescType0_t *cmd_desc_arr,
2116     int nr_elements)
2117 {
2118         struct unm_cmd_buffer   *pbuf;
2119         unsigned int            i = 0, producer;
2120 
2121         /*
2122          * We need to check if space is available.
2123          */
2124         UNM_SPIN_LOCK(&adapter->tx_lock);
2125         producer = adapter->cmdProducer;
2126 
2127         do {
2128                 pbuf = &adapter->cmd_buf_arr[producer];
2129                 pbuf->head = pbuf->tail = NULL;
2130                 pbuf->msg = NULL;
2131                 (void) memcpy(&adapter->ahw.cmdDescHead[producer],
2132                     &cmd_desc_arr[i], sizeof (cmdDescType0_t));
2133                 unm_desc_dma_sync(adapter->ahw.cmd_desc_dma_handle, producer,
2134                     1, adapter->MaxTxDescCount, sizeof (cmdDescType0_t),
2135                     DDI_DMA_SYNC_FORDEV);
2136                 producer = get_next_index(producer, adapter->MaxTxDescCount);
2137                 i++;
2138         } while (i != nr_elements);
2139 
2140         adapter->cmdProducer = adapter->ahw.cmdProducer = producer;
2141         adapter->freecmds -= i;
2142 
2143         unm_nic_update_cmd_producer(adapter, producer);
2144 
2145         UNM_SPIN_UNLOCK(&adapter->tx_lock);
2146         return (0);
2147 }
2148 
2149 typedef struct {
2150         u64     qhdr, req_hdr, words[6];
2151 } nx_nic_req_t;
2152 
2153 typedef struct {
2154         u8      op, tag, mac_addr[6];
2155 } nx_mac_req_t;
2156 
2157 static void
2158 nx_p3_sre_macaddr_change(unm_adapter *adapter, u8 *addr, u8 op)
2159 {
2160         nx_nic_req_t    req;
2161         nx_mac_req_t    mac_req;
2162         int             rv;
2163 
2164         (void) memset(&req, 0, sizeof (nx_nic_req_t));
2165         req.qhdr |= (NX_NIC_REQUEST << 23);
2166         req.req_hdr |= NX_MAC_EVENT;
2167         req.req_hdr |= ((u64)adapter->portnum << 16);
2168         mac_req.op = op;
2169         (void) memcpy(&mac_req.mac_addr, addr, 6);
2170         req.words[0] = HOST_TO_LE_64(*(u64 *)(uintptr_t)&mac_req);
2171 
2172         rv = nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1);
2173         if (rv != 0)
2174                 cmn_err(CE_WARN, "%s%d: Could not send mac update\n",
2175                     adapter->name, adapter->instance);
2176 }
2177 
2178 static int
2179 nx_p3_nic_set_promisc(unm_adapter *adapter, u32 mode)
2180 {
2181         nx_nic_req_t    req;
2182 
2183         (void) memset(&req, 0, sizeof (nx_nic_req_t));
2184 
2185         req.qhdr |= (NX_HOST_REQUEST << 23);
2186         req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE;
2187         req.req_hdr |= ((u64)adapter->portnum << 16);
2188         req.words[0] = HOST_TO_LE_64(mode);
2189 
2190         return (nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1));
2191 }
2192 
2193 /*
2194  * Currently only invoked at interface initialization time
2195  */
2196 void
2197 nx_p3_nic_set_multi(unm_adapter *adapter)
2198 {
2199         u8      bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2200 
2201         if (nx_p3_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL))
2202                 cmn_err(CE_WARN, "Could not set promisc mode\n");
2203 
2204         nx_p3_sre_macaddr_change(adapter, adapter->mac_addr, NETXEN_MAC_ADD);
2205         nx_p3_sre_macaddr_change(adapter, bcast_addr, NETXEN_MAC_ADD);
2206 }