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