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