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 (c) 2018, 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                 return (-1);
 708         }
 709 
 710         if (rv == 1) {
 711                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
 712                 crb_win_lock(adapter);
 713                 unm_nic_pci_set_crbwindow_2M(adapter, &off);
 714         }
 715 
 716         switch (len) {
 717         case 1:
 718                 UNM_NIC_PCI_WRITE_8(*(__uint8_t *)data, (void *) (uptr_t)off);
 719                 break;
 720         case 2:
 721                 UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, (void *) (uptr_t)off);
 722                 break;
 723         case 4:
 724                 UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, (void *) (uptr_t)off);
 725                 break;
 726         case 8:
 727                 UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, (void *) (uptr_t)off);
 728                 break;
 729         default:
 730 #if !defined(NDEBUG)
 731                 if ((len & 0x7) != 0)
 732                         cmn_err(CE_WARN, "%s: %s  len(%d) not multiple of 8.\n",
 733                             unm_nic_driver_name, __FUNCTION__, len);
 734 #endif
 735                 UNM_NIC_HW_BLOCK_WRITE_64(data, (uptr_t)off, (len>>3));
 736                 break;
 737         }
 738         if (rv == 1) {
 739                 crb_win_unlock(adapter);
 740                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 741         }
 742 
 743         return (0);
 744 }
 745 
 746 int
 747 unm_nic_hw_read_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
 748 {
 749         void            *addr;
 750         u64             offset;
 751 
 752         if (ADDR_IN_WINDOW1(off)) {// Window 1
 753                 addr = CRB_NORMALIZE(adapter, off);
 754                 if (!addr) {
 755                         offset = CRB_NORMAL(off);
 756                         if (adapter->ahw.pci_len0 == 0)
 757                                 offset -= UNM_PCI_CRBSPACE;
 758                         addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
 759                             offset);
 760                 }
 761                 UNM_READ_LOCK(&adapter->adapter_lock);
 762         } else {// Window 0
 763                 addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
 764                 if (!addr) {
 765                         offset = off;
 766                         addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
 767                             offset);
 768                 }
 769                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
 770                 unm_nic_pci_change_crbwindow_128M(adapter, 0);
 771         }
 772 
 773         switch (len) {
 774         case 1:
 775                 *(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
 776                 break;
 777         case 2:
 778                 *(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
 779                 break;
 780         case 4:
 781                 *(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
 782                 break;
 783         case 8:
 784                 *(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
 785                 break;
 786         default:
 787 #if !defined(NDEBUG)
 788                 if ((len & 0x7) != 0)
 789                         cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
 790                             unm_nic_driver_name, __FUNCTION__, len);
 791 #endif
 792                 UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
 793                 break;
 794         }
 795 
 796         if (ADDR_IN_WINDOW1(off)) {// Window 1
 797                 UNM_READ_UNLOCK(&adapter->adapter_lock);
 798         } else {// Window 0
 799                 unm_nic_pci_change_crbwindow_128M(adapter, 1);
 800                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 801         }
 802 
 803         return (0);
 804 }
 805 
 806 int
 807 unm_nic_hw_read_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
 808 {
 809         int rv;
 810 
 811         rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
 812 
 813         if (rv == -1) {
 814                 cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
 815                     __FUNCTION__, off);
 816                 return (-1);
 817         }
 818 
 819         if (rv == 1) {
 820                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
 821                 crb_win_lock(adapter);
 822                 unm_nic_pci_set_crbwindow_2M(adapter, &off);
 823         }
 824 
 825         switch (len) {
 826         case 1:
 827                 *(__uint8_t  *)data = UNM_NIC_PCI_READ_8((void *) (uptr_t)off);
 828                 break;
 829         case 2:
 830                 *(__uint16_t *)data = UNM_NIC_PCI_READ_16((void *) (uptr_t)off);
 831                 break;
 832         case 4:
 833                 *(__uint32_t *)data = UNM_NIC_PCI_READ_32((void *) (uptr_t)off);
 834                 break;
 835         case 8:
 836                 *(__uint64_t *)data = UNM_NIC_PCI_READ_64((void *) (uptr_t)off);
 837                 break;
 838         default:
 839 #if !defined(NDEBUG)
 840                 if ((len & 0x7) != 0)
 841                         cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
 842                             unm_nic_driver_name, __FUNCTION__, len);
 843 #endif
 844                 UNM_NIC_HW_BLOCK_READ_64(data, (void *) (uptr_t)off, (len>>3));
 845                 break;
 846         }
 847 
 848         if (rv == 1) {
 849                 crb_win_unlock(adapter);
 850                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 851         }
 852 
 853         return (0);
 854 }
 855 
 856 int
 857 unm_nic_hw_read_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
 858 {
 859         void *addr;
 860 
 861         if (ADDR_IN_WINDOW1(off)) {
 862                 // Window 1
 863                 addr = CRB_NORMALIZE(adapter, off);
 864                 UNM_READ_LOCK(&adapter->adapter_lock);
 865         } else {// Window 0
 866                 addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
 867                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
 868                 unm_nic_pci_change_crbwindow_128M(adapter, 0);
 869         }
 870 
 871         if (!addr) {
 872                 if (ADDR_IN_WINDOW1(off)) {// Window 1
 873                         UNM_READ_UNLOCK(&adapter->adapter_lock);
 874                 } else {// Window 0
 875                         unm_nic_pci_change_crbwindow_128M(adapter, 1);
 876                         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 877                 }
 878                 return (1);
 879         }
 880 
 881         switch (len) {
 882                 case 1:
 883                         *(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
 884                         break;
 885                 case 2:
 886                         *(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
 887                         break;
 888                 case 4:
 889                         *(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
 890                         break;
 891                 case 8:
 892                         *(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
 893                         break;
 894                 default:
 895 #if !defined(NDEBUG)
 896                         if ((len & 0x7) != 0)
 897                                 cmn_err(CE_WARN,
 898                                     "%s: %s len(%d) not multiple of 8.\n",
 899                                     unm_nic_driver_name, __FUNCTION__, len);
 900 #endif
 901                         UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
 902                         break;
 903         }
 904 
 905         if (ADDR_IN_WINDOW1(off)) {// Window 1
 906                 UNM_READ_UNLOCK(&adapter->adapter_lock);
 907         } else {// Window 0
 908                 unm_nic_pci_change_crbwindow_128M(adapter, 1);
 909                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
 910         }
 911 
 912         return (0);
 913 }
 914 
 915 /*  PCI Windowing for DDR regions.  */
 916 #define ADDR_IN_RANGE(addr, low, high)      \
 917         (((addr) <= (high)) && ((low) ? ((addr) >= (low)) : 1))
 918 
 919 /*
 920  * check memory access boundary.
 921  * used by test agent. support ddr access only for now
 922  */
 923 /* ARGSUSED */
 924 static unsigned long
 925 unm_nic_pci_mem_bound_check(struct unm_adapter_s *adapter,
 926     unsigned long long addr, int size)
 927 {
 928         if (!ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX) ||
 929             !ADDR_IN_RANGE(addr + size -1, UNM_ADDR_DDR_NET,
 930             UNM_ADDR_DDR_NET_MAX) || ((size != 1) && (size != 2) &&
 931             (size != 4) && (size != 8)))
 932                 return (0);
 933 
 934         return (1);
 935 }
 936 
 937 int unm_pci_set_window_warning_count = 0;
 938 
 939 unsigned long long
 940 unm_nic_pci_set_window_128M(struct unm_adapter_s *adapter,
 941     unsigned long long addr)
 942 {
 943         int             window;
 944         unsigned long long      qdr_max;
 945 
 946         if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 947                 qdr_max = NX_P2_ADDR_QDR_NET_MAX;
 948         } else {
 949                 qdr_max = NX_P3_ADDR_QDR_NET_MAX;
 950         }
 951 
 952         if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
 953                 /* DDR network side */
 954                 /* MN access should never come here */
 955                 cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
 956                 addr = -1ULL;
 957         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
 958                 addr -= UNM_ADDR_OCM0;
 959                 addr += UNM_PCI_OCM0;
 960         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
 961                 addr -= UNM_ADDR_OCM1;
 962                 addr += UNM_PCI_OCM1;
 963         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
 964                 /* QDR network side */
 965                 addr -= UNM_ADDR_QDR_NET;
 966                 window = (addr >> 22) & 0x3f;
 967                 if (adapter->ahw.qdr_sn_window != window) {
 968                         adapter->ahw.qdr_sn_window = window;
 969                         UNM_NIC_PCI_WRITE_32((window << 22),
 970                             (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
 971                             UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
 972                             adapter->ahw.pci_func)))));
 973                         /* MUST make sure window is set before we forge on... */
 974                         (void) UNM_NIC_PCI_READ_32((void *)
 975                             (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
 976                             UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
 977                             adapter->ahw.pci_func)))));
 978                 }
 979                 addr -= (window * 0x400000);
 980                 addr += UNM_PCI_QDR_NET;
 981         } else {
 982                 /*
 983                  * peg gdb frequently accesses memory that doesn't exist,
 984                  * this limits the chit chat so debugging isn't slowed down.
 985                  */
 986                 if ((unm_pci_set_window_warning_count++ < 8) ||
 987                     (unm_pci_set_window_warning_count%64 == 0)) {
 988                         cmn_err(CE_WARN, "%s: Warning:unm_nic_pci_set_window() "
 989                             "Unknown address range!\n", unm_nic_driver_name);
 990                 }
 991                 addr = -1ULL;
 992         }
 993         return (addr);
 994 }
 995 
 996 unsigned long long
 997 unm_nic_pci_set_window_2M(struct unm_adapter_s *adapter,
 998     unsigned long long addr)
 999 {
1000         int window;
1001         u32 win_read;
1002 
1003         if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
1004                 /* DDR network side */
1005                 window = MN_WIN(addr);
1006                 adapter->ahw.ddr_mn_window = window;
1007                 adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
1008                     UNM_PCI_CRBSPACE, &window, 4);
1009                 adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
1010                     UNM_PCI_CRBSPACE, &win_read, 4);
1011                 if ((win_read << 17) != window) {
1012                         cmn_err(CE_WARN,
1013                             "%s: Written MNwin (0x%x) != Read MNwin (0x%x)\n",
1014                             __FUNCTION__, window, win_read);
1015                 }
1016                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
1017         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
1018                 unsigned int temp1;
1019 // OCM: pci_addr[20:18] == 011 && pci_addr[17:11] != 7f
1020                 if ((addr & 0x00ff800) == 0xff800) {
1021                         // if bits 19:18&17:11 are on
1022                         cmn_err(CE_WARN, "%s: QM access not handled.\n",
1023                             __FUNCTION__);
1024                         addr = -1ULL;
1025                 }
1026 
1027                 window = OCM_WIN(addr);
1028                 adapter->ahw.ddr_mn_window = window;
1029                 adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
1030                     UNM_PCI_CRBSPACE, &window, 4);
1031                 adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
1032                     UNM_PCI_CRBSPACE, &win_read, 4);
1033                 temp1 = ((window & 0x1FF) << 7) |
1034                     ((window & 0x0FFFE0000) >> 17);
1035                 if (win_read != temp1) {
1036                         cmn_err(CE_WARN,
1037                             "%s: Written OCMwin(0x%x) != Read OCMwin(0x%x)\n",
1038                             __FUNCTION__, temp1, win_read);
1039                 }
1040                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
1041 
1042         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
1043             NX_P3_ADDR_QDR_NET_MAX)) {
1044                 /* QDR network side */
1045                 window = MS_WIN(addr);
1046                 adapter->ahw.qdr_sn_window = window;
1047                 adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.ms_win_crb |
1048                     UNM_PCI_CRBSPACE, &window, 4);
1049                 adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.ms_win_crb |
1050                     UNM_PCI_CRBSPACE, &win_read, 4);
1051                 if (win_read != window) {
1052                         cmn_err(CE_WARN,
1053                             "%s: Written MSwin (0x%x) != Read MSwin (0x%x)\n",
1054                             __FUNCTION__, window, win_read);
1055                 }
1056                 addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
1057 
1058         } else {
1059                 /*
1060                  * peg gdb frequently accesses memory that doesn't exist,
1061                  * this limits the chit chat so debugging isn't slowed down.
1062                  */
1063                 if ((unm_pci_set_window_warning_count++ < 8) ||
1064                     (unm_pci_set_window_warning_count%64 == 0)) {
1065                         cmn_err(CE_WARN, "%s%d: %s Unknown address range!\n",
1066                             adapter->name, adapter->instance, __FUNCTION__);
1067                 }
1068                 addr = -1ULL;
1069         }
1070         return (addr);
1071 }
1072 
1073 /* check if address is in the same windows as the previous access */
1074 static unsigned long
1075 unm_nic_pci_is_same_window(struct unm_adapter_s *adapter,
1076     unsigned long long addr)
1077 {
1078         int                     window;
1079         unsigned long long      qdr_max;
1080 
1081         if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1082                 qdr_max = NX_P2_ADDR_QDR_NET_MAX;
1083         } else {
1084                 qdr_max = NX_P3_ADDR_QDR_NET_MAX;
1085         }
1086 
1087         if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
1088                 /* DDR network side */
1089                 /* MN access can not come here */
1090                 cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
1091 #if 0
1092                 window = ((addr - UNM_ADDR_DDR_NET) >> 25) & 0x3ff;
1093                 if (adapter->ahw.ddr_mn_window == window) {
1094                         return (1);
1095                 }
1096 #endif
1097         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
1098                 return (1);
1099         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
1100                 return (1);
1101         } else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
1102                 /* QDR network side */
1103                 window = ((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f;
1104                 if (adapter->ahw.qdr_sn_window == window) {
1105                         return (1);
1106                 }
1107         }
1108 
1109         return (0);
1110 }
1111 
1112 static int
1113 unm_nic_pci_mem_read_direct(struct unm_adapter_s *adapter,
1114     u64 off, void *data, int size)
1115 {
1116         void                    *addr;
1117         int                             ret = 0;
1118         u64                             start;
1119 
1120 #if 0
1121         /*
1122          * This check can not be currently executed, since phanmon findq
1123          * command breaks this check whereby 8 byte reads are being attempted
1124          * on "aligned-by-4" addresses on x86. Reason this works is our version
1125          * breaks up the access into 2 consecutive 4 byte writes; on other
1126          * architectures, this might require "aligned-by-8" addresses and we
1127          * will run into trouble.
1128          *
1129          * Check alignment for expected sizes of 1, 2, 4, 8. Other size
1130          * values will not trigger access.
1131          */
1132         if ((off & (size - 1)) != 0)
1133                 return (-1);
1134 #endif
1135 
1136         UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1137 
1138         /*
1139          * If attempting to access unknown address or straddle hw windows,
1140          * do not access.
1141          */
1142         if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
1143             (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
1144                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1145                 cmn_err(CE_WARN, "%s out of bound pci memory access. "
1146                     "offset is 0x%llx\n", unm_nic_driver_name, off);
1147                 return (-1);
1148         }
1149 
1150         addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
1151         if (!addr)
1152                 addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
1153 
1154         switch (size) {
1155                 case 1:
1156                         *(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
1157                         break;
1158                 case 2:
1159                         *(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
1160                         break;
1161                 case 4:
1162                         *(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
1163                         break;
1164                 case 8:
1165                         *(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
1166                         break;
1167                 default:
1168                         ret = -1;
1169                         break;
1170         }
1171 
1172         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1173         return (ret);
1174 }
1175 
1176 static int
1177 unm_nic_pci_mem_write_direct(struct unm_adapter_s *adapter, u64 off,
1178     void *data, int size)
1179 {
1180         void    *addr;
1181         int             ret = 0;
1182         u64             start;
1183 
1184 #if 0
1185         /*
1186          * This check can not be currently executed, since firmware load
1187          * breaks this check whereby 8 byte writes are being attempted on
1188          * "aligned-by-4" addresses on x86. Reason this works is our version
1189          * breaks up the access into 2 consecutive 4 byte writes; on other
1190          * architectures, this might require "aligned-by-8" addresses and we
1191          * will run into trouble.
1192          *
1193          * Check alignment for expected sizes of 1, 2, 4, 8. Other size
1194          * values will not trigger access.
1195          */
1196         if ((off & (size - 1)) != 0)
1197                 return (-1);
1198 #endif
1199 
1200         UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1201 
1202         /*
1203          * If attempting to access unknown address or straddle hw windows,
1204          * do not access.
1205          */
1206         if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
1207             (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
1208                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1209                 cmn_err(CE_WARN, "%s out of bound pci memory access. "
1210                     "offset is 0x%llx\n", unm_nic_driver_name, off);
1211                 return (-1);
1212         }
1213 
1214         addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
1215         if (!addr)
1216                 addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
1217 
1218         switch (size) {
1219                 case 1:
1220                         UNM_NIC_PCI_WRITE_8(*(__uint8_t  *)data, addr);
1221                         break;
1222                 case 2:
1223                         UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, addr);
1224                         break;
1225                 case 4:
1226                         UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, addr);
1227                         break;
1228                 case 8:
1229                         UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, addr);
1230                         break;
1231                 default:
1232                         ret = -1;
1233                         break;
1234         }
1235         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1236         return (ret);
1237 }
1238 
1239 
1240 int
1241 unm_nic_pci_mem_write_128M(struct unm_adapter_s *adapter, u64 off, void *data,
1242     int size)
1243 {
1244         int             i, j, ret = 0, loop, sz[2], off0;
1245         __uint32_t              temp;
1246         __uint64_t              off8, mem_crb, tmpw, word[2] = {0, 0};
1247 #define MAX_CTL_CHECK   1000
1248 
1249         /*
1250          * If not MN, go check for MS or invalid.
1251          */
1252         if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1253                 return (unm_nic_pci_mem_write_direct(adapter, off, data, size));
1254 
1255         off8 = off & 0xfffffff8;
1256         off0 = off & 0x7;
1257         sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1258         sz[1] = size - sz[0];
1259         loop = ((off0 + size - 1) >> 3) + 1;
1260         /* LINTED: E_FALSE_LOGICAL_EXPR */
1261         mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
1262 
1263         if ((size != 8) || (off0 != 0))  {
1264                 for (i = 0; i < loop; i++) {
1265                         if (adapter->unm_nic_pci_mem_read(adapter,
1266                             off8 + (i << 3), &word[i], 8))
1267                                 return (-1);
1268                 }
1269         }
1270 
1271         switch (size) {
1272                 case 1:
1273                         tmpw = *((__uint8_t *)data);
1274                         break;
1275                 case 2:
1276                         tmpw = *((__uint16_t *)data);
1277                         break;
1278                 case 4:
1279                         tmpw = *((__uint32_t *)data);
1280                         break;
1281                 case 8:
1282                 default:
1283                         tmpw = *((__uint64_t *)data);
1284                         break;
1285         }
1286         word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1287         word[0] |= tmpw << (off0 * 8);
1288 
1289         if (loop == 2) {
1290                 word[1] &= ~(~0ULL << (sz[1] * 8));
1291                 word[1] |= tmpw >> (sz[0] * 8);
1292         }
1293 
1294         UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1295         unm_nic_pci_change_crbwindow_128M(adapter, 0);
1296 
1297         for (i = 0; i < loop; i++) {
1298                 UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
1299                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
1300                 UNM_NIC_PCI_WRITE_32(0,
1301                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
1302                 UNM_NIC_PCI_WRITE_32(word[i] & 0xffffffff,
1303                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_LO));
1304                 UNM_NIC_PCI_WRITE_32((word[i] >> 32) & 0xffffffff,
1305                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_HI));
1306                 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
1307                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1308                 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE |
1309                     MIU_TA_CTL_WRITE,
1310                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1311 
1312                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1313                         temp = UNM_NIC_PCI_READ_32((void *)
1314                             (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1315                         if ((temp & MIU_TA_CTL_BUSY) == 0) {
1316                                 break;
1317                         }
1318                 }
1319 
1320                 if (j >= MAX_CTL_CHECK) {
1321                         cmn_err(CE_WARN, "%s: %s Fail to write thru agent\n",
1322                             __FUNCTION__, unm_nic_driver_name);
1323                         ret = -1;
1324                         break;
1325                 }
1326         }
1327 
1328         unm_nic_pci_change_crbwindow_128M(adapter, 1);
1329         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1330         return (ret);
1331 }
1332 
1333 int
1334 unm_nic_pci_mem_read_128M(struct unm_adapter_s *adapter, u64 off, void *data,
1335     int size)
1336 {
1337         int             i, j = 0, k, start, end, loop, sz[2], off0[2];
1338         __uint32_t              temp;
1339         __uint64_t              off8, val, mem_crb, word[2] = {0, 0};
1340 #define MAX_CTL_CHECK   1000
1341 
1342         /*
1343          * If not MN, go check for MS or invalid.
1344          */
1345         if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1346                 return (unm_nic_pci_mem_read_direct(adapter, off, data, size));
1347 
1348         off8 = off & 0xfffffff8;
1349         off0[0] = off & 0x7;
1350         off0[1] = 0;
1351         sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1352         sz[1] = size - sz[0];
1353         loop = ((off0[0] + size - 1) >> 3) + 1;
1354         /* LINTED: E_FALSE_LOGICAL_EXPR */
1355         mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
1356 
1357         UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1358         unm_nic_pci_change_crbwindow_128M(adapter, 0);
1359 
1360         for (i = 0; i < loop; i++) {
1361                 UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
1362                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
1363                 UNM_NIC_PCI_WRITE_32(0,
1364                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
1365                 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE,
1366                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1367                 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
1368                     (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1369 
1370                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1371                         temp = UNM_NIC_PCI_READ_32((void *)
1372                             (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1373                         if ((temp & MIU_TA_CTL_BUSY) == 0) {
1374                                 break;
1375                         }
1376                 }
1377 
1378                 if (j >= MAX_CTL_CHECK) {
1379                         cmn_err(CE_WARN, "%s: %s Fail to read through agent\n",
1380                             __FUNCTION__, unm_nic_driver_name);
1381                         break;
1382                 }
1383 
1384                 start = off0[i] >> 2;
1385                 end   = (off0[i] + sz[i] - 1) >> 2;
1386                 word[i] = 0;
1387                 for (k = start; k <= end; k++) {
1388                         word[i] |= ((__uint64_t)UNM_NIC_PCI_READ_32(
1389                             (void *) (uptr_t)(mem_crb +
1390                             MIU_TEST_AGT_RDDATA(k))) << (32*k));
1391                 }
1392         }
1393 
1394         unm_nic_pci_change_crbwindow_128M(adapter, 1);
1395         UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1396 
1397         if (j >= MAX_CTL_CHECK)
1398                 return (-1);
1399 
1400         if (sz[0] == 8) {
1401                 val = word[0];
1402         } else {
1403                 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1404                     ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1405         }
1406 
1407         switch (size) {
1408         case 1:
1409                 *(__uint8_t  *)data = val;
1410                 break;
1411         case 2:
1412                 *(__uint16_t *)data = val;
1413                 break;
1414         case 4:
1415                 *(__uint32_t *)data = val;
1416                 break;
1417         case 8:
1418                 *(__uint64_t *)data = val;
1419                 break;
1420         }
1421         return (0);
1422 }
1423 
1424 
1425 
1426 int
1427 unm_nic_pci_mem_write_2M(struct unm_adapter_s *adapter, u64 off, void *data,
1428     int size)
1429 {
1430         int     i, j, ret = 0, loop, sz[2], off0;
1431         __uint32_t      temp;
1432         __uint64_t      off8, mem_crb, tmpw, word[2] = {0, 0};
1433 #define MAX_CTL_CHECK   1000
1434 
1435         /*
1436          * If not MN, go check for MS or invalid.
1437          */
1438         if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
1439                 mem_crb = UNM_CRB_QDR_NET;
1440         } else {
1441                 mem_crb = UNM_CRB_DDR_NET;
1442                 if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1443                         return (unm_nic_pci_mem_write_direct(adapter,
1444                             off, data, size));
1445         }
1446 
1447         off8 = off & 0xfffffff8;
1448         off0 = off & 0x7;
1449         sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1450         sz[1] = size - sz[0];
1451         loop = ((off0 + size - 1) >> 3) + 1;
1452 
1453         if ((size != 8) || (off0 != 0)) {
1454                 for (i = 0; i < loop; i++) {
1455                         if (adapter->unm_nic_pci_mem_read(adapter,
1456                             off8 + (i << 3), &word[i], 8))
1457                                 return (-1);
1458                 }
1459         }
1460 
1461         switch (size) {
1462                 case 1:
1463                         tmpw = *((__uint8_t *)data);
1464                         break;
1465                 case 2:
1466                         tmpw = *((__uint16_t *)data);
1467                         break;
1468                 case 4:
1469                         tmpw = *((__uint32_t *)data);
1470                         break;
1471                 case 8:
1472                 default:
1473                         tmpw = *((__uint64_t *)data);
1474                         break;
1475         }
1476 
1477         word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1478         word[0] |= tmpw << (off0 * 8);
1479 
1480         if (loop == 2) {
1481                 word[1] &= ~(~0ULL << (sz[1] * 8));
1482                 word[1] |= tmpw >> (sz[0] * 8);
1483         }
1484 
1485 // don't lock here - write_wx gets the lock if each time
1486 // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1487 // unm_nic_pci_change_crbwindow_128M(adapter, 0);
1488 
1489         for (i = 0; i < loop; i++) {
1490                 temp = off8 + (i << 3);
1491                 adapter->unm_nic_hw_write_wx(adapter,
1492                     mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
1493                 temp = 0;
1494                 adapter->unm_nic_hw_write_wx(adapter,
1495                     mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
1496                 temp = word[i] & 0xffffffff;
1497                 adapter->unm_nic_hw_write_wx(adapter,
1498                     mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
1499                 temp = (word[i] >> 32) & 0xffffffff;
1500                 adapter->unm_nic_hw_write_wx(adapter,
1501                     mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
1502                 temp = 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                 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
1506                 adapter->unm_nic_hw_write_wx(adapter,
1507                     mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
1508 
1509                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1510                         adapter->unm_nic_hw_read_wx(adapter,
1511                             mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1512                         if ((temp & MIU_TA_CTL_BUSY) == 0) {
1513                                 break;
1514                         }
1515                 }
1516 
1517                 if (j >= MAX_CTL_CHECK) {
1518                         cmn_err(CE_WARN, "%s: Fail to write through agent\n",
1519                             unm_nic_driver_name);
1520                         ret = -1;
1521                         break;
1522                 }
1523         }
1524 
1525 //  unm_nic_pci_change_crbwindow_128M(adapter, 1);
1526 //  UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1527         return (ret);
1528 }
1529 
1530 int
1531 unm_nic_pci_mem_read_2M(struct unm_adapter_s *adapter, u64 off, void *data,
1532     int size)
1533 {
1534 // unsigned long   flags;
1535         int             i, j = 0, k, start, end, loop, sz[2], off0[2];
1536         __uint32_t      temp;
1537         __uint64_t      off8, val, mem_crb, word[2] = {0, 0};
1538 #define MAX_CTL_CHECK   1000
1539 
1540         /*
1541          * If not MN, go check for MS or invalid.
1542          */
1543 
1544         if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
1545                 mem_crb = UNM_CRB_QDR_NET;
1546         } else {
1547                 mem_crb = UNM_CRB_DDR_NET;
1548                 if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1549                         return (unm_nic_pci_mem_read_direct(adapter,
1550                             off, data, size));
1551         }
1552 
1553         off8 = off & 0xfffffff8;
1554         off0[0] = off & 0x7;
1555         off0[1] = 0;
1556         sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1557         sz[1] = size - sz[0];
1558         loop = ((off0[0] + size - 1) >> 3) + 1;
1559 
1560 // don't get lock - write_wx will get it
1561 // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1562 // unm_nic_pci_change_crbwindow_128M(adapter, 0);
1563 
1564         for (i = 0; i < loop; i++) {
1565                 temp = off8 + (i << 3);
1566                 adapter->unm_nic_hw_write_wx(adapter,
1567                     mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
1568                 temp = 0;
1569                 adapter->unm_nic_hw_write_wx(adapter,
1570                     mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
1571                 temp = MIU_TA_CTL_ENABLE;
1572                 adapter->unm_nic_hw_write_wx(adapter,
1573                     mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1574                 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
1575                 adapter->unm_nic_hw_write_wx(adapter,
1576                     mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1577 
1578                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1579                         adapter->unm_nic_hw_read_wx(adapter,
1580                             mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1581                         if ((temp & MIU_TA_CTL_BUSY) == 0) {
1582                                 break;
1583                         }
1584                 }
1585 
1586                 if (j >= MAX_CTL_CHECK) {
1587                         cmn_err(CE_WARN, "%s: Fail to read through agent\n",
1588                             unm_nic_driver_name);
1589                         break;
1590                 }
1591 
1592                 start = off0[i] >> 2;
1593                 end   = (off0[i] + sz[i] - 1) >> 2;
1594                 for (k = start; k <= end; k++) {
1595                         adapter->unm_nic_hw_read_wx(adapter,
1596                             mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
1597                         word[i] |= ((__uint64_t)temp << (32 * k));
1598                 }
1599         }
1600 
1601 // unm_nic_pci_change_crbwindow_128M(adapter, 1);
1602 // UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1603 
1604         if (j >= MAX_CTL_CHECK)
1605                 return (-1);
1606 
1607         if (sz[0] == 8) {
1608                 val = word[0];
1609         } else {
1610                 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1611                     ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1612         }
1613 
1614         switch (size) {
1615                 case 1:
1616                         *(__uint8_t  *)data = val;
1617                         break;
1618                 case 2:
1619                         *(__uint16_t *)data = val;
1620                         break;
1621                 case 4:
1622                         *(__uint32_t *)data = val;
1623                         break;
1624                 case 8:
1625                         *(__uint64_t *)data = val;
1626                         break;
1627         }
1628         return (0);
1629 }
1630 
1631 int
1632 unm_crb_writelit_adapter_2M(struct unm_adapter_s *adapter, unsigned long off,
1633     int data)
1634 {
1635         return (unm_nic_hw_write_wx_2M(adapter, off, &data, 4));
1636 }
1637 
1638 int
1639 unm_crb_writelit_adapter_128M(struct unm_adapter_s *adapter, unsigned long off,
1640     int data)
1641 {
1642         void *addr;
1643 
1644         if (ADDR_IN_WINDOW1(off)) {
1645                 UNM_READ_LOCK(&adapter->adapter_lock);
1646                 UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
1647                 UNM_READ_UNLOCK(&adapter->adapter_lock);
1648         } else {
1649                 // unm_nic_write_w0 (adapter, off, data);
1650                 UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1651                 unm_nic_pci_change_crbwindow_128M(adapter, 0);
1652                 addr = (void *) (pci_base_offset(adapter, off));
1653                 UNM_NIC_PCI_WRITE_32(data, addr);
1654                 unm_nic_pci_change_crbwindow_128M(adapter, 1);
1655                 UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1656         }
1657 
1658         return (0);
1659 }
1660 
1661 int
1662 unm_nic_get_board_info(struct unm_adapter_s *adapter)
1663 {
1664         int     rv = 0;
1665         unm_board_info_t  *boardinfo;
1666         int             i;
1667         int             addr = BRDCFG_START;
1668         uint32_t          *ptr32;
1669         uint32_t        gpioval;
1670 
1671         boardinfo = &adapter->ahw.boardcfg;
1672         ptr32 = (uint32_t *)boardinfo;
1673 
1674         for (i = 0; i < sizeof (unm_board_info_t) / sizeof (uint32_t); i++) {
1675                 if (rom_fast_read(adapter, addr, (int *)ptr32) == -1) {
1676                         return (-1);
1677                 }
1678                 DPRINTF(1, (CE_WARN, "ROM(%d): %x\n", i, *ptr32));
1679                 ptr32++;
1680                 addr += sizeof (uint32_t);
1681         }
1682 
1683         if (boardinfo->magic != UNM_BDINFO_MAGIC) {
1684                 DPRINTF(1, (CE_WARN, "%s: ERROR reading board config."
1685                     " Read %x, expected %x\n", unm_nic_driver_name,
1686                     boardinfo->magic, UNM_BDINFO_MAGIC));
1687                 rv = -1;
1688         }
1689 
1690         if (boardinfo->header_version != UNM_BDINFO_VERSION) {
1691                 DPRINTF(1, (CE_WARN, "%s: Unknown board config version."
1692                     " Read %x, expected %x\n", unm_nic_driver_name,
1693                     boardinfo->header_version, UNM_BDINFO_VERSION));
1694                 rv = -1;
1695         }
1696 
1697         if (boardinfo->board_type == UNM_BRDTYPE_P3_4_GB_MM) {
1698                 gpioval = UNM_CRB_READ_VAL_ADAPTER(UNM_ROMUSB_GLB_PAD_GPIO_I,
1699                     adapter);
1700                 if ((gpioval & 0x8000) == 0)
1701                         boardinfo->board_type = UNM_BRDTYPE_P3_10G_TRP;
1702         }
1703 
1704         DPRINTF(0, (CE_WARN, "Discovered board type:0x%x  ",
1705             boardinfo->board_type));
1706 
1707         switch ((unm_brdtype_t)boardinfo->board_type) {
1708         case UNM_BRDTYPE_P2_SB35_4G:
1709                 adapter->ahw.board_type = UNM_NIC_GBE;
1710                 break;
1711         case UNM_BRDTYPE_P2_SB31_10G:
1712         case UNM_BRDTYPE_P2_SB31_10G_IMEZ:
1713         case UNM_BRDTYPE_P2_SB31_10G_HMEZ:
1714         case UNM_BRDTYPE_P2_SB31_10G_CX4:
1715         case UNM_BRDTYPE_P3_HMEZ:
1716         case UNM_BRDTYPE_P3_XG_LOM:
1717         case UNM_BRDTYPE_P3_10G_CX4:
1718         case UNM_BRDTYPE_P3_10G_CX4_LP:
1719         case UNM_BRDTYPE_P3_IMEZ:
1720         case UNM_BRDTYPE_P3_10G_SFP_PLUS:
1721         case UNM_BRDTYPE_P3_10G_XFP:
1722         case UNM_BRDTYPE_P3_10000_BASE_T:
1723                 adapter->ahw.board_type = UNM_NIC_XGBE;
1724                 break;
1725         case UNM_BRDTYPE_P3_REF_QG:
1726         case UNM_BRDTYPE_P3_4_GB:
1727         case UNM_BRDTYPE_P3_4_GB_MM:
1728                 adapter->ahw.board_type = UNM_NIC_GBE;
1729                 break;
1730         case UNM_BRDTYPE_P1_BD:
1731         case UNM_BRDTYPE_P1_SB:
1732         case UNM_BRDTYPE_P1_SMAX:
1733         case UNM_BRDTYPE_P1_SOCK:
1734                 adapter->ahw.board_type = UNM_NIC_GBE;
1735                 break;
1736         case UNM_BRDTYPE_P3_10G_TRP:
1737                 if (adapter->portnum < 2)
1738                         adapter->ahw.board_type = UNM_NIC_XGBE;
1739                 else
1740                         adapter->ahw.board_type = UNM_NIC_GBE;
1741                 break;
1742         default:
1743                 DPRINTF(1, (CE_WARN, "%s: Unknown(%x)\n", unm_nic_driver_name,
1744                     boardinfo->board_type));
1745                 break;
1746         }
1747 
1748         return (rv);
1749 }
1750 
1751 /* NIU access sections */
1752 
1753 int
1754 unm_nic_macaddr_set(struct unm_adapter_s *adapter, __uint8_t *addr)
1755 {
1756         int             ret = 0, i, retry_count = 10;
1757         unsigned char           mac_addr[MAX_ADDR_LEN];
1758 
1759         /* For P3, we should not set MAC in HW any more */
1760         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
1761                 return (0);
1762 
1763         switch (adapter->ahw.board_type) {
1764                 case UNM_NIC_GBE:
1765         /*
1766          * Flaky Mac address registers on qgig require several writes.
1767          */
1768                         for (i = 0; i < retry_count; ++i) {
1769                                 if (unm_niu_macaddr_set(adapter, addr) != 0)
1770                                         return (-1);
1771 
1772                                 (void) unm_niu_macaddr_get(adapter,
1773                                     (unsigned char *)mac_addr);
1774                                 if (memcmp(mac_addr, addr, 6) == 0)
1775                                         return (0);
1776                         }
1777                         cmn_err(CE_WARN, "%s: Flaky MAC addr registers\n",
1778                             unm_nic_driver_name);
1779                         break;
1780 
1781                 case UNM_NIC_XGBE:
1782                         ret = unm_niu_xg_macaddr_set(adapter, addr);
1783                         break;
1784 
1785                 default:
1786                         cmn_err(CE_WARN,  "\r\nUnknown board type encountered"
1787                             " while setting the MAC address.\n");
1788                         return (-1);
1789         }
1790         return (ret);
1791 }
1792 
1793 #define MTU_FUDGE_FACTOR 100
1794 int
1795 unm_nic_set_mtu(struct unm_adapter_s *adapter, int new_mtu)
1796 {
1797         long            port = adapter->physical_port;
1798         int                     ret = 0;
1799         u32                     port_mode = 0;
1800 
1801         if (adapter->ahw.revision_id >= NX_P3_A2)
1802                 return (nx_fw_cmd_set_mtu(adapter, new_mtu));
1803 
1804         new_mtu += MTU_FUDGE_FACTOR; /* so that MAC accepts frames > MTU */
1805         switch (adapter->ahw.board_type) {
1806                 case UNM_NIC_GBE:
1807                         unm_nic_write_w0(adapter,
1808                             UNM_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
1809                             new_mtu);
1810 
1811                         break;
1812 
1813                 case UNM_NIC_XGBE:
1814                         adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
1815                             &port_mode, 4);
1816                         if (port_mode == UNM_PORT_MODE_802_3_AP) {
1817                                 unm_nic_write_w0(adapter,
1818                                     UNM_NIU_AP_MAX_FRAME_SIZE(port), new_mtu);
1819                         } else {
1820                                 if (adapter->physical_port == 0) {
1821                                         unm_nic_write_w0(adapter,
1822                                             UNM_NIU_XGE_MAX_FRAME_SIZE,
1823                                             new_mtu);
1824                                 } else {
1825                                         unm_nic_write_w0(adapter,
1826                                             UNM_NIU_XG1_MAX_FRAME_SIZE,
1827                                             new_mtu);
1828                                 }
1829                         }
1830                         break;
1831 
1832                 default:
1833                         cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1834                             unm_nic_driver_name);
1835         }
1836 
1837         return (ret);
1838 }
1839 
1840 int
1841 unm_nic_set_promisc_mode(struct unm_adapter_s *adapter)
1842 {
1843         int             ret;
1844 
1845         if (adapter->promisc)
1846                 return (0);
1847 
1848         switch (adapter->ahw.board_type) {
1849                 case UNM_NIC_GBE:
1850                         ret = unm_niu_set_promiscuous_mode(adapter,
1851                             UNM_NIU_PROMISCOUS_MODE);
1852                         break;
1853 
1854                 case UNM_NIC_XGBE:
1855                         ret = unm_niu_xg_set_promiscuous_mode(adapter,
1856                             UNM_NIU_PROMISCOUS_MODE);
1857                         break;
1858 
1859                 default:
1860                         cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1861                             unm_nic_driver_name);
1862                         ret = -1;
1863                         break;
1864         }
1865 
1866         if (!ret)
1867                 adapter->promisc = 1;
1868 
1869         return (ret);
1870 }
1871 
1872 int
1873 unm_nic_unset_promisc_mode(struct unm_adapter_s *adapter)
1874 {
1875         int     ret = 0;
1876 
1877         /*
1878          * P3 does not unset promiscous mode. Why?
1879          */
1880         if (adapter->ahw.revision_id >= NX_P3_A2) {
1881                 return (0);
1882         }
1883 
1884         if (!adapter->promisc)
1885                 return (0);
1886 
1887         switch (adapter->ahw.board_type) {
1888                 case UNM_NIC_GBE:
1889                         ret = unm_niu_set_promiscuous_mode(adapter,
1890                             UNM_NIU_NON_PROMISCOUS_MODE);
1891                         break;
1892 
1893                 case UNM_NIC_XGBE:
1894                         ret = unm_niu_xg_set_promiscuous_mode(adapter,
1895                             UNM_NIU_NON_PROMISCOUS_MODE);
1896                         break;
1897 
1898                 default:
1899                         cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1900                             unm_nic_driver_name);
1901                         ret = -1;
1902                         break;
1903         }
1904 
1905         if (!ret)
1906                 adapter->promisc = 0;
1907 
1908         return (ret);
1909 }
1910 
1911 long
1912 unm_nic_phy_read(unm_adapter *adapter, long reg, __uint32_t *readval)
1913 {
1914         long    ret = 0;
1915 
1916         switch (adapter->ahw.board_type) {
1917         case UNM_NIC_GBE:
1918                 ret = unm_niu_gbe_phy_read(adapter, reg, readval);
1919                 break;
1920 
1921         case UNM_NIC_XGBE:
1922                 DPRINTF(1, (CE_WARN,
1923                     "%s: Function %s is not implemented for XG\n",
1924                     unm_nic_driver_name, __FUNCTION__));
1925                 break;
1926 
1927         default:
1928                 DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1929                     unm_nic_driver_name));
1930         }
1931 
1932         return (ret);
1933 }
1934 
1935 long
1936 unm_nic_init_port(struct unm_adapter_s *adapter)
1937 {
1938         long    portnum = adapter->physical_port;
1939         long    ret = 0;
1940         long    reg = 0;
1941         u32                     port_mode = 0;
1942 
1943         unm_nic_set_link_parameters(adapter);
1944 
1945         switch (adapter->ahw.board_type) {
1946         case UNM_NIC_GBE:
1947                 ret = unm_niu_enable_gbe_port(adapter);
1948                 break;
1949 
1950         case UNM_NIC_XGBE:
1951                 adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
1952                     &port_mode, 4);
1953                 if (port_mode == UNM_PORT_MODE_802_3_AP) {
1954                         ret = unm_niu_enable_gbe_port(adapter);
1955                 } else {
1956                         adapter->unm_crb_writelit_adapter(adapter,
1957                             UNM_NIU_XGE_CONFIG_0 + (0x10000 * portnum), 0x5);
1958                         UNM_CRB_READ_CHECK_ADAPTER(UNM_NIU_XGE_CONFIG_1 +
1959                             (0x10000 * portnum), &reg, adapter);
1960                         if (adapter->ahw.revision_id < NX_P3_A2)
1961                                 reg = (reg & ~0x2000UL);
1962                         adapter->unm_crb_writelit_adapter(adapter,
1963                             UNM_NIU_XGE_CONFIG_1 + (0x10000 * portnum), reg);
1964                 }
1965                 break;
1966 
1967         default:
1968                 DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1969                     unm_nic_driver_name));
1970         }
1971 
1972         return (ret);
1973 }
1974 
1975 void
1976 unm_nic_stop_port(struct unm_adapter_s *adapter)
1977 {
1978 
1979         (void) mac_unregister(adapter->mach);
1980 
1981         switch (adapter->ahw.board_type) {
1982         case UNM_NIC_GBE:
1983                 (void) unm_niu_disable_gbe_port(adapter);
1984                 break;
1985 
1986         case UNM_NIC_XGBE:
1987                 (void) unm_niu_disable_xg_port(adapter);
1988                 break;
1989 
1990         default:
1991                 DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1992                     unm_nic_driver_name));
1993         }
1994 }
1995 
1996 void
1997 unm_crb_write_adapter(unsigned long off, void *data,
1998     struct unm_adapter_s *adapter)
1999 {
2000         (void) adapter->unm_nic_hw_write_wx(adapter, off, data, 4);
2001 }
2002 
2003 int
2004 unm_crb_read_adapter(unsigned long off, void *data,
2005     struct unm_adapter_s *adapter)
2006 {
2007         return (adapter->unm_nic_hw_read_wx(adapter, off, data, 4));
2008 }
2009 
2010 int
2011 unm_crb_read_val_adapter(unsigned long off, struct unm_adapter_s *adapter)
2012 {
2013         int data;
2014 
2015         adapter->unm_nic_hw_read_wx(adapter, off, &data, 4);
2016         return (data);
2017 }
2018 
2019 void
2020 unm_nic_set_link_parameters(struct unm_adapter_s *adapter)
2021 {
2022         unm_niu_phy_status_t status;
2023         uint16_t defval = (uint16_t)-1;
2024         unm_niu_control_t mode;
2025         u32 port_mode = 0;
2026 
2027         unm_nic_read_w0(adapter, UNM_NIU_MODE, (uint32_t *)&mode);
2028         if (mode.enable_ge) { // Gb 10/100/1000 Mbps mode
2029                 adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
2030                     &port_mode, 4);
2031                 if (port_mode == UNM_PORT_MODE_802_3_AP) {
2032                         adapter->link_speed = MBPS_1000;
2033                         adapter->link_duplex = LINK_DUPLEX_FULL;
2034                 } else {
2035                 if (unm_nic_phy_read(adapter,
2036                     UNM_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
2037                     (unm_crbword_t *)&status) == 0) {
2038                         if (status.link) {
2039                                 switch (status.speed) {
2040                                 case 0: adapter->link_speed = MBPS_10;
2041                                         break;
2042                                 case 1: adapter->link_speed = MBPS_100;
2043                                         break;
2044                                 case 2: adapter->link_speed = MBPS_1000;
2045                                         break;
2046                                 default:
2047                                         adapter->link_speed = defval;
2048                                         break;
2049                                 }
2050                                 switch (status.duplex) {
2051                                 case 0: adapter->link_duplex = LINK_DUPLEX_HALF;
2052                                         break;
2053                                 case 1: adapter->link_duplex = LINK_DUPLEX_FULL;
2054                                         break;
2055                                 default:
2056                                         adapter->link_duplex = defval;
2057                                         break;
2058                                 }
2059                         } else {
2060                                 adapter->link_speed = defval;
2061                                 adapter->link_duplex = defval;
2062                         }
2063                 } else {
2064                         adapter->link_speed = defval;
2065                         adapter->link_duplex = defval;
2066                 }
2067                 }
2068         }
2069 }
2070 
2071 void
2072 unm_nic_flash_print(struct unm_adapter_s *adapter)
2073 {
2074         int valid = 1;
2075         unm_board_info_t *board_info = &(adapter->ahw.boardcfg);
2076 
2077         if (board_info->magic != UNM_BDINFO_MAGIC) {
2078                 cmn_err(CE_WARN, "%s UNM Unknown board config, Read 0x%x "
2079                     "expected as 0x%x\n", unm_nic_driver_name,
2080                     board_info->magic, UNM_BDINFO_MAGIC);
2081                 valid = 0;
2082         }
2083         if (board_info->header_version != UNM_BDINFO_VERSION) {
2084                 cmn_err(CE_WARN, "%s UNM Unknown board config version."
2085                     " Read %x, expected %x\n", unm_nic_driver_name,
2086                     board_info->header_version, UNM_BDINFO_VERSION);
2087                 valid = 0;
2088         }
2089         if (valid) {
2090                 unm_user_info_t  user_info;
2091                 int     i;
2092                 int     addr = USER_START;
2093                 int     *ptr32;
2094 
2095                 ptr32 = (int *)&user_info;
2096                 for (i = 0; i < sizeof (unm_user_info_t) / sizeof (uint32_t);
2097                     i++) {
2098                         if (rom_fast_read(adapter, addr, ptr32) == -1) {
2099                                 cmn_err(CE_WARN,
2100                                     "%s: ERROR reading %s board userarea.\n",
2101                                     unm_nic_driver_name, unm_nic_driver_name);
2102                                 return;
2103                         }
2104                         ptr32++;
2105                         addr += sizeof (uint32_t);
2106                 }
2107                 if (verbmsg != 0) {
2108                         char    *brd_name;
2109                         GET_BRD_NAME_BY_TYPE(board_info->board_type, brd_name);
2110                         cmn_err(CE_NOTE, "%s %s Board S/N %s  Chip id 0x%x\n",
2111                             unm_nic_driver_name, brd_name, user_info.serial_num,
2112                             board_info->chip_id);
2113                 }
2114         }
2115 }
2116 
2117 static int
2118 nx_nic_send_cmd_descs(unm_adapter *adapter, cmdDescType0_t *cmd_desc_arr,
2119     int nr_elements)
2120 {
2121         struct unm_cmd_buffer   *pbuf;
2122         unsigned int            i = 0, producer;
2123 
2124         /*
2125          * We need to check if space is available.
2126          */
2127         UNM_SPIN_LOCK(&adapter->tx_lock);
2128         producer = adapter->cmdProducer;
2129 
2130         do {
2131                 pbuf = &adapter->cmd_buf_arr[producer];
2132                 pbuf->head = pbuf->tail = NULL;
2133                 pbuf->msg = NULL;
2134                 (void) memcpy(&adapter->ahw.cmdDescHead[producer],
2135                     &cmd_desc_arr[i], sizeof (cmdDescType0_t));
2136                 unm_desc_dma_sync(adapter->ahw.cmd_desc_dma_handle, producer,
2137                     1, adapter->MaxTxDescCount, sizeof (cmdDescType0_t),
2138                     DDI_DMA_SYNC_FORDEV);
2139                 producer = get_next_index(producer, adapter->MaxTxDescCount);
2140                 i++;
2141         } while (i != nr_elements);
2142 
2143         adapter->cmdProducer = adapter->ahw.cmdProducer = producer;
2144         adapter->freecmds -= i;
2145 
2146         unm_nic_update_cmd_producer(adapter, producer);
2147 
2148         UNM_SPIN_UNLOCK(&adapter->tx_lock);
2149         return (0);
2150 }
2151 
2152 typedef struct {
2153         u64     qhdr, req_hdr, words[6];
2154 } nx_nic_req_t;
2155 
2156 typedef struct {
2157         u8      op, tag, mac_addr[6];
2158 } nx_mac_req_t;
2159 
2160 static void
2161 nx_p3_sre_macaddr_change(unm_adapter *adapter, u8 *addr, u8 op)
2162 {
2163         nx_nic_req_t    req;
2164         nx_mac_req_t    mac_req;
2165         int             rv;
2166 
2167         (void) memset(&req, 0, sizeof (nx_nic_req_t));
2168         req.qhdr |= (NX_NIC_REQUEST << 23);
2169         req.req_hdr |= NX_MAC_EVENT;
2170         req.req_hdr |= ((u64)adapter->portnum << 16);
2171         mac_req.op = op;
2172         (void) memcpy(&mac_req.mac_addr, addr, 6);
2173         req.words[0] = HOST_TO_LE_64(*(u64 *)(uintptr_t)&mac_req);
2174 
2175         rv = nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1);
2176         if (rv != 0)
2177                 cmn_err(CE_WARN, "%s%d: Could not send mac update\n",
2178                     adapter->name, adapter->instance);
2179 }
2180 
2181 static int
2182 nx_p3_nic_set_promisc(unm_adapter *adapter, u32 mode)
2183 {
2184         nx_nic_req_t    req;
2185 
2186         (void) memset(&req, 0, sizeof (nx_nic_req_t));
2187 
2188         req.qhdr |= (NX_HOST_REQUEST << 23);
2189         req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE;
2190         req.req_hdr |= ((u64)adapter->portnum << 16);
2191         req.words[0] = HOST_TO_LE_64(mode);
2192 
2193         return (nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1));
2194 }
2195 
2196 /*
2197  * Currently only invoked at interface initialization time
2198  */
2199 void
2200 nx_p3_nic_set_multi(unm_adapter *adapter)
2201 {
2202         u8      bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2203 
2204         if (nx_p3_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL))
2205                 cmn_err(CE_WARN, "Could not set promisc mode\n");
2206 
2207         nx_p3_sre_macaddr_change(adapter, adapter->mac_addr, NETXEN_MAC_ADD);
2208         nx_p3_sre_macaddr_change(adapter, bcast_addr, NETXEN_MAC_ADD);
2209 }