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