Deleted Added
full compact
if_wi.c (75229) if_wi.c (75275)
1/*
2 * Copyright (c) 1997, 1998, 1999
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD.
35 *
36 * Written by Bill Paul <wpaul@ctr.columbia.edu>
37 * Electrical Engineering Department
38 * Columbia University, New York City
39 */
40
41/*
42 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
43 * from Lucent. Unlike the older cards, the new ones are programmed
44 * entirely via a firmware-driven controller called the Hermes.
45 * Unfortunately, Lucent will not release the Hermes programming manual
46 * without an NDA (if at all). What they do release is an API library
47 * called the HCF (Hardware Control Functions) which is supposed to
48 * do the device-specific operations of a device driver for you. The
49 * publically available version of the HCF library (the 'HCF Light') is
50 * a) extremely gross, b) lacks certain features, particularly support
51 * for 802.11 frames, and c) is contaminated by the GNU Public License.
52 *
53 * This driver does not use the HCF or HCF Light at all. Instead, it
54 * programs the Hermes controller directly, using information gleaned
55 * from the HCF Light code and corresponding documentation.
56 *
57 * This driver supports both the PCMCIA and ISA versions of the
58 * WaveLAN/IEEE cards. Note however that the ISA card isn't really
59 * anything of the sort: it's actually a PCMCIA bridge adapter
60 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is
61 * inserted. Consequently, you need to use the pccard support for
62 * both the ISA and PCMCIA adapters.
63 */
64
65#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */
66#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */
67#define WICACHE /* turn on signal strength cache code */
68
69#include <sys/param.h>
70#include <sys/systm.h>
71#include <sys/sockio.h>
72#include <sys/mbuf.h>
73#include <sys/kernel.h>
74#include <sys/socket.h>
75#include <sys/module.h>
76#include <sys/bus.h>
77#include <sys/syslog.h>
78#include <sys/sysctl.h>
79
80#include <machine/bus.h>
81#include <machine/resource.h>
82#include <machine/md_var.h>
83#include <machine/bus_pio.h>
84#include <sys/rman.h>
85
86#include <pci/pcireg.h>
87#include <pci/pcivar.h>
88
89#include <net/if.h>
90#include <net/if_arp.h>
91#include <net/ethernet.h>
92#include <net/if_dl.h>
93#include <net/if_media.h>
94#include <net/if_types.h>
95
96#include <netinet/in.h>
97#include <netinet/in_systm.h>
98#include <netinet/in_var.h>
99#include <netinet/ip.h>
100#include <netinet/if_ether.h>
101
102#include <net/bpf.h>
103
104#include <dev/pccard/pccardvar.h>
105#include <dev/pccard/pccarddevs.h>
106
107#include <dev/wi/if_wavelan_ieee.h>
108#include <dev/wi/if_wireg.h>
109
110#include "card_if.h"
111
112#if !defined(lint)
113static const char rcsid[] =
1/*
2 * Copyright (c) 1997, 1998, 1999
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD.
35 *
36 * Written by Bill Paul <wpaul@ctr.columbia.edu>
37 * Electrical Engineering Department
38 * Columbia University, New York City
39 */
40
41/*
42 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
43 * from Lucent. Unlike the older cards, the new ones are programmed
44 * entirely via a firmware-driven controller called the Hermes.
45 * Unfortunately, Lucent will not release the Hermes programming manual
46 * without an NDA (if at all). What they do release is an API library
47 * called the HCF (Hardware Control Functions) which is supposed to
48 * do the device-specific operations of a device driver for you. The
49 * publically available version of the HCF library (the 'HCF Light') is
50 * a) extremely gross, b) lacks certain features, particularly support
51 * for 802.11 frames, and c) is contaminated by the GNU Public License.
52 *
53 * This driver does not use the HCF or HCF Light at all. Instead, it
54 * programs the Hermes controller directly, using information gleaned
55 * from the HCF Light code and corresponding documentation.
56 *
57 * This driver supports both the PCMCIA and ISA versions of the
58 * WaveLAN/IEEE cards. Note however that the ISA card isn't really
59 * anything of the sort: it's actually a PCMCIA bridge adapter
60 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is
61 * inserted. Consequently, you need to use the pccard support for
62 * both the ISA and PCMCIA adapters.
63 */
64
65#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */
66#define WI_HERMES_STATS_WAR /* Work around stats counter bug. */
67#define WICACHE /* turn on signal strength cache code */
68
69#include <sys/param.h>
70#include <sys/systm.h>
71#include <sys/sockio.h>
72#include <sys/mbuf.h>
73#include <sys/kernel.h>
74#include <sys/socket.h>
75#include <sys/module.h>
76#include <sys/bus.h>
77#include <sys/syslog.h>
78#include <sys/sysctl.h>
79
80#include <machine/bus.h>
81#include <machine/resource.h>
82#include <machine/md_var.h>
83#include <machine/bus_pio.h>
84#include <sys/rman.h>
85
86#include <pci/pcireg.h>
87#include <pci/pcivar.h>
88
89#include <net/if.h>
90#include <net/if_arp.h>
91#include <net/ethernet.h>
92#include <net/if_dl.h>
93#include <net/if_media.h>
94#include <net/if_types.h>
95
96#include <netinet/in.h>
97#include <netinet/in_systm.h>
98#include <netinet/in_var.h>
99#include <netinet/ip.h>
100#include <netinet/if_ether.h>
101
102#include <net/bpf.h>
103
104#include <dev/pccard/pccardvar.h>
105#include <dev/pccard/pccarddevs.h>
106
107#include <dev/wi/if_wavelan_ieee.h>
108#include <dev/wi/if_wireg.h>
109
110#include "card_if.h"
111
112#if !defined(lint)
113static const char rcsid[] =
114 "$FreeBSD: head/sys/dev/wi/if_wi.c 75229 2001-04-05 09:47:07Z alfred $";
114 "$FreeBSD: head/sys/dev/wi/if_wi.c 75275 2001-04-06 21:48:19Z alfred $";
115#endif
116
117#ifdef foo
118static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
119#endif
120
121static void wi_intr __P((void *));
122static void wi_reset __P((struct wi_softc *));
123static int wi_ioctl __P((struct ifnet *, u_long, caddr_t));
124static void wi_init __P((void *));
125static void wi_start __P((struct ifnet *));
126static void wi_stop __P((struct wi_softc *));
127static void wi_watchdog __P((struct ifnet *));
128static void wi_rxeof __P((struct wi_softc *));
129static void wi_txeof __P((struct wi_softc *, int));
130static void wi_update_stats __P((struct wi_softc *));
131static void wi_setmulti __P((struct wi_softc *));
132
133static int wi_cmd __P((struct wi_softc *, int, int));
134static int wi_read_record __P((struct wi_softc *, struct wi_ltv_gen *));
135static int wi_write_record __P((struct wi_softc *, struct wi_ltv_gen *));
136static int wi_read_data __P((struct wi_softc *, int,
137 int, caddr_t, int));
138static int wi_write_data __P((struct wi_softc *, int,
139 int, caddr_t, int));
140static int wi_seek __P((struct wi_softc *, int, int, int));
141static int wi_alloc_nicmem __P((struct wi_softc *, int, int *));
142static void wi_inquire __P((void *));
143static void wi_setdef __P((struct wi_softc *, struct wi_req *));
144static int wi_mgmt_xmit __P((struct wi_softc *, caddr_t, int));
145
146#ifdef WICACHE
147static
148void wi_cache_store __P((struct wi_softc *, struct ether_header *,
149 struct mbuf *, unsigned short));
150#endif
151
152static int wi_generic_attach __P((device_t));
153static int wi_pccard_match __P((device_t));
154static int wi_pccard_probe __P((device_t));
155static int wi_pci_probe __P((device_t));
156static int wi_pccard_attach __P((device_t));
157static int wi_pci_attach __P((device_t));
158static int wi_pccard_detach __P((device_t));
159static void wi_shutdown __P((device_t));
160
161static int wi_alloc __P((device_t, int));
162static void wi_free __P((device_t));
163
164static device_method_t wi_pccard_methods[] = {
165 /* Device interface */
166 DEVMETHOD(device_probe, pccard_compat_probe),
167 DEVMETHOD(device_attach, pccard_compat_attach),
168 DEVMETHOD(device_detach, wi_pccard_detach),
169 DEVMETHOD(device_shutdown, wi_shutdown),
170
171 /* Card interface */
172 DEVMETHOD(card_compat_match, wi_pccard_match),
173 DEVMETHOD(card_compat_probe, wi_pccard_probe),
174 DEVMETHOD(card_compat_attach, wi_pccard_attach),
175
176 { 0, 0 }
177};
178
179static device_method_t wi_pci_methods[] = {
180 /* Device interface */
181 DEVMETHOD(device_probe, wi_pci_probe),
182 DEVMETHOD(device_attach, wi_pci_attach),
183 DEVMETHOD(device_detach, wi_pccard_detach),
184 DEVMETHOD(device_shutdown, wi_shutdown),
185
186 { 0, 0 }
187};
188
189static driver_t wi_pccard_driver = {
190 "wi",
191 wi_pccard_methods,
192 sizeof(struct wi_softc)
193};
194
195static driver_t wi_pci_driver = {
196 "wi",
197 wi_pci_methods,
198 sizeof(struct wi_softc)
199};
200
201static devclass_t wi_pccard_devclass;
202static devclass_t wi_pci_devclass;
203
204DRIVER_MODULE(if_wi, pccard, wi_pccard_driver, wi_pccard_devclass, 0, 0);
205DRIVER_MODULE(if_wi, pci, wi_pci_driver, wi_pci_devclass, 0, 0);
206
207static const struct pccard_product wi_pccard_products[] = {
208 { PCCARD_STR_LUCENT_WAVELAN_IEEE, PCCARD_VENDOR_LUCENT,
209 PCCARD_PRODUCT_LUCENT_WAVELAN_IEEE, 0,
210 PCCARD_CIS_LUCENT_WAVELAN_IEEE },
211};
212
213static char wi_device_desc[] = "WaveLAN/IEEE 802.11";
214
215static int wi_pccard_match(dev)
216 device_t dev;
217{
218 const struct pccard_product *pp;
219
220 if ((pp = pccard_product_lookup(dev, wi_pccard_products,
221 sizeof(wi_pccard_products[0]), NULL)) != NULL) {
222 device_set_desc(dev, pp->pp_name);
223 return 0;
224 }
225 return ENXIO;
226}
227
228static int wi_pccard_probe(dev)
229 device_t dev;
230{
231 struct wi_softc *sc;
232 int error;
233
234 sc = device_get_softc(dev);
235 sc->wi_gone = 0;
236
237 error = wi_alloc(dev, 0);
238 if (error)
239 return (error);
240
241 wi_free(dev);
242
243 /* Make sure interrupts are disabled. */
244 CSR_WRITE_2(sc, WI_INT_EN, 0);
245 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
246
247 return (0);
248}
249
250static int
251wi_pci_probe(dev)
252 device_t dev;
253{
254 struct wi_softc *sc;
255
256 sc = device_get_softc(dev);
257 if ((pci_get_vendor(dev) == WI_PCI_VENDOR_EUMITCOM) &&
258 (pci_get_device(dev) == WI_PCI_DEVICE_PRISM2STA)) {
259 sc->wi_prism2 = 1;
260 device_set_desc(dev,
261 "PRISM2STA PCI WaveLAN/IEEE 802.11");
262 return (0);
263 }
264 return(ENXIO);
265}
266
267static int wi_pccard_detach(dev)
268 device_t dev;
269{
270 struct wi_softc *sc;
271 struct ifnet *ifp;
272
273 sc = device_get_softc(dev);
274 WI_LOCK(sc);
275 ifp = &sc->arpcom.ac_if;
276
277 if (sc->wi_gone) {
278 device_printf(dev, "already unloaded\n");
279 WI_UNLOCK(sc);
280 return(ENODEV);
281 }
282
283 wi_stop(sc);
284
285 ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
286 bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
287 wi_free(dev);
288 sc->wi_gone = 1;
289
290 WI_UNLOCK(sc);
291 mtx_destroy(&sc->wi_mtx);
292
293 return(0);
294}
295
296static int wi_pccard_attach(device_t dev)
297{
298 struct wi_softc *sc;
299 int error;
300 u_int32_t flags;
301
302 sc = device_get_softc(dev);
303
304 /*
305 * XXX: quick hack to support Prism II chip.
306 * Currently, we need to set a flags in pccard.conf to specify
307 * which type chip is used.
308 *
309 * We need to replace this code in a future.
310 * It is better to use CIS than using a flag.
311 */
312 flags = device_get_flags(dev);
313#define WI_FLAGS_PRISM2 0x10000
314 if (flags & WI_FLAGS_PRISM2) {
315 sc->wi_prism2 = 1;
316 if (bootverbose) {
317 device_printf(dev, "found PrismII chip\n");
318 }
319 }
320 else {
321 sc->wi_prism2 = 0;
322 if (bootverbose) {
323 device_printf(dev, "found Lucent chip\n");
324 }
325 }
326
327 error = wi_alloc(dev, 0);
328 if (error) {
329 device_printf(dev, "wi_alloc() failed! (%d)\n", error);
330 return (error);
331 }
332 return (wi_generic_attach(dev));
333}
334
335static int
336wi_pci_attach(device_t dev)
337{
338 struct wi_softc *sc;
339 u_int32_t command, wanted;
340 u_int16_t reg;
341 int error;
342
343 sc = device_get_softc(dev);
344
345 command = pci_read_config(dev, PCIR_COMMAND, 4);
346 wanted = PCIM_CMD_PORTEN|PCIM_CMD_MEMEN;
347 command |= wanted;
348 pci_write_config(dev, PCIR_COMMAND, command, 4);
349 command = pci_read_config(dev, PCIR_COMMAND, 4);
350 if ((command & wanted) != wanted) {
351 device_printf(dev, "wi_pci_attach() failed to enable pci!\n");
352 return (ENXIO);
353 }
354
355 error = wi_alloc(dev, WI_PCI_IORES);
356 if (error)
357 return (error);
358
359 device_set_desc(dev, wi_device_desc);
360
361 /* Make sure interrupts are disabled. */
362 CSR_WRITE_2(sc, WI_INT_EN, 0);
363 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
364
365 sc->mem_rid = WI_PCI_MEMRES;
366 sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid,
367 0, ~0, 1, RF_ACTIVE);
368 if (sc->mem == NULL) {
369 device_printf(dev, "couldn't allocate memory\n");
370 wi_free(dev);
371 return (ENXIO);
372 }
373 sc->wi_bmemtag = rman_get_bustag(sc->mem);
374 sc->wi_bmemhandle = rman_get_bushandle(sc->mem);
375
376 /*
377 * From Linux driver:
378 * Write COR to enable PC card
379 * This is a subset of the protocol that the pccard bus code
380 * would do.
381 */
382 CSM_WRITE_1(sc, WI_COR_OFFSET, WI_COR_VALUE);
383 reg = CSM_READ_1(sc, WI_COR_OFFSET);
384
385 CSR_WRITE_2(sc, WI_HFA384X_SWSUPPORT0_OFF, WI_PRISM2STA_MAGIC);
386 reg = CSR_READ_2(sc, WI_HFA384X_SWSUPPORT0_OFF);
387 if (reg != WI_PRISM2STA_MAGIC) {
388 device_printf(dev,
389 "CSR_READ_2(WI_HFA384X_SWSUPPORT0_OFF) "
390 "wanted %d, got %d\n", WI_PRISM2STA_MAGIC, reg);
391 wi_free(dev);
392 return (ENXIO);
393 }
394
395 error = wi_generic_attach(dev);
396 if (error != 0)
397 return (error);
398
399 return (0);
400}
401
402static int
403wi_generic_attach(device_t dev)
404{
405 struct wi_softc *sc;
406 struct wi_ltv_macaddr mac;
407 struct wi_ltv_gen gen;
408 struct ifnet *ifp;
409 int error;
410
411 sc = device_get_softc(dev);
412 ifp = &sc->arpcom.ac_if;
413
414 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
415 wi_intr, sc, &sc->wi_intrhand);
416
417 if (error) {
418 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
419 wi_free(dev);
420 return (error);
421 }
422
423 mtx_init(&sc->wi_mtx, device_get_nameunit(dev), MTX_DEF | MTX_RECURSE);
424 WI_LOCK(sc);
425
426 /* Reset the NIC. */
427 wi_reset(sc);
428
429 /* Read the station address. */
430 mac.wi_type = WI_RID_MAC_NODE;
431 mac.wi_len = 4;
432 if ((error = wi_read_record(sc, (struct wi_ltv_gen *)&mac)) != 0) {
433 device_printf(dev, "mac read failed %d\n", error);
434 wi_free(dev);
435 return (error);
436 }
437 bcopy((char *)&mac.wi_mac_addr,
438 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
439
440 device_printf(dev, "Ethernet address: %6D\n",
441 sc->arpcom.ac_enaddr, ":");
442
443 ifp->if_softc = sc;
444 ifp->if_unit = sc->wi_unit;
445 ifp->if_name = "wi";
446 ifp->if_mtu = ETHERMTU;
447 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
448 ifp->if_ioctl = wi_ioctl;
449 ifp->if_output = ether_output;
450 ifp->if_start = wi_start;
451 ifp->if_watchdog = wi_watchdog;
452 ifp->if_init = wi_init;
453 ifp->if_baudrate = 10000000;
454 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
455
456 bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
457 bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name,
458 sizeof(WI_DEFAULT_NODENAME) - 1);
459
460 bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
461 bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name,
462 sizeof(WI_DEFAULT_NETNAME) - 1);
463
464 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
465 bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name,
466 sizeof(WI_DEFAULT_IBSS) - 1);
467
468 sc->wi_portnum = WI_DEFAULT_PORT;
469 sc->wi_ptype = WI_PORTTYPE_BSS;
470 sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
471 sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
472 sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
473 sc->wi_max_data_len = WI_DEFAULT_DATALEN;
474 sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
475 sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
476 sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
477
478 /*
479 * Read the default channel from the NIC. This may vary
480 * depending on the country where the NIC was purchased, so
481 * we can't hard-code a default and expect it to work for
482 * everyone.
483 */
484 gen.wi_type = WI_RID_OWN_CHNL;
485 gen.wi_len = 2;
486 wi_read_record(sc, &gen);
487 sc->wi_channel = gen.wi_val;
488
489 /*
490 * Find out if we support WEP on this card.
491 */
492 gen.wi_type = WI_RID_WEP_AVAIL;
493 gen.wi_len = 2;
494 wi_read_record(sc, &gen);
495 sc->wi_has_wep = gen.wi_val;
496
497 if (bootverbose) {
498 device_printf(sc->dev,
499 __FUNCTION__ ":wi_has_wep = %d\n",
500 sc->wi_has_wep);
501 }
502
503 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
504
505 wi_init(sc);
506 wi_stop(sc);
507
508 /*
509 * Call MI attach routine.
510 */
511 ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
512 callout_handle_init(&sc->wi_stat_ch);
513 WI_UNLOCK(sc);
514
515 return(0);
516}
517
518static void wi_rxeof(sc)
519 struct wi_softc *sc;
520{
521 struct ifnet *ifp;
522 struct ether_header *eh;
523 struct wi_frame rx_frame;
524 struct mbuf *m;
525 int id;
526
527 ifp = &sc->arpcom.ac_if;
528
529 id = CSR_READ_2(sc, WI_RX_FID);
530
531 /* First read in the frame header */
532 if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
533 ifp->if_ierrors++;
534 return;
535 }
536
537 if (rx_frame.wi_status & WI_STAT_ERRSTAT) {
538 ifp->if_ierrors++;
539 return;
540 }
541
542 MGETHDR(m, M_DONTWAIT, MT_DATA);
543 if (m == NULL) {
544 ifp->if_ierrors++;
545 return;
546 }
547 MCLGET(m, M_DONTWAIT);
548 if (!(m->m_flags & M_EXT)) {
549 m_freem(m);
550 ifp->if_ierrors++;
551 return;
552 }
553
554 eh = mtod(m, struct ether_header *);
555 m->m_pkthdr.rcvif = ifp;
556
557 if (rx_frame.wi_status == WI_STAT_1042 ||
558 rx_frame.wi_status == WI_STAT_TUNNEL ||
559 rx_frame.wi_status == WI_STAT_WMP_MSG) {
560 if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) {
561 device_printf(sc->dev, "oversized packet received "
562 "(wi_dat_len=%d, wi_status=0x%x)\n",
563 rx_frame.wi_dat_len, rx_frame.wi_status);
564 m_freem(m);
565 ifp->if_ierrors++;
566 return;
567 }
568 m->m_pkthdr.len = m->m_len =
569 rx_frame.wi_dat_len + WI_SNAPHDR_LEN;
570
571 bcopy((char *)&rx_frame.wi_addr1,
572 (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
573 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) {
574 bcopy((char *)&rx_frame.wi_addr2,
575 (char *)&eh->ether_shost, ETHER_ADDR_LEN);
576 } else {
577 bcopy((char *)&rx_frame.wi_addr3,
578 (char *)&eh->ether_shost, ETHER_ADDR_LEN);
579 }
580 bcopy((char *)&rx_frame.wi_type,
581 (char *)&eh->ether_type, sizeof(u_int16_t));
582
583 if (wi_read_data(sc, id, WI_802_11_OFFSET,
584 mtod(m, caddr_t) + sizeof(struct ether_header),
585 m->m_len + 2)) {
586 m_freem(m);
587 ifp->if_ierrors++;
588 return;
589 }
590 } else {
591 if((rx_frame.wi_dat_len +
592 sizeof(struct ether_header)) > MCLBYTES) {
593 device_printf(sc->dev, "oversized packet received "
594 "(wi_dat_len=%d, wi_status=0x%x)\n",
595 rx_frame.wi_dat_len, rx_frame.wi_status);
596 m_freem(m);
597 ifp->if_ierrors++;
598 return;
599 }
600 m->m_pkthdr.len = m->m_len =
601 rx_frame.wi_dat_len + sizeof(struct ether_header);
602
603 if (wi_read_data(sc, id, WI_802_3_OFFSET,
604 mtod(m, caddr_t), m->m_len + 2)) {
605 m_freem(m);
606 ifp->if_ierrors++;
607 return;
608 }
609 }
610
611 ifp->if_ipackets++;
612
613 /* Receive packet. */
614 m_adj(m, sizeof(struct ether_header));
615#ifdef WICACHE
616 wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
617#endif
618 ether_input(ifp, eh, m);
619}
620
621static void wi_txeof(sc, status)
622 struct wi_softc *sc;
623 int status;
624{
625 struct ifnet *ifp;
626
627 ifp = &sc->arpcom.ac_if;
628
629 ifp->if_timer = 0;
630 ifp->if_flags &= ~IFF_OACTIVE;
631
632 if (status & WI_EV_TX_EXC)
633 ifp->if_oerrors++;
634 else
635 ifp->if_opackets++;
636
637 return;
638}
639
640void wi_inquire(xsc)
641 void *xsc;
642{
643 struct wi_softc *sc;
644 struct ifnet *ifp;
645
646 sc = xsc;
647 ifp = &sc->arpcom.ac_if;
648
649 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
650
651 /* Don't do this while we're transmitting */
652 if (ifp->if_flags & IFF_OACTIVE)
653 return;
654
655 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS);
656
657 return;
658}
659
660void wi_update_stats(sc)
661 struct wi_softc *sc;
662{
663 struct wi_ltv_gen gen;
664 u_int16_t id;
665 struct ifnet *ifp;
666 u_int32_t *ptr;
667 int i;
668 u_int16_t t;
669
670 ifp = &sc->arpcom.ac_if;
671
672 id = CSR_READ_2(sc, WI_INFO_FID);
673
674 wi_read_data(sc, id, 0, (char *)&gen, 4);
675
676 if (gen.wi_type != WI_INFO_COUNTERS ||
677 gen.wi_len > (sizeof(sc->wi_stats) / 4) + 1)
678 return;
679
680 ptr = (u_int32_t *)&sc->wi_stats;
681
682 for (i = 0; i < gen.wi_len - 1; i++) {
683 t = CSR_READ_2(sc, WI_DATA1);
684#ifdef WI_HERMES_STATS_WAR
685 if (t > 0xF000)
686 t = ~t & 0xFFFF;
687#endif
688 ptr[i] += t;
689 }
690
691 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
692 sc->wi_stats.wi_tx_multi_retries +
693 sc->wi_stats.wi_tx_retry_limit;
694
695 return;
696}
697
698static void wi_intr(xsc)
699 void *xsc;
700{
701 struct wi_softc *sc = xsc;
702 struct ifnet *ifp;
703 u_int16_t status;
704
705 WI_LOCK(sc);
706
707 ifp = &sc->arpcom.ac_if;
708
709 if (!(ifp->if_flags & IFF_UP)) {
710 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
711 CSR_WRITE_2(sc, WI_INT_EN, 0);
712 WI_UNLOCK(sc);
713 return;
714 }
715
716 /* Disable interrupts. */
717 CSR_WRITE_2(sc, WI_INT_EN, 0);
718
719 status = CSR_READ_2(sc, WI_EVENT_STAT);
720 CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
721
722 if (status & WI_EV_RX) {
723 wi_rxeof(sc);
724 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
725 }
726
727 if (status & WI_EV_TX) {
728 wi_txeof(sc, status);
729 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
730 }
731
732 if (status & WI_EV_ALLOC) {
733 int id;
734 id = CSR_READ_2(sc, WI_ALLOC_FID);
735 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
736 if (id == sc->wi_tx_data_id)
737 wi_txeof(sc, status);
738 }
739
740 if (status & WI_EV_INFO) {
741 wi_update_stats(sc);
742 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
743 }
744
745 if (status & WI_EV_TX_EXC) {
746 wi_txeof(sc, status);
747 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
748 }
749
750 if (status & WI_EV_INFO_DROP) {
751 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
752 }
753
754 /* Re-enable interrupts. */
755 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
756
757 if (ifp->if_snd.ifq_head != NULL)
758 wi_start(ifp);
759
760 WI_UNLOCK(sc);
761
762 return;
763}
764
765static int wi_cmd(sc, cmd, val)
766 struct wi_softc *sc;
767 int cmd;
768 int val;
769{
770 int i, s = 0;
771
772 /* wait for the busy bit to clear */
773 for (i = 200; i > 0; i--) {
774 if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) {
775 break;
776 }
777 DELAY(10*1000); /* 10 m sec */
778 }
779 if (i == 0) {
780 return(ETIMEDOUT);
781 }
782
783 CSR_WRITE_2(sc, WI_PARAM0, val);
784 CSR_WRITE_2(sc, WI_PARAM1, 0);
785 CSR_WRITE_2(sc, WI_PARAM2, 0);
786 CSR_WRITE_2(sc, WI_COMMAND, cmd);
787
788 for (i = 0; i < WI_TIMEOUT; i++) {
789 /*
790 * Wait for 'command complete' bit to be
791 * set in the event status register.
792 */
793 s = CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD;
794 if (s) {
795 /* Ack the event and read result code. */
796 s = CSR_READ_2(sc, WI_STATUS);
797 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
798#ifdef foo
799 if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK))
800 return(EIO);
801#endif
802 if (s & WI_STAT_CMD_RESULT)
803 return(EIO);
804 break;
805 }
806 }
807
808 if (i == WI_TIMEOUT)
809 return(ETIMEDOUT);
810
811 return(0);
812}
813
814static void wi_reset(sc)
815 struct wi_softc *sc;
816{
817 int i;
818
819 for (i = 0; i < 5; i++) {
820 if (wi_cmd(sc, WI_CMD_INI, 0) == 0)
821 break;
822 DELAY(100000);
823 }
824 if (i == 5)
825 device_printf(sc->dev, "init failed\n");
826 CSR_WRITE_2(sc, WI_INT_EN, 0);
827 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
828
829 /* Calibrate timer. */
830 WI_SETVAL(WI_RID_TICK_TIME, 8);
831
832 return;
833}
834
835/*
836 * Read an LTV record from the NIC.
837 */
838static int wi_read_record(sc, ltv)
839 struct wi_softc *sc;
840 struct wi_ltv_gen *ltv;
841{
842 u_int16_t *ptr;
843 int i, len, code;
844 struct wi_ltv_gen *oltv, p2ltv;
845
846 oltv = ltv;
847 if (sc->wi_prism2) {
848 switch (ltv->wi_type) {
849 case WI_RID_ENCRYPTION:
850 p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
851 p2ltv.wi_len = 2;
852 ltv = &p2ltv;
853 break;
854 case WI_RID_TX_CRYPT_KEY:
855 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
856 p2ltv.wi_len = 2;
857 ltv = &p2ltv;
858 break;
859 }
860 }
861
862 /* Tell the NIC to enter record read mode. */
863 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type))
864 return(EIO);
865
866 /* Seek to the record. */
867 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
868 return(EIO);
869
870 /*
871 * Read the length and record type and make sure they
872 * match what we expect (this verifies that we have enough
873 * room to hold all of the returned data).
874 */
875 len = CSR_READ_2(sc, WI_DATA1);
876 if (len > ltv->wi_len)
877 return(ENOSPC);
878 code = CSR_READ_2(sc, WI_DATA1);
879 if (code != ltv->wi_type)
880 return(EIO);
881
882 ltv->wi_len = len;
883 ltv->wi_type = code;
884
885 /* Now read the data. */
886 ptr = &ltv->wi_val;
887 for (i = 0; i < ltv->wi_len - 1; i++)
888 ptr[i] = CSR_READ_2(sc, WI_DATA1);
889
890 if (sc->wi_prism2) {
891 switch (oltv->wi_type) {
892 case WI_RID_TX_RATE:
893 case WI_RID_CUR_TX_RATE:
894 switch (ltv->wi_val) {
895 case 1: oltv->wi_val = 1; break;
896 case 2: oltv->wi_val = 2; break;
897 case 3: oltv->wi_val = 6; break;
898 case 4: oltv->wi_val = 5; break;
899 case 7: oltv->wi_val = 7; break;
900 case 8: oltv->wi_val = 11; break;
901 case 15: oltv->wi_val = 3; break;
902 default: oltv->wi_val = 0x100 + ltv->wi_val; break;
903 }
904 break;
905 case WI_RID_ENCRYPTION:
906 oltv->wi_len = 2;
907 if (ltv->wi_val & 0x01)
908 oltv->wi_val = 1;
909 else
910 oltv->wi_val = 0;
911 break;
912 case WI_RID_TX_CRYPT_KEY:
913 oltv->wi_len = 2;
914 oltv->wi_val = ltv->wi_val;
915 break;
916 }
917 }
918
919 return(0);
920}
921
922/*
923 * Same as read, except we inject data instead of reading it.
924 */
925static int wi_write_record(sc, ltv)
926 struct wi_softc *sc;
927 struct wi_ltv_gen *ltv;
928{
929 u_int16_t *ptr;
930 int i;
931 struct wi_ltv_gen p2ltv;
932
933 if (sc->wi_prism2) {
934 switch (ltv->wi_type) {
935 case WI_RID_TX_RATE:
936 p2ltv.wi_type = WI_RID_TX_RATE;
937 p2ltv.wi_len = 2;
938 switch (ltv->wi_val) {
939 case 1: p2ltv.wi_val = 1; break;
940 case 2: p2ltv.wi_val = 2; break;
941 case 3: p2ltv.wi_val = 15; break;
942 case 5: p2ltv.wi_val = 4; break;
943 case 6: p2ltv.wi_val = 3; break;
944 case 7: p2ltv.wi_val = 7; break;
945 case 11: p2ltv.wi_val = 8; break;
946 default: return EINVAL;
947 }
948 ltv = &p2ltv;
949 break;
950 case WI_RID_ENCRYPTION:
951 p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
952 p2ltv.wi_len = 2;
953 if (ltv->wi_val)
954 p2ltv.wi_val = 0x03;
955 else
956 p2ltv.wi_val = 0x90;
957 ltv = &p2ltv;
958 break;
959 case WI_RID_TX_CRYPT_KEY:
960 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
961 p2ltv.wi_len = 2;
962 p2ltv.wi_val = ltv->wi_val;
963 ltv = &p2ltv;
964 break;
965 case WI_RID_DEFLT_CRYPT_KEYS:
966 {
967 int error;
968 struct wi_ltv_str ws;
969 struct wi_ltv_keys *wk =
970 (struct wi_ltv_keys *)ltv;
971
972 for (i = 0; i < 4; i++) {
973 ws.wi_len = 4;
974 ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
975 memcpy(ws.wi_str,
976 &wk->wi_keys[i].wi_keydat, 5);
977 ws.wi_str[5] = '\0';
978 error = wi_write_record(sc,
979 (struct wi_ltv_gen *)&ws);
980 if (error)
981 return error;
982 }
983 return 0;
984 }
985 }
986 }
987
988 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
989 return(EIO);
990
991 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
992 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
993
994 ptr = &ltv->wi_val;
995 for (i = 0; i < ltv->wi_len - 1; i++)
996 CSR_WRITE_2(sc, WI_DATA1, ptr[i]);
997
998 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type))
999 return(EIO);
1000
1001 return(0);
1002}
1003
1004static int wi_seek(sc, id, off, chan)
1005 struct wi_softc *sc;
1006 int id, off, chan;
1007{
1008 int i;
1009 int selreg, offreg;
1010
1011 switch (chan) {
1012 case WI_BAP0:
1013 selreg = WI_SEL0;
1014 offreg = WI_OFF0;
1015 break;
1016 case WI_BAP1:
1017 selreg = WI_SEL1;
1018 offreg = WI_OFF1;
1019 break;
1020 default:
1021 device_printf(sc->dev, "invalid data path: %x\n", chan);
1022 return(EIO);
1023 }
1024
1025 CSR_WRITE_2(sc, selreg, id);
1026 CSR_WRITE_2(sc, offreg, off);
1027
1028 for (i = 0; i < WI_TIMEOUT; i++) {
1029 if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR)))
1030 break;
1031 }
1032
1033 if (i == WI_TIMEOUT)
1034 return(ETIMEDOUT);
1035
1036 return(0);
1037}
1038
1039static int wi_read_data(sc, id, off, buf, len)
1040 struct wi_softc *sc;
1041 int id, off;
1042 caddr_t buf;
1043 int len;
1044{
1045 int i;
1046 u_int16_t *ptr;
1047
1048 if (wi_seek(sc, id, off, WI_BAP1))
1049 return(EIO);
1050
1051 ptr = (u_int16_t *)buf;
1052 for (i = 0; i < len / 2; i++)
1053 ptr[i] = CSR_READ_2(sc, WI_DATA1);
1054
1055 return(0);
1056}
1057
1058/*
1059 * According to the comments in the HCF Light code, there is a bug in
1060 * the Hermes (or possibly in certain Hermes firmware revisions) where
1061 * the chip's internal autoincrement counter gets thrown off during
1062 * data writes: the autoincrement is missed, causing one data word to
1063 * be overwritten and subsequent words to be written to the wrong memory
1064 * locations. The end result is that we could end up transmitting bogus
1065 * frames without realizing it. The workaround for this is to write a
1066 * couple of extra guard words after the end of the transfer, then
1067 * attempt to read then back. If we fail to locate the guard words where
1068 * we expect them, we preform the transfer over again.
1069 */
1070static int wi_write_data(sc, id, off, buf, len)
1071 struct wi_softc *sc;
1072 int id, off;
1073 caddr_t buf;
1074 int len;
1075{
1076 int i;
1077 u_int16_t *ptr;
1078#ifdef WI_HERMES_AUTOINC_WAR
1079 int retries;
1080
1081 retries = WI_TIMEOUT >> 4;
1082again:
1083#endif
1084
1085 if (wi_seek(sc, id, off, WI_BAP0))
1086 return(EIO);
1087
1088 ptr = (u_int16_t *)buf;
1089 for (i = 0; i < (len / 2); i++)
1090 CSR_WRITE_2(sc, WI_DATA0, ptr[i]);
1091
1092#ifdef WI_HERMES_AUTOINC_WAR
1093 CSR_WRITE_2(sc, WI_DATA0, 0x1234);
1094 CSR_WRITE_2(sc, WI_DATA0, 0x5678);
1095
1096 if (wi_seek(sc, id, off + len, WI_BAP0))
1097 return(EIO);
1098
1099 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
1100 CSR_READ_2(sc, WI_DATA0) != 0x5678) {
1101 if (--retries >= 0)
1102 goto again;
1103 device_printf(sc->dev, "wi_write_data device timeout\n");
1104 return (EIO);
1105 }
1106#endif
1107
1108 return(0);
1109}
1110
1111/*
1112 * Allocate a region of memory inside the NIC and zero
1113 * it out.
1114 */
1115static int wi_alloc_nicmem(sc, len, id)
1116 struct wi_softc *sc;
1117 int len;
1118 int *id;
1119{
1120 int i;
1121
1122 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) {
1123 device_printf(sc->dev,
1124 "failed to allocate %d bytes on NIC\n", len);
1125 return(ENOMEM);
1126 }
1127
1128 for (i = 0; i < WI_TIMEOUT; i++) {
1129 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
1130 break;
1131 }
1132
1133 if (i == WI_TIMEOUT)
1134 return(ETIMEDOUT);
1135
1136 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1137 *id = CSR_READ_2(sc, WI_ALLOC_FID);
1138
1139 if (wi_seek(sc, *id, 0, WI_BAP0))
1140 return(EIO);
1141
1142 for (i = 0; i < len / 2; i++)
1143 CSR_WRITE_2(sc, WI_DATA0, 0);
1144
1145 return(0);
1146}
1147
1148static void wi_setmulti(sc)
1149 struct wi_softc *sc;
1150{
1151 struct ifnet *ifp;
1152 int i = 0;
1153 struct ifmultiaddr *ifma;
1154 struct wi_ltv_mcast mcast;
1155
1156 ifp = &sc->arpcom.ac_if;
1157
1158 bzero((char *)&mcast, sizeof(mcast));
1159
1160 mcast.wi_type = WI_RID_MCAST;
1161 mcast.wi_len = (3 * 16) + 1;
1162
1163 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
1164 wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1165 return;
1166 }
1167
1168 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1169 if (ifma->ifma_addr->sa_family != AF_LINK)
1170 continue;
1171 if (i < 16) {
1172 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
1173 (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN);
1174 i++;
1175 } else {
1176 bzero((char *)&mcast, sizeof(mcast));
1177 break;
1178 }
1179 }
1180
1181 mcast.wi_len = (i * 3) + 1;
1182 wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1183
1184 return;
1185}
1186
1187static void wi_setdef(sc, wreq)
1188 struct wi_softc *sc;
1189 struct wi_req *wreq;
1190{
1191 struct sockaddr_dl *sdl;
1192 struct ifaddr *ifa;
1193 struct ifnet *ifp;
1194
1195 ifp = &sc->arpcom.ac_if;
1196
1197 switch(wreq->wi_type) {
1198 case WI_RID_MAC_NODE:
1199 ifa = ifnet_addrs[ifp->if_index - 1];
1200 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1201 bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr,
1202 ETHER_ADDR_LEN);
1203 bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);
1204 break;
1205 case WI_RID_PORTTYPE:
1206 sc->wi_ptype = wreq->wi_val[0];
1207 break;
1208 case WI_RID_TX_RATE:
1209 sc->wi_tx_rate = wreq->wi_val[0];
1210 break;
1211 case WI_RID_MAX_DATALEN:
1212 sc->wi_max_data_len = wreq->wi_val[0];
1213 break;
1214 case WI_RID_RTS_THRESH:
1215 sc->wi_rts_thresh = wreq->wi_val[0];
1216 break;
1217 case WI_RID_SYSTEM_SCALE:
1218 sc->wi_ap_density = wreq->wi_val[0];
1219 break;
1220 case WI_RID_CREATE_IBSS:
1221 sc->wi_create_ibss = wreq->wi_val[0];
1222 break;
1223 case WI_RID_OWN_CHNL:
1224 sc->wi_channel = wreq->wi_val[0];
1225 break;
1226 case WI_RID_NODENAME:
1227 bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
1228 bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30);
1229 break;
1230 case WI_RID_DESIRED_SSID:
1231 bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
1232 bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30);
1233 break;
1234 case WI_RID_OWN_SSID:
1235 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
1236 bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30);
1237 break;
1238 case WI_RID_PM_ENABLED:
1239 sc->wi_pm_enabled = wreq->wi_val[0];
1240 break;
1241 case WI_RID_MAX_SLEEP:
1242 sc->wi_max_sleep = wreq->wi_val[0];
1243 break;
1244 case WI_RID_ENCRYPTION:
1245 sc->wi_use_wep = wreq->wi_val[0];
1246 break;
1247 case WI_RID_TX_CRYPT_KEY:
1248 sc->wi_tx_key = wreq->wi_val[0];
1249 break;
1250 case WI_RID_DEFLT_CRYPT_KEYS:
1251 bcopy((char *)wreq, (char *)&sc->wi_keys,
1252 sizeof(struct wi_ltv_keys));
1253 break;
1254 default:
1255 break;
1256 }
1257
1258 /* Reinitialize WaveLAN. */
1259 wi_init(sc);
1260
1261 return;
1262}
1263
1264static int wi_ioctl(ifp, command, data)
1265 struct ifnet *ifp;
1266 u_long command;
1267 caddr_t data;
1268{
1269 int error = 0;
1270 struct wi_softc *sc;
1271 struct wi_req wreq;
1272 struct ifreq *ifr;
1273 struct proc *p = curproc;
1274
1275 sc = ifp->if_softc;
1276 WI_LOCK(sc);
1277 ifr = (struct ifreq *)data;
1278
1279 if (sc->wi_gone) {
1280 error = ENODEV;
1281 goto out;
1282 }
1283
1284 switch(command) {
1285 case SIOCSIFADDR:
1286 case SIOCGIFADDR:
1287 case SIOCSIFMTU:
1288 error = ether_ioctl(ifp, command, data);
1289 break;
1290 case SIOCSIFFLAGS:
1291 if (ifp->if_flags & IFF_UP) {
1292 if (ifp->if_flags & IFF_RUNNING &&
1293 ifp->if_flags & IFF_PROMISC &&
1294 !(sc->wi_if_flags & IFF_PROMISC)) {
1295 WI_SETVAL(WI_RID_PROMISC, 1);
1296 } else if (ifp->if_flags & IFF_RUNNING &&
1297 !(ifp->if_flags & IFF_PROMISC) &&
1298 sc->wi_if_flags & IFF_PROMISC) {
1299 WI_SETVAL(WI_RID_PROMISC, 0);
1300 } else
1301 wi_init(sc);
1302 } else {
1303 if (ifp->if_flags & IFF_RUNNING) {
1304 wi_stop(sc);
1305 }
1306 }
1307 sc->wi_if_flags = ifp->if_flags;
1308 error = 0;
1309 break;
1310 case SIOCADDMULTI:
1311 case SIOCDELMULTI:
1312 wi_setmulti(sc);
1313 error = 0;
1314 break;
1315 case SIOCGWAVELAN:
1316 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1317 if (error)
1318 break;
1319 /* Don't show WEP keys to non-root users. */
1320 if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS && suser(p))
1321 break;
1322 if (wreq.wi_type == WI_RID_IFACE_STATS) {
1323 bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val,
1324 sizeof(sc->wi_stats));
1325 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1326 } else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {
1327 bcopy((char *)&sc->wi_keys, (char *)&wreq,
1328 sizeof(struct wi_ltv_keys));
1329 }
1330#ifdef WICACHE
1331 else if (wreq.wi_type == WI_RID_ZERO_CACHE) {
1332 sc->wi_sigitems = sc->wi_nextitem = 0;
1333 } else if (wreq.wi_type == WI_RID_READ_CACHE) {
1334 char *pt = (char *)&wreq.wi_val;
1335 bcopy((char *)&sc->wi_sigitems,
1336 (char *)pt, sizeof(int));
1337 pt += (sizeof (int));
1338 wreq.wi_len = sizeof(int) / 2;
1339 bcopy((char *)&sc->wi_sigcache, (char *)pt,
1340 sizeof(struct wi_sigcache) * sc->wi_sigitems);
1341 wreq.wi_len += ((sizeof(struct wi_sigcache) *
1342 sc->wi_sigitems) / 2) + 1;
1343 }
1344#endif
1345 else {
1346 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
1347 error = EINVAL;
1348 break;
1349 }
1350 }
1351 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1352 break;
1353 case SIOCSWAVELAN:
1354 if ((error = suser(p)))
1355 goto out;
1356 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1357 if (error)
1358 break;
1359 if (wreq.wi_type == WI_RID_IFACE_STATS) {
1360 error = EINVAL;
1361 break;
1362 } else if (wreq.wi_type == WI_RID_MGMT_XMIT) {
1363 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1364 wreq.wi_len);
1365 } else {
1366 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
1367 if (!error)
1368 wi_setdef(sc, &wreq);
1369 }
1370 break;
1371 default:
1372 error = EINVAL;
1373 break;
1374 }
1375out:
1376 WI_UNLOCK(sc);
1377
1378 return(error);
1379}
1380
1381static void wi_init(xsc)
1382 void *xsc;
1383{
1384 struct wi_softc *sc = xsc;
1385 struct ifnet *ifp = &sc->arpcom.ac_if;
1386 struct wi_ltv_macaddr mac;
1387 int id = 0;
1388
1389 WI_LOCK(sc);
1390
1391 if (sc->wi_gone) {
1392 WI_UNLOCK(sc);
1393 return;
1394 }
1395
1396 if (ifp->if_flags & IFF_RUNNING)
1397 wi_stop(sc);
1398
1399 wi_reset(sc);
1400
1401 /* Program max data length. */
1402 WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
1403
1404 /* Enable/disable IBSS creation. */
1405 WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
1406
1407 /* Set the port type. */
1408 WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
1409
1410 /* Program the RTS/CTS threshold. */
1411 WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
1412
1413 /* Program the TX rate */
1414 WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
1415
1416 /* Access point density */
1417 WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
1418
1419 /* Power Management Enabled */
1420 WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
1421
1422 /* Power Managment Max Sleep */
1423 WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
1424
1425 /* Specify the IBSS name */
1426 WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
1427
1428 /* Specify the network name */
1429 WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
1430
1431 /* Specify the frequency to use */
1432 WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
1433
1434 /* Program the nodename. */
1435 WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name);
1436
1437 /* Set our MAC address. */
1438 mac.wi_len = 4;
1439 mac.wi_type = WI_RID_MAC_NODE;
1440 bcopy((char *)&sc->arpcom.ac_enaddr,
1441 (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN);
1442 wi_write_record(sc, (struct wi_ltv_gen *)&mac);
1443
1444 /* Configure WEP. */
1445 if (sc->wi_has_wep) {
1446 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
1447 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
1448 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
1449 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
1450 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
1451 }
1452
1453 /* Initialize promisc mode. */
1454 if (ifp->if_flags & IFF_PROMISC) {
1455 WI_SETVAL(WI_RID_PROMISC, 1);
1456 } else {
1457 WI_SETVAL(WI_RID_PROMISC, 0);
1458 }
1459
1460 /* Set multicast filter. */
1461 wi_setmulti(sc);
1462
1463 /* Enable desired port */
1464 wi_cmd(sc, WI_CMD_ENABLE|sc->wi_portnum, 0);
1465
1466 if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id))
1467 device_printf(sc->dev, "tx buffer allocation failed\n");
1468 sc->wi_tx_data_id = id;
1469
1470 if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id))
1471 device_printf(sc->dev, "mgmt. buffer allocation failed\n");
1472 sc->wi_tx_mgmt_id = id;
1473
1474 /* enable interrupts */
1475 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
1476
1477 ifp->if_flags |= IFF_RUNNING;
1478 ifp->if_flags &= ~IFF_OACTIVE;
1479
1480 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
1481 WI_UNLOCK(sc);
1482
1483 return;
1484}
1485
1486static void wi_start(ifp)
1487 struct ifnet *ifp;
1488{
1489 struct wi_softc *sc;
1490 struct mbuf *m0;
1491 struct wi_frame tx_frame;
1492 struct ether_header *eh;
1493 int id;
1494
1495 sc = ifp->if_softc;
1496 WI_LOCK(sc);
1497
1498 if (sc->wi_gone) {
1499 WI_UNLOCK(sc);
1500 return;
1501 }
1502
1503 if (ifp->if_flags & IFF_OACTIVE) {
1504 WI_UNLOCK(sc);
1505 return;
1506 }
1507
1508 IF_DEQUEUE(&ifp->if_snd, m0);
1509 if (m0 == NULL) {
1510 WI_UNLOCK(sc);
1511 return;
1512 }
1513
1514 bzero((char *)&tx_frame, sizeof(tx_frame));
1515 id = sc->wi_tx_data_id;
1516 eh = mtod(m0, struct ether_header *);
1517
1518 /*
1519 * Use RFC1042 encoding for IP and ARP datagrams,
1520 * 802.3 for anything else.
1521 */
115#endif
116
117#ifdef foo
118static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
119#endif
120
121static void wi_intr __P((void *));
122static void wi_reset __P((struct wi_softc *));
123static int wi_ioctl __P((struct ifnet *, u_long, caddr_t));
124static void wi_init __P((void *));
125static void wi_start __P((struct ifnet *));
126static void wi_stop __P((struct wi_softc *));
127static void wi_watchdog __P((struct ifnet *));
128static void wi_rxeof __P((struct wi_softc *));
129static void wi_txeof __P((struct wi_softc *, int));
130static void wi_update_stats __P((struct wi_softc *));
131static void wi_setmulti __P((struct wi_softc *));
132
133static int wi_cmd __P((struct wi_softc *, int, int));
134static int wi_read_record __P((struct wi_softc *, struct wi_ltv_gen *));
135static int wi_write_record __P((struct wi_softc *, struct wi_ltv_gen *));
136static int wi_read_data __P((struct wi_softc *, int,
137 int, caddr_t, int));
138static int wi_write_data __P((struct wi_softc *, int,
139 int, caddr_t, int));
140static int wi_seek __P((struct wi_softc *, int, int, int));
141static int wi_alloc_nicmem __P((struct wi_softc *, int, int *));
142static void wi_inquire __P((void *));
143static void wi_setdef __P((struct wi_softc *, struct wi_req *));
144static int wi_mgmt_xmit __P((struct wi_softc *, caddr_t, int));
145
146#ifdef WICACHE
147static
148void wi_cache_store __P((struct wi_softc *, struct ether_header *,
149 struct mbuf *, unsigned short));
150#endif
151
152static int wi_generic_attach __P((device_t));
153static int wi_pccard_match __P((device_t));
154static int wi_pccard_probe __P((device_t));
155static int wi_pci_probe __P((device_t));
156static int wi_pccard_attach __P((device_t));
157static int wi_pci_attach __P((device_t));
158static int wi_pccard_detach __P((device_t));
159static void wi_shutdown __P((device_t));
160
161static int wi_alloc __P((device_t, int));
162static void wi_free __P((device_t));
163
164static device_method_t wi_pccard_methods[] = {
165 /* Device interface */
166 DEVMETHOD(device_probe, pccard_compat_probe),
167 DEVMETHOD(device_attach, pccard_compat_attach),
168 DEVMETHOD(device_detach, wi_pccard_detach),
169 DEVMETHOD(device_shutdown, wi_shutdown),
170
171 /* Card interface */
172 DEVMETHOD(card_compat_match, wi_pccard_match),
173 DEVMETHOD(card_compat_probe, wi_pccard_probe),
174 DEVMETHOD(card_compat_attach, wi_pccard_attach),
175
176 { 0, 0 }
177};
178
179static device_method_t wi_pci_methods[] = {
180 /* Device interface */
181 DEVMETHOD(device_probe, wi_pci_probe),
182 DEVMETHOD(device_attach, wi_pci_attach),
183 DEVMETHOD(device_detach, wi_pccard_detach),
184 DEVMETHOD(device_shutdown, wi_shutdown),
185
186 { 0, 0 }
187};
188
189static driver_t wi_pccard_driver = {
190 "wi",
191 wi_pccard_methods,
192 sizeof(struct wi_softc)
193};
194
195static driver_t wi_pci_driver = {
196 "wi",
197 wi_pci_methods,
198 sizeof(struct wi_softc)
199};
200
201static devclass_t wi_pccard_devclass;
202static devclass_t wi_pci_devclass;
203
204DRIVER_MODULE(if_wi, pccard, wi_pccard_driver, wi_pccard_devclass, 0, 0);
205DRIVER_MODULE(if_wi, pci, wi_pci_driver, wi_pci_devclass, 0, 0);
206
207static const struct pccard_product wi_pccard_products[] = {
208 { PCCARD_STR_LUCENT_WAVELAN_IEEE, PCCARD_VENDOR_LUCENT,
209 PCCARD_PRODUCT_LUCENT_WAVELAN_IEEE, 0,
210 PCCARD_CIS_LUCENT_WAVELAN_IEEE },
211};
212
213static char wi_device_desc[] = "WaveLAN/IEEE 802.11";
214
215static int wi_pccard_match(dev)
216 device_t dev;
217{
218 const struct pccard_product *pp;
219
220 if ((pp = pccard_product_lookup(dev, wi_pccard_products,
221 sizeof(wi_pccard_products[0]), NULL)) != NULL) {
222 device_set_desc(dev, pp->pp_name);
223 return 0;
224 }
225 return ENXIO;
226}
227
228static int wi_pccard_probe(dev)
229 device_t dev;
230{
231 struct wi_softc *sc;
232 int error;
233
234 sc = device_get_softc(dev);
235 sc->wi_gone = 0;
236
237 error = wi_alloc(dev, 0);
238 if (error)
239 return (error);
240
241 wi_free(dev);
242
243 /* Make sure interrupts are disabled. */
244 CSR_WRITE_2(sc, WI_INT_EN, 0);
245 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
246
247 return (0);
248}
249
250static int
251wi_pci_probe(dev)
252 device_t dev;
253{
254 struct wi_softc *sc;
255
256 sc = device_get_softc(dev);
257 if ((pci_get_vendor(dev) == WI_PCI_VENDOR_EUMITCOM) &&
258 (pci_get_device(dev) == WI_PCI_DEVICE_PRISM2STA)) {
259 sc->wi_prism2 = 1;
260 device_set_desc(dev,
261 "PRISM2STA PCI WaveLAN/IEEE 802.11");
262 return (0);
263 }
264 return(ENXIO);
265}
266
267static int wi_pccard_detach(dev)
268 device_t dev;
269{
270 struct wi_softc *sc;
271 struct ifnet *ifp;
272
273 sc = device_get_softc(dev);
274 WI_LOCK(sc);
275 ifp = &sc->arpcom.ac_if;
276
277 if (sc->wi_gone) {
278 device_printf(dev, "already unloaded\n");
279 WI_UNLOCK(sc);
280 return(ENODEV);
281 }
282
283 wi_stop(sc);
284
285 ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
286 bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
287 wi_free(dev);
288 sc->wi_gone = 1;
289
290 WI_UNLOCK(sc);
291 mtx_destroy(&sc->wi_mtx);
292
293 return(0);
294}
295
296static int wi_pccard_attach(device_t dev)
297{
298 struct wi_softc *sc;
299 int error;
300 u_int32_t flags;
301
302 sc = device_get_softc(dev);
303
304 /*
305 * XXX: quick hack to support Prism II chip.
306 * Currently, we need to set a flags in pccard.conf to specify
307 * which type chip is used.
308 *
309 * We need to replace this code in a future.
310 * It is better to use CIS than using a flag.
311 */
312 flags = device_get_flags(dev);
313#define WI_FLAGS_PRISM2 0x10000
314 if (flags & WI_FLAGS_PRISM2) {
315 sc->wi_prism2 = 1;
316 if (bootverbose) {
317 device_printf(dev, "found PrismII chip\n");
318 }
319 }
320 else {
321 sc->wi_prism2 = 0;
322 if (bootverbose) {
323 device_printf(dev, "found Lucent chip\n");
324 }
325 }
326
327 error = wi_alloc(dev, 0);
328 if (error) {
329 device_printf(dev, "wi_alloc() failed! (%d)\n", error);
330 return (error);
331 }
332 return (wi_generic_attach(dev));
333}
334
335static int
336wi_pci_attach(device_t dev)
337{
338 struct wi_softc *sc;
339 u_int32_t command, wanted;
340 u_int16_t reg;
341 int error;
342
343 sc = device_get_softc(dev);
344
345 command = pci_read_config(dev, PCIR_COMMAND, 4);
346 wanted = PCIM_CMD_PORTEN|PCIM_CMD_MEMEN;
347 command |= wanted;
348 pci_write_config(dev, PCIR_COMMAND, command, 4);
349 command = pci_read_config(dev, PCIR_COMMAND, 4);
350 if ((command & wanted) != wanted) {
351 device_printf(dev, "wi_pci_attach() failed to enable pci!\n");
352 return (ENXIO);
353 }
354
355 error = wi_alloc(dev, WI_PCI_IORES);
356 if (error)
357 return (error);
358
359 device_set_desc(dev, wi_device_desc);
360
361 /* Make sure interrupts are disabled. */
362 CSR_WRITE_2(sc, WI_INT_EN, 0);
363 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
364
365 sc->mem_rid = WI_PCI_MEMRES;
366 sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid,
367 0, ~0, 1, RF_ACTIVE);
368 if (sc->mem == NULL) {
369 device_printf(dev, "couldn't allocate memory\n");
370 wi_free(dev);
371 return (ENXIO);
372 }
373 sc->wi_bmemtag = rman_get_bustag(sc->mem);
374 sc->wi_bmemhandle = rman_get_bushandle(sc->mem);
375
376 /*
377 * From Linux driver:
378 * Write COR to enable PC card
379 * This is a subset of the protocol that the pccard bus code
380 * would do.
381 */
382 CSM_WRITE_1(sc, WI_COR_OFFSET, WI_COR_VALUE);
383 reg = CSM_READ_1(sc, WI_COR_OFFSET);
384
385 CSR_WRITE_2(sc, WI_HFA384X_SWSUPPORT0_OFF, WI_PRISM2STA_MAGIC);
386 reg = CSR_READ_2(sc, WI_HFA384X_SWSUPPORT0_OFF);
387 if (reg != WI_PRISM2STA_MAGIC) {
388 device_printf(dev,
389 "CSR_READ_2(WI_HFA384X_SWSUPPORT0_OFF) "
390 "wanted %d, got %d\n", WI_PRISM2STA_MAGIC, reg);
391 wi_free(dev);
392 return (ENXIO);
393 }
394
395 error = wi_generic_attach(dev);
396 if (error != 0)
397 return (error);
398
399 return (0);
400}
401
402static int
403wi_generic_attach(device_t dev)
404{
405 struct wi_softc *sc;
406 struct wi_ltv_macaddr mac;
407 struct wi_ltv_gen gen;
408 struct ifnet *ifp;
409 int error;
410
411 sc = device_get_softc(dev);
412 ifp = &sc->arpcom.ac_if;
413
414 error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
415 wi_intr, sc, &sc->wi_intrhand);
416
417 if (error) {
418 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
419 wi_free(dev);
420 return (error);
421 }
422
423 mtx_init(&sc->wi_mtx, device_get_nameunit(dev), MTX_DEF | MTX_RECURSE);
424 WI_LOCK(sc);
425
426 /* Reset the NIC. */
427 wi_reset(sc);
428
429 /* Read the station address. */
430 mac.wi_type = WI_RID_MAC_NODE;
431 mac.wi_len = 4;
432 if ((error = wi_read_record(sc, (struct wi_ltv_gen *)&mac)) != 0) {
433 device_printf(dev, "mac read failed %d\n", error);
434 wi_free(dev);
435 return (error);
436 }
437 bcopy((char *)&mac.wi_mac_addr,
438 (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
439
440 device_printf(dev, "Ethernet address: %6D\n",
441 sc->arpcom.ac_enaddr, ":");
442
443 ifp->if_softc = sc;
444 ifp->if_unit = sc->wi_unit;
445 ifp->if_name = "wi";
446 ifp->if_mtu = ETHERMTU;
447 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
448 ifp->if_ioctl = wi_ioctl;
449 ifp->if_output = ether_output;
450 ifp->if_start = wi_start;
451 ifp->if_watchdog = wi_watchdog;
452 ifp->if_init = wi_init;
453 ifp->if_baudrate = 10000000;
454 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
455
456 bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
457 bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name,
458 sizeof(WI_DEFAULT_NODENAME) - 1);
459
460 bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
461 bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name,
462 sizeof(WI_DEFAULT_NETNAME) - 1);
463
464 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
465 bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name,
466 sizeof(WI_DEFAULT_IBSS) - 1);
467
468 sc->wi_portnum = WI_DEFAULT_PORT;
469 sc->wi_ptype = WI_PORTTYPE_BSS;
470 sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
471 sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
472 sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
473 sc->wi_max_data_len = WI_DEFAULT_DATALEN;
474 sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
475 sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
476 sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
477
478 /*
479 * Read the default channel from the NIC. This may vary
480 * depending on the country where the NIC was purchased, so
481 * we can't hard-code a default and expect it to work for
482 * everyone.
483 */
484 gen.wi_type = WI_RID_OWN_CHNL;
485 gen.wi_len = 2;
486 wi_read_record(sc, &gen);
487 sc->wi_channel = gen.wi_val;
488
489 /*
490 * Find out if we support WEP on this card.
491 */
492 gen.wi_type = WI_RID_WEP_AVAIL;
493 gen.wi_len = 2;
494 wi_read_record(sc, &gen);
495 sc->wi_has_wep = gen.wi_val;
496
497 if (bootverbose) {
498 device_printf(sc->dev,
499 __FUNCTION__ ":wi_has_wep = %d\n",
500 sc->wi_has_wep);
501 }
502
503 bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
504
505 wi_init(sc);
506 wi_stop(sc);
507
508 /*
509 * Call MI attach routine.
510 */
511 ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
512 callout_handle_init(&sc->wi_stat_ch);
513 WI_UNLOCK(sc);
514
515 return(0);
516}
517
518static void wi_rxeof(sc)
519 struct wi_softc *sc;
520{
521 struct ifnet *ifp;
522 struct ether_header *eh;
523 struct wi_frame rx_frame;
524 struct mbuf *m;
525 int id;
526
527 ifp = &sc->arpcom.ac_if;
528
529 id = CSR_READ_2(sc, WI_RX_FID);
530
531 /* First read in the frame header */
532 if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
533 ifp->if_ierrors++;
534 return;
535 }
536
537 if (rx_frame.wi_status & WI_STAT_ERRSTAT) {
538 ifp->if_ierrors++;
539 return;
540 }
541
542 MGETHDR(m, M_DONTWAIT, MT_DATA);
543 if (m == NULL) {
544 ifp->if_ierrors++;
545 return;
546 }
547 MCLGET(m, M_DONTWAIT);
548 if (!(m->m_flags & M_EXT)) {
549 m_freem(m);
550 ifp->if_ierrors++;
551 return;
552 }
553
554 eh = mtod(m, struct ether_header *);
555 m->m_pkthdr.rcvif = ifp;
556
557 if (rx_frame.wi_status == WI_STAT_1042 ||
558 rx_frame.wi_status == WI_STAT_TUNNEL ||
559 rx_frame.wi_status == WI_STAT_WMP_MSG) {
560 if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) {
561 device_printf(sc->dev, "oversized packet received "
562 "(wi_dat_len=%d, wi_status=0x%x)\n",
563 rx_frame.wi_dat_len, rx_frame.wi_status);
564 m_freem(m);
565 ifp->if_ierrors++;
566 return;
567 }
568 m->m_pkthdr.len = m->m_len =
569 rx_frame.wi_dat_len + WI_SNAPHDR_LEN;
570
571 bcopy((char *)&rx_frame.wi_addr1,
572 (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
573 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) {
574 bcopy((char *)&rx_frame.wi_addr2,
575 (char *)&eh->ether_shost, ETHER_ADDR_LEN);
576 } else {
577 bcopy((char *)&rx_frame.wi_addr3,
578 (char *)&eh->ether_shost, ETHER_ADDR_LEN);
579 }
580 bcopy((char *)&rx_frame.wi_type,
581 (char *)&eh->ether_type, sizeof(u_int16_t));
582
583 if (wi_read_data(sc, id, WI_802_11_OFFSET,
584 mtod(m, caddr_t) + sizeof(struct ether_header),
585 m->m_len + 2)) {
586 m_freem(m);
587 ifp->if_ierrors++;
588 return;
589 }
590 } else {
591 if((rx_frame.wi_dat_len +
592 sizeof(struct ether_header)) > MCLBYTES) {
593 device_printf(sc->dev, "oversized packet received "
594 "(wi_dat_len=%d, wi_status=0x%x)\n",
595 rx_frame.wi_dat_len, rx_frame.wi_status);
596 m_freem(m);
597 ifp->if_ierrors++;
598 return;
599 }
600 m->m_pkthdr.len = m->m_len =
601 rx_frame.wi_dat_len + sizeof(struct ether_header);
602
603 if (wi_read_data(sc, id, WI_802_3_OFFSET,
604 mtod(m, caddr_t), m->m_len + 2)) {
605 m_freem(m);
606 ifp->if_ierrors++;
607 return;
608 }
609 }
610
611 ifp->if_ipackets++;
612
613 /* Receive packet. */
614 m_adj(m, sizeof(struct ether_header));
615#ifdef WICACHE
616 wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
617#endif
618 ether_input(ifp, eh, m);
619}
620
621static void wi_txeof(sc, status)
622 struct wi_softc *sc;
623 int status;
624{
625 struct ifnet *ifp;
626
627 ifp = &sc->arpcom.ac_if;
628
629 ifp->if_timer = 0;
630 ifp->if_flags &= ~IFF_OACTIVE;
631
632 if (status & WI_EV_TX_EXC)
633 ifp->if_oerrors++;
634 else
635 ifp->if_opackets++;
636
637 return;
638}
639
640void wi_inquire(xsc)
641 void *xsc;
642{
643 struct wi_softc *sc;
644 struct ifnet *ifp;
645
646 sc = xsc;
647 ifp = &sc->arpcom.ac_if;
648
649 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
650
651 /* Don't do this while we're transmitting */
652 if (ifp->if_flags & IFF_OACTIVE)
653 return;
654
655 wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS);
656
657 return;
658}
659
660void wi_update_stats(sc)
661 struct wi_softc *sc;
662{
663 struct wi_ltv_gen gen;
664 u_int16_t id;
665 struct ifnet *ifp;
666 u_int32_t *ptr;
667 int i;
668 u_int16_t t;
669
670 ifp = &sc->arpcom.ac_if;
671
672 id = CSR_READ_2(sc, WI_INFO_FID);
673
674 wi_read_data(sc, id, 0, (char *)&gen, 4);
675
676 if (gen.wi_type != WI_INFO_COUNTERS ||
677 gen.wi_len > (sizeof(sc->wi_stats) / 4) + 1)
678 return;
679
680 ptr = (u_int32_t *)&sc->wi_stats;
681
682 for (i = 0; i < gen.wi_len - 1; i++) {
683 t = CSR_READ_2(sc, WI_DATA1);
684#ifdef WI_HERMES_STATS_WAR
685 if (t > 0xF000)
686 t = ~t & 0xFFFF;
687#endif
688 ptr[i] += t;
689 }
690
691 ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
692 sc->wi_stats.wi_tx_multi_retries +
693 sc->wi_stats.wi_tx_retry_limit;
694
695 return;
696}
697
698static void wi_intr(xsc)
699 void *xsc;
700{
701 struct wi_softc *sc = xsc;
702 struct ifnet *ifp;
703 u_int16_t status;
704
705 WI_LOCK(sc);
706
707 ifp = &sc->arpcom.ac_if;
708
709 if (!(ifp->if_flags & IFF_UP)) {
710 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
711 CSR_WRITE_2(sc, WI_INT_EN, 0);
712 WI_UNLOCK(sc);
713 return;
714 }
715
716 /* Disable interrupts. */
717 CSR_WRITE_2(sc, WI_INT_EN, 0);
718
719 status = CSR_READ_2(sc, WI_EVENT_STAT);
720 CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
721
722 if (status & WI_EV_RX) {
723 wi_rxeof(sc);
724 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
725 }
726
727 if (status & WI_EV_TX) {
728 wi_txeof(sc, status);
729 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
730 }
731
732 if (status & WI_EV_ALLOC) {
733 int id;
734 id = CSR_READ_2(sc, WI_ALLOC_FID);
735 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
736 if (id == sc->wi_tx_data_id)
737 wi_txeof(sc, status);
738 }
739
740 if (status & WI_EV_INFO) {
741 wi_update_stats(sc);
742 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
743 }
744
745 if (status & WI_EV_TX_EXC) {
746 wi_txeof(sc, status);
747 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
748 }
749
750 if (status & WI_EV_INFO_DROP) {
751 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
752 }
753
754 /* Re-enable interrupts. */
755 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
756
757 if (ifp->if_snd.ifq_head != NULL)
758 wi_start(ifp);
759
760 WI_UNLOCK(sc);
761
762 return;
763}
764
765static int wi_cmd(sc, cmd, val)
766 struct wi_softc *sc;
767 int cmd;
768 int val;
769{
770 int i, s = 0;
771
772 /* wait for the busy bit to clear */
773 for (i = 200; i > 0; i--) {
774 if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) {
775 break;
776 }
777 DELAY(10*1000); /* 10 m sec */
778 }
779 if (i == 0) {
780 return(ETIMEDOUT);
781 }
782
783 CSR_WRITE_2(sc, WI_PARAM0, val);
784 CSR_WRITE_2(sc, WI_PARAM1, 0);
785 CSR_WRITE_2(sc, WI_PARAM2, 0);
786 CSR_WRITE_2(sc, WI_COMMAND, cmd);
787
788 for (i = 0; i < WI_TIMEOUT; i++) {
789 /*
790 * Wait for 'command complete' bit to be
791 * set in the event status register.
792 */
793 s = CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD;
794 if (s) {
795 /* Ack the event and read result code. */
796 s = CSR_READ_2(sc, WI_STATUS);
797 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
798#ifdef foo
799 if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK))
800 return(EIO);
801#endif
802 if (s & WI_STAT_CMD_RESULT)
803 return(EIO);
804 break;
805 }
806 }
807
808 if (i == WI_TIMEOUT)
809 return(ETIMEDOUT);
810
811 return(0);
812}
813
814static void wi_reset(sc)
815 struct wi_softc *sc;
816{
817 int i;
818
819 for (i = 0; i < 5; i++) {
820 if (wi_cmd(sc, WI_CMD_INI, 0) == 0)
821 break;
822 DELAY(100000);
823 }
824 if (i == 5)
825 device_printf(sc->dev, "init failed\n");
826 CSR_WRITE_2(sc, WI_INT_EN, 0);
827 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
828
829 /* Calibrate timer. */
830 WI_SETVAL(WI_RID_TICK_TIME, 8);
831
832 return;
833}
834
835/*
836 * Read an LTV record from the NIC.
837 */
838static int wi_read_record(sc, ltv)
839 struct wi_softc *sc;
840 struct wi_ltv_gen *ltv;
841{
842 u_int16_t *ptr;
843 int i, len, code;
844 struct wi_ltv_gen *oltv, p2ltv;
845
846 oltv = ltv;
847 if (sc->wi_prism2) {
848 switch (ltv->wi_type) {
849 case WI_RID_ENCRYPTION:
850 p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
851 p2ltv.wi_len = 2;
852 ltv = &p2ltv;
853 break;
854 case WI_RID_TX_CRYPT_KEY:
855 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
856 p2ltv.wi_len = 2;
857 ltv = &p2ltv;
858 break;
859 }
860 }
861
862 /* Tell the NIC to enter record read mode. */
863 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type))
864 return(EIO);
865
866 /* Seek to the record. */
867 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
868 return(EIO);
869
870 /*
871 * Read the length and record type and make sure they
872 * match what we expect (this verifies that we have enough
873 * room to hold all of the returned data).
874 */
875 len = CSR_READ_2(sc, WI_DATA1);
876 if (len > ltv->wi_len)
877 return(ENOSPC);
878 code = CSR_READ_2(sc, WI_DATA1);
879 if (code != ltv->wi_type)
880 return(EIO);
881
882 ltv->wi_len = len;
883 ltv->wi_type = code;
884
885 /* Now read the data. */
886 ptr = &ltv->wi_val;
887 for (i = 0; i < ltv->wi_len - 1; i++)
888 ptr[i] = CSR_READ_2(sc, WI_DATA1);
889
890 if (sc->wi_prism2) {
891 switch (oltv->wi_type) {
892 case WI_RID_TX_RATE:
893 case WI_RID_CUR_TX_RATE:
894 switch (ltv->wi_val) {
895 case 1: oltv->wi_val = 1; break;
896 case 2: oltv->wi_val = 2; break;
897 case 3: oltv->wi_val = 6; break;
898 case 4: oltv->wi_val = 5; break;
899 case 7: oltv->wi_val = 7; break;
900 case 8: oltv->wi_val = 11; break;
901 case 15: oltv->wi_val = 3; break;
902 default: oltv->wi_val = 0x100 + ltv->wi_val; break;
903 }
904 break;
905 case WI_RID_ENCRYPTION:
906 oltv->wi_len = 2;
907 if (ltv->wi_val & 0x01)
908 oltv->wi_val = 1;
909 else
910 oltv->wi_val = 0;
911 break;
912 case WI_RID_TX_CRYPT_KEY:
913 oltv->wi_len = 2;
914 oltv->wi_val = ltv->wi_val;
915 break;
916 }
917 }
918
919 return(0);
920}
921
922/*
923 * Same as read, except we inject data instead of reading it.
924 */
925static int wi_write_record(sc, ltv)
926 struct wi_softc *sc;
927 struct wi_ltv_gen *ltv;
928{
929 u_int16_t *ptr;
930 int i;
931 struct wi_ltv_gen p2ltv;
932
933 if (sc->wi_prism2) {
934 switch (ltv->wi_type) {
935 case WI_RID_TX_RATE:
936 p2ltv.wi_type = WI_RID_TX_RATE;
937 p2ltv.wi_len = 2;
938 switch (ltv->wi_val) {
939 case 1: p2ltv.wi_val = 1; break;
940 case 2: p2ltv.wi_val = 2; break;
941 case 3: p2ltv.wi_val = 15; break;
942 case 5: p2ltv.wi_val = 4; break;
943 case 6: p2ltv.wi_val = 3; break;
944 case 7: p2ltv.wi_val = 7; break;
945 case 11: p2ltv.wi_val = 8; break;
946 default: return EINVAL;
947 }
948 ltv = &p2ltv;
949 break;
950 case WI_RID_ENCRYPTION:
951 p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
952 p2ltv.wi_len = 2;
953 if (ltv->wi_val)
954 p2ltv.wi_val = 0x03;
955 else
956 p2ltv.wi_val = 0x90;
957 ltv = &p2ltv;
958 break;
959 case WI_RID_TX_CRYPT_KEY:
960 p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
961 p2ltv.wi_len = 2;
962 p2ltv.wi_val = ltv->wi_val;
963 ltv = &p2ltv;
964 break;
965 case WI_RID_DEFLT_CRYPT_KEYS:
966 {
967 int error;
968 struct wi_ltv_str ws;
969 struct wi_ltv_keys *wk =
970 (struct wi_ltv_keys *)ltv;
971
972 for (i = 0; i < 4; i++) {
973 ws.wi_len = 4;
974 ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
975 memcpy(ws.wi_str,
976 &wk->wi_keys[i].wi_keydat, 5);
977 ws.wi_str[5] = '\0';
978 error = wi_write_record(sc,
979 (struct wi_ltv_gen *)&ws);
980 if (error)
981 return error;
982 }
983 return 0;
984 }
985 }
986 }
987
988 if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
989 return(EIO);
990
991 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
992 CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
993
994 ptr = &ltv->wi_val;
995 for (i = 0; i < ltv->wi_len - 1; i++)
996 CSR_WRITE_2(sc, WI_DATA1, ptr[i]);
997
998 if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type))
999 return(EIO);
1000
1001 return(0);
1002}
1003
1004static int wi_seek(sc, id, off, chan)
1005 struct wi_softc *sc;
1006 int id, off, chan;
1007{
1008 int i;
1009 int selreg, offreg;
1010
1011 switch (chan) {
1012 case WI_BAP0:
1013 selreg = WI_SEL0;
1014 offreg = WI_OFF0;
1015 break;
1016 case WI_BAP1:
1017 selreg = WI_SEL1;
1018 offreg = WI_OFF1;
1019 break;
1020 default:
1021 device_printf(sc->dev, "invalid data path: %x\n", chan);
1022 return(EIO);
1023 }
1024
1025 CSR_WRITE_2(sc, selreg, id);
1026 CSR_WRITE_2(sc, offreg, off);
1027
1028 for (i = 0; i < WI_TIMEOUT; i++) {
1029 if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR)))
1030 break;
1031 }
1032
1033 if (i == WI_TIMEOUT)
1034 return(ETIMEDOUT);
1035
1036 return(0);
1037}
1038
1039static int wi_read_data(sc, id, off, buf, len)
1040 struct wi_softc *sc;
1041 int id, off;
1042 caddr_t buf;
1043 int len;
1044{
1045 int i;
1046 u_int16_t *ptr;
1047
1048 if (wi_seek(sc, id, off, WI_BAP1))
1049 return(EIO);
1050
1051 ptr = (u_int16_t *)buf;
1052 for (i = 0; i < len / 2; i++)
1053 ptr[i] = CSR_READ_2(sc, WI_DATA1);
1054
1055 return(0);
1056}
1057
1058/*
1059 * According to the comments in the HCF Light code, there is a bug in
1060 * the Hermes (or possibly in certain Hermes firmware revisions) where
1061 * the chip's internal autoincrement counter gets thrown off during
1062 * data writes: the autoincrement is missed, causing one data word to
1063 * be overwritten and subsequent words to be written to the wrong memory
1064 * locations. The end result is that we could end up transmitting bogus
1065 * frames without realizing it. The workaround for this is to write a
1066 * couple of extra guard words after the end of the transfer, then
1067 * attempt to read then back. If we fail to locate the guard words where
1068 * we expect them, we preform the transfer over again.
1069 */
1070static int wi_write_data(sc, id, off, buf, len)
1071 struct wi_softc *sc;
1072 int id, off;
1073 caddr_t buf;
1074 int len;
1075{
1076 int i;
1077 u_int16_t *ptr;
1078#ifdef WI_HERMES_AUTOINC_WAR
1079 int retries;
1080
1081 retries = WI_TIMEOUT >> 4;
1082again:
1083#endif
1084
1085 if (wi_seek(sc, id, off, WI_BAP0))
1086 return(EIO);
1087
1088 ptr = (u_int16_t *)buf;
1089 for (i = 0; i < (len / 2); i++)
1090 CSR_WRITE_2(sc, WI_DATA0, ptr[i]);
1091
1092#ifdef WI_HERMES_AUTOINC_WAR
1093 CSR_WRITE_2(sc, WI_DATA0, 0x1234);
1094 CSR_WRITE_2(sc, WI_DATA0, 0x5678);
1095
1096 if (wi_seek(sc, id, off + len, WI_BAP0))
1097 return(EIO);
1098
1099 if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
1100 CSR_READ_2(sc, WI_DATA0) != 0x5678) {
1101 if (--retries >= 0)
1102 goto again;
1103 device_printf(sc->dev, "wi_write_data device timeout\n");
1104 return (EIO);
1105 }
1106#endif
1107
1108 return(0);
1109}
1110
1111/*
1112 * Allocate a region of memory inside the NIC and zero
1113 * it out.
1114 */
1115static int wi_alloc_nicmem(sc, len, id)
1116 struct wi_softc *sc;
1117 int len;
1118 int *id;
1119{
1120 int i;
1121
1122 if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) {
1123 device_printf(sc->dev,
1124 "failed to allocate %d bytes on NIC\n", len);
1125 return(ENOMEM);
1126 }
1127
1128 for (i = 0; i < WI_TIMEOUT; i++) {
1129 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
1130 break;
1131 }
1132
1133 if (i == WI_TIMEOUT)
1134 return(ETIMEDOUT);
1135
1136 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1137 *id = CSR_READ_2(sc, WI_ALLOC_FID);
1138
1139 if (wi_seek(sc, *id, 0, WI_BAP0))
1140 return(EIO);
1141
1142 for (i = 0; i < len / 2; i++)
1143 CSR_WRITE_2(sc, WI_DATA0, 0);
1144
1145 return(0);
1146}
1147
1148static void wi_setmulti(sc)
1149 struct wi_softc *sc;
1150{
1151 struct ifnet *ifp;
1152 int i = 0;
1153 struct ifmultiaddr *ifma;
1154 struct wi_ltv_mcast mcast;
1155
1156 ifp = &sc->arpcom.ac_if;
1157
1158 bzero((char *)&mcast, sizeof(mcast));
1159
1160 mcast.wi_type = WI_RID_MCAST;
1161 mcast.wi_len = (3 * 16) + 1;
1162
1163 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
1164 wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1165 return;
1166 }
1167
1168 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1169 if (ifma->ifma_addr->sa_family != AF_LINK)
1170 continue;
1171 if (i < 16) {
1172 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
1173 (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN);
1174 i++;
1175 } else {
1176 bzero((char *)&mcast, sizeof(mcast));
1177 break;
1178 }
1179 }
1180
1181 mcast.wi_len = (i * 3) + 1;
1182 wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1183
1184 return;
1185}
1186
1187static void wi_setdef(sc, wreq)
1188 struct wi_softc *sc;
1189 struct wi_req *wreq;
1190{
1191 struct sockaddr_dl *sdl;
1192 struct ifaddr *ifa;
1193 struct ifnet *ifp;
1194
1195 ifp = &sc->arpcom.ac_if;
1196
1197 switch(wreq->wi_type) {
1198 case WI_RID_MAC_NODE:
1199 ifa = ifnet_addrs[ifp->if_index - 1];
1200 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1201 bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr,
1202 ETHER_ADDR_LEN);
1203 bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);
1204 break;
1205 case WI_RID_PORTTYPE:
1206 sc->wi_ptype = wreq->wi_val[0];
1207 break;
1208 case WI_RID_TX_RATE:
1209 sc->wi_tx_rate = wreq->wi_val[0];
1210 break;
1211 case WI_RID_MAX_DATALEN:
1212 sc->wi_max_data_len = wreq->wi_val[0];
1213 break;
1214 case WI_RID_RTS_THRESH:
1215 sc->wi_rts_thresh = wreq->wi_val[0];
1216 break;
1217 case WI_RID_SYSTEM_SCALE:
1218 sc->wi_ap_density = wreq->wi_val[0];
1219 break;
1220 case WI_RID_CREATE_IBSS:
1221 sc->wi_create_ibss = wreq->wi_val[0];
1222 break;
1223 case WI_RID_OWN_CHNL:
1224 sc->wi_channel = wreq->wi_val[0];
1225 break;
1226 case WI_RID_NODENAME:
1227 bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
1228 bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30);
1229 break;
1230 case WI_RID_DESIRED_SSID:
1231 bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
1232 bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30);
1233 break;
1234 case WI_RID_OWN_SSID:
1235 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
1236 bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30);
1237 break;
1238 case WI_RID_PM_ENABLED:
1239 sc->wi_pm_enabled = wreq->wi_val[0];
1240 break;
1241 case WI_RID_MAX_SLEEP:
1242 sc->wi_max_sleep = wreq->wi_val[0];
1243 break;
1244 case WI_RID_ENCRYPTION:
1245 sc->wi_use_wep = wreq->wi_val[0];
1246 break;
1247 case WI_RID_TX_CRYPT_KEY:
1248 sc->wi_tx_key = wreq->wi_val[0];
1249 break;
1250 case WI_RID_DEFLT_CRYPT_KEYS:
1251 bcopy((char *)wreq, (char *)&sc->wi_keys,
1252 sizeof(struct wi_ltv_keys));
1253 break;
1254 default:
1255 break;
1256 }
1257
1258 /* Reinitialize WaveLAN. */
1259 wi_init(sc);
1260
1261 return;
1262}
1263
1264static int wi_ioctl(ifp, command, data)
1265 struct ifnet *ifp;
1266 u_long command;
1267 caddr_t data;
1268{
1269 int error = 0;
1270 struct wi_softc *sc;
1271 struct wi_req wreq;
1272 struct ifreq *ifr;
1273 struct proc *p = curproc;
1274
1275 sc = ifp->if_softc;
1276 WI_LOCK(sc);
1277 ifr = (struct ifreq *)data;
1278
1279 if (sc->wi_gone) {
1280 error = ENODEV;
1281 goto out;
1282 }
1283
1284 switch(command) {
1285 case SIOCSIFADDR:
1286 case SIOCGIFADDR:
1287 case SIOCSIFMTU:
1288 error = ether_ioctl(ifp, command, data);
1289 break;
1290 case SIOCSIFFLAGS:
1291 if (ifp->if_flags & IFF_UP) {
1292 if (ifp->if_flags & IFF_RUNNING &&
1293 ifp->if_flags & IFF_PROMISC &&
1294 !(sc->wi_if_flags & IFF_PROMISC)) {
1295 WI_SETVAL(WI_RID_PROMISC, 1);
1296 } else if (ifp->if_flags & IFF_RUNNING &&
1297 !(ifp->if_flags & IFF_PROMISC) &&
1298 sc->wi_if_flags & IFF_PROMISC) {
1299 WI_SETVAL(WI_RID_PROMISC, 0);
1300 } else
1301 wi_init(sc);
1302 } else {
1303 if (ifp->if_flags & IFF_RUNNING) {
1304 wi_stop(sc);
1305 }
1306 }
1307 sc->wi_if_flags = ifp->if_flags;
1308 error = 0;
1309 break;
1310 case SIOCADDMULTI:
1311 case SIOCDELMULTI:
1312 wi_setmulti(sc);
1313 error = 0;
1314 break;
1315 case SIOCGWAVELAN:
1316 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1317 if (error)
1318 break;
1319 /* Don't show WEP keys to non-root users. */
1320 if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS && suser(p))
1321 break;
1322 if (wreq.wi_type == WI_RID_IFACE_STATS) {
1323 bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val,
1324 sizeof(sc->wi_stats));
1325 wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1326 } else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {
1327 bcopy((char *)&sc->wi_keys, (char *)&wreq,
1328 sizeof(struct wi_ltv_keys));
1329 }
1330#ifdef WICACHE
1331 else if (wreq.wi_type == WI_RID_ZERO_CACHE) {
1332 sc->wi_sigitems = sc->wi_nextitem = 0;
1333 } else if (wreq.wi_type == WI_RID_READ_CACHE) {
1334 char *pt = (char *)&wreq.wi_val;
1335 bcopy((char *)&sc->wi_sigitems,
1336 (char *)pt, sizeof(int));
1337 pt += (sizeof (int));
1338 wreq.wi_len = sizeof(int) / 2;
1339 bcopy((char *)&sc->wi_sigcache, (char *)pt,
1340 sizeof(struct wi_sigcache) * sc->wi_sigitems);
1341 wreq.wi_len += ((sizeof(struct wi_sigcache) *
1342 sc->wi_sigitems) / 2) + 1;
1343 }
1344#endif
1345 else {
1346 if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
1347 error = EINVAL;
1348 break;
1349 }
1350 }
1351 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1352 break;
1353 case SIOCSWAVELAN:
1354 if ((error = suser(p)))
1355 goto out;
1356 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1357 if (error)
1358 break;
1359 if (wreq.wi_type == WI_RID_IFACE_STATS) {
1360 error = EINVAL;
1361 break;
1362 } else if (wreq.wi_type == WI_RID_MGMT_XMIT) {
1363 error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1364 wreq.wi_len);
1365 } else {
1366 error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
1367 if (!error)
1368 wi_setdef(sc, &wreq);
1369 }
1370 break;
1371 default:
1372 error = EINVAL;
1373 break;
1374 }
1375out:
1376 WI_UNLOCK(sc);
1377
1378 return(error);
1379}
1380
1381static void wi_init(xsc)
1382 void *xsc;
1383{
1384 struct wi_softc *sc = xsc;
1385 struct ifnet *ifp = &sc->arpcom.ac_if;
1386 struct wi_ltv_macaddr mac;
1387 int id = 0;
1388
1389 WI_LOCK(sc);
1390
1391 if (sc->wi_gone) {
1392 WI_UNLOCK(sc);
1393 return;
1394 }
1395
1396 if (ifp->if_flags & IFF_RUNNING)
1397 wi_stop(sc);
1398
1399 wi_reset(sc);
1400
1401 /* Program max data length. */
1402 WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
1403
1404 /* Enable/disable IBSS creation. */
1405 WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
1406
1407 /* Set the port type. */
1408 WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
1409
1410 /* Program the RTS/CTS threshold. */
1411 WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
1412
1413 /* Program the TX rate */
1414 WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
1415
1416 /* Access point density */
1417 WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
1418
1419 /* Power Management Enabled */
1420 WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
1421
1422 /* Power Managment Max Sleep */
1423 WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
1424
1425 /* Specify the IBSS name */
1426 WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
1427
1428 /* Specify the network name */
1429 WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
1430
1431 /* Specify the frequency to use */
1432 WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
1433
1434 /* Program the nodename. */
1435 WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name);
1436
1437 /* Set our MAC address. */
1438 mac.wi_len = 4;
1439 mac.wi_type = WI_RID_MAC_NODE;
1440 bcopy((char *)&sc->arpcom.ac_enaddr,
1441 (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN);
1442 wi_write_record(sc, (struct wi_ltv_gen *)&mac);
1443
1444 /* Configure WEP. */
1445 if (sc->wi_has_wep) {
1446 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
1447 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
1448 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
1449 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
1450 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
1451 }
1452
1453 /* Initialize promisc mode. */
1454 if (ifp->if_flags & IFF_PROMISC) {
1455 WI_SETVAL(WI_RID_PROMISC, 1);
1456 } else {
1457 WI_SETVAL(WI_RID_PROMISC, 0);
1458 }
1459
1460 /* Set multicast filter. */
1461 wi_setmulti(sc);
1462
1463 /* Enable desired port */
1464 wi_cmd(sc, WI_CMD_ENABLE|sc->wi_portnum, 0);
1465
1466 if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id))
1467 device_printf(sc->dev, "tx buffer allocation failed\n");
1468 sc->wi_tx_data_id = id;
1469
1470 if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id))
1471 device_printf(sc->dev, "mgmt. buffer allocation failed\n");
1472 sc->wi_tx_mgmt_id = id;
1473
1474 /* enable interrupts */
1475 CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
1476
1477 ifp->if_flags |= IFF_RUNNING;
1478 ifp->if_flags &= ~IFF_OACTIVE;
1479
1480 sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
1481 WI_UNLOCK(sc);
1482
1483 return;
1484}
1485
1486static void wi_start(ifp)
1487 struct ifnet *ifp;
1488{
1489 struct wi_softc *sc;
1490 struct mbuf *m0;
1491 struct wi_frame tx_frame;
1492 struct ether_header *eh;
1493 int id;
1494
1495 sc = ifp->if_softc;
1496 WI_LOCK(sc);
1497
1498 if (sc->wi_gone) {
1499 WI_UNLOCK(sc);
1500 return;
1501 }
1502
1503 if (ifp->if_flags & IFF_OACTIVE) {
1504 WI_UNLOCK(sc);
1505 return;
1506 }
1507
1508 IF_DEQUEUE(&ifp->if_snd, m0);
1509 if (m0 == NULL) {
1510 WI_UNLOCK(sc);
1511 return;
1512 }
1513
1514 bzero((char *)&tx_frame, sizeof(tx_frame));
1515 id = sc->wi_tx_data_id;
1516 eh = mtod(m0, struct ether_header *);
1517
1518 /*
1519 * Use RFC1042 encoding for IP and ARP datagrams,
1520 * 802.3 for anything else.
1521 */
1522 if (ntohs(eh->ether_type) > 1518) {
1522 if (ntohs(eh->ether_type) > ETHER_MAX_LEN) {
1523 bcopy((char *)&eh->ether_dhost,
1524 (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN);
1525 bcopy((char *)&eh->ether_shost,
1526 (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN);
1527 bcopy((char *)&eh->ether_dhost,
1528 (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN);
1529 bcopy((char *)&eh->ether_shost,
1530 (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN);
1531
1532 tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN;
1533 tx_frame.wi_frame_ctl = WI_FTYPE_DATA;
1534 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
1535 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
1536 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1537 tx_frame.wi_type = eh->ether_type;
1538
1539 m_copydata(m0, sizeof(struct ether_header),
1540 m0->m_pkthdr.len - sizeof(struct ether_header),
1541 (caddr_t)&sc->wi_txbuf);
1542
1543 wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1544 sizeof(struct wi_frame));
1545 wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf,
1546 (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2);
1547 } else {
1548 tx_frame.wi_dat_len = m0->m_pkthdr.len;
1549
1550 eh->ether_type = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1551 m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf);
1552
1553 wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1554 sizeof(struct wi_frame));
1555 wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf,
1556 m0->m_pkthdr.len + 2);
1557 }
1558
1559 /*
1560 * If there's a BPF listner, bounce a copy of
1561 * this frame to him.
1562 */
1563 if (ifp->if_bpf)
1564 bpf_mtap(ifp, m0);
1565
1566 m_freem(m0);
1567
1568 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id))
1569 device_printf(sc->dev, "xmit failed\n");
1570
1571 ifp->if_flags |= IFF_OACTIVE;
1572
1573 /*
1574 * Set a timeout in case the chip goes out to lunch.
1575 */
1576 ifp->if_timer = 5;
1577
1578 WI_UNLOCK(sc);
1579 return;
1580}
1581
1582static int wi_mgmt_xmit(sc, data, len)
1583 struct wi_softc *sc;
1584 caddr_t data;
1585 int len;
1586{
1587 struct wi_frame tx_frame;
1588 int id;
1589 struct wi_80211_hdr *hdr;
1590 caddr_t dptr;
1591
1592 if (sc->wi_gone)
1593 return(ENODEV);
1594
1595 hdr = (struct wi_80211_hdr *)data;
1596 dptr = data + sizeof(struct wi_80211_hdr);
1597
1598 bzero((char *)&tx_frame, sizeof(tx_frame));
1599 id = sc->wi_tx_mgmt_id;
1600
1601 bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl,
1602 sizeof(struct wi_80211_hdr));
1603
1604 tx_frame.wi_dat_len = len - WI_SNAPHDR_LEN;
1605 tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN);
1606
1607 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame));
1608 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr,
1609 (len - sizeof(struct wi_80211_hdr)) + 2);
1610
1611 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) {
1612 device_printf(sc->dev, "xmit failed\n");
1613 return(EIO);
1614 }
1615
1616 return(0);
1617}
1618
1619static void wi_stop(sc)
1620 struct wi_softc *sc;
1621{
1622 struct ifnet *ifp;
1623
1624 WI_LOCK(sc);
1625
1626 if (sc->wi_gone) {
1627 WI_UNLOCK(sc);
1628 return;
1629 }
1630
1631 ifp = &sc->arpcom.ac_if;
1632
1633 /*
1634 * If the card is gone and the memory port isn't mapped, we will
1635 * (hopefully) get 0xffff back from the status read, which is not
1636 * a valid status value.
1637 */
1638 if (CSR_READ_2(sc, WI_STATUS) != 0xffff) {
1639 CSR_WRITE_2(sc, WI_INT_EN, 0);
1640 wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0);
1641 }
1642
1643 untimeout(wi_inquire, sc, sc->wi_stat_ch);
1644
1645 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
1646
1647 WI_UNLOCK(sc);
1648 return;
1649}
1650
1651static void wi_watchdog(ifp)
1652 struct ifnet *ifp;
1653{
1654 struct wi_softc *sc;
1655
1656 sc = ifp->if_softc;
1657
1658 device_printf(sc->dev, "watchdog timeout\n");
1659
1660 wi_init(sc);
1661
1662 ifp->if_oerrors++;
1663
1664 return;
1665}
1666
1667static int
1668wi_alloc(dev, io_rid)
1669 device_t dev;
1670 int io_rid;
1671{
1672 struct wi_softc *sc = device_get_softc(dev);
1673
1674 sc->iobase_rid = io_rid;
1675 sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->iobase_rid,
1676 0, ~0, (1 << 6),
1677 rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
1678 if (!sc->iobase) {
1679 device_printf(dev, "No I/O space?!\n");
1680 return (ENXIO);
1681 }
1682
1683 sc->irq_rid = 0;
1684 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
1685 0, ~0, 1, RF_ACTIVE);
1686 if (!sc->irq) {
1687 wi_free(dev);
1688 device_printf(dev, "No irq?!\n");
1689 return (ENXIO);
1690 }
1691
1692 sc->dev = dev;
1693 sc->wi_unit = device_get_unit(dev);
1694 sc->wi_io_addr = rman_get_start(sc->iobase);
1695 sc->wi_btag = rman_get_bustag(sc->iobase);
1696 sc->wi_bhandle = rman_get_bushandle(sc->iobase);
1697
1698 return (0);
1699}
1700
1701static void wi_free(dev)
1702 device_t dev;
1703{
1704 struct wi_softc *sc = device_get_softc(dev);
1705
1706 if (sc->iobase != NULL) {
1707 bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase);
1708 sc->iobase = NULL;
1709 }
1710 if (sc->irq != NULL) {
1711 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
1712 sc->irq = NULL;
1713 }
1714 if (sc->mem != NULL) {
1715 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
1716 sc->mem = NULL;
1717 }
1718
1719 return;
1720}
1721
1722static void wi_shutdown(dev)
1723 device_t dev;
1724{
1725 struct wi_softc *sc;
1726
1727 sc = device_get_softc(dev);
1728 wi_stop(sc);
1729
1730 return;
1731}
1732
1733#ifdef WICACHE
1734/* wavelan signal strength cache code.
1735 * store signal/noise/quality on per MAC src basis in
1736 * a small fixed cache. The cache wraps if > MAX slots
1737 * used. The cache may be zeroed out to start over.
1738 * Two simple filters exist to reduce computation:
1739 * 1. ip only (literally 0x800) which may be used
1740 * to ignore some packets. It defaults to ip only.
1741 * it could be used to focus on broadcast, non-IP 802.11 beacons.
1742 * 2. multicast/broadcast only. This may be used to
1743 * ignore unicast packets and only cache signal strength
1744 * for multicast/broadcast packets (beacons); e.g., Mobile-IP
1745 * beacons and not unicast traffic.
1746 *
1747 * The cache stores (MAC src(index), IP src (major clue), signal,
1748 * quality, noise)
1749 *
1750 * No apologies for storing IP src here. It's easy and saves much
1751 * trouble elsewhere. The cache is assumed to be INET dependent,
1752 * although it need not be.
1753 */
1754
1755#ifdef documentation
1756
1757int wi_sigitems; /* number of cached entries */
1758struct wi_sigcache wi_sigcache[MAXWICACHE]; /* array of cache entries */
1759int wi_nextitem; /* index/# of entries */
1760
1761
1762#endif
1763
1764/* control variables for cache filtering. Basic idea is
1765 * to reduce cost (e.g., to only Mobile-IP agent beacons
1766 * which are broadcast or multicast). Still you might
1767 * want to measure signal strength with unicast ping packets
1768 * on a pt. to pt. ant. setup.
1769 */
1770/* set true if you want to limit cache items to broadcast/mcast
1771 * only packets (not unicast). Useful for mobile-ip beacons which
1772 * are broadcast/multicast at network layer. Default is all packets
1773 * so ping/unicast will work say with pt. to pt. antennae setup.
1774 */
1775static int wi_cache_mcastonly = 0;
1776SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW,
1777 &wi_cache_mcastonly, 0, "");
1778
1779/* set true if you want to limit cache items to IP packets only
1780*/
1781static int wi_cache_iponly = 1;
1782SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW,
1783 &wi_cache_iponly, 0, "");
1784
1785/*
1786 * Original comments:
1787 * -----------------
1788 * wi_cache_store, per rx packet store signal
1789 * strength in MAC (src) indexed cache.
1790 *
1791 * follows linux driver in how signal strength is computed.
1792 * In ad hoc mode, we use the rx_quality field.
1793 * signal and noise are trimmed to fit in the range from 47..138.
1794 * rx_quality field MSB is signal strength.
1795 * rx_quality field LSB is noise.
1796 * "quality" is (signal - noise) as is log value.
1797 * note: quality CAN be negative.
1798 *
1799 * In BSS mode, we use the RID for communication quality.
1800 * TBD: BSS mode is currently untested.
1801 *
1802 * Bill's comments:
1803 * ---------------
1804 * Actually, we use the rx_quality field all the time for both "ad-hoc"
1805 * and BSS modes. Why? Because reading an RID is really, really expensive:
1806 * there's a bunch of PIO operations that have to be done to read a record
1807 * from the NIC, and reading the comms quality RID each time a packet is
1808 * received can really hurt performance. We don't have to do this anyway:
1809 * the comms quality field only reflects the values in the rx_quality field
1810 * anyway. The comms quality RID is only meaningful in infrastructure mode,
1811 * but the values it contains are updated based on the rx_quality from
1812 * frames received from the access point.
1813 *
1814 * Also, according to Lucent, the signal strength and noise level values
1815 * can be converted to dBms by subtracting 149, so I've modified the code
1816 * to do that instead of the scaling it did originally.
1817 */
1818static
1819void wi_cache_store (struct wi_softc *sc, struct ether_header *eh,
1820 struct mbuf *m, unsigned short rx_quality)
1821{
1822 struct ip *ip = 0;
1823 int i;
1824 static int cache_slot = 0; /* use this cache entry */
1825 static int wrapindex = 0; /* next "free" cache entry */
1826 int sig, noise;
1827 int sawip=0;
1828
1829 /* filters:
1830 * 1. ip only
1831 * 2. configurable filter to throw out unicast packets,
1832 * keep multicast only.
1833 */
1834
1835 if ((ntohs(eh->ether_type) == 0x800)) {
1836 sawip = 1;
1837 }
1838
1839 /* filter for ip packets only
1840 */
1841 if (wi_cache_iponly && !sawip) {
1842 return;
1843 }
1844
1845 /* filter for broadcast/multicast only
1846 */
1847 if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
1848 return;
1849 }
1850
1851#ifdef SIGDEBUG
1852 printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit,
1853 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
1854#endif
1855
1856 /* find the ip header. we want to store the ip_src
1857 * address.
1858 */
1859 if (sawip) {
1860 ip = mtod(m, struct ip *);
1861 }
1862
1863 /* do a linear search for a matching MAC address
1864 * in the cache table
1865 * . MAC address is 6 bytes,
1866 * . var w_nextitem holds total number of entries already cached
1867 */
1868 for(i = 0; i < sc->wi_nextitem; i++) {
1869 if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc, 6 )) {
1870 /* Match!,
1871 * so we already have this entry,
1872 * update the data
1873 */
1874 break;
1875 }
1876 }
1877
1878 /* did we find a matching mac address?
1879 * if yes, then overwrite a previously existing cache entry
1880 */
1881 if (i < sc->wi_nextitem ) {
1882 cache_slot = i;
1883 }
1884 /* else, have a new address entry,so
1885 * add this new entry,
1886 * if table full, then we need to replace LRU entry
1887 */
1888 else {
1889
1890 /* check for space in cache table
1891 * note: wi_nextitem also holds number of entries
1892 * added in the cache table
1893 */
1894 if ( sc->wi_nextitem < MAXWICACHE ) {
1895 cache_slot = sc->wi_nextitem;
1896 sc->wi_nextitem++;
1897 sc->wi_sigitems = sc->wi_nextitem;
1898 }
1899 /* no space found, so simply wrap with wrap index
1900 * and "zap" the next entry
1901 */
1902 else {
1903 if (wrapindex == MAXWICACHE) {
1904 wrapindex = 0;
1905 }
1906 cache_slot = wrapindex++;
1907 }
1908 }
1909
1910 /* invariant: cache_slot now points at some slot
1911 * in cache.
1912 */
1913 if (cache_slot < 0 || cache_slot >= MAXWICACHE) {
1914 log(LOG_ERR, "wi_cache_store, bad index: %d of "
1915 "[0..%d], gross cache error\n",
1916 cache_slot, MAXWICACHE);
1917 return;
1918 }
1919
1920 /* store items in cache
1921 * .ip source address
1922 * .mac src
1923 * .signal, etc.
1924 */
1925 if (sawip) {
1926 sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
1927 }
1928 bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc, 6);
1929
1930 sig = (rx_quality >> 8) & 0xFF;
1931 noise = rx_quality & 0xFF;
1932 sc->wi_sigcache[cache_slot].signal = sig - 149;
1933 sc->wi_sigcache[cache_slot].noise = noise - 149;
1934 sc->wi_sigcache[cache_slot].quality = sig - noise;
1935
1936 return;
1937}
1938#endif
1523 bcopy((char *)&eh->ether_dhost,
1524 (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN);
1525 bcopy((char *)&eh->ether_shost,
1526 (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN);
1527 bcopy((char *)&eh->ether_dhost,
1528 (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN);
1529 bcopy((char *)&eh->ether_shost,
1530 (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN);
1531
1532 tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN;
1533 tx_frame.wi_frame_ctl = WI_FTYPE_DATA;
1534 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
1535 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
1536 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1537 tx_frame.wi_type = eh->ether_type;
1538
1539 m_copydata(m0, sizeof(struct ether_header),
1540 m0->m_pkthdr.len - sizeof(struct ether_header),
1541 (caddr_t)&sc->wi_txbuf);
1542
1543 wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1544 sizeof(struct wi_frame));
1545 wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf,
1546 (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2);
1547 } else {
1548 tx_frame.wi_dat_len = m0->m_pkthdr.len;
1549
1550 eh->ether_type = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1551 m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf);
1552
1553 wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1554 sizeof(struct wi_frame));
1555 wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf,
1556 m0->m_pkthdr.len + 2);
1557 }
1558
1559 /*
1560 * If there's a BPF listner, bounce a copy of
1561 * this frame to him.
1562 */
1563 if (ifp->if_bpf)
1564 bpf_mtap(ifp, m0);
1565
1566 m_freem(m0);
1567
1568 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id))
1569 device_printf(sc->dev, "xmit failed\n");
1570
1571 ifp->if_flags |= IFF_OACTIVE;
1572
1573 /*
1574 * Set a timeout in case the chip goes out to lunch.
1575 */
1576 ifp->if_timer = 5;
1577
1578 WI_UNLOCK(sc);
1579 return;
1580}
1581
1582static int wi_mgmt_xmit(sc, data, len)
1583 struct wi_softc *sc;
1584 caddr_t data;
1585 int len;
1586{
1587 struct wi_frame tx_frame;
1588 int id;
1589 struct wi_80211_hdr *hdr;
1590 caddr_t dptr;
1591
1592 if (sc->wi_gone)
1593 return(ENODEV);
1594
1595 hdr = (struct wi_80211_hdr *)data;
1596 dptr = data + sizeof(struct wi_80211_hdr);
1597
1598 bzero((char *)&tx_frame, sizeof(tx_frame));
1599 id = sc->wi_tx_mgmt_id;
1600
1601 bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl,
1602 sizeof(struct wi_80211_hdr));
1603
1604 tx_frame.wi_dat_len = len - WI_SNAPHDR_LEN;
1605 tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN);
1606
1607 wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame));
1608 wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr,
1609 (len - sizeof(struct wi_80211_hdr)) + 2);
1610
1611 if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) {
1612 device_printf(sc->dev, "xmit failed\n");
1613 return(EIO);
1614 }
1615
1616 return(0);
1617}
1618
1619static void wi_stop(sc)
1620 struct wi_softc *sc;
1621{
1622 struct ifnet *ifp;
1623
1624 WI_LOCK(sc);
1625
1626 if (sc->wi_gone) {
1627 WI_UNLOCK(sc);
1628 return;
1629 }
1630
1631 ifp = &sc->arpcom.ac_if;
1632
1633 /*
1634 * If the card is gone and the memory port isn't mapped, we will
1635 * (hopefully) get 0xffff back from the status read, which is not
1636 * a valid status value.
1637 */
1638 if (CSR_READ_2(sc, WI_STATUS) != 0xffff) {
1639 CSR_WRITE_2(sc, WI_INT_EN, 0);
1640 wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0);
1641 }
1642
1643 untimeout(wi_inquire, sc, sc->wi_stat_ch);
1644
1645 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
1646
1647 WI_UNLOCK(sc);
1648 return;
1649}
1650
1651static void wi_watchdog(ifp)
1652 struct ifnet *ifp;
1653{
1654 struct wi_softc *sc;
1655
1656 sc = ifp->if_softc;
1657
1658 device_printf(sc->dev, "watchdog timeout\n");
1659
1660 wi_init(sc);
1661
1662 ifp->if_oerrors++;
1663
1664 return;
1665}
1666
1667static int
1668wi_alloc(dev, io_rid)
1669 device_t dev;
1670 int io_rid;
1671{
1672 struct wi_softc *sc = device_get_softc(dev);
1673
1674 sc->iobase_rid = io_rid;
1675 sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->iobase_rid,
1676 0, ~0, (1 << 6),
1677 rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
1678 if (!sc->iobase) {
1679 device_printf(dev, "No I/O space?!\n");
1680 return (ENXIO);
1681 }
1682
1683 sc->irq_rid = 0;
1684 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
1685 0, ~0, 1, RF_ACTIVE);
1686 if (!sc->irq) {
1687 wi_free(dev);
1688 device_printf(dev, "No irq?!\n");
1689 return (ENXIO);
1690 }
1691
1692 sc->dev = dev;
1693 sc->wi_unit = device_get_unit(dev);
1694 sc->wi_io_addr = rman_get_start(sc->iobase);
1695 sc->wi_btag = rman_get_bustag(sc->iobase);
1696 sc->wi_bhandle = rman_get_bushandle(sc->iobase);
1697
1698 return (0);
1699}
1700
1701static void wi_free(dev)
1702 device_t dev;
1703{
1704 struct wi_softc *sc = device_get_softc(dev);
1705
1706 if (sc->iobase != NULL) {
1707 bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase);
1708 sc->iobase = NULL;
1709 }
1710 if (sc->irq != NULL) {
1711 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
1712 sc->irq = NULL;
1713 }
1714 if (sc->mem != NULL) {
1715 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
1716 sc->mem = NULL;
1717 }
1718
1719 return;
1720}
1721
1722static void wi_shutdown(dev)
1723 device_t dev;
1724{
1725 struct wi_softc *sc;
1726
1727 sc = device_get_softc(dev);
1728 wi_stop(sc);
1729
1730 return;
1731}
1732
1733#ifdef WICACHE
1734/* wavelan signal strength cache code.
1735 * store signal/noise/quality on per MAC src basis in
1736 * a small fixed cache. The cache wraps if > MAX slots
1737 * used. The cache may be zeroed out to start over.
1738 * Two simple filters exist to reduce computation:
1739 * 1. ip only (literally 0x800) which may be used
1740 * to ignore some packets. It defaults to ip only.
1741 * it could be used to focus on broadcast, non-IP 802.11 beacons.
1742 * 2. multicast/broadcast only. This may be used to
1743 * ignore unicast packets and only cache signal strength
1744 * for multicast/broadcast packets (beacons); e.g., Mobile-IP
1745 * beacons and not unicast traffic.
1746 *
1747 * The cache stores (MAC src(index), IP src (major clue), signal,
1748 * quality, noise)
1749 *
1750 * No apologies for storing IP src here. It's easy and saves much
1751 * trouble elsewhere. The cache is assumed to be INET dependent,
1752 * although it need not be.
1753 */
1754
1755#ifdef documentation
1756
1757int wi_sigitems; /* number of cached entries */
1758struct wi_sigcache wi_sigcache[MAXWICACHE]; /* array of cache entries */
1759int wi_nextitem; /* index/# of entries */
1760
1761
1762#endif
1763
1764/* control variables for cache filtering. Basic idea is
1765 * to reduce cost (e.g., to only Mobile-IP agent beacons
1766 * which are broadcast or multicast). Still you might
1767 * want to measure signal strength with unicast ping packets
1768 * on a pt. to pt. ant. setup.
1769 */
1770/* set true if you want to limit cache items to broadcast/mcast
1771 * only packets (not unicast). Useful for mobile-ip beacons which
1772 * are broadcast/multicast at network layer. Default is all packets
1773 * so ping/unicast will work say with pt. to pt. antennae setup.
1774 */
1775static int wi_cache_mcastonly = 0;
1776SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW,
1777 &wi_cache_mcastonly, 0, "");
1778
1779/* set true if you want to limit cache items to IP packets only
1780*/
1781static int wi_cache_iponly = 1;
1782SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW,
1783 &wi_cache_iponly, 0, "");
1784
1785/*
1786 * Original comments:
1787 * -----------------
1788 * wi_cache_store, per rx packet store signal
1789 * strength in MAC (src) indexed cache.
1790 *
1791 * follows linux driver in how signal strength is computed.
1792 * In ad hoc mode, we use the rx_quality field.
1793 * signal and noise are trimmed to fit in the range from 47..138.
1794 * rx_quality field MSB is signal strength.
1795 * rx_quality field LSB is noise.
1796 * "quality" is (signal - noise) as is log value.
1797 * note: quality CAN be negative.
1798 *
1799 * In BSS mode, we use the RID for communication quality.
1800 * TBD: BSS mode is currently untested.
1801 *
1802 * Bill's comments:
1803 * ---------------
1804 * Actually, we use the rx_quality field all the time for both "ad-hoc"
1805 * and BSS modes. Why? Because reading an RID is really, really expensive:
1806 * there's a bunch of PIO operations that have to be done to read a record
1807 * from the NIC, and reading the comms quality RID each time a packet is
1808 * received can really hurt performance. We don't have to do this anyway:
1809 * the comms quality field only reflects the values in the rx_quality field
1810 * anyway. The comms quality RID is only meaningful in infrastructure mode,
1811 * but the values it contains are updated based on the rx_quality from
1812 * frames received from the access point.
1813 *
1814 * Also, according to Lucent, the signal strength and noise level values
1815 * can be converted to dBms by subtracting 149, so I've modified the code
1816 * to do that instead of the scaling it did originally.
1817 */
1818static
1819void wi_cache_store (struct wi_softc *sc, struct ether_header *eh,
1820 struct mbuf *m, unsigned short rx_quality)
1821{
1822 struct ip *ip = 0;
1823 int i;
1824 static int cache_slot = 0; /* use this cache entry */
1825 static int wrapindex = 0; /* next "free" cache entry */
1826 int sig, noise;
1827 int sawip=0;
1828
1829 /* filters:
1830 * 1. ip only
1831 * 2. configurable filter to throw out unicast packets,
1832 * keep multicast only.
1833 */
1834
1835 if ((ntohs(eh->ether_type) == 0x800)) {
1836 sawip = 1;
1837 }
1838
1839 /* filter for ip packets only
1840 */
1841 if (wi_cache_iponly && !sawip) {
1842 return;
1843 }
1844
1845 /* filter for broadcast/multicast only
1846 */
1847 if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
1848 return;
1849 }
1850
1851#ifdef SIGDEBUG
1852 printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit,
1853 rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
1854#endif
1855
1856 /* find the ip header. we want to store the ip_src
1857 * address.
1858 */
1859 if (sawip) {
1860 ip = mtod(m, struct ip *);
1861 }
1862
1863 /* do a linear search for a matching MAC address
1864 * in the cache table
1865 * . MAC address is 6 bytes,
1866 * . var w_nextitem holds total number of entries already cached
1867 */
1868 for(i = 0; i < sc->wi_nextitem; i++) {
1869 if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc, 6 )) {
1870 /* Match!,
1871 * so we already have this entry,
1872 * update the data
1873 */
1874 break;
1875 }
1876 }
1877
1878 /* did we find a matching mac address?
1879 * if yes, then overwrite a previously existing cache entry
1880 */
1881 if (i < sc->wi_nextitem ) {
1882 cache_slot = i;
1883 }
1884 /* else, have a new address entry,so
1885 * add this new entry,
1886 * if table full, then we need to replace LRU entry
1887 */
1888 else {
1889
1890 /* check for space in cache table
1891 * note: wi_nextitem also holds number of entries
1892 * added in the cache table
1893 */
1894 if ( sc->wi_nextitem < MAXWICACHE ) {
1895 cache_slot = sc->wi_nextitem;
1896 sc->wi_nextitem++;
1897 sc->wi_sigitems = sc->wi_nextitem;
1898 }
1899 /* no space found, so simply wrap with wrap index
1900 * and "zap" the next entry
1901 */
1902 else {
1903 if (wrapindex == MAXWICACHE) {
1904 wrapindex = 0;
1905 }
1906 cache_slot = wrapindex++;
1907 }
1908 }
1909
1910 /* invariant: cache_slot now points at some slot
1911 * in cache.
1912 */
1913 if (cache_slot < 0 || cache_slot >= MAXWICACHE) {
1914 log(LOG_ERR, "wi_cache_store, bad index: %d of "
1915 "[0..%d], gross cache error\n",
1916 cache_slot, MAXWICACHE);
1917 return;
1918 }
1919
1920 /* store items in cache
1921 * .ip source address
1922 * .mac src
1923 * .signal, etc.
1924 */
1925 if (sawip) {
1926 sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
1927 }
1928 bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc, 6);
1929
1930 sig = (rx_quality >> 8) & 0xFF;
1931 noise = rx_quality & 0xFF;
1932 sc->wi_sigcache[cache_slot].signal = sig - 149;
1933 sc->wi_sigcache[cache_slot].noise = noise - 149;
1934 sc->wi_sigcache[cache_slot].quality = sig - noise;
1935
1936 return;
1937}
1938#endif