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