Thu Dec 5 03:11:41 2019 UTC ()
 Remove SIOC[GS]IFMEDIA because ieee80211_ioctl() does the same thing.


(msaitoh)
diff -r1.98 -r1.99 src/sys/dev/ic/awi.c
diff -r1.253 -r1.254 src/sys/dev/ic/wi.c
diff -r1.67 -r1.68 src/sys/dev/usb/if_atu.c

cvs diff -r1.98 -r1.99 src/sys/dev/ic/awi.c (switch to unified diff)

--- src/sys/dev/ic/awi.c 2019/05/28 07:41:48 1.98
+++ src/sys/dev/ic/awi.c 2019/12/05 03:11:40 1.99
@@ -1,1863 +1,1858 @@ @@ -1,1863 +1,1858 @@
1/* $NetBSD: awi.c,v 1.98 2019/05/28 07:41:48 msaitoh Exp $ */ 1/* $NetBSD: awi.c,v 1.99 2019/12/05 03:11:40 msaitoh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999,2000,2001 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999,2000,2001 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Bill Sommerfeld 8 * by Bill Sommerfeld
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31/* 31/*
32 * Driver for AMD 802.11 firmware. 32 * Driver for AMD 802.11 firmware.
33 * Uses am79c930 chip driver to talk to firmware running on the am79c930. 33 * Uses am79c930 chip driver to talk to firmware running on the am79c930.
34 * 34 *
35 * More-or-less a generic ethernet-like if driver, with 802.11 gorp added. 35 * More-or-less a generic ethernet-like if driver, with 802.11 gorp added.
36 */ 36 */
37 37
38/* 38/*
39 * todo: 39 * todo:
40 * - flush tx queue on resynch. 40 * - flush tx queue on resynch.
41 * - clear oactive on "down". 41 * - clear oactive on "down".
42 * - rewrite copy-into-mbuf code 42 * - rewrite copy-into-mbuf code
43 * - mgmt state machine gets stuck retransmitting assoc requests. 43 * - mgmt state machine gets stuck retransmitting assoc requests.
44 * - multicast filter. 44 * - multicast filter.
45 * - fix device reset so it's more likely to work 45 * - fix device reset so it's more likely to work
46 * - show status goo through ifmedia. 46 * - show status goo through ifmedia.
47 * 47 *
48 * more todo: 48 * more todo:
49 * - deal with more 802.11 frames. 49 * - deal with more 802.11 frames.
50 * - send reassoc request 50 * - send reassoc request
51 * - deal with reassoc response 51 * - deal with reassoc response
52 * - send/deal with disassociation 52 * - send/deal with disassociation
53 * - deal with "full" access points (no room for me). 53 * - deal with "full" access points (no room for me).
54 * - power save mode 54 * - power save mode
55 * 55 *
56 * later: 56 * later:
57 * - SSID preferences 57 * - SSID preferences
58 * - need ioctls for poking at the MIBs 58 * - need ioctls for poking at the MIBs
59 * - implement ad-hoc mode (including bss creation). 59 * - implement ad-hoc mode (including bss creation).
60 * - decide when to do "ad hoc" vs. infrastructure mode (IFF_LINK flags?) 60 * - decide when to do "ad hoc" vs. infrastructure mode (IFF_LINK flags?)
61 * (focus on inf. mode since that will be needed for ietf) 61 * (focus on inf. mode since that will be needed for ietf)
62 * - deal with DH vs. FH versions of the card 62 * - deal with DH vs. FH versions of the card
63 * - deal with faster cards (2mb/s) 63 * - deal with faster cards (2mb/s)
64 * - ?WEP goo (mmm, rc4) (it looks not particularly useful). 64 * - ?WEP goo (mmm, rc4) (it looks not particularly useful).
65 * - ifmedia revision. 65 * - ifmedia revision.
66 * - common 802.11 mibish things. 66 * - common 802.11 mibish things.
67 * - common 802.11 media layer. 67 * - common 802.11 media layer.
68 */ 68 */
69 69
70/* 70/*
71 * Driver for AMD 802.11 PCnetMobile firmware. 71 * Driver for AMD 802.11 PCnetMobile firmware.
72 * Uses am79c930 chip driver to talk to firmware running on the am79c930. 72 * Uses am79c930 chip driver to talk to firmware running on the am79c930.
73 * 73 *
74 * The initial version of the driver was written by 74 * The initial version of the driver was written by
75 * Bill Sommerfeld <sommerfeld@NetBSD.org>. 75 * Bill Sommerfeld <sommerfeld@NetBSD.org>.
76 * Then the driver module completely rewritten to support cards with DS phy 76 * Then the driver module completely rewritten to support cards with DS phy
77 * and to support adhoc mode by Atsushi Onoe <onoe@NetBSD.org> 77 * and to support adhoc mode by Atsushi Onoe <onoe@NetBSD.org>
78 */ 78 */
79 79
80#include <sys/cdefs.h> 80#include <sys/cdefs.h>
81__KERNEL_RCSID(0, "$NetBSD: awi.c,v 1.98 2019/05/28 07:41:48 msaitoh Exp $"); 81__KERNEL_RCSID(0, "$NetBSD: awi.c,v 1.99 2019/12/05 03:11:40 msaitoh Exp $");
82 82
83#include "opt_inet.h" 83#include "opt_inet.h"
84 84
85#include <sys/param.h> 85#include <sys/param.h>
86#include <sys/systm.h> 86#include <sys/systm.h>
87#include <sys/kernel.h> 87#include <sys/kernel.h>
88#include <sys/mbuf.h> 88#include <sys/mbuf.h>
89#include <sys/malloc.h> 89#include <sys/malloc.h>
90#include <sys/proc.h> 90#include <sys/proc.h>
91#include <sys/socket.h> 91#include <sys/socket.h>
92#include <sys/sockio.h> 92#include <sys/sockio.h>
93#include <sys/errno.h> 93#include <sys/errno.h>
94#include <sys/endian.h> 94#include <sys/endian.h>
95#include <sys/device.h> 95#include <sys/device.h>
96#include <sys/cpu.h> 96#include <sys/cpu.h>
97#include <sys/bus.h> 97#include <sys/bus.h>
98 98
99#include <net/if.h> 99#include <net/if.h>
100#include <net/if_dl.h> 100#include <net/if_dl.h>
101#include <net/if_ether.h> 101#include <net/if_ether.h>
102#include <net/if_media.h> 102#include <net/if_media.h>
103#include <net/if_llc.h> 103#include <net/if_llc.h>
104#include <net/bpf.h> 104#include <net/bpf.h>
105 105
106#include <net80211/ieee80211_netbsd.h> 106#include <net80211/ieee80211_netbsd.h>
107#include <net80211/ieee80211_var.h> 107#include <net80211/ieee80211_var.h>
108 108
109#include <dev/ic/am79c930reg.h> 109#include <dev/ic/am79c930reg.h>
110#include <dev/ic/am79c930var.h> 110#include <dev/ic/am79c930var.h>
111#include <dev/ic/awireg.h> 111#include <dev/ic/awireg.h>
112#include <dev/ic/awivar.h> 112#include <dev/ic/awivar.h>
113 113
114static void awi_softintr(void *); 114static void awi_softintr(void *);
115static int awi_init(struct ifnet *); 115static int awi_init(struct ifnet *);
116static void awi_stop(struct ifnet *, int); 116static void awi_stop(struct ifnet *, int);
117static void awi_start(struct ifnet *); 117static void awi_start(struct ifnet *);
118static void awi_watchdog(struct ifnet *); 118static void awi_watchdog(struct ifnet *);
119static int awi_ioctl(struct ifnet *, u_long, void *); 119static int awi_ioctl(struct ifnet *, u_long, void *);
120static int awi_media_change(struct ifnet *); 120static int awi_media_change(struct ifnet *);
121static void awi_media_status(struct ifnet *, struct ifmediareq *); 121static void awi_media_status(struct ifnet *, struct ifmediareq *);
122static int awi_mode_init(struct awi_softc *); 122static int awi_mode_init(struct awi_softc *);
123static void awi_rx_int(struct awi_softc *); 123static void awi_rx_int(struct awi_softc *);
124static void awi_tx_int(struct awi_softc *); 124static void awi_tx_int(struct awi_softc *);
125static struct mbuf *awi_devget(struct awi_softc *, uint32_t, uint16_t); 125static struct mbuf *awi_devget(struct awi_softc *, uint32_t, uint16_t);
126static int awi_hw_init(struct awi_softc *); 126static int awi_hw_init(struct awi_softc *);
127static int awi_init_mibs(struct awi_softc *); 127static int awi_init_mibs(struct awi_softc *);
128static int awi_mib(struct awi_softc *, uint8_t, uint8_t, int); 128static int awi_mib(struct awi_softc *, uint8_t, uint8_t, int);
129static int awi_cmd(struct awi_softc *, uint8_t, int); 129static int awi_cmd(struct awi_softc *, uint8_t, int);
130static int awi_cmd_wait(struct awi_softc *); 130static int awi_cmd_wait(struct awi_softc *);
131static void awi_cmd_done(struct awi_softc *); 131static void awi_cmd_done(struct awi_softc *);
132static int awi_next_txd(struct awi_softc *, int, uint32_t *, uint32_t *); 132static int awi_next_txd(struct awi_softc *, int, uint32_t *, uint32_t *);
133static int awi_lock(struct awi_softc *); 133static int awi_lock(struct awi_softc *);
134static void awi_unlock(struct awi_softc *); 134static void awi_unlock(struct awi_softc *);
135static int awi_intr_lock(struct awi_softc *); 135static int awi_intr_lock(struct awi_softc *);
136static void awi_intr_unlock(struct awi_softc *); 136static void awi_intr_unlock(struct awi_softc *);
137static int awi_newstate(struct ieee80211com *, enum ieee80211_state, int); 137static int awi_newstate(struct ieee80211com *, enum ieee80211_state, int);
138static void awi_recv_mgmt(struct ieee80211com *, struct mbuf *, 138static void awi_recv_mgmt(struct ieee80211com *, struct mbuf *,
139 struct ieee80211_node *, int, int, uint32_t); 139 struct ieee80211_node *, int, int, uint32_t);
140static int awi_send_mgmt(struct ieee80211com *, struct ieee80211_node *, int, 140static int awi_send_mgmt(struct ieee80211com *, struct ieee80211_node *, int,
141 int); 141 int);
142static struct mbuf *awi_ether_encap(struct awi_softc *, struct mbuf *); 142static struct mbuf *awi_ether_encap(struct awi_softc *, struct mbuf *);
143static struct mbuf *awi_ether_modcap(struct awi_softc *, struct mbuf *); 143static struct mbuf *awi_ether_modcap(struct awi_softc *, struct mbuf *);
144 144
145/* Unaligned little endian access */ 145/* Unaligned little endian access */
146#define LE_READ_2(p) \ 146#define LE_READ_2(p) \
147 ((((uint8_t *)(p))[0] ) | (((uint8_t *)(p))[1] << 8)) 147 ((((uint8_t *)(p))[0] ) | (((uint8_t *)(p))[1] << 8))
148#define LE_READ_4(p) \ 148#define LE_READ_4(p) \
149 ((((uint8_t *)(p))[0] ) | (((uint8_t *)(p))[1] << 8) | \ 149 ((((uint8_t *)(p))[0] ) | (((uint8_t *)(p))[1] << 8) | \
150 (((uint8_t *)(p))[2] << 16) | (((uint8_t *)(p))[3] << 24)) 150 (((uint8_t *)(p))[2] << 16) | (((uint8_t *)(p))[3] << 24))
151#define LE_WRITE_2(p, v) \ 151#define LE_WRITE_2(p, v) \
152 ((((uint8_t *)(p))[0] = (((uint32_t)(v) ) & 0xff)), \ 152 ((((uint8_t *)(p))[0] = (((uint32_t)(v) ) & 0xff)), \
153 (((uint8_t *)(p))[1] = (((uint32_t)(v) >> 8) & 0xff))) 153 (((uint8_t *)(p))[1] = (((uint32_t)(v) >> 8) & 0xff)))
154#define LE_WRITE_4(p, v) \ 154#define LE_WRITE_4(p, v) \
155 ((((uint8_t *)(p))[0] = (((uint32_t)(v) ) & 0xff)), \ 155 ((((uint8_t *)(p))[0] = (((uint32_t)(v) ) & 0xff)), \
156 (((uint8_t *)(p))[1] = (((uint32_t)(v) >> 8) & 0xff)), \ 156 (((uint8_t *)(p))[1] = (((uint32_t)(v) >> 8) & 0xff)), \
157 (((uint8_t *)(p))[2] = (((uint32_t)(v) >> 16) & 0xff)), \ 157 (((uint8_t *)(p))[2] = (((uint32_t)(v) >> 16) & 0xff)), \
158 (((uint8_t *)(p))[3] = (((uint32_t)(v) >> 24) & 0xff))) 158 (((uint8_t *)(p))[3] = (((uint32_t)(v) >> 24) & 0xff)))
159 159
160static const struct awi_chanset awi_chanset[] = { 160static const struct awi_chanset awi_chanset[] = {
161 /* PHY type domain min max def */ 161 /* PHY type domain min max def */
162 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_JP, 6, 17, 6 }, 162 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_JP, 6, 17, 6 },
163 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_ES, 0, 26, 1 }, 163 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_ES, 0, 26, 1 },
164 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_FR, 0, 32, 1 }, 164 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_FR, 0, 32, 1 },
165 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_US, 0, 77, 1 }, 165 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_US, 0, 77, 1 },
166 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_CA, 0, 77, 1 }, 166 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_CA, 0, 77, 1 },
167 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_EU, 0, 77, 1 }, 167 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_EU, 0, 77, 1 },
168 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_JP, 14, 14, 14 }, 168 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_JP, 14, 14, 14 },
169 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_ES, 10, 11, 10 }, 169 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_ES, 10, 11, 10 },
170 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_FR, 10, 13, 10 }, 170 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_FR, 10, 13, 10 },
171 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_US, 1, 11, 3 }, 171 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_US, 1, 11, 3 },
172 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_CA, 1, 11, 3 }, 172 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_CA, 1, 11, 3 },
173 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_EU, 1, 13, 3 }, 173 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_EU, 1, 13, 3 },
174 { 0, 0, 0, 0, 0 } 174 { 0, 0, 0, 0, 0 }
175}; 175};
176 176
177#ifdef AWI_DEBUG 177#ifdef AWI_DEBUG
178int awi_debug = 0; 178int awi_debug = 0;
179 179
180#define DPRINTF(X) if (awi_debug) printf X 180#define DPRINTF(X) if (awi_debug) printf X
181#define DPRINTF2(X) if (awi_debug > 1) printf X 181#define DPRINTF2(X) if (awi_debug > 1) printf X
182#else 182#else
183#define DPRINTF(X) 183#define DPRINTF(X)
184#define DPRINTF2(X) 184#define DPRINTF2(X)
185#endif 185#endif
186 186
187int 187int
188awi_attach(struct awi_softc *sc) 188awi_attach(struct awi_softc *sc)
189{ 189{
190 struct ieee80211com *ic = &sc->sc_ic; 190 struct ieee80211com *ic = &sc->sc_ic;
191 struct ifnet *ifp = &sc->sc_if; 191 struct ifnet *ifp = &sc->sc_if;
192 int s, i, error, nrate; 192 int s, i, error, nrate;
193 int mword; 193 int mword;
194 enum ieee80211_phymode mode; 194 enum ieee80211_phymode mode;
195 195
196 s = splnet(); 196 s = splnet();
197 sc->sc_busy = 1; 197 sc->sc_busy = 1;
198 sc->sc_attached = 0; 198 sc->sc_attached = 0;
199 sc->sc_substate = AWI_ST_NONE; 199 sc->sc_substate = AWI_ST_NONE;
200 sc->sc_soft_ih = softint_establish(SOFTINT_NET, awi_softintr, sc); 200 sc->sc_soft_ih = softint_establish(SOFTINT_NET, awi_softintr, sc);
201 if (sc->sc_soft_ih == NULL) { 201 if (sc->sc_soft_ih == NULL) {
202 config_deactivate(sc->sc_dev); 202 config_deactivate(sc->sc_dev);
203 splx(s); 203 splx(s);
204 return ENOMEM; 204 return ENOMEM;
205 } 205 }
206 if ((error = awi_hw_init(sc)) != 0) { 206 if ((error = awi_hw_init(sc)) != 0) {
207 config_deactivate(sc->sc_dev); 207 config_deactivate(sc->sc_dev);
208 splx(s); 208 splx(s);
209 return error; 209 return error;
210 } 210 }
211 error = awi_init_mibs(sc); 211 error = awi_init_mibs(sc);
212 if (error != 0) { 212 if (error != 0) {
213 config_deactivate(sc->sc_dev); 213 config_deactivate(sc->sc_dev);
214 splx(s); 214 splx(s);
215 return error; 215 return error;
216 } 216 }
217 ifp->if_softc = sc; 217 ifp->if_softc = sc;
218 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 218 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
219 ifp->if_ioctl = awi_ioctl; 219 ifp->if_ioctl = awi_ioctl;
220 ifp->if_start = awi_start; 220 ifp->if_start = awi_start;
221 ifp->if_watchdog = awi_watchdog; 221 ifp->if_watchdog = awi_watchdog;
222 ifp->if_init = awi_init; 222 ifp->if_init = awi_init;
223 ifp->if_stop = awi_stop; 223 ifp->if_stop = awi_stop;
224 IFQ_SET_READY(&ifp->if_snd); 224 IFQ_SET_READY(&ifp->if_snd);
225 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 225 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
226 226
227 ic->ic_ifp = ifp; 227 ic->ic_ifp = ifp;
228 ic->ic_caps = IEEE80211_C_WEP | IEEE80211_C_IBSS | IEEE80211_C_HOSTAP; 228 ic->ic_caps = IEEE80211_C_WEP | IEEE80211_C_IBSS | IEEE80211_C_HOSTAP;
229 if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { 229 if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
230 ic->ic_phytype = IEEE80211_T_FH; 230 ic->ic_phytype = IEEE80211_T_FH;
231 mode = IEEE80211_MODE_FH; 231 mode = IEEE80211_MODE_FH;
232 } else { 232 } else {
233 ic->ic_phytype = IEEE80211_T_DS; 233 ic->ic_phytype = IEEE80211_T_DS;
234 ic->ic_caps |= IEEE80211_C_AHDEMO; 234 ic->ic_caps |= IEEE80211_C_AHDEMO;
235 mode = IEEE80211_MODE_11B; 235 mode = IEEE80211_MODE_11B;
236 } 236 }
237 ic->ic_opmode = IEEE80211_M_STA; 237 ic->ic_opmode = IEEE80211_M_STA;
238 nrate = sc->sc_mib_phy.aSuprt_Data_Rates[1]; 238 nrate = sc->sc_mib_phy.aSuprt_Data_Rates[1];
239 memcpy(ic->ic_sup_rates[mode].rs_rates, 239 memcpy(ic->ic_sup_rates[mode].rs_rates,
240 sc->sc_mib_phy.aSuprt_Data_Rates + 2, nrate); 240 sc->sc_mib_phy.aSuprt_Data_Rates + 2, nrate);
241 ic->ic_sup_rates[mode].rs_nrates = nrate; 241 ic->ic_sup_rates[mode].rs_nrates = nrate;
242 IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_mib_addr.aMAC_Address); 242 IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_mib_addr.aMAC_Address);
243 243
244 printf("%s: IEEE802.11 %s (firmware %s)\n", ifp->if_xname, 244 printf("%s: IEEE802.11 %s (firmware %s)\n", ifp->if_xname,
245 (ic->ic_phytype == IEEE80211_T_FH) ? "FH" : "DS", sc->sc_banner); 245 (ic->ic_phytype == IEEE80211_T_FH) ? "FH" : "DS", sc->sc_banner);
246 printf("%s: 802.11 address: %s\n", ifp->if_xname, 246 printf("%s: 802.11 address: %s\n", ifp->if_xname,
247 ether_sprintf(ic->ic_myaddr)); 247 ether_sprintf(ic->ic_myaddr));
248 248
249 if_attach(ifp); 249 if_attach(ifp);
250 ieee80211_ifattach(ic); 250 ieee80211_ifattach(ic);
251 251
252 sc->sc_newstate = ic->ic_newstate; 252 sc->sc_newstate = ic->ic_newstate;
253 ic->ic_newstate = awi_newstate; 253 ic->ic_newstate = awi_newstate;
254 254
255 sc->sc_recv_mgmt = ic->ic_recv_mgmt; 255 sc->sc_recv_mgmt = ic->ic_recv_mgmt;
256 ic->ic_recv_mgmt = awi_recv_mgmt; 256 ic->ic_recv_mgmt = awi_recv_mgmt;
257 257
258 sc->sc_send_mgmt = ic->ic_send_mgmt; 258 sc->sc_send_mgmt = ic->ic_send_mgmt;
259 ic->ic_send_mgmt = awi_send_mgmt; 259 ic->ic_send_mgmt = awi_send_mgmt;
260 260
261 ieee80211_media_init(ic, awi_media_change, awi_media_status); 261 ieee80211_media_init(ic, awi_media_change, awi_media_status);
262 262
263 /* Melco compatibility mode. */ 263 /* Melco compatibility mode. */
264#define ADD(s, o) ifmedia_add(&ic->ic_media, \ 264#define ADD(s, o) ifmedia_add(&ic->ic_media, \
265 IFM_MAKEWORD(IFM_IEEE80211, (s), (o), 0), 0, NULL) 265 IFM_MAKEWORD(IFM_IEEE80211, (s), (o), 0), 0, NULL)
266 ADD(IFM_AUTO, IFM_FLAG0); 266 ADD(IFM_AUTO, IFM_FLAG0);
267 267
268 for (i = 0; i < nrate; i++) { 268 for (i = 0; i < nrate; i++) {
269 mword = ieee80211_rate2media(ic, 269 mword = ieee80211_rate2media(ic,
270 ic->ic_sup_rates[mode].rs_rates[i], mode); 270 ic->ic_sup_rates[mode].rs_rates[i], mode);
271 if (mword == 0) 271 if (mword == 0)
272 continue; 272 continue;
273 ADD(mword, IFM_FLAG0); 273 ADD(mword, IFM_FLAG0);
274 } 274 }
275#undef ADD 275#undef ADD
276 276
277 if ((sc->sc_sdhook = shutdownhook_establish(awi_shutdown, sc)) == NULL) 277 if ((sc->sc_sdhook = shutdownhook_establish(awi_shutdown, sc)) == NULL)
278 printf("%s: WARNING: unable to establish shutdown hook\n", 278 printf("%s: WARNING: unable to establish shutdown hook\n",
279 ifp->if_xname); 279 ifp->if_xname);
280 if ((sc->sc_powerhook = 280 if ((sc->sc_powerhook =
281 powerhook_establish(ifp->if_xname, awi_power, sc)) == NULL) 281 powerhook_establish(ifp->if_xname, awi_power, sc)) == NULL)
282 printf("%s: WARNING: unable to establish power hook\n", 282 printf("%s: WARNING: unable to establish power hook\n",
283 ifp->if_xname); 283 ifp->if_xname);
284 sc->sc_attached = 1; 284 sc->sc_attached = 1;
285 splx(s); 285 splx(s);
286 286
287 /* Ready to accept ioctl */ 287 /* Ready to accept ioctl */
288 awi_unlock(sc); 288 awi_unlock(sc);
289 289
290 return 0; 290 return 0;
291} 291}
292 292
293int 293int
294awi_detach(struct awi_softc *sc) 294awi_detach(struct awi_softc *sc)
295{ 295{
296 struct ieee80211com *ic = &sc->sc_ic; 296 struct ieee80211com *ic = &sc->sc_ic;
297 struct ifnet *ifp = &sc->sc_if; 297 struct ifnet *ifp = &sc->sc_if;
298 int s; 298 int s;
299 299
300 if (!sc->sc_attached) 300 if (!sc->sc_attached)
301 return 0; 301 return 0;
302 302
303 s = splnet(); 303 s = splnet();
304 awi_stop(ifp, 1); 304 awi_stop(ifp, 1);
305 305
306 while (sc->sc_sleep_cnt > 0) { 306 while (sc->sc_sleep_cnt > 0) {
307 wakeup(sc); 307 wakeup(sc);
308 (void)tsleep(sc, PWAIT, "awidet", 1); 308 (void)tsleep(sc, PWAIT, "awidet", 1);
309 } 309 }
310 sc->sc_attached = 0; 310 sc->sc_attached = 0;
311 ieee80211_ifdetach(ic); 311 ieee80211_ifdetach(ic);
312 if_detach(ifp); 312 if_detach(ifp);
313 shutdownhook_disestablish(sc->sc_sdhook); 313 shutdownhook_disestablish(sc->sc_sdhook);
314 powerhook_disestablish(sc->sc_powerhook); 314 powerhook_disestablish(sc->sc_powerhook);
315 softint_disestablish(sc->sc_soft_ih); 315 softint_disestablish(sc->sc_soft_ih);
316 splx(s); 316 splx(s);
317 return 0; 317 return 0;
318} 318}
319 319
320int 320int
321awi_activate(device_t self, enum devact act) 321awi_activate(device_t self, enum devact act)
322{ 322{
323 struct awi_softc *sc = device_private(self); 323 struct awi_softc *sc = device_private(self);
324 324
325 switch (act) { 325 switch (act) {
326 case DVACT_DEACTIVATE: 326 case DVACT_DEACTIVATE:
327 if_deactivate(&sc->sc_if); 327 if_deactivate(&sc->sc_if);
328 return 0; 328 return 0;
329 default: 329 default:
330 return EOPNOTSUPP; 330 return EOPNOTSUPP;
331 } 331 }
332} 332}
333 333
334void 334void
335awi_power(int why, void *arg) 335awi_power(int why, void *arg)
336{ 336{
337 struct awi_softc *sc = arg; 337 struct awi_softc *sc = arg;
338 struct ifnet *ifp = &sc->sc_if; 338 struct ifnet *ifp = &sc->sc_if;
339 int s; 339 int s;
340 int ocansleep; 340 int ocansleep;
341 341
342 DPRINTF(("awi_power: %d\n", why)); 342 DPRINTF(("awi_power: %d\n", why));
343 s = splnet(); 343 s = splnet();
344 ocansleep = sc->sc_cansleep; 344 ocansleep = sc->sc_cansleep;
345 sc->sc_cansleep = 0; 345 sc->sc_cansleep = 0;
346 switch (why) { 346 switch (why) {
347 case PWR_SUSPEND: 347 case PWR_SUSPEND:
348 case PWR_STANDBY: 348 case PWR_STANDBY:
349 awi_stop(ifp, 1); 349 awi_stop(ifp, 1);
350 break; 350 break;
351 case PWR_RESUME: 351 case PWR_RESUME:
352 if (ifp->if_flags & IFF_UP) { 352 if (ifp->if_flags & IFF_UP) {
353 awi_init(ifp); 353 awi_init(ifp);
354 awi_softintr(sc); /* make sure */ 354 awi_softintr(sc); /* make sure */
355 } 355 }
356 break; 356 break;
357 case PWR_SOFTSUSPEND: 357 case PWR_SOFTSUSPEND:
358 case PWR_SOFTSTANDBY: 358 case PWR_SOFTSTANDBY:
359 case PWR_SOFTRESUME: 359 case PWR_SOFTRESUME:
360 break; 360 break;
361 } 361 }
362 sc->sc_cansleep = ocansleep; 362 sc->sc_cansleep = ocansleep;
363 splx(s); 363 splx(s);
364} 364}
365 365
366void 366void
367awi_shutdown(void *arg) 367awi_shutdown(void *arg)
368{ 368{
369 struct awi_softc *sc = arg; 369 struct awi_softc *sc = arg;
370 struct ifnet *ifp = &sc->sc_if; 370 struct ifnet *ifp = &sc->sc_if;
371 371
372 if (sc->sc_attached) 372 if (sc->sc_attached)
373 awi_stop(ifp, 1); 373 awi_stop(ifp, 1);
374} 374}
375 375
376int 376int
377awi_intr(void *arg) 377awi_intr(void *arg)
378{ 378{
379 struct awi_softc *sc = arg; 379 struct awi_softc *sc = arg;
380 380
381 if (!sc->sc_enabled || !sc->sc_enab_intr || 381 if (!sc->sc_enabled || !sc->sc_enab_intr ||
382 !device_is_active(sc->sc_dev)) { 382 !device_is_active(sc->sc_dev)) {
383 DPRINTF(("awi_intr: stray interrupt: " 383 DPRINTF(("awi_intr: stray interrupt: "
384 "enabled %d enab_intr %d invalid %d\n", 384 "enabled %d enab_intr %d invalid %d\n",
385 sc->sc_enabled, sc->sc_enab_intr, 385 sc->sc_enabled, sc->sc_enab_intr,
386 !device_is_active(sc->sc_dev))); 386 !device_is_active(sc->sc_dev)));
387 return 0; 387 return 0;
388 } 388 }
389 389
390 softint_schedule(sc->sc_soft_ih); 390 softint_schedule(sc->sc_soft_ih);
391 return 1; 391 return 1;
392} 392}
393 393
394static void 394static void
395awi_softintr(void *arg) 395awi_softintr(void *arg)
396{ 396{
397 struct awi_softc *sc = arg; 397 struct awi_softc *sc = arg;
398 uint16_t status; 398 uint16_t status;
399 int ocansleep; 399 int ocansleep;
400 int s; 400 int s;
401#ifdef AWI_DEBUG 401#ifdef AWI_DEBUG
402 static const char *intname[] = { 402 static const char *intname[] = {
403 "CMD", "RX", "TX", "SCAN_CMPLT", 403 "CMD", "RX", "TX", "SCAN_CMPLT",
404 "CFP_START", "DTIM", "CFP_ENDING", "GROGGY", 404 "CFP_START", "DTIM", "CFP_ENDING", "GROGGY",
405 "TXDATA", "TXBCAST", "TXPS", "TXCF", 405 "TXDATA", "TXBCAST", "TXPS", "TXCF",
406 "TXMGT", "#13", "RXDATA", "RXMGT" 406 "TXMGT", "#13", "RXDATA", "RXMGT"
407 }; 407 };
408#endif 408#endif
409 409
410 s = splnet(); 410 s = splnet();
411 am79c930_gcr_setbits(&sc->sc_chip, 411 am79c930_gcr_setbits(&sc->sc_chip,
412 AM79C930_GCR_DISPWDN | AM79C930_GCR_ECINT); 412 AM79C930_GCR_DISPWDN | AM79C930_GCR_ECINT);
413 awi_write_1(sc, AWI_DIS_PWRDN, 1); 413 awi_write_1(sc, AWI_DIS_PWRDN, 1);
414 ocansleep = sc->sc_cansleep; 414 ocansleep = sc->sc_cansleep;
415 sc->sc_cansleep = 0; 415 sc->sc_cansleep = 0;
416 416
417 for (;;) { 417 for (;;) {
418 if (awi_intr_lock(sc) != 0) 418 if (awi_intr_lock(sc) != 0)
419 break; 419 break;
420 status = awi_read_1(sc, AWI_INTSTAT); 420 status = awi_read_1(sc, AWI_INTSTAT);
421 awi_write_1(sc, AWI_INTSTAT, 0); 421 awi_write_1(sc, AWI_INTSTAT, 0);
422 awi_write_1(sc, AWI_INTSTAT, 0); 422 awi_write_1(sc, AWI_INTSTAT, 0);
423 status |= awi_read_1(sc, AWI_INTSTAT2) << 8; 423 status |= awi_read_1(sc, AWI_INTSTAT2) << 8;
424 awi_write_1(sc, AWI_INTSTAT2, 0); 424 awi_write_1(sc, AWI_INTSTAT2, 0);
425 DELAY(10); 425 DELAY(10);
426 awi_intr_unlock(sc); 426 awi_intr_unlock(sc);
427 if (!sc->sc_cmd_inprog) 427 if (!sc->sc_cmd_inprog)
428 status &= ~AWI_INT_CMD; /* make sure */ 428 status &= ~AWI_INT_CMD; /* make sure */
429 if (status == 0) 429 if (status == 0)
430 break; 430 break;
431#ifdef AWI_DEBUG 431#ifdef AWI_DEBUG
432 if (awi_debug > 1) { 432 if (awi_debug > 1) {
433 int i; 433 int i;
434 434
435 printf("awi_intr: status 0x%04x", status); 435 printf("awi_intr: status 0x%04x", status);
436 for (i = 0; i < sizeof(intname)/sizeof(intname[0]); 436 for (i = 0; i < sizeof(intname)/sizeof(intname[0]);
437 i++) { 437 i++) {
438 if (status & (1 << i)) 438 if (status & (1 << i))
439 printf(" %s", intname[i]); 439 printf(" %s", intname[i]);
440 } 440 }
441 printf("\n"); 441 printf("\n");
442 } 442 }
443#endif 443#endif
444 if (status & AWI_INT_RX) 444 if (status & AWI_INT_RX)
445 awi_rx_int(sc); 445 awi_rx_int(sc);
446 if (status & AWI_INT_TX) 446 if (status & AWI_INT_TX)
447 awi_tx_int(sc); 447 awi_tx_int(sc);
448 if (status & AWI_INT_CMD) 448 if (status & AWI_INT_CMD)
449 awi_cmd_done(sc); 449 awi_cmd_done(sc);
450 if (status & AWI_INT_SCAN_CMPLT) { 450 if (status & AWI_INT_SCAN_CMPLT) {
451 if (sc->sc_ic.ic_state == IEEE80211_S_SCAN && 451 if (sc->sc_ic.ic_state == IEEE80211_S_SCAN &&
452 sc->sc_substate == AWI_ST_NONE) 452 sc->sc_substate == AWI_ST_NONE)
453 ieee80211_next_scan(&sc->sc_ic); 453 ieee80211_next_scan(&sc->sc_ic);
454 } 454 }
455 } 455 }
456 456
457 sc->sc_cansleep = ocansleep; 457 sc->sc_cansleep = ocansleep;
458 am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_DISPWDN); 458 am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_DISPWDN);
459 awi_write_1(sc, AWI_DIS_PWRDN, 0); 459 awi_write_1(sc, AWI_DIS_PWRDN, 0);
460 splx(s); 460 splx(s);
461} 461}
462 462
463 463
464static int 464static int
465awi_init(struct ifnet *ifp) 465awi_init(struct ifnet *ifp)
466{ 466{
467 struct awi_softc *sc = ifp->if_softc; 467 struct awi_softc *sc = ifp->if_softc;
468 struct ieee80211com *ic = &sc->sc_ic; 468 struct ieee80211com *ic = &sc->sc_ic;
469 struct ieee80211_node *ni = ic->ic_bss; 469 struct ieee80211_node *ni = ic->ic_bss;
470 struct ieee80211_rateset *rs; 470 struct ieee80211_rateset *rs;
471 int error, rate, i; 471 int error, rate, i;
472 472
473 DPRINTF(("awi_init: enabled=%d\n", sc->sc_enabled)); 473 DPRINTF(("awi_init: enabled=%d\n", sc->sc_enabled));
474 if (sc->sc_enabled) { 474 if (sc->sc_enabled) {
475 awi_stop(ifp, 0); 475 awi_stop(ifp, 0);
476 } else { 476 } else {
477 if (sc->sc_enable) 477 if (sc->sc_enable)
478 (*sc->sc_enable)(sc); 478 (*sc->sc_enable)(sc);
479 sc->sc_enabled = 1; 479 sc->sc_enabled = 1;
480 if ((error = awi_hw_init(sc)) != 0) { 480 if ((error = awi_hw_init(sc)) != 0) {
481 if (sc->sc_disable) 481 if (sc->sc_disable)
482 (*sc->sc_disable)(sc); 482 (*sc->sc_disable)(sc);
483 sc->sc_enabled = 0; 483 sc->sc_enabled = 0;
484 return error; 484 return error;
485 } 485 }
486 } 486 }
487 ic->ic_state = IEEE80211_S_INIT; 487 ic->ic_state = IEEE80211_S_INIT;
488 488
489 ic->ic_flags &= ~IEEE80211_F_IBSSON; 489 ic->ic_flags &= ~IEEE80211_F_IBSSON;
490 switch (ic->ic_opmode) { 490 switch (ic->ic_opmode) {
491 case IEEE80211_M_STA: 491 case IEEE80211_M_STA:
492 sc->sc_mib_local.Network_Mode = 1; 492 sc->sc_mib_local.Network_Mode = 1;
493 sc->sc_mib_local.Acting_as_AP = 0; 493 sc->sc_mib_local.Acting_as_AP = 0;
494 break; 494 break;
495 case IEEE80211_M_IBSS: 495 case IEEE80211_M_IBSS:
496 ic->ic_flags |= IEEE80211_F_IBSSON; 496 ic->ic_flags |= IEEE80211_F_IBSSON;
497 /* FALLTHRU */ 497 /* FALLTHRU */
498 case IEEE80211_M_AHDEMO: 498 case IEEE80211_M_AHDEMO:
499 sc->sc_mib_local.Network_Mode = 0; 499 sc->sc_mib_local.Network_Mode = 0;
500 sc->sc_mib_local.Acting_as_AP = 0; 500 sc->sc_mib_local.Acting_as_AP = 0;
501 break; 501 break;
502 case IEEE80211_M_HOSTAP: 502 case IEEE80211_M_HOSTAP:
503 sc->sc_mib_local.Network_Mode = 1; 503 sc->sc_mib_local.Network_Mode = 1;
504 sc->sc_mib_local.Acting_as_AP = 1; 504 sc->sc_mib_local.Acting_as_AP = 1;
505 break; 505 break;
506 case IEEE80211_M_MONITOR: 506 case IEEE80211_M_MONITOR:
507 return ENODEV; 507 return ENODEV;
508 } 508 }
509#if 0 509#if 0
510 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 510 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
511#endif 511#endif
512 memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE); 512 memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE);
513 sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID; 513 sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID;
514 sc->sc_mib_mac.aDesired_ESS_ID[1] = ic->ic_des_esslen; 514 sc->sc_mib_mac.aDesired_ESS_ID[1] = ic->ic_des_esslen;
515 memcpy(&sc->sc_mib_mac.aDesired_ESS_ID[2], ic->ic_des_essid, 515 memcpy(&sc->sc_mib_mac.aDesired_ESS_ID[2], ic->ic_des_essid,
516 ic->ic_des_esslen); 516 ic->ic_des_esslen);
517 517
518 /* Configure basic rate */ 518 /* Configure basic rate */
519 if (ic->ic_phytype == IEEE80211_T_FH) 519 if (ic->ic_phytype == IEEE80211_T_FH)
520 rs = &ic->ic_sup_rates[IEEE80211_MODE_FH]; 520 rs = &ic->ic_sup_rates[IEEE80211_MODE_FH];
521 else 521 else
522 rs = &ic->ic_sup_rates[IEEE80211_MODE_11B]; 522 rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
523 if (ic->ic_fixed_rate != -1) { 523 if (ic->ic_fixed_rate != -1) {
524 rate = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 524 rate = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
525 } else { 525 } else {
526 rate = 0; 526 rate = 0;
527 for (i = 0; i < rs->rs_nrates; i++) { 527 for (i = 0; i < rs->rs_nrates; i++) {
528 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) && 528 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) &&
529 rate < (rs->rs_rates[i] & IEEE80211_RATE_VAL)) 529 rate < (rs->rs_rates[i] & IEEE80211_RATE_VAL))
530 rate = rs->rs_rates[i] & IEEE80211_RATE_VAL; 530 rate = rs->rs_rates[i] & IEEE80211_RATE_VAL;
531 } 531 }
532 } 532 }
533 rate *= 5; 533 rate *= 5;
534 LE_WRITE_2(&sc->sc_mib_mac.aStation_Basic_Rate, rate); 534 LE_WRITE_2(&sc->sc_mib_mac.aStation_Basic_Rate, rate);
535 535
536 if ((error = awi_mode_init(sc)) != 0) { 536 if ((error = awi_mode_init(sc)) != 0) {
537 DPRINTF(("awi_init: awi_mode_init failed %d\n", error)); 537 DPRINTF(("awi_init: awi_mode_init failed %d\n", error));
538 awi_stop(ifp, 1); 538 awi_stop(ifp, 1);
539 return error; 539 return error;
540 } 540 }
541 541
542 /* Start transmitter */ 542 /* Start transmitter */
543 sc->sc_txdone = sc->sc_txnext = sc->sc_txbase; 543 sc->sc_txdone = sc->sc_txnext = sc->sc_txbase;
544 awi_write_4(sc, sc->sc_txbase + AWI_TXD_START, 0); 544 awi_write_4(sc, sc->sc_txbase + AWI_TXD_START, 0);
545 awi_write_4(sc, sc->sc_txbase + AWI_TXD_NEXT, 0); 545 awi_write_4(sc, sc->sc_txbase + AWI_TXD_NEXT, 0);
546 awi_write_4(sc, sc->sc_txbase + AWI_TXD_LENGTH, 0); 546 awi_write_4(sc, sc->sc_txbase + AWI_TXD_LENGTH, 0);
547 awi_write_1(sc, sc->sc_txbase + AWI_TXD_RATE, 0); 547 awi_write_1(sc, sc->sc_txbase + AWI_TXD_RATE, 0);
548 awi_write_4(sc, sc->sc_txbase + AWI_TXD_NDA, 0); 548 awi_write_4(sc, sc->sc_txbase + AWI_TXD_NDA, 0);
549 awi_write_4(sc, sc->sc_txbase + AWI_TXD_NRA, 0); 549 awi_write_4(sc, sc->sc_txbase + AWI_TXD_NRA, 0);
550 awi_write_1(sc, sc->sc_txbase + AWI_TXD_STATE, 0); 550 awi_write_1(sc, sc->sc_txbase + AWI_TXD_STATE, 0);
551 awi_write_4(sc, AWI_CA_TX_DATA, sc->sc_txbase); 551 awi_write_4(sc, AWI_CA_TX_DATA, sc->sc_txbase);
552 awi_write_4(sc, AWI_CA_TX_MGT, 0); 552 awi_write_4(sc, AWI_CA_TX_MGT, 0);
553 awi_write_4(sc, AWI_CA_TX_BCAST, 0); 553 awi_write_4(sc, AWI_CA_TX_BCAST, 0);
554 awi_write_4(sc, AWI_CA_TX_PS, 0); 554 awi_write_4(sc, AWI_CA_TX_PS, 0);
555 awi_write_4(sc, AWI_CA_TX_CF, 0); 555 awi_write_4(sc, AWI_CA_TX_CF, 0);
556 if ((error = awi_cmd(sc, AWI_CMD_INIT_TX, AWI_WAIT)) != 0) { 556 if ((error = awi_cmd(sc, AWI_CMD_INIT_TX, AWI_WAIT)) != 0) {
557 DPRINTF(("awi_init: failed to start transmitter: %d\n", error)); 557 DPRINTF(("awi_init: failed to start transmitter: %d\n", error));
558 awi_stop(ifp, 1); 558 awi_stop(ifp, 1);
559 return error; 559 return error;
560 } 560 }
561 561
562 /* Start receiver */ 562 /* Start receiver */
563 if ((error = awi_cmd(sc, AWI_CMD_INIT_RX, AWI_WAIT)) != 0) { 563 if ((error = awi_cmd(sc, AWI_CMD_INIT_RX, AWI_WAIT)) != 0) {
564 DPRINTF(("awi_init: failed to start receiver: %d\n", error)); 564 DPRINTF(("awi_init: failed to start receiver: %d\n", error));
565 awi_stop(ifp, 1); 565 awi_stop(ifp, 1);
566 return error; 566 return error;
567 } 567 }
568 sc->sc_rxdoff = awi_read_4(sc, AWI_CA_IRX_DATA_DESC); 568 sc->sc_rxdoff = awi_read_4(sc, AWI_CA_IRX_DATA_DESC);
569 sc->sc_rxmoff = awi_read_4(sc, AWI_CA_IRX_PS_DESC); 569 sc->sc_rxmoff = awi_read_4(sc, AWI_CA_IRX_PS_DESC);
570 570
571 ifp->if_flags |= IFF_RUNNING; 571 ifp->if_flags |= IFF_RUNNING;
572 ifp->if_flags &= ~IFF_OACTIVE; 572 ifp->if_flags &= ~IFF_OACTIVE;
573 ic->ic_state = IEEE80211_S_INIT; 573 ic->ic_state = IEEE80211_S_INIT;
574 574
575 if (ic->ic_opmode == IEEE80211_M_AHDEMO || 575 if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
576 ic->ic_opmode == IEEE80211_M_HOSTAP) { 576 ic->ic_opmode == IEEE80211_M_HOSTAP) {
577 ni->ni_chan = ic->ic_ibss_chan; 577 ni->ni_chan = ic->ic_ibss_chan;
578 ni->ni_intval = ic->ic_lintval; 578 ni->ni_intval = ic->ic_lintval;
579 ni->ni_rssi = 0; 579 ni->ni_rssi = 0;
580 ni->ni_rstamp = 0; 580 ni->ni_rstamp = 0;
581 memset(&ni->ni_tstamp, 0, sizeof(ni->ni_tstamp)); 581 memset(&ni->ni_tstamp, 0, sizeof(ni->ni_tstamp));
582 ni->ni_rates = 582 ni->ni_rates =
583 ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)]; 583 ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
584 IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr); 584 IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr);
585 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 585 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
586 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr); 586 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr);
587 ni->ni_esslen = ic->ic_des_esslen; 587 ni->ni_esslen = ic->ic_des_esslen;
588 memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen); 588 memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
589 ni->ni_capinfo = IEEE80211_CAPINFO_ESS; 589 ni->ni_capinfo = IEEE80211_CAPINFO_ESS;
590 if (ic->ic_phytype == IEEE80211_T_FH) { 590 if (ic->ic_phytype == IEEE80211_T_FH) {
591 ni->ni_fhdwell = 200; /* XXX */ 591 ni->ni_fhdwell = 200; /* XXX */
592 ni->ni_fhindex = 1; 592 ni->ni_fhindex = 1;
593 } 593 }
594 } else { 594 } else {
595 ni->ni_capinfo = IEEE80211_CAPINFO_IBSS; 595 ni->ni_capinfo = IEEE80211_CAPINFO_IBSS;
596 memset(ni->ni_bssid, 0, IEEE80211_ADDR_LEN); 596 memset(ni->ni_bssid, 0, IEEE80211_ADDR_LEN);
597 ni->ni_esslen = 0; 597 ni->ni_esslen = 0;
598 } 598 }
599 if (ic->ic_flags & IEEE80211_F_PRIVACY) 599 if (ic->ic_flags & IEEE80211_F_PRIVACY)
600 ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY; 600 ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
601 if (ic->ic_opmode != IEEE80211_M_AHDEMO) 601 if (ic->ic_opmode != IEEE80211_M_AHDEMO)
602 ic->ic_flags |= IEEE80211_F_SIBSS; 602 ic->ic_flags |= IEEE80211_F_SIBSS;
603 ic->ic_state = IEEE80211_S_SCAN; /*XXX*/ 603 ic->ic_state = IEEE80211_S_SCAN; /*XXX*/
604 sc->sc_substate = AWI_ST_NONE; 604 sc->sc_substate = AWI_ST_NONE;
605 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 605 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
606 } else { 606 } else {
607 /* XXX check sc->sc_cur_chan */ 607 /* XXX check sc->sc_cur_chan */
608 ni->ni_chan = &ic->ic_channels[sc->sc_cur_chan]; 608 ni->ni_chan = &ic->ic_channels[sc->sc_cur_chan];
609 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 609 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
610 } 610 }
611 return 0; 611 return 0;
612} 612}
613 613
614static void 614static void
615awi_stop(struct ifnet *ifp, int disable) 615awi_stop(struct ifnet *ifp, int disable)
616{ 616{
617 struct awi_softc *sc = ifp->if_softc; 617 struct awi_softc *sc = ifp->if_softc;
618 618
619 if (!sc->sc_enabled) 619 if (!sc->sc_enabled)
620 return; 620 return;
621 621
622 DPRINTF(("awi_stop(%d)\n", disable)); 622 DPRINTF(("awi_stop(%d)\n", disable));
623 623
624 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1); 624 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
625 625
626 if (device_is_active(sc->sc_dev)) { 626 if (device_is_active(sc->sc_dev)) {
627 if (sc->sc_cmd_inprog) 627 if (sc->sc_cmd_inprog)
628 (void)awi_cmd_wait(sc); 628 (void)awi_cmd_wait(sc);
629 (void)awi_cmd(sc, AWI_CMD_KILL_RX, AWI_WAIT); 629 (void)awi_cmd(sc, AWI_CMD_KILL_RX, AWI_WAIT);
630 sc->sc_cmd_inprog = AWI_CMD_FLUSH_TX; 630 sc->sc_cmd_inprog = AWI_CMD_FLUSH_TX;
631 awi_write_1(sc, AWI_CA_FTX_DATA, 1); 631 awi_write_1(sc, AWI_CA_FTX_DATA, 1);
632 awi_write_1(sc, AWI_CA_FTX_MGT, 0); 632 awi_write_1(sc, AWI_CA_FTX_MGT, 0);
633 awi_write_1(sc, AWI_CA_FTX_BCAST, 0); 633 awi_write_1(sc, AWI_CA_FTX_BCAST, 0);
634 awi_write_1(sc, AWI_CA_FTX_PS, 0); 634 awi_write_1(sc, AWI_CA_FTX_PS, 0);
635 awi_write_1(sc, AWI_CA_FTX_CF, 0); 635 awi_write_1(sc, AWI_CA_FTX_CF, 0);
636 (void)awi_cmd(sc, AWI_CMD_FLUSH_TX, AWI_WAIT); 636 (void)awi_cmd(sc, AWI_CMD_FLUSH_TX, AWI_WAIT);
637 } 637 }
638 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 638 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
639 ifp->if_timer = 0; 639 ifp->if_timer = 0;
640 sc->sc_tx_timer = sc->sc_rx_timer = 0; 640 sc->sc_tx_timer = sc->sc_rx_timer = 0;
641 if (sc->sc_rxpend != NULL) { 641 if (sc->sc_rxpend != NULL) {
642 m_freem(sc->sc_rxpend); 642 m_freem(sc->sc_rxpend);
643 sc->sc_rxpend = NULL; 643 sc->sc_rxpend = NULL;
644 } 644 }
645 IFQ_PURGE(&ifp->if_snd); 645 IFQ_PURGE(&ifp->if_snd);
646 646
647 if (disable) { 647 if (disable) {
648 if (device_is_active(sc->sc_dev)) 648 if (device_is_active(sc->sc_dev))
649 am79c930_gcr_setbits(&sc->sc_chip, 649 am79c930_gcr_setbits(&sc->sc_chip,
650 AM79C930_GCR_CORESET); 650 AM79C930_GCR_CORESET);
651 if (sc->sc_disable) 651 if (sc->sc_disable)
652 (*sc->sc_disable)(sc); 652 (*sc->sc_disable)(sc);
653 sc->sc_enabled = 0; 653 sc->sc_enabled = 0;
654 } 654 }
655} 655}
656 656
657static void 657static void
658awi_start(struct ifnet *ifp) 658awi_start(struct ifnet *ifp)
659{ 659{
660 struct awi_softc *sc = ifp->if_softc; 660 struct awi_softc *sc = ifp->if_softc;
661 struct ieee80211com *ic = &sc->sc_ic; 661 struct ieee80211com *ic = &sc->sc_ic;
662 struct ether_header *eh; 662 struct ether_header *eh;
663 struct ieee80211_node *ni; 663 struct ieee80211_node *ni;
664 struct ieee80211_frame *wh; 664 struct ieee80211_frame *wh;
665 struct mbuf *m, *m0; 665 struct mbuf *m, *m0;
666 int len, dowep; 666 int len, dowep;
667 uint32_t txd, frame, ntxd; 667 uint32_t txd, frame, ntxd;
668 uint8_t rate; 668 uint8_t rate;
669 669
670 if (!sc->sc_enabled || !device_is_active(sc->sc_dev)) 670 if (!sc->sc_enabled || !device_is_active(sc->sc_dev))
671 return; 671 return;
672 672
673 for (;;) { 673 for (;;) {
674 txd = sc->sc_txnext; 674 txd = sc->sc_txnext;
675 IF_POLL(&ic->ic_mgtq, m0); 675 IF_POLL(&ic->ic_mgtq, m0);
676 dowep = 0; 676 dowep = 0;
677 if (m0 != NULL) { 677 if (m0 != NULL) {
678 len = m0->m_pkthdr.len; 678 len = m0->m_pkthdr.len;
679 if (awi_next_txd(sc, len, &frame, &ntxd)) { 679 if (awi_next_txd(sc, len, &frame, &ntxd)) {
680 ifp->if_flags |= IFF_OACTIVE; 680 ifp->if_flags |= IFF_OACTIVE;
681 break; 681 break;
682 } 682 }
683 IF_DEQUEUE(&ic->ic_mgtq, m0); 683 IF_DEQUEUE(&ic->ic_mgtq, m0);
684 ni = M_GETCTX(m0, struct ieee80211_node *); 684 ni = M_GETCTX(m0, struct ieee80211_node *);
685 } else { 685 } else {
686 if (ic->ic_state != IEEE80211_S_RUN) 686 if (ic->ic_state != IEEE80211_S_RUN)
687 break; 687 break;
688 IFQ_POLL(&ifp->if_snd, m0); 688 IFQ_POLL(&ifp->if_snd, m0);
689 if (m0 == NULL) 689 if (m0 == NULL)
690 break; 690 break;
691 /* 691 /*
692 * Need to calculate the real length to determine 692 * Need to calculate the real length to determine
693 * if the transmit buffer has a room for the packet. 693 * if the transmit buffer has a room for the packet.
694 */ 694 */
695 len = m0->m_pkthdr.len + sizeof(struct ieee80211_frame); 695 len = m0->m_pkthdr.len + sizeof(struct ieee80211_frame);
696 if (!(ifp->if_flags & IFF_LINK0) && !sc->sc_adhoc_ap) 696 if (!(ifp->if_flags & IFF_LINK0) && !sc->sc_adhoc_ap)
697 len += sizeof(struct llc) - 697 len += sizeof(struct llc) -
698 sizeof(struct ether_header); 698 sizeof(struct ether_header);
699 if (ic->ic_flags & IEEE80211_F_PRIVACY) { 699 if (ic->ic_flags & IEEE80211_F_PRIVACY) {
700 dowep = 1; 700 dowep = 1;
701 len += IEEE80211_WEP_IVLEN + 701 len += IEEE80211_WEP_IVLEN +
702 IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN; 702 IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
703 } 703 }
704 if (awi_next_txd(sc, len, &frame, &ntxd)) { 704 if (awi_next_txd(sc, len, &frame, &ntxd)) {
705 ifp->if_flags |= IFF_OACTIVE; 705 ifp->if_flags |= IFF_OACTIVE;
706 break; 706 break;
707 } 707 }
708 IFQ_DEQUEUE(&ifp->if_snd, m0); 708 IFQ_DEQUEUE(&ifp->if_snd, m0);
709 ifp->if_opackets++; 709 ifp->if_opackets++;
710 bpf_mtap(ifp, m0, BPF_D_OUT); 710 bpf_mtap(ifp, m0, BPF_D_OUT);
711 eh = mtod(m0, struct ether_header *); 711 eh = mtod(m0, struct ether_header *);
712 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 712 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
713 if (ni == NULL) { 713 if (ni == NULL) {
714 ifp->if_oerrors++; 714 ifp->if_oerrors++;
715 continue; 715 continue;
716 } 716 }
717 if ((ifp->if_flags & IFF_LINK0) || sc->sc_adhoc_ap) 717 if ((ifp->if_flags & IFF_LINK0) || sc->sc_adhoc_ap)
718 m0 = awi_ether_encap(sc, m0); 718 m0 = awi_ether_encap(sc, m0);
719 else { 719 else {
720 m0 = ieee80211_encap(ic, m0, ni); 720 m0 = ieee80211_encap(ic, m0, ni);
721 } 721 }
722 if (m0 == NULL) { 722 if (m0 == NULL) {
723 ieee80211_free_node(ni); 723 ieee80211_free_node(ni);
724 ifp->if_oerrors++; 724 ifp->if_oerrors++;
725 continue; 725 continue;
726 } 726 }
727 wh = mtod(m0, struct ieee80211_frame *); 727 wh = mtod(m0, struct ieee80211_frame *);
728 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 728 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
729 (ic->ic_opmode == IEEE80211_M_HOSTAP || 729 (ic->ic_opmode == IEEE80211_M_HOSTAP ||
730 ic->ic_opmode == IEEE80211_M_IBSS) && 730 ic->ic_opmode == IEEE80211_M_IBSS) &&
731 sc->sc_adhoc_ap == 0 && 731 sc->sc_adhoc_ap == 0 &&
732 (ifp->if_flags & IFF_LINK0) == 0 && 732 (ifp->if_flags & IFF_LINK0) == 0 &&
733 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 733 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
734 IEEE80211_FC0_TYPE_DATA) { 734 IEEE80211_FC0_TYPE_DATA) {
735 m_freem(m0); 735 m_freem(m0);
736 ieee80211_free_node(ni); 736 ieee80211_free_node(ni);
737 ifp->if_oerrors++; 737 ifp->if_oerrors++;
738 continue; 738 continue;
739 } 739 }
740 } 740 }
741 bpf_mtap3(ic->ic_rawbpf, m0, BPF_D_OUT); 741 bpf_mtap3(ic->ic_rawbpf, m0, BPF_D_OUT);
742 if (dowep) { 742 if (dowep) {
743 if ((ieee80211_crypto_encap(ic, ni, m0)) == NULL) { 743 if ((ieee80211_crypto_encap(ic, ni, m0)) == NULL) {
744 m_freem(m0); 744 m_freem(m0);
745 ieee80211_free_node(ni); 745 ieee80211_free_node(ni);
746 ifp->if_oerrors++; 746 ifp->if_oerrors++;
747 continue; 747 continue;
748 } 748 }
749 } 749 }
750 ieee80211_free_node(ni); 750 ieee80211_free_node(ni);
751#ifdef DIAGNOSTIC 751#ifdef DIAGNOSTIC
752 if (m0->m_pkthdr.len != len) { 752 if (m0->m_pkthdr.len != len) {
753 printf("%s: length %d should be %d\n", 753 printf("%s: length %d should be %d\n",
754 sc->sc_if.if_xname, m0->m_pkthdr.len, len); 754 sc->sc_if.if_xname, m0->m_pkthdr.len, len);
755 m_freem(m0); 755 m_freem(m0);
756 ifp->if_oerrors++; 756 ifp->if_oerrors++;
757 continue; 757 continue;
758 } 758 }
759#endif 759#endif
760 760
761 if ((ifp->if_flags & IFF_DEBUG) && (ifp->if_flags & IFF_LINK2)) 761 if ((ifp->if_flags & IFF_DEBUG) && (ifp->if_flags & IFF_LINK2))
762 ieee80211_dump_pkt(m0->m_data, m0->m_len, 762 ieee80211_dump_pkt(m0->m_data, m0->m_len,
763 ic->ic_bss->ni_rates. 763 ic->ic_bss->ni_rates.
764 rs_rates[ic->ic_bss->ni_txrate] & 764 rs_rates[ic->ic_bss->ni_txrate] &
765 IEEE80211_RATE_VAL, -1); 765 IEEE80211_RATE_VAL, -1);
766 766
767 for (m = m0, len = 0; m != NULL; m = m->m_next) { 767 for (m = m0, len = 0; m != NULL; m = m->m_next) {
768 awi_write_bytes(sc, frame + len, mtod(m, uint8_t *), 768 awi_write_bytes(sc, frame + len, mtod(m, uint8_t *),
769 m->m_len); 769 m->m_len);
770 len += m->m_len; 770 len += m->m_len;
771 } 771 }
772 m_freem(m0); 772 m_freem(m0);
773 rate = (ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate] & 773 rate = (ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate] &
774 IEEE80211_RATE_VAL) * 5; 774 IEEE80211_RATE_VAL) * 5;
775 awi_write_1(sc, ntxd + AWI_TXD_STATE, 0); 775 awi_write_1(sc, ntxd + AWI_TXD_STATE, 0);
776 awi_write_4(sc, txd + AWI_TXD_START, frame); 776 awi_write_4(sc, txd + AWI_TXD_START, frame);
777 awi_write_4(sc, txd + AWI_TXD_NEXT, ntxd); 777 awi_write_4(sc, txd + AWI_TXD_NEXT, ntxd);
778 awi_write_4(sc, txd + AWI_TXD_LENGTH, len); 778 awi_write_4(sc, txd + AWI_TXD_LENGTH, len);
779 awi_write_1(sc, txd + AWI_TXD_RATE, rate); 779 awi_write_1(sc, txd + AWI_TXD_RATE, rate);
780 awi_write_4(sc, txd + AWI_TXD_NDA, 0); 780 awi_write_4(sc, txd + AWI_TXD_NDA, 0);
781 awi_write_4(sc, txd + AWI_TXD_NRA, 0); 781 awi_write_4(sc, txd + AWI_TXD_NRA, 0);
782 awi_write_1(sc, txd + AWI_TXD_STATE, AWI_TXD_ST_OWN); 782 awi_write_1(sc, txd + AWI_TXD_STATE, AWI_TXD_ST_OWN);
783 sc->sc_txnext = ntxd; 783 sc->sc_txnext = ntxd;
784 784
785 sc->sc_tx_timer = 5; 785 sc->sc_tx_timer = 5;
786 ifp->if_timer = 1; 786 ifp->if_timer = 1;
787 } 787 }
788} 788}
789 789
790static void 790static void
791awi_watchdog(struct ifnet *ifp) 791awi_watchdog(struct ifnet *ifp)
792{ 792{
793 struct awi_softc *sc = ifp->if_softc; 793 struct awi_softc *sc = ifp->if_softc;
794 uint32_t prevdone; 794 uint32_t prevdone;
795 int ocansleep; 795 int ocansleep;
796 796
797 ifp->if_timer = 0; 797 ifp->if_timer = 0;
798 if (!sc->sc_enabled || !device_is_active(sc->sc_dev)) 798 if (!sc->sc_enabled || !device_is_active(sc->sc_dev))
799 return; 799 return;
800 800
801 ocansleep = sc->sc_cansleep; 801 ocansleep = sc->sc_cansleep;
802 sc->sc_cansleep = 0; 802 sc->sc_cansleep = 0;
803 if (sc->sc_tx_timer) { 803 if (sc->sc_tx_timer) {
804 if (--sc->sc_tx_timer == 0) { 804 if (--sc->sc_tx_timer == 0) {
805 printf("%s: device timeout\n", ifp->if_xname); 805 printf("%s: device timeout\n", ifp->if_xname);
806 prevdone = sc->sc_txdone; 806 prevdone = sc->sc_txdone;
807 awi_tx_int(sc); 807 awi_tx_int(sc);
808 if (sc->sc_txdone == prevdone) { 808 if (sc->sc_txdone == prevdone) {
809 ifp->if_oerrors++; 809 ifp->if_oerrors++;
810 awi_init(ifp); 810 awi_init(ifp);
811 goto out; 811 goto out;
812 } 812 }
813 } 813 }
814 ifp->if_timer = 1; 814 ifp->if_timer = 1;
815 } 815 }
816 if (sc->sc_rx_timer) { 816 if (sc->sc_rx_timer) {
817 if (--sc->sc_rx_timer == 0) { 817 if (--sc->sc_rx_timer == 0) {
818 if (sc->sc_ic.ic_state == IEEE80211_S_RUN) { 818 if (sc->sc_ic.ic_state == IEEE80211_S_RUN) {
819 ieee80211_new_state(&sc->sc_ic, 819 ieee80211_new_state(&sc->sc_ic,
820 IEEE80211_S_SCAN, -1); 820 IEEE80211_S_SCAN, -1);
821 goto out; 821 goto out;
822 } 822 }
823 } else 823 } else
824 ifp->if_timer = 1; 824 ifp->if_timer = 1;
825 } 825 }
826 /* TODO: rate control */ 826 /* TODO: rate control */
827 ieee80211_watchdog(&sc->sc_ic); 827 ieee80211_watchdog(&sc->sc_ic);
828 out: 828 out:
829 sc->sc_cansleep = ocansleep; 829 sc->sc_cansleep = ocansleep;
830} 830}
831 831
832static int 832static int
833awi_ioctl(struct ifnet *ifp, u_long cmd, void *data) 833awi_ioctl(struct ifnet *ifp, u_long cmd, void *data)
834{ 834{
835 struct awi_softc *sc = ifp->if_softc; 835 struct awi_softc *sc = ifp->if_softc;
836 struct ifreq *ifr = (struct ifreq *)data; 
837 int s, error; 836 int s, error;
838 837
839 s = splnet(); 838 s = splnet();
840 /* Serialize ioctl, since we may sleep */ 839 /* Serialize ioctl, since we may sleep */
841 if ((error = awi_lock(sc)) != 0) 840 if ((error = awi_lock(sc)) != 0)
842 goto cantlock; 841 goto cantlock;
843 842
844 switch (cmd) { 843 switch (cmd) {
845 case SIOCSIFFLAGS: 844 case SIOCSIFFLAGS:
846 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 845 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
847 break; 846 break;
848 if (ifp->if_flags & IFF_UP) { 847 if (ifp->if_flags & IFF_UP) {
849 if (sc->sc_enabled) { 848 if (sc->sc_enabled) {
850 /* 849 /*
851 * To avoid rescanning another access point, 850 * To avoid rescanning another access point,
852 * do not call awi_init() here. Instead, 851 * do not call awi_init() here. Instead,
853 * only reflect promisc mode settings. 852 * only reflect promisc mode settings.
854 */ 853 */
855 error = awi_mode_init(sc); 854 error = awi_mode_init(sc);
856 } else 855 } else
857 error = awi_init(ifp); 856 error = awi_init(ifp);
858 } else if (sc->sc_enabled) 857 } else if (sc->sc_enabled)
859 awi_stop(ifp, 1); 858 awi_stop(ifp, 1);
860 break; 859 break;
861 case SIOCSIFMEDIA: 
862 case SIOCGIFMEDIA: 
863 error = ifmedia_ioctl(ifp, ifr, &sc->sc_ic.ic_media, cmd); 
864 break; 
865 case SIOCADDMULTI: 860 case SIOCADDMULTI:
866 case SIOCDELMULTI: 861 case SIOCDELMULTI:
867 error = ether_ioctl(ifp, cmd, data); 862 error = ether_ioctl(ifp, cmd, data);
868 if (error == ENETRESET) { 863 if (error == ENETRESET) {
869 /* Do not rescan */ 864 /* Do not rescan */
870 if (ifp->if_flags & IFF_RUNNING) 865 if (ifp->if_flags & IFF_RUNNING)
871 error = awi_mode_init(sc); 866 error = awi_mode_init(sc);
872 else 867 else
873 error = 0; 868 error = 0;
874 } 869 }
875 break; 870 break;
876 default: 871 default:
877 error = ieee80211_ioctl(&sc->sc_ic, cmd, data); 872 error = ieee80211_ioctl(&sc->sc_ic, cmd, data);
878 if (error == ENETRESET) { 873 if (error == ENETRESET) {
879 if (sc->sc_enabled) 874 if (sc->sc_enabled)
880 error = awi_init(ifp); 875 error = awi_init(ifp);
881 else 876 else
882 error = 0; 877 error = 0;
883 } 878 }
884 break; 879 break;
885 } 880 }
886 awi_unlock(sc); 881 awi_unlock(sc);
887 cantlock: 882 cantlock:
888 splx(s); 883 splx(s);
889 return error; 884 return error;
890} 885}
891 886
892/* 887/*
893 * Called from ifmedia_ioctl via awi_ioctl with lock obtained. 888 * Called from ifmedia_ioctl via awi_ioctl with lock obtained.
894 * 889 *
895 * TBD factor with ieee80211_media_change 890 * TBD factor with ieee80211_media_change
896 */ 891 */
897static int 892static int
898awi_media_change(struct ifnet *ifp) 893awi_media_change(struct ifnet *ifp)
899{ 894{
900 struct awi_softc *sc = ifp->if_softc; 895 struct awi_softc *sc = ifp->if_softc;
901 struct ieee80211com *ic = &sc->sc_ic; 896 struct ieee80211com *ic = &sc->sc_ic;
902 struct ifmedia_entry *ime; 897 struct ifmedia_entry *ime;
903 enum ieee80211_opmode newmode; 898 enum ieee80211_opmode newmode;
904 int i, rate, newadhoc_ap, error = 0; 899 int i, rate, newadhoc_ap, error = 0;
905 900
906 ime = ic->ic_media.ifm_cur; 901 ime = ic->ic_media.ifm_cur;
907 if (IFM_SUBTYPE(ime->ifm_media) == IFM_AUTO) { 902 if (IFM_SUBTYPE(ime->ifm_media) == IFM_AUTO) {
908 i = -1; 903 i = -1;
909 } else { 904 } else {
910 struct ieee80211_rateset *rs = 905 struct ieee80211_rateset *rs =
911 &ic->ic_sup_rates[(ic->ic_phytype == IEEE80211_T_FH) 906 &ic->ic_sup_rates[(ic->ic_phytype == IEEE80211_T_FH)
912 ? IEEE80211_MODE_FH : IEEE80211_MODE_11B]; 907 ? IEEE80211_MODE_FH : IEEE80211_MODE_11B];
913 rate = ieee80211_media2rate(ime->ifm_media); 908 rate = ieee80211_media2rate(ime->ifm_media);
914 if (rate == 0) 909 if (rate == 0)
915 return EINVAL; 910 return EINVAL;
916 for (i = 0; i < rs->rs_nrates; i++) { 911 for (i = 0; i < rs->rs_nrates; i++) {
917 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate) 912 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate)
918 break; 913 break;
919 } 914 }
920 if (i == rs->rs_nrates) 915 if (i == rs->rs_nrates)
921 return EINVAL; 916 return EINVAL;
922 } 917 }
923 if (ic->ic_fixed_rate != i) { 918 if (ic->ic_fixed_rate != i) {
924 ic->ic_fixed_rate = i; 919 ic->ic_fixed_rate = i;
925 error = ENETRESET; 920 error = ENETRESET;
926 } 921 }
927 922
928 /* 923 /*
929 * Combination of mediaopt 924 * Combination of mediaopt
930 * 925 *
931 * hostap adhoc flag0 opmode adhoc_ap comment 926 * hostap adhoc flag0 opmode adhoc_ap comment
932 * + - - HOSTAP 0 HostAP 927 * + - - HOSTAP 0 HostAP
933 * - + - IBSS 0 IBSS 928 * - + - IBSS 0 IBSS
934 * - + + AHDEMO 0 WaveLAN adhoc 929 * - + + AHDEMO 0 WaveLAN adhoc
935 * - - + IBSS 1 Melco old Sta 930 * - - + IBSS 1 Melco old Sta
936 * also LINK0 931 * also LINK0
937 * - - - STA 0 Infra Station 932 * - - - STA 0 Infra Station
938 */ 933 */
939 newadhoc_ap = 0; 934 newadhoc_ap = 0;
940 if (ime->ifm_media & IFM_IEEE80211_HOSTAP) 935 if (ime->ifm_media & IFM_IEEE80211_HOSTAP)
941 newmode = IEEE80211_M_HOSTAP; 936 newmode = IEEE80211_M_HOSTAP;
942 else if (ime->ifm_media & IFM_IEEE80211_ADHOC) { 937 else if (ime->ifm_media & IFM_IEEE80211_ADHOC) {
943 if (ic->ic_phytype == IEEE80211_T_DS && 938 if (ic->ic_phytype == IEEE80211_T_DS &&
944 (ime->ifm_media & IFM_FLAG0)) 939 (ime->ifm_media & IFM_FLAG0))
945 newmode = IEEE80211_M_AHDEMO; 940 newmode = IEEE80211_M_AHDEMO;
946 else 941 else
947 newmode = IEEE80211_M_IBSS; 942 newmode = IEEE80211_M_IBSS;
948 } else if (ime->ifm_media & IFM_FLAG0) { 943 } else if (ime->ifm_media & IFM_FLAG0) {
949 newmode = IEEE80211_M_IBSS; 944 newmode = IEEE80211_M_IBSS;
950 newadhoc_ap = 1; 945 newadhoc_ap = 1;
951 } else 946 } else
952 newmode = IEEE80211_M_STA; 947 newmode = IEEE80211_M_STA;
953 if (ic->ic_opmode != newmode || sc->sc_adhoc_ap != newadhoc_ap) { 948 if (ic->ic_opmode != newmode || sc->sc_adhoc_ap != newadhoc_ap) {
954 ic->ic_opmode = newmode; 949 ic->ic_opmode = newmode;
955 sc->sc_adhoc_ap = newadhoc_ap; 950 sc->sc_adhoc_ap = newadhoc_ap;
956 error = ENETRESET; 951 error = ENETRESET;
957 } 952 }
958 953
959 if (error == ENETRESET) { 954 if (error == ENETRESET) {
960 if (sc->sc_enabled) 955 if (sc->sc_enabled)
961 error = awi_init(ifp); 956 error = awi_init(ifp);
962 else 957 else
963 error = 0; 958 error = 0;
964 } 959 }
965 return error; 960 return error;
966} 961}
967 962
968static void 963static void
969awi_media_status(struct ifnet *ifp, struct ifmediareq *imr) 964awi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
970{ 965{
971 struct awi_softc *sc = ifp->if_softc; 966 struct awi_softc *sc = ifp->if_softc;
972 struct ieee80211com *ic = &sc->sc_ic; 967 struct ieee80211com *ic = &sc->sc_ic;
973 int rate; 968 int rate;
974 enum ieee80211_phymode mode; 969 enum ieee80211_phymode mode;
975 970
976 imr->ifm_status = IFM_AVALID; 971 imr->ifm_status = IFM_AVALID;
977 if (ic->ic_state == IEEE80211_S_RUN) 972 if (ic->ic_state == IEEE80211_S_RUN)
978 imr->ifm_status |= IFM_ACTIVE; 973 imr->ifm_status |= IFM_ACTIVE;
979 imr->ifm_active = IFM_IEEE80211; 974 imr->ifm_active = IFM_IEEE80211;
980 if (ic->ic_phytype == IEEE80211_T_FH) 975 if (ic->ic_phytype == IEEE80211_T_FH)
981 mode = IEEE80211_MODE_FH; 976 mode = IEEE80211_MODE_FH;
982 else 977 else
983 mode = IEEE80211_MODE_11B; 978 mode = IEEE80211_MODE_11B;
984 if (ic->ic_state == IEEE80211_S_RUN) { 979 if (ic->ic_state == IEEE80211_S_RUN) {
985 rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate] & 980 rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate] &
986 IEEE80211_RATE_VAL; 981 IEEE80211_RATE_VAL;
987 } else { 982 } else {
988 if (ic->ic_fixed_rate == -1) 983 if (ic->ic_fixed_rate == -1)
989 rate = 0; 984 rate = 0;
990 else 985 else
991 rate = ic->ic_sup_rates[mode]. 986 rate = ic->ic_sup_rates[mode].
992 rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 987 rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
993 } 988 }
994 imr->ifm_active |= ieee80211_rate2media(ic, rate, mode); 989 imr->ifm_active |= ieee80211_rate2media(ic, rate, mode);
995 switch (ic->ic_opmode) { 990 switch (ic->ic_opmode) {
996 case IEEE80211_M_MONITOR: /* We should never reach here */ 991 case IEEE80211_M_MONITOR: /* We should never reach here */
997 break; 992 break;
998 case IEEE80211_M_STA: 993 case IEEE80211_M_STA:
999 break; 994 break;
1000 case IEEE80211_M_IBSS: 995 case IEEE80211_M_IBSS:
1001 if (sc->sc_adhoc_ap) 996 if (sc->sc_adhoc_ap)
1002 imr->ifm_active |= IFM_FLAG0; 997 imr->ifm_active |= IFM_FLAG0;
1003 else 998 else
1004 imr->ifm_active |= IFM_IEEE80211_ADHOC; 999 imr->ifm_active |= IFM_IEEE80211_ADHOC;
1005 break; 1000 break;
1006 case IEEE80211_M_AHDEMO: 1001 case IEEE80211_M_AHDEMO:
1007 imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0; 1002 imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0;
1008 break; 1003 break;
1009 case IEEE80211_M_HOSTAP: 1004 case IEEE80211_M_HOSTAP:
1010 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 1005 imr->ifm_active |= IFM_IEEE80211_HOSTAP;
1011 break; 1006 break;
1012 } 1007 }
1013} 1008}
1014 1009
1015static int 1010static int
1016awi_mode_init(struct awi_softc *sc) 1011awi_mode_init(struct awi_softc *sc)
1017{ 1012{
1018 struct ethercom *ec = &sc->sc_ec; 1013 struct ethercom *ec = &sc->sc_ec;
1019 struct ifnet *ifp = &sc->sc_if; 1014 struct ifnet *ifp = &sc->sc_if;
1020 int n, error; 1015 int n, error;
1021 struct ether_multi *enm; 1016 struct ether_multi *enm;
1022 struct ether_multistep step; 1017 struct ether_multistep step;
1023 1018
1024 /* Reinitialize muticast filter */ 1019 /* Reinitialize muticast filter */
1025 n = 0; 1020 n = 0;
1026 sc->sc_mib_local.Accept_All_Multicast_Dis = 0; 1021 sc->sc_mib_local.Accept_All_Multicast_Dis = 0;
1027 if (sc->sc_ic.ic_opmode != IEEE80211_M_HOSTAP && 1022 if (sc->sc_ic.ic_opmode != IEEE80211_M_HOSTAP &&
1028 (ifp->if_flags & IFF_PROMISC)) { 1023 (ifp->if_flags & IFF_PROMISC)) {
1029 sc->sc_mib_mac.aPromiscuous_Enable = 1; 1024 sc->sc_mib_mac.aPromiscuous_Enable = 1;
1030 goto set_mib; 1025 goto set_mib;
1031 } 1026 }
1032 sc->sc_mib_mac.aPromiscuous_Enable = 0; 1027 sc->sc_mib_mac.aPromiscuous_Enable = 0;
1033 ETHER_LOCK(ec); 1028 ETHER_LOCK(ec);
1034 ETHER_FIRST_MULTI(step, ec, enm); 1029 ETHER_FIRST_MULTI(step, ec, enm);
1035 while (enm != NULL) { 1030 while (enm != NULL) {
1036 if (n == AWI_GROUP_ADDR_SIZE || 1031 if (n == AWI_GROUP_ADDR_SIZE ||
1037 !IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi)) { 1032 !IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi)) {
1038 ETHER_UNLOCK(ec); 1033 ETHER_UNLOCK(ec);
1039 goto set_mib; 1034 goto set_mib;
1040 } 1035 }
1041 IEEE80211_ADDR_COPY(sc->sc_mib_addr.aGroup_Addresses[n], 1036 IEEE80211_ADDR_COPY(sc->sc_mib_addr.aGroup_Addresses[n],
1042 enm->enm_addrlo); 1037 enm->enm_addrlo);
1043 n++; 1038 n++;
1044 ETHER_NEXT_MULTI(step, enm); 1039 ETHER_NEXT_MULTI(step, enm);
1045 } 1040 }
1046 ETHER_UNLOCK(ec); 1041 ETHER_UNLOCK(ec);
1047 for (; n < AWI_GROUP_ADDR_SIZE; n++) 1042 for (; n < AWI_GROUP_ADDR_SIZE; n++)
1048 memset(sc->sc_mib_addr.aGroup_Addresses[n], 0, 1043 memset(sc->sc_mib_addr.aGroup_Addresses[n], 0,
1049 IEEE80211_ADDR_LEN); 1044 IEEE80211_ADDR_LEN);
1050 sc->sc_mib_local.Accept_All_Multicast_Dis = 1; 1045 sc->sc_mib_local.Accept_All_Multicast_Dis = 1;
1051 1046
1052 set_mib: 1047 set_mib:
1053 if (sc->sc_mib_local.Accept_All_Multicast_Dis) 1048 if (sc->sc_mib_local.Accept_All_Multicast_Dis)
1054 ifp->if_flags &= ~IFF_ALLMULTI; 1049 ifp->if_flags &= ~IFF_ALLMULTI;
1055 else 1050 else
1056 ifp->if_flags |= IFF_ALLMULTI; 1051 ifp->if_flags |= IFF_ALLMULTI;
1057 sc->sc_mib_mgt.Wep_Required = 1052 sc->sc_mib_mgt.Wep_Required =
1058 (sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) ? AWI_WEP_ON : AWI_WEP_OFF; 1053 (sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) ? AWI_WEP_ON : AWI_WEP_OFF;
1059 1054
1060 if ((error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_LOCAL, AWI_WAIT)) || 1055 if ((error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_LOCAL, AWI_WAIT)) ||
1061 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_ADDR, AWI_WAIT)) || 1056 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_ADDR, AWI_WAIT)) ||
1062 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MAC, AWI_WAIT)) || 1057 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MAC, AWI_WAIT)) ||
1063 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MGT, AWI_WAIT)) || 1058 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MGT, AWI_WAIT)) ||
1064 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_PHY, AWI_WAIT))) { 1059 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_PHY, AWI_WAIT))) {
1065 DPRINTF(("awi_mode_init: MIB set failed: %d\n", error)); 1060 DPRINTF(("awi_mode_init: MIB set failed: %d\n", error));
1066 return error; 1061 return error;
1067 } 1062 }
1068 return 0; 1063 return 0;
1069} 1064}
1070 1065
1071static void 1066static void
1072awi_rx_int(struct awi_softc *sc) 1067awi_rx_int(struct awi_softc *sc)
1073{ 1068{
1074 struct ieee80211com *ic = &sc->sc_ic; 1069 struct ieee80211com *ic = &sc->sc_ic;
1075 struct ifnet *ifp = &sc->sc_if; 1070 struct ifnet *ifp = &sc->sc_if;
1076 struct ieee80211_frame_min *wh; 1071 struct ieee80211_frame_min *wh;
1077 struct ieee80211_node *ni; 1072 struct ieee80211_node *ni;
1078 uint8_t state, rate, rssi; 1073 uint8_t state, rate, rssi;
1079 uint16_t len; 1074 uint16_t len;
1080 uint32_t frame, next, rstamp, rxoff; 1075 uint32_t frame, next, rstamp, rxoff;
1081 struct mbuf *m; 1076 struct mbuf *m;
1082 1077
1083 rxoff = sc->sc_rxdoff; 1078 rxoff = sc->sc_rxdoff;
1084 for (;;) { 1079 for (;;) {
1085 state = awi_read_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE); 1080 state = awi_read_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE);
1086 if (state & AWI_RXD_ST_OWN) 1081 if (state & AWI_RXD_ST_OWN)
1087 break; 1082 break;
1088 if (!(state & AWI_RXD_ST_CONSUMED)) { 1083 if (!(state & AWI_RXD_ST_CONSUMED)) {
1089 if (sc->sc_substate != AWI_ST_NONE) 1084 if (sc->sc_substate != AWI_ST_NONE)
1090 goto rx_next; 1085 goto rx_next;
1091 if (state & AWI_RXD_ST_RXERROR) { 1086 if (state & AWI_RXD_ST_RXERROR) {
1092 ifp->if_ierrors++; 1087 ifp->if_ierrors++;
1093 goto rx_next; 1088 goto rx_next;
1094 } 1089 }
1095 len = awi_read_2(sc, rxoff + AWI_RXD_LEN); 1090 len = awi_read_2(sc, rxoff + AWI_RXD_LEN);
1096 rate = awi_read_1(sc, rxoff + AWI_RXD_RATE); 1091 rate = awi_read_1(sc, rxoff + AWI_RXD_RATE);
1097 rssi = awi_read_1(sc, rxoff + AWI_RXD_RSSI); 1092 rssi = awi_read_1(sc, rxoff + AWI_RXD_RSSI);
1098 frame = awi_read_4(sc, rxoff + AWI_RXD_START_FRAME) & 1093 frame = awi_read_4(sc, rxoff + AWI_RXD_START_FRAME) &
1099 0x7fff; 1094 0x7fff;
1100 rstamp = awi_read_4(sc, rxoff + AWI_RXD_LOCALTIME); 1095 rstamp = awi_read_4(sc, rxoff + AWI_RXD_LOCALTIME);
1101 m = awi_devget(sc, frame, len); 1096 m = awi_devget(sc, frame, len);
1102 if (m == NULL) { 1097 if (m == NULL) {
1103 ifp->if_ierrors++; 1098 ifp->if_ierrors++;
1104 goto rx_next; 1099 goto rx_next;
1105 } 1100 }
1106 if (state & AWI_RXD_ST_LF) { 1101 if (state & AWI_RXD_ST_LF) {
1107 /* TODO check my bss */ 1102 /* TODO check my bss */
1108 if (!(sc->sc_ic.ic_flags & IEEE80211_F_SIBSS) && 1103 if (!(sc->sc_ic.ic_flags & IEEE80211_F_SIBSS) &&
1109 sc->sc_ic.ic_state == IEEE80211_S_RUN) { 1104 sc->sc_ic.ic_state == IEEE80211_S_RUN) {
1110 sc->sc_rx_timer = 10; 1105 sc->sc_rx_timer = 10;
1111 ifp->if_timer = 1; 1106 ifp->if_timer = 1;
1112 } 1107 }
1113 if ((ifp->if_flags & IFF_DEBUG) && 1108 if ((ifp->if_flags & IFF_DEBUG) &&
1114 (ifp->if_flags & IFF_LINK2)) 1109 (ifp->if_flags & IFF_LINK2))
1115 ieee80211_dump_pkt(m->m_data, m->m_len, 1110 ieee80211_dump_pkt(m->m_data, m->m_len,
1116 rate / 5, rssi); 1111 rate / 5, rssi);
1117 if ((ifp->if_flags & IFF_LINK0) || 1112 if ((ifp->if_flags & IFF_LINK0) ||
1118 sc->sc_adhoc_ap) 1113 sc->sc_adhoc_ap)
1119 m = awi_ether_modcap(sc, m); 1114 m = awi_ether_modcap(sc, m);
1120 else 1115 else
1121 m = m_pullup(m, sizeof(*wh)); 1116 m = m_pullup(m, sizeof(*wh));
1122 if (m == NULL) { 1117 if (m == NULL) {
1123 ifp->if_ierrors++; 1118 ifp->if_ierrors++;
1124 goto rx_next; 1119 goto rx_next;
1125 } 1120 }
1126 wh = mtod(m, struct ieee80211_frame_min *); 1121 wh = mtod(m, struct ieee80211_frame_min *);
1127 ni = ieee80211_find_rxnode(ic, wh); 1122 ni = ieee80211_find_rxnode(ic, wh);
1128 ieee80211_input(ic, m, ni, rssi, rstamp); 1123 ieee80211_input(ic, m, ni, rssi, rstamp);
1129 /* 1124 /*
1130 * The frame may have caused the 1125 * The frame may have caused the
1131 * node to be marked for reclamation 1126 * node to be marked for reclamation
1132 * (e.g. in response to a DEAUTH 1127 * (e.g. in response to a DEAUTH
1133 * message) so use release_node here 1128 * message) so use release_node here
1134 * instead of unref_node. 1129 * instead of unref_node.
1135 */ 1130 */
1136 ieee80211_free_node(ni); 1131 ieee80211_free_node(ni);
1137 } else 1132 } else
1138 sc->sc_rxpend = m; 1133 sc->sc_rxpend = m;
1139 rx_next: 1134 rx_next:
1140 state |= AWI_RXD_ST_CONSUMED; 1135 state |= AWI_RXD_ST_CONSUMED;
1141 awi_write_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE, state); 1136 awi_write_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE, state);
1142 } 1137 }
1143 next = awi_read_4(sc, rxoff + AWI_RXD_NEXT); 1138 next = awi_read_4(sc, rxoff + AWI_RXD_NEXT);
1144 if (next & AWI_RXD_NEXT_LAST) 1139 if (next & AWI_RXD_NEXT_LAST)
1145 break; 1140 break;
1146 /* Make sure the next pointer is correct */ 1141 /* Make sure the next pointer is correct */
1147 if (next != awi_read_4(sc, rxoff + AWI_RXD_NEXT)) 1142 if (next != awi_read_4(sc, rxoff + AWI_RXD_NEXT))
1148 break; 1143 break;
1149 state |= AWI_RXD_ST_OWN; 1144 state |= AWI_RXD_ST_OWN;
1150 awi_write_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE, state); 1145 awi_write_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE, state);
1151 rxoff = next & 0x7fff; 1146 rxoff = next & 0x7fff;
1152 } 1147 }
1153 sc->sc_rxdoff = rxoff; 1148 sc->sc_rxdoff = rxoff;
1154} 1149}
1155 1150
1156static void 1151static void
1157awi_tx_int(struct awi_softc *sc) 1152awi_tx_int(struct awi_softc *sc)
1158{ 1153{
1159 struct ifnet *ifp = &sc->sc_if; 1154 struct ifnet *ifp = &sc->sc_if;
1160 uint8_t flags; 1155 uint8_t flags;
1161 1156
1162 while (sc->sc_txdone != sc->sc_txnext) { 1157 while (sc->sc_txdone != sc->sc_txnext) {
1163 flags = awi_read_1(sc, sc->sc_txdone + AWI_TXD_STATE); 1158 flags = awi_read_1(sc, sc->sc_txdone + AWI_TXD_STATE);
1164 if ((flags & AWI_TXD_ST_OWN) || !(flags & AWI_TXD_ST_DONE)) 1159 if ((flags & AWI_TXD_ST_OWN) || !(flags & AWI_TXD_ST_DONE))
1165 break; 1160 break;
1166 if (flags & AWI_TXD_ST_ERROR) 1161 if (flags & AWI_TXD_ST_ERROR)
1167 ifp->if_oerrors++; 1162 ifp->if_oerrors++;
1168 sc->sc_txdone = awi_read_4(sc, sc->sc_txdone + AWI_TXD_NEXT) & 1163 sc->sc_txdone = awi_read_4(sc, sc->sc_txdone + AWI_TXD_NEXT) &
1169 0x7fff; 1164 0x7fff;
1170 } 1165 }
1171 DPRINTF2(("awi_txint: txdone %d txnext %d txbase %d txend %d\n", 1166 DPRINTF2(("awi_txint: txdone %d txnext %d txbase %d txend %d\n",
1172 sc->sc_txdone, sc->sc_txnext, sc->sc_txbase, sc->sc_txend)); 1167 sc->sc_txdone, sc->sc_txnext, sc->sc_txbase, sc->sc_txend));
1173 sc->sc_tx_timer = 0; 1168 sc->sc_tx_timer = 0;
1174 ifp->if_flags &= ~IFF_OACTIVE; 1169 ifp->if_flags &= ~IFF_OACTIVE;
1175 awi_start(ifp); /* in softint */ 1170 awi_start(ifp); /* in softint */
1176} 1171}
1177 1172
1178static struct mbuf * 1173static struct mbuf *
1179awi_devget(struct awi_softc *sc, uint32_t off, uint16_t len) 1174awi_devget(struct awi_softc *sc, uint32_t off, uint16_t len)
1180{ 1175{
1181 struct ifnet *ifp = &sc->sc_if; 1176 struct ifnet *ifp = &sc->sc_if;
1182 struct mbuf *m; 1177 struct mbuf *m;
1183 struct mbuf *top, **mp; 1178 struct mbuf *top, **mp;
1184 u_int tlen; 1179 u_int tlen;
1185 1180
1186 top = sc->sc_rxpend; 1181 top = sc->sc_rxpend;
1187 mp = &top; 1182 mp = &top;
1188 if (top != NULL) { 1183 if (top != NULL) {
1189 sc->sc_rxpend = NULL; 1184 sc->sc_rxpend = NULL;
1190 top->m_pkthdr.len += len; 1185 top->m_pkthdr.len += len;
1191 m = top; 1186 m = top;
1192 while (*mp != NULL) { 1187 while (*mp != NULL) {
1193 m = *mp; 1188 m = *mp;
1194 mp = &m->m_next; 1189 mp = &m->m_next;
1195 } 1190 }
1196 if (m->m_flags & M_EXT) 1191 if (m->m_flags & M_EXT)
1197 tlen = m->m_ext.ext_size; 1192 tlen = m->m_ext.ext_size;
1198 else if (m->m_flags & M_PKTHDR) 1193 else if (m->m_flags & M_PKTHDR)
1199 tlen = MHLEN; 1194 tlen = MHLEN;
1200 else 1195 else
1201 tlen = MLEN; 1196 tlen = MLEN;
1202 tlen -= m->m_len; 1197 tlen -= m->m_len;
1203 if (tlen > len) 1198 if (tlen > len)
1204 tlen = len; 1199 tlen = len;
1205 awi_read_bytes(sc, off, mtod(m, uint8_t *) + m->m_len, tlen); 1200 awi_read_bytes(sc, off, mtod(m, uint8_t *) + m->m_len, tlen);
1206 off += tlen; 1201 off += tlen;
1207 len -= tlen; 1202 len -= tlen;
1208 } 1203 }
1209 1204
1210 while (len > 0) { 1205 while (len > 0) {
1211 if (top == NULL) { 1206 if (top == NULL) {
1212 MGETHDR(m, M_DONTWAIT, MT_DATA); 1207 MGETHDR(m, M_DONTWAIT, MT_DATA);
1213 if (m == NULL) 1208 if (m == NULL)
1214 return NULL; 1209 return NULL;
1215 m_set_rcvif(m, ifp); 1210 m_set_rcvif(m, ifp);
1216 m->m_pkthdr.len = len; 1211 m->m_pkthdr.len = len;
1217 m->m_len = MHLEN; 1212 m->m_len = MHLEN;
1218 m->m_flags |= M_HASFCS; 1213 m->m_flags |= M_HASFCS;
1219 } else { 1214 } else {
1220 MGET(m, M_DONTWAIT, MT_DATA); 1215 MGET(m, M_DONTWAIT, MT_DATA);
1221 if (m == NULL) { 1216 if (m == NULL) {
1222 m_freem(top); 1217 m_freem(top);
1223 return NULL; 1218 return NULL;
1224 } 1219 }
1225 m->m_len = MLEN; 1220 m->m_len = MLEN;
1226 } 1221 }
1227 if (len >= MINCLSIZE) { 1222 if (len >= MINCLSIZE) {
1228 MCLGET(m, M_DONTWAIT); 1223 MCLGET(m, M_DONTWAIT);
1229 if (m->m_flags & M_EXT) 1224 if (m->m_flags & M_EXT)
1230 m->m_len = m->m_ext.ext_size; 1225 m->m_len = m->m_ext.ext_size;
1231 } 1226 }
1232 if (top == NULL) { 1227 if (top == NULL) {
1233 int hdrlen = sizeof(struct ieee80211_frame) + 1228 int hdrlen = sizeof(struct ieee80211_frame) +
1234 sizeof(struct llc); 1229 sizeof(struct llc);
1235 char *newdata = (char *) 1230 char *newdata = (char *)
1236 ALIGN(m->m_data + hdrlen) - hdrlen; 1231 ALIGN(m->m_data + hdrlen) - hdrlen;
1237 m->m_len -= newdata - m->m_data; 1232 m->m_len -= newdata - m->m_data;
1238 m->m_data = newdata; 1233 m->m_data = newdata;
1239 } 1234 }
1240 if (m->m_len > len) 1235 if (m->m_len > len)
1241 m->m_len = len; 1236 m->m_len = len;
1242 awi_read_bytes(sc, off, mtod(m, uint8_t *), m->m_len); 1237 awi_read_bytes(sc, off, mtod(m, uint8_t *), m->m_len);
1243 off += m->m_len; 1238 off += m->m_len;
1244 len -= m->m_len; 1239 len -= m->m_len;
1245 *mp = m; 1240 *mp = m;
1246 mp = &m->m_next; 1241 mp = &m->m_next;
1247 } 1242 }
1248 return top; 1243 return top;
1249} 1244}
1250 1245
1251/* 1246/*
1252 * Initialize hardware and start firmware to accept commands. 1247 * Initialize hardware and start firmware to accept commands.
1253 * Called everytime after power on firmware. 1248 * Called everytime after power on firmware.
1254 */ 1249 */
1255 1250
1256static int 1251static int
1257awi_hw_init(struct awi_softc *sc) 1252awi_hw_init(struct awi_softc *sc)
1258{ 1253{
1259 uint8_t status; 1254 uint8_t status;
1260 uint16_t intmask; 1255 uint16_t intmask;
1261 int i, error; 1256 int i, error;
1262 1257
1263 sc->sc_enab_intr = 0; 1258 sc->sc_enab_intr = 0;
1264 awi_drvstate(sc, AWI_DRV_RESET); 1259 awi_drvstate(sc, AWI_DRV_RESET);
1265 1260
1266 /* Reset firmware */ 1261 /* Reset firmware */
1267 am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_CORESET); 1262 am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_CORESET);
1268 DELAY(100); 1263 DELAY(100);
1269 awi_write_1(sc, AWI_SELFTEST, 0); 1264 awi_write_1(sc, AWI_SELFTEST, 0);
1270 awi_write_1(sc, AWI_CMD, 0); 1265 awi_write_1(sc, AWI_CMD, 0);
1271 awi_write_1(sc, AWI_BANNER, 0); 1266 awi_write_1(sc, AWI_BANNER, 0);
1272 am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_CORESET); 1267 am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_CORESET);
1273 DELAY(100); 1268 DELAY(100);
1274 1269
1275 /* Wait for selftest completion */ 1270 /* Wait for selftest completion */
1276 for (i = 0; ; i++) { 1271 for (i = 0; ; i++) {
1277 if (!device_is_active(sc->sc_dev)) 1272 if (!device_is_active(sc->sc_dev))
1278 return ENXIO; 1273 return ENXIO;
1279 if (i >= AWI_SELFTEST_TIMEOUT*hz/1000) { 1274 if (i >= AWI_SELFTEST_TIMEOUT*hz/1000) {
1280 printf("%s: failed to complete selftest (timeout)\n", 1275 printf("%s: failed to complete selftest (timeout)\n",
1281 sc->sc_if.if_xname); 1276 sc->sc_if.if_xname);
1282 return ENXIO; 1277 return ENXIO;
1283 } 1278 }
1284 status = awi_read_1(sc, AWI_SELFTEST); 1279 status = awi_read_1(sc, AWI_SELFTEST);
1285 if ((status & 0xf0) == 0xf0) 1280 if ((status & 0xf0) == 0xf0)
1286 break; 1281 break;
1287 if (sc->sc_cansleep) { 1282 if (sc->sc_cansleep) {
1288 sc->sc_sleep_cnt++; 1283 sc->sc_sleep_cnt++;
1289 (void)tsleep(sc, PWAIT, "awitst", 1); 1284 (void)tsleep(sc, PWAIT, "awitst", 1);
1290 sc->sc_sleep_cnt--; 1285 sc->sc_sleep_cnt--;
1291 } else { 1286 } else {
1292 DELAY(1000*1000/hz); 1287 DELAY(1000*1000/hz);
1293 } 1288 }
1294 } 1289 }
1295 if (status != AWI_SELFTEST_PASSED) { 1290 if (status != AWI_SELFTEST_PASSED) {
1296 printf("%s: failed to complete selftest (code %x)\n", 1291 printf("%s: failed to complete selftest (code %x)\n",
1297 sc->sc_if.if_xname, status); 1292 sc->sc_if.if_xname, status);
1298 return ENXIO; 1293 return ENXIO;
1299 } 1294 }
1300 1295
1301 /* Check banner to confirm firmware write it */ 1296 /* Check banner to confirm firmware write it */
1302 awi_read_bytes(sc, AWI_BANNER, sc->sc_banner, AWI_BANNER_LEN); 1297 awi_read_bytes(sc, AWI_BANNER, sc->sc_banner, AWI_BANNER_LEN);
1303 if (memcmp(sc->sc_banner, "PCnetMobile:", 12) != 0) { 1298 if (memcmp(sc->sc_banner, "PCnetMobile:", 12) != 0) {
1304 printf("%s: failed to complete selftest (bad banner)\n", 1299 printf("%s: failed to complete selftest (bad banner)\n",
1305 sc->sc_if.if_xname); 1300 sc->sc_if.if_xname);
1306 for (i = 0; i < AWI_BANNER_LEN; i++) 1301 for (i = 0; i < AWI_BANNER_LEN; i++)
1307 printf("%s%02x", i ? ":" : "\t", sc->sc_banner[i]); 1302 printf("%s%02x", i ? ":" : "\t", sc->sc_banner[i]);
1308 printf("\n"); 1303 printf("\n");
1309 return ENXIO; 1304 return ENXIO;
1310 } 1305 }
1311 1306
1312 /* Initializing interrupt */ 1307 /* Initializing interrupt */
1313 sc->sc_enab_intr = 1; 1308 sc->sc_enab_intr = 1;
1314 error = awi_intr_lock(sc); 1309 error = awi_intr_lock(sc);
1315 if (error) 1310 if (error)
1316 return error; 1311 return error;
1317 intmask = AWI_INT_GROGGY | AWI_INT_SCAN_CMPLT | 1312 intmask = AWI_INT_GROGGY | AWI_INT_SCAN_CMPLT |
1318 AWI_INT_TX | AWI_INT_RX | AWI_INT_CMD; 1313 AWI_INT_TX | AWI_INT_RX | AWI_INT_CMD;
1319 awi_write_1(sc, AWI_INTMASK, ~intmask & 0xff); 1314 awi_write_1(sc, AWI_INTMASK, ~intmask & 0xff);
1320 awi_write_1(sc, AWI_INTMASK2, 0); 1315 awi_write_1(sc, AWI_INTMASK2, 0);
1321 awi_write_1(sc, AWI_INTSTAT, 0); 1316 awi_write_1(sc, AWI_INTSTAT, 0);
1322 awi_write_1(sc, AWI_INTSTAT2, 0); 1317 awi_write_1(sc, AWI_INTSTAT2, 0);
1323 awi_intr_unlock(sc); 1318 awi_intr_unlock(sc);
1324 am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_ENECINT); 1319 am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_ENECINT);
1325 1320
1326 /* Issuing interface test command */ 1321 /* Issuing interface test command */
1327 error = awi_cmd(sc, AWI_CMD_NOP, AWI_WAIT); 1322 error = awi_cmd(sc, AWI_CMD_NOP, AWI_WAIT);
1328 if (error) { 1323 if (error) {
1329 printf("%s: failed to complete selftest", 1324 printf("%s: failed to complete selftest",
1330 sc->sc_if.if_xname); 1325 sc->sc_if.if_xname);
1331 if (error == ENXIO) 1326 if (error == ENXIO)
1332 printf(" (no hardware)\n"); 1327 printf(" (no hardware)\n");
1333 else if (error != EWOULDBLOCK) 1328 else if (error != EWOULDBLOCK)
1334 printf(" (error %d)\n", error); 1329 printf(" (error %d)\n", error);
1335 else if (sc->sc_cansleep) 1330 else if (sc->sc_cansleep)
1336 printf(" (lost interrupt)\n"); 1331 printf(" (lost interrupt)\n");
1337 else 1332 else
1338 printf(" (command timeout)\n"); 1333 printf(" (command timeout)\n");
1339 return error; 1334 return error;
1340 } 1335 }
1341 1336
1342 /* Initialize VBM */ 1337 /* Initialize VBM */
1343 awi_write_1(sc, AWI_VBM_OFFSET, 0); 1338 awi_write_1(sc, AWI_VBM_OFFSET, 0);
1344 awi_write_1(sc, AWI_VBM_LENGTH, 1); 1339 awi_write_1(sc, AWI_VBM_LENGTH, 1);
1345 awi_write_1(sc, AWI_VBM_BITMAP, 0); 1340 awi_write_1(sc, AWI_VBM_BITMAP, 0);
1346 return 0; 1341 return 0;
1347} 1342}
1348 1343
1349/* 1344/*
1350 * Extract the factory default MIB value from firmware and assign the driver 1345 * Extract the factory default MIB value from firmware and assign the driver
1351 * default value. 1346 * default value.
1352 * Called once at attaching the interface. 1347 * Called once at attaching the interface.
1353 */ 1348 */
1354 1349
1355static int 1350static int
1356awi_init_mibs(struct awi_softc *sc) 1351awi_init_mibs(struct awi_softc *sc)
1357{ 1352{
1358 int chan, i, error; 1353 int chan, i, error;
1359 struct ieee80211com *ic = &sc->sc_ic; 1354 struct ieee80211com *ic = &sc->sc_ic;
1360 const struct awi_chanset *cs; 1355 const struct awi_chanset *cs;
1361 1356
1362 if ((error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_LOCAL, AWI_WAIT)) || 1357 if ((error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_LOCAL, AWI_WAIT)) ||
1363 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_ADDR, AWI_WAIT)) || 1358 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_ADDR, AWI_WAIT)) ||
1364 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_MAC, AWI_WAIT)) || 1359 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_MAC, AWI_WAIT)) ||
1365 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_MGT, AWI_WAIT)) || 1360 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_MGT, AWI_WAIT)) ||
1366 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_PHY, AWI_WAIT))) { 1361 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_PHY, AWI_WAIT))) {
1367 printf("%s: failed to get default mib value (error %d)\n", 1362 printf("%s: failed to get default mib value (error %d)\n",
1368 sc->sc_if.if_xname, error); 1363 sc->sc_if.if_xname, error);
1369 return error; 1364 return error;
1370 } 1365 }
1371 1366
1372 memset(&sc->sc_ic.ic_chan_avail, 0, sizeof(sc->sc_ic.ic_chan_avail)); 1367 memset(&sc->sc_ic.ic_chan_avail, 0, sizeof(sc->sc_ic.ic_chan_avail));
1373 for (cs = awi_chanset; ; cs++) { 1368 for (cs = awi_chanset; ; cs++) {
1374 if (cs->cs_type == 0) { 1369 if (cs->cs_type == 0) {
1375 printf("%s: failed to set available channel\n", 1370 printf("%s: failed to set available channel\n",
1376 sc->sc_if.if_xname); 1371 sc->sc_if.if_xname);
1377 return ENXIO; 1372 return ENXIO;
1378 } 1373 }
1379 if (cs->cs_type == sc->sc_mib_phy.IEEE_PHY_Type && 1374 if (cs->cs_type == sc->sc_mib_phy.IEEE_PHY_Type &&
1380 cs->cs_region == sc->sc_mib_phy.aCurrent_Reg_Domain) 1375 cs->cs_region == sc->sc_mib_phy.aCurrent_Reg_Domain)
1381 break; 1376 break;
1382 } 1377 }
1383 if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { 1378 if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
1384 for (i = cs->cs_min; i <= cs->cs_max; i++) { 1379 for (i = cs->cs_min; i <= cs->cs_max; i++) {
1385 chan = IEEE80211_FH_CHAN(i % 3 + 1, i); 1380 chan = IEEE80211_FH_CHAN(i % 3 + 1, i);
1386 setbit(sc->sc_ic.ic_chan_avail, chan); 1381 setbit(sc->sc_ic.ic_chan_avail, chan);
1387 /* XXX for FHSS, does frequency matter? */ 1382 /* XXX for FHSS, does frequency matter? */
1388 ic->ic_channels[chan].ic_freq = 0; 1383 ic->ic_channels[chan].ic_freq = 0;
1389 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_FHSS; 1384 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_FHSS;
1390 /* 1385 /*
1391 * According to the IEEE 802.11 specification, 1386 * According to the IEEE 802.11 specification,
1392 * hop pattern parameter for FH phy should be 1387 * hop pattern parameter for FH phy should be
1393 * incremented by 3 for given hop chanset, i.e., 1388 * incremented by 3 for given hop chanset, i.e.,
1394 * the chanset parameter is calculated for given 1389 * the chanset parameter is calculated for given
1395 * hop patter. However, BayStack 650 Access Points 1390 * hop patter. However, BayStack 650 Access Points
1396 * apparently use fixed hop chanset parameter value 1391 * apparently use fixed hop chanset parameter value
1397 * 1 for any hop pattern. So we also try this 1392 * 1 for any hop pattern. So we also try this
1398 * combination of hop chanset and pattern. 1393 * combination of hop chanset and pattern.
1399 */ 1394 */
1400 chan = IEEE80211_FH_CHAN(1, i); 1395 chan = IEEE80211_FH_CHAN(1, i);
1401 setbit(sc->sc_ic.ic_chan_avail, chan); 1396 setbit(sc->sc_ic.ic_chan_avail, chan);
1402 ic->ic_channels[chan].ic_freq = 0; /* XXX */ 1397 ic->ic_channels[chan].ic_freq = 0; /* XXX */
1403 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_FHSS; 1398 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_FHSS;
1404 } 1399 }
1405 } else { 1400 } else {
1406 for (i = cs->cs_min; i <= cs->cs_max; i++) { 1401 for (i = cs->cs_min; i <= cs->cs_max; i++) {
1407 setbit(sc->sc_ic.ic_chan_avail, i); 1402 setbit(sc->sc_ic.ic_chan_avail, i);
1408 ic->ic_channels[i].ic_freq = 1403 ic->ic_channels[i].ic_freq =
1409 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 1404 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
1410 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B; 1405 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B;
1411 } 1406 }
1412 } 1407 }
1413 sc->sc_cur_chan = cs->cs_def; 1408 sc->sc_cur_chan = cs->cs_def;
1414 ic->ic_ibss_chan = &ic->ic_channels[cs->cs_def]; 1409 ic->ic_ibss_chan = &ic->ic_channels[cs->cs_def];
1415 1410
1416 sc->sc_mib_local.Fragmentation_Dis = 1; 1411 sc->sc_mib_local.Fragmentation_Dis = 1;
1417 sc->sc_mib_local.Add_PLCP_Dis = 0; 1412 sc->sc_mib_local.Add_PLCP_Dis = 0;
1418 sc->sc_mib_local.MAC_Hdr_Prsv = 0; 1413 sc->sc_mib_local.MAC_Hdr_Prsv = 0;
1419 sc->sc_mib_local.Rx_Mgmt_Que_En = 0; 1414 sc->sc_mib_local.Rx_Mgmt_Que_En = 0;
1420 sc->sc_mib_local.Re_Assembly_Dis = 1; 1415 sc->sc_mib_local.Re_Assembly_Dis = 1;
1421 sc->sc_mib_local.Strip_PLCP_Dis = 0; 1416 sc->sc_mib_local.Strip_PLCP_Dis = 0;
1422 sc->sc_mib_local.Power_Saving_Mode_Dis = 1; 1417 sc->sc_mib_local.Power_Saving_Mode_Dis = 1;
1423 sc->sc_mib_local.Accept_All_Multicast_Dis = 1; 1418 sc->sc_mib_local.Accept_All_Multicast_Dis = 1;
1424 sc->sc_mib_local.Check_Seq_Cntl_Dis = 0; 1419 sc->sc_mib_local.Check_Seq_Cntl_Dis = 0;
1425 sc->sc_mib_local.Flush_CFP_Queue_On_CF_End = 0; 1420 sc->sc_mib_local.Flush_CFP_Queue_On_CF_End = 0;
1426 sc->sc_mib_local.Network_Mode = 1; 1421 sc->sc_mib_local.Network_Mode = 1;
1427 sc->sc_mib_local.PWD_Lvl = 0; 1422 sc->sc_mib_local.PWD_Lvl = 0;
1428 sc->sc_mib_local.CFP_Mode = 0; 1423 sc->sc_mib_local.CFP_Mode = 0;
1429 1424
1430 /* Allocate buffers */ 1425 /* Allocate buffers */
1431 sc->sc_txbase = AWI_BUFFERS; 1426 sc->sc_txbase = AWI_BUFFERS;
1432 sc->sc_txend = sc->sc_txbase + 1427 sc->sc_txend = sc->sc_txbase +
1433 (AWI_TXD_SIZE + sizeof(struct ieee80211_frame) + 1428 (AWI_TXD_SIZE + sizeof(struct ieee80211_frame) +
1434 sizeof(struct ether_header) + ETHERMTU) * AWI_NTXBUFS; 1429 sizeof(struct ether_header) + ETHERMTU) * AWI_NTXBUFS;
1435 LE_WRITE_4(&sc->sc_mib_local.Tx_Buffer_Offset, sc->sc_txbase); 1430 LE_WRITE_4(&sc->sc_mib_local.Tx_Buffer_Offset, sc->sc_txbase);
1436 LE_WRITE_4(&sc->sc_mib_local.Tx_Buffer_Size, 1431 LE_WRITE_4(&sc->sc_mib_local.Tx_Buffer_Size,
1437 sc->sc_txend - sc->sc_txbase); 1432 sc->sc_txend - sc->sc_txbase);
1438 LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Offset, sc->sc_txend); 1433 LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Offset, sc->sc_txend);
1439 LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Size, 1434 LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Size,
1440 AWI_BUFFERS_END - sc->sc_txend); 1435 AWI_BUFFERS_END - sc->sc_txend);
1441 sc->sc_mib_local.Acting_as_AP = 0; 1436 sc->sc_mib_local.Acting_as_AP = 0;
1442 sc->sc_mib_local.Fill_CFP = 0; 1437 sc->sc_mib_local.Fill_CFP = 0;
1443 1438
1444 memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE); 1439 memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE);
1445 sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID; 1440 sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID;
1446 1441
1447 sc->sc_mib_mgt.aPower_Mgt_Mode = 0; 1442 sc->sc_mib_mgt.aPower_Mgt_Mode = 0;
1448 sc->sc_mib_mgt.aDTIM_Period = 1; 1443 sc->sc_mib_mgt.aDTIM_Period = 1;
1449 LE_WRITE_2(&sc->sc_mib_mgt.aATIM_Window, 0); 1444 LE_WRITE_2(&sc->sc_mib_mgt.aATIM_Window, 0);
1450 return 0; 1445 return 0;
1451} 1446}
1452 1447
1453static int 1448static int
1454awi_mib(struct awi_softc *sc, uint8_t cmd, uint8_t mib, int wflag) 1449awi_mib(struct awi_softc *sc, uint8_t cmd, uint8_t mib, int wflag)
1455{ 1450{
1456 int error; 1451 int error;
1457 uint8_t size, *ptr; 1452 uint8_t size, *ptr;
1458 1453
1459 switch (mib) { 1454 switch (mib) {
1460 case AWI_MIB_LOCAL: 1455 case AWI_MIB_LOCAL:
1461 ptr = (uint8_t *)&sc->sc_mib_local; 1456 ptr = (uint8_t *)&sc->sc_mib_local;
1462 size = sizeof(sc->sc_mib_local); 1457 size = sizeof(sc->sc_mib_local);
1463 break; 1458 break;
1464 case AWI_MIB_ADDR: 1459 case AWI_MIB_ADDR:
1465 ptr = (uint8_t *)&sc->sc_mib_addr; 1460 ptr = (uint8_t *)&sc->sc_mib_addr;
1466 size = sizeof(sc->sc_mib_addr); 1461 size = sizeof(sc->sc_mib_addr);
1467 break; 1462 break;
1468 case AWI_MIB_MAC: 1463 case AWI_MIB_MAC:
1469 ptr = (uint8_t *)&sc->sc_mib_mac; 1464 ptr = (uint8_t *)&sc->sc_mib_mac;
1470 size = sizeof(sc->sc_mib_mac); 1465 size = sizeof(sc->sc_mib_mac);
1471 break; 1466 break;
1472 case AWI_MIB_STAT: 1467 case AWI_MIB_STAT:
1473 ptr = (uint8_t *)&sc->sc_mib_stat; 1468 ptr = (uint8_t *)&sc->sc_mib_stat;
1474 size = sizeof(sc->sc_mib_stat); 1469 size = sizeof(sc->sc_mib_stat);
1475 break; 1470 break;
1476 case AWI_MIB_MGT: 1471 case AWI_MIB_MGT:
1477 ptr = (uint8_t *)&sc->sc_mib_mgt; 1472 ptr = (uint8_t *)&sc->sc_mib_mgt;
1478 size = sizeof(sc->sc_mib_mgt); 1473 size = sizeof(sc->sc_mib_mgt);
1479 break; 1474 break;
1480 case AWI_MIB_PHY: 1475 case AWI_MIB_PHY:
1481 ptr = (uint8_t *)&sc->sc_mib_phy; 1476 ptr = (uint8_t *)&sc->sc_mib_phy;
1482 size = sizeof(sc->sc_mib_phy); 1477 size = sizeof(sc->sc_mib_phy);
1483 break; 1478 break;
1484 default: 1479 default:
1485 return EINVAL; 1480 return EINVAL;
1486 } 1481 }
1487 if (sc->sc_cmd_inprog) { 1482 if (sc->sc_cmd_inprog) {
1488 if ((error = awi_cmd_wait(sc)) != 0) { 1483 if ((error = awi_cmd_wait(sc)) != 0) {
1489 if (error == EWOULDBLOCK) { 1484 if (error == EWOULDBLOCK) {
1490 DPRINTF(("awi_mib: cmd %d inprog", 1485 DPRINTF(("awi_mib: cmd %d inprog",
1491 sc->sc_cmd_inprog)); 1486 sc->sc_cmd_inprog));
1492 } 1487 }
1493 return error; 1488 return error;
1494 } 1489 }
1495 } 1490 }
1496 sc->sc_cmd_inprog = cmd; 1491 sc->sc_cmd_inprog = cmd;
1497 if (cmd == AWI_CMD_SET_MIB) 1492 if (cmd == AWI_CMD_SET_MIB)
1498 awi_write_bytes(sc, AWI_CA_MIB_DATA, ptr, size); 1493 awi_write_bytes(sc, AWI_CA_MIB_DATA, ptr, size);
1499 awi_write_1(sc, AWI_CA_MIB_TYPE, mib); 1494 awi_write_1(sc, AWI_CA_MIB_TYPE, mib);
1500 awi_write_1(sc, AWI_CA_MIB_SIZE, size); 1495 awi_write_1(sc, AWI_CA_MIB_SIZE, size);
1501 awi_write_1(sc, AWI_CA_MIB_INDEX, 0); 1496 awi_write_1(sc, AWI_CA_MIB_INDEX, 0);
1502 if ((error = awi_cmd(sc, cmd, wflag)) != 0) 1497 if ((error = awi_cmd(sc, cmd, wflag)) != 0)
1503 return error; 1498 return error;
1504 if (cmd == AWI_CMD_GET_MIB) { 1499 if (cmd == AWI_CMD_GET_MIB) {
1505 awi_read_bytes(sc, AWI_CA_MIB_DATA, ptr, size); 1500 awi_read_bytes(sc, AWI_CA_MIB_DATA, ptr, size);
1506#ifdef AWI_DEBUG 1501#ifdef AWI_DEBUG
1507 if (awi_debug) { 1502 if (awi_debug) {
1508 int i; 1503 int i;
1509 1504
1510 printf("awi_mib: #%d:", mib); 1505 printf("awi_mib: #%d:", mib);
1511 for (i = 0; i < size; i++) 1506 for (i = 0; i < size; i++)
1512 printf(" %02x", ptr[i]); 1507 printf(" %02x", ptr[i]);
1513 printf("\n"); 1508 printf("\n");
1514 } 1509 }
1515#endif 1510#endif
1516 } 1511 }
1517 return 0; 1512 return 0;
1518} 1513}
1519 1514
1520static int 1515static int
1521awi_cmd(struct awi_softc *sc, uint8_t cmd, int wflag) 1516awi_cmd(struct awi_softc *sc, uint8_t cmd, int wflag)
1522{ 1517{
1523 uint8_t status; 1518 uint8_t status;
1524 int error = 0; 1519 int error = 0;
1525#ifdef AWI_DEBUG 1520#ifdef AWI_DEBUG
1526 static const char *cmdname[] = { 1521 static const char *cmdname[] = {
1527 "IDLE", "NOP", "SET_MIB", "INIT_TX", "FLUSH_TX", "INIT_RX", 1522 "IDLE", "NOP", "SET_MIB", "INIT_TX", "FLUSH_TX", "INIT_RX",
1528 "KILL_RX", "SLEEP", "WAKE", "GET_MIB", "SCAN", "SYNC", "RESUME" 1523 "KILL_RX", "SLEEP", "WAKE", "GET_MIB", "SCAN", "SYNC", "RESUME"
1529 }; 1524 };
1530#endif 1525#endif
1531 1526
1532#ifdef AWI_DEBUG 1527#ifdef AWI_DEBUG
1533 if (awi_debug > 1) { 1528 if (awi_debug > 1) {
1534 if (cmd >= sizeof(cmdname)/sizeof(cmdname[0])) 1529 if (cmd >= sizeof(cmdname)/sizeof(cmdname[0]))
1535 printf("awi_cmd: #%d", cmd); 1530 printf("awi_cmd: #%d", cmd);
1536 else 1531 else
1537 printf("awi_cmd: %s", cmdname[cmd]); 1532 printf("awi_cmd: %s", cmdname[cmd]);
1538 printf(" %s\n", wflag == AWI_NOWAIT ? "nowait" : "wait"); 1533 printf(" %s\n", wflag == AWI_NOWAIT ? "nowait" : "wait");
1539 } 1534 }
1540#endif 1535#endif
1541 sc->sc_cmd_inprog = cmd; 1536 sc->sc_cmd_inprog = cmd;
1542 awi_write_1(sc, AWI_CMD_STATUS, AWI_STAT_IDLE); 1537 awi_write_1(sc, AWI_CMD_STATUS, AWI_STAT_IDLE);
1543 awi_write_1(sc, AWI_CMD, cmd); 1538 awi_write_1(sc, AWI_CMD, cmd);
1544 if (wflag == AWI_NOWAIT) 1539 if (wflag == AWI_NOWAIT)
1545 return EINPROGRESS; 1540 return EINPROGRESS;
1546 if ((error = awi_cmd_wait(sc)) != 0) 1541 if ((error = awi_cmd_wait(sc)) != 0)
1547 return error; 1542 return error;
1548 status = awi_read_1(sc, AWI_CMD_STATUS); 1543 status = awi_read_1(sc, AWI_CMD_STATUS);
1549 awi_write_1(sc, AWI_CMD, 0); 1544 awi_write_1(sc, AWI_CMD, 0);
1550 switch (status) { 1545 switch (status) {
1551 case AWI_STAT_OK: 1546 case AWI_STAT_OK:
1552 break; 1547 break;
1553 case AWI_STAT_BADPARM: 1548 case AWI_STAT_BADPARM:
1554 return EINVAL; 1549 return EINVAL;
1555 default: 1550 default:
1556 printf("%s: command %d failed %x\n", 1551 printf("%s: command %d failed %x\n",
1557 sc->sc_if.if_xname, cmd, status); 1552 sc->sc_if.if_xname, cmd, status);
1558 return ENXIO; 1553 return ENXIO;
1559 } 1554 }
1560 return 0; 1555 return 0;
1561} 1556}
1562 1557
1563static int 1558static int
1564awi_cmd_wait(struct awi_softc *sc) 1559awi_cmd_wait(struct awi_softc *sc)
1565{ 1560{
1566 int i, error = 0; 1561 int i, error = 0;
1567 1562
1568 i = 0; 1563 i = 0;
1569 while (sc->sc_cmd_inprog) { 1564 while (sc->sc_cmd_inprog) {
1570 if (!device_is_active(sc->sc_dev)) 1565 if (!device_is_active(sc->sc_dev))
1571 return ENXIO; 1566 return ENXIO;
1572 if (awi_read_1(sc, AWI_CMD) != sc->sc_cmd_inprog) { 1567 if (awi_read_1(sc, AWI_CMD) != sc->sc_cmd_inprog) {
1573 printf("%s: failed to access hardware\n", 1568 printf("%s: failed to access hardware\n",
1574 sc->sc_if.if_xname); 1569 sc->sc_if.if_xname);
1575 config_deactivate(sc->sc_dev); 1570 config_deactivate(sc->sc_dev);
1576 return ENXIO; 1571 return ENXIO;
1577 } 1572 }
1578 if (sc->sc_cansleep) { 1573 if (sc->sc_cansleep) {
1579 sc->sc_sleep_cnt++; 1574 sc->sc_sleep_cnt++;
1580 error = tsleep(sc, PWAIT, "awicmd", 1575 error = tsleep(sc, PWAIT, "awicmd",
1581 AWI_CMD_TIMEOUT*hz/1000); 1576 AWI_CMD_TIMEOUT*hz/1000);
1582 sc->sc_sleep_cnt--; 1577 sc->sc_sleep_cnt--;
1583 } else { 1578 } else {
1584 if (awi_read_1(sc, AWI_CMD_STATUS) != AWI_STAT_IDLE) { 1579 if (awi_read_1(sc, AWI_CMD_STATUS) != AWI_STAT_IDLE) {
1585 awi_cmd_done(sc); 1580 awi_cmd_done(sc);
1586 break; 1581 break;
1587 } 1582 }
1588 if (i++ >= AWI_CMD_TIMEOUT*1000/10) 1583 if (i++ >= AWI_CMD_TIMEOUT*1000/10)
1589 error = EWOULDBLOCK; 1584 error = EWOULDBLOCK;
1590 else 1585 else
1591 DELAY(10); 1586 DELAY(10);
1592 } 1587 }
1593 if (error) 1588 if (error)
1594 break; 1589 break;
1595 } 1590 }
1596 if (error) { 1591 if (error) {
1597 DPRINTF(("awi_cmd_wait: cmd 0x%x, error %d\n", 1592 DPRINTF(("awi_cmd_wait: cmd 0x%x, error %d\n",
1598 sc->sc_cmd_inprog, error)); 1593 sc->sc_cmd_inprog, error));
1599 } 1594 }
1600 return error; 1595 return error;
1601} 1596}
1602 1597
1603static void 1598static void
1604awi_cmd_done(struct awi_softc *sc) 1599awi_cmd_done(struct awi_softc *sc)
1605{ 1600{
1606 uint8_t cmd, status; 1601 uint8_t cmd, status;
1607 1602
1608 status = awi_read_1(sc, AWI_CMD_STATUS); 1603 status = awi_read_1(sc, AWI_CMD_STATUS);
1609 if (status == AWI_STAT_IDLE) 1604 if (status == AWI_STAT_IDLE)
1610 return; /* stray interrupt */ 1605 return; /* stray interrupt */
1611 1606
1612 cmd = sc->sc_cmd_inprog; 1607 cmd = sc->sc_cmd_inprog;
1613 sc->sc_cmd_inprog = 0; 1608 sc->sc_cmd_inprog = 0;
1614 wakeup(sc); 1609 wakeup(sc);
1615 awi_write_1(sc, AWI_CMD, 0); 1610 awi_write_1(sc, AWI_CMD, 0);
1616 1611
1617 if (status != AWI_STAT_OK) { 1612 if (status != AWI_STAT_OK) {
1618 printf("%s: command %d failed %x\n", 1613 printf("%s: command %d failed %x\n",
1619 sc->sc_if.if_xname, cmd, status); 1614 sc->sc_if.if_xname, cmd, status);
1620 sc->sc_substate = AWI_ST_NONE; 1615 sc->sc_substate = AWI_ST_NONE;
1621 return; 1616 return;
1622 } 1617 }
1623 if (sc->sc_substate != AWI_ST_NONE) 1618 if (sc->sc_substate != AWI_ST_NONE)
1624 (void)ieee80211_new_state(&sc->sc_ic, sc->sc_nstate, -1); 1619 (void)ieee80211_new_state(&sc->sc_ic, sc->sc_nstate, -1);
1625} 1620}
1626 1621
1627static int 1622static int
1628awi_next_txd(struct awi_softc *sc, int len, uint32_t *framep, uint32_t *ntxdp) 1623awi_next_txd(struct awi_softc *sc, int len, uint32_t *framep, uint32_t *ntxdp)
1629{ 1624{
1630 uint32_t txd, ntxd, frame; 1625 uint32_t txd, ntxd, frame;
1631 1626
1632 txd = sc->sc_txnext; 1627 txd = sc->sc_txnext;
1633 frame = txd + AWI_TXD_SIZE; 1628 frame = txd + AWI_TXD_SIZE;
1634 if (frame + len > sc->sc_txend) 1629 if (frame + len > sc->sc_txend)
1635 frame = sc->sc_txbase; 1630 frame = sc->sc_txbase;
1636 ntxd = frame + len; 1631 ntxd = frame + len;
1637 if (ntxd + AWI_TXD_SIZE > sc->sc_txend) 1632 if (ntxd + AWI_TXD_SIZE > sc->sc_txend)
1638 ntxd = sc->sc_txbase; 1633 ntxd = sc->sc_txbase;
1639 *framep = frame; 1634 *framep = frame;
1640 *ntxdp = ntxd; 1635 *ntxdp = ntxd;
1641 /* 1636 /*
1642 * Determine if there are any room in ring buffer. 1637 * Determine if there are any room in ring buffer.
1643 * --- send wait, === new data, +++ conflict (ENOBUFS) 1638 * --- send wait, === new data, +++ conflict (ENOBUFS)
1644 * base........................end 1639 * base........................end
1645 * done----txd=====ntxd OK 1640 * done----txd=====ntxd OK
1646 * --txd=====done++++ntxd-- full 1641 * --txd=====done++++ntxd-- full
1647 * --txd=====ntxd done-- OK 1642 * --txd=====ntxd done-- OK
1648 * ==ntxd done----txd=== OK 1643 * ==ntxd done----txd=== OK
1649 * ==done++++ntxd----txd=== full 1644 * ==done++++ntxd----txd=== full
1650 * ++ntxd txd=====done++ full 1645 * ++ntxd txd=====done++ full
1651 */ 1646 */
1652 if (txd < ntxd) { 1647 if (txd < ntxd) {
1653 if (txd < sc->sc_txdone && ntxd + AWI_TXD_SIZE > sc->sc_txdone) 1648 if (txd < sc->sc_txdone && ntxd + AWI_TXD_SIZE > sc->sc_txdone)
1654 return ENOBUFS; 1649 return ENOBUFS;
1655 } else { 1650 } else {
1656 if (txd < sc->sc_txdone || ntxd + AWI_TXD_SIZE > sc->sc_txdone) 1651 if (txd < sc->sc_txdone || ntxd + AWI_TXD_SIZE > sc->sc_txdone)
1657 return ENOBUFS; 1652 return ENOBUFS;
1658 } 1653 }
1659 return 0; 1654 return 0;
1660} 1655}
1661 1656
1662static int 1657static int
1663awi_lock(struct awi_softc *sc) 1658awi_lock(struct awi_softc *sc)
1664{ 1659{
1665 int error = 0; 1660 int error = 0;
1666 1661
1667 if (curlwp == NULL) { 1662 if (curlwp == NULL) {
1668 /* 1663 /*
1669 * XXX 1664 * XXX
1670 * Though driver ioctl should be called with context, 1665 * Though driver ioctl should be called with context,
1671 * KAME ipv6 stack calls ioctl in interrupt for now. 1666 * KAME ipv6 stack calls ioctl in interrupt for now.
1672 * We simply abort the request if there are other 1667 * We simply abort the request if there are other
1673 * ioctl requests in progress. 1668 * ioctl requests in progress.
1674 */ 1669 */
1675 if (sc->sc_busy) { 1670 if (sc->sc_busy) {
1676 if (!device_is_active(sc->sc_dev)) 1671 if (!device_is_active(sc->sc_dev))
1677 return ENXIO; 1672 return ENXIO;
1678 return EWOULDBLOCK; 1673 return EWOULDBLOCK;
1679 } 1674 }
1680 sc->sc_busy = 1; 1675 sc->sc_busy = 1;
1681 sc->sc_cansleep = 0; 1676 sc->sc_cansleep = 0;
1682 return 0; 1677 return 0;
1683 } 1678 }
1684 while (sc->sc_busy) { 1679 while (sc->sc_busy) {
1685 if (!device_is_active(sc->sc_dev)) 1680 if (!device_is_active(sc->sc_dev))
1686 return ENXIO; 1681 return ENXIO;
1687 sc->sc_sleep_cnt++; 1682 sc->sc_sleep_cnt++;
1688 error = tsleep(sc, PWAIT | PCATCH, "awilck", 0); 1683 error = tsleep(sc, PWAIT | PCATCH, "awilck", 0);
1689 sc->sc_sleep_cnt--; 1684 sc->sc_sleep_cnt--;
1690 if (error) 1685 if (error)
1691 return error; 1686 return error;
1692 } 1687 }
1693 sc->sc_busy = 1; 1688 sc->sc_busy = 1;
1694 sc->sc_cansleep = 1; 1689 sc->sc_cansleep = 1;
1695 return 0; 1690 return 0;
1696} 1691}
1697 1692
1698static void 1693static void
1699awi_unlock(struct awi_softc *sc) 1694awi_unlock(struct awi_softc *sc)
1700{ 1695{
1701 sc->sc_busy = 0; 1696 sc->sc_busy = 0;
1702 sc->sc_cansleep = 0; 1697 sc->sc_cansleep = 0;
1703 if (sc->sc_sleep_cnt) 1698 if (sc->sc_sleep_cnt)
1704 wakeup(sc); 1699 wakeup(sc);
1705} 1700}
1706 1701
1707static int 1702static int
1708awi_intr_lock(struct awi_softc *sc) 1703awi_intr_lock(struct awi_softc *sc)
1709{ 1704{
1710 uint8_t status; 1705 uint8_t status;
1711 int i, retry; 1706 int i, retry;
1712 1707
1713 status = 1; 1708 status = 1;
1714 for (retry = 0; retry < 10; retry++) { 1709 for (retry = 0; retry < 10; retry++) {
1715 for (i = 0; i < AWI_LOCKOUT_TIMEOUT*1000/5; i++) { 1710 for (i = 0; i < AWI_LOCKOUT_TIMEOUT*1000/5; i++) {
1716 if ((status = awi_read_1(sc, AWI_LOCKOUT_HOST)) == 0) 1711 if ((status = awi_read_1(sc, AWI_LOCKOUT_HOST)) == 0)
1717 break; 1712 break;
1718 DELAY(5); 1713 DELAY(5);
1719 } 1714 }
1720 if (status != 0) 1715 if (status != 0)
1721 break; 1716 break;
1722 awi_write_1(sc, AWI_LOCKOUT_MAC, 1); 1717 awi_write_1(sc, AWI_LOCKOUT_MAC, 1);
1723 if ((status = awi_read_1(sc, AWI_LOCKOUT_HOST)) == 0) 1718 if ((status = awi_read_1(sc, AWI_LOCKOUT_HOST)) == 0)
1724 break; 1719 break;
1725 awi_write_1(sc, AWI_LOCKOUT_MAC, 0); 1720 awi_write_1(sc, AWI_LOCKOUT_MAC, 0);
1726 } 1721 }
1727 if (status != 0) { 1722 if (status != 0) {
1728 printf("%s: failed to lock interrupt\n", 1723 printf("%s: failed to lock interrupt\n",
1729 sc->sc_if.if_xname); 1724 sc->sc_if.if_xname);
1730 return ENXIO; 1725 return ENXIO;
1731 } 1726 }
1732 return 0; 1727 return 0;
1733} 1728}
1734 1729
1735static void 1730static void
1736awi_intr_unlock(struct awi_softc *sc) 1731awi_intr_unlock(struct awi_softc *sc)
1737{ 1732{
1738 1733
1739 awi_write_1(sc, AWI_LOCKOUT_MAC, 0); 1734 awi_write_1(sc, AWI_LOCKOUT_MAC, 0);
1740} 1735}
1741 1736
1742static int 1737static int
1743awi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1738awi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1744{ 1739{
1745 struct ifnet *ifp = ic->ic_ifp; 1740 struct ifnet *ifp = ic->ic_ifp;
1746 struct awi_softc *sc = ifp->if_softc; 1741 struct awi_softc *sc = ifp->if_softc;
1747 struct ieee80211_node *ni; 1742 struct ieee80211_node *ni;
1748 int error; 1743 int error;
1749 uint8_t newmode; 1744 uint8_t newmode;
1750 enum ieee80211_state ostate; 1745 enum ieee80211_state ostate;
1751#ifdef AWI_DEBUG 1746#ifdef AWI_DEBUG
1752 static const char *stname[] = 1747 static const char *stname[] =
1753 { "INIT", "SCAN", "AUTH", "ASSOC", "RUN" }; 1748 { "INIT", "SCAN", "AUTH", "ASSOC", "RUN" };
1754 static const char *substname[] = 1749 static const char *substname[] =
1755 { "NONE", "SCAN_INIT", "SCAN_SETMIB", "SCAN_SCCMD", 1750 { "NONE", "SCAN_INIT", "SCAN_SETMIB", "SCAN_SCCMD",
1756 "SUB_INIT", "SUB_SETSS", "SUB_SYNC" }; 1751 "SUB_INIT", "SUB_SETSS", "SUB_SYNC" };
1757#endif /* AWI_DEBUG */ 1752#endif /* AWI_DEBUG */
1758 1753
1759 ostate = ic->ic_state; 1754 ostate = ic->ic_state;
1760 DPRINTF(("awi_newstate: %s (%s/%s) -> %s\n", stname[ostate], 1755 DPRINTF(("awi_newstate: %s (%s/%s) -> %s\n", stname[ostate],
1761 stname[sc->sc_nstate], substname[sc->sc_substate], stname[nstate])); 1756 stname[sc->sc_nstate], substname[sc->sc_substate], stname[nstate]));
1762 1757
1763 /* Set LED */ 1758 /* Set LED */
1764 switch (nstate) { 1759 switch (nstate) {
1765 case IEEE80211_S_INIT: 1760 case IEEE80211_S_INIT:
1766 awi_drvstate(sc, AWI_DRV_RESET); 1761 awi_drvstate(sc, AWI_DRV_RESET);
1767 break; 1762 break;
1768 case IEEE80211_S_SCAN: 1763 case IEEE80211_S_SCAN:
1769 if (ic->ic_opmode == IEEE80211_M_IBSS || 1764 if (ic->ic_opmode == IEEE80211_M_IBSS ||
1770 ic->ic_opmode == IEEE80211_M_AHDEMO) 1765 ic->ic_opmode == IEEE80211_M_AHDEMO)
1771 awi_drvstate(sc, AWI_DRV_ADHSC); 1766 awi_drvstate(sc, AWI_DRV_ADHSC);
1772 else 1767 else
1773 awi_drvstate(sc, AWI_DRV_INFSY); 1768 awi_drvstate(sc, AWI_DRV_INFSY);
1774 break; 1769 break;
1775 case IEEE80211_S_AUTH: 1770 case IEEE80211_S_AUTH:
1776 awi_drvstate(sc, AWI_DRV_INFSY); 1771 awi_drvstate(sc, AWI_DRV_INFSY);
1777 break; 1772 break;
1778 case IEEE80211_S_ASSOC: 1773 case IEEE80211_S_ASSOC:
1779 awi_drvstate(sc, AWI_DRV_INFAUTH); 1774 awi_drvstate(sc, AWI_DRV_INFAUTH);
1780 break; 1775 break;
1781 case IEEE80211_S_RUN: 1776 case IEEE80211_S_RUN:
1782 if (ic->ic_opmode == IEEE80211_M_IBSS || 1777 if (ic->ic_opmode == IEEE80211_M_IBSS ||
1783 ic->ic_opmode == IEEE80211_M_AHDEMO) 1778 ic->ic_opmode == IEEE80211_M_AHDEMO)
1784 awi_drvstate(sc, AWI_DRV_ADHSY); 1779 awi_drvstate(sc, AWI_DRV_ADHSY);
1785 else 1780 else
1786 awi_drvstate(sc, AWI_DRV_INFASSOC); 1781 awi_drvstate(sc, AWI_DRV_INFASSOC);
1787 break; 1782 break;
1788 } 1783 }
1789 1784
1790 if (nstate == IEEE80211_S_INIT) { 1785 if (nstate == IEEE80211_S_INIT) {
1791 sc->sc_substate = AWI_ST_NONE; 1786 sc->sc_substate = AWI_ST_NONE;
1792 ic->ic_flags &= ~IEEE80211_F_SIBSS; 1787 ic->ic_flags &= ~IEEE80211_F_SIBSS;
1793 return (*sc->sc_newstate)(ic, nstate, arg); 1788 return (*sc->sc_newstate)(ic, nstate, arg);
1794 } 1789 }
1795 1790
1796 /* State transition */ 1791 /* State transition */
1797 if (nstate == IEEE80211_S_SCAN) { 1792 if (nstate == IEEE80211_S_SCAN) {
1798 /* SCAN substate */ 1793 /* SCAN substate */
1799 if (sc->sc_substate == AWI_ST_NONE) { 1794 if (sc->sc_substate == AWI_ST_NONE) {
1800 sc->sc_nstate = nstate; /* next state in transition */ 1795 sc->sc_nstate = nstate; /* next state in transition */
1801 sc->sc_substate = AWI_ST_SCAN_INIT; 1796 sc->sc_substate = AWI_ST_SCAN_INIT;
1802 } 1797 }
1803 switch (sc->sc_substate) { 1798 switch (sc->sc_substate) {
1804 case AWI_ST_SCAN_INIT: 1799 case AWI_ST_SCAN_INIT:
1805 sc->sc_substate = AWI_ST_SCAN_SETMIB; 1800 sc->sc_substate = AWI_ST_SCAN_SETMIB;
1806 switch (ostate) { 1801 switch (ostate) {
1807 case IEEE80211_S_RUN: 1802 case IEEE80211_S_RUN:
1808 /* Beacon miss */ 1803 /* Beacon miss */
1809 if (ifp->if_flags & IFF_DEBUG) 1804 if (ifp->if_flags & IFF_DEBUG)
1810 printf("%s: no recent beacons from %s;" 1805 printf("%s: no recent beacons from %s;"
1811 " rescanning\n", 1806 " rescanning\n",
1812 ifp->if_xname, 1807 ifp->if_xname,
1813 ether_sprintf(ic->ic_bss->ni_bssid)); 1808 ether_sprintf(ic->ic_bss->ni_bssid));
1814 /* FALLTHRU */ 1809 /* FALLTHRU */
1815 case IEEE80211_S_AUTH: 1810 case IEEE80211_S_AUTH:
1816 case IEEE80211_S_ASSOC: 1811 case IEEE80211_S_ASSOC:
1817 case IEEE80211_S_INIT: 1812 case IEEE80211_S_INIT:
1818 ieee80211_begin_scan(ic, 1); 1813 ieee80211_begin_scan(ic, 1);
1819 /* FALLTHRU */ 1814 /* FALLTHRU */
1820 case IEEE80211_S_SCAN: 1815 case IEEE80211_S_SCAN:
1821 /* Scan next */ 1816 /* Scan next */
1822 break; 1817 break;
1823 } 1818 }
1824 if (ic->ic_flags & IEEE80211_F_ASCAN) 1819 if (ic->ic_flags & IEEE80211_F_ASCAN)
1825 newmode = AWI_SCAN_ACTIVE; 1820 newmode = AWI_SCAN_ACTIVE;
1826 else 1821 else
1827 newmode = AWI_SCAN_PASSIVE; 1822 newmode = AWI_SCAN_PASSIVE;
1828 if (sc->sc_mib_mgt.aScan_Mode != newmode) { 1823 if (sc->sc_mib_mgt.aScan_Mode != newmode) {
1829 sc->sc_mib_mgt.aScan_Mode = newmode; 1824 sc->sc_mib_mgt.aScan_Mode = newmode;
1830 if ((error = awi_mib(sc, AWI_CMD_SET_MIB, 1825 if ((error = awi_mib(sc, AWI_CMD_SET_MIB,
1831 AWI_MIB_MGT, AWI_NOWAIT)) != 0) 1826 AWI_MIB_MGT, AWI_NOWAIT)) != 0)
1832 break; 1827 break;
1833 } 1828 }
1834 /* FALLTHRU */ 1829 /* FALLTHRU */
1835 case AWI_ST_SCAN_SETMIB: 1830 case AWI_ST_SCAN_SETMIB:
1836 sc->sc_substate = AWI_ST_SCAN_SCCMD; 1831 sc->sc_substate = AWI_ST_SCAN_SCCMD;
1837 if (sc->sc_cmd_inprog) { 1832 if (sc->sc_cmd_inprog) {
1838 if ((error = awi_cmd_wait(sc)) != 0) 1833 if ((error = awi_cmd_wait(sc)) != 0)
1839 break; 1834 break;
1840 } 1835 }
1841 sc->sc_cmd_inprog = AWI_CMD_SCAN; 1836 sc->sc_cmd_inprog = AWI_CMD_SCAN;
1842 ni = ic->ic_bss; 1837 ni = ic->ic_bss;
1843 awi_write_2(sc, AWI_CA_SCAN_DURATION, 1838 awi_write_2(sc, AWI_CA_SCAN_DURATION,
1844 (ic->ic_flags & IEEE80211_F_ASCAN) ? 1839 (ic->ic_flags & IEEE80211_F_ASCAN) ?
1845 AWI_ASCAN_DURATION : AWI_PSCAN_DURATION); 1840 AWI_ASCAN_DURATION : AWI_PSCAN_DURATION);
1846 if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { 1841 if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
1847 awi_write_1(sc, AWI_CA_SCAN_SET, 1842 awi_write_1(sc, AWI_CA_SCAN_SET,
1848 IEEE80211_FH_CHANSET( 1843 IEEE80211_FH_CHANSET(
1849 ieee80211_chan2ieee(ic, ni->ni_chan))); 1844 ieee80211_chan2ieee(ic, ni->ni_chan)));
1850 awi_write_1(sc, AWI_CA_SCAN_PATTERN, 1845 awi_write_1(sc, AWI_CA_SCAN_PATTERN,
1851 IEEE80211_FH_CHANPAT( 1846 IEEE80211_FH_CHANPAT(
1852 ieee80211_chan2ieee(ic, ni->ni_chan))); 1847 ieee80211_chan2ieee(ic, ni->ni_chan)));
1853 awi_write_1(sc, AWI_CA_SCAN_IDX, 1); 1848 awi_write_1(sc, AWI_CA_SCAN_IDX, 1);
1854 } else { 1849 } else {
1855 awi_write_1(sc, AWI_CA_SCAN_SET, 1850 awi_write_1(sc, AWI_CA_SCAN_SET,
1856 ieee80211_chan2ieee(ic, ni->ni_chan)); 1851 ieee80211_chan2ieee(ic, ni->ni_chan));
1857 awi_write_1(sc, AWI_CA_SCAN_PATTERN, 0); 1852 awi_write_1(sc, AWI_CA_SCAN_PATTERN, 0);
1858 awi_write_1(sc, AWI_CA_SCAN_IDX, 0); 1853 awi_write_1(sc, AWI_CA_SCAN_IDX, 0);
1859 } 1854 }
1860 awi_write_1(sc, AWI_CA_SCAN_SUSP, 0); 1855 awi_write_1(sc, AWI_CA_SCAN_SUSP, 0);
1861 sc->sc_cur_chan = ieee80211_chan2ieee(ic, ni->ni_chan); 1856 sc->sc_cur_chan = ieee80211_chan2ieee(ic, ni->ni_chan);
1862 if ((error = awi_cmd(sc, AWI_CMD_SCAN, AWI_NOWAIT)) 1857 if ((error = awi_cmd(sc, AWI_CMD_SCAN, AWI_NOWAIT))
1863 != 0) 1858 != 0)

cvs diff -r1.253 -r1.254 src/sys/dev/ic/wi.c (switch to unified diff)

--- src/sys/dev/ic/wi.c 2019/05/28 07:41:48 1.253
+++ src/sys/dev/ic/wi.c 2019/12/05 03:11:40 1.254
@@ -1,2458 +1,2453 @@ @@ -1,2458 +1,2453 @@
1/* $NetBSD: wi.c,v 1.253 2019/05/28 07:41:48 msaitoh Exp $ */ 1/* $NetBSD: wi.c,v 1.254 2019/12/05 03:11:40 msaitoh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2004 The NetBSD Foundation, Inc. 4 * Copyright (c) 2004 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum. 8 * by Charles M. Hannum.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1997, 1998, 1999 33 * Copyright (c) 1997, 1998, 1999
34 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 34 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software 44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement: 45 * must display the following acknowledgement:
46 * This product includes software developed by Bill Paul. 46 * This product includes software developed by Bill Paul.
47 * 4. Neither the name of the author nor the names of any co-contributors 47 * 4. Neither the name of the author nor the names of any co-contributors
48 * may be used to endorse or promote products derived from this software 48 * may be used to endorse or promote products derived from this software
49 * without specific prior written permission. 49 * without specific prior written permission.
50 * 50 *
51 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 51 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 54 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
61 * THE POSSIBILITY OF SUCH DAMAGE. 61 * THE POSSIBILITY OF SUCH DAMAGE.
62 */ 62 */
63 63
64/* 64/*
65 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for NetBSD. 65 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for NetBSD.
66 * 66 *
67 * Original FreeBSD driver written by Bill Paul <wpaul@ctr.columbia.edu> 67 * Original FreeBSD driver written by Bill Paul <wpaul@ctr.columbia.edu>
68 * Electrical Engineering Department 68 * Electrical Engineering Department
69 * Columbia University, New York City 69 * Columbia University, New York City
70 */ 70 */
71 71
72/* 72/*
73 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN 73 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
74 * from Lucent. Unlike the older cards, the new ones are programmed 74 * from Lucent. Unlike the older cards, the new ones are programmed
75 * entirely via a firmware-driven controller called the Hermes. 75 * entirely via a firmware-driven controller called the Hermes.
76 * Unfortunately, Lucent will not release the Hermes programming manual 76 * Unfortunately, Lucent will not release the Hermes programming manual
77 * without an NDA (if at all). What they do release is an API library 77 * without an NDA (if at all). What they do release is an API library
78 * called the HCF (Hardware Control Functions) which is supposed to 78 * called the HCF (Hardware Control Functions) which is supposed to
79 * do the device-specific operations of a device driver for you. The 79 * do the device-specific operations of a device driver for you. The
80 * publically available version of the HCF library (the 'HCF Light') is 80 * publically available version of the HCF library (the 'HCF Light') is
81 * a) extremely gross, b) lacks certain features, particularly support 81 * a) extremely gross, b) lacks certain features, particularly support
82 * for 802.11 frames, and c) is contaminated by the GNU Public License. 82 * for 802.11 frames, and c) is contaminated by the GNU Public License.
83 * 83 *
84 * This driver does not use the HCF or HCF Light at all. Instead, it 84 * This driver does not use the HCF or HCF Light at all. Instead, it
85 * programs the Hermes controller directly, using information gleaned 85 * programs the Hermes controller directly, using information gleaned
86 * from the HCF Light code and corresponding documentation. 86 * from the HCF Light code and corresponding documentation.
87 * 87 *
88 * This driver supports both the PCMCIA and ISA versions of the 88 * This driver supports both the PCMCIA and ISA versions of the
89 * WaveLAN/IEEE cards. Note however that the ISA card isn't really 89 * WaveLAN/IEEE cards. Note however that the ISA card isn't really
90 * anything of the sort: it's actually a PCMCIA bridge adapter 90 * anything of the sort: it's actually a PCMCIA bridge adapter
91 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is 91 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is
92 * inserted. Consequently, you need to use the pccard support for 92 * inserted. Consequently, you need to use the pccard support for
93 * both the ISA and PCMCIA adapters. 93 * both the ISA and PCMCIA adapters.
94 */ 94 */
95 95
96/* 96/*
97 * FreeBSD driver ported to NetBSD by Bill Sommerfeld in the back of the 97 * FreeBSD driver ported to NetBSD by Bill Sommerfeld in the back of the
98 * Oslo IETF plenary meeting. 98 * Oslo IETF plenary meeting.
99 */ 99 */
100 100
101#include <sys/cdefs.h> 101#include <sys/cdefs.h>
102__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.253 2019/05/28 07:41:48 msaitoh Exp $"); 102__KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.254 2019/12/05 03:11:40 msaitoh Exp $");
103 103
104#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ 104#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */
105#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ 105#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */
106#undef WI_HISTOGRAM 106#undef WI_HISTOGRAM
107#undef WI_RING_DEBUG 107#undef WI_RING_DEBUG
108#define STATIC static 108#define STATIC static
109 109
110 110
111#include <sys/param.h> 111#include <sys/param.h>
112#include <sys/sysctl.h> 112#include <sys/sysctl.h>
113#include <sys/systm.h> 113#include <sys/systm.h>
114#include <sys/callout.h> 114#include <sys/callout.h>
115#include <sys/device.h> 115#include <sys/device.h>
116#include <sys/socket.h> 116#include <sys/socket.h>
117#include <sys/mbuf.h> 117#include <sys/mbuf.h>
118#include <sys/ioctl.h> 118#include <sys/ioctl.h>
119#include <sys/kernel.h> /* for hz */ 119#include <sys/kernel.h> /* for hz */
120#include <sys/proc.h> 120#include <sys/proc.h>
121#include <sys/kauth.h> 121#include <sys/kauth.h>
122 122
123#include <net/if.h> 123#include <net/if.h>
124#include <net/if_dl.h> 124#include <net/if_dl.h>
125#include <net/if_llc.h> 125#include <net/if_llc.h>
126#include <net/if_media.h> 126#include <net/if_media.h>
127#include <net/if_ether.h> 127#include <net/if_ether.h>
128#include <net/route.h> 128#include <net/route.h>
129#include <net/bpf.h> 129#include <net/bpf.h>
130 130
131#include <net80211/ieee80211_netbsd.h> 131#include <net80211/ieee80211_netbsd.h>
132#include <net80211/ieee80211_var.h> 132#include <net80211/ieee80211_var.h>
133#include <net80211/ieee80211_ioctl.h> 133#include <net80211/ieee80211_ioctl.h>
134#include <net80211/ieee80211_radiotap.h> 134#include <net80211/ieee80211_radiotap.h>
135#include <net80211/ieee80211_rssadapt.h> 135#include <net80211/ieee80211_rssadapt.h>
136 136
137#include <sys/bus.h> 137#include <sys/bus.h>
138#include <sys/intr.h> 138#include <sys/intr.h>
139 139
140#include <dev/ic/wi_ieee.h> 140#include <dev/ic/wi_ieee.h>
141#include <dev/ic/wireg.h> 141#include <dev/ic/wireg.h>
142#include <dev/ic/wivar.h> 142#include <dev/ic/wivar.h>
143 143
144STATIC int wi_init(struct ifnet *); 144STATIC int wi_init(struct ifnet *);
145STATIC void wi_stop(struct ifnet *, int); 145STATIC void wi_stop(struct ifnet *, int);
146STATIC void wi_start(struct ifnet *); 146STATIC void wi_start(struct ifnet *);
147STATIC int wi_reset(struct wi_softc *); 147STATIC int wi_reset(struct wi_softc *);
148STATIC void wi_watchdog(struct ifnet *); 148STATIC void wi_watchdog(struct ifnet *);
149STATIC int wi_ioctl(struct ifnet *, u_long, void *); 149STATIC int wi_ioctl(struct ifnet *, u_long, void *);
150STATIC int wi_media_change(struct ifnet *); 150STATIC int wi_media_change(struct ifnet *);
151STATIC void wi_media_status(struct ifnet *, struct ifmediareq *); 151STATIC void wi_media_status(struct ifnet *, struct ifmediareq *);
152STATIC void wi_softintr(void *); 152STATIC void wi_softintr(void *);
153 153
154static void wi_ioctl_init(struct wi_softc *); 154static void wi_ioctl_init(struct wi_softc *);
155static int wi_ioctl_enter(struct wi_softc *); 155static int wi_ioctl_enter(struct wi_softc *);
156static void wi_ioctl_exit(struct wi_softc *); 156static void wi_ioctl_exit(struct wi_softc *);
157static void wi_ioctl_drain(struct wi_softc *); 157static void wi_ioctl_drain(struct wi_softc *);
158 158
159STATIC struct ieee80211_node *wi_node_alloc(struct ieee80211_node_table *); 159STATIC struct ieee80211_node *wi_node_alloc(struct ieee80211_node_table *);
160STATIC void wi_node_free(struct ieee80211_node *); 160STATIC void wi_node_free(struct ieee80211_node *);
161 161
162STATIC void wi_raise_rate(struct ieee80211com *, struct ieee80211_rssdesc *); 162STATIC void wi_raise_rate(struct ieee80211com *, struct ieee80211_rssdesc *);
163STATIC void wi_lower_rate(struct ieee80211com *, struct ieee80211_rssdesc *); 163STATIC void wi_lower_rate(struct ieee80211com *, struct ieee80211_rssdesc *);
164STATIC int wi_choose_rate(struct ieee80211com *, struct ieee80211_node *, 164STATIC int wi_choose_rate(struct ieee80211com *, struct ieee80211_node *,
165 struct ieee80211_frame *, u_int); 165 struct ieee80211_frame *, u_int);
166STATIC void wi_rssadapt_updatestats_cb(void *, struct ieee80211_node *); 166STATIC void wi_rssadapt_updatestats_cb(void *, struct ieee80211_node *);
167STATIC void wi_rssadapt_updatestats(void *); 167STATIC void wi_rssadapt_updatestats(void *);
168STATIC void wi_rssdescs_init(struct wi_rssdesc (*)[], wi_rssdescq_t *); 168STATIC void wi_rssdescs_init(struct wi_rssdesc (*)[], wi_rssdescq_t *);
169STATIC void wi_rssdescs_reset(struct ieee80211com *, struct wi_rssdesc (*)[], 169STATIC void wi_rssdescs_reset(struct ieee80211com *, struct wi_rssdesc (*)[],
170 wi_rssdescq_t *, uint8_t (*)[]); 170 wi_rssdescq_t *, uint8_t (*)[]);
171STATIC void wi_sync_bssid(struct wi_softc *, uint8_t new_bssid[]); 171STATIC void wi_sync_bssid(struct wi_softc *, uint8_t new_bssid[]);
172 172
173STATIC void wi_rx_intr(struct wi_softc *); 173STATIC void wi_rx_intr(struct wi_softc *);
174STATIC void wi_txalloc_intr(struct wi_softc *); 174STATIC void wi_txalloc_intr(struct wi_softc *);
175STATIC void wi_cmd_intr(struct wi_softc *); 175STATIC void wi_cmd_intr(struct wi_softc *);
176STATIC void wi_tx_intr(struct wi_softc *); 176STATIC void wi_tx_intr(struct wi_softc *);
177STATIC void wi_tx_ex_intr(struct wi_softc *); 177STATIC void wi_tx_ex_intr(struct wi_softc *);
178STATIC void wi_info_intr(struct wi_softc *); 178STATIC void wi_info_intr(struct wi_softc *);
179 179
180STATIC int wi_key_delete(struct ieee80211com *, const struct ieee80211_key *); 180STATIC int wi_key_delete(struct ieee80211com *, const struct ieee80211_key *);
181STATIC int wi_key_set(struct ieee80211com *, const struct ieee80211_key *, 181STATIC int wi_key_set(struct ieee80211com *, const struct ieee80211_key *,
182 const uint8_t[IEEE80211_ADDR_LEN]); 182 const uint8_t[IEEE80211_ADDR_LEN]);
183STATIC void wi_key_update_begin(struct ieee80211com *); 183STATIC void wi_key_update_begin(struct ieee80211com *);
184STATIC void wi_key_update_end(struct ieee80211com *); 184STATIC void wi_key_update_end(struct ieee80211com *);
185 185
186STATIC void wi_push_packet(struct wi_softc *); 186STATIC void wi_push_packet(struct wi_softc *);
187STATIC int wi_get_cfg(struct ifnet *, u_long, void *); 187STATIC int wi_get_cfg(struct ifnet *, u_long, void *);
188STATIC int wi_set_cfg(struct ifnet *, u_long, void *); 188STATIC int wi_set_cfg(struct ifnet *, u_long, void *);
189STATIC int wi_cfg_txrate(struct wi_softc *); 189STATIC int wi_cfg_txrate(struct wi_softc *);
190STATIC int wi_write_txrate(struct wi_softc *, int); 190STATIC int wi_write_txrate(struct wi_softc *, int);
191STATIC int wi_write_wep(struct wi_softc *); 191STATIC int wi_write_wep(struct wi_softc *);
192STATIC int wi_write_multi(struct wi_softc *); 192STATIC int wi_write_multi(struct wi_softc *);
193STATIC int wi_alloc_fid(struct wi_softc *, int, int *); 193STATIC int wi_alloc_fid(struct wi_softc *, int, int *);
194STATIC void wi_read_nicid(struct wi_softc *); 194STATIC void wi_read_nicid(struct wi_softc *);
195STATIC int wi_write_ssid(struct wi_softc *, int, uint8_t *, int); 195STATIC int wi_write_ssid(struct wi_softc *, int, uint8_t *, int);
196 196
197STATIC int wi_cmd(struct wi_softc *, int, int, int, int); 197STATIC int wi_cmd(struct wi_softc *, int, int, int, int);
198STATIC int wi_cmd_start(struct wi_softc *, int, int, int, int); 198STATIC int wi_cmd_start(struct wi_softc *, int, int, int, int);
199STATIC int wi_cmd_wait(struct wi_softc *, int, int); 199STATIC int wi_cmd_wait(struct wi_softc *, int, int);
200STATIC int wi_seek_bap(struct wi_softc *, int, int); 200STATIC int wi_seek_bap(struct wi_softc *, int, int);
201STATIC int wi_read_bap(struct wi_softc *, int, int, void *, int); 201STATIC int wi_read_bap(struct wi_softc *, int, int, void *, int);
202STATIC int wi_write_bap(struct wi_softc *, int, int, void *, int); 202STATIC int wi_write_bap(struct wi_softc *, int, int, void *, int);
203STATIC int wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int); 203STATIC int wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int);
204STATIC int wi_read_rid(struct wi_softc *, int, void *, int *); 204STATIC int wi_read_rid(struct wi_softc *, int, void *, int *);
205STATIC int wi_write_rid(struct wi_softc *, int, void *, int); 205STATIC int wi_write_rid(struct wi_softc *, int, void *, int);
206 206
207STATIC int wi_newstate(struct ieee80211com *, enum ieee80211_state, int); 207STATIC int wi_newstate(struct ieee80211com *, enum ieee80211_state, int);
208STATIC void wi_set_tim(struct ieee80211_node *, int); 208STATIC void wi_set_tim(struct ieee80211_node *, int);
209 209
210STATIC int wi_scan_ap(struct wi_softc *, uint16_t, uint16_t); 210STATIC int wi_scan_ap(struct wi_softc *, uint16_t, uint16_t);
211STATIC void wi_scan_result(struct wi_softc *, int, int); 211STATIC void wi_scan_result(struct wi_softc *, int, int);
212 212
213STATIC void wi_dump_pkt(struct wi_frame *, struct ieee80211_node *, int rssi); 213STATIC void wi_dump_pkt(struct wi_frame *, struct ieee80211_node *, int rssi);
214STATIC void wi_mend_flags(struct wi_softc *, enum ieee80211_state); 214STATIC void wi_mend_flags(struct wi_softc *, enum ieee80211_state);
215 215
216static inline int 216static inline int
217wi_write_val(struct wi_softc *sc, int rid, uint16_t val) 217wi_write_val(struct wi_softc *sc, int rid, uint16_t val)
218{ 218{
219 219
220 val = htole16(val); 220 val = htole16(val);
221 return wi_write_rid(sc, rid, &val, sizeof(val)); 221 return wi_write_rid(sc, rid, &val, sizeof(val));
222} 222}
223 223
224static struct timeval lasttxerror; /* time of last tx error msg */ 224static struct timeval lasttxerror; /* time of last tx error msg */
225static int curtxeps = 0; /* current tx error msgs/sec */ 225static int curtxeps = 0; /* current tx error msgs/sec */
226static int wi_txerate = 0; /* tx error rate: max msgs/sec */ 226static int wi_txerate = 0; /* tx error rate: max msgs/sec */
227 227
228#ifdef WI_DEBUG 228#ifdef WI_DEBUG
229#define WI_DEBUG_MAX 2 229#define WI_DEBUG_MAX 2
230int wi_debug = 0; 230int wi_debug = 0;
231 231
232#define DPRINTF(X) if (wi_debug) printf X 232#define DPRINTF(X) if (wi_debug) printf X
233#define DPRINTF2(X) if (wi_debug > 1) printf X 233#define DPRINTF2(X) if (wi_debug > 1) printf X
234#define IFF_DUMPPKTS(_ifp) \ 234#define IFF_DUMPPKTS(_ifp) \
235 (((_ifp)->if_flags & (IFF_DEBUG |IFF_LINK2)) == (IFF_DEBUG |IFF_LINK2)) 235 (((_ifp)->if_flags & (IFF_DEBUG |IFF_LINK2)) == (IFF_DEBUG |IFF_LINK2))
236static int wi_sysctl_verify_debug(SYSCTLFN_PROTO); 236static int wi_sysctl_verify_debug(SYSCTLFN_PROTO);
237#else 237#else
238#define DPRINTF(X) 238#define DPRINTF(X)
239#define DPRINTF2(X) 239#define DPRINTF2(X)
240#define IFF_DUMPPKTS(_ifp) 0 240#define IFF_DUMPPKTS(_ifp) 0
241#endif 241#endif
242 242
243#define WI_INTRS (WI_EV_RX | WI_EV_ALLOC | WI_EV_INFO | \ 243#define WI_INTRS (WI_EV_RX | WI_EV_ALLOC | WI_EV_INFO | \
244 WI_EV_TX | WI_EV_TX_EXC | WI_EV_CMD) 244 WI_EV_TX | WI_EV_TX_EXC | WI_EV_CMD)
245 245
246static const struct wi_card_ident wi_card_ident[] = { 246static const struct wi_card_ident wi_card_ident[] = {
247 /* CARD_ID CARD_NAME FIRM_TYPE */ 247 /* CARD_ID CARD_NAME FIRM_TYPE */
248 { WI_NIC_LUCENT_ID, WI_NIC_LUCENT_STR, WI_LUCENT }, 248 { WI_NIC_LUCENT_ID, WI_NIC_LUCENT_STR, WI_LUCENT },
249 { WI_NIC_SONY_ID, WI_NIC_SONY_STR, WI_LUCENT }, 249 { WI_NIC_SONY_ID, WI_NIC_SONY_STR, WI_LUCENT },
250 { WI_NIC_LUCENT_EMB_ID, WI_NIC_LUCENT_EMB_STR, WI_LUCENT }, 250 { WI_NIC_LUCENT_EMB_ID, WI_NIC_LUCENT_EMB_STR, WI_LUCENT },
251 { WI_NIC_EVB2_ID, WI_NIC_EVB2_STR, WI_INTERSIL }, 251 { WI_NIC_EVB2_ID, WI_NIC_EVB2_STR, WI_INTERSIL },
252 { WI_NIC_HWB3763_ID, WI_NIC_HWB3763_STR, WI_INTERSIL }, 252 { WI_NIC_HWB3763_ID, WI_NIC_HWB3763_STR, WI_INTERSIL },
253 { WI_NIC_HWB3163_ID, WI_NIC_HWB3163_STR, WI_INTERSIL }, 253 { WI_NIC_HWB3163_ID, WI_NIC_HWB3163_STR, WI_INTERSIL },
254 { WI_NIC_HWB3163B_ID, WI_NIC_HWB3163B_STR, WI_INTERSIL }, 254 { WI_NIC_HWB3163B_ID, WI_NIC_HWB3163B_STR, WI_INTERSIL },
255 { WI_NIC_EVB3_ID, WI_NIC_EVB3_STR, WI_INTERSIL }, 255 { WI_NIC_EVB3_ID, WI_NIC_EVB3_STR, WI_INTERSIL },
256 { WI_NIC_HWB1153_ID, WI_NIC_HWB1153_STR, WI_INTERSIL }, 256 { WI_NIC_HWB1153_ID, WI_NIC_HWB1153_STR, WI_INTERSIL },
257 { WI_NIC_P2_SST_ID, WI_NIC_P2_SST_STR, WI_INTERSIL }, 257 { WI_NIC_P2_SST_ID, WI_NIC_P2_SST_STR, WI_INTERSIL },
258 { WI_NIC_EVB2_SST_ID, WI_NIC_EVB2_SST_STR, WI_INTERSIL }, 258 { WI_NIC_EVB2_SST_ID, WI_NIC_EVB2_SST_STR, WI_INTERSIL },
259 { WI_NIC_3842_EVA_ID, WI_NIC_3842_EVA_STR, WI_INTERSIL }, 259 { WI_NIC_3842_EVA_ID, WI_NIC_3842_EVA_STR, WI_INTERSIL },
260 { WI_NIC_3842_PCMCIA_AMD_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 260 { WI_NIC_3842_PCMCIA_AMD_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL },
261 { WI_NIC_3842_PCMCIA_SST_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 261 { WI_NIC_3842_PCMCIA_SST_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL },
262 { WI_NIC_3842_PCMCIA_ATM_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL }, 262 { WI_NIC_3842_PCMCIA_ATM_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL },
263 { WI_NIC_3842_MINI_AMD_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 263 { WI_NIC_3842_MINI_AMD_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL },
264 { WI_NIC_3842_MINI_SST_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 264 { WI_NIC_3842_MINI_SST_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL },
265 { WI_NIC_3842_MINI_ATM_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL }, 265 { WI_NIC_3842_MINI_ATM_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL },
266 { WI_NIC_3842_PCI_AMD_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 266 { WI_NIC_3842_PCI_AMD_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL },
267 { WI_NIC_3842_PCI_SST_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 267 { WI_NIC_3842_PCI_SST_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL },
268 { WI_NIC_3842_PCI_ATM_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL }, 268 { WI_NIC_3842_PCI_ATM_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL },
269 { WI_NIC_P3_PCMCIA_AMD_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL }, 269 { WI_NIC_P3_PCMCIA_AMD_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL },
270 { WI_NIC_P3_PCMCIA_SST_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL }, 270 { WI_NIC_P3_PCMCIA_SST_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL },
271 { WI_NIC_P3_MINI_AMD_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL }, 271 { WI_NIC_P3_MINI_AMD_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL },
272 { WI_NIC_P3_MINI_SST_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL }, 272 { WI_NIC_P3_MINI_SST_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL },
273 { 0, NULL, 0 }, 273 { 0, NULL, 0 },
274}; 274};
275 275
276#ifndef _MODULE 276#ifndef _MODULE
277/* 277/*
278 * Setup sysctl(3) MIB, hw.wi.* 278 * Setup sysctl(3) MIB, hw.wi.*
279 * 279 *
280 * TBD condition CTLFLAG_PERMANENT on being a module or not 280 * TBD condition CTLFLAG_PERMANENT on being a module or not
281 */ 281 */
282SYSCTL_SETUP(sysctl_wi, "sysctl wi(4) subtree setup") 282SYSCTL_SETUP(sysctl_wi, "sysctl wi(4) subtree setup")
283{ 283{
284 int rc; 284 int rc;
285 const struct sysctlnode *rnode; 285 const struct sysctlnode *rnode;
286#ifdef WI_DEBUG 286#ifdef WI_DEBUG
287 const struct sysctlnode *cnode; 287 const struct sysctlnode *cnode;
288#endif /* WI_DEBUG */ 288#endif /* WI_DEBUG */
289 289
290 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 290 if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
291 CTLFLAG_PERMANENT, CTLTYPE_NODE, "wi", 291 CTLFLAG_PERMANENT, CTLTYPE_NODE, "wi",
292 "Lucent/Prism/Symbol 802.11 controls", 292 "Lucent/Prism/Symbol 802.11 controls",
293 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) 293 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
294 goto err; 294 goto err;
295 295
296#ifdef WI_DEBUG 296#ifdef WI_DEBUG
297 /* control debugging printfs */ 297 /* control debugging printfs */
298 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode, 298 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
299 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 299 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
300 "debug", SYSCTL_DESCR("Enable debugging output"), 300 "debug", SYSCTL_DESCR("Enable debugging output"),
301 wi_sysctl_verify_debug, 0, &wi_debug, 0, CTL_CREATE, CTL_EOL)) != 0) 301 wi_sysctl_verify_debug, 0, &wi_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
302 goto err; 302 goto err;
303#endif /* WI_DEBUG */ 303#endif /* WI_DEBUG */
304 return; 304 return;
305err: 305err:
306 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 306 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
307} 307}
308#endif 308#endif
309 309
310#ifdef WI_DEBUG 310#ifdef WI_DEBUG
311static int 311static int
312wi_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper) 312wi_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper)
313{ 313{
314 int error, t; 314 int error, t;
315 struct sysctlnode node; 315 struct sysctlnode node;
316 316
317 node = *rnode; 317 node = *rnode;
318 t = *(int*)rnode->sysctl_data; 318 t = *(int*)rnode->sysctl_data;
319 node.sysctl_data = &t; 319 node.sysctl_data = &t;
320 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 320 error = sysctl_lookup(SYSCTLFN_CALL(&node));
321 if (error || newp == NULL) 321 if (error || newp == NULL)
322 return (error); 322 return (error);
323 323
324 if (t < lower || t > upper) 324 if (t < lower || t > upper)
325 return (EINVAL); 325 return (EINVAL);
326 326
327 *(int*)rnode->sysctl_data = t; 327 *(int*)rnode->sysctl_data = t;
328 328
329 return (0); 329 return (0);
330} 330}
331 331
332static int 332static int
333wi_sysctl_verify_debug(SYSCTLFN_ARGS) 333wi_sysctl_verify_debug(SYSCTLFN_ARGS)
334{ 334{
335 return wi_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 335 return wi_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)),
336 0, WI_DEBUG_MAX); 336 0, WI_DEBUG_MAX);
337} 337}
338#endif /* WI_DEBUG */ 338#endif /* WI_DEBUG */
339 339
340STATIC int 340STATIC int
341wi_read_xrid(struct wi_softc *sc, int rid, void *buf, int ebuflen) 341wi_read_xrid(struct wi_softc *sc, int rid, void *buf, int ebuflen)
342{ 342{
343 int buflen, rc; 343 int buflen, rc;
344 344
345 buflen = ebuflen; 345 buflen = ebuflen;
346 if ((rc = wi_read_rid(sc, rid, buf, &buflen)) != 0) 346 if ((rc = wi_read_rid(sc, rid, buf, &buflen)) != 0)
347 return rc; 347 return rc;
348 348
349 if (buflen < ebuflen) { 349 if (buflen < ebuflen) {
350#ifdef WI_DEBUG 350#ifdef WI_DEBUG
351 printf("%s: rid=%#04x read %d, expected %d\n", __func__, 351 printf("%s: rid=%#04x read %d, expected %d\n", __func__,
352 rid, buflen, ebuflen); 352 rid, buflen, ebuflen);
353#endif 353#endif
354 return -1; 354 return -1;
355 } 355 }
356 return 0; 356 return 0;
357} 357}
358 358
359int 359int
360wi_attach(struct wi_softc *sc, const uint8_t *macaddr) 360wi_attach(struct wi_softc *sc, const uint8_t *macaddr)
361{ 361{
362 struct ieee80211com *ic = &sc->sc_ic; 362 struct ieee80211com *ic = &sc->sc_ic;
363 struct ifnet *ifp = &sc->sc_if; 363 struct ifnet *ifp = &sc->sc_if;
364 int chan, nrate, buflen; 364 int chan, nrate, buflen;
365 uint16_t val, chanavail; 365 uint16_t val, chanavail;
366 struct { 366 struct {
367 uint16_t nrates; 367 uint16_t nrates;
368 char rates[IEEE80211_RATE_SIZE]; 368 char rates[IEEE80211_RATE_SIZE];
369 } ratebuf; 369 } ratebuf;
370 static const uint8_t empty_macaddr[IEEE80211_ADDR_LEN] = { 370 static const uint8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
372 }; 372 };
373 int s, rv; 373 int s, rv;
374 374
375 sc->sc_soft_ih = softint_establish(SOFTINT_NET, wi_softintr, sc); 375 sc->sc_soft_ih = softint_establish(SOFTINT_NET, wi_softintr, sc);
376 if (sc->sc_soft_ih == NULL) { 376 if (sc->sc_soft_ih == NULL) {
377 printf(" could not establish softint\n"); 377 printf(" could not establish softint\n");
378 goto err; 378 goto err;
379 } 379 }
380 380
381 wi_ioctl_init(sc); 381 wi_ioctl_init(sc);
382 382
383 s = splnet(); 383 s = splnet();
384 384
385 /* Make sure interrupts are disabled. */ 385 /* Make sure interrupts are disabled. */
386 CSR_WRITE_2(sc, WI_INT_EN, 0); 386 CSR_WRITE_2(sc, WI_INT_EN, 0);
387 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0); 387 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
388 388
389 sc->sc_invalid = 0; 389 sc->sc_invalid = 0;
390 390
391 /* Reset the NIC. */ 391 /* Reset the NIC. */
392 if (wi_reset(sc) != 0) { 392 if (wi_reset(sc) != 0) {
393 sc->sc_invalid = 1; 393 sc->sc_invalid = 1;
394 goto fail; 394 goto fail;
395 } 395 }
396 396
397 if (wi_read_xrid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, 397 if (wi_read_xrid(sc, WI_RID_MAC_NODE, ic->ic_myaddr,
398 IEEE80211_ADDR_LEN) != 0 || 398 IEEE80211_ADDR_LEN) != 0 ||
399 IEEE80211_ADDR_EQ(ic->ic_myaddr, empty_macaddr)) { 399 IEEE80211_ADDR_EQ(ic->ic_myaddr, empty_macaddr)) {
400 if (macaddr != NULL) 400 if (macaddr != NULL)
401 memcpy(ic->ic_myaddr, macaddr, IEEE80211_ADDR_LEN); 401 memcpy(ic->ic_myaddr, macaddr, IEEE80211_ADDR_LEN);
402 else { 402 else {
403 printf(" could not get mac address, attach failed\n"); 403 printf(" could not get mac address, attach failed\n");
404 goto fail; 404 goto fail;
405 } 405 }
406 } 406 }
407 407
408 printf(" 802.11 address %s\n", ether_sprintf(ic->ic_myaddr)); 408 printf(" 802.11 address %s\n", ether_sprintf(ic->ic_myaddr));
409 409
410 /* Read NIC identification */ 410 /* Read NIC identification */
411 wi_read_nicid(sc); 411 wi_read_nicid(sc);
412 412
413 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 413 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
414 ifp->if_softc = sc; 414 ifp->if_softc = sc;
415 ifp->if_start = wi_start; 415 ifp->if_start = wi_start;
416 ifp->if_ioctl = wi_ioctl; 416 ifp->if_ioctl = wi_ioctl;
417 ifp->if_watchdog = wi_watchdog; 417 ifp->if_watchdog = wi_watchdog;
418 ifp->if_init = wi_init; 418 ifp->if_init = wi_init;
419 ifp->if_stop = wi_stop; 419 ifp->if_stop = wi_stop;
420 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 420 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
421 IFQ_SET_READY(&ifp->if_snd); 421 IFQ_SET_READY(&ifp->if_snd);
422 422
423 ic->ic_ifp = ifp; 423 ic->ic_ifp = ifp;
424 ic->ic_phytype = IEEE80211_T_DS; 424 ic->ic_phytype = IEEE80211_T_DS;
425 ic->ic_opmode = IEEE80211_M_STA; 425 ic->ic_opmode = IEEE80211_M_STA;
426 ic->ic_caps = IEEE80211_C_AHDEMO; 426 ic->ic_caps = IEEE80211_C_AHDEMO;
427 ic->ic_state = IEEE80211_S_INIT; 427 ic->ic_state = IEEE80211_S_INIT;
428 ic->ic_max_aid = WI_MAX_AID; 428 ic->ic_max_aid = WI_MAX_AID;
429 429
430 /* Find available channel */ 430 /* Find available channel */
431 if (wi_read_xrid(sc, WI_RID_CHANNEL_LIST, &chanavail, 431 if (wi_read_xrid(sc, WI_RID_CHANNEL_LIST, &chanavail,
432 sizeof(chanavail)) != 0) { 432 sizeof(chanavail)) != 0) {
433 aprint_normal_dev(sc->sc_dev, "using default channel list\n"); 433 aprint_normal_dev(sc->sc_dev, "using default channel list\n");
434 chanavail = htole16(0x1fff); /* assume 1-13 */ 434 chanavail = htole16(0x1fff); /* assume 1-13 */
435 } 435 }
436 for (chan = 16; chan > 0; chan--) { 436 for (chan = 16; chan > 0; chan--) {
437 if (!isset((uint8_t*)&chanavail, chan - 1)) 437 if (!isset((uint8_t*)&chanavail, chan - 1))
438 continue; 438 continue;
439 ic->ic_ibss_chan = &ic->ic_channels[chan]; 439 ic->ic_ibss_chan = &ic->ic_channels[chan];
440 ic->ic_channels[chan].ic_freq = 440 ic->ic_channels[chan].ic_freq =
441 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); 441 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
442 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B; 442 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B;
443 } 443 }
444 444
445 /* Find default IBSS channel */ 445 /* Find default IBSS channel */
446 if (wi_read_xrid(sc, WI_RID_OWN_CHNL, &val, sizeof(val)) == 0) { 446 if (wi_read_xrid(sc, WI_RID_OWN_CHNL, &val, sizeof(val)) == 0) {
447 chan = le16toh(val); 447 chan = le16toh(val);
448 if (isset((uint8_t*)&chanavail, chan - 1)) 448 if (isset((uint8_t*)&chanavail, chan - 1))
449 ic->ic_ibss_chan = &ic->ic_channels[chan]; 449 ic->ic_ibss_chan = &ic->ic_channels[chan];
450 } 450 }
451 if (ic->ic_ibss_chan == NULL) { 451 if (ic->ic_ibss_chan == NULL) {
452 aprint_error_dev(sc->sc_dev, "no available channel\n"); 452 aprint_error_dev(sc->sc_dev, "no available channel\n");
453 goto fail; 453 goto fail;
454 } 454 }
455 455
456 if (sc->sc_firmware_type == WI_LUCENT) { 456 if (sc->sc_firmware_type == WI_LUCENT) {
457 sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET; 457 sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET;
458 } else { 458 } else {
459 if ((sc->sc_flags & WI_FLAGS_HAS_DBMADJUST) && 459 if ((sc->sc_flags & WI_FLAGS_HAS_DBMADJUST) &&
460 wi_read_xrid(sc, WI_RID_DBM_ADJUST, &val, sizeof(val)) == 0) 460 wi_read_xrid(sc, WI_RID_DBM_ADJUST, &val, sizeof(val)) == 0)
461 sc->sc_dbm_offset = le16toh(val); 461 sc->sc_dbm_offset = le16toh(val);
462 else 462 else
463 sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET; 463 sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;
464 } 464 }
465 465
466 sc->sc_flags |= WI_FLAGS_RSSADAPTSTA; 466 sc->sc_flags |= WI_FLAGS_RSSADAPTSTA;
467 467
468 /* 468 /*
469 * Set flags based on firmware version. 469 * Set flags based on firmware version.
470 */ 470 */
471 switch (sc->sc_firmware_type) { 471 switch (sc->sc_firmware_type) {
472 case WI_LUCENT: 472 case WI_LUCENT:
473 sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE; 473 sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
474#ifdef WI_HERMES_AUTOINC_WAR 474#ifdef WI_HERMES_AUTOINC_WAR
475 /* XXX: not confirmed, but never seen for recent firmware */ 475 /* XXX: not confirmed, but never seen for recent firmware */
476 if (sc->sc_sta_firmware_ver < 40000) { 476 if (sc->sc_sta_firmware_ver < 40000) {
477 sc->sc_flags |= WI_FLAGS_BUG_AUTOINC; 477 sc->sc_flags |= WI_FLAGS_BUG_AUTOINC;
478 } 478 }
479#endif 479#endif
480 if (sc->sc_sta_firmware_ver >= 60000) 480 if (sc->sc_sta_firmware_ver >= 60000)
481 sc->sc_flags |= WI_FLAGS_HAS_MOR; 481 sc->sc_flags |= WI_FLAGS_HAS_MOR;
482 if (sc->sc_sta_firmware_ver >= 60006) { 482 if (sc->sc_sta_firmware_ver >= 60006) {
483 ic->ic_caps |= IEEE80211_C_IBSS; 483 ic->ic_caps |= IEEE80211_C_IBSS;
484 ic->ic_caps |= IEEE80211_C_MONITOR; 484 ic->ic_caps |= IEEE80211_C_MONITOR;
485 } 485 }
486 ic->ic_caps |= IEEE80211_C_PMGT; 486 ic->ic_caps |= IEEE80211_C_PMGT;
487 sc->sc_ibss_port = 1; 487 sc->sc_ibss_port = 1;
488 break; 488 break;
489 489
490 case WI_INTERSIL: 490 case WI_INTERSIL:
491 sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR; 491 sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR;
492 sc->sc_flags |= WI_FLAGS_HAS_ROAMING; 492 sc->sc_flags |= WI_FLAGS_HAS_ROAMING;
493 sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE; 493 sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
494 if (sc->sc_sta_firmware_ver > 10101) 494 if (sc->sc_sta_firmware_ver > 10101)
495 sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST; 495 sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST;
496 if (sc->sc_sta_firmware_ver >= 800) { 496 if (sc->sc_sta_firmware_ver >= 800) {
497 if (sc->sc_sta_firmware_ver != 10402) 497 if (sc->sc_sta_firmware_ver != 10402)
498 ic->ic_caps |= IEEE80211_C_HOSTAP; 498 ic->ic_caps |= IEEE80211_C_HOSTAP;
499 ic->ic_caps |= IEEE80211_C_IBSS; 499 ic->ic_caps |= IEEE80211_C_IBSS;
500 ic->ic_caps |= IEEE80211_C_MONITOR; 500 ic->ic_caps |= IEEE80211_C_MONITOR;
501 } 501 }
502 ic->ic_caps |= IEEE80211_C_PMGT; 502 ic->ic_caps |= IEEE80211_C_PMGT;
503 sc->sc_ibss_port = 0; 503 sc->sc_ibss_port = 0;
504 sc->sc_alt_retry = 2; 504 sc->sc_alt_retry = 2;
505 break; 505 break;
506 506
507 case WI_SYMBOL: 507 case WI_SYMBOL:
508 sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY; 508 sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY;
509 if (sc->sc_sta_firmware_ver >= 20000) 509 if (sc->sc_sta_firmware_ver >= 20000)
510 ic->ic_caps |= IEEE80211_C_IBSS; 510 ic->ic_caps |= IEEE80211_C_IBSS;
511 sc->sc_ibss_port = 4; 511 sc->sc_ibss_port = 4;
512 break; 512 break;
513 } 513 }
514 514
515 /* 515 /*
516 * Find out if we support WEP on this card. 516 * Find out if we support WEP on this card.
517 */ 517 */
518 if (wi_read_xrid(sc, WI_RID_WEP_AVAIL, &val, sizeof(val)) == 0 && 518 if (wi_read_xrid(sc, WI_RID_WEP_AVAIL, &val, sizeof(val)) == 0 &&
519 val != htole16(0)) 519 val != htole16(0))
520 ic->ic_caps |= IEEE80211_C_WEP; 520 ic->ic_caps |= IEEE80211_C_WEP;
521 521
522 /* Find supported rates. */ 522 /* Find supported rates. */
523 buflen = sizeof(ratebuf); 523 buflen = sizeof(ratebuf);
524 if (wi_read_rid(sc, WI_RID_DATA_RATES, &ratebuf, &buflen) == 0 && 524 if (wi_read_rid(sc, WI_RID_DATA_RATES, &ratebuf, &buflen) == 0 &&
525 buflen > 2) { 525 buflen > 2) {
526 nrate = le16toh(ratebuf.nrates); 526 nrate = le16toh(ratebuf.nrates);
527 if (nrate > IEEE80211_RATE_SIZE) 527 if (nrate > IEEE80211_RATE_SIZE)
528 nrate = IEEE80211_RATE_SIZE; 528 nrate = IEEE80211_RATE_SIZE;
529 memcpy(ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates, 529 memcpy(ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates,
530 &ratebuf.rates[0], nrate); 530 &ratebuf.rates[0], nrate);
531 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate; 531 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate;
532 } else { 532 } else {
533 aprint_error_dev(sc->sc_dev, "no supported rate list\n"); 533 aprint_error_dev(sc->sc_dev, "no supported rate list\n");
534 goto fail; 534 goto fail;
535 } 535 }
536 536
537 sc->sc_max_datalen = 2304; 537 sc->sc_max_datalen = 2304;
538 sc->sc_rts_thresh = 2347; 538 sc->sc_rts_thresh = 2347;
539 sc->sc_frag_thresh = 2346; 539 sc->sc_frag_thresh = 2346;
540 sc->sc_system_scale = 1; 540 sc->sc_system_scale = 1;
541 sc->sc_cnfauthmode = IEEE80211_AUTH_OPEN; 541 sc->sc_cnfauthmode = IEEE80211_AUTH_OPEN;
542 sc->sc_roaming_mode = 1; 542 sc->sc_roaming_mode = 1;
543 543
544 callout_init(&sc->sc_rssadapt_ch, 0); 544 callout_init(&sc->sc_rssadapt_ch, 0);
545 545
546 /* 546 /*
547 * Call MI attach routines. 547 * Call MI attach routines.
548 */ 548 */
549 rv = if_initialize(ifp); 549 rv = if_initialize(ifp);
550 if (rv != 0) { 550 if (rv != 0) {
551 aprint_error_dev(sc->sc_dev, "if_initialize failed(%d)\n", rv); 551 aprint_error_dev(sc->sc_dev, "if_initialize failed(%d)\n", rv);
552 goto fail_2; 552 goto fail_2;
553 } 553 }
554 ieee80211_ifattach(ic); 554 ieee80211_ifattach(ic);
555 /* Use common softint-based if_input */ 555 /* Use common softint-based if_input */
556 ifp->if_percpuq = if_percpuq_create(ifp); 556 ifp->if_percpuq = if_percpuq_create(ifp);
557 if_register(ifp); 557 if_register(ifp);
558 558
559 sc->sc_newstate = ic->ic_newstate; 559 sc->sc_newstate = ic->ic_newstate;
560 sc->sc_set_tim = ic->ic_set_tim; 560 sc->sc_set_tim = ic->ic_set_tim;
561 ic->ic_newstate = wi_newstate; 561 ic->ic_newstate = wi_newstate;
562 ic->ic_node_alloc = wi_node_alloc; 562 ic->ic_node_alloc = wi_node_alloc;
563 ic->ic_node_free = wi_node_free; 563 ic->ic_node_free = wi_node_free;
564 ic->ic_set_tim = wi_set_tim; 564 ic->ic_set_tim = wi_set_tim;
565 565
566 ic->ic_crypto.cs_key_delete = wi_key_delete; 566 ic->ic_crypto.cs_key_delete = wi_key_delete;
567 ic->ic_crypto.cs_key_set = wi_key_set; 567 ic->ic_crypto.cs_key_set = wi_key_set;
568 ic->ic_crypto.cs_key_update_begin = wi_key_update_begin; 568 ic->ic_crypto.cs_key_update_begin = wi_key_update_begin;
569 ic->ic_crypto.cs_key_update_end = wi_key_update_end; 569 ic->ic_crypto.cs_key_update_end = wi_key_update_end;
570 570
571 ieee80211_media_init(ic, wi_media_change, wi_media_status); 571 ieee80211_media_init(ic, wi_media_change, wi_media_status);
572 572
573 bpf_attach2(ifp, DLT_IEEE802_11_RADIO, 573 bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
574 sizeof(struct ieee80211_frame) + 64, &sc->sc_drvbpf); 574 sizeof(struct ieee80211_frame) + 64, &sc->sc_drvbpf);
575 575
576 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu)); 576 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
577 sc->sc_rxtap.wr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu)); 577 sc->sc_rxtap.wr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu));
578 sc->sc_rxtap.wr_ihdr.it_present = htole32(WI_RX_RADIOTAP_PRESENT); 578 sc->sc_rxtap.wr_ihdr.it_present = htole32(WI_RX_RADIOTAP_PRESENT);
579 579
580 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu)); 580 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
581 sc->sc_txtap.wt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu)); 581 sc->sc_txtap.wt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu));
582 sc->sc_txtap.wt_ihdr.it_present = htole32(WI_TX_RADIOTAP_PRESENT); 582 sc->sc_txtap.wt_ihdr.it_present = htole32(WI_TX_RADIOTAP_PRESENT);
583 583
584 /* Attach is successful. */ 584 /* Attach is successful. */
585 sc->sc_attached = 1; 585 sc->sc_attached = 1;
586 586
587 splx(s); 587 splx(s);
588 ieee80211_announce(ic); 588 ieee80211_announce(ic);
589 return 0; 589 return 0;
590 590
591fail_2: 591fail_2:
592 callout_destroy(&sc->sc_rssadapt_ch); 592 callout_destroy(&sc->sc_rssadapt_ch);
593 593
594fail: splx(s); 594fail: splx(s);
595 softint_disestablish(sc->sc_soft_ih); 595 softint_disestablish(sc->sc_soft_ih);
596 sc->sc_soft_ih = NULL; 596 sc->sc_soft_ih = NULL;
597err: return 1; 597err: return 1;
598} 598}
599 599
600int 600int
601wi_detach(struct wi_softc *sc) 601wi_detach(struct wi_softc *sc)
602{ 602{
603 struct ifnet *ifp = &sc->sc_if; 603 struct ifnet *ifp = &sc->sc_if;
604 int s; 604 int s;
605 605
606 if (!sc->sc_attached) 606 if (!sc->sc_attached)
607 return 0; 607 return 0;
608 608
609 sc->sc_invalid = 1; 609 sc->sc_invalid = 1;
610 s = splnet(); 610 s = splnet();
611 611
612 wi_stop(ifp, 1); 612 wi_stop(ifp, 1);
613 613
614 ieee80211_ifdetach(&sc->sc_ic); 614 ieee80211_ifdetach(&sc->sc_ic);
615 if_detach(ifp); 615 if_detach(ifp);
616 splx(s); 616 splx(s);
617 wi_ioctl_drain(sc); 617 wi_ioctl_drain(sc);
618 softint_disestablish(sc->sc_soft_ih); 618 softint_disestablish(sc->sc_soft_ih);
619 sc->sc_soft_ih = NULL; 619 sc->sc_soft_ih = NULL;
620 return 0; 620 return 0;
621} 621}
622 622
623int 623int
624wi_activate(device_t self, enum devact act) 624wi_activate(device_t self, enum devact act)
625{ 625{
626 struct wi_softc *sc = device_private(self); 626 struct wi_softc *sc = device_private(self);
627 627
628 switch (act) { 628 switch (act) {
629 case DVACT_DEACTIVATE: 629 case DVACT_DEACTIVATE:
630 if_deactivate(&sc->sc_if); 630 if_deactivate(&sc->sc_if);
631 return 0; 631 return 0;
632 default: 632 default:
633 return EOPNOTSUPP; 633 return EOPNOTSUPP;
634 } 634 }
635} 635}
636 636
637int 637int
638wi_intr(void *arg) 638wi_intr(void *arg)
639{ 639{
640 struct wi_softc *sc = arg; 640 struct wi_softc *sc = arg;
641 struct ifnet *ifp = &sc->sc_if; 641 struct ifnet *ifp = &sc->sc_if;
642 uint16_t status; 642 uint16_t status;
643 643
644 if (sc->sc_enabled == 0 || 644 if (sc->sc_enabled == 0 ||
645 !device_is_active(sc->sc_dev) || 645 !device_is_active(sc->sc_dev) ||
646 (ifp->if_flags & IFF_RUNNING) == 0) 646 (ifp->if_flags & IFF_RUNNING) == 0)
647 return 0; 647 return 0;
648 648
649 if ((ifp->if_flags & IFF_UP) == 0) { 649 if ((ifp->if_flags & IFF_UP) == 0) {
650 CSR_WRITE_2(sc, WI_INT_EN, 0); 650 CSR_WRITE_2(sc, WI_INT_EN, 0);
651 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0); 651 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
652 return 1; 652 return 1;
653 } 653 }
654 654
655 /* This is superfluous on Prism, but Lucent breaks if we 655 /* This is superfluous on Prism, but Lucent breaks if we
656 * do not disable interrupts. 656 * do not disable interrupts.
657 */ 657 */
658 CSR_WRITE_2(sc, WI_INT_EN, 0); 658 CSR_WRITE_2(sc, WI_INT_EN, 0);
659 659
660 status = CSR_READ_2(sc, WI_EVENT_STAT); 660 status = CSR_READ_2(sc, WI_EVENT_STAT);
661#ifdef WI_DEBUG 661#ifdef WI_DEBUG
662 if (wi_debug > 1) { 662 if (wi_debug > 1) {
663 printf("%s: status %#04x\n", __func__, status); 663 printf("%s: status %#04x\n", __func__, status);
664 } 664 }
665#endif /* WI_DEBUG */ 665#endif /* WI_DEBUG */
666 if ((status & WI_INTRS) == 0) { 666 if ((status & WI_INTRS) == 0) {
667 /* re-enable interrupts */ 667 /* re-enable interrupts */
668 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 668 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
669 return 0; 669 return 0;
670 } 670 }
671 671
672 softint_schedule(sc->sc_soft_ih); 672 softint_schedule(sc->sc_soft_ih);
673 return 1; 673 return 1;
674} 674}
675 675
676STATIC void 676STATIC void
677wi_softintr(void *arg) 677wi_softintr(void *arg)
678{ 678{
679 int i, s; 679 int i, s;
680 struct wi_softc *sc = arg; 680 struct wi_softc *sc = arg;
681 struct ifnet *ifp = &sc->sc_if; 681 struct ifnet *ifp = &sc->sc_if;
682 uint16_t status; 682 uint16_t status;
683 683
684 if (sc->sc_enabled == 0 || 684 if (sc->sc_enabled == 0 ||
685 !device_is_active(sc->sc_dev) || 685 !device_is_active(sc->sc_dev) ||
686 (ifp->if_flags & IFF_RUNNING) == 0) 686 (ifp->if_flags & IFF_RUNNING) == 0)
687 goto out; 687 goto out;
688 688
689 if ((ifp->if_flags & IFF_UP) == 0) { 689 if ((ifp->if_flags & IFF_UP) == 0) {
690 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0); 690 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
691 return; 691 return;
692 } 692 }
693 693
694 /* maximum 10 loops per interrupt */ 694 /* maximum 10 loops per interrupt */
695 for (i = 0; i < 10; i++) { 695 for (i = 0; i < 10; i++) {
696 status = CSR_READ_2(sc, WI_EVENT_STAT); 696 status = CSR_READ_2(sc, WI_EVENT_STAT);
697#ifdef WI_DEBUG 697#ifdef WI_DEBUG
698 if (wi_debug > 1) { 698 if (wi_debug > 1) {
699 printf("%s: iter %d status %#04x\n", __func__, i, 699 printf("%s: iter %d status %#04x\n", __func__, i,
700 status); 700 status);
701 } 701 }
702#endif /* WI_DEBUG */ 702#endif /* WI_DEBUG */
703 if ((status & WI_INTRS) == 0) 703 if ((status & WI_INTRS) == 0)
704 break; 704 break;
705 705
706 sc->sc_status = status; 706 sc->sc_status = status;
707 707
708 if (status & WI_EV_RX) 708 if (status & WI_EV_RX)
709 wi_rx_intr(sc); 709 wi_rx_intr(sc);
710 710
711 if (status & WI_EV_ALLOC) 711 if (status & WI_EV_ALLOC)
712 wi_txalloc_intr(sc); 712 wi_txalloc_intr(sc);
713 713
714 if (status & WI_EV_TX) 714 if (status & WI_EV_TX)
715 wi_tx_intr(sc); 715 wi_tx_intr(sc);
716 716
717 if (status & WI_EV_TX_EXC) 717 if (status & WI_EV_TX_EXC)
718 wi_tx_ex_intr(sc); 718 wi_tx_ex_intr(sc);
719 719
720 if (status & WI_EV_INFO) 720 if (status & WI_EV_INFO)
721 wi_info_intr(sc); 721 wi_info_intr(sc);
722 722
723 CSR_WRITE_2(sc, WI_EVENT_ACK, sc->sc_status); 723 CSR_WRITE_2(sc, WI_EVENT_ACK, sc->sc_status);
724 724
725 if (sc->sc_status & WI_EV_CMD) 725 if (sc->sc_status & WI_EV_CMD)
726 wi_cmd_intr(sc); 726 wi_cmd_intr(sc);
727 727
728 if ((ifp->if_flags & IFF_OACTIVE) == 0 && 728 if ((ifp->if_flags & IFF_OACTIVE) == 0 &&
729 (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0 && 729 (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0 &&
730 !IFQ_IS_EMPTY(&ifp->if_snd)) { 730 !IFQ_IS_EMPTY(&ifp->if_snd)) {
731 s = splnet(); 731 s = splnet();
732 wi_start(ifp); 732 wi_start(ifp);
733 splx(s); 733 splx(s);
734 } 734 }
735 735
736 sc->sc_status = 0; 736 sc->sc_status = 0;
737 } 737 }
738 if (i == 10) 738 if (i == 10)
739 softint_schedule(sc->sc_soft_ih); 739 softint_schedule(sc->sc_soft_ih);
740 740
741out: 741out:
742 sc->sc_status = 0; 742 sc->sc_status = 0;
743 743
744 /* re-enable interrupts */ 744 /* re-enable interrupts */
745 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 745 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
746} 746}
747 747
748#define arraylen(a) (sizeof(a) / sizeof((a)[0])) 748#define arraylen(a) (sizeof(a) / sizeof((a)[0]))
749 749
750STATIC void 750STATIC void
751wi_rssdescs_init(struct wi_rssdesc (*rssd)[WI_NTXRSS], wi_rssdescq_t *rssdfree) 751wi_rssdescs_init(struct wi_rssdesc (*rssd)[WI_NTXRSS], wi_rssdescq_t *rssdfree)
752{ 752{
753 int i; 753 int i;
754 SLIST_INIT(rssdfree); 754 SLIST_INIT(rssdfree);
755 for (i = 0; i < arraylen(*rssd); i++) { 755 for (i = 0; i < arraylen(*rssd); i++) {
756 SLIST_INSERT_HEAD(rssdfree, &(*rssd)[i], rd_next); 756 SLIST_INSERT_HEAD(rssdfree, &(*rssd)[i], rd_next);
757 } 757 }
758} 758}
759 759
760STATIC void 760STATIC void
761wi_rssdescs_reset(struct ieee80211com *ic, struct wi_rssdesc (*rssd)[WI_NTXRSS], 761wi_rssdescs_reset(struct ieee80211com *ic, struct wi_rssdesc (*rssd)[WI_NTXRSS],
762 wi_rssdescq_t *rssdfree, uint8_t (*txpending)[IEEE80211_RATE_MAXSIZE]) 762 wi_rssdescq_t *rssdfree, uint8_t (*txpending)[IEEE80211_RATE_MAXSIZE])
763{ 763{
764 struct ieee80211_node *ni; 764 struct ieee80211_node *ni;
765 int i; 765 int i;
766 for (i = 0; i < arraylen(*rssd); i++) { 766 for (i = 0; i < arraylen(*rssd); i++) {
767 ni = (*rssd)[i].rd_desc.id_node; 767 ni = (*rssd)[i].rd_desc.id_node;
768 (*rssd)[i].rd_desc.id_node = NULL; 768 (*rssd)[i].rd_desc.id_node = NULL;
769 if (ni != NULL && (ic->ic_ifp->if_flags & IFF_DEBUG) != 0) 769 if (ni != NULL && (ic->ic_ifp->if_flags & IFF_DEBUG) != 0)
770 printf("%s: cleaning outstanding rssadapt " 770 printf("%s: cleaning outstanding rssadapt "
771 "descriptor for %s\n", 771 "descriptor for %s\n",
772 ic->ic_ifp->if_xname, ether_sprintf(ni->ni_macaddr)); 772 ic->ic_ifp->if_xname, ether_sprintf(ni->ni_macaddr));
773 if (ni != NULL) 773 if (ni != NULL)
774 ieee80211_free_node(ni); 774 ieee80211_free_node(ni);
775 } 775 }
776 memset(*txpending, 0, sizeof(*txpending)); 776 memset(*txpending, 0, sizeof(*txpending));
777 wi_rssdescs_init(rssd, rssdfree); 777 wi_rssdescs_init(rssd, rssdfree);
778} 778}
779 779
780STATIC int 780STATIC int
781wi_init(struct ifnet *ifp) 781wi_init(struct ifnet *ifp)
782{ 782{
783 struct wi_softc *sc = ifp->if_softc; 783 struct wi_softc *sc = ifp->if_softc;
784 struct ieee80211com *ic = &sc->sc_ic; 784 struct ieee80211com *ic = &sc->sc_ic;
785 struct wi_joinreq join; 785 struct wi_joinreq join;
786 int i; 786 int i;
787 int error = 0, wasenabled; 787 int error = 0, wasenabled;
788 788
789 DPRINTF(("wi_init: enabled %d\n", sc->sc_enabled)); 789 DPRINTF(("wi_init: enabled %d\n", sc->sc_enabled));
790 wasenabled = sc->sc_enabled; 790 wasenabled = sc->sc_enabled;
791 if (!sc->sc_enabled) { 791 if (!sc->sc_enabled) {
792 if ((error = (*sc->sc_enable)(sc->sc_dev, 1)) != 0) 792 if ((error = (*sc->sc_enable)(sc->sc_dev, 1)) != 0)
793 goto out; 793 goto out;
794 sc->sc_enabled = 1; 794 sc->sc_enabled = 1;
795 } else 795 } else
796 wi_stop(ifp, 0); 796 wi_stop(ifp, 0);
797 797
798 /* Symbol firmware cannot be initialized more than once */ 798 /* Symbol firmware cannot be initialized more than once */
799 if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) 799 if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled)
800 if ((error = wi_reset(sc)) != 0) 800 if ((error = wi_reset(sc)) != 0)
801 goto out; 801 goto out;
802 802
803 /* common 802.11 configuration */ 803 /* common 802.11 configuration */
804 ic->ic_flags &= ~IEEE80211_F_IBSSON; 804 ic->ic_flags &= ~IEEE80211_F_IBSSON;
805 sc->sc_flags &= ~WI_FLAGS_OUTRANGE; 805 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
806 switch (ic->ic_opmode) { 806 switch (ic->ic_opmode) {
807 case IEEE80211_M_STA: 807 case IEEE80211_M_STA:
808 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_BSS); 808 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_BSS);
809 break; 809 break;
810 case IEEE80211_M_IBSS: 810 case IEEE80211_M_IBSS:
811 wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_ibss_port); 811 wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_ibss_port);
812 ic->ic_flags |= IEEE80211_F_IBSSON; 812 ic->ic_flags |= IEEE80211_F_IBSSON;
813 break; 813 break;
814 case IEEE80211_M_AHDEMO: 814 case IEEE80211_M_AHDEMO:
815 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC); 815 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC);
816 break; 816 break;
817 case IEEE80211_M_HOSTAP: 817 case IEEE80211_M_HOSTAP:
818 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_HOSTAP); 818 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_HOSTAP);
819 break; 819 break;
820 case IEEE80211_M_MONITOR: 820 case IEEE80211_M_MONITOR:
821 if (sc->sc_firmware_type == WI_LUCENT) 821 if (sc->sc_firmware_type == WI_LUCENT)
822 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC); 822 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC);
823 wi_cmd(sc, WI_CMD_TEST | (WI_TEST_MONITOR << 8), 0, 0, 0); 823 wi_cmd(sc, WI_CMD_TEST | (WI_TEST_MONITOR << 8), 0, 0, 0);
824 break; 824 break;
825 } 825 }
826 826
827 /* Intersil interprets this RID as joining ESS even in IBSS mode */ 827 /* Intersil interprets this RID as joining ESS even in IBSS mode */
828 if (sc->sc_firmware_type == WI_LUCENT && 828 if (sc->sc_firmware_type == WI_LUCENT &&
829 (ic->ic_flags & IEEE80211_F_IBSSON) && ic->ic_des_esslen > 0) 829 (ic->ic_flags & IEEE80211_F_IBSSON) && ic->ic_des_esslen > 0)
830 wi_write_val(sc, WI_RID_CREATE_IBSS, 1); 830 wi_write_val(sc, WI_RID_CREATE_IBSS, 1);
831 else 831 else
832 wi_write_val(sc, WI_RID_CREATE_IBSS, 0); 832 wi_write_val(sc, WI_RID_CREATE_IBSS, 0);
833 wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval); 833 wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval);
834 wi_write_ssid(sc, WI_RID_DESIRED_SSID, ic->ic_des_essid, 834 wi_write_ssid(sc, WI_RID_DESIRED_SSID, ic->ic_des_essid,
835 ic->ic_des_esslen); 835 ic->ic_des_esslen);
836 wi_write_val(sc, WI_RID_OWN_CHNL, 836 wi_write_val(sc, WI_RID_OWN_CHNL,
837 ieee80211_chan2ieee(ic, ic->ic_ibss_chan)); 837 ieee80211_chan2ieee(ic, ic->ic_ibss_chan));
838 wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_essid, ic->ic_des_esslen); 838 wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_essid, ic->ic_des_esslen);
839 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 839 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
840 wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, IEEE80211_ADDR_LEN); 840 wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, IEEE80211_ADDR_LEN);
841 if (ic->ic_caps & IEEE80211_C_PMGT) 841 if (ic->ic_caps & IEEE80211_C_PMGT)
842 wi_write_val(sc, WI_RID_PM_ENABLED, 842 wi_write_val(sc, WI_RID_PM_ENABLED,
843 (ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0); 843 (ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0);
844 844
845 /* not yet common 802.11 configuration */ 845 /* not yet common 802.11 configuration */
846 wi_write_val(sc, WI_RID_MAX_DATALEN, sc->sc_max_datalen); 846 wi_write_val(sc, WI_RID_MAX_DATALEN, sc->sc_max_datalen);
847 wi_write_val(sc, WI_RID_RTS_THRESH, sc->sc_rts_thresh); 847 wi_write_val(sc, WI_RID_RTS_THRESH, sc->sc_rts_thresh);
848 if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) 848 if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)
849 wi_write_val(sc, WI_RID_FRAG_THRESH, sc->sc_frag_thresh); 849 wi_write_val(sc, WI_RID_FRAG_THRESH, sc->sc_frag_thresh);
850 850
851 /* driver specific 802.11 configuration */ 851 /* driver specific 802.11 configuration */
852 if (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) 852 if (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)
853 wi_write_val(sc, WI_RID_SYSTEM_SCALE, sc->sc_system_scale); 853 wi_write_val(sc, WI_RID_SYSTEM_SCALE, sc->sc_system_scale);
854 if (sc->sc_flags & WI_FLAGS_HAS_ROAMING) 854 if (sc->sc_flags & WI_FLAGS_HAS_ROAMING)
855 wi_write_val(sc, WI_RID_ROAMING_MODE, sc->sc_roaming_mode); 855 wi_write_val(sc, WI_RID_ROAMING_MODE, sc->sc_roaming_mode);
856 if (sc->sc_flags & WI_FLAGS_HAS_MOR) 856 if (sc->sc_flags & WI_FLAGS_HAS_MOR)
857 wi_write_val(sc, WI_RID_MICROWAVE_OVEN, sc->sc_microwave_oven); 857 wi_write_val(sc, WI_RID_MICROWAVE_OVEN, sc->sc_microwave_oven);
858 wi_cfg_txrate(sc); 858 wi_cfg_txrate(sc);
859 wi_write_ssid(sc, WI_RID_NODENAME, sc->sc_nodename, sc->sc_nodelen); 859 wi_write_ssid(sc, WI_RID_NODENAME, sc->sc_nodename, sc->sc_nodelen);
860 860
861#ifndef IEEE80211_NO_HOSTAP 861#ifndef IEEE80211_NO_HOSTAP
862 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 862 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
863 sc->sc_firmware_type == WI_INTERSIL) { 863 sc->sc_firmware_type == WI_INTERSIL) {
864 wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_lintval); 864 wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_lintval);
865 wi_write_val(sc, WI_RID_DTIM_PERIOD, 1); 865 wi_write_val(sc, WI_RID_DTIM_PERIOD, 1);
866 } 866 }
867#endif /* !IEEE80211_NO_HOSTAP */ 867#endif /* !IEEE80211_NO_HOSTAP */
868 868
869 if (sc->sc_firmware_type == WI_INTERSIL) { 869 if (sc->sc_firmware_type == WI_INTERSIL) {
870 struct ieee80211_rateset *rs = 870 struct ieee80211_rateset *rs =
871 &ic->ic_sup_rates[IEEE80211_MODE_11B]; 871 &ic->ic_sup_rates[IEEE80211_MODE_11B];
872 uint16_t basic = 0, supported = 0, rate; 872 uint16_t basic = 0, supported = 0, rate;
873 873
874 for (i = 0; i < rs->rs_nrates; i++) { 874 for (i = 0; i < rs->rs_nrates; i++) {
875 switch (rs->rs_rates[i] & IEEE80211_RATE_VAL) { 875 switch (rs->rs_rates[i] & IEEE80211_RATE_VAL) {
876 case 2: 876 case 2:
877 rate = 1; 877 rate = 1;
878 break; 878 break;
879 case 4: 879 case 4:
880 rate = 2; 880 rate = 2;
881 break; 881 break;
882 case 11: 882 case 11:
883 rate = 4; 883 rate = 4;
884 break; 884 break;
885 case 22: 885 case 22:
886 rate = 8; 886 rate = 8;
887 break; 887 break;
888 default: 888 default:
889 rate = 0; 889 rate = 0;
890 break; 890 break;
891 } 891 }
892 if (rs->rs_rates[i] & IEEE80211_RATE_BASIC) 892 if (rs->rs_rates[i] & IEEE80211_RATE_BASIC)
893 basic |= rate; 893 basic |= rate;
894 supported |= rate; 894 supported |= rate;
895 } 895 }
896 wi_write_val(sc, WI_RID_BASIC_RATE, basic); 896 wi_write_val(sc, WI_RID_BASIC_RATE, basic);
897 wi_write_val(sc, WI_RID_SUPPORT_RATE, supported); 897 wi_write_val(sc, WI_RID_SUPPORT_RATE, supported);
898 wi_write_val(sc, WI_RID_ALT_RETRY_COUNT, sc->sc_alt_retry); 898 wi_write_val(sc, WI_RID_ALT_RETRY_COUNT, sc->sc_alt_retry);
899 } 899 }
900 900
901 /* 901 /*
902 * Initialize promisc mode. 902 * Initialize promisc mode.
903 * Being in Host-AP mode causes a great 903 * Being in Host-AP mode causes a great
904 * deal of pain if promiscuous mode is set. 904 * deal of pain if promiscuous mode is set.
905 * Therefore we avoid confusing the firmware 905 * Therefore we avoid confusing the firmware
906 * and always reset promisc mode in Host-AP 906 * and always reset promisc mode in Host-AP
907 * mode. Host-AP sees all the packets anyway. 907 * mode. Host-AP sees all the packets anyway.
908 */ 908 */
909 if (ic->ic_opmode != IEEE80211_M_HOSTAP && 909 if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
910 (ifp->if_flags & IFF_PROMISC) != 0) { 910 (ifp->if_flags & IFF_PROMISC) != 0) {
911 wi_write_val(sc, WI_RID_PROMISC, 1); 911 wi_write_val(sc, WI_RID_PROMISC, 1);
912 } else { 912 } else {
913 wi_write_val(sc, WI_RID_PROMISC, 0); 913 wi_write_val(sc, WI_RID_PROMISC, 0);
914 } 914 }
915 915
916 /* Configure WEP. */ 916 /* Configure WEP. */
917 if (ic->ic_caps & IEEE80211_C_WEP) { 917 if (ic->ic_caps & IEEE80211_C_WEP) {
918 sc->sc_cnfauthmode = ic->ic_bss->ni_authmode; 918 sc->sc_cnfauthmode = ic->ic_bss->ni_authmode;
919 wi_write_wep(sc); 919 wi_write_wep(sc);
920 } 920 }
921 921
922 /* Set multicast filter. */ 922 /* Set multicast filter. */
923 wi_write_multi(sc); 923 wi_write_multi(sc);
924 924
925 sc->sc_txalloc = 0; 925 sc->sc_txalloc = 0;
926 sc->sc_txalloced = 0; 926 sc->sc_txalloced = 0;
927 sc->sc_txqueue = 0; 927 sc->sc_txqueue = 0;
928 sc->sc_txqueued = 0; 928 sc->sc_txqueued = 0;
929 sc->sc_txstart = 0; 929 sc->sc_txstart = 0;
930 sc->sc_txstarted = 0; 930 sc->sc_txstarted = 0;
931 931
932 if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) { 932 if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) {
933 sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame); 933 sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame);
934 if (sc->sc_firmware_type == WI_SYMBOL) 934 if (sc->sc_firmware_type == WI_SYMBOL)
935 sc->sc_buflen = 1585; /* XXX */ 935 sc->sc_buflen = 1585; /* XXX */
936 for (i = 0; i < WI_NTXBUF; i++) { 936 for (i = 0; i < WI_NTXBUF; i++) {
937 error = wi_alloc_fid(sc, sc->sc_buflen, 937 error = wi_alloc_fid(sc, sc->sc_buflen,
938 &sc->sc_txd[i].d_fid); 938 &sc->sc_txd[i].d_fid);
939 if (error) { 939 if (error) {
940 aprint_error_dev(sc->sc_dev, 940 aprint_error_dev(sc->sc_dev,
941 "tx buffer allocation failed\n"); 941 "tx buffer allocation failed\n");
942 goto out; 942 goto out;
943 } 943 }
944 DPRINTF2(("wi_init: txbuf %d allocated %x\n", i, 944 DPRINTF2(("wi_init: txbuf %d allocated %x\n", i,
945 sc->sc_txd[i].d_fid)); 945 sc->sc_txd[i].d_fid));
946 ++sc->sc_txalloced; 946 ++sc->sc_txalloced;
947 } 947 }
948 } 948 }
949 949
950 wi_rssdescs_init(&sc->sc_rssd, &sc->sc_rssdfree); 950 wi_rssdescs_init(&sc->sc_rssd, &sc->sc_rssdfree);
951 951
952 /* Enable desired port */ 952 /* Enable desired port */
953 wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0); 953 wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0);
954 ifp->if_flags |= IFF_RUNNING; 954 ifp->if_flags |= IFF_RUNNING;
955 ifp->if_flags &= ~IFF_OACTIVE; 955 ifp->if_flags &= ~IFF_OACTIVE;
956 ic->ic_state = IEEE80211_S_INIT; 956 ic->ic_state = IEEE80211_S_INIT;
957 957
958 if (ic->ic_opmode == IEEE80211_M_AHDEMO || 958 if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
959 ic->ic_opmode == IEEE80211_M_IBSS || 959 ic->ic_opmode == IEEE80211_M_IBSS ||
960 ic->ic_opmode == IEEE80211_M_MONITOR || 960 ic->ic_opmode == IEEE80211_M_MONITOR ||
961 ic->ic_opmode == IEEE80211_M_HOSTAP) 961 ic->ic_opmode == IEEE80211_M_HOSTAP)
962 ieee80211_create_ibss(ic, ic->ic_ibss_chan); 962 ieee80211_create_ibss(ic, ic->ic_ibss_chan);
963 963
964 /* Enable interrupts */ 964 /* Enable interrupts */
965 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); 965 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
966 966
967#ifndef IEEE80211_NO_HOSTAP 967#ifndef IEEE80211_NO_HOSTAP
968 if (!wasenabled && 968 if (!wasenabled &&
969 ic->ic_opmode == IEEE80211_M_HOSTAP && 969 ic->ic_opmode == IEEE80211_M_HOSTAP &&
970 sc->sc_firmware_type == WI_INTERSIL) { 970 sc->sc_firmware_type == WI_INTERSIL) {
971 /* XXX: some card need to be re-enabled for hostap */ 971 /* XXX: some card need to be re-enabled for hostap */
972 wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0); 972 wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0);
973 wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0); 973 wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0);
974 } 974 }
975#endif /* !IEEE80211_NO_HOSTAP */ 975#endif /* !IEEE80211_NO_HOSTAP */
976 976
977 if (ic->ic_opmode == IEEE80211_M_STA && 977 if (ic->ic_opmode == IEEE80211_M_STA &&
978 ((ic->ic_flags & IEEE80211_F_DESBSSID) || 978 ((ic->ic_flags & IEEE80211_F_DESBSSID) ||
979 ic->ic_des_chan != IEEE80211_CHAN_ANYC)) { 979 ic->ic_des_chan != IEEE80211_CHAN_ANYC)) {
980 memset(&join, 0, sizeof(join)); 980 memset(&join, 0, sizeof(join));
981 if (ic->ic_flags & IEEE80211_F_DESBSSID) 981 if (ic->ic_flags & IEEE80211_F_DESBSSID)
982 IEEE80211_ADDR_COPY(&join.wi_bssid, ic->ic_des_bssid); 982 IEEE80211_ADDR_COPY(&join.wi_bssid, ic->ic_des_bssid);
983 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) 983 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC)
984 join.wi_chan = 984 join.wi_chan =
985 htole16(ieee80211_chan2ieee(ic, ic->ic_des_chan)); 985 htole16(ieee80211_chan2ieee(ic, ic->ic_des_chan));
986 /* Lucent firmware does not support the JOIN RID. */ 986 /* Lucent firmware does not support the JOIN RID. */
987 if (sc->sc_firmware_type != WI_LUCENT) 987 if (sc->sc_firmware_type != WI_LUCENT)
988 wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join)); 988 wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join));
989 } 989 }
990 990
991 out: 991 out:
992 if (error) { 992 if (error) {
993 printf("%s: interface not running\n", device_xname(sc->sc_dev)); 993 printf("%s: interface not running\n", device_xname(sc->sc_dev));
994 wi_stop(ifp, 0); 994 wi_stop(ifp, 0);
995 } 995 }
996 DPRINTF(("wi_init: return %d\n", error)); 996 DPRINTF(("wi_init: return %d\n", error));
997 return error; 997 return error;
998} 998}
999 999
1000STATIC void 1000STATIC void
1001wi_txcmd_wait(struct wi_softc *sc) 1001wi_txcmd_wait(struct wi_softc *sc)
1002{ 1002{
1003 KASSERT(sc->sc_txcmds == 1); 1003 KASSERT(sc->sc_txcmds == 1);
1004 if (sc->sc_status & WI_EV_CMD) { 1004 if (sc->sc_status & WI_EV_CMD) {
1005 sc->sc_status &= ~WI_EV_CMD; 1005 sc->sc_status &= ~WI_EV_CMD;
1006 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); 1006 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
1007 } else 1007 } else
1008 (void)wi_cmd_wait(sc, WI_CMD_TX | WI_RECLAIM, 0); 1008 (void)wi_cmd_wait(sc, WI_CMD_TX | WI_RECLAIM, 0);
1009} 1009}
1010 1010
1011STATIC void 1011STATIC void
1012wi_stop(struct ifnet *ifp, int disable) 1012wi_stop(struct ifnet *ifp, int disable)
1013{ 1013{
1014 struct wi_softc *sc = ifp->if_softc; 1014 struct wi_softc *sc = ifp->if_softc;
1015 struct ieee80211com *ic = &sc->sc_ic; 1015 struct ieee80211com *ic = &sc->sc_ic;
1016 int s; 1016 int s;
1017 1017
1018 if (!sc->sc_enabled) 1018 if (!sc->sc_enabled)
1019 return; 1019 return;
1020 1020
1021 s = splnet(); 1021 s = splnet();
1022 1022
1023 DPRINTF(("wi_stop: disable %d\n", disable)); 1023 DPRINTF(("wi_stop: disable %d\n", disable));
1024 1024
1025 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 1025 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1026 1026
1027 /* wait for tx command completion (deassoc, deauth) */ 1027 /* wait for tx command completion (deassoc, deauth) */
1028 while (sc->sc_txcmds > 0) { 1028 while (sc->sc_txcmds > 0) {
1029 wi_txcmd_wait(sc); 1029 wi_txcmd_wait(sc);
1030 wi_cmd_intr(sc); 1030 wi_cmd_intr(sc);
1031 } 1031 }
1032 1032
1033 /* TBD wait for deassoc, deauth tx completion? */ 1033 /* TBD wait for deassoc, deauth tx completion? */
1034 1034
1035 if (!sc->sc_invalid) { 1035 if (!sc->sc_invalid) {
1036 CSR_WRITE_2(sc, WI_INT_EN, 0); 1036 CSR_WRITE_2(sc, WI_INT_EN, 0);
1037 wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0); 1037 wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0);
1038 } 1038 }
1039 1039
1040 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree, 1040 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1041 &sc->sc_txpending); 1041 &sc->sc_txpending);
1042 1042
1043 sc->sc_tx_timer = 0; 1043 sc->sc_tx_timer = 0;
1044 sc->sc_scan_timer = 0; 1044 sc->sc_scan_timer = 0;
1045 sc->sc_false_syns = 0; 1045 sc->sc_false_syns = 0;
1046 sc->sc_naps = 0; 1046 sc->sc_naps = 0;
1047 ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING); 1047 ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING);
1048 ifp->if_timer = 0; 1048 ifp->if_timer = 0;
1049 1049
1050 if (disable) { 1050 if (disable) {
1051 (*sc->sc_enable)(sc->sc_dev, 0); 1051 (*sc->sc_enable)(sc->sc_dev, 0);
1052 sc->sc_enabled = 0; 1052 sc->sc_enabled = 0;
1053 } 1053 }
1054 splx(s); 1054 splx(s);
1055} 1055}
1056 1056
1057/* 1057/*
1058 * Choose a data rate for a packet len bytes long that suits the packet 1058 * Choose a data rate for a packet len bytes long that suits the packet
1059 * type and the wireless conditions. 1059 * type and the wireless conditions.
1060 * 1060 *
1061 * TBD Adapt fragmentation threshold. 1061 * TBD Adapt fragmentation threshold.
1062 */ 1062 */
1063STATIC int 1063STATIC int
1064wi_choose_rate(struct ieee80211com *ic, struct ieee80211_node *ni, 1064wi_choose_rate(struct ieee80211com *ic, struct ieee80211_node *ni,
1065 struct ieee80211_frame *wh, u_int len) 1065 struct ieee80211_frame *wh, u_int len)
1066{ 1066{
1067 struct wi_softc *sc = ic->ic_ifp->if_softc; 1067 struct wi_softc *sc = ic->ic_ifp->if_softc;
1068 struct wi_node *wn = (void*)ni; 1068 struct wi_node *wn = (void*)ni;
1069 struct ieee80211_rssadapt *ra = &wn->wn_rssadapt; 1069 struct ieee80211_rssadapt *ra = &wn->wn_rssadapt;
1070 int do_not_adapt, i, rateidx, s; 1070 int do_not_adapt, i, rateidx, s;
1071 1071
1072 do_not_adapt = (ic->ic_opmode != IEEE80211_M_HOSTAP) && 1072 do_not_adapt = (ic->ic_opmode != IEEE80211_M_HOSTAP) &&
1073 (sc->sc_flags & WI_FLAGS_RSSADAPTSTA) == 0; 1073 (sc->sc_flags & WI_FLAGS_RSSADAPTSTA) == 0;
1074 1074
1075 s = splnet(); 1075 s = splnet();
1076 1076
1077 rateidx = ieee80211_rssadapt_choose(ra, &ni->ni_rates, wh, len, 1077 rateidx = ieee80211_rssadapt_choose(ra, &ni->ni_rates, wh, len,
1078 ic->ic_fixed_rate, 1078 ic->ic_fixed_rate,
1079 ((ic->ic_ifp->if_flags & IFF_DEBUG) == 0) ? NULL : ic->ic_ifp->if_xname, 1079 ((ic->ic_ifp->if_flags & IFF_DEBUG) == 0) ? NULL : ic->ic_ifp->if_xname,
1080 do_not_adapt); 1080 do_not_adapt);
1081 1081
1082 ni->ni_txrate = rateidx; 1082 ni->ni_txrate = rateidx;
1083 1083
1084 if (ic->ic_opmode != IEEE80211_M_HOSTAP) { 1084 if (ic->ic_opmode != IEEE80211_M_HOSTAP) {
1085 /* choose the slowest pending rate so that we don't 1085 /* choose the slowest pending rate so that we don't
1086 * accidentally send a packet on the MAC's queue 1086 * accidentally send a packet on the MAC's queue
1087 * too fast. TBD find out if the MAC labels Tx 1087 * too fast. TBD find out if the MAC labels Tx
1088 * packets w/ rate when enqueued or dequeued. 1088 * packets w/ rate when enqueued or dequeued.
1089 */ 1089 */
1090 for (i = 0; i < rateidx && sc->sc_txpending[i] == 0; i++); 1090 for (i = 0; i < rateidx && sc->sc_txpending[i] == 0; i++);
1091 rateidx = i; 1091 rateidx = i;
1092 } 1092 }
1093 1093
1094 splx(s); 1094 splx(s);
1095 return (rateidx); 1095 return (rateidx);
1096} 1096}
1097 1097
1098STATIC void 1098STATIC void
1099wi_raise_rate(struct ieee80211com *ic, struct ieee80211_rssdesc *id) 1099wi_raise_rate(struct ieee80211com *ic, struct ieee80211_rssdesc *id)
1100{ 1100{
1101 struct wi_node *wn; 1101 struct wi_node *wn;
1102 int s; 1102 int s;
1103 1103
1104 s = splnet(); 1104 s = splnet();
1105 if (id->id_node == NULL) 1105 if (id->id_node == NULL)
1106 goto out; 1106 goto out;
1107 1107
1108 wn = (void*)id->id_node; 1108 wn = (void*)id->id_node;
1109 ieee80211_rssadapt_raise_rate(ic, &wn->wn_rssadapt, id); 1109 ieee80211_rssadapt_raise_rate(ic, &wn->wn_rssadapt, id);
1110out: 1110out:
1111 splx(s); 1111 splx(s);
1112} 1112}
1113 1113
1114STATIC void 1114STATIC void
1115wi_lower_rate(struct ieee80211com *ic, struct ieee80211_rssdesc *id) 1115wi_lower_rate(struct ieee80211com *ic, struct ieee80211_rssdesc *id)
1116{ 1116{
1117 struct ieee80211_node *ni; 1117 struct ieee80211_node *ni;
1118 struct wi_node *wn; 1118 struct wi_node *wn;
1119 int s; 1119 int s;
1120 1120
1121 s = splnet(); 1121 s = splnet();
1122 1122
1123 if ((ni = id->id_node) == NULL) { 1123 if ((ni = id->id_node) == NULL) {
1124 DPRINTF(("wi_lower_rate: missing node\n")); 1124 DPRINTF(("wi_lower_rate: missing node\n"));
1125 goto out; 1125 goto out;
1126 } 1126 }
1127 1127
1128 wn = (void *)ni; 1128 wn = (void *)ni;
1129 1129
1130 ieee80211_rssadapt_lower_rate(ic, ni, &wn->wn_rssadapt, id); 1130 ieee80211_rssadapt_lower_rate(ic, ni, &wn->wn_rssadapt, id);
1131out: 1131out:
1132 splx(s); 1132 splx(s);
1133} 1133}
1134 1134
1135STATIC void 1135STATIC void
1136wi_start(struct ifnet *ifp) 1136wi_start(struct ifnet *ifp)
1137{ 1137{
1138 struct wi_softc *sc = ifp->if_softc; 1138 struct wi_softc *sc = ifp->if_softc;
1139 struct ieee80211com *ic = &sc->sc_ic; 1139 struct ieee80211com *ic = &sc->sc_ic;
1140 struct ether_header *eh; 1140 struct ether_header *eh;
1141 struct ieee80211_node *ni; 1141 struct ieee80211_node *ni;
1142 struct ieee80211_frame *wh; 1142 struct ieee80211_frame *wh;
1143 struct ieee80211_rateset *rs; 1143 struct ieee80211_rateset *rs;
1144 struct wi_rssdesc *rd; 1144 struct wi_rssdesc *rd;
1145 struct ieee80211_rssdesc *id; 1145 struct ieee80211_rssdesc *id;
1146 struct mbuf *m0; 1146 struct mbuf *m0;
1147 struct wi_frame frmhdr; 1147 struct wi_frame frmhdr;
1148 int cur, fid, off, rateidx; 1148 int cur, fid, off, rateidx;
1149 1149
1150 if (!sc->sc_enabled || sc->sc_invalid) 1150 if (!sc->sc_enabled || sc->sc_invalid)
1151 return; 1151 return;
1152 if (sc->sc_flags & WI_FLAGS_OUTRANGE) 1152 if (sc->sc_flags & WI_FLAGS_OUTRANGE)
1153 return; 1153 return;
1154 1154
1155 memset(&frmhdr, 0, sizeof(frmhdr)); 1155 memset(&frmhdr, 0, sizeof(frmhdr));
1156 cur = sc->sc_txqueue; 1156 cur = sc->sc_txqueue;
1157 for (;;) { 1157 for (;;) {
1158 ni = ic->ic_bss; 1158 ni = ic->ic_bss;
1159 if (sc->sc_txalloced == 0 || SLIST_EMPTY(&sc->sc_rssdfree)) { 1159 if (sc->sc_txalloced == 0 || SLIST_EMPTY(&sc->sc_rssdfree)) {
1160 ifp->if_flags |= IFF_OACTIVE; 1160 ifp->if_flags |= IFF_OACTIVE;
1161 break; 1161 break;
1162 } 1162 }
1163 if (!IF_IS_EMPTY(&ic->ic_mgtq)) { 1163 if (!IF_IS_EMPTY(&ic->ic_mgtq)) {
1164 IF_DEQUEUE(&ic->ic_mgtq, m0); 1164 IF_DEQUEUE(&ic->ic_mgtq, m0);
1165 m_copydata(m0, 4, ETHER_ADDR_LEN * 2, 1165 m_copydata(m0, 4, ETHER_ADDR_LEN * 2,
1166 (void *)&frmhdr.wi_ehdr); 1166 (void *)&frmhdr.wi_ehdr);
1167 frmhdr.wi_ehdr.ether_type = 0; 1167 frmhdr.wi_ehdr.ether_type = 0;
1168 wh = mtod(m0, struct ieee80211_frame *); 1168 wh = mtod(m0, struct ieee80211_frame *);
1169 ni = M_GETCTX(m0, struct ieee80211_node *); 1169 ni = M_GETCTX(m0, struct ieee80211_node *);
1170 M_CLEARCTX(m0); 1170 M_CLEARCTX(m0);
1171 } else if (ic->ic_state == IEEE80211_S_RUN) { 1171 } else if (ic->ic_state == IEEE80211_S_RUN) {
1172 IFQ_POLL(&ifp->if_snd, m0); 1172 IFQ_POLL(&ifp->if_snd, m0);
1173 if (m0 == NULL) 1173 if (m0 == NULL)
1174 break; 1174 break;
1175 IFQ_DEQUEUE(&ifp->if_snd, m0); 1175 IFQ_DEQUEUE(&ifp->if_snd, m0);
1176 ifp->if_opackets++; 1176 ifp->if_opackets++;
1177 m_copydata(m0, 0, ETHER_HDR_LEN, 1177 m_copydata(m0, 0, ETHER_HDR_LEN,
1178 (void *)&frmhdr.wi_ehdr); 1178 (void *)&frmhdr.wi_ehdr);
1179 bpf_mtap(ifp, m0, BPF_D_OUT); 1179 bpf_mtap(ifp, m0, BPF_D_OUT);
1180 1180
1181 eh = mtod(m0, struct ether_header *); 1181 eh = mtod(m0, struct ether_header *);
1182 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 1182 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
1183 if (ni == NULL) { 1183 if (ni == NULL) {
1184 ifp->if_oerrors++; 1184 ifp->if_oerrors++;
1185 continue; 1185 continue;
1186 } 1186 }
1187 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && 1187 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
1188 (m0->m_flags & M_PWR_SAV) == 0) { 1188 (m0->m_flags & M_PWR_SAV) == 0) {
1189 ieee80211_pwrsave(ic, ni, m0); 1189 ieee80211_pwrsave(ic, ni, m0);
1190 goto next; 1190 goto next;
1191 } 1191 }
1192 if ((m0 = ieee80211_encap(ic, m0, ni)) == NULL) { 1192 if ((m0 = ieee80211_encap(ic, m0, ni)) == NULL) {
1193 ieee80211_free_node(ni); 1193 ieee80211_free_node(ni);
1194 ifp->if_oerrors++; 1194 ifp->if_oerrors++;
1195 continue; 1195 continue;
1196 } 1196 }
1197 wh = mtod(m0, struct ieee80211_frame *); 1197 wh = mtod(m0, struct ieee80211_frame *);
1198 } else 1198 } else
1199 break; 1199 break;
1200 bpf_mtap3(ic->ic_rawbpf, m0, BPF_D_OUT); 1200 bpf_mtap3(ic->ic_rawbpf, m0, BPF_D_OUT);
1201 frmhdr.wi_tx_ctl = 1201 frmhdr.wi_tx_ctl =
1202 htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX|WI_TXCNTL_TX_OK); 1202 htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX|WI_TXCNTL_TX_OK);
1203#ifndef IEEE80211_NO_HOSTAP 1203#ifndef IEEE80211_NO_HOSTAP
1204 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 1204 if (ic->ic_opmode == IEEE80211_M_HOSTAP)
1205 frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_ALTRTRY); 1205 frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_ALTRTRY);
1206 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 1206 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
1207 (wh->i_fc[1] & IEEE80211_FC1_WEP)) { 1207 (wh->i_fc[1] & IEEE80211_FC1_WEP)) {
1208 if (ieee80211_crypto_encap(ic, ni, m0) == NULL) { 1208 if (ieee80211_crypto_encap(ic, ni, m0) == NULL) {
1209 m_freem(m0); 1209 m_freem(m0);
1210 ifp->if_oerrors++; 1210 ifp->if_oerrors++;
1211 goto next; 1211 goto next;
1212 } 1212 }
1213 frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT); 1213 frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
1214 } 1214 }
1215#endif /* !IEEE80211_NO_HOSTAP */ 1215#endif /* !IEEE80211_NO_HOSTAP */
1216 1216
1217 rateidx = wi_choose_rate(ic, ni, wh, m0->m_pkthdr.len); 1217 rateidx = wi_choose_rate(ic, ni, wh, m0->m_pkthdr.len);
1218 rs = &ni->ni_rates; 1218 rs = &ni->ni_rates;
1219 1219
1220 if (sc->sc_drvbpf) { 1220 if (sc->sc_drvbpf) {
1221 struct wi_tx_radiotap_header *tap = &sc->sc_txtap; 1221 struct wi_tx_radiotap_header *tap = &sc->sc_txtap;
1222 1222
1223 tap->wt_rate = rs->rs_rates[rateidx]; 1223 tap->wt_rate = rs->rs_rates[rateidx];
1224 tap->wt_chan_freq = 1224 tap->wt_chan_freq =
1225 htole16(ic->ic_bss->ni_chan->ic_freq); 1225 htole16(ic->ic_bss->ni_chan->ic_freq);
1226 tap->wt_chan_flags = 1226 tap->wt_chan_flags =
1227 htole16(ic->ic_bss->ni_chan->ic_flags); 1227 htole16(ic->ic_bss->ni_chan->ic_flags);
1228 /* TBD tap->wt_flags */ 1228 /* TBD tap->wt_flags */
1229 1229
1230 bpf_mtap2(sc->sc_drvbpf, tap, tap->wt_ihdr.it_len, m0, 1230 bpf_mtap2(sc->sc_drvbpf, tap, tap->wt_ihdr.it_len, m0,
1231 BPF_D_OUT); 1231 BPF_D_OUT);
1232 } 1232 }
1233 1233
1234 rd = SLIST_FIRST(&sc->sc_rssdfree); 1234 rd = SLIST_FIRST(&sc->sc_rssdfree);
1235 id = &rd->rd_desc; 1235 id = &rd->rd_desc;
1236 id->id_len = m0->m_pkthdr.len; 1236 id->id_len = m0->m_pkthdr.len;
1237 id->id_rateidx = ni->ni_txrate; 1237 id->id_rateidx = ni->ni_txrate;
1238 id->id_rssi = ni->ni_rssi; 1238 id->id_rssi = ni->ni_rssi;
1239 1239
1240 frmhdr.wi_tx_idx = rd - sc->sc_rssd; 1240 frmhdr.wi_tx_idx = rd - sc->sc_rssd;
1241 1241
1242 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 1242 if (ic->ic_opmode == IEEE80211_M_HOSTAP)
1243 frmhdr.wi_tx_rate = 5 * (rs->rs_rates[rateidx] & 1243 frmhdr.wi_tx_rate = 5 * (rs->rs_rates[rateidx] &
1244 IEEE80211_RATE_VAL); 1244 IEEE80211_RATE_VAL);
1245 else if (sc->sc_flags & WI_FLAGS_RSSADAPTSTA) 1245 else if (sc->sc_flags & WI_FLAGS_RSSADAPTSTA)
1246 (void)wi_write_txrate(sc, rs->rs_rates[rateidx]); 1246 (void)wi_write_txrate(sc, rs->rs_rates[rateidx]);
1247 1247
1248 m_copydata(m0, 0, sizeof(struct ieee80211_frame), 1248 m_copydata(m0, 0, sizeof(struct ieee80211_frame),
1249 (void *)&frmhdr.wi_whdr); 1249 (void *)&frmhdr.wi_whdr);
1250 m_adj(m0, sizeof(struct ieee80211_frame)); 1250 m_adj(m0, sizeof(struct ieee80211_frame));
1251 frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len); 1251 frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
1252 if (IFF_DUMPPKTS(ifp)) 1252 if (IFF_DUMPPKTS(ifp))
1253 wi_dump_pkt(&frmhdr, ni, -1); 1253 wi_dump_pkt(&frmhdr, ni, -1);
1254 fid = sc->sc_txd[cur].d_fid; 1254 fid = sc->sc_txd[cur].d_fid;
1255 off = sizeof(frmhdr); 1255 off = sizeof(frmhdr);
1256 if (wi_write_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0 || 1256 if (wi_write_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0 ||
1257 wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0) { 1257 wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0) {
1258 aprint_error_dev(sc->sc_dev, "%s write fid %x failed\n", 1258 aprint_error_dev(sc->sc_dev, "%s write fid %x failed\n",
1259 __func__, fid); 1259 __func__, fid);
1260 ifp->if_oerrors++; 1260 ifp->if_oerrors++;
1261 m_freem(m0); 1261 m_freem(m0);
1262 goto next; 1262 goto next;
1263 } 1263 }
1264 m_freem(m0); 1264 m_freem(m0);
1265 sc->sc_txpending[ni->ni_txrate]++; 1265 sc->sc_txpending[ni->ni_txrate]++;
1266 --sc->sc_txalloced; 1266 --sc->sc_txalloced;
1267 if (sc->sc_txqueued++ == 0) { 1267 if (sc->sc_txqueued++ == 0) {
1268#ifdef DIAGNOSTIC 1268#ifdef DIAGNOSTIC
1269 if (cur != sc->sc_txstart) 1269 if (cur != sc->sc_txstart)
1270 printf("%s: ring is desynchronized\n", 1270 printf("%s: ring is desynchronized\n",
1271 device_xname(sc->sc_dev)); 1271 device_xname(sc->sc_dev));
1272#endif 1272#endif
1273 wi_push_packet(sc); 1273 wi_push_packet(sc);
1274 } else { 1274 } else {
1275#ifdef WI_RING_DEBUG 1275#ifdef WI_RING_DEBUG
1276 printf("%s: queue %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n", 1276 printf("%s: queue %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1277 device_xname(sc->sc_dev), fid, 1277 device_xname(sc->sc_dev), fid,
1278 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart, 1278 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1279 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted); 1279 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1280#endif 1280#endif
1281 } 1281 }
1282 sc->sc_txqueue = cur = (cur + 1) % WI_NTXBUF; 1282 sc->sc_txqueue = cur = (cur + 1) % WI_NTXBUF;
1283 SLIST_REMOVE_HEAD(&sc->sc_rssdfree, rd_next); 1283 SLIST_REMOVE_HEAD(&sc->sc_rssdfree, rd_next);
1284 id->id_node = ni; 1284 id->id_node = ni;
1285 continue; 1285 continue;
1286next: 1286next:
1287 if (ni != NULL) 1287 if (ni != NULL)
1288 ieee80211_free_node(ni); 1288 ieee80211_free_node(ni);
1289 } 1289 }
1290} 1290}
1291 1291
1292 1292
1293STATIC int 1293STATIC int
1294wi_reset(struct wi_softc *sc) 1294wi_reset(struct wi_softc *sc)
1295{ 1295{
1296 int i, error; 1296 int i, error;
1297 1297
1298 DPRINTF(("wi_reset\n")); 1298 DPRINTF(("wi_reset\n"));
1299 1299
1300 if (sc->sc_reset) 1300 if (sc->sc_reset)
1301 (*sc->sc_reset)(sc); 1301 (*sc->sc_reset)(sc);
1302 1302
1303 error = 0; 1303 error = 0;
1304 for (i = 0; i < 5; i++) { 1304 for (i = 0; i < 5; i++) {
1305 if (sc->sc_invalid) 1305 if (sc->sc_invalid)
1306 return ENXIO; 1306 return ENXIO;
1307 DELAY(20*1000); /* XXX: way too long! */ 1307 DELAY(20*1000); /* XXX: way too long! */
1308 if ((error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0)) == 0) 1308 if ((error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0)) == 0)
1309 break; 1309 break;
1310 } 1310 }
1311 if (error) { 1311 if (error) {
1312 aprint_error_dev(sc->sc_dev, "init failed\n"); 1312 aprint_error_dev(sc->sc_dev, "init failed\n");
1313 return error; 1313 return error;
1314 } 1314 }
1315 CSR_WRITE_2(sc, WI_INT_EN, 0); 1315 CSR_WRITE_2(sc, WI_INT_EN, 0);
1316 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0); 1316 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
1317 1317
1318 /* Calibrate timer. */ 1318 /* Calibrate timer. */
1319 wi_write_val(sc, WI_RID_TICK_TIME, 0); 1319 wi_write_val(sc, WI_RID_TICK_TIME, 0);
1320 return 0; 1320 return 0;
1321} 1321}
1322 1322
1323STATIC void 1323STATIC void
1324wi_watchdog(struct ifnet *ifp) 1324wi_watchdog(struct ifnet *ifp)
1325{ 1325{
1326 struct wi_softc *sc = ifp->if_softc; 1326 struct wi_softc *sc = ifp->if_softc;
1327 1327
1328 ifp->if_timer = 0; 1328 ifp->if_timer = 0;
1329 if (!sc->sc_enabled) 1329 if (!sc->sc_enabled)
1330 return; 1330 return;
1331 1331
1332 if (sc->sc_tx_timer) { 1332 if (sc->sc_tx_timer) {
1333 if (--sc->sc_tx_timer == 0) { 1333 if (--sc->sc_tx_timer == 0) {
1334 printf("%s: device timeout\n", ifp->if_xname); 1334 printf("%s: device timeout\n", ifp->if_xname);
1335 ifp->if_oerrors++; 1335 ifp->if_oerrors++;
1336 wi_init(ifp); 1336 wi_init(ifp);
1337 return; 1337 return;
1338 } 1338 }
1339 ifp->if_timer = 1; 1339 ifp->if_timer = 1;
1340 } 1340 }
1341 1341
1342 if (sc->sc_scan_timer) { 1342 if (sc->sc_scan_timer) {
1343 if (--sc->sc_scan_timer <= WI_SCAN_WAIT - WI_SCAN_INQWAIT && 1343 if (--sc->sc_scan_timer <= WI_SCAN_WAIT - WI_SCAN_INQWAIT &&
1344 sc->sc_firmware_type == WI_INTERSIL) { 1344 sc->sc_firmware_type == WI_INTERSIL) {
1345 DPRINTF(("wi_watchdog: inquire scan\n")); 1345 DPRINTF(("wi_watchdog: inquire scan\n"));
1346 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0); 1346 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
1347 } 1347 }
1348 if (sc->sc_scan_timer) 1348 if (sc->sc_scan_timer)
1349 ifp->if_timer = 1; 1349 ifp->if_timer = 1;
1350 } 1350 }
1351 1351
1352 /* TODO: rate control */ 1352 /* TODO: rate control */
1353 ieee80211_watchdog(&sc->sc_ic); 1353 ieee80211_watchdog(&sc->sc_ic);
1354} 1354}
1355 1355
1356static int 1356static int
1357wi_ioctl_enter(struct wi_softc *sc) 1357wi_ioctl_enter(struct wi_softc *sc)
1358{ 1358{
1359 int rc = 0; 1359 int rc = 0;
1360 1360
1361 mutex_enter(&sc->sc_ioctl_mtx); 1361 mutex_enter(&sc->sc_ioctl_mtx);
1362 sc->sc_ioctl_nwait++; 1362 sc->sc_ioctl_nwait++;
1363 while (sc->sc_ioctl_lwp != NULL && sc->sc_ioctl_lwp != curlwp) { 1363 while (sc->sc_ioctl_lwp != NULL && sc->sc_ioctl_lwp != curlwp) {
1364 rc = sc->sc_ioctl_gone 1364 rc = sc->sc_ioctl_gone
1365 ? ENXIO 1365 ? ENXIO
1366 : cv_wait_sig(&sc->sc_ioctl_cv, &sc->sc_ioctl_mtx); 1366 : cv_wait_sig(&sc->sc_ioctl_cv, &sc->sc_ioctl_mtx);
1367 if (rc != 0) 1367 if (rc != 0)
1368 break; 1368 break;
1369 } 1369 }
1370 if (rc == 0) { 1370 if (rc == 0) {
1371 sc->sc_ioctl_lwp = curlwp; 1371 sc->sc_ioctl_lwp = curlwp;
1372 sc->sc_ioctl_depth++; 1372 sc->sc_ioctl_depth++;
1373 } 1373 }
1374 if (--sc->sc_ioctl_nwait == 0) 1374 if (--sc->sc_ioctl_nwait == 0)
1375 cv_signal(&sc->sc_ioctl_cv); 1375 cv_signal(&sc->sc_ioctl_cv);
1376 mutex_exit(&sc->sc_ioctl_mtx); 1376 mutex_exit(&sc->sc_ioctl_mtx);
1377 return rc; 1377 return rc;
1378} 1378}
1379 1379
1380static void 1380static void
1381wi_ioctl_exit(struct wi_softc *sc) 1381wi_ioctl_exit(struct wi_softc *sc)
1382{ 1382{
1383 KASSERT(sc->sc_ioctl_lwp == curlwp); 1383 KASSERT(sc->sc_ioctl_lwp == curlwp);
1384 mutex_enter(&sc->sc_ioctl_mtx); 1384 mutex_enter(&sc->sc_ioctl_mtx);
1385 if (--sc->sc_ioctl_depth == 0) { 1385 if (--sc->sc_ioctl_depth == 0) {
1386 sc->sc_ioctl_lwp = NULL; 1386 sc->sc_ioctl_lwp = NULL;
1387 cv_signal(&sc->sc_ioctl_cv); 1387 cv_signal(&sc->sc_ioctl_cv);
1388 } 1388 }
1389 mutex_exit(&sc->sc_ioctl_mtx); 1389 mutex_exit(&sc->sc_ioctl_mtx);
1390} 1390}
1391 1391
1392static void 1392static void
1393wi_ioctl_init(struct wi_softc *sc) 1393wi_ioctl_init(struct wi_softc *sc)
1394{ 1394{
1395 mutex_init(&sc->sc_ioctl_mtx, MUTEX_DEFAULT, IPL_NONE); 1395 mutex_init(&sc->sc_ioctl_mtx, MUTEX_DEFAULT, IPL_NONE);
1396 cv_init(&sc->sc_ioctl_cv, device_xname(sc->sc_dev)); 1396 cv_init(&sc->sc_ioctl_cv, device_xname(sc->sc_dev));
1397} 1397}
1398 1398
1399static void 1399static void
1400wi_ioctl_drain(struct wi_softc *sc) 1400wi_ioctl_drain(struct wi_softc *sc)
1401{ 1401{
1402 wi_ioctl_enter(sc); 1402 wi_ioctl_enter(sc);
1403 1403
1404 mutex_enter(&sc->sc_ioctl_mtx); 1404 mutex_enter(&sc->sc_ioctl_mtx);
1405 sc->sc_ioctl_gone = true; 1405 sc->sc_ioctl_gone = true;
1406 cv_broadcast(&sc->sc_ioctl_cv); 1406 cv_broadcast(&sc->sc_ioctl_cv);
1407 while (sc->sc_ioctl_nwait != 0) 1407 while (sc->sc_ioctl_nwait != 0)
1408 cv_wait(&sc->sc_ioctl_cv, &sc->sc_ioctl_mtx); 1408 cv_wait(&sc->sc_ioctl_cv, &sc->sc_ioctl_mtx);
1409 mutex_exit(&sc->sc_ioctl_mtx); 1409 mutex_exit(&sc->sc_ioctl_mtx);
1410 1410
1411 wi_ioctl_exit(sc); 1411 wi_ioctl_exit(sc);
1412 1412
1413 mutex_destroy(&sc->sc_ioctl_mtx); 1413 mutex_destroy(&sc->sc_ioctl_mtx);
1414 cv_destroy(&sc->sc_ioctl_cv); 1414 cv_destroy(&sc->sc_ioctl_cv);
1415} 1415}
1416 1416
1417STATIC int 1417STATIC int
1418wi_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1418wi_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1419{ 1419{
1420 struct wi_softc *sc = ifp->if_softc; 1420 struct wi_softc *sc = ifp->if_softc;
1421 struct ieee80211com *ic = &sc->sc_ic; 1421 struct ieee80211com *ic = &sc->sc_ic;
1422 struct ifreq *ifr = (struct ifreq *)data; 
1423 int s, error = 0; 1422 int s, error = 0;
1424 1423
1425 if (!device_is_active(sc->sc_dev)) 1424 if (!device_is_active(sc->sc_dev))
1426 return ENXIO; 1425 return ENXIO;
1427 1426
1428 s = splnet(); 1427 s = splnet();
1429 1428
1430 if ((error = wi_ioctl_enter(sc)) != 0) { 1429 if ((error = wi_ioctl_enter(sc)) != 0) {
1431 splx(s); 1430 splx(s);
1432 return error; 1431 return error;
1433 } 1432 }
1434 1433
1435 switch (cmd) { 1434 switch (cmd) {
1436 case SIOCSIFFLAGS: 1435 case SIOCSIFFLAGS:
1437 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 1436 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
1438 break; 1437 break;
1439 /* 1438 /*
1440 * Can't do promisc and hostap at the same time. If all that's 1439 * Can't do promisc and hostap at the same time. If all that's
1441 * changing is the promisc flag, try to short-circuit a call to 1440 * changing is the promisc flag, try to short-circuit a call to
1442 * wi_init() by just setting PROMISC in the hardware. 1441 * wi_init() by just setting PROMISC in the hardware.
1443 */ 1442 */
1444 if (ifp->if_flags & IFF_UP) { 1443 if (ifp->if_flags & IFF_UP) {
1445 if (sc->sc_enabled) { 1444 if (sc->sc_enabled) {
1446 if (ic->ic_opmode != IEEE80211_M_HOSTAP && 1445 if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
1447 (ifp->if_flags & IFF_PROMISC) != 0) 1446 (ifp->if_flags & IFF_PROMISC) != 0)
1448 wi_write_val(sc, WI_RID_PROMISC, 1); 1447 wi_write_val(sc, WI_RID_PROMISC, 1);
1449 else 1448 else
1450 wi_write_val(sc, WI_RID_PROMISC, 0); 1449 wi_write_val(sc, WI_RID_PROMISC, 0);
1451 } else 1450 } else
1452 error = wi_init(ifp); 1451 error = wi_init(ifp);
1453 } else if (sc->sc_enabled) 1452 } else if (sc->sc_enabled)
1454 wi_stop(ifp, 1); 1453 wi_stop(ifp, 1);
1455 break; 1454 break;
1456 case SIOCSIFMEDIA: 
1457 case SIOCGIFMEDIA: 
1458 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 
1459 break; 
1460 case SIOCADDMULTI: 1455 case SIOCADDMULTI:
1461 case SIOCDELMULTI: 1456 case SIOCDELMULTI:
1462 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 1457 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
1463 if (ifp->if_flags & IFF_RUNNING) { 1458 if (ifp->if_flags & IFF_RUNNING) {
1464 /* do not rescan */ 1459 /* do not rescan */
1465 error = wi_write_multi(sc); 1460 error = wi_write_multi(sc);
1466 } else 1461 } else
1467 error = 0; 1462 error = 0;
1468 } 1463 }
1469 break; 1464 break;
1470 case SIOCGIFGENERIC: 1465 case SIOCGIFGENERIC:
1471 error = wi_get_cfg(ifp, cmd, data); 1466 error = wi_get_cfg(ifp, cmd, data);
1472 break; 1467 break;
1473 case SIOCSIFGENERIC: 1468 case SIOCSIFGENERIC:
1474 error = kauth_authorize_network(curlwp->l_cred, 1469 error = kauth_authorize_network(curlwp->l_cred,
1475 KAUTH_NETWORK_INTERFACE, 1470 KAUTH_NETWORK_INTERFACE,
1476 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, KAUTH_ARG(cmd), 1471 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, KAUTH_ARG(cmd),
1477 NULL); 1472 NULL);
1478 if (error) 1473 if (error)
1479 break; 1474 break;
1480 error = wi_set_cfg(ifp, cmd, data); 1475 error = wi_set_cfg(ifp, cmd, data);
1481 if (error == ENETRESET) { 1476 if (error == ENETRESET) {
1482 if (ifp->if_flags & IFF_RUNNING) 1477 if (ifp->if_flags & IFF_RUNNING)
1483 error = wi_init(ifp); 1478 error = wi_init(ifp);
1484 else 1479 else
1485 error = 0; 1480 error = 0;
1486 } 1481 }
1487 break; 1482 break;
1488 case SIOCS80211BSSID: 1483 case SIOCS80211BSSID:
1489 if (sc->sc_firmware_type == WI_LUCENT) { 1484 if (sc->sc_firmware_type == WI_LUCENT) {
1490 error = ENODEV; 1485 error = ENODEV;
1491 break; 1486 break;
1492 } 1487 }
1493 /* fall through */ 1488 /* fall through */
1494 default: 1489 default:
1495 ic->ic_flags |= sc->sc_ic_flags; 1490 ic->ic_flags |= sc->sc_ic_flags;
1496 error = ieee80211_ioctl(&sc->sc_ic, cmd, data); 1491 error = ieee80211_ioctl(&sc->sc_ic, cmd, data);
1497 sc->sc_ic_flags = ic->ic_flags & IEEE80211_F_DROPUNENC; 1492 sc->sc_ic_flags = ic->ic_flags & IEEE80211_F_DROPUNENC;
1498 if (error == ENETRESET) { 1493 if (error == ENETRESET) {
1499 if (sc->sc_enabled) 1494 if (sc->sc_enabled)
1500 error = wi_init(ifp); 1495 error = wi_init(ifp);
1501 else 1496 else
1502 error = 0; 1497 error = 0;
1503 } 1498 }
1504 break; 1499 break;
1505 } 1500 }
1506 wi_mend_flags(sc, ic->ic_state); 1501 wi_mend_flags(sc, ic->ic_state);
1507 wi_ioctl_exit(sc); 1502 wi_ioctl_exit(sc);
1508 splx(s); 1503 splx(s);
1509 return error; 1504 return error;
1510} 1505}
1511 1506
1512STATIC int 1507STATIC int
1513wi_media_change(struct ifnet *ifp) 1508wi_media_change(struct ifnet *ifp)
1514{ 1509{
1515 struct wi_softc *sc = ifp->if_softc; 1510 struct wi_softc *sc = ifp->if_softc;
1516 struct ieee80211com *ic = &sc->sc_ic; 1511 struct ieee80211com *ic = &sc->sc_ic;
1517 int error; 1512 int error;
1518 1513
1519 error = ieee80211_media_change(ifp); 1514 error = ieee80211_media_change(ifp);
1520 if (error == ENETRESET) { 1515 if (error == ENETRESET) {
1521 if (sc->sc_enabled) 1516 if (sc->sc_enabled)
1522 error = wi_init(ifp); 1517 error = wi_init(ifp);
1523 else 1518 else
1524 error = 0; 1519 error = 0;
1525 } 1520 }
1526 ifp->if_baudrate = ifmedia_baudrate(ic->ic_media.ifm_cur->ifm_media); 1521 ifp->if_baudrate = ifmedia_baudrate(ic->ic_media.ifm_cur->ifm_media);
1527 1522
1528 return error; 1523 return error;
1529} 1524}
1530 1525
1531STATIC void 1526STATIC void
1532wi_media_status(struct ifnet *ifp, struct ifmediareq *imr) 1527wi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1533{ 1528{
1534 struct wi_softc *sc = ifp->if_softc; 1529 struct wi_softc *sc = ifp->if_softc;
1535 struct ieee80211com *ic = &sc->sc_ic; 1530 struct ieee80211com *ic = &sc->sc_ic;
1536 uint16_t val; 1531 uint16_t val;
1537 int rate; 1532 int rate;
1538 1533
1539 if (sc->sc_enabled == 0) { 1534 if (sc->sc_enabled == 0) {
1540 imr->ifm_active = IFM_IEEE80211 | IFM_NONE; 1535 imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
1541 imr->ifm_status = 0; 1536 imr->ifm_status = 0;
1542 return; 1537 return;
1543 } 1538 }
1544 1539
1545 imr->ifm_status = IFM_AVALID; 1540 imr->ifm_status = IFM_AVALID;
1546 imr->ifm_active = IFM_IEEE80211; 1541 imr->ifm_active = IFM_IEEE80211;
1547 if (ic->ic_state == IEEE80211_S_RUN && 1542 if (ic->ic_state == IEEE80211_S_RUN &&
1548 (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0) 1543 (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0)
1549 imr->ifm_status |= IFM_ACTIVE; 1544 imr->ifm_status |= IFM_ACTIVE;
1550 if (wi_read_xrid(sc, WI_RID_CUR_TX_RATE, &val, sizeof(val)) == 0) { 1545 if (wi_read_xrid(sc, WI_RID_CUR_TX_RATE, &val, sizeof(val)) == 0) {
1551 /* convert to 802.11 rate */ 1546 /* convert to 802.11 rate */
1552 val = le16toh(val); 1547 val = le16toh(val);
1553 rate = val * 2; 1548 rate = val * 2;
1554 if (sc->sc_firmware_type == WI_LUCENT) { 1549 if (sc->sc_firmware_type == WI_LUCENT) {
1555 if (rate == 10) 1550 if (rate == 10)
1556 rate = 11; /* 5.5Mbps */ 1551 rate = 11; /* 5.5Mbps */
1557 } else { 1552 } else {
1558 if (rate == 4*2) 1553 if (rate == 4*2)
1559 rate = 11; /* 5.5Mbps */ 1554 rate = 11; /* 5.5Mbps */
1560 else if (rate == 8*2) 1555 else if (rate == 8*2)
1561 rate = 22; /* 11Mbps */ 1556 rate = 22; /* 11Mbps */
1562 } 1557 }
1563 } else 1558 } else
1564 rate = 0; 1559 rate = 0;
1565 imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B); 1560 imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B);
1566 switch (ic->ic_opmode) { 1561 switch (ic->ic_opmode) {
1567 case IEEE80211_M_STA: 1562 case IEEE80211_M_STA:
1568 break; 1563 break;
1569 case IEEE80211_M_IBSS: 1564 case IEEE80211_M_IBSS:
1570 imr->ifm_active |= IFM_IEEE80211_ADHOC; 1565 imr->ifm_active |= IFM_IEEE80211_ADHOC;
1571 break; 1566 break;
1572 case IEEE80211_M_AHDEMO: 1567 case IEEE80211_M_AHDEMO:
1573 imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0; 1568 imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0;
1574 break; 1569 break;
1575 case IEEE80211_M_HOSTAP: 1570 case IEEE80211_M_HOSTAP:
1576 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 1571 imr->ifm_active |= IFM_IEEE80211_HOSTAP;
1577 break; 1572 break;
1578 case IEEE80211_M_MONITOR: 1573 case IEEE80211_M_MONITOR:
1579 imr->ifm_active |= IFM_IEEE80211_MONITOR; 1574 imr->ifm_active |= IFM_IEEE80211_MONITOR;
1580 break; 1575 break;
1581 } 1576 }
1582} 1577}
1583 1578
1584STATIC struct ieee80211_node * 1579STATIC struct ieee80211_node *
1585wi_node_alloc(struct ieee80211_node_table *nt) 1580wi_node_alloc(struct ieee80211_node_table *nt)
1586{ 1581{
1587 struct wi_node *wn = 1582 struct wi_node *wn =
1588 malloc(sizeof(struct wi_node), M_DEVBUF, M_NOWAIT | M_ZERO); 1583 malloc(sizeof(struct wi_node), M_DEVBUF, M_NOWAIT | M_ZERO);
1589 return wn ? &wn->wn_node : NULL; 1584 return wn ? &wn->wn_node : NULL;
1590} 1585}
1591 1586
1592STATIC void 1587STATIC void
1593wi_node_free(struct ieee80211_node *ni) 1588wi_node_free(struct ieee80211_node *ni)
1594{ 1589{
1595 struct wi_softc *sc = ni->ni_ic->ic_ifp->if_softc; 1590 struct wi_softc *sc = ni->ni_ic->ic_ifp->if_softc;
1596 int i; 1591 int i;
1597 1592
1598 for (i = 0; i < WI_NTXRSS; i++) { 1593 for (i = 0; i < WI_NTXRSS; i++) {
1599 if (sc->sc_rssd[i].rd_desc.id_node == ni) 1594 if (sc->sc_rssd[i].rd_desc.id_node == ni)
1600 sc->sc_rssd[i].rd_desc.id_node = NULL; 1595 sc->sc_rssd[i].rd_desc.id_node = NULL;
1601 } 1596 }
1602 free(ni, M_DEVBUF); 1597 free(ni, M_DEVBUF);
1603} 1598}
1604 1599
1605STATIC void 1600STATIC void
1606wi_sync_bssid(struct wi_softc *sc, uint8_t new_bssid[IEEE80211_ADDR_LEN]) 1601wi_sync_bssid(struct wi_softc *sc, uint8_t new_bssid[IEEE80211_ADDR_LEN])
1607{ 1602{
1608 struct ieee80211com *ic = &sc->sc_ic; 1603 struct ieee80211com *ic = &sc->sc_ic;
1609 struct ieee80211_node *ni = ic->ic_bss; 1604 struct ieee80211_node *ni = ic->ic_bss;
1610 struct ifnet *ifp = &sc->sc_if; 1605 struct ifnet *ifp = &sc->sc_if;
1611 int s; 1606 int s;
1612 1607
1613 if (IEEE80211_ADDR_EQ(new_bssid, ni->ni_bssid)) 1608 if (IEEE80211_ADDR_EQ(new_bssid, ni->ni_bssid))
1614 return; 1609 return;
1615 1610
1616 DPRINTF(("wi_sync_bssid: bssid %s -> ", ether_sprintf(ni->ni_bssid))); 1611 DPRINTF(("wi_sync_bssid: bssid %s -> ", ether_sprintf(ni->ni_bssid)));
1617 DPRINTF(("%s ?\n", ether_sprintf(new_bssid))); 1612 DPRINTF(("%s ?\n", ether_sprintf(new_bssid)));
1618 1613
1619 /* In promiscuous mode, the BSSID field is not a reliable 1614 /* In promiscuous mode, the BSSID field is not a reliable
1620 * indicator of the firmware's BSSID. Damp spurious 1615 * indicator of the firmware's BSSID. Damp spurious
1621 * change-of-BSSID indications. 1616 * change-of-BSSID indications.
1622 */ 1617 */
1623 if ((ifp->if_flags & IFF_PROMISC) != 0 && 1618 if ((ifp->if_flags & IFF_PROMISC) != 0 &&
1624 !ppsratecheck(&sc->sc_last_syn, &sc->sc_false_syns, 1619 !ppsratecheck(&sc->sc_last_syn, &sc->sc_false_syns,
1625 WI_MAX_FALSE_SYNS)) 1620 WI_MAX_FALSE_SYNS))
1626 return; 1621 return;
1627 1622
1628 sc->sc_false_syns = MAX(0, sc->sc_false_syns - 1); 1623 sc->sc_false_syns = MAX(0, sc->sc_false_syns - 1);
1629 /* 1624 /*
1630 * XXX hack; we should create a new node with the new bssid 1625 * XXX hack; we should create a new node with the new bssid
1631 * and replace the existing ic_bss with it but since we don't 1626 * and replace the existing ic_bss with it but since we don't
1632 * process management frames to collect state we cheat by 1627 * process management frames to collect state we cheat by
1633 * reusing the existing node as we know wi_newstate will be 1628 * reusing the existing node as we know wi_newstate will be
1634 * called and it will overwrite the node state. 1629 * called and it will overwrite the node state.
1635 */ 1630 */
1636 s = splnet(); 1631 s = splnet();
1637 ieee80211_sta_join(ic, ieee80211_ref_node(ni)); 1632 ieee80211_sta_join(ic, ieee80211_ref_node(ni));
1638 splx(s); 1633 splx(s);
1639} 1634}
1640 1635
1641static inline void 1636static inline void
1642wi_rssadapt_input(struct ieee80211com *ic, struct ieee80211_node *ni, 1637wi_rssadapt_input(struct ieee80211com *ic, struct ieee80211_node *ni,
1643 struct ieee80211_frame *wh, int rssi) 1638 struct ieee80211_frame *wh, int rssi)
1644{ 1639{
1645 struct wi_node *wn; 1640 struct wi_node *wn;
1646 1641
1647 if (ni == NULL) { 1642 if (ni == NULL) {
1648 printf("%s: null node", __func__); 1643 printf("%s: null node", __func__);
1649 return; 1644 return;
1650 } 1645 }
1651 1646
1652 wn = (void*)ni; 1647 wn = (void*)ni;
1653 ieee80211_rssadapt_input(ic, ni, &wn->wn_rssadapt, rssi); 1648 ieee80211_rssadapt_input(ic, ni, &wn->wn_rssadapt, rssi);
1654} 1649}
1655 1650
1656STATIC void 1651STATIC void
1657wi_rx_intr(struct wi_softc *sc) 1652wi_rx_intr(struct wi_softc *sc)
1658{ 1653{
1659 struct ieee80211com *ic = &sc->sc_ic; 1654 struct ieee80211com *ic = &sc->sc_ic;
1660 struct ifnet *ifp = &sc->sc_if; 1655 struct ifnet *ifp = &sc->sc_if;
1661 struct ieee80211_node *ni; 1656 struct ieee80211_node *ni;
1662 struct wi_frame frmhdr; 1657 struct wi_frame frmhdr;
1663 struct mbuf *m; 1658 struct mbuf *m;
1664 struct ieee80211_frame *wh; 1659 struct ieee80211_frame *wh;
1665 int fid, len, off, rssi; 1660 int fid, len, off, rssi;
1666 uint8_t dir; 1661 uint8_t dir;
1667 uint16_t status; 1662 uint16_t status;
1668 uint32_t rstamp; 1663 uint32_t rstamp;
1669 int s; 1664 int s;
1670 1665
1671 fid = CSR_READ_2(sc, WI_RX_FID); 1666 fid = CSR_READ_2(sc, WI_RX_FID);
1672 1667
1673 /* First read in the frame header */ 1668 /* First read in the frame header */
1674 if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) { 1669 if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) {
1675 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n", 1670 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n",
1676 __func__, fid); 1671 __func__, fid);
1677 ifp->if_ierrors++; 1672 ifp->if_ierrors++;
1678 return; 1673 return;
1679 } 1674 }
1680 1675
1681 if (IFF_DUMPPKTS(ifp)) 1676 if (IFF_DUMPPKTS(ifp))
1682 wi_dump_pkt(&frmhdr, NULL, frmhdr.wi_rx_signal); 1677 wi_dump_pkt(&frmhdr, NULL, frmhdr.wi_rx_signal);
1683 1678
1684 /* 1679 /*
1685 * Drop undecryptable or packets with receive errors here 1680 * Drop undecryptable or packets with receive errors here
1686 */ 1681 */
1687 status = le16toh(frmhdr.wi_status); 1682 status = le16toh(frmhdr.wi_status);
1688 if ((status & WI_STAT_ERRSTAT) != 0 && 1683 if ((status & WI_STAT_ERRSTAT) != 0 &&
1689 ic->ic_opmode != IEEE80211_M_MONITOR) { 1684 ic->ic_opmode != IEEE80211_M_MONITOR) {
1690 ifp->if_ierrors++; 1685 ifp->if_ierrors++;
1691 DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status)); 1686 DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status));
1692 return; 1687 return;
1693 } 1688 }
1694 rssi = frmhdr.wi_rx_signal; 1689 rssi = frmhdr.wi_rx_signal;
1695 rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) | 1690 rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) |
1696 le16toh(frmhdr.wi_rx_tstamp1); 1691 le16toh(frmhdr.wi_rx_tstamp1);
1697 1692
1698 len = le16toh(frmhdr.wi_dat_len); 1693 len = le16toh(frmhdr.wi_dat_len);
1699 off = ALIGN(sizeof(struct ieee80211_frame)); 1694 off = ALIGN(sizeof(struct ieee80211_frame));
1700 1695
1701 /* Sometimes the PRISM2.x returns bogusly large frames. Except 1696 /* Sometimes the PRISM2.x returns bogusly large frames. Except
1702 * in monitor mode, just throw them away. 1697 * in monitor mode, just throw them away.
1703 */ 1698 */
1704 if (off + len > MCLBYTES) { 1699 if (off + len > MCLBYTES) {
1705 if (ic->ic_opmode != IEEE80211_M_MONITOR) { 1700 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1706 ifp->if_ierrors++; 1701 ifp->if_ierrors++;
1707 DPRINTF(("wi_rx_intr: oversized packet\n")); 1702 DPRINTF(("wi_rx_intr: oversized packet\n"));
1708 return; 1703 return;
1709 } else 1704 } else
1710 len = 0; 1705 len = 0;
1711 } 1706 }
1712 1707
1713 MGETHDR(m, M_DONTWAIT, MT_DATA); 1708 MGETHDR(m, M_DONTWAIT, MT_DATA);
1714 if (m == NULL) { 1709 if (m == NULL) {
1715 ifp->if_ierrors++; 1710 ifp->if_ierrors++;
1716 DPRINTF(("wi_rx_intr: MGET failed\n")); 1711 DPRINTF(("wi_rx_intr: MGET failed\n"));
1717 return; 1712 return;
1718 } 1713 }
1719 if (off + len > MHLEN) { 1714 if (off + len > MHLEN) {
1720 MCLGET(m, M_DONTWAIT); 1715 MCLGET(m, M_DONTWAIT);
1721 if ((m->m_flags & M_EXT) == 0) { 1716 if ((m->m_flags & M_EXT) == 0) {
1722 m_freem(m); 1717 m_freem(m);
1723 ifp->if_ierrors++; 1718 ifp->if_ierrors++;
1724 DPRINTF(("wi_rx_intr: MCLGET failed\n")); 1719 DPRINTF(("wi_rx_intr: MCLGET failed\n"));
1725 return; 1720 return;
1726 } 1721 }
1727 } 1722 }
1728 1723
1729 m->m_data += off - sizeof(struct ieee80211_frame); 1724 m->m_data += off - sizeof(struct ieee80211_frame);
1730 memcpy(m->m_data, &frmhdr.wi_whdr, sizeof(struct ieee80211_frame)); 1725 memcpy(m->m_data, &frmhdr.wi_whdr, sizeof(struct ieee80211_frame));
1731 wi_read_bap(sc, fid, sizeof(frmhdr), 1726 wi_read_bap(sc, fid, sizeof(frmhdr),
1732 m->m_data + sizeof(struct ieee80211_frame), len); 1727 m->m_data + sizeof(struct ieee80211_frame), len);
1733 m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len; 1728 m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len;
1734 m_set_rcvif(m, ifp); 1729 m_set_rcvif(m, ifp);
1735 1730
1736 wh = mtod(m, struct ieee80211_frame *); 1731 wh = mtod(m, struct ieee80211_frame *);
1737 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1732 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1738 /* 1733 /*
1739 * WEP is decrypted by hardware. Clear WEP bit 1734 * WEP is decrypted by hardware. Clear WEP bit
1740 * header for ieee80211_input(). 1735 * header for ieee80211_input().
1741 */ 1736 */
1742 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 1737 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1743 } 1738 }
1744 1739
1745 s = splnet(); 1740 s = splnet();
1746 1741
1747 if (sc->sc_drvbpf) { 1742 if (sc->sc_drvbpf) {
1748 struct wi_rx_radiotap_header *tap = &sc->sc_rxtap; 1743 struct wi_rx_radiotap_header *tap = &sc->sc_rxtap;
1749 1744
1750 tap->wr_rate = frmhdr.wi_rx_rate / 5; 1745 tap->wr_rate = frmhdr.wi_rx_rate / 5;
1751 tap->wr_antsignal = frmhdr.wi_rx_signal; 1746 tap->wr_antsignal = frmhdr.wi_rx_signal;
1752 tap->wr_antnoise = frmhdr.wi_rx_silence; 1747 tap->wr_antnoise = frmhdr.wi_rx_silence;
1753 tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); 1748 tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
1754 tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); 1749 tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
1755 if (frmhdr.wi_status & WI_STAT_PCF) 1750 if (frmhdr.wi_status & WI_STAT_PCF)
1756 tap->wr_flags |= IEEE80211_RADIOTAP_F_CFP; 1751 tap->wr_flags |= IEEE80211_RADIOTAP_F_CFP;
1757 1752
1758 /* XXX IEEE80211_RADIOTAP_F_WEP */ 1753 /* XXX IEEE80211_RADIOTAP_F_WEP */
1759 bpf_mtap2(sc->sc_drvbpf, tap, tap->wr_ihdr.it_len, m, 1754 bpf_mtap2(sc->sc_drvbpf, tap, tap->wr_ihdr.it_len, m,
1760 BPF_D_IN); 1755 BPF_D_IN);
1761 } 1756 }
1762 1757
1763 /* synchronize driver's BSSID with firmware's BSSID */ 1758 /* synchronize driver's BSSID with firmware's BSSID */
1764 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 1759 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
1765 if (ic->ic_opmode == IEEE80211_M_IBSS && dir == IEEE80211_FC1_DIR_NODS) 1760 if (ic->ic_opmode == IEEE80211_M_IBSS && dir == IEEE80211_FC1_DIR_NODS)
1766 wi_sync_bssid(sc, wh->i_addr3); 1761 wi_sync_bssid(sc, wh->i_addr3);
1767 1762
1768 ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); 1763 ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
1769 1764
1770 ieee80211_input(ic, m, ni, rssi, rstamp); 1765 ieee80211_input(ic, m, ni, rssi, rstamp);
1771 1766
1772 wi_rssadapt_input(ic, ni, wh, rssi); 1767 wi_rssadapt_input(ic, ni, wh, rssi);
1773 1768
1774 /* 1769 /*
1775 * The frame may have caused the node to be marked for 1770 * The frame may have caused the node to be marked for
1776 * reclamation (e.g. in response to a DEAUTH message) 1771 * reclamation (e.g. in response to a DEAUTH message)
1777 * so use release_node here instead of unref_node. 1772 * so use release_node here instead of unref_node.
1778 */ 1773 */
1779 ieee80211_free_node(ni); 1774 ieee80211_free_node(ni);
1780 1775
1781 splx(s); 1776 splx(s);
1782} 1777}
1783 1778
1784STATIC void 1779STATIC void
1785wi_tx_ex_intr(struct wi_softc *sc) 1780wi_tx_ex_intr(struct wi_softc *sc)
1786{ 1781{
1787 struct ieee80211com *ic = &sc->sc_ic; 1782 struct ieee80211com *ic = &sc->sc_ic;
1788 struct ifnet *ifp = &sc->sc_if; 1783 struct ifnet *ifp = &sc->sc_if;
1789 struct ieee80211_node *ni; 1784 struct ieee80211_node *ni;
1790 struct ieee80211_rssdesc *id; 1785 struct ieee80211_rssdesc *id;
1791 struct wi_rssdesc *rssd; 1786 struct wi_rssdesc *rssd;
1792 struct wi_frame frmhdr; 1787 struct wi_frame frmhdr;
1793 int fid, s; 1788 int fid, s;
1794 uint16_t status; 1789 uint16_t status;
1795 1790
1796 s = splnet(); 1791 s = splnet();
1797 1792
1798 fid = CSR_READ_2(sc, WI_TX_CMP_FID); 1793 fid = CSR_READ_2(sc, WI_TX_CMP_FID);
1799 /* Read in the frame header */ 1794 /* Read in the frame header */
1800 if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0) { 1795 if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0) {
1801 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n", 1796 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n",
1802 __func__, fid); 1797 __func__, fid);
1803 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree, 1798 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1804 &sc->sc_txpending); 1799 &sc->sc_txpending);
1805 goto out; 1800 goto out;
1806 } 1801 }
1807 1802
1808 if (frmhdr.wi_tx_idx >= WI_NTXRSS) { 1803 if (frmhdr.wi_tx_idx >= WI_NTXRSS) {
1809 aprint_error_dev(sc->sc_dev, "%s bad idx %02x\n", 1804 aprint_error_dev(sc->sc_dev, "%s bad idx %02x\n",
1810 __func__, frmhdr.wi_tx_idx); 1805 __func__, frmhdr.wi_tx_idx);
1811 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree, 1806 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1812 &sc->sc_txpending); 1807 &sc->sc_txpending);
1813 goto out; 1808 goto out;
1814 } 1809 }
1815 1810
1816 status = le16toh(frmhdr.wi_status); 1811 status = le16toh(frmhdr.wi_status);
1817 1812
1818 /* 1813 /*
1819 * Spontaneous station disconnects appear as xmit 1814 * Spontaneous station disconnects appear as xmit
1820 * errors. Don't announce them and/or count them 1815 * errors. Don't announce them and/or count them
1821 * as an output error. 1816 * as an output error.
1822 */ 1817 */
1823 if (ppsratecheck(&lasttxerror, &curtxeps, wi_txerate)) { 1818 if (ppsratecheck(&lasttxerror, &curtxeps, wi_txerate)) {
1824 aprint_error_dev(sc->sc_dev, "tx failed"); 1819 aprint_error_dev(sc->sc_dev, "tx failed");
1825 if (status & WI_TXSTAT_RET_ERR) 1820 if (status & WI_TXSTAT_RET_ERR)
1826 printf(", retry limit exceeded"); 1821 printf(", retry limit exceeded");
1827 if (status & WI_TXSTAT_AGED_ERR) 1822 if (status & WI_TXSTAT_AGED_ERR)
1828 printf(", max transmit lifetime exceeded"); 1823 printf(", max transmit lifetime exceeded");
1829 if (status & WI_TXSTAT_DISCONNECT) 1824 if (status & WI_TXSTAT_DISCONNECT)
1830 printf(", port disconnected"); 1825 printf(", port disconnected");
1831 if (status & WI_TXSTAT_FORM_ERR) 1826 if (status & WI_TXSTAT_FORM_ERR)
1832 printf(", invalid format (data len %u src %s)", 1827 printf(", invalid format (data len %u src %s)",
1833 le16toh(frmhdr.wi_dat_len), 1828 le16toh(frmhdr.wi_dat_len),
1834 ether_sprintf(frmhdr.wi_ehdr.ether_shost)); 1829 ether_sprintf(frmhdr.wi_ehdr.ether_shost));
1835 if (status & ~0xf) 1830 if (status & ~0xf)
1836 printf(", status=0x%x", status); 1831 printf(", status=0x%x", status);
1837 printf("\n"); 1832 printf("\n");
1838 } 1833 }
1839 ifp->if_oerrors++; 1834 ifp->if_oerrors++;
1840 rssd = &sc->sc_rssd[frmhdr.wi_tx_idx]; 1835 rssd = &sc->sc_rssd[frmhdr.wi_tx_idx];
1841 id = &rssd->rd_desc; 1836 id = &rssd->rd_desc;
1842 if ((status & WI_TXSTAT_RET_ERR) != 0) 1837 if ((status & WI_TXSTAT_RET_ERR) != 0)
1843 wi_lower_rate(ic, id); 1838 wi_lower_rate(ic, id);
1844 1839
1845 ni = id->id_node; 1840 ni = id->id_node;
1846 id->id_node = NULL; 1841 id->id_node = NULL;
1847 1842
1848 if (ni == NULL) { 1843 if (ni == NULL) {
1849 aprint_error_dev(sc->sc_dev, "%s null node, rssdesc %02x\n", 1844 aprint_error_dev(sc->sc_dev, "%s null node, rssdesc %02x\n",
1850 __func__, frmhdr.wi_tx_idx); 1845 __func__, frmhdr.wi_tx_idx);
1851 goto out; 1846 goto out;
1852 } 1847 }
1853 1848
1854 if (sc->sc_txpending[id->id_rateidx]-- == 0) { 1849 if (sc->sc_txpending[id->id_rateidx]-- == 0) {
1855 aprint_error_dev(sc->sc_dev, "%s txpending[%i] wraparound", 1850 aprint_error_dev(sc->sc_dev, "%s txpending[%i] wraparound",
1856 __func__, id->id_rateidx); 1851 __func__, id->id_rateidx);
1857 sc->sc_txpending[id->id_rateidx] = 0; 1852 sc->sc_txpending[id->id_rateidx] = 0;
1858 } 1853 }
1859 if (ni != NULL) 1854 if (ni != NULL)
1860 ieee80211_free_node(ni); 1855 ieee80211_free_node(ni);
1861 SLIST_INSERT_HEAD(&sc->sc_rssdfree, rssd, rd_next); 1856 SLIST_INSERT_HEAD(&sc->sc_rssdfree, rssd, rd_next);
1862out: 1857out:
1863 ifp->if_flags &= ~IFF_OACTIVE; 1858 ifp->if_flags &= ~IFF_OACTIVE;
1864 splx(s); 1859 splx(s);
1865} 1860}
1866 1861
1867STATIC void 1862STATIC void
1868wi_txalloc_intr(struct wi_softc *sc) 1863wi_txalloc_intr(struct wi_softc *sc)
1869{ 1864{
1870 int fid, cur, s; 1865 int fid, cur, s;
1871 1866
1872 s = splnet(); 1867 s = splnet();
1873 1868
1874 fid = CSR_READ_2(sc, WI_ALLOC_FID); 1869 fid = CSR_READ_2(sc, WI_ALLOC_FID);
1875 1870
1876 cur = sc->sc_txalloc; 1871 cur = sc->sc_txalloc;
1877#ifdef DIAGNOSTIC 1872#ifdef DIAGNOSTIC
1878 if (sc->sc_txstarted == 0) { 1873 if (sc->sc_txstarted == 0) {
1879 printf("%s: spurious alloc %x != %x, alloc %d queue %d start %d alloced %d queued %d started %d\n", 1874 printf("%s: spurious alloc %x != %x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1880 device_xname(sc->sc_dev), fid, sc->sc_txd[cur].d_fid, cur, 1875 device_xname(sc->sc_dev), fid, sc->sc_txd[cur].d_fid, cur,
1881 sc->sc_txqueue, sc->sc_txstart, sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted); 1876 sc->sc_txqueue, sc->sc_txstart, sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1882 splx(s); 1877 splx(s);
1883 return; 1878 return;
1884 } 1879 }
1885#endif 1880#endif
1886 --sc->sc_txstarted; 1881 --sc->sc_txstarted;
1887 ++sc->sc_txalloced; 1882 ++sc->sc_txalloced;
1888 sc->sc_txd[cur].d_fid = fid; 1883 sc->sc_txd[cur].d_fid = fid;
1889 sc->sc_txalloc = (cur + 1) % WI_NTXBUF; 1884 sc->sc_txalloc = (cur + 1) % WI_NTXBUF;
1890#ifdef WI_RING_DEBUG 1885#ifdef WI_RING_DEBUG
1891 printf("%s: alloc %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n", 1886 printf("%s: alloc %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1892 device_xname(sc->sc_dev), fid, 1887 device_xname(sc->sc_dev), fid,
1893 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart, 1888 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1894 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted); 1889 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1895#endif 1890#endif
1896 splx(s); 1891 splx(s);
1897} 1892}
1898 1893
1899STATIC void 1894STATIC void
1900wi_cmd_intr(struct wi_softc *sc) 1895wi_cmd_intr(struct wi_softc *sc)
1901{ 1896{
1902 struct ifnet *ifp = &sc->sc_if; 1897 struct ifnet *ifp = &sc->sc_if;
1903 int s; 1898 int s;
1904 1899
1905 if (sc->sc_invalid) 1900 if (sc->sc_invalid)
1906 return; 1901 return;
1907 1902
1908 s = splnet(); 1903 s = splnet();
1909#ifdef WI_DEBUG 1904#ifdef WI_DEBUG
1910 if (wi_debug > 1) 1905 if (wi_debug > 1)
1911 printf("%s: %d txcmds outstanding\n", __func__, sc->sc_txcmds); 1906 printf("%s: %d txcmds outstanding\n", __func__, sc->sc_txcmds);
1912#endif 1907#endif
1913 KASSERT(sc->sc_txcmds > 0); 1908 KASSERT(sc->sc_txcmds > 0);
1914 1909
1915 --sc->sc_txcmds; 1910 --sc->sc_txcmds;
1916 1911
1917 if (--sc->sc_txqueued == 0) { 1912 if (--sc->sc_txqueued == 0) {
1918 sc->sc_tx_timer = 0; 1913 sc->sc_tx_timer = 0;
1919 ifp->if_flags &= ~IFF_OACTIVE; 1914 ifp->if_flags &= ~IFF_OACTIVE;
1920#ifdef WI_RING_DEBUG 1915#ifdef WI_RING_DEBUG
1921 printf("%s: cmd , alloc %d queue %d start %d alloced %d queued %d started %d\n", 1916 printf("%s: cmd , alloc %d queue %d start %d alloced %d queued %d started %d\n",
1922 device_xname(sc->sc_dev), 1917 device_xname(sc->sc_dev),
1923 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart, 1918 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1924 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted); 1919 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1925#endif 1920#endif
1926 } else 1921 } else
1927 wi_push_packet(sc); 1922 wi_push_packet(sc);
1928 splx(s); 1923 splx(s);
1929} 1924}
1930 1925
1931STATIC void 1926STATIC void
1932wi_push_packet(struct wi_softc *sc) 1927wi_push_packet(struct wi_softc *sc)
1933{ 1928{
1934 struct ifnet *ifp = &sc->sc_if; 1929 struct ifnet *ifp = &sc->sc_if;
1935 int cur, fid; 1930 int cur, fid;
1936 1931
1937 cur = sc->sc_txstart; 1932 cur = sc->sc_txstart;
1938 fid = sc->sc_txd[cur].d_fid; 1933 fid = sc->sc_txd[cur].d_fid;
1939 1934
1940 KASSERT(sc->sc_txcmds == 0); 1935 KASSERT(sc->sc_txcmds == 0);
1941 1936
1942 if (wi_cmd_start(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0)) { 1937 if (wi_cmd_start(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0)) {
1943 aprint_error_dev(sc->sc_dev, "xmit failed\n"); 1938 aprint_error_dev(sc->sc_dev, "xmit failed\n");
1944 /* XXX ring might have a hole */ 1939 /* XXX ring might have a hole */
1945 } 1940 }
1946 1941
1947 if (sc->sc_txcmds++ > 0) 1942 if (sc->sc_txcmds++ > 0)
1948 printf("%s: %d tx cmds pending!!!\n", __func__, sc->sc_txcmds); 1943 printf("%s: %d tx cmds pending!!!\n", __func__, sc->sc_txcmds);
1949 1944
1950 ++sc->sc_txstarted; 1945 ++sc->sc_txstarted;
1951#ifdef DIAGNOSTIC 1946#ifdef DIAGNOSTIC
1952 if (sc->sc_txstarted > WI_NTXBUF) 1947 if (sc->sc_txstarted > WI_NTXBUF)
1953 aprint_error_dev(sc->sc_dev, "too many buffers started\n"); 1948 aprint_error_dev(sc->sc_dev, "too many buffers started\n");
1954#endif 1949#endif
1955 sc->sc_txstart = (cur + 1) % WI_NTXBUF; 1950 sc->sc_txstart = (cur + 1) % WI_NTXBUF;
1956 sc->sc_tx_timer = 5; 1951 sc->sc_tx_timer = 5;
1957 ifp->if_timer = 1; 1952 ifp->if_timer = 1;
1958#ifdef WI_RING_DEBUG 1953#ifdef WI_RING_DEBUG
1959 printf("%s: push %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n", 1954 printf("%s: push %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1960 device_xname(sc->sc_dev), fid, 1955 device_xname(sc->sc_dev), fid,
1961 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart, 1956 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1962 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted); 1957 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1963#endif 1958#endif
1964} 1959}
1965 1960
1966STATIC void 1961STATIC void
1967wi_tx_intr(struct wi_softc *sc) 1962wi_tx_intr(struct wi_softc *sc)
1968{ 1963{
1969 struct ieee80211com *ic = &sc->sc_ic; 1964 struct ieee80211com *ic = &sc->sc_ic;
1970 struct ifnet *ifp = &sc->sc_if; 1965 struct ifnet *ifp = &sc->sc_if;
1971 struct ieee80211_node *ni; 1966 struct ieee80211_node *ni;
1972 struct ieee80211_rssdesc *id; 1967 struct ieee80211_rssdesc *id;
1973 struct wi_rssdesc *rssd; 1968 struct wi_rssdesc *rssd;
1974 struct wi_frame frmhdr; 1969 struct wi_frame frmhdr;
1975 int fid, s; 1970 int fid, s;
1976 1971
1977 s = splnet(); 1972 s = splnet();
1978 1973
1979 fid = CSR_READ_2(sc, WI_TX_CMP_FID); 1974 fid = CSR_READ_2(sc, WI_TX_CMP_FID);
1980 /* Read in the frame header */ 1975 /* Read in the frame header */
1981 if (wi_read_bap(sc, fid, offsetof(struct wi_frame, wi_tx_swsup2), 1976 if (wi_read_bap(sc, fid, offsetof(struct wi_frame, wi_tx_swsup2),
1982 &frmhdr.wi_tx_swsup2, 2) != 0) { 1977 &frmhdr.wi_tx_swsup2, 2) != 0) {
1983 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n", 1978 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n",
1984 __func__, fid); 1979 __func__, fid);
1985 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree, 1980 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1986 &sc->sc_txpending); 1981 &sc->sc_txpending);
1987 goto out; 1982 goto out;
1988 } 1983 }
1989 1984
1990 if (frmhdr.wi_tx_idx >= WI_NTXRSS) { 1985 if (frmhdr.wi_tx_idx >= WI_NTXRSS) {
1991 aprint_error_dev(sc->sc_dev, "%s bad idx %02x\n", 1986 aprint_error_dev(sc->sc_dev, "%s bad idx %02x\n",
1992 __func__, frmhdr.wi_tx_idx); 1987 __func__, frmhdr.wi_tx_idx);
1993 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree, 1988 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1994 &sc->sc_txpending); 1989 &sc->sc_txpending);
1995 goto out; 1990 goto out;
1996 } 1991 }
1997 1992
1998 rssd = &sc->sc_rssd[frmhdr.wi_tx_idx]; 1993 rssd = &sc->sc_rssd[frmhdr.wi_tx_idx];
1999 id = &rssd->rd_desc; 1994 id = &rssd->rd_desc;
2000 wi_raise_rate(ic, id); 1995 wi_raise_rate(ic, id);
2001 1996
2002 ni = id->id_node; 1997 ni = id->id_node;
2003 id->id_node = NULL; 1998 id->id_node = NULL;
2004 1999
2005 if (ni == NULL) { 2000 if (ni == NULL) {
2006 aprint_error_dev(sc->sc_dev, "%s null node, rssdesc %02x\n", 2001 aprint_error_dev(sc->sc_dev, "%s null node, rssdesc %02x\n",
2007 __func__, frmhdr.wi_tx_idx); 2002 __func__, frmhdr.wi_tx_idx);
2008 goto out; 2003 goto out;
2009 } 2004 }
2010 2005
2011 if (sc->sc_txpending[id->id_rateidx]-- == 0) { 2006 if (sc->sc_txpending[id->id_rateidx]-- == 0) {
2012 aprint_error_dev(sc->sc_dev, "%s txpending[%i] wraparound", 2007 aprint_error_dev(sc->sc_dev, "%s txpending[%i] wraparound",
2013 __func__, id->id_rateidx); 2008 __func__, id->id_rateidx);
2014 sc->sc_txpending[id->id_rateidx] = 0; 2009 sc->sc_txpending[id->id_rateidx] = 0;
2015 } 2010 }
2016 if (ni != NULL) 2011 if (ni != NULL)
2017 ieee80211_free_node(ni); 2012 ieee80211_free_node(ni);
2018 SLIST_INSERT_HEAD(&sc->sc_rssdfree, rssd, rd_next); 2013 SLIST_INSERT_HEAD(&sc->sc_rssdfree, rssd, rd_next);
2019out: 2014out:
2020 ifp->if_flags &= ~IFF_OACTIVE; 2015 ifp->if_flags &= ~IFF_OACTIVE;
2021 splx(s); 2016 splx(s);
2022} 2017}
2023 2018
2024STATIC void 2019STATIC void
2025wi_info_intr(struct wi_softc *sc) 2020wi_info_intr(struct wi_softc *sc)
2026{ 2021{
2027 struct ieee80211com *ic = &sc->sc_ic; 2022 struct ieee80211com *ic = &sc->sc_ic;
2028 struct ifnet *ifp = &sc->sc_if; 2023 struct ifnet *ifp = &sc->sc_if;
2029 int i, s, fid, len, off; 2024 int i, s, fid, len, off;
2030 uint16_t ltbuf[2]; 2025 uint16_t ltbuf[2];
2031 uint16_t stat; 2026 uint16_t stat;
2032 uint32_t *ptr; 2027 uint32_t *ptr;
2033 2028
2034 fid = CSR_READ_2(sc, WI_INFO_FID); 2029 fid = CSR_READ_2(sc, WI_INFO_FID);
2035 wi_read_bap(sc, fid, 0, ltbuf, sizeof(ltbuf)); 2030 wi_read_bap(sc, fid, 0, ltbuf, sizeof(ltbuf));
2036 2031
2037 switch (le16toh(ltbuf[1])) { 2032 switch (le16toh(ltbuf[1])) {
2038 2033
2039 case WI_INFO_LINK_STAT: 2034 case WI_INFO_LINK_STAT:
2040 wi_read_bap(sc, fid, sizeof(ltbuf), &stat, sizeof(stat)); 2035 wi_read_bap(sc, fid, sizeof(ltbuf), &stat, sizeof(stat));
2041 DPRINTF(("wi_info_intr: LINK_STAT 0x%x\n", le16toh(stat))); 2036 DPRINTF(("wi_info_intr: LINK_STAT 0x%x\n", le16toh(stat)));
2042 switch (le16toh(stat)) { 2037 switch (le16toh(stat)) {
2043 case CONNECTED: 2038 case CONNECTED:
2044 sc->sc_flags &= ~WI_FLAGS_OUTRANGE; 2039 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
2045 if (ic->ic_state == IEEE80211_S_RUN && 2040 if (ic->ic_state == IEEE80211_S_RUN &&
2046 ic->ic_opmode != IEEE80211_M_IBSS) 2041 ic->ic_opmode != IEEE80211_M_IBSS)
2047 break; 2042 break;
2048 /* FALLTHROUGH */ 2043 /* FALLTHROUGH */
2049 case AP_CHANGE: 2044 case AP_CHANGE:
2050 s = splnet(); 2045 s = splnet();
2051 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 2046 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2052 splx(s); 2047 splx(s);
2053 break; 2048 break;
2054 case AP_IN_RANGE: 2049 case AP_IN_RANGE:
2055 sc->sc_flags &= ~WI_FLAGS_OUTRANGE; 2050 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
2056 break; 2051 break;
2057 case AP_OUT_OF_RANGE: 2052 case AP_OUT_OF_RANGE:
2058 if (sc->sc_firmware_type == WI_SYMBOL && 2053 if (sc->sc_firmware_type == WI_SYMBOL &&
2059 sc->sc_scan_timer > 0) { 2054 sc->sc_scan_timer > 0) {
2060 if (wi_cmd(sc, WI_CMD_INQUIRE, 2055 if (wi_cmd(sc, WI_CMD_INQUIRE,
2061 WI_INFO_HOST_SCAN_RESULTS, 0, 0) != 0) 2056 WI_INFO_HOST_SCAN_RESULTS, 0, 0) != 0)
2062 sc->sc_scan_timer = 0; 2057 sc->sc_scan_timer = 0;
2063 break; 2058 break;
2064 } 2059 }
2065 if (ic->ic_opmode == IEEE80211_M_STA) 2060 if (ic->ic_opmode == IEEE80211_M_STA)
2066 sc->sc_flags |= WI_FLAGS_OUTRANGE; 2061 sc->sc_flags |= WI_FLAGS_OUTRANGE;
2067 break; 2062 break;
2068 case DISCONNECTED: 2063 case DISCONNECTED:
2069 case ASSOC_FAILED: 2064 case ASSOC_FAILED:
2070 s = splnet(); 2065 s = splnet();
2071 if (ic->ic_opmode == IEEE80211_M_STA) 2066 if (ic->ic_opmode == IEEE80211_M_STA)
2072 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2067 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2073 splx(s); 2068 splx(s);
2074 break; 2069 break;
2075 } 2070 }
2076 break; 2071 break;
2077 2072
2078 case WI_INFO_COUNTERS: 2073 case WI_INFO_COUNTERS:
2079 /* some card versions have a larger stats structure */ 2074 /* some card versions have a larger stats structure */
2080 len = uimin(le16toh(ltbuf[0]) - 1, sizeof(sc->sc_stats) / 4); 2075 len = uimin(le16toh(ltbuf[0]) - 1, sizeof(sc->sc_stats) / 4);
2081 ptr = (uint32_t *)&sc->sc_stats; 2076 ptr = (uint32_t *)&sc->sc_stats;
2082 off = sizeof(ltbuf); 2077 off = sizeof(ltbuf);
2083 for (i = 0; i < len; i++, off += 2, ptr++) { 2078 for (i = 0; i < len; i++, off += 2, ptr++) {
2084 wi_read_bap(sc, fid, off, &stat, sizeof(stat)); 2079 wi_read_bap(sc, fid, off, &stat, sizeof(stat));
2085 stat = le16toh(stat); 2080 stat = le16toh(stat);
2086#ifdef WI_HERMES_STATS_WAR 2081#ifdef WI_HERMES_STATS_WAR
2087 if (stat & 0xf000) 2082 if (stat & 0xf000)
2088 stat = ~stat; 2083 stat = ~stat;
2089#endif 2084#endif
2090 *ptr += stat; 2085 *ptr += stat;
2091 } 2086 }
2092 ifp->if_collisions = sc->sc_stats.wi_tx_single_retries + 2087 ifp->if_collisions = sc->sc_stats.wi_tx_single_retries +
2093 sc->sc_stats.wi_tx_multi_retries + 2088 sc->sc_stats.wi_tx_multi_retries +
2094 sc->sc_stats.wi_tx_retry_limit; 2089 sc->sc_stats.wi_tx_retry_limit;
2095 break; 2090 break;
2096 2091
2097 case WI_INFO_SCAN_RESULTS: 2092 case WI_INFO_SCAN_RESULTS:
2098 case WI_INFO_HOST_SCAN_RESULTS: 2093 case WI_INFO_HOST_SCAN_RESULTS:
2099 wi_scan_result(sc, fid, le16toh(ltbuf[0])); 2094 wi_scan_result(sc, fid, le16toh(ltbuf[0]));
2100 break; 2095 break;
2101 2096
2102 default: 2097 default:
2103 DPRINTF(("wi_info_intr: got fid %x type %x len %d\n", fid, 2098 DPRINTF(("wi_info_intr: got fid %x type %x len %d\n", fid,
2104 le16toh(ltbuf[1]), le16toh(ltbuf[0]))); 2099 le16toh(ltbuf[1]), le16toh(ltbuf[0])));
2105 break; 2100 break;
2106 } 2101 }
2107} 2102}
2108 2103
2109STATIC int 2104STATIC int
2110wi_write_multi(struct wi_softc *sc) 2105wi_write_multi(struct wi_softc *sc)
2111{ 2106{
2112 struct ethercom *ec = &sc->sc_ec; 2107 struct ethercom *ec = &sc->sc_ec;
2113 struct ifnet *ifp = &sc->sc_if; 2108 struct ifnet *ifp = &sc->sc_if;
2114 int n; 2109 int n;
2115 struct wi_mcast mlist; 2110 struct wi_mcast mlist;
2116 struct ether_multi *enm; 2111 struct ether_multi *enm;
2117 struct ether_multistep estep; 2112 struct ether_multistep estep;
2118 2113
2119 if ((ifp->if_flags & IFF_PROMISC) != 0) { 2114 if ((ifp->if_flags & IFF_PROMISC) != 0) {
2120allmulti: 2115allmulti:
2121 ifp->if_flags |= IFF_ALLMULTI; 2116 ifp->if_flags |= IFF_ALLMULTI;
2122 memset(&mlist, 0, sizeof(mlist)); 2117 memset(&mlist, 0, sizeof(mlist));
2123 return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, 2118 return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
2124 sizeof(mlist)); 2119 sizeof(mlist));
2125 } 2120 }
2126 2121
2127 n = 0; 2122 n = 0;
2128 ETHER_LOCK(ec); 2123 ETHER_LOCK(ec);
2129 ETHER_FIRST_MULTI(estep, ec, enm); 2124 ETHER_FIRST_MULTI(estep, ec, enm);
2130 while (enm != NULL) { 2125 while (enm != NULL) {
2131 /* Punt on ranges or too many multicast addresses. */ 2126 /* Punt on ranges or too many multicast addresses. */
2132 if (!IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi) || 2127 if (!IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi) ||
2133 n >= sizeof(mlist) / sizeof(mlist.wi_mcast[0])) { 2128 n >= sizeof(mlist) / sizeof(mlist.wi_mcast[0])) {
2134 ETHER_UNLOCK(ec); 2129 ETHER_UNLOCK(ec);
2135 goto allmulti; 2130 goto allmulti;
2136 } 2131 }
2137 2132
2138 IEEE80211_ADDR_COPY(&mlist.wi_mcast[n], enm->enm_addrlo); 2133 IEEE80211_ADDR_COPY(&mlist.wi_mcast[n], enm->enm_addrlo);
2139 n++; 2134 n++;
2140 ETHER_NEXT_MULTI(estep, enm); 2135 ETHER_NEXT_MULTI(estep, enm);
2141 } 2136 }
2142 ETHER_UNLOCK(ec); 2137 ETHER_UNLOCK(ec);
2143 ifp->if_flags &= ~IFF_ALLMULTI; 2138 ifp->if_flags &= ~IFF_ALLMULTI;
2144 return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist, 2139 return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
2145 IEEE80211_ADDR_LEN * n); 2140 IEEE80211_ADDR_LEN * n);
2146} 2141}
2147 2142
2148 2143
2149STATIC void 2144STATIC void
2150wi_read_nicid(struct wi_softc *sc) 2145wi_read_nicid(struct wi_softc *sc)
2151{ 2146{
2152 const struct wi_card_ident *id; 2147 const struct wi_card_ident *id;
2153 char *p; 2148 char *p;
2154 int len; 2149 int len;
2155 uint16_t ver[4]; 2150 uint16_t ver[4];
2156 2151
2157 /* getting chip identity */ 2152 /* getting chip identity */
2158 memset(ver, 0, sizeof(ver)); 2153 memset(ver, 0, sizeof(ver));
2159 len = sizeof(ver); 2154 len = sizeof(ver);
2160 wi_read_rid(sc, WI_RID_CARD_ID, ver, &len); 2155 wi_read_rid(sc, WI_RID_CARD_ID, ver, &len);
2161 printf("%s: using ", device_xname(sc->sc_dev)); 2156 printf("%s: using ", device_xname(sc->sc_dev));
2162DPRINTF2(("wi_read_nicid: CARD_ID: %x %x %x %x\n", le16toh(ver[0]), le16toh(ver[1]), le16toh(ver[2]), le16toh(ver[3]))); 2157DPRINTF2(("wi_read_nicid: CARD_ID: %x %x %x %x\n", le16toh(ver[0]), le16toh(ver[1]), le16toh(ver[2]), le16toh(ver[3])));
2163 2158
2164 sc->sc_firmware_type = WI_NOTYPE; 2159 sc->sc_firmware_type = WI_NOTYPE;
2165 for (id = wi_card_ident; id->card_name != NULL; id++) { 2160 for (id = wi_card_ident; id->card_name != NULL; id++) {
2166 if (le16toh(ver[0]) == id->card_id) { 2161 if (le16toh(ver[0]) == id->card_id) {
2167 printf("%s", id->card_name); 2162 printf("%s", id->card_name);
2168 sc->sc_firmware_type = id->firm_type; 2163 sc->sc_firmware_type = id->firm_type;
2169 break; 2164 break;
2170 } 2165 }
2171 } 2166 }
2172 if (sc->sc_firmware_type == WI_NOTYPE) { 2167 if (sc->sc_firmware_type == WI_NOTYPE) {
2173 if (le16toh(ver[0]) & 0x8000) { 2168 if (le16toh(ver[0]) & 0x8000) {
2174 printf("Unknown PRISM2 chip"); 2169 printf("Unknown PRISM2 chip");
2175 sc->sc_firmware_type = WI_INTERSIL; 2170 sc->sc_firmware_type = WI_INTERSIL;
2176 } else { 2171 } else {
2177 printf("Unknown Lucent chip"); 2172 printf("Unknown Lucent chip");
2178 sc->sc_firmware_type = WI_LUCENT; 2173 sc->sc_firmware_type = WI_LUCENT;
2179 } 2174 }
2180 } 2175 }
2181 2176
2182 /* get primary firmware version (Only Prism chips) */ 2177 /* get primary firmware version (Only Prism chips) */
2183 if (sc->sc_firmware_type != WI_LUCENT) { 2178 if (sc->sc_firmware_type != WI_LUCENT) {
2184 memset(ver, 0, sizeof(ver)); 2179 memset(ver, 0, sizeof(ver));
2185 len = sizeof(ver); 2180 len = sizeof(ver);
2186 wi_read_rid(sc, WI_RID_PRI_IDENTITY, ver, &len); 2181 wi_read_rid(sc, WI_RID_PRI_IDENTITY, ver, &len);
2187 sc->sc_pri_firmware_ver = le16toh(ver[2]) * 10000 + 2182 sc->sc_pri_firmware_ver = le16toh(ver[2]) * 10000 +
2188 le16toh(ver[3]) * 100 + le16toh(ver[1]); 2183 le16toh(ver[3]) * 100 + le16toh(ver[1]);
2189 } 2184 }
2190 2185
2191 /* get station firmware version */ 2186 /* get station firmware version */
2192 memset(ver, 0, sizeof(ver)); 2187 memset(ver, 0, sizeof(ver));
2193 len = sizeof(ver); 2188 len = sizeof(ver);
2194 wi_read_rid(sc, WI_RID_STA_IDENTITY, ver, &len); 2189 wi_read_rid(sc, WI_RID_STA_IDENTITY, ver, &len);
2195 sc->sc_sta_firmware_ver = le16toh(ver[2]) * 10000 + 2190 sc->sc_sta_firmware_ver = le16toh(ver[2]) * 10000 +
2196 le16toh(ver[3]) * 100 + le16toh(ver[1]); 2191 le16toh(ver[3]) * 100 + le16toh(ver[1]);
2197 if (sc->sc_firmware_type == WI_INTERSIL && 2192 if (sc->sc_firmware_type == WI_INTERSIL &&
2198 (sc->sc_sta_firmware_ver == 10102 || 2193 (sc->sc_sta_firmware_ver == 10102 ||
2199 sc->sc_sta_firmware_ver == 20102)) { 2194 sc->sc_sta_firmware_ver == 20102)) {
2200 char ident[12]; 2195 char ident[12];
2201 memset(ident, 0, sizeof(ident)); 2196 memset(ident, 0, sizeof(ident));
2202 len = sizeof(ident); 2197 len = sizeof(ident);
2203 /* value should be the format like "V2.00-11" */ 2198 /* value should be the format like "V2.00-11" */
2204 if (wi_read_rid(sc, WI_RID_SYMBOL_IDENTITY, ident, &len) == 0 && 2199 if (wi_read_rid(sc, WI_RID_SYMBOL_IDENTITY, ident, &len) == 0 &&
2205 *(p = (char *)ident) >= 'A' && 2200 *(p = (char *)ident) >= 'A' &&
2206 p[2] == '.' && p[5] == '-' && p[8] == '\0') { 2201 p[2] == '.' && p[5] == '-' && p[8] == '\0') {
2207 sc->sc_firmware_type = WI_SYMBOL; 2202 sc->sc_firmware_type = WI_SYMBOL;
2208 sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 + 2203 sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +
2209 (p[3] - '0') * 1000 + (p[4] - '0') * 100 + 2204 (p[3] - '0') * 1000 + (p[4] - '0') * 100 +
2210 (p[6] - '0') * 10 + (p[7] - '0'); 2205 (p[6] - '0') * 10 + (p[7] - '0');
2211 } 2206 }
2212 } 2207 }
2213 2208
2214 printf("\n%s: %s Firmware: ", device_xname(sc->sc_dev), 2209 printf("\n%s: %s Firmware: ", device_xname(sc->sc_dev),
2215 sc->sc_firmware_type == WI_LUCENT ? "Lucent" : 2210 sc->sc_firmware_type == WI_LUCENT ? "Lucent" :
2216 (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil")); 2211 (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil"));
2217 if (sc->sc_firmware_type != WI_LUCENT) /* XXX */ 2212 if (sc->sc_firmware_type != WI_LUCENT) /* XXX */
2218 printf("Primary (%u.%u.%u), ", 2213 printf("Primary (%u.%u.%u), ",
2219 sc->sc_pri_firmware_ver / 10000, 2214 sc->sc_pri_firmware_ver / 10000,
2220 (sc->sc_pri_firmware_ver % 10000) / 100, 2215 (sc->sc_pri_firmware_ver % 10000) / 100,
2221 sc->sc_pri_firmware_ver % 100); 2216 sc->sc_pri_firmware_ver % 100);
2222 printf("Station (%u.%u.%u)\n", 2217 printf("Station (%u.%u.%u)\n",
2223 sc->sc_sta_firmware_ver / 10000, 2218 sc->sc_sta_firmware_ver / 10000,
2224 (sc->sc_sta_firmware_ver % 10000) / 100, 2219 (sc->sc_sta_firmware_ver % 10000) / 100,
2225 sc->sc_sta_firmware_ver % 100); 2220 sc->sc_sta_firmware_ver % 100);
2226} 2221}
2227 2222
2228STATIC int 2223STATIC int
2229wi_write_ssid(struct wi_softc *sc, int rid, uint8_t *buf, int buflen) 2224wi_write_ssid(struct wi_softc *sc, int rid, uint8_t *buf, int buflen)
2230{ 2225{
2231 struct wi_ssid ssid; 2226 struct wi_ssid ssid;
2232 2227
2233 if (buflen > IEEE80211_NWID_LEN) 2228 if (buflen > IEEE80211_NWID_LEN)
2234 return ENOBUFS; 2229 return ENOBUFS;
2235 memset(&ssid, 0, sizeof(ssid)); 2230 memset(&ssid, 0, sizeof(ssid));
2236 ssid.wi_len = htole16(buflen); 2231 ssid.wi_len = htole16(buflen);
2237 memcpy(ssid.wi_ssid, buf, buflen); 2232 memcpy(ssid.wi_ssid, buf, buflen);
2238 return wi_write_rid(sc, rid, &ssid, sizeof(ssid)); 2233 return wi_write_rid(sc, rid, &ssid, sizeof(ssid));
2239} 2234}
2240 2235
2241STATIC int 2236STATIC int
2242wi_get_cfg(struct ifnet *ifp, u_long cmd, void *data) 2237wi_get_cfg(struct ifnet *ifp, u_long cmd, void *data)
2243{ 2238{
2244 struct wi_softc *sc = ifp->if_softc; 2239 struct wi_softc *sc = ifp->if_softc;
2245 struct ieee80211com *ic = &sc->sc_ic; 2240 struct ieee80211com *ic = &sc->sc_ic;
2246 struct ifreq *ifr = (struct ifreq *)data; 2241 struct ifreq *ifr = (struct ifreq *)data;
2247 struct wi_req wreq; 2242 struct wi_req wreq;
2248 int len, n, error; 2243 int len, n, error;
2249 2244
2250 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 2245 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
2251 if (error) 2246 if (error)
2252 return error; 2247 return error;
2253 len = (wreq.wi_len - 1) * 2; 2248 len = (wreq.wi_len - 1) * 2;
2254 if (len < sizeof(uint16_t)) 2249 if (len < sizeof(uint16_t))
2255 return ENOSPC; 2250 return ENOSPC;
2256 if (len > sizeof(wreq.wi_val)) 2251 if (len > sizeof(wreq.wi_val))
2257 len = sizeof(wreq.wi_val); 2252 len = sizeof(wreq.wi_val);
2258 2253
2259 switch (wreq.wi_type) { 2254 switch (wreq.wi_type) {
2260 2255
2261 case WI_RID_IFACE_STATS: 2256 case WI_RID_IFACE_STATS:
2262 memcpy(wreq.wi_val, &sc->sc_stats, sizeof(sc->sc_stats)); 2257 memcpy(wreq.wi_val, &sc->sc_stats, sizeof(sc->sc_stats));
2263 if (len < sizeof(sc->sc_stats)) 2258 if (len < sizeof(sc->sc_stats))
2264 error = ENOSPC; 2259 error = ENOSPC;
2265 else 2260 else
2266 len = sizeof(sc->sc_stats); 2261 len = sizeof(sc->sc_stats);
2267 break; 2262 break;
2268 2263
2269 case WI_RID_ENCRYPTION: 2264 case WI_RID_ENCRYPTION:
2270 case WI_RID_TX_CRYPT_KEY: 2265 case WI_RID_TX_CRYPT_KEY:
2271 case WI_RID_DEFLT_CRYPT_KEYS: 2266 case WI_RID_DEFLT_CRYPT_KEYS:
2272 case WI_RID_TX_RATE: 2267 case WI_RID_TX_RATE:
2273 return ieee80211_cfgget(ic, cmd, data); 2268 return ieee80211_cfgget(ic, cmd, data);
2274 2269
2275 case WI_RID_MICROWAVE_OVEN: 2270 case WI_RID_MICROWAVE_OVEN:
2276 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_MOR)) { 2271 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_MOR)) {
2277 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2272 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2278 &len); 2273 &len);
2279 break; 2274 break;
2280 } 2275 }
2281 wreq.wi_val[0] = htole16(sc->sc_microwave_oven); 2276 wreq.wi_val[0] = htole16(sc->sc_microwave_oven);
2282 len = sizeof(uint16_t); 2277 len = sizeof(uint16_t);
2283 break; 2278 break;
2284 2279
2285 case WI_RID_DBM_ADJUST: 2280 case WI_RID_DBM_ADJUST:
2286 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_DBMADJUST)) { 2281 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_DBMADJUST)) {
2287 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2282 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2288 &len); 2283 &len);
2289 break; 2284 break;
2290 } 2285 }
2291 wreq.wi_val[0] = htole16(sc->sc_dbm_offset); 2286 wreq.wi_val[0] = htole16(sc->sc_dbm_offset);
2292 len = sizeof(uint16_t); 2287 len = sizeof(uint16_t);
2293 break; 2288 break;
2294 2289
2295 case WI_RID_ROAMING_MODE: 2290 case WI_RID_ROAMING_MODE:
2296 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_ROAMING)) { 2291 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_ROAMING)) {
2297 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2292 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2298 &len); 2293 &len);
2299 break; 2294 break;
2300 } 2295 }
2301 wreq.wi_val[0] = htole16(sc->sc_roaming_mode); 2296 wreq.wi_val[0] = htole16(sc->sc_roaming_mode);
2302 len = sizeof(uint16_t); 2297 len = sizeof(uint16_t);
2303 break; 2298 break;
2304 2299
2305 case WI_RID_SYSTEM_SCALE: 2300 case WI_RID_SYSTEM_SCALE:
2306 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)) { 2301 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)) {
2307 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2302 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2308 &len); 2303 &len);
2309 break; 2304 break;
2310 } 2305 }
2311 wreq.wi_val[0] = htole16(sc->sc_system_scale); 2306 wreq.wi_val[0] = htole16(sc->sc_system_scale);
2312 len = sizeof(uint16_t); 2307 len = sizeof(uint16_t);
2313 break; 2308 break;
2314 2309
2315 case WI_RID_FRAG_THRESH: 2310 case WI_RID_FRAG_THRESH:
2316 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)) { 2311 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)) {
2317 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2312 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2318 &len); 2313 &len);
2319 break; 2314 break;
2320 } 2315 }
2321 wreq.wi_val[0] = htole16(sc->sc_frag_thresh); 2316 wreq.wi_val[0] = htole16(sc->sc_frag_thresh);
2322 len = sizeof(uint16_t); 2317 len = sizeof(uint16_t);
2323 break; 2318 break;
2324 2319
2325 case WI_RID_READ_APS: 2320 case WI_RID_READ_APS:
2326#ifndef IEEE80211_NO_HOSTAP 2321#ifndef IEEE80211_NO_HOSTAP
2327 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 2322 if (ic->ic_opmode == IEEE80211_M_HOSTAP)
2328 return ieee80211_cfgget(ic, cmd, data); 2323 return ieee80211_cfgget(ic, cmd, data);
2329#endif /* !IEEE80211_NO_HOSTAP */ 2324#endif /* !IEEE80211_NO_HOSTAP */
2330 if (sc->sc_scan_timer > 0) { 2325 if (sc->sc_scan_timer > 0) {
2331 error = EINPROGRESS; 2326 error = EINPROGRESS;
2332 break; 2327 break;
2333 } 2328 }
2334 n = sc->sc_naps; 2329 n = sc->sc_naps;
2335 if (len < sizeof(n)) { 2330 if (len < sizeof(n)) {
2336 error = ENOSPC; 2331 error = ENOSPC;
2337 break; 2332 break;
2338 } 2333 }
2339 if (len < sizeof(n) + sizeof(struct wi_apinfo) * n) 2334 if (len < sizeof(n) + sizeof(struct wi_apinfo) * n)
2340 n = (len - sizeof(n)) / sizeof(struct wi_apinfo); 2335 n = (len - sizeof(n)) / sizeof(struct wi_apinfo);
2341 len = sizeof(n) + sizeof(struct wi_apinfo) * n; 2336 len = sizeof(n) + sizeof(struct wi_apinfo) * n;
2342 memcpy(wreq.wi_val, &n, sizeof(n)); 2337 memcpy(wreq.wi_val, &n, sizeof(n));
2343 memcpy((char *)wreq.wi_val + sizeof(n), sc->sc_aps, 2338 memcpy((char *)wreq.wi_val + sizeof(n), sc->sc_aps,
2344 sizeof(struct wi_apinfo) * n); 2339 sizeof(struct wi_apinfo) * n);
2345 break; 2340 break;
2346 2341
2347 default: 2342 default:
2348 if (sc->sc_enabled) { 2343 if (sc->sc_enabled) {
2349 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, 2344 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2350 &len); 2345 &len);
2351 break; 2346 break;
2352 } 2347 }
2353 switch (wreq.wi_type) { 2348 switch (wreq.wi_type) {
2354 case WI_RID_MAX_DATALEN: 2349 case WI_RID_MAX_DATALEN:
2355 wreq.wi_val[0] = htole16(sc->sc_max_datalen); 2350 wreq.wi_val[0] = htole16(sc->sc_max_datalen);
2356 len = sizeof(uint16_t); 2351 len = sizeof(uint16_t);
2357 break; 2352 break;
2358 case WI_RID_FRAG_THRESH: 2353 case WI_RID_FRAG_THRESH:
2359 wreq.wi_val[0] = htole16(sc->sc_frag_thresh); 2354 wreq.wi_val[0] = htole16(sc->sc_frag_thresh);
2360 len = sizeof(uint16_t); 2355 len = sizeof(uint16_t);
2361 break; 2356 break;
2362 case WI_RID_RTS_THRESH: 2357 case WI_RID_RTS_THRESH:
2363 wreq.wi_val[0] = htole16(sc->sc_rts_thresh); 2358 wreq.wi_val[0] = htole16(sc->sc_rts_thresh);
2364 len = sizeof(uint16_t); 2359 len = sizeof(uint16_t);
2365 break; 2360 break;
2366 case WI_RID_CNFAUTHMODE: 2361 case WI_RID_CNFAUTHMODE:
2367 wreq.wi_val[0] = htole16(sc->sc_cnfauthmode); 2362 wreq.wi_val[0] = htole16(sc->sc_cnfauthmode);
2368 len = sizeof(uint16_t); 2363 len = sizeof(uint16_t);
2369 break; 2364 break;
2370 case WI_RID_NODENAME: 2365 case WI_RID_NODENAME:
2371 if (len < sc->sc_nodelen + sizeof(uint16_t)) { 2366 if (len < sc->sc_nodelen + sizeof(uint16_t)) {
2372 error = ENOSPC; 2367 error = ENOSPC;
2373 break; 2368 break;
2374 } 2369 }
2375 len = sc->sc_nodelen + sizeof(uint16_t); 2370 len = sc->sc_nodelen + sizeof(uint16_t);
2376 wreq.wi_val[0] = htole16((sc->sc_nodelen + 1) / 2); 2371 wreq.wi_val[0] = htole16((sc->sc_nodelen + 1) / 2);
2377 memcpy(&wreq.wi_val[1], sc->sc_nodename, 2372 memcpy(&wreq.wi_val[1], sc->sc_nodename,
2378 sc->sc_nodelen); 2373 sc->sc_nodelen);
2379 break; 2374 break;
2380 default: 2375 default:
2381 return ieee80211_cfgget(ic, cmd, data); 2376 return ieee80211_cfgget(ic, cmd, data);
2382 } 2377 }
2383 break; 2378 break;
2384 } 2379 }
2385 if (error) 2380 if (error)
2386 return error; 2381 return error;
2387 wreq.wi_len = (len + 1) / 2 + 1; 2382 wreq.wi_len = (len + 1) / 2 + 1;
2388 return copyout(&wreq, ifr->ifr_data, (wreq.wi_len + 1) * 2); 2383 return copyout(&wreq, ifr->ifr_data, (wreq.wi_len + 1) * 2);
2389} 2384}
2390 2385
2391STATIC int 2386STATIC int
2392wi_set_cfg(struct ifnet *ifp, u_long cmd, void *data) 2387wi_set_cfg(struct ifnet *ifp, u_long cmd, void *data)
2393{ 2388{
2394 struct wi_softc *sc = ifp->if_softc; 2389 struct wi_softc *sc = ifp->if_softc;
2395 struct ieee80211com *ic = &sc->sc_ic; 2390 struct ieee80211com *ic = &sc->sc_ic;
2396 struct ifreq *ifr = (struct ifreq *)data; 2391 struct ifreq *ifr = (struct ifreq *)data;
2397 struct ieee80211_rateset *rs = &ic->ic_sup_rates[IEEE80211_MODE_11B]; 2392 struct ieee80211_rateset *rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
2398 struct wi_req wreq; 2393 struct wi_req wreq;
2399 struct mbuf *m; 2394 struct mbuf *m;
2400 int i, len, error; 2395 int i, len, error;
2401 2396
2402 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 2397 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
2403 if (error) 2398 if (error)
2404 return error; 2399 return error;
2405 len = (wreq.wi_len - 1) * 2; 2400 len = (wreq.wi_len - 1) * 2;
2406 switch (wreq.wi_type) { 2401 switch (wreq.wi_type) {
2407 case WI_RID_MAC_NODE: 2402 case WI_RID_MAC_NODE:
2408 /* XXX convert to SIOCALIFADDR, AF_LINK, IFLR_ACTIVE */ 2403 /* XXX convert to SIOCALIFADDR, AF_LINK, IFLR_ACTIVE */
2409 (void)memcpy(ic->ic_myaddr, wreq.wi_val, ETHER_ADDR_LEN); 2404 (void)memcpy(ic->ic_myaddr, wreq.wi_val, ETHER_ADDR_LEN);
2410 if_set_sadl(ifp, ic->ic_myaddr, ETHER_ADDR_LEN, false); 2405 if_set_sadl(ifp, ic->ic_myaddr, ETHER_ADDR_LEN, false);
2411 wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, 2406 wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr,
2412 IEEE80211_ADDR_LEN); 2407 IEEE80211_ADDR_LEN);
2413 break; 2408 break;
2414 2409
2415 case WI_RID_DBM_ADJUST: 2410 case WI_RID_DBM_ADJUST:
2416 return ENODEV; 2411 return ENODEV;
2417 2412
2418 case WI_RID_NODENAME: 2413 case WI_RID_NODENAME:
2419 if (le16toh(wreq.wi_val[0]) * 2 > len || 2414 if (le16toh(wreq.wi_val[0]) * 2 > len ||
2420 le16toh(wreq.wi_val[0]) > sizeof(sc->sc_nodename)) { 2415 le16toh(wreq.wi_val[0]) > sizeof(sc->sc_nodename)) {
2421 error = ENOSPC; 2416 error = ENOSPC;
2422 break; 2417 break;
2423 } 2418 }
2424 if (sc->sc_enabled) { 2419 if (sc->sc_enabled) {
2425 error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val, 2420 error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2426 len); 2421 len);
2427 if (error) 2422 if (error)
2428 break; 2423 break;
2429 } 2424 }
2430 sc->sc_nodelen = le16toh(wreq.wi_val[0]) * 2; 2425 sc->sc_nodelen = le16toh(wreq.wi_val[0]) * 2;
2431 memcpy(sc->sc_nodename, &wreq.wi_val[1], sc->sc_nodelen); 2426 memcpy(sc->sc_nodename, &wreq.wi_val[1], sc->sc_nodelen);
2432 break; 2427 break;
2433 2428
2434 case WI_RID_MICROWAVE_OVEN: 2429 case WI_RID_MICROWAVE_OVEN:
2435 case WI_RID_ROAMING_MODE: 2430 case WI_RID_ROAMING_MODE:
2436 case WI_RID_SYSTEM_SCALE: 2431 case WI_RID_SYSTEM_SCALE:
2437 case WI_RID_FRAG_THRESH: 2432 case WI_RID_FRAG_THRESH:
2438 if (wreq.wi_type == WI_RID_MICROWAVE_OVEN && 2433 if (wreq.wi_type == WI_RID_MICROWAVE_OVEN &&
2439 (sc->sc_flags & WI_FLAGS_HAS_MOR) == 0) 2434 (sc->sc_flags & WI_FLAGS_HAS_MOR) == 0)
2440 break; 2435 break;
2441 if (wreq.wi_type == WI_RID_ROAMING_MODE && 2436 if (wreq.wi_type == WI_RID_ROAMING_MODE &&
2442 (sc->sc_flags & WI_FLAGS_HAS_ROAMING) == 0) 2437 (sc->sc_flags & WI_FLAGS_HAS_ROAMING) == 0)
2443 break; 2438 break;
2444 if (wreq.wi_type == WI_RID_SYSTEM_SCALE && 2439 if (wreq.wi_type == WI_RID_SYSTEM_SCALE &&
2445 (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) == 0) 2440 (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) == 0)
2446 break; 2441 break;
2447 if (wreq.wi_type == WI_RID_FRAG_THRESH && 2442 if (wreq.wi_type == WI_RID_FRAG_THRESH &&
2448 (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) == 0) 2443 (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) == 0)
2449 break; 2444 break;
2450 /* FALLTHROUGH */ 2445 /* FALLTHROUGH */
2451 case WI_RID_RTS_THRESH: 2446 case WI_RID_RTS_THRESH:
2452 case WI_RID_CNFAUTHMODE: 2447 case WI_RID_CNFAUTHMODE:
2453 case WI_RID_MAX_DATALEN: 2448 case WI_RID_MAX_DATALEN:
2454 if (sc->sc_enabled) { 2449 if (sc->sc_enabled) {
2455 error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val, 2450 error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2456 sizeof(uint16_t)); 2451 sizeof(uint16_t));
2457 if (error) 2452 if (error)
2458 break; 2453 break;

cvs diff -r1.67 -r1.68 src/sys/dev/usb/if_atu.c (switch to unified diff)

--- src/sys/dev/usb/if_atu.c 2019/12/01 12:47:10 1.67
+++ src/sys/dev/usb/if_atu.c 2019/12/05 03:11:41 1.68
@@ -1,1050 +1,1050 @@ @@ -1,1050 +1,1050 @@
1/* $NetBSD: if_atu.c,v 1.67 2019/12/01 12:47:10 maxv Exp $ */ 1/* $NetBSD: if_atu.c,v 1.68 2019/12/05 03:11:41 msaitoh Exp $ */
2/* $OpenBSD: if_atu.c,v 1.48 2004/12/30 01:53:21 dlg Exp $ */ 2/* $OpenBSD: if_atu.c,v 1.48 2004/12/30 01:53:21 dlg Exp $ */
3/* 3/*
4 * Copyright (c) 2003, 2004 4 * Copyright (c) 2003, 2004
5 * Daan Vreeken <Danovitsch@Vitsch.net>. All rights reserved. 5 * Daan Vreeken <Danovitsch@Vitsch.net>. 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 Daan Vreeken. 17 * This product includes software developed by Daan Vreeken.
18 * 4. Neither the name of the author nor the names of any co-contributors 18 * 4. Neither the name of the author nor the names of any co-contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY Daan Vreeken AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY Daan Vreeken AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL Daan Vreeken OR THE VOICES IN HIS HEAD 25 * ARE DISCLAIMED. IN NO EVENT SHALL Daan Vreeken OR THE VOICES IN HIS HEAD
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE. 32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * Atmel AT76c503 / AT76c503a / AT76c505 / AT76c505a USB WLAN driver 36 * Atmel AT76c503 / AT76c503a / AT76c505 / AT76c505a USB WLAN driver
37 * version 0.5 - 2004-08-03 37 * version 0.5 - 2004-08-03
38 * 38 *
39 * Originally written by Daan Vreeken <Danovitsch @ Vitsch . net> 39 * Originally written by Daan Vreeken <Danovitsch @ Vitsch . net>
40 * http://vitsch.net/bsd/atuwi 40 * http://vitsch.net/bsd/atuwi
41 * 41 *
42 * Contributed to by : 42 * Contributed to by :
43 * Chris Whitehouse, Alistair Phillips, Peter Pilka, Martijn van Buul, 43 * Chris Whitehouse, Alistair Phillips, Peter Pilka, Martijn van Buul,
44 * Suihong Liang, Arjan van Leeuwen, Stuart Walsh 44 * Suihong Liang, Arjan van Leeuwen, Stuart Walsh
45 * 45 *
46 * Ported to OpenBSD by Theo de Raadt and David Gwynne. 46 * Ported to OpenBSD by Theo de Raadt and David Gwynne.
47 * Ported to NetBSD by Jesse Off 47 * Ported to NetBSD by Jesse Off
48 */ 48 */
49 49
50#include <sys/cdefs.h> 50#include <sys/cdefs.h>
51__KERNEL_RCSID(0, "$NetBSD: if_atu.c,v 1.67 2019/12/01 12:47:10 maxv Exp $"); 51__KERNEL_RCSID(0, "$NetBSD: if_atu.c,v 1.68 2019/12/05 03:11:41 msaitoh Exp $");
52 52
53#ifdef _KERNEL_OPT 53#ifdef _KERNEL_OPT
54#include "opt_usb.h" 54#include "opt_usb.h"
55#endif 55#endif
56 56
57#include <sys/param.h> 57#include <sys/param.h>
58#include <sys/sockio.h> 58#include <sys/sockio.h>
59#include <sys/mbuf.h> 59#include <sys/mbuf.h>
60#include <sys/kernel.h> 60#include <sys/kernel.h>
61#include <sys/socket.h> 61#include <sys/socket.h>
62#include <sys/systm.h> 62#include <sys/systm.h>
63#include <sys/kthread.h> 63#include <sys/kthread.h>
64#include <sys/queue.h> 64#include <sys/queue.h>
65#include <sys/device.h> 65#include <sys/device.h>
66#include <sys/bus.h> 66#include <sys/bus.h>
67 67
68#include <dev/usb/usb.h> 68#include <dev/usb/usb.h>
69#include <dev/usb/usbdi.h> 69#include <dev/usb/usbdi.h>
70#include <dev/usb/usbdi_util.h> 70#include <dev/usb/usbdi_util.h>
71#include <dev/usb/usbdivar.h> 71#include <dev/usb/usbdivar.h>
72#include <dev/usb/usbdevs.h> 72#include <dev/usb/usbdevs.h>
73 73
74#include <dev/microcode/atmel/atmel_intersil_fw.h> 74#include <dev/microcode/atmel/atmel_intersil_fw.h>
75#include <dev/microcode/atmel/atmel_rfmd2958-smc_fw.h> 75#include <dev/microcode/atmel/atmel_rfmd2958-smc_fw.h>
76#include <dev/microcode/atmel/atmel_rfmd2958_fw.h> 76#include <dev/microcode/atmel/atmel_rfmd2958_fw.h>
77#include <dev/microcode/atmel/atmel_rfmd_fw.h> 77#include <dev/microcode/atmel/atmel_rfmd_fw.h>
78 78
79#include <net/bpf.h> 79#include <net/bpf.h>
80#include <net/if.h> 80#include <net/if.h>
81#include <net/if_dl.h> 81#include <net/if_dl.h>
82#include <net/if_media.h> 82#include <net/if_media.h>
83#include <net/if_ether.h> 83#include <net/if_ether.h>
84 84
85#ifdef INET 85#ifdef INET
86#include <netinet/in.h> 86#include <netinet/in.h>
87#include <netinet/if_ether.h> 87#include <netinet/if_ether.h>
88#endif 88#endif
89 89
90#include <net80211/ieee80211_var.h> 90#include <net80211/ieee80211_var.h>
91#include <net80211/ieee80211_radiotap.h> 91#include <net80211/ieee80211_radiotap.h>
92 92
93#include <dev/usb/if_atureg.h> 93#include <dev/usb/if_atureg.h>
94 94
95#ifdef ATU_DEBUG 95#ifdef ATU_DEBUG
96#define DPRINTF(x) do { if (atudebug) printf x; } while (0) 96#define DPRINTF(x) do { if (atudebug) printf x; } while (0)
97#define DPRINTFN(n,x) do { if (atudebug>(n)) printf x; } while (0) 97#define DPRINTFN(n,x) do { if (atudebug>(n)) printf x; } while (0)
98int atudebug = 1; 98int atudebug = 1;
99#else 99#else
100#define DPRINTF(x) 100#define DPRINTF(x)
101#define DPRINTFN(n,x) 101#define DPRINTFN(n,x)
102#endif 102#endif
103 103
104/* 104/*
105 * Various supported device vendors/products/radio type. 105 * Various supported device vendors/products/radio type.
106 */ 106 */
107static const struct atu_type atu_devs[] = { 107static const struct atu_type atu_devs[] = {
108 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3CRSHEW696, 108 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3CRSHEW696,
109 RadioRFMD, ATU_NO_QUIRK }, 109 RadioRFMD, ATU_NO_QUIRK },
110 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_BWU613, 110 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_BWU613,
111 RadioRFMD, ATU_NO_QUIRK }, 111 RadioRFMD, ATU_NO_QUIRK },
112 { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_2664W, 112 { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_2664W,
113 AT76C503_rfmd_acc, ATU_NO_QUIRK }, 113 AT76C503_rfmd_acc, ATU_NO_QUIRK },
114 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL300, 114 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL300,
115 RadioIntersil, ATU_NO_QUIRK }, 115 RadioIntersil, ATU_NO_QUIRK },
116 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL400, 116 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL400,
117 RadioRFMD, ATU_NO_QUIRK }, 117 RadioRFMD, ATU_NO_QUIRK },
118 { USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_UAT1, 118 { USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_UAT1,
119 RadioRFMD, ATU_NO_QUIRK }, 119 RadioRFMD, ATU_NO_QUIRK },
120 { USB_VENDOR_ADDTRON, USB_PRODUCT_ADDTRON_AWU120, 120 { USB_VENDOR_ADDTRON, USB_PRODUCT_ADDTRON_AWU120,
121 RadioIntersil, ATU_NO_QUIRK }, 121 RadioIntersil, ATU_NO_QUIRK },
122 { USB_VENDOR_AINCOMM, USB_PRODUCT_AINCOMM_AWU2000B, 122 { USB_VENDOR_AINCOMM, USB_PRODUCT_AINCOMM_AWU2000B,
123 RadioRFMD2958, ATU_NO_QUIRK }, 123 RadioRFMD2958, ATU_NO_QUIRK },
124 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_VOYAGER1010, 124 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_VOYAGER1010,
125 RadioIntersil, ATU_NO_QUIRK }, 125 RadioIntersil, ATU_NO_QUIRK },
126 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013I, 126 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013I,
127 RadioIntersil, ATU_NO_QUIRK }, 127 RadioIntersil, ATU_NO_QUIRK },
128 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013, 128 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013,
129 RadioRFMD, ATU_NO_QUIRK }, 129 RadioRFMD, ATU_NO_QUIRK },
130 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I1, 130 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I1,
131 RadioIntersil, ATU_NO_QUIRK }, 131 RadioIntersil, ATU_NO_QUIRK },
132 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I2, 132 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I2,
133 AT76C503_i3863, ATU_NO_QUIRK }, 133 AT76C503_i3863, ATU_NO_QUIRK },
134 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503RFMD, 134 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503RFMD,
135 RadioRFMD, ATU_NO_QUIRK }, 135 RadioRFMD, ATU_NO_QUIRK },
136 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD, 136 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD,
137 AT76C505_rfmd, ATU_NO_QUIRK }, 137 AT76C505_rfmd, ATU_NO_QUIRK },
138 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD2958, 138 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD2958,
139 RadioRFMD2958, ATU_NO_QUIRK }, 139 RadioRFMD2958, ATU_NO_QUIRK },
140 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505A, /* SMC2662 V.4 */ 140 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505A, /* SMC2662 V.4 */
141 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 141 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
142 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505AS, /* quirk? */ 142 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505AS, /* quirk? */
143 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 143 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
144 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_WN210, 144 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_WN210,
145 RadioRFMD, ATU_NO_QUIRK }, 145 RadioRFMD, ATU_NO_QUIRK },
146 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D6050, 146 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D6050,
147 RadioRFMD, ATU_NO_QUIRK }, 147 RadioRFMD, ATU_NO_QUIRK },
148 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C11U, 148 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C11U,
149 RadioIntersil, ATU_NO_QUIRK }, 149 RadioIntersil, ATU_NO_QUIRK },
150 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_WL210, 150 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_WL210,
151 RadioIntersil, ATU_NO_QUIRK }, 151 RadioIntersil, ATU_NO_QUIRK },
152 { USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQWLAN, 152 { USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQWLAN,
153 RadioRFMD, ATU_NO_QUIRK }, 153 RadioRFMD, ATU_NO_QUIRK },
154 { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_STICK, 154 { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_STICK,
155 RadioRFMD2958, ATU_NO_QUIRK }, 155 RadioRFMD2958, ATU_NO_QUIRK },
156 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CHUSB611G, 156 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CHUSB611G,
157 RadioRFMD2958, ATU_NO_QUIRK }, 157 RadioRFMD2958, ATU_NO_QUIRK },
158 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL200U, 158 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL200U,
159 RadioRFMD, ATU_NO_QUIRK }, 159 RadioRFMD, ATU_NO_QUIRK },
160 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL240U, 160 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL240U,
161 RadioRFMD2958, ATU_NO_QUIRK }, 161 RadioRFMD2958, ATU_NO_QUIRK },
162 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_XH1153, 162 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_XH1153,
163 RadioRFMD, ATU_NO_QUIRK }, 163 RadioRFMD, ATU_NO_QUIRK },
164 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL120E, 164 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL120E,
165 RadioRFMD, ATU_NO_QUIRK }, 165 RadioRFMD, ATU_NO_QUIRK },
166 { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWLBM101, 166 { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWLBM101,
167 RadioRFMD, ATU_NO_QUIRK }, 167 RadioRFMD, ATU_NO_QUIRK },
168 { USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_WLAN, /* quirk? */ 168 { USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_WLAN, /* quirk? */
169 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 169 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
170 { USB_VENDOR_HP, USB_PRODUCT_HP_HN210W, 170 { USB_VENDOR_HP, USB_PRODUCT_HP_HN210W,
171 RadioIntersil, ATU_NO_QUIRK }, 171 RadioIntersil, ATU_NO_QUIRK },
172 { USB_VENDOR_INTEL, USB_PRODUCT_INTEL_AP310, 172 { USB_VENDOR_INTEL, USB_PRODUCT_INTEL_AP310,
173 RadioIntersil, ATU_NO_QUIRK }, 173 RadioIntersil, ATU_NO_QUIRK },
174 { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNB11A, 174 { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNB11A,
175 RadioIntersil, ATU_NO_QUIRK }, 175 RadioIntersil, ATU_NO_QUIRK },
176 { USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_2662WAR, 176 { USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_2662WAR,
177 RadioRFMD, ATU_NO_QUIRK }, 177 RadioRFMD, ATU_NO_QUIRK },
178 { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB11, 178 { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB11,
179 RadioIntersil, ATU_NO_QUIRK }, 179 RadioIntersil, ATU_NO_QUIRK },
180 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_WUSB11, 180 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_WUSB11,
181 RadioRFMD, ATU_NO_QUIRK }, 181 RadioRFMD, ATU_NO_QUIRK },
182 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_NWU11B, 182 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_NWU11B,
183 RadioRFMD, ATU_NO_QUIRK }, 183 RadioRFMD, ATU_NO_QUIRK },
184 { USB_VENDOR_LINKSYS3, USB_PRODUCT_LINKSYS3_WUSB11V28, 184 { USB_VENDOR_LINKSYS3, USB_PRODUCT_LINKSYS3_WUSB11V28,
185 RadioRFMD2958, ATU_NO_QUIRK }, 185 RadioRFMD2958, ATU_NO_QUIRK },
186 { USB_VENDOR_MSI, USB_PRODUCT_MSI_WLAN, 186 { USB_VENDOR_MSI, USB_PRODUCT_MSI_WLAN,
187 RadioRFMD2958, ATU_NO_QUIRK }, 187 RadioRFMD2958, ATU_NO_QUIRK },
188 { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101, 188 { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101,
189 RadioIntersil, ATU_NO_QUIRK }, 189 RadioIntersil, ATU_NO_QUIRK },
190 { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101B, 190 { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101B,
191 RadioRFMD, ATU_NO_QUIRK }, 191 RadioRFMD, ATU_NO_QUIRK },
192 { USB_VENDOR_OQO, USB_PRODUCT_OQO_WIFI01, 192 { USB_VENDOR_OQO, USB_PRODUCT_OQO_WIFI01,
193 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 193 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
194 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US11S, 194 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US11S,
195 RadioRFMD, ATU_NO_QUIRK }, 195 RadioRFMD, ATU_NO_QUIRK },
196 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_SWL2100W, 196 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_SWL2100W,
197 AT76C503_i3863, ATU_NO_QUIRK }, 197 AT76C503_i3863, ATU_NO_QUIRK },
198 { USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WLL013, 198 { USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WLL013,
199 RadioRFMD, ATU_NO_QUIRK }, 199 RadioRFMD, ATU_NO_QUIRK },
200 { USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV1, 200 { USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV1,
201 RadioIntersil, ATU_NO_QUIRK }, 201 RadioIntersil, ATU_NO_QUIRK },
202 { USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV2, 202 { USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV2,
203 AT76C503_rfmd_acc, ATU_NO_QUIRK }, 203 AT76C503_rfmd_acc, ATU_NO_QUIRK },
204 { USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_U300C, 204 { USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_U300C,
205 RadioIntersil, ATU_NO_QUIRK }, 205 RadioIntersil, ATU_NO_QUIRK },
206 { USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_M4Y750, 206 { USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_M4Y750,
207 RadioIntersil, ATU_NO_QUIRK }, 207 RadioIntersil, ATU_NO_QUIRK },
208}; 208};
209 209
210static const struct atu_radfirm { 210static const struct atu_radfirm {
211 enum atu_radio_type atur_type; 211 enum atu_radio_type atur_type;
212 unsigned char *atur_internal; 212 unsigned char *atur_internal;
213 size_t atur_internal_sz; 213 size_t atur_internal_sz;
214 unsigned char *atur_external; 214 unsigned char *atur_external;
215 size_t atur_external_sz; 215 size_t atur_external_sz;
216} atu_radfirm[] = { 216} atu_radfirm[] = {
217 { RadioRFMD, 217 { RadioRFMD,
218 atmel_fw_rfmd_int, sizeof(atmel_fw_rfmd_int), 218 atmel_fw_rfmd_int, sizeof(atmel_fw_rfmd_int),
219 atmel_fw_rfmd_ext, sizeof(atmel_fw_rfmd_ext) }, 219 atmel_fw_rfmd_ext, sizeof(atmel_fw_rfmd_ext) },
220 { RadioRFMD2958, 220 { RadioRFMD2958,
221 atmel_fw_rfmd2958_int, sizeof(atmel_fw_rfmd2958_int), 221 atmel_fw_rfmd2958_int, sizeof(atmel_fw_rfmd2958_int),
222 atmel_fw_rfmd2958_ext, sizeof(atmel_fw_rfmd2958_ext) }, 222 atmel_fw_rfmd2958_ext, sizeof(atmel_fw_rfmd2958_ext) },
223 { RadioRFMD2958_SMC, 223 { RadioRFMD2958_SMC,
224 atmel_fw_rfmd2958_smc_int, sizeof(atmel_fw_rfmd2958_smc_int), 224 atmel_fw_rfmd2958_smc_int, sizeof(atmel_fw_rfmd2958_smc_int),
225 atmel_fw_rfmd2958_smc_ext, sizeof(atmel_fw_rfmd2958_smc_ext) }, 225 atmel_fw_rfmd2958_smc_ext, sizeof(atmel_fw_rfmd2958_smc_ext) },
226 { RadioIntersil, 226 { RadioIntersil,
227 atmel_fw_intersil_int, sizeof(atmel_fw_intersil_int), 227 atmel_fw_intersil_int, sizeof(atmel_fw_intersil_int),
228 atmel_fw_intersil_ext, sizeof(atmel_fw_intersil_ext) } 228 atmel_fw_intersil_ext, sizeof(atmel_fw_intersil_ext) }
229}; 229};
230 230
231static int atu_newbuf(struct atu_softc *, struct atu_chain *, struct mbuf *); 231static int atu_newbuf(struct atu_softc *, struct atu_chain *, struct mbuf *);
232static void atu_rxeof(struct usbd_xfer *, void *, usbd_status); 232static void atu_rxeof(struct usbd_xfer *, void *, usbd_status);
233static void atu_txeof(struct usbd_xfer *, void *, usbd_status); 233static void atu_txeof(struct usbd_xfer *, void *, usbd_status);
234static void atu_start(struct ifnet *); 234static void atu_start(struct ifnet *);
235static int atu_ioctl(struct ifnet *, u_long, void *); 235static int atu_ioctl(struct ifnet *, u_long, void *);
236static int atu_init(struct ifnet *); 236static int atu_init(struct ifnet *);
237static void atu_stop(struct ifnet *, int); 237static void atu_stop(struct ifnet *, int);
238static void atu_watchdog(struct ifnet *); 238static void atu_watchdog(struct ifnet *);
239static usbd_status atu_usb_request(struct atu_softc *, uint8_t, 239static usbd_status atu_usb_request(struct atu_softc *, uint8_t,
240 uint8_t, uint16_t, uint16_t, 240 uint8_t, uint16_t, uint16_t,
241 uint16_t, uint8_t *); 241 uint16_t, uint8_t *);
242static int atu_send_command(struct atu_softc *, uint8_t *, int); 242static int atu_send_command(struct atu_softc *, uint8_t *, int);
243static int atu_get_cmd_status(struct atu_softc *, uint8_t, 243static int atu_get_cmd_status(struct atu_softc *, uint8_t,
244 uint8_t *); 244 uint8_t *);
245static int atu_wait_completion(struct atu_softc *, uint8_t, 245static int atu_wait_completion(struct atu_softc *, uint8_t,
246 uint8_t *); 246 uint8_t *);
247static int atu_send_mib(struct atu_softc *, uint8_t, 247static int atu_send_mib(struct atu_softc *, uint8_t,
248 uint8_t, uint8_t, void *); 248 uint8_t, uint8_t, void *);
249static int atu_get_mib(struct atu_softc *, uint8_t, 249static int atu_get_mib(struct atu_softc *, uint8_t,
250 uint8_t, uint8_t, uint8_t *); 250 uint8_t, uint8_t, uint8_t *);
251#if 0 251#if 0
252int atu_start_ibss(struct atu_softc *); 252int atu_start_ibss(struct atu_softc *);
253#endif 253#endif
254static int atu_start_scan(struct atu_softc *); 254static int atu_start_scan(struct atu_softc *);
255static int atu_switch_radio(struct atu_softc *, int); 255static int atu_switch_radio(struct atu_softc *, int);
256static int atu_initial_config(struct atu_softc *); 256static int atu_initial_config(struct atu_softc *);
257static int atu_join(struct atu_softc *, struct ieee80211_node *); 257static int atu_join(struct atu_softc *, struct ieee80211_node *);
258static int8_t atu_get_dfu_state(struct atu_softc *); 258static int8_t atu_get_dfu_state(struct atu_softc *);
259static uint8_t atu_get_opmode(struct atu_softc *, uint8_t *); 259static uint8_t atu_get_opmode(struct atu_softc *, uint8_t *);
260static void atu_internal_firmware(device_t); 260static void atu_internal_firmware(device_t);
261static void atu_external_firmware(device_t); 261static void atu_external_firmware(device_t);
262static int atu_get_card_config(struct atu_softc *); 262static int atu_get_card_config(struct atu_softc *);
263static int atu_media_change(struct ifnet *); 263static int atu_media_change(struct ifnet *);
264static void atu_media_status(struct ifnet *, struct ifmediareq *); 264static void atu_media_status(struct ifnet *, struct ifmediareq *);
265static int atu_tx_list_init(struct atu_softc *); 265static int atu_tx_list_init(struct atu_softc *);
266static int atu_rx_list_init(struct atu_softc *); 266static int atu_rx_list_init(struct atu_softc *);
267static void atu_xfer_list_free(struct atu_softc *, struct atu_chain *, 267static void atu_xfer_list_free(struct atu_softc *, struct atu_chain *,
268 int); 268 int);
269 269
270static void atu_task(void *); 270static void atu_task(void *);
271static int atu_newstate(struct ieee80211com *, enum ieee80211_state, int); 271static int atu_newstate(struct ieee80211com *, enum ieee80211_state, int);
272static int atu_tx_start(struct atu_softc *, struct ieee80211_node *, 272static int atu_tx_start(struct atu_softc *, struct ieee80211_node *,
273 struct atu_chain *, struct mbuf *); 273 struct atu_chain *, struct mbuf *);
274static void atu_complete_attach(struct atu_softc *); 274static void atu_complete_attach(struct atu_softc *);
275static uint8_t atu_calculate_padding(int); 275static uint8_t atu_calculate_padding(int);
276 276
277static int atu_match(device_t, cfdata_t, void *); 277static int atu_match(device_t, cfdata_t, void *);
278static void atu_attach(device_t, device_t, void *); 278static void atu_attach(device_t, device_t, void *);
279static int atu_detach(device_t, int); 279static int atu_detach(device_t, int);
280static int atu_activate(device_t, enum devact); 280static int atu_activate(device_t, enum devact);
281 281
282CFATTACH_DECL_NEW(atu, sizeof(struct atu_softc), atu_match, atu_attach, 282CFATTACH_DECL_NEW(atu, sizeof(struct atu_softc), atu_match, atu_attach,
283 atu_detach, atu_activate); 283 atu_detach, atu_activate);
284 284
285static usbd_status 285static usbd_status
286atu_usb_request(struct atu_softc *sc, uint8_t type, 286atu_usb_request(struct atu_softc *sc, uint8_t type,
287 uint8_t request, uint16_t value, uint16_t index, uint16_t length, 287 uint8_t request, uint16_t value, uint16_t index, uint16_t length,
288 uint8_t *data) 288 uint8_t *data)
289{ 289{
290 usb_device_request_t req; 290 usb_device_request_t req;
291 struct usbd_xfer *xfer; 291 struct usbd_xfer *xfer;
292 usbd_status err; 292 usbd_status err;
293 int total_len = 0, s; 293 int total_len = 0, s;
294 294
295 req.bmRequestType = type; 295 req.bmRequestType = type;
296 req.bRequest = request; 296 req.bRequest = request;
297 USETW(req.wValue, value); 297 USETW(req.wValue, value);
298 USETW(req.wIndex, index); 298 USETW(req.wIndex, index);
299 USETW(req.wLength, length); 299 USETW(req.wLength, length);
300 300
301#ifdef ATU_DEBUG 301#ifdef ATU_DEBUG
302 if (atudebug) { 302 if (atudebug) {
303 DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x " 303 DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x "
304 "len=%02x\n", device_xname(sc->atu_dev), request, 304 "len=%02x\n", device_xname(sc->atu_dev), request,
305 value, index, length)); 305 value, index, length));
306 } 306 }
307#endif /* ATU_DEBUG */ 307#endif /* ATU_DEBUG */
308 308
309 s = splnet(); 309 s = splnet();
310 310
311 struct usbd_pipe *pipe0 = usbd_get_pipe0(sc->atu_udev); 311 struct usbd_pipe *pipe0 = usbd_get_pipe0(sc->atu_udev);
312 int error = usbd_create_xfer(pipe0, length, 0, 0, 312 int error = usbd_create_xfer(pipe0, length, 0, 0,
313 &xfer); 313 &xfer);
314 if (error) { 314 if (error) {
315 splx(s); 315 splx(s);
316 return USBD_IOERROR; 316 return USBD_IOERROR;
317 } 317 }
318 usbd_setup_default_xfer(xfer, sc->atu_udev, 0, 500000, &req, data, 318 usbd_setup_default_xfer(xfer, sc->atu_udev, 0, 500000, &req, data,
319 length, USBD_SHORT_XFER_OK, NULL); 319 length, USBD_SHORT_XFER_OK, NULL);
320 320
321 err = usbd_sync_transfer(xfer); 321 err = usbd_sync_transfer(xfer);
322 322
323 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 323 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
324 324
325#ifdef ATU_DEBUG 325#ifdef ATU_DEBUG
326 if (atudebug) { 326 if (atudebug) {
327 if (type & UT_READ) { 327 if (type & UT_READ) {
328 DPRINTFN(20, ("%s: transfered 0x%x bytes in\n", 328 DPRINTFN(20, ("%s: transfered 0x%x bytes in\n",
329 device_xname(sc->atu_dev), total_len)); 329 device_xname(sc->atu_dev), total_len));
330 } else { 330 } else {
331 if (total_len != length) 331 if (total_len != length)
332 DPRINTF(("%s: wrote only %x bytes\n", 332 DPRINTF(("%s: wrote only %x bytes\n",
333 device_xname(sc->atu_dev), total_len)); 333 device_xname(sc->atu_dev), total_len));
334 } 334 }
335 } 335 }
336#endif /* ATU_DEBUG */ 336#endif /* ATU_DEBUG */
337 337
338 usbd_destroy_xfer(xfer); 338 usbd_destroy_xfer(xfer);
339 339
340 splx(s); 340 splx(s);
341 return err; 341 return err;
342} 342}
343 343
344static int 344static int
345atu_send_command(struct atu_softc *sc, uint8_t *command, int size) 345atu_send_command(struct atu_softc *sc, uint8_t *command, int size)
346{ 346{
347 return atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000, 347 return atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000,
348 0x0000, size, command); 348 0x0000, size, command);
349} 349}
350 350
351static int 351static int
352atu_get_cmd_status(struct atu_softc *sc, uint8_t cmd, uint8_t *status) 352atu_get_cmd_status(struct atu_softc *sc, uint8_t cmd, uint8_t *status)
353{ 353{
354 /* 354 /*
355 * all other drivers (including Windoze) request 40 bytes of status 355 * all other drivers (including Windoze) request 40 bytes of status
356 * and get a short-xfer of just 6 bytes. we can save 34 bytes of 356 * and get a short-xfer of just 6 bytes. we can save 34 bytes of
357 * buffer if we just request those 6 bytes in the first place :) 357 * buffer if we just request those 6 bytes in the first place :)
358 */ 358 */
359 /* 359 /*
360 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd, 360 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd,
361 0x0000, 40, status); 361 0x0000, 40, status);
362 */ 362 */
363 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd, 363 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd,
364 0x0000, 6, status); 364 0x0000, 6, status);
365} 365}
366 366
367static int 367static int
368atu_wait_completion(struct atu_softc *sc, uint8_t cmd, uint8_t *status) 368atu_wait_completion(struct atu_softc *sc, uint8_t cmd, uint8_t *status)
369{ 369{
370 int idle_count = 0, err; 370 int idle_count = 0, err;
371 uint8_t statusreq[6]; 371 uint8_t statusreq[6];
372 372
373 DPRINTFN(15, ("%s: wait-completion: cmd=%02x\n", 373 DPRINTFN(15, ("%s: wait-completion: cmd=%02x\n",
374 device_xname(sc->atu_dev), cmd)); 374 device_xname(sc->atu_dev), cmd));
375 375
376 while (1) { 376 while (1) {
377 err = atu_get_cmd_status(sc, cmd, statusreq); 377 err = atu_get_cmd_status(sc, cmd, statusreq);
378 if (err) 378 if (err)
379 return err; 379 return err;
380 380
381#ifdef ATU_DEBUG 381#ifdef ATU_DEBUG
382 if (atudebug) { 382 if (atudebug) {
383 DPRINTFN(20, ("%s: status=%s cmd=%02x\n", 383 DPRINTFN(20, ("%s: status=%s cmd=%02x\n",
384 device_xname(sc->atu_dev), 384 device_xname(sc->atu_dev),
385 ether_sprintf(statusreq), cmd)); 385 ether_sprintf(statusreq), cmd));
386 } 386 }
387#endif /* ATU_DEBUG */ 387#endif /* ATU_DEBUG */
388 388
389 /* 389 /*
390 * during normal operations waiting on STATUS_IDLE 390 * during normal operations waiting on STATUS_IDLE
391 * will never happen more than once 391 * will never happen more than once
392 */ 392 */
393 if ((statusreq[5] == STATUS_IDLE) && (idle_count++ > 20)) { 393 if ((statusreq[5] == STATUS_IDLE) && (idle_count++ > 20)) {
394 DPRINTF(("%s: idle_count > 20!\n", 394 DPRINTF(("%s: idle_count > 20!\n",
395 device_xname(sc->atu_dev))); 395 device_xname(sc->atu_dev)));
396 return 0; 396 return 0;
397 } 397 }
398 398
399 if ((statusreq[5] != STATUS_IN_PROGRESS) && 399 if ((statusreq[5] != STATUS_IN_PROGRESS) &&
400 (statusreq[5] != STATUS_IDLE)) { 400 (statusreq[5] != STATUS_IDLE)) {
401 if (status != NULL) 401 if (status != NULL)
402 *status = statusreq[5]; 402 *status = statusreq[5];
403 return 0; 403 return 0;
404 } 404 }
405 usbd_delay_ms(sc->atu_udev, 25); 405 usbd_delay_ms(sc->atu_udev, 25);
406 } 406 }
407} 407}
408 408
409static int 409static int
410atu_send_mib(struct atu_softc *sc, uint8_t type, uint8_t size, 410atu_send_mib(struct atu_softc *sc, uint8_t type, uint8_t size,
411 uint8_t index, void *data) 411 uint8_t index, void *data)
412{ 412{
413 int err; 413 int err;
414 struct atu_cmd_set_mib request; 414 struct atu_cmd_set_mib request;
415 415
416 /* 416 /*
417 * We don't construct a MIB packet first and then memcpy it into an 417 * We don't construct a MIB packet first and then memcpy it into an
418 * Atmel-command-packet, we just construct it the right way at once :) 418 * Atmel-command-packet, we just construct it the right way at once :)
419 */ 419 */
420 420
421 memset(&request, 0, sizeof(request)); 421 memset(&request, 0, sizeof(request));
422 422
423 request.AtCmd = CMD_SET_MIB; 423 request.AtCmd = CMD_SET_MIB;
424 USETW(request.AtSize, size + 4); 424 USETW(request.AtSize, size + 4);
425 425
426 request.MIBType = type; 426 request.MIBType = type;
427 request.MIBSize = size; 427 request.MIBSize = size;
428 request.MIBIndex = index; 428 request.MIBIndex = index;
429 request.MIBReserved = 0; 429 request.MIBReserved = 0;
430 430
431 /* 431 /*
432 * For 1 and 2 byte requests we assume a direct value, 432 * For 1 and 2 byte requests we assume a direct value,
433 * everything bigger than 2 bytes we assume a pointer to the data 433 * everything bigger than 2 bytes we assume a pointer to the data
434 */ 434 */
435 switch (size) { 435 switch (size) {
436 case 0: 436 case 0:
437 break; 437 break;
438 case 1: 438 case 1:
439 request.data[0]=(long)data & 0x000000ff; 439 request.data[0]=(long)data & 0x000000ff;
440 break; 440 break;
441 case 2: 441 case 2:
442 request.data[0]=(long)data & 0x000000ff; 442 request.data[0]=(long)data & 0x000000ff;
443 request.data[1]=(long)data >> 8; 443 request.data[1]=(long)data >> 8;
444 break; 444 break;
445 default: 445 default:
446 memcpy(request.data, data, size); 446 memcpy(request.data, data, size);
447 break; 447 break;
448 } 448 }
449 449
450 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000, 450 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000,
451 0x0000, size+8, (uByte *)&request); 451 0x0000, size+8, (uByte *)&request);
452 if (err) 452 if (err)
453 return err; 453 return err;
454 454
455 DPRINTFN(15, ("%s: sendmib : waitcompletion...\n", 455 DPRINTFN(15, ("%s: sendmib : waitcompletion...\n",
456 device_xname(sc->atu_dev))); 456 device_xname(sc->atu_dev)));
457 return atu_wait_completion(sc, CMD_SET_MIB, NULL); 457 return atu_wait_completion(sc, CMD_SET_MIB, NULL);
458} 458}
459 459
460static int 460static int
461atu_get_mib(struct atu_softc *sc, uint8_t type, uint8_t size, 461atu_get_mib(struct atu_softc *sc, uint8_t type, uint8_t size,
462 uint8_t index, uint8_t *buf) 462 uint8_t index, uint8_t *buf)
463{ 463{
464 464
465 /* linux/at76c503.c - 478 */ 465 /* linux/at76c503.c - 478 */
466 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x033, 466 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x033,
467 type << 8, index, size, buf); 467 type << 8, index, size, buf);
468} 468}
469 469
470#if 0 470#if 0
471int 471int
472atu_start_ibss(struct atu_softc *sc) 472atu_start_ibss(struct atu_softc *sc)
473{ 473{
474 struct ieee80211com *ic = &sc->sc_ic; 474 struct ieee80211com *ic = &sc->sc_ic;
475 int err; 475 int err;
476 struct atu_cmd_start_ibss Request; 476 struct atu_cmd_start_ibss Request;
477 477
478 Request.Cmd = CMD_START_IBSS; 478 Request.Cmd = CMD_START_IBSS;
479 Request.Reserved = 0; 479 Request.Reserved = 0;
480 Request.Size = sizeof(Request) - 4; 480 Request.Size = sizeof(Request) - 4;
481 481
482 memset(Request.BSSID, 0x00, sizeof(Request.BSSID)); 482 memset(Request.BSSID, 0x00, sizeof(Request.BSSID));
483 memset(Request.SSID, 0x00, sizeof(Request.SSID)); 483 memset(Request.SSID, 0x00, sizeof(Request.SSID));
484 memcpy(Request.SSID, ic->ic_des_ssid, ic->ic_des_ssidlen); 484 memcpy(Request.SSID, ic->ic_des_ssid, ic->ic_des_ssidlen);
485 Request.SSIDSize = ic->ic_des_ssidlen; 485 Request.SSIDSize = ic->ic_des_ssidlen;
486 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) 486 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
487 Request.Channel = (uint8_t)sc->atu_desired_channel; 487 Request.Channel = (uint8_t)sc->atu_desired_channel;
488 else 488 else
489 Request.Channel = ATU_DEFAULT_CHANNEL; 489 Request.Channel = ATU_DEFAULT_CHANNEL;
490 Request.BSSType = AD_HOC_MODE; 490 Request.BSSType = AD_HOC_MODE;
491 memset(Request.Res, 0x00, sizeof(Request.Res)); 491 memset(Request.Res, 0x00, sizeof(Request.Res));
492 492
493 /* Write config to adapter */ 493 /* Write config to adapter */
494 err = atu_send_command(sc, (uint8_t *)&Request, sizeof(Request)); 494 err = atu_send_command(sc, (uint8_t *)&Request, sizeof(Request));
495 if (err) { 495 if (err) {
496 DPRINTF(("%s: start ibss failed!\n", 496 DPRINTF(("%s: start ibss failed!\n",
497 device_xname(sc->atu_dev))); 497 device_xname(sc->atu_dev)));
498 return err; 498 return err;
499 } 499 }
500 500
501 /* Wait for the adapter to do its thing */ 501 /* Wait for the adapter to do its thing */
502 err = atu_wait_completion(sc, CMD_START_IBSS, NULL); 502 err = atu_wait_completion(sc, CMD_START_IBSS, NULL);
503 if (err) { 503 if (err) {
504 DPRINTF(("%s: error waiting for start_ibss\n", 504 DPRINTF(("%s: error waiting for start_ibss\n",
505 device_xname(sc->atu_dev))); 505 device_xname(sc->atu_dev)));
506 return err; 506 return err;
507 } 507 }
508 508
509 /* Get the current BSSID */ 509 /* Get the current BSSID */
510 err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, sc->atu_bssid); 510 err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, sc->atu_bssid);
511 if (err) { 511 if (err) {
512 DPRINTF(("%s: could not get BSSID!\n", 512 DPRINTF(("%s: could not get BSSID!\n",
513 device_xname(sc->atu_dev))); 513 device_xname(sc->atu_dev)));
514 return err; 514 return err;
515 } 515 }
516 516
517 DPRINTF(("%s: started a new IBSS (BSSID=%s)\n", 517 DPRINTF(("%s: started a new IBSS (BSSID=%s)\n",
518 device_xname(sc->atu_dev), ether_sprintf(sc->atu_bssid))); 518 device_xname(sc->atu_dev), ether_sprintf(sc->atu_bssid)));
519 return 0; 519 return 0;
520} 520}
521#endif 521#endif
522 522
523static int 523static int
524atu_start_scan(struct atu_softc *sc) 524atu_start_scan(struct atu_softc *sc)
525{ 525{
526 struct ieee80211com *ic = &sc->sc_ic; 526 struct ieee80211com *ic = &sc->sc_ic;
527 struct atu_cmd_do_scan Scan; 527 struct atu_cmd_do_scan Scan;
528 usbd_status err; 528 usbd_status err;
529 int Cnt; 529 int Cnt;
530 530
531 memset(&Scan, 0, sizeof(Scan)); 531 memset(&Scan, 0, sizeof(Scan));
532 532
533 Scan.Cmd = CMD_START_SCAN; 533 Scan.Cmd = CMD_START_SCAN;
534 Scan.Reserved = 0; 534 Scan.Reserved = 0;
535 USETW(Scan.Size, sizeof(Scan) - 4); 535 USETW(Scan.Size, sizeof(Scan) - 4);
536 536
537 /* use the broadcast BSSID (in active scan) */ 537 /* use the broadcast BSSID (in active scan) */
538 for (Cnt=0; Cnt<6; Cnt++) 538 for (Cnt=0; Cnt<6; Cnt++)
539 Scan.BSSID[Cnt] = 0xff; 539 Scan.BSSID[Cnt] = 0xff;
540 540
541 memset(Scan.SSID, 0x00, sizeof(Scan.SSID)); 541 memset(Scan.SSID, 0x00, sizeof(Scan.SSID));
542 memcpy(Scan.SSID, ic->ic_des_essid, ic->ic_des_esslen); 542 memcpy(Scan.SSID, ic->ic_des_essid, ic->ic_des_esslen);
543 Scan.SSID_Len = ic->ic_des_esslen; 543 Scan.SSID_Len = ic->ic_des_esslen;
544 544
545 /* default values for scan */ 545 /* default values for scan */
546 Scan.ScanType = ATU_SCAN_ACTIVE; 546 Scan.ScanType = ATU_SCAN_ACTIVE;
547 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) 547 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
548 Scan.Channel = (uint8_t)sc->atu_desired_channel; 548 Scan.Channel = (uint8_t)sc->atu_desired_channel;
549 else 549 else
550 Scan.Channel = sc->atu_channel; 550 Scan.Channel = sc->atu_channel;
551 551
552 ic->ic_curchan = &ic->ic_channels[Scan.Channel]; 552 ic->ic_curchan = &ic->ic_channels[Scan.Channel];
553 553
554 /* we like scans to be quick :) */ 554 /* we like scans to be quick :) */
555 /* the time we wait before sending probe's */ 555 /* the time we wait before sending probe's */
556 USETW(Scan.ProbeDelay, 0); 556 USETW(Scan.ProbeDelay, 0);
557 /* the time we stay on one channel */ 557 /* the time we stay on one channel */
558 USETW(Scan.MinChannelTime, 100); 558 USETW(Scan.MinChannelTime, 100);
559 USETW(Scan.MaxChannelTime, 200); 559 USETW(Scan.MaxChannelTime, 200);
560 /* whether or not we scan all channels */ 560 /* whether or not we scan all channels */
561 Scan.InternationalScan = 0xc1; 561 Scan.InternationalScan = 0xc1;
562 562
563#ifdef ATU_DEBUG 563#ifdef ATU_DEBUG
564 if (atudebug) { 564 if (atudebug) {
565 DPRINTFN(20, ("%s: scan cmd len=%02zx\n", 565 DPRINTFN(20, ("%s: scan cmd len=%02zx\n",
566 device_xname(sc->atu_dev), sizeof(Scan))); 566 device_xname(sc->atu_dev), sizeof(Scan)));
567 } 567 }
568#endif /* ATU_DEBUG */ 568#endif /* ATU_DEBUG */
569 569
570 /* Write config to adapter */ 570 /* Write config to adapter */
571 err = atu_send_command(sc, (uint8_t *)&Scan, sizeof(Scan)); 571 err = atu_send_command(sc, (uint8_t *)&Scan, sizeof(Scan));
572 if (err) 572 if (err)
573 return err; 573 return err;
574 574
575 /* 575 /*
576 * We don't wait for the command to finish... the mgmt-thread will do 576 * We don't wait for the command to finish... the mgmt-thread will do
577 * that for us 577 * that for us
578 */ 578 */
579 /* 579 /*
580 err = atu_wait_completion(sc, CMD_START_SCAN, NULL); 580 err = atu_wait_completion(sc, CMD_START_SCAN, NULL);
581 if (err) 581 if (err)
582 return err; 582 return err;
583 */ 583 */
584 return 0; 584 return 0;
585} 585}
586 586
587static int 587static int
588atu_switch_radio(struct atu_softc *sc, int state) 588atu_switch_radio(struct atu_softc *sc, int state)
589{ 589{
590 usbd_status err; 590 usbd_status err;
591 struct atu_cmd CmdRadio; 591 struct atu_cmd CmdRadio;
592 592
593 if (sc->atu_radio == RadioIntersil) { 593 if (sc->atu_radio == RadioIntersil) {
594 /* 594 /*
595 * Intersil doesn't seem to need/support switching the radio 595 * Intersil doesn't seem to need/support switching the radio
596 * on/off 596 * on/off
597 */ 597 */
598 return 0; 598 return 0;
599 } 599 }
600 600
601 memset(&CmdRadio, 0, sizeof(CmdRadio)); 601 memset(&CmdRadio, 0, sizeof(CmdRadio));
602 CmdRadio.Cmd = CMD_RADIO_ON; 602 CmdRadio.Cmd = CMD_RADIO_ON;
603 603
604 if (sc->atu_radio_on != state) { 604 if (sc->atu_radio_on != state) {
605 if (state == 0) 605 if (state == 0)
606 CmdRadio.Cmd = CMD_RADIO_OFF; 606 CmdRadio.Cmd = CMD_RADIO_OFF;
607 607
608 err = atu_send_command(sc, (uint8_t *)&CmdRadio, 608 err = atu_send_command(sc, (uint8_t *)&CmdRadio,
609 sizeof(CmdRadio)); 609 sizeof(CmdRadio));
610 if (err) 610 if (err)
611 return err; 611 return err;
612 612
613 err = atu_wait_completion(sc, CmdRadio.Cmd, NULL); 613 err = atu_wait_completion(sc, CmdRadio.Cmd, NULL);
614 if (err) 614 if (err)
615 return err; 615 return err;
616 616
617 DPRINTFN(10, ("%s: radio turned %s\n", 617 DPRINTFN(10, ("%s: radio turned %s\n",
618 device_xname(sc->atu_dev), state ? "on" : "off")); 618 device_xname(sc->atu_dev), state ? "on" : "off"));
619 sc->atu_radio_on = state; 619 sc->atu_radio_on = state;
620 } 620 }
621 return 0; 621 return 0;
622} 622}
623 623
624static int 624static int
625atu_initial_config(struct atu_softc *sc) 625atu_initial_config(struct atu_softc *sc)
626{ 626{
627 struct ieee80211com *ic = &sc->sc_ic; 627 struct ieee80211com *ic = &sc->sc_ic;
628 uint32_t i; 628 uint32_t i;
629 usbd_status err; 629 usbd_status err;
630/* uint8_t rates[4] = {0x82, 0x84, 0x8B, 0x96};*/ 630/* uint8_t rates[4] = {0x82, 0x84, 0x8B, 0x96};*/
631 uint8_t rates[4] = {0x82, 0x04, 0x0B, 0x16}; 631 uint8_t rates[4] = {0x82, 0x04, 0x0B, 0x16};
632 struct atu_cmd_card_config cmd; 632 struct atu_cmd_card_config cmd;
633 uint8_t reg_domain; 633 uint8_t reg_domain;
634 634
635 DPRINTFN(10, ("%s: sending mac-addr\n", device_xname(sc->atu_dev))); 635 DPRINTFN(10, ("%s: sending mac-addr\n", device_xname(sc->atu_dev)));
636 err = atu_send_mib(sc, MIB_MAC_ADDR__ADDR, ic->ic_myaddr); 636 err = atu_send_mib(sc, MIB_MAC_ADDR__ADDR, ic->ic_myaddr);
637 if (err) { 637 if (err) {
638 DPRINTF(("%s: error setting mac-addr\n", 638 DPRINTF(("%s: error setting mac-addr\n",
639 device_xname(sc->atu_dev))); 639 device_xname(sc->atu_dev)));
640 return err; 640 return err;
641 } 641 }
642 642
643 /* 643 /*
644 DPRINTF(("%s: sending reg-domain\n", device_xname(sc->atu_dev))); 644 DPRINTF(("%s: sending reg-domain\n", device_xname(sc->atu_dev)));
645 err = atu_send_mib(sc, MIB_PHY__REG_DOMAIN, NR(0x30)); 645 err = atu_send_mib(sc, MIB_PHY__REG_DOMAIN, NR(0x30));
646 if (err) { 646 if (err) {
647 DPRINTF(("%s: error setting mac-addr\n", 647 DPRINTF(("%s: error setting mac-addr\n",
648 device_xname(sc->atu_dev))); 648 device_xname(sc->atu_dev)));
649 return err; 649 return err;
650 } 650 }
651 */ 651 */
652 652
653 memset(&cmd, 0, sizeof(cmd)); 653 memset(&cmd, 0, sizeof(cmd));
654 cmd.Cmd = CMD_STARTUP; 654 cmd.Cmd = CMD_STARTUP;
655 cmd.Reserved = 0; 655 cmd.Reserved = 0;
656 USETW(cmd.Size, sizeof(cmd) - 4); 656 USETW(cmd.Size, sizeof(cmd) - 4);
657 657
658 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) 658 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
659 cmd.Channel = (uint8_t)sc->atu_desired_channel; 659 cmd.Channel = (uint8_t)sc->atu_desired_channel;
660 else 660 else
661 cmd.Channel = sc->atu_channel; 661 cmd.Channel = sc->atu_channel;
662 cmd.AutoRateFallback = 1; 662 cmd.AutoRateFallback = 1;
663 memcpy(cmd.BasicRateSet, rates, 4); 663 memcpy(cmd.BasicRateSet, rates, 4);
664 664
665 /* ShortRetryLimit should be 7 according to 802.11 spec */ 665 /* ShortRetryLimit should be 7 according to 802.11 spec */
666 cmd.ShortRetryLimit = 7; 666 cmd.ShortRetryLimit = 7;
667 USETW(cmd.RTS_Threshold, 2347); 667 USETW(cmd.RTS_Threshold, 2347);
668 USETW(cmd.FragThreshold, 2346); 668 USETW(cmd.FragThreshold, 2346);
669 669
670 /* Doesn't seem to work, but we'll set it to 1 anyway */ 670 /* Doesn't seem to work, but we'll set it to 1 anyway */
671 cmd.PromiscuousMode = 1; 671 cmd.PromiscuousMode = 1;
672 672
673 /* this goes into the beacon we transmit */ 673 /* this goes into the beacon we transmit */
674 if (ic->ic_flags & IEEE80211_F_PRIVACY) 674 if (ic->ic_flags & IEEE80211_F_PRIVACY)
675 cmd.PrivacyInvoked = 1; 675 cmd.PrivacyInvoked = 1;
676 else 676 else
677 cmd.PrivacyInvoked = 0; 677 cmd.PrivacyInvoked = 0;
678 678
679 cmd.ExcludeUnencrypted = 0; 679 cmd.ExcludeUnencrypted = 0;
680 680
681 if (ic->ic_flags & IEEE80211_F_PRIVACY) { 681 if (ic->ic_flags & IEEE80211_F_PRIVACY) {
682 switch (ic->ic_nw_keys[ic->ic_def_txkey].wk_keylen) { 682 switch (ic->ic_nw_keys[ic->ic_def_txkey].wk_keylen) {
683 case 5: 683 case 5:
684 cmd.EncryptionType = ATU_WEP_40BITS; 684 cmd.EncryptionType = ATU_WEP_40BITS;
685 break; 685 break;
686 case 13: 686 case 13:
687 cmd.EncryptionType = ATU_WEP_104BITS; 687 cmd.EncryptionType = ATU_WEP_104BITS;
688 break; 688 break;
689 default: 689 default:
690 cmd.EncryptionType = ATU_WEP_OFF; 690 cmd.EncryptionType = ATU_WEP_OFF;
691 break; 691 break;
692 } 692 }
693 693
694 694
695 cmd.WEP_DefaultKeyID = ic->ic_def_txkey; 695 cmd.WEP_DefaultKeyID = ic->ic_def_txkey;
696 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 696 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
697 memcpy(cmd.WEP_DefaultKey[i], ic->ic_nw_keys[i].wk_key, 697 memcpy(cmd.WEP_DefaultKey[i], ic->ic_nw_keys[i].wk_key,
698 ic->ic_nw_keys[i].wk_keylen); 698 ic->ic_nw_keys[i].wk_keylen);
699 } 699 }
700 } 700 }
701 701
702 /* Setting the SSID here doesn't seem to do anything */ 702 /* Setting the SSID here doesn't seem to do anything */
703 memset(cmd.SSID, 0x00, sizeof(cmd.SSID)); 703 memset(cmd.SSID, 0x00, sizeof(cmd.SSID));
704 memcpy(cmd.SSID, ic->ic_des_essid, ic->ic_des_esslen); 704 memcpy(cmd.SSID, ic->ic_des_essid, ic->ic_des_esslen);
705 cmd.SSID_Len = ic->ic_des_esslen; 705 cmd.SSID_Len = ic->ic_des_esslen;
706 706
707 cmd.ShortPreamble = 0; 707 cmd.ShortPreamble = 0;
708 USETW(cmd.BeaconPeriod, 100); 708 USETW(cmd.BeaconPeriod, 100);
709 /* cmd.BeaconPeriod = 65535; */ 709 /* cmd.BeaconPeriod = 65535; */
710 710
711 /* 711 /*
712 * TODO: 712 * TODO:
713 * read reg domain MIB_PHY @ 0x17 (1 byte), (reply = 0x30) 713 * read reg domain MIB_PHY @ 0x17 (1 byte), (reply = 0x30)
714 * we should do something useful with this info. right now it's just 714 * we should do something useful with this info. right now it's just
715 * ignored 715 * ignored
716 */ 716 */
717 err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, &reg_domain); 717 err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, &reg_domain);
718 if (err) { 718 if (err) {
719 DPRINTF(("%s: could not get regdomain!\n", 719 DPRINTF(("%s: could not get regdomain!\n",
720 device_xname(sc->atu_dev))); 720 device_xname(sc->atu_dev)));
721 } else { 721 } else {
722 DPRINTF(("%s: in reg domain 0x%x according to the " 722 DPRINTF(("%s: in reg domain 0x%x according to the "
723 "adapter\n", device_xname(sc->atu_dev), reg_domain)); 723 "adapter\n", device_xname(sc->atu_dev), reg_domain));
724 } 724 }
725 725
726#ifdef ATU_DEBUG 726#ifdef ATU_DEBUG
727 if (atudebug) { 727 if (atudebug) {
728 DPRINTFN(20, ("%s: configlen=%02zx\n", 728 DPRINTFN(20, ("%s: configlen=%02zx\n",
729 device_xname(sc->atu_dev), sizeof(cmd))); 729 device_xname(sc->atu_dev), sizeof(cmd)));
730 } 730 }
731#endif /* ATU_DEBUG */ 731#endif /* ATU_DEBUG */
732 732
733 /* Windoze : driver says exclude-unencrypted=1 & encr-type=1 */ 733 /* Windoze : driver says exclude-unencrypted=1 & encr-type=1 */
734 734
735 err = atu_send_command(sc, (uint8_t *)&cmd, sizeof(cmd)); 735 err = atu_send_command(sc, (uint8_t *)&cmd, sizeof(cmd));
736 if (err) 736 if (err)
737 return err; 737 return err;
738 err = atu_wait_completion(sc, CMD_STARTUP, NULL); 738 err = atu_wait_completion(sc, CMD_STARTUP, NULL);
739 if (err) 739 if (err)
740 return err; 740 return err;
741 741
742 /* Turn on radio now */ 742 /* Turn on radio now */
743 err = atu_switch_radio(sc, 1); 743 err = atu_switch_radio(sc, 1);
744 if (err) 744 if (err)
745 return err; 745 return err;
746 746
747 /* preamble type = short */ 747 /* preamble type = short */
748 err = atu_send_mib(sc, MIB_LOCAL__PREAMBLE, NR(PREAMBLE_SHORT)); 748 err = atu_send_mib(sc, MIB_LOCAL__PREAMBLE, NR(PREAMBLE_SHORT));
749 if (err) 749 if (err)
750 return err; 750 return err;
751 751
752 /* frag = 1536 */ 752 /* frag = 1536 */
753 err = atu_send_mib(sc, MIB_MAC__FRAG, NR(2346)); 753 err = atu_send_mib(sc, MIB_MAC__FRAG, NR(2346));
754 if (err) 754 if (err)
755 return err; 755 return err;
756 756
757 /* rts = 1536 */ 757 /* rts = 1536 */
758 err = atu_send_mib(sc, MIB_MAC__RTS, NR(2347)); 758 err = atu_send_mib(sc, MIB_MAC__RTS, NR(2347));
759 if (err) 759 if (err)
760 return err; 760 return err;
761 761
762 /* auto rate fallback = 1 */ 762 /* auto rate fallback = 1 */
763 err = atu_send_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, NR(1)); 763 err = atu_send_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, NR(1));
764 if (err) 764 if (err)
765 return err; 765 return err;
766 766
767 /* power mode = full on, no power saving */ 767 /* power mode = full on, no power saving */
768 err = atu_send_mib(sc, MIB_MAC_MGMT__POWER_MODE, 768 err = atu_send_mib(sc, MIB_MAC_MGMT__POWER_MODE,
769 NR(POWER_MODE_ACTIVE)); 769 NR(POWER_MODE_ACTIVE));
770 if (err) 770 if (err)
771 return err; 771 return err;
772 772
773 DPRINTFN(10, ("%s: completed initial config\n", 773 DPRINTFN(10, ("%s: completed initial config\n",
774 device_xname(sc->atu_dev))); 774 device_xname(sc->atu_dev)));
775 return 0; 775 return 0;
776} 776}
777 777
778static int 778static int
779atu_join(struct atu_softc *sc, struct ieee80211_node *node) 779atu_join(struct atu_softc *sc, struct ieee80211_node *node)
780{ 780{
781 struct atu_cmd_join join; 781 struct atu_cmd_join join;
782 uint8_t status = 0; /* XXX: GCC */ 782 uint8_t status = 0; /* XXX: GCC */
783 usbd_status err; 783 usbd_status err;
784 784
785 memset(&join, 0, sizeof(join)); 785 memset(&join, 0, sizeof(join));
786 786
787 join.Cmd = CMD_JOIN; 787 join.Cmd = CMD_JOIN;
788 join.Reserved = 0x00; 788 join.Reserved = 0x00;
789 USETW(join.Size, sizeof(join) - 4); 789 USETW(join.Size, sizeof(join) - 4);
790 790
791 DPRINTFN(15, ("%s: pre-join sc->atu_bssid=%s\n", 791 DPRINTFN(15, ("%s: pre-join sc->atu_bssid=%s\n",
792 device_xname(sc->atu_dev), ether_sprintf(sc->atu_bssid))); 792 device_xname(sc->atu_dev), ether_sprintf(sc->atu_bssid)));
793 DPRINTFN(15, ("%s: mode=%d\n", device_xname(sc->atu_dev), 793 DPRINTFN(15, ("%s: mode=%d\n", device_xname(sc->atu_dev),
794 sc->atu_mode)); 794 sc->atu_mode));
795 memcpy(join.bssid, node->ni_bssid, IEEE80211_ADDR_LEN); 795 memcpy(join.bssid, node->ni_bssid, IEEE80211_ADDR_LEN);
796 memset(join.essid, 0x00, 32); 796 memset(join.essid, 0x00, 32);
797 memcpy(join.essid, node->ni_essid, node->ni_esslen); 797 memcpy(join.essid, node->ni_essid, node->ni_esslen);
798 join.essid_size = node->ni_esslen; 798 join.essid_size = node->ni_esslen;
799 if (node->ni_capinfo & IEEE80211_CAPINFO_IBSS) 799 if (node->ni_capinfo & IEEE80211_CAPINFO_IBSS)
800 join.bss_type = AD_HOC_MODE; 800 join.bss_type = AD_HOC_MODE;
801 else 801 else
802 join.bss_type = INFRASTRUCTURE_MODE; 802 join.bss_type = INFRASTRUCTURE_MODE;
803 join.channel = ieee80211_chan2ieee(&sc->sc_ic, node->ni_chan); 803 join.channel = ieee80211_chan2ieee(&sc->sc_ic, node->ni_chan);
804 804
805 USETW(join.timeout, ATU_JOIN_TIMEOUT); 805 USETW(join.timeout, ATU_JOIN_TIMEOUT);
806 join.reserved = 0x00; 806 join.reserved = 0x00;
807 807
808 DPRINTFN(10, ("%s: trying to join BSSID=%s\n", 808 DPRINTFN(10, ("%s: trying to join BSSID=%s\n",
809 device_xname(sc->atu_dev), ether_sprintf(join.bssid))); 809 device_xname(sc->atu_dev), ether_sprintf(join.bssid)));
810 err = atu_send_command(sc, (uint8_t *)&join, sizeof(join)); 810 err = atu_send_command(sc, (uint8_t *)&join, sizeof(join));
811 if (err) { 811 if (err) {
812 DPRINTF(("%s: ERROR trying to join IBSS\n", 812 DPRINTF(("%s: ERROR trying to join IBSS\n",
813 device_xname(sc->atu_dev))); 813 device_xname(sc->atu_dev)));
814 return err; 814 return err;
815 } 815 }
816 err = atu_wait_completion(sc, CMD_JOIN, &status); 816 err = atu_wait_completion(sc, CMD_JOIN, &status);
817 if (err) { 817 if (err) {
818 DPRINTF(("%s: error joining BSS!\n", 818 DPRINTF(("%s: error joining BSS!\n",
819 device_xname(sc->atu_dev))); 819 device_xname(sc->atu_dev)));
820 return err; 820 return err;
821 } 821 }
822 if (status != STATUS_COMPLETE) { 822 if (status != STATUS_COMPLETE) {
823 DPRINTF(("%s: error joining... [status=%02x]\n", 823 DPRINTF(("%s: error joining... [status=%02x]\n",
824 device_xname(sc->atu_dev), status)); 824 device_xname(sc->atu_dev), status));
825 return status; 825 return status;
826 } else { 826 } else {
827 DPRINTFN(10, ("%s: joined BSS\n", device_xname(sc->atu_dev))); 827 DPRINTFN(10, ("%s: joined BSS\n", device_xname(sc->atu_dev)));
828 } 828 }
829 return err; 829 return err;
830} 830}
831 831
832/* 832/*
833 * Get the state of the DFU unit 833 * Get the state of the DFU unit
834 */ 834 */
835static int8_t 835static int8_t
836atu_get_dfu_state(struct atu_softc *sc) 836atu_get_dfu_state(struct atu_softc *sc)
837{ 837{
838 uint8_t state; 838 uint8_t state;
839 839
840 if (atu_usb_request(sc, DFU_GETSTATE, 0, 0, 1, &state)) 840 if (atu_usb_request(sc, DFU_GETSTATE, 0, 0, 1, &state))
841 return -1; 841 return -1;
842 return state; 842 return state;
843} 843}
844 844
845/* 845/*
846 * Get MAC opmode 846 * Get MAC opmode
847 */ 847 */
848static uint8_t 848static uint8_t
849atu_get_opmode(struct atu_softc *sc, uint8_t *mode) 849atu_get_opmode(struct atu_softc *sc, uint8_t *mode)
850{ 850{
851 851
852 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0001, 852 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0001,
853 0x0000, 1, mode); 853 0x0000, 1, mode);
854} 854}
855 855
856/* 856/*
857 * Upload the internal firmware into the device 857 * Upload the internal firmware into the device
858 */ 858 */
859static void 859static void
860atu_internal_firmware(device_t arg) 860atu_internal_firmware(device_t arg)
861{ 861{
862 struct atu_softc *sc = device_private(arg); 862 struct atu_softc *sc = device_private(arg);
863 u_char state, *ptr = NULL, *firm = NULL, status[6]; 863 u_char state, *ptr = NULL, *firm = NULL, status[6];
864 int block_size, block = 0, err, i; 864 int block_size, block = 0, err, i;
865 size_t bytes_left = 0; 865 size_t bytes_left = 0;
866 866
867 /* 867 /*
868 * Uploading firmware is done with the DFU (Device Firmware Upgrade) 868 * Uploading firmware is done with the DFU (Device Firmware Upgrade)
869 * interface. See "Universal Serial Bus - Device Class Specification 869 * interface. See "Universal Serial Bus - Device Class Specification
870 * for Device Firmware Upgrade" pdf for details of the protocol. 870 * for Device Firmware Upgrade" pdf for details of the protocol.
871 * Maybe this could be moved to a separate 'firmware driver' once more 871 * Maybe this could be moved to a separate 'firmware driver' once more
872 * device drivers need it... For now we'll just do it here. 872 * device drivers need it... For now we'll just do it here.
873 * 873 *
874 * Just for your information, the Atmel's DFU descriptor looks like 874 * Just for your information, the Atmel's DFU descriptor looks like
875 * this: 875 * this:
876 * 876 *
877 * 07 size 877 * 07 size
878 * 21 type 878 * 21 type
879 * 01 capabilities : only firmware download, need reset 879 * 01 capabilities : only firmware download, need reset
880 * after download 880 * after download
881 * 13 05 detach timeout : max 1299ms between DFU_DETACH and 881 * 13 05 detach timeout : max 1299ms between DFU_DETACH and
882 * reset 882 * reset
883 * 00 04 max bytes of firmware per transaction : 1024 883 * 00 04 max bytes of firmware per transaction : 1024
884 */ 884 */
885 885
886 /* Choose the right firmware for the device */ 886 /* Choose the right firmware for the device */
887 for (i = 0; i < __arraycount(atu_radfirm); i++) 887 for (i = 0; i < __arraycount(atu_radfirm); i++)
888 if (sc->atu_radio == atu_radfirm[i].atur_type) { 888 if (sc->atu_radio == atu_radfirm[i].atur_type) {
889 firm = atu_radfirm[i].atur_internal; 889 firm = atu_radfirm[i].atur_internal;
890 bytes_left = atu_radfirm[i].atur_internal_sz; 890 bytes_left = atu_radfirm[i].atur_internal_sz;
891 } 891 }
892 892
893 if (firm == NULL) { 893 if (firm == NULL) {
894 aprint_error_dev(arg, "no firmware found\n"); 894 aprint_error_dev(arg, "no firmware found\n");
895 return; 895 return;
896 } 896 }
897 897
898 ptr = firm; 898 ptr = firm;
899 state = atu_get_dfu_state(sc); 899 state = atu_get_dfu_state(sc);
900 900
901 while (block >= 0 && state > 0) { 901 while (block >= 0 && state > 0) {
902 switch (state) { 902 switch (state) {
903 case DFUState_DnLoadSync: 903 case DFUState_DnLoadSync:
904 /* get DFU status */ 904 /* get DFU status */
905 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0 , 6, 905 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0 , 6,
906 status); 906 status);
907 if (err) { 907 if (err) {
908 DPRINTF(("%s: dfu_getstatus failed!\n", 908 DPRINTF(("%s: dfu_getstatus failed!\n",
909 device_xname(sc->atu_dev))); 909 device_xname(sc->atu_dev)));
910 return; 910 return;
911 } 911 }
912 /* success means state => DnLoadIdle */ 912 /* success means state => DnLoadIdle */
913 state = DFUState_DnLoadIdle; 913 state = DFUState_DnLoadIdle;
914 continue; 914 continue;
915 break; 915 break;
916 916
917 case DFUState_DFUIdle: 917 case DFUState_DFUIdle:
918 case DFUState_DnLoadIdle: 918 case DFUState_DnLoadIdle:
919 if (bytes_left>=DFU_MaxBlockSize) 919 if (bytes_left>=DFU_MaxBlockSize)
920 block_size = DFU_MaxBlockSize; 920 block_size = DFU_MaxBlockSize;
921 else 921 else
922 block_size = bytes_left; 922 block_size = bytes_left;
923 DPRINTFN(15, ("%s: firmware block %d\n", 923 DPRINTFN(15, ("%s: firmware block %d\n",
924 device_xname(sc->atu_dev), block)); 924 device_xname(sc->atu_dev), block));
925 925
926 err = atu_usb_request(sc, DFU_DNLOAD, block++, 0, 926 err = atu_usb_request(sc, DFU_DNLOAD, block++, 0,
927 block_size, ptr); 927 block_size, ptr);
928 if (err) { 928 if (err) {
929 DPRINTF(("%s: dfu_dnload failed\n", 929 DPRINTF(("%s: dfu_dnload failed\n",
930 device_xname(sc->atu_dev))); 930 device_xname(sc->atu_dev)));
931 return; 931 return;
932 } 932 }
933 933
934 ptr += block_size; 934 ptr += block_size;
935 bytes_left -= block_size; 935 bytes_left -= block_size;
936 if (block_size == 0) 936 if (block_size == 0)
937 block = -1; 937 block = -1;
938 break; 938 break;
939 939
940 default: 940 default:
941 usbd_delay_ms(sc->atu_udev, 100); 941 usbd_delay_ms(sc->atu_udev, 100);
942 DPRINTFN(20, ("%s: sleeping for a while\n", 942 DPRINTFN(20, ("%s: sleeping for a while\n",
943 device_xname(sc->atu_dev))); 943 device_xname(sc->atu_dev)));
944 break; 944 break;
945 } 945 }
946 946
947 state = atu_get_dfu_state(sc); 947 state = atu_get_dfu_state(sc);
948 } 948 }
949 949
950 if (state != DFUState_ManifestSync) { 950 if (state != DFUState_ManifestSync) {
951 DPRINTF(("%s: state != manifestsync... eek!\n", 951 DPRINTF(("%s: state != manifestsync... eek!\n",
952 device_xname(sc->atu_dev))); 952 device_xname(sc->atu_dev)));
953 } 953 }
954 954
955 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0, 6, status); 955 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0, 6, status);
956 if (err) { 956 if (err) {
957 DPRINTF(("%s: dfu_getstatus failed!\n", 957 DPRINTF(("%s: dfu_getstatus failed!\n",
958 device_xname(sc->atu_dev))); 958 device_xname(sc->atu_dev)));
959 return; 959 return;
960 } 960 }
961 961
962 DPRINTFN(15, ("%s: sending remap\n", device_xname(sc->atu_dev))); 962 DPRINTFN(15, ("%s: sending remap\n", device_xname(sc->atu_dev)));
963 err = atu_usb_request(sc, DFU_REMAP, 0, 0, 0, NULL); 963 err = atu_usb_request(sc, DFU_REMAP, 0, 0, 0, NULL);
964 if ((err) && !(sc->atu_quirk & ATU_QUIRK_NO_REMAP)) { 964 if ((err) && !(sc->atu_quirk & ATU_QUIRK_NO_REMAP)) {
965 DPRINTF(("%s: remap failed!\n", device_xname(sc->atu_dev))); 965 DPRINTF(("%s: remap failed!\n", device_xname(sc->atu_dev)));
966 return; 966 return;
967 } 967 }
968 968
969 /* after a lot of trying and measuring I found out the device needs 969 /* after a lot of trying and measuring I found out the device needs
970 * about 56 miliseconds after sending the remap command before 970 * about 56 miliseconds after sending the remap command before
971 * it's ready to communicate again. So we'll wait just a little bit 971 * it's ready to communicate again. So we'll wait just a little bit
972 * longer than that to be sure... 972 * longer than that to be sure...
973 */ 973 */
974 usbd_delay_ms(sc->atu_udev, 56+100); 974 usbd_delay_ms(sc->atu_udev, 56+100);
975 975
976 aprint_error_dev(arg, "reattaching after firmware upload\n"); 976 aprint_error_dev(arg, "reattaching after firmware upload\n");
977 usb_needs_reattach(sc->atu_udev); 977 usb_needs_reattach(sc->atu_udev);
978} 978}
979 979
980static void 980static void
981atu_external_firmware(device_t arg) 981atu_external_firmware(device_t arg)
982{ 982{
983 struct atu_softc *sc = device_private(arg); 983 struct atu_softc *sc = device_private(arg);
984 u_char *ptr = NULL, *firm = NULL; 984 u_char *ptr = NULL, *firm = NULL;
985 int block_size, block = 0, err, i; 985 int block_size, block = 0, err, i;
986 size_t bytes_left = 0; 986 size_t bytes_left = 0;
987 987
988 for (i = 0; i < __arraycount(atu_radfirm); i++) 988 for (i = 0; i < __arraycount(atu_radfirm); i++)
989 if (sc->atu_radio == atu_radfirm[i].atur_type) { 989 if (sc->atu_radio == atu_radfirm[i].atur_type) {
990 firm = atu_radfirm[i].atur_external; 990 firm = atu_radfirm[i].atur_external;
991 bytes_left = atu_radfirm[i].atur_external_sz; 991 bytes_left = atu_radfirm[i].atur_external_sz;
992 } 992 }
993 993
994 if (firm == NULL) { 994 if (firm == NULL) {
995 aprint_error_dev(arg, "no firmware found\n"); 995 aprint_error_dev(arg, "no firmware found\n");
996 return; 996 return;
997 } 997 }
998 ptr = firm; 998 ptr = firm;
999 999
1000 while (bytes_left) { 1000 while (bytes_left) {
1001 if (bytes_left > 1024) 1001 if (bytes_left > 1024)
1002 block_size = 1024; 1002 block_size = 1024;
1003 else 1003 else
1004 block_size = bytes_left; 1004 block_size = bytes_left;
1005 1005
1006 DPRINTFN(15, ("%s: block:%d size:%d\n", 1006 DPRINTFN(15, ("%s: block:%d size:%d\n",
1007 device_xname(sc->atu_dev), block, block_size)); 1007 device_xname(sc->atu_dev), block, block_size));
1008 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 1008 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e,
1009 0x0802, block, block_size, ptr); 1009 0x0802, block, block_size, ptr);
1010 if (err) { 1010 if (err) {
1011 DPRINTF(("%s: could not load external firmware " 1011 DPRINTF(("%s: could not load external firmware "
1012 "block\n", device_xname(sc->atu_dev))); 1012 "block\n", device_xname(sc->atu_dev)));
1013 return; 1013 return;
1014 } 1014 }
1015 1015
1016 ptr += block_size; 1016 ptr += block_size;
1017 block++; 1017 block++;
1018 bytes_left -= block_size; 1018 bytes_left -= block_size;
1019 } 1019 }
1020 1020
1021 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0802, 1021 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0802,
1022 block, 0, NULL); 1022 block, 0, NULL);
1023 if (err) { 1023 if (err) {
1024 DPRINTF(("%s: could not load last zero-length firmware " 1024 DPRINTF(("%s: could not load last zero-length firmware "
1025 "block\n", device_xname(sc->atu_dev))); 1025 "block\n", device_xname(sc->atu_dev)));
1026 return; 1026 return;
1027 } 1027 }
1028 1028
1029 /* 1029 /*
1030 * The SMC2662w V.4 seems to require some time to do its thing with 1030 * The SMC2662w V.4 seems to require some time to do its thing with
1031 * the external firmware... 20 ms isn't enough, but 21 ms works 100 1031 * the external firmware... 20 ms isn't enough, but 21 ms works 100
1032 * times out of 100 tries. We'll wait a bit longer just to be sure 1032 * times out of 100 tries. We'll wait a bit longer just to be sure
1033 */ 1033 */
1034 if (sc->atu_quirk & ATU_QUIRK_FW_DELAY) 1034 if (sc->atu_quirk & ATU_QUIRK_FW_DELAY)
1035 usbd_delay_ms(sc->atu_udev, 21 + 100); 1035 usbd_delay_ms(sc->atu_udev, 21 + 100);
1036 1036
1037 DPRINTFN(10, ("%s: external firmware upload done\n", 1037 DPRINTFN(10, ("%s: external firmware upload done\n",
1038 device_xname(sc->atu_dev))); 1038 device_xname(sc->atu_dev)));
1039 /* complete configuration after the firmwares have been uploaded */ 1039 /* complete configuration after the firmwares have been uploaded */
1040 atu_complete_attach(sc); 1040 atu_complete_attach(sc);
1041} 1041}
1042 1042
1043static int 1043static int
1044atu_get_card_config(struct atu_softc *sc) 1044atu_get_card_config(struct atu_softc *sc)
1045{ 1045{
1046 struct ieee80211com *ic = &sc->sc_ic; 1046 struct ieee80211com *ic = &sc->sc_ic;
1047 struct atu_rfmd_conf rfmd_conf; 1047 struct atu_rfmd_conf rfmd_conf;
1048 struct atu_intersil_conf intersil_conf; 1048 struct atu_intersil_conf intersil_conf;
1049 int err; 1049 int err;
1050 1050
@@ -1142,1139 +1142,1133 @@ atu_media_status(struct ifnet *ifp, stru @@ -1142,1139 +1142,1133 @@ atu_media_status(struct ifnet *ifp, stru
1142 1142
1143static void 1143static void
1144atu_task(void *arg) 1144atu_task(void *arg)
1145{ 1145{
1146 struct atu_softc *sc = (struct atu_softc *)arg; 1146 struct atu_softc *sc = (struct atu_softc *)arg;
1147 struct ieee80211com *ic = &sc->sc_ic; 1147 struct ieee80211com *ic = &sc->sc_ic;
1148 usbd_status err; 1148 usbd_status err;
1149 int s; 1149 int s;
1150 1150
1151 DPRINTFN(10, ("%s: atu_task\n", device_xname(sc->atu_dev))); 1151 DPRINTFN(10, ("%s: atu_task\n", device_xname(sc->atu_dev)));
1152 1152
1153 if (sc->sc_state != ATU_S_OK) 1153 if (sc->sc_state != ATU_S_OK)
1154 return; 1154 return;
1155 1155
1156 switch (sc->sc_cmd) { 1156 switch (sc->sc_cmd) {
1157 case ATU_C_SCAN: 1157 case ATU_C_SCAN:
1158 1158
1159 err = atu_start_scan(sc); 1159 err = atu_start_scan(sc);
1160 if (err) { 1160 if (err) {
1161 DPRINTFN(1, ("%s: atu_task: couldn't start scan!\n", 1161 DPRINTFN(1, ("%s: atu_task: couldn't start scan!\n",
1162 device_xname(sc->atu_dev))); 1162 device_xname(sc->atu_dev)));
1163 return; 1163 return;
1164 } 1164 }
1165 1165
1166 err = atu_wait_completion(sc, CMD_START_SCAN, NULL); 1166 err = atu_wait_completion(sc, CMD_START_SCAN, NULL);
1167 if (err) { 1167 if (err) {
1168 DPRINTF(("%s: atu_task: error waiting for scan\n", 1168 DPRINTF(("%s: atu_task: error waiting for scan\n",
1169 device_xname(sc->atu_dev))); 1169 device_xname(sc->atu_dev)));
1170 return; 1170 return;
1171 } 1171 }
1172 1172
1173 DPRINTF(("%s: ==========================> END OF SCAN!\n", 1173 DPRINTF(("%s: ==========================> END OF SCAN!\n",
1174 device_xname(sc->atu_dev))); 1174 device_xname(sc->atu_dev)));
1175 1175
1176 s = splnet(); 1176 s = splnet();
1177 ieee80211_next_scan(ic); 1177 ieee80211_next_scan(ic);
1178 splx(s); 1178 splx(s);
1179 1179
1180 DPRINTF(("%s: ----------------------======> END OF SCAN2!\n", 1180 DPRINTF(("%s: ----------------------======> END OF SCAN2!\n",
1181 device_xname(sc->atu_dev))); 1181 device_xname(sc->atu_dev)));
1182 break; 1182 break;
1183 1183
1184 case ATU_C_JOIN: 1184 case ATU_C_JOIN:
1185 atu_join(sc, ic->ic_bss); 1185 atu_join(sc, ic->ic_bss);
1186 } 1186 }
1187} 1187}
1188 1188
1189static int 1189static int
1190atu_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1190atu_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1191{ 1191{
1192 struct ifnet *ifp = ic->ic_ifp; 1192 struct ifnet *ifp = ic->ic_ifp;
1193 struct atu_softc *sc = ifp->if_softc; 1193 struct atu_softc *sc = ifp->if_softc;
1194 enum ieee80211_state ostate = ic->ic_state; 1194 enum ieee80211_state ostate = ic->ic_state;
1195 1195
1196 DPRINTFN(10, ("%s: atu_newstate: %s -> %s\n", device_xname(sc->atu_dev), 1196 DPRINTFN(10, ("%s: atu_newstate: %s -> %s\n", device_xname(sc->atu_dev),
1197 ieee80211_state_name[ostate], ieee80211_state_name[nstate])); 1197 ieee80211_state_name[ostate], ieee80211_state_name[nstate]));
1198 1198
1199 switch (nstate) { 1199 switch (nstate) {
1200 case IEEE80211_S_SCAN: 1200 case IEEE80211_S_SCAN:
1201 memcpy(ic->ic_chan_scan, ic->ic_chan_active, 1201 memcpy(ic->ic_chan_scan, ic->ic_chan_active,
1202 sizeof(ic->ic_chan_active)); 1202 sizeof(ic->ic_chan_active));
1203 ieee80211_node_table_reset(&ic->ic_scan); 1203 ieee80211_node_table_reset(&ic->ic_scan);
1204 1204
1205 /* tell the event thread that we want a scan */ 1205 /* tell the event thread that we want a scan */
1206 sc->sc_cmd = ATU_C_SCAN; 1206 sc->sc_cmd = ATU_C_SCAN;
1207 usb_add_task(sc->atu_udev, &sc->sc_task, USB_TASKQ_DRIVER); 1207 usb_add_task(sc->atu_udev, &sc->sc_task, USB_TASKQ_DRIVER);
1208 1208
1209 /* handle this ourselves */ 1209 /* handle this ourselves */
1210 ic->ic_state = nstate; 1210 ic->ic_state = nstate;
1211 return 0; 1211 return 0;
1212 1212
1213 case IEEE80211_S_AUTH: 1213 case IEEE80211_S_AUTH:
1214 case IEEE80211_S_RUN: 1214 case IEEE80211_S_RUN:
1215 if (ostate == IEEE80211_S_SCAN) { 1215 if (ostate == IEEE80211_S_SCAN) {
1216 sc->sc_cmd = ATU_C_JOIN; 1216 sc->sc_cmd = ATU_C_JOIN;
1217 usb_add_task(sc->atu_udev, &sc->sc_task, 1217 usb_add_task(sc->atu_udev, &sc->sc_task,
1218 USB_TASKQ_DRIVER); 1218 USB_TASKQ_DRIVER);
1219 } 1219 }
1220 break; 1220 break;
1221 default: 1221 default:
1222 /* nothing to do */ 1222 /* nothing to do */
1223 break; 1223 break;
1224 } 1224 }
1225 1225
1226 return (*sc->sc_newstate)(ic, nstate, arg); 1226 return (*sc->sc_newstate)(ic, nstate, arg);
1227} 1227}
1228 1228
1229/* 1229/*
1230 * Attach the interface. Allocate softc structures, do 1230 * Attach the interface. Allocate softc structures, do
1231 * setup and ethernet/BPF attach. 1231 * setup and ethernet/BPF attach.
1232 */ 1232 */
1233static void 1233static void
1234atu_attach(device_t parent, device_t self, void *aux) 1234atu_attach(device_t parent, device_t self, void *aux)
1235{ 1235{
1236 struct atu_softc *sc = device_private(self); 1236 struct atu_softc *sc = device_private(self);
1237 struct usb_attach_arg *uaa = aux; 1237 struct usb_attach_arg *uaa = aux;
1238 char *devinfop; 1238 char *devinfop;
1239 usbd_status err; 1239 usbd_status err;
1240 struct usbd_device *dev = uaa->uaa_device; 1240 struct usbd_device *dev = uaa->uaa_device;
1241 uint8_t mode, channel; 1241 uint8_t mode, channel;
1242 int i; 1242 int i;
1243 1243
1244 sc->atu_dev = self; 1244 sc->atu_dev = self;
1245 sc->sc_state = ATU_S_UNCONFIG; 1245 sc->sc_state = ATU_S_UNCONFIG;
1246 1246
1247 aprint_naive("\n"); 1247 aprint_naive("\n");
1248 aprint_normal("\n"); 1248 aprint_normal("\n");
1249 1249
1250 devinfop = usbd_devinfo_alloc(dev, 0); 1250 devinfop = usbd_devinfo_alloc(dev, 0);
1251 aprint_normal_dev(self, "%s\n", devinfop); 1251 aprint_normal_dev(self, "%s\n", devinfop);
1252 usbd_devinfo_free(devinfop); 1252 usbd_devinfo_free(devinfop);
1253 1253
1254 err = usbd_set_config_no(dev, ATU_CONFIG_NO, 1); 1254 err = usbd_set_config_no(dev, ATU_CONFIG_NO, 1);
1255 if (err) { 1255 if (err) {
1256 aprint_error_dev(self, "failed to set configuration" 1256 aprint_error_dev(self, "failed to set configuration"
1257 ", err=%s\n", usbd_errstr(err)); 1257 ", err=%s\n", usbd_errstr(err));
1258 return; 1258 return;
1259 } 1259 }
1260 1260
1261 err = usbd_device2interface_handle(dev, ATU_IFACE_IDX, &sc->atu_iface); 1261 err = usbd_device2interface_handle(dev, ATU_IFACE_IDX, &sc->atu_iface);
1262 if (err) { 1262 if (err) {
1263 aprint_error_dev(self, "getting interface handle failed\n"); 1263 aprint_error_dev(self, "getting interface handle failed\n");
1264 return; 1264 return;
1265 } 1265 }
1266 1266
1267 sc->atu_unit = device_unit(self); 1267 sc->atu_unit = device_unit(self);
1268 sc->atu_udev = dev; 1268 sc->atu_udev = dev;
1269 1269
1270 /* 1270 /*
1271 * look up the radio_type for the device 1271 * look up the radio_type for the device
1272 * basically does the same as atu_match 1272 * basically does the same as atu_match
1273 */ 1273 */
1274 for (i = 0; i < __arraycount(atu_devs); i++) { 1274 for (i = 0; i < __arraycount(atu_devs); i++) {
1275 const struct atu_type *t = &atu_devs[i]; 1275 const struct atu_type *t = &atu_devs[i];
1276 1276
1277 if (uaa->uaa_vendor == t->atu_vid && 1277 if (uaa->uaa_vendor == t->atu_vid &&
1278 uaa->uaa_product == t->atu_pid) { 1278 uaa->uaa_product == t->atu_pid) {
1279 sc->atu_radio = t->atu_radio; 1279 sc->atu_radio = t->atu_radio;
1280 sc->atu_quirk = t->atu_quirk; 1280 sc->atu_quirk = t->atu_quirk;
1281 } 1281 }
1282 } 1282 }
1283 1283
1284 /* 1284 /*
1285 * Check in the interface descriptor if we're in DFU mode 1285 * Check in the interface descriptor if we're in DFU mode
1286 * If we're in DFU mode, we upload the external firmware 1286 * If we're in DFU mode, we upload the external firmware
1287 * If we're not, the PC must have rebooted without power-cycling 1287 * If we're not, the PC must have rebooted without power-cycling
1288 * the device.. I've tried this out, a reboot only requeres the 1288 * the device.. I've tried this out, a reboot only requeres the
1289 * external firmware to be reloaded :) 1289 * external firmware to be reloaded :)
1290 * 1290 *
1291 * Hmm. The at76c505a doesn't report a DFU descriptor when it's 1291 * Hmm. The at76c505a doesn't report a DFU descriptor when it's
1292 * in DFU mode... Let's just try to get the opmode 1292 * in DFU mode... Let's just try to get the opmode
1293 */ 1293 */
1294 err = atu_get_opmode(sc, &mode); 1294 err = atu_get_opmode(sc, &mode);
1295 DPRINTFN(20, ("%s: opmode: %d\n", device_xname(sc->atu_dev), mode)); 1295 DPRINTFN(20, ("%s: opmode: %d\n", device_xname(sc->atu_dev), mode));
1296 if (err || (mode != MODE_NETCARD && mode != MODE_NOFLASHNETCARD)) { 1296 if (err || (mode != MODE_NETCARD && mode != MODE_NOFLASHNETCARD)) {
1297 DPRINTF(("%s: starting internal firmware download\n", 1297 DPRINTF(("%s: starting internal firmware download\n",
1298 device_xname(sc->atu_dev))); 1298 device_xname(sc->atu_dev)));
1299 1299
1300 atu_internal_firmware(sc->atu_dev); 1300 atu_internal_firmware(sc->atu_dev);
1301 /* 1301 /*
1302 * atu_internal_firmware will cause a reset of the device 1302 * atu_internal_firmware will cause a reset of the device
1303 * so we don't want to do any more configuration after this 1303 * so we don't want to do any more configuration after this
1304 * point. 1304 * point.
1305 */ 1305 */
1306 return; 1306 return;
1307 } 1307 }
1308 1308
1309 if (mode != MODE_NETCARD) { 1309 if (mode != MODE_NETCARD) {
1310 DPRINTFN(15, ("%s: device needs external firmware\n", 1310 DPRINTFN(15, ("%s: device needs external firmware\n",
1311 device_xname(sc->atu_dev))); 1311 device_xname(sc->atu_dev)));
1312 1312
1313 if (mode != MODE_NOFLASHNETCARD) { 1313 if (mode != MODE_NOFLASHNETCARD) {
1314 DPRINTF(("%s: unexpected opmode=%d\n", 1314 DPRINTF(("%s: unexpected opmode=%d\n",
1315 device_xname(sc->atu_dev), mode)); 1315 device_xname(sc->atu_dev), mode));
1316 } 1316 }
1317 1317
1318 /* 1318 /*
1319 * There is no difference in opmode before and after external 1319 * There is no difference in opmode before and after external
1320 * firmware upload with the SMC2662 V.4 . So instead we'll try 1320 * firmware upload with the SMC2662 V.4 . So instead we'll try
1321 * to read the channel number. If we succeed, external 1321 * to read the channel number. If we succeed, external
1322 * firmwaremust have been already uploaded... 1322 * firmwaremust have been already uploaded...
1323 */ 1323 */
1324 if (sc->atu_radio != RadioIntersil) { 1324 if (sc->atu_radio != RadioIntersil) {
1325 err = atu_get_mib(sc, MIB_PHY__CHANNEL, &channel); 1325 err = atu_get_mib(sc, MIB_PHY__CHANNEL, &channel);
1326 if (!err) { 1326 if (!err) {
1327 DPRINTF(("%s: external firmware has already" 1327 DPRINTF(("%s: external firmware has already"
1328 " been downloaded\n", 1328 " been downloaded\n",
1329 device_xname(sc->atu_dev))); 1329 device_xname(sc->atu_dev)));
1330 atu_complete_attach(sc); 1330 atu_complete_attach(sc);
1331 return; 1331 return;
1332 } 1332 }
1333 } 1333 }
1334 1334
1335 atu_external_firmware(sc->atu_dev); 1335 atu_external_firmware(sc->atu_dev);
1336 1336
1337 /* 1337 /*
1338 * atu_external_firmware will call atu_complete_attach after 1338 * atu_external_firmware will call atu_complete_attach after
1339 * it's finished so we can just return. 1339 * it's finished so we can just return.
1340 */ 1340 */
1341 } else { 1341 } else {
1342 /* all the firmwares are in place, so complete the attach */ 1342 /* all the firmwares are in place, so complete the attach */
1343 atu_complete_attach(sc); 1343 atu_complete_attach(sc);
1344 } 1344 }
1345 1345
1346 return; 1346 return;
1347} 1347}
1348 1348
1349static void 1349static void
1350atu_complete_attach(struct atu_softc *sc) 1350atu_complete_attach(struct atu_softc *sc)
1351{ 1351{
1352 struct ieee80211com *ic = &sc->sc_ic; 1352 struct ieee80211com *ic = &sc->sc_ic;
1353 struct ifnet *ifp = &sc->sc_if; 1353 struct ifnet *ifp = &sc->sc_if;
1354 usb_interface_descriptor_t *id; 1354 usb_interface_descriptor_t *id;
1355 usb_endpoint_descriptor_t *ed; 1355 usb_endpoint_descriptor_t *ed;
1356 usbd_status err; 1356 usbd_status err;
1357 int i; 1357 int i;
1358#ifdef ATU_DEBUG 1358#ifdef ATU_DEBUG
1359 struct atu_fw fw; 1359 struct atu_fw fw;
1360#endif 1360#endif
1361 1361
1362 id = usbd_get_interface_descriptor(sc->atu_iface); 1362 id = usbd_get_interface_descriptor(sc->atu_iface);
1363 1363
1364 /* Find endpoints. */ 1364 /* Find endpoints. */
1365 for (i = 0; i < id->bNumEndpoints; i++) { 1365 for (i = 0; i < id->bNumEndpoints; i++) {
1366 ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i); 1366 ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i);
1367 if (!ed) { 1367 if (!ed) {
1368 DPRINTF(("%s: num_endp:%d\n", device_xname(sc->atu_dev), 1368 DPRINTF(("%s: num_endp:%d\n", device_xname(sc->atu_dev),
1369 sc->atu_iface->ui_idesc->bNumEndpoints)); 1369 sc->atu_iface->ui_idesc->bNumEndpoints));
1370 DPRINTF(("%s: couldn't get ep %d\n", 1370 DPRINTF(("%s: couldn't get ep %d\n",
1371 device_xname(sc->atu_dev), i)); 1371 device_xname(sc->atu_dev), i));
1372 return; 1372 return;
1373 } 1373 }
1374 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 1374 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1375 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1375 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1376 sc->atu_ed[ATU_ENDPT_RX] = ed->bEndpointAddress; 1376 sc->atu_ed[ATU_ENDPT_RX] = ed->bEndpointAddress;
1377 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 1377 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
1378 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1378 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1379 sc->atu_ed[ATU_ENDPT_TX] = ed->bEndpointAddress; 1379 sc->atu_ed[ATU_ENDPT_TX] = ed->bEndpointAddress;
1380 } 1380 }
1381 } 1381 }
1382 1382
1383 /* read device config & get MAC address */ 1383 /* read device config & get MAC address */
1384 err = atu_get_card_config(sc); 1384 err = atu_get_card_config(sc);
1385 if (err) { 1385 if (err) {
1386 aprint_error("\n%s: could not get card cfg!\n", 1386 aprint_error("\n%s: could not get card cfg!\n",
1387 device_xname(sc->atu_dev)); 1387 device_xname(sc->atu_dev));
1388 return; 1388 return;
1389 } 1389 }
1390 1390
1391#ifdef ATU_DEBUG 1391#ifdef ATU_DEBUG
1392 /* DEBUG : try to get firmware version */ 1392 /* DEBUG : try to get firmware version */
1393 err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0, (uint8_t *)&fw); 1393 err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0, (uint8_t *)&fw);
1394 if (!err) { 1394 if (!err) {
1395 DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d " 1395 DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d "
1396 "build:%d\n", device_xname(sc->atu_dev), fw.major, 1396 "build:%d\n", device_xname(sc->atu_dev), fw.major,
1397 fw.minor, fw.patch, fw.build)); 1397 fw.minor, fw.patch, fw.build));
1398 } else { 1398 } else {
1399 DPRINTF(("%s: get firmware version failed\n", 1399 DPRINTF(("%s: get firmware version failed\n",
1400 device_xname(sc->atu_dev))); 1400 device_xname(sc->atu_dev)));
1401 } 1401 }
1402#endif /* ATU_DEBUG */ 1402#endif /* ATU_DEBUG */
1403 1403
1404 /* Show the world our MAC address */ 1404 /* Show the world our MAC address */
1405 aprint_normal_dev(sc->atu_dev, "MAC address %s\n", 1405 aprint_normal_dev(sc->atu_dev, "MAC address %s\n",
1406 ether_sprintf(ic->ic_myaddr)); 1406 ether_sprintf(ic->ic_myaddr));
1407 1407
1408 sc->atu_cdata.atu_tx_inuse = 0; 1408 sc->atu_cdata.atu_tx_inuse = 0;
1409 sc->atu_encrypt = ATU_WEP_OFF; 1409 sc->atu_encrypt = ATU_WEP_OFF;
1410 sc->atu_wepkeylen = ATU_WEP_104BITS; 1410 sc->atu_wepkeylen = ATU_WEP_104BITS;
1411 sc->atu_wepkey = 0; 1411 sc->atu_wepkey = 0;
1412 1412
1413 memset(sc->atu_bssid, 0, ETHER_ADDR_LEN); 1413 memset(sc->atu_bssid, 0, ETHER_ADDR_LEN);
1414 sc->atu_channel = ATU_DEFAULT_CHANNEL; 1414 sc->atu_channel = ATU_DEFAULT_CHANNEL;
1415 sc->atu_desired_channel = IEEE80211_CHAN_ANY; 1415 sc->atu_desired_channel = IEEE80211_CHAN_ANY;
1416 sc->atu_mode = INFRASTRUCTURE_MODE; 1416 sc->atu_mode = INFRASTRUCTURE_MODE;
1417 1417
1418 ic->ic_ifp = ifp; 1418 ic->ic_ifp = ifp;
1419 ic->ic_phytype = IEEE80211_T_DS; 1419 ic->ic_phytype = IEEE80211_T_DS;
1420 ic->ic_opmode = IEEE80211_M_STA; 1420 ic->ic_opmode = IEEE80211_M_STA;
1421 ic->ic_state = IEEE80211_S_INIT; 1421 ic->ic_state = IEEE80211_S_INIT;
1422#ifdef FIXME 1422#ifdef FIXME
1423 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP | IEEE80211_C_SCANALL; 1423 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP | IEEE80211_C_SCANALL;
1424#else 1424#else
1425 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP; 1425 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP;
1426#endif 1426#endif
1427 1427
1428 i = 0; 1428 i = 0;
1429 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 1429 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
1430 1430
1431 for (i = 1; i <= 14; i++) { 1431 for (i = 1; i <= 14; i++) {
1432 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B | 1432 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B |
1433 IEEE80211_CHAN_PASSIVE; 1433 IEEE80211_CHAN_PASSIVE;
1434 ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i, 1434 ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i,
1435 ic->ic_channels[i].ic_flags); 1435 ic->ic_channels[i].ic_flags);
1436 } 1436 }
1437 1437
1438 ic->ic_ibss_chan = &ic->ic_channels[0]; 1438 ic->ic_ibss_chan = &ic->ic_channels[0];
1439 1439
1440 ifp->if_softc = sc; 1440 ifp->if_softc = sc;
1441 memcpy(ifp->if_xname, device_xname(sc->atu_dev), IFNAMSIZ); 1441 memcpy(ifp->if_xname, device_xname(sc->atu_dev), IFNAMSIZ);
1442 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1442 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1443 ifp->if_init = atu_init; 1443 ifp->if_init = atu_init;
1444 ifp->if_stop = atu_stop; 1444 ifp->if_stop = atu_stop;
1445 ifp->if_start = atu_start; 1445 ifp->if_start = atu_start;
1446 ifp->if_ioctl = atu_ioctl; 1446 ifp->if_ioctl = atu_ioctl;
1447 ifp->if_watchdog = atu_watchdog; 1447 ifp->if_watchdog = atu_watchdog;
1448 ifp->if_mtu = ATU_DEFAULT_MTU; 1448 ifp->if_mtu = ATU_DEFAULT_MTU;
1449 IFQ_SET_READY(&ifp->if_snd); 1449 IFQ_SET_READY(&ifp->if_snd);
1450 1450
1451 /* Call MI attach routine. */ 1451 /* Call MI attach routine. */
1452 if_attach(ifp); 1452 if_attach(ifp);
1453 ieee80211_ifattach(ic); 1453 ieee80211_ifattach(ic);
1454 1454
1455 sc->sc_newstate = ic->ic_newstate; 1455 sc->sc_newstate = ic->ic_newstate;
1456 ic->ic_newstate = atu_newstate; 1456 ic->ic_newstate = atu_newstate;
1457 1457
1458 /* setup ifmedia interface */ 1458 /* setup ifmedia interface */
1459 ieee80211_media_init(ic, atu_media_change, atu_media_status); 1459 ieee80211_media_init(ic, atu_media_change, atu_media_status);
1460 1460
1461 usb_init_task(&sc->sc_task, atu_task, sc, 0); 1461 usb_init_task(&sc->sc_task, atu_task, sc, 0);
1462 1462
1463 sc->sc_state = ATU_S_OK; 1463 sc->sc_state = ATU_S_OK;
1464} 1464}
1465 1465
1466static int 1466static int
1467atu_detach(device_t self, int flags) 1467atu_detach(device_t self, int flags)
1468{ 1468{
1469 struct atu_softc *sc = device_private(self); 1469 struct atu_softc *sc = device_private(self);
1470 struct ifnet *ifp = &sc->sc_if; 1470 struct ifnet *ifp = &sc->sc_if;
1471 1471
1472 DPRINTFN(10, ("%s: atu_detach state=%d\n", device_xname(sc->atu_dev), 1472 DPRINTFN(10, ("%s: atu_detach state=%d\n", device_xname(sc->atu_dev),
1473 sc->sc_state)); 1473 sc->sc_state));
1474 1474
1475 if (sc->sc_state != ATU_S_UNCONFIG) { 1475 if (sc->sc_state != ATU_S_UNCONFIG) {
1476 atu_stop(ifp, 1); 1476 atu_stop(ifp, 1);
1477 1477
1478 ieee80211_ifdetach(&sc->sc_ic); 1478 ieee80211_ifdetach(&sc->sc_ic);
1479 if_detach(ifp); 1479 if_detach(ifp);
1480 } 1480 }
1481 1481
1482 return 0; 1482 return 0;
1483} 1483}
1484 1484
1485static int 1485static int
1486atu_activate(device_t self, enum devact act) 1486atu_activate(device_t self, enum devact act)
1487{ 1487{
1488 struct atu_softc *sc = device_private(self); 1488 struct atu_softc *sc = device_private(self);
1489 1489
1490 switch (act) { 1490 switch (act) {
1491 case DVACT_DEACTIVATE: 1491 case DVACT_DEACTIVATE:
1492 if (sc->sc_state != ATU_S_UNCONFIG) { 1492 if (sc->sc_state != ATU_S_UNCONFIG) {
1493 if_deactivate(&sc->atu_ec.ec_if); 1493 if_deactivate(&sc->atu_ec.ec_if);
1494 sc->sc_state = ATU_S_DEAD; 1494 sc->sc_state = ATU_S_DEAD;
1495 } 1495 }
1496 return 0; 1496 return 0;
1497 default: 1497 default:
1498 return EOPNOTSUPP; 1498 return EOPNOTSUPP;
1499 } 1499 }
1500} 1500}
1501 1501
1502/* 1502/*
1503 * Initialize an RX descriptor and attach an MBUF cluster. 1503 * Initialize an RX descriptor and attach an MBUF cluster.
1504 */ 1504 */
1505static int 1505static int
1506atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m) 1506atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m)
1507{ 1507{
1508 struct mbuf *m_new = NULL; 1508 struct mbuf *m_new = NULL;
1509 1509
1510 if (m == NULL) { 1510 if (m == NULL) {
1511 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 1511 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1512 if (m_new == NULL) { 1512 if (m_new == NULL) {
1513 DPRINTF(("%s: no memory for rx list\n", 1513 DPRINTF(("%s: no memory for rx list\n",
1514 device_xname(sc->atu_dev))); 1514 device_xname(sc->atu_dev)));
1515 return ENOBUFS; 1515 return ENOBUFS;
1516 } 1516 }
1517 1517
1518 MCLGET(m_new, M_DONTWAIT); 1518 MCLGET(m_new, M_DONTWAIT);
1519 if (!(m_new->m_flags & M_EXT)) { 1519 if (!(m_new->m_flags & M_EXT)) {
1520 DPRINTF(("%s: no memory for rx list\n", 1520 DPRINTF(("%s: no memory for rx list\n",
1521 device_xname(sc->atu_dev))); 1521 device_xname(sc->atu_dev)));
1522 m_freem(m_new); 1522 m_freem(m_new);
1523 return ENOBUFS; 1523 return ENOBUFS;
1524 } 1524 }
1525 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 1525 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1526 } else { 1526 } else {
1527 m_new = m; 1527 m_new = m;
1528 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 1528 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1529 m_new->m_data = m_new->m_ext.ext_buf; 1529 m_new->m_data = m_new->m_ext.ext_buf;
1530 } 1530 }
1531 c->atu_mbuf = m_new; 1531 c->atu_mbuf = m_new;
1532 return 0; 1532 return 0;
1533} 1533}
1534 1534
1535static int 1535static int
1536atu_rx_list_init(struct atu_softc *sc) 1536atu_rx_list_init(struct atu_softc *sc)
1537{ 1537{
1538 struct atu_cdata *cd = &sc->atu_cdata; 1538 struct atu_cdata *cd = &sc->atu_cdata;
1539 struct atu_chain *c; 1539 struct atu_chain *c;
1540 int i; 1540 int i;
1541 1541
1542 DPRINTFN(15, ("%s: atu_rx_list_init: enter\n", 1542 DPRINTFN(15, ("%s: atu_rx_list_init: enter\n",
1543 device_xname(sc->atu_dev))); 1543 device_xname(sc->atu_dev)));
1544 1544
1545 for (i = 0; i < ATU_RX_LIST_CNT; i++) { 1545 for (i = 0; i < ATU_RX_LIST_CNT; i++) {
1546 c = &cd->atu_rx_chain[i]; 1546 c = &cd->atu_rx_chain[i];
1547 c->atu_sc = sc; 1547 c->atu_sc = sc;
1548 c->atu_idx = i; 1548 c->atu_idx = i;
1549 if (c->atu_xfer == NULL) { 1549 if (c->atu_xfer == NULL) {
1550 int err = usbd_create_xfer(sc->atu_ep[ATU_ENDPT_RX], 1550 int err = usbd_create_xfer(sc->atu_ep[ATU_ENDPT_RX],
1551 ATU_RX_BUFSZ, 0, 0, &c->atu_xfer); 1551 ATU_RX_BUFSZ, 0, 0, &c->atu_xfer);
1552 if (err) 1552 if (err)
1553 return err; 1553 return err;
1554 c->atu_buf = usbd_get_buffer(c->atu_xfer); 1554 c->atu_buf = usbd_get_buffer(c->atu_xfer);
1555 if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */ 1555 if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */
1556 return ENOBUFS; 1556 return ENOBUFS;
1557 } 1557 }
1558 } 1558 }
1559 return 0; 1559 return 0;
1560} 1560}
1561 1561
1562static int 1562static int
1563atu_tx_list_init(struct atu_softc *sc) 1563atu_tx_list_init(struct atu_softc *sc)
1564{ 1564{
1565 struct atu_cdata *cd = &sc->atu_cdata; 1565 struct atu_cdata *cd = &sc->atu_cdata;
1566 struct atu_chain *c; 1566 struct atu_chain *c;
1567 int i; 1567 int i;
1568 1568
1569 DPRINTFN(15, ("%s: atu_tx_list_init\n", 1569 DPRINTFN(15, ("%s: atu_tx_list_init\n",
1570 device_xname(sc->atu_dev))); 1570 device_xname(sc->atu_dev)));
1571 1571
1572 SLIST_INIT(&cd->atu_tx_free); 1572 SLIST_INIT(&cd->atu_tx_free);
1573 sc->atu_cdata.atu_tx_inuse = 0; 1573 sc->atu_cdata.atu_tx_inuse = 0;
1574 1574
1575 for (i = 0; i < ATU_TX_LIST_CNT; i++) { 1575 for (i = 0; i < ATU_TX_LIST_CNT; i++) {
1576 c = &cd->atu_tx_chain[i]; 1576 c = &cd->atu_tx_chain[i];
1577 c->atu_sc = sc; 1577 c->atu_sc = sc;
1578 c->atu_idx = i; 1578 c->atu_idx = i;
1579 if (c->atu_xfer == NULL) { 1579 if (c->atu_xfer == NULL) {
1580 int err = usbd_create_xfer(sc->atu_ep[ATU_ENDPT_TX], 1580 int err = usbd_create_xfer(sc->atu_ep[ATU_ENDPT_TX],
1581 ATU_TX_BUFSZ, 0, 0, &c->atu_xfer); 1581 ATU_TX_BUFSZ, 0, 0, &c->atu_xfer);
1582 if (err) { 1582 if (err) {
1583 return err; 1583 return err;
1584 } 1584 }
1585 c->atu_buf = usbd_get_buffer(c->atu_xfer); 1585 c->atu_buf = usbd_get_buffer(c->atu_xfer);
1586 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list); 1586 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list);
1587 } 1587 }
1588 } 1588 }
1589 return 0; 1589 return 0;
1590} 1590}
1591 1591
1592static void 1592static void
1593atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch, int listlen) 1593atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch, int listlen)
1594{ 1594{
1595 int i; 1595 int i;
1596 1596
1597 /* Free resources. */ 1597 /* Free resources. */
1598 for (i = 0; i < listlen; i++) { 1598 for (i = 0; i < listlen; i++) {
1599 if (ch[i].atu_buf != NULL) 1599 if (ch[i].atu_buf != NULL)
1600 ch[i].atu_buf = NULL; 1600 ch[i].atu_buf = NULL;
1601 if (ch[i].atu_mbuf != NULL) { 1601 if (ch[i].atu_mbuf != NULL) {
1602 m_freem(ch[i].atu_mbuf); 1602 m_freem(ch[i].atu_mbuf);
1603 ch[i].atu_mbuf = NULL; 1603 ch[i].atu_mbuf = NULL;
1604 } 1604 }
1605 if (ch[i].atu_xfer != NULL) { 1605 if (ch[i].atu_xfer != NULL) {
1606 usbd_destroy_xfer(ch[i].atu_xfer); 1606 usbd_destroy_xfer(ch[i].atu_xfer);
1607 ch[i].atu_xfer = NULL; 1607 ch[i].atu_xfer = NULL;
1608 } 1608 }
1609 } 1609 }
1610} 1610}
1611 1611
1612/* 1612/*
1613 * A frame has been uploaded: pass the resulting mbuf chain up to 1613 * A frame has been uploaded: pass the resulting mbuf chain up to
1614 * the higher level protocols. 1614 * the higher level protocols.
1615 */ 1615 */
1616static void 1616static void
1617atu_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1617atu_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1618{ 1618{
1619 struct atu_chain *c = (struct atu_chain *)priv; 1619 struct atu_chain *c = (struct atu_chain *)priv;
1620 struct atu_softc *sc = c->atu_sc; 1620 struct atu_softc *sc = c->atu_sc;
1621 struct ieee80211com *ic = &sc->sc_ic; 1621 struct ieee80211com *ic = &sc->sc_ic;
1622 struct ifnet *ifp = &sc->sc_if; 1622 struct ifnet *ifp = &sc->sc_if;
1623 struct atu_rx_hdr *h; 1623 struct atu_rx_hdr *h;
1624 struct ieee80211_frame_min *wh; 1624 struct ieee80211_frame_min *wh;
1625 struct ieee80211_node *ni; 1625 struct ieee80211_node *ni;
1626 struct mbuf *m; 1626 struct mbuf *m;
1627 uint32_t len; 1627 uint32_t len;
1628 int s; 1628 int s;
1629 1629
1630 DPRINTFN(25, ("%s: atu_rxeof\n", device_xname(sc->atu_dev))); 1630 DPRINTFN(25, ("%s: atu_rxeof\n", device_xname(sc->atu_dev)));
1631 1631
1632 if (sc->sc_state != ATU_S_OK) 1632 if (sc->sc_state != ATU_S_OK)
1633 return; 1633 return;
1634 1634
1635 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) 1635 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
1636 goto done; 1636 goto done;
1637 1637
1638 if (status != USBD_NORMAL_COMPLETION) { 1638 if (status != USBD_NORMAL_COMPLETION) {
1639 DPRINTF(("%s: status != USBD_NORMAL_COMPLETION\n", 1639 DPRINTF(("%s: status != USBD_NORMAL_COMPLETION\n",
1640 device_xname(sc->atu_dev))); 1640 device_xname(sc->atu_dev)));
1641 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 1641 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1642 return; 1642 return;
1643 } 1643 }
1644#if 0 1644#if 0
1645 if (status == USBD_IOERROR) { 1645 if (status == USBD_IOERROR) {
1646 DPRINTF(("%s: rx: EEK! lost device?\n", 1646 DPRINTF(("%s: rx: EEK! lost device?\n",
1647 device_xname(sc->atu_dev))); 1647 device_xname(sc->atu_dev)));
1648 1648
1649 /* 1649 /*
1650 * My experience with USBD_IOERROR is that trying to 1650 * My experience with USBD_IOERROR is that trying to
1651 * restart the transfer will always fail and we'll 1651 * restart the transfer will always fail and we'll
1652 * keep on looping restarting transfers untill someone 1652 * keep on looping restarting transfers untill someone
1653 * pulls the plug of the device. 1653 * pulls the plug of the device.
1654 * So we don't restart the transfer, but just let it 1654 * So we don't restart the transfer, but just let it
1655 * die... If someone knows of a situation where we can 1655 * die... If someone knows of a situation where we can
1656 * recover from USBD_IOERROR, let me know. 1656 * recover from USBD_IOERROR, let me know.
1657 */ 1657 */
1658 splx(s); 1658 splx(s);
1659 return; 1659 return;
1660 } 1660 }
1661#endif /* 0 */ 1661#endif /* 0 */
1662 1662
1663 if (usbd_ratecheck(&sc->atu_rx_notice)) { 1663 if (usbd_ratecheck(&sc->atu_rx_notice)) {
1664 DPRINTF(("%s: usb error on rx: %s\n", 1664 DPRINTF(("%s: usb error on rx: %s\n",
1665 device_xname(sc->atu_dev), usbd_errstr(status))); 1665 device_xname(sc->atu_dev), usbd_errstr(status)));
1666 } 1666 }
1667 if (status == USBD_STALLED) 1667 if (status == USBD_STALLED)
1668 usbd_clear_endpoint_stall_async( 1668 usbd_clear_endpoint_stall_async(
1669 sc->atu_ep[ATU_ENDPT_RX]); 1669 sc->atu_ep[ATU_ENDPT_RX]);
1670 goto done; 1670 goto done;
1671 } 1671 }
1672 1672
1673 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1673 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
1674 1674
1675 if (len <= 1) { 1675 if (len <= 1) {
1676 DPRINTF(("%s: atu_rxeof: too short\n", 1676 DPRINTF(("%s: atu_rxeof: too short\n",
1677 device_xname(sc->atu_dev))); 1677 device_xname(sc->atu_dev)));
1678 goto done; 1678 goto done;
1679 } 1679 }
1680 1680
1681 h = (struct atu_rx_hdr *)c->atu_buf; 1681 h = (struct atu_rx_hdr *)c->atu_buf;
1682 len = UGETW(h->length) - 4; /* XXX magic number */ 1682 len = UGETW(h->length) - 4; /* XXX magic number */
1683 1683
1684 m = c->atu_mbuf; 1684 m = c->atu_mbuf;
1685 memcpy(mtod(m, char *), c->atu_buf + ATU_RX_HDRLEN, len); 1685 memcpy(mtod(m, char *), c->atu_buf + ATU_RX_HDRLEN, len);
1686 m_set_rcvif(m, ifp); 1686 m_set_rcvif(m, ifp);
1687 m->m_pkthdr.len = m->m_len = len; 1687 m->m_pkthdr.len = m->m_len = len;
1688 1688
1689 wh = mtod(m, struct ieee80211_frame_min *); 1689 wh = mtod(m, struct ieee80211_frame_min *);
1690 ni = ieee80211_find_rxnode(ic, wh); 1690 ni = ieee80211_find_rxnode(ic, wh);
1691 1691
1692 ifp->if_ipackets++; 1692 ifp->if_ipackets++;
1693 1693
1694 s = splnet(); 1694 s = splnet();
1695 1695
1696 if (atu_newbuf(sc, c, NULL) == ENOBUFS) { 1696 if (atu_newbuf(sc, c, NULL) == ENOBUFS) {
1697 ifp->if_ierrors++; 1697 ifp->if_ierrors++;
1698 goto done1; /* XXX if we can't allocate, why restart it? */ 1698 goto done1; /* XXX if we can't allocate, why restart it? */
1699 } 1699 }
1700 1700
1701 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1701 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1702 /* 1702 /*
1703 * WEP is decrypted by hardware. Clear WEP bit 1703 * WEP is decrypted by hardware. Clear WEP bit
1704 * header for ieee80211_input(). 1704 * header for ieee80211_input().
1705 */ 1705 */
1706 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 1706 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1707 } 1707 }
1708 1708
1709 ieee80211_input(ic, m, ni, h->rssi, UGETDW(h->rx_time)); 1709 ieee80211_input(ic, m, ni, h->rssi, UGETDW(h->rx_time));
1710 1710
1711 ieee80211_free_node(ni); 1711 ieee80211_free_node(ni);
1712done1: 1712done1:
1713 splx(s); 1713 splx(s);
1714done: 1714done:
1715 /* Setup new transfer. */ 1715 /* Setup new transfer. */
1716 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, ATU_RX_BUFSZ, 1716 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, ATU_RX_BUFSZ,
1717 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof); 1717 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof);
1718 usbd_transfer(c->atu_xfer); 1718 usbd_transfer(c->atu_xfer);
1719} 1719}
1720 1720
1721/* 1721/*
1722 * A frame was downloaded to the chip. It's safe for us to clean up 1722 * A frame was downloaded to the chip. It's safe for us to clean up
1723 * the list buffers. 1723 * the list buffers.
1724 */ 1724 */
1725static void 1725static void
1726atu_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1726atu_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1727{ 1727{
1728 struct atu_chain *c = (struct atu_chain *)priv; 1728 struct atu_chain *c = (struct atu_chain *)priv;
1729 struct atu_softc *sc = c->atu_sc; 1729 struct atu_softc *sc = c->atu_sc;
1730 struct ifnet *ifp = &sc->sc_if; 1730 struct ifnet *ifp = &sc->sc_if;
1731 usbd_status err; 1731 usbd_status err;
1732 int s; 1732 int s;
1733 1733
1734 DPRINTFN(25, ("%s: atu_txeof status=%d\n", device_xname(sc->atu_dev), 1734 DPRINTFN(25, ("%s: atu_txeof status=%d\n", device_xname(sc->atu_dev),
1735 status)); 1735 status));
1736 1736
1737 if (c->atu_mbuf) { 1737 if (c->atu_mbuf) {
1738 m_freem(c->atu_mbuf); 1738 m_freem(c->atu_mbuf);
1739 c->atu_mbuf = NULL; 1739 c->atu_mbuf = NULL;
1740 } 1740 }
1741 1741
1742 if (status != USBD_NORMAL_COMPLETION) { 1742 if (status != USBD_NORMAL_COMPLETION) {
1743 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 1743 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1744 return; 1744 return;
1745 1745
1746 DPRINTF(("%s: usb error on tx: %s\n", 1746 DPRINTF(("%s: usb error on tx: %s\n",
1747 device_xname(sc->atu_dev), usbd_errstr(status))); 1747 device_xname(sc->atu_dev), usbd_errstr(status)));
1748 if (status == USBD_STALLED) 1748 if (status == USBD_STALLED)
1749 usbd_clear_endpoint_stall_async( 1749 usbd_clear_endpoint_stall_async(
1750 sc->atu_ep[ATU_ENDPT_TX]); 1750 sc->atu_ep[ATU_ENDPT_TX]);
1751 return; 1751 return;
1752 } 1752 }
1753 1753
1754 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, &err); 1754 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, &err);
1755 1755
1756 if (err) 1756 if (err)
1757 ifp->if_oerrors++; 1757 ifp->if_oerrors++;
1758 else 1758 else
1759 ifp->if_opackets++; 1759 ifp->if_opackets++;
1760 1760
1761 s = splnet(); 1761 s = splnet();
1762 SLIST_INSERT_HEAD(&sc->atu_cdata.atu_tx_free, c, atu_list); 1762 SLIST_INSERT_HEAD(&sc->atu_cdata.atu_tx_free, c, atu_list);
1763 sc->atu_cdata.atu_tx_inuse--; 1763 sc->atu_cdata.atu_tx_inuse--;
1764 if (sc->atu_cdata.atu_tx_inuse == 0) 1764 if (sc->atu_cdata.atu_tx_inuse == 0)
1765 ifp->if_timer = 0; 1765 ifp->if_timer = 0;
1766 ifp->if_flags &= ~IFF_OACTIVE; 1766 ifp->if_flags &= ~IFF_OACTIVE;
1767 splx(s); 1767 splx(s);
1768 1768
1769 atu_start(ifp); 1769 atu_start(ifp);
1770} 1770}
1771 1771
1772static uint8_t 1772static uint8_t
1773atu_calculate_padding(int size) 1773atu_calculate_padding(int size)
1774{ 1774{
1775 size %= 64; 1775 size %= 64;
1776 1776
1777 if (size < 50) 1777 if (size < 50)
1778 return 50 - size; 1778 return 50 - size;
1779 if (size >=61) 1779 if (size >=61)
1780 return 64 + 50 - size; 1780 return 64 + 50 - size;
1781 return 0; 1781 return 0;
1782} 1782}
1783 1783
1784static int 1784static int
1785atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni, 1785atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni,
1786 struct atu_chain *c, struct mbuf *m) 1786 struct atu_chain *c, struct mbuf *m)
1787{ 1787{
1788 int len; 1788 int len;
1789 struct atu_tx_hdr *h; 1789 struct atu_tx_hdr *h;
1790 usbd_status err; 1790 usbd_status err;
1791 uint8_t pad; 1791 uint8_t pad;
1792 1792
1793 DPRINTFN(25, ("%s: atu_tx_start\n", device_xname(sc->atu_dev))); 1793 DPRINTFN(25, ("%s: atu_tx_start\n", device_xname(sc->atu_dev)));
1794 1794
1795 /* Don't try to send when we're shutting down the driver */ 1795 /* Don't try to send when we're shutting down the driver */
1796 if (sc->sc_state != ATU_S_OK) { 1796 if (sc->sc_state != ATU_S_OK) {
1797 m_freem(m); 1797 m_freem(m);
1798 return EIO; 1798 return EIO;
1799 } 1799 }
1800 1800
1801 /* 1801 /*
1802 * Copy the mbuf data into a contiguous buffer, leaving 1802 * Copy the mbuf data into a contiguous buffer, leaving
1803 * enough room for the atmel headers 1803 * enough room for the atmel headers
1804 */ 1804 */
1805 len = m->m_pkthdr.len; 1805 len = m->m_pkthdr.len;
1806 1806
1807 m_copydata(m, 0, m->m_pkthdr.len, c->atu_buf + ATU_TX_HDRLEN); 1807 m_copydata(m, 0, m->m_pkthdr.len, c->atu_buf + ATU_TX_HDRLEN);
1808 1808
1809 h = (struct atu_tx_hdr *)c->atu_buf; 1809 h = (struct atu_tx_hdr *)c->atu_buf;
1810 memset(h, 0, ATU_TX_HDRLEN); 1810 memset(h, 0, ATU_TX_HDRLEN);
1811 USETW(h->length, len); 1811 USETW(h->length, len);
1812 h->tx_rate = 4; /* XXX rate = auto */ 1812 h->tx_rate = 4; /* XXX rate = auto */
1813 len += ATU_TX_HDRLEN; 1813 len += ATU_TX_HDRLEN;
1814 1814
1815 pad = atu_calculate_padding(len); 1815 pad = atu_calculate_padding(len);
1816 len += pad; 1816 len += pad;
1817 h->padding = pad; 1817 h->padding = pad;
1818 1818
1819 c->atu_length = len; 1819 c->atu_length = len;
1820 c->atu_mbuf = m; 1820 c->atu_mbuf = m;
1821 1821
1822 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, c->atu_length, 0, 1822 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, c->atu_length, 0,
1823 ATU_TX_TIMEOUT, atu_txeof); 1823 ATU_TX_TIMEOUT, atu_txeof);
1824 1824
1825 /* Let's get this thing into the air! */ 1825 /* Let's get this thing into the air! */
1826 c->atu_in_xfer = 1; 1826 c->atu_in_xfer = 1;
1827 err = usbd_transfer(c->atu_xfer); 1827 err = usbd_transfer(c->atu_xfer);
1828 if (err != USBD_IN_PROGRESS) { 1828 if (err != USBD_IN_PROGRESS) {
1829 DPRINTFN(25, ("%s: atu_tx_start, err=%d", 1829 DPRINTFN(25, ("%s: atu_tx_start, err=%d",
1830 device_xname(sc->atu_dev), err)); 1830 device_xname(sc->atu_dev), err));
1831 c->atu_mbuf = NULL; 1831 c->atu_mbuf = NULL;
1832 m_freem(m); 1832 m_freem(m);
1833 return EIO; 1833 return EIO;
1834 } 1834 }
1835 1835
1836 return 0; 1836 return 0;
1837} 1837}
1838 1838
1839static void 1839static void
1840atu_start(struct ifnet *ifp) 1840atu_start(struct ifnet *ifp)
1841{ 1841{
1842 struct atu_softc *sc = ifp->if_softc; 1842 struct atu_softc *sc = ifp->if_softc;
1843 struct ieee80211com *ic = &sc->sc_ic; 1843 struct ieee80211com *ic = &sc->sc_ic;
1844 struct atu_cdata *cd = &sc->atu_cdata; 1844 struct atu_cdata *cd = &sc->atu_cdata;
1845 struct ieee80211_node *ni; 1845 struct ieee80211_node *ni;
1846 struct atu_chain *c; 1846 struct atu_chain *c;
1847 struct mbuf *m = NULL; 1847 struct mbuf *m = NULL;
1848 int s; 1848 int s;
1849 1849
1850 DPRINTFN(25, ("%s: atu_start: enter\n", device_xname(sc->atu_dev))); 1850 DPRINTFN(25, ("%s: atu_start: enter\n", device_xname(sc->atu_dev)));
1851 1851
1852 if ((ifp->if_flags & IFF_RUNNING) == 0) { 1852 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1853 return; 1853 return;
1854 } 1854 }
1855 if (ifp->if_flags & IFF_OACTIVE) { 1855 if (ifp->if_flags & IFF_OACTIVE) {
1856 DPRINTFN(30, ("%s: atu_start: IFF_OACTIVE\n", 1856 DPRINTFN(30, ("%s: atu_start: IFF_OACTIVE\n",
1857 device_xname(sc->atu_dev))); 1857 device_xname(sc->atu_dev)));
1858 return; 1858 return;
1859 } 1859 }
1860 1860
1861 for (;;) { 1861 for (;;) {
1862 /* grab a TX buffer */ 1862 /* grab a TX buffer */
1863 s = splnet(); 1863 s = splnet();
1864 c = SLIST_FIRST(&cd->atu_tx_free); 1864 c = SLIST_FIRST(&cd->atu_tx_free);
1865 if (c != NULL) { 1865 if (c != NULL) {
1866 SLIST_REMOVE_HEAD(&cd->atu_tx_free, atu_list); 1866 SLIST_REMOVE_HEAD(&cd->atu_tx_free, atu_list);
1867 cd->atu_tx_inuse++; 1867 cd->atu_tx_inuse++;
1868 if (cd->atu_tx_inuse == ATU_TX_LIST_CNT) 1868 if (cd->atu_tx_inuse == ATU_TX_LIST_CNT)
1869 ifp->if_flags |= IFF_OACTIVE; 1869 ifp->if_flags |= IFF_OACTIVE;
1870 } 1870 }
1871 splx(s); 1871 splx(s);
1872 if (c == NULL) { 1872 if (c == NULL) {
1873 DPRINTFN(10, ("%s: out of tx xfers\n", 1873 DPRINTFN(10, ("%s: out of tx xfers\n",
1874 device_xname(sc->atu_dev))); 1874 device_xname(sc->atu_dev)));
1875 ifp->if_flags |= IFF_OACTIVE; 1875 ifp->if_flags |= IFF_OACTIVE;
1876 break; 1876 break;
1877 } 1877 }
1878 1878
1879 /* 1879 /*
1880 * Poll the management queue for frames, it has priority over 1880 * Poll the management queue for frames, it has priority over
1881 * normal data frames. 1881 * normal data frames.
1882 */ 1882 */
1883 IF_DEQUEUE(&ic->ic_mgtq, m); 1883 IF_DEQUEUE(&ic->ic_mgtq, m);
1884 if (m == NULL) { 1884 if (m == NULL) {
1885 DPRINTFN(10, ("%s: atu_start: data packet\n", 1885 DPRINTFN(10, ("%s: atu_start: data packet\n",
1886 device_xname(sc->atu_dev))); 1886 device_xname(sc->atu_dev)));
1887 if (ic->ic_state != IEEE80211_S_RUN) { 1887 if (ic->ic_state != IEEE80211_S_RUN) {
1888 DPRINTFN(25, ("%s: no data till running\n", 1888 DPRINTFN(25, ("%s: no data till running\n",
1889 device_xname(sc->atu_dev))); 1889 device_xname(sc->atu_dev)));
1890 /* put the xfer back on the list */ 1890 /* put the xfer back on the list */
1891 s = splnet(); 1891 s = splnet();
1892 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 1892 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
1893 atu_list); 1893 atu_list);
1894 cd->atu_tx_inuse--; 1894 cd->atu_tx_inuse--;
1895 splx(s); 1895 splx(s);
1896 break; 1896 break;
1897 } 1897 }
1898 1898
1899 IFQ_DEQUEUE(&ifp->if_snd, m); 1899 IFQ_DEQUEUE(&ifp->if_snd, m);
1900 if (m == NULL) { 1900 if (m == NULL) {
1901 DPRINTFN(25, ("%s: nothing to send\n", 1901 DPRINTFN(25, ("%s: nothing to send\n",
1902 device_xname(sc->atu_dev))); 1902 device_xname(sc->atu_dev)));
1903 s = splnet(); 1903 s = splnet();
1904 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 1904 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
1905 atu_list); 1905 atu_list);
1906 cd->atu_tx_inuse--; 1906 cd->atu_tx_inuse--;
1907 splx(s); 1907 splx(s);
1908 break; 1908 break;
1909 } 1909 }
1910 bpf_mtap(ifp, m, BPF_D_OUT); 1910 bpf_mtap(ifp, m, BPF_D_OUT);
1911 ni = ieee80211_find_txnode(ic, 1911 ni = ieee80211_find_txnode(ic,
1912 mtod(m, struct ether_header *)->ether_dhost); 1912 mtod(m, struct ether_header *)->ether_dhost);
1913 if (ni == NULL) { 1913 if (ni == NULL) {
1914 m_freem(m); 1914 m_freem(m);
1915 goto bad; 1915 goto bad;
1916 } 1916 }
1917 m = ieee80211_encap(ic, m, ni); 1917 m = ieee80211_encap(ic, m, ni);
1918 if (m == NULL) 1918 if (m == NULL)
1919 goto bad; 1919 goto bad;
1920 } else { 1920 } else {
1921 DPRINTFN(25, ("%s: atu_start: mgmt packet\n", 1921 DPRINTFN(25, ("%s: atu_start: mgmt packet\n",
1922 device_xname(sc->atu_dev))); 1922 device_xname(sc->atu_dev)));
1923 1923
1924 /* 1924 /*
1925 * Hack! The referenced node pointer is in the 1925 * Hack! The referenced node pointer is in the
1926 * rcvif field of the packet header. This is 1926 * rcvif field of the packet header. This is
1927 * placed there by ieee80211_mgmt_output because 1927 * placed there by ieee80211_mgmt_output because
1928 * we need to hold the reference with the frame 1928 * we need to hold the reference with the frame
1929 * and there's no other way (other than packet 1929 * and there's no other way (other than packet
1930 * tags which we consider too expensive to use) 1930 * tags which we consider too expensive to use)
1931 * to pass it along. 1931 * to pass it along.
1932 */ 1932 */
1933 ni = M_GETCTX(m, struct ieee80211_node *); 1933 ni = M_GETCTX(m, struct ieee80211_node *);
1934 M_CLEARCTX(m); 1934 M_CLEARCTX(m);
1935 1935
1936 /* sc->sc_stats.ast_tx_mgmt++; */ 1936 /* sc->sc_stats.ast_tx_mgmt++; */
1937 } 1937 }
1938 1938
1939 bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT); 1939 bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT);
1940 1940
1941 if (atu_tx_start(sc, ni, c, m)) { 1941 if (atu_tx_start(sc, ni, c, m)) {
1942bad: 1942bad:
1943 s = splnet(); 1943 s = splnet();
1944 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 1944 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
1945 atu_list); 1945 atu_list);
1946 cd->atu_tx_inuse--; 1946 cd->atu_tx_inuse--;
1947 splx(s); 1947 splx(s);
1948 /* ifp_if_oerrors++; */ 1948 /* ifp_if_oerrors++; */
1949 if (ni != NULL) 1949 if (ni != NULL)
1950 ieee80211_free_node(ni); 1950 ieee80211_free_node(ni);
1951 continue; 1951 continue;
1952 } 1952 }
1953 ifp->if_timer = 5; 1953 ifp->if_timer = 5;
1954 } 1954 }
1955} 1955}
1956 1956
1957static int 1957static int
1958atu_init(struct ifnet *ifp) 1958atu_init(struct ifnet *ifp)
1959{ 1959{
1960 struct atu_softc *sc = ifp->if_softc; 1960 struct atu_softc *sc = ifp->if_softc;
1961 struct ieee80211com *ic = &sc->sc_ic; 1961 struct ieee80211com *ic = &sc->sc_ic;
1962 struct atu_chain *c; 1962 struct atu_chain *c;
1963 usbd_status err; 1963 usbd_status err;
1964 int i, s; 1964 int i, s;
1965 1965
1966 s = splnet(); 1966 s = splnet();
1967 1967
1968 DPRINTFN(10, ("%s: atu_init\n", device_xname(sc->atu_dev))); 1968 DPRINTFN(10, ("%s: atu_init\n", device_xname(sc->atu_dev)));
1969 1969
1970 if (ifp->if_flags & IFF_RUNNING) { 1970 if (ifp->if_flags & IFF_RUNNING) {
1971 splx(s); 1971 splx(s);
1972 return 0; 1972 return 0;
1973 } 1973 }
1974 1974
1975 /* Load the multicast filter. */ 1975 /* Load the multicast filter. */
1976 /*atu_setmulti(sc); */ 1976 /*atu_setmulti(sc); */
1977 1977
1978 /* Open RX and TX pipes. */ 1978 /* Open RX and TX pipes. */
1979 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_RX], 1979 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_RX],
1980 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_RX]); 1980 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_RX]);
1981 if (err) { 1981 if (err) {
1982 DPRINTF(("%s: open rx pipe failed: %s\n", 1982 DPRINTF(("%s: open rx pipe failed: %s\n",
1983 device_xname(sc->atu_dev), usbd_errstr(err))); 1983 device_xname(sc->atu_dev), usbd_errstr(err)));
1984 splx(s); 1984 splx(s);
1985 return EIO; 1985 return EIO;
1986 } 1986 }
1987 1987
1988 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_TX], 1988 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_TX],
1989 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_TX]); 1989 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_TX]);
1990 if (err) { 1990 if (err) {
1991 DPRINTF(("%s: open tx pipe failed: %s\n", 1991 DPRINTF(("%s: open tx pipe failed: %s\n",
1992 device_xname(sc->atu_dev), usbd_errstr(err))); 1992 device_xname(sc->atu_dev), usbd_errstr(err)));
1993 splx(s); 1993 splx(s);
1994 return EIO; 1994 return EIO;
1995 } 1995 }
1996 1996
1997 /* Init TX ring */ 1997 /* Init TX ring */
1998 if (atu_tx_list_init(sc)) 1998 if (atu_tx_list_init(sc))
1999 printf("%s: tx list init failed\n", device_xname(sc->atu_dev)); 1999 printf("%s: tx list init failed\n", device_xname(sc->atu_dev));
2000 2000
2001 /* Init RX ring */ 2001 /* Init RX ring */
2002 if (atu_rx_list_init(sc)) 2002 if (atu_rx_list_init(sc))
2003 printf("%s: rx list init failed\n", device_xname(sc->atu_dev)); 2003 printf("%s: rx list init failed\n", device_xname(sc->atu_dev));
2004 2004
2005 /* Start up the receive pipe. */ 2005 /* Start up the receive pipe. */
2006 for (i = 0; i < ATU_RX_LIST_CNT; i++) { 2006 for (i = 0; i < ATU_RX_LIST_CNT; i++) {
2007 c = &sc->atu_cdata.atu_rx_chain[i]; 2007 c = &sc->atu_cdata.atu_rx_chain[i];
2008 2008
2009 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, ATU_RX_BUFSZ, 2009 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, ATU_RX_BUFSZ,
2010 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof); 2010 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof);
2011 usbd_transfer(c->atu_xfer); 2011 usbd_transfer(c->atu_xfer);
2012 } 2012 }
2013 2013
2014 DPRINTFN(10, ("%s: starting up using MAC=%s\n", 2014 DPRINTFN(10, ("%s: starting up using MAC=%s\n",
2015 device_xname(sc->atu_dev), ether_sprintf(ic->ic_myaddr))); 2015 device_xname(sc->atu_dev), ether_sprintf(ic->ic_myaddr)));
2016 2016
2017 /* Do initial setup */ 2017 /* Do initial setup */
2018 err = atu_initial_config(sc); 2018 err = atu_initial_config(sc);
2019 if (err) { 2019 if (err) {
2020 DPRINTF(("%s: initial config failed!\n", 2020 DPRINTF(("%s: initial config failed!\n",
2021 device_xname(sc->atu_dev))); 2021 device_xname(sc->atu_dev)));
2022 splx(s); 2022 splx(s);
2023 return EIO; 2023 return EIO;
2024 } 2024 }
2025 DPRINTFN(10, ("%s: initialised transceiver\n", 2025 DPRINTFN(10, ("%s: initialised transceiver\n",
2026 device_xname(sc->atu_dev))); 2026 device_xname(sc->atu_dev)));
2027 2027
2028 /* sc->atu_rxfilt = ATU_RXFILT_UNICAST|ATU_RXFILT_BROADCAST; */ 2028 /* sc->atu_rxfilt = ATU_RXFILT_UNICAST|ATU_RXFILT_BROADCAST; */
2029 2029
2030 /* If we want promiscuous mode, set the allframes bit. */ 2030 /* If we want promiscuous mode, set the allframes bit. */
2031 /* 2031 /*
2032 if (ifp->if_flags & IFF_PROMISC) 2032 if (ifp->if_flags & IFF_PROMISC)
2033 sc->atu_rxfilt |= ATU_RXFILT_PROMISC; 2033 sc->atu_rxfilt |= ATU_RXFILT_PROMISC;
2034 */ 2034 */
2035 2035
2036 ifp->if_flags |= IFF_RUNNING; 2036 ifp->if_flags |= IFF_RUNNING;
2037 ifp->if_flags &= ~IFF_OACTIVE; 2037 ifp->if_flags &= ~IFF_OACTIVE;
2038 splx(s); 2038 splx(s);
2039 2039
2040 /* XXX the following HAS to be replaced */ 2040 /* XXX the following HAS to be replaced */
2041 s = splnet(); 2041 s = splnet();
2042 err = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2042 err = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2043 if (err) { 2043 if (err) {
2044 DPRINTFN(1, ("%s: atu_init: error calling " 2044 DPRINTFN(1, ("%s: atu_init: error calling "
2045 "ieee80211_net_state", device_xname(sc->atu_dev))); 2045 "ieee80211_net_state", device_xname(sc->atu_dev)));
2046 } 2046 }
2047 splx(s); 2047 splx(s);
2048 2048
2049 return 0; 2049 return 0;
2050} 2050}
2051 2051
2052#if 0 && defined(ATU_DEBUG) /* XXX XXX XXX UNUSED */ 2052#if 0 && defined(ATU_DEBUG) /* XXX XXX XXX UNUSED */
2053static void atu_debug_print(struct atu_softc *); 2053static void atu_debug_print(struct atu_softc *);
2054static void 2054static void
2055atu_debug_print(struct atu_softc *sc) 2055atu_debug_print(struct atu_softc *sc)
2056{ 2056{
2057 usbd_status err; 2057 usbd_status err;
2058 uint8_t tmp[32]; 2058 uint8_t tmp[32];
2059 2059
2060 /* DEBUG */ 2060 /* DEBUG */
2061 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, tmp))) 2061 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, tmp)))
2062 return; 2062 return;
2063 DPRINTF(("%s: DEBUG: current BSSID=%s\n", device_xname(sc->atu_dev), 2063 DPRINTF(("%s: DEBUG: current BSSID=%s\n", device_xname(sc->atu_dev),
2064 ether_sprintf(tmp))); 2064 ether_sprintf(tmp)));
2065 2065
2066 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__BEACON_PERIOD, tmp))) 2066 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__BEACON_PERIOD, tmp)))
2067 return; 2067 return;
2068 DPRINTF(("%s: DEBUG: beacon period=%d\n", device_xname(sc->atu_dev), 2068 DPRINTF(("%s: DEBUG: beacon period=%d\n", device_xname(sc->atu_dev),
2069 tmp[0])); 2069 tmp[0]));
2070 2070
2071 if ((err = atu_get_mib(sc, MIB_MAC_WEP__PRIVACY_INVOKED, tmp))) 2071 if ((err = atu_get_mib(sc, MIB_MAC_WEP__PRIVACY_INVOKED, tmp)))
2072 return; 2072 return;
2073 DPRINTF(("%s: DEBUG: privacy invoked=%d\n", device_xname(sc->atu_dev), 2073 DPRINTF(("%s: DEBUG: privacy invoked=%d\n", device_xname(sc->atu_dev),
2074 tmp[0])); 2074 tmp[0]));
2075 2075
2076 if ((err = atu_get_mib(sc, MIB_MAC_WEP__ENCR_LEVEL, tmp))) 2076 if ((err = atu_get_mib(sc, MIB_MAC_WEP__ENCR_LEVEL, tmp)))
2077 return; 2077 return;
2078 DPRINTF(("%s: DEBUG: encr_level=%d\n", device_xname(sc->atu_dev), 2078 DPRINTF(("%s: DEBUG: encr_level=%d\n", device_xname(sc->atu_dev),
2079 tmp[0])); 2079 tmp[0]));
2080 2080
2081 if ((err = atu_get_mib(sc, MIB_MAC_WEP__ICV_ERROR_COUNT, tmp))) 2081 if ((err = atu_get_mib(sc, MIB_MAC_WEP__ICV_ERROR_COUNT, tmp)))
2082 return; 2082 return;
2083 DPRINTF(("%s: DEBUG: icv error count=%d\n", device_xname(sc->atu_dev), 2083 DPRINTF(("%s: DEBUG: icv error count=%d\n", device_xname(sc->atu_dev),
2084 *(short *)tmp)); 2084 *(short *)tmp));
2085 2085
2086 if ((err = atu_get_mib(sc, MIB_MAC_WEP__EXCLUDED_COUNT, tmp))) 2086 if ((err = atu_get_mib(sc, MIB_MAC_WEP__EXCLUDED_COUNT, tmp)))
2087 return; 2087 return;
2088 DPRINTF(("%s: DEBUG: wep excluded count=%d\n", 2088 DPRINTF(("%s: DEBUG: wep excluded count=%d\n",
2089 device_xname(sc->atu_dev), *(short *)tmp)); 2089 device_xname(sc->atu_dev), *(short *)tmp));
2090 2090
2091 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__POWER_MODE, tmp))) 2091 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__POWER_MODE, tmp)))
2092 return; 2092 return;
2093 DPRINTF(("%s: DEBUG: power mode=%d\n", device_xname(sc->atu_dev), 2093 DPRINTF(("%s: DEBUG: power mode=%d\n", device_xname(sc->atu_dev),
2094 tmp[0])); 2094 tmp[0]));
2095 2095
2096 if ((err = atu_get_mib(sc, MIB_PHY__CHANNEL, tmp))) 2096 if ((err = atu_get_mib(sc, MIB_PHY__CHANNEL, tmp)))
2097 return; 2097 return;
2098 DPRINTF(("%s: DEBUG: channel=%d\n", device_xname(sc->atu_dev), tmp[0])); 2098 DPRINTF(("%s: DEBUG: channel=%d\n", device_xname(sc->atu_dev), tmp[0]));
2099 2099
2100 if ((err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, tmp))) 2100 if ((err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, tmp)))
2101 return; 2101 return;
2102 DPRINTF(("%s: DEBUG: reg domain=%d\n", device_xname(sc->atu_dev), 2102 DPRINTF(("%s: DEBUG: reg domain=%d\n", device_xname(sc->atu_dev),
2103 tmp[0])); 2103 tmp[0]));
2104 2104
2105 if ((err = atu_get_mib(sc, MIB_LOCAL__SSID_SIZE, tmp))) 2105 if ((err = atu_get_mib(sc, MIB_LOCAL__SSID_SIZE, tmp)))
2106 return; 2106 return;
2107 DPRINTF(("%s: DEBUG: ssid size=%d\n", device_xname(sc->atu_dev), 2107 DPRINTF(("%s: DEBUG: ssid size=%d\n", device_xname(sc->atu_dev),
2108 tmp[0])); 2108 tmp[0]));
2109 2109
2110 if ((err = atu_get_mib(sc, MIB_LOCAL__BEACON_ENABLE, tmp))) 2110 if ((err = atu_get_mib(sc, MIB_LOCAL__BEACON_ENABLE, tmp)))
2111 return; 2111 return;
2112 DPRINTF(("%s: DEBUG: beacon enable=%d\n", device_xname(sc->atu_dev), 2112 DPRINTF(("%s: DEBUG: beacon enable=%d\n", device_xname(sc->atu_dev),
2113 tmp[0])); 2113 tmp[0]));
2114 2114
2115 if ((err = atu_get_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, tmp))) 2115 if ((err = atu_get_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, tmp)))
2116 return; 2116 return;
2117 DPRINTF(("%s: DEBUG: auto rate fallback=%d\n", 2117 DPRINTF(("%s: DEBUG: auto rate fallback=%d\n",
2118 device_xname(sc->atu_dev), tmp[0])); 2118 device_xname(sc->atu_dev), tmp[0]));
2119 2119
2120 if ((err = atu_get_mib(sc, MIB_MAC_ADDR__ADDR, tmp))) 2120 if ((err = atu_get_mib(sc, MIB_MAC_ADDR__ADDR, tmp)))
2121 return; 2121 return;
2122 DPRINTF(("%s: DEBUG: mac addr=%s\n", device_xname(sc->atu_dev), 2122 DPRINTF(("%s: DEBUG: mac addr=%s\n", device_xname(sc->atu_dev),
2123 ether_sprintf(tmp))); 2123 ether_sprintf(tmp)));
2124 2124
2125 if ((err = atu_get_mib(sc, MIB_MAC__DESIRED_SSID, tmp))) 2125 if ((err = atu_get_mib(sc, MIB_MAC__DESIRED_SSID, tmp)))
2126 return; 2126 return;
2127 DPRINTF(("%s: DEBUG: desired ssid=%s\n", device_xname(sc->atu_dev), 2127 DPRINTF(("%s: DEBUG: desired ssid=%s\n", device_xname(sc->atu_dev),
2128 tmp)); 2128 tmp));
2129 2129
2130 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_ESSID, tmp))) 2130 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_ESSID, tmp)))
2131 return; 2131 return;
2132 DPRINTF(("%s: DEBUG: current ESSID=%s\n", device_xname(sc->atu_dev), 2132 DPRINTF(("%s: DEBUG: current ESSID=%s\n", device_xname(sc->atu_dev),
2133 tmp)); 2133 tmp));
2134} 2134}
2135#endif /* ATU_DEBUG */ 2135#endif /* ATU_DEBUG */
2136 2136
2137static int 2137static int
2138atu_ioctl(struct ifnet *ifp, u_long command, void *data) 2138atu_ioctl(struct ifnet *ifp, u_long command, void *data)
2139{ 2139{
2140 struct atu_softc *sc = ifp->if_softc; 2140 struct atu_softc *sc = ifp->if_softc;
2141 struct ifreq *ifr = (struct ifreq *)data; 
2142 struct ieee80211com *ic = &sc->sc_ic; 2141 struct ieee80211com *ic = &sc->sc_ic;
2143 int err = 0, s; 2142 int err = 0, s;
2144 2143
2145 s = splnet(); 2144 s = splnet();
2146 switch (command) { 2145 switch (command) {
2147 case SIOCSIFMEDIA: 
2148 case SIOCGIFMEDIA: 
2149 err = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command); 
2150 break; 
2151 
2152 default: 2146 default:
2153 DPRINTFN(15, ("%s: ieee80211_ioctl (%lu)\n", 2147 DPRINTFN(15, ("%s: ieee80211_ioctl (%lu)\n",
2154 device_xname(sc->atu_dev), command)); 2148 device_xname(sc->atu_dev), command));
2155 err = ieee80211_ioctl(ic, command, data); 2149 err = ieee80211_ioctl(ic, command, data);
2156 break; 2150 break;
2157 } 2151 }
2158 2152
2159 if (err == ENETRESET) { 2153 if (err == ENETRESET) {
2160 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 2154 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
2161 (IFF_RUNNING|IFF_UP)) { 2155 (IFF_RUNNING|IFF_UP)) {
2162 DPRINTF(("%s: atu_ioctl(): netreset %lu\n", 2156 DPRINTF(("%s: atu_ioctl(): netreset %lu\n",
2163 device_xname(sc->atu_dev), command)); 2157 device_xname(sc->atu_dev), command));
2164 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2158 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2165 atu_initial_config(sc); 2159 atu_initial_config(sc);
2166 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2160 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2167 } 2161 }
2168 err = 0; 2162 err = 0;
2169 } 2163 }
2170 2164
2171 splx(s); 2165 splx(s);
2172 return err; 2166 return err;
2173} 2167}
2174 2168
2175static void 2169static void
2176atu_watchdog(struct ifnet *ifp) 2170atu_watchdog(struct ifnet *ifp)
2177{ 2171{
2178 struct atu_softc *sc = ifp->if_softc; 2172 struct atu_softc *sc = ifp->if_softc;
2179 struct atu_chain *c; 2173 struct atu_chain *c;
2180 usbd_status stat; 2174 usbd_status stat;
2181 int cnt, s; 2175 int cnt, s;
2182 2176
2183 DPRINTF(("%s: atu_watchdog\n", device_xname(sc->atu_dev))); 2177 DPRINTF(("%s: atu_watchdog\n", device_xname(sc->atu_dev)));
2184 2178
2185 ifp->if_timer = 0; 2179 ifp->if_timer = 0;
2186 2180
2187 if (sc->sc_state != ATU_S_OK || (ifp->if_flags & IFF_RUNNING) == 0) 2181 if (sc->sc_state != ATU_S_OK || (ifp->if_flags & IFF_RUNNING) == 0)
2188 return; 2182 return;
2189 2183
2190 sc = ifp->if_softc; 2184 sc = ifp->if_softc;
2191 s = splnet(); 2185 s = splnet();
2192 ifp->if_oerrors++; 2186 ifp->if_oerrors++;
2193 DPRINTF(("%s: watchdog timeout\n", device_xname(sc->atu_dev))); 2187 DPRINTF(("%s: watchdog timeout\n", device_xname(sc->atu_dev)));
2194 2188
2195 /* 2189 /*
2196 * TODO: 2190 * TODO:
2197 * we should change this since we have multiple TX tranfers... 2191 * we should change this since we have multiple TX tranfers...
2198 */ 2192 */
2199 for (cnt = 0; cnt < ATU_TX_LIST_CNT; cnt++) { 2193 for (cnt = 0; cnt < ATU_TX_LIST_CNT; cnt++) {
2200 c = &sc->atu_cdata.atu_tx_chain[cnt]; 2194 c = &sc->atu_cdata.atu_tx_chain[cnt];
2201 if (c->atu_in_xfer) { 2195 if (c->atu_in_xfer) {
2202 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, 2196 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL,
2203 &stat); 2197 &stat);
2204 atu_txeof(c->atu_xfer, c, stat); 2198 atu_txeof(c->atu_xfer, c, stat);
2205 } 2199 }
2206 } 2200 }
2207 2201
2208 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 2202 if (!IFQ_IS_EMPTY(&ifp->if_snd))
2209 atu_start(ifp); 2203 atu_start(ifp);
2210 splx(s); 2204 splx(s);
2211 2205
2212 ieee80211_watchdog(&sc->sc_ic); 2206 ieee80211_watchdog(&sc->sc_ic);
2213} 2207}
2214 2208
2215/* 2209/*
2216 * Stop the adapter and free any mbufs allocated to the 2210 * Stop the adapter and free any mbufs allocated to the
2217 * RX and TX lists. 2211 * RX and TX lists.
2218 */ 2212 */
2219static void 2213static void
2220atu_stop(struct ifnet *ifp, int disable) 2214atu_stop(struct ifnet *ifp, int disable)
2221{ 2215{
2222 struct atu_softc *sc = ifp->if_softc; 2216 struct atu_softc *sc = ifp->if_softc;
2223 struct ieee80211com *ic = &sc->sc_ic; 2217 struct ieee80211com *ic = &sc->sc_ic;
2224 struct atu_cdata *cd; 2218 struct atu_cdata *cd;
2225 usbd_status err; 2219 usbd_status err;
2226 int s; 2220 int s;
2227 2221
2228 s = splnet(); 2222 s = splnet();
2229 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2223 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2230 ifp->if_timer = 0; 2224 ifp->if_timer = 0;
2231 2225
2232 usb_rem_task_wait(sc->atu_udev, &sc->sc_task, USB_TASKQ_DRIVER, NULL); 2226 usb_rem_task_wait(sc->atu_udev, &sc->sc_task, USB_TASKQ_DRIVER, NULL);
2233 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2227 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2234 2228
2235 /* Stop transfers. */ 2229 /* Stop transfers. */
2236 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) { 2230 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) {
2237 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]); 2231 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]);
2238 if (err) { 2232 if (err) {
2239 DPRINTF(("%s: abort rx pipe failed: %s\n", 2233 DPRINTF(("%s: abort rx pipe failed: %s\n",
2240 device_xname(sc->atu_dev), usbd_errstr(err))); 2234 device_xname(sc->atu_dev), usbd_errstr(err)));
2241 } 2235 }
2242 } 2236 }
2243 2237
2244 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) { 2238 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) {
2245 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); 2239 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]);
2246 if (err) { 2240 if (err) {
2247 DPRINTF(("%s: abort tx pipe failed: %s\n", 2241 DPRINTF(("%s: abort tx pipe failed: %s\n",
2248 device_xname(sc->atu_dev), usbd_errstr(err))); 2242 device_xname(sc->atu_dev), usbd_errstr(err)));
2249 } 2243 }
2250 } 2244 }
2251 2245
2252 /* Free RX/TX/MGMT list resources. */ 2246 /* Free RX/TX/MGMT list resources. */
2253 cd = &sc->atu_cdata; 2247 cd = &sc->atu_cdata;
2254 atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT); 2248 atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT);
2255 atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT); 2249 atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT);
2256 2250
2257 /* Close pipes */ 2251 /* Close pipes */
2258 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) { 2252 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) {
2259 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]); 2253 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]);
2260 if (err) { 2254 if (err) {
2261 DPRINTF(("%s: close rx pipe failed: %s\n", 2255 DPRINTF(("%s: close rx pipe failed: %s\n",
2262 device_xname(sc->atu_dev), usbd_errstr(err))); 2256 device_xname(sc->atu_dev), usbd_errstr(err)));
2263 } 2257 }
2264 sc->atu_ep[ATU_ENDPT_RX] = NULL; 2258 sc->atu_ep[ATU_ENDPT_RX] = NULL;
2265 } 2259 }
2266 2260
2267 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) { 2261 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) {
2268 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]); 2262 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]);
2269 if (err) { 2263 if (err) {
2270 DPRINTF(("%s: close tx pipe failed: %s\n", 2264 DPRINTF(("%s: close tx pipe failed: %s\n",
2271 device_xname(sc->atu_dev), usbd_errstr(err))); 2265 device_xname(sc->atu_dev), usbd_errstr(err)));
2272 } 2266 }
2273 sc->atu_ep[ATU_ENDPT_TX] = NULL; 2267 sc->atu_ep[ATU_ENDPT_TX] = NULL;
2274 } 2268 }
2275 2269
2276 /* Let's be nice and turn off the radio before we leave */ 2270 /* Let's be nice and turn off the radio before we leave */
2277 atu_switch_radio(sc, 0); 2271 atu_switch_radio(sc, 0);
2278 2272
2279 splx(s); 2273 splx(s);
2280} 2274}