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