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