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