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