1 /* $OpenBSD: if_wi_pci.c,v 1.6 2001/07/06 17:22:07 jason Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Todd C. Miller <Todd.Miller@courtesan.com> 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, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 /* 30 * Copyright (c) 1997, 1998, 1999 31 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 32 * 33 * Redistribution and use in source and binary forms, with or without 34 * modification, are permitted provided that the following conditions 35 * are met: 36 * 1. Redistributions of source code must retain the above copyright 37 * notice, this list of conditions and the following disclaimer. 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 3. All advertising materials mentioning features or use of this software 42 * must display the following acknowledgement: 43 * This product includes software developed by Bill Paul. 44 * 4. Neither the name of the author nor the names of any co-contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 52 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 56 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 58 * THE POSSIBILITY OF SUCH DAMAGE. 59 */ 60 61 /* 62 * This is a PCI shim for the Wavelan wireless network driver. 63 * It works with PCI adaptors based on the PLX 9050 and PLX 9052 64 * PCI to "dumb bus" bridge chip. It has been tested with the 65 * Global Sun Technology GL24110P02 (aka Linksys WDT11) and is 66 * expected to work with the Global Sun GL24110P and Eumitcom WL11000P. 67 * 68 * All we do here is handle the PCI match and attach, set up an 69 * interrupt handler entry point, and setup the PLX chip for level 70 * interrupts and config index 1. 71 * 72 * The PLX 9052 provides us with multiple PCI address space mappings. 73 * The primary mappings at PCI registers 0x10 (mem) and 0x14 (I/O) are for 74 * the PLX chip itself, *NOT* the pcmcia card. 75 * The PLX 9052 provides 4 local address space registers: 0x18, 0x1C, 76 * 0x20, and 0x24. The mem and I/O spaces for the PCMCIA card are 77 * mapped to 0x18 and 0x1C respectively. 78 * 79 * The datasheet may be downloaded from PLX (though you do have to register) 80 * http://www.plxtech.com/products/toolbox/9050.htm 81 */ 82 83 #include <sys/param.h> 84 #include <sys/systm.h> 85 #include <sys/device.h> 86 #include <sys/timeout.h> 87 #include <sys/socket.h> 88 89 #include <net/if.h> 90 #include <net/if_dl.h> 91 #include <net/if_media.h> 92 93 #ifdef INET 94 #include <netinet/in.h> 95 #include <netinet/if_ether.h> 96 #endif 97 98 #include <net/if_ieee80211.h> 99 100 #include <machine/bus.h> 101 102 #include <dev/pci/pcireg.h> 103 #include <dev/pci/pcivar.h> 104 #include <dev/pci/pcidevs.h> 105 106 #include <dev/ic/if_wireg.h> 107 #include <dev/ic/if_wi_ieee.h> 108 #include <dev/ic/if_wivar.h> 109 110 #define WI_PCI_PLX_LOMEM 0x10 /* PLX chip membase */ 111 #define WI_PCI_PLX_LOIO 0x14 /* PLX chip iobase */ 112 #define WI_PCI_LOMEM 0x18 /* ISA membase */ 113 #define WI_PCI_LOIO 0x1C /* ISA iobase */ 114 115 int wi_pci_match __P((struct device *, void *, void *)); 116 void wi_pci_attach __P((struct device *, struct device *, void *)); 117 int wi_intr __P((void *)); 118 int wi_attach __P((struct wi_softc *, int)); 119 120 struct cfattach wi_pci_ca = { 121 sizeof (struct wi_softc), wi_pci_match, wi_pci_attach 122 }; 123 124 static const struct wi_pci_product { 125 pci_vendor_id_t pp_vendor; 126 pci_product_id_t pp_product; 127 } wi_pci_products[] = { 128 { PCI_VENDOR_GLOBALSUN, PCI_PRODUCT_GLOBALSUN_GL24110P }, 129 { PCI_VENDOR_GLOBALSUN, PCI_PRODUCT_GLOBALSUN_GL24110P02 }, 130 { PCI_VENDOR_EUMITCOM, PCI_PRODUCT_EUMITCOM_WL11000P }, 131 { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CRWE777A }, 132 { 0, 0 } 133 }; 134 135 int 136 wi_pci_match(parent, match, aux) 137 struct device *parent; 138 void *match; 139 void *aux; 140 { 141 struct pci_attach_args *pa = aux; 142 const struct wi_pci_product *pp; 143 144 for (pp = wi_pci_products; pp->pp_product != 0; pp++) { 145 if (PCI_VENDOR(pa->pa_id) == pp->pp_vendor && 146 PCI_PRODUCT(pa->pa_id) == pp->pp_product) 147 return(1); 148 } 149 150 return(0); 151 } 152 153 void 154 wi_pci_attach(parent, self, aux) 155 struct device *parent; 156 struct device *self; 157 void *aux; 158 { 159 struct wi_softc *sc = (struct wi_softc *)self; 160 struct pci_attach_args *pa = aux; 161 pci_intr_handle_t ih; 162 bus_space_handle_t ioh, memh; 163 bus_space_tag_t iot = pa->pa_iot; 164 bus_space_tag_t memt = pa->pa_memt; 165 pci_chipset_tag_t pc = pa->pa_pc; 166 pcireg_t csr; 167 const char *intrstr; 168 169 /* Map memory and I/O registers. */ 170 if (pci_mapreg_map(pa, WI_PCI_LOMEM, PCI_MAPREG_TYPE_MEM, 0, 171 &memt, &memh, NULL, NULL, 0) != 0) { 172 printf(": can't map mem space\n"); 173 return; 174 } 175 if (pci_mapreg_map(pa, WI_PCI_LOIO, PCI_MAPREG_TYPE_IO, 0, 176 &iot, &ioh, NULL, NULL, 0) != 0) { 177 printf(": can't map I/O space\n"); 178 return; 179 } 180 sc->wi_btag = iot; 181 sc->wi_bhandle = ioh; 182 183 /* Enable the card. */ 184 csr = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 185 pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 186 csr | PCI_COMMAND_MASTER_ENABLE); 187 188 /* Make sure interrupts are disabled. */ 189 CSR_WRITE_2(sc, WI_INT_EN, 0); 190 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); 191 192 /* Map and establish the interrupt. */ 193 if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin, 194 pa->pa_intrline, &ih)) { 195 printf(": couldn't map interrupt\n"); 196 return; 197 } 198 intrstr = pci_intr_string(pc, ih); 199 sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, wi_intr, sc, 200 sc->sc_dev.dv_xname); 201 if (sc->sc_ih == NULL) { 202 printf(": couldn't establish interrupt"); 203 if (intrstr != NULL) 204 printf(" at %s", intrstr); 205 printf("\n"); 206 return; 207 } 208 printf(": %s", intrstr); 209 210 /* 211 * Setup the PLX chip for level interrupts and config index 1 212 * XXX - should really reset the PLX chip too. 213 */ 214 bus_space_write_1(memt, memh, WI_COR_OFFSET, WI_COR_VALUE); 215 216 wi_attach(sc, 1); 217 } 218