1 /* $OpenBSD: if_ath_pci.c,v 1.13 2006/08/03 02:29:33 brad Exp $ */ 2 /* $NetBSD: if_ath_pci.c,v 1.7 2004/06/30 05:58:17 mycroft Exp $ */ 3 4 /*- 5 * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer, 13 * without modification. 14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 15 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 16 * redistribution must be conditioned upon including a substantially 17 * similar Disclaimer requirement for further binary redistribution. 18 * 3. Neither the names of the above-listed copyright holders nor the names 19 * of any contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * Alternatively, this software may be distributed under the terms of the 23 * GNU General Public License ("GPL") version 2 as published by the Free 24 * Software Foundation. 25 * 26 * NO WARRANTY 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 30 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 31 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 32 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 35 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 37 * THE POSSIBILITY OF SUCH DAMAGES. 38 */ 39 40 /* 41 * PCI front-end for the Atheros Wireless LAN controller driver. 42 */ 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/mbuf.h> 47 #include <sys/malloc.h> 48 #include <sys/kernel.h> 49 #include <sys/lock.h> 50 #include <sys/socket.h> 51 #include <sys/sockio.h> 52 #include <sys/errno.h> 53 #include <sys/device.h> 54 #include <sys/gpio.h> 55 56 #include <machine/bus.h> 57 58 #include <net/if.h> 59 #include <net/if_dl.h> 60 #include <net/if_media.h> 61 #include <net/if_llc.h> 62 #include <net/if_arp.h> 63 #ifdef INET 64 #include <netinet/in.h> 65 #include <netinet/if_ether.h> 66 #endif 67 68 #include <net80211/ieee80211_var.h> 69 #include <net80211/ieee80211_rssadapt.h> 70 71 #include <dev/gpio/gpiovar.h> 72 73 #include <dev/pci/pcivar.h> 74 #include <dev/pci/pcireg.h> 75 #include <dev/pci/pcidevs.h> 76 77 #include <dev/ic/athvar.h> 78 79 /* 80 * PCI glue. 81 */ 82 83 struct ath_pci_softc { 84 struct ath_softc sc_sc; 85 86 pci_chipset_tag_t sc_pc; 87 pcitag_t sc_pcitag; 88 89 void *sc_ih; /* interrupt handler */ 90 }; 91 92 /* Base Address Register */ 93 #define ATH_BAR0 0x10 94 95 int ath_pci_match(struct device *, void *, void *); 96 void ath_pci_attach(struct device *, struct device *, void *); 97 void ath_pci_shutdown(void *); 98 int ath_pci_detach(struct device *, int); 99 100 struct cfattach ath_pci_ca = { 101 sizeof(struct ath_pci_softc), 102 ath_pci_match, 103 ath_pci_attach, 104 ath_pci_detach 105 }; 106 107 int 108 ath_pci_match(struct device *parent, void *match, void *aux) 109 { 110 const char* devname; 111 struct pci_attach_args *pa = aux; 112 pci_vendor_id_t vendor; 113 114 vendor = PCI_VENDOR(pa->pa_id); 115 if (vendor == 0x128c) 116 vendor = PCI_VENDOR_ATHEROS; 117 devname = ath_hal_probe(vendor, PCI_PRODUCT(pa->pa_id)); 118 if (devname) 119 return 1; 120 121 return 0; 122 } 123 124 void 125 ath_pci_attach(struct device *parent, struct device *self, void *aux) 126 { 127 struct ath_pci_softc *psc = (struct ath_pci_softc *)self; 128 struct ath_softc *sc = &psc->sc_sc; 129 struct pci_attach_args *pa = aux; 130 pci_chipset_tag_t pc = pa->pa_pc; 131 pcitag_t pt = pa->pa_tag; 132 bus_space_tag_t iot; 133 bus_space_handle_t ioh; 134 pci_intr_handle_t ih; 135 pcireg_t mem_type; 136 void *hook; 137 const char *intrstr = NULL; 138 139 psc->sc_pc = pc; 140 psc->sc_pcitag = pt; 141 142 /* 143 * Setup memory-mapping of PCI registers. 144 */ 145 mem_type = pci_mapreg_type(pc, pa->pa_tag, ATH_BAR0); 146 if (mem_type != PCI_MAPREG_TYPE_MEM && 147 mem_type != PCI_MAPREG_MEM_TYPE_64BIT) { 148 printf(": bad PCI register type %d\n", (int)mem_type); 149 goto bad; 150 } 151 if (pci_mapreg_map(pa, ATH_BAR0, mem_type, 0, &iot, &ioh, 152 NULL, NULL, 0)) { 153 printf(": cannot map register space\n"); 154 goto bad; 155 } 156 sc->sc_st = iot; 157 sc->sc_sh = ioh; 158 159 sc->sc_invalid = 1; 160 161 /* 162 * Arrange interrupt line. 163 */ 164 if (pci_intr_map(pa, &ih)) { 165 printf(": couldn't map interrupt\n"); 166 goto bad1; 167 } 168 169 intrstr = pci_intr_string(pc, ih); 170 psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ath_intr, sc, 171 sc->sc_dev.dv_xname); 172 if (psc->sc_ih == NULL) { 173 printf(": couldn't map interrupt\n"); 174 goto bad2; 175 } 176 177 printf(": %s\n", intrstr); 178 179 sc->sc_dmat = pa->pa_dmat; 180 181 hook = shutdownhook_establish(ath_pci_shutdown, psc); 182 if (hook == NULL) { 183 printf(": couldn't make shutdown hook\n"); 184 goto bad3; 185 } 186 187 if (ath_attach(PCI_PRODUCT(pa->pa_id), sc) == 0) 188 return; 189 190 shutdownhook_disestablish(hook); 191 192 bad3: pci_intr_disestablish(pc, psc->sc_ih); 193 bad2: /* XXX */ 194 bad1: /* XXX */ 195 bad: 196 return; 197 } 198 199 int 200 ath_pci_detach(struct device *self, int flags) 201 { 202 struct ath_pci_softc *psc = (struct ath_pci_softc *)self; 203 204 ath_detach(&psc->sc_sc, flags); 205 pci_intr_disestablish(psc->sc_pc, psc->sc_ih); 206 207 return (0); 208 } 209 210 void 211 ath_pci_shutdown(void *self) 212 { 213 struct ath_pci_softc *psc = (struct ath_pci_softc *)self; 214 215 ath_shutdown(&psc->sc_sc); 216 } 217