qca955x_pci.c revision 287882
1/*- 2 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org> 3 * Copyright (c) 2011, Luiz Otavio O Souza. 4 * Copyright (c) 2015, Adrian Chadd <adrian@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: head/sys/mips/atheros/qca955x_pci.c 287882 2015-09-16 23:34:51Z zbb $"); 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 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> /* XXX aim to eliminate this! */ 61#include <mips/atheros/qca955xreg.h> 62#include <mips/atheros/ar71xx_setup.h> 63#include <mips/atheros/ar71xx_pci_bus_space.h> 64 65#include <mips/atheros/ar71xx_cpudef.h> 66 67#undef AR724X_PCI_DEBUG 68//#define AR724X_PCI_DEBUG 69#ifdef AR724X_PCI_DEBUG 70#define dprintf printf 71#else 72#define dprintf(x, arg...) 73#endif 74 75/* 76 * This is a PCI controller for the QCA955x and later SoCs. 77 * It needs to be aware of >1 PCIe host endpoints. 78 * 79 * XXX TODO; it may be nice to merge this with ar724x_pci.c; 80 * they're very similar. 81 */ 82struct ar71xx_pci_irq { 83 struct ar71xx_pci_softc *sc; 84 int irq; 85}; 86 87struct ar71xx_pci_softc { 88 device_t sc_dev; 89 90 int sc_busno; 91 struct rman sc_mem_rman; 92 struct rman sc_irq_rman; 93 94 uint32_t sc_pci_reg_base; /* XXX until bus stuff is done */ 95 uint32_t sc_pci_crp_base; /* XXX until bus stuff is done */ 96 uint32_t sc_pci_ctrl_base; /* XXX until bus stuff is done */ 97 uint32_t sc_pci_mem_base; /* XXX until bus stuff is done */ 98 uint32_t sc_pci_membase_limit; 99 100 struct intr_event *sc_eventstab[AR71XX_PCI_NIRQS]; 101 mips_intrcnt_t sc_intr_counter[AR71XX_PCI_NIRQS]; 102 struct ar71xx_pci_irq sc_pci_irq[AR71XX_PCI_NIRQS]; 103 struct resource *sc_irq; 104 void *sc_ih; 105}; 106 107static int qca955x_pci_setup_intr(device_t, device_t, struct resource *, int, 108 driver_filter_t *, driver_intr_t *, void *, void **); 109static int qca955x_pci_teardown_intr(device_t, device_t, struct resource *, 110 void *); 111static int qca955x_pci_intr(void *); 112 113static void 114qca955x_pci_write(uint32_t reg, uint32_t offset, uint32_t data, int bytes) 115{ 116 uint32_t val, mask, shift; 117 118 /* Register access is 32-bit aligned */ 119 shift = (offset & 3) * 8; 120 if (bytes % 4) 121 mask = (1 << (bytes * 8)) - 1; 122 else 123 mask = 0xffffffff; 124 125 val = ATH_READ_REG(reg + (offset & ~3)); 126 val &= ~(mask << shift); 127 val |= ((data & mask) << shift); 128 ATH_WRITE_REG(reg + (offset & ~3), val); 129 130 dprintf("%s: %#x/%#x addr=%#x, data=%#x(%#x), bytes=%d\n", __func__, 131 reg, reg + (offset & ~3), offset, data, val, bytes); 132} 133 134static uint32_t 135qca955x_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, 136 u_int reg, int bytes) 137{ 138 struct ar71xx_pci_softc *sc = device_get_softc(dev); 139 uint32_t data, shift, mask; 140 141 /* Register access is 32-bit aligned */ 142 shift = (reg & 3) * 8; 143 144 /* Create a mask based on the width, post-shift */ 145 if (bytes == 2) 146 mask = 0xffff; 147 else if (bytes == 1) 148 mask = 0xff; 149 else 150 mask = 0xffffffff; 151 152 dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, 153 func, reg, bytes); 154 155 if ((bus == 0) && (slot == 0) && (func == 0)) 156 data = ATH_READ_REG(sc->sc_pci_reg_base + (reg & ~3)); 157 else 158 data = -1; 159 160 /* Get request bytes from 32-bit word */ 161 data = (data >> shift) & mask; 162 163 dprintf("%s: read 0x%x\n", __func__, data); 164 165 return (data); 166} 167 168static void 169qca955x_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, 170 u_int reg, uint32_t data, int bytes) 171{ 172 struct ar71xx_pci_softc *sc = device_get_softc(dev); 173 174 dprintf("%s: tag (%x, %x, %x) reg %d(%d): %x\n", __func__, bus, slot, 175 func, reg, bytes, data); 176 177 if ((bus != 0) || (slot != 0) || (func != 0)) 178 return; 179 180 qca955x_pci_write(sc->sc_pci_reg_base, reg, data, bytes); 181} 182 183static void 184qca955x_pci_mask_irq(void *source) 185{ 186 uint32_t reg; 187 struct ar71xx_pci_irq *pirq = source; 188 struct ar71xx_pci_softc *sc = pirq->sc; 189 190 /* XXX - Only one interrupt ? Only one device ? */ 191 if (pirq->irq != AR71XX_PCI_IRQ_START) 192 return; 193 194 /* Update the interrupt mask reg */ 195 reg = ATH_READ_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_INTR_MASK); 196 ATH_WRITE_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_INTR_MASK, 197 reg & ~QCA955X_PCI_INTR_DEV0); 198 199 /* Clear any pending interrupt */ 200 reg = ATH_READ_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_INTR_STATUS); 201 ATH_WRITE_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_INTR_STATUS, 202 reg | QCA955X_PCI_INTR_DEV0); 203} 204 205static void 206qca955x_pci_unmask_irq(void *source) 207{ 208 uint32_t reg; 209 struct ar71xx_pci_irq *pirq = source; 210 struct ar71xx_pci_softc *sc = pirq->sc; 211 212 if (pirq->irq != AR71XX_PCI_IRQ_START) 213 return; 214 215 /* Update the interrupt mask reg */ 216 reg = ATH_READ_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_INTR_MASK); 217 ATH_WRITE_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_INTR_MASK, 218 reg | QCA955X_PCI_INTR_DEV0); 219} 220 221static int 222qca955x_pci_setup(device_t dev) 223{ 224 struct ar71xx_pci_softc *sc = device_get_softc(dev); 225 uint32_t reg; 226 227 /* setup COMMAND register */ 228 reg = PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | PCIM_CMD_SERRESPEN | 229 PCIM_CMD_BACKTOBACK | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN; 230 231 qca955x_pci_write(sc->sc_pci_crp_base, PCIR_COMMAND, reg, 2); 232 233 /* These are the memory/prefetch base/limit parameters */ 234 qca955x_pci_write(sc->sc_pci_crp_base, 0x20, sc->sc_pci_membase_limit, 4); 235 qca955x_pci_write(sc->sc_pci_crp_base, 0x24, sc->sc_pci_membase_limit, 4); 236 237 reg = ATH_READ_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_RESET); 238 if (reg != 0x7) { 239 DELAY(100000); 240 ATH_WRITE_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_RESET, 0); 241 ATH_READ_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_RESET); 242 DELAY(100); 243 ATH_WRITE_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_RESET, 4); 244 ATH_READ_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_RESET); 245 DELAY(100000); 246 } 247 248 ATH_WRITE_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_APP, 0x1ffc1); 249 /* Flush write */ 250 (void) ATH_READ_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_APP); 251 252 DELAY(1000); 253 254 reg = ATH_READ_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_RESET); 255 if ((reg & QCA955X_PCI_RESET_LINK_UP) == 0) { 256 device_printf(dev, "no PCIe controller found\n"); 257 return (ENXIO); 258 } 259 260 return (0); 261} 262 263static int 264qca955x_pci_probe(device_t dev) 265{ 266 267 return (BUS_PROBE_NOWILDCARD); 268} 269 270static int 271qca955x_pci_attach(device_t dev) 272{ 273 struct ar71xx_pci_softc *sc = device_get_softc(dev); 274 int unit = device_get_unit(dev); 275 int busno = 0; 276 int rid = 0; 277 278 /* Dirty; maybe these could all just be hints */ 279 if (unit == 0) { 280 sc->sc_pci_reg_base = QCA955X_PCI_CFG_BASE0; 281 sc->sc_pci_crp_base = QCA955X_PCI_CRP_BASE0; 282 sc->sc_pci_ctrl_base = QCA955X_PCI_CTRL_BASE0; 283 sc->sc_pci_mem_base = QCA955X_PCI_MEM_BASE0; 284 /* XXX verify */ 285 sc->sc_pci_membase_limit = 0x11f01000; 286 } else if (unit == 1) { 287 sc->sc_pci_reg_base = QCA955X_PCI_CFG_BASE1; 288 sc->sc_pci_crp_base = QCA955X_PCI_CRP_BASE1; 289 sc->sc_pci_ctrl_base = QCA955X_PCI_CTRL_BASE1; 290 sc->sc_pci_mem_base = QCA955X_PCI_MEM_BASE1; 291 /* XXX verify */ 292 sc->sc_pci_membase_limit = 0x12f01200; 293 } else { 294 device_printf(dev, "%s: invalid unit (%d)\n", __func__, unit); 295 return (ENXIO); 296 } 297 298 sc->sc_mem_rman.rm_type = RMAN_ARRAY; 299 sc->sc_mem_rman.rm_descr = "qca955x PCI memory window"; 300 if (rman_init(&sc->sc_mem_rman) != 0 || 301 rman_manage_region(&sc->sc_mem_rman, 302 sc->sc_pci_mem_base, 303 sc->sc_pci_mem_base + QCA955X_PCI_MEM_SIZE - 1) != 0) { 304 panic("qca955x_pci_attach: failed to set up I/O rman"); 305 } 306 307 sc->sc_irq_rman.rm_type = RMAN_ARRAY; 308 sc->sc_irq_rman.rm_descr = "qca955x PCI IRQs"; 309 if (rman_init(&sc->sc_irq_rman) != 0 || 310 rman_manage_region(&sc->sc_irq_rman, AR71XX_PCI_IRQ_START, 311 AR71XX_PCI_IRQ_END) != 0) 312 panic("qca955x_pci_attach: failed to set up IRQ rman"); 313 314 /* Disable interrupts */ 315 ATH_WRITE_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_INTR_STATUS, 0); 316 ATH_WRITE_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_INTR_MASK, 0); 317 318 /* Hook up our interrupt handler. */ 319 if ((sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 320 RF_SHAREABLE | RF_ACTIVE)) == NULL) { 321 device_printf(dev, "unable to allocate IRQ resource\n"); 322 return (ENXIO); 323 } 324 325 if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, 326 qca955x_pci_intr, NULL, sc, &sc->sc_ih))) { 327 device_printf(dev, 328 "WARNING: unable to register interrupt handler\n"); 329 return (ENXIO); 330 } 331 332 /* Reset PCIe core and PCIe PHY */ 333 ar71xx_device_stop(QCA955X_RESET_PCIE); 334 ar71xx_device_stop(QCA955X_RESET_PCIE_PHY); 335 DELAY(100); 336 ar71xx_device_start(QCA955X_RESET_PCIE_PHY); 337 ar71xx_device_start(QCA955X_RESET_PCIE); 338 339 if (qca955x_pci_setup(dev)) 340 return (ENXIO); 341 342 /* 343 * Write initial base address. 344 * 345 * I'm not yet sure why this is required and/or why it isn't 346 * initialised like this. The AR71xx PCI code initialises 347 * the PCI windows for each device, but neither it or the 348 * 724x PCI bridge modules explicitly initialise the BAR. 349 * 350 * So before this gets committed, have a chat with jhb@ or 351 * someone else who knows PCI well and figure out whether 352 * the initial BAR is supposed to be determined by /other/ 353 * means. 354 */ 355 qca955x_pci_write_config(dev, 0, 0, 0, PCIR_BAR(0), 356 sc->sc_pci_mem_base, 357 4); 358 359 /* Fixup internal PCI bridge */ 360 qca955x_pci_write_config(dev, 0, 0, 0, PCIR_COMMAND, 361 PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN 362 | PCIM_CMD_SERRESPEN | PCIM_CMD_BACKTOBACK 363 | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN, 2); 364 365 device_add_child(dev, "pci", -1); 366 return (bus_generic_attach(dev)); 367} 368 369static int 370qca955x_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 371{ 372 struct ar71xx_pci_softc *sc = device_get_softc(dev); 373 374 switch (which) { 375 case PCIB_IVAR_DOMAIN: 376 *result = 0; 377 return (0); 378 case PCIB_IVAR_BUS: 379 *result = sc->sc_busno; 380 return (0); 381 } 382 383 return (ENOENT); 384} 385 386static int 387qca955x_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t result) 388{ 389 struct ar71xx_pci_softc * sc = device_get_softc(dev); 390 391 switch (which) { 392 case PCIB_IVAR_BUS: 393 sc->sc_busno = result; 394 return (0); 395 } 396 397 return (ENOENT); 398} 399 400static struct resource * 401qca955x_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, 402 u_long start, u_long end, u_long count, u_int flags) 403{ 404 struct ar71xx_pci_softc *sc = device_get_softc(bus); 405 struct resource *rv; 406 struct rman *rm; 407 408 switch (type) { 409 case SYS_RES_IRQ: 410 rm = &sc->sc_irq_rman; 411 break; 412 case SYS_RES_MEMORY: 413 rm = &sc->sc_mem_rman; 414 break; 415 default: 416 return (NULL); 417 } 418 419 rv = rman_reserve_resource(rm, start, end, count, flags, child); 420 421 if (rv == NULL) 422 return (NULL); 423 424 rman_set_rid(rv, *rid); 425 426 if (flags & RF_ACTIVE) { 427 if (bus_activate_resource(child, type, *rid, rv)) { 428 rman_release_resource(rv); 429 return (NULL); 430 } 431 } 432 433 return (rv); 434} 435 436static int 437qca955x_pci_activate_resource(device_t bus, device_t child, int type, int rid, 438 struct resource *r) 439{ 440 int res = (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), 441 child, type, rid, r)); 442 443 if (!res) { 444 switch(type) { 445 case SYS_RES_MEMORY: 446 case SYS_RES_IOPORT: 447 448 rman_set_bustag(r, ar71xx_bus_space_pcimem); 449 break; 450 } 451 } 452 453 return (res); 454} 455 456static int 457qca955x_pci_setup_intr(device_t bus, device_t child, struct resource *ires, 458 int flags, driver_filter_t *filt, driver_intr_t *handler, 459 void *arg, void **cookiep) 460{ 461 struct ar71xx_pci_softc *sc = device_get_softc(bus); 462 struct intr_event *event; 463 int irq, error; 464 465 irq = rman_get_start(ires); 466 if (irq > AR71XX_PCI_IRQ_END) 467 panic("%s: bad irq %d", __func__, irq); 468 469 event = sc->sc_eventstab[irq]; 470 if (event == NULL) { 471 sc->sc_pci_irq[irq].sc = sc; 472 sc->sc_pci_irq[irq].irq = irq; 473 error = intr_event_create(&event, (void *)&sc->sc_pci_irq[irq], 474 0, irq, 475 qca955x_pci_mask_irq, 476 qca955x_pci_unmask_irq, 477 NULL, NULL, 478 "pci intr%d:", irq); 479 480 if (error == 0) { 481 sc->sc_eventstab[irq] = event; 482 sc->sc_intr_counter[irq] = 483 mips_intrcnt_create(event->ie_name); 484 } 485 else 486 return error; 487 } 488 489 intr_event_add_handler(event, device_get_nameunit(child), filt, 490 handler, arg, intr_priority(flags), flags, cookiep); 491 mips_intrcnt_setname(sc->sc_intr_counter[irq], event->ie_fullname); 492 493 qca955x_pci_unmask_irq(&sc->sc_pci_irq[irq]); 494 495 return (0); 496} 497 498static int 499qca955x_pci_teardown_intr(device_t dev, device_t child, struct resource *ires, 500 void *cookie) 501{ 502 struct ar71xx_pci_softc *sc = device_get_softc(dev); 503 int irq, result; 504 505 irq = rman_get_start(ires); 506 if (irq > AR71XX_PCI_IRQ_END) 507 panic("%s: bad irq %d", __func__, irq); 508 509 if (sc->sc_eventstab[irq] == NULL) 510 panic("Trying to teardown unoccupied IRQ"); 511 512 qca955x_pci_mask_irq(&sc->sc_pci_irq[irq]); 513 514 result = intr_event_remove_handler(cookie); 515 if (!result) 516 sc->sc_eventstab[irq] = NULL; 517 518 return (result); 519} 520 521static int 522qca955x_pci_intr(void *arg) 523{ 524 struct ar71xx_pci_softc *sc = arg; 525 struct intr_event *event; 526 uint32_t reg, irq, mask; 527 528 /* There's only one PCIe DDR flush for both PCIe EPs */ 529 ar71xx_device_flush_ddr(AR71XX_CPU_DDR_FLUSH_PCIE); 530 531 reg = ATH_READ_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_INTR_STATUS); 532 mask = ATH_READ_REG(sc->sc_pci_ctrl_base + QCA955X_PCI_INTR_MASK); 533 534 /* 535 * Handle only unmasked interrupts 536 */ 537 reg &= mask; 538 /* 539 * XXX TODO: handle >1 PCIe end point! 540 */ 541 if (reg & QCA955X_PCI_INTR_DEV0) { 542 irq = AR71XX_PCI_IRQ_START; 543 event = sc->sc_eventstab[irq]; 544 if (!event || TAILQ_EMPTY(&event->ie_handlers)) { 545 printf("Stray IRQ %d\n", irq); 546 return (FILTER_STRAY); 547 } 548 549 /* TODO: frame instead of NULL? */ 550 intr_event_handle(event, NULL); 551 mips_intrcnt_inc(sc->sc_intr_counter[irq]); 552 } 553 554 return (FILTER_HANDLED); 555} 556 557static int 558qca955x_pci_maxslots(device_t dev) 559{ 560 561 return (PCI_SLOTMAX); 562} 563 564static int 565qca955x_pci_route_interrupt(device_t pcib, device_t device, int pin) 566{ 567 568 return (pci_get_slot(device)); 569} 570 571static device_method_t qca955x_pci_methods[] = { 572 /* Device interface */ 573 DEVMETHOD(device_probe, qca955x_pci_probe), 574 DEVMETHOD(device_attach, qca955x_pci_attach), 575 DEVMETHOD(device_shutdown, bus_generic_shutdown), 576 DEVMETHOD(device_suspend, bus_generic_suspend), 577 DEVMETHOD(device_resume, bus_generic_resume), 578 579 /* Bus interface */ 580 DEVMETHOD(bus_read_ivar, qca955x_pci_read_ivar), 581 DEVMETHOD(bus_write_ivar, qca955x_pci_write_ivar), 582 DEVMETHOD(bus_alloc_resource, qca955x_pci_alloc_resource), 583 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 584 DEVMETHOD(bus_activate_resource, qca955x_pci_activate_resource), 585 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 586 DEVMETHOD(bus_setup_intr, qca955x_pci_setup_intr), 587 DEVMETHOD(bus_teardown_intr, qca955x_pci_teardown_intr), 588 589 /* pcib interface */ 590 DEVMETHOD(pcib_maxslots, qca955x_pci_maxslots), 591 DEVMETHOD(pcib_read_config, qca955x_pci_read_config), 592 DEVMETHOD(pcib_write_config, qca955x_pci_write_config), 593 DEVMETHOD(pcib_route_interrupt, qca955x_pci_route_interrupt), 594 595 DEVMETHOD_END 596}; 597 598static driver_t qca955x_pci_driver = { 599 "pcib", 600 qca955x_pci_methods, 601 sizeof(struct ar71xx_pci_softc), 602}; 603 604static devclass_t qca955x_pci_devclass; 605 606DRIVER_MODULE(qca955x_pci, nexus, qca955x_pci_driver, qca955x_pci_devclass, 0, 0); 607DRIVER_MODULE(qca955x_pci, apb, qca955x_pci_driver, qca955x_pci_devclass, 0, 0); 608