Fri Aug 7 18:25:33 2009 UTC ()
Pull up following revision(s) (requested by sborrill in ticket #903):
	sys/dev/cardbus/if_ath_cardbus.c: revision 1.32
	sys/dev/pci/if_ath_pci.c: revision 1.32
Sync ath(4) with the new HAL, mostly based on <jmcneill>'s patches.
Everything should be fine again !


(snj)
diff -r1.31 -r1.31.4.1 src/sys/dev/cardbus/if_ath_cardbus.c
diff -r1.31 -r1.31.4.1 src/sys/dev/pci/if_ath_pci.c

cvs diff -r1.31 -r1.31.4.1 src/sys/dev/cardbus/if_ath_cardbus.c (switch to unified diff)

--- src/sys/dev/cardbus/if_ath_cardbus.c 2008/07/10 05:11:10 1.31
+++ src/sys/dev/cardbus/if_ath_cardbus.c 2009/08/07 18:25:33 1.31.4.1
@@ -1,283 +1,284 @@ @@ -1,283 +1,284 @@
1/* $NetBSD: if_ath_cardbus.c,v 1.31 2008/07/10 05:11:10 cegger Exp $ */ 1/* $NetBSD: if_ath_cardbus.c,v 1.31.4.1 2009/08/07 18:25:33 snj Exp $ */
2/* 2/*
3 * Copyright (c) 2003 3 * Copyright (c) 2003
4 * Ichiro FUKUHARA <ichiro@ichiro.org>. 4 * Ichiro FUKUHARA <ichiro@ichiro.org>.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Ichiro FUKUHARA. 17 * This product includes software developed by Ichiro FUKUHARA.
18 * 4. The name of the company nor the name of the author may be used to 18 * 4. The name of the company nor the name of the author may be used to
19 * endorse or promote products derived from this software without specific 19 * endorse or promote products derived from this software without specific
20 * prior written permission. 20 * prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR 25 * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
26 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34/* 34/*
35 * CardBus bus front-end for the AR5001 Wireless LAN 802.11a/b/g CardBus. 35 * CardBus bus front-end for the AR5001 Wireless LAN 802.11a/b/g CardBus.
36 */ 36 */
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: if_ath_cardbus.c,v 1.31 2008/07/10 05:11:10 cegger Exp $"); 39__KERNEL_RCSID(0, "$NetBSD: if_ath_cardbus.c,v 1.31.4.1 2009/08/07 18:25:33 snj Exp $");
40 40
41#include "opt_inet.h" 41#include "opt_inet.h"
42#include "bpfilter.h" 42#include "bpfilter.h"
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <sys/mbuf.h> 46#include <sys/mbuf.h>
47#include <sys/malloc.h> 47#include <sys/malloc.h>
48#include <sys/kernel.h> 48#include <sys/kernel.h>
49#include <sys/socket.h> 49#include <sys/socket.h>
50#include <sys/ioctl.h> 50#include <sys/ioctl.h>
51#include <sys/errno.h> 51#include <sys/errno.h>
52#include <sys/device.h> 52#include <sys/device.h>
53 53
54#include <machine/endian.h> 54#include <machine/endian.h>
55 55
56#include <net/if.h> 56#include <net/if.h>
57#include <net/if_dl.h> 57#include <net/if_dl.h>
58#include <net/if_media.h> 58#include <net/if_media.h>
59#include <net/if_ether.h> 59#include <net/if_ether.h>
60 60
61#include <net80211/ieee80211_netbsd.h> 61#include <net80211/ieee80211_netbsd.h>
62#include <net80211/ieee80211_var.h> 62#include <net80211/ieee80211_var.h>
63 63
64#if NBPFILTER > 0 64#if NBPFILTER > 0
65#include <net/bpf.h> 65#include <net/bpf.h>
66#endif 66#endif
67 67
68#ifdef INET 68#ifdef INET
69#include <netinet/in.h> 69#include <netinet/in.h>
70#include <netinet/if_inarp.h> 70#include <netinet/if_inarp.h>
71#endif 71#endif
72 72
73 73
74#include <sys/bus.h> 74#include <sys/bus.h>
75#include <sys/intr.h> 75#include <sys/intr.h>
76 76
77#include <dev/mii/miivar.h> 77#include <dev/mii/miivar.h>
78#include <dev/mii/mii_bitbang.h> 78#include <dev/mii/mii_bitbang.h>
79 79
80#include <dev/ic/ath_netbsd.h> 80#include <dev/ic/ath_netbsd.h>
81#include <dev/ic/athvar.h> 81#include <dev/ic/athvar.h>
82#include <contrib/dev/ath/ah.h> 82
 83#include <external/isc/atheros_hal/dist/ah.h>
83 84
84#include <dev/pci/pcivar.h> 85#include <dev/pci/pcivar.h>
85#include <dev/pci/pcireg.h> 86#include <dev/pci/pcireg.h>
86#include <dev/pci/pcidevs.h> 87#include <dev/pci/pcidevs.h>
87 88
88#include <dev/cardbus/cardbusvar.h> 89#include <dev/cardbus/cardbusvar.h>
89#include <dev/pci/pcidevs.h> 90#include <dev/pci/pcidevs.h>
90 91
91/* 92/*
92 * PCI configuration space registers 93 * PCI configuration space registers
93 */ 94 */
94#define ATH_PCI_MMBA 0x10 /* memory mapped base */ 95#define ATH_PCI_MMBA 0x10 /* memory mapped base */
95 96
96struct ath_cardbus_softc { 97struct ath_cardbus_softc {
97 struct ath_softc sc_ath; 98 struct ath_softc sc_ath;
98 99
99 /* CardBus-specific goo. */ 100 /* CardBus-specific goo. */
100 void *sc_ih; /* interrupt handle */ 101 void *sc_ih; /* interrupt handle */
101 cardbus_devfunc_t sc_ct; /* our CardBus devfuncs */ 102 cardbus_devfunc_t sc_ct; /* our CardBus devfuncs */
102 cardbustag_t sc_tag; /* our CardBus tag */ 103 cardbustag_t sc_tag; /* our CardBus tag */
103 bus_size_t sc_mapsize; /* the size of mapped bus space region */ 104 bus_size_t sc_mapsize; /* the size of mapped bus space region */
104 105
105 pcireg_t sc_bar_val; /* value of the BAR */ 106 pcireg_t sc_bar_val; /* value of the BAR */
106 107
107 cardbus_intr_line_t sc_intrline; /* interrupt line */ 108 cardbus_intr_line_t sc_intrline; /* interrupt line */
108 bus_space_tag_t sc_iot; 109 bus_space_tag_t sc_iot;
109 bus_space_handle_t sc_ioh; 110 bus_space_handle_t sc_ioh;
110}; 111};
111 112
112int ath_cardbus_match(device_t, cfdata_t, void *); 113int ath_cardbus_match(device_t, cfdata_t, void *);
113void ath_cardbus_attach(device_t, device_t, void *); 114void ath_cardbus_attach(device_t, device_t, void *);
114int ath_cardbus_detach(device_t, int); 115int ath_cardbus_detach(device_t, int);
115 116
116CFATTACH_DECL_NEW(ath_cardbus, sizeof(struct ath_cardbus_softc), 117CFATTACH_DECL_NEW(ath_cardbus, sizeof(struct ath_cardbus_softc),
117 ath_cardbus_match, ath_cardbus_attach, ath_cardbus_detach, NULL); 118 ath_cardbus_match, ath_cardbus_attach, ath_cardbus_detach, NULL);
118 119
119void ath_cardbus_setup(struct ath_cardbus_softc *); 120void ath_cardbus_setup(struct ath_cardbus_softc *);
120 121
121static bool 122static bool
122ath_cardbus_suspend(device_t self PMF_FN_ARGS) 123ath_cardbus_suspend(device_t self PMF_FN_ARGS)
123{ 124{
124 struct ath_cardbus_softc *csc = device_private(self); 125 struct ath_cardbus_softc *csc = device_private(self);
125 126
126 ath_suspend(&csc->sc_ath); 127 ath_suspend(&csc->sc_ath);
127 if (csc->sc_ih != NULL) { 128 if (csc->sc_ih != NULL) {
128 cardbus_intr_disestablish(csc->sc_ct->ct_cc, csc->sc_ct->ct_cf, 129 cardbus_intr_disestablish(csc->sc_ct->ct_cc, csc->sc_ct->ct_cf,
129 csc->sc_ih); 130 csc->sc_ih);
130 csc->sc_ih = NULL; 131 csc->sc_ih = NULL;
131 } 132 }
132 return true; 133 return true;
133} 134}
134 135
135static bool 136static bool
136ath_cardbus_resume(device_t self PMF_FN_ARGS) 137ath_cardbus_resume(device_t self PMF_FN_ARGS)
137{ 138{
138 struct ath_cardbus_softc *csc = device_private(self); 139 struct ath_cardbus_softc *csc = device_private(self);
139 140
140 csc->sc_ih = cardbus_intr_establish(csc->sc_ct->ct_cc, 141 csc->sc_ih = cardbus_intr_establish(csc->sc_ct->ct_cc,
141 csc->sc_ct->ct_cf, csc->sc_intrline, IPL_NET, ath_intr, 142 csc->sc_ct->ct_cf, csc->sc_intrline, IPL_NET, ath_intr,
142 &csc->sc_ath); 143 &csc->sc_ath);
143 144
144 if (csc->sc_ih == NULL) { 145 if (csc->sc_ih == NULL) {
145 aprint_error_dev(self, 146 aprint_error_dev(self,
146 "unable to establish interrupt\n"); 147 "unable to establish interrupt\n");
147 return false; 148 return false;
148 } 149 }
149 150
150 return ath_resume(&csc->sc_ath); 151 return ath_resume(&csc->sc_ath);
151} 152}
152 153
153int 154int
154ath_cardbus_match(device_t parent, struct cfdata *match, void *aux) 155ath_cardbus_match(device_t parent, struct cfdata *match, void *aux)
155{ 156{
156 struct cardbus_attach_args *ca = aux; 157 struct cardbus_attach_args *ca = aux;
157 const char *devname; 158 const char *devname;
158 159
159 devname = ath_hal_probe(PCI_VENDOR(ca->ca_id), PCI_PRODUCT(ca->ca_id)); 160 devname = ath_hal_probe(PCI_VENDOR(ca->ca_id), PCI_PRODUCT(ca->ca_id));
160 161
161 if (devname) 162 if (devname)
162 return 1; 163 return 1;
163 164
164 return 0; 165 return 0;
165} 166}
166 167
167void 168void
168ath_cardbus_attach(device_t parent, device_t self, void *aux) 169ath_cardbus_attach(device_t parent, device_t self, void *aux)
169{ 170{
170 struct ath_cardbus_softc *csc = device_private(self); 171 struct ath_cardbus_softc *csc = device_private(self);
171 struct ath_softc *sc = &csc->sc_ath; 172 struct ath_softc *sc = &csc->sc_ath;
172 struct cardbus_attach_args *ca = aux; 173 struct cardbus_attach_args *ca = aux;
173 cardbus_devfunc_t ct = ca->ca_ct; 174 cardbus_devfunc_t ct = ca->ca_ct;
174 bus_addr_t adr; 175 bus_addr_t adr;
175 176
176 sc->sc_dev = self; 177 sc->sc_dev = self;
177 sc->sc_dmat = ca->ca_dmat; 178 sc->sc_dmat = ca->ca_dmat;
178 csc->sc_ct = ct; 179 csc->sc_ct = ct;
179 csc->sc_tag = ca->ca_tag; 180 csc->sc_tag = ca->ca_tag;
180 181
181 aprint_normal("\n"); 182 aprint_normal("\n");
182 183
183 /* 184 /*
184 * Map the device. 185 * Map the device.
185 */ 186 */
186 if (Cardbus_mapreg_map(ct, ATH_PCI_MMBA, PCI_MAPREG_TYPE_MEM, 0, 187 if (Cardbus_mapreg_map(ct, ATH_PCI_MMBA, PCI_MAPREG_TYPE_MEM, 0,
187 &csc->sc_iot, &csc->sc_ioh, &adr, &csc->sc_mapsize) == 0) { 188 &csc->sc_iot, &csc->sc_ioh, &adr, &csc->sc_mapsize) == 0) {
188#if rbus 189#if rbus
189#else 190#else
190 (*ct->ct_cf->cardbus_mem_open)(cc, 0, adr, adr+csc->sc_mapsize); 191 (*ct->ct_cf->cardbus_mem_open)(cc, 0, adr, adr+csc->sc_mapsize);
191#endif 192#endif
192 csc->sc_bar_val = adr | PCI_MAPREG_TYPE_MEM; 193 csc->sc_bar_val = adr | PCI_MAPREG_TYPE_MEM;
193 } else { 194 } else {
194 aprint_error_dev(self, "unable to map device registers\n"); 195 aprint_error_dev(self, "unable to map device registers\n");
195 return; 196 return;
196 } 197 }
197 198
198 sc->sc_st = HALTAG(csc->sc_iot); 199 sc->sc_st = HALTAG(csc->sc_iot);
199 sc->sc_sh = HALHANDLE(csc->sc_ioh); 200 sc->sc_sh = HALHANDLE(csc->sc_ioh);
200 201
201 /* 202 /*
202 * Set up the PCI configuration registers. 203 * Set up the PCI configuration registers.
203 */ 204 */
204 ath_cardbus_setup(csc); 205 ath_cardbus_setup(csc);
205 206
206 /* Remember which interrupt line. */ 207 /* Remember which interrupt line. */
207 csc->sc_intrline = ca->ca_intrline; 208 csc->sc_intrline = ca->ca_intrline;
208 209
209 ATH_LOCK_INIT(sc); 210 ATH_LOCK_INIT(sc);
210 211
211 /* 212 /*
212 * Finish off the attach. 213 * Finish off the attach.
213 */ 214 */
214 if (ath_attach(PCI_PRODUCT(ca->ca_id), sc) != 0) 215 if (ath_attach(PCI_PRODUCT(ca->ca_id), sc) != 0)
215 return; 216 return;
216 217
217 if (!pmf_device_register(self, ath_cardbus_suspend, ath_cardbus_resume)) 218 if (!pmf_device_register(self, ath_cardbus_suspend, ath_cardbus_resume))
218 aprint_error_dev(self, "couldn't establish power handler\n"); 219 aprint_error_dev(self, "couldn't establish power handler\n");
219 else { 220 else {
220 pmf_class_network_register(self, &sc->sc_if); 221 pmf_class_network_register(self, &sc->sc_if);
221 pmf_device_suspend_self(self); 222 pmf_device_suspend_self(self);
222 } 223 }
223} 224}
224 225
225int 226int
226ath_cardbus_detach(device_t self, int flags) 227ath_cardbus_detach(device_t self, int flags)
227{ 228{
228 struct ath_cardbus_softc *csc = device_private(self); 229 struct ath_cardbus_softc *csc = device_private(self);
229 struct ath_softc *sc = &csc->sc_ath; 230 struct ath_softc *sc = &csc->sc_ath;
230 struct cardbus_devfunc *ct = csc->sc_ct; 231 struct cardbus_devfunc *ct = csc->sc_ct;
231 int rv; 232 int rv;
232 233
233#if defined(DIAGNOSTIC) 234#if defined(DIAGNOSTIC)
234 if (ct == NULL) 235 if (ct == NULL)
235 panic("%s: data structure lacks", device_xname(sc->sc_dev)); 236 panic("%s: data structure lacks", device_xname(sc->sc_dev));
236#endif 237#endif
237 238
238 rv = ath_detach(sc); 239 rv = ath_detach(sc);
239 if (rv) 240 if (rv)
240 return (rv); 241 return (rv);
241 242
242 pmf_device_deregister(self); 243 pmf_device_deregister(self);
243 244
244 /* 245 /*
245 * Unhook the interrupt handler. 246 * Unhook the interrupt handler.
246 */ 247 */
247 if (csc->sc_ih != NULL) { 248 if (csc->sc_ih != NULL) {
248 cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih); 249 cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih);
249 csc->sc_ih = NULL; 250 csc->sc_ih = NULL;
250 } 251 }
251 252
252 /* 253 /*
253 * Release bus space and close window. 254 * Release bus space and close window.
254 */ 255 */
255 Cardbus_mapreg_unmap(ct, ATH_PCI_MMBA, csc->sc_iot, csc->sc_ioh, 256 Cardbus_mapreg_unmap(ct, ATH_PCI_MMBA, csc->sc_iot, csc->sc_ioh,
256 csc->sc_mapsize); 257 csc->sc_mapsize);
257 258
258 ATH_LOCK_DESTROY(sc); 259 ATH_LOCK_DESTROY(sc);
259 260
260 return (0); 261 return (0);
261} 262}
262 263
263void 264void
264ath_cardbus_setup(struct ath_cardbus_softc *csc) 265ath_cardbus_setup(struct ath_cardbus_softc *csc)
265{ 266{
266 cardbus_devfunc_t ct = csc->sc_ct; 267 cardbus_devfunc_t ct = csc->sc_ct;
267 cardbus_chipset_tag_t cc = ct->ct_cc; 268 cardbus_chipset_tag_t cc = ct->ct_cc;
268 cardbus_function_tag_t cf = ct->ct_cf; 269 cardbus_function_tag_t cf = ct->ct_cf;
269 int rc; 270 int rc;
270 pcireg_t reg; 271 pcireg_t reg;
271 272
272 if ((rc = cardbus_set_powerstate(ct, csc->sc_tag, PCI_PWR_D0)) != 0) 273 if ((rc = cardbus_set_powerstate(ct, csc->sc_tag, PCI_PWR_D0)) != 0)
273 aprint_debug("%s: cardbus_set_powerstate %d\n", __func__, rc); 274 aprint_debug("%s: cardbus_set_powerstate %d\n", __func__, rc);
274 275
275 /* Program the BAR. */ 276 /* Program the BAR. */
276 cardbus_conf_write(cc, cf, csc->sc_tag, ATH_PCI_MMBA, csc->sc_bar_val); 277 cardbus_conf_write(cc, cf, csc->sc_tag, ATH_PCI_MMBA, csc->sc_bar_val);
277 278
278 /* Enable the appropriate bits in the PCI CSR. */ 279 /* Enable the appropriate bits in the PCI CSR. */
279 reg = cardbus_conf_read(cc, cf, csc->sc_tag, 280 reg = cardbus_conf_read(cc, cf, csc->sc_tag,
280 PCI_COMMAND_STATUS_REG); 281 PCI_COMMAND_STATUS_REG);
281 reg |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE; 282 reg |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE;
282 cardbus_conf_write(cc, cf, csc->sc_tag, PCI_COMMAND_STATUS_REG, reg); 283 cardbus_conf_write(cc, cf, csc->sc_tag, PCI_COMMAND_STATUS_REG, reg);
283} 284}

