Line data Source code
1 : /* $OpenBSD: atw.c,v 1.96 2017/09/22 13:44:00 kevlo Exp $ */
2 : /* $NetBSD: atw.c,v 1.69 2004/07/23 07:07:55 dyoung Exp $ */
3 :
4 : /*-
5 : * Copyright (c) 1998, 1999, 2000, 2002, 2003, 2004 The NetBSD Foundation, Inc.
6 : * All rights reserved.
7 : *
8 : * This code is derived from software contributed to The NetBSD Foundation
9 : * by David Young, by Jason R. Thorpe, and by Charles M. Hannum.
10 : *
11 : * Redistribution and use in source and binary forms, with or without
12 : * modification, are permitted provided that the following conditions
13 : * are met:
14 : * 1. Redistributions of source code must retain the above copyright
15 : * notice, this list of conditions and the following disclaimer.
16 : * 2. Redistributions in binary form must reproduce the above copyright
17 : * notice, this list of conditions and the following disclaimer in the
18 : * documentation and/or other materials provided with the distribution.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 : * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 : * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 : * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 : * POSSIBILITY OF SUCH DAMAGE.
31 : */
32 :
33 : /*
34 : * Device driver for the ADMtek ADM8211 802.11 MAC/BBP.
35 : */
36 :
37 : #include "bpfilter.h"
38 :
39 : #include <sys/param.h>
40 : #include <sys/systm.h>
41 : #include <sys/mbuf.h>
42 : #include <sys/malloc.h>
43 : #include <sys/kernel.h>
44 : #include <sys/socket.h>
45 : #include <sys/ioctl.h>
46 : #include <sys/errno.h>
47 : #include <sys/device.h>
48 : #include <sys/time.h>
49 : #include <sys/endian.h>
50 :
51 : #include <net/if.h>
52 : #include <net/if_media.h>
53 :
54 : #if NBPFILTER > 0
55 : #include <net/bpf.h>
56 : #endif
57 :
58 : #include <netinet/in.h>
59 : #include <netinet/if_ether.h>
60 :
61 : #include <net80211/ieee80211_var.h>
62 : #include <net80211/ieee80211_radiotap.h>
63 :
64 : #include <machine/bus.h>
65 : #include <machine/intr.h>
66 :
67 : #include <dev/ic/atwreg.h>
68 : #include <dev/ic/rf3000reg.h>
69 : #include <dev/ic/si4136reg.h>
70 : #include <dev/ic/atwvar.h>
71 : #include <dev/ic/smc93cx6var.h>
72 :
73 : /* XXX TBD open questions
74 : *
75 : *
76 : * When should I set DSSS PAD in reg 0x15 of RF3000? In 1-2Mbps
77 : * modes only, or all modes (5.5-11 Mbps CCK modes, too?) Does the MAC
78 : * handle this for me?
79 : *
80 : */
81 : /* device attachment
82 : *
83 : * print TOFS[012]
84 : *
85 : * device initialization
86 : *
87 : * clear ATW_FRCTL_MAXPSP to disable max power saving
88 : * set ATW_TXBR_ALCUPDATE to enable ALC
89 : * set TOFS[012]? (hope not)
90 : * disable rx/tx
91 : * set ATW_PAR_SWR (software reset)
92 : * wait for ATW_PAR_SWR clear
93 : * disable interrupts
94 : * ack status register
95 : * enable interrupts
96 : *
97 : * rx/tx initialization
98 : *
99 : * disable rx/tx w/ ATW_NAR_SR, ATW_NAR_ST
100 : * allocate and init descriptor rings
101 : * write ATW_PAR_DSL (descriptor skip length)
102 : * write descriptor base addrs: ATW_TDBD, ATW_TDBP, write ATW_RDB
103 : * write ATW_NAR_SQ for one/both transmit descriptor rings
104 : * write ATW_NAR_SQ for one/both transmit descriptor rings
105 : * enable rx/tx w/ ATW_NAR_SR, ATW_NAR_ST
106 : *
107 : * rx/tx end
108 : *
109 : * stop DMA
110 : * disable rx/tx w/ ATW_NAR_SR, ATW_NAR_ST
111 : * flush tx w/ ATW_NAR_HF
112 : *
113 : * scan
114 : *
115 : * initialize rx/tx
116 : *
117 : * BSS join: (re)association response
118 : *
119 : * set ATW_FRCTL_AID
120 : *
121 : * optimizations ???
122 : *
123 : */
124 :
125 : #define ATW_REFSLAVE /* slavishly do what the reference driver does */
126 :
127 : int atw_bbp_io_enable_delay = 20 * 1000;
128 : int atw_bbp_io_disable_delay = 2 * 1000;
129 : int atw_writewep_delay = 1000;
130 : int atw_beacon_len_adjust = 4;
131 : int atw_dwelltime = 200;
132 : int atw_xindiv2 = 0;
133 :
134 : #ifdef ATW_DEBUG
135 : int atw_debug = 0;
136 :
137 : #define ATW_DPRINTF(x) if (atw_debug > 0) printf x
138 : #define ATW_DPRINTF2(x) if (atw_debug > 1) printf x
139 : #define ATW_DPRINTF3(x) if (atw_debug > 2) printf x
140 : #define DPRINTF(sc, x) if ((sc)->sc_ic.ic_if.if_flags & IFF_DEBUG) printf x
141 : #define DPRINTF2(sc, x) if ((sc)->sc_ic.ic_if.if_flags & IFF_DEBUG) ATW_DPRINTF2(x)
142 : #define DPRINTF3(sc, x) if ((sc)->sc_ic.ic_if.if_flags & IFF_DEBUG) ATW_DPRINTF3(x)
143 : void atw_print_regs(struct atw_softc *, const char *);
144 : void atw_dump_pkt(struct ifnet *, struct mbuf *);
145 :
146 : /* Note well: I never got atw_rf3000_read or atw_si4126_read to work. */
147 : # ifdef ATW_BBPDEBUG
148 : int atw_rf3000_read(struct atw_softc *sc, u_int, u_int *);
149 : void atw_rf3000_print(struct atw_softc *);
150 : # endif /* ATW_BBPDEBUG */
151 :
152 : # ifdef ATW_SYNDEBUG
153 : int atw_si4126_read(struct atw_softc *, u_int, u_int *);
154 : void atw_si4126_print(struct atw_softc *);
155 : # endif /* ATW_SYNDEBUG */
156 :
157 : #else
158 : #define ATW_DPRINTF(x)
159 : #define ATW_DPRINTF2(x)
160 : #define ATW_DPRINTF3(x)
161 : #define DPRINTF(sc, x) /* nothing */
162 : #define DPRINTF2(sc, x) /* nothing */
163 : #define DPRINTF3(sc, x) /* nothing */
164 : #endif
165 :
166 : #ifdef ATW_STATS
167 : void atw_print_stats(struct atw_softc *);
168 : #endif
169 :
170 : const char *atw_printmac(u_int8_t);
171 :
172 : /* ifnet methods */
173 : void atw_start(struct ifnet *);
174 : void atw_watchdog(struct ifnet *);
175 : int atw_ioctl(struct ifnet *, u_long, caddr_t);
176 : int atw_init(struct ifnet *);
177 : void atw_stop(struct ifnet *, int);
178 :
179 : /* Rx/Tx process */
180 : void atw_rxdrain(struct atw_softc *);
181 : void atw_txdrain(struct atw_softc *);
182 : int atw_add_rxbuf(struct atw_softc *, int);
183 : void atw_idle(struct atw_softc *, u_int32_t);
184 :
185 : /* Device (de)activation and power state */
186 : void atw_disable(struct atw_softc *);
187 : void atw_reset(struct atw_softc *);
188 :
189 : /* Interrupt handlers */
190 : void atw_rxintr(struct atw_softc *);
191 : void atw_txintr(struct atw_softc *);
192 : void atw_linkintr(struct atw_softc *, u_int32_t);
193 :
194 : /* 802.11 state machine */
195 : int atw_newstate(struct ieee80211com *, enum ieee80211_state, int);
196 : int atw_tune(struct atw_softc *);
197 : #ifndef IEEE80211_STA_ONLY
198 : void atw_recv_mgmt(struct ieee80211com *, struct mbuf *,
199 : struct ieee80211_node *, struct ieee80211_rxinfo *, int);
200 : #endif
201 : void atw_next_scan(void *);
202 :
203 : /* Device initialization */
204 : void atw_wcsr_init(struct atw_softc *);
205 : void atw_cmdr_init(struct atw_softc *);
206 : void atw_tofs2_init(struct atw_softc *);
207 : void atw_txlmt_init(struct atw_softc *);
208 : void atw_test1_init(struct atw_softc *);
209 : void atw_rf_reset(struct atw_softc *);
210 : void atw_cfp_init(struct atw_softc *);
211 : void atw_tofs0_init(struct atw_softc *);
212 : void atw_ifs_init(struct atw_softc *);
213 : void atw_response_times_init(struct atw_softc *);
214 : void atw_bbp_io_init(struct atw_softc *);
215 : void atw_nar_init(struct atw_softc *);
216 :
217 : /* RAM/ROM utilities */
218 : void atw_clear_sram(struct atw_softc *);
219 : void atw_write_sram(struct atw_softc *, u_int, u_int8_t *, u_int);
220 : int atw_read_srom(struct atw_softc *);
221 :
222 : /* BSS setup */
223 : void atw_predict_beacon(struct atw_softc *sc);
224 : void atw_start_beacon(struct atw_softc *, int);
225 : void atw_write_bssid(struct atw_softc *);
226 : void atw_write_ssid(struct atw_softc *);
227 : void atw_write_sup_rates(struct atw_softc *);
228 : void atw_write_wep(struct atw_softc *);
229 :
230 : /* Media */
231 : int atw_media_change(struct ifnet *);
232 : void atw_media_status(struct ifnet *, struct ifmediareq *);
233 :
234 : void atw_filter_setup(struct atw_softc *);
235 :
236 : /* 802.11 utilities */
237 : struct ieee80211_node *atw_node_alloc(struct ieee80211com *);
238 : void atw_node_free(struct ieee80211com *, struct ieee80211_node *);
239 : static __inline uint32_t atw_last_even_tsft(uint32_t, uint32_t, uint32_t);
240 : uint64_t atw_get_tsft(struct atw_softc *sc);
241 : void atw_change_ibss(struct atw_softc *);
242 : int atw_compute_duration1(int, int, uint32_t, int, struct atw_duration *);
243 : int atw_compute_duration(struct ieee80211_frame *, int, uint32_t, int,
244 : int, struct atw_duration *, struct atw_duration *, int *, int);
245 :
246 : /*
247 : * Tuner/transceiver/modem
248 : */
249 : void atw_bbp_io_enable(struct atw_softc *, int);
250 :
251 : /* RFMD RF3000 Baseband Processor */
252 : int atw_rf3000_init(struct atw_softc *);
253 : int atw_rf3000_tune(struct atw_softc *, u_int);
254 : int atw_rf3000_write(struct atw_softc *, u_int, u_int);
255 :
256 : /* Silicon Laboratories Si4126 RF/IF Synthesizer */
257 : void atw_si4126_tune(struct atw_softc *, u_int);
258 : void atw_si4126_write(struct atw_softc *, u_int, u_int);
259 : void atw_si4126_init(struct atw_softc *);
260 :
261 : const struct atw_txthresh_tab atw_txthresh_tab_lo[] = {
262 : { ATW_NAR_TR_L64, "64 bytes" },
263 : { ATW_NAR_TR_L160, "160 bytes" },
264 : { ATW_NAR_TR_L192, "192 bytes" },
265 : { ATW_NAR_SF, "store and forward" },
266 : { 0, NULL }
267 : };
268 : const struct atw_txthresh_tab atw_txthresh_tab_hi[] = {
269 : { ATW_NAR_TR_H96, "96 bytes" },
270 : { ATW_NAR_TR_H288, "288 bytes" },
271 : { ATW_NAR_TR_H544, "544 bytes" },
272 : { ATW_NAR_SF, "store and forward" },
273 : { 0, NULL }
274 : };
275 :
276 : struct cfdriver atw_cd = {
277 : NULL, "atw", DV_IFNET
278 : };
279 :
280 : static const u_int atw_rfmd2958_ifn[] = {
281 : 0x22bd, 0x22d2, 0x22e8, 0x22fe, 0x2314, 0x232a, 0x2340,
282 : 0x2355, 0x236b, 0x2381, 0x2397, 0x23ad, 0x23c2, 0x23f7
283 : };
284 :
285 : static const u_int atw_rfmd2958_rf1r[] = {
286 : 0x05d17, 0x3a2e8, 0x2e8ba, 0x22e8b, 0x1745d, 0x0ba2e, 0x00000,
287 : 0x345d1, 0x28ba2, 0x1d174, 0x11745, 0x05d17, 0x3a2e8, 0x11745
288 : };
289 :
290 :
291 : #ifdef ATW_DEBUG
292 :
293 : const char *atw_tx_state[] = {
294 : "STOPPED",
295 : "RUNNING - read descriptor",
296 : "RUNNING - transmitting",
297 : "RUNNING - filling fifo", /* XXX */
298 : "SUSPENDED",
299 : "RUNNING -- write descriptor",
300 : "RUNNING -- write last descriptor",
301 : "RUNNING - fifo full"
302 : };
303 :
304 : const char *atw_rx_state[] = {
305 : "STOPPED",
306 : "RUNNING - read descriptor",
307 : "RUNNING - check this packet, pre-fetch next",
308 : "RUNNING - wait for reception",
309 : "SUSPENDED",
310 : "RUNNING - write descriptor",
311 : "RUNNING - flush fifo",
312 : "RUNNING - fifo drain"
313 : };
314 :
315 : #endif
316 :
317 : /*
318 : * atw_enable:
319 : *
320 : * Enable the ADM8211 chip.
321 : */
322 : int
323 0 : atw_enable(struct atw_softc *sc)
324 : {
325 :
326 0 : if (ATW_IS_ENABLED(sc) == 0) {
327 0 : if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
328 0 : printf("%s: device enable failed\n",
329 0 : sc->sc_dev.dv_xname);
330 0 : return (EIO);
331 : }
332 0 : sc->sc_flags |= ATWF_ENABLED;
333 0 : }
334 0 : return (0);
335 0 : }
336 :
337 : /*
338 : * atw_disable:
339 : *
340 : * Disable the ADM8211 chip.
341 : */
342 : void
343 0 : atw_disable(struct atw_softc *sc)
344 : {
345 0 : if (!ATW_IS_ENABLED(sc))
346 : return;
347 0 : if (sc->sc_disable != NULL)
348 0 : (*sc->sc_disable)(sc);
349 0 : sc->sc_flags &= ~ATWF_ENABLED;
350 0 : }
351 :
352 : /* Returns -1 on failure. */
353 : int
354 0 : atw_read_srom(struct atw_softc *sc)
355 : {
356 0 : struct seeprom_descriptor sd;
357 : u_int32_t test0, fail_bits;
358 :
359 0 : (void)memset(&sd, 0, sizeof(sd));
360 :
361 0 : test0 = ATW_READ(sc, ATW_TEST0);
362 :
363 0 : switch (sc->sc_rev) {
364 : case ATW_REVISION_BA:
365 : case ATW_REVISION_CA:
366 : fail_bits = ATW_TEST0_EPNE;
367 0 : break;
368 : default:
369 : fail_bits = ATW_TEST0_EPNE|ATW_TEST0_EPSNM;
370 0 : break;
371 : }
372 0 : if ((test0 & fail_bits) != 0) {
373 0 : printf("%s: bad or missing/bad SROM\n", sc->sc_dev.dv_xname);
374 0 : return -1;
375 : }
376 :
377 0 : switch (test0 & ATW_TEST0_EPTYP_MASK) {
378 : case ATW_TEST0_EPTYP_93c66:
379 : ATW_DPRINTF(("%s: 93c66 SROM\n", sc->sc_dev.dv_xname));
380 0 : sc->sc_sromsz = 512;
381 0 : sd.sd_chip = C56_66;
382 0 : break;
383 : case ATW_TEST0_EPTYP_93c46:
384 : ATW_DPRINTF(("%s: 93c46 SROM\n", sc->sc_dev.dv_xname));
385 0 : sc->sc_sromsz = 128;
386 0 : sd.sd_chip = C46;
387 0 : break;
388 : default:
389 : printf("%s: unknown SROM type %d\n", sc->sc_dev.dv_xname,
390 : MASK_AND_RSHIFT(test0, ATW_TEST0_EPTYP_MASK));
391 : return -1;
392 : }
393 :
394 0 : sc->sc_srom = malloc(sc->sc_sromsz, M_DEVBUF, M_NOWAIT | M_ZERO);
395 0 : if (sc->sc_srom == NULL) {
396 0 : printf("%s: unable to allocate SROM buffer\n",
397 0 : sc->sc_dev.dv_xname);
398 0 : return -1;
399 : }
400 :
401 : /*
402 : * ADM8211 has a single 32-bit register for controlling the
403 : * 93cx6 SROM. Bit SRS enables the serial port. There is no
404 : * "ready" bit. The ADM8211 input/output sense is the reverse
405 : * of read_seeprom's.
406 : */
407 0 : sd.sd_tag = sc->sc_st;
408 0 : sd.sd_bsh = sc->sc_sh;
409 0 : sd.sd_regsize = 4;
410 0 : sd.sd_control_offset = ATW_SPR;
411 0 : sd.sd_status_offset = ATW_SPR;
412 0 : sd.sd_dataout_offset = ATW_SPR;
413 0 : sd.sd_CK = ATW_SPR_SCLK;
414 0 : sd.sd_CS = ATW_SPR_SCS;
415 0 : sd.sd_DI = ATW_SPR_SDO;
416 0 : sd.sd_DO = ATW_SPR_SDI;
417 0 : sd.sd_MS = ATW_SPR_SRS;
418 0 : sd.sd_RDY = 0;
419 :
420 0 : if (!read_seeprom(&sd, sc->sc_srom, 0, sc->sc_sromsz/2)) {
421 0 : printf("%s: could not read SROM\n", sc->sc_dev.dv_xname);
422 0 : free(sc->sc_srom, M_DEVBUF, sc->sc_sromsz);
423 0 : return -1;
424 : }
425 : #ifdef ATW_DEBUG
426 : {
427 : int i;
428 : ATW_DPRINTF(("\nSerial EEPROM:\n\t"));
429 : for (i = 0; i < sc->sc_sromsz/2; i = i + 1) {
430 : if (((i % 8) == 0) && (i != 0)) {
431 : ATW_DPRINTF(("\n\t"));
432 : }
433 : ATW_DPRINTF((" 0x%x", sc->sc_srom[i]));
434 : }
435 : ATW_DPRINTF(("\n"));
436 : }
437 : #endif /* ATW_DEBUG */
438 0 : return 0;
439 0 : }
440 :
441 : #ifdef ATW_DEBUG
442 : void
443 : atw_print_regs(struct atw_softc *sc, const char *where)
444 : {
445 : #define PRINTREG(sc, reg) \
446 : ATW_DPRINTF2(("%s: reg[ " #reg " / %03x ] = %08x\n", \
447 : sc->sc_dev.dv_xname, reg, ATW_READ(sc, reg)))
448 :
449 : ATW_DPRINTF2(("%s: %s\n", sc->sc_dev.dv_xname, where));
450 :
451 : PRINTREG(sc, ATW_PAR);
452 : PRINTREG(sc, ATW_FRCTL);
453 : PRINTREG(sc, ATW_TDR);
454 : PRINTREG(sc, ATW_WTDP);
455 : PRINTREG(sc, ATW_RDR);
456 : PRINTREG(sc, ATW_WRDP);
457 : PRINTREG(sc, ATW_RDB);
458 : PRINTREG(sc, ATW_CSR3A);
459 : PRINTREG(sc, ATW_TDBD);
460 : PRINTREG(sc, ATW_TDBP);
461 : PRINTREG(sc, ATW_STSR);
462 : PRINTREG(sc, ATW_CSR5A);
463 : PRINTREG(sc, ATW_NAR);
464 : PRINTREG(sc, ATW_CSR6A);
465 : PRINTREG(sc, ATW_IER);
466 : PRINTREG(sc, ATW_CSR7A);
467 : PRINTREG(sc, ATW_LPC);
468 : PRINTREG(sc, ATW_TEST1);
469 : PRINTREG(sc, ATW_SPR);
470 : PRINTREG(sc, ATW_TEST0);
471 : PRINTREG(sc, ATW_WCSR);
472 : PRINTREG(sc, ATW_WPDR);
473 : PRINTREG(sc, ATW_GPTMR);
474 : PRINTREG(sc, ATW_GPIO);
475 : PRINTREG(sc, ATW_BBPCTL);
476 : PRINTREG(sc, ATW_SYNCTL);
477 : PRINTREG(sc, ATW_PLCPHD);
478 : PRINTREG(sc, ATW_MMIWADDR);
479 : PRINTREG(sc, ATW_MMIRADDR1);
480 : PRINTREG(sc, ATW_MMIRADDR2);
481 : PRINTREG(sc, ATW_TXBR);
482 : PRINTREG(sc, ATW_CSR15A);
483 : PRINTREG(sc, ATW_ALCSTAT);
484 : PRINTREG(sc, ATW_TOFS2);
485 : PRINTREG(sc, ATW_CMDR);
486 : PRINTREG(sc, ATW_PCIC);
487 : PRINTREG(sc, ATW_PMCSR);
488 : PRINTREG(sc, ATW_PAR0);
489 : PRINTREG(sc, ATW_PAR1);
490 : PRINTREG(sc, ATW_MAR0);
491 : PRINTREG(sc, ATW_MAR1);
492 : PRINTREG(sc, ATW_ATIMDA0);
493 : PRINTREG(sc, ATW_ABDA1);
494 : PRINTREG(sc, ATW_BSSID0);
495 : PRINTREG(sc, ATW_TXLMT);
496 : PRINTREG(sc, ATW_MIBCNT);
497 : PRINTREG(sc, ATW_BCNT);
498 : PRINTREG(sc, ATW_TSFTH);
499 : PRINTREG(sc, ATW_TSC);
500 : PRINTREG(sc, ATW_SYNRF);
501 : PRINTREG(sc, ATW_BPLI);
502 : PRINTREG(sc, ATW_CAP0);
503 : PRINTREG(sc, ATW_CAP1);
504 : PRINTREG(sc, ATW_RMD);
505 : PRINTREG(sc, ATW_CFPP);
506 : PRINTREG(sc, ATW_TOFS0);
507 : PRINTREG(sc, ATW_TOFS1);
508 : PRINTREG(sc, ATW_IFST);
509 : PRINTREG(sc, ATW_RSPT);
510 : PRINTREG(sc, ATW_TSFTL);
511 : PRINTREG(sc, ATW_WEPCTL);
512 : PRINTREG(sc, ATW_WESK);
513 : PRINTREG(sc, ATW_WEPCNT);
514 : PRINTREG(sc, ATW_MACTEST);
515 : PRINTREG(sc, ATW_FER);
516 : PRINTREG(sc, ATW_FEMR);
517 : PRINTREG(sc, ATW_FPSR);
518 : PRINTREG(sc, ATW_FFER);
519 : #undef PRINTREG
520 : }
521 : #endif /* ATW_DEBUG */
522 :
523 : const char*
524 0 : atw_printmac(u_int8_t rev) {
525 0 : switch (rev) {
526 : case ATW_REVISION_AB:
527 0 : return "ADM8211AB";
528 : case ATW_REVISION_AF:
529 0 : return "ADM8211AF";
530 : case ATW_REVISION_BA:
531 0 : return "ADM8211BA";
532 : case ATW_REVISION_CA:
533 0 : return "ADM8211CA";
534 : default:
535 0 : return "unknown";
536 : }
537 0 : }
538 :
539 : /*
540 : * Finish attaching an ADMtek ADM8211 MAC. Called by bus-specific front-end.
541 : */
542 : void
543 0 : atw_attach(struct atw_softc *sc)
544 : {
545 : static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
546 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
547 : };
548 0 : struct ieee80211com *ic = &sc->sc_ic;
549 0 : struct ifnet *ifp = &ic->ic_if;
550 : int country_code, error, i, srom_major;
551 : u_int32_t reg;
552 : static const char *type_strings[] = {"Intersil (not supported)",
553 : "RFMD", "Marvel (not supported)"};
554 :
555 0 : sc->sc_txth = atw_txthresh_tab_lo;
556 :
557 0 : SIMPLEQ_INIT(&sc->sc_txfreeq);
558 0 : SIMPLEQ_INIT(&sc->sc_txdirtyq);
559 :
560 : #ifdef ATW_DEBUG
561 : atw_print_regs(sc, "atw_attach");
562 : #endif /* ATW_DEBUG */
563 :
564 : /*
565 : * Allocate the control data structures, and create and load the
566 : * DMA map for it.
567 : */
568 0 : if ((error = bus_dmamem_alloc(sc->sc_dmat,
569 : sizeof(struct atw_control_data), PAGE_SIZE, 0, &sc->sc_cdseg,
570 0 : 1, &sc->sc_cdnseg, 0)) != 0) {
571 0 : printf("%s: unable to allocate control data, error = %d\n",
572 0 : sc->sc_dev.dv_xname, error);
573 0 : goto fail_0;
574 : }
575 :
576 0 : if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg,
577 : sizeof(struct atw_control_data), (caddr_t *)&sc->sc_control_data,
578 0 : BUS_DMA_COHERENT)) != 0) {
579 0 : printf("%s: unable to map control data, error = %d\n",
580 0 : sc->sc_dev.dv_xname, error);
581 0 : goto fail_1;
582 : }
583 :
584 0 : if ((error = bus_dmamap_create(sc->sc_dmat,
585 : sizeof(struct atw_control_data), 1,
586 0 : sizeof(struct atw_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
587 0 : printf("%s: unable to create control data DMA map, "
588 0 : "error = %d\n", sc->sc_dev.dv_xname, error);
589 0 : goto fail_2;
590 : }
591 :
592 0 : if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
593 : sc->sc_control_data, sizeof(struct atw_control_data), NULL,
594 0 : 0)) != 0) {
595 0 : printf("%s: unable to load control data DMA map, error = %d\n",
596 0 : sc->sc_dev.dv_xname, error);
597 0 : goto fail_3;
598 : }
599 :
600 : /*
601 : * Create the transmit buffer DMA maps.
602 : */
603 0 : sc->sc_ntxsegs = ATW_NTXSEGS;
604 0 : for (i = 0; i < ATW_TXQUEUELEN; i++) {
605 0 : if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
606 : sc->sc_ntxsegs, MCLBYTES, 0, 0,
607 0 : &sc->sc_txsoft[i].txs_dmamap)) != 0) {
608 0 : printf("%s: unable to create tx DMA map %d, "
609 0 : "error = %d\n", sc->sc_dev.dv_xname, i, error);
610 0 : goto fail_4;
611 : }
612 : }
613 :
614 : /*
615 : * Create the receive buffer DMA maps.
616 : */
617 0 : for (i = 0; i < ATW_NRXDESC; i++) {
618 0 : if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
619 0 : MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
620 0 : printf("%s: unable to create rx DMA map %d, "
621 0 : "error = %d\n", sc->sc_dev.dv_xname, i, error);
622 : goto fail_5;
623 : }
624 : }
625 0 : for (i = 0; i < ATW_NRXDESC; i++) {
626 0 : sc->sc_rxsoft[i].rxs_mbuf = NULL;
627 : }
628 :
629 0 : switch (sc->sc_rev) {
630 : case ATW_REVISION_AB:
631 : case ATW_REVISION_AF:
632 0 : sc->sc_sramlen = ATW_SRAM_A_SIZE;
633 0 : break;
634 : case ATW_REVISION_BA:
635 : case ATW_REVISION_CA:
636 0 : sc->sc_sramlen = ATW_SRAM_B_SIZE;
637 0 : break;
638 : }
639 :
640 : /* Reset the chip to a known state. */
641 0 : atw_reset(sc);
642 :
643 0 : if (atw_read_srom(sc) == -1)
644 0 : return;
645 :
646 0 : sc->sc_rftype = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CSR20],
647 : ATW_SR_RFTYPE_MASK);
648 :
649 0 : sc->sc_bbptype = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CSR20],
650 : ATW_SR_BBPTYPE_MASK);
651 :
652 0 : if (sc->sc_rftype >= nitems(type_strings)) {
653 0 : printf("%s: unknown RF\n", sc->sc_dev.dv_xname);
654 0 : return;
655 : }
656 0 : if (sc->sc_bbptype >= nitems(type_strings)) {
657 0 : printf("%s: unknown BBP\n", sc->sc_dev.dv_xname);
658 0 : return;
659 : }
660 :
661 0 : printf("%s: MAC %s, BBP %s, RF %s", sc->sc_dev.dv_xname,
662 0 : atw_printmac(sc->sc_rev), type_strings[sc->sc_bbptype],
663 0 : type_strings[sc->sc_rftype]);
664 :
665 : /* XXX There exists a Linux driver which seems to use RFType = 0 for
666 : * MARVEL. My bug, or theirs?
667 : */
668 :
669 0 : reg = LSHIFT(sc->sc_rftype, ATW_SYNCTL_RFTYPE_MASK);
670 :
671 0 : switch (sc->sc_rftype) {
672 : case ATW_RFTYPE_INTERSIL:
673 0 : reg |= ATW_SYNCTL_CS1;
674 0 : break;
675 : case ATW_RFTYPE_RFMD:
676 0 : reg |= ATW_SYNCTL_CS0;
677 0 : break;
678 : case ATW_RFTYPE_MARVEL:
679 : break;
680 : }
681 :
682 0 : sc->sc_synctl_rd = reg | ATW_SYNCTL_RD;
683 0 : sc->sc_synctl_wr = reg | ATW_SYNCTL_WR;
684 :
685 0 : reg = LSHIFT(sc->sc_bbptype, ATW_BBPCTL_TYPE_MASK);
686 :
687 0 : switch (sc->sc_bbptype) {
688 : case ATW_BBPTYPE_INTERSIL:
689 0 : reg |= ATW_BBPCTL_TWI;
690 0 : break;
691 : case ATW_BBPTYPE_RFMD:
692 0 : reg |= ATW_BBPCTL_RF3KADDR_ADDR | ATW_BBPCTL_NEGEDGE_DO |
693 : ATW_BBPCTL_CCA_ACTLO;
694 0 : break;
695 : case ATW_BBPTYPE_MARVEL:
696 : break;
697 : case ATW_C_BBPTYPE_RFMD:
698 0 : printf("%s: ADM8211C MAC/RFMD BBP not supported yet.\n",
699 : sc->sc_dev.dv_xname);
700 0 : break;
701 : }
702 :
703 0 : sc->sc_bbpctl_wr = reg | ATW_BBPCTL_WR;
704 0 : sc->sc_bbpctl_rd = reg | ATW_BBPCTL_RD;
705 :
706 : /*
707 : * From this point forward, the attachment cannot fail. A failure
708 : * before this point releases all resources that may have been
709 : * allocated.
710 : */
711 0 : sc->sc_flags |= ATWF_ATTACHED /* | ATWF_RTSCTS */;
712 :
713 : ATW_DPRINTF((" SROM MAC %04x%04x%04x",
714 : htole16(sc->sc_srom[ATW_SR_MAC00]),
715 : htole16(sc->sc_srom[ATW_SR_MAC01]),
716 : htole16(sc->sc_srom[ATW_SR_MAC10])));
717 :
718 0 : srom_major = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_FORMAT_VERSION],
719 : ATW_SR_MAJOR_MASK);
720 :
721 0 : if (srom_major < 2)
722 0 : sc->sc_rf3000_options1 = 0;
723 0 : else if (sc->sc_rev == ATW_REVISION_BA) {
724 0 : sc->sc_rf3000_options1 =
725 0 : MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CR28_CR03],
726 : ATW_SR_CR28_MASK);
727 0 : } else
728 0 : sc->sc_rf3000_options1 = 0;
729 :
730 0 : sc->sc_rf3000_options2 = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CTRY_CR29],
731 : ATW_SR_CR29_MASK);
732 :
733 0 : country_code = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CTRY_CR29],
734 : ATW_SR_CTRY_MASK);
735 :
736 : #define ADD_CHANNEL(_ic, _chan) do { \
737 : _ic->ic_channels[_chan].ic_flags = IEEE80211_CHAN_B; \
738 : _ic->ic_channels[_chan].ic_freq = \
739 : ieee80211_ieee2mhz(_chan, _ic->ic_channels[_chan].ic_flags);\
740 : } while (0)
741 :
742 : /* Find available channels */
743 0 : switch (country_code) {
744 : case COUNTRY_MMK2: /* 1-14 */
745 0 : ADD_CHANNEL(ic, 14);
746 : /*FALLTHROUGH*/
747 : case COUNTRY_ETSI: /* 1-13 */
748 0 : for (i = 1; i <= 13; i++)
749 0 : ADD_CHANNEL(ic, i);
750 : break;
751 : case COUNTRY_FCC: /* 1-11 */
752 : case COUNTRY_IC: /* 1-11 */
753 0 : for (i = 1; i <= 11; i++)
754 0 : ADD_CHANNEL(ic, i);
755 : break;
756 : case COUNTRY_MMK: /* 14 */
757 0 : ADD_CHANNEL(ic, 14);
758 0 : break;
759 : case COUNTRY_FRANCE: /* 10-13 */
760 0 : for (i = 10; i <= 13; i++)
761 0 : ADD_CHANNEL(ic, i);
762 : break;
763 : default: /* assume channels 10-11 */
764 : case COUNTRY_SPAIN: /* 10-11 */
765 0 : for (i = 10; i <= 11; i++)
766 0 : ADD_CHANNEL(ic, i);
767 : break;
768 : }
769 :
770 : /* Read the MAC address. */
771 0 : reg = ATW_READ(sc, ATW_PAR0);
772 0 : ic->ic_myaddr[0] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB0_MASK);
773 0 : ic->ic_myaddr[1] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB1_MASK);
774 0 : ic->ic_myaddr[2] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB2_MASK);
775 0 : ic->ic_myaddr[3] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB3_MASK);
776 0 : reg = ATW_READ(sc, ATW_PAR1);
777 0 : ic->ic_myaddr[4] = MASK_AND_RSHIFT(reg, ATW_PAR1_PAB4_MASK);
778 0 : ic->ic_myaddr[5] = MASK_AND_RSHIFT(reg, ATW_PAR1_PAB5_MASK);
779 :
780 0 : if (IEEE80211_ADDR_EQ(ic->ic_myaddr, empty_macaddr)) {
781 0 : printf(" could not get mac address, attach failed\n");
782 0 : return;
783 : }
784 :
785 0 : printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
786 :
787 0 : memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
788 0 : ifp->if_softc = sc;
789 0 : ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
790 0 : ifp->if_ioctl = atw_ioctl;
791 0 : ifp->if_start = atw_start;
792 0 : ifp->if_watchdog = atw_watchdog;
793 :
794 0 : ic->ic_phytype = IEEE80211_T_DS;
795 0 : ic->ic_opmode = IEEE80211_M_STA;
796 0 : ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
797 : #ifndef IEEE80211_STA_ONLY
798 0 : ic->ic_caps |= IEEE80211_C_IBSS;
799 : #endif
800 0 : ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
801 :
802 : /*
803 : * Call MI attach routines.
804 : */
805 :
806 0 : if_attach(ifp);
807 0 : ieee80211_ifattach(ifp);
808 :
809 0 : sc->sc_newstate = ic->ic_newstate;
810 0 : ic->ic_newstate = atw_newstate;
811 :
812 : #ifndef IEEE80211_STA_ONLY
813 0 : sc->sc_recv_mgmt = ic->ic_recv_mgmt;
814 0 : ic->ic_recv_mgmt = atw_recv_mgmt;
815 : #endif
816 :
817 0 : sc->sc_node_free = ic->ic_node_free;
818 0 : ic->ic_node_free = atw_node_free;
819 :
820 0 : sc->sc_node_alloc = ic->ic_node_alloc;
821 0 : ic->ic_node_alloc = atw_node_alloc;
822 :
823 : /* possibly we should fill in our own sc_send_prresp, since
824 : * the ADM8211 is probably sending probe responses in ad hoc
825 : * mode.
826 : */
827 :
828 : /* complete initialization */
829 0 : ieee80211_media_init(ifp, atw_media_change, atw_media_status);
830 0 : timeout_set(&sc->sc_scan_to, atw_next_scan, sc);
831 :
832 : #if NBPFILTER > 0
833 0 : bpfattach(&sc->sc_radiobpf, ifp, DLT_IEEE802_11_RADIO,
834 : sizeof(struct ieee80211_frame) + 64);
835 : #endif
836 :
837 0 : memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
838 0 : sc->sc_rxtap.ar_ihdr.it_len = sizeof(sc->sc_rxtapu);
839 0 : sc->sc_rxtap.ar_ihdr.it_present = ATW_RX_RADIOTAP_PRESENT;
840 :
841 0 : memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
842 0 : sc->sc_txtap.at_ihdr.it_len = sizeof(sc->sc_txtapu);
843 0 : sc->sc_txtap.at_ihdr.it_present = ATW_TX_RADIOTAP_PRESENT;
844 :
845 0 : return;
846 :
847 : /*
848 : * Free any resources we've allocated during the failed attach
849 : * attempt. Do this in reverse order and fall through.
850 : */
851 : fail_5:
852 0 : for (i = 0; i < ATW_NRXDESC; i++) {
853 0 : if (sc->sc_rxsoft[i].rxs_dmamap == NULL)
854 : continue;
855 0 : bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxsoft[i].rxs_dmamap);
856 0 : }
857 : fail_4:
858 0 : for (i = 0; i < ATW_TXQUEUELEN; i++) {
859 0 : if (sc->sc_txsoft[i].txs_dmamap == NULL)
860 : continue;
861 0 : bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].txs_dmamap);
862 0 : }
863 0 : bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
864 : fail_3:
865 0 : bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
866 : fail_2:
867 0 : bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
868 : sizeof(struct atw_control_data));
869 : fail_1:
870 0 : bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
871 : fail_0:
872 0 : return;
873 0 : }
874 :
875 : struct ieee80211_node *
876 0 : atw_node_alloc(struct ieee80211com *ic)
877 : {
878 0 : struct atw_softc *sc = (struct atw_softc *)ic->ic_if.if_softc;
879 0 : struct ieee80211_node *ni = (*sc->sc_node_alloc)(ic);
880 :
881 : DPRINTF(sc, ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni));
882 0 : return ni;
883 : }
884 :
885 : void
886 0 : atw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
887 : {
888 0 : struct atw_softc *sc = (struct atw_softc *)ic->ic_if.if_softc;
889 :
890 : DPRINTF(sc, ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni,
891 : ether_sprintf(ni->ni_bssid)));
892 0 : (*sc->sc_node_free)(ic, ni);
893 0 : }
894 :
895 :
896 : static void
897 0 : atw_test1_reset(struct atw_softc *sc)
898 : {
899 0 : switch (sc->sc_rev) {
900 : case ATW_REVISION_BA:
901 : if (1 /* XXX condition on transceiver type */) {
902 0 : ATW_SET(sc, ATW_TEST1, ATW_TEST1_TESTMODE_MONITOR);
903 : }
904 0 : break;
905 : case ATW_REVISION_CA:
906 0 : ATW_CLR(sc, ATW_TEST1, ATW_TEST1_TESTMODE_MASK);
907 0 : break;
908 : default:
909 : break;
910 : }
911 0 : }
912 :
913 : /*
914 : * atw_reset:
915 : *
916 : * Perform a soft reset on the ADM8211.
917 : */
918 : void
919 0 : atw_reset(struct atw_softc *sc)
920 : {
921 : int i;
922 : uint32_t lpc;
923 :
924 0 : ATW_WRITE(sc, ATW_NAR, 0x0);
925 0 : DELAY(20 * 1000);
926 :
927 : /* Reference driver has a cryptic remark indicating that this might
928 : * power-on the chip. I know that it turns off power-saving....
929 : */
930 0 : ATW_WRITE(sc, ATW_FRCTL, 0x0);
931 :
932 0 : ATW_WRITE(sc, ATW_PAR, ATW_PAR_SWR);
933 :
934 0 : for (i = 0; i < 50; i++) {
935 0 : if (ATW_READ(sc, ATW_PAR) == 0)
936 : break;
937 0 : DELAY(1000);
938 : }
939 :
940 : /* ... and then pause 100ms longer for good measure. */
941 0 : DELAY(100 * 1000);
942 :
943 : DPRINTF2(sc, ("%s: atw_reset %d iterations\n", sc->sc_dev.dv_xname, i));
944 :
945 0 : if (ATW_ISSET(sc, ATW_PAR, ATW_PAR_SWR))
946 0 : printf("%s: reset failed to complete\n", sc->sc_dev.dv_xname);
947 :
948 0 : atw_test1_reset(sc);
949 : /*
950 : * Initialize the PCI Access Register.
951 : */
952 0 : sc->sc_busmode = ATW_PAR_PBL_8DW;
953 :
954 0 : ATW_WRITE(sc, ATW_PAR, sc->sc_busmode);
955 : DPRINTF(sc, ("%s: ATW_PAR %08x busmode %08x\n", sc->sc_dev.dv_xname,
956 : ATW_READ(sc, ATW_PAR), sc->sc_busmode));
957 :
958 : /* Turn off maximum power saving, etc.
959 : *
960 : * XXX Following example of reference driver, should I set
961 : * an AID of 1? It didn't seem to help....
962 : */
963 0 : ATW_WRITE(sc, ATW_FRCTL, 0x0);
964 :
965 0 : DELAY(100 * 1000);
966 :
967 : /* Recall EEPROM. */
968 0 : ATW_SET(sc, ATW_TEST0, ATW_TEST0_EPRLD);
969 :
970 0 : DELAY(10 * 1000);
971 :
972 0 : lpc = ATW_READ(sc, ATW_LPC);
973 :
974 : DPRINTF(sc, ("%s: ATW_LPC %#08x\n", __func__, lpc));
975 :
976 : /* A reset seems to affect the SRAM contents, so put them into
977 : * a known state.
978 : */
979 0 : atw_clear_sram(sc);
980 :
981 0 : memset(sc->sc_bssid, 0xff, sizeof(sc->sc_bssid));
982 0 : }
983 :
984 : void
985 0 : atw_clear_sram(struct atw_softc *sc)
986 : {
987 0 : memset(sc->sc_sram, 0, sizeof(sc->sc_sram));
988 : /* XXX not for revision 0x20. */
989 0 : atw_write_sram(sc, 0, sc->sc_sram, sc->sc_sramlen);
990 0 : }
991 :
992 : /* TBD atw_init
993 : *
994 : * set MAC based on ic->ic_bss->myaddr
995 : * write WEP keys
996 : * set TX rate
997 : */
998 :
999 : /* Tell the ADM8211 to raise ATW_INTR_LINKOFF if 7 beacon intervals pass
1000 : * without receiving a beacon with the preferred BSSID & SSID.
1001 : * atw_write_bssid & atw_write_ssid set the BSSID & SSID.
1002 : */
1003 : void
1004 0 : atw_wcsr_init(struct atw_softc *sc)
1005 : {
1006 : uint32_t wcsr;
1007 :
1008 0 : wcsr = ATW_READ(sc, ATW_WCSR);
1009 0 : wcsr &= ~(ATW_WCSR_BLN_MASK|ATW_WCSR_LSOE|ATW_WCSR_MPRE|ATW_WCSR_LSOE);
1010 0 : wcsr |= LSHIFT(7, ATW_WCSR_BLN_MASK);
1011 0 : ATW_WRITE(sc, ATW_WCSR, wcsr); /* XXX resets wake-up status bits */
1012 :
1013 : DPRINTF(sc, ("%s: %s reg[WCSR] = %08x\n",
1014 : sc->sc_dev.dv_xname, __func__, ATW_READ(sc, ATW_WCSR)));
1015 0 : }
1016 :
1017 : /* Turn off power management. Set Rx store-and-forward mode. */
1018 : void
1019 0 : atw_cmdr_init(struct atw_softc *sc)
1020 : {
1021 : uint32_t cmdr;
1022 0 : cmdr = ATW_READ(sc, ATW_CMDR);
1023 0 : cmdr &= ~ATW_CMDR_APM;
1024 0 : cmdr |= ATW_CMDR_RTE;
1025 0 : cmdr &= ~ATW_CMDR_DRT_MASK;
1026 0 : cmdr |= ATW_CMDR_DRT_SF;
1027 :
1028 0 : ATW_WRITE(sc, ATW_CMDR, cmdr);
1029 0 : }
1030 :
1031 : void
1032 0 : atw_tofs2_init(struct atw_softc *sc)
1033 : {
1034 : uint32_t tofs2;
1035 : /* XXX this magic can probably be figured out from the RFMD docs */
1036 : #ifndef ATW_REFSLAVE
1037 : tofs2 = LSHIFT(4, ATW_TOFS2_PWR1UP_MASK) | /* 8 ms = 4 * 2 ms */
1038 : LSHIFT(13, ATW_TOFS2_PWR0PAPE_MASK) | /* 13 us */
1039 : LSHIFT(8, ATW_TOFS2_PWR1PAPE_MASK) | /* 8 us */
1040 : LSHIFT(5, ATW_TOFS2_PWR0TRSW_MASK) | /* 5 us */
1041 : LSHIFT(12, ATW_TOFS2_PWR1TRSW_MASK) | /* 12 us */
1042 : LSHIFT(13, ATW_TOFS2_PWR0PE2_MASK) | /* 13 us */
1043 : LSHIFT(4, ATW_TOFS2_PWR1PE2_MASK) | /* 4 us */
1044 : LSHIFT(5, ATW_TOFS2_PWR0TXPE_MASK); /* 5 us */
1045 : #else
1046 : /* XXX new magic from reference driver source */
1047 : tofs2 = LSHIFT(8, ATW_TOFS2_PWR1UP_MASK) | /* 8 ms = 4 * 2 ms */
1048 : LSHIFT(8, ATW_TOFS2_PWR0PAPE_MASK) | /* 13 us */
1049 : LSHIFT(1, ATW_TOFS2_PWR1PAPE_MASK) | /* 8 us */
1050 : LSHIFT(5, ATW_TOFS2_PWR0TRSW_MASK) | /* 5 us */
1051 : LSHIFT(12, ATW_TOFS2_PWR1TRSW_MASK) | /* 12 us */
1052 : LSHIFT(13, ATW_TOFS2_PWR0PE2_MASK) | /* 13 us */
1053 : LSHIFT(1, ATW_TOFS2_PWR1PE2_MASK) | /* 4 us */
1054 : LSHIFT(8, ATW_TOFS2_PWR0TXPE_MASK); /* 5 us */
1055 : #endif
1056 0 : ATW_WRITE(sc, ATW_TOFS2, tofs2);
1057 0 : }
1058 :
1059 : void
1060 0 : atw_nar_init(struct atw_softc *sc)
1061 : {
1062 0 : ATW_WRITE(sc, ATW_NAR, ATW_NAR_SF|ATW_NAR_PB);
1063 0 : }
1064 :
1065 : void
1066 0 : atw_txlmt_init(struct atw_softc *sc)
1067 : {
1068 0 : ATW_WRITE(sc, ATW_TXLMT, LSHIFT(512, ATW_TXLMT_MTMLT_MASK) |
1069 : LSHIFT(1, ATW_TXLMT_SRTYLIM_MASK));
1070 0 : }
1071 :
1072 : void
1073 0 : atw_test1_init(struct atw_softc *sc)
1074 : {
1075 : uint32_t test1;
1076 :
1077 0 : test1 = ATW_READ(sc, ATW_TEST1);
1078 0 : test1 &= ~(ATW_TEST1_DBGREAD_MASK|ATW_TEST1_CONTROL);
1079 : /* XXX magic 0x1 */
1080 0 : test1 |= LSHIFT(0x1, ATW_TEST1_DBGREAD_MASK) | ATW_TEST1_CONTROL;
1081 0 : ATW_WRITE(sc, ATW_TEST1, test1);
1082 0 : }
1083 :
1084 : void
1085 0 : atw_rf_reset(struct atw_softc *sc)
1086 : {
1087 : /* XXX this resets an Intersil RF front-end? */
1088 : /* TBD condition on Intersil RFType? */
1089 0 : ATW_WRITE(sc, ATW_SYNRF, ATW_SYNRF_INTERSIL_EN);
1090 0 : DELAY(10 * 1000);
1091 0 : ATW_WRITE(sc, ATW_SYNRF, 0);
1092 0 : DELAY(5 * 1000);
1093 0 : }
1094 :
1095 : /* Set 16 TU max duration for the contention-free period (CFP). */
1096 : void
1097 0 : atw_cfp_init(struct atw_softc *sc)
1098 : {
1099 : uint32_t cfpp;
1100 :
1101 0 : cfpp = ATW_READ(sc, ATW_CFPP);
1102 0 : cfpp &= ~ATW_CFPP_CFPMD;
1103 0 : cfpp |= LSHIFT(16, ATW_CFPP_CFPMD);
1104 0 : ATW_WRITE(sc, ATW_CFPP, cfpp);
1105 0 : }
1106 :
1107 : void
1108 0 : atw_tofs0_init(struct atw_softc *sc)
1109 : {
1110 : /* XXX I guess that the Cardbus clock is 22MHz?
1111 : * I am assuming that the role of ATW_TOFS0_USCNT is
1112 : * to divide the bus clock to get a 1MHz clock---the datasheet is not
1113 : * very clear on this point. It says in the datasheet that it is
1114 : * possible for the ADM8211 to accommodate bus speeds between 22MHz
1115 : * and 33MHz; maybe this is the way? I see a binary-only driver write
1116 : * these values. These values are also the power-on default.
1117 : */
1118 0 : ATW_WRITE(sc, ATW_TOFS0,
1119 : LSHIFT(22, ATW_TOFS0_USCNT_MASK) |
1120 : ATW_TOFS0_TUCNT_MASK /* set all bits in TUCNT */);
1121 0 : }
1122 :
1123 : /* Initialize interframe spacing: 802.11b slot time, SIFS, DIFS, EIFS. */
1124 : void
1125 0 : atw_ifs_init(struct atw_softc *sc)
1126 : {
1127 : uint32_t ifst;
1128 : /* XXX EIFS=0x64, SIFS=110 are used by the reference driver.
1129 : * Go figure.
1130 : */
1131 : ifst = LSHIFT(IEEE80211_DUR_DS_SLOT, ATW_IFST_SLOT_MASK) |
1132 : LSHIFT(22 * 5 /* IEEE80211_DUR_DS_SIFS */ /* # of 22MHz cycles */,
1133 : ATW_IFST_SIFS_MASK) |
1134 : LSHIFT(IEEE80211_DUR_DS_DIFS, ATW_IFST_DIFS_MASK) |
1135 : LSHIFT(0x64 /* IEEE80211_DUR_DS_EIFS */, ATW_IFST_EIFS_MASK);
1136 :
1137 0 : ATW_WRITE(sc, ATW_IFST, ifst);
1138 0 : }
1139 :
1140 : void
1141 0 : atw_response_times_init(struct atw_softc *sc)
1142 : {
1143 : /* XXX More magic. Relates to ACK timing? The datasheet seems to
1144 : * indicate that the MAC expects at least SIFS + MIRT microseconds
1145 : * to pass after it transmits a frame that requires a response;
1146 : * it waits at most SIFS + MART microseconds for the response.
1147 : * Surely this is not the ACK timeout?
1148 : */
1149 0 : ATW_WRITE(sc, ATW_RSPT, LSHIFT(0xffff, ATW_RSPT_MART_MASK) |
1150 : LSHIFT(0xff, ATW_RSPT_MIRT_MASK));
1151 0 : }
1152 :
1153 : /* Set up the MMI read/write addresses for the baseband. The Tx/Rx
1154 : * engines read and write baseband registers after Rx and before
1155 : * Tx, respectively.
1156 : */
1157 : void
1158 0 : atw_bbp_io_init(struct atw_softc *sc)
1159 : {
1160 : uint32_t mmiraddr2;
1161 :
1162 : /* XXX The reference driver does this, but is it *really*
1163 : * necessary?
1164 : */
1165 0 : switch (sc->sc_rev) {
1166 : case ATW_REVISION_AB:
1167 : case ATW_REVISION_AF:
1168 : mmiraddr2 = 0x0;
1169 0 : break;
1170 : default:
1171 0 : mmiraddr2 = ATW_READ(sc, ATW_MMIRADDR2);
1172 0 : mmiraddr2 &=
1173 : ~(ATW_MMIRADDR2_PROREXT|ATW_MMIRADDR2_PRORLEN_MASK);
1174 0 : break;
1175 : }
1176 :
1177 0 : switch (sc->sc_bbptype) {
1178 : case ATW_BBPTYPE_INTERSIL:
1179 0 : ATW_WRITE(sc, ATW_MMIWADDR, ATW_MMIWADDR_INTERSIL);
1180 0 : ATW_WRITE(sc, ATW_MMIRADDR1, ATW_MMIRADDR1_INTERSIL);
1181 0 : mmiraddr2 |= ATW_MMIRADDR2_INTERSIL;
1182 0 : break;
1183 : case ATW_BBPTYPE_MARVEL:
1184 : /* TBD find out the Marvel settings. */
1185 : break;
1186 : case ATW_BBPTYPE_RFMD:
1187 : default:
1188 0 : ATW_WRITE(sc, ATW_MMIWADDR, ATW_MMIWADDR_RFMD);
1189 0 : ATW_WRITE(sc, ATW_MMIRADDR1, ATW_MMIRADDR1_RFMD);
1190 0 : mmiraddr2 |= ATW_MMIRADDR2_RFMD;
1191 0 : break;
1192 : }
1193 0 : ATW_WRITE(sc, ATW_MMIRADDR2, mmiraddr2);
1194 :
1195 0 : atw_si4126_init(sc);
1196 :
1197 0 : ATW_WRITE(sc, ATW_MACTEST, ATW_MACTEST_MMI_USETXCLK);
1198 0 : }
1199 :
1200 : void
1201 0 : atw_si4126_init(struct atw_softc *sc)
1202 : {
1203 0 : switch (sc->sc_rftype) {
1204 : case ATW_RFTYPE_RFMD:
1205 0 : if (sc->sc_rev >= ATW_REVISION_BA) {
1206 0 : atw_si4126_write(sc, 0x1f, 0x00000);
1207 0 : atw_si4126_write(sc, 0x0c, 0x3001f);
1208 0 : atw_si4126_write(sc, SI4126_GAIN, 0x29c03);
1209 0 : atw_si4126_write(sc, SI4126_RF1N, 0x1ff6f);
1210 0 : atw_si4126_write(sc, SI4126_RF2N, 0x29403);
1211 0 : atw_si4126_write(sc, SI4126_RF2R, 0x1456f);
1212 0 : atw_si4126_write(sc, 0x09, 0x10050);
1213 0 : atw_si4126_write(sc, SI4126_IFR, 0x3fff8);
1214 0 : }
1215 : break;
1216 : default:
1217 : break;
1218 : }
1219 0 : }
1220 :
1221 : /*
1222 : * atw_init: [ ifnet interface function ]
1223 : *
1224 : * Initialize the interface. Must be called at splnet().
1225 : */
1226 : int
1227 0 : atw_init(struct ifnet *ifp)
1228 : {
1229 0 : struct atw_softc *sc = ifp->if_softc;
1230 0 : struct ieee80211com *ic = &sc->sc_ic;
1231 : struct atw_txsoft *txs;
1232 : struct atw_rxsoft *rxs;
1233 : int i, error = 0;
1234 :
1235 0 : if ((error = atw_enable(sc)) != 0)
1236 : goto out;
1237 :
1238 : /*
1239 : * Cancel any pending I/O. This also resets.
1240 : */
1241 0 : atw_stop(ifp, 0);
1242 :
1243 0 : ic->ic_bss->ni_chan = ic->ic_ibss_chan;
1244 : DPRINTF(sc, ("%s: channel %d freq %d flags 0x%04x\n",
1245 : __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
1246 : ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags));
1247 :
1248 0 : atw_wcsr_init(sc);
1249 :
1250 0 : atw_cmdr_init(sc);
1251 :
1252 : /* Set data rate for PLCP Signal field, 1Mbps = 10 x 100Kb/s.
1253 : *
1254 : * XXX Set transmit power for ATIM, RTS, Beacon.
1255 : */
1256 0 : ATW_WRITE(sc, ATW_PLCPHD, LSHIFT(10, ATW_PLCPHD_SIGNAL_MASK) |
1257 : LSHIFT(0xb0, ATW_PLCPHD_SERVICE_MASK));
1258 :
1259 0 : atw_tofs2_init(sc);
1260 :
1261 0 : atw_nar_init(sc);
1262 :
1263 0 : atw_txlmt_init(sc);
1264 :
1265 0 : atw_test1_init(sc);
1266 :
1267 0 : atw_rf_reset(sc);
1268 :
1269 0 : atw_cfp_init(sc);
1270 :
1271 0 : atw_tofs0_init(sc);
1272 :
1273 0 : atw_ifs_init(sc);
1274 :
1275 : /* XXX Fall asleep after one second of inactivity.
1276 : * XXX A frame may only dribble in for 65536us.
1277 : */
1278 0 : ATW_WRITE(sc, ATW_RMD,
1279 : LSHIFT(1, ATW_RMD_PCNT) | LSHIFT(0xffff, ATW_RMD_RMRD_MASK));
1280 :
1281 0 : atw_response_times_init(sc);
1282 :
1283 0 : atw_bbp_io_init(sc);
1284 :
1285 0 : ATW_WRITE(sc, ATW_STSR, 0xffffffff);
1286 :
1287 0 : if ((error = atw_rf3000_init(sc)) != 0)
1288 : goto out;
1289 :
1290 0 : ATW_WRITE(sc, ATW_PAR, sc->sc_busmode);
1291 : DPRINTF(sc, ("%s: ATW_PAR %08x busmode %08x\n", sc->sc_dev.dv_xname,
1292 : ATW_READ(sc, ATW_PAR), sc->sc_busmode));
1293 :
1294 : /*
1295 : * Initialize the transmit descriptor ring.
1296 : */
1297 0 : memset(sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
1298 0 : for (i = 0; i < ATW_NTXDESC; i++) {
1299 0 : sc->sc_txdescs[i].at_ctl = 0;
1300 : /* no transmit chaining */
1301 0 : sc->sc_txdescs[i].at_flags = 0 /* ATW_TXFLAG_TCH */;
1302 0 : sc->sc_txdescs[i].at_buf2 =
1303 0 : htole32(ATW_CDTXADDR(sc, ATW_NEXTTX(i)));
1304 : }
1305 : /* use ring mode */
1306 0 : sc->sc_txdescs[ATW_NTXDESC - 1].at_flags |= htole32(ATW_TXFLAG_TER);
1307 0 : ATW_CDTXSYNC(sc, 0, ATW_NTXDESC,
1308 : BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1309 0 : sc->sc_txfree = ATW_NTXDESC;
1310 0 : sc->sc_txnext = 0;
1311 :
1312 : /*
1313 : * Initialize the transmit job descriptors.
1314 : */
1315 0 : SIMPLEQ_INIT(&sc->sc_txfreeq);
1316 0 : SIMPLEQ_INIT(&sc->sc_txdirtyq);
1317 0 : for (i = 0; i < ATW_TXQUEUELEN; i++) {
1318 0 : txs = &sc->sc_txsoft[i];
1319 0 : txs->txs_mbuf = NULL;
1320 0 : SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
1321 : }
1322 :
1323 : /*
1324 : * Initialize the receive descriptor and receive job
1325 : * descriptor rings.
1326 : */
1327 0 : for (i = 0; i < ATW_NRXDESC; i++) {
1328 0 : rxs = &sc->sc_rxsoft[i];
1329 0 : if (rxs->rxs_mbuf == NULL) {
1330 0 : if ((error = atw_add_rxbuf(sc, i)) != 0) {
1331 0 : printf("%s: unable to allocate or map rx "
1332 : "buffer %d, error = %d\n",
1333 0 : sc->sc_dev.dv_xname, i, error);
1334 : /*
1335 : * XXX Should attempt to run with fewer receive
1336 : * XXX buffers instead of just failing.
1337 : */
1338 0 : atw_rxdrain(sc);
1339 0 : goto out;
1340 : }
1341 : } else
1342 0 : ATW_INIT_RXDESC(sc, i);
1343 : }
1344 0 : sc->sc_rxptr = 0;
1345 :
1346 : /*
1347 : * Initialize the interrupt mask and enable interrupts.
1348 : */
1349 : /* normal interrupts */
1350 0 : sc->sc_inten = ATW_INTR_TCI | ATW_INTR_TDU | ATW_INTR_RCI |
1351 : ATW_INTR_NISS | ATW_INTR_LINKON | ATW_INTR_BCNTC;
1352 :
1353 : /* abnormal interrupts */
1354 0 : sc->sc_inten |= ATW_INTR_TPS | ATW_INTR_TLT | ATW_INTR_TRT |
1355 : ATW_INTR_TUF | ATW_INTR_RDU | ATW_INTR_RPS | ATW_INTR_AISS |
1356 : ATW_INTR_FBE | ATW_INTR_LINKOFF | ATW_INTR_TSFTF | ATW_INTR_TSCZ;
1357 :
1358 0 : sc->sc_linkint_mask = ATW_INTR_LINKON | ATW_INTR_LINKOFF |
1359 : ATW_INTR_BCNTC | ATW_INTR_TSFTF | ATW_INTR_TSCZ;
1360 0 : sc->sc_rxint_mask = ATW_INTR_RCI | ATW_INTR_RDU;
1361 0 : sc->sc_txint_mask = ATW_INTR_TCI | ATW_INTR_TUF | ATW_INTR_TLT |
1362 : ATW_INTR_TRT;
1363 :
1364 0 : sc->sc_linkint_mask &= sc->sc_inten;
1365 0 : sc->sc_rxint_mask &= sc->sc_inten;
1366 0 : sc->sc_txint_mask &= sc->sc_inten;
1367 :
1368 0 : ATW_WRITE(sc, ATW_IER, sc->sc_inten);
1369 0 : ATW_WRITE(sc, ATW_STSR, 0xffffffff);
1370 :
1371 : DPRINTF(sc, ("%s: ATW_IER %08x, inten %08x\n",
1372 : sc->sc_dev.dv_xname, ATW_READ(sc, ATW_IER), sc->sc_inten));
1373 :
1374 : /*
1375 : * Give the transmit and receive rings to the ADM8211.
1376 : */
1377 0 : ATW_WRITE(sc, ATW_RDB, ATW_CDRXADDR(sc, sc->sc_rxptr));
1378 0 : ATW_WRITE(sc, ATW_TDBD, ATW_CDTXADDR(sc, sc->sc_txnext));
1379 :
1380 0 : sc->sc_txthresh = 0;
1381 0 : sc->sc_opmode = ATW_NAR_SR | ATW_NAR_ST |
1382 0 : sc->sc_txth[sc->sc_txthresh].txth_opmode;
1383 :
1384 : /* common 802.11 configuration */
1385 0 : ic->ic_flags &= ~IEEE80211_F_IBSSON;
1386 0 : switch (ic->ic_opmode) {
1387 : case IEEE80211_M_STA:
1388 : break;
1389 : #ifndef IEEE80211_STA_ONLY
1390 : case IEEE80211_M_AHDEMO: /* XXX */
1391 : case IEEE80211_M_IBSS:
1392 0 : ic->ic_flags |= IEEE80211_F_IBSSON;
1393 : /*FALLTHROUGH*/
1394 : #endif
1395 : default: /* XXX */
1396 : break;
1397 : }
1398 :
1399 : #ifndef IEEE80211_STA_ONLY
1400 0 : switch (ic->ic_opmode) {
1401 : case IEEE80211_M_AHDEMO:
1402 0 : ic->ic_bss->ni_intval = ic->ic_lintval;
1403 0 : ic->ic_bss->ni_rssi = 0;
1404 0 : ic->ic_bss->ni_rstamp = 0;
1405 0 : break;
1406 : default: /* XXX */
1407 : break;
1408 : }
1409 : #endif
1410 0 : sc->sc_wepctl = 0;
1411 :
1412 0 : atw_write_ssid(sc);
1413 0 : atw_write_sup_rates(sc);
1414 0 : if (ic->ic_caps & IEEE80211_C_WEP)
1415 0 : atw_write_wep(sc);
1416 :
1417 0 : ic->ic_state = IEEE80211_S_INIT;
1418 :
1419 : /*
1420 : * Set the receive filter. This will start the transmit and
1421 : * receive processes.
1422 : */
1423 0 : atw_filter_setup(sc);
1424 :
1425 : /*
1426 : * Start the receive process.
1427 : */
1428 0 : ATW_WRITE(sc, ATW_RDR, 0x1);
1429 :
1430 : /*
1431 : * Note that the interface is now running.
1432 : */
1433 0 : ifp->if_flags |= IFF_RUNNING;
1434 0 : ifq_clr_oactive(&ifp->if_snd);
1435 :
1436 : /* send no beacons, yet. */
1437 0 : atw_start_beacon(sc, 0);
1438 :
1439 0 : if (ic->ic_opmode == IEEE80211_M_MONITOR)
1440 0 : error = ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1441 : else
1442 0 : error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
1443 : out:
1444 0 : if (error) {
1445 0 : ifp->if_flags &= ~IFF_RUNNING;
1446 0 : ifq_clr_oactive(&ifp->if_snd);
1447 0 : ifp->if_timer = 0;
1448 0 : printf("%s: interface not running\n", sc->sc_dev.dv_xname);
1449 0 : }
1450 : #ifdef ATW_DEBUG
1451 : atw_print_regs(sc, "end of init");
1452 : #endif /* ATW_DEBUG */
1453 :
1454 0 : return (error);
1455 : }
1456 :
1457 : /* enable == 1: host control of RF3000/Si4126 through ATW_SYNCTL.
1458 : * 0: MAC control of RF3000/Si4126.
1459 : *
1460 : * Applies power, or selects RF front-end? Sets reset condition.
1461 : *
1462 : * TBD support non-RFMD BBP, non-SiLabs synth.
1463 : */
1464 : void
1465 0 : atw_bbp_io_enable(struct atw_softc *sc, int enable)
1466 : {
1467 0 : if (enable) {
1468 0 : ATW_WRITE(sc, ATW_SYNRF,
1469 : ATW_SYNRF_SELRF|ATW_SYNRF_PE1|ATW_SYNRF_PHYRST);
1470 0 : DELAY(atw_bbp_io_enable_delay);
1471 0 : } else {
1472 0 : ATW_WRITE(sc, ATW_SYNRF, 0);
1473 0 : DELAY(atw_bbp_io_disable_delay); /* shorter for some reason */
1474 : }
1475 0 : }
1476 :
1477 : int
1478 0 : atw_tune(struct atw_softc *sc)
1479 : {
1480 : int rc;
1481 : u_int chan;
1482 0 : struct ieee80211com *ic = &sc->sc_ic;
1483 :
1484 0 : chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1485 0 : if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1486 0 : return 0;
1487 :
1488 0 : if (chan == sc->sc_cur_chan)
1489 0 : return 0;
1490 :
1491 : DPRINTF(sc, ("%s: chan %d -> %d\n", sc->sc_dev.dv_xname,
1492 : sc->sc_cur_chan, chan));
1493 :
1494 0 : atw_idle(sc, ATW_NAR_SR|ATW_NAR_ST);
1495 :
1496 0 : atw_si4126_tune(sc, chan);
1497 0 : if ((rc = atw_rf3000_tune(sc, chan)) != 0)
1498 0 : printf("%s: failed to tune channel %d\n", sc->sc_dev.dv_xname,
1499 : chan);
1500 :
1501 0 : ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
1502 0 : DELAY(20 * 1000);
1503 0 : ATW_WRITE(sc, ATW_RDR, 0x1);
1504 :
1505 0 : if (rc == 0)
1506 0 : sc->sc_cur_chan = chan;
1507 :
1508 0 : return rc;
1509 0 : }
1510 :
1511 : #ifdef ATW_SYNDEBUG
1512 : void
1513 : atw_si4126_print(struct atw_softc *sc)
1514 : {
1515 : struct ifnet *ifp = &sc->sc_ic.ic_if;
1516 : u_int addr, val;
1517 :
1518 : if (atw_debug < 3 || (ifp->if_flags & IFF_DEBUG) == 0)
1519 : return;
1520 :
1521 : for (addr = 0; addr <= 8; addr++) {
1522 : printf("%s: synth[%d] = ", sc->sc_dev.dv_xname, addr);
1523 : if (atw_si4126_read(sc, addr, &val) == 0) {
1524 : printf("<unknown> (quitting print-out)\n");
1525 : break;
1526 : }
1527 : printf("%05x\n", val);
1528 : }
1529 : }
1530 : #endif /* ATW_SYNDEBUG */
1531 :
1532 : /* Tune to channel chan by adjusting the Si4126 RF/IF synthesizer.
1533 : *
1534 : * The RF/IF synthesizer produces two reference frequencies for
1535 : * the RF2948B transceiver. The first frequency the RF2948B requires
1536 : * is two times the so-called "intermediate frequency" (IF). Since
1537 : * a SAW filter on the radio fixes the IF at 374MHz, I program the
1538 : * Si4126 to generate IF LO = 374MHz x 2 = 748MHz. The second
1539 : * frequency required by the transceiver is the radio frequency
1540 : * (RF). This is a superheterodyne transceiver; for f(chan) the
1541 : * center frequency of the channel we are tuning, RF = f(chan) -
1542 : * IF.
1543 : *
1544 : * XXX I am told by SiLabs that the Si4126 will accept a broader range
1545 : * of XIN than the 2-25MHz mentioned by the datasheet, even *without*
1546 : * XINDIV2 = 1. I've tried this (it is necessary to double R) and it
1547 : * works, but I have still programmed for XINDIV2 = 1 to be safe.
1548 : */
1549 : void
1550 0 : atw_si4126_tune(struct atw_softc *sc, u_int chan)
1551 : {
1552 : u_int mhz;
1553 : u_int R;
1554 : u_int32_t gpio;
1555 : u_int16_t gain;
1556 :
1557 : #ifdef ATW_SYNDEBUG
1558 : atw_si4126_print(sc);
1559 : #endif /* ATW_SYNDEBUG */
1560 :
1561 0 : if (sc->sc_rev >= ATW_REVISION_BA) {
1562 0 : atw_si4126_write(sc, SI4126_MAIN, 0x04007);
1563 0 : atw_si4126_write(sc, SI4126_POWER, 0x00033);
1564 0 : atw_si4126_write(sc, SI4126_IFN,
1565 0 : atw_rfmd2958_ifn[chan - 1]);
1566 0 : atw_si4126_write(sc, SI4126_RF1R,
1567 0 : atw_rfmd2958_rf1r[chan - 1]);
1568 : #ifdef NOTYET
1569 : /* set TX POWER? */
1570 : atw_si4126_write(sc, 0x0a,
1571 : (sc->sc_srom[ATW_SR_CSR20] & mask) |
1572 : power << 9);
1573 : #endif
1574 : /* set TX GAIN */
1575 0 : atw_si4126_write(sc, 0x09, 0x00050 |
1576 0 : sc->sc_srom[ATW_SR_TXPOWER(chan - 1)]);
1577 : /* wait 100us from power-up for RF, IF to settle */
1578 0 : DELAY(100);
1579 :
1580 0 : return;
1581 : }
1582 :
1583 0 : if (chan == 14)
1584 0 : mhz = 2484;
1585 : else
1586 0 : mhz = 2412 + 5 * (chan - 1);
1587 :
1588 : /* Tune IF to 748MHz to suit the IF LO input of the
1589 : * RF2494B, which is 2 x IF. No need to set an IF divider
1590 : * because an IF in 526MHz - 952MHz is allowed.
1591 : *
1592 : * XIN is 44.000MHz, so divide it by two to get allowable
1593 : * range of 2-25MHz. SiLabs tells me that this is not
1594 : * strictly necessary.
1595 : */
1596 :
1597 0 : if (atw_xindiv2)
1598 0 : R = 44;
1599 : else
1600 : R = 88;
1601 :
1602 : /* Power-up RF, IF synthesizers. */
1603 0 : atw_si4126_write(sc, SI4126_POWER,
1604 : SI4126_POWER_PDIB|SI4126_POWER_PDRB);
1605 :
1606 : /* set LPWR, too? */
1607 0 : atw_si4126_write(sc, SI4126_MAIN,
1608 0 : (atw_xindiv2) ? SI4126_MAIN_XINDIV2 : 0);
1609 :
1610 : /* Set the phase-locked loop gain. If RF2 N > 2047, then
1611 : * set KP2 to 1.
1612 : *
1613 : * REFDIF This is different from the reference driver, which
1614 : * always sets SI4126_GAIN to 0.
1615 : */
1616 0 : gain = LSHIFT(((mhz - 374) > 2047) ? 1 : 0, SI4126_GAIN_KP2_MASK);
1617 :
1618 0 : atw_si4126_write(sc, SI4126_GAIN, gain);
1619 :
1620 : /* XIN = 44MHz.
1621 : *
1622 : * If XINDIV2 = 1, IF = N/(2 * R) * XIN. I choose N = 1496,
1623 : * R = 44 so that 1496/(2 * 44) * 44MHz = 748MHz.
1624 : *
1625 : * If XINDIV2 = 0, IF = N/R * XIN. I choose N = 1496, R = 88
1626 : * so that 1496/88 * 44MHz = 748MHz.
1627 : */
1628 0 : atw_si4126_write(sc, SI4126_IFN, 1496);
1629 :
1630 0 : atw_si4126_write(sc, SI4126_IFR, R);
1631 :
1632 : #ifndef ATW_REFSLAVE
1633 : /* Set RF1 arbitrarily. DO NOT configure RF1 after RF2, because
1634 : * then RF1 becomes the active RF synthesizer, even on the Si4126,
1635 : * which has no RF1!
1636 : */
1637 : atw_si4126_write(sc, SI4126_RF1R, R);
1638 :
1639 : atw_si4126_write(sc, SI4126_RF1N, mhz - 374);
1640 : #endif
1641 :
1642 : /* N/R * XIN = RF. XIN = 44MHz. We desire RF = mhz - IF,
1643 : * where IF = 374MHz. Let's divide XIN to 1MHz. So R = 44.
1644 : * Now let's multiply it to mhz. So mhz - IF = N.
1645 : */
1646 0 : atw_si4126_write(sc, SI4126_RF2R, R);
1647 :
1648 0 : atw_si4126_write(sc, SI4126_RF2N, mhz - 374);
1649 :
1650 : /* wait 100us from power-up for RF, IF to settle */
1651 0 : DELAY(100);
1652 :
1653 0 : gpio = ATW_READ(sc, ATW_GPIO);
1654 0 : gpio &= ~(ATW_GPIO_EN_MASK|ATW_GPIO_O_MASK|ATW_GPIO_I_MASK);
1655 0 : gpio |= LSHIFT(1, ATW_GPIO_EN_MASK);
1656 :
1657 0 : if ((sc->sc_if.if_flags & IFF_LINK1) != 0 && chan != 14) {
1658 : /* Set a Prism RF front-end to a special mode for channel 14?
1659 : *
1660 : * Apparently the SMC2635W needs this, although I don't think
1661 : * it has a Prism RF.
1662 : */
1663 0 : gpio |= LSHIFT(1, ATW_GPIO_O_MASK);
1664 0 : }
1665 0 : ATW_WRITE(sc, ATW_GPIO, gpio);
1666 :
1667 : #ifdef ATW_SYNDEBUG
1668 : atw_si4126_print(sc);
1669 : #endif /* ATW_SYNDEBUG */
1670 0 : }
1671 :
1672 : /* Baseline initialization of RF3000 BBP: set CCA mode and enable antenna
1673 : * diversity.
1674 : *
1675 : * !!!
1676 : * !!! Call this w/ Tx/Rx suspended, atw_idle(, ATW_NAR_ST|ATW_NAR_SR).
1677 : * !!!
1678 : */
1679 : int
1680 0 : atw_rf3000_init(struct atw_softc *sc)
1681 : {
1682 : int rc = 0;
1683 :
1684 0 : atw_bbp_io_enable(sc, 1);
1685 :
1686 : /* CCA is acquisition sensitive */
1687 0 : rc = atw_rf3000_write(sc, RF3000_CCACTL,
1688 : LSHIFT(RF3000_CCACTL_MODE_BOTH, RF3000_CCACTL_MODE_MASK));
1689 :
1690 0 : if (rc != 0)
1691 : goto out;
1692 :
1693 : /* enable diversity */
1694 0 : rc = atw_rf3000_write(sc, RF3000_DIVCTL, RF3000_DIVCTL_ENABLE);
1695 :
1696 0 : if (rc != 0)
1697 : goto out;
1698 :
1699 : /* sensible setting from a binary-only driver */
1700 0 : rc = atw_rf3000_write(sc, RF3000_GAINCTL,
1701 : LSHIFT(0x1d, RF3000_GAINCTL_TXVGC_MASK));
1702 :
1703 0 : if (rc != 0)
1704 : goto out;
1705 :
1706 : /* magic from a binary-only driver */
1707 0 : rc = atw_rf3000_write(sc, RF3000_LOGAINCAL,
1708 : LSHIFT(0x38, RF3000_LOGAINCAL_CAL_MASK));
1709 :
1710 0 : if (rc != 0)
1711 : goto out;
1712 :
1713 0 : rc = atw_rf3000_write(sc, RF3000_HIGAINCAL, RF3000_HIGAINCAL_DSSSPAD);
1714 :
1715 0 : if (rc != 0)
1716 : goto out;
1717 :
1718 : /*
1719 : * XXX Reference driver remarks that Abocom sets this to 50.
1720 : * Meaning 0x50, I think.... 50 = 0x32, which would set a bit
1721 : * in the "reserved" area of register RF3000_OPTIONS1.
1722 : */
1723 0 : rc = atw_rf3000_write(sc, RF3000_OPTIONS1, sc->sc_rf3000_options1);
1724 :
1725 0 : if (rc != 0)
1726 : goto out;
1727 :
1728 0 : rc = atw_rf3000_write(sc, RF3000_OPTIONS2, sc->sc_rf3000_options2);
1729 :
1730 : if (rc != 0)
1731 0 : goto out;
1732 :
1733 : out:
1734 0 : atw_bbp_io_enable(sc, 0);
1735 0 : return rc;
1736 : }
1737 :
1738 : #ifdef ATW_BBPDEBUG
1739 : void
1740 : atw_rf3000_print(struct atw_softc *sc)
1741 : {
1742 : struct ifnet *ifp = &sc->sc_ic.ic_if;
1743 : u_int addr, val;
1744 :
1745 : if (atw_debug < 3 || (ifp->if_flags & IFF_DEBUG) == 0)
1746 : return;
1747 :
1748 : for (addr = 0x01; addr <= 0x15; addr++) {
1749 : printf("%s: bbp[%d] = \n", sc->sc_dev.dv_xname, addr);
1750 : if (atw_rf3000_read(sc, addr, &val) != 0) {
1751 : printf("<unknown> (quitting print-out)\n");
1752 : break;
1753 : }
1754 : printf("%08x\n", val);
1755 : }
1756 : }
1757 : #endif /* ATW_BBPDEBUG */
1758 :
1759 : /* Set the power settings on the BBP for channel `chan'. */
1760 : int
1761 0 : atw_rf3000_tune(struct atw_softc *sc, u_int chan)
1762 : {
1763 : int rc = 0;
1764 : u_int32_t reg;
1765 : u_int16_t txpower, lpf_cutoff, lna_gs_thresh;
1766 :
1767 0 : txpower = sc->sc_srom[ATW_SR_TXPOWER(chan)];
1768 0 : lpf_cutoff = sc->sc_srom[ATW_SR_LPF_CUTOFF(chan)];
1769 0 : lna_gs_thresh = sc->sc_srom[ATW_SR_LNA_GS_THRESH(chan)];
1770 :
1771 : /* odd channels: LSB, even channels: MSB */
1772 0 : if (chan % 2 == 1) {
1773 0 : txpower &= 0xFF;
1774 0 : lpf_cutoff &= 0xFF;
1775 0 : lna_gs_thresh &= 0xFF;
1776 0 : } else {
1777 0 : txpower >>= 8;
1778 0 : lpf_cutoff >>= 8;
1779 0 : lna_gs_thresh >>= 8;
1780 : }
1781 :
1782 : #ifdef ATW_BBPDEBUG
1783 : atw_rf3000_print(sc);
1784 : #endif /* ATW_BBPDEBUG */
1785 :
1786 : DPRINTF(sc, ("%s: chan %d txpower %02x, lpf_cutoff %02x, "
1787 : "lna_gs_thresh %02x\n",
1788 : sc->sc_dev.dv_xname, chan, txpower, lpf_cutoff, lna_gs_thresh));
1789 :
1790 0 : atw_bbp_io_enable(sc, 1);
1791 :
1792 0 : if ((rc = atw_rf3000_write(sc, RF3000_GAINCTL,
1793 0 : LSHIFT(txpower, RF3000_GAINCTL_TXVGC_MASK))) != 0)
1794 : goto out;
1795 :
1796 0 : if ((rc = atw_rf3000_write(sc, RF3000_LOGAINCAL, lpf_cutoff)) != 0)
1797 : goto out;
1798 :
1799 0 : if ((rc = atw_rf3000_write(sc, RF3000_HIGAINCAL, lna_gs_thresh)) != 0)
1800 : goto out;
1801 :
1802 0 : if ((rc = atw_rf3000_write(sc, RF3000_OPTIONS1, 0x0)) != 0)
1803 : goto out;
1804 :
1805 0 : rc = atw_rf3000_write(sc, RF3000_OPTIONS2, RF3000_OPTIONS2_LNAGS_DELAY);
1806 : if (rc != 0)
1807 0 : goto out;
1808 :
1809 : #ifdef ATW_BBPDEBUG
1810 : atw_rf3000_print(sc);
1811 : #endif /* ATW_BBPDEBUG */
1812 :
1813 : out:
1814 0 : atw_bbp_io_enable(sc, 0);
1815 :
1816 : /* set beacon, rts, atim transmit power */
1817 0 : reg = ATW_READ(sc, ATW_PLCPHD);
1818 0 : reg &= ~ATW_PLCPHD_SERVICE_MASK;
1819 0 : reg |= LSHIFT(LSHIFT(txpower, RF3000_GAINCTL_TXVGC_MASK),
1820 : ATW_PLCPHD_SERVICE_MASK);
1821 0 : ATW_WRITE(sc, ATW_PLCPHD, reg);
1822 0 : DELAY(2 * 1000);
1823 :
1824 0 : return rc;
1825 : }
1826 :
1827 : /* Write a register on the RF3000 baseband processor using the
1828 : * registers provided by the ADM8211 for this purpose.
1829 : *
1830 : * Return 0 on success.
1831 : */
1832 : int
1833 0 : atw_rf3000_write(struct atw_softc *sc, u_int addr, u_int val)
1834 : {
1835 : u_int32_t reg;
1836 : int i;
1837 :
1838 0 : reg = sc->sc_bbpctl_wr |
1839 0 : LSHIFT(val & 0xff, ATW_BBPCTL_DATA_MASK) |
1840 0 : LSHIFT(addr & 0x7f, ATW_BBPCTL_ADDR_MASK);
1841 :
1842 0 : for (i = 10; --i >= 0; ) {
1843 0 : ATW_WRITE(sc, ATW_BBPCTL, reg);
1844 0 : DELAY(2000);
1845 0 : if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_WR) == 0)
1846 : break;
1847 : }
1848 :
1849 0 : if (i < 0) {
1850 0 : printf("%s: BBPCTL still busy\n", sc->sc_dev.dv_xname);
1851 0 : return ETIMEDOUT;
1852 : }
1853 0 : return 0;
1854 0 : }
1855 :
1856 : /* Read a register on the RF3000 baseband processor using the registers
1857 : * the ADM8211 provides for this purpose.
1858 : *
1859 : * The 7-bit register address is addr. Record the 8-bit data in the register
1860 : * in *val.
1861 : *
1862 : * Return 0 on success.
1863 : *
1864 : * XXX This does not seem to work. The ADM8211 must require more or
1865 : * different magic to read the chip than to write it. Possibly some
1866 : * of the magic I have derived from a binary-only driver concerns
1867 : * the "chip address" (see the RF3000 manual).
1868 : */
1869 : #ifdef ATW_BBPDEBUG
1870 : int
1871 : atw_rf3000_read(struct atw_softc *sc, u_int addr, u_int *val)
1872 : {
1873 : u_int32_t reg;
1874 : int i;
1875 :
1876 : for (i = 1000; --i >= 0; ) {
1877 : if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_RD|ATW_BBPCTL_WR) == 0)
1878 : break;
1879 : DELAY(100);
1880 : }
1881 :
1882 : if (i < 0) {
1883 : printf("%s: start atw_rf3000_read, BBPCTL busy\n",
1884 : sc->sc_dev.dv_xname);
1885 : return ETIMEDOUT;
1886 : }
1887 :
1888 : reg = sc->sc_bbpctl_rd | LSHIFT(addr & 0x7f, ATW_BBPCTL_ADDR_MASK);
1889 :
1890 : ATW_WRITE(sc, ATW_BBPCTL, reg);
1891 :
1892 : for (i = 1000; --i >= 0; ) {
1893 : DELAY(100);
1894 : if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_RD) == 0)
1895 : break;
1896 : }
1897 :
1898 : ATW_CLR(sc, ATW_BBPCTL, ATW_BBPCTL_RD);
1899 :
1900 : if (i < 0) {
1901 : printf("%s: atw_rf3000_read wrote %08x; BBPCTL still busy\n",
1902 : sc->sc_dev.dv_xname, reg);
1903 : return ETIMEDOUT;
1904 : }
1905 : if (val != NULL)
1906 : *val = MASK_AND_RSHIFT(reg, ATW_BBPCTL_DATA_MASK);
1907 : return 0;
1908 : }
1909 : #endif /* ATW_BBPDEBUG */
1910 :
1911 : /* Write a register on the Si4126 RF/IF synthesizer using the registers
1912 : * provided by the ADM8211 for that purpose.
1913 : *
1914 : * val is 18 bits of data, and val is the 4-bit address of the register.
1915 : *
1916 : * Return 0 on success.
1917 : */
1918 : void
1919 0 : atw_si4126_write(struct atw_softc *sc, u_int addr, u_int val)
1920 : {
1921 : uint32_t bits, mask, reg;
1922 : int nbits;
1923 :
1924 0 : if (sc->sc_rev >= ATW_REVISION_BA) {
1925 : nbits = 24;
1926 :
1927 0 : val &= 0x3ffff;
1928 0 : addr &= 0x1f;
1929 0 : bits = val | (addr << 18);
1930 0 : } else {
1931 : nbits = 22;
1932 :
1933 0 : KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
1934 0 : KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
1935 :
1936 0 : bits = LSHIFT(val, SI4126_TWI_DATA_MASK) |
1937 : LSHIFT(addr, SI4126_TWI_ADDR_MASK);
1938 : }
1939 :
1940 : reg = ATW_SYNRF_SELSYN;
1941 : /* reference driver: reset Si4126 serial bus to initial
1942 : * conditions?
1943 : */
1944 0 : ATW_WRITE(sc, ATW_SYNRF, reg | ATW_SYNRF_LEIF);
1945 0 : ATW_WRITE(sc, ATW_SYNRF, reg);
1946 :
1947 0 : for (mask = (1 << (nbits - 1)); mask != 0; mask >>= 1) {
1948 0 : if ((bits & mask) != 0)
1949 0 : reg |= ATW_SYNRF_SYNDATA;
1950 : else
1951 0 : reg &= ~ATW_SYNRF_SYNDATA;
1952 0 : ATW_WRITE(sc, ATW_SYNRF, reg);
1953 0 : ATW_WRITE(sc, ATW_SYNRF, reg | ATW_SYNRF_SYNCLK);
1954 0 : ATW_WRITE(sc, ATW_SYNRF, reg);
1955 : }
1956 0 : ATW_WRITE(sc, ATW_SYNRF, reg | ATW_SYNRF_LEIF);
1957 0 : ATW_WRITE(sc, ATW_SYNRF, 0x0);
1958 0 : }
1959 :
1960 : /* Read 18-bit data from the 4-bit address addr in Si4126
1961 : * RF synthesizer and write the data to *val. Return 0 on success.
1962 : *
1963 : * XXX This does not seem to work. The ADM8211 must require more or
1964 : * different magic to read the chip than to write it.
1965 : */
1966 : #ifdef ATW_SYNDEBUG
1967 : int
1968 : atw_si4126_read(struct atw_softc *sc, u_int addr, u_int *val)
1969 : {
1970 : u_int32_t reg;
1971 : int i;
1972 :
1973 : KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
1974 :
1975 : for (i = 1000; --i >= 0; ) {
1976 : if (ATW_ISSET(sc, ATW_SYNCTL, ATW_SYNCTL_RD|ATW_SYNCTL_WR) == 0)
1977 : break;
1978 : DELAY(100);
1979 : }
1980 :
1981 : if (i < 0) {
1982 : printf("%s: start atw_si4126_read, SYNCTL busy\n",
1983 : sc->sc_dev.dv_xname);
1984 : return ETIMEDOUT;
1985 : }
1986 :
1987 : reg = sc->sc_synctl_rd | LSHIFT(addr, ATW_SYNCTL_DATA_MASK);
1988 :
1989 : ATW_WRITE(sc, ATW_SYNCTL, reg);
1990 :
1991 : for (i = 1000; --i >= 0; ) {
1992 : DELAY(100);
1993 : if (ATW_ISSET(sc, ATW_SYNCTL, ATW_SYNCTL_RD) == 0)
1994 : break;
1995 : }
1996 :
1997 : ATW_CLR(sc, ATW_SYNCTL, ATW_SYNCTL_RD);
1998 :
1999 : if (i < 0) {
2000 : printf("%s: atw_si4126_read wrote %#08x, SYNCTL still busy\n",
2001 : sc->sc_dev.dv_xname, reg);
2002 : return ETIMEDOUT;
2003 : }
2004 : if (val != NULL)
2005 : *val = MASK_AND_RSHIFT(ATW_READ(sc, ATW_SYNCTL),
2006 : ATW_SYNCTL_DATA_MASK);
2007 : return 0;
2008 : }
2009 : #endif /* ATW_SYNDEBUG */
2010 :
2011 : /* XXX is the endianness correct? test. */
2012 : #define atw_calchash(addr) \
2013 : (ether_crc32_le((addr), IEEE80211_ADDR_LEN) & 0x3f)
2014 :
2015 : /*
2016 : * atw_filter_setup:
2017 : *
2018 : * Set the ADM8211's receive filter.
2019 : */
2020 : void
2021 0 : atw_filter_setup(struct atw_softc *sc)
2022 : {
2023 0 : struct ieee80211com *ic = &sc->sc_ic;
2024 0 : struct arpcom *ac = &ic->ic_ac;
2025 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
2026 : int hash;
2027 0 : u_int32_t hashes[2];
2028 : struct ether_multi *enm;
2029 : struct ether_multistep step;
2030 :
2031 : /* According to comments in tlp_al981_filter_setup
2032 : * (dev/ic/tulip.c) the ADMtek AL981 does not like for its
2033 : * multicast filter to be set while it is running. Hopefully
2034 : * the ADM8211 is not the same!
2035 : */
2036 0 : if ((ifp->if_flags & IFF_RUNNING) != 0)
2037 0 : atw_idle(sc, ATW_NAR_SR);
2038 :
2039 0 : sc->sc_opmode &= ~(ATW_NAR_PR|ATW_NAR_MM);
2040 :
2041 : /* XXX in scan mode, do not filter packets. Maybe this is
2042 : * unnecessary.
2043 : */
2044 0 : if (ic->ic_state == IEEE80211_S_SCAN ||
2045 0 : (ifp->if_flags & IFF_PROMISC) != 0) {
2046 0 : sc->sc_opmode |= ATW_NAR_PR;
2047 0 : goto allmulti;
2048 : }
2049 :
2050 0 : hashes[0] = hashes[1] = 0x0;
2051 :
2052 0 : if (ac->ac_multirangecnt > 0)
2053 : goto allmulti;
2054 :
2055 : /*
2056 : * Program the 64-bit multicast hash filter.
2057 : */
2058 0 : ETHER_FIRST_MULTI(step, ac, enm);
2059 0 : while (enm != NULL) {
2060 0 : hash = atw_calchash(enm->enm_addrlo);
2061 0 : hashes[hash >> 5] |= 1 << (hash & 0x1f);
2062 0 : ETHER_NEXT_MULTI(step, enm);
2063 0 : sc->sc_opmode |= ATW_NAR_MM;
2064 : }
2065 0 : ifp->if_flags &= ~IFF_ALLMULTI;
2066 0 : goto setit;
2067 :
2068 : allmulti:
2069 0 : sc->sc_opmode |= ATW_NAR_MM;
2070 0 : ifp->if_flags |= IFF_ALLMULTI;
2071 0 : hashes[0] = hashes[1] = 0xffffffff;
2072 :
2073 : setit:
2074 0 : ATW_WRITE(sc, ATW_MAR0, hashes[0]);
2075 0 : ATW_WRITE(sc, ATW_MAR1, hashes[1]);
2076 0 : ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
2077 0 : DELAY(20 * 1000);
2078 0 : ATW_WRITE(sc, ATW_RDR, 0x1);
2079 :
2080 : DPRINTF(sc, ("%s: ATW_NAR %08x opmode %08x\n", sc->sc_dev.dv_xname,
2081 : ATW_READ(sc, ATW_NAR), sc->sc_opmode));
2082 0 : }
2083 :
2084 : /* Tell the ADM8211 our preferred BSSID. The ADM8211 must match
2085 : * a beacon's BSSID and SSID against the preferred BSSID and SSID
2086 : * before it will raise ATW_INTR_LINKON. When the ADM8211 receives
2087 : * no beacon with the preferred BSSID and SSID in the number of
2088 : * beacon intervals given in ATW_BPLI, then it raises ATW_INTR_LINKOFF.
2089 : */
2090 : void
2091 0 : atw_write_bssid(struct atw_softc *sc)
2092 : {
2093 0 : struct ieee80211com *ic = &sc->sc_ic;
2094 : u_int8_t *bssid;
2095 :
2096 0 : bssid = ic->ic_bss->ni_bssid;
2097 :
2098 0 : ATW_WRITE(sc, ATW_BSSID0,
2099 : LSHIFT(bssid[0], ATW_BSSID0_BSSIDB0_MASK) |
2100 : LSHIFT(bssid[1], ATW_BSSID0_BSSIDB1_MASK) |
2101 : LSHIFT(bssid[2], ATW_BSSID0_BSSIDB2_MASK) |
2102 : LSHIFT(bssid[3], ATW_BSSID0_BSSIDB3_MASK));
2103 :
2104 0 : ATW_WRITE(sc, ATW_ABDA1,
2105 : (ATW_READ(sc, ATW_ABDA1) &
2106 : ~(ATW_ABDA1_BSSIDB4_MASK|ATW_ABDA1_BSSIDB5_MASK)) |
2107 : LSHIFT(bssid[4], ATW_ABDA1_BSSIDB4_MASK) |
2108 : LSHIFT(bssid[5], ATW_ABDA1_BSSIDB5_MASK));
2109 :
2110 : DPRINTF(sc, ("%s: BSSID %s -> ", sc->sc_dev.dv_xname,
2111 : ether_sprintf(sc->sc_bssid)));
2112 : DPRINTF(sc, ("%s\n", ether_sprintf(bssid)));
2113 :
2114 0 : memcpy(sc->sc_bssid, bssid, sizeof(sc->sc_bssid));
2115 0 : }
2116 :
2117 : /* Write buflen bytes from buf to SRAM starting at the SRAM's ofs'th
2118 : * 16-bit word.
2119 : */
2120 : void
2121 0 : atw_write_sram(struct atw_softc *sc, u_int ofs, u_int8_t *buf, u_int buflen)
2122 : {
2123 : u_int i;
2124 : u_int8_t *ptr;
2125 :
2126 0 : memcpy(&sc->sc_sram[ofs], buf, buflen);
2127 :
2128 0 : KASSERT(ofs % 2 == 0 && buflen % 2 == 0);
2129 :
2130 0 : KASSERT(buflen + ofs <= sc->sc_sramlen);
2131 :
2132 : ptr = &sc->sc_sram[ofs];
2133 :
2134 0 : for (i = 0; i < buflen; i += 2) {
2135 0 : ATW_WRITE(sc, ATW_WEPCTL, ATW_WEPCTL_WR |
2136 : LSHIFT((ofs + i) / 2, ATW_WEPCTL_TBLADD_MASK));
2137 0 : DELAY(atw_writewep_delay);
2138 :
2139 0 : ATW_WRITE(sc, ATW_WESK,
2140 : LSHIFT((ptr[i + 1] << 8) | ptr[i], ATW_WESK_DATA_MASK));
2141 0 : DELAY(atw_writewep_delay);
2142 : }
2143 0 : ATW_WRITE(sc, ATW_WEPCTL, sc->sc_wepctl); /* restore WEP condition */
2144 :
2145 0 : if (sc->sc_if.if_flags & IFF_DEBUG) {
2146 : int n_octets = 0;
2147 0 : printf("%s: wrote %d bytes at 0x%x wepctl 0x%08x\n",
2148 0 : sc->sc_dev.dv_xname, buflen, ofs, sc->sc_wepctl);
2149 0 : for (i = 0; i < buflen; i++) {
2150 0 : printf(" %02x", ptr[i]);
2151 0 : if (++n_octets % 24 == 0)
2152 0 : printf("\n");
2153 : }
2154 0 : if (n_octets % 24 != 0)
2155 0 : printf("\n");
2156 0 : }
2157 0 : }
2158 :
2159 : /* Write WEP keys from the ieee80211com to the ADM8211's SRAM. */
2160 : void
2161 0 : atw_write_wep(struct atw_softc *sc)
2162 : {
2163 0 : struct ieee80211com *ic = &sc->sc_ic;
2164 : #if 0
2165 : u_int32_t reg;
2166 : int i;
2167 : #endif
2168 : /* SRAM shared-key record format: key0 flags key1 ... key12 */
2169 0 : u_int8_t buf[IEEE80211_WEP_NKID]
2170 : [1 /* key[0] */ + 1 /* flags */ + 12 /* key[1 .. 12] */];
2171 :
2172 0 : sc->sc_wepctl = 0;
2173 0 : ATW_WRITE(sc, ATW_WEPCTL, sc->sc_wepctl);
2174 :
2175 0 : if ((ic->ic_flags & IEEE80211_F_WEPON) == 0)
2176 0 : return;
2177 :
2178 0 : memset(&buf[0][0], 0, sizeof(buf));
2179 :
2180 : #if 0
2181 : for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2182 : if (ic->ic_nw_keys[i].k_len > 5) {
2183 : buf[i][1] = ATW_WEP_ENABLED | ATW_WEP_104BIT;
2184 : } else if (ic->ic_nw_keys[i].k_len != 0) {
2185 : buf[i][1] = ATW_WEP_ENABLED;
2186 : } else {
2187 : buf[i][1] = 0;
2188 : continue;
2189 : }
2190 : buf[i][0] = ic->ic_nw_keys[i].k_key[0];
2191 : memcpy(&buf[i][2], &ic->ic_nw_keys[i].k_key[1],
2192 : ic->ic_nw_keys[i].k_len - 1);
2193 : }
2194 :
2195 : reg = ATW_READ(sc, ATW_MACTEST);
2196 : reg |= ATW_MACTEST_MMI_USETXCLK | ATW_MACTEST_FORCE_KEYID;
2197 : reg &= ~ATW_MACTEST_KEYID_MASK;
2198 : reg |= LSHIFT(ic->ic_wep_txkey, ATW_MACTEST_KEYID_MASK);
2199 : ATW_WRITE(sc, ATW_MACTEST, reg);
2200 :
2201 : sc->sc_wepctl = ATW_WEPCTL_WEPENABLE;
2202 :
2203 : switch (sc->sc_rev) {
2204 : case ATW_REVISION_AB:
2205 : case ATW_REVISION_AF:
2206 : /* Bypass WEP on Rx. */
2207 : sc->sc_wepctl |= ATW_WEPCTL_WEPRXBYP;
2208 : break;
2209 : default:
2210 : break;
2211 : }
2212 : #endif
2213 :
2214 0 : atw_write_sram(sc, ATW_SRAM_ADDR_SHARED_KEY, (u_int8_t*)&buf[0][0],
2215 : sizeof(buf));
2216 0 : }
2217 :
2218 : void
2219 0 : atw_change_ibss(struct atw_softc *sc)
2220 : {
2221 0 : atw_predict_beacon(sc);
2222 0 : atw_write_bssid(sc);
2223 0 : atw_start_beacon(sc, 1);
2224 0 : }
2225 :
2226 : #ifndef IEEE80211_STA_ONLY
2227 : void
2228 0 : atw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
2229 : struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int subtype)
2230 : {
2231 0 : struct atw_softc *sc = (struct atw_softc*)ic->ic_softc;
2232 :
2233 : /* The ADM8211A answers probe requests. */
2234 0 : if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_REQ &&
2235 0 : sc->sc_rev < ATW_REVISION_BA)
2236 0 : return;
2237 :
2238 0 : (*sc->sc_recv_mgmt)(ic, m, ni, rxi, subtype);
2239 :
2240 0 : switch (subtype) {
2241 : case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
2242 : case IEEE80211_FC0_SUBTYPE_BEACON:
2243 0 : if (ic->ic_opmode != IEEE80211_M_IBSS ||
2244 0 : ic->ic_state != IEEE80211_S_RUN)
2245 : break;
2246 0 : if (ieee80211_ibss_merge(ic, ni, atw_get_tsft(sc)) == ENETRESET)
2247 0 : atw_change_ibss(sc);
2248 : break;
2249 : default:
2250 : break;
2251 : }
2252 0 : return;
2253 0 : }
2254 : #endif
2255 :
2256 : /* Write the SSID in the ieee80211com to the SRAM on the ADM8211.
2257 : * In ad hoc mode, the SSID is written to the beacons sent by the
2258 : * ADM8211. In both ad hoc and infrastructure mode, beacons received
2259 : * with matching SSID affect ATW_INTR_LINKON/ATW_INTR_LINKOFF
2260 : * indications.
2261 : */
2262 : void
2263 0 : atw_write_ssid(struct atw_softc *sc)
2264 : {
2265 0 : struct ieee80211com *ic = &sc->sc_ic;
2266 : /* 34 bytes are reserved in ADM8211 SRAM for the SSID, but
2267 : * it only expects the element length, not its ID.
2268 : */
2269 0 : u_int8_t buf[roundup(1 /* length */ + IEEE80211_NWID_LEN, 2)];
2270 :
2271 0 : memset(buf, 0, sizeof(buf));
2272 0 : buf[0] = ic->ic_bss->ni_esslen;
2273 0 : memcpy(&buf[1], ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen);
2274 :
2275 0 : atw_write_sram(sc, ATW_SRAM_ADDR_SSID, buf,
2276 0 : roundup(1 + ic->ic_bss->ni_esslen, 2));
2277 0 : }
2278 :
2279 : /* Write the supported rates in the ieee80211com to the SRAM of the ADM8211.
2280 : * In ad hoc mode, the supported rates are written to beacons sent by the
2281 : * ADM8211.
2282 : */
2283 : void
2284 0 : atw_write_sup_rates(struct atw_softc *sc)
2285 : {
2286 0 : struct ieee80211com *ic = &sc->sc_ic;
2287 : /*
2288 : * There is not enough space in the ADM8211 SRAM for the
2289 : * full IEEE80211_RATE_MAXSIZE
2290 : */
2291 0 : u_int8_t buf[12];
2292 : u_int8_t nrates;
2293 :
2294 0 : memset(buf, 0, sizeof(buf));
2295 0 : if (ic->ic_bss->ni_rates.rs_nrates > sizeof(buf) - 1)
2296 0 : nrates = sizeof(buf) - 1;
2297 : else
2298 : nrates = ic->ic_bss->ni_rates.rs_nrates;
2299 0 : buf[0] = nrates;
2300 0 : memcpy(&buf[1], ic->ic_bss->ni_rates.rs_rates, nrates);
2301 :
2302 : /* XXX deal with rev BA bug linux driver talks of? */
2303 :
2304 0 : atw_write_sram(sc, ATW_SRAM_ADDR_SUPRATES, buf, sizeof(buf));
2305 0 : }
2306 :
2307 : /* Start/stop sending beacons. */
2308 : void
2309 0 : atw_start_beacon(struct atw_softc *sc, int start)
2310 : {
2311 0 : struct ieee80211com *ic = &sc->sc_ic;
2312 : #ifndef IEEE80211_STA_ONLY
2313 : uint16_t chan;
2314 : uint32_t bpli;
2315 : #endif
2316 : uint32_t bcnt, cap0, cap1, capinfo;
2317 : size_t len;
2318 :
2319 0 : if (ATW_IS_ENABLED(sc) == 0)
2320 0 : return;
2321 :
2322 : /* start beacons */
2323 : len = sizeof(struct ieee80211_frame) +
2324 : 8 /* timestamp */ + 2 /* beacon interval */ +
2325 : 2 /* capability info */ +
2326 0 : 2 + ic->ic_bss->ni_esslen /* SSID element */ +
2327 0 : 2 + ic->ic_bss->ni_rates.rs_nrates /* rates element */ +
2328 0 : 3 /* DS parameters */ +
2329 : IEEE80211_CRC_LEN;
2330 :
2331 0 : bcnt = ATW_READ(sc, ATW_BCNT) & ~ATW_BCNT_BCNT_MASK;
2332 0 : cap0 = ATW_READ(sc, ATW_CAP0) & ~ATW_CAP0_CHN_MASK;
2333 0 : cap1 = ATW_READ(sc, ATW_CAP1) & ~ATW_CAP1_CAPI_MASK;
2334 :
2335 0 : ATW_WRITE(sc, ATW_BCNT, bcnt);
2336 0 : ATW_WRITE(sc, ATW_CAP1, cap1);
2337 :
2338 0 : if (!start)
2339 0 : return;
2340 :
2341 : /* TBD use ni_capinfo */
2342 :
2343 : capinfo = 0;
2344 0 : if (sc->sc_flags & ATWF_SHORT_PREAMBLE)
2345 0 : capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
2346 0 : if (ic->ic_flags & IEEE80211_F_WEPON)
2347 0 : capinfo |= IEEE80211_CAPINFO_PRIVACY;
2348 :
2349 : #ifndef IEEE80211_STA_ONLY
2350 0 : switch (ic->ic_opmode) {
2351 : case IEEE80211_M_IBSS:
2352 0 : len += 4; /* IBSS parameters */
2353 0 : capinfo |= IEEE80211_CAPINFO_IBSS;
2354 : break;
2355 : default:
2356 0 : return;
2357 : }
2358 :
2359 : /* set listen interval
2360 : * XXX do software units agree w/ hardware?
2361 : */
2362 0 : bpli = LSHIFT(ic->ic_bss->ni_intval, ATW_BPLI_BP_MASK) |
2363 0 : LSHIFT(ic->ic_lintval / ic->ic_bss->ni_intval, ATW_BPLI_LI_MASK);
2364 :
2365 0 : chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
2366 :
2367 0 : bcnt |= LSHIFT(len, ATW_BCNT_BCNT_MASK);
2368 0 : cap0 |= LSHIFT(chan, ATW_CAP0_CHN_MASK);
2369 0 : cap1 |= LSHIFT(capinfo, ATW_CAP1_CAPI_MASK);
2370 :
2371 0 : ATW_WRITE(sc, ATW_BCNT, bcnt);
2372 0 : ATW_WRITE(sc, ATW_BPLI, bpli);
2373 0 : ATW_WRITE(sc, ATW_CAP0, cap0);
2374 0 : ATW_WRITE(sc, ATW_CAP1, cap1);
2375 :
2376 : DPRINTF(sc, ("%s: atw_start_beacon reg[ATW_BCNT] = %08x\n",
2377 : sc->sc_dev.dv_xname, bcnt));
2378 : DPRINTF(sc, ("%s: atw_start_beacon reg[ATW_CAP1] = %08x\n",
2379 : sc->sc_dev.dv_xname, cap1));
2380 : #endif
2381 0 : }
2382 :
2383 : /* Return the 32 lsb of the last TSFT divisible by ival. */
2384 : static __inline uint32_t
2385 0 : atw_last_even_tsft(uint32_t tsfth, uint32_t tsftl, uint32_t ival)
2386 : {
2387 : /* Following the reference driver's lead, I compute
2388 : *
2389 : * (uint32_t)((((uint64_t)tsfth << 32) | tsftl) % ival)
2390 : *
2391 : * without using 64-bit arithmetic, using the following
2392 : * relationship:
2393 : *
2394 : * (0x100000000 * H + L) % m
2395 : * = ((0x100000000 % m) * H + L) % m
2396 : * = (((0xffffffff + 1) % m) * H + L) % m
2397 : * = ((0xffffffff % m + 1 % m) * H + L) % m
2398 : * = ((0xffffffff % m + 1) * H + L) % m
2399 : */
2400 0 : return ((0xFFFFFFFF % ival + 1) * tsfth + tsftl) % ival;
2401 : }
2402 :
2403 : uint64_t
2404 0 : atw_get_tsft(struct atw_softc *sc)
2405 : {
2406 : int i;
2407 : uint32_t tsfth, tsftl;
2408 0 : for (i = 0; i < 2; i++) {
2409 0 : tsfth = ATW_READ(sc, ATW_TSFTH);
2410 0 : tsftl = ATW_READ(sc, ATW_TSFTL);
2411 0 : if (ATW_READ(sc, ATW_TSFTH) == tsfth)
2412 : break;
2413 : }
2414 0 : return ((uint64_t)tsfth << 32) | tsftl;
2415 : }
2416 :
2417 : /* If we've created an IBSS, write the TSF time in the ADM8211 to
2418 : * the ieee80211com.
2419 : *
2420 : * Predict the next target beacon transmission time (TBTT) and
2421 : * write it to the ADM8211.
2422 : */
2423 : void
2424 0 : atw_predict_beacon(struct atw_softc *sc)
2425 : {
2426 : #define TBTTOFS 20 /* TU */
2427 :
2428 0 : struct ieee80211com *ic = &sc->sc_ic;
2429 : uint64_t tsft;
2430 : uint32_t ival, past_even, tbtt, tsfth, tsftl;
2431 : union {
2432 : uint64_t word;
2433 : uint8_t tstamp[8];
2434 : } u;
2435 :
2436 : #ifndef IEEE80211_STA_ONLY
2437 0 : if ((ic->ic_opmode == IEEE80211_M_IBSS) &&
2438 0 : (ic->ic_flags & IEEE80211_F_SIBSS)) {
2439 0 : tsft = atw_get_tsft(sc);
2440 : u.word = htole64(tsft);
2441 0 : (void)memcpy(&ic->ic_bss->ni_tstamp[0], &u.tstamp[0],
2442 : sizeof(ic->ic_bss->ni_tstamp));
2443 0 : } else
2444 : #endif
2445 : {
2446 0 : (void)memcpy(&u, &ic->ic_bss->ni_tstamp[0], sizeof(u));
2447 : tsft = letoh64(u.word);
2448 : }
2449 :
2450 0 : ival = ic->ic_bss->ni_intval * IEEE80211_DUR_TU;
2451 :
2452 0 : tsftl = tsft & 0xFFFFFFFF;
2453 0 : tsfth = tsft >> 32;
2454 :
2455 : /* We sent/received the last beacon `past' microseconds
2456 : * after the interval divided the TSF timer.
2457 : */
2458 0 : past_even = tsftl - atw_last_even_tsft(tsfth, tsftl, ival);
2459 :
2460 : /* Skip ten beacons so that the TBTT cannot pass before
2461 : * we've programmed it. Ten is an arbitrary number.
2462 : */
2463 0 : tbtt = past_even + ival * 10;
2464 :
2465 0 : ATW_WRITE(sc, ATW_TOFS1,
2466 : LSHIFT(1, ATW_TOFS1_TSFTOFSR_MASK) |
2467 : LSHIFT(TBTTOFS, ATW_TOFS1_TBTTOFS_MASK) |
2468 : LSHIFT(MASK_AND_RSHIFT(tbtt - TBTTOFS * IEEE80211_DUR_TU,
2469 : ATW_TBTTPRE_MASK), ATW_TOFS1_TBTTPRE_MASK));
2470 : #undef TBTTOFS
2471 0 : }
2472 :
2473 : void
2474 0 : atw_next_scan(void *arg)
2475 : {
2476 0 : struct atw_softc *sc = arg;
2477 0 : struct ieee80211com *ic = &sc->sc_ic;
2478 0 : struct ifnet *ifp = &ic->ic_if;
2479 : int s;
2480 :
2481 : /* don't call atw_start w/o network interrupts blocked */
2482 0 : s = splnet();
2483 0 : if (ic->ic_state == IEEE80211_S_SCAN)
2484 0 : ieee80211_next_scan(ifp);
2485 0 : splx(s);
2486 0 : }
2487 :
2488 : /* Synchronize the hardware state with the software state. */
2489 : int
2490 0 : atw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
2491 : {
2492 0 : struct ifnet *ifp = &ic->ic_if;
2493 0 : struct atw_softc *sc = ifp->if_softc;
2494 0 : enum ieee80211_state ostate = ic->ic_state;
2495 : int error;
2496 :
2497 0 : if (nstate == IEEE80211_S_INIT) {
2498 0 : timeout_del(&sc->sc_scan_to);
2499 0 : sc->sc_cur_chan = IEEE80211_CHAN_ANY;
2500 0 : atw_start_beacon(sc, 0);
2501 0 : return (*sc->sc_newstate)(ic, nstate, arg);
2502 : }
2503 :
2504 0 : if ((error = atw_tune(sc)) != 0)
2505 0 : return error;
2506 :
2507 0 : switch (nstate) {
2508 : case IEEE80211_S_ASSOC:
2509 : break;
2510 : case IEEE80211_S_INIT:
2511 0 : panic("%s: unexpected state IEEE80211_S_INIT", __func__);
2512 : break;
2513 : case IEEE80211_S_SCAN:
2514 0 : timeout_add_msec(&sc->sc_scan_to, atw_dwelltime);
2515 0 : break;
2516 : case IEEE80211_S_RUN:
2517 0 : if (ic->ic_opmode == IEEE80211_M_STA)
2518 : break;
2519 : /*FALLTHROUGH*/
2520 : case IEEE80211_S_AUTH:
2521 0 : atw_write_bssid(sc);
2522 0 : atw_write_ssid(sc);
2523 0 : atw_write_sup_rates(sc);
2524 :
2525 : if (
2526 : #ifndef IEEE80211_STA_ONLY
2527 0 : ic->ic_opmode == IEEE80211_M_AHDEMO ||
2528 : #endif
2529 0 : ic->ic_opmode == IEEE80211_M_MONITOR)
2530 : break;
2531 :
2532 : /* set listen interval
2533 : * XXX do software units agree w/ hardware?
2534 : */
2535 0 : ATW_WRITE(sc, ATW_BPLI,
2536 : LSHIFT(ic->ic_bss->ni_intval, ATW_BPLI_BP_MASK) |
2537 : LSHIFT(ic->ic_lintval / ic->ic_bss->ni_intval,
2538 : ATW_BPLI_LI_MASK));
2539 :
2540 : DPRINTF(sc, ("%s: reg[ATW_BPLI] = %08x\n",
2541 : sc->sc_dev.dv_xname, ATW_READ(sc, ATW_BPLI)));
2542 :
2543 0 : atw_predict_beacon(sc);
2544 0 : break;
2545 : }
2546 :
2547 0 : if (nstate != IEEE80211_S_SCAN)
2548 0 : timeout_del(&sc->sc_scan_to);
2549 :
2550 : #ifndef IEEE80211_STA_ONLY
2551 0 : if (nstate == IEEE80211_S_RUN &&
2552 0 : ic->ic_opmode == IEEE80211_M_IBSS)
2553 0 : atw_start_beacon(sc, 1);
2554 : else
2555 : #endif
2556 0 : atw_start_beacon(sc, 0);
2557 :
2558 0 : error = (*sc->sc_newstate)(ic, nstate, arg);
2559 :
2560 0 : if (ostate == IEEE80211_S_INIT && nstate == IEEE80211_S_SCAN)
2561 0 : atw_write_bssid(sc);
2562 :
2563 0 : return error;
2564 0 : }
2565 :
2566 : /*
2567 : * atw_add_rxbuf:
2568 : *
2569 : * Add a receive buffer to the indicated descriptor.
2570 : */
2571 : int
2572 0 : atw_add_rxbuf(struct atw_softc *sc, int idx)
2573 : {
2574 0 : struct atw_rxsoft *rxs = &sc->sc_rxsoft[idx];
2575 : struct mbuf *m;
2576 : int error;
2577 :
2578 0 : MGETHDR(m, M_DONTWAIT, MT_DATA);
2579 0 : if (m == NULL)
2580 0 : return (ENOBUFS);
2581 :
2582 0 : MCLGET(m, M_DONTWAIT);
2583 0 : if ((m->m_flags & M_EXT) == 0) {
2584 0 : m_freem(m);
2585 0 : return (ENOBUFS);
2586 : }
2587 :
2588 0 : if (rxs->rxs_mbuf != NULL)
2589 0 : bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
2590 :
2591 0 : rxs->rxs_mbuf = m;
2592 :
2593 0 : error = bus_dmamap_load(sc->sc_dmat, rxs->rxs_dmamap,
2594 : m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
2595 : BUS_DMA_READ|BUS_DMA_NOWAIT);
2596 0 : if (error) {
2597 0 : printf("%s: can't load rx DMA map %d, error = %d\n",
2598 0 : sc->sc_dev.dv_xname, idx, error);
2599 0 : panic("atw_add_rxbuf"); /* XXX */
2600 : }
2601 :
2602 0 : bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
2603 : rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
2604 :
2605 0 : ATW_INIT_RXDESC(sc, idx);
2606 :
2607 0 : return (0);
2608 0 : }
2609 :
2610 : /*
2611 : * Release any queued transmit buffers.
2612 : */
2613 : void
2614 0 : atw_txdrain(struct atw_softc *sc)
2615 : {
2616 : struct atw_txsoft *txs;
2617 :
2618 0 : while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
2619 0 : SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
2620 0 : if (txs->txs_mbuf != NULL) {
2621 0 : bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
2622 0 : m_freem(txs->txs_mbuf);
2623 0 : txs->txs_mbuf = NULL;
2624 0 : }
2625 0 : SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
2626 : }
2627 0 : sc->sc_tx_timer = 0;
2628 0 : }
2629 :
2630 : /*
2631 : * atw_stop: [ ifnet interface function ]
2632 : *
2633 : * Stop transmission on the interface.
2634 : */
2635 : void
2636 0 : atw_stop(struct ifnet *ifp, int disable)
2637 : {
2638 0 : struct atw_softc *sc = ifp->if_softc;
2639 0 : struct ieee80211com *ic = &sc->sc_ic;
2640 :
2641 0 : ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2642 :
2643 : /*
2644 : * Mark the interface down and cancel the watchdog timer.
2645 : */
2646 0 : ifp->if_flags &= ~IFF_RUNNING;
2647 0 : ifq_clr_oactive(&ifp->if_snd);
2648 0 : ifp->if_timer = 0;
2649 :
2650 : /* Disable interrupts. */
2651 0 : ATW_WRITE(sc, ATW_IER, 0);
2652 :
2653 : /* Stop the transmit and receive processes. */
2654 0 : sc->sc_opmode = 0;
2655 0 : ATW_WRITE(sc, ATW_NAR, 0);
2656 0 : DELAY(20 * 1000);
2657 0 : ATW_WRITE(sc, ATW_TDBD, 0);
2658 0 : ATW_WRITE(sc, ATW_TDBP, 0);
2659 0 : ATW_WRITE(sc, ATW_RDB, 0);
2660 :
2661 0 : atw_txdrain(sc);
2662 :
2663 0 : if (disable) {
2664 0 : atw_rxdrain(sc);
2665 0 : atw_disable(sc);
2666 0 : }
2667 :
2668 0 : if (!disable)
2669 0 : atw_reset(sc);
2670 0 : }
2671 :
2672 : /*
2673 : * atw_rxdrain:
2674 : *
2675 : * Drain the receive queue.
2676 : */
2677 : void
2678 0 : atw_rxdrain(struct atw_softc *sc)
2679 : {
2680 : struct atw_rxsoft *rxs;
2681 : int i;
2682 :
2683 0 : for (i = 0; i < ATW_NRXDESC; i++) {
2684 0 : rxs = &sc->sc_rxsoft[i];
2685 0 : if (rxs->rxs_mbuf == NULL)
2686 : continue;
2687 0 : bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
2688 0 : m_freem(rxs->rxs_mbuf);
2689 0 : rxs->rxs_mbuf = NULL;
2690 0 : }
2691 0 : }
2692 :
2693 : /*
2694 : * atw_detach:
2695 : *
2696 : * Detach an ADM8211 interface.
2697 : */
2698 : int
2699 0 : atw_detach(struct atw_softc *sc)
2700 : {
2701 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
2702 : struct atw_rxsoft *rxs;
2703 : struct atw_txsoft *txs;
2704 : int i;
2705 :
2706 : /*
2707 : * Succeed now if there isn't any work to do.
2708 : */
2709 0 : if ((sc->sc_flags & ATWF_ATTACHED) == 0)
2710 0 : return (0);
2711 :
2712 0 : timeout_del(&sc->sc_scan_to);
2713 :
2714 0 : ieee80211_ifdetach(ifp);
2715 0 : if_detach(ifp);
2716 :
2717 0 : for (i = 0; i < ATW_NRXDESC; i++) {
2718 0 : rxs = &sc->sc_rxsoft[i];
2719 0 : if (rxs->rxs_mbuf != NULL) {
2720 0 : bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
2721 0 : m_freem(rxs->rxs_mbuf);
2722 0 : rxs->rxs_mbuf = NULL;
2723 0 : }
2724 0 : bus_dmamap_destroy(sc->sc_dmat, rxs->rxs_dmamap);
2725 : }
2726 0 : for (i = 0; i < ATW_TXQUEUELEN; i++) {
2727 0 : txs = &sc->sc_txsoft[i];
2728 0 : if (txs->txs_mbuf != NULL) {
2729 0 : bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
2730 0 : m_freem(txs->txs_mbuf);
2731 0 : txs->txs_mbuf = NULL;
2732 0 : }
2733 0 : bus_dmamap_destroy(sc->sc_dmat, txs->txs_dmamap);
2734 : }
2735 0 : bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
2736 0 : bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
2737 0 : bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
2738 : sizeof(struct atw_control_data));
2739 0 : bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
2740 :
2741 0 : if (sc->sc_srom)
2742 0 : free(sc->sc_srom, M_DEVBUF, sc->sc_sromsz);
2743 :
2744 0 : return (0);
2745 0 : }
2746 :
2747 : int
2748 0 : atw_intr(void *arg)
2749 : {
2750 0 : struct atw_softc *sc = arg;
2751 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
2752 : u_int32_t status, rxstatus, txstatus, linkstatus;
2753 : int handled = 0, txthresh;
2754 :
2755 : #ifdef DEBUG
2756 : if (ATW_IS_ENABLED(sc) == 0)
2757 : panic("%s: atw_intr: not enabled", sc->sc_dev.dv_xname);
2758 : #endif
2759 :
2760 : /*
2761 : * If the interface isn't running, the interrupt couldn't
2762 : * possibly have come from us.
2763 : */
2764 0 : if ((ifp->if_flags & IFF_RUNNING) == 0 ||
2765 0 : (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
2766 0 : return (0);
2767 :
2768 0 : for (;;) {
2769 0 : status = ATW_READ(sc, ATW_STSR);
2770 :
2771 0 : if (status)
2772 0 : ATW_WRITE(sc, ATW_STSR, status);
2773 :
2774 : #ifdef ATW_DEBUG
2775 : #define PRINTINTR(flag) do { \
2776 : if ((status & flag) != 0) { \
2777 : printf("%s" #flag, delim); \
2778 : delim = ","; \
2779 : } \
2780 : } while (0)
2781 :
2782 : if (atw_debug > 1 && status) {
2783 : const char *delim = "<";
2784 :
2785 : printf("%s: reg[STSR] = %x",
2786 : sc->sc_dev.dv_xname, status);
2787 :
2788 : PRINTINTR(ATW_INTR_FBE);
2789 : PRINTINTR(ATW_INTR_LINKOFF);
2790 : PRINTINTR(ATW_INTR_LINKON);
2791 : PRINTINTR(ATW_INTR_RCI);
2792 : PRINTINTR(ATW_INTR_RDU);
2793 : PRINTINTR(ATW_INTR_REIS);
2794 : PRINTINTR(ATW_INTR_RPS);
2795 : PRINTINTR(ATW_INTR_TCI);
2796 : PRINTINTR(ATW_INTR_TDU);
2797 : PRINTINTR(ATW_INTR_TLT);
2798 : PRINTINTR(ATW_INTR_TPS);
2799 : PRINTINTR(ATW_INTR_TRT);
2800 : PRINTINTR(ATW_INTR_TUF);
2801 : PRINTINTR(ATW_INTR_BCNTC);
2802 : PRINTINTR(ATW_INTR_ATIME);
2803 : PRINTINTR(ATW_INTR_TBTT);
2804 : PRINTINTR(ATW_INTR_TSCZ);
2805 : PRINTINTR(ATW_INTR_TSFTF);
2806 : printf(">\n");
2807 : }
2808 : #undef PRINTINTR
2809 : #endif /* ATW_DEBUG */
2810 :
2811 0 : if ((status & sc->sc_inten) == 0)
2812 : break;
2813 :
2814 : handled = 1;
2815 :
2816 0 : rxstatus = status & sc->sc_rxint_mask;
2817 0 : txstatus = status & sc->sc_txint_mask;
2818 0 : linkstatus = status & sc->sc_linkint_mask;
2819 :
2820 0 : if (linkstatus) {
2821 0 : atw_linkintr(sc, linkstatus);
2822 0 : }
2823 :
2824 0 : if (rxstatus) {
2825 : /* Grab any new packets. */
2826 0 : atw_rxintr(sc);
2827 :
2828 0 : if (rxstatus & ATW_INTR_RDU) {
2829 0 : printf("%s: receive ring overrun\n",
2830 0 : sc->sc_dev.dv_xname);
2831 : /* Get the receive process going again. */
2832 0 : ATW_WRITE(sc, ATW_RDR, 0x1);
2833 0 : break;
2834 : }
2835 : }
2836 :
2837 0 : if (txstatus) {
2838 : /* Sweep up transmit descriptors. */
2839 0 : atw_txintr(sc);
2840 :
2841 0 : if (txstatus & ATW_INTR_TLT)
2842 : DPRINTF(sc, ("%s: tx lifetime exceeded\n",
2843 : sc->sc_dev.dv_xname));
2844 :
2845 0 : if (txstatus & ATW_INTR_TRT)
2846 : DPRINTF(sc, ("%s: tx retry limit exceeded\n",
2847 : sc->sc_dev.dv_xname));
2848 :
2849 : /* If Tx under-run, increase our transmit threshold
2850 : * if another is available.
2851 : */
2852 0 : txthresh = sc->sc_txthresh + 1;
2853 0 : if ((txstatus & ATW_INTR_TUF) &&
2854 0 : sc->sc_txth[txthresh].txth_name != NULL) {
2855 : /* Idle the transmit process. */
2856 0 : atw_idle(sc, ATW_NAR_ST);
2857 :
2858 0 : sc->sc_txthresh = txthresh;
2859 0 : sc->sc_opmode &= ~(ATW_NAR_TR_MASK|ATW_NAR_SF);
2860 0 : sc->sc_opmode |=
2861 0 : sc->sc_txth[txthresh].txth_opmode;
2862 0 : printf("%s: transmit underrun; new "
2863 0 : "threshold: %s\n", sc->sc_dev.dv_xname,
2864 0 : sc->sc_txth[txthresh].txth_name);
2865 :
2866 : /* Set the new threshold and restart
2867 : * the transmit process.
2868 : */
2869 0 : ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
2870 0 : DELAY(20 * 1000);
2871 0 : ATW_WRITE(sc, ATW_RDR, 0x1);
2872 : /* XXX Log every Nth underrun from
2873 : * XXX now on?
2874 : */
2875 0 : }
2876 : }
2877 :
2878 0 : if (status & (ATW_INTR_TPS|ATW_INTR_RPS)) {
2879 0 : if (status & ATW_INTR_TPS)
2880 0 : printf("%s: transmit process stopped\n",
2881 0 : sc->sc_dev.dv_xname);
2882 0 : if (status & ATW_INTR_RPS)
2883 0 : printf("%s: receive process stopped\n",
2884 0 : sc->sc_dev.dv_xname);
2885 0 : (void)atw_init(ifp);
2886 0 : break;
2887 : }
2888 :
2889 0 : if (status & ATW_INTR_FBE) {
2890 0 : printf("%s: fatal bus error\n", sc->sc_dev.dv_xname);
2891 0 : (void)atw_init(ifp);
2892 0 : break;
2893 : }
2894 :
2895 : /*
2896 : * Not handled:
2897 : *
2898 : * Transmit buffer unavailable -- normal
2899 : * condition, nothing to do, really.
2900 : *
2901 : * Early receive interrupt -- not available on
2902 : * all chips, we just use RI. We also only
2903 : * use single-segment receive DMA, so this
2904 : * is mostly useless.
2905 : *
2906 : * TBD others
2907 : */
2908 : }
2909 :
2910 : /* Try to get more packets going. */
2911 0 : atw_start(ifp);
2912 :
2913 0 : return (handled);
2914 0 : }
2915 :
2916 : /*
2917 : * atw_idle:
2918 : *
2919 : * Cause the transmit and/or receive processes to go idle.
2920 : *
2921 : * XXX It seems that the ADM8211 will not signal the end of the Rx/Tx
2922 : * process in STSR if I clear SR or ST after the process has already
2923 : * ceased. Fair enough. But the Rx process status bits in ATW_TEST0
2924 : * do not seem to be too reliable. Perhaps I have the sense of the
2925 : * Rx bits switched with the Tx bits?
2926 : */
2927 : void
2928 0 : atw_idle(struct atw_softc *sc, u_int32_t bits)
2929 : {
2930 : u_int32_t ackmask = 0, opmode, stsr, test0;
2931 : int i, s;
2932 :
2933 0 : s = splnet();
2934 :
2935 0 : opmode = sc->sc_opmode & ~bits;
2936 :
2937 0 : if (bits & ATW_NAR_SR)
2938 0 : ackmask |= ATW_INTR_RPS;
2939 :
2940 0 : if (bits & ATW_NAR_ST) {
2941 0 : ackmask |= ATW_INTR_TPS;
2942 : /* set ATW_NAR_HF to flush TX FIFO. */
2943 0 : opmode |= ATW_NAR_HF;
2944 0 : }
2945 :
2946 0 : ATW_WRITE(sc, ATW_NAR, opmode);
2947 0 : DELAY(20 * 1000);
2948 :
2949 0 : for (i = 0; i < 10; i++) {
2950 0 : stsr = ATW_READ(sc, ATW_STSR);
2951 0 : if ((stsr & ackmask) == ackmask)
2952 : break;
2953 0 : DELAY(1000);
2954 : }
2955 :
2956 0 : ATW_WRITE(sc, ATW_STSR, stsr & ackmask);
2957 :
2958 0 : if ((stsr & ackmask) == ackmask)
2959 : goto out;
2960 :
2961 0 : test0 = ATW_READ(sc, ATW_TEST0);
2962 :
2963 : if ((bits & ATW_NAR_ST) != 0 && (stsr & ATW_INTR_TPS) == 0 &&
2964 : (test0 & ATW_TEST0_TS_MASK) != ATW_TEST0_TS_STOPPED) {
2965 : DPRINTF2(sc, ("%s: transmit process not idle [%s]\n",
2966 : sc->sc_dev.dv_xname,
2967 : atw_tx_state[MASK_AND_RSHIFT(test0, ATW_TEST0_TS_MASK)]));
2968 : DPRINTF2(sc, ("%s: bits %08x test0 %08x stsr %08x\n",
2969 : sc->sc_dev.dv_xname, bits, test0, stsr));
2970 : }
2971 :
2972 0 : if ((bits & ATW_NAR_SR) != 0 && (stsr & ATW_INTR_RPS) == 0 &&
2973 : (test0 & ATW_TEST0_RS_MASK) != ATW_TEST0_RS_STOPPED) {
2974 : DPRINTF2(sc, ("%s: receive process not idle [%s]\n",
2975 : sc->sc_dev.dv_xname,
2976 : atw_rx_state[MASK_AND_RSHIFT(test0, ATW_TEST0_RS_MASK)]));
2977 : DPRINTF2(sc, ("%s: bits %08x test0 %08x stsr %08x\n",
2978 : sc->sc_dev.dv_xname, bits, test0, stsr));
2979 : }
2980 : out:
2981 0 : if ((bits & ATW_NAR_ST) != 0)
2982 0 : atw_txdrain(sc);
2983 0 : splx(s);
2984 : return;
2985 0 : }
2986 :
2987 : /*
2988 : * atw_linkintr:
2989 : *
2990 : * Helper; handle link-status interrupts.
2991 : */
2992 : void
2993 0 : atw_linkintr(struct atw_softc *sc, u_int32_t linkstatus)
2994 : {
2995 0 : struct ieee80211com *ic = &sc->sc_ic;
2996 :
2997 0 : if (ic->ic_state != IEEE80211_S_RUN)
2998 0 : return;
2999 :
3000 0 : if (linkstatus & ATW_INTR_LINKON) {
3001 : DPRINTF(sc, ("%s: link on\n", sc->sc_dev.dv_xname));
3002 0 : sc->sc_rescan_timer = 0;
3003 0 : } else if (linkstatus & ATW_INTR_LINKOFF) {
3004 : DPRINTF(sc, ("%s: link off\n", sc->sc_dev.dv_xname));
3005 0 : if (ic->ic_opmode != IEEE80211_M_STA)
3006 0 : return;
3007 0 : sc->sc_rescan_timer = 3;
3008 0 : ic->ic_if.if_timer = 1;
3009 0 : }
3010 0 : }
3011 :
3012 : #if 0
3013 : static __inline int
3014 : atw_hw_decrypted(struct atw_softc *sc, struct ieee80211_frame *wh)
3015 : {
3016 : if ((sc->sc_ic.ic_flags & IEEE80211_F_WEPON) == 0)
3017 : return 0;
3018 : if ((wh->i_fc[1] & IEEE80211_FC1_WEP) == 0)
3019 : return 0;
3020 : return (sc->sc_wepctl & ATW_WEPCTL_WEPRXBYP) == 0;
3021 : }
3022 : #endif
3023 :
3024 : /*
3025 : * atw_rxintr:
3026 : *
3027 : * Helper; handle receive interrupts.
3028 : */
3029 : void
3030 0 : atw_rxintr(struct atw_softc *sc)
3031 : {
3032 : static int rate_tbl[] = {2, 4, 11, 22, 44};
3033 0 : struct ieee80211com *ic = &sc->sc_ic;
3034 0 : struct ieee80211_rxinfo rxi;
3035 : struct ieee80211_node *ni;
3036 : struct ieee80211_frame *wh;
3037 0 : struct ifnet *ifp = &ic->ic_if;
3038 : struct atw_rxsoft *rxs;
3039 : struct mbuf *m;
3040 : u_int32_t rxstat;
3041 : int i, len, rate, rate0;
3042 : u_int32_t rssi, rssi0;
3043 :
3044 0 : for (i = sc->sc_rxptr;; i = ATW_NEXTRX(i)) {
3045 0 : rxs = &sc->sc_rxsoft[i];
3046 :
3047 0 : ATW_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3048 :
3049 0 : rxstat = letoh32(sc->sc_rxdescs[i].ar_stat);
3050 0 : rssi0 = letoh32(sc->sc_rxdescs[i].ar_rssi);
3051 0 : rate0 = MASK_AND_RSHIFT(rxstat, ATW_RXSTAT_RXDR_MASK);
3052 :
3053 0 : if (rxstat & ATW_RXSTAT_OWN)
3054 : break; /* We have processed all receive buffers. */
3055 :
3056 : DPRINTF3(sc,
3057 : ("%s: rx stat %08x rssi0 %08x buf1 %08x buf2 %08x\n",
3058 : sc->sc_dev.dv_xname,
3059 : rxstat, rssi0,
3060 : letoh32(sc->sc_rxdescs[i].ar_buf1),
3061 : letoh32(sc->sc_rxdescs[i].ar_buf2)));
3062 :
3063 : /*
3064 : * Make sure the packet fits in one buffer. This should
3065 : * always be the case.
3066 : */
3067 0 : if ((rxstat & (ATW_RXSTAT_FS|ATW_RXSTAT_LS)) !=
3068 : (ATW_RXSTAT_FS|ATW_RXSTAT_LS)) {
3069 0 : printf("%s: incoming packet spilled, resetting\n",
3070 0 : sc->sc_dev.dv_xname);
3071 0 : (void)atw_init(ifp);
3072 0 : return;
3073 : }
3074 :
3075 : /*
3076 : * If an error occurred, update stats, clear the status
3077 : * word, and leave the packet buffer in place. It will
3078 : * simply be reused the next time the ring comes around.
3079 : * If 802.1Q VLAN MTU is enabled, ignore the Frame Too Long
3080 : * error.
3081 : */
3082 :
3083 0 : if ((rxstat & ATW_RXSTAT_ES) != 0 &&
3084 0 : ((sc->sc_ic.ic_if.if_capabilities & IFCAP_VLAN_MTU) == 0 ||
3085 0 : (rxstat & (ATW_RXSTAT_DE | ATW_RXSTAT_SFDE |
3086 : ATW_RXSTAT_SIGE | ATW_RXSTAT_CRC16E |
3087 : ATW_RXSTAT_RXTOE | ATW_RXSTAT_CRC32E |
3088 0 : ATW_RXSTAT_ICVE)) != 0)) {
3089 : #define PRINTERR(bit, str) \
3090 : if (rxstat & (bit)) \
3091 : printf("%s: receive error: %s\n", \
3092 : sc->sc_dev.dv_xname, str)
3093 0 : ifp->if_ierrors++;
3094 0 : PRINTERR(ATW_RXSTAT_DE, "descriptor error");
3095 0 : PRINTERR(ATW_RXSTAT_SFDE, "PLCP SFD error");
3096 0 : PRINTERR(ATW_RXSTAT_SIGE, "PLCP signal error");
3097 0 : PRINTERR(ATW_RXSTAT_CRC16E, "PLCP CRC16 error");
3098 0 : PRINTERR(ATW_RXSTAT_RXTOE, "time-out");
3099 0 : PRINTERR(ATW_RXSTAT_CRC32E, "FCS error");
3100 0 : PRINTERR(ATW_RXSTAT_ICVE, "WEP ICV error");
3101 : #undef PRINTERR
3102 0 : ATW_INIT_RXDESC(sc, i);
3103 0 : continue;
3104 : }
3105 :
3106 0 : bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
3107 : rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
3108 :
3109 : /*
3110 : * No errors; receive the packet. Note the ADM8211
3111 : * includes the CRC in promiscuous mode.
3112 : */
3113 0 : len = MASK_AND_RSHIFT(rxstat, ATW_RXSTAT_FL_MASK);
3114 :
3115 : /*
3116 : * Allocate a new mbuf cluster. If that fails, we are
3117 : * out of memory, and must drop the packet and recycle
3118 : * the buffer that's already attached to this descriptor.
3119 : */
3120 0 : m = rxs->rxs_mbuf;
3121 0 : if (atw_add_rxbuf(sc, i) != 0) {
3122 0 : ifp->if_ierrors++;
3123 0 : ATW_INIT_RXDESC(sc, i);
3124 0 : bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
3125 : rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
3126 0 : continue;
3127 : }
3128 :
3129 0 : if (sc->sc_opmode & ATW_NAR_PR)
3130 0 : len -= IEEE80211_CRC_LEN;
3131 0 : m->m_pkthdr.len = m->m_len = MIN(m->m_ext.ext_size, len);
3132 :
3133 0 : if (rate0 >= sizeof(rate_tbl) / sizeof(rate_tbl[0]))
3134 0 : rate = 0;
3135 : else
3136 0 : rate = rate_tbl[rate0];
3137 :
3138 : /* The RSSI comes straight from a register in the
3139 : * baseband processor. I know that for the RF3000,
3140 : * the RSSI register also contains the antenna-selection
3141 : * bits. Mask those off.
3142 : *
3143 : * TBD Treat other basebands.
3144 : */
3145 0 : if (sc->sc_bbptype == ATW_BBPTYPE_RFMD)
3146 0 : rssi = rssi0 & RF3000_RSSI_MASK;
3147 : else
3148 : rssi = rssi0;
3149 :
3150 : #if NBPFILTER > 0
3151 : /* Pass this up to any BPF listeners. */
3152 0 : if (sc->sc_radiobpf != NULL) {
3153 0 : struct mbuf mb;
3154 :
3155 0 : struct atw_rx_radiotap_header *tap = &sc->sc_rxtap;
3156 :
3157 0 : tap->ar_rate = rate;
3158 0 : tap->ar_chan_freq = ic->ic_bss->ni_chan->ic_freq;
3159 0 : tap->ar_chan_flags = ic->ic_bss->ni_chan->ic_flags;
3160 :
3161 : /* TBD verify units are dB */
3162 0 : tap->ar_antsignal = (int)rssi;
3163 : /* TBD tap->ar_flags */
3164 :
3165 0 : mb.m_data = (caddr_t)tap;
3166 0 : mb.m_len = tap->ar_ihdr.it_len;
3167 0 : mb.m_next = m;
3168 0 : mb.m_nextpkt = NULL;
3169 0 : mb.m_type = 0;
3170 0 : mb.m_flags = 0;
3171 0 : bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN);
3172 0 : }
3173 : #endif /* NBPFILTER > 0 */
3174 :
3175 0 : wh = mtod(m, struct ieee80211_frame *);
3176 0 : ni = ieee80211_find_rxnode(ic, wh);
3177 0 : rxi.rxi_flags = 0;
3178 : #if 0
3179 : if (atw_hw_decrypted(sc, wh)) {
3180 : wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
3181 : rxi.rxi_flags |= IEEE80211_RXI_HWDEC;
3182 : }
3183 : #endif
3184 0 : rxi.rxi_rssi = (int)rssi;
3185 0 : rxi.rxi_tstamp = 0;
3186 0 : ieee80211_input(ifp, m, ni, &rxi);
3187 : /*
3188 : * The frame may have caused the node to be marked for
3189 : * reclamation (e.g. in response to a DEAUTH message)
3190 : * so use release_node here instead of unref_node.
3191 : */
3192 0 : ieee80211_release_node(ic, ni);
3193 0 : }
3194 :
3195 : /* Update the receive pointer. */
3196 0 : sc->sc_rxptr = i;
3197 0 : }
3198 :
3199 : /*
3200 : * atw_txintr:
3201 : *
3202 : * Helper; handle transmit interrupts.
3203 : */
3204 : void
3205 0 : atw_txintr(struct atw_softc *sc)
3206 : {
3207 : #define TXSTAT_ERRMASK (ATW_TXSTAT_TUF | ATW_TXSTAT_TLT | ATW_TXSTAT_TRT | \
3208 : ATW_TXSTAT_TRO | ATW_TXSTAT_SOFBR)
3209 : #define TXSTAT_FMT "\20\31ATW_TXSTAT_SOFBR\32ATW_TXSTAT_TRO\33ATW_TXSTAT_TUF" \
3210 : "\34ATW_TXSTAT_TRT\35ATW_TXSTAT_TLT"
3211 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
3212 : struct atw_txsoft *txs;
3213 : u_int32_t txstat;
3214 :
3215 : DPRINTF3(sc, ("%s: atw_txintr: sc_flags 0x%08x\n",
3216 : sc->sc_dev.dv_xname, sc->sc_flags));
3217 :
3218 0 : ifq_clr_oactive(&ifp->if_snd);
3219 :
3220 : /*
3221 : * Go through our Tx list and free mbufs for those
3222 : * frames that have been transmitted.
3223 : */
3224 0 : while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
3225 0 : ATW_CDTXSYNC(sc, txs->txs_lastdesc, 1,
3226 : BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3227 :
3228 : #ifdef ATW_DEBUG
3229 : if ((ifp->if_flags & IFF_DEBUG) != 0 && atw_debug > 2) {
3230 : int i;
3231 : printf(" txsoft %p transmit chain:\n", txs);
3232 : ATW_CDTXSYNC(sc, txs->txs_firstdesc,
3233 : txs->txs_ndescs - 1,
3234 : BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3235 : for (i = txs->txs_firstdesc;; i = ATW_NEXTTX(i)) {
3236 : printf(" descriptor %d:\n", i);
3237 : printf(" at_status: 0x%08x\n",
3238 : letoh32(sc->sc_txdescs[i].at_stat));
3239 : printf(" at_flags: 0x%08x\n",
3240 : letoh32(sc->sc_txdescs[i].at_flags));
3241 : printf(" at_buf1: 0x%08x\n",
3242 : letoh32(sc->sc_txdescs[i].at_buf1));
3243 : printf(" at_buf2: 0x%08x\n",
3244 : letoh32(sc->sc_txdescs[i].at_buf2));
3245 : if (i == txs->txs_lastdesc)
3246 : break;
3247 : }
3248 : }
3249 : #endif
3250 :
3251 0 : txstat = letoh32(sc->sc_txdescs[txs->txs_lastdesc].at_stat);
3252 0 : if (txstat & ATW_TXSTAT_OWN)
3253 : break;
3254 :
3255 0 : SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
3256 :
3257 0 : sc->sc_txfree += txs->txs_ndescs;
3258 :
3259 0 : bus_dmamap_sync(sc->sc_dmat, txs->txs_dmamap,
3260 : 0, txs->txs_dmamap->dm_mapsize,
3261 : BUS_DMASYNC_POSTWRITE);
3262 0 : bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
3263 0 : m_freem(txs->txs_mbuf);
3264 0 : txs->txs_mbuf = NULL;
3265 :
3266 0 : SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
3267 :
3268 0 : if ((ifp->if_flags & IFF_DEBUG) != 0 &&
3269 0 : (txstat & TXSTAT_ERRMASK) != 0) {
3270 0 : printf("%s: txstat %b %d\n", sc->sc_dev.dv_xname,
3271 : txstat & TXSTAT_ERRMASK, TXSTAT_FMT,
3272 0 : MASK_AND_RSHIFT(txstat, ATW_TXSTAT_ARC_MASK));
3273 0 : }
3274 :
3275 : /*
3276 : * Check for errors and collisions.
3277 : */
3278 0 : if (txstat & ATW_TXSTAT_TUF)
3279 0 : sc->sc_stats.ts_tx_tuf++;
3280 0 : if (txstat & ATW_TXSTAT_TLT)
3281 0 : sc->sc_stats.ts_tx_tlt++;
3282 0 : if (txstat & ATW_TXSTAT_TRT)
3283 0 : sc->sc_stats.ts_tx_trt++;
3284 0 : if (txstat & ATW_TXSTAT_TRO)
3285 0 : sc->sc_stats.ts_tx_tro++;
3286 0 : if (txstat & ATW_TXSTAT_SOFBR) {
3287 0 : sc->sc_stats.ts_tx_sofbr++;
3288 0 : }
3289 :
3290 0 : if ((txstat & ATW_TXSTAT_ES) == 0)
3291 0 : ifp->if_collisions +=
3292 0 : MASK_AND_RSHIFT(txstat, ATW_TXSTAT_ARC_MASK);
3293 : else
3294 0 : ifp->if_oerrors++;
3295 : }
3296 :
3297 : /*
3298 : * If there are no more pending transmissions, cancel the watchdog
3299 : * timer.
3300 : */
3301 0 : if (txs == NULL)
3302 0 : sc->sc_tx_timer = 0;
3303 : #undef TXSTAT_ERRMASK
3304 : #undef TXSTAT_FMT
3305 0 : }
3306 :
3307 : /*
3308 : * atw_watchdog: [ifnet interface function]
3309 : *
3310 : * Watchdog timer handler.
3311 : */
3312 : void
3313 0 : atw_watchdog(struct ifnet *ifp)
3314 : {
3315 0 : struct atw_softc *sc = ifp->if_softc;
3316 0 : struct ieee80211com *ic = &sc->sc_ic;
3317 : uint32_t test1, rra, rwa;
3318 :
3319 0 : ifp->if_timer = 0;
3320 0 : if (ATW_IS_ENABLED(sc) == 0)
3321 0 : return;
3322 :
3323 0 : if (sc->sc_rescan_timer) {
3324 0 : if (--sc->sc_rescan_timer == 0)
3325 0 : (void)ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
3326 : }
3327 0 : if (sc->sc_tx_timer) {
3328 0 : if (--sc->sc_tx_timer == 0 &&
3329 0 : !SIMPLEQ_EMPTY(&sc->sc_txdirtyq)) {
3330 0 : printf("%s: transmit timeout\n", ifp->if_xname);
3331 0 : ifp->if_oerrors++;
3332 0 : (void)atw_init(ifp);
3333 0 : atw_start(ifp);
3334 0 : }
3335 : }
3336 0 : if (sc->sc_tx_timer != 0 || sc->sc_rescan_timer != 0)
3337 0 : ifp->if_timer = 1;
3338 :
3339 : /*
3340 : * ADM8211B seems to stall every so often, check for this.
3341 : * These bits are what the Linux driver checks, they don't
3342 : * seem to be documented by ADMTek/Infineon?
3343 : */
3344 0 : if (sc->sc_rev == ATW_REVISION_BA) {
3345 0 : test1 = ATW_READ(sc, ATW_TEST1);
3346 0 : rra = (test1 >> 12) & 0x1ff;
3347 0 : rwa = (test1 >> 2) & 0x1ff;
3348 :
3349 0 : if ((rra != rwa) && !(test1 & 0x2)) {
3350 0 : atw_init(ifp);
3351 0 : atw_start(ifp);
3352 0 : }
3353 : }
3354 :
3355 0 : ieee80211_watchdog(ifp);
3356 0 : }
3357 :
3358 : /*
3359 : * Arguments in:
3360 : *
3361 : * paylen: payload length (no FCS, no WEP header)
3362 : *
3363 : * hdrlen: header length
3364 : *
3365 : * rate: MSDU speed, units 500kb/s
3366 : *
3367 : * flags: IEEE80211_F_SHPREAMBLE (use short preamble),
3368 : * IEEE80211_F_SHSLOT (use short slot length)
3369 : *
3370 : * Arguments out:
3371 : *
3372 : * d: 802.11 Duration field for RTS,
3373 : * 802.11 Duration field for data frame,
3374 : * PLCP Length for data frame,
3375 : * residual octets at end of data slot
3376 : */
3377 : int
3378 0 : atw_compute_duration1(int len, int use_ack, uint32_t flags, int rate,
3379 : struct atw_duration *d)
3380 : {
3381 : int pre, ctsrate;
3382 : int ack, bitlen, data_dur, remainder;
3383 :
3384 : /* RTS reserves medium for SIFS | CTS | SIFS | (DATA) | SIFS | ACK
3385 : * DATA reserves medium for SIFS | ACK
3386 : *
3387 : * XXXMYC: no ACK on multicast/broadcast or control packets
3388 : */
3389 :
3390 0 : bitlen = len * 8;
3391 :
3392 : pre = IEEE80211_DUR_DS_SIFS;
3393 0 : if ((flags & IEEE80211_F_SHPREAMBLE) != 0)
3394 0 : pre += IEEE80211_DUR_DS_SHORT_PREAMBLE +
3395 : IEEE80211_DUR_DS_FAST_PLCPHDR;
3396 : else
3397 : pre += IEEE80211_DUR_DS_LONG_PREAMBLE +
3398 : IEEE80211_DUR_DS_SLOW_PLCPHDR;
3399 :
3400 0 : d->d_residue = 0;
3401 0 : data_dur = (bitlen * 2) / rate;
3402 0 : remainder = (bitlen * 2) % rate;
3403 0 : if (remainder != 0) {
3404 0 : d->d_residue = (rate - remainder) / 16;
3405 0 : data_dur++;
3406 0 : }
3407 :
3408 0 : switch (rate) {
3409 : case 2: /* 1 Mb/s */
3410 : case 4: /* 2 Mb/s */
3411 : /* 1 - 2 Mb/s WLAN: send ACK/CTS at 1 Mb/s */
3412 : ctsrate = 2;
3413 0 : break;
3414 : case 11: /* 5.5 Mb/s */
3415 : case 22: /* 11 Mb/s */
3416 : case 44: /* 22 Mb/s */
3417 : /* 5.5 - 11 Mb/s WLAN: send ACK/CTS at 2 Mb/s */
3418 : ctsrate = 4;
3419 0 : break;
3420 : default:
3421 : /* TBD */
3422 0 : return -1;
3423 : }
3424 :
3425 0 : d->d_plcp_len = data_dur;
3426 :
3427 0 : ack = (use_ack) ? pre + (IEEE80211_DUR_DS_SLOW_ACK * 2) / ctsrate : 0;
3428 :
3429 0 : d->d_rts_dur =
3430 0 : pre + (IEEE80211_DUR_DS_SLOW_CTS * 2) / ctsrate +
3431 0 : pre + data_dur +
3432 : ack;
3433 :
3434 0 : d->d_data_dur = ack;
3435 :
3436 0 : return 0;
3437 0 : }
3438 :
3439 : /*
3440 : * Arguments in:
3441 : *
3442 : * wh: 802.11 header
3443 : *
3444 : * len: packet length
3445 : *
3446 : * rate: MSDU speed, units 500kb/s
3447 : *
3448 : * fraglen: fragment length, set to maximum (or higher) for no
3449 : * fragmentation
3450 : *
3451 : * flags: IEEE80211_F_WEPON (hardware adds WEP),
3452 : * IEEE80211_F_SHPREAMBLE (use short preamble),
3453 : * IEEE80211_F_SHSLOT (use short slot length)
3454 : *
3455 : * Arguments out:
3456 : *
3457 : * d0: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields
3458 : * of first/only fragment
3459 : *
3460 : * dn: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields
3461 : * of first/only fragment
3462 : */
3463 : int
3464 0 : atw_compute_duration(struct ieee80211_frame *wh, int len, uint32_t flags,
3465 : int fraglen, int rate, struct atw_duration *d0, struct atw_duration *dn,
3466 : int *npktp, int debug)
3467 : {
3468 : int ack, rc;
3469 : int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen;
3470 :
3471 0 : if (ieee80211_has_addr4(wh))
3472 0 : hdrlen = sizeof(struct ieee80211_frame_addr4);
3473 : else
3474 : hdrlen = sizeof(struct ieee80211_frame);
3475 :
3476 0 : paylen = len - hdrlen;
3477 :
3478 0 : if ((flags & IEEE80211_F_WEPON) != 0)
3479 0 : overlen = IEEE80211_WEP_TOTLEN + IEEE80211_CRC_LEN;
3480 : else
3481 : overlen = IEEE80211_CRC_LEN;
3482 :
3483 0 : npkt = paylen / fraglen;
3484 0 : lastlen0 = paylen % fraglen;
3485 :
3486 0 : if (npkt == 0) /* no fragments */
3487 0 : lastlen = paylen + overlen;
3488 0 : else if (lastlen0 != 0) { /* a short "tail" fragment */
3489 0 : lastlen = lastlen0 + overlen;
3490 0 : npkt++;
3491 0 : } else /* full-length "tail" fragment */
3492 0 : lastlen = fraglen + overlen;
3493 :
3494 0 : if (npktp != NULL)
3495 0 : *npktp = npkt;
3496 :
3497 0 : if (npkt > 1)
3498 0 : firstlen = fraglen + overlen;
3499 : else
3500 0 : firstlen = paylen + overlen;
3501 :
3502 0 : if (debug) {
3503 0 : printf("%s: npkt %d firstlen %d lastlen0 %d lastlen %d "
3504 : "fraglen %d overlen %d len %d rate %d flags %08x\n",
3505 : __func__, npkt, firstlen, lastlen0, lastlen, fraglen,
3506 : overlen, len, rate, flags);
3507 0 : }
3508 :
3509 0 : ack = !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
3510 0 : (wh->i_fc[1] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL;
3511 :
3512 0 : rc = atw_compute_duration1(firstlen + hdrlen, ack, flags, rate, d0);
3513 0 : if (rc == -1)
3514 0 : return rc;
3515 :
3516 0 : if (npkt <= 1) {
3517 0 : *dn = *d0;
3518 0 : return 0;
3519 : }
3520 0 : return atw_compute_duration1(lastlen + hdrlen, ack, flags, rate, dn);
3521 0 : }
3522 :
3523 : #ifdef ATW_DEBUG
3524 : void
3525 : atw_dump_pkt(struct ifnet *ifp, struct mbuf *m0)
3526 : {
3527 : struct atw_softc *sc = ifp->if_softc;
3528 : struct mbuf *m;
3529 : int i, noctets = 0;
3530 :
3531 : printf("%s: %d-byte packet\n", sc->sc_dev.dv_xname,
3532 : m0->m_pkthdr.len);
3533 :
3534 : for (m = m0; m; m = m->m_next) {
3535 : if (m->m_len == 0)
3536 : continue;
3537 : for (i = 0; i < m->m_len; i++) {
3538 : printf(" %02x", ((u_int8_t*)m->m_data)[i]);
3539 : if (++noctets % 24 == 0)
3540 : printf("\n");
3541 : }
3542 : }
3543 : printf("%s%s: %d bytes emitted\n",
3544 : (noctets % 24 != 0) ? "\n" : "", sc->sc_dev.dv_xname, noctets);
3545 : }
3546 : #endif /* ATW_DEBUG */
3547 :
3548 : /*
3549 : * atw_start: [ifnet interface function]
3550 : *
3551 : * Start packet transmission on the interface.
3552 : */
3553 : void
3554 0 : atw_start(struct ifnet *ifp)
3555 : {
3556 0 : struct atw_softc *sc = ifp->if_softc;
3557 0 : struct ieee80211com *ic = &sc->sc_ic;
3558 0 : struct ieee80211_node *ni;
3559 : struct ieee80211_frame *wh;
3560 : struct ieee80211_key *k;
3561 : struct atw_frame *hh;
3562 : struct mbuf *m0, *m;
3563 : struct atw_txsoft *txs, *last_txs;
3564 : struct atw_txdesc *txd;
3565 0 : int do_encrypt, npkt, rate;
3566 : bus_dmamap_t dmamap;
3567 : int ctl, error, firsttx, nexttx, lasttx = -1, first, ofree, seg;
3568 :
3569 : DPRINTF2(sc, ("%s: atw_start: sc_flags 0x%08x, if_flags 0x%08x\n",
3570 : sc->sc_dev.dv_xname, sc->sc_flags, ifp->if_flags));
3571 :
3572 0 : if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
3573 0 : return;
3574 :
3575 : /*
3576 : * Remember the previous number of free descriptors and
3577 : * the first descriptor we'll use.
3578 : */
3579 0 : ofree = sc->sc_txfree;
3580 0 : firsttx = sc->sc_txnext;
3581 :
3582 : DPRINTF2(sc, ("%s: atw_start: txfree %d, txnext %d\n",
3583 : sc->sc_dev.dv_xname, ofree, firsttx));
3584 :
3585 : /*
3586 : * Loop through the send queue, setting up transmit descriptors
3587 : * until we drain the queue, or use up all available transmit
3588 : * descriptors.
3589 : */
3590 0 : while ((txs = SIMPLEQ_FIRST(&sc->sc_txfreeq)) != NULL &&
3591 0 : sc->sc_txfree != 0) {
3592 :
3593 : /*
3594 : * Grab a packet off the management queue, if it
3595 : * is not empty. Otherwise, from the data queue.
3596 : */
3597 0 : m0 = mq_dequeue(&ic->ic_mgtq);
3598 0 : if (m0 != NULL) {
3599 0 : ni = m0->m_pkthdr.ph_cookie;
3600 0 : } else {
3601 : /* send no data packets until we are associated */
3602 0 : if (ic->ic_state != IEEE80211_S_RUN)
3603 : break;
3604 0 : IFQ_DEQUEUE(&ifp->if_snd, m0);
3605 0 : if (m0 == NULL)
3606 : break;
3607 : #if NBPFILTER > 0
3608 0 : if (ifp->if_bpf != NULL)
3609 0 : bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
3610 : #endif /* NBPFILTER > 0 */
3611 0 : if ((m0 = ieee80211_encap(ifp, m0, &ni)) == NULL) {
3612 0 : ifp->if_oerrors++;
3613 0 : break;
3614 : }
3615 :
3616 0 : if (ic->ic_flags & IEEE80211_F_WEPON) {
3617 0 : wh = mtod(m0, struct ieee80211_frame *);
3618 0 : k = ieee80211_get_txkey(ic, wh, ni);
3619 0 : m0 = ieee80211_encrypt(ic, m0, k);
3620 0 : if (m0 == NULL) {
3621 0 : ifp->if_oerrors++;
3622 0 : break;
3623 : }
3624 : }
3625 : }
3626 :
3627 0 : wh = mtod(m0, struct ieee80211_frame *);
3628 :
3629 : /* XXX do real rate control */
3630 0 : if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
3631 : IEEE80211_FC0_TYPE_MGT)
3632 0 : rate = 2;
3633 : else
3634 0 : rate = MAX(2, ieee80211_get_rate(ic));
3635 :
3636 0 : if (atw_compute_duration(wh, m0->m_pkthdr.len,
3637 0 : ic->ic_flags & ~IEEE80211_F_WEPON, ic->ic_fragthreshold,
3638 0 : rate, &txs->txs_d0, &txs->txs_dn, &npkt,
3639 0 : (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
3640 0 : (IFF_DEBUG|IFF_LINK2)) == -1) {
3641 : DPRINTF2(sc, ("%s: fail compute duration\n", __func__));
3642 0 : m_freem(m0);
3643 0 : break;
3644 : }
3645 :
3646 : /*
3647 : * XXX Misleading if fragmentation is enabled. Better
3648 : * to fragment in software?
3649 : */
3650 0 : *(uint16_t *)wh->i_dur = htole16(txs->txs_d0.d_rts_dur);
3651 :
3652 : #if NBPFILTER > 0
3653 : /*
3654 : * Pass the packet to any BPF listeners.
3655 : */
3656 0 : if (ic->ic_rawbpf != NULL)
3657 0 : bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
3658 :
3659 0 : if (sc->sc_radiobpf != NULL) {
3660 0 : struct mbuf mb;
3661 0 : struct atw_tx_radiotap_header *tap = &sc->sc_txtap;
3662 :
3663 0 : tap->at_rate = rate;
3664 0 : tap->at_chan_freq = ic->ic_bss->ni_chan->ic_freq;
3665 0 : tap->at_chan_flags = ic->ic_bss->ni_chan->ic_flags;
3666 :
3667 : /* TBD tap->at_flags */
3668 :
3669 0 : mb.m_data = (caddr_t)tap;
3670 0 : mb.m_len = tap->at_ihdr.it_len;
3671 0 : mb.m_next = m0;
3672 0 : mb.m_nextpkt = NULL;
3673 0 : mb.m_type = 0;
3674 0 : mb.m_flags = 0;
3675 0 : bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT);
3676 0 : }
3677 : #endif /* NBPFILTER > 0 */
3678 :
3679 0 : M_PREPEND(m0, offsetof(struct atw_frame, atw_ihdr), M_DONTWAIT);
3680 :
3681 0 : if (ni != NULL)
3682 0 : ieee80211_release_node(ic, ni);
3683 :
3684 0 : if (m0 == NULL) {
3685 0 : ifp->if_oerrors++;
3686 0 : break;
3687 : }
3688 :
3689 : /* just to make sure. */
3690 0 : m0 = m_pullup(m0, sizeof(struct atw_frame));
3691 :
3692 0 : if (m0 == NULL) {
3693 0 : ifp->if_oerrors++;
3694 0 : break;
3695 : }
3696 :
3697 0 : hh = mtod(m0, struct atw_frame *);
3698 0 : wh = &hh->atw_ihdr;
3699 :
3700 0 : do_encrypt = ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0) ? 1 : 0;
3701 :
3702 : /* Copy everything we need from the 802.11 header:
3703 : * Frame Control; address 1, address 3, or addresses
3704 : * 3 and 4. NIC fills in BSSID, SA.
3705 : */
3706 0 : if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
3707 0 : if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
3708 0 : panic("%s: illegal WDS frame",
3709 0 : sc->sc_dev.dv_xname);
3710 0 : memcpy(hh->atw_dst, wh->i_addr3, IEEE80211_ADDR_LEN);
3711 0 : } else
3712 0 : memcpy(hh->atw_dst, wh->i_addr1, IEEE80211_ADDR_LEN);
3713 :
3714 0 : *(u_int16_t*)hh->atw_fc = *(u_int16_t*)wh->i_fc;
3715 :
3716 : /* initialize remaining Tx parameters */
3717 0 : memset(&hh->u, 0, sizeof(hh->u));
3718 :
3719 0 : hh->atw_rate = rate * 5;
3720 : /* XXX this could be incorrect if M_FCS. _encap should
3721 : * probably strip FCS just in case it sticks around in
3722 : * bridged packets.
3723 : */
3724 0 : hh->atw_service = IEEE80211_PLCP_SERVICE; /* XXX guess */
3725 0 : hh->atw_paylen = htole16(m0->m_pkthdr.len -
3726 : sizeof(struct atw_frame));
3727 :
3728 0 : hh->atw_fragthr = htole16(ATW_FRAGTHR_FRAGTHR_MASK);
3729 0 : hh->atw_rtylmt = 3;
3730 0 : hh->atw_hdrctl = htole16(ATW_HDRCTL_UNKNOWN1);
3731 : #if 0
3732 : if (do_encrypt) {
3733 : hh->atw_hdrctl |= htole16(ATW_HDRCTL_WEP);
3734 : hh->atw_keyid = ic->ic_wep_txkey;
3735 : }
3736 : #endif
3737 :
3738 0 : hh->atw_head_plcplen = htole16(txs->txs_d0.d_plcp_len);
3739 0 : hh->atw_tail_plcplen = htole16(txs->txs_dn.d_plcp_len);
3740 0 : if (txs->txs_d0.d_residue)
3741 0 : hh->atw_head_plcplen |= htole16(0x8000);
3742 0 : if (txs->txs_dn.d_residue)
3743 0 : hh->atw_tail_plcplen |= htole16(0x8000);
3744 0 : hh->atw_head_dur = htole16(txs->txs_d0.d_rts_dur);
3745 0 : hh->atw_tail_dur = htole16(txs->txs_dn.d_rts_dur);
3746 :
3747 : /* never fragment multicast frames */
3748 0 : if (IEEE80211_IS_MULTICAST(hh->atw_dst)) {
3749 0 : hh->atw_fragthr = htole16(ATW_FRAGTHR_FRAGTHR_MASK);
3750 0 : } else if (sc->sc_flags & ATWF_RTSCTS) {
3751 0 : hh->atw_hdrctl |= htole16(ATW_HDRCTL_RTSCTS);
3752 0 : }
3753 :
3754 : #ifdef ATW_DEBUG
3755 : hh->atw_fragnum = 0;
3756 :
3757 : if ((ifp->if_flags & IFF_DEBUG) != 0 && atw_debug > 2) {
3758 : printf("%s: dst = %s, rate = 0x%02x, "
3759 : "service = 0x%02x, paylen = 0x%04x\n",
3760 : sc->sc_dev.dv_xname, ether_sprintf(hh->atw_dst),
3761 : hh->atw_rate, hh->atw_service, hh->atw_paylen);
3762 :
3763 : printf("%s: fc[0] = 0x%02x, fc[1] = 0x%02x, "
3764 : "dur1 = 0x%04x, dur2 = 0x%04x, "
3765 : "dur3 = 0x%04x, rts_dur = 0x%04x\n",
3766 : sc->sc_dev.dv_xname, hh->atw_fc[0], hh->atw_fc[1],
3767 : hh->atw_tail_plcplen, hh->atw_head_plcplen,
3768 : hh->atw_tail_dur, hh->atw_head_dur);
3769 :
3770 : printf("%s: hdrctl = 0x%04x, fragthr = 0x%04x, "
3771 : "fragnum = 0x%02x, rtylmt = 0x%04x\n",
3772 : sc->sc_dev.dv_xname, hh->atw_hdrctl,
3773 : hh->atw_fragthr, hh->atw_fragnum, hh->atw_rtylmt);
3774 :
3775 : printf("%s: keyid = %d\n",
3776 : sc->sc_dev.dv_xname, hh->atw_keyid);
3777 :
3778 : atw_dump_pkt(ifp, m0);
3779 : }
3780 : #endif /* ATW_DEBUG */
3781 :
3782 0 : dmamap = txs->txs_dmamap;
3783 :
3784 : /*
3785 : * Load the DMA map. Copy and try (once) again if the packet
3786 : * didn't fit in the alloted number of segments.
3787 : */
3788 0 : for (first = 1;
3789 0 : (error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
3790 0 : BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 && first;
3791 : first = 0) {
3792 0 : MGETHDR(m, M_DONTWAIT, MT_DATA);
3793 0 : if (m == NULL) {
3794 0 : printf("%s: unable to allocate Tx mbuf\n",
3795 0 : sc->sc_dev.dv_xname);
3796 0 : break;
3797 : }
3798 0 : if (m0->m_pkthdr.len > MHLEN) {
3799 0 : MCLGET(m, M_DONTWAIT);
3800 0 : if ((m->m_flags & M_EXT) == 0) {
3801 0 : printf("%s: unable to allocate Tx "
3802 0 : "cluster\n", sc->sc_dev.dv_xname);
3803 0 : m_freem(m);
3804 0 : break;
3805 : }
3806 : }
3807 0 : m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
3808 0 : m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
3809 0 : m_freem(m0);
3810 : m0 = m;
3811 : m = NULL;
3812 : }
3813 0 : if (error != 0) {
3814 0 : printf("%s: unable to load Tx buffer, "
3815 0 : "error = %d\n", sc->sc_dev.dv_xname, error);
3816 0 : m_freem(m0);
3817 0 : break;
3818 : }
3819 :
3820 : /*
3821 : * Ensure we have enough descriptors free to describe
3822 : * the packet.
3823 : */
3824 0 : if (dmamap->dm_nsegs > sc->sc_txfree) {
3825 : /*
3826 : * Not enough free descriptors to transmit
3827 : * this packet. Unload the DMA map and
3828 : * drop the packet. Notify the upper layer
3829 : * that there are no more slots left.
3830 : *
3831 : * XXX We could allocate an mbuf and copy, but
3832 : * XXX it is worth it?
3833 : */
3834 0 : ifq_set_oactive(&ifp->if_snd);
3835 0 : bus_dmamap_unload(sc->sc_dmat, dmamap);
3836 0 : m_freem(m0);
3837 0 : break;
3838 : }
3839 :
3840 : /*
3841 : * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
3842 : */
3843 :
3844 : /* Sync the DMA map. */
3845 0 : bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
3846 : BUS_DMASYNC_PREWRITE);
3847 :
3848 : /* XXX arbitrary retry limit; 8 because I have seen it in
3849 : * use already and maybe 0 means "no tries" !
3850 : */
3851 : ctl = htole32(LSHIFT(8, ATW_TXCTL_TL_MASK));
3852 :
3853 : DPRINTF2(sc, ("%s: TXDR <- max(10, %d)\n",
3854 : sc->sc_dev.dv_xname, rate * 5));
3855 0 : ctl |= htole32(LSHIFT(MAX(10, rate * 5), ATW_TXCTL_TXDR_MASK));
3856 :
3857 : /*
3858 : * Initialize the transmit descriptors.
3859 : */
3860 0 : for (nexttx = sc->sc_txnext, seg = 0;
3861 0 : seg < dmamap->dm_nsegs;
3862 0 : seg++, nexttx = ATW_NEXTTX(nexttx)) {
3863 : /*
3864 : * If this is the first descriptor we're
3865 : * enqueueing, don't set the OWN bit just
3866 : * yet. That could cause a race condition.
3867 : * We'll do it below.
3868 : */
3869 0 : txd = &sc->sc_txdescs[nexttx];
3870 0 : txd->at_ctl = ctl |
3871 0 : ((nexttx == firsttx) ? 0 : htole32(ATW_TXCTL_OWN));
3872 :
3873 0 : txd->at_buf1 = htole32(dmamap->dm_segs[seg].ds_addr);
3874 0 : txd->at_flags =
3875 0 : htole32(LSHIFT(dmamap->dm_segs[seg].ds_len,
3876 0 : ATW_TXFLAG_TBS1_MASK)) |
3877 0 : ((nexttx == (ATW_NTXDESC - 1))
3878 : ? htole32(ATW_TXFLAG_TER) : 0);
3879 : lasttx = nexttx;
3880 : }
3881 :
3882 0 : if (lasttx == -1)
3883 0 : panic("%s: bad lastx", ifp->if_xname);
3884 : /* Set `first segment' and `last segment' appropriately. */
3885 0 : sc->sc_txdescs[sc->sc_txnext].at_flags |=
3886 : htole32(ATW_TXFLAG_FS);
3887 0 : sc->sc_txdescs[lasttx].at_flags |= htole32(ATW_TXFLAG_LS);
3888 :
3889 : #ifdef ATW_DEBUG
3890 : if ((ifp->if_flags & IFF_DEBUG) != 0 && atw_debug > 2) {
3891 : printf(" txsoft %p transmit chain:\n", txs);
3892 : for (seg = sc->sc_txnext;; seg = ATW_NEXTTX(seg)) {
3893 : printf(" descriptor %d:\n", seg);
3894 : printf(" at_ctl: 0x%08x\n",
3895 : letoh32(sc->sc_txdescs[seg].at_ctl));
3896 : printf(" at_flags: 0x%08x\n",
3897 : letoh32(sc->sc_txdescs[seg].at_flags));
3898 : printf(" at_buf1: 0x%08x\n",
3899 : letoh32(sc->sc_txdescs[seg].at_buf1));
3900 : printf(" at_buf2: 0x%08x\n",
3901 : letoh32(sc->sc_txdescs[seg].at_buf2));
3902 : if (seg == lasttx)
3903 : break;
3904 : }
3905 : }
3906 : #endif
3907 :
3908 : /* Sync the descriptors we're using. */
3909 0 : ATW_CDTXSYNC(sc, sc->sc_txnext, dmamap->dm_nsegs,
3910 : BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3911 :
3912 : /*
3913 : * Store a pointer to the packet so we can free it later,
3914 : * and remember what txdirty will be once the packet is
3915 : * done.
3916 : */
3917 0 : txs->txs_mbuf = m0;
3918 0 : txs->txs_firstdesc = sc->sc_txnext;
3919 0 : txs->txs_lastdesc = lasttx;
3920 0 : txs->txs_ndescs = dmamap->dm_nsegs;
3921 :
3922 : /* Advance the tx pointer. */
3923 0 : sc->sc_txfree -= dmamap->dm_nsegs;
3924 0 : sc->sc_txnext = nexttx;
3925 :
3926 0 : SIMPLEQ_REMOVE_HEAD(&sc->sc_txfreeq, txs_q);
3927 0 : SIMPLEQ_INSERT_TAIL(&sc->sc_txdirtyq, txs, txs_q);
3928 :
3929 : last_txs = txs;
3930 : }
3931 :
3932 0 : if (txs == NULL || sc->sc_txfree == 0) {
3933 : /* No more slots left; notify upper layer. */
3934 0 : ifq_set_oactive(&ifp->if_snd);
3935 0 : }
3936 :
3937 0 : if (sc->sc_txfree != ofree) {
3938 : DPRINTF2(sc, ("%s: packets enqueued, IC on %d, OWN on %d\n",
3939 : sc->sc_dev.dv_xname, lasttx, firsttx));
3940 : /*
3941 : * Cause a transmit interrupt to happen on the
3942 : * last packet we enqueued.
3943 : */
3944 0 : sc->sc_txdescs[lasttx].at_flags |= htole32(ATW_TXFLAG_IC);
3945 0 : ATW_CDTXSYNC(sc, lasttx, 1,
3946 : BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3947 :
3948 : /*
3949 : * The entire packet chain is set up. Give the
3950 : * first descriptor to the chip now.
3951 : */
3952 0 : sc->sc_txdescs[firsttx].at_ctl |= htole32(ATW_TXCTL_OWN);
3953 0 : ATW_CDTXSYNC(sc, firsttx, 1,
3954 : BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3955 :
3956 : /* Wake up the transmitter. */
3957 0 : ATW_WRITE(sc, ATW_TDR, 0x1);
3958 :
3959 : /* Set a watchdog timer in case the chip flakes out. */
3960 0 : sc->sc_tx_timer = 5;
3961 0 : ifp->if_timer = 1;
3962 0 : }
3963 0 : }
3964 :
3965 : int
3966 0 : atw_activate(struct device *self, int act)
3967 : {
3968 0 : struct atw_softc *sc = (struct atw_softc *)self;
3969 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
3970 :
3971 0 : switch (act) {
3972 : case DVACT_SUSPEND:
3973 0 : if (ifp->if_flags & IFF_RUNNING)
3974 0 : atw_stop(ifp, 1);
3975 0 : if (sc->sc_power != NULL)
3976 0 : (*sc->sc_power)(sc, act);
3977 : break;
3978 : case DVACT_WAKEUP:
3979 0 : atw_wakeup(sc);
3980 0 : break;
3981 : }
3982 0 : return 0;
3983 : }
3984 :
3985 : void
3986 0 : atw_wakeup(struct atw_softc *sc)
3987 : {
3988 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
3989 :
3990 0 : if (sc->sc_power != NULL)
3991 0 : (*sc->sc_power)(sc, DVACT_RESUME);
3992 0 : if (ifp->if_flags & IFF_UP)
3993 0 : atw_init(ifp);
3994 0 : }
3995 :
3996 : /*
3997 : * atw_ioctl: [ifnet interface function]
3998 : *
3999 : * Handle control requests from the operator.
4000 : */
4001 : int
4002 0 : atw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
4003 : {
4004 0 : struct atw_softc *sc = ifp->if_softc;
4005 0 : struct ifreq *ifr = (struct ifreq *)data;
4006 : int s, error = 0;
4007 :
4008 : /* XXX monkey see, monkey do. comes from wi_ioctl. */
4009 0 : if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
4010 0 : return ENXIO;
4011 :
4012 0 : s = splnet();
4013 :
4014 0 : switch (cmd) {
4015 : case SIOCSIFADDR:
4016 0 : ifp->if_flags |= IFF_UP;
4017 : /* FALLTHROUGH */
4018 :
4019 : case SIOCSIFFLAGS:
4020 0 : if (ifp->if_flags & IFF_UP) {
4021 0 : if (ATW_IS_ENABLED(sc)) {
4022 : /*
4023 : * To avoid rescanning another access point,
4024 : * do not call atw_init() here. Instead,
4025 : * only reflect media settings.
4026 : */
4027 0 : atw_filter_setup(sc);
4028 0 : } else
4029 0 : error = atw_init(ifp);
4030 0 : } else if (ATW_IS_ENABLED(sc))
4031 0 : atw_stop(ifp, 1);
4032 : break;
4033 :
4034 : case SIOCADDMULTI:
4035 : case SIOCDELMULTI:
4036 0 : error = (cmd == SIOCADDMULTI) ?
4037 0 : ether_addmulti(ifr, &sc->sc_ic.ic_ac) :
4038 0 : ether_delmulti(ifr, &sc->sc_ic.ic_ac);
4039 :
4040 0 : if (error == ENETRESET) {
4041 0 : if (ifp->if_flags & IFF_RUNNING)
4042 0 : atw_filter_setup(sc); /* do not rescan */
4043 : error = 0;
4044 0 : }
4045 : break;
4046 :
4047 : default:
4048 0 : error = ieee80211_ioctl(ifp, cmd, data);
4049 0 : if (error == ENETRESET) {
4050 0 : if (ATW_IS_ENABLED(sc))
4051 0 : error = atw_init(ifp);
4052 : else
4053 : error = 0;
4054 : }
4055 : break;
4056 : }
4057 :
4058 : /* Try to get more packets going. */
4059 0 : if (ATW_IS_ENABLED(sc))
4060 0 : atw_start(ifp);
4061 :
4062 0 : splx(s);
4063 0 : return (error);
4064 0 : }
4065 :
4066 : int
4067 0 : atw_media_change(struct ifnet *ifp)
4068 : {
4069 : int error;
4070 :
4071 0 : error = ieee80211_media_change(ifp);
4072 0 : if (error == ENETRESET) {
4073 0 : if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
4074 : (IFF_RUNNING|IFF_UP))
4075 0 : atw_init(ifp); /* XXX lose error */
4076 : error = 0;
4077 0 : }
4078 0 : return error;
4079 : }
4080 :
4081 : void
4082 0 : atw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
4083 : {
4084 0 : struct atw_softc *sc = ifp->if_softc;
4085 :
4086 0 : if (ATW_IS_ENABLED(sc) == 0) {
4087 0 : imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
4088 0 : imr->ifm_status = 0;
4089 0 : return;
4090 : }
4091 0 : ieee80211_media_status(ifp, imr);
4092 0 : }
|