Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/pciex/pcie.c
+++ new/usr/src/uts/common/io/pciex/pcie.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 #include <sys/sysmacros.h>
27 27 #include <sys/types.h>
28 28 #include <sys/kmem.h>
29 29 #include <sys/modctl.h>
30 30 #include <sys/ddi.h>
31 31 #include <sys/sunddi.h>
32 32 #include <sys/sunndi.h>
33 33 #include <sys/fm/protocol.h>
34 34 #include <sys/fm/util.h>
35 35 #include <sys/promif.h>
36 36 #include <sys/disp.h>
37 37 #include <sys/stat.h>
38 38 #include <sys/file.h>
39 39 #include <sys/pci_cap.h>
40 40 #include <sys/pci_impl.h>
41 41 #include <sys/pcie_impl.h>
42 42 #include <sys/hotplug/pci/pcie_hp.h>
43 43 #include <sys/hotplug/pci/pciehpc.h>
44 44 #include <sys/hotplug/pci/pcishpc.h>
45 45 #include <sys/hotplug/pci/pcicfg.h>
46 46 #include <sys/pci_cfgacc.h>
47 47
48 48 /* Local functions prototypes */
49 49 static void pcie_init_pfd(dev_info_t *);
50 50 static void pcie_fini_pfd(dev_info_t *);
51 51
52 52 #if defined(__i386) || defined(__amd64)
53 53 static void pcie_check_io_mem_range(ddi_acc_handle_t, boolean_t *, boolean_t *);
54 54 #endif /* defined(__i386) || defined(__amd64) */
55 55
56 56 #ifdef DEBUG
57 57 uint_t pcie_debug_flags = 0;
58 58 static void pcie_print_bus(pcie_bus_t *bus_p);
59 59 void pcie_dbg(char *fmt, ...);
60 60 #endif /* DEBUG */
61 61
62 62 /* Variable to control default PCI-Express config settings */
63 63 ushort_t pcie_command_default =
64 64 PCI_COMM_SERR_ENABLE |
65 65 PCI_COMM_WAIT_CYC_ENAB |
66 66 PCI_COMM_PARITY_DETECT |
67 67 PCI_COMM_ME |
68 68 PCI_COMM_MAE |
69 69 PCI_COMM_IO;
70 70
71 71 /* xxx_fw are bits that are controlled by FW and should not be modified */
72 72 ushort_t pcie_command_default_fw =
73 73 PCI_COMM_SPEC_CYC |
74 74 PCI_COMM_MEMWR_INVAL |
75 75 PCI_COMM_PALETTE_SNOOP |
76 76 PCI_COMM_WAIT_CYC_ENAB |
77 77 0xF800; /* Reserved Bits */
78 78
79 79 ushort_t pcie_bdg_command_default_fw =
80 80 PCI_BCNF_BCNTRL_ISA_ENABLE |
81 81 PCI_BCNF_BCNTRL_VGA_ENABLE |
82 82 0xF000; /* Reserved Bits */
83 83
84 84 /* PCI-Express Base error defaults */
85 85 ushort_t pcie_base_err_default =
86 86 PCIE_DEVCTL_CE_REPORTING_EN |
87 87 PCIE_DEVCTL_NFE_REPORTING_EN |
88 88 PCIE_DEVCTL_FE_REPORTING_EN |
89 89 PCIE_DEVCTL_UR_REPORTING_EN;
90 90
91 91 /* PCI-Express Device Control Register */
92 92 uint16_t pcie_devctl_default = PCIE_DEVCTL_RO_EN |
93 93 PCIE_DEVCTL_MAX_READ_REQ_512;
94 94
95 95 /* PCI-Express AER Root Control Register */
96 96 #define PCIE_ROOT_SYS_ERR (PCIE_ROOTCTL_SYS_ERR_ON_CE_EN | \
97 97 PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | \
98 98 PCIE_ROOTCTL_SYS_ERR_ON_FE_EN)
99 99
100 100 ushort_t pcie_root_ctrl_default =
101 101 PCIE_ROOTCTL_SYS_ERR_ON_CE_EN |
102 102 PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN |
103 103 PCIE_ROOTCTL_SYS_ERR_ON_FE_EN;
104 104
105 105 /* PCI-Express Root Error Command Register */
106 106 ushort_t pcie_root_error_cmd_default =
107 107 PCIE_AER_RE_CMD_CE_REP_EN |
108 108 PCIE_AER_RE_CMD_NFE_REP_EN |
109 109 PCIE_AER_RE_CMD_FE_REP_EN;
110 110
111 111 /* ECRC settings in the PCIe AER Control Register */
112 112 uint32_t pcie_ecrc_value =
113 113 PCIE_AER_CTL_ECRC_GEN_ENA |
114 114 PCIE_AER_CTL_ECRC_CHECK_ENA;
115 115
116 116 /*
117 117 * If a particular platform wants to disable certain errors such as UR/MA,
118 118 * instead of using #defines have the platform's PCIe Root Complex driver set
119 119 * these masks using the pcie_get_XXX_mask and pcie_set_XXX_mask functions. For
120 120 * x86 the closest thing to a PCIe root complex driver is NPE. For SPARC the
121 121 * closest PCIe root complex driver is PX.
122 122 *
123 123 * pcie_serr_disable_flag : disable SERR only (in RCR and command reg) x86
124 124 * systems may want to disable SERR in general. For root ports, enabling SERR
125 125 * causes NMIs which are not handled and results in a watchdog timeout error.
126 126 */
127 127 uint32_t pcie_aer_uce_mask = 0; /* AER UE Mask */
128 128 uint32_t pcie_aer_ce_mask = 0; /* AER CE Mask */
129 129 uint32_t pcie_aer_suce_mask = 0; /* AER Secondary UE Mask */
130 130 uint32_t pcie_serr_disable_flag = 0; /* Disable SERR */
131 131
132 132 /* Default severities needed for eversholt. Error handling doesn't care */
133 133 uint32_t pcie_aer_uce_severity = PCIE_AER_UCE_MTLP | PCIE_AER_UCE_RO | \
134 134 PCIE_AER_UCE_FCP | PCIE_AER_UCE_SD | PCIE_AER_UCE_DLP | \
135 135 PCIE_AER_UCE_TRAINING;
136 136 uint32_t pcie_aer_suce_severity = PCIE_AER_SUCE_SERR_ASSERT | \
137 137 PCIE_AER_SUCE_UC_ADDR_ERR | PCIE_AER_SUCE_UC_ATTR_ERR | \
138 138 PCIE_AER_SUCE_USC_MSG_DATA_ERR;
139 139
140 140 int pcie_max_mps = PCIE_DEVCTL_MAX_PAYLOAD_4096 >> 5;
141 141 int pcie_disable_ari = 0;
142 142
143 143 static void pcie_scan_mps(dev_info_t *rc_dip, dev_info_t *dip,
144 144 int *max_supported);
145 145 static int pcie_get_max_supported(dev_info_t *dip, void *arg);
146 146 static int pcie_map_phys(dev_info_t *dip, pci_regspec_t *phys_spec,
147 147 caddr_t *addrp, ddi_acc_handle_t *handlep);
148 148 static void pcie_unmap_phys(ddi_acc_handle_t *handlep, pci_regspec_t *ph);
149 149
150 150 dev_info_t *pcie_get_rc_dip(dev_info_t *dip);
151 151
152 152 /*
↓ open down ↓ |
152 lines elided |
↑ open up ↑ |
153 153 * modload support
154 154 */
155 155
156 156 static struct modlmisc modlmisc = {
157 157 &mod_miscops, /* Type of module */
158 158 "PCI Express Framework Module"
159 159 };
160 160
161 161 static struct modlinkage modlinkage = {
162 162 MODREV_1,
163 - (void *)&modlmisc,
164 - NULL
163 + { (void *)&modlmisc, NULL }
165 164 };
166 165
167 166 /*
168 167 * Global Variables needed for a non-atomic version of ddi_fm_ereport_post.
169 168 * Currently used to send the pci.fabric ereports whose payload depends on the
170 169 * type of PCI device it is being sent for.
171 170 */
172 171 char *pcie_nv_buf;
173 172 nv_alloc_t *pcie_nvap;
174 173 nvlist_t *pcie_nvl;
175 174
176 175 int
177 176 _init(void)
178 177 {
179 178 int rval;
180 179
181 180 pcie_nv_buf = kmem_alloc(ERPT_DATA_SZ, KM_SLEEP);
182 181 pcie_nvap = fm_nva_xcreate(pcie_nv_buf, ERPT_DATA_SZ);
183 182 pcie_nvl = fm_nvlist_create(pcie_nvap);
184 183
185 184 if ((rval = mod_install(&modlinkage)) != 0) {
186 185 fm_nvlist_destroy(pcie_nvl, FM_NVA_RETAIN);
187 186 fm_nva_xdestroy(pcie_nvap);
188 187 kmem_free(pcie_nv_buf, ERPT_DATA_SZ);
189 188 }
190 189 return (rval);
191 190 }
192 191
193 192 int
194 193 _fini()
195 194 {
196 195 int rval;
197 196
198 197 if ((rval = mod_remove(&modlinkage)) == 0) {
199 198 fm_nvlist_destroy(pcie_nvl, FM_NVA_RETAIN);
200 199 fm_nva_xdestroy(pcie_nvap);
201 200 kmem_free(pcie_nv_buf, ERPT_DATA_SZ);
202 201 }
203 202 return (rval);
204 203 }
205 204
206 205 int
207 206 _info(struct modinfo *modinfop)
208 207 {
209 208 return (mod_info(&modlinkage, modinfop));
210 209 }
211 210
212 211 /* ARGSUSED */
213 212 int
214 213 pcie_init(dev_info_t *dip, caddr_t arg)
215 214 {
216 215 int ret = DDI_SUCCESS;
217 216
218 217 /*
219 218 * Create a "devctl" minor node to support DEVCTL_DEVICE_*
220 219 * and DEVCTL_BUS_* ioctls to this bus.
221 220 */
222 221 if ((ret = ddi_create_minor_node(dip, "devctl", S_IFCHR,
223 222 PCI_MINOR_NUM(ddi_get_instance(dip), PCI_DEVCTL_MINOR),
224 223 DDI_NT_NEXUS, 0)) != DDI_SUCCESS) {
225 224 PCIE_DBG("Failed to create devctl minor node for %s%d\n",
226 225 ddi_driver_name(dip), ddi_get_instance(dip));
227 226
228 227 return (ret);
229 228 }
230 229
231 230 if ((ret = pcie_hp_init(dip, arg)) != DDI_SUCCESS) {
232 231 /*
233 232 * On some x86 platforms, we observed unexpected hotplug
234 233 * initialization failures in recent years. The known cause
235 234 * is a hardware issue: while the problem PCI bridges have
236 235 * the Hotplug Capable registers set, the machine actually
237 236 * does not implement the expected ACPI object.
238 237 *
239 238 * We don't want to stop PCI driver attach and system boot
240 239 * just because of this hotplug initialization failure.
241 240 * Continue with a debug message printed.
242 241 */
243 242 PCIE_DBG("%s%d: Failed setting hotplug framework\n",
244 243 ddi_driver_name(dip), ddi_get_instance(dip));
245 244
246 245 #if defined(__sparc)
247 246 ddi_remove_minor_node(dip, "devctl");
248 247
249 248 return (ret);
250 249 #endif /* defined(__sparc) */
251 250 }
252 251
253 252 return (DDI_SUCCESS);
254 253 }
255 254
256 255 /* ARGSUSED */
257 256 int
258 257 pcie_uninit(dev_info_t *dip)
259 258 {
260 259 int ret = DDI_SUCCESS;
261 260
262 261 if (pcie_ari_is_enabled(dip) == PCIE_ARI_FORW_ENABLED)
263 262 (void) pcie_ari_disable(dip);
264 263
265 264 if ((ret = pcie_hp_uninit(dip)) != DDI_SUCCESS) {
266 265 PCIE_DBG("Failed to uninitialize hotplug for %s%d\n",
267 266 ddi_driver_name(dip), ddi_get_instance(dip));
268 267
269 268 return (ret);
270 269 }
271 270
272 271 ddi_remove_minor_node(dip, "devctl");
273 272
274 273 return (ret);
275 274 }
276 275
277 276 /*
278 277 * PCIe module interface for enabling hotplug interrupt.
279 278 *
280 279 * It should be called after pcie_init() is done and bus driver's
281 280 * interrupt handlers have being attached.
282 281 */
283 282 int
284 283 pcie_hpintr_enable(dev_info_t *dip)
285 284 {
286 285 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
287 286 pcie_hp_ctrl_t *ctrl_p = PCIE_GET_HP_CTRL(dip);
288 287
289 288 if (PCIE_IS_PCIE_HOTPLUG_ENABLED(bus_p)) {
290 289 (void) (ctrl_p->hc_ops.enable_hpc_intr)(ctrl_p);
291 290 } else if (PCIE_IS_PCI_HOTPLUG_ENABLED(bus_p)) {
292 291 (void) pcishpc_enable_irqs(ctrl_p);
293 292 }
294 293 return (DDI_SUCCESS);
295 294 }
296 295
297 296 /*
298 297 * PCIe module interface for disabling hotplug interrupt.
299 298 *
300 299 * It should be called before pcie_uninit() is called and bus driver's
301 300 * interrupt handlers is dettached.
302 301 */
303 302 int
304 303 pcie_hpintr_disable(dev_info_t *dip)
305 304 {
306 305 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
307 306 pcie_hp_ctrl_t *ctrl_p = PCIE_GET_HP_CTRL(dip);
308 307
309 308 if (PCIE_IS_PCIE_HOTPLUG_ENABLED(bus_p)) {
310 309 (void) (ctrl_p->hc_ops.disable_hpc_intr)(ctrl_p);
311 310 } else if (PCIE_IS_PCI_HOTPLUG_ENABLED(bus_p)) {
312 311 (void) pcishpc_disable_irqs(ctrl_p);
313 312 }
314 313 return (DDI_SUCCESS);
315 314 }
316 315
317 316 /* ARGSUSED */
318 317 int
319 318 pcie_intr(dev_info_t *dip)
320 319 {
321 320 return (pcie_hp_intr(dip));
322 321 }
323 322
324 323 /* ARGSUSED */
325 324 int
326 325 pcie_open(dev_info_t *dip, dev_t *devp, int flags, int otyp, cred_t *credp)
327 326 {
328 327 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
329 328
330 329 /*
331 330 * Make sure the open is for the right file type.
332 331 */
333 332 if (otyp != OTYP_CHR)
334 333 return (EINVAL);
335 334
336 335 /*
337 336 * Handle the open by tracking the device state.
338 337 */
339 338 if ((bus_p->bus_soft_state == PCI_SOFT_STATE_OPEN_EXCL) ||
340 339 ((flags & FEXCL) &&
341 340 (bus_p->bus_soft_state != PCI_SOFT_STATE_CLOSED))) {
342 341 return (EBUSY);
343 342 }
344 343
345 344 if (flags & FEXCL)
346 345 bus_p->bus_soft_state = PCI_SOFT_STATE_OPEN_EXCL;
347 346 else
348 347 bus_p->bus_soft_state = PCI_SOFT_STATE_OPEN;
349 348
350 349 return (0);
351 350 }
352 351
353 352 /* ARGSUSED */
354 353 int
355 354 pcie_close(dev_info_t *dip, dev_t dev, int flags, int otyp, cred_t *credp)
356 355 {
357 356 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
358 357
359 358 if (otyp != OTYP_CHR)
360 359 return (EINVAL);
361 360
362 361 bus_p->bus_soft_state = PCI_SOFT_STATE_CLOSED;
363 362
364 363 return (0);
365 364 }
366 365
367 366 /* ARGSUSED */
368 367 int
369 368 pcie_ioctl(dev_info_t *dip, dev_t dev, int cmd, intptr_t arg, int mode,
370 369 cred_t *credp, int *rvalp)
371 370 {
372 371 struct devctl_iocdata *dcp;
373 372 uint_t bus_state;
374 373 int rv = DDI_SUCCESS;
375 374
376 375 /*
377 376 * We can use the generic implementation for devctl ioctl
378 377 */
379 378 switch (cmd) {
380 379 case DEVCTL_DEVICE_GETSTATE:
381 380 case DEVCTL_DEVICE_ONLINE:
382 381 case DEVCTL_DEVICE_OFFLINE:
383 382 case DEVCTL_BUS_GETSTATE:
384 383 return (ndi_devctl_ioctl(dip, cmd, arg, mode, 0));
385 384 default:
386 385 break;
387 386 }
388 387
389 388 /*
390 389 * read devctl ioctl data
391 390 */
392 391 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
393 392 return (EFAULT);
394 393
395 394 switch (cmd) {
396 395 case DEVCTL_BUS_QUIESCE:
397 396 if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS)
398 397 if (bus_state == BUS_QUIESCED)
399 398 break;
400 399 (void) ndi_set_bus_state(dip, BUS_QUIESCED);
401 400 break;
402 401 case DEVCTL_BUS_UNQUIESCE:
403 402 if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS)
404 403 if (bus_state == BUS_ACTIVE)
405 404 break;
406 405 (void) ndi_set_bus_state(dip, BUS_ACTIVE);
407 406 break;
408 407 case DEVCTL_BUS_RESET:
409 408 case DEVCTL_BUS_RESETALL:
410 409 case DEVCTL_DEVICE_RESET:
411 410 rv = ENOTSUP;
412 411 break;
413 412 default:
414 413 rv = ENOTTY;
415 414 }
416 415
417 416 ndi_dc_freehdl(dcp);
418 417 return (rv);
419 418 }
420 419
421 420 /* ARGSUSED */
422 421 int
423 422 pcie_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
424 423 int flags, char *name, caddr_t valuep, int *lengthp)
425 424 {
426 425 if (dev == DDI_DEV_T_ANY)
427 426 goto skip;
428 427
429 428 if (PCIE_IS_HOTPLUG_CAPABLE(dip) &&
430 429 strcmp(name, "pci-occupant") == 0) {
431 430 int pci_dev = PCI_MINOR_NUM_TO_PCI_DEVNUM(getminor(dev));
432 431
433 432 pcie_hp_create_occupant_props(dip, dev, pci_dev);
434 433 }
435 434
436 435 skip:
437 436 return (ddi_prop_op(dev, dip, prop_op, flags, name, valuep, lengthp));
438 437 }
439 438
440 439 int
441 440 pcie_init_cfghdl(dev_info_t *cdip)
442 441 {
443 442 pcie_bus_t *bus_p;
444 443 ddi_acc_handle_t eh = NULL;
445 444
446 445 bus_p = PCIE_DIP2BUS(cdip);
447 446 if (bus_p == NULL)
448 447 return (DDI_FAILURE);
449 448
450 449 /* Create an config access special to error handling */
451 450 if (pci_config_setup(cdip, &eh) != DDI_SUCCESS) {
452 451 cmn_err(CE_WARN, "Cannot setup config access"
453 452 " for BDF 0x%x\n", bus_p->bus_bdf);
454 453 return (DDI_FAILURE);
455 454 }
456 455
457 456 bus_p->bus_cfg_hdl = eh;
458 457 return (DDI_SUCCESS);
459 458 }
460 459
461 460 void
462 461 pcie_fini_cfghdl(dev_info_t *cdip)
463 462 {
464 463 pcie_bus_t *bus_p = PCIE_DIP2BUS(cdip);
465 464
466 465 pci_config_teardown(&bus_p->bus_cfg_hdl);
467 466 }
468 467
469 468 /*
470 469 * PCI-Express child device initialization.
471 470 * This function enables generic pci-express interrupts and error
472 471 * handling.
473 472 *
474 473 * @param pdip root dip (root nexus's dip)
475 474 * @param cdip child's dip (device's dip)
476 475 * @return DDI_SUCCESS or DDI_FAILURE
477 476 */
478 477 /* ARGSUSED */
479 478 int
480 479 pcie_initchild(dev_info_t *cdip)
481 480 {
482 481 uint16_t tmp16, reg16;
483 482 pcie_bus_t *bus_p;
484 483 uint32_t devid, venid;
485 484
486 485 bus_p = PCIE_DIP2BUS(cdip);
487 486 if (bus_p == NULL) {
488 487 PCIE_DBG("%s: BUS not found.\n",
489 488 ddi_driver_name(cdip));
490 489
491 490 return (DDI_FAILURE);
492 491 }
493 492
494 493 if (pcie_init_cfghdl(cdip) != DDI_SUCCESS)
495 494 return (DDI_FAILURE);
496 495
497 496 /*
498 497 * Update pcie_bus_t with real Vendor Id Device Id.
499 498 *
500 499 * For assigned devices in IOV environment, the OBP will return
501 500 * faked device id/vendor id on configration read and for both
502 501 * properties in root domain. translate_devid() function will
503 502 * update the properties with real device-id/vendor-id on such
504 503 * platforms, so that we can utilize the properties here to get
505 504 * real device-id/vendor-id and overwrite the faked ids.
506 505 *
507 506 * For unassigned devices or devices in non-IOV environment, the
508 507 * operation below won't make a difference.
509 508 *
510 509 * The IOV implementation only supports assignment of PCIE
511 510 * endpoint devices. Devices under pci-pci bridges don't need
512 511 * operation like this.
513 512 */
514 513 devid = ddi_prop_get_int(DDI_DEV_T_ANY, cdip, DDI_PROP_DONTPASS,
515 514 "device-id", -1);
516 515 venid = ddi_prop_get_int(DDI_DEV_T_ANY, cdip, DDI_PROP_DONTPASS,
517 516 "vendor-id", -1);
518 517 bus_p->bus_dev_ven_id = (devid << 16) | (venid & 0xffff);
519 518
520 519 /* Clear the device's status register */
521 520 reg16 = PCIE_GET(16, bus_p, PCI_CONF_STAT);
522 521 PCIE_PUT(16, bus_p, PCI_CONF_STAT, reg16);
523 522
524 523 /* Setup the device's command register */
525 524 reg16 = PCIE_GET(16, bus_p, PCI_CONF_COMM);
526 525 tmp16 = (reg16 & pcie_command_default_fw) | pcie_command_default;
527 526
528 527 #if defined(__i386) || defined(__amd64)
529 528 boolean_t empty_io_range = B_FALSE;
530 529 boolean_t empty_mem_range = B_FALSE;
531 530 /*
532 531 * Check for empty IO and Mem ranges on bridges. If so disable IO/Mem
533 532 * access as it can cause a hang if enabled.
534 533 */
535 534 pcie_check_io_mem_range(bus_p->bus_cfg_hdl, &empty_io_range,
536 535 &empty_mem_range);
537 536 if ((empty_io_range == B_TRUE) &&
538 537 (pcie_command_default & PCI_COMM_IO)) {
539 538 tmp16 &= ~PCI_COMM_IO;
540 539 PCIE_DBG("No I/O range found for %s, bdf 0x%x\n",
541 540 ddi_driver_name(cdip), bus_p->bus_bdf);
542 541 }
543 542 if ((empty_mem_range == B_TRUE) &&
544 543 (pcie_command_default & PCI_COMM_MAE)) {
545 544 tmp16 &= ~PCI_COMM_MAE;
546 545 PCIE_DBG("No Mem range found for %s, bdf 0x%x\n",
547 546 ddi_driver_name(cdip), bus_p->bus_bdf);
548 547 }
549 548 #endif /* defined(__i386) || defined(__amd64) */
550 549
551 550 if (pcie_serr_disable_flag && PCIE_IS_PCIE(bus_p))
552 551 tmp16 &= ~PCI_COMM_SERR_ENABLE;
553 552
554 553 PCIE_PUT(16, bus_p, PCI_CONF_COMM, tmp16);
555 554 PCIE_DBG_CFG(cdip, bus_p, "COMMAND", 16, PCI_CONF_COMM, reg16);
556 555
557 556 /*
558 557 * If the device has a bus control register then program it
559 558 * based on the settings in the command register.
560 559 */
561 560 if (PCIE_IS_BDG(bus_p)) {
562 561 /* Clear the device's secondary status register */
563 562 reg16 = PCIE_GET(16, bus_p, PCI_BCNF_SEC_STATUS);
564 563 PCIE_PUT(16, bus_p, PCI_BCNF_SEC_STATUS, reg16);
565 564
566 565 /* Setup the device's secondary command register */
567 566 reg16 = PCIE_GET(16, bus_p, PCI_BCNF_BCNTRL);
568 567 tmp16 = (reg16 & pcie_bdg_command_default_fw);
569 568
570 569 tmp16 |= PCI_BCNF_BCNTRL_SERR_ENABLE;
571 570 /*
572 571 * Workaround for this Nvidia bridge. Don't enable the SERR
573 572 * enable bit in the bridge control register as it could lead to
574 573 * bogus NMIs.
575 574 */
576 575 if (bus_p->bus_dev_ven_id == 0x037010DE)
577 576 tmp16 &= ~PCI_BCNF_BCNTRL_SERR_ENABLE;
578 577
579 578 if (pcie_command_default & PCI_COMM_PARITY_DETECT)
580 579 tmp16 |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
581 580
582 581 /*
583 582 * Enable Master Abort Mode only if URs have not been masked.
584 583 * For PCI and PCIe-PCI bridges, enabling this bit causes a
585 584 * Master Aborts/UR to be forwarded as a UR/TA or SERR. If this
586 585 * bit is masked, posted requests are dropped and non-posted
587 586 * requests are returned with -1.
588 587 */
589 588 if (pcie_aer_uce_mask & PCIE_AER_UCE_UR)
590 589 tmp16 &= ~PCI_BCNF_BCNTRL_MAST_AB_MODE;
591 590 else
592 591 tmp16 |= PCI_BCNF_BCNTRL_MAST_AB_MODE;
593 592 PCIE_PUT(16, bus_p, PCI_BCNF_BCNTRL, tmp16);
594 593 PCIE_DBG_CFG(cdip, bus_p, "SEC CMD", 16, PCI_BCNF_BCNTRL,
595 594 reg16);
596 595 }
597 596
598 597 if (PCIE_IS_PCIE(bus_p)) {
599 598 /* Setup PCIe device control register */
600 599 reg16 = PCIE_CAP_GET(16, bus_p, PCIE_DEVCTL);
601 600 /* note: MPS/MRRS are initialized in pcie_initchild_mps() */
602 601 tmp16 = (reg16 & (PCIE_DEVCTL_MAX_READ_REQ_MASK |
603 602 PCIE_DEVCTL_MAX_PAYLOAD_MASK)) |
604 603 (pcie_devctl_default & ~(PCIE_DEVCTL_MAX_READ_REQ_MASK |
605 604 PCIE_DEVCTL_MAX_PAYLOAD_MASK));
606 605 PCIE_CAP_PUT(16, bus_p, PCIE_DEVCTL, tmp16);
607 606 PCIE_DBG_CAP(cdip, bus_p, "DEVCTL", 16, PCIE_DEVCTL, reg16);
608 607
609 608 /* Enable PCIe errors */
610 609 pcie_enable_errors(cdip);
611 610 }
612 611
613 612 bus_p->bus_ari = B_FALSE;
614 613 if ((pcie_ari_is_enabled(ddi_get_parent(cdip))
615 614 == PCIE_ARI_FORW_ENABLED) && (pcie_ari_device(cdip)
616 615 == PCIE_ARI_DEVICE)) {
617 616 bus_p->bus_ari = B_TRUE;
618 617 }
619 618
620 619 if (pcie_initchild_mps(cdip) == DDI_FAILURE) {
621 620 pcie_fini_cfghdl(cdip);
622 621 return (DDI_FAILURE);
623 622 }
624 623
625 624 return (DDI_SUCCESS);
626 625 }
627 626
628 627 static void
629 628 pcie_init_pfd(dev_info_t *dip)
630 629 {
631 630 pf_data_t *pfd_p = PCIE_ZALLOC(pf_data_t);
632 631 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
633 632
634 633 PCIE_DIP2PFD(dip) = pfd_p;
635 634
636 635 pfd_p->pe_bus_p = bus_p;
637 636 pfd_p->pe_severity_flags = 0;
638 637 pfd_p->pe_orig_severity_flags = 0;
639 638 pfd_p->pe_lock = B_FALSE;
640 639 pfd_p->pe_valid = B_FALSE;
641 640
642 641 /* Allocate the root fault struct for both RC and RP */
643 642 if (PCIE_IS_ROOT(bus_p)) {
644 643 PCIE_ROOT_FAULT(pfd_p) = PCIE_ZALLOC(pf_root_fault_t);
645 644 PCIE_ROOT_FAULT(pfd_p)->scan_bdf = PCIE_INVALID_BDF;
646 645 PCIE_ROOT_EH_SRC(pfd_p) = PCIE_ZALLOC(pf_root_eh_src_t);
647 646 }
648 647
649 648 PCI_ERR_REG(pfd_p) = PCIE_ZALLOC(pf_pci_err_regs_t);
650 649 PFD_AFFECTED_DEV(pfd_p) = PCIE_ZALLOC(pf_affected_dev_t);
651 650 PFD_AFFECTED_DEV(pfd_p)->pe_affected_bdf = PCIE_INVALID_BDF;
652 651
653 652 if (PCIE_IS_BDG(bus_p))
654 653 PCI_BDG_ERR_REG(pfd_p) = PCIE_ZALLOC(pf_pci_bdg_err_regs_t);
655 654
656 655 if (PCIE_IS_PCIE(bus_p)) {
657 656 PCIE_ERR_REG(pfd_p) = PCIE_ZALLOC(pf_pcie_err_regs_t);
658 657
659 658 if (PCIE_IS_RP(bus_p))
660 659 PCIE_RP_REG(pfd_p) =
661 660 PCIE_ZALLOC(pf_pcie_rp_err_regs_t);
662 661
663 662 PCIE_ADV_REG(pfd_p) = PCIE_ZALLOC(pf_pcie_adv_err_regs_t);
664 663 PCIE_ADV_REG(pfd_p)->pcie_ue_tgt_bdf = PCIE_INVALID_BDF;
665 664
666 665 if (PCIE_IS_RP(bus_p)) {
667 666 PCIE_ADV_RP_REG(pfd_p) =
668 667 PCIE_ZALLOC(pf_pcie_adv_rp_err_regs_t);
669 668 PCIE_ADV_RP_REG(pfd_p)->pcie_rp_ce_src_id =
670 669 PCIE_INVALID_BDF;
671 670 PCIE_ADV_RP_REG(pfd_p)->pcie_rp_ue_src_id =
672 671 PCIE_INVALID_BDF;
673 672 } else if (PCIE_IS_PCIE_BDG(bus_p)) {
674 673 PCIE_ADV_BDG_REG(pfd_p) =
675 674 PCIE_ZALLOC(pf_pcie_adv_bdg_err_regs_t);
676 675 PCIE_ADV_BDG_REG(pfd_p)->pcie_sue_tgt_bdf =
677 676 PCIE_INVALID_BDF;
678 677 }
679 678
680 679 if (PCIE_IS_PCIE_BDG(bus_p) && PCIE_IS_PCIX(bus_p)) {
681 680 PCIX_BDG_ERR_REG(pfd_p) =
682 681 PCIE_ZALLOC(pf_pcix_bdg_err_regs_t);
683 682
684 683 if (PCIX_ECC_VERSION_CHECK(bus_p)) {
685 684 PCIX_BDG_ECC_REG(pfd_p, 0) =
686 685 PCIE_ZALLOC(pf_pcix_ecc_regs_t);
687 686 PCIX_BDG_ECC_REG(pfd_p, 1) =
688 687 PCIE_ZALLOC(pf_pcix_ecc_regs_t);
689 688 }
690 689 }
691 690 } else if (PCIE_IS_PCIX(bus_p)) {
692 691 if (PCIE_IS_BDG(bus_p)) {
693 692 PCIX_BDG_ERR_REG(pfd_p) =
694 693 PCIE_ZALLOC(pf_pcix_bdg_err_regs_t);
695 694
696 695 if (PCIX_ECC_VERSION_CHECK(bus_p)) {
697 696 PCIX_BDG_ECC_REG(pfd_p, 0) =
698 697 PCIE_ZALLOC(pf_pcix_ecc_regs_t);
699 698 PCIX_BDG_ECC_REG(pfd_p, 1) =
700 699 PCIE_ZALLOC(pf_pcix_ecc_regs_t);
701 700 }
702 701 } else {
703 702 PCIX_ERR_REG(pfd_p) = PCIE_ZALLOC(pf_pcix_err_regs_t);
704 703
705 704 if (PCIX_ECC_VERSION_CHECK(bus_p))
706 705 PCIX_ECC_REG(pfd_p) =
707 706 PCIE_ZALLOC(pf_pcix_ecc_regs_t);
708 707 }
709 708 }
710 709 }
711 710
712 711 static void
713 712 pcie_fini_pfd(dev_info_t *dip)
714 713 {
715 714 pf_data_t *pfd_p = PCIE_DIP2PFD(dip);
716 715 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
717 716
718 717 if (PCIE_IS_PCIE(bus_p)) {
719 718 if (PCIE_IS_PCIE_BDG(bus_p) && PCIE_IS_PCIX(bus_p)) {
720 719 if (PCIX_ECC_VERSION_CHECK(bus_p)) {
721 720 kmem_free(PCIX_BDG_ECC_REG(pfd_p, 0),
722 721 sizeof (pf_pcix_ecc_regs_t));
723 722 kmem_free(PCIX_BDG_ECC_REG(pfd_p, 1),
724 723 sizeof (pf_pcix_ecc_regs_t));
725 724 }
726 725
727 726 kmem_free(PCIX_BDG_ERR_REG(pfd_p),
728 727 sizeof (pf_pcix_bdg_err_regs_t));
729 728 }
730 729
731 730 if (PCIE_IS_RP(bus_p))
732 731 kmem_free(PCIE_ADV_RP_REG(pfd_p),
733 732 sizeof (pf_pcie_adv_rp_err_regs_t));
734 733 else if (PCIE_IS_PCIE_BDG(bus_p))
735 734 kmem_free(PCIE_ADV_BDG_REG(pfd_p),
736 735 sizeof (pf_pcie_adv_bdg_err_regs_t));
737 736
738 737 kmem_free(PCIE_ADV_REG(pfd_p),
739 738 sizeof (pf_pcie_adv_err_regs_t));
740 739
741 740 if (PCIE_IS_RP(bus_p))
742 741 kmem_free(PCIE_RP_REG(pfd_p),
743 742 sizeof (pf_pcie_rp_err_regs_t));
744 743
745 744 kmem_free(PCIE_ERR_REG(pfd_p), sizeof (pf_pcie_err_regs_t));
746 745 } else if (PCIE_IS_PCIX(bus_p)) {
747 746 if (PCIE_IS_BDG(bus_p)) {
748 747 if (PCIX_ECC_VERSION_CHECK(bus_p)) {
749 748 kmem_free(PCIX_BDG_ECC_REG(pfd_p, 0),
750 749 sizeof (pf_pcix_ecc_regs_t));
751 750 kmem_free(PCIX_BDG_ECC_REG(pfd_p, 1),
752 751 sizeof (pf_pcix_ecc_regs_t));
753 752 }
754 753
755 754 kmem_free(PCIX_BDG_ERR_REG(pfd_p),
756 755 sizeof (pf_pcix_bdg_err_regs_t));
757 756 } else {
758 757 if (PCIX_ECC_VERSION_CHECK(bus_p))
759 758 kmem_free(PCIX_ECC_REG(pfd_p),
760 759 sizeof (pf_pcix_ecc_regs_t));
761 760
762 761 kmem_free(PCIX_ERR_REG(pfd_p),
763 762 sizeof (pf_pcix_err_regs_t));
764 763 }
765 764 }
766 765
767 766 if (PCIE_IS_BDG(bus_p))
768 767 kmem_free(PCI_BDG_ERR_REG(pfd_p),
769 768 sizeof (pf_pci_bdg_err_regs_t));
770 769
771 770 kmem_free(PFD_AFFECTED_DEV(pfd_p), sizeof (pf_affected_dev_t));
772 771 kmem_free(PCI_ERR_REG(pfd_p), sizeof (pf_pci_err_regs_t));
773 772
774 773 if (PCIE_IS_ROOT(bus_p)) {
775 774 kmem_free(PCIE_ROOT_FAULT(pfd_p), sizeof (pf_root_fault_t));
776 775 kmem_free(PCIE_ROOT_EH_SRC(pfd_p), sizeof (pf_root_eh_src_t));
777 776 }
778 777
779 778 kmem_free(PCIE_DIP2PFD(dip), sizeof (pf_data_t));
780 779
781 780 PCIE_DIP2PFD(dip) = NULL;
782 781 }
783 782
784 783
785 784 /*
786 785 * Special functions to allocate pf_data_t's for PCIe root complexes.
787 786 * Note: Root Complex not Root Port
788 787 */
789 788 void
790 789 pcie_rc_init_pfd(dev_info_t *dip, pf_data_t *pfd_p)
791 790 {
792 791 pfd_p->pe_bus_p = PCIE_DIP2DOWNBUS(dip);
793 792 pfd_p->pe_severity_flags = 0;
794 793 pfd_p->pe_orig_severity_flags = 0;
795 794 pfd_p->pe_lock = B_FALSE;
796 795 pfd_p->pe_valid = B_FALSE;
797 796
798 797 PCIE_ROOT_FAULT(pfd_p) = PCIE_ZALLOC(pf_root_fault_t);
799 798 PCIE_ROOT_FAULT(pfd_p)->scan_bdf = PCIE_INVALID_BDF;
800 799 PCIE_ROOT_EH_SRC(pfd_p) = PCIE_ZALLOC(pf_root_eh_src_t);
801 800 PCI_ERR_REG(pfd_p) = PCIE_ZALLOC(pf_pci_err_regs_t);
802 801 PFD_AFFECTED_DEV(pfd_p) = PCIE_ZALLOC(pf_affected_dev_t);
803 802 PFD_AFFECTED_DEV(pfd_p)->pe_affected_bdf = PCIE_INVALID_BDF;
804 803 PCI_BDG_ERR_REG(pfd_p) = PCIE_ZALLOC(pf_pci_bdg_err_regs_t);
805 804 PCIE_ERR_REG(pfd_p) = PCIE_ZALLOC(pf_pcie_err_regs_t);
806 805 PCIE_RP_REG(pfd_p) = PCIE_ZALLOC(pf_pcie_rp_err_regs_t);
807 806 PCIE_ADV_REG(pfd_p) = PCIE_ZALLOC(pf_pcie_adv_err_regs_t);
808 807 PCIE_ADV_RP_REG(pfd_p) = PCIE_ZALLOC(pf_pcie_adv_rp_err_regs_t);
809 808 PCIE_ADV_RP_REG(pfd_p)->pcie_rp_ce_src_id = PCIE_INVALID_BDF;
810 809 PCIE_ADV_RP_REG(pfd_p)->pcie_rp_ue_src_id = PCIE_INVALID_BDF;
811 810
812 811 PCIE_ADV_REG(pfd_p)->pcie_ue_sev = pcie_aer_uce_severity;
813 812 }
814 813
815 814 void
816 815 pcie_rc_fini_pfd(pf_data_t *pfd_p)
817 816 {
818 817 kmem_free(PCIE_ADV_RP_REG(pfd_p), sizeof (pf_pcie_adv_rp_err_regs_t));
819 818 kmem_free(PCIE_ADV_REG(pfd_p), sizeof (pf_pcie_adv_err_regs_t));
820 819 kmem_free(PCIE_RP_REG(pfd_p), sizeof (pf_pcie_rp_err_regs_t));
821 820 kmem_free(PCIE_ERR_REG(pfd_p), sizeof (pf_pcie_err_regs_t));
822 821 kmem_free(PCI_BDG_ERR_REG(pfd_p), sizeof (pf_pci_bdg_err_regs_t));
823 822 kmem_free(PFD_AFFECTED_DEV(pfd_p), sizeof (pf_affected_dev_t));
824 823 kmem_free(PCI_ERR_REG(pfd_p), sizeof (pf_pci_err_regs_t));
825 824 kmem_free(PCIE_ROOT_FAULT(pfd_p), sizeof (pf_root_fault_t));
826 825 kmem_free(PCIE_ROOT_EH_SRC(pfd_p), sizeof (pf_root_eh_src_t));
827 826 }
828 827
829 828 /*
830 829 * init pcie_bus_t for root complex
831 830 *
832 831 * Only a few of the fields in bus_t is valid for root complex.
833 832 * The fields that are bracketed are initialized in this routine:
834 833 *
835 834 * dev_info_t * <bus_dip>
836 835 * dev_info_t * bus_rp_dip
837 836 * ddi_acc_handle_t bus_cfg_hdl
838 837 * uint_t <bus_fm_flags>
839 838 * pcie_req_id_t bus_bdf
840 839 * pcie_req_id_t bus_rp_bdf
841 840 * uint32_t bus_dev_ven_id
842 841 * uint8_t bus_rev_id
843 842 * uint8_t <bus_hdr_type>
844 843 * uint16_t <bus_dev_type>
845 844 * uint8_t bus_bdg_secbus
846 845 * uint16_t bus_pcie_off
847 846 * uint16_t <bus_aer_off>
848 847 * uint16_t bus_pcix_off
849 848 * uint16_t bus_ecc_ver
850 849 * pci_bus_range_t bus_bus_range
851 850 * ppb_ranges_t * bus_addr_ranges
852 851 * int bus_addr_entries
853 852 * pci_regspec_t * bus_assigned_addr
854 853 * int bus_assigned_entries
855 854 * pf_data_t * bus_pfd
856 855 * pcie_domain_t * <bus_dom>
857 856 * int bus_mps
858 857 * uint64_t bus_cfgacc_base
859 858 * void * bus_plat_private
860 859 */
861 860 void
862 861 pcie_rc_init_bus(dev_info_t *dip)
863 862 {
864 863 pcie_bus_t *bus_p;
865 864
866 865 bus_p = (pcie_bus_t *)kmem_zalloc(sizeof (pcie_bus_t), KM_SLEEP);
867 866 bus_p->bus_dip = dip;
868 867 bus_p->bus_dev_type = PCIE_PCIECAP_DEV_TYPE_RC_PSEUDO;
869 868 bus_p->bus_hdr_type = PCI_HEADER_ONE;
870 869
871 870 /* Fake that there are AER logs */
872 871 bus_p->bus_aer_off = (uint16_t)-1;
873 872
874 873 /* Needed only for handle lookup */
875 874 bus_p->bus_fm_flags |= PF_FM_READY;
876 875
877 876 ndi_set_bus_private(dip, B_FALSE, DEVI_PORT_TYPE_PCI, bus_p);
878 877
879 878 PCIE_BUS2DOM(bus_p) = PCIE_ZALLOC(pcie_domain_t);
880 879 }
881 880
882 881 void
883 882 pcie_rc_fini_bus(dev_info_t *dip)
884 883 {
885 884 pcie_bus_t *bus_p = PCIE_DIP2DOWNBUS(dip);
886 885 ndi_set_bus_private(dip, B_FALSE, NULL, NULL);
887 886 kmem_free(PCIE_BUS2DOM(bus_p), sizeof (pcie_domain_t));
888 887 kmem_free(bus_p, sizeof (pcie_bus_t));
889 888 }
890 889
891 890 /*
892 891 * partially init pcie_bus_t for device (dip,bdf) for accessing pci
893 892 * config space
894 893 *
895 894 * This routine is invoked during boot, either after creating a devinfo node
896 895 * (x86 case) or during px driver attach (sparc case); it is also invoked
897 896 * in hotplug context after a devinfo node is created.
898 897 *
899 898 * The fields that are bracketed are initialized if flag PCIE_BUS_INITIAL
900 899 * is set:
901 900 *
902 901 * dev_info_t * <bus_dip>
903 902 * dev_info_t * <bus_rp_dip>
904 903 * ddi_acc_handle_t bus_cfg_hdl
905 904 * uint_t bus_fm_flags
906 905 * pcie_req_id_t <bus_bdf>
907 906 * pcie_req_id_t <bus_rp_bdf>
908 907 * uint32_t <bus_dev_ven_id>
909 908 * uint8_t <bus_rev_id>
910 909 * uint8_t <bus_hdr_type>
911 910 * uint16_t <bus_dev_type>
912 911 * uint8_t <bus_bdg_secbus
913 912 * uint16_t <bus_pcie_off>
914 913 * uint16_t <bus_aer_off>
915 914 * uint16_t <bus_pcix_off>
916 915 * uint16_t <bus_ecc_ver>
917 916 * pci_bus_range_t bus_bus_range
918 917 * ppb_ranges_t * bus_addr_ranges
919 918 * int bus_addr_entries
920 919 * pci_regspec_t * bus_assigned_addr
921 920 * int bus_assigned_entries
922 921 * pf_data_t * bus_pfd
923 922 * pcie_domain_t * bus_dom
924 923 * int bus_mps
925 924 * uint64_t bus_cfgacc_base
926 925 * void * bus_plat_private
927 926 *
928 927 * The fields that are bracketed are initialized if flag PCIE_BUS_FINAL
929 928 * is set:
930 929 *
931 930 * dev_info_t * bus_dip
932 931 * dev_info_t * bus_rp_dip
933 932 * ddi_acc_handle_t bus_cfg_hdl
934 933 * uint_t bus_fm_flags
935 934 * pcie_req_id_t bus_bdf
936 935 * pcie_req_id_t bus_rp_bdf
937 936 * uint32_t bus_dev_ven_id
938 937 * uint8_t bus_rev_id
939 938 * uint8_t bus_hdr_type
940 939 * uint16_t bus_dev_type
941 940 * uint8_t <bus_bdg_secbus>
942 941 * uint16_t bus_pcie_off
943 942 * uint16_t bus_aer_off
944 943 * uint16_t bus_pcix_off
945 944 * uint16_t bus_ecc_ver
946 945 * pci_bus_range_t <bus_bus_range>
947 946 * ppb_ranges_t * <bus_addr_ranges>
948 947 * int <bus_addr_entries>
949 948 * pci_regspec_t * <bus_assigned_addr>
950 949 * int <bus_assigned_entries>
951 950 * pf_data_t * <bus_pfd>
952 951 * pcie_domain_t * bus_dom
953 952 * int bus_mps
954 953 * uint64_t bus_cfgacc_base
955 954 * void * <bus_plat_private>
956 955 */
957 956
958 957 pcie_bus_t *
959 958 pcie_init_bus(dev_info_t *dip, pcie_req_id_t bdf, uint8_t flags)
960 959 {
961 960 uint16_t status, base, baseptr, num_cap;
962 961 uint32_t capid;
963 962 int range_size;
964 963 pcie_bus_t *bus_p;
965 964 dev_info_t *rcdip;
966 965 dev_info_t *pdip;
967 966 const char *errstr = NULL;
968 967
969 968 if (!(flags & PCIE_BUS_INITIAL))
970 969 goto initial_done;
971 970
972 971 bus_p = kmem_zalloc(sizeof (pcie_bus_t), KM_SLEEP);
973 972
974 973 bus_p->bus_dip = dip;
975 974 bus_p->bus_bdf = bdf;
976 975
977 976 rcdip = pcie_get_rc_dip(dip);
978 977 ASSERT(rcdip != NULL);
979 978
980 979 /* Save the Vendor ID, Device ID and revision ID */
981 980 bus_p->bus_dev_ven_id = pci_cfgacc_get32(rcdip, bdf, PCI_CONF_VENID);
982 981 bus_p->bus_rev_id = pci_cfgacc_get8(rcdip, bdf, PCI_CONF_REVID);
983 982 /* Save the Header Type */
984 983 bus_p->bus_hdr_type = pci_cfgacc_get8(rcdip, bdf, PCI_CONF_HEADER);
985 984 bus_p->bus_hdr_type &= PCI_HEADER_TYPE_M;
986 985
987 986 /*
988 987 * Figure out the device type and all the relavant capability offsets
989 988 */
990 989 /* set default value */
991 990 bus_p->bus_dev_type = PCIE_PCIECAP_DEV_TYPE_PCI_PSEUDO;
992 991
993 992 status = pci_cfgacc_get16(rcdip, bdf, PCI_CONF_STAT);
994 993 if (status == PCI_CAP_EINVAL16 || !(status & PCI_STAT_CAP))
995 994 goto caps_done; /* capability not supported */
996 995
997 996 /* Relevant conventional capabilities first */
998 997
999 998 /* Conventional caps: PCI_CAP_ID_PCI_E, PCI_CAP_ID_PCIX */
1000 999 num_cap = 2;
1001 1000
1002 1001 switch (bus_p->bus_hdr_type) {
1003 1002 case PCI_HEADER_ZERO:
1004 1003 baseptr = PCI_CONF_CAP_PTR;
1005 1004 break;
1006 1005 case PCI_HEADER_PPB:
1007 1006 baseptr = PCI_BCNF_CAP_PTR;
1008 1007 break;
1009 1008 case PCI_HEADER_CARDBUS:
1010 1009 baseptr = PCI_CBUS_CAP_PTR;
1011 1010 break;
1012 1011 default:
1013 1012 cmn_err(CE_WARN, "%s: unexpected pci header type:%x",
1014 1013 __func__, bus_p->bus_hdr_type);
1015 1014 goto caps_done;
1016 1015 }
1017 1016
1018 1017 base = baseptr;
1019 1018 for (base = pci_cfgacc_get8(rcdip, bdf, base); base && num_cap;
1020 1019 base = pci_cfgacc_get8(rcdip, bdf, base + PCI_CAP_NEXT_PTR)) {
1021 1020 capid = pci_cfgacc_get8(rcdip, bdf, base);
1022 1021 switch (capid) {
1023 1022 case PCI_CAP_ID_PCI_E:
1024 1023 bus_p->bus_pcie_off = base;
1025 1024 bus_p->bus_dev_type = pci_cfgacc_get16(rcdip, bdf,
1026 1025 base + PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
1027 1026
1028 1027 /* Check and save PCIe hotplug capability information */
1029 1028 if ((PCIE_IS_RP(bus_p) || PCIE_IS_SWD(bus_p)) &&
1030 1029 (pci_cfgacc_get16(rcdip, bdf, base + PCIE_PCIECAP)
1031 1030 & PCIE_PCIECAP_SLOT_IMPL) &&
1032 1031 (pci_cfgacc_get32(rcdip, bdf, base + PCIE_SLOTCAP)
1033 1032 & PCIE_SLOTCAP_HP_CAPABLE))
1034 1033 bus_p->bus_hp_sup_modes |= PCIE_NATIVE_HP_MODE;
1035 1034
1036 1035 num_cap--;
1037 1036 break;
1038 1037 case PCI_CAP_ID_PCIX:
1039 1038 bus_p->bus_pcix_off = base;
1040 1039 if (PCIE_IS_BDG(bus_p))
1041 1040 bus_p->bus_ecc_ver =
1042 1041 pci_cfgacc_get16(rcdip, bdf, base +
1043 1042 PCI_PCIX_SEC_STATUS) & PCI_PCIX_VER_MASK;
1044 1043 else
1045 1044 bus_p->bus_ecc_ver =
1046 1045 pci_cfgacc_get16(rcdip, bdf, base +
1047 1046 PCI_PCIX_COMMAND) & PCI_PCIX_VER_MASK;
1048 1047 num_cap--;
1049 1048 break;
1050 1049 default:
1051 1050 break;
1052 1051 }
1053 1052 }
1054 1053
1055 1054 /* Check and save PCI hotplug (SHPC) capability information */
1056 1055 if (PCIE_IS_BDG(bus_p)) {
1057 1056 base = baseptr;
1058 1057 for (base = pci_cfgacc_get8(rcdip, bdf, base);
1059 1058 base; base = pci_cfgacc_get8(rcdip, bdf,
1060 1059 base + PCI_CAP_NEXT_PTR)) {
1061 1060 capid = pci_cfgacc_get8(rcdip, bdf, base);
1062 1061 if (capid == PCI_CAP_ID_PCI_HOTPLUG) {
1063 1062 bus_p->bus_pci_hp_off = base;
1064 1063 bus_p->bus_hp_sup_modes |= PCIE_PCI_HP_MODE;
1065 1064 break;
1066 1065 }
1067 1066 }
1068 1067 }
1069 1068
1070 1069 /* Then, relevant extended capabilities */
1071 1070
1072 1071 if (!PCIE_IS_PCIE(bus_p))
1073 1072 goto caps_done;
1074 1073
1075 1074 /* Extended caps: PCIE_EXT_CAP_ID_AER */
1076 1075 for (base = PCIE_EXT_CAP; base; base = (capid >>
1077 1076 PCIE_EXT_CAP_NEXT_PTR_SHIFT) & PCIE_EXT_CAP_NEXT_PTR_MASK) {
1078 1077 capid = pci_cfgacc_get32(rcdip, bdf, base);
1079 1078 if (capid == PCI_CAP_EINVAL32)
1080 1079 break;
1081 1080 if (((capid >> PCIE_EXT_CAP_ID_SHIFT) & PCIE_EXT_CAP_ID_MASK)
1082 1081 == PCIE_EXT_CAP_ID_AER) {
1083 1082 bus_p->bus_aer_off = base;
1084 1083 break;
1085 1084 }
1086 1085 }
1087 1086
1088 1087 caps_done:
1089 1088 /* save RP dip and RP bdf */
1090 1089 if (PCIE_IS_RP(bus_p)) {
1091 1090 bus_p->bus_rp_dip = dip;
1092 1091 bus_p->bus_rp_bdf = bus_p->bus_bdf;
1093 1092 } else {
1094 1093 for (pdip = ddi_get_parent(dip); pdip;
1095 1094 pdip = ddi_get_parent(pdip)) {
1096 1095 pcie_bus_t *parent_bus_p = PCIE_DIP2BUS(pdip);
1097 1096
1098 1097 /*
1099 1098 * If RP dip and RP bdf in parent's bus_t have
1100 1099 * been initialized, simply use these instead of
1101 1100 * continuing up to the RC.
1102 1101 */
1103 1102 if (parent_bus_p->bus_rp_dip != NULL) {
1104 1103 bus_p->bus_rp_dip = parent_bus_p->bus_rp_dip;
1105 1104 bus_p->bus_rp_bdf = parent_bus_p->bus_rp_bdf;
1106 1105 break;
1107 1106 }
1108 1107
1109 1108 /*
1110 1109 * When debugging be aware that some NVIDIA x86
1111 1110 * architectures have 2 nodes for each RP, One at Bus
1112 1111 * 0x0 and one at Bus 0x80. The requester is from Bus
1113 1112 * 0x80
1114 1113 */
1115 1114 if (PCIE_IS_ROOT(parent_bus_p)) {
1116 1115 bus_p->bus_rp_dip = pdip;
1117 1116 bus_p->bus_rp_bdf = parent_bus_p->bus_bdf;
1118 1117 break;
1119 1118 }
1120 1119 }
1121 1120 }
1122 1121
1123 1122 bus_p->bus_soft_state = PCI_SOFT_STATE_CLOSED;
1124 1123 bus_p->bus_fm_flags = 0;
1125 1124 bus_p->bus_mps = 0;
1126 1125
1127 1126 ndi_set_bus_private(dip, B_TRUE, DEVI_PORT_TYPE_PCI, (void *)bus_p);
1128 1127
1129 1128 if (PCIE_IS_HOTPLUG_CAPABLE(dip))
1130 1129 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
1131 1130 "hotplug-capable");
1132 1131
1133 1132 initial_done:
1134 1133 if (!(flags & PCIE_BUS_FINAL))
1135 1134 goto final_done;
1136 1135
1137 1136 /* already initialized? */
1138 1137 bus_p = PCIE_DIP2BUS(dip);
1139 1138
1140 1139 /* Save the Range information if device is a switch/bridge */
1141 1140 if (PCIE_IS_BDG(bus_p)) {
1142 1141 /* get "bus_range" property */
1143 1142 range_size = sizeof (pci_bus_range_t);
1144 1143 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1145 1144 "bus-range", (caddr_t)&bus_p->bus_bus_range, &range_size)
1146 1145 != DDI_PROP_SUCCESS) {
1147 1146 errstr = "Cannot find \"bus-range\" property";
1148 1147 cmn_err(CE_WARN,
1149 1148 "PCIE init err info failed BDF 0x%x:%s\n",
1150 1149 bus_p->bus_bdf, errstr);
1151 1150 }
1152 1151
1153 1152 /* get secondary bus number */
1154 1153 rcdip = pcie_get_rc_dip(dip);
1155 1154 ASSERT(rcdip != NULL);
1156 1155
1157 1156 bus_p->bus_bdg_secbus = pci_cfgacc_get8(rcdip,
1158 1157 bus_p->bus_bdf, PCI_BCNF_SECBUS);
1159 1158
1160 1159 /* Get "ranges" property */
1161 1160 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1162 1161 "ranges", (caddr_t)&bus_p->bus_addr_ranges,
1163 1162 &bus_p->bus_addr_entries) != DDI_PROP_SUCCESS)
1164 1163 bus_p->bus_addr_entries = 0;
1165 1164 bus_p->bus_addr_entries /= sizeof (ppb_ranges_t);
1166 1165 }
1167 1166
1168 1167 /* save "assigned-addresses" property array, ignore failues */
1169 1168 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1170 1169 "assigned-addresses", (caddr_t)&bus_p->bus_assigned_addr,
1171 1170 &bus_p->bus_assigned_entries) == DDI_PROP_SUCCESS)
1172 1171 bus_p->bus_assigned_entries /= sizeof (pci_regspec_t);
1173 1172 else
1174 1173 bus_p->bus_assigned_entries = 0;
1175 1174
1176 1175 pcie_init_pfd(dip);
1177 1176
1178 1177 pcie_init_plat(dip);
1179 1178
1180 1179 final_done:
1181 1180
1182 1181 PCIE_DBG("Add %s(dip 0x%p, bdf 0x%x, secbus 0x%x)\n",
1183 1182 ddi_driver_name(dip), (void *)dip, bus_p->bus_bdf,
1184 1183 bus_p->bus_bdg_secbus);
1185 1184 #ifdef DEBUG
1186 1185 pcie_print_bus(bus_p);
1187 1186 #endif
1188 1187
1189 1188 return (bus_p);
1190 1189 }
1191 1190
1192 1191 /*
1193 1192 * Invoked before destroying devinfo node, mostly during hotplug
1194 1193 * operation to free pcie_bus_t data structure
1195 1194 */
1196 1195 /* ARGSUSED */
1197 1196 void
1198 1197 pcie_fini_bus(dev_info_t *dip, uint8_t flags)
1199 1198 {
1200 1199 pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip);
1201 1200 ASSERT(bus_p);
1202 1201
1203 1202 if (flags & PCIE_BUS_INITIAL) {
1204 1203 pcie_fini_plat(dip);
1205 1204 pcie_fini_pfd(dip);
1206 1205
1207 1206 kmem_free(bus_p->bus_assigned_addr,
1208 1207 (sizeof (pci_regspec_t) * bus_p->bus_assigned_entries));
1209 1208 kmem_free(bus_p->bus_addr_ranges,
1210 1209 (sizeof (ppb_ranges_t) * bus_p->bus_addr_entries));
1211 1210 /* zero out the fields that have been destroyed */
1212 1211 bus_p->bus_assigned_addr = NULL;
1213 1212 bus_p->bus_addr_ranges = NULL;
1214 1213 bus_p->bus_assigned_entries = 0;
1215 1214 bus_p->bus_addr_entries = 0;
1216 1215 }
1217 1216
1218 1217 if (flags & PCIE_BUS_FINAL) {
1219 1218 if (PCIE_IS_HOTPLUG_CAPABLE(dip)) {
1220 1219 (void) ndi_prop_remove(DDI_DEV_T_NONE, dip,
1221 1220 "hotplug-capable");
1222 1221 }
1223 1222
1224 1223 ndi_set_bus_private(dip, B_TRUE, NULL, NULL);
1225 1224 kmem_free(bus_p, sizeof (pcie_bus_t));
1226 1225 }
1227 1226 }
1228 1227
1229 1228 int
1230 1229 pcie_postattach_child(dev_info_t *cdip)
1231 1230 {
1232 1231 pcie_bus_t *bus_p = PCIE_DIP2BUS(cdip);
1233 1232
1234 1233 if (!bus_p)
1235 1234 return (DDI_FAILURE);
1236 1235
1237 1236 return (pcie_enable_ce(cdip));
1238 1237 }
1239 1238
1240 1239 /*
1241 1240 * PCI-Express child device de-initialization.
1242 1241 * This function disables generic pci-express interrupts and error
1243 1242 * handling.
1244 1243 */
1245 1244 void
1246 1245 pcie_uninitchild(dev_info_t *cdip)
1247 1246 {
1248 1247 pcie_disable_errors(cdip);
1249 1248 pcie_fini_cfghdl(cdip);
1250 1249 pcie_fini_dom(cdip);
1251 1250 }
1252 1251
1253 1252 /*
1254 1253 * find the root complex dip
1255 1254 */
1256 1255 dev_info_t *
1257 1256 pcie_get_rc_dip(dev_info_t *dip)
1258 1257 {
1259 1258 dev_info_t *rcdip;
1260 1259 pcie_bus_t *rc_bus_p;
1261 1260
1262 1261 for (rcdip = ddi_get_parent(dip); rcdip;
1263 1262 rcdip = ddi_get_parent(rcdip)) {
1264 1263 rc_bus_p = PCIE_DIP2BUS(rcdip);
1265 1264 if (rc_bus_p && PCIE_IS_RC(rc_bus_p))
1266 1265 break;
1267 1266 }
1268 1267
1269 1268 return (rcdip);
1270 1269 }
1271 1270
1272 1271 static boolean_t
1273 1272 pcie_is_pci_device(dev_info_t *dip)
1274 1273 {
1275 1274 dev_info_t *pdip;
1276 1275 char *device_type;
1277 1276
1278 1277 pdip = ddi_get_parent(dip);
1279 1278 ASSERT(pdip);
1280 1279
1281 1280 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS,
1282 1281 "device_type", &device_type) != DDI_PROP_SUCCESS)
1283 1282 return (B_FALSE);
1284 1283
1285 1284 if (strcmp(device_type, "pciex") != 0 &&
1286 1285 strcmp(device_type, "pci") != 0) {
1287 1286 ddi_prop_free(device_type);
1288 1287 return (B_FALSE);
1289 1288 }
1290 1289
1291 1290 ddi_prop_free(device_type);
1292 1291 return (B_TRUE);
1293 1292 }
1294 1293
1295 1294 typedef struct {
1296 1295 boolean_t init;
1297 1296 uint8_t flags;
1298 1297 } pcie_bus_arg_t;
1299 1298
1300 1299 /*ARGSUSED*/
1301 1300 static int
1302 1301 pcie_fab_do_init_fini(dev_info_t *dip, void *arg)
1303 1302 {
1304 1303 pcie_req_id_t bdf;
1305 1304 pcie_bus_arg_t *bus_arg = (pcie_bus_arg_t *)arg;
1306 1305
1307 1306 if (!pcie_is_pci_device(dip))
1308 1307 goto out;
1309 1308
1310 1309 if (bus_arg->init) {
1311 1310 if (pcie_get_bdf_from_dip(dip, &bdf) != DDI_SUCCESS)
1312 1311 goto out;
1313 1312
1314 1313 (void) pcie_init_bus(dip, bdf, bus_arg->flags);
1315 1314 } else {
1316 1315 (void) pcie_fini_bus(dip, bus_arg->flags);
1317 1316 }
1318 1317
1319 1318 return (DDI_WALK_CONTINUE);
1320 1319
1321 1320 out:
1322 1321 return (DDI_WALK_PRUNECHILD);
1323 1322 }
1324 1323
1325 1324 void
1326 1325 pcie_fab_init_bus(dev_info_t *rcdip, uint8_t flags)
1327 1326 {
1328 1327 int circular_count;
1329 1328 dev_info_t *dip = ddi_get_child(rcdip);
1330 1329 pcie_bus_arg_t arg;
1331 1330
1332 1331 arg.init = B_TRUE;
1333 1332 arg.flags = flags;
1334 1333
1335 1334 ndi_devi_enter(rcdip, &circular_count);
1336 1335 ddi_walk_devs(dip, pcie_fab_do_init_fini, &arg);
1337 1336 ndi_devi_exit(rcdip, circular_count);
1338 1337 }
1339 1338
1340 1339 void
1341 1340 pcie_fab_fini_bus(dev_info_t *rcdip, uint8_t flags)
1342 1341 {
1343 1342 int circular_count;
1344 1343 dev_info_t *dip = ddi_get_child(rcdip);
1345 1344 pcie_bus_arg_t arg;
1346 1345
1347 1346 arg.init = B_FALSE;
1348 1347 arg.flags = flags;
1349 1348
1350 1349 ndi_devi_enter(rcdip, &circular_count);
1351 1350 ddi_walk_devs(dip, pcie_fab_do_init_fini, &arg);
1352 1351 ndi_devi_exit(rcdip, circular_count);
1353 1352 }
1354 1353
1355 1354 void
1356 1355 pcie_enable_errors(dev_info_t *dip)
1357 1356 {
1358 1357 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
1359 1358 uint16_t reg16, tmp16;
1360 1359 uint32_t reg32, tmp32;
1361 1360
1362 1361 ASSERT(bus_p);
1363 1362
1364 1363 /*
1365 1364 * Clear any pending errors
1366 1365 */
1367 1366 pcie_clear_errors(dip);
1368 1367
1369 1368 if (!PCIE_IS_PCIE(bus_p))
1370 1369 return;
1371 1370
1372 1371 /*
1373 1372 * Enable Baseline Error Handling but leave CE reporting off (poweron
1374 1373 * default).
1375 1374 */
1376 1375 if ((reg16 = PCIE_CAP_GET(16, bus_p, PCIE_DEVCTL)) !=
1377 1376 PCI_CAP_EINVAL16) {
1378 1377 tmp16 = (reg16 & (PCIE_DEVCTL_MAX_READ_REQ_MASK |
1379 1378 PCIE_DEVCTL_MAX_PAYLOAD_MASK)) |
1380 1379 (pcie_devctl_default & ~(PCIE_DEVCTL_MAX_READ_REQ_MASK |
1381 1380 PCIE_DEVCTL_MAX_PAYLOAD_MASK)) |
1382 1381 (pcie_base_err_default & (~PCIE_DEVCTL_CE_REPORTING_EN));
1383 1382
1384 1383 PCIE_CAP_PUT(16, bus_p, PCIE_DEVCTL, tmp16);
1385 1384 PCIE_DBG_CAP(dip, bus_p, "DEVCTL", 16, PCIE_DEVCTL, reg16);
1386 1385 }
1387 1386
1388 1387 /* Enable Root Port Baseline Error Receiving */
1389 1388 if (PCIE_IS_ROOT(bus_p) &&
1390 1389 (reg16 = PCIE_CAP_GET(16, bus_p, PCIE_ROOTCTL)) !=
1391 1390 PCI_CAP_EINVAL16) {
1392 1391
1393 1392 tmp16 = pcie_serr_disable_flag ?
1394 1393 (pcie_root_ctrl_default & ~PCIE_ROOT_SYS_ERR) :
1395 1394 pcie_root_ctrl_default;
1396 1395 PCIE_CAP_PUT(16, bus_p, PCIE_ROOTCTL, tmp16);
1397 1396 PCIE_DBG_CAP(dip, bus_p, "ROOT DEVCTL", 16, PCIE_ROOTCTL,
1398 1397 reg16);
1399 1398 }
1400 1399
1401 1400 /*
1402 1401 * Enable PCI-Express Advanced Error Handling if Exists
1403 1402 */
1404 1403 if (!PCIE_HAS_AER(bus_p))
1405 1404 return;
1406 1405
1407 1406 /* Set Uncorrectable Severity */
1408 1407 if ((reg32 = PCIE_AER_GET(32, bus_p, PCIE_AER_UCE_SERV)) !=
1409 1408 PCI_CAP_EINVAL32) {
1410 1409 tmp32 = pcie_aer_uce_severity;
1411 1410
1412 1411 PCIE_AER_PUT(32, bus_p, PCIE_AER_UCE_SERV, tmp32);
1413 1412 PCIE_DBG_AER(dip, bus_p, "AER UCE SEV", 32, PCIE_AER_UCE_SERV,
1414 1413 reg32);
1415 1414 }
1416 1415
1417 1416 /* Enable Uncorrectable errors */
1418 1417 if ((reg32 = PCIE_AER_GET(32, bus_p, PCIE_AER_UCE_MASK)) !=
1419 1418 PCI_CAP_EINVAL32) {
1420 1419 tmp32 = pcie_aer_uce_mask;
1421 1420
1422 1421 PCIE_AER_PUT(32, bus_p, PCIE_AER_UCE_MASK, tmp32);
1423 1422 PCIE_DBG_AER(dip, bus_p, "AER UCE MASK", 32, PCIE_AER_UCE_MASK,
1424 1423 reg32);
1425 1424 }
1426 1425
1427 1426 /* Enable ECRC generation and checking */
1428 1427 if ((reg32 = PCIE_AER_GET(32, bus_p, PCIE_AER_CTL)) !=
1429 1428 PCI_CAP_EINVAL32) {
1430 1429 tmp32 = reg32 | pcie_ecrc_value;
1431 1430 PCIE_AER_PUT(32, bus_p, PCIE_AER_CTL, tmp32);
1432 1431 PCIE_DBG_AER(dip, bus_p, "AER CTL", 32, PCIE_AER_CTL, reg32);
1433 1432 }
1434 1433
1435 1434 /* Enable Secondary Uncorrectable errors if this is a bridge */
1436 1435 if (!PCIE_IS_PCIE_BDG(bus_p))
1437 1436 goto root;
1438 1437
1439 1438 /* Set Uncorrectable Severity */
1440 1439 if ((reg32 = PCIE_AER_GET(32, bus_p, PCIE_AER_SUCE_SERV)) !=
1441 1440 PCI_CAP_EINVAL32) {
1442 1441 tmp32 = pcie_aer_suce_severity;
1443 1442
1444 1443 PCIE_AER_PUT(32, bus_p, PCIE_AER_SUCE_SERV, tmp32);
1445 1444 PCIE_DBG_AER(dip, bus_p, "AER SUCE SEV", 32, PCIE_AER_SUCE_SERV,
1446 1445 reg32);
1447 1446 }
1448 1447
1449 1448 if ((reg32 = PCIE_AER_GET(32, bus_p, PCIE_AER_SUCE_MASK)) !=
1450 1449 PCI_CAP_EINVAL32) {
1451 1450 PCIE_AER_PUT(32, bus_p, PCIE_AER_SUCE_MASK, pcie_aer_suce_mask);
1452 1451 PCIE_DBG_AER(dip, bus_p, "AER SUCE MASK", 32,
1453 1452 PCIE_AER_SUCE_MASK, reg32);
1454 1453 }
1455 1454
1456 1455 root:
1457 1456 /*
1458 1457 * Enable Root Control this is a Root device
1459 1458 */
1460 1459 if (!PCIE_IS_ROOT(bus_p))
1461 1460 return;
1462 1461
1463 1462 if ((reg16 = PCIE_AER_GET(16, bus_p, PCIE_AER_RE_CMD)) !=
1464 1463 PCI_CAP_EINVAL16) {
1465 1464 PCIE_AER_PUT(16, bus_p, PCIE_AER_RE_CMD,
1466 1465 pcie_root_error_cmd_default);
1467 1466 PCIE_DBG_AER(dip, bus_p, "AER Root Err Cmd", 16,
1468 1467 PCIE_AER_RE_CMD, reg16);
1469 1468 }
1470 1469 }
1471 1470
1472 1471 /*
1473 1472 * This function is used for enabling CE reporting and setting the AER CE mask.
1474 1473 * When called from outside the pcie module it should always be preceded by
1475 1474 * a call to pcie_enable_errors.
1476 1475 */
1477 1476 int
1478 1477 pcie_enable_ce(dev_info_t *dip)
1479 1478 {
1480 1479 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
1481 1480 uint16_t device_sts, device_ctl;
1482 1481 uint32_t tmp_pcie_aer_ce_mask;
1483 1482
1484 1483 if (!PCIE_IS_PCIE(bus_p))
1485 1484 return (DDI_SUCCESS);
1486 1485
1487 1486 /*
1488 1487 * The "pcie_ce_mask" property is used to control both the CE reporting
1489 1488 * enable field in the device control register and the AER CE mask. We
1490 1489 * leave CE reporting disabled if pcie_ce_mask is set to -1.
1491 1490 */
1492 1491
1493 1492 tmp_pcie_aer_ce_mask = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1494 1493 DDI_PROP_DONTPASS, "pcie_ce_mask", pcie_aer_ce_mask);
1495 1494
1496 1495 if (tmp_pcie_aer_ce_mask == (uint32_t)-1) {
1497 1496 /*
1498 1497 * Nothing to do since CE reporting has already been disabled.
1499 1498 */
1500 1499 return (DDI_SUCCESS);
1501 1500 }
1502 1501
1503 1502 if (PCIE_HAS_AER(bus_p)) {
1504 1503 /* Enable AER CE */
1505 1504 PCIE_AER_PUT(32, bus_p, PCIE_AER_CE_MASK, tmp_pcie_aer_ce_mask);
1506 1505 PCIE_DBG_AER(dip, bus_p, "AER CE MASK", 32, PCIE_AER_CE_MASK,
1507 1506 0);
1508 1507
1509 1508 /* Clear any pending AER CE errors */
1510 1509 PCIE_AER_PUT(32, bus_p, PCIE_AER_CE_STS, -1);
1511 1510 }
1512 1511
1513 1512 /* clear any pending CE errors */
1514 1513 if ((device_sts = PCIE_CAP_GET(16, bus_p, PCIE_DEVSTS)) !=
1515 1514 PCI_CAP_EINVAL16)
1516 1515 PCIE_CAP_PUT(16, bus_p, PCIE_DEVSTS,
1517 1516 device_sts & (~PCIE_DEVSTS_CE_DETECTED));
1518 1517
1519 1518 /* Enable CE reporting */
1520 1519 device_ctl = PCIE_CAP_GET(16, bus_p, PCIE_DEVCTL);
1521 1520 PCIE_CAP_PUT(16, bus_p, PCIE_DEVCTL,
1522 1521 (device_ctl & (~PCIE_DEVCTL_ERR_MASK)) | pcie_base_err_default);
1523 1522 PCIE_DBG_CAP(dip, bus_p, "DEVCTL", 16, PCIE_DEVCTL, device_ctl);
1524 1523
1525 1524 return (DDI_SUCCESS);
1526 1525 }
1527 1526
1528 1527 /* ARGSUSED */
1529 1528 void
1530 1529 pcie_disable_errors(dev_info_t *dip)
1531 1530 {
1532 1531 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
1533 1532 uint16_t device_ctl;
1534 1533 uint32_t aer_reg;
1535 1534
1536 1535 if (!PCIE_IS_PCIE(bus_p))
1537 1536 return;
1538 1537
1539 1538 /*
1540 1539 * Disable PCI-Express Baseline Error Handling
1541 1540 */
1542 1541 device_ctl = PCIE_CAP_GET(16, bus_p, PCIE_DEVCTL);
1543 1542 device_ctl &= ~PCIE_DEVCTL_ERR_MASK;
1544 1543 PCIE_CAP_PUT(16, bus_p, PCIE_DEVCTL, device_ctl);
1545 1544
1546 1545 /*
1547 1546 * Disable PCI-Express Advanced Error Handling if Exists
1548 1547 */
1549 1548 if (!PCIE_HAS_AER(bus_p))
1550 1549 goto root;
1551 1550
1552 1551 /* Disable Uncorrectable errors */
1553 1552 PCIE_AER_PUT(32, bus_p, PCIE_AER_UCE_MASK, PCIE_AER_UCE_BITS);
1554 1553
1555 1554 /* Disable Correctable errors */
1556 1555 PCIE_AER_PUT(32, bus_p, PCIE_AER_CE_MASK, PCIE_AER_CE_BITS);
1557 1556
1558 1557 /* Disable ECRC generation and checking */
1559 1558 if ((aer_reg = PCIE_AER_GET(32, bus_p, PCIE_AER_CTL)) !=
1560 1559 PCI_CAP_EINVAL32) {
1561 1560 aer_reg &= ~(PCIE_AER_CTL_ECRC_GEN_ENA |
1562 1561 PCIE_AER_CTL_ECRC_CHECK_ENA);
1563 1562
1564 1563 PCIE_AER_PUT(32, bus_p, PCIE_AER_CTL, aer_reg);
1565 1564 }
1566 1565 /*
1567 1566 * Disable Secondary Uncorrectable errors if this is a bridge
1568 1567 */
1569 1568 if (!PCIE_IS_PCIE_BDG(bus_p))
1570 1569 goto root;
1571 1570
1572 1571 PCIE_AER_PUT(32, bus_p, PCIE_AER_SUCE_MASK, PCIE_AER_SUCE_BITS);
1573 1572
1574 1573 root:
1575 1574 /*
1576 1575 * disable Root Control this is a Root device
1577 1576 */
1578 1577 if (!PCIE_IS_ROOT(bus_p))
1579 1578 return;
1580 1579
1581 1580 if (!pcie_serr_disable_flag) {
1582 1581 device_ctl = PCIE_CAP_GET(16, bus_p, PCIE_ROOTCTL);
1583 1582 device_ctl &= ~PCIE_ROOT_SYS_ERR;
1584 1583 PCIE_CAP_PUT(16, bus_p, PCIE_ROOTCTL, device_ctl);
1585 1584 }
1586 1585
1587 1586 if (!PCIE_HAS_AER(bus_p))
1588 1587 return;
1589 1588
1590 1589 if ((device_ctl = PCIE_CAP_GET(16, bus_p, PCIE_AER_RE_CMD)) !=
1591 1590 PCI_CAP_EINVAL16) {
1592 1591 device_ctl &= ~pcie_root_error_cmd_default;
1593 1592 PCIE_CAP_PUT(16, bus_p, PCIE_AER_RE_CMD, device_ctl);
1594 1593 }
1595 1594 }
1596 1595
1597 1596 /*
1598 1597 * Extract bdf from "reg" property.
1599 1598 */
1600 1599 int
1601 1600 pcie_get_bdf_from_dip(dev_info_t *dip, pcie_req_id_t *bdf)
1602 1601 {
1603 1602 pci_regspec_t *regspec;
1604 1603 int reglen;
1605 1604
1606 1605 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1607 1606 "reg", (int **)®spec, (uint_t *)®len) != DDI_SUCCESS)
1608 1607 return (DDI_FAILURE);
1609 1608
1610 1609 if (reglen < (sizeof (pci_regspec_t) / sizeof (int))) {
1611 1610 ddi_prop_free(regspec);
1612 1611 return (DDI_FAILURE);
1613 1612 }
1614 1613
1615 1614 /* Get phys_hi from first element. All have same bdf. */
1616 1615 *bdf = (regspec->pci_phys_hi & (PCI_REG_BDFR_M ^ PCI_REG_REG_M)) >> 8;
1617 1616
1618 1617 ddi_prop_free(regspec);
1619 1618 return (DDI_SUCCESS);
1620 1619 }
1621 1620
1622 1621 dev_info_t *
1623 1622 pcie_get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip)
1624 1623 {
1625 1624 dev_info_t *cdip = rdip;
1626 1625
1627 1626 for (; ddi_get_parent(cdip) != dip; cdip = ddi_get_parent(cdip))
1628 1627 ;
1629 1628
1630 1629 return (cdip);
1631 1630 }
1632 1631
1633 1632 uint32_t
1634 1633 pcie_get_bdf_for_dma_xfer(dev_info_t *dip, dev_info_t *rdip)
1635 1634 {
1636 1635 dev_info_t *cdip;
1637 1636
1638 1637 /*
1639 1638 * As part of the probing, the PCI fcode interpreter may setup a DMA
1640 1639 * request if a given card has a fcode on it using dip and rdip of the
1641 1640 * hotplug connector i.e, dip and rdip of px/pcieb driver. In this
1642 1641 * case, return a invalid value for the bdf since we cannot get to the
1643 1642 * bdf value of the actual device which will be initiating this DMA.
1644 1643 */
1645 1644 if (rdip == dip)
1646 1645 return (PCIE_INVALID_BDF);
1647 1646
1648 1647 cdip = pcie_get_my_childs_dip(dip, rdip);
1649 1648
1650 1649 /*
1651 1650 * For a given rdip, return the bdf value of dip's (px or pcieb)
1652 1651 * immediate child or secondary bus-id if dip is a PCIe2PCI bridge.
1653 1652 *
1654 1653 * XXX - For now, return a invalid bdf value for all PCI and PCI-X
1655 1654 * devices since this needs more work.
1656 1655 */
1657 1656 return (PCI_GET_PCIE2PCI_SECBUS(cdip) ?
1658 1657 PCIE_INVALID_BDF : PCI_GET_BDF(cdip));
1659 1658 }
1660 1659
1661 1660 uint32_t
1662 1661 pcie_get_aer_uce_mask() {
1663 1662 return (pcie_aer_uce_mask);
1664 1663 }
1665 1664 uint32_t
1666 1665 pcie_get_aer_ce_mask() {
1667 1666 return (pcie_aer_ce_mask);
1668 1667 }
1669 1668 uint32_t
1670 1669 pcie_get_aer_suce_mask() {
1671 1670 return (pcie_aer_suce_mask);
1672 1671 }
1673 1672 uint32_t
1674 1673 pcie_get_serr_mask() {
1675 1674 return (pcie_serr_disable_flag);
1676 1675 }
1677 1676
1678 1677 void
1679 1678 pcie_set_aer_uce_mask(uint32_t mask) {
1680 1679 pcie_aer_uce_mask = mask;
1681 1680 if (mask & PCIE_AER_UCE_UR)
1682 1681 pcie_base_err_default &= ~PCIE_DEVCTL_UR_REPORTING_EN;
1683 1682 else
1684 1683 pcie_base_err_default |= PCIE_DEVCTL_UR_REPORTING_EN;
1685 1684
1686 1685 if (mask & PCIE_AER_UCE_ECRC)
1687 1686 pcie_ecrc_value = 0;
1688 1687 }
1689 1688
1690 1689 void
1691 1690 pcie_set_aer_ce_mask(uint32_t mask) {
1692 1691 pcie_aer_ce_mask = mask;
1693 1692 }
1694 1693 void
1695 1694 pcie_set_aer_suce_mask(uint32_t mask) {
1696 1695 pcie_aer_suce_mask = mask;
1697 1696 }
1698 1697 void
1699 1698 pcie_set_serr_mask(uint32_t mask) {
1700 1699 pcie_serr_disable_flag = mask;
1701 1700 }
1702 1701
1703 1702 /*
1704 1703 * Is the rdip a child of dip. Used for checking certain CTLOPS from bubbling
1705 1704 * up erronously. Ex. ISA ctlops to a PCI-PCI Bridge.
1706 1705 */
1707 1706 boolean_t
1708 1707 pcie_is_child(dev_info_t *dip, dev_info_t *rdip)
1709 1708 {
1710 1709 dev_info_t *cdip = ddi_get_child(dip);
1711 1710 for (; cdip; cdip = ddi_get_next_sibling(cdip))
1712 1711 if (cdip == rdip)
1713 1712 break;
1714 1713 return (cdip != NULL);
1715 1714 }
1716 1715
1717 1716 boolean_t
1718 1717 pcie_is_link_disabled(dev_info_t *dip)
1719 1718 {
1720 1719 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
1721 1720
1722 1721 if (PCIE_IS_PCIE(bus_p)) {
1723 1722 if (PCIE_CAP_GET(16, bus_p, PCIE_LINKCTL) &
1724 1723 PCIE_LINKCTL_LINK_DISABLE)
1725 1724 return (B_TRUE);
1726 1725 }
1727 1726 return (B_FALSE);
1728 1727 }
1729 1728
1730 1729 /*
1731 1730 * Initialize the MPS for a root port.
1732 1731 *
1733 1732 * dip - dip of root port device.
1734 1733 */
1735 1734 void
1736 1735 pcie_init_root_port_mps(dev_info_t *dip)
1737 1736 {
1738 1737 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
1739 1738 int rp_cap, max_supported = pcie_max_mps;
1740 1739
1741 1740 (void) pcie_get_fabric_mps(ddi_get_parent(dip),
1742 1741 ddi_get_child(dip), &max_supported);
1743 1742
1744 1743 rp_cap = PCI_CAP_GET16(bus_p->bus_cfg_hdl, NULL,
1745 1744 bus_p->bus_pcie_off, PCIE_DEVCAP) &
1746 1745 PCIE_DEVCAP_MAX_PAYLOAD_MASK;
1747 1746
1748 1747 if (rp_cap < max_supported)
1749 1748 max_supported = rp_cap;
1750 1749
1751 1750 bus_p->bus_mps = max_supported;
1752 1751 (void) pcie_initchild_mps(dip);
1753 1752 }
1754 1753
1755 1754 /*
1756 1755 * Initialize the Maximum Payload Size of a device.
1757 1756 *
1758 1757 * cdip - dip of device.
1759 1758 *
1760 1759 * returns - DDI_SUCCESS or DDI_FAILURE
1761 1760 */
1762 1761 int
1763 1762 pcie_initchild_mps(dev_info_t *cdip)
1764 1763 {
1765 1764 pcie_bus_t *bus_p;
1766 1765 dev_info_t *pdip = ddi_get_parent(cdip);
1767 1766 uint8_t dev_type;
1768 1767
1769 1768 bus_p = PCIE_DIP2BUS(cdip);
1770 1769 if (bus_p == NULL) {
1771 1770 PCIE_DBG("%s: BUS not found.\n",
1772 1771 ddi_driver_name(cdip));
1773 1772 return (DDI_FAILURE);
1774 1773 }
1775 1774
1776 1775 dev_type = bus_p->bus_dev_type;
1777 1776
1778 1777 /*
1779 1778 * For ARI Devices, only function zero's MPS needs to be set.
1780 1779 */
1781 1780 if ((dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) &&
1782 1781 (pcie_ari_is_enabled(pdip) == PCIE_ARI_FORW_ENABLED)) {
1783 1782 pcie_req_id_t child_bdf;
1784 1783
1785 1784 if (pcie_get_bdf_from_dip(cdip, &child_bdf) == DDI_FAILURE)
1786 1785 return (DDI_FAILURE);
1787 1786 if ((child_bdf & PCIE_REQ_ID_ARI_FUNC_MASK) != 0)
1788 1787 return (DDI_SUCCESS);
1789 1788 }
1790 1789
1791 1790 if (PCIE_IS_PCIE(bus_p)) {
1792 1791 int suggested_mrrs, fabric_mps;
1793 1792 uint16_t device_mps, device_mps_cap, device_mrrs, dev_ctrl;
1794 1793
1795 1794 dev_ctrl = PCIE_CAP_GET(16, bus_p, PCIE_DEVCTL);
1796 1795 if ((fabric_mps = (PCIE_IS_RP(bus_p) ? bus_p :
1797 1796 PCIE_DIP2BUS(pdip))->bus_mps) < 0) {
1798 1797 dev_ctrl = (dev_ctrl & ~(PCIE_DEVCTL_MAX_READ_REQ_MASK |
1799 1798 PCIE_DEVCTL_MAX_PAYLOAD_MASK)) |
1800 1799 (pcie_devctl_default &
1801 1800 (PCIE_DEVCTL_MAX_READ_REQ_MASK |
1802 1801 PCIE_DEVCTL_MAX_PAYLOAD_MASK));
1803 1802
1804 1803 PCIE_CAP_PUT(16, bus_p, PCIE_DEVCTL, dev_ctrl);
1805 1804 return (DDI_SUCCESS);
1806 1805 }
1807 1806
1808 1807 device_mps_cap = PCIE_CAP_GET(16, bus_p, PCIE_DEVCAP) &
1809 1808 PCIE_DEVCAP_MAX_PAYLOAD_MASK;
1810 1809
1811 1810 device_mrrs = (dev_ctrl & PCIE_DEVCTL_MAX_READ_REQ_MASK) >>
1812 1811 PCIE_DEVCTL_MAX_READ_REQ_SHIFT;
1813 1812
1814 1813 if (device_mps_cap < fabric_mps)
1815 1814 device_mrrs = device_mps = device_mps_cap;
1816 1815 else
1817 1816 device_mps = (uint16_t)fabric_mps;
1818 1817
1819 1818 suggested_mrrs = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY,
1820 1819 cdip, DDI_PROP_DONTPASS, "suggested-mrrs", device_mrrs);
1821 1820
1822 1821 if ((device_mps == fabric_mps) ||
1823 1822 (suggested_mrrs < device_mrrs))
1824 1823 device_mrrs = (uint16_t)suggested_mrrs;
1825 1824
1826 1825 /*
1827 1826 * Replace MPS and MRRS settings.
1828 1827 */
1829 1828 dev_ctrl &= ~(PCIE_DEVCTL_MAX_READ_REQ_MASK |
1830 1829 PCIE_DEVCTL_MAX_PAYLOAD_MASK);
1831 1830
1832 1831 dev_ctrl |= ((device_mrrs << PCIE_DEVCTL_MAX_READ_REQ_SHIFT) |
1833 1832 device_mps << PCIE_DEVCTL_MAX_PAYLOAD_SHIFT);
1834 1833
1835 1834 PCIE_CAP_PUT(16, bus_p, PCIE_DEVCTL, dev_ctrl);
1836 1835
1837 1836 bus_p->bus_mps = device_mps;
1838 1837 }
1839 1838
1840 1839 return (DDI_SUCCESS);
1841 1840 }
1842 1841
1843 1842 /*
1844 1843 * Scans a device tree/branch for a maximum payload size capabilities.
1845 1844 *
1846 1845 * rc_dip - dip of Root Complex.
1847 1846 * dip - dip of device where scan will begin.
1848 1847 * max_supported (IN) - maximum allowable MPS.
1849 1848 * max_supported (OUT) - maximum payload size capability of fabric.
1850 1849 */
1851 1850 void
1852 1851 pcie_get_fabric_mps(dev_info_t *rc_dip, dev_info_t *dip, int *max_supported)
1853 1852 {
1854 1853 if (dip == NULL)
1855 1854 return;
1856 1855
1857 1856 /*
1858 1857 * Perform a fabric scan to obtain Maximum Payload Capabilities
1859 1858 */
1860 1859 (void) pcie_scan_mps(rc_dip, dip, max_supported);
1861 1860
1862 1861 PCIE_DBG("MPS: Highest Common MPS= %x\n", max_supported);
1863 1862 }
1864 1863
1865 1864 /*
1866 1865 * Scans fabric and determines Maximum Payload Size based on
1867 1866 * highest common denominator alogorithm
1868 1867 */
1869 1868 static void
1870 1869 pcie_scan_mps(dev_info_t *rc_dip, dev_info_t *dip, int *max_supported)
1871 1870 {
1872 1871 int circular_count;
1873 1872 pcie_max_supported_t max_pay_load_supported;
1874 1873
1875 1874 max_pay_load_supported.dip = rc_dip;
1876 1875 max_pay_load_supported.highest_common_mps = *max_supported;
1877 1876
1878 1877 ndi_devi_enter(ddi_get_parent(dip), &circular_count);
1879 1878 ddi_walk_devs(dip, pcie_get_max_supported,
1880 1879 (void *)&max_pay_load_supported);
1881 1880 ndi_devi_exit(ddi_get_parent(dip), circular_count);
1882 1881
1883 1882 *max_supported = max_pay_load_supported.highest_common_mps;
1884 1883 }
1885 1884
1886 1885 /*
1887 1886 * Called as part of the Maximum Payload Size scan.
1888 1887 */
1889 1888 static int
1890 1889 pcie_get_max_supported(dev_info_t *dip, void *arg)
1891 1890 {
1892 1891 uint32_t max_supported;
1893 1892 uint16_t cap_ptr;
1894 1893 pcie_max_supported_t *current = (pcie_max_supported_t *)arg;
1895 1894 pci_regspec_t *reg;
1896 1895 int rlen;
1897 1896 caddr_t virt;
1898 1897 ddi_acc_handle_t config_handle;
1899 1898
1900 1899 if (ddi_get_child(current->dip) == NULL) {
1901 1900 goto fail1;
1902 1901 }
1903 1902
1904 1903 if (pcie_dev(dip) == DDI_FAILURE) {
1905 1904 PCIE_DBG("MPS: pcie_get_max_supported: %s: "
1906 1905 "Not a PCIe dev\n", ddi_driver_name(dip));
1907 1906 goto fail1;
1908 1907 }
1909 1908
1910 1909 /*
1911 1910 * If the suggested-mrrs property exists, then don't include this
1912 1911 * device in the MPS capabilities scan.
1913 1912 */
1914 1913 if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1915 1914 "suggested-mrrs") != 0)
1916 1915 goto fail1;
1917 1916
1918 1917 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg",
1919 1918 (caddr_t)®, &rlen) != DDI_PROP_SUCCESS) {
1920 1919 PCIE_DBG("MPS: pcie_get_max_supported: %s: "
1921 1920 "Can not read reg\n", ddi_driver_name(dip));
1922 1921 goto fail1;
1923 1922 }
1924 1923
1925 1924 if (pcie_map_phys(ddi_get_child(current->dip), reg, &virt,
1926 1925 &config_handle) != DDI_SUCCESS) {
1927 1926 PCIE_DBG("MPS: pcie_get_max_supported: %s: pcie_map_phys "
1928 1927 "failed\n", ddi_driver_name(dip));
1929 1928 goto fail2;
1930 1929 }
1931 1930
1932 1931 if ((PCI_CAP_LOCATE(config_handle, PCI_CAP_ID_PCI_E, &cap_ptr)) ==
1933 1932 DDI_FAILURE) {
1934 1933 goto fail3;
1935 1934 }
1936 1935
1937 1936 max_supported = PCI_CAP_GET16(config_handle, NULL, cap_ptr,
1938 1937 PCIE_DEVCAP) & PCIE_DEVCAP_MAX_PAYLOAD_MASK;
1939 1938
1940 1939 PCIE_DBG("PCIE MPS: %s: MPS Capabilities %x\n", ddi_driver_name(dip),
1941 1940 max_supported);
1942 1941
1943 1942 if (max_supported < current->highest_common_mps)
1944 1943 current->highest_common_mps = max_supported;
1945 1944
1946 1945 fail3:
1947 1946 pcie_unmap_phys(&config_handle, reg);
1948 1947 fail2:
1949 1948 kmem_free(reg, rlen);
1950 1949 fail1:
1951 1950 return (DDI_WALK_CONTINUE);
1952 1951 }
1953 1952
1954 1953 /*
1955 1954 * Determines if there are any root ports attached to a root complex.
1956 1955 *
1957 1956 * dip - dip of root complex
1958 1957 *
1959 1958 * Returns - DDI_SUCCESS if there is at least one root port otherwise
1960 1959 * DDI_FAILURE.
1961 1960 */
1962 1961 int
1963 1962 pcie_root_port(dev_info_t *dip)
1964 1963 {
1965 1964 int port_type;
1966 1965 uint16_t cap_ptr;
1967 1966 ddi_acc_handle_t config_handle;
1968 1967 dev_info_t *cdip = ddi_get_child(dip);
1969 1968
1970 1969 /*
1971 1970 * Determine if any of the children of the passed in dip
1972 1971 * are root ports.
1973 1972 */
1974 1973 for (; cdip; cdip = ddi_get_next_sibling(cdip)) {
1975 1974
1976 1975 if (pci_config_setup(cdip, &config_handle) != DDI_SUCCESS)
1977 1976 continue;
1978 1977
1979 1978 if ((PCI_CAP_LOCATE(config_handle, PCI_CAP_ID_PCI_E,
1980 1979 &cap_ptr)) == DDI_FAILURE) {
1981 1980 pci_config_teardown(&config_handle);
1982 1981 continue;
1983 1982 }
1984 1983
1985 1984 port_type = PCI_CAP_GET16(config_handle, NULL, cap_ptr,
1986 1985 PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
1987 1986
1988 1987 pci_config_teardown(&config_handle);
1989 1988
1990 1989 if (port_type == PCIE_PCIECAP_DEV_TYPE_ROOT)
1991 1990 return (DDI_SUCCESS);
1992 1991 }
1993 1992
1994 1993 /* No root ports were found */
1995 1994
1996 1995 return (DDI_FAILURE);
1997 1996 }
1998 1997
1999 1998 /*
2000 1999 * Function that determines if a device a PCIe device.
2001 2000 *
2002 2001 * dip - dip of device.
2003 2002 *
2004 2003 * returns - DDI_SUCCESS if device is a PCIe device, otherwise DDI_FAILURE.
2005 2004 */
2006 2005 int
2007 2006 pcie_dev(dev_info_t *dip)
2008 2007 {
2009 2008 /* get parent device's device_type property */
2010 2009 char *device_type;
2011 2010 int rc = DDI_FAILURE;
2012 2011 dev_info_t *pdip = ddi_get_parent(dip);
2013 2012
2014 2013 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
2015 2014 DDI_PROP_DONTPASS, "device_type", &device_type)
2016 2015 != DDI_PROP_SUCCESS) {
2017 2016 return (DDI_FAILURE);
2018 2017 }
2019 2018
2020 2019 if (strcmp(device_type, "pciex") == 0)
2021 2020 rc = DDI_SUCCESS;
2022 2021 else
2023 2022 rc = DDI_FAILURE;
2024 2023
2025 2024 ddi_prop_free(device_type);
2026 2025 return (rc);
2027 2026 }
2028 2027
2029 2028 /*
2030 2029 * Function to map in a device's memory space.
2031 2030 */
2032 2031 static int
2033 2032 pcie_map_phys(dev_info_t *dip, pci_regspec_t *phys_spec,
2034 2033 caddr_t *addrp, ddi_acc_handle_t *handlep)
2035 2034 {
2036 2035 ddi_map_req_t mr;
2037 2036 ddi_acc_hdl_t *hp;
2038 2037 int result;
2039 2038 ddi_device_acc_attr_t attr;
2040 2039
2041 2040 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
2042 2041 attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
2043 2042 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
2044 2043 attr.devacc_attr_access = DDI_CAUTIOUS_ACC;
2045 2044
2046 2045 *handlep = impl_acc_hdl_alloc(KM_SLEEP, NULL);
2047 2046 hp = impl_acc_hdl_get(*handlep);
2048 2047 hp->ah_vers = VERS_ACCHDL;
2049 2048 hp->ah_dip = dip;
2050 2049 hp->ah_rnumber = 0;
2051 2050 hp->ah_offset = 0;
2052 2051 hp->ah_len = 0;
2053 2052 hp->ah_acc = attr;
2054 2053
2055 2054 mr.map_op = DDI_MO_MAP_LOCKED;
2056 2055 mr.map_type = DDI_MT_REGSPEC;
2057 2056 mr.map_obj.rp = (struct regspec *)phys_spec;
2058 2057 mr.map_prot = PROT_READ | PROT_WRITE;
2059 2058 mr.map_flags = DDI_MF_KERNEL_MAPPING;
2060 2059 mr.map_handlep = hp;
2061 2060 mr.map_vers = DDI_MAP_VERSION;
2062 2061
2063 2062 result = ddi_map(dip, &mr, 0, 0, addrp);
2064 2063
2065 2064 if (result != DDI_SUCCESS) {
2066 2065 impl_acc_hdl_free(*handlep);
2067 2066 *handlep = (ddi_acc_handle_t)NULL;
2068 2067 } else {
2069 2068 hp->ah_addr = *addrp;
2070 2069 }
2071 2070
2072 2071 return (result);
2073 2072 }
2074 2073
2075 2074 /*
2076 2075 * Map out memory that was mapped in with pcie_map_phys();
2077 2076 */
2078 2077 static void
2079 2078 pcie_unmap_phys(ddi_acc_handle_t *handlep, pci_regspec_t *ph)
2080 2079 {
2081 2080 ddi_map_req_t mr;
2082 2081 ddi_acc_hdl_t *hp;
2083 2082
2084 2083 hp = impl_acc_hdl_get(*handlep);
2085 2084 ASSERT(hp);
2086 2085
2087 2086 mr.map_op = DDI_MO_UNMAP;
2088 2087 mr.map_type = DDI_MT_REGSPEC;
2089 2088 mr.map_obj.rp = (struct regspec *)ph;
2090 2089 mr.map_prot = PROT_READ | PROT_WRITE;
2091 2090 mr.map_flags = DDI_MF_KERNEL_MAPPING;
2092 2091 mr.map_handlep = hp;
2093 2092 mr.map_vers = DDI_MAP_VERSION;
2094 2093
2095 2094 (void) ddi_map(hp->ah_dip, &mr, hp->ah_offset,
2096 2095 hp->ah_len, &hp->ah_addr);
2097 2096
2098 2097 impl_acc_hdl_free(*handlep);
2099 2098 *handlep = (ddi_acc_handle_t)NULL;
2100 2099 }
2101 2100
2102 2101 void
2103 2102 pcie_set_rber_fatal(dev_info_t *dip, boolean_t val)
2104 2103 {
2105 2104 pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip);
2106 2105 bus_p->bus_pfd->pe_rber_fatal = val;
2107 2106 }
2108 2107
2109 2108 /*
2110 2109 * Return parent Root Port's pe_rber_fatal value.
2111 2110 */
2112 2111 boolean_t
2113 2112 pcie_get_rber_fatal(dev_info_t *dip)
2114 2113 {
2115 2114 pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip);
2116 2115 pcie_bus_t *rp_bus_p = PCIE_DIP2UPBUS(bus_p->bus_rp_dip);
2117 2116 return (rp_bus_p->bus_pfd->pe_rber_fatal);
2118 2117 }
2119 2118
2120 2119 int
2121 2120 pcie_ari_supported(dev_info_t *dip)
2122 2121 {
2123 2122 uint32_t devcap2;
2124 2123 uint16_t pciecap;
2125 2124 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
2126 2125 uint8_t dev_type;
2127 2126
2128 2127 PCIE_DBG("pcie_ari_supported: dip=%p\n", dip);
2129 2128
2130 2129 if (bus_p == NULL)
2131 2130 return (PCIE_ARI_FORW_NOT_SUPPORTED);
2132 2131
2133 2132 dev_type = bus_p->bus_dev_type;
2134 2133
2135 2134 if ((dev_type != PCIE_PCIECAP_DEV_TYPE_DOWN) &&
2136 2135 (dev_type != PCIE_PCIECAP_DEV_TYPE_ROOT))
2137 2136 return (PCIE_ARI_FORW_NOT_SUPPORTED);
2138 2137
2139 2138 if (pcie_disable_ari) {
2140 2139 PCIE_DBG("pcie_ari_supported: dip=%p: ARI Disabled\n", dip);
2141 2140 return (PCIE_ARI_FORW_NOT_SUPPORTED);
2142 2141 }
2143 2142
2144 2143 pciecap = PCIE_CAP_GET(16, bus_p, PCIE_PCIECAP);
2145 2144
2146 2145 if ((pciecap & PCIE_PCIECAP_VER_MASK) < PCIE_PCIECAP_VER_2_0) {
2147 2146 PCIE_DBG("pcie_ari_supported: dip=%p: Not 2.0\n", dip);
2148 2147 return (PCIE_ARI_FORW_NOT_SUPPORTED);
2149 2148 }
2150 2149
2151 2150 devcap2 = PCIE_CAP_GET(32, bus_p, PCIE_DEVCAP2);
2152 2151
2153 2152 PCIE_DBG("pcie_ari_supported: dip=%p: DevCap2=0x%x\n",
2154 2153 dip, devcap2);
2155 2154
2156 2155 if (devcap2 & PCIE_DEVCAP2_ARI_FORWARD) {
2157 2156 PCIE_DBG("pcie_ari_supported: "
2158 2157 "dip=%p: ARI Forwarding is supported\n", dip);
2159 2158 return (PCIE_ARI_FORW_SUPPORTED);
2160 2159 }
2161 2160 return (PCIE_ARI_FORW_NOT_SUPPORTED);
2162 2161 }
2163 2162
2164 2163 int
2165 2164 pcie_ari_enable(dev_info_t *dip)
2166 2165 {
2167 2166 uint16_t devctl2;
2168 2167 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
2169 2168
2170 2169 PCIE_DBG("pcie_ari_enable: dip=%p\n", dip);
2171 2170
2172 2171 if (pcie_ari_supported(dip) == PCIE_ARI_FORW_NOT_SUPPORTED)
2173 2172 return (DDI_FAILURE);
2174 2173
2175 2174 devctl2 = PCIE_CAP_GET(16, bus_p, PCIE_DEVCTL2);
2176 2175 devctl2 |= PCIE_DEVCTL2_ARI_FORWARD_EN;
2177 2176 PCIE_CAP_PUT(16, bus_p, PCIE_DEVCTL2, devctl2);
2178 2177
2179 2178 PCIE_DBG("pcie_ari_enable: dip=%p: writing 0x%x to DevCtl2\n",
2180 2179 dip, devctl2);
2181 2180
2182 2181 return (DDI_SUCCESS);
2183 2182 }
2184 2183
2185 2184 int
2186 2185 pcie_ari_disable(dev_info_t *dip)
2187 2186 {
2188 2187 uint16_t devctl2;
2189 2188 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
2190 2189
2191 2190 PCIE_DBG("pcie_ari_disable: dip=%p\n", dip);
2192 2191
2193 2192 if (pcie_ari_supported(dip) == PCIE_ARI_FORW_NOT_SUPPORTED)
2194 2193 return (DDI_FAILURE);
2195 2194
2196 2195 devctl2 = PCIE_CAP_GET(16, bus_p, PCIE_DEVCTL2);
2197 2196 devctl2 &= ~PCIE_DEVCTL2_ARI_FORWARD_EN;
2198 2197 PCIE_CAP_PUT(16, bus_p, PCIE_DEVCTL2, devctl2);
2199 2198
2200 2199 PCIE_DBG("pcie_ari_disable: dip=%p: writing 0x%x to DevCtl2\n",
2201 2200 dip, devctl2);
2202 2201
2203 2202 return (DDI_SUCCESS);
2204 2203 }
2205 2204
2206 2205 int
2207 2206 pcie_ari_is_enabled(dev_info_t *dip)
2208 2207 {
2209 2208 uint16_t devctl2;
2210 2209 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
2211 2210
2212 2211 PCIE_DBG("pcie_ari_is_enabled: dip=%p\n", dip);
2213 2212
2214 2213 if (pcie_ari_supported(dip) == PCIE_ARI_FORW_NOT_SUPPORTED)
2215 2214 return (PCIE_ARI_FORW_DISABLED);
2216 2215
2217 2216 devctl2 = PCIE_CAP_GET(32, bus_p, PCIE_DEVCTL2);
2218 2217
2219 2218 PCIE_DBG("pcie_ari_is_enabled: dip=%p: DevCtl2=0x%x\n",
2220 2219 dip, devctl2);
2221 2220
2222 2221 if (devctl2 & PCIE_DEVCTL2_ARI_FORWARD_EN) {
2223 2222 PCIE_DBG("pcie_ari_is_enabled: "
2224 2223 "dip=%p: ARI Forwarding is enabled\n", dip);
2225 2224 return (PCIE_ARI_FORW_ENABLED);
2226 2225 }
2227 2226
2228 2227 return (PCIE_ARI_FORW_DISABLED);
2229 2228 }
2230 2229
2231 2230 int
2232 2231 pcie_ari_device(dev_info_t *dip)
2233 2232 {
2234 2233 ddi_acc_handle_t handle;
2235 2234 uint16_t cap_ptr;
2236 2235
2237 2236 PCIE_DBG("pcie_ari_device: dip=%p\n", dip);
2238 2237
2239 2238 /*
2240 2239 * XXX - This function may be called before the bus_p structure
2241 2240 * has been populated. This code can be changed to remove
2242 2241 * pci_config_setup()/pci_config_teardown() when the RFE
2243 2242 * to populate the bus_p structures early in boot is putback.
2244 2243 */
2245 2244
2246 2245 /* First make sure it is a PCIe device */
2247 2246
2248 2247 if (pci_config_setup(dip, &handle) != DDI_SUCCESS)
2249 2248 return (PCIE_NOT_ARI_DEVICE);
2250 2249
2251 2250 if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_ptr))
2252 2251 != DDI_SUCCESS) {
2253 2252 pci_config_teardown(&handle);
2254 2253 return (PCIE_NOT_ARI_DEVICE);
2255 2254 }
2256 2255
2257 2256 /* Locate the ARI Capability */
2258 2257
2259 2258 if ((PCI_CAP_LOCATE(handle, PCI_CAP_XCFG_SPC(PCIE_EXT_CAP_ID_ARI),
2260 2259 &cap_ptr)) == DDI_FAILURE) {
2261 2260 pci_config_teardown(&handle);
2262 2261 return (PCIE_NOT_ARI_DEVICE);
2263 2262 }
2264 2263
2265 2264 /* ARI Capability was found so it must be a ARI device */
2266 2265 PCIE_DBG("pcie_ari_device: ARI Device dip=%p\n", dip);
2267 2266
2268 2267 pci_config_teardown(&handle);
2269 2268 return (PCIE_ARI_DEVICE);
2270 2269 }
2271 2270
2272 2271 int
2273 2272 pcie_ari_get_next_function(dev_info_t *dip, int *func)
2274 2273 {
2275 2274 uint32_t val;
2276 2275 uint16_t cap_ptr, next_function;
2277 2276 ddi_acc_handle_t handle;
2278 2277
2279 2278 /*
2280 2279 * XXX - This function may be called before the bus_p structure
2281 2280 * has been populated. This code can be changed to remove
2282 2281 * pci_config_setup()/pci_config_teardown() when the RFE
2283 2282 * to populate the bus_p structures early in boot is putback.
2284 2283 */
2285 2284
2286 2285 if (pci_config_setup(dip, &handle) != DDI_SUCCESS)
2287 2286 return (DDI_FAILURE);
2288 2287
2289 2288 if ((PCI_CAP_LOCATE(handle,
2290 2289 PCI_CAP_XCFG_SPC(PCIE_EXT_CAP_ID_ARI), &cap_ptr)) == DDI_FAILURE) {
2291 2290 pci_config_teardown(&handle);
2292 2291 return (DDI_FAILURE);
2293 2292 }
2294 2293
2295 2294 val = PCI_CAP_GET32(handle, NULL, cap_ptr, PCIE_ARI_CAP);
2296 2295
2297 2296 next_function = (val >> PCIE_ARI_CAP_NEXT_FUNC_SHIFT) &
2298 2297 PCIE_ARI_CAP_NEXT_FUNC_MASK;
2299 2298
2300 2299 pci_config_teardown(&handle);
2301 2300
2302 2301 *func = next_function;
2303 2302
2304 2303 return (DDI_SUCCESS);
2305 2304 }
2306 2305
2307 2306 dev_info_t *
2308 2307 pcie_func_to_dip(dev_info_t *dip, pcie_req_id_t function)
2309 2308 {
2310 2309 pcie_req_id_t child_bdf;
2311 2310 dev_info_t *cdip;
2312 2311
2313 2312 for (cdip = ddi_get_child(dip); cdip;
2314 2313 cdip = ddi_get_next_sibling(cdip)) {
2315 2314
2316 2315 if (pcie_get_bdf_from_dip(cdip, &child_bdf) == DDI_FAILURE)
2317 2316 return (NULL);
2318 2317
2319 2318 if ((child_bdf & PCIE_REQ_ID_ARI_FUNC_MASK) == function)
2320 2319 return (cdip);
2321 2320 }
2322 2321 return (NULL);
2323 2322 }
2324 2323
2325 2324 #ifdef DEBUG
2326 2325
2327 2326 static void
2328 2327 pcie_print_bus(pcie_bus_t *bus_p)
2329 2328 {
2330 2329 pcie_dbg("\tbus_dip = 0x%p\n", bus_p->bus_dip);
2331 2330 pcie_dbg("\tbus_fm_flags = 0x%x\n", bus_p->bus_fm_flags);
2332 2331
2333 2332 pcie_dbg("\tbus_bdf = 0x%x\n", bus_p->bus_bdf);
2334 2333 pcie_dbg("\tbus_dev_ven_id = 0x%x\n", bus_p->bus_dev_ven_id);
2335 2334 pcie_dbg("\tbus_rev_id = 0x%x\n", bus_p->bus_rev_id);
2336 2335 pcie_dbg("\tbus_hdr_type = 0x%x\n", bus_p->bus_hdr_type);
2337 2336 pcie_dbg("\tbus_dev_type = 0x%x\n", bus_p->bus_dev_type);
2338 2337 pcie_dbg("\tbus_bdg_secbus = 0x%x\n", bus_p->bus_bdg_secbus);
2339 2338 pcie_dbg("\tbus_pcie_off = 0x%x\n", bus_p->bus_pcie_off);
2340 2339 pcie_dbg("\tbus_aer_off = 0x%x\n", bus_p->bus_aer_off);
2341 2340 pcie_dbg("\tbus_pcix_off = 0x%x\n", bus_p->bus_pcix_off);
2342 2341 pcie_dbg("\tbus_ecc_ver = 0x%x\n", bus_p->bus_ecc_ver);
2343 2342 }
2344 2343
2345 2344 /*
2346 2345 * For debugging purposes set pcie_dbg_print != 0 to see printf messages
2347 2346 * during interrupt.
2348 2347 *
2349 2348 * When a proper solution is in place this code will disappear.
2350 2349 * Potential solutions are:
2351 2350 * o circular buffers
2352 2351 * o taskq to print at lower pil
2353 2352 */
2354 2353 int pcie_dbg_print = 0;
2355 2354 void
2356 2355 pcie_dbg(char *fmt, ...)
2357 2356 {
2358 2357 va_list ap;
2359 2358
2360 2359 if (!pcie_debug_flags) {
2361 2360 return;
2362 2361 }
2363 2362 va_start(ap, fmt);
2364 2363 if (servicing_interrupt()) {
2365 2364 if (pcie_dbg_print) {
2366 2365 prom_vprintf(fmt, ap);
2367 2366 }
2368 2367 } else {
2369 2368 prom_vprintf(fmt, ap);
2370 2369 }
2371 2370 va_end(ap);
2372 2371 }
2373 2372 #endif /* DEBUG */
2374 2373
2375 2374 #if defined(__i386) || defined(__amd64)
2376 2375 static void
2377 2376 pcie_check_io_mem_range(ddi_acc_handle_t cfg_hdl, boolean_t *empty_io_range,
2378 2377 boolean_t *empty_mem_range)
2379 2378 {
2380 2379 uint8_t class, subclass;
2381 2380 uint_t val;
2382 2381
2383 2382 class = pci_config_get8(cfg_hdl, PCI_CONF_BASCLASS);
2384 2383 subclass = pci_config_get8(cfg_hdl, PCI_CONF_SUBCLASS);
2385 2384
2386 2385 if ((class == PCI_CLASS_BRIDGE) && (subclass == PCI_BRIDGE_PCI)) {
2387 2386 val = (((uint_t)pci_config_get8(cfg_hdl, PCI_BCNF_IO_BASE_LOW) &
2388 2387 PCI_BCNF_IO_MASK) << 8);
2389 2388 /*
2390 2389 * Assuming that a zero based io_range[0] implies an
2391 2390 * invalid I/O range. Likewise for mem_range[0].
2392 2391 */
2393 2392 if (val == 0)
2394 2393 *empty_io_range = B_TRUE;
2395 2394 val = (((uint_t)pci_config_get16(cfg_hdl, PCI_BCNF_MEM_BASE) &
2396 2395 PCI_BCNF_MEM_MASK) << 16);
2397 2396 if (val == 0)
2398 2397 *empty_mem_range = B_TRUE;
2399 2398 }
2400 2399 }
2401 2400
2402 2401 #endif /* defined(__i386) || defined(__amd64) */
↓ open down ↓ |
2228 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX