Home | History | Annotate | Line # | Download | only in ic
awi.c revision 1.6
      1  1.6  sommerfe /* $NetBSD: awi.c,v 1.6 1999/11/08 15:45:00 sommerfeld Exp $ */
      2  1.3  sommerfe 
      3  1.1  sommerfe /*-
      4  1.1  sommerfe  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5  1.1  sommerfe  * All rights reserved.
      6  1.1  sommerfe  *
      7  1.1  sommerfe  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1  sommerfe  * by Bill Sommerfeld
      9  1.1  sommerfe  *
     10  1.1  sommerfe  * Redistribution and use in source and binary forms, with or without
     11  1.1  sommerfe  * modification, are permitted provided that the following conditions
     12  1.1  sommerfe  * are met:
     13  1.1  sommerfe  * 1. Redistributions of source code must retain the above copyright
     14  1.1  sommerfe  *    notice, this list of conditions and the following disclaimer.
     15  1.1  sommerfe  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  sommerfe  *    notice, this list of conditions and the following disclaimer in the
     17  1.1  sommerfe  *    documentation and/or other materials provided with the distribution.
     18  1.1  sommerfe  * 3. All advertising materials mentioning features or use of this software
     19  1.1  sommerfe  *    must display the following acknowledgement:
     20  1.1  sommerfe  *        This product includes software developed by the NetBSD
     21  1.1  sommerfe  *        Foundation, Inc. and its contributors.
     22  1.1  sommerfe  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.1  sommerfe  *    contributors may be used to endorse or promote products derived
     24  1.1  sommerfe  *    from this software without specific prior written permission.
     25  1.1  sommerfe  *
     26  1.1  sommerfe  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.1  sommerfe  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.1  sommerfe  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.1  sommerfe  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.1  sommerfe  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.1  sommerfe  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.1  sommerfe  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.1  sommerfe  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.1  sommerfe  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.1  sommerfe  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.1  sommerfe  * POSSIBILITY OF SUCH DAMAGE.
     37  1.1  sommerfe  */
     38  1.1  sommerfe /*
     39  1.1  sommerfe  * Driver for AMD 802.11 firmware.
     40  1.1  sommerfe  * Uses am79c930 chip driver to talk to firmware running on the am79c930.
     41  1.1  sommerfe  *
     42  1.1  sommerfe  * More-or-less a generic ethernet-like if driver, with 802.11 gorp added.
     43  1.1  sommerfe  */
     44  1.1  sommerfe 
     45  1.1  sommerfe /*
     46  1.1  sommerfe  * todo:
     47  1.1  sommerfe  *	- don't print "management timeout"/"assoc with" for normal
     48  1.1  sommerfe  *		association keepalive goo.
     49  1.1  sommerfe  *	- multicast filter.
     50  1.1  sommerfe  *	- use cluster mbufs on rx?
     51  1.1  sommerfe  *	- fix device reset so it's more likely to work
     52  1.1  sommerfe  *	- allow i/o-space-only access to device (over in am79c930.c)
     53  1.1  sommerfe  *	- show status goo through ifmedia.
     54  1.1  sommerfe  *
     55  1.1  sommerfe  * more todo:
     56  1.1  sommerfe  *	- deal with more 802.11 frames.
     57  1.1  sommerfe  *		- send reassoc request
     58  1.1  sommerfe  *		- deal with reassoc response
     59  1.1  sommerfe  *		- send/deal with disassociation
     60  1.1  sommerfe  *	- deal with "full" access points (no room for me).
     61  1.1  sommerfe  *	- power save mode
     62  1.1  sommerfe  *	- if no traffic, let ourselves gracefully desync?
     63  1.1  sommerfe  *
     64  1.1  sommerfe  * later:
     65  1.1  sommerfe  *	- SSID preferences
     66  1.1  sommerfe  *	- need ioctls for poking at the MIBs
     67  1.1  sommerfe  *	- implement ad-hoc mode (including bss creation).
     68  1.1  sommerfe  *	- decide when to do "ad hoc" vs. infrastructure mode (IFF_LINK flags?)
     69  1.1  sommerfe  *		(focus on inf. mode since that will be needed for ietf)
     70  1.1  sommerfe  *	- deal with DH vs. FH versions of the card
     71  1.1  sommerfe  *	- deal with faster cards (2mb/s)
     72  1.1  sommerfe  *	- ?WEP goo (mmm, rc4) (it looks not particularly useful).
     73  1.1  sommerfe  *	- ifmedia revision.
     74  1.1  sommerfe  *	- common 802.11 mibish things.
     75  1.1  sommerfe  *	- common 802.11 media layer.
     76  1.1  sommerfe  */
     77  1.1  sommerfe 
     78  1.1  sommerfe #include "opt_inet.h"
     79  1.1  sommerfe #include "opt_ns.h"
     80  1.1  sommerfe #include "bpfilter.h"
     81  1.1  sommerfe #include "rnd.h"
     82  1.1  sommerfe 
     83  1.1  sommerfe #include <sys/param.h>
     84  1.1  sommerfe #include <sys/systm.h>
     85  1.1  sommerfe #include <sys/kernel.h>
     86  1.1  sommerfe #include <sys/mbuf.h>
     87  1.1  sommerfe #include <sys/socket.h>
     88  1.1  sommerfe #include <sys/ioctl.h>
     89  1.1  sommerfe #include <sys/errno.h>
     90  1.1  sommerfe #include <sys/syslog.h>
     91  1.1  sommerfe #include <sys/select.h>
     92  1.1  sommerfe #include <sys/device.h>
     93  1.1  sommerfe #if NRND > 0
     94  1.1  sommerfe #include <sys/rnd.h>
     95  1.1  sommerfe #endif
     96  1.1  sommerfe 
     97  1.1  sommerfe #include <net/if.h>
     98  1.1  sommerfe #include <net/if_dl.h>
     99  1.1  sommerfe #include <net/if_ether.h>
    100  1.1  sommerfe #include <net/if_media.h>
    101  1.1  sommerfe 
    102  1.1  sommerfe #ifdef INET
    103  1.1  sommerfe #include <netinet/in.h>
    104  1.1  sommerfe #include <netinet/in_systm.h>
    105  1.1  sommerfe #include <netinet/in_var.h>
    106  1.1  sommerfe #include <netinet/ip.h>
    107  1.1  sommerfe #include <netinet/if_inarp.h>
    108  1.1  sommerfe #endif
    109  1.1  sommerfe 
    110  1.1  sommerfe #ifdef NS
    111  1.1  sommerfe #include <netns/ns.h>
    112  1.1  sommerfe #include <netns/ns_if.h>
    113  1.1  sommerfe #endif
    114  1.1  sommerfe 
    115  1.1  sommerfe #if NBPFILTER > 0
    116  1.1  sommerfe #include <net/bpf.h>
    117  1.1  sommerfe #include <net/bpfdesc.h>
    118  1.1  sommerfe #endif
    119  1.1  sommerfe 
    120  1.1  sommerfe #include <machine/cpu.h>
    121  1.1  sommerfe #include <machine/bus.h>
    122  1.1  sommerfe #include <machine/intr.h>
    123  1.1  sommerfe 
    124  1.1  sommerfe #include <dev/ic/am79c930reg.h>
    125  1.1  sommerfe #include <dev/ic/am79c930var.h>
    126  1.1  sommerfe #include <dev/ic/awireg.h>
    127  1.1  sommerfe #include <dev/ic/awivar.h>
    128  1.1  sommerfe 
    129  1.1  sommerfe void awi_insane __P((struct awi_softc *sc));
    130  1.1  sommerfe int awi_intlock __P((struct awi_softc *sc));
    131  1.1  sommerfe void awi_intunlock __P((struct awi_softc *sc));
    132  1.1  sommerfe void awi_intrinit __P((struct awi_softc *sc));
    133  1.1  sommerfe u_int8_t awi_read_intst __P((struct awi_softc *sc));
    134  1.1  sommerfe void awi_stop __P((struct awi_softc *sc));
    135  1.1  sommerfe void awi_init __P((struct awi_softc *sc));
    136  1.1  sommerfe void awi_set_mc __P((struct awi_softc *sc));
    137  1.1  sommerfe void awi_rxint __P((struct awi_softc *));
    138  1.1  sommerfe void awi_txint __P((struct awi_softc *));
    139  1.1  sommerfe void awi_tx_packet __P((struct awi_softc *, int, struct mbuf *));
    140  1.1  sommerfe 
    141  1.1  sommerfe void awi_rcv __P((struct awi_softc *, struct mbuf *, u_int32_t, u_int8_t));
    142  1.1  sommerfe void awi_rcv_mgt __P((struct awi_softc *, struct mbuf *, u_int32_t, u_int8_t));
    143  1.1  sommerfe void awi_rcv_data __P((struct awi_softc *, struct mbuf *));
    144  1.1  sommerfe void awi_rcv_ctl __P((struct awi_softc *, struct mbuf *));
    145  1.1  sommerfe 
    146  1.1  sommerfe int awi_enable __P((struct awi_softc *sc));
    147  1.1  sommerfe void awi_disable __P((struct awi_softc *sc));
    148  1.1  sommerfe 
    149  1.1  sommerfe void awi_zero __P((struct awi_softc *, u_int32_t, u_int32_t));
    150  1.1  sommerfe 
    151  1.1  sommerfe void awi_cmd __P((struct awi_softc *, u_int8_t));
    152  1.1  sommerfe void awi_cmd_test_if __P((struct awi_softc *));
    153  1.1  sommerfe void awi_cmd_get_mib __P((struct awi_softc *sc, u_int8_t, u_int8_t, u_int8_t));
    154  1.1  sommerfe void awi_cmd_txinit __P((struct awi_softc *sc));
    155  1.1  sommerfe void awi_cmd_scan __P((struct awi_softc *sc));
    156  1.1  sommerfe void awi_scan_next __P((struct awi_softc *sc));
    157  1.1  sommerfe void awi_try_sync __P((struct awi_softc *sc));
    158  1.1  sommerfe void awi_cmd_set_ss __P((struct awi_softc *sc));
    159  1.1  sommerfe void awi_cmd_set_promisc __P((struct awi_softc *sc));
    160  1.1  sommerfe void awi_cmd_set_allmulti __P((struct awi_softc *sc));
    161  1.1  sommerfe void awi_cmd_set_infra __P((struct awi_softc *sc));
    162  1.1  sommerfe void awi_cmd_set_notap __P((struct awi_softc *sc));
    163  1.1  sommerfe void awi_cmd_get_myaddr __P((struct awi_softc *sc));
    164  1.1  sommerfe 
    165  1.1  sommerfe 
    166  1.1  sommerfe void awi_cmd_scan_done __P((struct awi_softc *sc, u_int8_t));
    167  1.1  sommerfe void awi_cmd_sync_done __P((struct awi_softc *sc, u_int8_t));
    168  1.1  sommerfe void awi_cmd_set_ss_done __P((struct awi_softc *sc, u_int8_t));
    169  1.1  sommerfe void awi_cmd_set_allmulti_done __P((struct awi_softc *sc, u_int8_t));
    170  1.1  sommerfe void awi_cmd_set_promisc_done __P((struct awi_softc *sc, u_int8_t));
    171  1.1  sommerfe void awi_cmd_set_infra_done __P((struct awi_softc *sc, u_int8_t));
    172  1.1  sommerfe void awi_cmd_set_notap_done __P((struct awi_softc *sc, u_int8_t));
    173  1.1  sommerfe void awi_cmd_get_myaddr_done __P((struct awi_softc *sc, u_int8_t));
    174  1.1  sommerfe 
    175  1.1  sommerfe void awi_reset __P((struct awi_softc *));
    176  1.1  sommerfe void awi_init_1 __P((struct awi_softc *));
    177  1.1  sommerfe void awi_init_2 __P((struct awi_softc *, u_int8_t));
    178  1.1  sommerfe void awi_mibdump __P((struct awi_softc *, u_int8_t));
    179  1.1  sommerfe void awi_init_read_bufptrs_done __P((struct awi_softc *, u_int8_t));
    180  1.1  sommerfe void awi_init_4 __P((struct awi_softc *, u_int8_t));
    181  1.1  sommerfe void awi_init_5 __P((struct awi_softc *, u_int8_t));
    182  1.1  sommerfe void awi_init_6 __P((struct awi_softc *, u_int8_t));
    183  1.1  sommerfe void awi_running __P((struct awi_softc *));
    184  1.1  sommerfe 
    185  1.1  sommerfe void awi_init_txdescr __P((struct awi_softc *));
    186  1.1  sommerfe void awi_init_txd __P((struct awi_softc *, int, int, int, int));
    187  1.1  sommerfe 
    188  1.1  sommerfe void awi_watchdog __P((struct ifnet *));
    189  1.1  sommerfe void awi_start __P((struct ifnet *));
    190  1.1  sommerfe int awi_ioctl __P((struct ifnet *, u_long, caddr_t));
    191  1.1  sommerfe void awi_dump_rxchain __P((struct awi_softc *, char *, u_int32_t *));
    192  1.1  sommerfe 
    193  1.1  sommerfe void awi_send_frame __P((struct awi_softc *, struct mbuf *));
    194  1.1  sommerfe void awi_send_authreq __P((struct awi_softc *));
    195  1.1  sommerfe void awi_send_assocreq __P((struct awi_softc *));
    196  1.1  sommerfe void awi_parse_tlv __P((u_int8_t *base, u_int8_t *end, u_int8_t **vals, u_int8_t *lens, size_t nattr));
    197  1.1  sommerfe 
    198  1.1  sommerfe u_int8_t *awi_add_rates __P((struct awi_softc *, struct mbuf *, u_int8_t *));
    199  1.1  sommerfe u_int8_t *awi_add_ssid __P((struct awi_softc *, struct mbuf *, u_int8_t *));
    200  1.1  sommerfe void * awi_init_hdr __P((struct awi_softc *, struct mbuf *, int, int));
    201  1.1  sommerfe 
    202  1.1  sommerfe void awi_hexdump __P((char *tag, u_int8_t *data, int len));
    203  1.1  sommerfe void awi_card_hexdump __P((struct awi_softc *, char *tag, u_int32_t offset, int len));
    204  1.1  sommerfe 
    205  1.1  sommerfe int awi_drop_output __P((struct ifnet *, struct mbuf *,
    206  1.1  sommerfe     struct sockaddr *, struct rtentry *));
    207  1.1  sommerfe void awi_drop_input __P((struct ifnet *, struct mbuf *));
    208  1.1  sommerfe struct mbuf *awi_output_kludge __P((struct awi_softc *, struct mbuf *));
    209  1.1  sommerfe void awi_set_timer __P((struct awi_softc *));
    210  1.1  sommerfe void awi_restart_scan __P((struct awi_softc *));
    211  1.1  sommerfe 
    212  1.1  sommerfe static const u_int8_t snap_magic[] = { 0xaa, 0xaa, 3, 0, 0, 0 };
    213  1.1  sommerfe 
    214  1.5  sommerfe int awi_scan_keepalive = 10;
    215  1.5  sommerfe 
    216  1.1  sommerfe /*
    217  1.1  sommerfe  * attach (called by bus-specific front end)
    218  1.1  sommerfe  *
    219  1.1  sommerfe  *	look for banner message
    220  1.1  sommerfe  *	wait for selftests to complete (up to 2s??? eeee.)
    221  1.1  sommerfe  *		(do this with a timeout!!??!!)
    222  1.1  sommerfe  *	on timeout completion:
    223  1.1  sommerfe  *		issue test_interface command.
    224  1.1  sommerfe  *	get_mib command  to locate TX buffer.
    225  1.1  sommerfe  *	set_mib command to set any non-default variables.
    226  1.1  sommerfe  *	init tx first.
    227  1.1  sommerfe  * 	init rx second with enable receiver command
    228  1.1  sommerfe  *
    229  1.1  sommerfe  *	mac mgmt portion executes sync command to start BSS
    230  1.1  sommerfe  *
    231  1.1  sommerfe  */
    232  1.1  sommerfe 
    233  1.1  sommerfe /*
    234  1.1  sommerfe  * device shutdown routine.
    235  1.1  sommerfe  */
    236  1.1  sommerfe 
    237  1.1  sommerfe /*
    238  1.1  sommerfe  * device appears to be insane.  rather than hanging, whap device upside
    239  1.1  sommerfe  * the head on next timeout.
    240  1.1  sommerfe  */
    241  1.1  sommerfe 
    242  1.1  sommerfe void
    243  1.1  sommerfe awi_insane(sc)
    244  1.1  sommerfe 	struct awi_softc *sc;
    245  1.1  sommerfe {
    246  1.1  sommerfe 	struct ifnet *ifp = sc->sc_ifp;
    247  1.1  sommerfe 	printf("%s: device timeout\n", sc->sc_dev.dv_xname);
    248  1.1  sommerfe 
    249  1.1  sommerfe 	/* whap device on next timeout. */
    250  1.1  sommerfe 	sc->sc_state = AWI_ST_INSANE;
    251  1.1  sommerfe 	ifp->if_timer = 1;
    252  1.1  sommerfe }
    253  1.1  sommerfe 
    254  1.1  sommerfe void
    255  1.1  sommerfe awi_set_timer (sc)
    256  1.1  sommerfe 	struct awi_softc *sc;
    257  1.1  sommerfe {
    258  1.1  sommerfe 	if (sc->sc_tx_timer || sc->sc_scan_timer ||
    259  1.1  sommerfe 	    sc->sc_mgt_timer || sc->sc_cmd_timer)
    260  1.1  sommerfe 		sc->sc_ifp->if_timer = 1;
    261  1.1  sommerfe }
    262  1.1  sommerfe 
    263  1.1  sommerfe 
    264  1.1  sommerfe /*
    265  1.1  sommerfe  * Copy m0 into the given TX descriptor and give the descriptor to the
    266  1.1  sommerfe  * device so it starts transmiting..
    267  1.1  sommerfe  */
    268  1.1  sommerfe 
    269  1.1  sommerfe void
    270  1.1  sommerfe awi_tx_packet (sc, txd, m0)
    271  1.1  sommerfe 	struct awi_softc *sc;
    272  1.1  sommerfe 	int txd;
    273  1.1  sommerfe 	struct mbuf *m0;
    274  1.1  sommerfe {
    275  1.1  sommerfe 	u_int32_t frame = sc->sc_txd[txd].frame;
    276  1.1  sommerfe 	u_int32_t len = sc->sc_txd[txd].len;
    277  1.1  sommerfe 	struct mbuf *m;
    278  1.1  sommerfe 
    279  1.1  sommerfe 	for (m = m0; m != NULL; m = m->m_next) {
    280  1.1  sommerfe 		u_int32_t nmove;
    281  1.1  sommerfe 		nmove = min(len, m->m_len);
    282  1.1  sommerfe 		awi_write_bytes (sc, frame, m->m_data, nmove);
    283  1.1  sommerfe 		if (nmove != m->m_len) {
    284  1.1  sommerfe 			printf("%s: large frame truncated\n",
    285  1.1  sommerfe 			    sc->sc_dev.dv_xname);
    286  1.1  sommerfe 			break;
    287  1.1  sommerfe 		}
    288  1.1  sommerfe 		frame += nmove;
    289  1.1  sommerfe 		len -= nmove;
    290  1.1  sommerfe 	}
    291  1.1  sommerfe 
    292  1.1  sommerfe 	awi_init_txd (sc,
    293  1.1  sommerfe 	    txd,
    294  1.1  sommerfe 	    AWI_TXD_ST_OWN,
    295  1.1  sommerfe 	    frame - sc->sc_txd[txd].frame,
    296  1.1  sommerfe 	    AWI_RATE_1MBIT);
    297  1.1  sommerfe 
    298  1.1  sommerfe #if 0
    299  1.1  sommerfe 	awi_card_hexdump (sc, "txd to go", sc->sc_txd[txd].descr,
    300  1.1  sommerfe 	    AWI_TXD_SIZE);
    301  1.1  sommerfe #endif
    302  1.1  sommerfe 
    303  1.1  sommerfe }
    304  1.1  sommerfe 
    305  1.1  sommerfe /*
    306  1.1  sommerfe  * XXX KLUDGE XXX
    307  1.1  sommerfe  *
    308  1.1  sommerfe  * Convert ethernet-formatted frame into 802.11 data frame
    309  1.1  sommerfe  * for infrastructure mode.
    310  1.1  sommerfe  */
    311  1.1  sommerfe 
    312  1.1  sommerfe struct mbuf *
    313  1.1  sommerfe awi_output_kludge (sc, m0)
    314  1.1  sommerfe 	struct awi_softc *sc;
    315  1.1  sommerfe 	struct mbuf *m0;
    316  1.1  sommerfe {
    317  1.1  sommerfe 	u_int8_t *framehdr;
    318  1.1  sommerfe 	u_int8_t *llchdr;
    319  1.1  sommerfe 	u_int8_t dstaddr[ETHER_ADDR_LEN];
    320  1.1  sommerfe 	struct awi_mac_header *amhdr;
    321  1.1  sommerfe 	u_int16_t etype;
    322  1.1  sommerfe 	struct ether_header *eh = mtod(m0, struct ether_header *);
    323  1.1  sommerfe 
    324  1.1  sommerfe #if 0
    325  1.1  sommerfe 	awi_hexdump("etherframe", m0->m_data, m0->m_len);
    326  1.1  sommerfe #endif
    327  1.1  sommerfe 
    328  1.1  sommerfe 	memcpy(dstaddr, eh->ether_dhost, sizeof(dstaddr));
    329  1.1  sommerfe 	etype = eh->ether_type;
    330  1.1  sommerfe 
    331  1.1  sommerfe 	m_adj(m0, sizeof(struct ether_header));
    332  1.1  sommerfe 
    333  1.1  sommerfe 	M_PREPEND(m0, sizeof(struct awi_mac_header) + 8, M_DONTWAIT);
    334  1.1  sommerfe 
    335  1.1  sommerfe 	if (m0 == NULL) {
    336  1.1  sommerfe 		printf("oops, prepend failed\n");
    337  1.1  sommerfe 		return NULL;
    338  1.1  sommerfe 	}
    339  1.1  sommerfe 
    340  1.1  sommerfe 	if (m0->m_len < 32) {
    341  1.1  sommerfe 		printf("oops, prepend only left %d bytes\n", m0->m_len);
    342  1.1  sommerfe 		m_freem(m0);
    343  1.1  sommerfe 		return NULL;
    344  1.1  sommerfe 	}
    345  1.1  sommerfe 	framehdr = mtod(m0, u_int8_t *);
    346  1.1  sommerfe 	amhdr = mtod(m0, struct awi_mac_header *);
    347  1.1  sommerfe 
    348  1.1  sommerfe 	amhdr->awi_fc = IEEEWL_FC_VERS |
    349  1.1  sommerfe 	    IEEEWL_FC_TYPE_DATA<<IEEEWL_FC_TYPE_SHIFT;
    350  1.1  sommerfe 	amhdr->awi_f2 = IEEEWL_FC2_TODS;
    351  1.1  sommerfe 
    352  1.1  sommerfe 	memcpy(amhdr->awi_addr3, dstaddr, ETHER_ADDR_LEN); /* ether DST */
    353  1.1  sommerfe 	memcpy(amhdr->awi_addr1, sc->sc_active_bss.bss_id, ETHER_ADDR_LEN);
    354  1.1  sommerfe 	memcpy(amhdr->awi_addr2, sc->sc_my_addr, ETHER_ADDR_LEN);
    355  1.1  sommerfe 	amhdr->awi_duration = 0;
    356  1.1  sommerfe 	amhdr->awi_seqctl = 0;
    357  1.1  sommerfe 	llchdr = (u_int8_t *) (amhdr + 1);
    358  1.1  sommerfe 	memcpy(llchdr, snap_magic, 6);
    359  1.1  sommerfe 	memcpy(llchdr+6, &etype, 2);
    360  1.1  sommerfe 
    361  1.1  sommerfe 	return m0;
    362  1.1  sommerfe }
    363  1.1  sommerfe /*
    364  1.1  sommerfe  * device start routine
    365  1.1  sommerfe  *
    366  1.1  sommerfe  * loop while there are free tx buffer descriptors and mbufs in the queue:
    367  1.1  sommerfe  *	-> copy mbufs to tx buffer and free mbufs.
    368  1.1  sommerfe  *	-> mark txd as good to go	       (OWN bit set, all others clear)
    369  1.1  sommerfe  */
    370  1.1  sommerfe 
    371  1.1  sommerfe void
    372  1.1  sommerfe awi_start(ifp)
    373  1.1  sommerfe 	struct ifnet *ifp;
    374  1.1  sommerfe {
    375  1.1  sommerfe 	struct awi_softc *sc = ifp->if_softc;
    376  1.1  sommerfe 	struct mbuf *m0;
    377  1.1  sommerfe 	int opending;
    378  1.1  sommerfe 
    379  1.1  sommerfe 	if ((ifp->if_flags & IFF_RUNNING) == 0) {
    380  1.1  sommerfe 		printf("%s: start called while not running\n",
    381  1.1  sommerfe 		    sc->sc_dev.dv_xname);
    382  1.1  sommerfe 		return;
    383  1.1  sommerfe 	}
    384  1.1  sommerfe 
    385  1.1  sommerfe 	/*
    386  1.1  sommerfe 	 * loop through send queue, setting up tx descriptors
    387  1.1  sommerfe 	 * until we either run out of stuff to send, or descriptors
    388  1.1  sommerfe 	 * to send them in.
    389  1.1  sommerfe 	 */
    390  1.1  sommerfe 	opending = sc->sc_txpending;
    391  1.1  sommerfe 
    392  1.1  sommerfe 	while (sc->sc_txpending < sc->sc_ntxd) {
    393  1.1  sommerfe 		/*
    394  1.1  sommerfe 		 * Grab a packet off the queue.
    395  1.1  sommerfe 		 */
    396  1.1  sommerfe 		IF_DEQUEUE (&sc->sc_mgtq, m0);
    397  1.1  sommerfe 
    398  1.1  sommerfe 		if (m0 == NULL) {
    399  1.1  sommerfe 			/* XXX defer sending if not synched yet? */
    400  1.1  sommerfe 			IF_DEQUEUE (&ifp->if_snd, m0);
    401  1.1  sommerfe 			if (m0 == NULL)
    402  1.1  sommerfe 				break;
    403  1.1  sommerfe #if NBPFILTER > 0
    404  1.1  sommerfe 			/*
    405  1.1  sommerfe 			 * Pass packet to bpf if there is a listener.
    406  1.1  sommerfe 			 */
    407  1.1  sommerfe 			if (ifp->if_bpf)
    408  1.1  sommerfe 				bpf_mtap(ifp->if_bpf, m0);
    409  1.1  sommerfe #endif
    410  1.1  sommerfe 			/*
    411  1.1  sommerfe 			 * We've got an ethernet-format frame.
    412  1.1  sommerfe 			 * we need to mangle it into 802.11 form..
    413  1.1  sommerfe 			 */
    414  1.1  sommerfe 			m0 = awi_output_kludge(sc, m0);
    415  1.1  sommerfe 			if (m0 == NULL)
    416  1.1  sommerfe 				continue;
    417  1.1  sommerfe 		}
    418  1.1  sommerfe 
    419  1.1  sommerfe 		awi_tx_packet(sc, sc->sc_txnext, m0);
    420  1.1  sommerfe 
    421  1.1  sommerfe 		sc->sc_txpending++;
    422  1.1  sommerfe 		sc->sc_txnext = (sc->sc_txnext + 1) % sc->sc_ntxd;
    423  1.1  sommerfe 
    424  1.1  sommerfe 		m_freem(m0);
    425  1.1  sommerfe 	}
    426  1.1  sommerfe 	if (sc->sc_txpending >= sc->sc_ntxd) {
    427  1.1  sommerfe 		/* no more slots available.. */
    428  1.1  sommerfe 		ifp->if_flags |= IFF_OACTIVE;
    429  1.1  sommerfe 	}
    430  1.1  sommerfe 	if (sc->sc_txpending != opending) {
    431  1.1  sommerfe 		/* set watchdog timer in case unit flakes out */
    432  1.1  sommerfe 		if (sc->sc_tx_timer == 0)
    433  1.1  sommerfe 			sc->sc_tx_timer = 5;
    434  1.1  sommerfe 		awi_set_timer(sc);
    435  1.1  sommerfe 	}
    436  1.1  sommerfe }
    437  1.1  sommerfe 
    438  1.1  sommerfe int
    439  1.1  sommerfe awi_enable(sc)
    440  1.1  sommerfe 	struct awi_softc *sc;
    441  1.1  sommerfe {
    442  1.1  sommerfe 	if (sc->sc_enabled == 0) {
    443  1.1  sommerfe 		if ((sc->sc_enable != NULL) && ((*sc->sc_enable)(sc) != 0)) {
    444  1.1  sommerfe 			printf("%s: device enable failed\n",
    445  1.1  sommerfe 			    sc->sc_dev.dv_xname);
    446  1.1  sommerfe 			return (EIO);
    447  1.1  sommerfe 		}
    448  1.1  sommerfe 		awi_init(sc);
    449  1.1  sommerfe 	}
    450  1.1  sommerfe 	sc->sc_enabled = 1;
    451  1.1  sommerfe 	return 0;
    452  1.1  sommerfe }
    453  1.1  sommerfe 
    454  1.1  sommerfe void
    455  1.1  sommerfe awi_disable(sc)
    456  1.1  sommerfe 	struct awi_softc *sc;
    457  1.1  sommerfe {
    458  1.1  sommerfe 	if (sc->sc_enabled != 0 && sc->sc_disable != NULL) {
    459  1.1  sommerfe 		(*sc->sc_disable)(sc);
    460  1.1  sommerfe 		sc->sc_enabled = 0;
    461  1.1  sommerfe 	}
    462  1.1  sommerfe }
    463  1.1  sommerfe 
    464  1.1  sommerfe 
    465  1.1  sommerfe 
    466  1.1  sommerfe int
    467  1.1  sommerfe awi_intlock(sc)
    468  1.1  sommerfe 	struct awi_softc *sc;
    469  1.1  sommerfe {
    470  1.1  sommerfe 	int i, j;
    471  1.1  sommerfe 	u_int8_t lockout;
    472  1.1  sommerfe 
    473  1.1  sommerfe 	DELAY(5);
    474  1.1  sommerfe 	for (j=0; j<10; j++) {
    475  1.1  sommerfe 		for (i=0; i<AWI_LOCKOUT_SPIN; i++) {
    476  1.1  sommerfe 			lockout = awi_read_1(sc, AWI_LOCKOUT_HOST);
    477  1.1  sommerfe 			if (!lockout)
    478  1.1  sommerfe 				break;
    479  1.1  sommerfe 			DELAY(5);
    480  1.1  sommerfe 		}
    481  1.1  sommerfe 		if (lockout)
    482  1.1  sommerfe 			break;
    483  1.1  sommerfe 		awi_write_1 (sc, AWI_LOCKOUT_MAC, 1);
    484  1.1  sommerfe 		lockout = awi_read_1(sc, AWI_LOCKOUT_HOST);
    485  1.1  sommerfe 
    486  1.1  sommerfe 		if (!lockout)
    487  1.1  sommerfe 			break;
    488  1.1  sommerfe 		/* oops, lost the race.. try again */
    489  1.1  sommerfe 		awi_write_1 (sc, AWI_LOCKOUT_MAC, 0);
    490  1.1  sommerfe 	}
    491  1.1  sommerfe 
    492  1.1  sommerfe 	if (lockout) {
    493  1.1  sommerfe 		awi_insane(sc);
    494  1.1  sommerfe 		return 0;
    495  1.1  sommerfe 	}
    496  1.1  sommerfe 	return 1;
    497  1.1  sommerfe }
    498  1.1  sommerfe 
    499  1.1  sommerfe void
    500  1.1  sommerfe awi_intunlock(sc)
    501  1.1  sommerfe 	struct awi_softc *sc;
    502  1.1  sommerfe {
    503  1.1  sommerfe 	awi_write_1 (sc, AWI_LOCKOUT_MAC, 0);
    504  1.1  sommerfe }
    505  1.1  sommerfe 
    506  1.1  sommerfe void
    507  1.1  sommerfe awi_intrinit(sc)
    508  1.1  sommerfe 	struct awi_softc *sc;
    509  1.1  sommerfe {
    510  1.1  sommerfe 	u_int8_t intmask;
    511  1.1  sommerfe 
    512  1.1  sommerfe 	am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_ENECINT);
    513  1.1  sommerfe 
    514  1.1  sommerfe 	intmask = AWI_INT_GROGGY|AWI_INT_SCAN_CMPLT|
    515  1.1  sommerfe 	    AWI_INT_TX|AWI_INT_RX|AWI_INT_CMD;
    516  1.1  sommerfe 
    517  1.1  sommerfe 	intmask = ~intmask;
    518  1.1  sommerfe 
    519  1.1  sommerfe 	if (!awi_intlock(sc))
    520  1.1  sommerfe 		return;
    521  1.1  sommerfe 
    522  1.1  sommerfe 	awi_write_1(sc, AWI_INTMASK, intmask);
    523  1.1  sommerfe 	awi_write_1(sc, AWI_INTMASK2, 0);
    524  1.1  sommerfe 
    525  1.1  sommerfe 	awi_intunlock(sc);
    526  1.1  sommerfe }
    527  1.1  sommerfe 
    528  1.1  sommerfe void awi_hexdump (char *tag, u_int8_t *data, int len)
    529  1.1  sommerfe {
    530  1.1  sommerfe 	int i;
    531  1.1  sommerfe 
    532  1.1  sommerfe 	printf("%s:", tag);
    533  1.1  sommerfe 	for (i=0; i<len; i++) {
    534  1.1  sommerfe 		printf(" %02x", data[i]);
    535  1.1  sommerfe 	}
    536  1.1  sommerfe 	printf("\n");
    537  1.1  sommerfe }
    538  1.1  sommerfe 
    539  1.1  sommerfe void awi_card_hexdump (sc, tag, offset, len)
    540  1.1  sommerfe 	struct awi_softc *sc;
    541  1.1  sommerfe 	char *tag;
    542  1.1  sommerfe 	u_int32_t offset;
    543  1.1  sommerfe 	int len;
    544  1.1  sommerfe {
    545  1.1  sommerfe 	int i;
    546  1.1  sommerfe 
    547  1.1  sommerfe 	printf("%s:", tag);
    548  1.1  sommerfe 	for (i=0; i<len; i++) {
    549  1.1  sommerfe 		printf(" %02x", awi_read_1(sc, offset+i));
    550  1.1  sommerfe 	}
    551  1.1  sommerfe 	printf("\n");
    552  1.1  sommerfe }
    553  1.1  sommerfe 
    554  1.1  sommerfe u_int8_t
    555  1.1  sommerfe awi_read_intst(sc)
    556  1.1  sommerfe 	struct awi_softc *sc;
    557  1.1  sommerfe {
    558  1.1  sommerfe 	u_int8_t state;
    559  1.1  sommerfe 
    560  1.1  sommerfe 	if (!awi_intlock(sc))
    561  1.1  sommerfe 		return 0;
    562  1.1  sommerfe 
    563  1.1  sommerfe 	/* we have int lock.. */
    564  1.1  sommerfe 
    565  1.1  sommerfe 	state = awi_read_1 (sc, AWI_INTSTAT);
    566  1.1  sommerfe 	awi_write_1(sc, AWI_INTSTAT, 0);
    567  1.1  sommerfe 
    568  1.1  sommerfe 	awi_intunlock(sc);
    569  1.1  sommerfe 
    570  1.1  sommerfe 	return state;
    571  1.1  sommerfe }
    572  1.1  sommerfe 
    573  1.1  sommerfe 
    574  1.1  sommerfe void
    575  1.1  sommerfe awi_parse_tlv (u_int8_t *base, u_int8_t *end, u_int8_t **vals, u_int8_t *lens, size_t nattr)
    576  1.1  sommerfe {
    577  1.1  sommerfe 	u_int8_t tag, len;
    578  1.1  sommerfe 
    579  1.1  sommerfe 	int i;
    580  1.1  sommerfe 
    581  1.1  sommerfe 	for (i=0; i<nattr; i++) {
    582  1.1  sommerfe 		vals[i] = NULL;
    583  1.1  sommerfe 		lens[i] = 0;
    584  1.1  sommerfe 	}
    585  1.1  sommerfe 
    586  1.1  sommerfe 	while (base < end) {
    587  1.1  sommerfe 		tag = base[0];
    588  1.1  sommerfe 		len = base[1];
    589  1.1  sommerfe 
    590  1.1  sommerfe 		base += 2;
    591  1.1  sommerfe 
    592  1.1  sommerfe 		if (tag < nattr) {
    593  1.1  sommerfe 			lens[tag] = len;
    594  1.1  sommerfe 			vals[tag] = base;
    595  1.1  sommerfe 		}
    596  1.1  sommerfe 		base += len;
    597  1.1  sommerfe 	}
    598  1.1  sommerfe }
    599  1.1  sommerfe 
    600  1.1  sommerfe void
    601  1.1  sommerfe awi_send_frame (sc, m)
    602  1.1  sommerfe 	struct awi_softc *sc;
    603  1.1  sommerfe 	struct mbuf *m;
    604  1.1  sommerfe {
    605  1.1  sommerfe 	IF_ENQUEUE(&sc->sc_mgtq, m);
    606  1.1  sommerfe 
    607  1.1  sommerfe 	awi_start(sc->sc_ifp);
    608  1.1  sommerfe }
    609  1.1  sommerfe 
    610  1.1  sommerfe void *
    611  1.1  sommerfe awi_init_hdr (sc, m, f1, f2)
    612  1.1  sommerfe 	struct awi_softc *sc;
    613  1.1  sommerfe 	struct mbuf *m;
    614  1.1  sommerfe 	int f1;
    615  1.1  sommerfe 	int f2;
    616  1.1  sommerfe {
    617  1.1  sommerfe 	struct awi_mac_header *amhp;
    618  1.1  sommerfe 
    619  1.1  sommerfe 	/*
    620  1.1  sommerfe 	 * initialize 802.11 mac header in mbuf, return pointer to next byte..
    621  1.1  sommerfe 	 */
    622  1.1  sommerfe 
    623  1.1  sommerfe 	amhp = mtod(m, struct awi_mac_header *);
    624  1.1  sommerfe 
    625  1.1  sommerfe 	amhp->awi_fc = f1;
    626  1.1  sommerfe 	amhp->awi_f2 = f2;
    627  1.1  sommerfe 	amhp->awi_duration = 0;
    628  1.1  sommerfe 
    629  1.1  sommerfe 	memcpy(amhp->awi_addr1, sc->sc_active_bss.bss_id, ETHER_ADDR_LEN);
    630  1.1  sommerfe 	memcpy(amhp->awi_addr2, sc->sc_my_addr, ETHER_ADDR_LEN);
    631  1.1  sommerfe 	memcpy(amhp->awi_addr3, sc->sc_active_bss.bss_id, ETHER_ADDR_LEN);
    632  1.1  sommerfe 
    633  1.1  sommerfe 	amhp->awi_seqctl = 0;
    634  1.1  sommerfe 
    635  1.1  sommerfe 	return amhp+1;
    636  1.1  sommerfe }
    637  1.1  sommerfe 
    638  1.1  sommerfe 
    639  1.1  sommerfe 
    640  1.1  sommerfe u_int8_t *
    641  1.1  sommerfe awi_add_rates (sc, m, ptr)
    642  1.1  sommerfe 	struct awi_softc *sc;
    643  1.1  sommerfe 	struct mbuf *m;
    644  1.1  sommerfe 	u_int8_t *ptr;
    645  1.1  sommerfe {
    646  1.1  sommerfe 	*ptr++ = 1;		/* XXX */
    647  1.1  sommerfe 	*ptr++ = 1;		/* XXX */
    648  1.1  sommerfe 	*ptr++ = 0x82;		/* XXX */
    649  1.1  sommerfe 	return ptr;
    650  1.1  sommerfe }
    651  1.1  sommerfe 
    652  1.1  sommerfe u_int8_t *
    653  1.1  sommerfe awi_add_ssid (sc, m, ptr)
    654  1.1  sommerfe 	struct awi_softc *sc;
    655  1.1  sommerfe 	struct mbuf *m;
    656  1.1  sommerfe 	u_int8_t *ptr;
    657  1.1  sommerfe {
    658  1.1  sommerfe 	int len = sc->sc_active_bss.sslen;
    659  1.1  sommerfe 	*ptr++ = 0;		/* XXX */
    660  1.1  sommerfe 	*ptr++ = len;
    661  1.1  sommerfe 	memcpy(ptr, sc->sc_active_bss.ssid, len);
    662  1.1  sommerfe 	ptr += len;
    663  1.1  sommerfe 	return ptr;
    664  1.1  sommerfe }
    665  1.1  sommerfe 
    666  1.1  sommerfe 
    667  1.1  sommerfe 
    668  1.1  sommerfe void
    669  1.1  sommerfe awi_send_authreq (sc)
    670  1.1  sommerfe 	struct awi_softc *sc;
    671  1.1  sommerfe {
    672  1.1  sommerfe 	struct mbuf *m;
    673  1.1  sommerfe 	struct awi_auth_hdr *amahp;
    674  1.1  sommerfe 	u_int8_t *tlvptr;
    675  1.1  sommerfe 
    676  1.1  sommerfe 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    677  1.1  sommerfe 
    678  1.1  sommerfe 	/*
    679  1.1  sommerfe 	 * form an "association request" message.
    680  1.1  sommerfe 	 */
    681  1.1  sommerfe 
    682  1.1  sommerfe 	/*
    683  1.5  sommerfe 	 * auth alg number.  2 bytes.  = 0
    684  1.5  sommerfe 	 * auth txn seq number = 2 bytes = 1
    685  1.5  sommerfe 	 *  status code	       = 2 bytes = 0
    686  1.5  sommerfe 	 *  challenge text	(not present)
    687  1.5  sommerfe 	 */
    688  1.1  sommerfe 
    689  1.1  sommerfe 	if (m == 0)
    690  1.1  sommerfe 		return;		/* we'll try again later.. */
    691  1.1  sommerfe 
    692  1.1  sommerfe 	amahp = awi_init_hdr (sc, m,
    693  1.1  sommerfe 	    (IEEEWL_FC_VERS |
    694  1.1  sommerfe 	    (IEEEWL_FC_TYPE_MGT << IEEEWL_FC_TYPE_SHIFT) |
    695  1.1  sommerfe 	    (IEEEWL_SUBTYPE_AUTH << IEEEWL_FC_SUBTYPE_SHIFT)),
    696  1.1  sommerfe 	    0);
    697  1.1  sommerfe 
    698  1.1  sommerfe 	amahp->awi_algno[0] = 0;
    699  1.1  sommerfe 	amahp->awi_algno[1] = 0;
    700  1.1  sommerfe 	amahp->awi_seqno[0] = 1;
    701  1.1  sommerfe 	amahp->awi_seqno[1] = 0;
    702  1.1  sommerfe 	amahp->awi_status[0] = 0;
    703  1.1  sommerfe 	amahp->awi_status[1] = 0;
    704  1.1  sommerfe 
    705  1.1  sommerfe 	/*
    706  1.1  sommerfe 	 * form an "authentication" message.
    707  1.1  sommerfe 	 */
    708  1.1  sommerfe 
    709  1.1  sommerfe 	tlvptr = (u_int8_t *)(amahp+1);
    710  1.1  sommerfe 
    711  1.1  sommerfe 	tlvptr = awi_add_ssid(sc, m, tlvptr);
    712  1.1  sommerfe 	tlvptr = awi_add_rates(sc, m, tlvptr);
    713  1.1  sommerfe 
    714  1.1  sommerfe 	m->m_len = tlvptr - mtod(m, u_int8_t *);
    715  1.1  sommerfe 
    716  1.6  sommerfe 	if (sc->sc_ifp->if_flags & IFF_DEBUG) {
    717  1.6  sommerfe 		printf("%s: sending auth request\n",
    718  1.6  sommerfe 		    sc->sc_dev.dv_xname);
    719  1.6  sommerfe 		awi_hexdump("frame", m->m_data, m->m_len);
    720  1.6  sommerfe 	}
    721  1.6  sommerfe 
    722  1.1  sommerfe 	awi_send_frame(sc, m);
    723  1.1  sommerfe 
    724  1.1  sommerfe 	sc->sc_mgt_timer = 2;
    725  1.1  sommerfe 	awi_set_timer(sc);
    726  1.1  sommerfe }
    727  1.1  sommerfe 
    728  1.1  sommerfe void
    729  1.1  sommerfe awi_send_assocreq (sc)
    730  1.1  sommerfe 	struct awi_softc *sc;
    731  1.1  sommerfe {
    732  1.1  sommerfe 	struct mbuf *m;
    733  1.1  sommerfe 	struct awi_assoc_hdr *amahp;
    734  1.1  sommerfe 	u_int8_t *tlvptr;
    735  1.1  sommerfe 
    736  1.1  sommerfe 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    737  1.1  sommerfe 
    738  1.1  sommerfe 	/*
    739  1.1  sommerfe 	 * form an "association request" message.
    740  1.1  sommerfe 	 */
    741  1.1  sommerfe 
    742  1.1  sommerfe 	if (m == 0)
    743  1.1  sommerfe 		return;		/* we'll try again later.. */
    744  1.1  sommerfe 
    745  1.1  sommerfe 	/*
    746  1.1  sommerfe 	 * cap info (2 bytes)
    747  1.1  sommerfe 	 * listen interval	(2 bytes)
    748  1.1  sommerfe 	 * ssid			(variable)
    749  1.1  sommerfe 	 * supported rates	(variable)
    750  1.1  sommerfe 	 */
    751  1.1  sommerfe 
    752  1.1  sommerfe 	amahp = awi_init_hdr (sc, m,
    753  1.1  sommerfe 	    IEEEWL_FC_TYPE_MGT, IEEEWL_SUBTYPE_ASSOCREQ);
    754  1.1  sommerfe 
    755  1.1  sommerfe 	amahp->awi_cap_info[0] = 4; /* XXX magic (CF-pollable) */
    756  1.1  sommerfe 	amahp->awi_cap_info[1] = 0;
    757  1.1  sommerfe 	amahp->awi_li[0] = 1;
    758  1.1  sommerfe 	amahp->awi_li[1] = 0;
    759  1.1  sommerfe 
    760  1.1  sommerfe 	tlvptr = (u_int8_t *)(amahp+1);
    761  1.1  sommerfe 
    762  1.1  sommerfe 	tlvptr = awi_add_ssid(sc, m, tlvptr);
    763  1.1  sommerfe 	tlvptr = awi_add_rates(sc, m, tlvptr);
    764  1.1  sommerfe 
    765  1.1  sommerfe 	m->m_len = tlvptr - mtod(m, u_int8_t *);
    766  1.1  sommerfe 
    767  1.6  sommerfe 
    768  1.6  sommerfe 	if (sc->sc_ifp->if_flags & IFF_DEBUG) {
    769  1.6  sommerfe 		printf("%s: sending assoc request\n",
    770  1.6  sommerfe 		    sc->sc_dev.dv_xname);
    771  1.6  sommerfe 		awi_hexdump("frame", m->m_data, m->m_len);
    772  1.6  sommerfe 	}
    773  1.6  sommerfe 
    774  1.1  sommerfe 	awi_send_frame(sc, m);
    775  1.1  sommerfe 
    776  1.1  sommerfe 	sc->sc_mgt_timer = 2;
    777  1.1  sommerfe 	awi_set_timer(sc);
    778  1.1  sommerfe }
    779  1.1  sommerfe 
    780  1.1  sommerfe #if 0
    781  1.1  sommerfe void
    782  1.1  sommerfe awi_send_reassocreq (sc)
    783  1.1  sommerfe {
    784  1.1  sommerfe 
    785  1.1  sommerfe 	/*
    786  1.1  sommerfe 	 * form an "reassociation request" message.
    787  1.1  sommerfe 	 */
    788  1.1  sommerfe 
    789  1.1  sommerfe 	/* 2 bytes frame control
    790  1.1  sommerfe 	   00100000 00000000
    791  1.1  sommerfe 	   2 bytes goo
    792  1.1  sommerfe 	   00000000 00000000
    793  1.1  sommerfe 	   address 1: bssid
    794  1.1  sommerfe 	   address 2: my address
    795  1.1  sommerfe 	   address 3: bssid
    796  1.1  sommerfe 	   2 bytes seq/ctl
    797  1.1  sommerfe 	   00000000 00000000
    798  1.1  sommerfe 
    799  1.1  sommerfe 	   cap info (2 bytes)
    800  1.1  sommerfe 	   listen interval		(2 bytes)
    801  1.1  sommerfe 	   current ap address		(6 bytes)
    802  1.1  sommerfe 	   ssid				(variable)
    803  1.1  sommerfe 	   supported rates		(va
    804  1.1  sommerfe 	*/
    805  1.1  sommerfe }
    806  1.1  sommerfe 
    807  1.1  sommerfe #endif
    808  1.1  sommerfe 
    809  1.1  sommerfe void
    810  1.1  sommerfe awi_rcv_ctl (sc, m)
    811  1.1  sommerfe 	struct awi_softc *sc;
    812  1.1  sommerfe 	struct mbuf *m;
    813  1.1  sommerfe {
    814  1.1  sommerfe 	printf("%s: ctl\n", sc->sc_dev.dv_xname);
    815  1.1  sommerfe }
    816  1.1  sommerfe 
    817  1.1  sommerfe void
    818  1.1  sommerfe awi_rcv_data (sc, m)
    819  1.1  sommerfe 	struct awi_softc *sc;
    820  1.1  sommerfe 	struct mbuf *m;
    821  1.1  sommerfe {
    822  1.1  sommerfe 	struct ifnet *ifp = sc->sc_ifp;
    823  1.1  sommerfe 	u_int8_t *llc;
    824  1.1  sommerfe 	u_int8_t *to, *from;
    825  1.1  sommerfe 	struct awi_mac_header *amhp;
    826  1.1  sommerfe 
    827  1.5  sommerfe 	sc->sc_scan_timer = awi_scan_keepalive;	/* user data is as good
    828  1.1  sommerfe 				   as a beacon as a keepalive.. */
    829  1.1  sommerfe 
    830  1.1  sommerfe 	amhp = mtod(m, struct awi_mac_header *);
    831  1.1  sommerfe 
    832  1.1  sommerfe 	/*
    833  1.1  sommerfe 	 * we have: 4 bytes useless goo.
    834  1.1  sommerfe 	 *	    3 x 6 bytes MAC addresses.
    835  1.1  sommerfe 	 *	    2 bytes goo.
    836  1.1  sommerfe 	 *	    802.x LLC header, SNAP header, and data.
    837  1.1  sommerfe 	 *
    838  1.1  sommerfe 	 * for now, we fake up a "normal" ethernet header and feed
    839  1.1  sommerfe 	 * this to the appropriate input routine.
    840  1.1  sommerfe 	 */
    841  1.1  sommerfe 
    842  1.1  sommerfe 	llc = (u_int8_t *)(amhp+1);
    843  1.1  sommerfe 
    844  1.1  sommerfe 	if (amhp->awi_f2 & IEEEWL_FC2_TODS) {
    845  1.1  sommerfe 		printf("drop packet to DS\n");
    846  1.1  sommerfe 		goto drop;
    847  1.1  sommerfe 	}
    848  1.1  sommerfe 
    849  1.1  sommerfe 	to = amhp->awi_addr1;
    850  1.1  sommerfe 	if (amhp->awi_f2 & IEEEWL_FC2_FROMDS)
    851  1.1  sommerfe 		from = amhp->awi_addr3;
    852  1.1  sommerfe 	else
    853  1.1  sommerfe 		from = amhp->awi_addr2;
    854  1.1  sommerfe 	if (memcmp (llc, snap_magic, 6) != 0)
    855  1.1  sommerfe 		goto drop;
    856  1.1  sommerfe 
    857  1.1  sommerfe 	/* XXX overwrite llc with "from" address */
    858  1.1  sommerfe 	/* XXX overwrite llc-6 with "to" address */
    859  1.1  sommerfe 	memcpy(llc, from, ETHER_ADDR_LEN);
    860  1.1  sommerfe 	memcpy(llc-6, to, ETHER_ADDR_LEN);
    861  1.1  sommerfe 
    862  1.1  sommerfe 	m_adj(m, sizeof(struct awi_mac_header) + sizeof(struct awi_llc_header)
    863  1.1  sommerfe 	    - sizeof(struct ether_header));
    864  1.1  sommerfe 
    865  1.1  sommerfe #if NBPFILTER > 0
    866  1.1  sommerfe 	/*
    867  1.1  sommerfe 	 * Pass packet to bpf if there is a listener.
    868  1.1  sommerfe 	 */
    869  1.1  sommerfe 	if (ifp->if_bpf)
    870  1.1  sommerfe 		bpf_mtap(ifp->if_bpf, m);
    871  1.1  sommerfe #endif
    872  1.1  sommerfe 
    873  1.2  sommerfe #if __NetBSD_Version__ > 104010000
    874  1.2  sommerfe 	m->m_flags |= M_HASFCS;
    875  1.1  sommerfe 	(*ifp->if_input)(ifp, m);
    876  1.2  sommerfe #else
    877  1.2  sommerfe 	{
    878  1.2  sommerfe 		struct ether_header *eh;
    879  1.2  sommerfe 		eh = mtod(m, struct ether_header *);
    880  1.2  sommerfe 		m_adj(m, sizeof(*eh));
    881  1.2  sommerfe 		m_adj(m, -ETHER_CRC_LEN);
    882  1.2  sommerfe 		ether_input(ifp, eh, m);
    883  1.2  sommerfe 	}
    884  1.2  sommerfe #endif
    885  1.1  sommerfe 	return;
    886  1.1  sommerfe  drop:
    887  1.1  sommerfe 	m_freem(m);
    888  1.1  sommerfe }
    889  1.1  sommerfe 
    890  1.1  sommerfe void
    891  1.1  sommerfe awi_rcv_mgt (sc, m, rxts, rssi)
    892  1.1  sommerfe 	struct awi_softc *sc;
    893  1.1  sommerfe 	struct mbuf *m;
    894  1.1  sommerfe 	u_int32_t rxts;
    895  1.1  sommerfe 	u_int8_t rssi;
    896  1.1  sommerfe {
    897  1.1  sommerfe 	u_int8_t subtype;
    898  1.1  sommerfe 	u_int8_t *framehdr, *mgthdr, *end, *timestamp;
    899  1.1  sommerfe 	struct awi_auth_hdr *auhp;
    900  1.6  sommerfe 	struct ifnet *ifp = sc->sc_ifp;
    901  1.1  sommerfe 
    902  1.1  sommerfe #define IEEEWL_MGT_NATTR		10 /* XXX */
    903  1.1  sommerfe 	u_int8_t *attr[IEEEWL_MGT_NATTR];
    904  1.1  sommerfe 	u_int8_t attrlen[IEEEWL_MGT_NATTR];
    905  1.1  sommerfe 	u_int8_t *addr1, *addr2, *addr3;
    906  1.1  sommerfe 	u_int8_t *sa, *da, *bss;
    907  1.1  sommerfe 
    908  1.1  sommerfe 	framehdr = mtod(m, u_int8_t *);
    909  1.1  sommerfe 
    910  1.1  sommerfe 	/*
    911  1.1  sommerfe 	 * mgt frame:
    912  1.1  sommerfe 	 *  2 bytes frame goo
    913  1.1  sommerfe 	 *  2 bytes duration
    914  1.1  sommerfe 	 *  6 bytes a1
    915  1.1  sommerfe 	 *  6 bytes a2
    916  1.1  sommerfe 	 *  6 bytes a3
    917  1.1  sommerfe 	 *  2 bytes seq control.
    918  1.1  sommerfe 	 * --
    919  1.1  sommerfe 	 * 24 bytes goo.
    920  1.1  sommerfe 	 */
    921  1.1  sommerfe 
    922  1.1  sommerfe 	subtype = (framehdr[IEEEWL_FC] & IEEEWL_FC_SUBTYPE_MASK)
    923  1.1  sommerfe 	    >> IEEEWL_FC_SUBTYPE_SHIFT;
    924  1.1  sommerfe 
    925  1.1  sommerfe 	addr1 = framehdr + 4;	/* XXX */
    926  1.1  sommerfe 	addr2 = addr1+ETHER_ADDR_LEN;
    927  1.1  sommerfe 	addr3 = addr2+ETHER_ADDR_LEN;
    928  1.1  sommerfe 
    929  1.1  sommerfe 	/* XXX look at to/from DS bits here!! */
    930  1.1  sommerfe 	da = addr1;
    931  1.1  sommerfe 	sa = addr3;
    932  1.1  sommerfe 	bss = addr2;
    933  1.1  sommerfe 
    934  1.1  sommerfe 	framehdr = mtod(m, u_int8_t *);
    935  1.1  sommerfe 	end = framehdr + m->m_len;
    936  1.1  sommerfe 	end -= 4;	/* trim TLV */
    937  1.1  sommerfe 
    938  1.1  sommerfe 	mgthdr = framehdr + 24;	/* XXX magic */
    939  1.1  sommerfe 
    940  1.1  sommerfe 	switch (subtype) {
    941  1.1  sommerfe 
    942  1.1  sommerfe 	case IEEEWL_SUBTYPE_ASSOCRESP:
    943  1.1  sommerfe 		/*
    944  1.1  sommerfe 		 * this acknowledges that the AP will be forwarding traffic
    945  1.1  sommerfe 		 * for us..
    946  1.1  sommerfe 		 *
    947  1.1  sommerfe 		 * contains:
    948  1.1  sommerfe 		 *	cap info
    949  1.1  sommerfe 		 *	status code
    950  1.1  sommerfe 		 *	AId
    951  1.1  sommerfe 		 *	supported rates.
    952  1.1  sommerfe 		 */
    953  1.6  sommerfe 		if (ifp->if_flags & IFF_DEBUG) {
    954  1.6  sommerfe 			printf("%s: got assoc resp\n",
    955  1.6  sommerfe 			    sc->sc_dev.dv_xname);
    956  1.6  sommerfe 			awi_hexdump("assocresp", m->m_data, m->m_len);
    957  1.6  sommerfe 		}
    958  1.1  sommerfe 		awi_drvstate (sc, AWI_DRV_INFASSOC);
    959  1.1  sommerfe 		sc->sc_state = AWI_ST_RUNNING;
    960  1.1  sommerfe 		sc->sc_mgt_timer = AWI_ASSOC_REFRESH;
    961  1.1  sommerfe 		awi_set_timer(sc);
    962  1.1  sommerfe 		if (sc->sc_new_bss) {
    963  1.1  sommerfe 			printf("%s: associated with %s, SSID: %s\n",
    964  1.1  sommerfe 			    sc->sc_dev.dv_xname,
    965  1.1  sommerfe 			    ether_sprintf(sc->sc_active_bss.bss_id),
    966  1.1  sommerfe 			    sc->sc_active_bss.ssid);
    967  1.1  sommerfe 			sc->sc_new_bss = 0;
    968  1.1  sommerfe 		}
    969  1.1  sommerfe 
    970  1.1  sommerfe 		/* XXX set media status to "i see carrier" */
    971  1.1  sommerfe 		break;
    972  1.1  sommerfe 
    973  1.1  sommerfe 	case IEEEWL_SUBTYPE_REASSOCRESP:
    974  1.1  sommerfe 		/*
    975  1.1  sommerfe 		 * this indicates that we've moved from one AP to another
    976  1.1  sommerfe 		 * within the same DS.
    977  1.1  sommerfe 		 */
    978  1.1  sommerfe 		printf("reassoc_resp\n");
    979  1.1  sommerfe 
    980  1.1  sommerfe 		break;
    981  1.1  sommerfe 
    982  1.5  sommerfe 	case IEEEWL_SUBTYPE_PROBEREQ:
    983  1.5  sommerfe 		/* discard */
    984  1.5  sommerfe 		break;
    985  1.5  sommerfe 
    986  1.1  sommerfe 	case IEEEWL_SUBTYPE_PROBERESP:
    987  1.1  sommerfe 		/*
    988  1.1  sommerfe 		 * 8 bytes timestamp.
    989  1.1  sommerfe 		 * 2 bytes beacon intvl.
    990  1.1  sommerfe 		 * 2 bytes cap info.
    991  1.1  sommerfe 		 * then tlv data..
    992  1.1  sommerfe 		 */
    993  1.1  sommerfe 		timestamp = mgthdr;
    994  1.1  sommerfe 
    995  1.6  sommerfe 		if (ifp->if_flags & IFF_DEBUG) {
    996  1.6  sommerfe 			printf("%s: got probe resp\n",
    997  1.6  sommerfe 			    sc->sc_dev.dv_xname);
    998  1.6  sommerfe 			awi_hexdump("proberesp", m->m_data, m->m_len);
    999  1.6  sommerfe 		}
   1000  1.1  sommerfe 		/* now, into the tlv goo.. */
   1001  1.1  sommerfe 		mgthdr += 12;	/* XXX magic */
   1002  1.1  sommerfe 		awi_parse_tlv (mgthdr, end, attr, attrlen, IEEEWL_MGT_NATTR);
   1003  1.1  sommerfe 
   1004  1.1  sommerfe 		if (attr[IEEEWL_MGT_TLV_SSID] &&
   1005  1.1  sommerfe 		    attr[IEEEWL_MGT_TLV_FHPARMS] &&
   1006  1.1  sommerfe 		    attrlen[IEEEWL_MGT_TLV_SSID] < AWI_SSID_LEN) {
   1007  1.1  sommerfe 			struct awi_bss_binding *bp = NULL;
   1008  1.1  sommerfe 			int i;
   1009  1.1  sommerfe 
   1010  1.1  sommerfe 			for (i=0; i< sc->sc_nbindings; i++) {
   1011  1.1  sommerfe 				struct awi_bss_binding *bp1 =
   1012  1.1  sommerfe 				    &sc->sc_bindings[i];
   1013  1.1  sommerfe 				if (memcmp(bp1->bss_id, bss, ETHER_ADDR_LEN) == 0) {
   1014  1.1  sommerfe 					bp = bp1;
   1015  1.1  sommerfe 					break;
   1016  1.1  sommerfe 				}
   1017  1.1  sommerfe 			}
   1018  1.1  sommerfe 
   1019  1.1  sommerfe 			if (bp == NULL && sc->sc_nbindings < NBND) {
   1020  1.1  sommerfe 				bp = &sc->sc_bindings[sc->sc_nbindings++];
   1021  1.1  sommerfe 			}
   1022  1.1  sommerfe 			if (bp != NULL) {
   1023  1.1  sommerfe 				u_int8_t *fhparms =
   1024  1.1  sommerfe 				    attr[IEEEWL_MGT_TLV_FHPARMS];
   1025  1.1  sommerfe 
   1026  1.1  sommerfe 				bp->sslen = attrlen[IEEEWL_MGT_TLV_SSID];
   1027  1.1  sommerfe 
   1028  1.1  sommerfe 				memcpy(bp->ssid, attr[IEEEWL_MGT_TLV_SSID],
   1029  1.1  sommerfe 				    bp->sslen);
   1030  1.1  sommerfe 				bp->ssid[bp->sslen] = 0;
   1031  1.1  sommerfe 
   1032  1.1  sommerfe 				memcpy(bp->bss_id, bss, ETHER_ADDR_LEN);
   1033  1.1  sommerfe 
   1034  1.1  sommerfe 				/* XXX more magic numbers.. */
   1035  1.1  sommerfe 				bp->dwell_time = fhparms[0] | (fhparms[1]<<8);
   1036  1.1  sommerfe 				bp->chanset = fhparms[2];
   1037  1.1  sommerfe 				bp->pattern = fhparms[3];
   1038  1.1  sommerfe 				bp->index = fhparms[4];
   1039  1.1  sommerfe 				bp->rssi = rssi;
   1040  1.1  sommerfe 				bp->rxtime = rxts;
   1041  1.1  sommerfe 				memcpy(bp->bss_timestamp, timestamp, 8);
   1042  1.1  sommerfe 			}
   1043  1.1  sommerfe 		}
   1044  1.1  sommerfe 
   1045  1.1  sommerfe 		break;
   1046  1.1  sommerfe 
   1047  1.1  sommerfe 	case IEEEWL_SUBTYPE_BEACON:
   1048  1.6  sommerfe 		if ((ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) ==
   1049  1.6  sommerfe 		    (IFF_DEBUG|IFF_LINK2)) {
   1050  1.6  sommerfe 			printf("%s: beacon from %s\n",
   1051  1.6  sommerfe 			    sc->sc_dev.dv_xname,
   1052  1.6  sommerfe 			    ether_sprintf(addr2));
   1053  1.6  sommerfe 			awi_hexdump("beacon", m->m_data, m->m_len);
   1054  1.6  sommerfe 		}
   1055  1.1  sommerfe 		/*
   1056  1.1  sommerfe 		 * Note that AP is still alive so we don't have to go looking
   1057  1.1  sommerfe 		 * for one for a while.
   1058  1.1  sommerfe 		 *
   1059  1.1  sommerfe 		 * XXX Beacons from other AP's should be recorded for
   1060  1.1  sommerfe 		 * potential use if we lose this AP..  (also, may want
   1061  1.1  sommerfe 		 * to notice if rssi of new AP is significantly
   1062  1.1  sommerfe 		 * stronger than old one and jump ship..)
   1063  1.1  sommerfe 		 */
   1064  1.1  sommerfe 		if ((sc->sc_state >= AWI_ST_SYNCED) &&
   1065  1.1  sommerfe 		    (memcmp (addr2, sc->sc_active_bss.bss_id,
   1066  1.1  sommerfe 			ETHER_ADDR_LEN) == 0)) {
   1067  1.5  sommerfe 			sc->sc_scan_timer = awi_scan_keepalive;
   1068  1.1  sommerfe 			awi_set_timer(sc);
   1069  1.1  sommerfe 		}
   1070  1.1  sommerfe 
   1071  1.1  sommerfe 		break;
   1072  1.1  sommerfe 
   1073  1.1  sommerfe 	case IEEEWL_SUBTYPE_DISSOC:
   1074  1.1  sommerfe 		printf("dissoc\n");
   1075  1.1  sommerfe 
   1076  1.1  sommerfe 		break;
   1077  1.1  sommerfe 
   1078  1.1  sommerfe 	case IEEEWL_SUBTYPE_AUTH:
   1079  1.6  sommerfe 		if (ifp->if_flags & IFF_DEBUG) {
   1080  1.6  sommerfe 			printf("%s: got auth\n",
   1081  1.6  sommerfe 			    sc->sc_dev.dv_xname);
   1082  1.6  sommerfe 			awi_hexdump("auth", m->m_data, m->m_len);
   1083  1.6  sommerfe 		}
   1084  1.1  sommerfe 		/*
   1085  1.1  sommerfe 		 * woohoo!  somebody likes us!
   1086  1.1  sommerfe 		 */
   1087  1.1  sommerfe 
   1088  1.1  sommerfe 		auhp = (struct awi_auth_hdr *)mgthdr;
   1089  1.1  sommerfe 
   1090  1.1  sommerfe 		if ((auhp->awi_status[0] == 0) && (auhp->awi_status[1] == 0))
   1091  1.1  sommerfe 		{
   1092  1.1  sommerfe 			awi_drvstate (sc, AWI_DRV_INFAUTH);
   1093  1.1  sommerfe 			sc->sc_state = AWI_ST_AUTHED;
   1094  1.1  sommerfe 			awi_send_assocreq (sc);
   1095  1.1  sommerfe 		}
   1096  1.1  sommerfe 		break;
   1097  1.1  sommerfe 
   1098  1.1  sommerfe 	case IEEEWL_SUBTYPE_DEAUTH:
   1099  1.6  sommerfe 		if (ifp->if_flags & IFF_DEBUG) {
   1100  1.6  sommerfe 			printf("%s: got deauth\n",
   1101  1.6  sommerfe 			    sc->sc_dev.dv_xname);
   1102  1.6  sommerfe 			awi_hexdump("deauth", m->m_data, m->m_len);
   1103  1.6  sommerfe 		}
   1104  1.1  sommerfe 		sc->sc_state = AWI_ST_SYNCED;
   1105  1.1  sommerfe 		sc->sc_new_bss = 1;
   1106  1.1  sommerfe 		awi_send_authreq(sc);
   1107  1.1  sommerfe 		break;
   1108  1.1  sommerfe 	default:
   1109  1.1  sommerfe 		printf("unk mgt subtype %x\n", subtype);
   1110  1.1  sommerfe 		break;
   1111  1.1  sommerfe 	}
   1112  1.1  sommerfe 	m_freem(m);		/* done.. */
   1113  1.1  sommerfe }
   1114  1.1  sommerfe 
   1115  1.1  sommerfe 
   1116  1.1  sommerfe 
   1117  1.1  sommerfe 
   1118  1.1  sommerfe 
   1119  1.1  sommerfe /*
   1120  1.1  sommerfe  * Do 802.11 receive processing.  "m" contains a receive frame;
   1121  1.1  sommerfe  * rxts is the local receive timestamp
   1122  1.1  sommerfe  */
   1123  1.1  sommerfe 
   1124  1.1  sommerfe void
   1125  1.1  sommerfe awi_rcv (sc, m, rxts, rssi)
   1126  1.1  sommerfe 	struct awi_softc *sc;
   1127  1.1  sommerfe 	struct mbuf *m;
   1128  1.1  sommerfe 	u_int32_t rxts;
   1129  1.1  sommerfe 	u_int8_t rssi;
   1130  1.1  sommerfe {
   1131  1.1  sommerfe 	u_int8_t *framehdr;
   1132  1.1  sommerfe 	u_int8_t framectl;
   1133  1.1  sommerfe 
   1134  1.1  sommerfe 	framehdr = mtod(m, u_int8_t *);
   1135  1.1  sommerfe 
   1136  1.1  sommerfe 	/*
   1137  1.1  sommerfe 	 * peek at first byte of frame header.
   1138  1.1  sommerfe 	 *  check version subfield (must be zero)
   1139  1.1  sommerfe 	 *  check type subfield (00 = mgt, 01 = ctl, 10 = data)
   1140  1.1  sommerfe 	 *  check subtype field (next four bits)
   1141  1.1  sommerfe 	 */
   1142  1.1  sommerfe 
   1143  1.1  sommerfe 	/*
   1144  1.1  sommerfe 	 * Not counting WDS mode, the IEEE 802.11 frame header format
   1145  1.1  sommerfe 	 * has *three* MAC addresses.
   1146  1.1  sommerfe 	 * (source, destination, and BSS).
   1147  1.1  sommerfe 	 *
   1148  1.1  sommerfe 	 * The BSS indicates which wireless "cable segment" we're part of;
   1149  1.1  sommerfe 	 * we discover this dynamically..
   1150  1.1  sommerfe 	 *
   1151  1.1  sommerfe 	 * Not content to put them in a fixed order, the exact
   1152  1.1  sommerfe 	 * ordering of these addresses depends on other attribute bits
   1153  1.1  sommerfe 	 * in the frame control word!
   1154  1.1  sommerfe 	 *
   1155  1.1  sommerfe 	 * an alternate presentation which is more self-consistent:
   1156  1.1  sommerfe 	 * address 1 is the "wireless destination" -- either the
   1157  1.1  sommerfe 	 * station address,
   1158  1.1  sommerfe 	 * for wireless->wireless traffic, or the BSS id of an AP.
   1159  1.1  sommerfe 	 *
   1160  1.1  sommerfe 	 * address 2 is the "wireless source" -- either the
   1161  1.1  sommerfe 	 * station address of a wireless node, or the BSS id of an AP.
   1162  1.1  sommerfe 	 *
   1163  1.1  sommerfe 	 * address 3 is the "other address" -- for STA->AP, the
   1164  1.1  sommerfe 	 * eventual destination; for AP->STA, the original source, and
   1165  1.1  sommerfe 	 * for ad-hoc mode, the BSS id..
   1166  1.1  sommerfe 	 */
   1167  1.1  sommerfe 
   1168  1.1  sommerfe 	framectl = framehdr[IEEEWL_FC];
   1169  1.1  sommerfe 
   1170  1.1  sommerfe 	if ((framectl & IEEEWL_FC_VERS_MASK) != IEEEWL_FC_VERS) {
   1171  1.1  sommerfe 		printf("wrong vers.  drop");
   1172  1.1  sommerfe 		goto drop;
   1173  1.1  sommerfe 	}
   1174  1.1  sommerfe 
   1175  1.1  sommerfe 	switch (framectl & IEEEWL_FC_TYPE_MASK) {
   1176  1.1  sommerfe 	case IEEEWL_FC_TYPE_MGT << IEEEWL_FC_TYPE_SHIFT:
   1177  1.1  sommerfe 		awi_rcv_mgt (sc, m, rxts, rssi);
   1178  1.1  sommerfe 		m = 0;
   1179  1.1  sommerfe 		break;
   1180  1.1  sommerfe 
   1181  1.1  sommerfe 	case IEEEWL_FC_TYPE_DATA << IEEEWL_FC_TYPE_SHIFT:
   1182  1.1  sommerfe 		awi_rcv_data (sc, m);
   1183  1.1  sommerfe 		m = 0;
   1184  1.1  sommerfe 		break;
   1185  1.1  sommerfe 
   1186  1.1  sommerfe 	case IEEEWL_FC_TYPE_CTL << IEEEWL_FC_TYPE_SHIFT:
   1187  1.1  sommerfe 		awi_rcv_ctl (sc, m);
   1188  1.1  sommerfe 	default:
   1189  1.1  sommerfe 		goto drop;
   1190  1.1  sommerfe 	}
   1191  1.1  sommerfe 
   1192  1.1  sommerfe  drop:
   1193  1.1  sommerfe 	if (m) m_freem(m);
   1194  1.1  sommerfe }
   1195  1.1  sommerfe 
   1196  1.1  sommerfe 
   1197  1.1  sommerfe void
   1198  1.1  sommerfe awi_dump_rxchain (sc, what, descr)
   1199  1.1  sommerfe 	struct awi_softc *sc;
   1200  1.1  sommerfe 	char *what;
   1201  1.1  sommerfe 	u_int32_t *descr;
   1202  1.1  sommerfe {
   1203  1.1  sommerfe 	u_int32_t next, cur;
   1204  1.1  sommerfe 	int i;
   1205  1.1  sommerfe 	struct ifnet *ifp = sc->sc_ifp;
   1206  1.1  sommerfe 	u_int8_t *mptr;
   1207  1.1  sommerfe 	int mleft;
   1208  1.1  sommerfe 
   1209  1.1  sommerfe 	struct mbuf *top = NULL, *m = NULL, *m1 = NULL;
   1210  1.1  sommerfe 	cur = *descr;
   1211  1.1  sommerfe 
   1212  1.1  sommerfe 
   1213  1.1  sommerfe 	if (cur & AWI_RXD_NEXT_LAST)
   1214  1.1  sommerfe 		return;
   1215  1.1  sommerfe 
   1216  1.1  sommerfe 	for (i=0;i<1000;i++) {
   1217  1.1  sommerfe 		u_int16_t len;
   1218  1.1  sommerfe 		u_int8_t state, rate, rssi, index;
   1219  1.1  sommerfe 		u_int32_t frame;
   1220  1.1  sommerfe 		u_int32_t rxts;
   1221  1.1  sommerfe 
   1222  1.1  sommerfe 		top = 0;
   1223  1.1  sommerfe 
   1224  1.1  sommerfe 		next = awi_read_4(sc, cur + AWI_RXD_NEXT);
   1225  1.1  sommerfe 
   1226  1.1  sommerfe 		if (next & AWI_RXD_NEXT_LAST)
   1227  1.1  sommerfe 			break;
   1228  1.1  sommerfe 
   1229  1.1  sommerfe 		state = awi_read_1(sc, cur + AWI_RXD_HOST_DESC_STATE);
   1230  1.1  sommerfe 		len = awi_read_2 (sc, cur + AWI_RXD_LEN);
   1231  1.1  sommerfe 		rate = awi_read_1 (sc, cur + AWI_RXD_RATE);
   1232  1.1  sommerfe 		rssi = awi_read_1 (sc, cur + AWI_RXD_RSSI);
   1233  1.1  sommerfe 		index = awi_read_1 (sc, cur + AWI_RXD_INDEX);
   1234  1.1  sommerfe 		frame = awi_read_4 (sc, cur + AWI_RXD_START_FRAME);
   1235  1.1  sommerfe 		rxts = awi_read_4 (sc, cur + AWI_RXD_LOCALTIME);
   1236  1.1  sommerfe 
   1237  1.1  sommerfe 		/*
   1238  1.1  sommerfe 		 * only the low order bits of "frame" and "next" are valid.
   1239  1.1  sommerfe 		 * (the documentation doesn't mention this).
   1240  1.1  sommerfe 		 */
   1241  1.1  sommerfe 		frame &= 0xffff;
   1242  1.1  sommerfe 		next &= 0xffff;
   1243  1.1  sommerfe 
   1244  1.1  sommerfe 		if (state & AWI_RXD_ST_CONSUMED) {
   1245  1.1  sommerfe 			state |= AWI_RXD_ST_CONSUMED | AWI_RXD_ST_OWN;
   1246  1.1  sommerfe 			awi_write_1(sc, cur + AWI_RXD_HOST_DESC_STATE, state);
   1247  1.1  sommerfe 		} else {
   1248  1.1  sommerfe 			MGETHDR(top, M_DONTWAIT, MT_DATA);
   1249  1.1  sommerfe 			if (top != 0) {
   1250  1.4  sommerfe 				if (len >= MINCLSIZE)
   1251  1.4  sommerfe 					MCLGET(top, M_DONTWAIT);
   1252  1.4  sommerfe 
   1253  1.1  sommerfe 				m = top;
   1254  1.1  sommerfe 				m->m_pkthdr.rcvif = ifp;
   1255  1.1  sommerfe 				m->m_pkthdr.len = 0;
   1256  1.1  sommerfe 				m->m_len = 0;
   1257  1.1  sommerfe 
   1258  1.4  sommerfe 				mleft = (m->m_flags & M_EXT) ?
   1259  1.4  sommerfe 				    MCLBYTES : MHLEN;
   1260  1.1  sommerfe 				mptr = mtod(m, u_int8_t *);
   1261  1.1  sommerfe 			}
   1262  1.1  sommerfe 			for(;;) {
   1263  1.1  sommerfe 				if (top != 0) {
   1264  1.1  sommerfe 					/* copy data into mbuf */
   1265  1.1  sommerfe 					while (len > 0) {
   1266  1.1  sommerfe 						int nmove = min (len, mleft);
   1267  1.1  sommerfe 
   1268  1.1  sommerfe 						awi_read_bytes (sc, frame, mptr, nmove);
   1269  1.1  sommerfe 						len -= nmove;
   1270  1.1  sommerfe 						mleft -= nmove;
   1271  1.1  sommerfe 						mptr += nmove;
   1272  1.1  sommerfe 						frame += nmove;
   1273  1.1  sommerfe 
   1274  1.1  sommerfe 						top->m_pkthdr.len += nmove;
   1275  1.1  sommerfe 						m->m_len += nmove;
   1276  1.1  sommerfe 
   1277  1.1  sommerfe 						if (mleft == 0) {
   1278  1.1  sommerfe 							/* Get next mbuf.. */
   1279  1.1  sommerfe 							MGET(m1, M_DONTWAIT, MT_DATA);
   1280  1.1  sommerfe 							if (m1 == NULL) {
   1281  1.5  sommerfe 								m_freem(top);
   1282  1.5  sommerfe 								top = NULL;
   1283  1.1  sommerfe 							}
   1284  1.1  sommerfe 							m->m_next = m1;
   1285  1.1  sommerfe 							m = m1;
   1286  1.1  sommerfe 							m->m_len = 0;
   1287  1.1  sommerfe 
   1288  1.1  sommerfe 							mleft = MLEN;
   1289  1.1  sommerfe 							mptr = mtod(m, u_int8_t *);
   1290  1.1  sommerfe 						}
   1291  1.1  sommerfe 					}
   1292  1.1  sommerfe 				}
   1293  1.1  sommerfe 				state |= AWI_RXD_ST_CONSUMED | AWI_RXD_ST_OWN;
   1294  1.1  sommerfe 				awi_write_1(sc, cur + AWI_RXD_HOST_DESC_STATE, state);
   1295  1.1  sommerfe 
   1296  1.1  sommerfe 				if (state & AWI_RXD_ST_LF)
   1297  1.1  sommerfe 					break;
   1298  1.1  sommerfe 
   1299  1.1  sommerfe 				if (next & AWI_RXD_NEXT_LAST)
   1300  1.1  sommerfe 					panic("awi oops"); /* XXX */
   1301  1.1  sommerfe 
   1302  1.1  sommerfe 				/* XXX deal with dummy frames here?? */
   1303  1.1  sommerfe 
   1304  1.1  sommerfe 				cur = next;
   1305  1.1  sommerfe 				state = awi_read_1(sc, cur + AWI_RXD_HOST_DESC_STATE);
   1306  1.1  sommerfe 				len = awi_read_2 (sc, cur + AWI_RXD_LEN);
   1307  1.1  sommerfe 				rate = awi_read_1 (sc, cur + AWI_RXD_RATE);
   1308  1.1  sommerfe 				rssi = awi_read_1 (sc, cur + AWI_RXD_RSSI);
   1309  1.1  sommerfe 				index = awi_read_1 (sc, cur + AWI_RXD_INDEX);
   1310  1.1  sommerfe 				frame = awi_read_4 (sc, cur + AWI_RXD_START_FRAME);
   1311  1.1  sommerfe 				frame &= 0xffff;
   1312  1.1  sommerfe 				next &= 0xffff;
   1313  1.1  sommerfe 			}
   1314  1.1  sommerfe 		}
   1315  1.1  sommerfe 		if (top) {
   1316  1.1  sommerfe 			awi_rcv(sc, top, rxts, rssi);
   1317  1.1  sommerfe 			top = 0;
   1318  1.1  sommerfe 		}
   1319  1.1  sommerfe 		cur = next;
   1320  1.1  sommerfe 	}
   1321  1.1  sommerfe 	*descr = cur;
   1322  1.1  sommerfe }
   1323  1.1  sommerfe 
   1324  1.1  sommerfe 
   1325  1.1  sommerfe 
   1326  1.1  sommerfe 
   1327  1.1  sommerfe void
   1328  1.1  sommerfe awi_rxint (sc)
   1329  1.1  sommerfe 	struct awi_softc *sc;
   1330  1.1  sommerfe {
   1331  1.1  sommerfe 	awi_dump_rxchain (sc, "mgt", &sc->sc_rx_mgt_desc);
   1332  1.1  sommerfe 	awi_dump_rxchain (sc, "data", &sc->sc_rx_data_desc);
   1333  1.1  sommerfe }
   1334  1.1  sommerfe 
   1335  1.1  sommerfe void
   1336  1.1  sommerfe awi_init_txd (sc, tx, flag, len, rate)
   1337  1.1  sommerfe 	struct awi_softc *sc;
   1338  1.1  sommerfe 	int tx;
   1339  1.1  sommerfe 	int flag;
   1340  1.1  sommerfe 	int len;
   1341  1.1  sommerfe 	int rate;
   1342  1.1  sommerfe {
   1343  1.1  sommerfe 	u_int32_t txdbase = sc->sc_txd[tx].descr;
   1344  1.1  sommerfe 	u_int32_t framebase = sc->sc_txd[tx].frame;
   1345  1.1  sommerfe 	u_int32_t nextbase = sc->sc_txd[(tx+1)%sc->sc_ntxd].descr;
   1346  1.1  sommerfe 
   1347  1.1  sommerfe 	awi_write_4 (sc, txdbase + AWI_TXD_START, framebase);
   1348  1.1  sommerfe 	awi_write_4 (sc, txdbase + AWI_TXD_NEXT, nextbase);
   1349  1.1  sommerfe 	awi_write_4 (sc, txdbase + AWI_TXD_LENGTH, len);
   1350  1.1  sommerfe 	awi_write_1 (sc, txdbase + AWI_TXD_RATE, rate);
   1351  1.1  sommerfe 	/* zeroize tail end of txd */
   1352  1.1  sommerfe 	awi_write_4 (sc, txdbase + AWI_TXD_NDA, 0);
   1353  1.1  sommerfe 	awi_write_4 (sc, txdbase + AWI_TXD_NRA, 0);
   1354  1.1  sommerfe 	/* Init state last; firmware keys off of this to know when to start tx */
   1355  1.1  sommerfe 	awi_write_1 (sc, txdbase + AWI_TXD_STATE, flag);
   1356  1.1  sommerfe }
   1357  1.1  sommerfe 
   1358  1.1  sommerfe void
   1359  1.1  sommerfe awi_init_txdescr (sc)
   1360  1.1  sommerfe 	struct awi_softc *sc;
   1361  1.1  sommerfe {
   1362  1.1  sommerfe 	int i;
   1363  1.1  sommerfe 	u_int32_t offset = sc->sc_txbase;
   1364  1.1  sommerfe 
   1365  1.1  sommerfe 	sc->sc_txfirst = 0;
   1366  1.1  sommerfe 	sc->sc_txnext = 0;
   1367  1.1  sommerfe 
   1368  1.1  sommerfe 	sc->sc_ntxd = sc->sc_txlen / (AWI_FRAME_SIZE + AWI_TXD_SIZE);
   1369  1.1  sommerfe 	if (sc->sc_ntxd > NTXD) {
   1370  1.1  sommerfe 		sc->sc_ntxd = NTXD;
   1371  1.1  sommerfe 		printf("oops, no, only %d\n", sc->sc_ntxd);
   1372  1.1  sommerfe 	}
   1373  1.1  sommerfe 
   1374  1.1  sommerfe 	/* Allocate TXD's */
   1375  1.1  sommerfe 	for (i=0; i<sc->sc_ntxd; i++) {
   1376  1.1  sommerfe 		sc->sc_txd[i].descr = offset;
   1377  1.1  sommerfe 		offset += AWI_TXD_SIZE;
   1378  1.1  sommerfe 	}
   1379  1.1  sommerfe 	/* now, allocate buffer space to each txd.. */
   1380  1.1  sommerfe 	for (i=0; i<sc->sc_ntxd; i++) {
   1381  1.1  sommerfe 		sc->sc_txd[i].frame = offset;
   1382  1.1  sommerfe 		sc->sc_txd[i].len = AWI_FRAME_SIZE;
   1383  1.1  sommerfe 		offset += AWI_FRAME_SIZE;
   1384  1.1  sommerfe 
   1385  1.1  sommerfe 	}
   1386  1.1  sommerfe 
   1387  1.1  sommerfe 	/* now, initialize the TX descriptors into a circular linked list. */
   1388  1.1  sommerfe 
   1389  1.1  sommerfe 	for (i= 0; i<sc->sc_ntxd; i++) {
   1390  1.1  sommerfe 		awi_init_txd(sc, i, 0, 0, 0);
   1391  1.1  sommerfe 	}
   1392  1.1  sommerfe }
   1393  1.1  sommerfe 
   1394  1.1  sommerfe void
   1395  1.1  sommerfe awi_txint (sc)
   1396  1.1  sommerfe 	struct awi_softc *sc;
   1397  1.1  sommerfe {
   1398  1.1  sommerfe 	struct ifnet *ifp = sc->sc_ifp;
   1399  1.1  sommerfe 	int txfirst;
   1400  1.1  sommerfe 
   1401  1.1  sommerfe 	sc->sc_tx_timer = 0;
   1402  1.1  sommerfe 
   1403  1.1  sommerfe 	txfirst = sc->sc_txfirst;
   1404  1.1  sommerfe 	while (sc->sc_txpending > 0) {
   1405  1.1  sommerfe 		u_int8_t flags = awi_read_1 (sc, sc->sc_txd[txfirst].descr +
   1406  1.1  sommerfe 		    AWI_TXD_STATE);
   1407  1.1  sommerfe 
   1408  1.1  sommerfe 		if (flags & AWI_TXD_ST_OWN)
   1409  1.1  sommerfe 			break;
   1410  1.1  sommerfe 
   1411  1.1  sommerfe 		if (flags & AWI_TXD_ST_ERROR) {
   1412  1.1  sommerfe 			/* increment oerrs */;
   1413  1.1  sommerfe 		}
   1414  1.1  sommerfe 
   1415  1.1  sommerfe 		txfirst = (txfirst + 1) % sc->sc_ntxd;
   1416  1.1  sommerfe 		sc->sc_txpending--;
   1417  1.1  sommerfe 	}
   1418  1.1  sommerfe 
   1419  1.1  sommerfe 	sc->sc_txfirst = txfirst;
   1420  1.1  sommerfe 
   1421  1.1  sommerfe 	if (sc->sc_txpending < sc->sc_ntxd)
   1422  1.1  sommerfe 		ifp->if_flags &= ~IFF_OACTIVE;
   1423  1.1  sommerfe 
   1424  1.1  sommerfe 	/*
   1425  1.1  sommerfe 	 * see which descriptors are done..
   1426  1.1  sommerfe 	 */
   1427  1.1  sommerfe 
   1428  1.1  sommerfe 	awi_start(sc->sc_ifp);
   1429  1.1  sommerfe }
   1430  1.1  sommerfe 
   1431  1.1  sommerfe 
   1432  1.1  sommerfe 
   1433  1.1  sommerfe 
   1434  1.1  sommerfe /*
   1435  1.1  sommerfe  * device interrupt routine.
   1436  1.1  sommerfe  *
   1437  1.1  sommerfe  *	lock out MAC
   1438  1.1  sommerfe  *	loop:
   1439  1.1  sommerfe  *		look at intr status, DTRT.
   1440  1.1  sommerfe  *
   1441  1.1  sommerfe  *		on tx done, reclaim free buffers from tx, call start.
   1442  1.1  sommerfe  *		on rx done, look at rx queue, copy to mbufs, mark as free,
   1443  1.1  sommerfe  *			hand to ether media layer rx routine.
   1444  1.1  sommerfe  *		on cmd done, call cmd cmpl continuation.
   1445  1.1  sommerfe  *
   1446  1.1  sommerfe  */
   1447  1.1  sommerfe 
   1448  1.1  sommerfe int
   1449  1.1  sommerfe awi_intr(arg)
   1450  1.1  sommerfe 	void *arg;
   1451  1.1  sommerfe {
   1452  1.1  sommerfe 	struct awi_softc *sc = arg;
   1453  1.1  sommerfe 	int handled = 0;
   1454  1.1  sommerfe 
   1455  1.1  sommerfe 	if (sc->sc_state == AWI_ST_OFF) {
   1456  1.1  sommerfe 		u_int8_t intstate = awi_read_intst (sc);
   1457  1.1  sommerfe 		return intstate != 0;
   1458  1.1  sommerfe 	}
   1459  1.1  sommerfe 
   1460  1.1  sommerfe 	/* disable power down, (and implicitly ack interrupt) */
   1461  1.1  sommerfe 	am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_DISPWDN);
   1462  1.1  sommerfe 	awi_write_1(sc, AWI_DIS_PWRDN, 1);
   1463  1.1  sommerfe 
   1464  1.1  sommerfe 	for (;;) {
   1465  1.1  sommerfe 		u_int8_t intstate = awi_read_intst (sc);
   1466  1.1  sommerfe 
   1467  1.1  sommerfe 		if (!intstate)
   1468  1.1  sommerfe 			break;
   1469  1.1  sommerfe 
   1470  1.1  sommerfe 		handled = 1;
   1471  1.1  sommerfe 
   1472  1.1  sommerfe 		if (intstate & AWI_INT_RX)
   1473  1.1  sommerfe 			awi_rxint(sc);
   1474  1.1  sommerfe 
   1475  1.1  sommerfe 		if (intstate & AWI_INT_TX)
   1476  1.1  sommerfe 			awi_txint(sc);
   1477  1.1  sommerfe 
   1478  1.1  sommerfe 		if (intstate & AWI_INT_CMD) {
   1479  1.1  sommerfe 			u_int8_t status;
   1480  1.1  sommerfe 
   1481  1.1  sommerfe 			if (!(sc->sc_flags & AWI_FL_CMD_INPROG))
   1482  1.1  sommerfe 				printf("%s: no command in progress?\n",
   1483  1.1  sommerfe 				    sc->sc_dev.dv_xname);
   1484  1.1  sommerfe 			status = awi_read_1(sc, AWI_CMD_STATUS);
   1485  1.1  sommerfe 			awi_write_1 (sc, AWI_CMD, 0);
   1486  1.1  sommerfe 			sc->sc_cmd_timer = 0;
   1487  1.1  sommerfe 			sc->sc_flags &= ~AWI_FL_CMD_INPROG;
   1488  1.1  sommerfe 
   1489  1.1  sommerfe 			if (sc->sc_completion)
   1490  1.1  sommerfe 				(*sc->sc_completion)(sc, status);
   1491  1.1  sommerfe 		}
   1492  1.1  sommerfe 		if (intstate & AWI_INT_SCAN_CMPLT) {
   1493  1.1  sommerfe 			if (sc->sc_flags & AWI_FL_CMD_INPROG) {
   1494  1.1  sommerfe 				panic("i can't take it any more");
   1495  1.1  sommerfe 			}
   1496  1.1  sommerfe 			/*
   1497  1.1  sommerfe 			 * scan completion heuristic..
   1498  1.1  sommerfe 			 */
   1499  1.1  sommerfe 			if ((sc->sc_nbindings >= NBND)
   1500  1.1  sommerfe 			    || ((sc->sc_scan_timer == 0) &&
   1501  1.1  sommerfe 				(sc->sc_nbindings > 0)))
   1502  1.1  sommerfe 				awi_try_sync(sc);
   1503  1.1  sommerfe 			else
   1504  1.1  sommerfe 				awi_scan_next(sc);
   1505  1.1  sommerfe 		}
   1506  1.1  sommerfe 
   1507  1.1  sommerfe 	}
   1508  1.1  sommerfe 	/* reenable power down */
   1509  1.1  sommerfe 	am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_DISPWDN);
   1510  1.1  sommerfe 	awi_write_1(sc, AWI_DIS_PWRDN, 0);
   1511  1.1  sommerfe 
   1512  1.1  sommerfe 	return handled;
   1513  1.1  sommerfe }
   1514  1.1  sommerfe 
   1515  1.1  sommerfe /*
   1516  1.1  sommerfe  * device stop routine
   1517  1.1  sommerfe  */
   1518  1.1  sommerfe 
   1519  1.1  sommerfe void
   1520  1.1  sommerfe awi_stop(sc)
   1521  1.1  sommerfe 	struct awi_softc *sc;
   1522  1.1  sommerfe {
   1523  1.1  sommerfe 	struct ifnet *ifp = sc->sc_ifp;
   1524  1.1  sommerfe 
   1525  1.1  sommerfe 	/* Turn off timer.. */
   1526  1.1  sommerfe 	ifp->if_timer = 0;
   1527  1.1  sommerfe 	sc->sc_state = AWI_ST_OFF;
   1528  1.1  sommerfe 	(void) awi_read_intst (sc);
   1529  1.1  sommerfe 	/*
   1530  1.1  sommerfe 	 * XXX for pcmcia, there's no point in  disabling the device,
   1531  1.1  sommerfe 	 * as it's about to be powered off..
   1532  1.1  sommerfe 	 * for non-PCMCIA attachments, we should, however, stop
   1533  1.1  sommerfe 	 * the receiver and transmitter here.
   1534  1.1  sommerfe 	 */
   1535  1.1  sommerfe }
   1536  1.1  sommerfe 
   1537  1.1  sommerfe /*
   1538  1.1  sommerfe  * Watchdog routine, triggered by timer.
   1539  1.1  sommerfe  * This does periodic maintainance-type tasks on the interface.
   1540  1.1  sommerfe  */
   1541  1.1  sommerfe 
   1542  1.1  sommerfe void
   1543  1.1  sommerfe awi_watchdog(ifp)
   1544  1.1  sommerfe 	struct ifnet *ifp;
   1545  1.1  sommerfe {
   1546  1.1  sommerfe 	struct awi_softc *sc = ifp->if_softc;
   1547  1.1  sommerfe 	u_int8_t test;
   1548  1.1  sommerfe 	int i;
   1549  1.1  sommerfe 
   1550  1.1  sommerfe 	if (sc->sc_state == AWI_ST_OFF)
   1551  1.1  sommerfe 		/* nothing to do */
   1552  1.1  sommerfe 		return;
   1553  1.1  sommerfe 	else if (sc->sc_state == AWI_ST_INSANE) {
   1554  1.1  sommerfe 		awi_reset(sc);
   1555  1.1  sommerfe 		return;
   1556  1.1  sommerfe 	} else if (sc->sc_state == AWI_ST_SELFTEST) {
   1557  1.1  sommerfe 		/* check for selftest completion.. */
   1558  1.1  sommerfe 		test = awi_read_1(sc, AWI_SELFTEST);
   1559  1.1  sommerfe 		if ((test & 0xf0)  == 0xf0) { /* XXX magic numbers */
   1560  1.1  sommerfe 			if (test == AWI_SELFTEST_PASSED) {
   1561  1.1  sommerfe 				awi_init_1(sc);
   1562  1.1  sommerfe 			} else {
   1563  1.1  sommerfe 				printf("%s: selftest failed (code %x)\n",
   1564  1.1  sommerfe 				    sc->sc_dev.dv_xname, test);
   1565  1.1  sommerfe 				awi_reset(sc);
   1566  1.1  sommerfe 			}
   1567  1.1  sommerfe 		}
   1568  1.1  sommerfe 		sc->sc_selftest_tries++;
   1569  1.1  sommerfe 		/* still running.  try again on next tick */
   1570  1.1  sommerfe 		if (sc->sc_selftest_tries < 5) {
   1571  1.1  sommerfe 			ifp->if_timer = 1;
   1572  1.1  sommerfe 		} else {
   1573  1.1  sommerfe 			/*
   1574  1.1  sommerfe 			 * XXX should power down card, wait 1s, power it back
   1575  1.1  sommerfe 			 * up again..
   1576  1.1  sommerfe 			 */
   1577  1.1  sommerfe 			printf("%s: device failed to complete selftest (code %x)\n",
   1578  1.1  sommerfe 			    sc->sc_dev.dv_xname, test);
   1579  1.1  sommerfe 			ifp->if_timer = 0;
   1580  1.1  sommerfe 		}
   1581  1.1  sommerfe 		return;
   1582  1.1  sommerfe 	}
   1583  1.1  sommerfe 
   1584  1.1  sommerfe 
   1585  1.1  sommerfe 	/*
   1586  1.1  sommerfe 	 * command timer: if it goes to zero, device failed to respond.
   1587  1.1  sommerfe 	 * boot to the head.
   1588  1.1  sommerfe 	 */
   1589  1.1  sommerfe 	if (sc->sc_cmd_timer) {
   1590  1.1  sommerfe 		sc->sc_cmd_timer--;
   1591  1.1  sommerfe 		if (sc->sc_cmd_timer == 0) {
   1592  1.1  sommerfe 			sc->sc_flags &= ~AWI_FL_CMD_INPROG;
   1593  1.1  sommerfe 
   1594  1.1  sommerfe 			printf("%s: timeout waiting for command completion\n",
   1595  1.1  sommerfe 			    sc->sc_dev.dv_xname);
   1596  1.1  sommerfe 			test = awi_read_1(sc, AWI_CMD_STATUS);
   1597  1.1  sommerfe 			printf("%s: cmd status: %x\n", sc->sc_dev.dv_xname, test);
   1598  1.1  sommerfe 			test = awi_read_1(sc, AWI_CMD);
   1599  1.1  sommerfe 			printf("%s: cmd: %x\n", sc->sc_dev.dv_xname, test);
   1600  1.1  sommerfe 			awi_card_hexdump(sc, "CSB", AWI_CSB, 16);
   1601  1.1  sommerfe 			awi_reset(sc);
   1602  1.1  sommerfe 			return;
   1603  1.1  sommerfe 		}
   1604  1.1  sommerfe 	}
   1605  1.1  sommerfe 	/*
   1606  1.1  sommerfe 	 * Transmit timer.  If it goes to zero, device failed to deliver a
   1607  1.1  sommerfe 	 * tx complete interrupt.  boot to the head.
   1608  1.1  sommerfe 	 */
   1609  1.1  sommerfe 	if (sc->sc_tx_timer) {
   1610  1.1  sommerfe 		sc->sc_tx_timer--;
   1611  1.1  sommerfe 		if ((sc->sc_tx_timer == 0)  && (sc->sc_txpending)) {
   1612  1.1  sommerfe 			awi_card_hexdump(sc, "CSB", AWI_CSB, 16);
   1613  1.1  sommerfe 			printf("%s: transmit timeout\n", sc->sc_dev.dv_xname);
   1614  1.1  sommerfe 			awi_card_hexdump(sc, "last_txd", AWI_LAST_TXD, 5*4);
   1615  1.1  sommerfe 			for (i=0; i<sc->sc_ntxd; i++) {
   1616  1.1  sommerfe 				awi_card_hexdump(sc, "txd",
   1617  1.1  sommerfe 				    sc->sc_txd[i].descr, AWI_TXD_SIZE);
   1618  1.1  sommerfe 			}
   1619  1.1  sommerfe 			awi_reset(sc);
   1620  1.1  sommerfe 			return;
   1621  1.1  sommerfe 		}
   1622  1.1  sommerfe 	}
   1623  1.1  sommerfe 	/*
   1624  1.1  sommerfe 	 * Scan timer.
   1625  1.1  sommerfe 	 * When synched, this is used to notice when we've stopped
   1626  1.1  sommerfe 	 * receiving beacons and should attempt to resynch.
   1627  1.1  sommerfe 	 *
   1628  1.1  sommerfe 	 * When unsynched, this is used to notice if we've received an
   1629  1.1  sommerfe 	 * interesting probe response and should synch up.
   1630  1.1  sommerfe 	 */
   1631  1.1  sommerfe 
   1632  1.1  sommerfe 	if (sc->sc_scan_timer) {
   1633  1.1  sommerfe 		sc->sc_scan_timer--;
   1634  1.1  sommerfe 		if (sc->sc_scan_timer == 0) {
   1635  1.1  sommerfe 			if (sc->sc_state == AWI_ST_SCAN) {
   1636  1.1  sommerfe 				/*
   1637  1.1  sommerfe 				 * XXX what if device fails to deliver
   1638  1.1  sommerfe 				 * a scan-completion interrupt?
   1639  1.1  sommerfe 				 */
   1640  1.1  sommerfe 			} else {
   1641  1.1  sommerfe 				printf("%s: no recent beacon from %s; rescanning\n",
   1642  1.1  sommerfe 				    sc->sc_dev.dv_xname,
   1643  1.1  sommerfe 				    ether_sprintf(sc->sc_active_bss.bss_id));
   1644  1.1  sommerfe 				awi_restart_scan(sc);
   1645  1.1  sommerfe 			}
   1646  1.1  sommerfe 		}
   1647  1.1  sommerfe 	}
   1648  1.1  sommerfe 
   1649  1.1  sommerfe 	/*
   1650  1.1  sommerfe 	 * Management timer.  Used to know when to send auth
   1651  1.1  sommerfe 	 * requests and associate requests.
   1652  1.1  sommerfe 	 */
   1653  1.1  sommerfe 	if (sc->sc_mgt_timer) {
   1654  1.1  sommerfe 		sc->sc_mgt_timer--;
   1655  1.1  sommerfe 		if (sc->sc_mgt_timer == 0) {
   1656  1.1  sommerfe 			switch (sc->sc_state)
   1657  1.1  sommerfe 			{
   1658  1.1  sommerfe 			case AWI_ST_SYNCED:
   1659  1.1  sommerfe 			case AWI_ST_RUNNING:
   1660  1.1  sommerfe 				sc->sc_state = AWI_ST_SYNCED;
   1661  1.1  sommerfe 				awi_send_authreq(sc);
   1662  1.1  sommerfe 				break;
   1663  1.1  sommerfe 			case AWI_ST_AUTHED:
   1664  1.1  sommerfe 				awi_send_assocreq(sc);
   1665  1.1  sommerfe 				break;
   1666  1.1  sommerfe 			default:
   1667  1.1  sommerfe 				printf("weird state for mgt timeout!\n");
   1668  1.1  sommerfe 				break;
   1669  1.1  sommerfe 			}
   1670  1.1  sommerfe 		}
   1671  1.1  sommerfe 	}
   1672  1.1  sommerfe 	awi_set_timer(sc);
   1673  1.1  sommerfe }
   1674  1.1  sommerfe 
   1675  1.1  sommerfe void
   1676  1.1  sommerfe awi_set_mc (sc)
   1677  1.1  sommerfe 	struct awi_softc  *sc;
   1678  1.1  sommerfe {
   1679  1.1  sommerfe 	/* XXX not implemented yet.. */
   1680  1.1  sommerfe }
   1681  1.1  sommerfe 
   1682  1.1  sommerfe /*
   1683  1.1  sommerfe  * init routine
   1684  1.1  sommerfe  */
   1685  1.1  sommerfe 
   1686  1.1  sommerfe /*
   1687  1.1  sommerfe  * ioctl routine
   1688  1.1  sommerfe  * SIOCSIFADDR sets IFF_UP
   1689  1.1  sommerfe  * SIOCIFMTU
   1690  1.1  sommerfe  * SIOCSIFFLAGS
   1691  1.1  sommerfe  * SIOCADDMULTI/SIOCDELMULTI
   1692  1.1  sommerfe  */
   1693  1.1  sommerfe 
   1694  1.1  sommerfe int
   1695  1.1  sommerfe awi_ioctl(ifp, cmd, data)
   1696  1.1  sommerfe 	register struct ifnet *ifp;
   1697  1.1  sommerfe 	u_long cmd;
   1698  1.1  sommerfe 	caddr_t data;
   1699  1.1  sommerfe {
   1700  1.1  sommerfe 	struct awi_softc *sc = ifp->if_softc;
   1701  1.1  sommerfe 	struct ifaddr *ifa = (struct ifaddr *)data;
   1702  1.1  sommerfe 	struct ifreq *ifr = (struct ifreq *)data;
   1703  1.1  sommerfe 	int s, error = 0;
   1704  1.1  sommerfe 
   1705  1.1  sommerfe 	s = splnet();
   1706  1.1  sommerfe 
   1707  1.1  sommerfe 	switch (cmd) {
   1708  1.1  sommerfe 	case SIOCSIFADDR:
   1709  1.1  sommerfe 		if ((error = awi_enable(sc)) != 0)
   1710  1.1  sommerfe 			break;
   1711  1.1  sommerfe 
   1712  1.1  sommerfe 		ifp->if_flags |= IFF_UP;
   1713  1.1  sommerfe 
   1714  1.1  sommerfe 		/* XXX other AF support: inet6, NS, ... */
   1715  1.1  sommerfe 		switch (ifa->ifa_addr->sa_family) {
   1716  1.1  sommerfe #ifdef INET
   1717  1.1  sommerfe 		case AF_INET:
   1718  1.5  sommerfe 			arp_ifinit(sc->sc_ifp, ifa);
   1719  1.1  sommerfe 			break;
   1720  1.1  sommerfe #endif
   1721  1.1  sommerfe 		default:
   1722  1.1  sommerfe 			break;
   1723  1.1  sommerfe 		}
   1724  1.1  sommerfe 		break;
   1725  1.1  sommerfe 
   1726  1.1  sommerfe 	case SIOCSIFFLAGS:
   1727  1.1  sommerfe 		if ((ifp->if_flags & IFF_UP) == 0 &&
   1728  1.1  sommerfe 		    (sc->sc_state != AWI_ST_OFF)) {
   1729  1.1  sommerfe 			/*
   1730  1.1  sommerfe 			 * If interface is marked down and it is enabled, then
   1731  1.1  sommerfe 			 * stop it.
   1732  1.1  sommerfe 			 */
   1733  1.1  sommerfe 			ifp->if_flags &= ~IFF_RUNNING;
   1734  1.1  sommerfe 			awi_stop(sc);
   1735  1.1  sommerfe 			awi_disable(sc);
   1736  1.1  sommerfe 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
   1737  1.1  sommerfe 			   (ifp->if_flags & IFF_RUNNING) == 0) {
   1738  1.1  sommerfe 			/*
   1739  1.1  sommerfe 			 * If interface is marked up and it is stopped, then
   1740  1.1  sommerfe 			 * start it.
   1741  1.1  sommerfe 			 */
   1742  1.1  sommerfe 			if ((error = awi_enable(sc)) != 0)
   1743  1.1  sommerfe 				break;
   1744  1.1  sommerfe 		} else if ((ifp->if_flags & IFF_UP) != 0) {
   1745  1.1  sommerfe 			/*
   1746  1.1  sommerfe 			 * Deal with other flags that change hardware
   1747  1.1  sommerfe 			 * state, i.e. IFF_PROMISC.
   1748  1.1  sommerfe 			 */
   1749  1.1  sommerfe 			awi_set_mc(sc);
   1750  1.1  sommerfe 		}
   1751  1.1  sommerfe 		break;
   1752  1.4  sommerfe 	case SIOCADDMULTI:
   1753  1.4  sommerfe 	case SIOCDELMULTI:
   1754  1.4  sommerfe 		error = (cmd == SIOCADDMULTI) ?
   1755  1.4  sommerfe 		    ether_addmulti(ifr, &sc->sc_ec) :
   1756  1.4  sommerfe 		    ether_delmulti(ifr, &sc->sc_ec);
   1757  1.4  sommerfe 		if (error == ENETRESET) {
   1758  1.4  sommerfe 			error = 0;
   1759  1.4  sommerfe 			awi_set_mc(sc);
   1760  1.4  sommerfe 		}
   1761  1.4  sommerfe 		break;
   1762  1.4  sommerfe 
   1763  1.1  sommerfe 	default:
   1764  1.1  sommerfe 		error = EINVAL;
   1765  1.1  sommerfe 		break;
   1766  1.1  sommerfe 
   1767  1.1  sommerfe 	}
   1768  1.1  sommerfe 	splx(s);
   1769  1.1  sommerfe 	return error;
   1770  1.1  sommerfe 
   1771  1.1  sommerfe }
   1772  1.1  sommerfe 
   1773  1.1  sommerfe int awi_activate (self, act)
   1774  1.1  sommerfe 	struct device *self;
   1775  1.1  sommerfe 	enum devact act;
   1776  1.1  sommerfe {
   1777  1.1  sommerfe 	int s = splnet();
   1778  1.1  sommerfe 	panic("awi_activate");
   1779  1.1  sommerfe 
   1780  1.1  sommerfe #if 0
   1781  1.1  sommerfe 	switch (act) {
   1782  1.1  sommerfe 	case DVACT_ACTIVATE:
   1783  1.1  sommerfe 		rv = EOPNOTSUPP;
   1784  1.1  sommerfe 		break;
   1785  1.1  sommerfe 
   1786  1.1  sommerfe 	case DVACT_DEACTIVATE:
   1787  1.1  sommerfe #ifdef notyet
   1788  1.1  sommerfe 		/* First, kill off the interface. */
   1789  1.1  sommerfe 		if_detach(sc->sc_ethercom.ec_if);
   1790  1.1  sommerfe #endif
   1791  1.1  sommerfe 
   1792  1.1  sommerfe 		/* Now disable the interface. */
   1793  1.1  sommerfe 		awidisable(sc);
   1794  1.1  sommerfe 		break;
   1795  1.1  sommerfe 	}
   1796  1.1  sommerfe #endif
   1797  1.1  sommerfe 	splx(s);
   1798  1.1  sommerfe 
   1799  1.1  sommerfe }
   1800  1.1  sommerfe 
   1801  1.1  sommerfe int
   1802  1.1  sommerfe awi_drop_output (ifp, m0, dst, rt0)
   1803  1.1  sommerfe 	struct ifnet *ifp;
   1804  1.1  sommerfe 	struct mbuf *m0;
   1805  1.1  sommerfe 	struct sockaddr *dst;
   1806  1.1  sommerfe 	struct rtentry *rt0;
   1807  1.1  sommerfe {
   1808  1.1  sommerfe 	m_freem(m0);
   1809  1.1  sommerfe 	return 0;
   1810  1.1  sommerfe }
   1811  1.1  sommerfe 
   1812  1.1  sommerfe void
   1813  1.1  sommerfe awi_drop_input (ifp, m0)
   1814  1.1  sommerfe 	struct ifnet *ifp;
   1815  1.1  sommerfe 	struct mbuf *m0;
   1816  1.1  sommerfe {
   1817  1.1  sommerfe 	m_freem(m0);
   1818  1.1  sommerfe }
   1819  1.1  sommerfe 
   1820  1.4  sommerfe int awi_attach (sc, macaddr)
   1821  1.1  sommerfe 	struct awi_softc *sc;
   1822  1.4  sommerfe 	u_int8_t *macaddr;
   1823  1.1  sommerfe {
   1824  1.1  sommerfe 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1825  1.1  sommerfe 	u_int8_t version[AWI_BANNER_LEN];
   1826  1.1  sommerfe 
   1827  1.1  sommerfe 	sc->sc_ifp = ifp;
   1828  1.1  sommerfe 
   1829  1.1  sommerfe 	awi_read_bytes (sc, AWI_BANNER, version, AWI_BANNER_LEN);
   1830  1.1  sommerfe 	printf("%s: firmware %s\n", sc->sc_dev.dv_xname, version);
   1831  1.4  sommerfe 
   1832  1.4  sommerfe 	memcpy(sc->sc_my_addr, macaddr, ETHER_ADDR_LEN);
   1833  1.4  sommerfe 	printf("%s: 802.11 address %s\n", sc->sc_dev.dv_xname,
   1834  1.4  sommerfe 	    ether_sprintf(sc->sc_my_addr));
   1835  1.4  sommerfe 
   1836  1.1  sommerfe 
   1837  1.1  sommerfe 	memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
   1838  1.1  sommerfe 	ifp->if_softc = sc;
   1839  1.1  sommerfe 	ifp->if_start = awi_start;
   1840  1.1  sommerfe 	ifp->if_ioctl = awi_ioctl;
   1841  1.1  sommerfe 	ifp->if_watchdog = awi_watchdog;
   1842  1.1  sommerfe 	ifp->if_mtu = ETHERMTU;
   1843  1.1  sommerfe 	/* XXX simplex may not be correct here.. */
   1844  1.1  sommerfe 	ifp->if_flags =
   1845  1.1  sommerfe 	    IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
   1846  1.1  sommerfe 
   1847  1.1  sommerfe 	sc->sc_mgtq.ifq_maxlen = 5;
   1848  1.1  sommerfe 
   1849  1.1  sommerfe 	if_attach(ifp);
   1850  1.4  sommerfe 	ether_ifattach(ifp, sc->sc_my_addr);
   1851  1.4  sommerfe 	ifp->if_hdrlen = 32;	/* 802.11 headers are bigger.. */
   1852  1.1  sommerfe 
   1853  1.1  sommerfe #if NBPFILTER > 0
   1854  1.1  sommerfe 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
   1855  1.1  sommerfe #endif
   1856  1.1  sommerfe 	return 0;
   1857  1.1  sommerfe }
   1858  1.1  sommerfe 
   1859  1.1  sommerfe void
   1860  1.1  sommerfe awi_zero (sc, from, to)
   1861  1.1  sommerfe 	struct awi_softc *sc;
   1862  1.1  sommerfe 	u_int32_t from, to;
   1863  1.1  sommerfe {
   1864  1.1  sommerfe 	u_int32_t i;
   1865  1.1  sommerfe 	for (i=from; i<to; i++)
   1866  1.1  sommerfe 		awi_write_1(sc, i, 0);
   1867  1.1  sommerfe }
   1868  1.1  sommerfe 
   1869  1.1  sommerfe void
   1870  1.1  sommerfe awi_init (sc)
   1871  1.1  sommerfe 	struct awi_softc *sc;
   1872  1.1  sommerfe {
   1873  1.1  sommerfe 	struct ifnet *ifp = sc->sc_ifp;
   1874  1.1  sommerfe 
   1875  1.1  sommerfe 	sc->sc_scan_duration = 100; /* scan for 100ms */
   1876  1.1  sommerfe 
   1877  1.1  sommerfe 	/*
   1878  1.1  sommerfe 	 * Maybe we should randomize these....
   1879  1.1  sommerfe 	 */
   1880  1.1  sommerfe 	sc->sc_scan_chanset = IEEEWL_FH_CHANSET_MIN;
   1881  1.1  sommerfe 	sc->sc_scan_pattern = IEEEWL_FH_PATTERN_MIN;
   1882  1.1  sommerfe 
   1883  1.1  sommerfe 	sc->sc_flags &= ~AWI_FL_CMD_INPROG;
   1884  1.1  sommerfe 
   1885  1.1  sommerfe 	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
   1886  1.1  sommerfe 	ifp->if_timer = 0;
   1887  1.1  sommerfe 
   1888  1.1  sommerfe 	sc->sc_cmd_timer = 0;
   1889  1.1  sommerfe 	sc->sc_tx_timer = 0;
   1890  1.1  sommerfe 	sc->sc_mgt_timer = 0;
   1891  1.1  sommerfe 	sc->sc_scan_timer = 0;
   1892  1.1  sommerfe 
   1893  1.1  sommerfe 	sc->sc_nbindings = 0;
   1894  1.1  sommerfe 
   1895  1.1  sommerfe 	/*
   1896  1.1  sommerfe 	 * this reset sequence doesn't seem to always do the trick.
   1897  1.1  sommerfe 	 * hard-power-cycling the card may do it..
   1898  1.1  sommerfe 	 */
   1899  1.1  sommerfe 
   1900  1.1  sommerfe 	/*
   1901  1.1  sommerfe 	 * reset the hardware, just to be sure.
   1902  1.1  sommerfe 	 * (bring out the big hammer here..)
   1903  1.1  sommerfe 	 */
   1904  1.1  sommerfe 	/* XXX insert delay here? */
   1905  1.1  sommerfe 
   1906  1.1  sommerfe 	am79c930_gcr_setbits (&sc->sc_chip, AM79C930_GCR_CORESET);
   1907  1.1  sommerfe 	delay(10);		/* XXX arbitrary value */
   1908  1.1  sommerfe 
   1909  1.1  sommerfe 	/*
   1910  1.1  sommerfe 	 * clear control memory regions (firmware should do this but...)
   1911  1.1  sommerfe 	 */
   1912  1.1  sommerfe 	awi_zero(sc, AWI_LAST_TXD, AWI_BUFFERS);
   1913  1.1  sommerfe 
   1914  1.1  sommerfe 	awi_drvstate(sc, AWI_DRV_RESET);
   1915  1.1  sommerfe 	sc->sc_selftest_tries = 0;
   1916  1.1  sommerfe 
   1917  1.1  sommerfe 	/*
   1918  1.1  sommerfe 	 * release reset
   1919  1.1  sommerfe 	 */
   1920  1.1  sommerfe 	am79c930_gcr_clearbits (&sc->sc_chip, AM79C930_GCR_CORESET);
   1921  1.1  sommerfe 	delay(10);
   1922  1.1  sommerfe 
   1923  1.1  sommerfe 	sc->sc_state = AWI_ST_SELFTEST;
   1924  1.1  sommerfe 	ifp->if_timer = 1;
   1925  1.1  sommerfe 
   1926  1.1  sommerfe }
   1927  1.1  sommerfe 
   1928  1.1  sommerfe void
   1929  1.1  sommerfe awi_cmd (sc, opcode)
   1930  1.1  sommerfe 	struct awi_softc *sc;
   1931  1.1  sommerfe 	u_int8_t opcode;
   1932  1.1  sommerfe {
   1933  1.1  sommerfe 	if (sc->sc_flags & AWI_FL_CMD_INPROG)
   1934  1.1  sommerfe 		panic("%s: command reentered", sc->sc_dev.dv_xname);
   1935  1.1  sommerfe 
   1936  1.1  sommerfe 	sc->sc_flags |= AWI_FL_CMD_INPROG;
   1937  1.1  sommerfe 
   1938  1.1  sommerfe 	/* issue test-interface command */
   1939  1.1  sommerfe 	awi_write_1(sc, AWI_CMD, opcode);
   1940  1.1  sommerfe 
   1941  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_STATUS, 0);
   1942  1.1  sommerfe 
   1943  1.1  sommerfe 	sc->sc_cmd_timer = 2;
   1944  1.1  sommerfe 	awi_set_timer(sc);
   1945  1.1  sommerfe }
   1946  1.1  sommerfe 
   1947  1.1  sommerfe void
   1948  1.1  sommerfe awi_cmd_test_if (sc)
   1949  1.1  sommerfe 	struct awi_softc *sc;
   1950  1.1  sommerfe {
   1951  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_NOP);
   1952  1.1  sommerfe }
   1953  1.1  sommerfe 
   1954  1.1  sommerfe void
   1955  1.1  sommerfe awi_cmd_get_mib (sc, var, offset, len)
   1956  1.1  sommerfe 	struct awi_softc *sc;
   1957  1.1  sommerfe 	u_int8_t var;
   1958  1.1  sommerfe 	u_int8_t offset;
   1959  1.1  sommerfe 	u_int8_t len;
   1960  1.1  sommerfe {
   1961  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_TYPE, var);
   1962  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_SIZE, len);
   1963  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_INDEX, offset);
   1964  1.1  sommerfe 
   1965  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_GET_MIB);
   1966  1.1  sommerfe }
   1967  1.1  sommerfe 
   1968  1.1  sommerfe void
   1969  1.1  sommerfe awi_cmd_txinit (sc)
   1970  1.1  sommerfe 	struct awi_softc *sc;
   1971  1.1  sommerfe {
   1972  1.1  sommerfe 	awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_TX_DATA, sc->sc_txbase);
   1973  1.1  sommerfe 	awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_TX_MGT, 0);
   1974  1.1  sommerfe 	awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_TX_BCAST, 0);
   1975  1.1  sommerfe 	awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_TX_PS, 0);
   1976  1.1  sommerfe 	awi_write_4(sc, AWI_CMD_PARAMS+AWI_CA_TX_CF, 0);
   1977  1.1  sommerfe 
   1978  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_INIT_TX);
   1979  1.1  sommerfe }
   1980  1.1  sommerfe 
   1981  1.1  sommerfe int awi_max_chan = -1;
   1982  1.1  sommerfe int awi_min_chan = 1000;
   1983  1.1  sommerfe int awi_max_pattern = -1;
   1984  1.1  sommerfe int awi_min_pattern = 1000;
   1985  1.1  sommerfe 
   1986  1.1  sommerfe 
   1987  1.1  sommerfe /*
   1988  1.1  sommerfe  * timeout-driven routine: complete device init once device has passed
   1989  1.1  sommerfe  * selftest.
   1990  1.1  sommerfe  */
   1991  1.1  sommerfe 
   1992  1.1  sommerfe void awi_init_1 (sc)
   1993  1.1  sommerfe 	struct awi_softc *sc;
   1994  1.1  sommerfe {
   1995  1.1  sommerfe 	struct ifnet *ifp = sc->sc_ifp;
   1996  1.1  sommerfe 
   1997  1.1  sommerfe 	awi_intrinit(sc);
   1998  1.1  sommerfe 
   1999  1.1  sommerfe 	sc->sc_state = AWI_ST_IFTEST;
   2000  1.1  sommerfe 
   2001  1.1  sommerfe 	if (ifp->if_flags & IFF_DEBUG) {
   2002  1.1  sommerfe 		awi_card_hexdump(sc, "init_1 CSB", AWI_CSB, 16);
   2003  1.1  sommerfe 		sc->sc_completion = awi_mibdump;
   2004  1.1  sommerfe 	} else
   2005  1.1  sommerfe 		sc->sc_completion = awi_init_2;
   2006  1.1  sommerfe 
   2007  1.1  sommerfe 	sc->sc_curmib = 0;
   2008  1.1  sommerfe 
   2009  1.1  sommerfe 	awi_cmd_test_if (sc);
   2010  1.1  sommerfe }
   2011  1.1  sommerfe 
   2012  1.1  sommerfe void awi_mibdump (sc, status)
   2013  1.1  sommerfe 	struct awi_softc *sc;
   2014  1.1  sommerfe 	u_int8_t status;
   2015  1.1  sommerfe {
   2016  1.1  sommerfe 	u_int8_t mibblk[256];
   2017  1.1  sommerfe 
   2018  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2019  1.1  sommerfe 		printf("%s: pre-mibread failed (card unhappy?)\n",
   2020  1.1  sommerfe 		    sc->sc_dev.dv_xname);
   2021  1.1  sommerfe 		awi_reset(sc);
   2022  1.1  sommerfe 		return;
   2023  1.1  sommerfe 	}
   2024  1.1  sommerfe 
   2025  1.1  sommerfe 	if (sc->sc_curmib != 0) {
   2026  1.1  sommerfe 		awi_read_bytes(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA,
   2027  1.1  sommerfe 		    mibblk, 72);
   2028  1.1  sommerfe 		awi_hexdump("mib", mibblk, 72);
   2029  1.1  sommerfe 	}
   2030  1.1  sommerfe 	if (sc->sc_curmib > AWI_MIB_LAST) {
   2031  1.1  sommerfe 		awi_init_2 (sc, status);
   2032  1.1  sommerfe 	} else {
   2033  1.1  sommerfe 		sc->sc_completion = awi_mibdump;
   2034  1.1  sommerfe 		printf("mib %d\n", sc->sc_curmib);
   2035  1.1  sommerfe 		awi_cmd_get_mib (sc, sc->sc_curmib, 0, 30);
   2036  1.1  sommerfe 		sc->sc_curmib++;
   2037  1.1  sommerfe 		/* skip over reserved MIB's.. */
   2038  1.1  sommerfe 		if ((sc->sc_curmib == 1) || (sc->sc_curmib == 6))
   2039  1.1  sommerfe 			sc->sc_curmib++;
   2040  1.1  sommerfe 	}
   2041  1.1  sommerfe }
   2042  1.1  sommerfe 
   2043  1.1  sommerfe 
   2044  1.1  sommerfe /*
   2045  1.1  sommerfe  * called on completion of test-interface command in first-stage init.
   2046  1.1  sommerfe  */
   2047  1.1  sommerfe 
   2048  1.1  sommerfe void awi_init_2 (sc, status)
   2049  1.1  sommerfe 	struct awi_softc *sc;
   2050  1.1  sommerfe 	u_int8_t status;
   2051  1.1  sommerfe {
   2052  1.1  sommerfe 	/* did it succeed? */
   2053  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2054  1.1  sommerfe 		printf("%s: nop failed (card unhappy?)\n",
   2055  1.1  sommerfe 		    sc->sc_dev.dv_xname);
   2056  1.1  sommerfe 		awi_reset(sc);
   2057  1.1  sommerfe 	}
   2058  1.1  sommerfe 
   2059  1.1  sommerfe 	sc->sc_state = AWI_ST_MIB_GET;
   2060  1.1  sommerfe 	sc->sc_completion = awi_init_read_bufptrs_done;
   2061  1.1  sommerfe 
   2062  1.1  sommerfe 	awi_cmd_get_mib (sc, AWI_MIB_LOCAL, 0, AWI_MIB_LOCAL_SIZE);
   2063  1.1  sommerfe }
   2064  1.1  sommerfe 
   2065  1.1  sommerfe void awi_init_read_bufptrs_done (sc, status)
   2066  1.1  sommerfe 	struct awi_softc *sc;
   2067  1.1  sommerfe 	u_int8_t status;
   2068  1.1  sommerfe {
   2069  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2070  1.1  sommerfe 		printf("%s: get_mib failed (card unhappy?)\n",
   2071  1.1  sommerfe 		    sc->sc_dev.dv_xname);
   2072  1.1  sommerfe 		awi_reset(sc);
   2073  1.1  sommerfe 	}
   2074  1.1  sommerfe 
   2075  1.1  sommerfe 	sc->sc_txbase = awi_read_4 (sc,
   2076  1.1  sommerfe 	    AWI_CMD_PARAMS+AWI_CA_MIB_DATA+AWI_MIB_LOCAL_TXB_OFFSET);
   2077  1.1  sommerfe 	sc->sc_txlen = awi_read_4 (sc,
   2078  1.1  sommerfe 	    AWI_CMD_PARAMS+AWI_CA_MIB_DATA+AWI_MIB_LOCAL_TXB_SIZE);
   2079  1.1  sommerfe 	sc->sc_rxbase = awi_read_4 (sc,
   2080  1.1  sommerfe 	    AWI_CMD_PARAMS+AWI_CA_MIB_DATA+AWI_MIB_LOCAL_RXB_OFFSET);
   2081  1.1  sommerfe 	sc->sc_rxlen = awi_read_4 (sc,
   2082  1.1  sommerfe 	    AWI_CMD_PARAMS+AWI_CA_MIB_DATA+AWI_MIB_LOCAL_RXB_SIZE);
   2083  1.1  sommerfe 	/*
   2084  1.1  sommerfe 	 * XXX consider repartitioning buffer space to allow for
   2085  1.1  sommerfe 	 * more efficient usage.
   2086  1.1  sommerfe 	 * 6144: 3 txds, 1476 waste	(current partition)
   2087  1.1  sommerfe 	 * better splits:
   2088  1.1  sommerfe 	 * 4864: 3 txds, 196 waste
   2089  1.1  sommerfe 	 * 6400: 4 txds, 176 waste
   2090  1.1  sommerfe 	 * 7936: 5 txds, 156 waste
   2091  1.1  sommerfe 	 */
   2092  1.1  sommerfe 
   2093  1.1  sommerfe #if 0
   2094  1.1  sommerfe 	printf("tx offset: %x\n", sc->sc_txbase);
   2095  1.1  sommerfe 	printf("tx size: %x\n", sc->sc_txlen);
   2096  1.1  sommerfe 	printf("rx offset: %x\n", sc->sc_rxbase);
   2097  1.1  sommerfe 	printf("rx size: %x\n", sc->sc_rxlen);
   2098  1.1  sommerfe #endif
   2099  1.1  sommerfe 
   2100  1.1  sommerfe 	sc->sc_state = AWI_ST_MIB_SET;
   2101  1.1  sommerfe 	awi_cmd_set_notap(sc);
   2102  1.1  sommerfe }
   2103  1.1  sommerfe 
   2104  1.1  sommerfe void awi_cmd_set_notap (sc)
   2105  1.1  sommerfe 	struct awi_softc *sc;
   2106  1.1  sommerfe {
   2107  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_TYPE, AWI_MIB_LOCAL);
   2108  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_SIZE, 1);
   2109  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_INDEX,
   2110  1.1  sommerfe 	    AWI_MIB_LOCAL_ACTING_AS_AP);
   2111  1.1  sommerfe 
   2112  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA, 0);
   2113  1.1  sommerfe 	sc->sc_completion = awi_cmd_set_notap_done;
   2114  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_SET_MIB);
   2115  1.1  sommerfe }
   2116  1.1  sommerfe 
   2117  1.1  sommerfe void awi_cmd_set_notap_done (sc, status)
   2118  1.1  sommerfe 	struct awi_softc *sc;
   2119  1.1  sommerfe 	u_int8_t status;
   2120  1.1  sommerfe {
   2121  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2122  1.1  sommerfe 		int erroffset = awi_read_1 (sc, AWI_ERROR_OFFSET);
   2123  1.1  sommerfe 		printf("%s: set_infra failed (card unhappy?); erroffset %d\n",
   2124  1.1  sommerfe 		    sc->sc_dev.dv_xname,
   2125  1.1  sommerfe 		    erroffset);
   2126  1.1  sommerfe 		awi_reset(sc);
   2127  1.1  sommerfe 		return;
   2128  1.1  sommerfe 	}
   2129  1.1  sommerfe 	awi_cmd_set_infra (sc);
   2130  1.1  sommerfe }
   2131  1.1  sommerfe 
   2132  1.1  sommerfe void awi_cmd_set_infra (sc)
   2133  1.1  sommerfe 	struct awi_softc *sc;
   2134  1.1  sommerfe {
   2135  1.1  sommerfe 
   2136  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_TYPE, AWI_MIB_LOCAL);
   2137  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_SIZE, 1);
   2138  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_INDEX,
   2139  1.1  sommerfe 	    AWI_MIB_LOCAL_INFRA_MODE);
   2140  1.1  sommerfe 
   2141  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA, 1);
   2142  1.1  sommerfe 	sc->sc_completion = awi_cmd_set_infra_done;
   2143  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_SET_MIB);
   2144  1.1  sommerfe }
   2145  1.1  sommerfe 
   2146  1.1  sommerfe void awi_cmd_set_infra_done (sc, status)
   2147  1.1  sommerfe 	struct awi_softc *sc;
   2148  1.1  sommerfe 	u_int8_t status;
   2149  1.1  sommerfe {
   2150  1.1  sommerfe #if 0
   2151  1.1  sommerfe 	printf("set_infra done\n");
   2152  1.1  sommerfe #endif
   2153  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2154  1.1  sommerfe 		int erroffset = awi_read_1 (sc, AWI_ERROR_OFFSET);
   2155  1.1  sommerfe 		printf("%s: set_infra failed (card unhappy?); erroffset %d\n",
   2156  1.1  sommerfe 		    sc->sc_dev.dv_xname,
   2157  1.1  sommerfe 		    erroffset);
   2158  1.1  sommerfe 		awi_reset(sc);
   2159  1.1  sommerfe 		return;
   2160  1.1  sommerfe 	}
   2161  1.1  sommerfe #if 0
   2162  1.1  sommerfe 	printf("%s: set_infra done\n", sc->sc_dev.dv_xname);
   2163  1.1  sommerfe #endif
   2164  1.1  sommerfe 	awi_cmd_set_allmulti (sc);
   2165  1.1  sommerfe }
   2166  1.1  sommerfe 
   2167  1.1  sommerfe void awi_cmd_set_allmulti (sc)
   2168  1.1  sommerfe 	struct awi_softc *sc;
   2169  1.1  sommerfe {
   2170  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_TYPE, AWI_MIB_LOCAL);
   2171  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_SIZE, 1);
   2172  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_INDEX,
   2173  1.1  sommerfe 	    AWI_MIB_LOCAL_FILTMULTI);
   2174  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA, 0);
   2175  1.1  sommerfe 	sc->sc_completion = awi_cmd_set_allmulti_done;
   2176  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_SET_MIB);
   2177  1.1  sommerfe }
   2178  1.1  sommerfe 
   2179  1.1  sommerfe void awi_cmd_set_allmulti_done (sc, status)
   2180  1.1  sommerfe 	struct awi_softc *sc;
   2181  1.1  sommerfe 	u_int8_t status;
   2182  1.1  sommerfe {
   2183  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2184  1.1  sommerfe 		int erroffset = awi_read_1 (sc, AWI_ERROR_OFFSET);
   2185  1.1  sommerfe 		printf("%s: set_almulti_done failed (card unhappy?); erroffset %d\n",
   2186  1.1  sommerfe 		    sc->sc_dev.dv_xname,
   2187  1.1  sommerfe 		    erroffset);
   2188  1.1  sommerfe 		awi_reset(sc);
   2189  1.1  sommerfe 		return;
   2190  1.1  sommerfe 	}
   2191  1.1  sommerfe 	awi_cmd_set_promisc (sc);
   2192  1.1  sommerfe }
   2193  1.1  sommerfe 
   2194  1.1  sommerfe void awi_cmd_set_promisc (sc)
   2195  1.1  sommerfe 	struct awi_softc *sc;
   2196  1.1  sommerfe {
   2197  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_TYPE, AWI_MIB_MAC);
   2198  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_SIZE, 1);
   2199  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_INDEX,
   2200  1.1  sommerfe 	    AWI_MIB_MAC_PROMISC);
   2201  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA, 0); /* XXX */
   2202  1.1  sommerfe 	sc->sc_completion = awi_cmd_set_promisc_done;
   2203  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_SET_MIB);
   2204  1.1  sommerfe }
   2205  1.1  sommerfe 
   2206  1.1  sommerfe void awi_cmd_set_promisc_done (sc, status)
   2207  1.1  sommerfe 	struct awi_softc *sc;
   2208  1.1  sommerfe 	u_int8_t status;
   2209  1.1  sommerfe {
   2210  1.1  sommerfe #if 0
   2211  1.1  sommerfe 	printf("set promisc_done\n");
   2212  1.1  sommerfe #endif
   2213  1.1  sommerfe 
   2214  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2215  1.1  sommerfe 		int erroffset = awi_read_1 (sc, AWI_ERROR_OFFSET);
   2216  1.1  sommerfe 		printf("%s: set_promisc_done failed (card unhappy?); erroffset %d\n",
   2217  1.1  sommerfe 		    sc->sc_dev.dv_xname,
   2218  1.1  sommerfe 		    erroffset);
   2219  1.1  sommerfe 		awi_reset(sc);
   2220  1.1  sommerfe 		return;
   2221  1.1  sommerfe 	}
   2222  1.1  sommerfe #if 0
   2223  1.1  sommerfe 	printf("%s: set_promisc done\n", sc->sc_dev.dv_xname);
   2224  1.1  sommerfe #endif
   2225  1.1  sommerfe 
   2226  1.1  sommerfe 	awi_init_txdescr(sc);
   2227  1.1  sommerfe 
   2228  1.1  sommerfe 	sc->sc_state = AWI_ST_TXINIT;
   2229  1.1  sommerfe 	sc->sc_completion = awi_init_4;
   2230  1.1  sommerfe 	awi_cmd_txinit(sc);
   2231  1.1  sommerfe }
   2232  1.1  sommerfe 
   2233  1.1  sommerfe void
   2234  1.1  sommerfe awi_init_4 (sc, status)
   2235  1.1  sommerfe 	struct awi_softc *sc;
   2236  1.1  sommerfe 	u_int8_t status;
   2237  1.1  sommerfe {
   2238  1.1  sommerfe #if 0
   2239  1.1  sommerfe 	printf("%s: awi_init_4, st %x\n", sc->sc_dev.dv_xname, status);
   2240  1.1  sommerfe 	awi_card_hexdump(sc, "init_4 CSB", AWI_CSB, 16);
   2241  1.1  sommerfe #endif
   2242  1.1  sommerfe 
   2243  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2244  1.1  sommerfe 		int erroffset = awi_read_1 (sc, AWI_ERROR_OFFSET);
   2245  1.1  sommerfe 		printf("%s: init_tx failed (card unhappy?); erroffset %d\n",
   2246  1.1  sommerfe 		    sc->sc_dev.dv_xname,
   2247  1.1  sommerfe 		    erroffset);
   2248  1.1  sommerfe 		awi_reset(sc);
   2249  1.1  sommerfe 		return;
   2250  1.1  sommerfe 	}
   2251  1.1  sommerfe 
   2252  1.1  sommerfe 	sc->sc_state = AWI_ST_RXINIT;
   2253  1.1  sommerfe 	sc->sc_completion = awi_init_5;
   2254  1.1  sommerfe 
   2255  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_INIT_RX);
   2256  1.1  sommerfe }
   2257  1.1  sommerfe 
   2258  1.1  sommerfe void awi_init_5 (sc, status)
   2259  1.1  sommerfe 	struct awi_softc *sc;
   2260  1.1  sommerfe 	u_int8_t status;
   2261  1.1  sommerfe {
   2262  1.1  sommerfe #if 0
   2263  1.1  sommerfe 	struct ifnet *ifp = sc->sc_ifp;
   2264  1.1  sommerfe #endif
   2265  1.1  sommerfe 
   2266  1.1  sommerfe #if 0
   2267  1.1  sommerfe 	printf("%s: awi_init_5, st %x\n", sc->sc_dev.dv_xname, status);
   2268  1.1  sommerfe 	awi_card_hexdump(sc, "init_5 CSB", AWI_CSB, 16);
   2269  1.1  sommerfe #endif
   2270  1.1  sommerfe 
   2271  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2272  1.1  sommerfe 		printf("%s: init_rx failed (card unhappy?)\n",
   2273  1.1  sommerfe 		    sc->sc_dev.dv_xname);
   2274  1.1  sommerfe 		awi_reset(sc);
   2275  1.1  sommerfe 		return;
   2276  1.1  sommerfe 	}
   2277  1.1  sommerfe 
   2278  1.1  sommerfe 	sc->sc_rx_data_desc = awi_read_4(sc, AWI_CMD_PARAMS+AWI_CA_IRX_DATA_DESC);
   2279  1.1  sommerfe 	sc->sc_rx_mgt_desc = awi_read_4(sc, AWI_CMD_PARAMS+AWI_CA_IRX_PS_DESC);
   2280  1.1  sommerfe 
   2281  1.1  sommerfe #if 0
   2282  1.1  sommerfe 	printf("%s: data desc %x, mgt desc %x\n", sc->sc_dev.dv_xname,
   2283  1.1  sommerfe 	    sc->sc_rx_data_desc, sc->sc_rx_mgt_desc);
   2284  1.1  sommerfe #endif
   2285  1.1  sommerfe 	awi_restart_scan(sc);
   2286  1.1  sommerfe }
   2287  1.1  sommerfe 
   2288  1.1  sommerfe void awi_restart_scan (sc)
   2289  1.1  sommerfe 	struct awi_softc *sc;
   2290  1.1  sommerfe {
   2291  1.6  sommerfe 	if (sc->sc_ifp->if_flags & IFF_DEBUG) {
   2292  1.6  sommerfe 		printf("%s: starting scan\n", sc->sc_dev.dv_xname);
   2293  1.6  sommerfe 	}
   2294  1.5  sommerfe 	sc->sc_scan_timer = 2;
   2295  1.1  sommerfe 	sc->sc_mgt_timer = 0;
   2296  1.1  sommerfe 	awi_set_timer(sc);
   2297  1.1  sommerfe 
   2298  1.1  sommerfe 	sc->sc_nbindings = 0;
   2299  1.1  sommerfe 	sc->sc_state = AWI_ST_SCAN;
   2300  1.1  sommerfe 	awi_drvstate (sc, AWI_DRV_INFSC);
   2301  1.1  sommerfe 	awi_cmd_scan (sc);
   2302  1.1  sommerfe }
   2303  1.1  sommerfe 
   2304  1.1  sommerfe void
   2305  1.1  sommerfe awi_cmd_scan (sc)
   2306  1.1  sommerfe 	struct awi_softc *sc;
   2307  1.1  sommerfe {
   2308  1.1  sommerfe 
   2309  1.1  sommerfe 	awi_write_2 (sc, AWI_CMD_PARAMS+AWI_CA_SCAN_DURATION,
   2310  1.1  sommerfe 	    sc->sc_scan_duration);
   2311  1.1  sommerfe 	awi_write_1 (sc, AWI_CMD_PARAMS+AWI_CA_SCAN_SET,
   2312  1.1  sommerfe 	    sc->sc_scan_chanset);
   2313  1.1  sommerfe 	awi_write_1 (sc, AWI_CMD_PARAMS+AWI_CA_SCAN_PATTERN,
   2314  1.1  sommerfe 	    sc->sc_scan_pattern);
   2315  1.1  sommerfe 	awi_write_1 (sc, AWI_CMD_PARAMS+AWI_CA_SCAN_IDX, 1);
   2316  1.1  sommerfe 	awi_write_1 (sc, AWI_CMD_PARAMS+AWI_CA_SCAN_SUSP, 0);
   2317  1.1  sommerfe 
   2318  1.1  sommerfe 	sc->sc_completion = awi_cmd_scan_done;
   2319  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_SCAN);
   2320  1.1  sommerfe }
   2321  1.1  sommerfe 
   2322  1.1  sommerfe void
   2323  1.1  sommerfe awi_cmd_scan_done (sc, status)
   2324  1.1  sommerfe 	struct awi_softc *sc;
   2325  1.1  sommerfe 	u_int8_t status;
   2326  1.1  sommerfe {
   2327  1.1  sommerfe #if 0
   2328  1.1  sommerfe 	int erroffset;
   2329  1.1  sommerfe #endif
   2330  1.1  sommerfe 	if (status == AWI_STAT_OK) {
   2331  1.1  sommerfe 		if (sc->sc_scan_chanset > awi_max_chan)
   2332  1.1  sommerfe 			awi_max_chan = sc->sc_scan_chanset;
   2333  1.1  sommerfe 		if (sc->sc_scan_chanset < awi_min_chan)
   2334  1.1  sommerfe 			awi_min_chan = sc->sc_scan_chanset;
   2335  1.1  sommerfe 		if (sc->sc_scan_pattern > awi_max_pattern)
   2336  1.1  sommerfe 			awi_max_pattern = sc->sc_scan_pattern;
   2337  1.1  sommerfe 		if (sc->sc_scan_pattern < awi_min_pattern)
   2338  1.1  sommerfe 			awi_min_pattern = sc->sc_scan_pattern;
   2339  1.1  sommerfe 
   2340  1.1  sommerfe 		return;
   2341  1.1  sommerfe 	}
   2342  1.1  sommerfe #if 0
   2343  1.1  sommerfe 	erroffset = awi_read_1 (sc, AWI_ERROR_OFFSET);
   2344  1.1  sommerfe 	printf("%s: scan failed; erroffset %d\n", sc->sc_dev.dv_xname,
   2345  1.1  sommerfe 	    erroffset);
   2346  1.1  sommerfe #endif
   2347  1.1  sommerfe 	/* wait for response or scan timeout.. */
   2348  1.1  sommerfe }
   2349  1.1  sommerfe 
   2350  1.1  sommerfe void
   2351  1.1  sommerfe awi_scan_next (sc)
   2352  1.1  sommerfe 	struct awi_softc *sc;
   2353  1.1  sommerfe {
   2354  1.1  sommerfe 	sc->sc_scan_pattern++;
   2355  1.1  sommerfe 	if (sc->sc_scan_pattern > IEEEWL_FH_PATTERN_MAX) {
   2356  1.1  sommerfe 		sc->sc_scan_pattern = IEEEWL_FH_PATTERN_MIN;
   2357  1.1  sommerfe 
   2358  1.1  sommerfe 		sc->sc_scan_chanset++;
   2359  1.1  sommerfe 		if (sc->sc_scan_chanset > IEEEWL_FH_CHANSET_MAX)
   2360  1.1  sommerfe 			sc->sc_scan_chanset = IEEEWL_FH_CHANSET_MIN;
   2361  1.1  sommerfe 	}
   2362  1.1  sommerfe #if 0
   2363  1.1  sommerfe 	printf("scan: pattern %x chanset %x\n", sc->sc_scan_pattern,
   2364  1.1  sommerfe 	    sc->sc_scan_chanset);
   2365  1.1  sommerfe #endif
   2366  1.1  sommerfe 
   2367  1.1  sommerfe 	awi_cmd_scan(sc);
   2368  1.1  sommerfe }
   2369  1.1  sommerfe 
   2370  1.1  sommerfe void
   2371  1.1  sommerfe awi_try_sync (sc)
   2372  1.1  sommerfe 	struct awi_softc *sc;
   2373  1.1  sommerfe {
   2374  1.1  sommerfe 	int max_rssi = 0, best = 0;
   2375  1.1  sommerfe 	int i;
   2376  1.1  sommerfe 	struct awi_bss_binding *bp = NULL;
   2377  1.1  sommerfe 
   2378  1.6  sommerfe 	if (sc->sc_ifp->if_flags & IFF_DEBUG) {
   2379  1.6  sommerfe 		printf("%s: looking for best of %d\n",
   2380  1.6  sommerfe 		    sc->sc_dev.dv_xname, sc->sc_nbindings);
   2381  1.6  sommerfe 	}
   2382  1.1  sommerfe 	/* pick one with best rssi */
   2383  1.1  sommerfe 	for (i=0; i<sc->sc_nbindings; i++) {
   2384  1.1  sommerfe 		bp = &sc->sc_bindings[i];
   2385  1.1  sommerfe 
   2386  1.1  sommerfe 		if (bp->rssi > max_rssi) {
   2387  1.1  sommerfe 			max_rssi = bp->rssi;
   2388  1.1  sommerfe 			best = i;
   2389  1.1  sommerfe 		}
   2390  1.1  sommerfe 	}
   2391  1.1  sommerfe 
   2392  1.1  sommerfe 	if (bp == NULL) {
   2393  1.6  sommerfe 		printf("%s: no beacons seen\n", sc->sc_dev.dv_xname);
   2394  1.6  sommerfe 		awi_scan_next(sc);
   2395  1.1  sommerfe 		return;
   2396  1.1  sommerfe 	}
   2397  1.6  sommerfe 
   2398  1.6  sommerfe 	if (sc->sc_ifp->if_flags & IFF_DEBUG) {
   2399  1.6  sommerfe 		printf("%s: best %d\n", sc->sc_dev.dv_xname, best);
   2400  1.6  sommerfe 	}
   2401  1.5  sommerfe 	sc->sc_scan_timer = awi_scan_keepalive;
   2402  1.1  sommerfe 
   2403  1.1  sommerfe 	bp = &sc->sc_bindings[best];
   2404  1.1  sommerfe 	memcpy(&sc->sc_active_bss, bp, sizeof(*bp));
   2405  1.1  sommerfe 	sc->sc_new_bss = 1;
   2406  1.1  sommerfe 
   2407  1.1  sommerfe 	awi_write_1 (sc, AWI_CMD_PARAMS+AWI_CA_SYNC_SET, bp->chanset);
   2408  1.1  sommerfe 	awi_write_1 (sc, AWI_CMD_PARAMS+AWI_CA_SYNC_PATTERN, bp->pattern);
   2409  1.1  sommerfe 	awi_write_1 (sc, AWI_CMD_PARAMS+AWI_CA_SYNC_IDX, bp->index);
   2410  1.1  sommerfe 	awi_write_1 (sc, AWI_CMD_PARAMS+AWI_CA_SYNC_STARTBSS, 0);
   2411  1.1  sommerfe 
   2412  1.1  sommerfe 	awi_write_2 (sc, AWI_CMD_PARAMS+AWI_CA_SYNC_DWELL, bp->dwell_time);
   2413  1.1  sommerfe 	awi_write_2 (sc, AWI_CMD_PARAMS+AWI_CA_SYNC_MBZ, 0);
   2414  1.1  sommerfe 
   2415  1.1  sommerfe 	awi_write_bytes (sc, AWI_CMD_PARAMS+AWI_CA_SYNC_TIMESTAMP,
   2416  1.1  sommerfe 	    bp->bss_timestamp, 8);
   2417  1.1  sommerfe 	awi_write_4 (sc, AWI_CMD_PARAMS+AWI_CA_SYNC_REFTIME, bp->rxtime);
   2418  1.1  sommerfe 
   2419  1.1  sommerfe 	sc->sc_completion = awi_cmd_sync_done;
   2420  1.1  sommerfe 
   2421  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_SYNC);
   2422  1.1  sommerfe 
   2423  1.1  sommerfe }
   2424  1.1  sommerfe 
   2425  1.1  sommerfe void
   2426  1.1  sommerfe awi_cmd_sync_done (sc, status)
   2427  1.1  sommerfe 	struct awi_softc *sc;
   2428  1.1  sommerfe 	u_int8_t status;
   2429  1.1  sommerfe {
   2430  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2431  1.1  sommerfe 		int erroffset = awi_read_1 (sc, AWI_ERROR_OFFSET);
   2432  1.1  sommerfe 		printf("%s: sync_done failed (card unhappy?); erroffset %d\n",
   2433  1.1  sommerfe 		    sc->sc_dev.dv_xname,
   2434  1.1  sommerfe 		    erroffset);
   2435  1.1  sommerfe 		awi_reset(sc);
   2436  1.1  sommerfe 		return;
   2437  1.1  sommerfe 	}
   2438  1.1  sommerfe 
   2439  1.1  sommerfe 	/*
   2440  1.1  sommerfe 	 * at this point, the card should be synchronized with the AP
   2441  1.1  sommerfe 	 * we heard from.  tell the card what BSS and ESS it's running in..
   2442  1.1  sommerfe 	 */
   2443  1.1  sommerfe 
   2444  1.1  sommerfe 	awi_drvstate (sc, AWI_DRV_INFSY);
   2445  1.6  sommerfe 	if (sc->sc_ifp->if_flags & IFF_DEBUG) {
   2446  1.6  sommerfe 		printf("%s: sync done, setting bss/iss parameters\n",
   2447  1.6  sommerfe 		    sc->sc_dev.dv_xname);
   2448  1.6  sommerfe 		awi_hexdump ("bss", sc->sc_active_bss.bss_id, ETHER_ADDR_LEN);
   2449  1.6  sommerfe 		printf("ssid: %s\n", sc->sc_active_bss.ssid);
   2450  1.6  sommerfe 	}
   2451  1.6  sommerfe 
   2452  1.1  sommerfe 	awi_cmd_set_ss (sc);
   2453  1.1  sommerfe }
   2454  1.1  sommerfe 
   2455  1.1  sommerfe 
   2456  1.1  sommerfe void awi_cmd_set_ss (sc)
   2457  1.1  sommerfe 	struct awi_softc *sc;
   2458  1.1  sommerfe {
   2459  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_TYPE, AWI_MIB_MAC_MGT);
   2460  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_SIZE,
   2461  1.1  sommerfe 	    ETHER_ADDR_LEN + AWI_MIB_MGT_ESS_SIZE);
   2462  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_INDEX,
   2463  1.1  sommerfe 	    AWI_MIB_MGT_BSS_ID);
   2464  1.1  sommerfe 
   2465  1.1  sommerfe 	awi_write_bytes(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA,
   2466  1.1  sommerfe 	    sc->sc_active_bss.bss_id, ETHER_ADDR_LEN);
   2467  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA+ETHER_ADDR_LEN,
   2468  1.1  sommerfe 	    0);			/* XXX */
   2469  1.1  sommerfe 	awi_write_1(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA+ETHER_ADDR_LEN+1,
   2470  1.1  sommerfe 	    sc->sc_active_bss.sslen);
   2471  1.1  sommerfe 	awi_write_bytes(sc, AWI_CMD_PARAMS+AWI_CA_MIB_DATA+8,
   2472  1.1  sommerfe 	    sc->sc_active_bss.ssid, AWI_MIB_MGT_ESS_SIZE-2);
   2473  1.1  sommerfe 
   2474  1.1  sommerfe 	sc->sc_completion = awi_cmd_set_ss_done;
   2475  1.1  sommerfe 	awi_cmd (sc, AWI_CMD_SET_MIB);
   2476  1.1  sommerfe }
   2477  1.1  sommerfe 
   2478  1.1  sommerfe void awi_cmd_set_ss_done (sc, status)
   2479  1.1  sommerfe 	struct awi_softc *sc;
   2480  1.1  sommerfe 	u_int8_t status;
   2481  1.1  sommerfe {
   2482  1.1  sommerfe 	if (status != AWI_STAT_OK) {
   2483  1.1  sommerfe 		int erroffset = awi_read_1 (sc, AWI_ERROR_OFFSET);
   2484  1.1  sommerfe 		printf("%s: set_ss_done failed (card unhappy?); erroffset %d\n",
   2485  1.1  sommerfe 		    sc->sc_dev.dv_xname,
   2486  1.1  sommerfe 		    erroffset);
   2487  1.1  sommerfe 		awi_reset(sc);
   2488  1.1  sommerfe 		return;
   2489  1.1  sommerfe 	}
   2490  1.1  sommerfe #if 0
   2491  1.1  sommerfe 	printf("%s: set_ss done\n", sc->sc_dev.dv_xname);
   2492  1.1  sommerfe #endif
   2493  1.1  sommerfe 
   2494  1.1  sommerfe 	awi_running (sc);
   2495  1.1  sommerfe 
   2496  1.1  sommerfe 	/*
   2497  1.1  sommerfe 	 * now, we *should* be getting broadcast frames..
   2498  1.1  sommerfe 	 */
   2499  1.1  sommerfe 	sc->sc_state = AWI_ST_SYNCED;
   2500  1.1  sommerfe 	awi_send_authreq (sc);
   2501  1.1  sommerfe 
   2502  1.1  sommerfe }
   2503  1.1  sommerfe 
   2504  1.1  sommerfe void awi_running (sc)
   2505  1.1  sommerfe 	struct awi_softc *sc;
   2506  1.1  sommerfe 
   2507  1.1  sommerfe {
   2508  1.1  sommerfe 	struct ifnet *ifp = sc->sc_ifp;
   2509  1.1  sommerfe 
   2510  1.1  sommerfe 	/*
   2511  1.1  sommerfe 	 * Who knows what it is to be running?
   2512  1.1  sommerfe 	 * Only he who is running knows..
   2513  1.1  sommerfe 	 */
   2514  1.1  sommerfe 	ifp->if_flags |= IFF_RUNNING;
   2515  1.1  sommerfe 	awi_start(ifp);
   2516  1.1  sommerfe }
   2517  1.1  sommerfe 
   2518  1.1  sommerfe 
   2519  1.1  sommerfe void awi_reset (sc)
   2520  1.1  sommerfe 	struct awi_softc *sc;
   2521  1.1  sommerfe {
   2522  1.1  sommerfe 	printf("%s: reset\n", sc->sc_dev.dv_xname);
   2523  1.1  sommerfe 
   2524  1.1  sommerfe }
   2525