wi.c revision 1.241 1 /* $NetBSD: wi.c,v 1.241 2017/02/01 02:37:43 nonaka Exp $ */
2
3 /*-
4 * Copyright (c) 2004 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
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
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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
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
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1997, 1998, 1999
34 * Bill Paul <wpaul (at) ctr.columbia.edu>. All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by Bill Paul.
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
49 * without specific prior written permission.
50 *
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
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
55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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
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
61 * THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64 /*
65 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for NetBSD.
66 *
67 * Original FreeBSD driver written by Bill Paul <wpaul (at) ctr.columbia.edu>
68 * Electrical Engineering Department
69 * Columbia University, New York City
70 */
71
72 /*
73 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
74 * from Lucent. Unlike the older cards, the new ones are programmed
75 * entirely via a firmware-driven controller called the Hermes.
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
78 * called the HCF (Hardware Control Functions) which is supposed to
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
81 * a) extremely gross, b) lacks certain features, particularly support
82 * for 802.11 frames, and c) is contaminated by the GNU Public License.
83 *
84 * This driver does not use the HCF or HCF Light at all. Instead, it
85 * programs the Hermes controller directly, using information gleaned
86 * from the HCF Light code and corresponding documentation.
87 *
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
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
92 * inserted. Consequently, you need to use the pccard support for
93 * both the ISA and PCMCIA adapters.
94 */
95
96 /*
97 * FreeBSD driver ported to NetBSD by Bill Sommerfeld in the back of the
98 * Oslo IETF plenary meeting.
99 */
100
101 #include <sys/cdefs.h>
102 __KERNEL_RCSID(0, "$NetBSD: wi.c,v 1.241 2017/02/01 02:37:43 nonaka Exp $");
103
104 #define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */
105 #define WI_HERMES_STATS_WAR /* Work around stats counter bug. */
106 #undef WI_HISTOGRAM
107 #undef WI_RING_DEBUG
108 #define STATIC static
109
110
111 #include <sys/param.h>
112 #include <sys/sysctl.h>
113 #include <sys/systm.h>
114 #include <sys/callout.h>
115 #include <sys/device.h>
116 #include <sys/socket.h>
117 #include <sys/mbuf.h>
118 #include <sys/ioctl.h>
119 #include <sys/kernel.h> /* for hz */
120 #include <sys/proc.h>
121 #include <sys/kauth.h>
122
123 #include <net/if.h>
124 #include <net/if_dl.h>
125 #include <net/if_llc.h>
126 #include <net/if_media.h>
127 #include <net/if_ether.h>
128 #include <net/route.h>
129
130 #include <net80211/ieee80211_netbsd.h>
131 #include <net80211/ieee80211_var.h>
132 #include <net80211/ieee80211_ioctl.h>
133 #include <net80211/ieee80211_radiotap.h>
134 #include <net80211/ieee80211_rssadapt.h>
135
136 #include <net/bpf.h>
137 #include <net/bpfdesc.h>
138
139 #include <sys/bus.h>
140
141 #include <dev/ic/wi_ieee.h>
142 #include <dev/ic/wireg.h>
143 #include <dev/ic/wivar.h>
144
145 STATIC int wi_init(struct ifnet *);
146 STATIC void wi_stop(struct ifnet *, int);
147 STATIC void wi_start(struct ifnet *);
148 STATIC int wi_reset(struct wi_softc *);
149 STATIC void wi_watchdog(struct ifnet *);
150 STATIC int wi_ioctl(struct ifnet *, u_long, void *);
151 STATIC int wi_media_change(struct ifnet *);
152 STATIC void wi_media_status(struct ifnet *, struct ifmediareq *);
153
154 static void wi_ioctl_init(struct wi_softc *);
155 static int wi_ioctl_enter(struct wi_softc *);
156 static void wi_ioctl_exit(struct wi_softc *);
157 static void wi_ioctl_drain(struct wi_softc *);
158
159 STATIC struct ieee80211_node *wi_node_alloc(struct ieee80211_node_table *);
160 STATIC void wi_node_free(struct ieee80211_node *);
161
162 STATIC void wi_raise_rate(struct ieee80211com *, struct ieee80211_rssdesc *);
163 STATIC void wi_lower_rate(struct ieee80211com *, struct ieee80211_rssdesc *);
164 STATIC int wi_choose_rate(struct ieee80211com *, struct ieee80211_node *,
165 struct ieee80211_frame *, u_int);
166 STATIC void wi_rssadapt_updatestats_cb(void *, struct ieee80211_node *);
167 STATIC void wi_rssadapt_updatestats(void *);
168 STATIC void wi_rssdescs_init(struct wi_rssdesc (*)[], wi_rssdescq_t *);
169 STATIC void wi_rssdescs_reset(struct ieee80211com *, struct wi_rssdesc (*)[],
170 wi_rssdescq_t *, u_int8_t (*)[]);
171 STATIC void wi_sync_bssid(struct wi_softc *, u_int8_t new_bssid[]);
172
173 STATIC void wi_rx_intr(struct wi_softc *);
174 STATIC void wi_txalloc_intr(struct wi_softc *);
175 STATIC void wi_cmd_intr(struct wi_softc *);
176 STATIC void wi_tx_intr(struct wi_softc *);
177 STATIC void wi_tx_ex_intr(struct wi_softc *);
178 STATIC void wi_info_intr(struct wi_softc *);
179
180 STATIC int wi_key_delete(struct ieee80211com *, const struct ieee80211_key *);
181 STATIC int wi_key_set(struct ieee80211com *, const struct ieee80211_key *,
182 const u_int8_t[IEEE80211_ADDR_LEN]);
183 STATIC void wi_key_update_begin(struct ieee80211com *);
184 STATIC void wi_key_update_end(struct ieee80211com *);
185
186 STATIC void wi_push_packet(struct wi_softc *);
187 STATIC int wi_get_cfg(struct ifnet *, u_long, void *);
188 STATIC int wi_set_cfg(struct ifnet *, u_long, void *);
189 STATIC int wi_cfg_txrate(struct wi_softc *);
190 STATIC int wi_write_txrate(struct wi_softc *, int);
191 STATIC int wi_write_wep(struct wi_softc *);
192 STATIC int wi_write_multi(struct wi_softc *);
193 STATIC int wi_alloc_fid(struct wi_softc *, int, int *);
194 STATIC void wi_read_nicid(struct wi_softc *);
195 STATIC int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int);
196
197 STATIC int wi_cmd(struct wi_softc *, int, int, int, int);
198 STATIC int wi_cmd_start(struct wi_softc *, int, int, int, int);
199 STATIC int wi_cmd_wait(struct wi_softc *, int, int);
200 STATIC int wi_seek_bap(struct wi_softc *, int, int);
201 STATIC int wi_read_bap(struct wi_softc *, int, int, void *, int);
202 STATIC int wi_write_bap(struct wi_softc *, int, int, void *, int);
203 STATIC int wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int);
204 STATIC int wi_read_rid(struct wi_softc *, int, void *, int *);
205 STATIC int wi_write_rid(struct wi_softc *, int, void *, int);
206
207 STATIC int wi_newstate(struct ieee80211com *, enum ieee80211_state, int);
208 STATIC void wi_set_tim(struct ieee80211_node *, int);
209
210 STATIC int wi_scan_ap(struct wi_softc *, u_int16_t, u_int16_t);
211 STATIC void wi_scan_result(struct wi_softc *, int, int);
212
213 STATIC void wi_dump_pkt(struct wi_frame *, struct ieee80211_node *, int rssi);
214 STATIC void wi_mend_flags(struct wi_softc *, enum ieee80211_state);
215
216 static inline int
217 wi_write_val(struct wi_softc *sc, int rid, u_int16_t val)
218 {
219
220 val = htole16(val);
221 return wi_write_rid(sc, rid, &val, sizeof(val));
222 }
223
224 static struct timeval lasttxerror; /* time of last tx error msg */
225 static int curtxeps = 0; /* current tx error msgs/sec */
226 static int wi_txerate = 0; /* tx error rate: max msgs/sec */
227
228 #ifdef WI_DEBUG
229 #define WI_DEBUG_MAX 2
230 int wi_debug = 0;
231
232 #define DPRINTF(X) if (wi_debug) printf X
233 #define DPRINTF2(X) if (wi_debug > 1) printf X
234 #define IFF_DUMPPKTS(_ifp) \
235 (((_ifp)->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
236 static int wi_sysctl_verify_debug(SYSCTLFN_PROTO);
237 #else
238 #define DPRINTF(X)
239 #define DPRINTF2(X)
240 #define IFF_DUMPPKTS(_ifp) 0
241 #endif
242
243 #define WI_INTRS (WI_EV_RX | WI_EV_ALLOC | WI_EV_INFO | \
244 WI_EV_TX | WI_EV_TX_EXC | WI_EV_CMD)
245
246 struct wi_card_ident
247 wi_card_ident[] = {
248 /* CARD_ID CARD_NAME FIRM_TYPE */
249 { WI_NIC_LUCENT_ID, WI_NIC_LUCENT_STR, WI_LUCENT },
250 { WI_NIC_SONY_ID, WI_NIC_SONY_STR, WI_LUCENT },
251 { WI_NIC_LUCENT_EMB_ID, WI_NIC_LUCENT_EMB_STR, WI_LUCENT },
252 { WI_NIC_EVB2_ID, WI_NIC_EVB2_STR, WI_INTERSIL },
253 { WI_NIC_HWB3763_ID, WI_NIC_HWB3763_STR, WI_INTERSIL },
254 { WI_NIC_HWB3163_ID, WI_NIC_HWB3163_STR, WI_INTERSIL },
255 { WI_NIC_HWB3163B_ID, WI_NIC_HWB3163B_STR, WI_INTERSIL },
256 { WI_NIC_EVB3_ID, WI_NIC_EVB3_STR, WI_INTERSIL },
257 { WI_NIC_HWB1153_ID, WI_NIC_HWB1153_STR, WI_INTERSIL },
258 { WI_NIC_P2_SST_ID, WI_NIC_P2_SST_STR, WI_INTERSIL },
259 { WI_NIC_EVB2_SST_ID, WI_NIC_EVB2_SST_STR, WI_INTERSIL },
260 { WI_NIC_3842_EVA_ID, WI_NIC_3842_EVA_STR, WI_INTERSIL },
261 { WI_NIC_3842_PCMCIA_AMD_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL },
262 { WI_NIC_3842_PCMCIA_SST_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL },
263 { WI_NIC_3842_PCMCIA_ATM_ID, WI_NIC_3842_PCMCIA_STR, WI_INTERSIL },
264 { WI_NIC_3842_MINI_AMD_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL },
265 { WI_NIC_3842_MINI_SST_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL },
266 { WI_NIC_3842_MINI_ATM_ID, WI_NIC_3842_MINI_STR, WI_INTERSIL },
267 { WI_NIC_3842_PCI_AMD_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL },
268 { WI_NIC_3842_PCI_SST_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL },
269 { WI_NIC_3842_PCI_ATM_ID, WI_NIC_3842_PCI_STR, WI_INTERSIL },
270 { WI_NIC_P3_PCMCIA_AMD_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL },
271 { WI_NIC_P3_PCMCIA_SST_ID, WI_NIC_P3_PCMCIA_STR, WI_INTERSIL },
272 { WI_NIC_P3_MINI_AMD_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL },
273 { WI_NIC_P3_MINI_SST_ID, WI_NIC_P3_MINI_STR, WI_INTERSIL },
274 { 0, NULL, 0 },
275 };
276
277 #ifndef _MODULE
278 /*
279 * Setup sysctl(3) MIB, hw.wi.*
280 *
281 * TBD condition CTLFLAG_PERMANENT on being a module or not
282 */
283 SYSCTL_SETUP(sysctl_wi, "sysctl wi(4) subtree setup")
284 {
285 int rc;
286 const struct sysctlnode *rnode;
287 #ifdef WI_DEBUG
288 const struct sysctlnode *cnode;
289 #endif /* WI_DEBUG */
290
291 if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
292 CTLFLAG_PERMANENT, CTLTYPE_NODE, "wi",
293 "Lucent/Prism/Symbol 802.11 controls",
294 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
295 goto err;
296
297 #ifdef WI_DEBUG
298 /* control debugging printfs */
299 if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
300 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
301 "debug", SYSCTL_DESCR("Enable debugging output"),
302 wi_sysctl_verify_debug, 0, &wi_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
303 goto err;
304 #endif /* WI_DEBUG */
305 return;
306 err:
307 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
308 }
309 #endif
310
311 #ifdef WI_DEBUG
312 static int
313 wi_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper)
314 {
315 int error, t;
316 struct sysctlnode node;
317
318 node = *rnode;
319 t = *(int*)rnode->sysctl_data;
320 node.sysctl_data = &t;
321 error = sysctl_lookup(SYSCTLFN_CALL(&node));
322 if (error || newp == NULL)
323 return (error);
324
325 if (t < lower || t > upper)
326 return (EINVAL);
327
328 *(int*)rnode->sysctl_data = t;
329
330 return (0);
331 }
332
333 static int
334 wi_sysctl_verify_debug(SYSCTLFN_ARGS)
335 {
336 return wi_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)),
337 0, WI_DEBUG_MAX);
338 }
339 #endif /* WI_DEBUG */
340
341 STATIC int
342 wi_read_xrid(struct wi_softc *sc, int rid, void *buf, int ebuflen)
343 {
344 int buflen, rc;
345
346 buflen = ebuflen;
347 if ((rc = wi_read_rid(sc, rid, buf, &buflen)) != 0)
348 return rc;
349
350 if (buflen < ebuflen) {
351 #ifdef WI_DEBUG
352 printf("%s: rid=%#04x read %d, expected %d\n", __func__,
353 rid, buflen, ebuflen);
354 #endif
355 return -1;
356 }
357 return 0;
358 }
359
360 int
361 wi_attach(struct wi_softc *sc, const u_int8_t *macaddr)
362 {
363 struct ieee80211com *ic = &sc->sc_ic;
364 struct ifnet *ifp = &sc->sc_if;
365 int chan, nrate, buflen;
366 u_int16_t val, chanavail;
367 struct {
368 u_int16_t nrates;
369 char rates[IEEE80211_RATE_SIZE];
370 } ratebuf;
371 static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
373 };
374 int s;
375
376 wi_ioctl_init(sc);
377
378 s = splnet();
379
380 /* Make sure interrupts are disabled. */
381 CSR_WRITE_2(sc, WI_INT_EN, 0);
382 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
383
384 sc->sc_invalid = 0;
385
386 /* Reset the NIC. */
387 if (wi_reset(sc) != 0) {
388 sc->sc_invalid = 1;
389 splx(s);
390 return 1;
391 }
392
393 if (wi_read_xrid(sc, WI_RID_MAC_NODE, ic->ic_myaddr,
394 IEEE80211_ADDR_LEN) != 0 ||
395 IEEE80211_ADDR_EQ(ic->ic_myaddr, empty_macaddr)) {
396 if (macaddr != NULL)
397 memcpy(ic->ic_myaddr, macaddr, IEEE80211_ADDR_LEN);
398 else {
399 printf(" could not get mac address, attach failed\n");
400 splx(s);
401 return 1;
402 }
403 }
404
405 printf(" 802.11 address %s\n", ether_sprintf(ic->ic_myaddr));
406
407 /* Read NIC identification */
408 wi_read_nicid(sc);
409
410 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
411 ifp->if_softc = sc;
412 ifp->if_start = wi_start;
413 ifp->if_ioctl = wi_ioctl;
414 ifp->if_watchdog = wi_watchdog;
415 ifp->if_init = wi_init;
416 ifp->if_stop = wi_stop;
417 ifp->if_flags =
418 IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST | IFF_NOTRAILERS;
419 IFQ_SET_READY(&ifp->if_snd);
420
421 ic->ic_ifp = ifp;
422 ic->ic_phytype = IEEE80211_T_DS;
423 ic->ic_opmode = IEEE80211_M_STA;
424 ic->ic_caps = IEEE80211_C_AHDEMO;
425 ic->ic_state = IEEE80211_S_INIT;
426 ic->ic_max_aid = WI_MAX_AID;
427
428 /* Find available channel */
429 if (wi_read_xrid(sc, WI_RID_CHANNEL_LIST, &chanavail,
430 sizeof(chanavail)) != 0) {
431 aprint_normal_dev(sc->sc_dev, "using default channel list\n");
432 chanavail = htole16(0x1fff); /* assume 1-13 */
433 }
434 for (chan = 16; chan > 0; chan--) {
435 if (!isset((u_int8_t*)&chanavail, chan - 1))
436 continue;
437 ic->ic_ibss_chan = &ic->ic_channels[chan];
438 ic->ic_channels[chan].ic_freq =
439 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
440 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_B;
441 }
442
443 /* Find default IBSS channel */
444 if (wi_read_xrid(sc, WI_RID_OWN_CHNL, &val, sizeof(val)) == 0) {
445 chan = le16toh(val);
446 if (isset((u_int8_t*)&chanavail, chan - 1))
447 ic->ic_ibss_chan = &ic->ic_channels[chan];
448 }
449 if (ic->ic_ibss_chan == NULL) {
450 aprint_error_dev(sc->sc_dev, "no available channel\n");
451 return 1;
452 }
453
454 if (sc->sc_firmware_type == WI_LUCENT) {
455 sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET;
456 } else {
457 if ((sc->sc_flags & WI_FLAGS_HAS_DBMADJUST) &&
458 wi_read_xrid(sc, WI_RID_DBM_ADJUST, &val, sizeof(val)) == 0)
459 sc->sc_dbm_offset = le16toh(val);
460 else
461 sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;
462 }
463
464 sc->sc_flags |= WI_FLAGS_RSSADAPTSTA;
465
466 /*
467 * Set flags based on firmware version.
468 */
469 switch (sc->sc_firmware_type) {
470 case WI_LUCENT:
471 sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
472 #ifdef WI_HERMES_AUTOINC_WAR
473 /* XXX: not confirmed, but never seen for recent firmware */
474 if (sc->sc_sta_firmware_ver < 40000) {
475 sc->sc_flags |= WI_FLAGS_BUG_AUTOINC;
476 }
477 #endif
478 if (sc->sc_sta_firmware_ver >= 60000)
479 sc->sc_flags |= WI_FLAGS_HAS_MOR;
480 if (sc->sc_sta_firmware_ver >= 60006) {
481 ic->ic_caps |= IEEE80211_C_IBSS;
482 ic->ic_caps |= IEEE80211_C_MONITOR;
483 }
484 ic->ic_caps |= IEEE80211_C_PMGT;
485 sc->sc_ibss_port = 1;
486 break;
487
488 case WI_INTERSIL:
489 sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR;
490 sc->sc_flags |= WI_FLAGS_HAS_ROAMING;
491 sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
492 if (sc->sc_sta_firmware_ver > 10101)
493 sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST;
494 if (sc->sc_sta_firmware_ver >= 800) {
495 if (sc->sc_sta_firmware_ver != 10402)
496 ic->ic_caps |= IEEE80211_C_HOSTAP;
497 ic->ic_caps |= IEEE80211_C_IBSS;
498 ic->ic_caps |= IEEE80211_C_MONITOR;
499 }
500 ic->ic_caps |= IEEE80211_C_PMGT;
501 sc->sc_ibss_port = 0;
502 sc->sc_alt_retry = 2;
503 break;
504
505 case WI_SYMBOL:
506 sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY;
507 if (sc->sc_sta_firmware_ver >= 20000)
508 ic->ic_caps |= IEEE80211_C_IBSS;
509 sc->sc_ibss_port = 4;
510 break;
511 }
512
513 /*
514 * Find out if we support WEP on this card.
515 */
516 if (wi_read_xrid(sc, WI_RID_WEP_AVAIL, &val, sizeof(val)) == 0 &&
517 val != htole16(0))
518 ic->ic_caps |= IEEE80211_C_WEP;
519
520 /* Find supported rates. */
521 buflen = sizeof(ratebuf);
522 if (wi_read_rid(sc, WI_RID_DATA_RATES, &ratebuf, &buflen) == 0 &&
523 buflen > 2) {
524 nrate = le16toh(ratebuf.nrates);
525 if (nrate > IEEE80211_RATE_SIZE)
526 nrate = IEEE80211_RATE_SIZE;
527 memcpy(ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates,
528 &ratebuf.rates[0], nrate);
529 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate;
530 } else {
531 aprint_error_dev(sc->sc_dev, "no supported rate list\n");
532 return 1;
533 }
534
535 sc->sc_max_datalen = 2304;
536 sc->sc_rts_thresh = 2347;
537 sc->sc_frag_thresh = 2346;
538 sc->sc_system_scale = 1;
539 sc->sc_cnfauthmode = IEEE80211_AUTH_OPEN;
540 sc->sc_roaming_mode = 1;
541
542 callout_init(&sc->sc_rssadapt_ch, 0);
543
544 /*
545 * Call MI attach routines.
546 */
547 if_attach(ifp);
548 ieee80211_ifattach(ic);
549
550 sc->sc_newstate = ic->ic_newstate;
551 sc->sc_set_tim = ic->ic_set_tim;
552 ic->ic_newstate = wi_newstate;
553 ic->ic_node_alloc = wi_node_alloc;
554 ic->ic_node_free = wi_node_free;
555 ic->ic_set_tim = wi_set_tim;
556
557 ic->ic_crypto.cs_key_delete = wi_key_delete;
558 ic->ic_crypto.cs_key_set = wi_key_set;
559 ic->ic_crypto.cs_key_update_begin = wi_key_update_begin;
560 ic->ic_crypto.cs_key_update_end = wi_key_update_end;
561
562 ieee80211_media_init(ic, wi_media_change, wi_media_status);
563
564 bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
565 sizeof(struct ieee80211_frame) + 64, &sc->sc_drvbpf);
566
567 memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
568 sc->sc_rxtap.wr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu));
569 sc->sc_rxtap.wr_ihdr.it_present = htole32(WI_RX_RADIOTAP_PRESENT);
570
571 memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
572 sc->sc_txtap.wt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu));
573 sc->sc_txtap.wt_ihdr.it_present = htole32(WI_TX_RADIOTAP_PRESENT);
574
575 /* Attach is successful. */
576 sc->sc_attached = 1;
577
578 splx(s);
579 ieee80211_announce(ic);
580 return 0;
581 }
582
583 int
584 wi_detach(struct wi_softc *sc)
585 {
586 struct ifnet *ifp = &sc->sc_if;
587 int s;
588
589 if (!sc->sc_attached)
590 return 0;
591
592 sc->sc_invalid = 1;
593 s = splnet();
594
595 wi_stop(ifp, 1);
596
597 ieee80211_ifdetach(&sc->sc_ic);
598 if_detach(ifp);
599 splx(s);
600 wi_ioctl_drain(sc);
601 return 0;
602 }
603
604 int
605 wi_activate(device_t self, enum devact act)
606 {
607 struct wi_softc *sc = device_private(self);
608
609 switch (act) {
610 case DVACT_DEACTIVATE:
611 if_deactivate(&sc->sc_if);
612 return 0;
613 default:
614 return EOPNOTSUPP;
615 }
616 }
617
618 int
619 wi_intr(void *arg)
620 {
621 int i;
622 struct wi_softc *sc = arg;
623 struct ifnet *ifp = &sc->sc_if;
624 u_int16_t status;
625
626 if (sc->sc_enabled == 0 ||
627 !device_is_active(sc->sc_dev) ||
628 (ifp->if_flags & IFF_RUNNING) == 0)
629 return 0;
630
631 if ((ifp->if_flags & IFF_UP) == 0) {
632 CSR_WRITE_2(sc, WI_INT_EN, 0);
633 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
634 return 1;
635 }
636
637 /* This is superfluous on Prism, but Lucent breaks if we
638 * do not disable interrupts.
639 */
640 CSR_WRITE_2(sc, WI_INT_EN, 0);
641
642 /* maximum 10 loops per interrupt */
643 for (i = 0; i < 10; i++) {
644 status = CSR_READ_2(sc, WI_EVENT_STAT);
645 #ifdef WI_DEBUG
646 if (wi_debug > 1) {
647 printf("%s: iter %d status %#04x\n", __func__, i,
648 status);
649 }
650 #endif /* WI_DEBUG */
651 if ((status & WI_INTRS) == 0)
652 break;
653
654 sc->sc_status = status;
655
656 if (status & WI_EV_RX)
657 wi_rx_intr(sc);
658
659 if (status & WI_EV_ALLOC)
660 wi_txalloc_intr(sc);
661
662 if (status & WI_EV_TX)
663 wi_tx_intr(sc);
664
665 if (status & WI_EV_TX_EXC)
666 wi_tx_ex_intr(sc);
667
668 if (status & WI_EV_INFO)
669 wi_info_intr(sc);
670
671 CSR_WRITE_2(sc, WI_EVENT_ACK, sc->sc_status);
672
673 if (sc->sc_status & WI_EV_CMD)
674 wi_cmd_intr(sc);
675
676 if ((ifp->if_flags & IFF_OACTIVE) == 0 &&
677 (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0 &&
678 !IFQ_IS_EMPTY(&ifp->if_snd))
679 wi_start(ifp);
680
681 sc->sc_status = 0;
682 }
683
684 /* re-enable interrupts */
685 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
686
687 sc->sc_status = 0;
688
689 return 1;
690 }
691
692 #define arraylen(a) (sizeof(a) / sizeof((a)[0]))
693
694 STATIC void
695 wi_rssdescs_init(struct wi_rssdesc (*rssd)[WI_NTXRSS], wi_rssdescq_t *rssdfree)
696 {
697 int i;
698 SLIST_INIT(rssdfree);
699 for (i = 0; i < arraylen(*rssd); i++) {
700 SLIST_INSERT_HEAD(rssdfree, &(*rssd)[i], rd_next);
701 }
702 }
703
704 STATIC void
705 wi_rssdescs_reset(struct ieee80211com *ic, struct wi_rssdesc (*rssd)[WI_NTXRSS],
706 wi_rssdescq_t *rssdfree, u_int8_t (*txpending)[IEEE80211_RATE_MAXSIZE])
707 {
708 struct ieee80211_node *ni;
709 int i;
710 for (i = 0; i < arraylen(*rssd); i++) {
711 ni = (*rssd)[i].rd_desc.id_node;
712 (*rssd)[i].rd_desc.id_node = NULL;
713 if (ni != NULL && (ic->ic_ifp->if_flags & IFF_DEBUG) != 0)
714 printf("%s: cleaning outstanding rssadapt "
715 "descriptor for %s\n",
716 ic->ic_ifp->if_xname, ether_sprintf(ni->ni_macaddr));
717 if (ni != NULL)
718 ieee80211_free_node(ni);
719 }
720 memset(*txpending, 0, sizeof(*txpending));
721 wi_rssdescs_init(rssd, rssdfree);
722 }
723
724 STATIC int
725 wi_init(struct ifnet *ifp)
726 {
727 struct wi_softc *sc = ifp->if_softc;
728 struct ieee80211com *ic = &sc->sc_ic;
729 struct wi_joinreq join;
730 int i;
731 int error = 0, wasenabled;
732
733 DPRINTF(("wi_init: enabled %d\n", sc->sc_enabled));
734 wasenabled = sc->sc_enabled;
735 if (!sc->sc_enabled) {
736 if ((error = (*sc->sc_enable)(sc->sc_dev, 1)) != 0)
737 goto out;
738 sc->sc_enabled = 1;
739 } else
740 wi_stop(ifp, 0);
741
742 /* Symbol firmware cannot be initialized more than once */
743 if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled)
744 if ((error = wi_reset(sc)) != 0)
745 goto out;
746
747 /* common 802.11 configuration */
748 ic->ic_flags &= ~IEEE80211_F_IBSSON;
749 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
750 switch (ic->ic_opmode) {
751 case IEEE80211_M_STA:
752 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_BSS);
753 break;
754 case IEEE80211_M_IBSS:
755 wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_ibss_port);
756 ic->ic_flags |= IEEE80211_F_IBSSON;
757 break;
758 case IEEE80211_M_AHDEMO:
759 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC);
760 break;
761 case IEEE80211_M_HOSTAP:
762 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_HOSTAP);
763 break;
764 case IEEE80211_M_MONITOR:
765 if (sc->sc_firmware_type == WI_LUCENT)
766 wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC);
767 wi_cmd(sc, WI_CMD_TEST | (WI_TEST_MONITOR << 8), 0, 0, 0);
768 break;
769 }
770
771 /* Intersil interprets this RID as joining ESS even in IBSS mode */
772 if (sc->sc_firmware_type == WI_LUCENT &&
773 (ic->ic_flags & IEEE80211_F_IBSSON) && ic->ic_des_esslen > 0)
774 wi_write_val(sc, WI_RID_CREATE_IBSS, 1);
775 else
776 wi_write_val(sc, WI_RID_CREATE_IBSS, 0);
777 wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval);
778 wi_write_ssid(sc, WI_RID_DESIRED_SSID, ic->ic_des_essid,
779 ic->ic_des_esslen);
780 wi_write_val(sc, WI_RID_OWN_CHNL,
781 ieee80211_chan2ieee(ic, ic->ic_ibss_chan));
782 wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_essid, ic->ic_des_esslen);
783 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
784 wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, IEEE80211_ADDR_LEN);
785 if (ic->ic_caps & IEEE80211_C_PMGT)
786 wi_write_val(sc, WI_RID_PM_ENABLED,
787 (ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0);
788
789 /* not yet common 802.11 configuration */
790 wi_write_val(sc, WI_RID_MAX_DATALEN, sc->sc_max_datalen);
791 wi_write_val(sc, WI_RID_RTS_THRESH, sc->sc_rts_thresh);
792 if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)
793 wi_write_val(sc, WI_RID_FRAG_THRESH, sc->sc_frag_thresh);
794
795 /* driver specific 802.11 configuration */
796 if (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)
797 wi_write_val(sc, WI_RID_SYSTEM_SCALE, sc->sc_system_scale);
798 if (sc->sc_flags & WI_FLAGS_HAS_ROAMING)
799 wi_write_val(sc, WI_RID_ROAMING_MODE, sc->sc_roaming_mode);
800 if (sc->sc_flags & WI_FLAGS_HAS_MOR)
801 wi_write_val(sc, WI_RID_MICROWAVE_OVEN, sc->sc_microwave_oven);
802 wi_cfg_txrate(sc);
803 wi_write_ssid(sc, WI_RID_NODENAME, sc->sc_nodename, sc->sc_nodelen);
804
805 #ifndef IEEE80211_NO_HOSTAP
806 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
807 sc->sc_firmware_type == WI_INTERSIL) {
808 wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_lintval);
809 wi_write_val(sc, WI_RID_DTIM_PERIOD, 1);
810 }
811 #endif /* !IEEE80211_NO_HOSTAP */
812
813 if (sc->sc_firmware_type == WI_INTERSIL) {
814 struct ieee80211_rateset *rs =
815 &ic->ic_sup_rates[IEEE80211_MODE_11B];
816 u_int16_t basic = 0, supported = 0, rate;
817
818 for (i = 0; i < rs->rs_nrates; i++) {
819 switch (rs->rs_rates[i] & IEEE80211_RATE_VAL) {
820 case 2:
821 rate = 1;
822 break;
823 case 4:
824 rate = 2;
825 break;
826 case 11:
827 rate = 4;
828 break;
829 case 22:
830 rate = 8;
831 break;
832 default:
833 rate = 0;
834 break;
835 }
836 if (rs->rs_rates[i] & IEEE80211_RATE_BASIC)
837 basic |= rate;
838 supported |= rate;
839 }
840 wi_write_val(sc, WI_RID_BASIC_RATE, basic);
841 wi_write_val(sc, WI_RID_SUPPORT_RATE, supported);
842 wi_write_val(sc, WI_RID_ALT_RETRY_COUNT, sc->sc_alt_retry);
843 }
844
845 /*
846 * Initialize promisc mode.
847 * Being in Host-AP mode causes a great
848 * deal of pain if promiscuous mode is set.
849 * Therefore we avoid confusing the firmware
850 * and always reset promisc mode in Host-AP
851 * mode. Host-AP sees all the packets anyway.
852 */
853 if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
854 (ifp->if_flags & IFF_PROMISC) != 0) {
855 wi_write_val(sc, WI_RID_PROMISC, 1);
856 } else {
857 wi_write_val(sc, WI_RID_PROMISC, 0);
858 }
859
860 /* Configure WEP. */
861 if (ic->ic_caps & IEEE80211_C_WEP) {
862 sc->sc_cnfauthmode = ic->ic_bss->ni_authmode;
863 wi_write_wep(sc);
864 }
865
866 /* Set multicast filter. */
867 wi_write_multi(sc);
868
869 sc->sc_txalloc = 0;
870 sc->sc_txalloced = 0;
871 sc->sc_txqueue = 0;
872 sc->sc_txqueued = 0;
873 sc->sc_txstart = 0;
874 sc->sc_txstarted = 0;
875
876 if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) {
877 sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame);
878 if (sc->sc_firmware_type == WI_SYMBOL)
879 sc->sc_buflen = 1585; /* XXX */
880 for (i = 0; i < WI_NTXBUF; i++) {
881 error = wi_alloc_fid(sc, sc->sc_buflen,
882 &sc->sc_txd[i].d_fid);
883 if (error) {
884 aprint_error_dev(sc->sc_dev,
885 "tx buffer allocation failed\n");
886 goto out;
887 }
888 DPRINTF2(("wi_init: txbuf %d allocated %x\n", i,
889 sc->sc_txd[i].d_fid));
890 ++sc->sc_txalloced;
891 }
892 }
893
894 wi_rssdescs_init(&sc->sc_rssd, &sc->sc_rssdfree);
895
896 /* Enable desired port */
897 wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0);
898 ifp->if_flags |= IFF_RUNNING;
899 ifp->if_flags &= ~IFF_OACTIVE;
900 ic->ic_state = IEEE80211_S_INIT;
901
902 if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
903 ic->ic_opmode == IEEE80211_M_IBSS ||
904 ic->ic_opmode == IEEE80211_M_MONITOR ||
905 ic->ic_opmode == IEEE80211_M_HOSTAP)
906 ieee80211_create_ibss(ic, ic->ic_ibss_chan);
907
908 /* Enable interrupts */
909 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
910
911 #ifndef IEEE80211_NO_HOSTAP
912 if (!wasenabled &&
913 ic->ic_opmode == IEEE80211_M_HOSTAP &&
914 sc->sc_firmware_type == WI_INTERSIL) {
915 /* XXX: some card need to be re-enabled for hostap */
916 wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0);
917 wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0);
918 }
919 #endif /* !IEEE80211_NO_HOSTAP */
920
921 if (ic->ic_opmode == IEEE80211_M_STA &&
922 ((ic->ic_flags & IEEE80211_F_DESBSSID) ||
923 ic->ic_des_chan != IEEE80211_CHAN_ANYC)) {
924 memset(&join, 0, sizeof(join));
925 if (ic->ic_flags & IEEE80211_F_DESBSSID)
926 IEEE80211_ADDR_COPY(&join.wi_bssid, ic->ic_des_bssid);
927 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC)
928 join.wi_chan =
929 htole16(ieee80211_chan2ieee(ic, ic->ic_des_chan));
930 /* Lucent firmware does not support the JOIN RID. */
931 if (sc->sc_firmware_type != WI_LUCENT)
932 wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join));
933 }
934
935 out:
936 if (error) {
937 printf("%s: interface not running\n", device_xname(sc->sc_dev));
938 wi_stop(ifp, 0);
939 }
940 DPRINTF(("wi_init: return %d\n", error));
941 return error;
942 }
943
944 STATIC void
945 wi_txcmd_wait(struct wi_softc *sc)
946 {
947 KASSERT(sc->sc_txcmds == 1);
948 if (sc->sc_status & WI_EV_CMD) {
949 sc->sc_status &= ~WI_EV_CMD;
950 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
951 } else
952 (void)wi_cmd_wait(sc, WI_CMD_TX | WI_RECLAIM, 0);
953 }
954
955 STATIC void
956 wi_stop(struct ifnet *ifp, int disable)
957 {
958 struct wi_softc *sc = ifp->if_softc;
959 struct ieee80211com *ic = &sc->sc_ic;
960 int s;
961
962 if (!sc->sc_enabled)
963 return;
964
965 s = splnet();
966
967 DPRINTF(("wi_stop: disable %d\n", disable));
968
969 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
970
971 /* wait for tx command completion (deassoc, deauth) */
972 while (sc->sc_txcmds > 0) {
973 wi_txcmd_wait(sc);
974 wi_cmd_intr(sc);
975 }
976
977 /* TBD wait for deassoc, deauth tx completion? */
978
979 if (!sc->sc_invalid) {
980 CSR_WRITE_2(sc, WI_INT_EN, 0);
981 wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0);
982 }
983
984 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
985 &sc->sc_txpending);
986
987 sc->sc_tx_timer = 0;
988 sc->sc_scan_timer = 0;
989 sc->sc_false_syns = 0;
990 sc->sc_naps = 0;
991 ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING);
992 ifp->if_timer = 0;
993
994 if (disable) {
995 (*sc->sc_enable)(sc->sc_dev, 0);
996 sc->sc_enabled = 0;
997 }
998 splx(s);
999 }
1000
1001 /*
1002 * Choose a data rate for a packet len bytes long that suits the packet
1003 * type and the wireless conditions.
1004 *
1005 * TBD Adapt fragmentation threshold.
1006 */
1007 STATIC int
1008 wi_choose_rate(struct ieee80211com *ic, struct ieee80211_node *ni,
1009 struct ieee80211_frame *wh, u_int len)
1010 {
1011 struct wi_softc *sc = ic->ic_ifp->if_softc;
1012 struct wi_node *wn = (void*)ni;
1013 struct ieee80211_rssadapt *ra = &wn->wn_rssadapt;
1014 int do_not_adapt, i, rateidx, s;
1015
1016 do_not_adapt = (ic->ic_opmode != IEEE80211_M_HOSTAP) &&
1017 (sc->sc_flags & WI_FLAGS_RSSADAPTSTA) == 0;
1018
1019 s = splnet();
1020
1021 rateidx = ieee80211_rssadapt_choose(ra, &ni->ni_rates, wh, len,
1022 ic->ic_fixed_rate,
1023 ((ic->ic_ifp->if_flags & IFF_DEBUG) == 0) ? NULL : ic->ic_ifp->if_xname,
1024 do_not_adapt);
1025
1026 ni->ni_txrate = rateidx;
1027
1028 if (ic->ic_opmode != IEEE80211_M_HOSTAP) {
1029 /* choose the slowest pending rate so that we don't
1030 * accidentally send a packet on the MAC's queue
1031 * too fast. TBD find out if the MAC labels Tx
1032 * packets w/ rate when enqueued or dequeued.
1033 */
1034 for (i = 0; i < rateidx && sc->sc_txpending[i] == 0; i++);
1035 rateidx = i;
1036 }
1037
1038 splx(s);
1039 return (rateidx);
1040 }
1041
1042 STATIC void
1043 wi_raise_rate(struct ieee80211com *ic, struct ieee80211_rssdesc *id)
1044 {
1045 struct wi_node *wn;
1046 if (id->id_node == NULL)
1047 return;
1048
1049 wn = (void*)id->id_node;
1050 ieee80211_rssadapt_raise_rate(ic, &wn->wn_rssadapt, id);
1051 }
1052
1053 STATIC void
1054 wi_lower_rate(struct ieee80211com *ic, struct ieee80211_rssdesc *id)
1055 {
1056 struct ieee80211_node *ni;
1057 struct wi_node *wn;
1058 int s;
1059
1060 s = splnet();
1061
1062 if ((ni = id->id_node) == NULL) {
1063 DPRINTF(("wi_lower_rate: missing node\n"));
1064 goto out;
1065 }
1066
1067 wn = (void *)ni;
1068
1069 ieee80211_rssadapt_lower_rate(ic, ni, &wn->wn_rssadapt, id);
1070 out:
1071 splx(s);
1072 return;
1073 }
1074
1075 STATIC void
1076 wi_start(struct ifnet *ifp)
1077 {
1078 struct wi_softc *sc = ifp->if_softc;
1079 struct ieee80211com *ic = &sc->sc_ic;
1080 struct ether_header *eh;
1081 struct ieee80211_node *ni;
1082 struct ieee80211_frame *wh;
1083 struct ieee80211_rateset *rs;
1084 struct wi_rssdesc *rd;
1085 struct ieee80211_rssdesc *id;
1086 struct mbuf *m0;
1087 struct wi_frame frmhdr;
1088 int cur, fid, off, rateidx;
1089
1090 if (!sc->sc_enabled || sc->sc_invalid)
1091 return;
1092 if (sc->sc_flags & WI_FLAGS_OUTRANGE)
1093 return;
1094
1095 memset(&frmhdr, 0, sizeof(frmhdr));
1096 cur = sc->sc_txqueue;
1097 for (;;) {
1098 ni = ic->ic_bss;
1099 if (sc->sc_txalloced == 0 || SLIST_EMPTY(&sc->sc_rssdfree)) {
1100 ifp->if_flags |= IFF_OACTIVE;
1101 break;
1102 }
1103 if (!IF_IS_EMPTY(&ic->ic_mgtq)) {
1104 IF_DEQUEUE(&ic->ic_mgtq, m0);
1105 m_copydata(m0, 4, ETHER_ADDR_LEN * 2,
1106 (void *)&frmhdr.wi_ehdr);
1107 frmhdr.wi_ehdr.ether_type = 0;
1108 wh = mtod(m0, struct ieee80211_frame *);
1109 ni = M_GETCTX(m0, struct ieee80211_node *);
1110 M_CLEARCTX(m0);
1111 } else if (ic->ic_state == IEEE80211_S_RUN) {
1112 IFQ_POLL(&ifp->if_snd, m0);
1113 if (m0 == NULL)
1114 break;
1115 IFQ_DEQUEUE(&ifp->if_snd, m0);
1116 ifp->if_opackets++;
1117 m_copydata(m0, 0, ETHER_HDR_LEN,
1118 (void *)&frmhdr.wi_ehdr);
1119 bpf_mtap(ifp, m0);
1120
1121 eh = mtod(m0, struct ether_header *);
1122 ni = ieee80211_find_txnode(ic, eh->ether_dhost);
1123 if (ni == NULL) {
1124 ifp->if_oerrors++;
1125 continue;
1126 }
1127 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
1128 (m0->m_flags & M_PWR_SAV) == 0) {
1129 ieee80211_pwrsave(ic, ni, m0);
1130 goto next;
1131 }
1132 if ((m0 = ieee80211_encap(ic, m0, ni)) == NULL) {
1133 ieee80211_free_node(ni);
1134 ifp->if_oerrors++;
1135 continue;
1136 }
1137 wh = mtod(m0, struct ieee80211_frame *);
1138 } else
1139 break;
1140 bpf_mtap3(ic->ic_rawbpf, m0);
1141 frmhdr.wi_tx_ctl =
1142 htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX|WI_TXCNTL_TX_OK);
1143 #ifndef IEEE80211_NO_HOSTAP
1144 if (ic->ic_opmode == IEEE80211_M_HOSTAP)
1145 frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_ALTRTRY);
1146 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
1147 (wh->i_fc[1] & IEEE80211_FC1_WEP)) {
1148 if (ieee80211_crypto_encap(ic, ni, m0) == NULL) {
1149 m_freem(m0);
1150 ifp->if_oerrors++;
1151 goto next;
1152 }
1153 frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
1154 }
1155 #endif /* !IEEE80211_NO_HOSTAP */
1156
1157 rateidx = wi_choose_rate(ic, ni, wh, m0->m_pkthdr.len);
1158 rs = &ni->ni_rates;
1159
1160 if (sc->sc_drvbpf) {
1161 struct wi_tx_radiotap_header *tap = &sc->sc_txtap;
1162
1163 tap->wt_rate = rs->rs_rates[rateidx];
1164 tap->wt_chan_freq =
1165 htole16(ic->ic_bss->ni_chan->ic_freq);
1166 tap->wt_chan_flags =
1167 htole16(ic->ic_bss->ni_chan->ic_flags);
1168 /* TBD tap->wt_flags */
1169
1170 bpf_mtap2(sc->sc_drvbpf, tap, tap->wt_ihdr.it_len, m0);
1171 }
1172
1173 rd = SLIST_FIRST(&sc->sc_rssdfree);
1174 id = &rd->rd_desc;
1175 id->id_len = m0->m_pkthdr.len;
1176 id->id_rateidx = ni->ni_txrate;
1177 id->id_rssi = ni->ni_rssi;
1178
1179 frmhdr.wi_tx_idx = rd - sc->sc_rssd;
1180
1181 if (ic->ic_opmode == IEEE80211_M_HOSTAP)
1182 frmhdr.wi_tx_rate = 5 * (rs->rs_rates[rateidx] &
1183 IEEE80211_RATE_VAL);
1184 else if (sc->sc_flags & WI_FLAGS_RSSADAPTSTA)
1185 (void)wi_write_txrate(sc, rs->rs_rates[rateidx]);
1186
1187 m_copydata(m0, 0, sizeof(struct ieee80211_frame),
1188 (void *)&frmhdr.wi_whdr);
1189 m_adj(m0, sizeof(struct ieee80211_frame));
1190 frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
1191 if (IFF_DUMPPKTS(ifp))
1192 wi_dump_pkt(&frmhdr, ni, -1);
1193 fid = sc->sc_txd[cur].d_fid;
1194 off = sizeof(frmhdr);
1195 if (wi_write_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0 ||
1196 wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0) {
1197 aprint_error_dev(sc->sc_dev, "%s write fid %x failed\n",
1198 __func__, fid);
1199 ifp->if_oerrors++;
1200 m_freem(m0);
1201 goto next;
1202 }
1203 m_freem(m0);
1204 sc->sc_txpending[ni->ni_txrate]++;
1205 --sc->sc_txalloced;
1206 if (sc->sc_txqueued++ == 0) {
1207 #ifdef DIAGNOSTIC
1208 if (cur != sc->sc_txstart)
1209 printf("%s: ring is desynchronized\n",
1210 device_xname(sc->sc_dev));
1211 #endif
1212 wi_push_packet(sc);
1213 } else {
1214 #ifdef WI_RING_DEBUG
1215 printf("%s: queue %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1216 device_xname(sc->sc_dev), fid,
1217 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1218 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1219 #endif
1220 }
1221 sc->sc_txqueue = cur = (cur + 1) % WI_NTXBUF;
1222 SLIST_REMOVE_HEAD(&sc->sc_rssdfree, rd_next);
1223 id->id_node = ni;
1224 continue;
1225 next:
1226 if (ni != NULL)
1227 ieee80211_free_node(ni);
1228 }
1229 }
1230
1231
1232 STATIC int
1233 wi_reset(struct wi_softc *sc)
1234 {
1235 int i, error;
1236
1237 DPRINTF(("wi_reset\n"));
1238
1239 if (sc->sc_reset)
1240 (*sc->sc_reset)(sc);
1241
1242 error = 0;
1243 for (i = 0; i < 5; i++) {
1244 if (sc->sc_invalid)
1245 return ENXIO;
1246 DELAY(20*1000); /* XXX: way too long! */
1247 if ((error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0)) == 0)
1248 break;
1249 }
1250 if (error) {
1251 aprint_error_dev(sc->sc_dev, "init failed\n");
1252 return error;
1253 }
1254 CSR_WRITE_2(sc, WI_INT_EN, 0);
1255 CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
1256
1257 /* Calibrate timer. */
1258 wi_write_val(sc, WI_RID_TICK_TIME, 0);
1259 return 0;
1260 }
1261
1262 STATIC void
1263 wi_watchdog(struct ifnet *ifp)
1264 {
1265 struct wi_softc *sc = ifp->if_softc;
1266
1267 ifp->if_timer = 0;
1268 if (!sc->sc_enabled)
1269 return;
1270
1271 if (sc->sc_tx_timer) {
1272 if (--sc->sc_tx_timer == 0) {
1273 printf("%s: device timeout\n", ifp->if_xname);
1274 ifp->if_oerrors++;
1275 wi_init(ifp);
1276 return;
1277 }
1278 ifp->if_timer = 1;
1279 }
1280
1281 if (sc->sc_scan_timer) {
1282 if (--sc->sc_scan_timer <= WI_SCAN_WAIT - WI_SCAN_INQWAIT &&
1283 sc->sc_firmware_type == WI_INTERSIL) {
1284 DPRINTF(("wi_watchdog: inquire scan\n"));
1285 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
1286 }
1287 if (sc->sc_scan_timer)
1288 ifp->if_timer = 1;
1289 }
1290
1291 /* TODO: rate control */
1292 ieee80211_watchdog(&sc->sc_ic);
1293 }
1294
1295 static int
1296 wi_ioctl_enter(struct wi_softc *sc)
1297 {
1298 int rc = 0;
1299
1300 mutex_enter(&sc->sc_ioctl_mtx);
1301 sc->sc_ioctl_nwait++;
1302 while (sc->sc_ioctl_lwp != NULL && sc->sc_ioctl_lwp != curlwp) {
1303 rc = sc->sc_ioctl_gone
1304 ? ENXIO
1305 : cv_wait_sig(&sc->sc_ioctl_cv, &sc->sc_ioctl_mtx);
1306 if (rc != 0)
1307 break;
1308 }
1309 if (rc == 0) {
1310 sc->sc_ioctl_lwp = curlwp;
1311 sc->sc_ioctl_depth++;
1312 }
1313 if (--sc->sc_ioctl_nwait == 0)
1314 cv_signal(&sc->sc_ioctl_cv);
1315 mutex_exit(&sc->sc_ioctl_mtx);
1316 return rc;
1317 }
1318
1319 static void
1320 wi_ioctl_exit(struct wi_softc *sc)
1321 {
1322 KASSERT(sc->sc_ioctl_lwp == curlwp);
1323 mutex_enter(&sc->sc_ioctl_mtx);
1324 if (--sc->sc_ioctl_depth == 0) {
1325 sc->sc_ioctl_lwp = NULL;
1326 cv_signal(&sc->sc_ioctl_cv);
1327 }
1328 mutex_exit(&sc->sc_ioctl_mtx);
1329 }
1330
1331 static void
1332 wi_ioctl_init(struct wi_softc *sc)
1333 {
1334 mutex_init(&sc->sc_ioctl_mtx, MUTEX_DEFAULT, IPL_NONE);
1335 cv_init(&sc->sc_ioctl_cv, device_xname(sc->sc_dev));
1336 }
1337
1338 static void
1339 wi_ioctl_drain(struct wi_softc *sc)
1340 {
1341 wi_ioctl_enter(sc);
1342
1343 mutex_enter(&sc->sc_ioctl_mtx);
1344 sc->sc_ioctl_gone = true;
1345 cv_broadcast(&sc->sc_ioctl_cv);
1346 while (sc->sc_ioctl_nwait != 0)
1347 cv_wait(&sc->sc_ioctl_cv, &sc->sc_ioctl_mtx);
1348 mutex_exit(&sc->sc_ioctl_mtx);
1349
1350 wi_ioctl_exit(sc);
1351
1352 mutex_destroy(&sc->sc_ioctl_mtx);
1353 cv_destroy(&sc->sc_ioctl_cv);
1354 }
1355
1356 STATIC int
1357 wi_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1358 {
1359 struct wi_softc *sc = ifp->if_softc;
1360 struct ieee80211com *ic = &sc->sc_ic;
1361 struct ifreq *ifr = (struct ifreq *)data;
1362 int s, error = 0;
1363
1364 if (!device_is_active(sc->sc_dev))
1365 return ENXIO;
1366
1367 s = splnet();
1368
1369 if ((error = wi_ioctl_enter(sc)) != 0) {
1370 splx(s);
1371 return error;
1372 }
1373
1374 switch (cmd) {
1375 case SIOCSIFFLAGS:
1376 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
1377 break;
1378 /*
1379 * Can't do promisc and hostap at the same time. If all that's
1380 * changing is the promisc flag, try to short-circuit a call to
1381 * wi_init() by just setting PROMISC in the hardware.
1382 */
1383 if (ifp->if_flags & IFF_UP) {
1384 if (sc->sc_enabled) {
1385 if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
1386 (ifp->if_flags & IFF_PROMISC) != 0)
1387 wi_write_val(sc, WI_RID_PROMISC, 1);
1388 else
1389 wi_write_val(sc, WI_RID_PROMISC, 0);
1390 } else
1391 error = wi_init(ifp);
1392 } else if (sc->sc_enabled)
1393 wi_stop(ifp, 1);
1394 break;
1395 case SIOCSIFMEDIA:
1396 case SIOCGIFMEDIA:
1397 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1398 break;
1399 case SIOCADDMULTI:
1400 case SIOCDELMULTI:
1401 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
1402 if (ifp->if_flags & IFF_RUNNING) {
1403 /* do not rescan */
1404 error = wi_write_multi(sc);
1405 } else
1406 error = 0;
1407 }
1408 break;
1409 case SIOCGIFGENERIC:
1410 error = wi_get_cfg(ifp, cmd, data);
1411 break;
1412 case SIOCSIFGENERIC:
1413 error = kauth_authorize_network(curlwp->l_cred,
1414 KAUTH_NETWORK_INTERFACE,
1415 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, KAUTH_ARG(cmd),
1416 NULL);
1417 if (error)
1418 break;
1419 error = wi_set_cfg(ifp, cmd, data);
1420 if (error == ENETRESET) {
1421 if (ifp->if_flags & IFF_RUNNING)
1422 error = wi_init(ifp);
1423 else
1424 error = 0;
1425 }
1426 break;
1427 case SIOCS80211BSSID:
1428 if (sc->sc_firmware_type == WI_LUCENT) {
1429 error = ENODEV;
1430 break;
1431 }
1432 /* fall through */
1433 default:
1434 ic->ic_flags |= sc->sc_ic_flags;
1435 error = ieee80211_ioctl(&sc->sc_ic, cmd, data);
1436 sc->sc_ic_flags = ic->ic_flags & IEEE80211_F_DROPUNENC;
1437 if (error == ENETRESET) {
1438 if (sc->sc_enabled)
1439 error = wi_init(ifp);
1440 else
1441 error = 0;
1442 }
1443 break;
1444 }
1445 wi_mend_flags(sc, ic->ic_state);
1446 wi_ioctl_exit(sc);
1447 splx(s);
1448 return error;
1449 }
1450
1451 STATIC int
1452 wi_media_change(struct ifnet *ifp)
1453 {
1454 struct wi_softc *sc = ifp->if_softc;
1455 struct ieee80211com *ic = &sc->sc_ic;
1456 int error;
1457
1458 error = ieee80211_media_change(ifp);
1459 if (error == ENETRESET) {
1460 if (sc->sc_enabled)
1461 error = wi_init(ifp);
1462 else
1463 error = 0;
1464 }
1465 ifp->if_baudrate = ifmedia_baudrate(ic->ic_media.ifm_cur->ifm_media);
1466
1467 return error;
1468 }
1469
1470 STATIC void
1471 wi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1472 {
1473 struct wi_softc *sc = ifp->if_softc;
1474 struct ieee80211com *ic = &sc->sc_ic;
1475 u_int16_t val;
1476 int rate;
1477
1478 if (sc->sc_enabled == 0) {
1479 imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
1480 imr->ifm_status = 0;
1481 return;
1482 }
1483
1484 imr->ifm_status = IFM_AVALID;
1485 imr->ifm_active = IFM_IEEE80211;
1486 if (ic->ic_state == IEEE80211_S_RUN &&
1487 (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0)
1488 imr->ifm_status |= IFM_ACTIVE;
1489 if (wi_read_xrid(sc, WI_RID_CUR_TX_RATE, &val, sizeof(val)) == 0) {
1490 /* convert to 802.11 rate */
1491 val = le16toh(val);
1492 rate = val * 2;
1493 if (sc->sc_firmware_type == WI_LUCENT) {
1494 if (rate == 10)
1495 rate = 11; /* 5.5Mbps */
1496 } else {
1497 if (rate == 4*2)
1498 rate = 11; /* 5.5Mbps */
1499 else if (rate == 8*2)
1500 rate = 22; /* 11Mbps */
1501 }
1502 } else
1503 rate = 0;
1504 imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B);
1505 switch (ic->ic_opmode) {
1506 case IEEE80211_M_STA:
1507 break;
1508 case IEEE80211_M_IBSS:
1509 imr->ifm_active |= IFM_IEEE80211_ADHOC;
1510 break;
1511 case IEEE80211_M_AHDEMO:
1512 imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0;
1513 break;
1514 case IEEE80211_M_HOSTAP:
1515 imr->ifm_active |= IFM_IEEE80211_HOSTAP;
1516 break;
1517 case IEEE80211_M_MONITOR:
1518 imr->ifm_active |= IFM_IEEE80211_MONITOR;
1519 break;
1520 }
1521 }
1522
1523 STATIC struct ieee80211_node *
1524 wi_node_alloc(struct ieee80211_node_table *nt)
1525 {
1526 struct wi_node *wn =
1527 malloc(sizeof(struct wi_node), M_DEVBUF, M_NOWAIT | M_ZERO);
1528 return wn ? &wn->wn_node : NULL;
1529 }
1530
1531 STATIC void
1532 wi_node_free(struct ieee80211_node *ni)
1533 {
1534 struct wi_softc *sc = ni->ni_ic->ic_ifp->if_softc;
1535 int i;
1536
1537 for (i = 0; i < WI_NTXRSS; i++) {
1538 if (sc->sc_rssd[i].rd_desc.id_node == ni)
1539 sc->sc_rssd[i].rd_desc.id_node = NULL;
1540 }
1541 free(ni, M_DEVBUF);
1542 }
1543
1544 STATIC void
1545 wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN])
1546 {
1547 struct ieee80211com *ic = &sc->sc_ic;
1548 struct ieee80211_node *ni = ic->ic_bss;
1549 struct ifnet *ifp = &sc->sc_if;
1550
1551 if (IEEE80211_ADDR_EQ(new_bssid, ni->ni_bssid))
1552 return;
1553
1554 DPRINTF(("wi_sync_bssid: bssid %s -> ", ether_sprintf(ni->ni_bssid)));
1555 DPRINTF(("%s ?\n", ether_sprintf(new_bssid)));
1556
1557 /* In promiscuous mode, the BSSID field is not a reliable
1558 * indicator of the firmware's BSSID. Damp spurious
1559 * change-of-BSSID indications.
1560 */
1561 if ((ifp->if_flags & IFF_PROMISC) != 0 &&
1562 !ppsratecheck(&sc->sc_last_syn, &sc->sc_false_syns,
1563 WI_MAX_FALSE_SYNS))
1564 return;
1565
1566 sc->sc_false_syns = MAX(0, sc->sc_false_syns - 1);
1567 /*
1568 * XXX hack; we should create a new node with the new bssid
1569 * and replace the existing ic_bss with it but since we don't
1570 * process management frames to collect state we cheat by
1571 * reusing the existing node as we know wi_newstate will be
1572 * called and it will overwrite the node state.
1573 */
1574 ieee80211_sta_join(ic, ieee80211_ref_node(ni));
1575 }
1576
1577 static inline void
1578 wi_rssadapt_input(struct ieee80211com *ic, struct ieee80211_node *ni,
1579 struct ieee80211_frame *wh, int rssi)
1580 {
1581 struct wi_node *wn;
1582
1583 if (ni == NULL) {
1584 printf("%s: null node", __func__);
1585 return;
1586 }
1587
1588 wn = (void*)ni;
1589 ieee80211_rssadapt_input(ic, ni, &wn->wn_rssadapt, rssi);
1590 }
1591
1592 STATIC void
1593 wi_rx_intr(struct wi_softc *sc)
1594 {
1595 struct ieee80211com *ic = &sc->sc_ic;
1596 struct ifnet *ifp = &sc->sc_if;
1597 struct ieee80211_node *ni;
1598 struct wi_frame frmhdr;
1599 struct mbuf *m;
1600 struct ieee80211_frame *wh;
1601 int fid, len, off, rssi;
1602 u_int8_t dir;
1603 u_int16_t status;
1604 u_int32_t rstamp;
1605
1606 fid = CSR_READ_2(sc, WI_RX_FID);
1607
1608 /* First read in the frame header */
1609 if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) {
1610 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n",
1611 __func__, fid);
1612 ifp->if_ierrors++;
1613 return;
1614 }
1615
1616 if (IFF_DUMPPKTS(ifp))
1617 wi_dump_pkt(&frmhdr, NULL, frmhdr.wi_rx_signal);
1618
1619 /*
1620 * Drop undecryptable or packets with receive errors here
1621 */
1622 status = le16toh(frmhdr.wi_status);
1623 if ((status & WI_STAT_ERRSTAT) != 0 &&
1624 ic->ic_opmode != IEEE80211_M_MONITOR) {
1625 ifp->if_ierrors++;
1626 DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status));
1627 return;
1628 }
1629 rssi = frmhdr.wi_rx_signal;
1630 rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) |
1631 le16toh(frmhdr.wi_rx_tstamp1);
1632
1633 len = le16toh(frmhdr.wi_dat_len);
1634 off = ALIGN(sizeof(struct ieee80211_frame));
1635
1636 /* Sometimes the PRISM2.x returns bogusly large frames. Except
1637 * in monitor mode, just throw them away.
1638 */
1639 if (off + len > MCLBYTES) {
1640 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1641 ifp->if_ierrors++;
1642 DPRINTF(("wi_rx_intr: oversized packet\n"));
1643 return;
1644 } else
1645 len = 0;
1646 }
1647
1648 MGETHDR(m, M_DONTWAIT, MT_DATA);
1649 if (m == NULL) {
1650 ifp->if_ierrors++;
1651 DPRINTF(("wi_rx_intr: MGET failed\n"));
1652 return;
1653 }
1654 if (off + len > MHLEN) {
1655 MCLGET(m, M_DONTWAIT);
1656 if ((m->m_flags & M_EXT) == 0) {
1657 m_freem(m);
1658 ifp->if_ierrors++;
1659 DPRINTF(("wi_rx_intr: MCLGET failed\n"));
1660 return;
1661 }
1662 }
1663
1664 m->m_data += off - sizeof(struct ieee80211_frame);
1665 memcpy(m->m_data, &frmhdr.wi_whdr, sizeof(struct ieee80211_frame));
1666 wi_read_bap(sc, fid, sizeof(frmhdr),
1667 m->m_data + sizeof(struct ieee80211_frame), len);
1668 m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len;
1669 m_set_rcvif(m, ifp);
1670
1671 wh = mtod(m, struct ieee80211_frame *);
1672 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1673 /*
1674 * WEP is decrypted by hardware. Clear WEP bit
1675 * header for ieee80211_input().
1676 */
1677 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1678 }
1679 if (sc->sc_drvbpf) {
1680 struct wi_rx_radiotap_header *tap = &sc->sc_rxtap;
1681
1682 tap->wr_rate = frmhdr.wi_rx_rate / 5;
1683 tap->wr_antsignal = frmhdr.wi_rx_signal;
1684 tap->wr_antnoise = frmhdr.wi_rx_silence;
1685 tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
1686 tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
1687 if (frmhdr.wi_status & WI_STAT_PCF)
1688 tap->wr_flags |= IEEE80211_RADIOTAP_F_CFP;
1689
1690 /* XXX IEEE80211_RADIOTAP_F_WEP */
1691 bpf_mtap2(sc->sc_drvbpf, tap, tap->wr_ihdr.it_len, m);
1692 }
1693
1694 /* synchronize driver's BSSID with firmware's BSSID */
1695 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
1696 if (ic->ic_opmode == IEEE80211_M_IBSS && dir == IEEE80211_FC1_DIR_NODS)
1697 wi_sync_bssid(sc, wh->i_addr3);
1698
1699 ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
1700
1701 ieee80211_input(ic, m, ni, rssi, rstamp);
1702
1703 wi_rssadapt_input(ic, ni, wh, rssi);
1704
1705 /*
1706 * The frame may have caused the node to be marked for
1707 * reclamation (e.g. in response to a DEAUTH message)
1708 * so use release_node here instead of unref_node.
1709 */
1710 ieee80211_free_node(ni);
1711 }
1712
1713 STATIC void
1714 wi_tx_ex_intr(struct wi_softc *sc)
1715 {
1716 struct ieee80211com *ic = &sc->sc_ic;
1717 struct ifnet *ifp = &sc->sc_if;
1718 struct ieee80211_node *ni;
1719 struct ieee80211_rssdesc *id;
1720 struct wi_rssdesc *rssd;
1721 struct wi_frame frmhdr;
1722 int fid;
1723 u_int16_t status;
1724
1725 fid = CSR_READ_2(sc, WI_TX_CMP_FID);
1726 /* Read in the frame header */
1727 if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0) {
1728 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n",
1729 __func__, fid);
1730 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1731 &sc->sc_txpending);
1732 goto out;
1733 }
1734
1735 if (frmhdr.wi_tx_idx >= WI_NTXRSS) {
1736 aprint_error_dev(sc->sc_dev, "%s bad idx %02x\n",
1737 __func__, frmhdr.wi_tx_idx);
1738 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1739 &sc->sc_txpending);
1740 goto out;
1741 }
1742
1743 status = le16toh(frmhdr.wi_status);
1744
1745 /*
1746 * Spontaneous station disconnects appear as xmit
1747 * errors. Don't announce them and/or count them
1748 * as an output error.
1749 */
1750 if (ppsratecheck(&lasttxerror, &curtxeps, wi_txerate)) {
1751 aprint_error_dev(sc->sc_dev, "tx failed");
1752 if (status & WI_TXSTAT_RET_ERR)
1753 printf(", retry limit exceeded");
1754 if (status & WI_TXSTAT_AGED_ERR)
1755 printf(", max transmit lifetime exceeded");
1756 if (status & WI_TXSTAT_DISCONNECT)
1757 printf(", port disconnected");
1758 if (status & WI_TXSTAT_FORM_ERR)
1759 printf(", invalid format (data len %u src %s)",
1760 le16toh(frmhdr.wi_dat_len),
1761 ether_sprintf(frmhdr.wi_ehdr.ether_shost));
1762 if (status & ~0xf)
1763 printf(", status=0x%x", status);
1764 printf("\n");
1765 }
1766 ifp->if_oerrors++;
1767 rssd = &sc->sc_rssd[frmhdr.wi_tx_idx];
1768 id = &rssd->rd_desc;
1769 if ((status & WI_TXSTAT_RET_ERR) != 0)
1770 wi_lower_rate(ic, id);
1771
1772 ni = id->id_node;
1773 id->id_node = NULL;
1774
1775 if (ni == NULL) {
1776 aprint_error_dev(sc->sc_dev, "%s null node, rssdesc %02x\n",
1777 __func__, frmhdr.wi_tx_idx);
1778 goto out;
1779 }
1780
1781 if (sc->sc_txpending[id->id_rateidx]-- == 0) {
1782 aprint_error_dev(sc->sc_dev, "%s txpending[%i] wraparound",
1783 __func__, id->id_rateidx);
1784 sc->sc_txpending[id->id_rateidx] = 0;
1785 }
1786 if (ni != NULL)
1787 ieee80211_free_node(ni);
1788 SLIST_INSERT_HEAD(&sc->sc_rssdfree, rssd, rd_next);
1789 out:
1790 ifp->if_flags &= ~IFF_OACTIVE;
1791 }
1792
1793 STATIC void
1794 wi_txalloc_intr(struct wi_softc *sc)
1795 {
1796 int fid, cur;
1797
1798 fid = CSR_READ_2(sc, WI_ALLOC_FID);
1799
1800 cur = sc->sc_txalloc;
1801 #ifdef DIAGNOSTIC
1802 if (sc->sc_txstarted == 0) {
1803 printf("%s: spurious alloc %x != %x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1804 device_xname(sc->sc_dev), fid, sc->sc_txd[cur].d_fid, cur,
1805 sc->sc_txqueue, sc->sc_txstart, sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1806 return;
1807 }
1808 #endif
1809 --sc->sc_txstarted;
1810 ++sc->sc_txalloced;
1811 sc->sc_txd[cur].d_fid = fid;
1812 sc->sc_txalloc = (cur + 1) % WI_NTXBUF;
1813 #ifdef WI_RING_DEBUG
1814 printf("%s: alloc %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1815 device_xname(sc->sc_dev), fid,
1816 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1817 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1818 #endif
1819 }
1820
1821 STATIC void
1822 wi_cmd_intr(struct wi_softc *sc)
1823 {
1824 struct ifnet *ifp = &sc->sc_if;
1825
1826 if (sc->sc_invalid)
1827 return;
1828 #ifdef WI_DEBUG
1829 if (wi_debug > 1)
1830 printf("%s: %d txcmds outstanding\n", __func__, sc->sc_txcmds);
1831 #endif
1832 KASSERT(sc->sc_txcmds > 0);
1833
1834 --sc->sc_txcmds;
1835
1836 if (--sc->sc_txqueued == 0) {
1837 sc->sc_tx_timer = 0;
1838 ifp->if_flags &= ~IFF_OACTIVE;
1839 #ifdef WI_RING_DEBUG
1840 printf("%s: cmd , alloc %d queue %d start %d alloced %d queued %d started %d\n",
1841 device_xname(sc->sc_dev),
1842 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1843 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1844 #endif
1845 } else
1846 wi_push_packet(sc);
1847 }
1848
1849 STATIC void
1850 wi_push_packet(struct wi_softc *sc)
1851 {
1852 struct ifnet *ifp = &sc->sc_if;
1853 int cur, fid;
1854
1855 cur = sc->sc_txstart;
1856 fid = sc->sc_txd[cur].d_fid;
1857
1858 KASSERT(sc->sc_txcmds == 0);
1859
1860 if (wi_cmd_start(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0)) {
1861 aprint_error_dev(sc->sc_dev, "xmit failed\n");
1862 /* XXX ring might have a hole */
1863 }
1864
1865 if (sc->sc_txcmds++ > 0)
1866 printf("%s: %d tx cmds pending!!!\n", __func__, sc->sc_txcmds);
1867
1868 ++sc->sc_txstarted;
1869 #ifdef DIAGNOSTIC
1870 if (sc->sc_txstarted > WI_NTXBUF)
1871 aprint_error_dev(sc->sc_dev, "too many buffers started\n");
1872 #endif
1873 sc->sc_txstart = (cur + 1) % WI_NTXBUF;
1874 sc->sc_tx_timer = 5;
1875 ifp->if_timer = 1;
1876 #ifdef WI_RING_DEBUG
1877 printf("%s: push %04x, alloc %d queue %d start %d alloced %d queued %d started %d\n",
1878 device_xname(sc->sc_dev), fid,
1879 sc->sc_txalloc, sc->sc_txqueue, sc->sc_txstart,
1880 sc->sc_txalloced, sc->sc_txqueued, sc->sc_txstarted);
1881 #endif
1882 }
1883
1884 STATIC void
1885 wi_tx_intr(struct wi_softc *sc)
1886 {
1887 struct ieee80211com *ic = &sc->sc_ic;
1888 struct ifnet *ifp = &sc->sc_if;
1889 struct ieee80211_node *ni;
1890 struct ieee80211_rssdesc *id;
1891 struct wi_rssdesc *rssd;
1892 struct wi_frame frmhdr;
1893 int fid;
1894
1895 fid = CSR_READ_2(sc, WI_TX_CMP_FID);
1896 /* Read in the frame header */
1897 if (wi_read_bap(sc, fid, offsetof(struct wi_frame, wi_tx_swsup2),
1898 &frmhdr.wi_tx_swsup2, 2) != 0) {
1899 aprint_error_dev(sc->sc_dev, "%s read fid %x failed\n",
1900 __func__, fid);
1901 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1902 &sc->sc_txpending);
1903 goto out;
1904 }
1905
1906 if (frmhdr.wi_tx_idx >= WI_NTXRSS) {
1907 aprint_error_dev(sc->sc_dev, "%s bad idx %02x\n",
1908 __func__, frmhdr.wi_tx_idx);
1909 wi_rssdescs_reset(ic, &sc->sc_rssd, &sc->sc_rssdfree,
1910 &sc->sc_txpending);
1911 goto out;
1912 }
1913
1914 rssd = &sc->sc_rssd[frmhdr.wi_tx_idx];
1915 id = &rssd->rd_desc;
1916 wi_raise_rate(ic, id);
1917
1918 ni = id->id_node;
1919 id->id_node = NULL;
1920
1921 if (ni == NULL) {
1922 aprint_error_dev(sc->sc_dev, "%s null node, rssdesc %02x\n",
1923 __func__, frmhdr.wi_tx_idx);
1924 goto out;
1925 }
1926
1927 if (sc->sc_txpending[id->id_rateidx]-- == 0) {
1928 aprint_error_dev(sc->sc_dev, "%s txpending[%i] wraparound",
1929 __func__, id->id_rateidx);
1930 sc->sc_txpending[id->id_rateidx] = 0;
1931 }
1932 if (ni != NULL)
1933 ieee80211_free_node(ni);
1934 SLIST_INSERT_HEAD(&sc->sc_rssdfree, rssd, rd_next);
1935 out:
1936 ifp->if_flags &= ~IFF_OACTIVE;
1937 }
1938
1939 STATIC void
1940 wi_info_intr(struct wi_softc *sc)
1941 {
1942 struct ieee80211com *ic = &sc->sc_ic;
1943 struct ifnet *ifp = &sc->sc_if;
1944 int i, fid, len, off;
1945 u_int16_t ltbuf[2];
1946 u_int16_t stat;
1947 u_int32_t *ptr;
1948
1949 fid = CSR_READ_2(sc, WI_INFO_FID);
1950 wi_read_bap(sc, fid, 0, ltbuf, sizeof(ltbuf));
1951
1952 switch (le16toh(ltbuf[1])) {
1953
1954 case WI_INFO_LINK_STAT:
1955 wi_read_bap(sc, fid, sizeof(ltbuf), &stat, sizeof(stat));
1956 DPRINTF(("wi_info_intr: LINK_STAT 0x%x\n", le16toh(stat)));
1957 switch (le16toh(stat)) {
1958 case CONNECTED:
1959 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
1960 if (ic->ic_state == IEEE80211_S_RUN &&
1961 ic->ic_opmode != IEEE80211_M_IBSS)
1962 break;
1963 /* FALLTHROUGH */
1964 case AP_CHANGE:
1965 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1966 break;
1967 case AP_IN_RANGE:
1968 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
1969 break;
1970 case AP_OUT_OF_RANGE:
1971 if (sc->sc_firmware_type == WI_SYMBOL &&
1972 sc->sc_scan_timer > 0) {
1973 if (wi_cmd(sc, WI_CMD_INQUIRE,
1974 WI_INFO_HOST_SCAN_RESULTS, 0, 0) != 0)
1975 sc->sc_scan_timer = 0;
1976 break;
1977 }
1978 if (ic->ic_opmode == IEEE80211_M_STA)
1979 sc->sc_flags |= WI_FLAGS_OUTRANGE;
1980 break;
1981 case DISCONNECTED:
1982 case ASSOC_FAILED:
1983 if (ic->ic_opmode == IEEE80211_M_STA)
1984 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1985 break;
1986 }
1987 break;
1988
1989 case WI_INFO_COUNTERS:
1990 /* some card versions have a larger stats structure */
1991 len = min(le16toh(ltbuf[0]) - 1, sizeof(sc->sc_stats) / 4);
1992 ptr = (u_int32_t *)&sc->sc_stats;
1993 off = sizeof(ltbuf);
1994 for (i = 0; i < len; i++, off += 2, ptr++) {
1995 wi_read_bap(sc, fid, off, &stat, sizeof(stat));
1996 stat = le16toh(stat);
1997 #ifdef WI_HERMES_STATS_WAR
1998 if (stat & 0xf000)
1999 stat = ~stat;
2000 #endif
2001 *ptr += stat;
2002 }
2003 ifp->if_collisions = sc->sc_stats.wi_tx_single_retries +
2004 sc->sc_stats.wi_tx_multi_retries +
2005 sc->sc_stats.wi_tx_retry_limit;
2006 break;
2007
2008 case WI_INFO_SCAN_RESULTS:
2009 case WI_INFO_HOST_SCAN_RESULTS:
2010 wi_scan_result(sc, fid, le16toh(ltbuf[0]));
2011 break;
2012
2013 default:
2014 DPRINTF(("wi_info_intr: got fid %x type %x len %d\n", fid,
2015 le16toh(ltbuf[1]), le16toh(ltbuf[0])));
2016 break;
2017 }
2018 }
2019
2020 STATIC int
2021 wi_write_multi(struct wi_softc *sc)
2022 {
2023 struct ifnet *ifp = &sc->sc_if;
2024 int n;
2025 struct wi_mcast mlist;
2026 struct ether_multi *enm;
2027 struct ether_multistep estep;
2028
2029 if ((ifp->if_flags & IFF_PROMISC) != 0) {
2030 allmulti:
2031 ifp->if_flags |= IFF_ALLMULTI;
2032 memset(&mlist, 0, sizeof(mlist));
2033 return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
2034 sizeof(mlist));
2035 }
2036
2037 n = 0;
2038 ETHER_FIRST_MULTI(estep, &sc->sc_ec, enm);
2039 while (enm != NULL) {
2040 /* Punt on ranges or too many multicast addresses. */
2041 if (!IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi) ||
2042 n >= sizeof(mlist) / sizeof(mlist.wi_mcast[0]))
2043 goto allmulti;
2044
2045 IEEE80211_ADDR_COPY(&mlist.wi_mcast[n], enm->enm_addrlo);
2046 n++;
2047 ETHER_NEXT_MULTI(estep, enm);
2048 }
2049 ifp->if_flags &= ~IFF_ALLMULTI;
2050 return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
2051 IEEE80211_ADDR_LEN * n);
2052 }
2053
2054
2055 STATIC void
2056 wi_read_nicid(struct wi_softc *sc)
2057 {
2058 struct wi_card_ident *id;
2059 char *p;
2060 int len;
2061 u_int16_t ver[4];
2062
2063 /* getting chip identity */
2064 memset(ver, 0, sizeof(ver));
2065 len = sizeof(ver);
2066 wi_read_rid(sc, WI_RID_CARD_ID, ver, &len);
2067 printf("%s: using ", device_xname(sc->sc_dev));
2068 DPRINTF2(("wi_read_nicid: CARD_ID: %x %x %x %x\n", le16toh(ver[0]), le16toh(ver[1]), le16toh(ver[2]), le16toh(ver[3])));
2069
2070 sc->sc_firmware_type = WI_NOTYPE;
2071 for (id = wi_card_ident; id->card_name != NULL; id++) {
2072 if (le16toh(ver[0]) == id->card_id) {
2073 printf("%s", id->card_name);
2074 sc->sc_firmware_type = id->firm_type;
2075 break;
2076 }
2077 }
2078 if (sc->sc_firmware_type == WI_NOTYPE) {
2079 if (le16toh(ver[0]) & 0x8000) {
2080 printf("Unknown PRISM2 chip");
2081 sc->sc_firmware_type = WI_INTERSIL;
2082 } else {
2083 printf("Unknown Lucent chip");
2084 sc->sc_firmware_type = WI_LUCENT;
2085 }
2086 }
2087
2088 /* get primary firmware version (Only Prism chips) */
2089 if (sc->sc_firmware_type != WI_LUCENT) {
2090 memset(ver, 0, sizeof(ver));
2091 len = sizeof(ver);
2092 wi_read_rid(sc, WI_RID_PRI_IDENTITY, ver, &len);
2093 sc->sc_pri_firmware_ver = le16toh(ver[2]) * 10000 +
2094 le16toh(ver[3]) * 100 + le16toh(ver[1]);
2095 }
2096
2097 /* get station firmware version */
2098 memset(ver, 0, sizeof(ver));
2099 len = sizeof(ver);
2100 wi_read_rid(sc, WI_RID_STA_IDENTITY, ver, &len);
2101 sc->sc_sta_firmware_ver = le16toh(ver[2]) * 10000 +
2102 le16toh(ver[3]) * 100 + le16toh(ver[1]);
2103 if (sc->sc_firmware_type == WI_INTERSIL &&
2104 (sc->sc_sta_firmware_ver == 10102 ||
2105 sc->sc_sta_firmware_ver == 20102)) {
2106 char ident[12];
2107 memset(ident, 0, sizeof(ident));
2108 len = sizeof(ident);
2109 /* value should be the format like "V2.00-11" */
2110 if (wi_read_rid(sc, WI_RID_SYMBOL_IDENTITY, ident, &len) == 0 &&
2111 *(p = (char *)ident) >= 'A' &&
2112 p[2] == '.' && p[5] == '-' && p[8] == '\0') {
2113 sc->sc_firmware_type = WI_SYMBOL;
2114 sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +
2115 (p[3] - '0') * 1000 + (p[4] - '0') * 100 +
2116 (p[6] - '0') * 10 + (p[7] - '0');
2117 }
2118 }
2119
2120 printf("\n%s: %s Firmware: ", device_xname(sc->sc_dev),
2121 sc->sc_firmware_type == WI_LUCENT ? "Lucent" :
2122 (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil"));
2123 if (sc->sc_firmware_type != WI_LUCENT) /* XXX */
2124 printf("Primary (%u.%u.%u), ",
2125 sc->sc_pri_firmware_ver / 10000,
2126 (sc->sc_pri_firmware_ver % 10000) / 100,
2127 sc->sc_pri_firmware_ver % 100);
2128 printf("Station (%u.%u.%u)\n",
2129 sc->sc_sta_firmware_ver / 10000,
2130 (sc->sc_sta_firmware_ver % 10000) / 100,
2131 sc->sc_sta_firmware_ver % 100);
2132 }
2133
2134 STATIC int
2135 wi_write_ssid(struct wi_softc *sc, int rid, u_int8_t *buf, int buflen)
2136 {
2137 struct wi_ssid ssid;
2138
2139 if (buflen > IEEE80211_NWID_LEN)
2140 return ENOBUFS;
2141 memset(&ssid, 0, sizeof(ssid));
2142 ssid.wi_len = htole16(buflen);
2143 memcpy(ssid.wi_ssid, buf, buflen);
2144 return wi_write_rid(sc, rid, &ssid, sizeof(ssid));
2145 }
2146
2147 STATIC int
2148 wi_get_cfg(struct ifnet *ifp, u_long cmd, void *data)
2149 {
2150 struct wi_softc *sc = ifp->if_softc;
2151 struct ieee80211com *ic = &sc->sc_ic;
2152 struct ifreq *ifr = (struct ifreq *)data;
2153 struct wi_req wreq;
2154 int len, n, error;
2155
2156 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
2157 if (error)
2158 return error;
2159 len = (wreq.wi_len - 1) * 2;
2160 if (len < sizeof(u_int16_t))
2161 return ENOSPC;
2162 if (len > sizeof(wreq.wi_val))
2163 len = sizeof(wreq.wi_val);
2164
2165 switch (wreq.wi_type) {
2166
2167 case WI_RID_IFACE_STATS:
2168 memcpy(wreq.wi_val, &sc->sc_stats, sizeof(sc->sc_stats));
2169 if (len < sizeof(sc->sc_stats))
2170 error = ENOSPC;
2171 else
2172 len = sizeof(sc->sc_stats);
2173 break;
2174
2175 case WI_RID_ENCRYPTION:
2176 case WI_RID_TX_CRYPT_KEY:
2177 case WI_RID_DEFLT_CRYPT_KEYS:
2178 case WI_RID_TX_RATE:
2179 return ieee80211_cfgget(ic, cmd, data);
2180
2181 case WI_RID_MICROWAVE_OVEN:
2182 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_MOR)) {
2183 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2184 &len);
2185 break;
2186 }
2187 wreq.wi_val[0] = htole16(sc->sc_microwave_oven);
2188 len = sizeof(u_int16_t);
2189 break;
2190
2191 case WI_RID_DBM_ADJUST:
2192 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_DBMADJUST)) {
2193 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2194 &len);
2195 break;
2196 }
2197 wreq.wi_val[0] = htole16(sc->sc_dbm_offset);
2198 len = sizeof(u_int16_t);
2199 break;
2200
2201 case WI_RID_ROAMING_MODE:
2202 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_ROAMING)) {
2203 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2204 &len);
2205 break;
2206 }
2207 wreq.wi_val[0] = htole16(sc->sc_roaming_mode);
2208 len = sizeof(u_int16_t);
2209 break;
2210
2211 case WI_RID_SYSTEM_SCALE:
2212 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)) {
2213 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2214 &len);
2215 break;
2216 }
2217 wreq.wi_val[0] = htole16(sc->sc_system_scale);
2218 len = sizeof(u_int16_t);
2219 break;
2220
2221 case WI_RID_FRAG_THRESH:
2222 if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)) {
2223 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2224 &len);
2225 break;
2226 }
2227 wreq.wi_val[0] = htole16(sc->sc_frag_thresh);
2228 len = sizeof(u_int16_t);
2229 break;
2230
2231 case WI_RID_READ_APS:
2232 #ifndef IEEE80211_NO_HOSTAP
2233 if (ic->ic_opmode == IEEE80211_M_HOSTAP)
2234 return ieee80211_cfgget(ic, cmd, data);
2235 #endif /* !IEEE80211_NO_HOSTAP */
2236 if (sc->sc_scan_timer > 0) {
2237 error = EINPROGRESS;
2238 break;
2239 }
2240 n = sc->sc_naps;
2241 if (len < sizeof(n)) {
2242 error = ENOSPC;
2243 break;
2244 }
2245 if (len < sizeof(n) + sizeof(struct wi_apinfo) * n)
2246 n = (len - sizeof(n)) / sizeof(struct wi_apinfo);
2247 len = sizeof(n) + sizeof(struct wi_apinfo) * n;
2248 memcpy(wreq.wi_val, &n, sizeof(n));
2249 memcpy((char *)wreq.wi_val + sizeof(n), sc->sc_aps,
2250 sizeof(struct wi_apinfo) * n);
2251 break;
2252
2253 default:
2254 if (sc->sc_enabled) {
2255 error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2256 &len);
2257 break;
2258 }
2259 switch (wreq.wi_type) {
2260 case WI_RID_MAX_DATALEN:
2261 wreq.wi_val[0] = htole16(sc->sc_max_datalen);
2262 len = sizeof(u_int16_t);
2263 break;
2264 case WI_RID_FRAG_THRESH:
2265 wreq.wi_val[0] = htole16(sc->sc_frag_thresh);
2266 len = sizeof(u_int16_t);
2267 break;
2268 case WI_RID_RTS_THRESH:
2269 wreq.wi_val[0] = htole16(sc->sc_rts_thresh);
2270 len = sizeof(u_int16_t);
2271 break;
2272 case WI_RID_CNFAUTHMODE:
2273 wreq.wi_val[0] = htole16(sc->sc_cnfauthmode);
2274 len = sizeof(u_int16_t);
2275 break;
2276 case WI_RID_NODENAME:
2277 if (len < sc->sc_nodelen + sizeof(u_int16_t)) {
2278 error = ENOSPC;
2279 break;
2280 }
2281 len = sc->sc_nodelen + sizeof(u_int16_t);
2282 wreq.wi_val[0] = htole16((sc->sc_nodelen + 1) / 2);
2283 memcpy(&wreq.wi_val[1], sc->sc_nodename,
2284 sc->sc_nodelen);
2285 break;
2286 default:
2287 return ieee80211_cfgget(ic, cmd, data);
2288 }
2289 break;
2290 }
2291 if (error)
2292 return error;
2293 wreq.wi_len = (len + 1) / 2 + 1;
2294 return copyout(&wreq, ifr->ifr_data, (wreq.wi_len + 1) * 2);
2295 }
2296
2297 STATIC int
2298 wi_set_cfg(struct ifnet *ifp, u_long cmd, void *data)
2299 {
2300 struct wi_softc *sc = ifp->if_softc;
2301 struct ieee80211com *ic = &sc->sc_ic;
2302 struct ifreq *ifr = (struct ifreq *)data;
2303 struct ieee80211_rateset *rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
2304 struct wi_req wreq;
2305 struct mbuf *m;
2306 int i, len, error;
2307
2308 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
2309 if (error)
2310 return error;
2311 len = (wreq.wi_len - 1) * 2;
2312 switch (wreq.wi_type) {
2313 case WI_RID_MAC_NODE:
2314 /* XXX convert to SIOCALIFADDR, AF_LINK, IFLR_ACTIVE */
2315 (void)memcpy(ic->ic_myaddr, wreq.wi_val, ETHER_ADDR_LEN);
2316 if_set_sadl(ifp, ic->ic_myaddr, ETHER_ADDR_LEN, false);
2317 wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr,
2318 IEEE80211_ADDR_LEN);
2319 break;
2320
2321 case WI_RID_DBM_ADJUST:
2322 return ENODEV;
2323
2324 case WI_RID_NODENAME:
2325 if (le16toh(wreq.wi_val[0]) * 2 > len ||
2326 le16toh(wreq.wi_val[0]) > sizeof(sc->sc_nodename)) {
2327 error = ENOSPC;
2328 break;
2329 }
2330 if (sc->sc_enabled) {
2331 error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2332 len);
2333 if (error)
2334 break;
2335 }
2336 sc->sc_nodelen = le16toh(wreq.wi_val[0]) * 2;
2337 memcpy(sc->sc_nodename, &wreq.wi_val[1], sc->sc_nodelen);
2338 break;
2339
2340 case WI_RID_MICROWAVE_OVEN:
2341 case WI_RID_ROAMING_MODE:
2342 case WI_RID_SYSTEM_SCALE:
2343 case WI_RID_FRAG_THRESH:
2344 if (wreq.wi_type == WI_RID_MICROWAVE_OVEN &&
2345 (sc->sc_flags & WI_FLAGS_HAS_MOR) == 0)
2346 break;
2347 if (wreq.wi_type == WI_RID_ROAMING_MODE &&
2348 (sc->sc_flags & WI_FLAGS_HAS_ROAMING) == 0)
2349 break;
2350 if (wreq.wi_type == WI_RID_SYSTEM_SCALE &&
2351 (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) == 0)
2352 break;
2353 if (wreq.wi_type == WI_RID_FRAG_THRESH &&
2354 (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) == 0)
2355 break;
2356 /* FALLTHROUGH */
2357 case WI_RID_RTS_THRESH:
2358 case WI_RID_CNFAUTHMODE:
2359 case WI_RID_MAX_DATALEN:
2360 if (sc->sc_enabled) {
2361 error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2362 sizeof(u_int16_t));
2363 if (error)
2364 break;
2365 }
2366 switch (wreq.wi_type) {
2367 case WI_RID_FRAG_THRESH:
2368 sc->sc_frag_thresh = le16toh(wreq.wi_val[0]);
2369 break;
2370 case WI_RID_RTS_THRESH:
2371 sc->sc_rts_thresh = le16toh(wreq.wi_val[0]);
2372 break;
2373 case WI_RID_MICROWAVE_OVEN:
2374 sc->sc_microwave_oven = le16toh(wreq.wi_val[0]);
2375 break;
2376 case WI_RID_ROAMING_MODE:
2377 sc->sc_roaming_mode = le16toh(wreq.wi_val[0]);
2378 break;
2379 case WI_RID_SYSTEM_SCALE:
2380 sc->sc_system_scale = le16toh(wreq.wi_val[0]);
2381 break;
2382 case WI_RID_CNFAUTHMODE:
2383 sc->sc_cnfauthmode = le16toh(wreq.wi_val[0]);
2384 break;
2385 case WI_RID_MAX_DATALEN:
2386 sc->sc_max_datalen = le16toh(wreq.wi_val[0]);
2387 break;
2388 }
2389 break;
2390
2391 case WI_RID_TX_RATE:
2392 switch (le16toh(wreq.wi_val[0])) {
2393 case 3:
2394 ic->ic_fixed_rate = -1;
2395 break;
2396 default:
2397 for (i = 0; i < IEEE80211_RATE_SIZE; i++) {
2398 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL)
2399 / 2 == le16toh(wreq.wi_val[0]))
2400 break;
2401 }
2402 if (i == IEEE80211_RATE_SIZE)
2403 return EINVAL;
2404 ic->ic_fixed_rate = i;
2405 }
2406 if (sc->sc_enabled)
2407 error = wi_cfg_txrate(sc);
2408 break;
2409
2410 case WI_RID_SCAN_APS:
2411 if (sc->sc_enabled && ic->ic_opmode != IEEE80211_M_HOSTAP)
2412 error = wi_scan_ap(sc, 0x3fff, 0x000f);
2413 break;
2414
2415 case WI_RID_MGMT_XMIT:
2416 if (!sc->sc_enabled) {
2417 error = ENETDOWN;
2418 break;
2419 }
2420 if (ic->ic_mgtq.ifq_len > 5) {
2421 error = EAGAIN;
2422 break;
2423 }
2424 /* XXX wi_len looks in u_int8_t, not in u_int16_t */
2425 m = m_devget((char *)&wreq.wi_val, wreq.wi_len, 0, ifp, NULL);
2426 if (m == NULL) {
2427 error = ENOMEM;
2428 break;
2429 }
2430 IF_ENQUEUE(&ic->ic_mgtq, m);
2431 break;
2432
2433 default:
2434 if (sc->sc_enabled) {
2435 error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2436 len);
2437 if (error)
2438 break;
2439 }
2440 error = ieee80211_cfgset(ic, cmd, data);
2441 break;
2442 }
2443 return error;
2444 }
2445
2446 /* Rate is 0 for hardware auto-select, otherwise rate is
2447 * 2, 4, 11, or 22 (units of 500Kbps).
2448 */
2449 STATIC int
2450 wi_write_txrate(struct wi_softc *sc, int rate)
2451 {
2452 u_int16_t hwrate;
2453
2454 /* rate: 0, 2, 4, 11, 22 */
2455 switch (sc->sc_firmware_type) {
2456 case WI_LUCENT:
2457 switch (rate & IEEE80211_RATE_VAL) {
2458 case 2:
2459 hwrate = 1;
2460 break;
2461 case 4:
2462 hwrate = 2;
2463 break;
2464 default:
2465 hwrate = 3; /* auto */
2466 break;
2467 case 11:
2468 hwrate = 4;
2469 break;
2470 case 22:
2471 hwrate = 5;
2472 break;
2473 }
2474 break;
2475 default:
2476 switch (rate & IEEE80211_RATE_VAL) {
2477 case 2:
2478 hwrate = 1;
2479 break;
2480 case 4:
2481 hwrate = 2;
2482 break;
2483 case 11:
2484 hwrate = 4;
2485 break;
2486 case 22:
2487 hwrate = 8;
2488 break;
2489 default:
2490 hwrate = 15; /* auto */
2491 break;
2492 }
2493 break;
2494 }
2495
2496 if (sc->sc_tx_rate == hwrate)
2497 return 0;
2498
2499 if (sc->sc_if.if_flags & IFF_DEBUG)
2500 printf("%s: tx rate %d -> %d (%d)\n", __func__, sc->sc_tx_rate,
2501 hwrate, rate);
2502
2503 sc->sc_tx_rate = hwrate;
2504
2505 return wi_write_val(sc, WI_RID_TX_RATE, sc->sc_tx_rate);
2506 }
2507
2508 STATIC int
2509 wi_cfg_txrate(struct wi_softc *sc)
2510 {
2511 struct ieee80211com *ic = &sc->sc_ic;
2512 struct ieee80211_rateset *rs;
2513 int rate;
2514
2515 rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
2516
2517 sc->sc_tx_rate = 0; /* force write to RID */
2518
2519 if (ic->ic_fixed_rate < 0)
2520 rate = 0; /* auto */
2521 else
2522 rate = rs->rs_rates[ic->ic_fixed_rate];
2523
2524 return wi_write_txrate(sc, rate);
2525 }
2526
2527 STATIC int
2528 wi_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k)
2529 {
2530 struct wi_softc *sc = ic->ic_ifp->if_softc;
2531 u_int keyix = k->wk_keyix;
2532
2533 DPRINTF(("%s: delete key %u\n", __func__, keyix));
2534
2535 if (keyix >= IEEE80211_WEP_NKID)
2536 return 0;
2537 if (k->wk_keylen != 0)
2538 sc->sc_flags &= ~WI_FLAGS_WEP_VALID;
2539
2540 return 1;
2541 }
2542
2543 static int
2544 wi_key_set(struct ieee80211com *ic, const struct ieee80211_key *k,
2545 const u_int8_t mac[IEEE80211_ADDR_LEN])
2546 {
2547 struct wi_softc *sc = ic->ic_ifp->if_softc;
2548
2549 DPRINTF(("%s: set key %u\n", __func__, k->wk_keyix));
2550
2551 if (k->wk_keyix >= IEEE80211_WEP_NKID)
2552 return 0;
2553
2554 sc->sc_flags &= ~WI_FLAGS_WEP_VALID;
2555
2556 return 1;
2557 }
2558
2559 STATIC void
2560 wi_key_update_begin(struct ieee80211com *ic)
2561 {
2562 DPRINTF(("%s:\n", __func__));
2563 }
2564
2565 STATIC void
2566 wi_key_update_end(struct ieee80211com *ic)
2567 {
2568 struct ifnet *ifp = ic->ic_ifp;
2569 struct wi_softc *sc = ifp->if_softc;
2570
2571 DPRINTF(("%s:\n", __func__));
2572
2573 if ((sc->sc_flags & WI_FLAGS_WEP_VALID) != 0)
2574 return;
2575 if ((ic->ic_caps & IEEE80211_C_WEP) != 0 && sc->sc_enabled &&
2576 !sc->sc_invalid)
2577 (void)wi_write_wep(sc);
2578 }
2579
2580 STATIC int
2581 wi_write_wep(struct wi_softc *sc)
2582 {
2583 struct ifnet *ifp = &sc->sc_if;
2584 struct ieee80211com *ic = &sc->sc_ic;
2585 int error = 0;
2586 int i, keylen;
2587 u_int16_t val;
2588 struct wi_key wkey[IEEE80211_WEP_NKID];
2589
2590 if ((ifp->if_flags & IFF_RUNNING) != 0)
2591 wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0);
2592
2593 switch (sc->sc_firmware_type) {
2594 case WI_LUCENT:
2595 val = (ic->ic_flags & IEEE80211_F_PRIVACY) ? 1 : 0;
2596 error = wi_write_val(sc, WI_RID_ENCRYPTION, val);
2597 if (error)
2598 break;
2599 error = wi_write_val(sc, WI_RID_TX_CRYPT_KEY, ic->ic_def_txkey);
2600 if (error)
2601 break;
2602 memset(wkey, 0, sizeof(wkey));
2603 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2604 keylen = ic->ic_nw_keys[i].wk_keylen;
2605 wkey[i].wi_keylen = htole16(keylen);
2606 memcpy(wkey[i].wi_keydat, ic->ic_nw_keys[i].wk_key,
2607 keylen);
2608 }
2609 error = wi_write_rid(sc, WI_RID_DEFLT_CRYPT_KEYS,
2610 wkey, sizeof(wkey));
2611 break;
2612
2613 case WI_INTERSIL:
2614 case WI_SYMBOL:
2615 if (ic->ic_flags & IEEE80211_F_PRIVACY) {
2616 /*
2617 * ONLY HWB3163 EVAL-CARD Firmware version
2618 * less than 0.8 variant2
2619 *
2620 * If promiscuous mode disable, Prism2 chip
2621 * does not work with WEP .
2622 * It is under investigation for details.
2623 * (ichiro (at) NetBSD.org)
2624 */
2625 if (sc->sc_firmware_type == WI_INTERSIL &&
2626 sc->sc_sta_firmware_ver < 802 ) {
2627 /* firm ver < 0.8 variant 2 */
2628 wi_write_val(sc, WI_RID_PROMISC, 1);
2629 }
2630 wi_write_val(sc, WI_RID_CNFAUTHMODE,
2631 sc->sc_cnfauthmode);
2632 val = PRIVACY_INVOKED;
2633 if ((sc->sc_ic_flags & IEEE80211_F_DROPUNENC) != 0)
2634 val |= EXCLUDE_UNENCRYPTED;
2635 #ifndef IEEE80211_NO_HOSTAP
2636 /*
2637 * Encryption firmware has a bug for HostAP mode.
2638 */
2639 if (sc->sc_firmware_type == WI_INTERSIL &&
2640 ic->ic_opmode == IEEE80211_M_HOSTAP)
2641 val |= HOST_ENCRYPT;
2642 #endif /* !IEEE80211_NO_HOSTAP */
2643 } else {
2644 wi_write_val(sc, WI_RID_CNFAUTHMODE,
2645 IEEE80211_AUTH_OPEN);
2646 val = HOST_ENCRYPT | HOST_DECRYPT;
2647 }
2648 error = wi_write_val(sc, WI_RID_P2_ENCRYPTION, val);
2649 if (error)
2650 break;
2651 error = wi_write_val(sc, WI_RID_P2_TX_CRYPT_KEY,
2652 ic->ic_def_txkey);
2653 if (error)
2654 break;
2655 /*
2656 * It seems that the firmware accept 104bit key only if
2657 * all the keys have 104bit length. We get the length of
2658 * the transmit key and use it for all other keys.
2659 * Perhaps we should use software WEP for such situation.
2660 */
2661 if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE ||
2662 IEEE80211_KEY_UNDEFINED(ic->ic_nw_keys[ic->ic_def_txkey]))
2663 keylen = 13; /* No keys => 104bit ok */
2664 else
2665 keylen = ic->ic_nw_keys[ic->ic_def_txkey].wk_keylen;
2666
2667 if (keylen > IEEE80211_WEP_KEYLEN)
2668 keylen = 13; /* 104bit keys */
2669 else
2670 keylen = IEEE80211_WEP_KEYLEN;
2671 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2672 error = wi_write_rid(sc, WI_RID_P2_CRYPT_KEY0 + i,
2673 ic->ic_nw_keys[i].wk_key, keylen);
2674 if (error)
2675 break;
2676 }
2677 break;
2678 }
2679 if ((ifp->if_flags & IFF_RUNNING) != 0)
2680 wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0);
2681 if (error == 0)
2682 sc->sc_flags |= WI_FLAGS_WEP_VALID;
2683 return error;
2684 }
2685
2686 /* Must be called at proper protection level! */
2687 STATIC int
2688 wi_cmd_start(struct wi_softc *sc, int cmd, int val0, int val1, int val2)
2689 {
2690 #ifdef WI_HISTOGRAM
2691 static int hist1[11];
2692 static int hist1count;
2693 #endif
2694 int i;
2695
2696 /* wait for the busy bit to clear */
2697 for (i = 500; i > 0; i--) { /* 5s */
2698 if ((CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY) == 0)
2699 break;
2700 if (sc->sc_invalid)
2701 return ENXIO;
2702 DELAY(1000); /* 1 m sec */
2703 }
2704 if (i == 0) {
2705 aprint_error_dev(sc->sc_dev, "wi_cmd: busy bit won't clear.\n");
2706 return(ETIMEDOUT);
2707 }
2708 #ifdef WI_HISTOGRAM
2709 if (i > 490)
2710 hist1[500 - i]++;
2711 else
2712 hist1[10]++;
2713 if (++hist1count == 1000) {
2714 hist1count = 0;
2715 printf("%s: hist1: %d %d %d %d %d %d %d %d %d %d %d\n",
2716 device_xname(sc->sc_dev),
2717 hist1[0], hist1[1], hist1[2], hist1[3], hist1[4],
2718 hist1[5], hist1[6], hist1[7], hist1[8], hist1[9],
2719 hist1[10]);
2720 }
2721 #endif
2722 CSR_WRITE_2(sc, WI_PARAM0, val0);
2723 CSR_WRITE_2(sc, WI_PARAM1, val1);
2724 CSR_WRITE_2(sc, WI_PARAM2, val2);
2725 CSR_WRITE_2(sc, WI_COMMAND, cmd);
2726
2727 return 0;
2728 }
2729
2730 STATIC int
2731 wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2)
2732 {
2733 int rc;
2734
2735 #ifdef WI_DEBUG
2736 if (wi_debug) {
2737 printf("%s: [enter] %d txcmds outstanding\n", __func__,
2738 sc->sc_txcmds);
2739 }
2740 #endif
2741 if (sc->sc_txcmds > 0)
2742 wi_txcmd_wait(sc);
2743
2744 if ((rc = wi_cmd_start(sc, cmd, val0, val1, val2)) != 0)
2745 return rc;
2746
2747 if (cmd == WI_CMD_INI) {
2748 /* XXX: should sleep here. */
2749 if (sc->sc_invalid)
2750 return ENXIO;
2751 DELAY(100*1000);
2752 }
2753 rc = wi_cmd_wait(sc, cmd, val0);
2754
2755 #ifdef WI_DEBUG
2756 if (wi_debug) {
2757 printf("%s: [ ] %d txcmds outstanding\n", __func__,
2758 sc->sc_txcmds);
2759 }
2760 #endif
2761 if (sc->sc_txcmds > 0)
2762 wi_cmd_intr(sc);
2763
2764 #ifdef WI_DEBUG
2765 if (wi_debug) {
2766 printf("%s: [leave] %d txcmds outstanding\n", __func__,
2767 sc->sc_txcmds);
2768 }
2769 #endif
2770 return rc;
2771 }
2772
2773 STATIC int
2774 wi_cmd_wait(struct wi_softc *sc, int cmd, int val0)
2775 {
2776 #ifdef WI_HISTOGRAM
2777 static int hist2[11];
2778 static int hist2count;
2779 #endif
2780 int i, status;
2781 #ifdef WI_DEBUG
2782 if (wi_debug > 1)
2783 printf("%s: cmd=%#x, arg=%#x\n", __func__, cmd, val0);
2784 #endif /* WI_DEBUG */
2785
2786 /* wait for the cmd completed bit */
2787 for (i = 0; i < WI_TIMEOUT; i++) {
2788 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD)
2789 break;
2790 if (sc->sc_invalid)
2791 return ENXIO;
2792 DELAY(WI_DELAY);
2793 }
2794
2795 #ifdef WI_HISTOGRAM
2796 if (i < 100)
2797 hist2[i/10]++;
2798 else
2799 hist2[10]++;
2800 if (++hist2count == 1000) {
2801 hist2count = 0;
2802 printf("%s: hist2: %d %d %d %d %d %d %d %d %d %d %d\n",
2803 device_xname(sc->sc_dev),
2804 hist2[0], hist2[1], hist2[2], hist2[3], hist2[4],
2805 hist2[5], hist2[6], hist2[7], hist2[8], hist2[9],
2806 hist2[10]);
2807 }
2808 #endif
2809
2810 status = CSR_READ_2(sc, WI_STATUS);
2811
2812 if (i == WI_TIMEOUT) {
2813 aprint_error_dev(sc->sc_dev,
2814 "command timed out, cmd=0x%x, arg=0x%x\n",
2815 cmd, val0);
2816 return ETIMEDOUT;
2817 }
2818
2819 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
2820
2821 if (status & WI_STAT_CMD_RESULT) {
2822 aprint_error_dev(sc->sc_dev,
2823 "command failed, cmd=0x%x, arg=0x%x\n",
2824 cmd, val0);
2825 return EIO;
2826 }
2827 return 0;
2828 }
2829
2830 STATIC int
2831 wi_seek_bap(struct wi_softc *sc, int id, int off)
2832 {
2833 #ifdef WI_HISTOGRAM
2834 static int hist4[11];
2835 static int hist4count;
2836 #endif
2837 int i, status;
2838
2839 CSR_WRITE_2(sc, WI_SEL0, id);
2840 CSR_WRITE_2(sc, WI_OFF0, off);
2841
2842 for (i = 0; ; i++) {
2843 status = CSR_READ_2(sc, WI_OFF0);
2844 if ((status & WI_OFF_BUSY) == 0)
2845 break;
2846 if (i == WI_TIMEOUT) {
2847 aprint_error_dev(sc->sc_dev,
2848 "timeout in wi_seek to %x/%x\n",
2849 id, off);
2850 sc->sc_bap_off = WI_OFF_ERR; /* invalidate */
2851 return ETIMEDOUT;
2852 }
2853 if (sc->sc_invalid)
2854 return ENXIO;
2855 DELAY(2);
2856 }
2857 #ifdef WI_HISTOGRAM
2858 if (i < 100)
2859 hist4[i/10]++;
2860 else
2861 hist4[10]++;
2862 if (++hist4count == 2500) {
2863 hist4count = 0;
2864 printf("%s: hist4: %d %d %d %d %d %d %d %d %d %d %d\n",
2865 device_xname(sc->sc_dev),
2866 hist4[0], hist4[1], hist4[2], hist4[3], hist4[4],
2867 hist4[5], hist4[6], hist4[7], hist4[8], hist4[9],
2868 hist4[10]);
2869 }
2870 #endif
2871 if (status & WI_OFF_ERR) {
2872 printf("%s: failed in wi_seek to %x/%x\n",
2873 device_xname(sc->sc_dev), id, off);
2874 sc->sc_bap_off = WI_OFF_ERR; /* invalidate */
2875 return EIO;
2876 }
2877 sc->sc_bap_id = id;
2878 sc->sc_bap_off = off;
2879 return 0;
2880 }
2881
2882 STATIC int
2883 wi_read_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
2884 {
2885 int error, cnt;
2886
2887 if (buflen == 0)
2888 return 0;
2889 if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
2890 if ((error = wi_seek_bap(sc, id, off)) != 0)
2891 return error;
2892 }
2893 cnt = (buflen + 1) / 2;
2894 CSR_READ_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt);
2895 sc->sc_bap_off += cnt * 2;
2896 return 0;
2897 }
2898
2899 STATIC int
2900 wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
2901 {
2902 int error, cnt;
2903
2904 if (buflen == 0)
2905 return 0;
2906
2907 #ifdef WI_HERMES_AUTOINC_WAR
2908 again:
2909 #endif
2910 if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
2911 if ((error = wi_seek_bap(sc, id, off)) != 0)
2912 return error;
2913 }
2914 cnt = (buflen + 1) / 2;
2915 CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt);
2916 sc->sc_bap_off += cnt * 2;
2917
2918 #ifdef WI_HERMES_AUTOINC_WAR
2919 /*
2920 * According to the comments in the HCF Light code, there is a bug
2921 * in the Hermes (or possibly in certain Hermes firmware revisions)
2922 * where the chip's internal autoincrement counter gets thrown off
2923 * during data writes: the autoincrement is missed, causing one
2924 * data word to be overwritten and subsequent words to be written to
2925 * the wrong memory locations. The end result is that we could end
2926 * up transmitting bogus frames without realizing it. The workaround
2927 * for this is to write a couple of extra guard words after the end
2928 * of the transfer, then attempt to read then back. If we fail to
2929 * locate the guard words where we expect them, we preform the
2930 * transfer over again.
2931 */
2932 if ((sc->sc_flags & WI_FLAGS_BUG_AUTOINC) && (id & 0xf000) == 0) {
2933 CSR_WRITE_2(sc, WI_DATA0, 0x1234);
2934 CSR_WRITE_2(sc, WI_DATA0, 0x5678);
2935 wi_seek_bap(sc, id, sc->sc_bap_off);
2936 sc->sc_bap_off = WI_OFF_ERR; /* invalidate */
2937 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
2938 CSR_READ_2(sc, WI_DATA0) != 0x5678) {
2939 aprint_error_dev(sc->sc_dev,
2940 "detect auto increment bug, try again\n");
2941 goto again;
2942 }
2943 }
2944 #endif
2945 return 0;
2946 }
2947
2948 STATIC int
2949 wi_mwrite_bap(struct wi_softc *sc, int id, int off, struct mbuf *m0, int totlen)
2950 {
2951 int error, len;
2952 struct mbuf *m;
2953
2954 for (m = m0; m != NULL && totlen > 0; m = m->m_next) {
2955 if (m->m_len == 0)
2956 continue;
2957
2958 len = min(m->m_len, totlen);
2959
2960 if (((u_long)m->m_data) % 2 != 0 || len % 2 != 0) {
2961 m_copydata(m, 0, totlen, (void *)&sc->sc_txbuf);
2962 return wi_write_bap(sc, id, off, (void *)&sc->sc_txbuf,
2963 totlen);
2964 }
2965
2966 if ((error = wi_write_bap(sc, id, off, m->m_data, len)) != 0)
2967 return error;
2968
2969 off += m->m_len;
2970 totlen -= len;
2971 }
2972 return 0;
2973 }
2974
2975 STATIC int
2976 wi_alloc_fid(struct wi_softc *sc, int len, int *idp)
2977 {
2978 int i;
2979
2980 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {
2981 aprint_error_dev(sc->sc_dev, "failed to allocate %d bytes on NIC\n", len);
2982 return ENOMEM;
2983 }
2984
2985 for (i = 0; i < WI_TIMEOUT; i++) {
2986 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
2987 break;
2988 DELAY(1);
2989 }
2990 if (i == WI_TIMEOUT) {
2991 aprint_error_dev(sc->sc_dev, "timeout in alloc\n");
2992 return ETIMEDOUT;
2993 }
2994 *idp = CSR_READ_2(sc, WI_ALLOC_FID);
2995 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
2996 return 0;
2997 }
2998
2999 STATIC int
3000 wi_read_rid(struct wi_softc *sc, int rid, void *buf, int *buflenp)
3001 {
3002 int error, len;
3003 u_int16_t ltbuf[2];
3004
3005 /* Tell the NIC to enter record read mode. */
3006 error = wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_READ, rid, 0, 0);
3007 if (error)
3008 return error;
3009
3010 error = wi_read_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
3011 if (error)
3012 return error;
3013
3014 if (le16toh(ltbuf[0]) == 0)
3015 return EOPNOTSUPP;
3016 if (le16toh(ltbuf[1]) != rid) {
3017 aprint_error_dev(sc->sc_dev,
3018 "record read mismatch, rid=%x, got=%x\n",
3019 rid, le16toh(ltbuf[1]));
3020 return EIO;
3021 }
3022 len = (le16toh(ltbuf[0]) - 1) * 2; /* already got rid */
3023 if (*buflenp < len) {
3024 aprint_error_dev(sc->sc_dev, "record buffer is too small, "
3025 "rid=%x, size=%d, len=%d\n",
3026 rid, *buflenp, len);
3027 return ENOSPC;
3028 }
3029 *buflenp = len;
3030 return wi_read_bap(sc, rid, sizeof(ltbuf), buf, len);
3031 }
3032
3033 STATIC int
3034 wi_write_rid(struct wi_softc *sc, int rid, void *buf, int buflen)
3035 {
3036 int error;
3037 u_int16_t ltbuf[2];
3038
3039 ltbuf[0] = htole16((buflen + 1) / 2 + 1); /* includes rid */
3040 ltbuf[1] = htole16(rid);
3041
3042 error = wi_write_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
3043 if (error)
3044 return error;
3045 error = wi_write_bap(sc, rid, sizeof(ltbuf), buf, buflen);
3046 if (error)
3047 return error;
3048
3049 return wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_WRITE, rid, 0, 0);
3050 }
3051
3052 STATIC void
3053 wi_rssadapt_updatestats_cb(void *arg, struct ieee80211_node *ni)
3054 {
3055 struct wi_node *wn = (void*)ni;
3056 ieee80211_rssadapt_updatestats(&wn->wn_rssadapt);
3057 }
3058
3059 STATIC void
3060 wi_rssadapt_updatestats(void *arg)
3061 {
3062 struct wi_softc *sc = arg;
3063 struct ieee80211com *ic = &sc->sc_ic;
3064 ieee80211_iterate_nodes(&ic->ic_sta, wi_rssadapt_updatestats_cb, arg);
3065 if (ic->ic_opmode != IEEE80211_M_MONITOR &&
3066 ic->ic_state == IEEE80211_S_RUN)
3067 callout_reset(&sc->sc_rssadapt_ch, hz / 10,
3068 wi_rssadapt_updatestats, arg);
3069 }
3070
3071 /*
3072 * In HOSTAP mode, restore IEEE80211_F_DROPUNENC when operating
3073 * with WEP enabled so that the AP drops unencoded frames at the
3074 * 802.11 layer.
3075 *
3076 * In all other modes, clear IEEE80211_F_DROPUNENC when operating
3077 * with WEP enabled so we don't drop unencoded frames at the 802.11
3078 * layer. This is necessary because we must strip the WEP bit from
3079 * the 802.11 header before passing frames to ieee80211_input
3080 * because the card has already stripped the WEP crypto header from
3081 * the packet.
3082 */
3083 STATIC void
3084 wi_mend_flags(struct wi_softc *sc, enum ieee80211_state nstate)
3085 {
3086 struct ieee80211com *ic = &sc->sc_ic;
3087
3088 if (nstate == IEEE80211_S_RUN &&
3089 (ic->ic_flags & IEEE80211_F_PRIVACY) != 0 &&
3090 ic->ic_opmode != IEEE80211_M_HOSTAP)
3091 ic->ic_flags &= ~IEEE80211_F_DROPUNENC;
3092 else
3093 ic->ic_flags |= sc->sc_ic_flags;
3094
3095 DPRINTF(("%s: state %d, "
3096 "ic->ic_flags & IEEE80211_F_DROPUNENC = %#" PRIx32 ", "
3097 "sc->sc_ic_flags & IEEE80211_F_DROPUNENC = %#" PRIx32 "\n",
3098 __func__, nstate,
3099 ic->ic_flags & IEEE80211_F_DROPUNENC,
3100 sc->sc_ic_flags & IEEE80211_F_DROPUNENC));
3101 }
3102
3103 STATIC int
3104 wi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
3105 {
3106 struct ifnet *ifp = ic->ic_ifp;
3107 struct wi_softc *sc = ifp->if_softc;
3108 struct ieee80211_node *ni = ic->ic_bss;
3109 u_int16_t val;
3110 struct wi_ssid ssid;
3111 struct wi_macaddr bssid, old_bssid;
3112 enum ieee80211_state ostate __unused;
3113 #ifdef WI_DEBUG
3114 static const char *stname[] =
3115 { "INIT", "SCAN", "AUTH", "ASSOC", "RUN" };
3116 #endif /* WI_DEBUG */
3117
3118 ostate = ic->ic_state;
3119 DPRINTF(("wi_newstate: %s -> %s\n", stname[ostate], stname[nstate]));
3120
3121 switch (nstate) {
3122 case IEEE80211_S_INIT:
3123 if (ic->ic_opmode != IEEE80211_M_MONITOR)
3124 callout_stop(&sc->sc_rssadapt_ch);
3125 ic->ic_flags &= ~IEEE80211_F_SIBSS;
3126 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
3127 break;
3128
3129 case IEEE80211_S_SCAN:
3130 case IEEE80211_S_AUTH:
3131 case IEEE80211_S_ASSOC:
3132 ic->ic_state = nstate; /* NB: skip normal ieee80211 handling */
3133 wi_mend_flags(sc, nstate);
3134 return 0;
3135
3136 case IEEE80211_S_RUN:
3137 sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
3138 IEEE80211_ADDR_COPY(old_bssid.wi_mac_addr, ni->ni_bssid);
3139 wi_read_xrid(sc, WI_RID_CURRENT_BSSID, &bssid,
3140 IEEE80211_ADDR_LEN);
3141 IEEE80211_ADDR_COPY(ni->ni_bssid, &bssid);
3142 IEEE80211_ADDR_COPY(ni->ni_macaddr, &bssid);
3143 wi_read_xrid(sc, WI_RID_CURRENT_CHAN, &val, sizeof(val));
3144 if (!isset(ic->ic_chan_avail, le16toh(val)))
3145 panic("%s: invalid channel %d\n",
3146 device_xname(sc->sc_dev), le16toh(val));
3147 ni->ni_chan = &ic->ic_channels[le16toh(val)];
3148
3149 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
3150 #ifndef IEEE80211_NO_HOSTAP
3151 ni->ni_esslen = ic->ic_des_esslen;
3152 memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
3153 ni->ni_rates = ic->ic_sup_rates[
3154 ieee80211_chan2mode(ic, ni->ni_chan)];
3155 ni->ni_intval = ic->ic_lintval;
3156 ni->ni_capinfo = IEEE80211_CAPINFO_ESS;
3157 if (ic->ic_flags & IEEE80211_F_PRIVACY)
3158 ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
3159 #endif /* !IEEE80211_NO_HOSTAP */
3160 } else {
3161 wi_read_xrid(sc, WI_RID_CURRENT_SSID, &ssid,
3162 sizeof(ssid));
3163 ni->ni_esslen = le16toh(ssid.wi_len);
3164 if (ni->ni_esslen > IEEE80211_NWID_LEN)
3165 ni->ni_esslen = IEEE80211_NWID_LEN; /*XXX*/
3166 memcpy(ni->ni_essid, ssid.wi_ssid, ni->ni_esslen);
3167 ni->ni_rates = ic->ic_sup_rates[
3168 ieee80211_chan2mode(ic, ni->ni_chan)]; /*XXX*/
3169 }
3170 if (ic->ic_opmode != IEEE80211_M_MONITOR)
3171 callout_reset(&sc->sc_rssadapt_ch, hz / 10,
3172 wi_rssadapt_updatestats, sc);
3173 /* Trigger routing socket messages. XXX Copied from
3174 * ieee80211_newstate.
3175 */
3176 if (ic->ic_opmode == IEEE80211_M_STA)
3177 ieee80211_notify_node_join(ic, ic->ic_bss,
3178 arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
3179 break;
3180 }
3181 wi_mend_flags(sc, nstate);
3182 return (*sc->sc_newstate)(ic, nstate, arg);
3183 }
3184
3185 STATIC void
3186 wi_set_tim(struct ieee80211_node *ni, int set)
3187 {
3188 struct ieee80211com *ic = ni->ni_ic;
3189 struct wi_softc *sc = ic->ic_ifp->if_softc;
3190
3191 (*sc->sc_set_tim)(ni, set);
3192
3193 if ((ic->ic_flags & IEEE80211_F_TIMUPDATE) == 0)
3194 return;
3195
3196 ic->ic_flags &= ~IEEE80211_F_TIMUPDATE;
3197
3198 (void)wi_write_val(sc, WI_RID_SET_TIM,
3199 IEEE80211_AID(ni->ni_associd) | (set ? 0x8000 : 0));
3200 }
3201
3202 STATIC int
3203 wi_scan_ap(struct wi_softc *sc, u_int16_t chanmask, u_int16_t txrate)
3204 {
3205 int error = 0;
3206 u_int16_t val[2];
3207
3208 if (!sc->sc_enabled)
3209 return ENXIO;
3210 switch (sc->sc_firmware_type) {
3211 case WI_LUCENT:
3212 (void)wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
3213 break;
3214 case WI_INTERSIL:
3215 val[0] = htole16(chanmask); /* channel */
3216 val[1] = htole16(txrate); /* tx rate */
3217 error = wi_write_rid(sc, WI_RID_SCAN_REQ, val, sizeof(val));
3218 break;
3219 case WI_SYMBOL:
3220 /*
3221 * XXX only supported on 3.x ?
3222 */
3223 val[0] = htole16(BSCAN_BCAST | BSCAN_ONETIME);
3224 error = wi_write_rid(sc, WI_RID_BCAST_SCAN_REQ,
3225 val, sizeof(val[0]));
3226 break;
3227 }
3228 if (error == 0) {
3229 sc->sc_scan_timer = WI_SCAN_WAIT;
3230 sc->sc_if.if_timer = 1;
3231 DPRINTF(("wi_scan_ap: start scanning, "
3232 "chanmask 0x%x txrate 0x%x\n", chanmask, txrate));
3233 }
3234 return error;
3235 }
3236
3237 STATIC void
3238 wi_scan_result(struct wi_softc *sc, int fid, int cnt)
3239 {
3240 #define N(a) (sizeof (a) / sizeof (a[0]))
3241 int i, naps, off, szbuf;
3242 struct wi_scan_header ws_hdr; /* Prism2 header */
3243 struct wi_scan_data_p2 ws_dat; /* Prism2 scantable*/
3244 struct wi_apinfo *ap;
3245
3246 off = sizeof(u_int16_t) * 2;
3247 memset(&ws_hdr, 0, sizeof(ws_hdr));
3248 switch (sc->sc_firmware_type) {
3249 case WI_INTERSIL:
3250 wi_read_bap(sc, fid, off, &ws_hdr, sizeof(ws_hdr));
3251 off += sizeof(ws_hdr);
3252 szbuf = sizeof(struct wi_scan_data_p2);
3253 break;
3254 case WI_SYMBOL:
3255 szbuf = sizeof(struct wi_scan_data_p2) + 6;
3256 break;
3257 case WI_LUCENT:
3258 szbuf = sizeof(struct wi_scan_data);
3259 break;
3260 default:
3261 aprint_error_dev(sc->sc_dev,
3262 "wi_scan_result: unknown firmware type %u\n",
3263 sc->sc_firmware_type);
3264 naps = 0;
3265 goto done;
3266 }
3267 naps = (cnt * 2 + 2 - off) / szbuf;
3268 if (naps > N(sc->sc_aps))
3269 naps = N(sc->sc_aps);
3270 sc->sc_naps = naps;
3271 /* Read Data */
3272 ap = sc->sc_aps;
3273 memset(&ws_dat, 0, sizeof(ws_dat));
3274 for (i = 0; i < naps; i++, ap++) {
3275 wi_read_bap(sc, fid, off, &ws_dat,
3276 (sizeof(ws_dat) < szbuf ? sizeof(ws_dat) : szbuf));
3277 DPRINTF2(("wi_scan_result: #%d: off %d bssid %s\n", i, off,
3278 ether_sprintf(ws_dat.wi_bssid)));
3279 off += szbuf;
3280 ap->scanreason = le16toh(ws_hdr.wi_reason);
3281 memcpy(ap->bssid, ws_dat.wi_bssid, sizeof(ap->bssid));
3282 ap->channel = le16toh(ws_dat.wi_chid);
3283 ap->signal = le16toh(ws_dat.wi_signal);
3284 ap->noise = le16toh(ws_dat.wi_noise);
3285 ap->quality = ap->signal - ap->noise;
3286 ap->capinfo = le16toh(ws_dat.wi_capinfo);
3287 ap->interval = le16toh(ws_dat.wi_interval);
3288 ap->rate = le16toh(ws_dat.wi_rate);
3289 ap->namelen = le16toh(ws_dat.wi_namelen);
3290 if (ap->namelen > sizeof(ap->name))
3291 ap->namelen = sizeof(ap->name);
3292 memcpy(ap->name, ws_dat.wi_name, ap->namelen);
3293 }
3294 done:
3295 /* Done scanning */
3296 sc->sc_scan_timer = 0;
3297 DPRINTF(("wi_scan_result: scan complete: ap %d\n", naps));
3298 #undef N
3299 }
3300
3301 STATIC void
3302 wi_dump_pkt(struct wi_frame *wh, struct ieee80211_node *ni, int rssi)
3303 {
3304 ieee80211_dump_pkt((u_int8_t *) &wh->wi_whdr, sizeof(wh->wi_whdr),
3305 ni ? ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL
3306 : -1,
3307 rssi);
3308 printf(" status 0x%x rx_tstamp1 %u rx_tstamp0 0x%u rx_silence %u\n",
3309 le16toh(wh->wi_status), le16toh(wh->wi_rx_tstamp1),
3310 le16toh(wh->wi_rx_tstamp0), wh->wi_rx_silence);
3311 printf(" rx_signal %u rx_rate %u rx_flow %u\n",
3312 wh->wi_rx_signal, wh->wi_rx_rate, wh->wi_rx_flow);
3313 printf(" tx_rtry %u tx_rate %u tx_ctl 0x%x dat_len %u\n",
3314 wh->wi_tx_rtry, wh->wi_tx_rate,
3315 le16toh(wh->wi_tx_ctl), le16toh(wh->wi_dat_len));
3316 printf(" ehdr dst %s src %s type 0x%x\n",
3317 ether_sprintf(wh->wi_ehdr.ether_dhost),
3318 ether_sprintf(wh->wi_ehdr.ether_shost),
3319 wh->wi_ehdr.ether_type);
3320 }
3321