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