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