ar71xx_pci.c revision 285121
1/*- 2 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> 29__FBSDID("$FreeBSD: head/sys/mips/atheros/ar71xx_pci.c 285121 2015-07-04 03:05:57Z adrian $"); 30 31#include "opt_ar71xx.h" 32 33#include <sys/param.h> 34#include <sys/systm.h> 35 36#include <sys/bus.h> 37#include <sys/interrupt.h> 38#include <sys/malloc.h> 39#include <sys/kernel.h> 40#include <sys/module.h> 41#include <sys/rman.h> 42#include <sys/lock.h> 43#include <sys/mutex.h> 44 45#include <vm/vm.h> 46#include <vm/pmap.h> 47#include <vm/vm_extern.h> 48 49#include <machine/bus.h> 50#include <machine/cpu.h> 51#include <machine/intr_machdep.h> 52#include <machine/pmap.h> 53 54#include <dev/pci/pcivar.h> 55#include <dev/pci/pcireg.h> 56 57#include <dev/pci/pcib_private.h> 58#include "pcib_if.h" 59 60#include <mips/atheros/ar71xxreg.h> 61#include <mips/atheros/ar71xx_pci_bus_space.h> 62 63#include <mips/atheros/ar71xx_cpudef.h> 64 65#ifdef AR71XX_ATH_EEPROM 66#include <mips/atheros/ar71xx_fixup.h> 67#endif /* AR71XX_ATH_EEPROM */ 68 69#undef AR71XX_PCI_DEBUG 70#ifdef AR71XX_PCI_DEBUG 71#define dprintf printf 72#else 73#define dprintf(x, arg...) 74#endif 75 76struct mtx ar71xx_pci_mtx; 77MTX_SYSINIT(ar71xx_pci_mtx, &ar71xx_pci_mtx, "ar71xx PCI space mutex", 78 MTX_SPIN); 79 80struct ar71xx_pci_softc { 81 device_t sc_dev; 82 83 int sc_busno; 84 int sc_baseslot; 85 struct rman sc_mem_rman; 86 struct rman sc_irq_rman; 87 88 struct intr_event *sc_eventstab[AR71XX_PCI_NIRQS]; 89 mips_intrcnt_t sc_intr_counter[AR71XX_PCI_NIRQS]; 90 struct resource *sc_irq; 91 void *sc_ih; 92}; 93 94static int ar71xx_pci_setup_intr(device_t, device_t, struct resource *, int, 95 driver_filter_t *, driver_intr_t *, void *, void **); 96static int ar71xx_pci_teardown_intr(device_t, device_t, struct resource *, 97 void *); 98static int ar71xx_pci_intr(void *); 99 100static void 101ar71xx_pci_mask_irq(void *source) 102{ 103 uint32_t reg; 104 unsigned int irq = (unsigned int)source; 105 106 /* XXX is the PCI lock required here? */ 107 reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); 108 /* flush */ 109 reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); 110 ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg & ~(1 << irq)); 111} 112 113static void 114ar71xx_pci_unmask_irq(void *source) 115{ 116 uint32_t reg; 117 unsigned int irq = (unsigned int)source; 118 119 /* XXX is the PCI lock required here? */ 120 reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); 121 ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg | (1 << irq)); 122 /* flush */ 123 reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); 124} 125 126/* 127 * get bitmask for bytes of interest: 128 * 0 - we want this byte, 1 - ignore it. e.g: we read 1 byte 129 * from register 7. Bitmask would be: 0111 130 */ 131static uint32_t 132ar71xx_get_bytes_to_read(int reg, int bytes) 133{ 134 uint32_t bytes_to_read = 0; 135 136 if ((bytes % 4) == 0) 137 bytes_to_read = 0; 138 else if ((bytes % 4) == 1) 139 bytes_to_read = (~(1 << (reg % 4))) & 0xf; 140 else if ((bytes % 4) == 2) 141 bytes_to_read = (~(3 << (reg % 4))) & 0xf; 142 else 143 panic("%s: wrong combination", __func__); 144 145 return (bytes_to_read); 146} 147 148static int 149ar71xx_pci_check_bus_error(void) 150{ 151 uint32_t error, addr, has_errors = 0; 152 153 mtx_assert(&ar71xx_pci_mtx, MA_OWNED); 154 155 error = ATH_READ_REG(AR71XX_PCI_ERROR) & 0x3; 156 dprintf("%s: PCI error = %02x\n", __func__, error); 157 if (error) { 158 addr = ATH_READ_REG(AR71XX_PCI_ERROR_ADDR); 159 160 /* Do not report it yet */ 161#if 0 162 printf("PCI bus error %d at addr 0x%08x\n", error, addr); 163#endif 164 ATH_WRITE_REG(AR71XX_PCI_ERROR, error); 165 has_errors = 1; 166 } 167 168 error = ATH_READ_REG(AR71XX_PCI_AHB_ERROR) & 0x1; 169 dprintf("%s: AHB error = %02x\n", __func__, error); 170 if (error) { 171 addr = ATH_READ_REG(AR71XX_PCI_AHB_ERROR_ADDR); 172 /* Do not report it yet */ 173#if 0 174 printf("AHB bus error %d at addr 0x%08x\n", error, addr); 175#endif 176 ATH_WRITE_REG(AR71XX_PCI_AHB_ERROR, error); 177 has_errors = 1; 178 } 179 180 return (has_errors); 181} 182 183static uint32_t 184ar71xx_pci_make_addr(int bus, int slot, int func, int reg) 185{ 186 if (bus == 0) { 187 return ((1 << slot) | (func << 8) | (reg & ~3)); 188 } else { 189 return ((bus << 16) | (slot << 11) | (func << 8) 190 | (reg & ~3) | 1); 191 } 192} 193 194static int 195ar71xx_pci_conf_setup(int bus, int slot, int func, int reg, int bytes, 196 uint32_t cmd) 197{ 198 uint32_t addr = ar71xx_pci_make_addr(bus, slot, func, (reg & ~3)); 199 200 mtx_assert(&ar71xx_pci_mtx, MA_OWNED); 201 202 cmd |= (ar71xx_get_bytes_to_read(reg, bytes) << 4); 203 ATH_WRITE_REG(AR71XX_PCI_CONF_ADDR, addr); 204 ATH_WRITE_REG(AR71XX_PCI_CONF_CMD, cmd); 205 206 dprintf("%s: tag (%x, %x, %x) %d/%d addr=%08x, cmd=%08x\n", __func__, 207 bus, slot, func, reg, bytes, addr, cmd); 208 209 return ar71xx_pci_check_bus_error(); 210} 211 212static uint32_t 213ar71xx_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, 214 u_int reg, int bytes) 215{ 216 uint32_t data; 217 uint32_t shift, mask; 218 219 /* register access is 32-bit aligned */ 220 shift = (reg & 3) * 8; 221 222 /* Create a mask based on the width, post-shift */ 223 if (bytes == 2) 224 mask = 0xffff; 225 else if (bytes == 1) 226 mask = 0xff; 227 else 228 mask = 0xffffffff; 229 230 dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, 231 func, reg, bytes); 232 233 mtx_lock_spin(&ar71xx_pci_mtx); 234 if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, 235 PCI_CONF_CMD_READ) == 0) 236 data = ATH_READ_REG(AR71XX_PCI_CONF_READ_DATA); 237 else 238 data = -1; 239 mtx_unlock_spin(&ar71xx_pci_mtx); 240 241 /* get request bytes from 32-bit word */ 242 data = (data >> shift) & mask; 243 244 dprintf("%s: read 0x%x\n", __func__, data); 245 246 return (data); 247} 248 249static void 250ar71xx_pci_local_write(device_t dev, uint32_t reg, uint32_t data, int bytes) 251{ 252 uint32_t cmd; 253 254 dprintf("%s: local write reg %d(%d)\n", __func__, reg, bytes); 255 256 data = data << (8*(reg % 4)); 257 cmd = PCI_LCONF_CMD_WRITE | (reg & ~3); 258 cmd |= (ar71xx_get_bytes_to_read(reg, bytes) << 20); 259 mtx_lock_spin(&ar71xx_pci_mtx); 260 ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd); 261 ATH_WRITE_REG(AR71XX_PCI_LCONF_WRITE_DATA, data); 262 mtx_unlock_spin(&ar71xx_pci_mtx); 263} 264 265static void 266ar71xx_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, 267 u_int reg, uint32_t data, int bytes) 268{ 269 270 dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, 271 func, reg, bytes); 272 273 data = data << (8*(reg % 4)); 274 mtx_lock_spin(&ar71xx_pci_mtx); 275 if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, 276 PCI_CONF_CMD_WRITE) == 0) 277 ATH_WRITE_REG(AR71XX_PCI_CONF_WRITE_DATA, data); 278 mtx_unlock_spin(&ar71xx_pci_mtx); 279} 280 281#ifdef AR71XX_ATH_EEPROM 282/* 283 * Some embedded boards (eg AP94) have the MAC attached via PCI but they 284 * don't have the MAC-attached EEPROM. The register initialisation 285 * values and calibration data are stored in the on-board flash. 286 * This routine initialises the NIC via the EEPROM register contents 287 * before the probe/attach routines get a go at things. 288 */ 289static void 290ar71xx_pci_fixup(device_t dev, u_int bus, u_int slot, u_int func, 291 long flash_addr, int len) 292{ 293 uint16_t *cal_data = (uint16_t *) MIPS_PHYS_TO_KSEG1(flash_addr); 294 uint32_t reg, val, bar0; 295 296 if (bootverbose) 297 device_printf(dev, "%s: flash_addr=%lx, cal_data=%p\n", 298 __func__, flash_addr, cal_data); 299 300 /* XXX check 0xa55a */ 301 /* Save bar(0) address - just to flush bar(0) (SoC WAR) ? */ 302 bar0 = ar71xx_pci_read_config(dev, bus, slot, func, PCIR_BAR(0), 4); 303 ar71xx_pci_write_config(dev, bus, slot, func, PCIR_BAR(0), 304 AR71XX_PCI_MEM_BASE, 4); 305 306 val = ar71xx_pci_read_config(dev, bus, slot, func, PCIR_COMMAND, 2); 307 val |= (PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN); 308 ar71xx_pci_write_config(dev, bus, slot, func, PCIR_COMMAND, val, 2); 309 310 cal_data += 3; 311 while (*cal_data != 0xffff) { 312 reg = *cal_data++; 313 val = *cal_data++; 314 val |= (*cal_data++) << 16; 315 if (bootverbose) 316 printf(" reg: %x, val=%x\n", reg, val); 317 318 /* Write eeprom fixup data to device memory */ 319 ATH_WRITE_REG(AR71XX_PCI_MEM_BASE + reg, val); 320 DELAY(100); 321 } 322 323 val = ar71xx_pci_read_config(dev, bus, slot, func, PCIR_COMMAND, 2); 324 val &= ~(PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN); 325 ar71xx_pci_write_config(dev, bus, slot, func, PCIR_COMMAND, val, 2); 326 327 /* Write the saved bar(0) address */ 328 ar71xx_pci_write_config(dev, bus, slot, func, PCIR_BAR(0), bar0, 4); 329} 330 331static void 332ar71xx_pci_slot_fixup(device_t dev, u_int bus, u_int slot, u_int func) 333{ 334 long int flash_addr; 335 char buf[64]; 336 int size; 337 338 /* 339 * Check whether the given slot has a hint to poke. 340 */ 341 if (bootverbose) 342 device_printf(dev, "%s: checking dev %s, %d/%d/%d\n", 343 __func__, device_get_nameunit(dev), bus, slot, func); 344 345 snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_addr", 346 bus, slot, func); 347 348 if (resource_long_value(device_get_name(dev), device_get_unit(dev), 349 buf, &flash_addr) == 0) { 350 snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_size", 351 bus, slot, func); 352 if (resource_int_value(device_get_name(dev), 353 device_get_unit(dev), buf, &size) != 0) { 354 device_printf(dev, 355 "%s: missing hint '%s', aborting EEPROM\n", 356 __func__, buf); 357 return; 358 } 359 360 361 device_printf(dev, "found EEPROM at 0x%lx on %d.%d.%d\n", 362 flash_addr, bus, slot, func); 363 ar71xx_pci_fixup(dev, bus, slot, func, flash_addr, size); 364 ar71xx_pci_slot_create_eeprom_firmware(dev, bus, slot, func, 365 flash_addr, size); 366 } 367} 368#endif /* AR71XX_ATH_EEPROM */ 369 370static int 371ar71xx_pci_probe(device_t dev) 372{ 373 374 return (BUS_PROBE_NOWILDCARD); 375} 376 377static int 378ar71xx_pci_attach(device_t dev) 379{ 380 int busno = 0; 381 int rid = 0; 382 struct ar71xx_pci_softc *sc = device_get_softc(dev); 383 384 sc->sc_mem_rman.rm_type = RMAN_ARRAY; 385 sc->sc_mem_rman.rm_descr = "ar71xx PCI memory window"; 386 if (rman_init(&sc->sc_mem_rman) != 0 || 387 rman_manage_region(&sc->sc_mem_rman, AR71XX_PCI_MEM_BASE, 388 AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1) != 0) { 389 panic("ar71xx_pci_attach: failed to set up I/O rman"); 390 } 391 392 sc->sc_irq_rman.rm_type = RMAN_ARRAY; 393 sc->sc_irq_rman.rm_descr = "ar71xx PCI IRQs"; 394 if (rman_init(&sc->sc_irq_rman) != 0 || 395 rman_manage_region(&sc->sc_irq_rman, AR71XX_PCI_IRQ_START, 396 AR71XX_PCI_IRQ_END) != 0) 397 panic("ar71xx_pci_attach: failed to set up IRQ rman"); 398 399 /* 400 * Check if there is a base slot hint. Otherwise use default value. 401 */ 402 if (resource_int_value(device_get_name(dev), 403 device_get_unit(dev), "baseslot", &sc->sc_baseslot) != 0) { 404 device_printf(dev, 405 "%s: missing hint '%s', default to AR71XX_PCI_BASE_SLOT\n", 406 __func__, "baseslot"); 407 sc->sc_baseslot = AR71XX_PCI_BASE_SLOT; 408 } 409 410 ATH_WRITE_REG(AR71XX_PCI_INTR_STATUS, 0); 411 ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, 0); 412 413 /* Hook up our interrupt handler. */ 414 if ((sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 415 RF_SHAREABLE | RF_ACTIVE)) == NULL) { 416 device_printf(dev, "unable to allocate IRQ resource\n"); 417 return ENXIO; 418 } 419 420 if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, 421 ar71xx_pci_intr, NULL, sc, &sc->sc_ih))) { 422 device_printf(dev, 423 "WARNING: unable to register interrupt handler\n"); 424 return ENXIO; 425 } 426 427 /* reset PCI core and PCI bus */ 428 ar71xx_device_stop(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); 429 DELAY(100000); 430 431 ar71xx_device_start(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); 432 DELAY(100000); 433 434 /* Init PCI windows */ 435 ATH_WRITE_REG(AR71XX_PCI_WINDOW0, PCI_WINDOW0_ADDR); 436 ATH_WRITE_REG(AR71XX_PCI_WINDOW1, PCI_WINDOW1_ADDR); 437 ATH_WRITE_REG(AR71XX_PCI_WINDOW2, PCI_WINDOW2_ADDR); 438 ATH_WRITE_REG(AR71XX_PCI_WINDOW3, PCI_WINDOW3_ADDR); 439 ATH_WRITE_REG(AR71XX_PCI_WINDOW4, PCI_WINDOW4_ADDR); 440 ATH_WRITE_REG(AR71XX_PCI_WINDOW5, PCI_WINDOW5_ADDR); 441 ATH_WRITE_REG(AR71XX_PCI_WINDOW6, PCI_WINDOW6_ADDR); 442 ATH_WRITE_REG(AR71XX_PCI_WINDOW7, PCI_WINDOW7_CONF_ADDR); 443 DELAY(100000); 444 445 mtx_lock_spin(&ar71xx_pci_mtx); 446 ar71xx_pci_check_bus_error(); 447 mtx_unlock_spin(&ar71xx_pci_mtx); 448 449 /* Fixup internal PCI bridge */ 450 ar71xx_pci_local_write(dev, PCIR_COMMAND, 451 PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN 452 | PCIM_CMD_SERRESPEN | PCIM_CMD_BACKTOBACK 453 | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN, 4); 454 455#ifdef AR71XX_ATH_EEPROM 456 /* 457 * Hard-code a check for slot 17 and 18 - these are 458 * the two PCI slots which may have a PCI device that 459 * requires "fixing". 460 */ 461 ar71xx_pci_slot_fixup(dev, 0, 17, 0); 462 ar71xx_pci_slot_fixup(dev, 0, 18, 0); 463#endif /* AR71XX_ATH_EEPROM */ 464 465 device_add_child(dev, "pci", busno); 466 return (bus_generic_attach(dev)); 467} 468 469static int 470ar71xx_pci_read_ivar(device_t dev, device_t child, int which, 471 uintptr_t *result) 472{ 473 struct ar71xx_pci_softc *sc = device_get_softc(dev); 474 475 switch (which) { 476 case PCIB_IVAR_DOMAIN: 477 *result = 0; 478 return (0); 479 case PCIB_IVAR_BUS: 480 *result = sc->sc_busno; 481 return (0); 482 } 483 484 return (ENOENT); 485} 486 487static int 488ar71xx_pci_write_ivar(device_t dev, device_t child, int which, 489 uintptr_t result) 490{ 491 struct ar71xx_pci_softc * sc = device_get_softc(dev); 492 493 switch (which) { 494 case PCIB_IVAR_BUS: 495 sc->sc_busno = result; 496 return (0); 497 } 498 499 return (ENOENT); 500} 501 502static struct resource * 503ar71xx_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, 504 u_long start, u_long end, u_long count, u_int flags) 505{ 506 507 struct ar71xx_pci_softc *sc = device_get_softc(bus); 508 struct resource *rv; 509 struct rman *rm; 510 511 switch (type) { 512 case SYS_RES_IRQ: 513 rm = &sc->sc_irq_rman; 514 break; 515 case SYS_RES_MEMORY: 516 rm = &sc->sc_mem_rman; 517 break; 518 default: 519 return (NULL); 520 } 521 522 rv = rman_reserve_resource(rm, start, end, count, flags, child); 523 524 if (rv == NULL) 525 return (NULL); 526 527 rman_set_rid(rv, *rid); 528 529 if (flags & RF_ACTIVE) { 530 if (bus_activate_resource(child, type, *rid, rv)) { 531 rman_release_resource(rv); 532 return (NULL); 533 } 534 } 535 return (rv); 536} 537 538static int 539ar71xx_pci_activate_resource(device_t bus, device_t child, int type, int rid, 540 struct resource *r) 541{ 542 int res = (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), 543 child, type, rid, r)); 544 545 if (!res) { 546 switch(type) { 547 case SYS_RES_MEMORY: 548 case SYS_RES_IOPORT: 549 rman_set_bustag(r, ar71xx_bus_space_pcimem); 550 break; 551 } 552 } 553 return (res); 554} 555 556static int 557ar71xx_pci_setup_intr(device_t bus, device_t child, struct resource *ires, 558 int flags, driver_filter_t *filt, driver_intr_t *handler, 559 void *arg, void **cookiep) 560{ 561 struct ar71xx_pci_softc *sc = device_get_softc(bus); 562 struct intr_event *event; 563 int irq, error; 564 565 irq = rman_get_start(ires); 566 567 if (irq > AR71XX_PCI_IRQ_END) 568 panic("%s: bad irq %d", __func__, irq); 569 570 event = sc->sc_eventstab[irq]; 571 if (event == NULL) { 572 error = intr_event_create(&event, (void *)irq, 0, irq, 573 ar71xx_pci_mask_irq, ar71xx_pci_unmask_irq, NULL, NULL, 574 "pci intr%d:", irq); 575 576 if (error == 0) { 577 sc->sc_eventstab[irq] = event; 578 sc->sc_intr_counter[irq] = 579 mips_intrcnt_create(event->ie_name); 580 } 581 else 582 return (error); 583 } 584 585 intr_event_add_handler(event, device_get_nameunit(child), filt, 586 handler, arg, intr_priority(flags), flags, cookiep); 587 mips_intrcnt_setname(sc->sc_intr_counter[irq], event->ie_fullname); 588 589 ar71xx_pci_unmask_irq((void*)irq); 590 591 return (0); 592} 593 594static int 595ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *ires, 596 void *cookie) 597{ 598 struct ar71xx_pci_softc *sc = device_get_softc(dev); 599 int irq, result; 600 601 irq = rman_get_start(ires); 602 if (irq > AR71XX_PCI_IRQ_END) 603 panic("%s: bad irq %d", __func__, irq); 604 605 if (sc->sc_eventstab[irq] == NULL) 606 panic("Trying to teardown unoccupied IRQ"); 607 608 ar71xx_pci_mask_irq((void*)irq); 609 610 result = intr_event_remove_handler(cookie); 611 if (!result) 612 sc->sc_eventstab[irq] = NULL; 613 614 return (result); 615} 616 617static int 618ar71xx_pci_intr(void *arg) 619{ 620 struct ar71xx_pci_softc *sc = arg; 621 struct intr_event *event; 622 uint32_t reg, irq, mask; 623 624 reg = ATH_READ_REG(AR71XX_PCI_INTR_STATUS); 625 mask = ATH_READ_REG(AR71XX_PCI_INTR_MASK); 626 /* 627 * Handle only unmasked interrupts 628 */ 629 reg &= mask; 630 for (irq = AR71XX_PCI_IRQ_START; irq <= AR71XX_PCI_IRQ_END; irq++) { 631 if (reg & (1 << irq)) { 632 event = sc->sc_eventstab[irq]; 633 if (!event || TAILQ_EMPTY(&event->ie_handlers)) { 634 /* Ignore timer interrupts */ 635 if (irq != 0) 636 printf("Stray IRQ %d\n", irq); 637 continue; 638 } 639 640 /* Flush DDR FIFO for PCI/PCIe */ 641 ar71xx_device_flush_ddr(AR71XX_CPU_DDR_FLUSH_PCIE); 642 643 /* TODO: frame instead of NULL? */ 644 intr_event_handle(event, NULL); 645 mips_intrcnt_inc(sc->sc_intr_counter[irq]); 646 } 647 } 648 649 return (FILTER_HANDLED); 650} 651 652static int 653ar71xx_pci_maxslots(device_t dev) 654{ 655 656 return (PCI_SLOTMAX); 657} 658 659static int 660ar71xx_pci_route_interrupt(device_t pcib, device_t device, int pin) 661{ 662 struct ar71xx_pci_softc *sc = device_get_softc(pcib); 663 664 if (pci_get_slot(device) < sc->sc_baseslot) 665 panic("%s: PCI slot %d is less then AR71XX_PCI_BASE_SLOT", 666 __func__, pci_get_slot(device)); 667 668 return (pci_get_slot(device) - sc->sc_baseslot); 669} 670 671static device_method_t ar71xx_pci_methods[] = { 672 /* Device interface */ 673 DEVMETHOD(device_probe, ar71xx_pci_probe), 674 DEVMETHOD(device_attach, ar71xx_pci_attach), 675 DEVMETHOD(device_shutdown, bus_generic_shutdown), 676 DEVMETHOD(device_suspend, bus_generic_suspend), 677 DEVMETHOD(device_resume, bus_generic_resume), 678 679 /* Bus interface */ 680 DEVMETHOD(bus_read_ivar, ar71xx_pci_read_ivar), 681 DEVMETHOD(bus_write_ivar, ar71xx_pci_write_ivar), 682 DEVMETHOD(bus_alloc_resource, ar71xx_pci_alloc_resource), 683 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 684 DEVMETHOD(bus_activate_resource, ar71xx_pci_activate_resource), 685 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 686 DEVMETHOD(bus_setup_intr, ar71xx_pci_setup_intr), 687 DEVMETHOD(bus_teardown_intr, ar71xx_pci_teardown_intr), 688 689 /* pcib interface */ 690 DEVMETHOD(pcib_maxslots, ar71xx_pci_maxslots), 691 DEVMETHOD(pcib_read_config, ar71xx_pci_read_config), 692 DEVMETHOD(pcib_write_config, ar71xx_pci_write_config), 693 DEVMETHOD(pcib_route_interrupt, ar71xx_pci_route_interrupt), 694 695 DEVMETHOD_END 696}; 697 698static driver_t ar71xx_pci_driver = { 699 "pcib", 700 ar71xx_pci_methods, 701 sizeof(struct ar71xx_pci_softc), 702}; 703 704static devclass_t ar71xx_pci_devclass; 705 706DRIVER_MODULE(ar71xx_pci, nexus, ar71xx_pci_driver, ar71xx_pci_devclass, 0, 0); 707