cvs diff -r1.31 -r1.31.4.1 src/sys/dev/pci/if_ath_pci.c (switch to unified diff)

--- src/sys/dev/pci/if_ath_pci.c 2008/07/09 19:47:24 1.31
+++ src/sys/dev/pci/if_ath_pci.c 2009/08/07 18:25:33 1.31.4.1
@@ -1,294 +1,295 @@ @@ -1,294 +1,295 @@
1/* $NetBSD: if_ath_pci.c,v 1.31 2008/07/09 19:47:24 joerg Exp $ */ 1/* $NetBSD: if_ath_pci.c,v 1.31.4.1 2009/08/07 18:25:33 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 4 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer, 11 * notice, this list of conditions and the following disclaimer,
12 * without modification. 12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 14 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15 * redistribution must be conditioned upon including a substantially 15 * redistribution must be conditioned upon including a substantially
16 * similar Disclaimer requirement for further binary redistribution. 16 * similar Disclaimer requirement for further binary redistribution.
17 * 3. Neither the names of the above-listed copyright holders nor the names 17 * 3. Neither the names of the above-listed copyright holders nor the names
18 * of any contributors may be used to endorse or promote products derived 18 * of any contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission. 19 * from this software without specific prior written permission.
20 * 20 *
21 * Alternatively, this software may be distributed under the terms of the 21 * Alternatively, this software may be distributed under the terms of the
22 * GNU General Public License ("GPL") version 2 as published by the Free 22 * GNU General Public License ("GPL") version 2 as published by the Free
23 * Software Foundation. 23 * Software Foundation.
24 * 24 *
25 * NO WARRANTY 25 * NO WARRANTY
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 28 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
29 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 29 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
30 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 30 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
31 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
34 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36 * THE POSSIBILITY OF SUCH DAMAGES. 36 * THE POSSIBILITY OF SUCH DAMAGES.
37 */ 37 */
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#ifdef __FreeBSD__ 40#ifdef __FreeBSD__
41__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath_pci.c,v 1.11 2005/01/18 18:08:16 sam Exp $"); 41__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath_pci.c,v 1.11 2005/01/18 18:08:16 sam Exp $");
42#endif 42#endif
43#ifdef __NetBSD__ 43#ifdef __NetBSD__
44__KERNEL_RCSID(0, "$NetBSD: if_ath_pci.c,v 1.31 2008/07/09 19:47:24 joerg Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: if_ath_pci.c,v 1.31.4.1 2009/08/07 18:25:33 snj Exp $");
45#endif 45#endif
46 46
47/* 47/*
48 * PCI/Cardbus front-end for the Atheros Wireless LAN controller driver. 48 * PCI/Cardbus front-end for the Atheros Wireless LAN controller driver.
49 */ 49 */
50 50
51#include <sys/param.h> 51#include <sys/param.h>
52#include <sys/systm.h> 52#include <sys/systm.h>
53#include <sys/mbuf.h> 53#include <sys/mbuf.h>
54#include <sys/malloc.h> 54#include <sys/malloc.h>
55#include <sys/kernel.h> 55#include <sys/kernel.h>
56#include <sys/socket.h> 56#include <sys/socket.h>
57#include <sys/errno.h> 57#include <sys/errno.h>
58#include <sys/device.h> 58#include <sys/device.h>
59 59
60#include <net/if.h> 60#include <net/if.h>
61#include <net/if_media.h> 61#include <net/if_media.h>
62#include <net/if_ether.h> 62#include <net/if_ether.h>
63 63
64#include <net80211/ieee80211_netbsd.h> 64#include <net80211/ieee80211_netbsd.h>
65#include <net80211/ieee80211_var.h> 65#include <net80211/ieee80211_var.h>
66 66
67#ifdef INET 67#ifdef INET
68#include <netinet/in.h> 68#include <netinet/in.h>
69#endif 69#endif
70 70
 71#include <external/isc/atheros_hal/dist/ah.h>
 72
