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), ®, 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 }