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