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