71#include <dev/ic/ath_netbsd.h> 73#include <dev/ic/ath_netbsd.h>
72#include <dev/ic/athvar.h> 74#include <dev/ic/athvar.h>
73#include <contrib/dev/ath/ah.h> 
74 75
75#include <dev/pci/pcivar.h> 76#include <dev/pci/pcivar.h>
76#include <dev/pci/pcireg.h> 77#include <dev/pci/pcireg.h>
77#include <dev/pci/pcidevs.h> 78#include <dev/pci/pcidevs.h>
78 79
79/* 80/*
80 * PCI glue. 81 * PCI glue.
81 */ 82 */
82 83
83struct ath_pci_softc { 84struct ath_pci_softc {
84 struct ath_softc sc_sc; 85 struct ath_softc sc_sc;
85 pci_chipset_tag_t sc_pc; 86 pci_chipset_tag_t sc_pc;
86 pcitag_t sc_pcitag;  87 pcitag_t sc_pcitag;
87 pci_intr_handle_t sc_pih; 88 pci_intr_handle_t sc_pih;
88 void *sc_ih; /* interrupt handler */ 89 void *sc_ih; /* interrupt handler */
89 bus_space_tag_t sc_iot; 90 bus_space_tag_t sc_iot;
90 bus_space_handle_t sc_ioh; 91 bus_space_handle_t sc_ioh;
91 bus_size_t sc_mapsz; 92 bus_size_t sc_mapsz;
92}; 93};
93 94
94#define BS_BAR 0x10 95#define BS_BAR 0x10
95 96
96static void ath_pci_attach(device_t, device_t, void *); 97static void ath_pci_attach(device_t, device_t, void *);
97static int ath_pci_detach(device_t, int); 98static int ath_pci_detach(device_t, int);
98static int ath_pci_match(device_t, cfdata_t, void *); 99static int ath_pci_match(device_t, cfdata_t, void *);
99static int ath_pci_detach(device_t, int); 100static int ath_pci_detach(device_t, int);
100 101
101CFATTACH_DECL_NEW(ath_pci, 102CFATTACH_DECL_NEW(ath_pci,
102 sizeof(struct ath_pci_softc), 103 sizeof(struct ath_pci_softc),
103 ath_pci_match, 104 ath_pci_match,
104 ath_pci_attach, 105 ath_pci_attach,
105 ath_pci_detach, 106 ath_pci_detach,
106 NULL); 107 NULL);
107 108
108static int 109static int
109ath_pci_match(device_t parent, struct cfdata *match, void *aux) 110ath_pci_match(device_t parent, struct cfdata *match, void *aux)
110{ 111{
111 const char* devname; 112 const char* devname;
112 struct pci_attach_args *pa = aux; 113 struct pci_attach_args *pa = aux;
113 114
114 devname = ath_hal_probe(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)); 115 devname = ath_hal_probe(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id));
115 if (devname != NULL) 116 if (devname != NULL)
116 return 1; 117 return 1;
117 return 0; 118 return 0;
118} 119}
119 120
120static bool 121static bool
121ath_pci_suspend(device_t self PMF_FN_ARGS) 122ath_pci_suspend(device_t self PMF_FN_ARGS)
122{ 123{
123 struct ath_pci_softc *sc = device_private(self); 124 struct ath_pci_softc *sc = device_private(self);
124 125
125 ath_suspend(&sc->sc_sc); 126 ath_suspend(&sc->sc_sc);
126 pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 127 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
127 sc->sc_ih = NULL; 128 sc->sc_ih = NULL;
128 129
129 return true; 130 return true;
130} 131}
131 132
132static bool 133static bool
133ath_pci_resume(device_t self PMF_FN_ARGS) 134ath_pci_resume(device_t self PMF_FN_ARGS)
134{ 135{
135 struct ath_pci_softc *sc = device_private(self); 136 struct ath_pci_softc *sc = device_private(self);
136 137
137 sc->sc_ih = pci_intr_establish(sc->sc_pc, sc->sc_pih, IPL_NET, ath_intr, 138 sc->sc_ih = pci_intr_establish(sc->sc_pc, sc->sc_pih, IPL_NET, ath_intr,
138 &sc->sc_sc); 139 &sc->sc_sc);
139 if (sc->sc_ih == NULL) { 140 if (sc->sc_ih == NULL) {
140 aprint_error_dev(self, "couldn't map interrupt\n"); 141 aprint_error_dev(self, "couldn't map interrupt\n");
141 return false; 142 return false;
142 } 143 }
143 ath_resume(&sc->sc_sc); 144 ath_resume(&sc->sc_sc);
144 145
145 return true; 146 return true;
146} 147}
147 148
148static int 149static int
149ath_pci_setup(struct ath_pci_softc *sc) 150ath_pci_setup(struct ath_pci_softc *sc)
150{ 151{
151 pcireg_t bhlc, csr, icr, lattimer; 152 pcireg_t bhlc, csr, icr, lattimer;
152 /* 153 /*
153 * Enable memory mapping and bus mastering. 154 * Enable memory mapping and bus mastering.
154 */ 155 */
155 csr = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG); 156 csr = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
156 csr |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE; 157 csr |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE;
157 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, csr); 158 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, csr);
158 csr = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG); 159 csr = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
159 160
160 if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) { 161 if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) {
161 aprint_error("couldn't enable memory mapping\n"); 162 aprint_error("couldn't enable memory mapping\n");
162 return 0; 163 return 0;
163 } 164 }
164 if ((csr & PCI_COMMAND_MASTER_ENABLE) == 0) { 165 if ((csr & PCI_COMMAND_MASTER_ENABLE) == 0) {
165 aprint_error("couldn't enable bus mastering\n"); 166 aprint_error("couldn't enable bus mastering\n");
166 return 0; 167 return 0;
167 } 168 }
168 169
169 /* 170 /*
170 * XXX Both this comment and code are replicated in 171 * XXX Both this comment and code are replicated in
171 * XXX cardbus_rescan(). 172 * XXX cardbus_rescan().
172 * 173 *
173 * Make sure the latency timer is set to some reasonable 174 * Make sure the latency timer is set to some reasonable
174 * value. 175 * value.
175 * 176 *
176 * I will set the initial value of the Latency Timer here. 177 * I will set the initial value of the Latency Timer here.
177 * 178 *
178 * While a PCI device owns the bus, its Latency Timer counts 179 * While a PCI device owns the bus, its Latency Timer counts
179 * down bus cycles from its initial value to 0. Minimum 180 * down bus cycles from its initial value to 0. Minimum
180 * Grant tells for how long the device wants to own the 181 * Grant tells for how long the device wants to own the
181 * bus once it gets access, in units of 250ns. 182 * bus once it gets access, in units of 250ns.
182 * 183 *
183 * On a 33 MHz bus, there are 8 cycles per 250ns. So I 184 * On a 33 MHz bus, there are 8 cycles per 250ns. So I
184 * multiply the Minimum Grant by 8 to find out the initial 185 * multiply the Minimum Grant by 8 to find out the initial
185 * value of the Latency Timer. 186 * value of the Latency Timer.
186 * 187 *
187 * I never set a Latency Timer less than 0x10, since that 188 * I never set a Latency Timer less than 0x10, since that
188 * is what the old code did. 189 * is what the old code did.
189 */ 190 */
190 bhlc = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_BHLC_REG); 191 bhlc = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_BHLC_REG);
191 icr = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_INTERRUPT_REG); 192 icr = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PCI_INTERRUPT_REG);
192 lattimer = MAX(0x10, MIN(0xf8, 8 * PCI_MIN_GNT(icr))); 193 lattimer = MAX(0x10, MIN(0xf8, 8 * PCI_MIN_GNT(icr)));
193 if (PCI_LATTIMER(bhlc) < lattimer) { 194 if (PCI_LATTIMER(bhlc) < lattimer) {
194 bhlc &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT); 195 bhlc &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
195 bhlc |= (lattimer << PCI_LATTIMER_SHIFT); 196 bhlc |= (lattimer << PCI_LATTIMER_SHIFT);
196 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PCI_BHLC_REG, bhlc); 197 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PCI_BHLC_REG, bhlc);
197 } 198 }
198 return 1; 199 return 1;
199} 200}
200 201
201static void 202static void
202ath_pci_attach(device_t parent, device_t self, void *aux) 203ath_pci_attach(device_t parent, device_t self, void *aux)
203{ 204{
204 struct ath_pci_softc *psc = device_private(self); 205 struct ath_pci_softc *psc = device_private(self);
205 struct ath_softc *sc = &psc->sc_sc; 206 struct ath_softc *sc = &psc->sc_sc;
206 struct pci_attach_args *pa = aux; 207 struct pci_attach_args *pa = aux;
207 pci_chipset_tag_t pc = pa->pa_pc; 208 pci_chipset_tag_t pc = pa->pa_pc;
208 pcireg_t mem_type; 209 pcireg_t mem_type;
209 const char *intrstr = NULL; 210 const char *intrstr = NULL;
210 211
211 sc->sc_dev = self; 212 sc->sc_dev = self;
212 psc->sc_pc = pc; 213 psc->sc_pc = pc;
213 214
214 psc->sc_pcitag = pa->pa_tag; 215 psc->sc_pcitag = pa->pa_tag;
215 216
216 if (!ath_pci_setup(psc)) 217 if (!ath_pci_setup(psc))
217 goto bad;  218 goto bad;
218 219
219 /* 220 /*
220 * Setup memory-mapping of PCI registers. 221 * Setup memory-mapping of PCI registers.
221 */ 222 */
222 mem_type = pci_mapreg_type(pc, pa->pa_tag, BS_BAR); 223 mem_type = pci_mapreg_type(pc, pa->pa_tag, BS_BAR);
223 if (mem_type != PCI_MAPREG_TYPE_MEM && 224 if (mem_type != PCI_MAPREG_TYPE_MEM &&
224 mem_type != PCI_MAPREG_MEM_TYPE_64BIT) { 225 mem_type != PCI_MAPREG_MEM_TYPE_64BIT) {
225 aprint_error("bad pci register type %d\n", (int)mem_type); 226 aprint_error("bad pci register type %d\n", (int)mem_type);
226 goto bad; 227 goto bad;
227 } 228 }
228 if (pci_mapreg_map(pa, BS_BAR, mem_type, 0, &psc->sc_iot, 229 if (pci_mapreg_map(pa, BS_BAR, mem_type, 0, &psc->sc_iot,
229 &psc->sc_ioh, NULL, &psc->sc_mapsz)) { 230 &psc->sc_ioh, NULL, &psc->sc_mapsz)) {
230 aprint_error("cannot map register space\n"); 231 aprint_error("cannot map register space\n");
231 goto bad; 232 goto bad;
232 } 233 }
233 234
234 sc->sc_st = HALTAG(psc->sc_iot); 235 sc->sc_st = HALTAG(psc->sc_iot);
235 sc->sc_sh = HALHANDLE(psc->sc_ioh); 236 sc->sc_sh = HALHANDLE(psc->sc_ioh);
236 237
237 /* 238 /*
238 * Arrange interrupt line. 239 * Arrange interrupt line.
239 */ 240 */
240 if (pci_intr_map(pa, &psc->sc_pih)) { 241 if (pci_intr_map(pa, &psc->sc_pih)) {
241 aprint_error("couldn't map interrupt\n"); 242 aprint_error("couldn't map interrupt\n");
242 goto bad1; 243 goto bad1;
243 } 244 }
244 245
245 intrstr = pci_intr_string(pc, psc->sc_pih);  246 intrstr = pci_intr_string(pc, psc->sc_pih);
246 psc->sc_ih = pci_intr_establish(pc, psc->sc_pih, IPL_NET, ath_intr, sc); 247 psc->sc_ih = pci_intr_establish(pc, psc->sc_pih, IPL_NET, ath_intr, sc);
247 if (psc->sc_ih == NULL) { 248 if (psc->sc_ih == NULL) {
248 aprint_error("couldn't map interrupt\n"); 249 aprint_error("couldn't map interrupt\n");
249 goto bad2; 250 goto bad2;
250 } 251 }
251 252
252 aprint_normal("\n"); 253 aprint_normal("\n");
253 aprint_verbose_dev(self, "interrupting at %s\n", intrstr); 254 aprint_verbose_dev(self, "interrupting at %s\n", intrstr);
254 255
255 sc->sc_dmat = pa->pa_dmat; 256 sc->sc_dmat = pa->pa_dmat;
256 257
257 ATH_LOCK_INIT(sc); 258 ATH_LOCK_INIT(sc);
258 259
259 if (ath_attach(PCI_PRODUCT(pa->pa_id), sc) != 0) 260 if (ath_attach(PCI_PRODUCT(pa->pa_id), sc) != 0)
260 goto bad3; 261 goto bad3;
261 262
262 if (!pmf_device_register(self, ath_pci_suspend, ath_pci_resume)) 263 if (!pmf_device_register(self, ath_pci_suspend, ath_pci_resume))
263 aprint_error_dev(self, "couldn't establish power handler\n"); 264 aprint_error_dev(self, "couldn't establish power handler\n");
264 else { 265 else {
265 pmf_class_network_register(self, &sc->sc_if); 266 pmf_class_network_register(self, &sc->sc_if);
266 pmf_device_suspend_self(self); 267 pmf_device_suspend_self(self);
267 } 268 }
268 return; 269 return;
269bad3: 270bad3:
270 ATH_LOCK_DESTROY(sc); 271 ATH_LOCK_DESTROY(sc);
271 272
272 pci_intr_disestablish(pc, psc->sc_ih); 273 pci_intr_disestablish(pc, psc->sc_ih);
273bad2: /* XXX */ 274bad2: /* XXX */
274bad1: 275bad1:
275 bus_space_unmap(psc->sc_iot, psc->sc_ioh, psc->sc_mapsz); 276 bus_space_unmap(psc->sc_iot, psc->sc_ioh, psc->sc_mapsz);
276bad: /* XXX */ 277bad: /* XXX */
277 return; 278 return;
278} 279}
279 280
280static int 281static int
281ath_pci_detach(device_t self, int flags) 282ath_pci_detach(device_t self, int flags)
282{ 283{
283 struct ath_pci_softc *psc = device_private(self); 284 struct ath_pci_softc *psc = device_private(self);
284 285
285 ath_detach(&psc->sc_sc); 286 ath_detach(&psc->sc_sc);
286 pmf_device_deregister(self); 287 pmf_device_deregister(self);
287 if (psc->sc_ih != NULL) 288 if (psc->sc_ih != NULL)
288 pci_intr_disestablish(psc->sc_pc, psc->sc_ih); 289 pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
289 bus_space_unmap(psc->sc_iot, psc->sc_ioh, psc->sc_mapsz); 290 bus_space_unmap(psc->sc_iot, psc->sc_ioh, psc->sc_mapsz);
290 291
291 ATH_LOCK_DESTROY(&psc->sc_sc); 292 ATH_LOCK_DESTROY(&psc->sc_sc);
292 293
293 return (0); 294 return (0);
294} 295}