Line data Source code
1 : /* $OpenBSD: if_acx_pci.c,v 1.9 2015/11/24 17:11:39 mpi Exp $ */
2 :
3 : /*-
4 : * Copyright (c) 2006 Theo de Raadt <deraadt@openbsd.org>
5 : * Copyright (c) 2005, 2006
6 : * Damien Bergamini <damien.bergamini@free.fr>
7 : *
8 : * Permission to use, copy, modify, and distribute this software for any
9 : * purpose with or without fee is hereby granted, provided that the above
10 : * copyright notice and this permission notice appear in all copies.
11 : *
12 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 : */
20 :
21 : /*
22 : * PCI front-end for the ACX100/111
23 : */
24 :
25 : #include "bpfilter.h"
26 :
27 : #include <sys/param.h>
28 : #include <sys/sockio.h>
29 : #include <sys/mbuf.h>
30 : #include <sys/kernel.h>
31 : #include <sys/socket.h>
32 : #include <sys/systm.h>
33 : #include <sys/malloc.h>
34 : #include <sys/timeout.h>
35 : #include <sys/device.h>
36 :
37 : #include <machine/bus.h>
38 : #include <machine/intr.h>
39 :
40 : #include <net/if.h>
41 : #include <net/if_media.h>
42 :
43 : #include <netinet/in.h>
44 : #include <netinet/if_ether.h>
45 :
46 : #include <net80211/ieee80211_var.h>
47 : #include <net80211/ieee80211_amrr.h>
48 : #include <net80211/ieee80211_radiotap.h>
49 :
50 : #include <dev/ic/acxvar.h>
51 :
52 : #include <dev/pci/pcireg.h>
53 : #include <dev/pci/pcivar.h>
54 : #include <dev/pci/pcidevs.h>
55 :
56 : struct acx_pci_softc {
57 : struct acx_softc sc_acx;
58 :
59 : /* PCI specific goo */
60 : struct acx_opns *sc_opns;
61 : pci_chipset_tag_t sc_pc;
62 : void *sc_ih;
63 : bus_size_t sc_mapsize1;
64 : bus_size_t sc_mapsize2;
65 : int sc_intrline;
66 :
67 : /* hack for ACX100A */
68 : bus_space_tag_t sc_io_bt;
69 : bus_space_handle_t sc_io_bh;
70 : bus_size_t sc_iomapsize;
71 : };
72 :
73 : /* Base Address Register */
74 : #define ACX_PCI_BAR0 0x10
75 : #define ACX_PCI_BAR1 0x14
76 : #define ACX_PCI_BAR2 0x18
77 :
78 : int acx_pci_match(struct device *, void *, void *);
79 : void acx_pci_attach(struct device *, struct device *, void *);
80 : int acx_pci_detach(struct device *, int);
81 :
82 : struct cfattach acx_pci_ca = {
83 : sizeof (struct acx_pci_softc), acx_pci_match, acx_pci_attach,
84 : acx_pci_detach
85 : };
86 :
87 : const struct pci_matchid acx_pci_devices[] = {
88 : { PCI_VENDOR_TI, PCI_PRODUCT_TI_ACX100A },
89 : { PCI_VENDOR_TI, PCI_PRODUCT_TI_ACX100B },
90 : { PCI_VENDOR_TI, PCI_PRODUCT_TI_ACX111 }
91 : };
92 :
93 : int
94 0 : acx_pci_match(struct device *parent, void *match, void *aux)
95 : {
96 0 : return (pci_matchbyid((struct pci_attach_args *)aux, acx_pci_devices,
97 : sizeof (acx_pci_devices) / sizeof (acx_pci_devices[0])));
98 : }
99 :
100 : void
101 0 : acx_pci_attach(struct device *parent, struct device *self, void *aux)
102 : {
103 0 : struct acx_pci_softc *psc = (struct acx_pci_softc *)self;
104 0 : struct acx_softc *sc = &psc->sc_acx;
105 0 : struct pci_attach_args *pa = aux;
106 : const char *intrstr = NULL;
107 0 : pci_intr_handle_t ih;
108 : int error, b1 = ACX_PCI_BAR0, b2 = ACX_PCI_BAR1;
109 :
110 0 : sc->sc_dmat = pa->pa_dmat;
111 0 : psc->sc_pc = pa->pa_pc;
112 :
113 : /* map control/status registers */
114 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_TI_ACX100A) {
115 0 : error = pci_mapreg_map(pa, ACX_PCI_BAR0,
116 0 : PCI_MAPREG_TYPE_IO, 0, &psc->sc_io_bt,
117 0 : &psc->sc_io_bh, NULL, &psc->sc_iomapsize, 0);
118 0 : if (error != 0) {
119 0 : printf(": can't map i/o space\n");
120 0 : return;
121 : }
122 : b1 = ACX_PCI_BAR1;
123 : b2 = ACX_PCI_BAR2;
124 0 : }
125 :
126 0 : error = pci_mapreg_map(pa, b1, PCI_MAPREG_TYPE_MEM |
127 0 : PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_mem1_bt,
128 0 : &sc->sc_mem1_bh, NULL, &psc->sc_mapsize1, 0);
129 0 : if (error != 0) {
130 0 : printf(": can't map mem1 space\n");
131 0 : return;
132 : }
133 :
134 0 : error = pci_mapreg_map(pa, b2, PCI_MAPREG_TYPE_MEM |
135 0 : PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_mem2_bt,
136 0 : &sc->sc_mem2_bh, NULL, &psc->sc_mapsize2, 0);
137 0 : if (error != 0) {
138 0 : printf(": can't map mem2 space\n");
139 0 : return;
140 : }
141 :
142 0 : if (pci_intr_map(pa, &ih) != 0) {
143 0 : printf(": can't map interrupt\n");
144 0 : return;
145 : }
146 :
147 0 : intrstr = pci_intr_string(psc->sc_pc, ih);
148 0 : psc->sc_ih = pci_intr_establish(psc->sc_pc, ih, IPL_NET,
149 0 : acx_intr, sc, sc->sc_dev.dv_xname);
150 0 : if (psc->sc_ih == NULL) {
151 0 : printf(": can't establish interrupt");
152 0 : if (intrstr != NULL)
153 0 : printf(" at %s", intrstr);
154 0 : printf("\n");
155 0 : return;
156 : }
157 0 : printf(": %s\n", intrstr);
158 :
159 0 : if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_TI_ACX111)
160 0 : acx111_set_param(sc);
161 : else
162 0 : acx100_set_param(sc);
163 :
164 0 : acx_attach(sc);
165 0 : }
166 :
167 : int
168 0 : acx_pci_detach(struct device *self, int flags)
169 : {
170 0 : struct acx_pci_softc *psc = (struct acx_pci_softc *)self;
171 0 : struct acx_softc *sc = &psc->sc_acx;
172 :
173 0 : acx_detach(sc);
174 0 : pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
175 :
176 0 : return 0;
177 : }
|