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