]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/wi/if_wi.c
When in infrastructure mode, use address 3 from the 802.11 header as the
[FreeBSD/FreeBSD.git] / sys / dev / wi / if_wi.c
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  * $FreeBSD$
33  */
34
35 /*
36  * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD.
37  *
38  * Written by Bill Paul <wpaul@ctr.columbia.edu>
39  * Electrical Engineering Department
40  * Columbia University, New York City
41  */
42
43 /*
44  * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
45  * from Lucent. Unlike the older cards, the new ones are programmed
46  * entirely via a firmware-driven controller called the Hermes.
47  * Unfortunately, Lucent will not release the Hermes programming manual
48  * without an NDA (if at all). What they do release is an API library
49  * called the HCF (Hardware Control Functions) which is supposed to
50  * do the device-specific operations of a device driver for you. The
51  * publically available version of the HCF library (the 'HCF Light') is 
52  * a) extremely gross, b) lacks certain features, particularly support
53  * for 802.11 frames, and c) is contaminated by the GNU Public License.
54  *
55  * This driver does not use the HCF or HCF Light at all. Instead, it
56  * programs the Hermes controller directly, using information gleaned
57  * from the HCF Light code and corresponding documentation.
58  *
59  * This driver supports both the PCMCIA and ISA versions of the
60  * WaveLAN/IEEE cards. Note however that the ISA card isn't really
61  * anything of the sort: it's actually a PCMCIA bridge adapter
62  * that fits into an ISA slot, into which a PCMCIA WaveLAN card is
63  * inserted. Consequently, you need to use the pccard support for
64  * both the ISA and PCMCIA adapters.
65  */
66
67 #define WI_HERMES_AUTOINC_WAR   /* Work around data write autoinc bug. */
68 #define WI_HERMES_STATS_WAR     /* Work around stats counter bug. */
69 #define WICACHE                 /* turn on signal strength cache code */  
70
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/sockio.h>
74 #include <sys/mbuf.h>
75 #include <sys/malloc.h>
76 #include <sys/kernel.h>
77 #include <sys/socket.h>
78 #include <sys/module.h>
79 #include <sys/bus.h>
80 #include <sys/syslog.h>
81 #include <sys/sysctl.h>
82
83 #include <machine/bus.h>
84 #include <machine/resource.h>
85 #include <machine/clock.h>
86 #include <machine/md_var.h>
87 #include <machine/bus_pio.h>
88 #include <sys/rman.h>
89
90 #include <net/if.h>
91 #include <net/if_arp.h>
92 #include <net/ethernet.h>
93 #include <net/if_dl.h>
94 #include <net/if_media.h>
95 #include <net/if_types.h>
96
97 #include <netinet/in.h>
98 #include <netinet/in_systm.h>
99 #include <netinet/in_var.h>
100 #include <netinet/ip.h>
101 #include <netinet/if_ether.h>
102
103 #include <net/bpf.h>
104
105 #include <machine/if_wavelan_ieee.h>
106 #include <i386/isa/if_wireg.h>
107
108 #if !defined(lint)
109 static const char rcsid[] =
110   "$FreeBSD$";
111 #endif
112
113 #ifdef foo
114 static u_int8_t wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
115 #endif
116
117 static void wi_intr             __P((void *));
118 static void wi_reset            __P((struct wi_softc *));
119 static int wi_ioctl             __P((struct ifnet *, u_long, caddr_t));
120 static void wi_init             __P((void *));
121 static void wi_start            __P((struct ifnet *));
122 static void wi_stop             __P((struct wi_softc *));
123 static void wi_watchdog         __P((struct ifnet *));
124 static void wi_rxeof            __P((struct wi_softc *));
125 static void wi_txeof            __P((struct wi_softc *, int));
126 static void wi_update_stats     __P((struct wi_softc *));
127 static void wi_setmulti         __P((struct wi_softc *));
128
129 static int wi_cmd               __P((struct wi_softc *, int, int));
130 static int wi_read_record       __P((struct wi_softc *, struct wi_ltv_gen *));
131 static int wi_write_record      __P((struct wi_softc *, struct wi_ltv_gen *));
132 static int wi_read_data         __P((struct wi_softc *, int,
133                                         int, caddr_t, int));
134 static int wi_write_data        __P((struct wi_softc *, int,
135                                         int, caddr_t, int));
136 static int wi_seek              __P((struct wi_softc *, int, int, int));
137 static int wi_alloc_nicmem      __P((struct wi_softc *, int, int *));
138 static void wi_inquire          __P((void *));
139 static void wi_setdef           __P((struct wi_softc *, struct wi_req *));
140 static int wi_mgmt_xmit         __P((struct wi_softc *, caddr_t, int));
141
142 #ifdef WICACHE
143 static
144 void wi_cache_store __P((struct wi_softc *, struct ether_header *,
145         struct mbuf *, unsigned short));
146 #endif
147
148 static int wi_pccard_probe      __P((device_t));
149 static int wi_pccard_attach     __P((device_t));
150 static int wi_pccard_detach     __P((device_t));
151 static void wi_shutdown         __P((device_t));
152
153 static int wi_alloc             __P((device_t));
154 static void wi_free             __P((device_t));
155
156 static device_method_t wi_pccard_methods[] = {
157         /* Device interface */
158         DEVMETHOD(device_probe,         wi_pccard_probe),
159         DEVMETHOD(device_attach,        wi_pccard_attach),
160         DEVMETHOD(device_detach,        wi_pccard_detach),
161         DEVMETHOD(device_shutdown,      wi_shutdown),
162
163         { 0, 0 }
164 };
165
166 static driver_t wi_pccard_driver = {
167         "wi",
168         wi_pccard_methods,
169         sizeof(struct wi_softc)
170 };
171
172 static devclass_t wi_pccard_devclass;
173
174 DRIVER_MODULE(if_wi, pccard, wi_pccard_driver, wi_pccard_devclass, 0, 0);
175
176 static int wi_pccard_probe(dev)
177         device_t        dev;
178 {
179         struct wi_softc *sc;
180         int             error;
181
182         sc = device_get_softc(dev);
183         sc->wi_gone = 0;
184
185         error = wi_alloc(dev);
186         if (error)
187                 return (error);
188
189         device_set_desc(dev, "WaveLAN/IEEE 802.11");
190         wi_free(dev);
191
192         /* Make sure interrupts are disabled. */
193         CSR_WRITE_2(sc, WI_INT_EN, 0);
194         CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
195
196         return (0);
197 }
198
199 static int wi_pccard_detach(dev)
200         device_t                dev;
201 {
202         struct wi_softc         *sc;
203         struct ifnet            *ifp;
204         int                     s;
205
206         s = splimp();
207
208         sc = device_get_softc(dev);
209         ifp = &sc->arpcom.ac_if;
210
211         if (sc->wi_gone) {
212                 device_printf(dev, "already unloaded\n");
213                 return(ENODEV);
214         }
215
216         wi_stop(sc);
217
218         bpfdetach(ifp);
219         if_detach(ifp);
220         bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
221         wi_free(dev);
222         sc->wi_gone = 1;
223
224         splx(s);
225         device_printf(dev, "unload\n");
226
227         return(0);
228 }
229
230 static int wi_pccard_attach(device_t dev)
231 {
232         struct wi_softc         *sc;
233         struct wi_ltv_macaddr   mac;
234         struct wi_ltv_gen       gen;
235         struct ifnet            *ifp;
236         int                     error;
237
238         sc = device_get_softc(dev);
239         ifp = &sc->arpcom.ac_if;
240
241         error = wi_alloc(dev);
242         if (error) {
243                 device_printf(dev, "wi_alloc() failed! (%d)\n", error);
244                 return (error);
245         }
246
247         error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
248                                wi_intr, sc, &sc->wi_intrhand);
249
250         if (error) {
251                 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
252                 wi_free(dev);
253                 return (error);
254         }
255
256         /* Reset the NIC. */
257         wi_reset(sc);
258
259         /* Read the station address. */
260         mac.wi_type = WI_RID_MAC_NODE;
261         mac.wi_len = 4;
262         wi_read_record(sc, (struct wi_ltv_gen *)&mac);
263         bcopy((char *)&mac.wi_mac_addr,
264            (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
265
266         device_printf(dev, "Ethernet address: %6D\n",
267             sc->arpcom.ac_enaddr, ":");
268
269         ifp->if_softc = sc;
270         ifp->if_unit = sc->wi_unit;
271         ifp->if_name = "wi";
272         ifp->if_mtu = ETHERMTU;
273         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
274         ifp->if_ioctl = wi_ioctl;
275         ifp->if_output = ether_output;
276         ifp->if_start = wi_start;
277         ifp->if_watchdog = wi_watchdog;
278         ifp->if_init = wi_init;
279         ifp->if_baudrate = 10000000;
280         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
281
282         bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
283         bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name,
284             sizeof(WI_DEFAULT_NODENAME) - 1);
285
286         bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
287         bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name,
288             sizeof(WI_DEFAULT_NETNAME) - 1);
289
290         bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
291         bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name,
292             sizeof(WI_DEFAULT_IBSS) - 1);
293
294         sc->wi_portnum = WI_DEFAULT_PORT;
295         sc->wi_ptype = WI_PORTTYPE_ADHOC;
296         sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
297         sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
298         sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
299         sc->wi_max_data_len = WI_DEFAULT_DATALEN;
300         sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
301         sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
302         sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
303
304         /*
305          * Read the default channel from the NIC. This may vary
306          * depending on the country where the NIC was purchased, so
307          * we can't hard-code a default and expect it to work for
308          * everyone.
309          */
310         gen.wi_type = WI_RID_OWN_CHNL;
311         gen.wi_len = 2;
312         wi_read_record(sc, &gen);
313         sc->wi_channel = gen.wi_val;
314
315         /*
316          * Find out if we support WEP on this card.
317          */
318         gen.wi_type = WI_RID_WEP_AVAIL;
319         gen.wi_len = 2;
320         wi_read_record(sc, &gen);
321         sc->wi_has_wep = gen.wi_val;
322
323         bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
324
325         wi_init(sc);
326         wi_stop(sc);
327
328         /*
329          * Call MI attach routines.
330          */
331         if_attach(ifp);
332         ether_ifattach(ifp);
333         callout_handle_init(&sc->wi_stat_ch);
334         bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
335
336         return(0);
337 }
338
339 static void wi_rxeof(sc)
340         struct wi_softc         *sc;
341 {
342         struct ifnet            *ifp;
343         struct ether_header     *eh;
344         struct wi_frame         rx_frame;
345         struct mbuf             *m;
346         int                     id;
347
348         ifp = &sc->arpcom.ac_if;
349
350         id = CSR_READ_2(sc, WI_RX_FID);
351
352         /* First read in the frame header */
353         if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
354                 ifp->if_ierrors++;
355                 return;
356         }
357
358         if (rx_frame.wi_status & WI_STAT_ERRSTAT) {
359                 ifp->if_ierrors++;
360                 return;
361         }
362
363         MGETHDR(m, M_DONTWAIT, MT_DATA);
364         if (m == NULL) {
365                 ifp->if_ierrors++;
366                 return;
367         }
368         MCLGET(m, M_DONTWAIT);
369         if (!(m->m_flags & M_EXT)) {
370                 m_freem(m);
371                 ifp->if_ierrors++;
372                 return;
373         }
374
375         eh = mtod(m, struct ether_header *);
376         m->m_pkthdr.rcvif = ifp;
377
378         if (rx_frame.wi_status == WI_STAT_1042 ||
379             rx_frame.wi_status == WI_STAT_TUNNEL ||
380             rx_frame.wi_status == WI_STAT_WMP_MSG) {
381                 if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) {
382                         device_printf(sc->dev, "oversized packet received "
383                             "(wi_dat_len=%d, wi_status=0x%x)\n",
384                             rx_frame.wi_dat_len, rx_frame.wi_status);
385                         m_freem(m);
386                         ifp->if_ierrors++;
387                         return;
388                 }
389                 m->m_pkthdr.len = m->m_len =
390                     rx_frame.wi_dat_len + WI_SNAPHDR_LEN;
391
392                 bcopy((char *)&rx_frame.wi_addr1,
393                     (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
394                 if (sc->wi_ptype == WI_PORTTYPE_ADHOC) {
395                         bcopy((char *)&rx_frame.wi_addr2,
396                             (char *)&eh->ether_shost, ETHER_ADDR_LEN);
397                 } else {
398                         bcopy((char *)&rx_frame.wi_addr3,
399                             (char *)&eh->ether_shost, ETHER_ADDR_LEN);
400                 }
401                 bcopy((char *)&rx_frame.wi_type,
402                     (char *)&eh->ether_type, sizeof(u_int16_t));
403
404                 if (wi_read_data(sc, id, WI_802_11_OFFSET,
405                     mtod(m, caddr_t) + sizeof(struct ether_header),
406                     m->m_len + 2)) {
407                         m_freem(m);
408                         ifp->if_ierrors++;
409                         return;
410                 }
411         } else {
412                 if((rx_frame.wi_dat_len +
413                     sizeof(struct ether_header)) > MCLBYTES) {
414                         device_printf(sc->dev, "oversized packet received "
415                             "(wi_dat_len=%d, wi_status=0x%x)\n",
416                             rx_frame.wi_dat_len, rx_frame.wi_status);
417                         m_freem(m);
418                         ifp->if_ierrors++;
419                         return;
420                 }
421                 m->m_pkthdr.len = m->m_len =
422                     rx_frame.wi_dat_len + sizeof(struct ether_header);
423
424                 if (wi_read_data(sc, id, WI_802_3_OFFSET,
425                     mtod(m, caddr_t), m->m_len + 2)) {
426                         m_freem(m);
427                         ifp->if_ierrors++;
428                         return;
429                 }
430         }
431
432         ifp->if_ipackets++;
433
434         /* Handle BPF listeners. */
435         if (ifp->if_bpf) {
436                 bpf_mtap(ifp, m);
437                 if (ifp->if_flags & IFF_PROMISC &&
438                     (bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
439                     ETHER_ADDR_LEN) && (eh->ether_dhost[0] & 1) == 0)) {
440                         m_freem(m);
441                         return;
442                 }
443         }
444
445         /* Receive packet. */
446         m_adj(m, sizeof(struct ether_header));
447 #ifdef WICACHE
448         wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
449 #endif  
450         ether_input(ifp, eh, m);
451
452         return;
453 }
454
455 static void wi_txeof(sc, status)
456         struct wi_softc         *sc;
457         int                     status;
458 {
459         struct ifnet            *ifp;
460
461         ifp = &sc->arpcom.ac_if;
462
463         ifp->if_timer = 0;
464         ifp->if_flags &= ~IFF_OACTIVE;
465
466         if (status & WI_EV_TX_EXC)
467                 ifp->if_oerrors++;
468         else
469                 ifp->if_opackets++;
470
471         return;
472 }
473
474 void wi_inquire(xsc)
475         void                    *xsc;
476 {
477         struct wi_softc         *sc;
478         struct ifnet            *ifp;
479
480         sc = xsc;
481         ifp = &sc->arpcom.ac_if;
482
483         sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
484
485         /* Don't do this while we're transmitting */
486         if (ifp->if_flags & IFF_OACTIVE)
487                 return;
488
489         wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS);
490
491         return;
492 }
493
494 void wi_update_stats(sc)
495         struct wi_softc         *sc;
496 {
497         struct wi_ltv_gen       gen;
498         u_int16_t               id;
499         struct ifnet            *ifp;
500         u_int32_t               *ptr;
501         int                     i;
502         u_int16_t               t;
503
504         ifp = &sc->arpcom.ac_if;
505
506         id = CSR_READ_2(sc, WI_INFO_FID);
507
508         wi_read_data(sc, id, 0, (char *)&gen, 4);
509
510         if (gen.wi_type != WI_INFO_COUNTERS ||
511             gen.wi_len > (sizeof(sc->wi_stats) / 4) + 1)
512                 return;
513
514         ptr = (u_int32_t *)&sc->wi_stats;
515
516         for (i = 0; i < gen.wi_len - 1; i++) {
517                 t = CSR_READ_2(sc, WI_DATA1);
518 #ifdef WI_HERMES_STATS_WAR
519                 if (t > 0xF000)
520                         t = ~t & 0xFFFF;
521 #endif
522                 ptr[i] += t;
523         }
524
525         ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
526             sc->wi_stats.wi_tx_multi_retries +
527             sc->wi_stats.wi_tx_retry_limit;
528
529         return;
530 }
531
532 static void wi_intr(xsc)
533         void            *xsc;
534 {
535         struct wi_softc         *sc = xsc;
536         struct ifnet            *ifp;
537         u_int16_t               status;
538
539         ifp = &sc->arpcom.ac_if;
540
541         if (!(ifp->if_flags & IFF_UP)) {
542                 CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
543                 CSR_WRITE_2(sc, WI_INT_EN, 0);
544                 return;
545         }
546
547         /* Disable interrupts. */
548         CSR_WRITE_2(sc, WI_INT_EN, 0);
549
550         status = CSR_READ_2(sc, WI_EVENT_STAT);
551         CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
552
553         if (status & WI_EV_RX) {
554                 wi_rxeof(sc);
555                 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
556         }
557
558         if (status & WI_EV_TX) {
559                 wi_txeof(sc, status);
560                 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
561         }
562
563         if (status & WI_EV_ALLOC) {
564                 int                     id;
565                 id = CSR_READ_2(sc, WI_ALLOC_FID);
566                 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
567                 if (id == sc->wi_tx_data_id)
568                         wi_txeof(sc, status);
569         }
570
571         if (status & WI_EV_INFO) {
572                 wi_update_stats(sc);
573                 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
574         }
575
576         if (status & WI_EV_TX_EXC) {
577                 wi_txeof(sc, status);
578                 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
579         }
580
581         if (status & WI_EV_INFO_DROP) {
582                 CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
583         }
584
585         /* Re-enable interrupts. */
586         CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
587
588         if (ifp->if_snd.ifq_head != NULL)
589                 wi_start(ifp);
590
591         return;
592 }
593
594 static int wi_cmd(sc, cmd, val)
595         struct wi_softc         *sc;
596         int                     cmd;
597         int                     val;
598 {
599         int                     i, s = 0;
600
601         CSR_WRITE_2(sc, WI_PARAM0, val);
602         CSR_WRITE_2(sc, WI_COMMAND, cmd);
603
604         for (i = 0; i < WI_TIMEOUT; i++) {
605                 /*
606                  * Wait for 'command complete' bit to be
607                  * set in the event status register.
608                  */
609                 s = CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD;
610                 if (s) {
611                         /* Ack the event and read result code. */
612                         s = CSR_READ_2(sc, WI_STATUS);
613                         CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
614 #ifdef foo
615                         if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK))
616                                 return(EIO);
617 #endif
618                         if (s & WI_STAT_CMD_RESULT)
619                                 return(EIO);
620                         break;
621                 }
622         }
623
624         if (i == WI_TIMEOUT)
625                 return(ETIMEDOUT);
626
627         return(0);
628 }
629
630 static void wi_reset(sc)
631         struct wi_softc         *sc;
632 {
633         wi_cmd(sc, WI_CMD_INI, 0);
634         DELAY(100000);
635         wi_cmd(sc, WI_CMD_INI, 0);
636         DELAY(100000);
637 #ifdef foo
638         if (wi_cmd(sc, WI_CMD_INI, 0))
639                 device_printf(sc->dev, "init failed\n");
640         CSR_WRITE_2(sc, WI_INT_EN, 0);
641         CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
642
643         /* Calibrate timer. */
644         WI_SETVAL(WI_RID_TICK_TIME, 8);
645 #endif
646         return;
647 }
648
649 /*
650  * Read an LTV record from the NIC.
651  */
652 static int wi_read_record(sc, ltv)
653         struct wi_softc         *sc;
654         struct wi_ltv_gen       *ltv;
655 {
656         u_int16_t               *ptr;
657         int                     i, len, code;
658
659         /* Tell the NIC to enter record read mode. */
660         if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type))
661                 return(EIO);
662
663         /* Seek to the record. */
664         if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
665                 return(EIO);
666
667         /*
668          * Read the length and record type and make sure they
669          * match what we expect (this verifies that we have enough
670          * room to hold all of the returned data).
671          */
672         len = CSR_READ_2(sc, WI_DATA1);
673         if (len > ltv->wi_len)
674                 return(ENOSPC);
675         code = CSR_READ_2(sc, WI_DATA1);
676         if (code != ltv->wi_type)
677                 return(EIO);
678
679         ltv->wi_len = len;
680         ltv->wi_type = code;
681
682         /* Now read the data. */
683         ptr = &ltv->wi_val;
684         for (i = 0; i < ltv->wi_len - 1; i++)
685                 ptr[i] = CSR_READ_2(sc, WI_DATA1);
686
687         return(0);
688 }
689
690 /*
691  * Same as read, except we inject data instead of reading it.
692  */
693 static int wi_write_record(sc, ltv)
694         struct wi_softc         *sc;
695         struct wi_ltv_gen       *ltv;
696 {
697         u_int16_t               *ptr;
698         int                     i;
699
700         if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
701                 return(EIO);
702
703         CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
704         CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
705
706         ptr = &ltv->wi_val;
707         for (i = 0; i < ltv->wi_len - 1; i++)
708                 CSR_WRITE_2(sc, WI_DATA1, ptr[i]);
709
710         if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type))
711                 return(EIO);
712
713         return(0);
714 }
715
716 static int wi_seek(sc, id, off, chan)
717         struct wi_softc         *sc;
718         int                     id, off, chan;
719 {
720         int                     i;
721         int                     selreg, offreg;
722
723         switch (chan) {
724         case WI_BAP0:
725                 selreg = WI_SEL0;
726                 offreg = WI_OFF0;
727                 break;
728         case WI_BAP1:
729                 selreg = WI_SEL1;
730                 offreg = WI_OFF1;
731                 break;
732         default:
733                 device_printf(sc->dev, "invalid data path: %x\n", chan);
734                 return(EIO);
735         }
736
737         CSR_WRITE_2(sc, selreg, id);
738         CSR_WRITE_2(sc, offreg, off);
739
740         for (i = 0; i < WI_TIMEOUT; i++) {
741                 if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR)))
742                         break;
743         }
744
745         if (i == WI_TIMEOUT)
746                 return(ETIMEDOUT);
747
748         return(0);
749 }
750
751 static int wi_read_data(sc, id, off, buf, len)
752         struct wi_softc         *sc;
753         int                     id, off;
754         caddr_t                 buf;
755         int                     len;
756 {
757         int                     i;
758         u_int16_t               *ptr;
759
760         if (wi_seek(sc, id, off, WI_BAP1))
761                 return(EIO);
762
763         ptr = (u_int16_t *)buf;
764         for (i = 0; i < len / 2; i++)
765                 ptr[i] = CSR_READ_2(sc, WI_DATA1);
766
767         return(0);
768 }
769
770 /*
771  * According to the comments in the HCF Light code, there is a bug in
772  * the Hermes (or possibly in certain Hermes firmware revisions) where
773  * the chip's internal autoincrement counter gets thrown off during
774  * data writes: the autoincrement is missed, causing one data word to
775  * be overwritten and subsequent words to be written to the wrong memory
776  * locations. The end result is that we could end up transmitting bogus
777  * frames without realizing it. The workaround for this is to write a
778  * couple of extra guard words after the end of the transfer, then
779  * attempt to read then back. If we fail to locate the guard words where
780  * we expect them, we preform the transfer over again.
781  */
782 static int wi_write_data(sc, id, off, buf, len)
783         struct wi_softc         *sc;
784         int                     id, off;
785         caddr_t                 buf;
786         int                     len;
787 {
788         int                     i;
789         u_int16_t               *ptr;
790
791 #ifdef WI_HERMES_AUTOINC_WAR
792 again:
793 #endif
794
795         if (wi_seek(sc, id, off, WI_BAP0))
796                 return(EIO);
797
798         ptr = (u_int16_t *)buf;
799         for (i = 0; i < (len / 2); i++)
800                 CSR_WRITE_2(sc, WI_DATA0, ptr[i]);
801
802 #ifdef WI_HERMES_AUTOINC_WAR
803         CSR_WRITE_2(sc, WI_DATA0, 0x1234);
804         CSR_WRITE_2(sc, WI_DATA0, 0x5678);
805
806         if (wi_seek(sc, id, off + len, WI_BAP0))
807                 return(EIO);
808
809         if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
810             CSR_READ_2(sc, WI_DATA0) != 0x5678)
811                 goto again;
812 #endif
813
814         return(0);
815 }
816
817 /*
818  * Allocate a region of memory inside the NIC and zero
819  * it out.
820  */
821 static int wi_alloc_nicmem(sc, len, id)
822         struct wi_softc         *sc;
823         int                     len;
824         int                     *id;
825 {
826         int                     i;
827
828         if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) {
829                 device_printf(sc->dev, "failed to allocate %d bytes on NIC\n", len);
830                 return(ENOMEM);
831         }
832
833         for (i = 0; i < WI_TIMEOUT; i++) {
834                 if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
835                         break;
836         }
837
838         if (i == WI_TIMEOUT)
839                 return(ETIMEDOUT);
840
841         CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
842         *id = CSR_READ_2(sc, WI_ALLOC_FID);
843
844         if (wi_seek(sc, *id, 0, WI_BAP0))
845                 return(EIO);
846
847         for (i = 0; i < len / 2; i++)
848                 CSR_WRITE_2(sc, WI_DATA0, 0);
849
850         return(0);
851 }
852
853 static void wi_setmulti(sc)
854         struct wi_softc         *sc;
855 {
856         struct ifnet            *ifp;
857         int                     i = 0;
858         struct ifmultiaddr      *ifma;
859         struct wi_ltv_mcast     mcast;
860
861         ifp = &sc->arpcom.ac_if;
862
863         bzero((char *)&mcast, sizeof(mcast));
864
865         mcast.wi_type = WI_RID_MCAST;
866         mcast.wi_len = (3 * 16) + 1;
867
868         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
869                 wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
870                 return;
871         }
872
873         for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
874                                 ifma = ifma->ifma_link.le_next) {
875                 if (ifma->ifma_addr->sa_family != AF_LINK)
876                         continue;
877                 if (i < 16) {
878                         bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
879                             (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN);
880                         i++;
881                 } else {
882                         bzero((char *)&mcast, sizeof(mcast));
883                         break;
884                 }
885         }
886
887         mcast.wi_len = (i * 3) + 1;
888         wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
889
890         return;
891 }
892
893 static void wi_setdef(sc, wreq)
894         struct wi_softc         *sc;
895         struct wi_req           *wreq;
896 {
897         struct sockaddr_dl      *sdl;
898         struct ifaddr           *ifa;
899         struct ifnet            *ifp;
900
901         ifp = &sc->arpcom.ac_if;
902
903         switch(wreq->wi_type) {
904         case WI_RID_MAC_NODE:
905                 ifa = ifnet_addrs[ifp->if_index - 1];
906                 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
907                 bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr,
908                    ETHER_ADDR_LEN);
909                 bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);
910                 break;
911         case WI_RID_PORTTYPE:
912                 sc->wi_ptype = wreq->wi_val[0];
913                 break;
914         case WI_RID_TX_RATE:
915                 sc->wi_tx_rate = wreq->wi_val[0];
916                 break;
917         case WI_RID_MAX_DATALEN:
918                 sc->wi_max_data_len = wreq->wi_val[0];
919                 break;
920         case WI_RID_RTS_THRESH:
921                 sc->wi_rts_thresh = wreq->wi_val[0];
922                 break;
923         case WI_RID_SYSTEM_SCALE:
924                 sc->wi_ap_density = wreq->wi_val[0];
925                 break;
926         case WI_RID_CREATE_IBSS:
927                 sc->wi_create_ibss = wreq->wi_val[0];
928                 break;
929         case WI_RID_OWN_CHNL:
930                 sc->wi_channel = wreq->wi_val[0];
931                 break;
932         case WI_RID_NODENAME:
933                 bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
934                 bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30);
935                 break;
936         case WI_RID_DESIRED_SSID:
937                 bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
938                 bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30);
939                 break;
940         case WI_RID_OWN_SSID:
941                 bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
942                 bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30);
943                 break;
944         case WI_RID_PM_ENABLED:
945                 sc->wi_pm_enabled = wreq->wi_val[0];
946                 break;
947         case WI_RID_MAX_SLEEP:
948                 sc->wi_max_sleep = wreq->wi_val[0];
949                 break;
950         case WI_RID_ENCRYPTION:
951                 sc->wi_use_wep = wreq->wi_val[0];
952                 break;
953         case WI_RID_TX_CRYPT_KEY:
954                 sc->wi_tx_key = wreq->wi_val[0];
955                 break;
956         case WI_RID_DEFLT_CRYPT_KEYS:
957                 bcopy((char *)wreq, (char *)&sc->wi_keys,
958                     sizeof(struct wi_ltv_keys));
959                 break;
960         default:
961                 break;
962         }
963
964         /* Reinitialize WaveLAN. */
965         wi_init(sc);
966
967         return;
968 }
969
970 static int wi_ioctl(ifp, command, data)
971         struct ifnet            *ifp;
972         u_long                  command;
973         caddr_t                 data;
974 {
975         int                     s, error = 0;
976         struct wi_softc         *sc;
977         struct wi_req           wreq;
978         struct ifreq            *ifr;
979
980         s = splimp();
981
982         sc = ifp->if_softc;
983         ifr = (struct ifreq *)data;
984
985         if (sc->wi_gone)
986                 return(ENODEV);
987
988         switch(command) {
989         case SIOCSIFADDR:
990         case SIOCGIFADDR:
991         case SIOCSIFMTU:
992                 error = ether_ioctl(ifp, command, data);
993                 break;
994         case SIOCSIFFLAGS:
995                 if (ifp->if_flags & IFF_UP) {
996                         if (ifp->if_flags & IFF_RUNNING &&
997                             ifp->if_flags & IFF_PROMISC &&
998                             !(sc->wi_if_flags & IFF_PROMISC)) {
999                                 WI_SETVAL(WI_RID_PROMISC, 1);
1000                         } else if (ifp->if_flags & IFF_RUNNING &&
1001                             !(ifp->if_flags & IFF_PROMISC) &&
1002                             sc->wi_if_flags & IFF_PROMISC) {
1003                                 WI_SETVAL(WI_RID_PROMISC, 0);
1004                         } else
1005                                 wi_init(sc);
1006                 } else {
1007                         if (ifp->if_flags & IFF_RUNNING) {
1008                                 wi_stop(sc);
1009                         }
1010                 }
1011                 sc->wi_if_flags = ifp->if_flags;
1012                 error = 0;
1013                 break;
1014         case SIOCADDMULTI:
1015         case SIOCDELMULTI:
1016                 wi_setmulti(sc);
1017                 error = 0;
1018                 break;
1019         case SIOCGWAVELAN:
1020                 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1021                 if (error)
1022                         break;
1023                 if (wreq.wi_type == WI_RID_IFACE_STATS) {
1024                         bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val,
1025                             sizeof(sc->wi_stats));
1026                         wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1027                 } else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {
1028                         bcopy((char *)&sc->wi_keys, (char *)&wreq,
1029                             sizeof(struct wi_ltv_keys));
1030                 }
1031 #ifdef WICACHE
1032                 else if (wreq.wi_type == WI_RID_ZERO_CACHE) {
1033                         sc->wi_sigitems = sc->wi_nextitem = 0;
1034                 } else if (wreq.wi_type == WI_RID_READ_CACHE) {
1035                         char *pt = (char *)&wreq.wi_val;
1036                         bcopy((char *)&sc->wi_sigitems,
1037                             (char *)pt, sizeof(int));
1038                         pt += (sizeof (int));
1039                         wreq.wi_len = sizeof(int) / 2;
1040                         bcopy((char *)&sc->wi_sigcache, (char *)pt,
1041                             sizeof(struct wi_sigcache) * sc->wi_sigitems);
1042                         wreq.wi_len += ((sizeof(struct wi_sigcache) *
1043                             sc->wi_sigitems) / 2) + 1;
1044                 }
1045 #endif
1046                 else {
1047                         if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
1048                                 error = EINVAL;
1049                                 break;
1050                         }
1051                 }
1052                 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1053                 break;
1054         case SIOCSWAVELAN:
1055                 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1056                 if (error)
1057                         break;
1058                 if (wreq.wi_type == WI_RID_IFACE_STATS) {
1059                         error = EINVAL;
1060                         break;
1061                 } else if (wreq.wi_type == WI_RID_MGMT_XMIT) {
1062                         error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1063                             wreq.wi_len);
1064                 } else {
1065                         error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
1066                         if (!error)
1067                                 wi_setdef(sc, &wreq);
1068                 }
1069                 break;
1070         default:
1071                 error = EINVAL;
1072                 break;
1073         }
1074
1075         splx(s);
1076
1077         return(error);
1078 }
1079
1080 static void wi_init(xsc)
1081         void                    *xsc;
1082 {
1083         struct wi_softc         *sc = xsc;
1084         struct ifnet            *ifp = &sc->arpcom.ac_if;
1085         int                     s;
1086         struct wi_ltv_macaddr   mac;
1087         int                     id = 0;
1088
1089         if (sc->wi_gone)
1090                 return;
1091
1092         s = splimp();
1093
1094         if (ifp->if_flags & IFF_RUNNING)
1095                 wi_stop(sc);
1096
1097         wi_reset(sc);
1098
1099         /* Program max data length. */
1100         WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
1101
1102         /* Enable/disable IBSS creation. */
1103         WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
1104
1105         /* Set the port type. */
1106         WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
1107
1108         /* Program the RTS/CTS threshold. */
1109         WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
1110
1111         /* Program the TX rate */
1112         WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
1113
1114         /* Access point density */
1115         WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
1116
1117         /* Power Management Enabled */
1118         WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
1119
1120         /* Power Managment Max Sleep */
1121         WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
1122
1123         /* Specify the IBSS name */
1124         WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
1125
1126         /* Specify the network name */
1127         WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
1128
1129         /* Specify the frequency to use */
1130         WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
1131
1132         /* Program the nodename. */
1133         WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name);
1134
1135         /* Set our MAC address. */
1136         mac.wi_len = 4;
1137         mac.wi_type = WI_RID_MAC_NODE;
1138         bcopy((char *)&sc->arpcom.ac_enaddr,
1139            (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN);
1140         wi_write_record(sc, (struct wi_ltv_gen *)&mac);
1141
1142         /* Configure WEP. */
1143         if (sc->wi_has_wep) {
1144                 WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
1145                 WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
1146                 sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
1147                 sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
1148                 wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
1149         }
1150
1151         /* Initialize promisc mode. */
1152         if (ifp->if_flags & IFF_PROMISC) {
1153                 WI_SETVAL(WI_RID_PROMISC, 1);
1154         } else {
1155                 WI_SETVAL(WI_RID_PROMISC, 0);
1156         }
1157
1158         /* Set multicast filter. */
1159         wi_setmulti(sc);
1160
1161         /* Enable desired port */
1162         wi_cmd(sc, WI_CMD_ENABLE|sc->wi_portnum, 0);
1163
1164         if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id))
1165                 device_printf(sc->dev, "tx buffer allocation failed\n");
1166         sc->wi_tx_data_id = id;
1167
1168         if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id))
1169                 device_printf(sc->dev, "mgmt. buffer allocation failed\n");
1170         sc->wi_tx_mgmt_id = id;
1171
1172         /* enable interrupts */
1173         CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
1174
1175         splx(s);
1176
1177         ifp->if_flags |= IFF_RUNNING;
1178         ifp->if_flags &= ~IFF_OACTIVE;
1179
1180         sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
1181
1182         return;
1183 }
1184
1185 static void wi_start(ifp)
1186         struct ifnet            *ifp;
1187 {
1188         struct wi_softc         *sc;
1189         struct mbuf             *m0;
1190         struct wi_frame         tx_frame;
1191         struct ether_header     *eh;
1192         int                     id;
1193
1194         sc = ifp->if_softc;
1195
1196         if (sc->wi_gone)
1197                 return;
1198
1199         if (ifp->if_flags & IFF_OACTIVE)
1200                 return;
1201
1202         IF_DEQUEUE(&ifp->if_snd, m0);
1203         if (m0 == NULL)
1204                 return;
1205
1206         bzero((char *)&tx_frame, sizeof(tx_frame));
1207         id = sc->wi_tx_data_id;
1208         eh = mtod(m0, struct ether_header *);
1209
1210         /*
1211          * Use RFC1042 encoding for IP and ARP datagrams,
1212          * 802.3 for anything else.
1213          */
1214         if (ntohs(eh->ether_type) > 1518) {
1215                 bcopy((char *)&eh->ether_dhost,
1216                     (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN);
1217                 bcopy((char *)&eh->ether_shost,
1218                     (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN);
1219                 bcopy((char *)&eh->ether_dhost,
1220                     (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN);
1221                 bcopy((char *)&eh->ether_shost,
1222                     (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN);
1223
1224                 tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN;
1225                 tx_frame.wi_frame_ctl = WI_FTYPE_DATA;
1226                 tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
1227                 tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
1228                 tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1229                 tx_frame.wi_type = eh->ether_type;
1230
1231                 m_copydata(m0, sizeof(struct ether_header),
1232                     m0->m_pkthdr.len - sizeof(struct ether_header),
1233                     (caddr_t)&sc->wi_txbuf);
1234
1235                 wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1236                     sizeof(struct wi_frame));
1237                 wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf,
1238                     (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2);
1239         } else {
1240                 tx_frame.wi_dat_len = m0->m_pkthdr.len;
1241
1242                 eh->ether_type = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1243                 m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf);
1244
1245                 wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1246                     sizeof(struct wi_frame));
1247                 wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf,
1248                     m0->m_pkthdr.len + 2);
1249         }
1250
1251         /*
1252          * If there's a BPF listner, bounce a copy of
1253          * this frame to him.
1254          */
1255         if (ifp->if_bpf)
1256                 bpf_mtap(ifp, m0);
1257
1258         m_freem(m0);
1259
1260         if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id))
1261                 device_printf(sc->dev, "xmit failed\n");
1262
1263         ifp->if_flags |= IFF_OACTIVE;
1264
1265         /*
1266          * Set a timeout in case the chip goes out to lunch.
1267          */
1268         ifp->if_timer = 5;
1269
1270         return;
1271 }
1272
1273 static int wi_mgmt_xmit(sc, data, len)
1274         struct wi_softc         *sc;
1275         caddr_t                 data;
1276         int                     len;
1277 {
1278         struct wi_frame         tx_frame;
1279         int                     id;
1280         struct wi_80211_hdr     *hdr;
1281         caddr_t                 dptr;
1282
1283         if (sc->wi_gone)
1284                 return(ENODEV);
1285
1286         hdr = (struct wi_80211_hdr *)data;
1287         dptr = data + sizeof(struct wi_80211_hdr);
1288
1289         bzero((char *)&tx_frame, sizeof(tx_frame));
1290         id = sc->wi_tx_mgmt_id;
1291
1292         bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl,
1293            sizeof(struct wi_80211_hdr));
1294
1295         tx_frame.wi_dat_len = len - WI_SNAPHDR_LEN;
1296         tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN);
1297
1298         wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame));
1299         wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr,
1300             (len - sizeof(struct wi_80211_hdr)) + 2);
1301
1302         if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) {
1303                 device_printf(sc->dev, "xmit failed\n");
1304                 return(EIO);
1305         }
1306
1307         return(0);
1308 }
1309
1310 static void wi_stop(sc)
1311         struct wi_softc         *sc;
1312 {
1313         struct ifnet            *ifp;
1314
1315         if (sc->wi_gone)
1316                 return;
1317
1318         ifp = &sc->arpcom.ac_if;
1319
1320         CSR_WRITE_2(sc, WI_INT_EN, 0);
1321         wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0);
1322
1323         untimeout(wi_inquire, sc, sc->wi_stat_ch);
1324
1325         ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
1326
1327         return;
1328 }
1329
1330 static void wi_watchdog(ifp)
1331         struct ifnet            *ifp;
1332 {
1333         struct wi_softc         *sc;
1334
1335         sc = ifp->if_softc;
1336
1337         device_printf(sc->dev,"device timeout\n");
1338
1339         wi_init(sc);
1340
1341         ifp->if_oerrors++;
1342
1343         return;
1344 }
1345
1346 static int wi_alloc(dev)
1347         device_t                dev;
1348 {
1349         struct wi_softc         *sc = device_get_softc(dev);
1350         int                     rid;
1351
1352         rid = 0;
1353         sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
1354                                         0, ~0, 1, RF_ACTIVE);
1355         if (!sc->iobase) {
1356                 device_printf(dev, "No I/O space?!\n");
1357                 return (ENXIO);
1358         }
1359
1360         rid = 0;
1361         sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
1362                                      0, ~0, 1, RF_ACTIVE);
1363         if (!sc->irq) {
1364                 device_printf(dev, "No irq?!\n");
1365                 return (ENXIO);
1366         }
1367
1368         sc->dev = dev;
1369         sc->wi_unit = device_get_unit(dev);
1370         sc->wi_io_addr = rman_get_start(sc->iobase);
1371         sc->wi_btag = rman_get_bustag(sc->iobase);
1372         sc->wi_bhandle = rman_get_bushandle(sc->iobase);
1373
1374         return (0);
1375 }
1376
1377 static void wi_free(dev)
1378         device_t                dev;
1379 {
1380         struct wi_softc         *sc = device_get_softc(dev);
1381
1382         if (sc->iobase != NULL)
1383                 bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->iobase);
1384         if (sc->irq != NULL)
1385                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
1386
1387         return;
1388 }
1389
1390 static void wi_shutdown(dev)
1391         device_t                dev;
1392 {
1393         struct wi_softc         *sc;
1394
1395         sc = device_get_softc(dev);
1396         wi_stop(sc);
1397
1398         return;
1399 }
1400
1401 #ifdef WICACHE
1402 /* wavelan signal strength cache code.
1403  * store signal/noise/quality on per MAC src basis in
1404  * a small fixed cache.  The cache wraps if > MAX slots
1405  * used.  The cache may be zeroed out to start over.
1406  * Two simple filters exist to reduce computation:
1407  * 1. ip only (literally 0x800) which may be used
1408  * to ignore some packets.  It defaults to ip only.
1409  * it could be used to focus on broadcast, non-IP 802.11 beacons.
1410  * 2. multicast/broadcast only.  This may be used to
1411  * ignore unicast packets and only cache signal strength
1412  * for multicast/broadcast packets (beacons); e.g., Mobile-IP
1413  * beacons and not unicast traffic.
1414  *
1415  * The cache stores (MAC src(index), IP src (major clue), signal,
1416  *      quality, noise)
1417  *
1418  * No apologies for storing IP src here.  It's easy and saves much
1419  * trouble elsewhere.  The cache is assumed to be INET dependent, 
1420  * although it need not be.
1421  */
1422
1423 #ifdef documentation
1424
1425 int wi_sigitems;                                /* number of cached entries */
1426 struct wi_sigcache wi_sigcache[MAXWICACHE];  /*  array of cache entries */
1427 int wi_nextitem;                                /*  index/# of entries */
1428
1429
1430 #endif
1431
1432 /* control variables for cache filtering.  Basic idea is
1433  * to reduce cost (e.g., to only Mobile-IP agent beacons
1434  * which are broadcast or multicast).  Still you might
1435  * want to measure signal strength with unicast ping packets
1436  * on a pt. to pt. ant. setup.
1437  */
1438 /* set true if you want to limit cache items to broadcast/mcast 
1439  * only packets (not unicast).  Useful for mobile-ip beacons which
1440  * are broadcast/multicast at network layer.  Default is all packets
1441  * so ping/unicast will work say with pt. to pt. antennae setup.
1442  */
1443 static int wi_cache_mcastonly = 0;
1444 SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW, 
1445         &wi_cache_mcastonly, 0, "");
1446
1447 /* set true if you want to limit cache items to IP packets only
1448 */
1449 static int wi_cache_iponly = 1;
1450 SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW, 
1451         &wi_cache_iponly, 0, "");
1452
1453 /*
1454  * Original comments:
1455  * -----------------
1456  * wi_cache_store, per rx packet store signal
1457  * strength in MAC (src) indexed cache.
1458  *
1459  * follows linux driver in how signal strength is computed.
1460  * In ad hoc mode, we use the rx_quality field. 
1461  * signal and noise are trimmed to fit in the range from 47..138.
1462  * rx_quality field MSB is signal strength.
1463  * rx_quality field LSB is noise.
1464  * "quality" is (signal - noise) as is log value.
1465  * note: quality CAN be negative.
1466  * 
1467  * In BSS mode, we use the RID for communication quality.
1468  * TBD:  BSS mode is currently untested.
1469  *
1470  * Bill's comments:
1471  * ---------------
1472  * Actually, we use the rx_quality field all the time for both "ad-hoc"
1473  * and BSS modes. Why? Because reading an RID is really, really expensive:
1474  * there's a bunch of PIO operations that have to be done to read a record
1475  * from the NIC, and reading the comms quality RID each time a packet is
1476  * received can really hurt performance. We don't have to do this anyway:
1477  * the comms quality field only reflects the values in the rx_quality field
1478  * anyway. The comms quality RID is only meaningful in infrastructure mode,
1479  * but the values it contains are updated based on the rx_quality from
1480  * frames received from the access point.
1481  *
1482  * Also, according to Lucent, the signal strength and noise level values
1483  * can be converted to dBms by subtracting 149, so I've modified the code
1484  * to do that instead of the scaling it did originally.
1485  */
1486 static  
1487 void wi_cache_store (struct wi_softc *sc, struct ether_header *eh,
1488                      struct mbuf *m, unsigned short rx_quality)
1489 {
1490         struct ip *ip = 0; 
1491         int i;
1492         static int cache_slot = 0;      /* use this cache entry */
1493         static int wrapindex = 0;       /* next "free" cache entry */
1494         int sig, noise;
1495         int sawip=0;
1496
1497         /* filters:
1498          * 1. ip only
1499          * 2. configurable filter to throw out unicast packets,
1500          * keep multicast only.
1501          */
1502  
1503         if ((ntohs(eh->ether_type) == 0x800)) {
1504                 sawip = 1;
1505         }
1506
1507         /* filter for ip packets only 
1508         */
1509         if (wi_cache_iponly && !sawip) {
1510                 return;
1511         }
1512
1513         /* filter for broadcast/multicast only
1514          */
1515         if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
1516                 return;
1517         }
1518
1519 #ifdef SIGDEBUG
1520         printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit,
1521             rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
1522 #endif
1523
1524         /* find the ip header.  we want to store the ip_src
1525          * address.  
1526          */
1527         if (sawip) {
1528                 ip = mtod(m, struct ip *);
1529         }
1530         
1531         /* do a linear search for a matching MAC address 
1532          * in the cache table
1533          * . MAC address is 6 bytes,
1534          * . var w_nextitem holds total number of entries already cached
1535          */
1536         for(i = 0; i < sc->wi_nextitem; i++) {
1537                 if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc,  6 )) {
1538                         /* Match!,
1539                          * so we already have this entry,
1540                          * update the data
1541                          */
1542                         break;  
1543                 }
1544         }
1545
1546         /* did we find a matching mac address?
1547          * if yes, then overwrite a previously existing cache entry
1548          */
1549         if (i < sc->wi_nextitem )   {
1550                 cache_slot = i; 
1551         }
1552         /* else, have a new address entry,so
1553          * add this new entry,
1554          * if table full, then we need to replace LRU entry
1555          */
1556         else    {                          
1557
1558                 /* check for space in cache table 
1559                  * note: wi_nextitem also holds number of entries
1560                  * added in the cache table 
1561                  */
1562                 if ( sc->wi_nextitem < MAXWICACHE ) {
1563                         cache_slot = sc->wi_nextitem;
1564                         sc->wi_nextitem++;                 
1565                         sc->wi_sigitems = sc->wi_nextitem;
1566                 }
1567                 /* no space found, so simply wrap with wrap index
1568                  * and "zap" the next entry
1569                  */
1570                 else {
1571                         if (wrapindex == MAXWICACHE) {
1572                                 wrapindex = 0;
1573                         }
1574                         cache_slot = wrapindex++;
1575                 }
1576         }
1577
1578         /* invariant: cache_slot now points at some slot
1579          * in cache.
1580          */
1581         if (cache_slot < 0 || cache_slot >= MAXWICACHE) {
1582                 log(LOG_ERR, "wi_cache_store, bad index: %d of "
1583                     "[0..%d], gross cache error\n",
1584                     cache_slot, MAXWICACHE);
1585                 return;
1586         }
1587
1588         /*  store items in cache
1589          *  .ip source address
1590          *  .mac src
1591          *  .signal, etc.
1592          */
1593         if (sawip) {
1594                 sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
1595         }
1596         bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc,  6);
1597
1598         sig = (rx_quality >> 8) & 0xFF;
1599         noise = rx_quality & 0xFF;
1600         sc->wi_sigcache[cache_slot].signal = sig - 149;
1601         sc->wi_sigcache[cache_slot].noise = noise - 149;
1602         sc->wi_sigcache[cache_slot].quality = sig - noise;
1603
1604         return;
1605 }
1606 #endif