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