Annotation of sys/dev/ic/ath.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ath.c,v 1.66 2007/07/18 18:10:31 damien Exp $ */
2: /* $NetBSD: ath.c,v 1.37 2004/08/18 21:59:39 dyoung Exp $ */
3:
4: /*-
5: * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer,
13: * without modification.
14: * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15: * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
16: * redistribution must be conditioned upon including a substantially
17: * similar Disclaimer requirement for further binary redistribution.
18: * 3. Neither the names of the above-listed copyright holders nor the names
19: * of any contributors may be used to endorse or promote products derived
20: * from this software without specific prior written permission.
21: *
22: * NO WARRANTY
23: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25: * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
26: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
27: * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
28: * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
31: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33: * THE POSSIBILITY OF SUCH DAMAGES.
34: */
35:
36: /*
37: * Driver for the Atheros Wireless LAN controller.
38: *
39: * This software is derived from work of Atsushi Onoe; his contribution
40: * is greatly appreciated. It has been modified for OpenBSD to use an
41: * open source HAL instead of the original binary-only HAL.
42: */
43:
44: #include "bpfilter.h"
45:
46: #include <sys/param.h>
47: #include <sys/systm.h>
48: #include <sys/sysctl.h>
49: #include <sys/mbuf.h>
50: #include <sys/malloc.h>
51: #include <sys/lock.h>
52: #include <sys/kernel.h>
53: #include <sys/socket.h>
54: #include <sys/sockio.h>
55: #include <sys/device.h>
56: #include <sys/errno.h>
57: #include <sys/timeout.h>
58: #include <sys/gpio.h>
59:
60: #include <machine/endian.h>
61: #include <machine/bus.h>
62:
63: #include <net/if.h>
64: #include <net/if_dl.h>
65: #include <net/if_media.h>
66: #include <net/if_arp.h>
67: #include <net/if_llc.h>
68: #if NBPFILTER > 0
69: #include <net/bpf.h>
70: #endif
71: #ifdef INET
72: #include <netinet/in.h>
73: #include <netinet/if_ether.h>
74: #endif
75:
76: #include <net80211/ieee80211_var.h>
77: #include <net80211/ieee80211_rssadapt.h>
78:
79: #include <dev/pci/pcidevs.h>
80: #include <dev/gpio/gpiovar.h>
81: #include <dev/ic/athvar.h>
82:
83: int ath_init(struct ifnet *);
84: int ath_init1(struct ath_softc *);
85: int ath_intr1(struct ath_softc *);
86: void ath_stop(struct ifnet *);
87: void ath_start(struct ifnet *);
88: void ath_reset(struct ath_softc *, int);
89: int ath_media_change(struct ifnet *);
90: void ath_watchdog(struct ifnet *);
91: int ath_ioctl(struct ifnet *, u_long, caddr_t);
92: void ath_fatal_proc(void *, int);
93: void ath_rxorn_proc(void *, int);
94: void ath_bmiss_proc(void *, int);
95: u_int ath_chan2flags(struct ieee80211com *, struct ieee80211_channel *);
96: int ath_initkeytable(struct ath_softc *);
97: void ath_mcastfilter_accum(caddr_t, u_int32_t (*)[2]);
98: void ath_mcastfilter_compute(struct ath_softc *, u_int32_t (*)[2]);
99: u_int32_t ath_calcrxfilter(struct ath_softc *);
100: void ath_mode_init(struct ath_softc *);
101: int ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *);
102: void ath_beacon_proc(void *, int);
103: void ath_beacon_free(struct ath_softc *);
104: void ath_beacon_config(struct ath_softc *);
105: int ath_desc_alloc(struct ath_softc *);
106: void ath_desc_free(struct ath_softc *);
107: struct ieee80211_node *ath_node_alloc(struct ieee80211com *);
108: struct mbuf *ath_getmbuf(int, int, u_int);
109: void ath_node_free(struct ieee80211com *, struct ieee80211_node *);
110: void ath_node_copy(struct ieee80211com *,
111: struct ieee80211_node *, const struct ieee80211_node *);
112: u_int8_t ath_node_getrssi(struct ieee80211com *,
113: const struct ieee80211_node *);
114: int ath_rxbuf_init(struct ath_softc *, struct ath_buf *);
115: void ath_rx_proc(void *, int);
116: int ath_tx_start(struct ath_softc *, struct ieee80211_node *,
117: struct ath_buf *, struct mbuf *);
118: void ath_tx_proc(void *, int);
119: int ath_chan_set(struct ath_softc *, struct ieee80211_channel *);
120: void ath_draintxq(struct ath_softc *);
121: void ath_stoprecv(struct ath_softc *);
122: int ath_startrecv(struct ath_softc *);
123: void ath_next_scan(void *);
124: int ath_set_slot_time(struct ath_softc *);
125: void ath_calibrate(void *);
126: void ath_ledstate(struct ath_softc *, enum ieee80211_state);
127: int ath_newstate(struct ieee80211com *, enum ieee80211_state, int);
128: void ath_newassoc(struct ieee80211com *,
129: struct ieee80211_node *, int);
130: int ath_getchannels(struct ath_softc *, HAL_BOOL outdoor,
131: HAL_BOOL xchanmode);
132: int ath_rate_setup(struct ath_softc *sc, u_int mode);
133: void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
134: void ath_rssadapt_updatenode(void *, struct ieee80211_node *);
135: void ath_rssadapt_updatestats(void *);
136: void ath_recv_mgmt(struct ieee80211com *, struct mbuf *,
137: struct ieee80211_node *, int, int, u_int32_t);
138: void ath_disable(struct ath_softc *);
139: void ath_power(int, void *);
140:
141: int ath_gpio_attach(struct ath_softc *, u_int16_t);
142: int ath_gpio_pin_read(void *, int);
143: void ath_gpio_pin_write(void *, int, int);
144: void ath_gpio_pin_ctl(void *, int, int);
145:
146: #ifdef AR_DEBUG
147: void ath_printrxbuf(struct ath_buf *, int);
148: void ath_printtxbuf(struct ath_buf *, int);
149: int ath_debug = 0;
150: #endif
151:
152: int ath_dwelltime = 200; /* 5 channels/second */
153: int ath_calinterval = 30; /* calibrate every 30 secs */
154: int ath_outdoor = AH_TRUE; /* outdoor operation */
155: int ath_xchanmode = AH_TRUE; /* enable extended channels */
156:
157: struct cfdriver ath_cd = {
158: NULL, "ath", DV_IFNET
159: };
160:
161: #if 0
162: int
163: ath_activate(struct device *self, enum devact act)
164: {
165: struct ath_softc *sc = (struct ath_softc *)self;
166: int rv = 0, s;
167:
168: s = splnet();
169: switch (act) {
170: case DVACT_ACTIVATE:
171: break;
172: case DVACT_DEACTIVATE:
173: if_deactivate(&sc->sc_ic.ic_if);
174: break;
175: }
176: splx(s);
177: return rv;
178: }
179: #endif
180:
181: int
182: ath_enable(struct ath_softc *sc)
183: {
184: if (ATH_IS_ENABLED(sc) == 0) {
185: if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
186: printf("%s: device enable failed\n",
187: sc->sc_dev.dv_xname);
188: return (EIO);
189: }
190: sc->sc_flags |= ATH_ENABLED;
191: }
192: return (0);
193: }
194:
195: void
196: ath_disable(struct ath_softc *sc)
197: {
198: if (!ATH_IS_ENABLED(sc))
199: return;
200: if (sc->sc_disable != NULL)
201: (*sc->sc_disable)(sc);
202: sc->sc_flags &= ~ATH_ENABLED;
203: }
204:
205: int
206: ath_attach(u_int16_t devid, struct ath_softc *sc)
207: {
208: struct ieee80211com *ic = &sc->sc_ic;
209: struct ifnet *ifp = &ic->ic_if;
210: struct ath_hal *ah;
211: HAL_STATUS status;
212: HAL_TXQ_INFO qinfo;
213: int error = 0, i;
214:
215: DPRINTF(ATH_DEBUG_ANY, ("%s: devid 0x%x\n", __func__, devid));
216:
217: bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
218: sc->sc_flags &= ~ATH_ATTACHED; /* make sure that it's not attached */
219:
220: ah = ath_hal_attach(devid, sc, sc->sc_st, sc->sc_sh, sc->sc_64bit,
221: &status);
222: if (ah == NULL) {
223: printf("%s: unable to attach hardware; HAL status %d\n",
224: ifp->if_xname, status);
225: error = ENXIO;
226: goto bad;
227: }
228: if (ah->ah_abi != HAL_ABI_VERSION) {
229: printf("%s: HAL ABI mismatch detected (0x%x != 0x%x)\n",
230: ifp->if_xname, ah->ah_abi, HAL_ABI_VERSION);
231: error = ENXIO;
232: goto bad;
233: }
234:
235: if (ah->ah_single_chip == AH_TRUE) {
236: printf("%s: AR%s %u.%u phy %u.%u rf %u.%u", ifp->if_xname,
237: ar5k_printver(AR5K_VERSION_DEV, devid),
238: ah->ah_mac_version, ah->ah_mac_revision,
239: ah->ah_phy_revision >> 4, ah->ah_phy_revision & 0xf,
240: ah->ah_radio_5ghz_revision >> 4,
241: ah->ah_radio_5ghz_revision & 0xf);
242: } else {
243: printf("%s: AR%s %u.%u phy %u.%u", ifp->if_xname,
244: ar5k_printver(AR5K_VERSION_VER, ah->ah_mac_srev),
245: ah->ah_mac_version, ah->ah_mac_revision,
246: ah->ah_phy_revision >> 4, ah->ah_phy_revision & 0xf);
247: printf(" rf%s %u.%u",
248: ar5k_printver(AR5K_VERSION_RAD, ah->ah_radio_5ghz_revision),
249: ah->ah_radio_5ghz_revision >> 4,
250: ah->ah_radio_5ghz_revision & 0xf);
251: if (ah->ah_radio_2ghz_revision != 0) {
252: printf(" rf%s %u.%u",
253: ar5k_printver(AR5K_VERSION_RAD,
254: ah->ah_radio_2ghz_revision),
255: ah->ah_radio_2ghz_revision >> 4,
256: ah->ah_radio_2ghz_revision & 0xf);
257: }
258: }
259:
260: #if 0
261: if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_UNSUPP ||
262: ah->ah_radio_2ghz_revision >= AR5K_SREV_RAD_UNSUPP) {
263: printf(": RF radio not supported\n");
264: error = EOPNOTSUPP;
265: goto bad;
266: }
267: #endif
268:
269: sc->sc_ah = ah;
270: sc->sc_invalid = 0; /* ready to go, enable interrupt handling */
271:
272: /*
273: * Get regulation domain either stored in the EEPROM or defined
274: * as the default value. Some devices are known to have broken
275: * regulation domain values in their EEPROM.
276: */
277: ath_hal_get_regdomain(ah, &ah->ah_regdomain);
278:
279: /*
280: * Construct channel list based on the current regulation domain.
281: */
282: error = ath_getchannels(sc, ath_outdoor, ath_xchanmode);
283: if (error != 0)
284: goto bad;
285:
286: /*
287: * Setup rate tables for all potential media types.
288: */
289: ath_rate_setup(sc, IEEE80211_MODE_11A);
290: ath_rate_setup(sc, IEEE80211_MODE_11B);
291: ath_rate_setup(sc, IEEE80211_MODE_11G);
292: ath_rate_setup(sc, IEEE80211_MODE_TURBO);
293:
294: error = ath_desc_alloc(sc);
295: if (error != 0) {
296: printf(": failed to allocate descriptors: %d\n", error);
297: goto bad;
298: }
299: timeout_set(&sc->sc_scan_to, ath_next_scan, sc);
300: timeout_set(&sc->sc_cal_to, ath_calibrate, sc);
301: timeout_set(&sc->sc_rssadapt_to, ath_rssadapt_updatestats, sc);
302:
303: #ifdef __FreeBSD__
304: ATH_TXBUF_LOCK_INIT(sc);
305: ATH_TXQ_LOCK_INIT(sc);
306: #endif
307:
308: ATH_TASK_INIT(&sc->sc_txtask, ath_tx_proc, sc);
309: ATH_TASK_INIT(&sc->sc_rxtask, ath_rx_proc, sc);
310: ATH_TASK_INIT(&sc->sc_rxorntask, ath_rxorn_proc, sc);
311: ATH_TASK_INIT(&sc->sc_fataltask, ath_fatal_proc, sc);
312: ATH_TASK_INIT(&sc->sc_bmisstask, ath_bmiss_proc, sc);
313: ATH_TASK_INIT(&sc->sc_swbatask, ath_beacon_proc, sc);
314:
315: /*
316: * For now just pre-allocate one data queue and one
317: * beacon queue. Note that the HAL handles resetting
318: * them at the needed time. Eventually we'll want to
319: * allocate more tx queues for splitting management
320: * frames and for QOS support.
321: */
322: sc->sc_bhalq = ath_hal_setup_tx_queue(ah, HAL_TX_QUEUE_BEACON, NULL);
323: if (sc->sc_bhalq == (u_int) -1) {
324: printf(": unable to setup a beacon xmit queue!\n");
325: goto bad2;
326: }
327:
328: for (i = 0; i <= HAL_TX_QUEUE_ID_DATA_MAX; i++) {
329: bzero(&qinfo, sizeof(qinfo));
330: qinfo.tqi_type = HAL_TX_QUEUE_DATA;
331: qinfo.tqi_subtype = i; /* should be mapped to WME types */
332: sc->sc_txhalq[i] = ath_hal_setup_tx_queue(ah,
333: HAL_TX_QUEUE_DATA, &qinfo);
334: if (sc->sc_txhalq[i] == (u_int) -1) {
335: printf(": unable to setup a data xmit queue %u!\n", i);
336: goto bad2;
337: }
338: }
339:
340: ifp->if_softc = sc;
341: ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST
342: | IFF_NOTRAILERS;
343: ifp->if_start = ath_start;
344: ifp->if_watchdog = ath_watchdog;
345: ifp->if_ioctl = ath_ioctl;
346: #ifndef __OpenBSD__
347: ifp->if_init = ath_init;
348: ifp->if_stop = ath_stop; /* XXX */
349: #endif
350: IFQ_SET_MAXLEN(&ifp->if_snd, ATH_TXBUF * ATH_TXDESC);
351: IFQ_SET_READY(&ifp->if_snd);
352:
353: ic->ic_softc = sc;
354: ic->ic_newassoc = ath_newassoc;
355: /* XXX not right but it's not used anywhere important */
356: ic->ic_phytype = IEEE80211_T_OFDM;
357: ic->ic_opmode = IEEE80211_M_STA;
358: ic->ic_caps = IEEE80211_C_WEP /* wep supported */
359: | IEEE80211_C_PMGT /* power management */
360: | IEEE80211_C_IBSS /* ibss, nee adhoc, mode */
361: | IEEE80211_C_HOSTAP /* hostap mode */
362: | IEEE80211_C_MONITOR /* monitor mode */
363: | IEEE80211_C_SHSLOT /* short slot time supported */
364: | IEEE80211_C_SHPREAMBLE; /* short preamble supported */
365:
366: /*
367: * Not all chips have the VEOL support we want to use with
368: * IBSS beacon; check here for it.
369: */
370: sc->sc_veol = ath_hal_has_veol(ah);
371:
372: /* get mac address from hardware */
373: ath_hal_get_lladdr(ah, ic->ic_myaddr);
374:
375: if_attach(ifp);
376:
377: /* call MI attach routine. */
378: ieee80211_ifattach(ifp);
379:
380: /* override default methods */
381: ic->ic_node_alloc = ath_node_alloc;
382: sc->sc_node_free = ic->ic_node_free;
383: ic->ic_node_free = ath_node_free;
384: sc->sc_node_copy = ic->ic_node_copy;
385: ic->ic_node_copy = ath_node_copy;
386: ic->ic_node_getrssi = ath_node_getrssi;
387: sc->sc_newstate = ic->ic_newstate;
388: ic->ic_newstate = ath_newstate;
389: sc->sc_recv_mgmt = ic->ic_recv_mgmt;
390: ic->ic_recv_mgmt = ath_recv_mgmt;
391: ic->ic_max_rssi = AR5K_MAX_RSSI;
392: bcopy(etherbroadcastaddr, sc->sc_broadcast_addr, IEEE80211_ADDR_LEN);
393:
394: /* complete initialization */
395: ieee80211_media_init(ifp, ath_media_change, ieee80211_media_status);
396:
397: #if NBPFILTER > 0
398: bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
399: sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);
400:
401: sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
402: bzero(&sc->sc_rxtapu, sc->sc_rxtap_len);
403: sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
404: sc->sc_rxtap.wr_ihdr.it_present = htole32(ATH_RX_RADIOTAP_PRESENT);
405:
406: sc->sc_txtap_len = sizeof(sc->sc_txtapu);
407: bzero(&sc->sc_txtapu, sc->sc_txtap_len);
408: sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
409: sc->sc_txtap.wt_ihdr.it_present = htole32(ATH_TX_RADIOTAP_PRESENT);
410: #endif
411:
412: sc->sc_flags |= ATH_ATTACHED;
413: /*
414: * Make sure the interface is shutdown during reboot.
415: */
416: sc->sc_sdhook = shutdownhook_establish(ath_shutdown, sc);
417: if (sc->sc_sdhook == NULL)
418: printf(": WARNING: unable to establish shutdown hook\n");
419: sc->sc_powerhook = powerhook_establish(ath_power, sc);
420: if (sc->sc_powerhook == NULL)
421: printf(": WARNING: unable to establish power hook\n");
422:
423: /*
424: * Print regulation domain and the mac address. The regulation domain
425: * will be marked with a * if the EEPROM value has been overwritten.
426: */
427: printf(", %s%s, address %s\n",
428: ieee80211_regdomain2name(ah->ah_regdomain),
429: ah->ah_regdomain != ah->ah_regdomain_hw ? "*" : "",
430: ether_sprintf(ic->ic_myaddr));
431:
432: if (ath_gpio_attach(sc, devid) == 0)
433: sc->sc_flags |= ATH_GPIO;
434:
435: return 0;
436: bad2:
437: ath_desc_free(sc);
438: bad:
439: if (ah)
440: ath_hal_detach(ah);
441: sc->sc_invalid = 1;
442: return error;
443: }
444:
445: int
446: ath_detach(struct ath_softc *sc, int flags)
447: {
448: struct ifnet *ifp = &sc->sc_ic.ic_if;
449: int s;
450:
451: if ((sc->sc_flags & ATH_ATTACHED) == 0)
452: return (0);
453:
454: config_detach_children(&sc->sc_dev, flags);
455:
456: DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
457:
458: timeout_del(&sc->sc_scan_to);
459: timeout_del(&sc->sc_cal_to);
460: timeout_del(&sc->sc_rssadapt_to);
461:
462: s = splnet();
463: ath_stop(ifp);
464: ath_desc_free(sc);
465: ath_hal_detach(sc->sc_ah);
466:
467: ieee80211_ifdetach(ifp);
468: if_detach(ifp);
469:
470: splx(s);
471: if (sc->sc_powerhook != NULL)
472: powerhook_disestablish(sc->sc_powerhook);
473: if (sc->sc_sdhook != NULL)
474: shutdownhook_disestablish(sc->sc_sdhook);
475: #ifdef __FreeBSD__
476: ATH_TXBUF_LOCK_DESTROY(sc);
477: ATH_TXQ_LOCK_DESTROY(sc);
478: #endif
479:
480: return 0;
481: }
482:
483: void
484: ath_power(int why, void *arg)
485: {
486: struct ath_softc *sc = arg;
487: int s;
488:
489: DPRINTF(ATH_DEBUG_ANY, ("ath_power(%d)\n", why));
490:
491: s = splnet();
492: switch (why) {
493: case PWR_SUSPEND:
494: case PWR_STANDBY:
495: ath_suspend(sc, why);
496: break;
497: case PWR_RESUME:
498: ath_resume(sc, why);
499: break;
500: #if !defined(__OpenBSD__)
501: case PWR_SOFTSUSPEND:
502: case PWR_SOFTSTANDBY:
503: case PWR_SOFTRESUME:
504: break;
505: #endif
506: }
507: splx(s);
508: }
509:
510: void
511: ath_suspend(struct ath_softc *sc, int why)
512: {
513: struct ifnet *ifp = &sc->sc_ic.ic_if;
514:
515: DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
516:
517: ath_stop(ifp);
518: if (sc->sc_power != NULL)
519: (*sc->sc_power)(sc, why);
520: }
521:
522: void
523: ath_resume(struct ath_softc *sc, int why)
524: {
525: struct ifnet *ifp = &sc->sc_ic.ic_if;
526:
527: DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
528:
529: if (ifp->if_flags & IFF_UP) {
530: ath_init(ifp);
531: #if 0
532: (void)ath_intr(sc);
533: #endif
534: if (sc->sc_power != NULL)
535: (*sc->sc_power)(sc, why);
536: if (ifp->if_flags & IFF_RUNNING)
537: ath_start(ifp);
538: }
539: }
540:
541: void
542: ath_shutdown(void *arg)
543: {
544: struct ath_softc *sc = arg;
545:
546: ath_stop(&sc->sc_ic.ic_if);
547: }
548:
549: int
550: ath_intr(void *arg)
551: {
552: return ath_intr1((struct ath_softc *)arg);
553: }
554:
555: int
556: ath_intr1(struct ath_softc *sc)
557: {
558: struct ieee80211com *ic = &sc->sc_ic;
559: struct ifnet *ifp = &ic->ic_if;
560: struct ath_hal *ah = sc->sc_ah;
561: HAL_INT status;
562:
563: if (sc->sc_invalid) {
564: /*
565: * The hardware is not ready/present, don't touch anything.
566: * Note this can happen early on if the IRQ is shared.
567: */
568: DPRINTF(ATH_DEBUG_ANY, ("%s: invalid; ignored\n", __func__));
569: return 0;
570: }
571: if (!ath_hal_is_intr_pending(ah)) /* shared irq, not for us */
572: return 0;
573: if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) {
574: DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags 0x%x\n",
575: __func__, ifp->if_flags));
576: ath_hal_get_isr(ah, &status); /* clear ISR */
577: ath_hal_set_intr(ah, 0); /* disable further intr's */
578: return 1; /* XXX */
579: }
580: ath_hal_get_isr(ah, &status); /* NB: clears ISR too */
581: DPRINTF(ATH_DEBUG_INTR, ("%s: status 0x%x\n", __func__, status));
582: status &= sc->sc_imask; /* discard unasked for bits */
583: if (status & HAL_INT_FATAL) {
584: sc->sc_stats.ast_hardware++;
585: ath_hal_set_intr(ah, 0); /* disable intr's until reset */
586: ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_fataltask);
587: } else if (status & HAL_INT_RXORN) {
588: sc->sc_stats.ast_rxorn++;
589: ath_hal_set_intr(ah, 0); /* disable intr's until reset */
590: ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_rxorntask);
591: } else if (status & HAL_INT_MIB) {
592: DPRINTF(ATH_DEBUG_INTR,
593: ("%s: resetting MIB counters\n", __func__));
594: sc->sc_stats.ast_mib++;
595: ath_hal_update_mib_counters(ah, &sc->sc_mib_stats);
596: } else {
597: if (status & HAL_INT_RXEOL) {
598: /*
599: * NB: the hardware should re-read the link when
600: * RXE bit is written, but it doesn't work at
601: * least on older hardware revs.
602: */
603: sc->sc_stats.ast_rxeol++;
604: sc->sc_rxlink = NULL;
605: }
606: if (status & HAL_INT_TXURN) {
607: sc->sc_stats.ast_txurn++;
608: /* bump tx trigger level */
609: ath_hal_update_tx_triglevel(ah, AH_TRUE);
610: }
611: if (status & HAL_INT_RX)
612: ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_rxtask);
613: if (status & HAL_INT_TX)
614: ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_txtask);
615: if (status & HAL_INT_SWBA)
616: ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_swbatask);
617: if (status & HAL_INT_BMISS) {
618: sc->sc_stats.ast_bmiss++;
619: ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_bmisstask);
620: }
621: }
622: return 1;
623: }
624:
625: void
626: ath_fatal_proc(void *arg, int pending)
627: {
628: struct ath_softc *sc = arg;
629: struct ieee80211com *ic = &sc->sc_ic;
630: struct ifnet *ifp = &ic->ic_if;
631:
632: if (ifp->if_flags & IFF_DEBUG)
633: printf("%s: hardware error; resetting\n", ifp->if_xname);
634: ath_reset(sc, 1);
635: }
636:
637: void
638: ath_rxorn_proc(void *arg, int pending)
639: {
640: struct ath_softc *sc = arg;
641: struct ieee80211com *ic = &sc->sc_ic;
642: struct ifnet *ifp = &ic->ic_if;
643:
644: if (ifp->if_flags & IFF_DEBUG)
645: printf("%s: rx FIFO overrun; resetting\n", ifp->if_xname);
646: ath_reset(sc, 1);
647: }
648:
649: void
650: ath_bmiss_proc(void *arg, int pending)
651: {
652: struct ath_softc *sc = arg;
653: struct ieee80211com *ic = &sc->sc_ic;
654:
655: DPRINTF(ATH_DEBUG_ANY, ("%s: pending %u\n", __func__, pending));
656: if (ic->ic_opmode != IEEE80211_M_STA)
657: return;
658: if (ic->ic_state == IEEE80211_S_RUN) {
659: /*
660: * Rather than go directly to scan state, try to
661: * reassociate first. If that fails then the state
662: * machine will drop us into scanning after timing
663: * out waiting for a probe response.
664: */
665: ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
666: }
667: }
668:
669: u_int
670: ath_chan2flags(struct ieee80211com *ic, struct ieee80211_channel *chan)
671: {
672: enum ieee80211_phymode mode = ieee80211_chan2mode(ic, chan);
673:
674: switch (mode) {
675: case IEEE80211_MODE_AUTO:
676: return 0;
677: case IEEE80211_MODE_11A:
678: return CHANNEL_A;
679: case IEEE80211_MODE_11B:
680: return CHANNEL_B;
681: case IEEE80211_MODE_11G:
682: return CHANNEL_G;
683: case IEEE80211_MODE_TURBO:
684: return CHANNEL_T;
685: default:
686: panic("%s: unsupported mode %d", __func__, mode);
687: return 0;
688: }
689: }
690:
691: int
692: ath_init(struct ifnet *ifp)
693: {
694: return ath_init1((struct ath_softc *)ifp->if_softc);
695: }
696:
697: int
698: ath_init1(struct ath_softc *sc)
699: {
700: struct ieee80211com *ic = &sc->sc_ic;
701: struct ifnet *ifp = &ic->ic_if;
702: struct ieee80211_node *ni;
703: enum ieee80211_phymode mode;
704: struct ath_hal *ah = sc->sc_ah;
705: HAL_STATUS status;
706: HAL_CHANNEL hchan;
707: int error = 0, s;
708:
709: DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags 0x%x\n",
710: __func__, ifp->if_flags));
711:
712: if ((error = ath_enable(sc)) != 0)
713: return error;
714:
715: s = splnet();
716: /*
717: * Stop anything previously setup. This is safe
718: * whether this is the first time through or not.
719: */
720: ath_stop(ifp);
721:
722: /*
723: * Reset the link layer address to the latest value.
724: */
725: IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
726: ath_hal_set_lladdr(ah, ic->ic_myaddr);
727:
728: /*
729: * The basic interface to setting the hardware in a good
730: * state is ``reset''. On return the hardware is known to
731: * be powered up and with interrupts disabled. This must
732: * be followed by initialization of the appropriate bits
733: * and then setup of the interrupt mask.
734: */
735: hchan.channel = ic->ic_ibss_chan->ic_freq;
736: hchan.channelFlags = ath_chan2flags(ic, ic->ic_ibss_chan);
737: if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE, &status)) {
738: printf("%s: unable to reset hardware; hal status %u\n",
739: ifp->if_xname, status);
740: error = EIO;
741: goto done;
742: }
743: ath_set_slot_time(sc);
744: /*
745: * Setup the hardware after reset: the key cache
746: * is filled as needed and the receive engine is
747: * set going. Frame transmit is handled entirely
748: * in the frame output path; there's nothing to do
749: * here except setup the interrupt mask.
750: */
751: if (ic->ic_flags & IEEE80211_F_WEPON) {
752: if ((error = ath_initkeytable(sc)) != 0) {
753: printf("%s: unable to initialize the key cache\n",
754: ifp->if_xname);
755: goto done;
756: }
757: }
758: if ((error = ath_startrecv(sc)) != 0) {
759: printf("%s: unable to start recv logic\n", ifp->if_xname);
760: goto done;
761: }
762:
763: /*
764: * Enable interrupts.
765: */
766: sc->sc_imask = HAL_INT_RX | HAL_INT_TX
767: | HAL_INT_RXEOL | HAL_INT_RXORN
768: | HAL_INT_FATAL | HAL_INT_GLOBAL;
769: if (ic->ic_opmode == IEEE80211_M_HOSTAP)
770: sc->sc_imask |= HAL_INT_MIB;
771: ath_hal_set_intr(ah, sc->sc_imask);
772:
773: ifp->if_flags |= IFF_RUNNING;
774: ic->ic_state = IEEE80211_S_INIT;
775:
776: /*
777: * The hardware should be ready to go now so it's safe
778: * to kick the 802.11 state machine as it's likely to
779: * immediately call back to us to send mgmt frames.
780: */
781: ni = ic->ic_bss;
782: ni->ni_chan = ic->ic_ibss_chan;
783: mode = ieee80211_chan2mode(ic, ni->ni_chan);
784: if (mode != sc->sc_curmode)
785: ath_setcurmode(sc, mode);
786: if (ic->ic_opmode != IEEE80211_M_MONITOR) {
787: ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
788: } else {
789: ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
790: }
791: done:
792: splx(s);
793: return error;
794: }
795:
796: void
797: ath_stop(struct ifnet *ifp)
798: {
799: struct ieee80211com *ic = (struct ieee80211com *) ifp;
800: struct ath_softc *sc = ifp->if_softc;
801: struct ath_hal *ah = sc->sc_ah;
802: int s;
803:
804: DPRINTF(ATH_DEBUG_ANY, ("%s: invalid %u if_flags 0x%x\n",
805: __func__, sc->sc_invalid, ifp->if_flags));
806:
807: s = splnet();
808: if (ifp->if_flags & IFF_RUNNING) {
809: /*
810: * Shutdown the hardware and driver:
811: * disable interrupts
812: * turn off timers
813: * clear transmit machinery
814: * clear receive machinery
815: * drain and release tx queues
816: * reclaim beacon resources
817: * reset 802.11 state machine
818: * power down hardware
819: *
820: * Note that some of this work is not possible if the
821: * hardware is gone (invalid).
822: */
823: ifp->if_flags &= ~IFF_RUNNING;
824: ifp->if_timer = 0;
825: if (!sc->sc_invalid)
826: ath_hal_set_intr(ah, 0);
827: ath_draintxq(sc);
828: if (!sc->sc_invalid) {
829: ath_stoprecv(sc);
830: } else {
831: sc->sc_rxlink = NULL;
832: }
833: IFQ_PURGE(&ifp->if_snd);
834: ath_beacon_free(sc);
835: ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
836: if (!sc->sc_invalid) {
837: ath_hal_set_power(ah, HAL_PM_FULL_SLEEP, 0);
838: }
839: ath_disable(sc);
840: }
841: splx(s);
842: }
843:
844: /*
845: * Reset the hardware w/o losing operational state. This is
846: * basically a more efficient way of doing ath_stop, ath_init,
847: * followed by state transitions to the current 802.11
848: * operational state. Used to recover from errors rx overrun
849: * and to reset the hardware when rf gain settings must be reset.
850: */
851: void
852: ath_reset(struct ath_softc *sc, int full)
853: {
854: struct ieee80211com *ic = &sc->sc_ic;
855: struct ifnet *ifp = &ic->ic_if;
856: struct ath_hal *ah = sc->sc_ah;
857: struct ieee80211_channel *c;
858: HAL_STATUS status;
859: HAL_CHANNEL hchan;
860:
861: /*
862: * Convert to a HAL channel description with the flags
863: * constrained to reflect the current operating mode.
864: */
865: c = ic->ic_ibss_chan;
866: hchan.channel = c->ic_freq;
867: hchan.channelFlags = ath_chan2flags(ic, c);
868:
869: ath_hal_set_intr(ah, 0); /* disable interrupts */
870: ath_draintxq(sc); /* stop xmit side */
871: ath_stoprecv(sc); /* stop recv side */
872: /* NB: indicate channel change so we do a full reset */
873: if (!ath_hal_reset(ah, ic->ic_opmode, &hchan,
874: full ? AH_TRUE : AH_FALSE, &status)) {
875: printf("%s: %s: unable to reset hardware; hal status %u\n",
876: ifp->if_xname, __func__, status);
877: }
878: ath_set_slot_time(sc);
879: /* In case channel changed, save as a node channel */
880: ic->ic_bss->ni_chan = ic->ic_ibss_chan;
881: ath_hal_set_intr(ah, sc->sc_imask);
882: if (ath_startrecv(sc) != 0) /* restart recv */
883: printf("%s: %s: unable to start recv logic\n", ifp->if_xname,
884: __func__);
885: ath_start(ifp); /* restart xmit */
886: if (ic->ic_state == IEEE80211_S_RUN)
887: ath_beacon_config(sc); /* restart beacons */
888: }
889:
890: void
891: ath_start(struct ifnet *ifp)
892: {
893: struct ath_softc *sc = ifp->if_softc;
894: struct ath_hal *ah = sc->sc_ah;
895: struct ieee80211com *ic = &sc->sc_ic;
896: struct ieee80211_node *ni;
897: struct ath_buf *bf;
898: struct mbuf *m;
899: struct ieee80211_frame *wh;
900: int s;
901:
902: if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING ||
903: sc->sc_invalid)
904: return;
905: for (;;) {
906: /*
907: * Grab a TX buffer and associated resources.
908: */
909: s = splnet();
910: bf = TAILQ_FIRST(&sc->sc_txbuf);
911: if (bf != NULL)
912: TAILQ_REMOVE(&sc->sc_txbuf, bf, bf_list);
913: splx(s);
914: if (bf == NULL) {
915: DPRINTF(ATH_DEBUG_ANY, ("%s: out of xmit buffers\n",
916: __func__));
917: sc->sc_stats.ast_tx_qstop++;
918: ifp->if_flags |= IFF_OACTIVE;
919: break;
920: }
921: /*
922: * Poll the management queue for frames; they
923: * have priority over normal data frames.
924: */
925: IF_DEQUEUE(&ic->ic_mgtq, m);
926: if (m == NULL) {
927: /*
928: * No data frames go out unless we're associated.
929: */
930: if (ic->ic_state != IEEE80211_S_RUN) {
931: DPRINTF(ATH_DEBUG_ANY,
932: ("%s: ignore data packet, state %u\n",
933: __func__, ic->ic_state));
934: sc->sc_stats.ast_tx_discard++;
935: s = splnet();
936: TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
937: splx(s);
938: break;
939: }
940: IFQ_DEQUEUE(&ifp->if_snd, m);
941: if (m == NULL) {
942: s = splnet();
943: TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
944: splx(s);
945: break;
946: }
947: ifp->if_opackets++;
948:
949: #if NBPFILTER > 0
950: if (ifp->if_bpf)
951: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
952: #endif
953:
954: /*
955: * Encapsulate the packet in prep for transmission.
956: */
957: m = ieee80211_encap(ifp, m, &ni);
958: if (m == NULL) {
959: DPRINTF(ATH_DEBUG_ANY,
960: ("%s: encapsulation failure\n",
961: __func__));
962: sc->sc_stats.ast_tx_encap++;
963: goto bad;
964: }
965: wh = mtod(m, struct ieee80211_frame *);
966: } else {
967: /*
968: * Hack! The referenced node pointer is in the
969: * rcvif field of the packet header. This is
970: * placed there by ieee80211_mgmt_output because
971: * we need to hold the reference with the frame
972: * and there's no other way (other than packet
973: * tags which we consider too expensive to use)
974: * to pass it along.
975: */
976: ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
977: m->m_pkthdr.rcvif = NULL;
978:
979: wh = mtod(m, struct ieee80211_frame *);
980: if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
981: IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
982: /* fill time stamp */
983: u_int64_t tsf;
984: u_int32_t *tstamp;
985:
986: tsf = ath_hal_get_tsf64(ah);
987: /* XXX: adjust 100us delay to xmit */
988: tsf += 100;
989: tstamp = (u_int32_t *)&wh[1];
990: tstamp[0] = htole32(tsf & 0xffffffff);
991: tstamp[1] = htole32(tsf >> 32);
992: }
993: sc->sc_stats.ast_tx_mgmt++;
994: }
995:
996: if (ath_tx_start(sc, ni, bf, m)) {
997: bad:
998: s = splnet();
999: TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
1000: splx(s);
1001: ifp->if_oerrors++;
1002: if (ni != NULL)
1003: ieee80211_release_node(ic, ni);
1004: continue;
1005: }
1006:
1007: sc->sc_tx_timer = 5;
1008: ifp->if_timer = 1;
1009: }
1010: }
1011:
1012: int
1013: ath_media_change(struct ifnet *ifp)
1014: {
1015: int error;
1016:
1017: error = ieee80211_media_change(ifp);
1018: if (error == ENETRESET) {
1019: if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
1020: (IFF_RUNNING|IFF_UP))
1021: ath_init(ifp); /* XXX lose error */
1022: error = 0;
1023: }
1024: return error;
1025: }
1026:
1027: void
1028: ath_watchdog(struct ifnet *ifp)
1029: {
1030: struct ath_softc *sc = ifp->if_softc;
1031:
1032: ifp->if_timer = 0;
1033: if ((ifp->if_flags & IFF_RUNNING) == 0 || sc->sc_invalid)
1034: return;
1035: if (sc->sc_tx_timer) {
1036: if (--sc->sc_tx_timer == 0) {
1037: printf("%s: device timeout\n", ifp->if_xname);
1038: ath_reset(sc, 1);
1039: ifp->if_oerrors++;
1040: sc->sc_stats.ast_watchdog++;
1041: return;
1042: }
1043: ifp->if_timer = 1;
1044: }
1045:
1046: ieee80211_watchdog(ifp);
1047: }
1048:
1049: int
1050: ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1051: {
1052: struct ath_softc *sc = ifp->if_softc;
1053: struct ieee80211com *ic = &sc->sc_ic;
1054: struct ifreq *ifr = (struct ifreq *)data;
1055: struct ifaddr *ifa = (struct ifaddr *)data;
1056: int error = 0, s;
1057:
1058: s = splnet();
1059: switch (cmd) {
1060: case SIOCSIFADDR:
1061: ifp->if_flags |= IFF_UP;
1062: #ifdef INET
1063: if (ifa->ifa_addr->sa_family == AF_INET) {
1064: arp_ifinit(&ic->ic_ac, ifa);
1065: }
1066: #endif /* INET */
1067: /* FALLTHROUGH */
1068: case SIOCSIFFLAGS:
1069: if (ifp->if_flags & IFF_UP) {
1070: if (ifp->if_flags & IFF_RUNNING) {
1071: /*
1072: * To avoid rescanning another access point,
1073: * do not call ath_init() here. Instead,
1074: * only reflect promisc mode settings.
1075: */
1076: ath_mode_init(sc);
1077: } else {
1078: /*
1079: * Beware of being called during detach to
1080: * reset promiscuous mode. In that case we
1081: * will still be marked UP but not RUNNING.
1082: * However trying to re-init the interface
1083: * is the wrong thing to do as we've already
1084: * torn down much of our state. There's
1085: * probably a better way to deal with this.
1086: */
1087: if (!sc->sc_invalid)
1088: ath_init(ifp); /* XXX lose error */
1089: }
1090: } else
1091: ath_stop(ifp);
1092: break;
1093: case SIOCADDMULTI:
1094: case SIOCDELMULTI:
1095: #ifdef __FreeBSD__
1096: /*
1097: * The upper layer has already installed/removed
1098: * the multicast address(es), just recalculate the
1099: * multicast filter for the card.
1100: */
1101: if (ifp->if_flags & IFF_RUNNING)
1102: ath_mode_init(sc);
1103: #endif
1104: error = (cmd == SIOCADDMULTI) ?
1105: ether_addmulti(ifr, &sc->sc_ic.ic_ac) :
1106: ether_delmulti(ifr, &sc->sc_ic.ic_ac);
1107: if (error == ENETRESET) {
1108: if (ifp->if_flags & IFF_RUNNING)
1109: ath_mode_init(sc);
1110: error = 0;
1111: }
1112: break;
1113: case SIOCGATHSTATS:
1114: error = copyout(&sc->sc_stats,
1115: ifr->ifr_data, sizeof (sc->sc_stats));
1116: break;
1117: default:
1118: error = ieee80211_ioctl(ifp, cmd, data);
1119: if (error == ENETRESET) {
1120: if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
1121: (IFF_RUNNING|IFF_UP)) {
1122: struct ieee80211com *ic = &sc->sc_ic;
1123:
1124: if (ic->ic_opmode != IEEE80211_M_MONITOR)
1125: ath_init(ifp); /* XXX lose error */
1126: else
1127: ath_reset(sc, 1);
1128: }
1129: error = 0;
1130: }
1131: break;
1132: }
1133: splx(s);
1134: return error;
1135: }
1136:
1137: /*
1138: * Fill the hardware key cache with key entries.
1139: */
1140: int
1141: ath_initkeytable(struct ath_softc *sc)
1142: {
1143: struct ieee80211com *ic = &sc->sc_ic;
1144: struct ath_hal *ah = sc->sc_ah;
1145: int i;
1146:
1147: /* XXX maybe should reset all keys when !WEPON */
1148: for (i = 0; i < IEEE80211_WEP_NKID; i++) {
1149: struct ieee80211_key *k = &ic->ic_nw_keys[i];
1150: if (k->k_len == 0)
1151: ath_hal_reset_key(ah, i);
1152: else {
1153: HAL_KEYVAL hk;
1154:
1155: bzero(&hk, sizeof(hk));
1156: /*
1157: * Pad the key to a supported key length. It
1158: * is always a good idea to use full-length
1159: * keys without padded zeros but this seems
1160: * to be the default behaviour used by many
1161: * implementations.
1162: */
1163: if (k->k_cipher == IEEE80211_CIPHER_WEP40)
1164: hk.wk_len = AR5K_KEYVAL_LENGTH_40;
1165: else if (k->k_cipher == IEEE80211_CIPHER_WEP104)
1166: hk.wk_len = AR5K_KEYVAL_LENGTH_104;
1167: else
1168: return (EINVAL);
1169: bcopy(k->k_key, hk.wk_key, hk.wk_len);
1170:
1171: if (ath_hal_set_key(ah, i, &hk) != AH_TRUE)
1172: return (EINVAL);
1173: }
1174: }
1175:
1176: return (0);
1177: }
1178:
1179: void
1180: ath_mcastfilter_accum(caddr_t dl, u_int32_t (*mfilt)[2])
1181: {
1182: u_int32_t val;
1183: u_int8_t pos;
1184:
1185: val = LE_READ_4(dl + 0);
1186: pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
1187: val = LE_READ_4(dl + 3);
1188: pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
1189: pos &= 0x3f;
1190: (*mfilt)[pos / 32] |= (1 << (pos % 32));
1191: }
1192:
1193: void
1194: ath_mcastfilter_compute(struct ath_softc *sc, u_int32_t (*mfilt)[2])
1195: {
1196: struct ifnet *ifp = &sc->sc_ic.ic_if;
1197: struct ether_multi *enm;
1198: struct ether_multistep estep;
1199:
1200: ETHER_FIRST_MULTI(estep, &sc->sc_ic.ic_ac, enm);
1201: while (enm != NULL) {
1202: /* XXX Punt on ranges. */
1203: if (!IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi)) {
1204: (*mfilt)[0] = (*mfilt)[1] = ~((u_int32_t)0);
1205: ifp->if_flags |= IFF_ALLMULTI;
1206: return;
1207: }
1208: ath_mcastfilter_accum(enm->enm_addrlo, mfilt);
1209: ETHER_NEXT_MULTI(estep, enm);
1210: }
1211: ifp->if_flags &= ~IFF_ALLMULTI;
1212: }
1213:
1214: /*
1215: * Calculate the receive filter according to the
1216: * operating mode and state:
1217: *
1218: * o always accept unicast, broadcast, and multicast traffic
1219: * o maintain current state of phy error reception
1220: * o probe request frames are accepted only when operating in
1221: * hostap, adhoc, or monitor modes
1222: * o enable promiscuous mode according to the interface state
1223: * o accept beacons:
1224: * - when operating in adhoc mode so the 802.11 layer creates
1225: * node table entries for peers,
1226: * - when operating in station mode for collecting rssi data when
1227: * the station is otherwise quiet, or
1228: * - when scanning
1229: */
1230: u_int32_t
1231: ath_calcrxfilter(struct ath_softc *sc)
1232: {
1233: struct ieee80211com *ic = &sc->sc_ic;
1234: struct ath_hal *ah = sc->sc_ah;
1235: struct ifnet *ifp = &ic->ic_if;
1236: u_int32_t rfilt;
1237:
1238: rfilt = (ath_hal_get_rx_filter(ah) & HAL_RX_FILTER_PHYERR)
1239: | HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST;
1240: if (ic->ic_opmode != IEEE80211_M_STA)
1241: rfilt |= HAL_RX_FILTER_PROBEREQ;
1242: if (ic->ic_opmode != IEEE80211_M_AHDEMO)
1243: rfilt |= HAL_RX_FILTER_BEACON;
1244: if (ifp->if_flags & IFF_PROMISC)
1245: rfilt |= HAL_RX_FILTER_PROM;
1246: return rfilt;
1247: }
1248:
1249: void
1250: ath_mode_init(struct ath_softc *sc)
1251: {
1252: struct ath_hal *ah = sc->sc_ah;
1253: u_int32_t rfilt, mfilt[2];
1254:
1255: /* configure rx filter */
1256: rfilt = ath_calcrxfilter(sc);
1257: ath_hal_set_rx_filter(ah, rfilt);
1258:
1259: /* configure operational mode */
1260: ath_hal_set_opmode(ah);
1261:
1262: /* calculate and install multicast filter */
1263: mfilt[0] = mfilt[1] = 0;
1264: ath_mcastfilter_compute(sc, &mfilt);
1265: ath_hal_set_mcast_filter(ah, mfilt[0], mfilt[1]);
1266: DPRINTF(ATH_DEBUG_MODE, ("%s: RX filter 0x%x, MC filter %08x:%08x\n",
1267: __func__, rfilt, mfilt[0], mfilt[1]));
1268: }
1269:
1270: struct mbuf *
1271: ath_getmbuf(int flags, int type, u_int pktlen)
1272: {
1273: struct mbuf *m;
1274:
1275: KASSERT(pktlen <= MCLBYTES, ("802.11 packet too large: %u", pktlen));
1276: #ifdef __FreeBSD__
1277: if (pktlen <= MHLEN) {
1278: MGETHDR(m, flags, type);
1279: } else {
1280: m = m_getcl(flags, type, M_PKTHDR);
1281: }
1282: #else
1283: MGETHDR(m, flags, type);
1284: if (m != NULL && pktlen > MHLEN) {
1285: MCLGET(m, flags);
1286: if ((m->m_flags & M_EXT) == 0) {
1287: m_free(m);
1288: m = NULL;
1289: }
1290: }
1291: #endif
1292: return m;
1293: }
1294:
1295: int
1296: ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_node *ni)
1297: {
1298: struct ieee80211com *ic = &sc->sc_ic;
1299: struct ath_hal *ah = sc->sc_ah;
1300: struct ath_buf *bf;
1301: struct ath_desc *ds;
1302: struct mbuf *m;
1303: int error;
1304: u_int8_t rate;
1305: const HAL_RATE_TABLE *rt;
1306: u_int flags = 0;
1307:
1308: bf = sc->sc_bcbuf;
1309: if (bf->bf_m != NULL) {
1310: bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
1311: m_freem(bf->bf_m);
1312: bf->bf_m = NULL;
1313: bf->bf_node = NULL;
1314: }
1315: /*
1316: * NB: the beacon data buffer must be 32-bit aligned;
1317: * we assume the mbuf routines will return us something
1318: * with this alignment (perhaps should assert).
1319: */
1320: m = ieee80211_beacon_alloc(ic, ni);
1321: if (m == NULL) {
1322: DPRINTF(ATH_DEBUG_BEACON, ("%s: cannot get mbuf/cluster\n",
1323: __func__));
1324: sc->sc_stats.ast_be_nombuf++;
1325: return ENOMEM;
1326: }
1327:
1328: DPRINTF(ATH_DEBUG_BEACON, ("%s: m %p len %u\n", __func__, m, m->m_len));
1329: error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_dmamap, m,
1330: BUS_DMA_NOWAIT);
1331: if (error != 0) {
1332: m_freem(m);
1333: return error;
1334: }
1335: KASSERT(bf->bf_nseg == 1,
1336: ("%s: multi-segment packet; nseg %u", __func__, bf->bf_nseg));
1337: bf->bf_m = m;
1338:
1339: /* setup descriptors */
1340: ds = bf->bf_desc;
1341: bzero(ds, sizeof(struct ath_desc));
1342:
1343: if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_veol) {
1344: ds->ds_link = bf->bf_daddr; /* link to self */
1345: flags |= HAL_TXDESC_VEOL;
1346: } else {
1347: ds->ds_link = 0;
1348: }
1349: ds->ds_data = bf->bf_segs[0].ds_addr;
1350:
1351: DPRINTF(ATH_DEBUG_ANY, ("%s: segaddr %p seglen %u\n", __func__,
1352: (caddr_t)bf->bf_segs[0].ds_addr, (u_int)bf->bf_segs[0].ds_len));
1353:
1354: /*
1355: * Calculate rate code.
1356: * XXX everything at min xmit rate
1357: */
1358: rt = sc->sc_currates;
1359: KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
1360: if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) {
1361: rate = rt->info[0].rateCode | rt->info[0].shortPreamble;
1362: } else {
1363: rate = rt->info[0].rateCode;
1364: }
1365:
1366: flags = HAL_TXDESC_NOACK;
1367: if (ic->ic_opmode == IEEE80211_M_IBSS)
1368: flags |= HAL_TXDESC_VEOL;
1369:
1370: if (!ath_hal_setup_tx_desc(ah, ds
1371: , m->m_pkthdr.len + IEEE80211_CRC_LEN /* packet length */
1372: , sizeof(struct ieee80211_frame) /* header length */
1373: , HAL_PKT_TYPE_BEACON /* Atheros packet type */
1374: , 60 /* txpower XXX */
1375: , rate, 1 /* series 0 rate/tries */
1376: , HAL_TXKEYIX_INVALID /* no encryption */
1377: , 0 /* antenna mode */
1378: , flags /* no ack for beacons */
1379: , 0 /* rts/cts rate */
1380: , 0 /* rts/cts duration */
1381: )) {
1382: printf("%s: ath_hal_setup_tx_desc failed\n", __func__);
1383: return -1;
1384: }
1385: /* NB: beacon's BufLen must be a multiple of 4 bytes */
1386: /* XXX verify mbuf data area covers this roundup */
1387: if (!ath_hal_fill_tx_desc(ah, ds
1388: , roundup(bf->bf_segs[0].ds_len, 4) /* buffer length */
1389: , AH_TRUE /* first segment */
1390: , AH_TRUE /* last segment */
1391: )) {
1392: printf("%s: ath_hal_fill_tx_desc failed\n", __func__);
1393: return -1;
1394: }
1395:
1396: /* XXX it is not appropriate to bus_dmamap_sync? -dcy */
1397:
1398: return 0;
1399: }
1400:
1401: void
1402: ath_beacon_proc(void *arg, int pending)
1403: {
1404: struct ath_softc *sc = arg;
1405: struct ieee80211com *ic = &sc->sc_ic;
1406: struct ath_buf *bf = sc->sc_bcbuf;
1407: struct ath_hal *ah = sc->sc_ah;
1408:
1409: DPRINTF(ATH_DEBUG_BEACON_PROC, ("%s: pending %u\n", __func__, pending));
1410: if (ic->ic_opmode == IEEE80211_M_STA ||
1411: bf == NULL || bf->bf_m == NULL) {
1412: DPRINTF(ATH_DEBUG_ANY, ("%s: ic_flags=%x bf=%p bf_m=%p\n",
1413: __func__, ic->ic_flags, bf, bf ? bf->bf_m : NULL));
1414: return;
1415: }
1416: /* TODO: update beacon to reflect PS poll state */
1417: if (!ath_hal_stop_tx_dma(ah, sc->sc_bhalq)) {
1418: DPRINTF(ATH_DEBUG_ANY, ("%s: beacon queue %u did not stop?\n",
1419: __func__, sc->sc_bhalq));
1420: }
1421: bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 0,
1422: bf->bf_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
1423:
1424: ath_hal_put_tx_buf(ah, sc->sc_bhalq, bf->bf_daddr);
1425: ath_hal_tx_start(ah, sc->sc_bhalq);
1426: DPRINTF(ATH_DEBUG_BEACON_PROC,
1427: ("%s: TXDP%u = %p (%p)\n", __func__,
1428: sc->sc_bhalq, (caddr_t)bf->bf_daddr, bf->bf_desc));
1429: }
1430:
1431: void
1432: ath_beacon_free(struct ath_softc *sc)
1433: {
1434: struct ath_buf *bf = sc->sc_bcbuf;
1435:
1436: if (bf->bf_m != NULL) {
1437: bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
1438: m_freem(bf->bf_m);
1439: bf->bf_m = NULL;
1440: bf->bf_node = NULL;
1441: }
1442: }
1443:
1444: /*
1445: * Configure the beacon and sleep timers.
1446: *
1447: * When operating as an AP this resets the TSF and sets
1448: * up the hardware to notify us when we need to issue beacons.
1449: *
1450: * When operating in station mode this sets up the beacon
1451: * timers according to the timestamp of the last received
1452: * beacon and the current TSF, configures PCF and DTIM
1453: * handling, programs the sleep registers so the hardware
1454: * will wakeup in time to receive beacons, and configures
1455: * the beacon miss handling so we'll receive a BMISS
1456: * interrupt when we stop seeing beacons from the AP
1457: * we've associated with.
1458: */
1459: void
1460: ath_beacon_config(struct ath_softc *sc)
1461: {
1462: #define MS_TO_TU(x) (((x) * 1000) / 1024)
1463: struct ath_hal *ah = sc->sc_ah;
1464: struct ieee80211com *ic = &sc->sc_ic;
1465: struct ieee80211_node *ni = ic->ic_bss;
1466: u_int32_t nexttbtt, intval;
1467:
1468: nexttbtt = (LE_READ_4(ni->ni_tstamp + 4) << 22) |
1469: (LE_READ_4(ni->ni_tstamp) >> 10);
1470: intval = MAX(1, ni->ni_intval) & HAL_BEACON_PERIOD;
1471: if (nexttbtt == 0) { /* e.g. for ap mode */
1472: nexttbtt = intval;
1473: } else if (intval) {
1474: nexttbtt = roundup(nexttbtt, intval);
1475: }
1476: DPRINTF(ATH_DEBUG_BEACON, ("%s: intval %u nexttbtt %u\n",
1477: __func__, ni->ni_intval, nexttbtt));
1478: if (ic->ic_opmode == IEEE80211_M_STA) {
1479: HAL_BEACON_STATE bs;
1480: u_int32_t bmisstime;
1481:
1482: /* NB: no PCF support right now */
1483: bzero(&bs, sizeof(bs));
1484: bs.bs_intval = intval;
1485: bs.bs_nexttbtt = nexttbtt;
1486: bs.bs_dtimperiod = bs.bs_intval;
1487: bs.bs_nextdtim = nexttbtt;
1488: /*
1489: * Calculate the number of consecutive beacons to miss
1490: * before taking a BMISS interrupt. The configuration
1491: * is specified in ms, so we need to convert that to
1492: * TU's and then calculate based on the beacon interval.
1493: * Note that we clamp the result to at most 10 beacons.
1494: */
1495: bmisstime = MAX(7, ic->ic_bmisstimeout);
1496: bs.bs_bmissthreshold = howmany(bmisstime, intval);
1497: if (bs.bs_bmissthreshold > 7) {
1498: bs.bs_bmissthreshold = 7;
1499: } else if (bs.bs_bmissthreshold <= 0) {
1500: bs.bs_bmissthreshold = 1;
1501: }
1502:
1503: /*
1504: * Calculate sleep duration. The configuration is
1505: * given in ms. We insure a multiple of the beacon
1506: * period is used. Also, if the sleep duration is
1507: * greater than the DTIM period then it makes senses
1508: * to make it a multiple of that.
1509: *
1510: * XXX fixed at 100ms
1511: */
1512: bs.bs_sleepduration =
1513: roundup(MS_TO_TU(100), bs.bs_intval);
1514: if (bs.bs_sleepduration > bs.bs_dtimperiod) {
1515: bs.bs_sleepduration =
1516: roundup(bs.bs_sleepduration, bs.bs_dtimperiod);
1517: }
1518:
1519: DPRINTF(ATH_DEBUG_BEACON,
1520: ("%s: intval %u nexttbtt %u dtim %u nextdtim %u bmiss %u"
1521: " sleep %u\n"
1522: , __func__
1523: , bs.bs_intval
1524: , bs.bs_nexttbtt
1525: , bs.bs_dtimperiod
1526: , bs.bs_nextdtim
1527: , bs.bs_bmissthreshold
1528: , bs.bs_sleepduration
1529: ));
1530: ath_hal_set_intr(ah, 0);
1531: ath_hal_set_beacon_timers(ah, &bs, 0/*XXX*/, 0, 0);
1532: sc->sc_imask |= HAL_INT_BMISS;
1533: ath_hal_set_intr(ah, sc->sc_imask);
1534: } else {
1535: ath_hal_set_intr(ah, 0);
1536: if (nexttbtt == intval)
1537: intval |= HAL_BEACON_RESET_TSF;
1538: if (ic->ic_opmode == IEEE80211_M_IBSS) {
1539: /*
1540: * In IBSS mode enable the beacon timers but ony
1541: * enable SWBA interrupts if we need to moanually
1542: * prepare beacon frames. Otherwise we use a
1543: * self-linked tx descriptor and let the hardware
1544: * deal with things.
1545: */
1546: intval |= HAL_BEACON_ENA;
1547: if (!sc->sc_veol)
1548: sc->sc_imask |= HAL_INT_SWBA;
1549: } else if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
1550: /*
1551: * In AP mode we enable the beacon timers and
1552: * SWBA interrupts to prepare beacon frames.
1553: */
1554: intval |= HAL_BEACON_ENA;
1555: sc->sc_imask |= HAL_INT_SWBA; /* beacon prepare */
1556: }
1557: ath_hal_init_beacon(ah, nexttbtt, intval);
1558: ath_hal_set_intr(ah, sc->sc_imask);
1559: /*
1560: * When using a self-linked beacon descriptor in IBBS
1561: * mode load it once here.
1562: */
1563: if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_veol)
1564: ath_beacon_proc(sc, 0);
1565: }
1566: }
1567:
1568: int
1569: ath_desc_alloc(struct ath_softc *sc)
1570: {
1571: int i, bsize, error = -1;
1572: struct ath_desc *ds;
1573: struct ath_buf *bf;
1574:
1575: /* allocate descriptors */
1576: sc->sc_desc_len = sizeof(struct ath_desc) *
1577: (ATH_TXBUF * ATH_TXDESC + ATH_RXBUF + 1);
1578: if ((error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_desc_len, PAGE_SIZE,
1579: 0, &sc->sc_dseg, 1, &sc->sc_dnseg, 0)) != 0) {
1580: printf("%s: unable to allocate control data, error = %d\n",
1581: sc->sc_dev.dv_xname, error);
1582: goto fail0;
1583: }
1584:
1585: if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg,
1586: sc->sc_desc_len, (caddr_t *)&sc->sc_desc, BUS_DMA_COHERENT)) != 0) {
1587: printf("%s: unable to map control data, error = %d\n",
1588: sc->sc_dev.dv_xname, error);
1589: goto fail1;
1590: }
1591:
1592: if ((error = bus_dmamap_create(sc->sc_dmat, sc->sc_desc_len, 1,
1593: sc->sc_desc_len, 0, 0, &sc->sc_ddmamap)) != 0) {
1594: printf("%s: unable to create control data DMA map, "
1595: "error = %d\n", sc->sc_dev.dv_xname, error);
1596: goto fail2;
1597: }
1598:
1599: if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_ddmamap, sc->sc_desc,
1600: sc->sc_desc_len, NULL, 0)) != 0) {
1601: printf("%s: unable to load control data DMA map, error = %d\n",
1602: sc->sc_dev.dv_xname, error);
1603: goto fail3;
1604: }
1605:
1606: ds = sc->sc_desc;
1607: sc->sc_desc_paddr = sc->sc_ddmamap->dm_segs[0].ds_addr;
1608:
1609: DPRINTF(ATH_DEBUG_XMIT_DESC|ATH_DEBUG_RECV_DESC,
1610: ("ath_desc_alloc: DMA map: %p (%lu) -> %p (%lu)\n",
1611: ds, (u_long)sc->sc_desc_len,
1612: (caddr_t) sc->sc_desc_paddr, /*XXX*/ (u_long) sc->sc_desc_len));
1613:
1614: /* allocate buffers */
1615: bsize = sizeof(struct ath_buf) * (ATH_TXBUF + ATH_RXBUF + 1);
1616: bf = malloc(bsize, M_DEVBUF, M_NOWAIT);
1617: if (bf == NULL) {
1618: printf("%s: unable to allocate Tx/Rx buffers\n",
1619: sc->sc_dev.dv_xname);
1620: error = ENOMEM;
1621: goto fail3;
1622: }
1623: bzero(bf, bsize);
1624: sc->sc_bufptr = bf;
1625:
1626: TAILQ_INIT(&sc->sc_rxbuf);
1627: for (i = 0; i < ATH_RXBUF; i++, bf++, ds++) {
1628: bf->bf_desc = ds;
1629: bf->bf_daddr = sc->sc_desc_paddr +
1630: ((caddr_t)ds - (caddr_t)sc->sc_desc);
1631: if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
1632: MCLBYTES, 0, 0, &bf->bf_dmamap)) != 0) {
1633: printf("%s: unable to create Rx dmamap, error = %d\n",
1634: sc->sc_dev.dv_xname, error);
1635: goto fail4;
1636: }
1637: TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
1638: }
1639:
1640: TAILQ_INIT(&sc->sc_txbuf);
1641: for (i = 0; i < ATH_TXBUF; i++, bf++, ds += ATH_TXDESC) {
1642: bf->bf_desc = ds;
1643: bf->bf_daddr = sc->sc_desc_paddr +
1644: ((caddr_t)ds - (caddr_t)sc->sc_desc);
1645: if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
1646: ATH_TXDESC, MCLBYTES, 0, 0, &bf->bf_dmamap)) != 0) {
1647: printf("%s: unable to create Tx dmamap, error = %d\n",
1648: sc->sc_dev.dv_xname, error);
1649: goto fail5;
1650: }
1651: TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
1652: }
1653: TAILQ_INIT(&sc->sc_txq);
1654:
1655: /* beacon buffer */
1656: bf->bf_desc = ds;
1657: bf->bf_daddr = sc->sc_desc_paddr + ((caddr_t)ds - (caddr_t)sc->sc_desc);
1658: if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 0,
1659: &bf->bf_dmamap)) != 0) {
1660: printf("%s: unable to create beacon dmamap, error = %d\n",
1661: sc->sc_dev.dv_xname, error);
1662: goto fail5;
1663: }
1664: sc->sc_bcbuf = bf;
1665: return 0;
1666:
1667: fail5:
1668: for (i = ATH_RXBUF; i < ATH_RXBUF + ATH_TXBUF; i++) {
1669: if (sc->sc_bufptr[i].bf_dmamap == NULL)
1670: continue;
1671: bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufptr[i].bf_dmamap);
1672: }
1673: fail4:
1674: for (i = 0; i < ATH_RXBUF; i++) {
1675: if (sc->sc_bufptr[i].bf_dmamap == NULL)
1676: continue;
1677: bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufptr[i].bf_dmamap);
1678: }
1679: fail3:
1680: bus_dmamap_unload(sc->sc_dmat, sc->sc_ddmamap);
1681: fail2:
1682: bus_dmamap_destroy(sc->sc_dmat, sc->sc_ddmamap);
1683: sc->sc_ddmamap = NULL;
1684: fail1:
1685: bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_desc, sc->sc_desc_len);
1686: fail0:
1687: bus_dmamem_free(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg);
1688: return error;
1689: }
1690:
1691: void
1692: ath_desc_free(struct ath_softc *sc)
1693: {
1694: struct ath_buf *bf;
1695:
1696: bus_dmamap_unload(sc->sc_dmat, sc->sc_ddmamap);
1697: bus_dmamap_destroy(sc->sc_dmat, sc->sc_ddmamap);
1698: bus_dmamem_free(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg);
1699:
1700: TAILQ_FOREACH(bf, &sc->sc_txq, bf_list) {
1701: bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
1702: bus_dmamap_destroy(sc->sc_dmat, bf->bf_dmamap);
1703: m_freem(bf->bf_m);
1704: }
1705: TAILQ_FOREACH(bf, &sc->sc_txbuf, bf_list)
1706: bus_dmamap_destroy(sc->sc_dmat, bf->bf_dmamap);
1707: TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
1708: if (bf->bf_m) {
1709: bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
1710: bus_dmamap_destroy(sc->sc_dmat, bf->bf_dmamap);
1711: m_freem(bf->bf_m);
1712: bf->bf_m = NULL;
1713: }
1714: }
1715: if (sc->sc_bcbuf != NULL) {
1716: bus_dmamap_unload(sc->sc_dmat, sc->sc_bcbuf->bf_dmamap);
1717: bus_dmamap_destroy(sc->sc_dmat, sc->sc_bcbuf->bf_dmamap);
1718: sc->sc_bcbuf = NULL;
1719: }
1720:
1721: TAILQ_INIT(&sc->sc_rxbuf);
1722: TAILQ_INIT(&sc->sc_txbuf);
1723: TAILQ_INIT(&sc->sc_txq);
1724: free(sc->sc_bufptr, M_DEVBUF);
1725: sc->sc_bufptr = NULL;
1726: }
1727:
1728: struct ieee80211_node *
1729: ath_node_alloc(struct ieee80211com *ic)
1730: {
1731: struct ath_node *an =
1732: malloc(sizeof(struct ath_node), M_DEVBUF, M_NOWAIT);
1733: if (an) {
1734: int i;
1735: bzero(an, sizeof(struct ath_node));
1736: for (i = 0; i < ATH_RHIST_SIZE; i++)
1737: an->an_rx_hist[i].arh_ticks = ATH_RHIST_NOTIME;
1738: an->an_rx_hist_next = ATH_RHIST_SIZE-1;
1739: return &an->an_node;
1740: } else
1741: return NULL;
1742: }
1743:
1744: void
1745: ath_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
1746: {
1747: struct ath_softc *sc = ic->ic_if.if_softc;
1748: struct ath_buf *bf;
1749:
1750: TAILQ_FOREACH(bf, &sc->sc_txq, bf_list) {
1751: if (bf->bf_node == ni)
1752: bf->bf_node = NULL;
1753: }
1754: (*sc->sc_node_free)(ic, ni);
1755: }
1756:
1757: void
1758: ath_node_copy(struct ieee80211com *ic,
1759: struct ieee80211_node *dst, const struct ieee80211_node *src)
1760: {
1761: struct ath_softc *sc = ic->ic_if.if_softc;
1762:
1763: bcopy(&src[1], &dst[1],
1764: sizeof(struct ath_node) - sizeof(struct ieee80211_node));
1765: (*sc->sc_node_copy)(ic, dst, src);
1766: }
1767:
1768: u_int8_t
1769: ath_node_getrssi(struct ieee80211com *ic, const struct ieee80211_node *ni)
1770: {
1771: const struct ath_node *an = ATH_NODE(ni);
1772: int i, now, nsamples, rssi;
1773:
1774: /*
1775: * Calculate the average over the last second of sampled data.
1776: */
1777: now = ATH_TICKS();
1778: nsamples = 0;
1779: rssi = 0;
1780: i = an->an_rx_hist_next;
1781: do {
1782: const struct ath_recv_hist *rh = &an->an_rx_hist[i];
1783: if (rh->arh_ticks == ATH_RHIST_NOTIME)
1784: goto done;
1785: if (now - rh->arh_ticks > hz)
1786: goto done;
1787: rssi += rh->arh_rssi;
1788: nsamples++;
1789: if (i == 0) {
1790: i = ATH_RHIST_SIZE-1;
1791: } else {
1792: i--;
1793: }
1794: } while (i != an->an_rx_hist_next);
1795: done:
1796: /*
1797: * Return either the average or the last known
1798: * value if there is no recent data.
1799: */
1800: return (nsamples ? rssi / nsamples : an->an_rx_hist[i].arh_rssi);
1801: }
1802:
1803: int
1804: ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
1805: {
1806: struct ath_hal *ah = sc->sc_ah;
1807: struct ieee80211com *ic = &sc->sc_ic;
1808: int error;
1809: struct mbuf *m;
1810: struct ath_desc *ds;
1811:
1812: m = bf->bf_m;
1813: if (m == NULL) {
1814: /*
1815: * NB: by assigning a page to the rx dma buffer we
1816: * implicitly satisfy the Atheros requirement that
1817: * this buffer be cache-line-aligned and sized to be
1818: * multiple of the cache line size. Not doing this
1819: * causes weird stuff to happen (for the 5210 at least).
1820: */
1821: m = ath_getmbuf(M_DONTWAIT, MT_DATA, MCLBYTES);
1822: if (m == NULL) {
1823: DPRINTF(ATH_DEBUG_ANY,
1824: ("%s: no mbuf/cluster\n", __func__));
1825: sc->sc_stats.ast_rx_nombuf++;
1826: return ENOMEM;
1827: }
1828: bf->bf_m = m;
1829: m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
1830:
1831: error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_dmamap, m,
1832: BUS_DMA_NOWAIT);
1833: if (error != 0) {
1834: DPRINTF(ATH_DEBUG_ANY,
1835: ("%s: ath_bus_dmamap_load_mbuf failed;"
1836: " error %d\n", __func__, error));
1837: sc->sc_stats.ast_rx_busdma++;
1838: return error;
1839: }
1840: KASSERT(bf->bf_nseg == 1,
1841: ("ath_rxbuf_init: multi-segment packet; nseg %u",
1842: bf->bf_nseg));
1843: }
1844: bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 0,
1845: bf->bf_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
1846:
1847: /*
1848: * Setup descriptors. For receive we always terminate
1849: * the descriptor list with a self-linked entry so we'll
1850: * not get overrun under high load (as can happen with a
1851: * 5212 when ANI processing enables PHY errors).
1852: *
1853: * To insure the last descriptor is self-linked we create
1854: * each descriptor as self-linked and add it to the end. As
1855: * each additional descriptor is added the previous self-linked
1856: * entry is ``fixed'' naturally. This should be safe even
1857: * if DMA is happening. When processing RX interrupts we
1858: * never remove/process the last, self-linked, entry on the
1859: * descriptor list. This insures the hardware always has
1860: * someplace to write a new frame.
1861: */
1862: ds = bf->bf_desc;
1863: bzero(ds, sizeof(struct ath_desc));
1864: if (ic->ic_opmode != IEEE80211_M_HOSTAP)
1865: ds->ds_link = bf->bf_daddr; /* link to self */
1866: ds->ds_data = bf->bf_segs[0].ds_addr;
1867: ath_hal_setup_rx_desc(ah, ds
1868: , m->m_len /* buffer size */
1869: , 0
1870: );
1871:
1872: if (sc->sc_rxlink != NULL)
1873: *sc->sc_rxlink = bf->bf_daddr;
1874: sc->sc_rxlink = &ds->ds_link;
1875: return 0;
1876: }
1877:
1878: void
1879: ath_rx_proc(void *arg, int npending)
1880: {
1881: #define PA2DESC(_sc, _pa) \
1882: ((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \
1883: ((_pa) - (_sc)->sc_desc_paddr)))
1884: struct ath_softc *sc = arg;
1885: struct ath_buf *bf;
1886: struct ieee80211com *ic = &sc->sc_ic;
1887: struct ifnet *ifp = &ic->ic_if;
1888: struct ath_hal *ah = sc->sc_ah;
1889: struct ath_desc *ds;
1890: struct mbuf *m;
1891: struct ieee80211_frame *wh, whbuf;
1892: struct ieee80211_node *ni;
1893: struct ath_node *an;
1894: struct ath_recv_hist *rh;
1895: int len;
1896: u_int phyerr;
1897: HAL_STATUS status;
1898:
1899: DPRINTF(ATH_DEBUG_RX_PROC, ("%s: pending %u\n", __func__, npending));
1900: do {
1901: bf = TAILQ_FIRST(&sc->sc_rxbuf);
1902: if (bf == NULL) { /* NB: shouldn't happen */
1903: printf("%s: ath_rx_proc: no buffer!\n", ifp->if_xname);
1904: break;
1905: }
1906: ds = bf->bf_desc;
1907: if (ds->ds_link == bf->bf_daddr) {
1908: /* NB: never process the self-linked entry at the end */
1909: break;
1910: }
1911: m = bf->bf_m;
1912: if (m == NULL) { /* NB: shouldn't happen */
1913: printf("%s: ath_rx_proc: no mbuf!\n", ifp->if_xname);
1914: continue;
1915: }
1916: /* XXX sync descriptor memory */
1917: /*
1918: * Must provide the virtual address of the current
1919: * descriptor, the physical address, and the virtual
1920: * address of the next descriptor in the h/w chain.
1921: * This allows the HAL to look ahead to see if the
1922: * hardware is done with a descriptor by checking the
1923: * done bit in the following descriptor and the address
1924: * of the current descriptor the DMA engine is working
1925: * on. All this is necessary because of our use of
1926: * a self-linked list to avoid rx overruns.
1927: */
1928: status = ath_hal_proc_rx_desc(ah, ds,
1929: bf->bf_daddr, PA2DESC(sc, ds->ds_link));
1930: #ifdef AR_DEBUG
1931: if (ath_debug & ATH_DEBUG_RECV_DESC)
1932: ath_printrxbuf(bf, status == HAL_OK);
1933: #endif
1934: if (status == HAL_EINPROGRESS)
1935: break;
1936: TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list);
1937:
1938: if (ds->ds_rxstat.rs_more) {
1939: /*
1940: * Frame spans multiple descriptors; this
1941: * cannot happen yet as we don't support
1942: * jumbograms. If not in monitor mode,
1943: * discard the frame.
1944: */
1945:
1946: /*
1947: * Enable this if you want to see error
1948: * frames in Monitor mode.
1949: */
1950: #ifdef ERROR_FRAMES
1951: if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1952: /* XXX statistic */
1953: goto rx_next;
1954: }
1955: #endif
1956: /* fall thru for monitor mode handling... */
1957:
1958: } else if (ds->ds_rxstat.rs_status != 0) {
1959: if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC)
1960: sc->sc_stats.ast_rx_crcerr++;
1961: if (ds->ds_rxstat.rs_status & HAL_RXERR_FIFO)
1962: sc->sc_stats.ast_rx_fifoerr++;
1963: if (ds->ds_rxstat.rs_status & HAL_RXERR_DECRYPT)
1964: sc->sc_stats.ast_rx_badcrypt++;
1965: if (ds->ds_rxstat.rs_status & HAL_RXERR_PHY) {
1966: sc->sc_stats.ast_rx_phyerr++;
1967: phyerr = ds->ds_rxstat.rs_phyerr & 0x1f;
1968: sc->sc_stats.ast_rx_phy[phyerr]++;
1969: }
1970:
1971: /*
1972: * reject error frames, we normally don't want
1973: * to see them in monitor mode.
1974: */
1975: if ((ds->ds_rxstat.rs_status & HAL_RXERR_DECRYPT ) ||
1976: (ds->ds_rxstat.rs_status & HAL_RXERR_PHY))
1977: goto rx_next;
1978:
1979: /*
1980: * In monitor mode, allow through packets that
1981: * cannot be decrypted
1982: */
1983: if ((ds->ds_rxstat.rs_status & ~HAL_RXERR_DECRYPT) ||
1984: sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
1985: goto rx_next;
1986: }
1987:
1988: len = ds->ds_rxstat.rs_datalen;
1989: if (len < IEEE80211_MIN_LEN) {
1990: DPRINTF(ATH_DEBUG_RECV, ("%s: short packet %d\n",
1991: __func__, len));
1992: sc->sc_stats.ast_rx_tooshort++;
1993: goto rx_next;
1994: }
1995:
1996: bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 0,
1997: bf->bf_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1998:
1999: bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
2000: bf->bf_m = NULL;
2001: m->m_pkthdr.rcvif = ifp;
2002: m->m_pkthdr.len = m->m_len = len;
2003:
2004: #if NBPFILTER > 0
2005: if (sc->sc_drvbpf) {
2006: struct mbuf mb;
2007:
2008: sc->sc_rxtap.wr_rate =
2009: sc->sc_hwmap[ds->ds_rxstat.rs_rate] &
2010: IEEE80211_RATE_VAL;
2011: sc->sc_rxtap.wr_antenna = ds->ds_rxstat.rs_antenna;
2012: sc->sc_rxtap.wr_rssi = ds->ds_rxstat.rs_rssi;
2013: sc->sc_rxtap.wr_max_rssi = ic->ic_max_rssi;
2014:
2015: mb.m_data = (caddr_t)&sc->sc_rxtap;
2016: mb.m_len = sc->sc_rxtap_len;
2017: mb.m_next = m;
2018: mb.m_nextpkt = NULL;
2019: mb.m_type = 0;
2020: mb.m_flags = 0;
2021: bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
2022: }
2023: #endif
2024:
2025: m_adj(m, -IEEE80211_CRC_LEN);
2026: wh = mtod(m, struct ieee80211_frame *);
2027: if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2028: /*
2029: * WEP is decrypted by hardware. Clear WEP bit
2030: * and trim WEP header for ieee80211_input().
2031: */
2032: wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
2033: bcopy(wh, &whbuf, sizeof(whbuf));
2034: m_adj(m, IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN);
2035: wh = mtod(m, struct ieee80211_frame *);
2036: bcopy(&whbuf, wh, sizeof(whbuf));
2037: /*
2038: * Also trim WEP ICV from the tail.
2039: */
2040: m_adj(m, -IEEE80211_WEP_CRCLEN);
2041: /*
2042: * The header has probably moved.
2043: */
2044: wh = mtod(m, struct ieee80211_frame *);
2045: }
2046:
2047: /*
2048: * Locate the node for sender, track state, and
2049: * then pass this node (referenced) up to the 802.11
2050: * layer for its use.
2051: */
2052: ni = ieee80211_find_rxnode(ic, wh);
2053:
2054: /*
2055: * Record driver-specific state.
2056: */
2057: an = ATH_NODE(ni);
2058: if (++(an->an_rx_hist_next) == ATH_RHIST_SIZE)
2059: an->an_rx_hist_next = 0;
2060: rh = &an->an_rx_hist[an->an_rx_hist_next];
2061: rh->arh_ticks = ATH_TICKS();
2062: rh->arh_rssi = ds->ds_rxstat.rs_rssi;
2063: rh->arh_antenna = ds->ds_rxstat.rs_antenna;
2064:
2065: /*
2066: * Send frame up for processing.
2067: */
2068: ieee80211_input(ifp, m, ni,
2069: ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp);
2070:
2071: /* Handle the rate adaption */
2072: ieee80211_rssadapt_input(ic, ni, &an->an_rssadapt,
2073: ds->ds_rxstat.rs_rssi);
2074:
2075: /*
2076: * The frame may have caused the node to be marked for
2077: * reclamation (e.g. in response to a DEAUTH message)
2078: * so use release_node here instead of unref_node.
2079: */
2080: ieee80211_release_node(ic, ni);
2081:
2082: rx_next:
2083: TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
2084: } while (ath_rxbuf_init(sc, bf) == 0);
2085:
2086: ath_hal_set_rx_signal(ah); /* rx signal state monitoring */
2087: ath_hal_start_rx(ah); /* in case of RXEOL */
2088:
2089: if ((ifp->if_flags & IFF_OACTIVE) == 0 && !IFQ_IS_EMPTY(&ifp->if_snd))
2090: ath_start(ifp);
2091: #undef PA2DESC
2092: }
2093:
2094: /*
2095: * XXX Size of an ACK control frame in bytes.
2096: */
2097: #define IEEE80211_ACK_SIZE (2+2+IEEE80211_ADDR_LEN+4)
2098:
2099: int
2100: ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni,
2101: struct ath_buf *bf, struct mbuf *m0)
2102: {
2103: struct ieee80211com *ic = &sc->sc_ic;
2104: struct ath_hal *ah = sc->sc_ah;
2105: struct ifnet *ifp = &sc->sc_ic.ic_if;
2106: int i, error, iswep, hdrlen, pktlen, len, s;
2107: u_int8_t rix, cix, txrate, ctsrate;
2108: struct ath_desc *ds;
2109: struct mbuf *m;
2110: struct ieee80211_frame *wh;
2111: u_int32_t iv;
2112: u_int8_t *ivp;
2113: u_int8_t hdrbuf[sizeof(struct ieee80211_frame) +
2114: IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN];
2115: u_int subtype, flags, ctsduration, antenna;
2116: HAL_PKT_TYPE atype;
2117: const HAL_RATE_TABLE *rt;
2118: HAL_BOOL shortPreamble;
2119: struct ath_node *an;
2120: u_int8_t hwqueue = HAL_TX_QUEUE_ID_DATA_MIN;
2121:
2122: wh = mtod(m0, struct ieee80211_frame *);
2123: iswep = wh->i_fc[1] & IEEE80211_FC1_WEP;
2124: hdrlen = sizeof(struct ieee80211_frame);
2125: pktlen = m0->m_pkthdr.len;
2126:
2127: if (iswep) {
2128: bcopy(mtod(m0, caddr_t), hdrbuf, hdrlen);
2129: m_adj(m0, hdrlen);
2130: M_PREPEND(m0, sizeof(hdrbuf), M_DONTWAIT);
2131: if (m0 == NULL) {
2132: sc->sc_stats.ast_tx_nombuf++;
2133: return ENOMEM;
2134: }
2135: ivp = hdrbuf + hdrlen;
2136: wh = mtod(m0, struct ieee80211_frame *);
2137: /*
2138: * XXX
2139: * IV must not duplicate during the lifetime of the key.
2140: * But no mechanism to renew keys is defined in IEEE 802.11
2141: * for WEP. And the IV may be duplicated at other stations
2142: * because the session key itself is shared. So we use a
2143: * pseudo random IV for now, though it is not the right way.
2144: *
2145: * NB: Rather than use a strictly random IV we select a
2146: * random one to start and then increment the value for
2147: * each frame. This is an explicit tradeoff between
2148: * overhead and security. Given the basic insecurity of
2149: * WEP this seems worthwhile.
2150: */
2151:
2152: /*
2153: * Skip 'bad' IVs from Fluhrer/Mantin/Shamir:
2154: * (B, 255, N) with 3 <= B < 16 and 0 <= N <= 255
2155: */
2156: iv = ic->ic_iv;
2157: if ((iv & 0xff00) == 0xff00) {
2158: int B = (iv & 0xff0000) >> 16;
2159: if (3 <= B && B < 16)
2160: iv = (B+1) << 16;
2161: }
2162: ic->ic_iv = iv + 1;
2163:
2164: /*
2165: * NB: Preserve byte order of IV for packet
2166: * sniffers; it doesn't matter otherwise.
2167: */
2168: #if AH_BYTE_ORDER == AH_BIG_ENDIAN
2169: ivp[0] = iv >> 0;
2170: ivp[1] = iv >> 8;
2171: ivp[2] = iv >> 16;
2172: #else
2173: ivp[2] = iv >> 0;
2174: ivp[1] = iv >> 8;
2175: ivp[0] = iv >> 16;
2176: #endif
2177: ivp[3] = ic->ic_wep_txkey << 6; /* Key ID and pad */
2178: bcopy(hdrbuf, mtod(m0, caddr_t), sizeof(hdrbuf));
2179: /*
2180: * The length of hdrlen and pktlen must be increased for WEP
2181: */
2182: len = IEEE80211_WEP_IVLEN +
2183: IEEE80211_WEP_KIDLEN +
2184: IEEE80211_WEP_CRCLEN;
2185: hdrlen += len;
2186: pktlen += len;
2187: }
2188: pktlen += IEEE80211_CRC_LEN;
2189:
2190: /*
2191: * Load the DMA map so any coalescing is done. This
2192: * also calculates the number of descriptors we need.
2193: */
2194: error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_dmamap, m0,
2195: BUS_DMA_NOWAIT);
2196: /*
2197: * Discard null packets and check for packets that
2198: * require too many TX descriptors. We try to convert
2199: * the latter to a cluster.
2200: */
2201: if (error == EFBIG) { /* too many desc's, linearize */
2202: sc->sc_stats.ast_tx_linear++;
2203: MGETHDR(m, M_DONTWAIT, MT_DATA);
2204: if (m == NULL) {
2205: sc->sc_stats.ast_tx_nombuf++;
2206: m_freem(m0);
2207: return ENOMEM;
2208: }
2209:
2210: M_DUP_PKTHDR(m, m0);
2211: MCLGET(m, M_DONTWAIT);
2212: if ((m->m_flags & M_EXT) == 0) {
2213: sc->sc_stats.ast_tx_nomcl++;
2214: m_freem(m0);
2215: m_free(m);
2216: return ENOMEM;
2217: }
2218: m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
2219: m_freem(m0);
2220: m->m_len = m->m_pkthdr.len;
2221: m0 = m;
2222: error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_dmamap, m0,
2223: BUS_DMA_NOWAIT);
2224: if (error != 0) {
2225: sc->sc_stats.ast_tx_busdma++;
2226: m_freem(m0);
2227: return error;
2228: }
2229: KASSERT(bf->bf_nseg == 1,
2230: ("ath_tx_start: packet not one segment; nseg %u",
2231: bf->bf_nseg));
2232: } else if (error != 0) {
2233: sc->sc_stats.ast_tx_busdma++;
2234: m_freem(m0);
2235: return error;
2236: } else if (bf->bf_nseg == 0) { /* null packet, discard */
2237: sc->sc_stats.ast_tx_nodata++;
2238: m_freem(m0);
2239: return EIO;
2240: }
2241: DPRINTF(ATH_DEBUG_XMIT, ("%s: m %p len %u\n", __func__, m0, pktlen));
2242: bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 0,
2243: bf->bf_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
2244: bf->bf_m = m0;
2245: bf->bf_node = ni; /* NB: held reference */
2246: an = ATH_NODE(ni);
2247:
2248: /* setup descriptors */
2249: ds = bf->bf_desc;
2250: rt = sc->sc_currates;
2251: KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
2252:
2253: /*
2254: * Calculate Atheros packet type from IEEE80211 packet header
2255: * and setup for rate calculations.
2256: */
2257: bf->bf_id.id_node = NULL;
2258: atype = HAL_PKT_TYPE_NORMAL; /* default */
2259: switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
2260: case IEEE80211_FC0_TYPE_MGT:
2261: subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
2262: if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
2263: atype = HAL_PKT_TYPE_BEACON;
2264: } else if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
2265: atype = HAL_PKT_TYPE_PROBE_RESP;
2266: } else if (subtype == IEEE80211_FC0_SUBTYPE_ATIM) {
2267: atype = HAL_PKT_TYPE_ATIM;
2268: }
2269: rix = 0; /* XXX lowest rate */
2270: break;
2271: case IEEE80211_FC0_TYPE_CTL:
2272: subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
2273: if (subtype == IEEE80211_FC0_SUBTYPE_PS_POLL)
2274: atype = HAL_PKT_TYPE_PSPOLL;
2275: rix = 0; /* XXX lowest rate */
2276: break;
2277: default:
2278: /* remember link conditions for rate adaptation algorithm */
2279: if (ic->ic_fixed_rate == -1) {
2280: bf->bf_id.id_len = m0->m_pkthdr.len;
2281: bf->bf_id.id_rateidx = ni->ni_txrate;
2282: bf->bf_id.id_node = ni;
2283: bf->bf_id.id_rssi = ath_node_getrssi(ic, ni);
2284: }
2285: ni->ni_txrate = ieee80211_rssadapt_choose(&an->an_rssadapt,
2286: &ni->ni_rates, wh, m0->m_pkthdr.len, ic->ic_fixed_rate,
2287: ifp->if_xname, 0);
2288: rix = sc->sc_rixmap[ni->ni_rates.rs_rates[ni->ni_txrate] &
2289: IEEE80211_RATE_VAL];
2290: if (rix == 0xff) {
2291: printf("%s: bogus xmit rate 0x%x (idx 0x%x)\n",
2292: ifp->if_xname, ni->ni_rates.rs_rates[ni->ni_txrate],
2293: ni->ni_txrate);
2294: sc->sc_stats.ast_tx_badrate++;
2295: m_freem(m0);
2296: return EIO;
2297: }
2298: break;
2299: }
2300:
2301: /*
2302: * NB: the 802.11 layer marks whether or not we should
2303: * use short preamble based on the current mode and
2304: * negotiated parameters.
2305: */
2306: if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
2307: (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
2308: txrate = rt->info[rix].rateCode | rt->info[rix].shortPreamble;
2309: shortPreamble = AH_TRUE;
2310: sc->sc_stats.ast_tx_shortpre++;
2311: } else {
2312: txrate = rt->info[rix].rateCode;
2313: shortPreamble = AH_FALSE;
2314: }
2315:
2316: /*
2317: * Calculate miscellaneous flags.
2318: */
2319: flags = HAL_TXDESC_CLRDMASK; /* XXX needed for wep errors */
2320: if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2321: flags |= HAL_TXDESC_NOACK; /* no ack on broad/multicast */
2322: sc->sc_stats.ast_tx_noack++;
2323: } else if (pktlen > ic->ic_rtsthreshold) {
2324: flags |= HAL_TXDESC_RTSENA; /* RTS based on frame length */
2325: sc->sc_stats.ast_tx_rts++;
2326: }
2327:
2328: /*
2329: * Calculate duration. This logically belongs in the 802.11
2330: * layer but it lacks sufficient information to calculate it.
2331: */
2332: if ((flags & HAL_TXDESC_NOACK) == 0 &&
2333: (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL) {
2334: u_int16_t dur;
2335: /*
2336: * XXX not right with fragmentation.
2337: */
2338: dur = ath_hal_computetxtime(ah, rt, IEEE80211_ACK_SIZE,
2339: rix, shortPreamble);
2340: *((u_int16_t*) wh->i_dur) = htole16(dur);
2341: }
2342:
2343: /*
2344: * Calculate RTS/CTS rate and duration if needed.
2345: */
2346: ctsduration = 0;
2347: if (flags & (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)) {
2348: /*
2349: * CTS transmit rate is derived from the transmit rate
2350: * by looking in the h/w rate table. We must also factor
2351: * in whether or not a short preamble is to be used.
2352: */
2353: cix = rt->info[rix].controlRate;
2354: ctsrate = rt->info[cix].rateCode;
2355: if (shortPreamble)
2356: ctsrate |= rt->info[cix].shortPreamble;
2357: /*
2358: * Compute the transmit duration based on the size
2359: * of an ACK frame. We call into the HAL to do the
2360: * computation since it depends on the characteristics
2361: * of the actual PHY being used.
2362: */
2363: if (flags & HAL_TXDESC_RTSENA) { /* SIFS + CTS */
2364: ctsduration += ath_hal_computetxtime(ah,
2365: rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
2366: }
2367: /* SIFS + data */
2368: ctsduration += ath_hal_computetxtime(ah,
2369: rt, pktlen, rix, shortPreamble);
2370: if ((flags & HAL_TXDESC_NOACK) == 0) { /* SIFS + ACK */
2371: ctsduration += ath_hal_computetxtime(ah,
2372: rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
2373: }
2374: } else
2375: ctsrate = 0;
2376:
2377: /*
2378: * For now use the antenna on which the last good
2379: * frame was received on. We assume this field is
2380: * initialized to 0 which gives us ``auto'' or the
2381: * ``default'' antenna.
2382: */
2383: if (an->an_tx_antenna) {
2384: antenna = an->an_tx_antenna;
2385: } else {
2386: antenna = an->an_rx_hist[an->an_rx_hist_next].arh_antenna;
2387: }
2388:
2389: #if NBPFILTER > 0
2390: if (ic->ic_rawbpf)
2391: bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
2392:
2393: if (sc->sc_drvbpf) {
2394: struct mbuf mb;
2395:
2396: sc->sc_txtap.wt_flags = 0;
2397: if (shortPreamble)
2398: sc->sc_txtap.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
2399: if (iswep)
2400: sc->sc_txtap.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2401: sc->sc_txtap.wt_rate = ni->ni_rates.rs_rates[ni->ni_txrate] &
2402: IEEE80211_RATE_VAL;
2403: sc->sc_txtap.wt_txpower = 30;
2404: sc->sc_txtap.wt_antenna = antenna;
2405: sc->sc_txtap.wt_hwqueue = hwqueue;
2406:
2407: mb.m_data = (caddr_t)&sc->sc_txtap;
2408: mb.m_len = sc->sc_txtap_len;
2409: mb.m_next = m0;
2410: mb.m_nextpkt = NULL;
2411: mb.m_type = 0;
2412: mb.m_flags = 0;
2413: bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
2414: }
2415: #endif
2416:
2417: /*
2418: * Formulate first tx descriptor with tx controls.
2419: */
2420: /* XXX check return value? */
2421: ath_hal_setup_tx_desc(ah, ds
2422: , pktlen /* packet length */
2423: , hdrlen /* header length */
2424: , atype /* Atheros packet type */
2425: , 60 /* txpower XXX */
2426: , txrate, 1+10 /* series 0 rate/tries */
2427: , iswep ? sc->sc_ic.ic_wep_txkey : HAL_TXKEYIX_INVALID
2428: , antenna /* antenna mode */
2429: , flags /* flags */
2430: , ctsrate /* rts/cts rate */
2431: , ctsduration /* rts/cts duration */
2432: );
2433: #ifdef notyet
2434: ath_hal_setup_xtx_desc(ah, ds
2435: , AH_FALSE /* short preamble */
2436: , 0, 0 /* series 1 rate/tries */
2437: , 0, 0 /* series 2 rate/tries */
2438: , 0, 0 /* series 3 rate/tries */
2439: );
2440: #endif
2441: /*
2442: * Fillin the remainder of the descriptor info.
2443: */
2444: for (i = 0; i < bf->bf_nseg; i++, ds++) {
2445: ds->ds_data = bf->bf_segs[i].ds_addr;
2446: if (i == bf->bf_nseg - 1) {
2447: ds->ds_link = 0;
2448: } else {
2449: ds->ds_link = bf->bf_daddr + sizeof(*ds) * (i + 1);
2450: }
2451: ath_hal_fill_tx_desc(ah, ds
2452: , bf->bf_segs[i].ds_len /* segment length */
2453: , i == 0 /* first segment */
2454: , i == bf->bf_nseg - 1 /* last segment */
2455: );
2456: DPRINTF(ATH_DEBUG_XMIT,
2457: ("%s: %d: %08x %08x %08x %08x %08x %08x\n",
2458: __func__, i, ds->ds_link, ds->ds_data,
2459: ds->ds_ctl0, ds->ds_ctl1, ds->ds_hw[0], ds->ds_hw[1]));
2460: }
2461:
2462: /*
2463: * Insert the frame on the outbound list and
2464: * pass it on to the hardware.
2465: */
2466: s = splnet();
2467: TAILQ_INSERT_TAIL(&sc->sc_txq, bf, bf_list);
2468: if (sc->sc_txlink == NULL) {
2469: ath_hal_put_tx_buf(ah, sc->sc_txhalq[hwqueue], bf->bf_daddr);
2470: DPRINTF(ATH_DEBUG_XMIT, ("%s: TXDP0 = %p (%p)\n", __func__,
2471: (caddr_t)bf->bf_daddr, bf->bf_desc));
2472: } else {
2473: *sc->sc_txlink = bf->bf_daddr;
2474: DPRINTF(ATH_DEBUG_XMIT, ("%s: link(%p)=%p (%p)\n", __func__,
2475: sc->sc_txlink, (caddr_t)bf->bf_daddr, bf->bf_desc));
2476: }
2477: sc->sc_txlink = &bf->bf_desc[bf->bf_nseg - 1].ds_link;
2478: splx(s);
2479:
2480: ath_hal_tx_start(ah, sc->sc_txhalq[hwqueue]);
2481: return 0;
2482: }
2483:
2484: void
2485: ath_tx_proc(void *arg, int npending)
2486: {
2487: struct ath_softc *sc = arg;
2488: struct ath_hal *ah = sc->sc_ah;
2489: struct ath_buf *bf;
2490: struct ieee80211com *ic = &sc->sc_ic;
2491: struct ifnet *ifp = &ic->ic_if;
2492: struct ath_desc *ds;
2493: struct ieee80211_node *ni;
2494: struct ath_node *an;
2495: int sr, lr, s;
2496: HAL_STATUS status;
2497:
2498: for (;;) {
2499: s = splnet();
2500: bf = TAILQ_FIRST(&sc->sc_txq);
2501: if (bf == NULL) {
2502: sc->sc_txlink = NULL;
2503: splx(s);
2504: break;
2505: }
2506: /* only the last descriptor is needed */
2507: ds = &bf->bf_desc[bf->bf_nseg - 1];
2508: status = ath_hal_proc_tx_desc(ah, ds);
2509: #ifdef AR_DEBUG
2510: if (ath_debug & ATH_DEBUG_XMIT_DESC)
2511: ath_printtxbuf(bf, status == HAL_OK);
2512: #endif
2513: if (status == HAL_EINPROGRESS) {
2514: splx(s);
2515: break;
2516: }
2517: TAILQ_REMOVE(&sc->sc_txq, bf, bf_list);
2518: splx(s);
2519:
2520: ni = bf->bf_node;
2521: if (ni != NULL) {
2522: an = (struct ath_node *) ni;
2523: if (ds->ds_txstat.ts_status == 0) {
2524: if (bf->bf_id.id_node != NULL)
2525: ieee80211_rssadapt_raise_rate(ic,
2526: &an->an_rssadapt, &bf->bf_id);
2527: an->an_tx_antenna = ds->ds_txstat.ts_antenna;
2528: } else {
2529: if (bf->bf_id.id_node != NULL)
2530: ieee80211_rssadapt_lower_rate(ic, ni,
2531: &an->an_rssadapt, &bf->bf_id);
2532: ifp->if_oerrors++;
2533: if (ds->ds_txstat.ts_status & HAL_TXERR_XRETRY)
2534: sc->sc_stats.ast_tx_xretries++;
2535: if (ds->ds_txstat.ts_status & HAL_TXERR_FIFO)
2536: sc->sc_stats.ast_tx_fifoerr++;
2537: if (ds->ds_txstat.ts_status & HAL_TXERR_FILT)
2538: sc->sc_stats.ast_tx_filtered++;
2539: an->an_tx_antenna = 0; /* invalidate */
2540: }
2541: sr = ds->ds_txstat.ts_shortretry;
2542: lr = ds->ds_txstat.ts_longretry;
2543: sc->sc_stats.ast_tx_shortretry += sr;
2544: sc->sc_stats.ast_tx_longretry += lr;
2545: /*
2546: * Reclaim reference to node.
2547: *
2548: * NB: the node may be reclaimed here if, for example
2549: * this is a DEAUTH message that was sent and the
2550: * node was timed out due to inactivity.
2551: */
2552: ieee80211_release_node(ic, ni);
2553: }
2554: bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 0,
2555: bf->bf_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
2556: bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
2557: m_freem(bf->bf_m);
2558: bf->bf_m = NULL;
2559: bf->bf_node = NULL;
2560:
2561: s = splnet();
2562: TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
2563: splx(s);
2564: }
2565: ifp->if_flags &= ~IFF_OACTIVE;
2566: sc->sc_tx_timer = 0;
2567:
2568: ath_start(ifp);
2569: }
2570:
2571: /*
2572: * Drain the transmit queue and reclaim resources.
2573: */
2574: void
2575: ath_draintxq(struct ath_softc *sc)
2576: {
2577: struct ath_hal *ah = sc->sc_ah;
2578: struct ieee80211com *ic = &sc->sc_ic;
2579: struct ifnet *ifp = &ic->ic_if;
2580: struct ieee80211_node *ni;
2581: struct ath_buf *bf;
2582: int s, i;
2583:
2584: /* XXX return value */
2585: if (!sc->sc_invalid) {
2586: for (i = 0; i <= HAL_TX_QUEUE_ID_DATA_MAX; i++) {
2587: /* don't touch the hardware if marked invalid */
2588: (void) ath_hal_stop_tx_dma(ah, sc->sc_txhalq[i]);
2589: DPRINTF(ATH_DEBUG_RESET,
2590: ("%s: tx queue %d (%p), link %p\n", __func__, i,
2591: (caddr_t)(u_intptr_t)ath_hal_get_tx_buf(ah,
2592: sc->sc_txhalq[i]), sc->sc_txlink));
2593: }
2594: (void) ath_hal_stop_tx_dma(ah, sc->sc_bhalq);
2595: DPRINTF(ATH_DEBUG_RESET,
2596: ("%s: beacon queue (%p)\n", __func__,
2597: (caddr_t)(u_intptr_t)ath_hal_get_tx_buf(ah, sc->sc_bhalq)));
2598: }
2599: for (;;) {
2600: s = splnet();
2601: bf = TAILQ_FIRST(&sc->sc_txq);
2602: if (bf == NULL) {
2603: sc->sc_txlink = NULL;
2604: splx(s);
2605: break;
2606: }
2607: TAILQ_REMOVE(&sc->sc_txq, bf, bf_list);
2608: splx(s);
2609: #ifdef AR_DEBUG
2610: if (ath_debug & ATH_DEBUG_RESET) {
2611: ath_printtxbuf(bf,
2612: ath_hal_proc_tx_desc(ah, bf->bf_desc) == HAL_OK);
2613: }
2614: #endif /* AR_DEBUG */
2615: bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
2616: m_freem(bf->bf_m);
2617: bf->bf_m = NULL;
2618: ni = bf->bf_node;
2619: bf->bf_node = NULL;
2620: s = splnet();
2621: if (ni != NULL) {
2622: /*
2623: * Reclaim node reference.
2624: */
2625: ieee80211_release_node(ic, ni);
2626: }
2627: TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
2628: splx(s);
2629: }
2630: ifp->if_flags &= ~IFF_OACTIVE;
2631: sc->sc_tx_timer = 0;
2632: }
2633:
2634: /*
2635: * Disable the receive h/w in preparation for a reset.
2636: */
2637: void
2638: ath_stoprecv(struct ath_softc *sc)
2639: {
2640: #define PA2DESC(_sc, _pa) \
2641: ((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \
2642: ((_pa) - (_sc)->sc_desc_paddr)))
2643: struct ath_hal *ah = sc->sc_ah;
2644:
2645: ath_hal_stop_pcu_recv(ah); /* disable PCU */
2646: ath_hal_set_rx_filter(ah, 0); /* clear recv filter */
2647: ath_hal_stop_rx_dma(ah); /* disable DMA engine */
2648: #ifdef AR_DEBUG
2649: if (ath_debug & ATH_DEBUG_RESET) {
2650: struct ath_buf *bf;
2651:
2652: printf("%s: rx queue %p, link %p\n", __func__,
2653: (caddr_t)(u_intptr_t)ath_hal_get_rx_buf(ah), sc->sc_rxlink);
2654: TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
2655: struct ath_desc *ds = bf->bf_desc;
2656: if (ath_hal_proc_rx_desc(ah, ds, bf->bf_daddr,
2657: PA2DESC(sc, ds->ds_link)) == HAL_OK)
2658: ath_printrxbuf(bf, 1);
2659: }
2660: }
2661: #endif
2662: sc->sc_rxlink = NULL; /* just in case */
2663: #undef PA2DESC
2664: }
2665:
2666: /*
2667: * Enable the receive h/w following a reset.
2668: */
2669: int
2670: ath_startrecv(struct ath_softc *sc)
2671: {
2672: struct ath_hal *ah = sc->sc_ah;
2673: struct ath_buf *bf;
2674:
2675: sc->sc_rxlink = NULL;
2676: TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
2677: int error = ath_rxbuf_init(sc, bf);
2678: if (error != 0) {
2679: DPRINTF(ATH_DEBUG_RECV,
2680: ("%s: ath_rxbuf_init failed %d\n",
2681: __func__, error));
2682: return error;
2683: }
2684: }
2685:
2686: bf = TAILQ_FIRST(&sc->sc_rxbuf);
2687: ath_hal_put_rx_buf(ah, bf->bf_daddr);
2688: ath_hal_start_rx(ah); /* enable recv descriptors */
2689: ath_mode_init(sc); /* set filters, etc. */
2690: ath_hal_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
2691: return 0;
2692: }
2693:
2694: /*
2695: * Set/change channels. If the channel is really being changed,
2696: * it's done by resetting the chip. To accomplish this we must
2697: * first cleanup any pending DMA, then restart stuff after a la
2698: * ath_init.
2699: */
2700: int
2701: ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
2702: {
2703: struct ath_hal *ah = sc->sc_ah;
2704: struct ieee80211com *ic = &sc->sc_ic;
2705: struct ifnet *ifp = &ic->ic_if;
2706:
2707: DPRINTF(ATH_DEBUG_ANY, ("%s: %u (%u MHz) -> %u (%u MHz)\n", __func__,
2708: ieee80211_chan2ieee(ic, ic->ic_ibss_chan),
2709: ic->ic_ibss_chan->ic_freq,
2710: ieee80211_chan2ieee(ic, chan), chan->ic_freq));
2711: if (chan != ic->ic_ibss_chan) {
2712: HAL_STATUS status;
2713: HAL_CHANNEL hchan;
2714: enum ieee80211_phymode mode;
2715:
2716: /*
2717: * To switch channels clear any pending DMA operations;
2718: * wait long enough for the RX fifo to drain, reset the
2719: * hardware at the new frequency, and then re-enable
2720: * the relevant bits of the h/w.
2721: */
2722: ath_hal_set_intr(ah, 0); /* disable interrupts */
2723: ath_draintxq(sc); /* clear pending tx frames */
2724: ath_stoprecv(sc); /* turn off frame recv */
2725: /*
2726: * Convert to a HAL channel description with
2727: * the flags constrained to reflect the current
2728: * operating mode.
2729: */
2730: hchan.channel = chan->ic_freq;
2731: hchan.channelFlags = ath_chan2flags(ic, chan);
2732: if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE,
2733: &status)) {
2734: printf("%s: ath_chan_set: unable to reset "
2735: "channel %u (%u MHz)\n", ifp->if_xname,
2736: ieee80211_chan2ieee(ic, chan), chan->ic_freq);
2737: return EIO;
2738: }
2739: ath_set_slot_time(sc);
2740: /*
2741: * Re-enable rx framework.
2742: */
2743: if (ath_startrecv(sc) != 0) {
2744: printf("%s: ath_chan_set: unable to restart recv "
2745: "logic\n", ifp->if_xname);
2746: return EIO;
2747: }
2748:
2749: #if NBPFILTER > 0
2750: /*
2751: * Update BPF state.
2752: */
2753: sc->sc_txtap.wt_chan_freq = sc->sc_rxtap.wr_chan_freq =
2754: htole16(chan->ic_freq);
2755: sc->sc_txtap.wt_chan_flags = sc->sc_rxtap.wr_chan_flags =
2756: htole16(chan->ic_flags);
2757: #endif
2758:
2759: /*
2760: * Change channels and update the h/w rate map
2761: * if we're switching; e.g. 11a to 11b/g.
2762: */
2763: ic->ic_ibss_chan = chan;
2764: mode = ieee80211_chan2mode(ic, chan);
2765: if (mode != sc->sc_curmode)
2766: ath_setcurmode(sc, mode);
2767:
2768: /*
2769: * Re-enable interrupts.
2770: */
2771: ath_hal_set_intr(ah, sc->sc_imask);
2772: }
2773: return 0;
2774: }
2775:
2776: void
2777: ath_next_scan(void *arg)
2778: {
2779: struct ath_softc *sc = arg;
2780: struct ieee80211com *ic = &sc->sc_ic;
2781: struct ifnet *ifp = &ic->ic_if;
2782: int s;
2783:
2784: /* don't call ath_start w/o network interrupts blocked */
2785: s = splnet();
2786:
2787: if (ic->ic_state == IEEE80211_S_SCAN)
2788: ieee80211_next_scan(ifp);
2789: splx(s);
2790: }
2791:
2792: int
2793: ath_set_slot_time(struct ath_softc *sc)
2794: {
2795: struct ath_hal *ah = sc->sc_ah;
2796: struct ieee80211com *ic = &sc->sc_ic;
2797:
2798: if (ic->ic_flags & IEEE80211_F_SHSLOT)
2799: return (ath_hal_set_slot_time(ah, HAL_SLOT_TIME_9));
2800:
2801: return (0);
2802: }
2803:
2804: /*
2805: * Periodically recalibrate the PHY to account
2806: * for temperature/environment changes.
2807: */
2808: void
2809: ath_calibrate(void *arg)
2810: {
2811: struct ath_softc *sc = arg;
2812: struct ath_hal *ah = sc->sc_ah;
2813: struct ieee80211com *ic = &sc->sc_ic;
2814: struct ieee80211_channel *c;
2815: HAL_CHANNEL hchan;
2816: int s;
2817:
2818: sc->sc_stats.ast_per_cal++;
2819:
2820: /*
2821: * Convert to a HAL channel description with the flags
2822: * constrained to reflect the current operating mode.
2823: */
2824: c = ic->ic_ibss_chan;
2825: hchan.channel = c->ic_freq;
2826: hchan.channelFlags = ath_chan2flags(ic, c);
2827:
2828: s = splnet();
2829: DPRINTF(ATH_DEBUG_CALIBRATE,
2830: ("%s: channel %u/%x\n", __func__, c->ic_freq, c->ic_flags));
2831:
2832: if (ath_hal_get_rf_gain(ah) == HAL_RFGAIN_NEED_CHANGE) {
2833: /*
2834: * Rfgain is out of bounds, reset the chip
2835: * to load new gain values.
2836: */
2837: sc->sc_stats.ast_per_rfgain++;
2838: ath_reset(sc, 1);
2839: }
2840: if (!ath_hal_calibrate(ah, &hchan)) {
2841: DPRINTF(ATH_DEBUG_ANY,
2842: ("%s: calibration of channel %u failed\n",
2843: __func__, c->ic_freq));
2844: sc->sc_stats.ast_per_calfail++;
2845: }
2846: timeout_add(&sc->sc_cal_to, hz * ath_calinterval);
2847: splx(s);
2848: }
2849:
2850: void
2851: ath_ledstate(struct ath_softc *sc, enum ieee80211_state state)
2852: {
2853: HAL_LED_STATE led = HAL_LED_INIT;
2854: u_int32_t softled = AR5K_SOFTLED_OFF;
2855:
2856: switch (state) {
2857: case IEEE80211_S_INIT:
2858: break;
2859: case IEEE80211_S_SCAN:
2860: led = HAL_LED_SCAN;
2861: break;
2862: case IEEE80211_S_AUTH:
2863: led = HAL_LED_AUTH;
2864: break;
2865: case IEEE80211_S_ASSOC:
2866: led = HAL_LED_ASSOC;
2867: softled = AR5K_SOFTLED_ON;
2868: break;
2869: case IEEE80211_S_RUN:
2870: led = HAL_LED_RUN;
2871: softled = AR5K_SOFTLED_ON;
2872: break;
2873: }
2874:
2875: ath_hal_set_ledstate(sc->sc_ah, led);
2876: if (sc->sc_softled) {
2877: ath_hal_set_gpio_output(sc->sc_ah, AR5K_SOFTLED_PIN);
2878: ath_hal_set_gpio(sc->sc_ah, AR5K_SOFTLED_PIN, softled);
2879: }
2880: }
2881:
2882: int
2883: ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
2884: {
2885: struct ifnet *ifp = &ic->ic_if;
2886: struct ath_softc *sc = ifp->if_softc;
2887: struct ath_hal *ah = sc->sc_ah;
2888: struct ieee80211_node *ni;
2889: const u_int8_t *bssid;
2890: int i, error;
2891: u_int32_t rfilt;
2892:
2893: DPRINTF(ATH_DEBUG_ANY, ("%s: %s -> %s\n", __func__,
2894: ieee80211_state_name[ic->ic_state],
2895: ieee80211_state_name[nstate]));
2896:
2897: timeout_del(&sc->sc_scan_to);
2898: timeout_del(&sc->sc_cal_to);
2899: ath_ledstate(sc, nstate);
2900:
2901: if (nstate == IEEE80211_S_INIT) {
2902: timeout_del(&sc->sc_rssadapt_to);
2903: sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
2904: ath_hal_set_intr(ah, sc->sc_imask);
2905: return (*sc->sc_newstate)(ic, nstate, arg);
2906: }
2907: ni = ic->ic_bss;
2908: error = ath_chan_set(sc, ni->ni_chan);
2909: if (error != 0)
2910: goto bad;
2911: rfilt = ath_calcrxfilter(sc);
2912: if (nstate == IEEE80211_S_SCAN ||
2913: ic->ic_opmode == IEEE80211_M_MONITOR) {
2914: bssid = sc->sc_broadcast_addr;
2915: } else {
2916: bssid = ni->ni_bssid;
2917: }
2918: ath_hal_set_rx_filter(ah, rfilt);
2919: DPRINTF(ATH_DEBUG_ANY, ("%s: RX filter 0x%x bssid %s\n",
2920: __func__, rfilt, ether_sprintf((u_char*)bssid)));
2921:
2922: if (nstate == IEEE80211_S_RUN && ic->ic_opmode == IEEE80211_M_STA) {
2923: ath_hal_set_associd(ah, bssid, ni->ni_associd);
2924: } else {
2925: ath_hal_set_associd(ah, bssid, 0);
2926: }
2927:
2928: if (ic->ic_flags & IEEE80211_F_WEPON) {
2929: for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2930: if (ath_hal_is_key_valid(ah, i))
2931: ath_hal_set_key_lladdr(ah, i, bssid);
2932: }
2933: }
2934:
2935: if (ic->ic_opmode == IEEE80211_M_MONITOR) {
2936: /* nothing to do */
2937: } else if (nstate == IEEE80211_S_RUN) {
2938: DPRINTF(ATH_DEBUG_ANY, ("%s(RUN): "
2939: "ic_flags=0x%08x iv=%d bssid=%s "
2940: "capinfo=0x%04x chan=%d\n",
2941: __func__,
2942: ic->ic_flags,
2943: ni->ni_intval,
2944: ether_sprintf(ni->ni_bssid),
2945: ni->ni_capinfo,
2946: ieee80211_chan2ieee(ic, ni->ni_chan)));
2947:
2948: /*
2949: * Allocate and setup the beacon frame for AP or adhoc mode.
2950: */
2951: if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
2952: ic->ic_opmode == IEEE80211_M_IBSS) {
2953: error = ath_beacon_alloc(sc, ni);
2954: if (error != 0)
2955: goto bad;
2956: }
2957:
2958: /*
2959: * Configure the beacon and sleep timers.
2960: */
2961: ath_beacon_config(sc);
2962: } else {
2963: sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
2964: ath_hal_set_intr(ah, sc->sc_imask);
2965: }
2966:
2967: /*
2968: * Invoke the parent method to complete the work.
2969: */
2970: error = (*sc->sc_newstate)(ic, nstate, arg);
2971:
2972: if (nstate == IEEE80211_S_RUN) {
2973: /* start periodic recalibration timer */
2974: timeout_add(&sc->sc_cal_to, hz * ath_calinterval);
2975:
2976: if (ic->ic_opmode != IEEE80211_M_MONITOR)
2977: timeout_add(&sc->sc_rssadapt_to, hz / 10);
2978: } else if (nstate == IEEE80211_S_SCAN) {
2979: /* start ap/neighbor scan timer */
2980: timeout_add(&sc->sc_scan_to, (hz * ath_dwelltime) / 1000);
2981: }
2982: bad:
2983: return error;
2984: }
2985:
2986: void
2987: ath_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
2988: struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
2989: {
2990: struct ath_softc *sc = (struct ath_softc*)ic->ic_softc;
2991: struct ath_hal *ah = sc->sc_ah;
2992:
2993: (*sc->sc_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
2994:
2995: switch (subtype) {
2996: case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
2997: case IEEE80211_FC0_SUBTYPE_BEACON:
2998: if (ic->ic_opmode != IEEE80211_M_IBSS ||
2999: ic->ic_state != IEEE80211_S_RUN)
3000: break;
3001: if (ieee80211_ibss_merge(ic, ni, ath_hal_get_tsf64(ah)) ==
3002: ENETRESET)
3003: ath_hal_set_associd(ah, ic->ic_bss->ni_bssid, 0);
3004: break;
3005: default:
3006: break;
3007: }
3008: return;
3009: }
3010:
3011: /*
3012: * Setup driver-specific state for a newly associated node.
3013: * Note that we're called also on a re-associate, the isnew
3014: * param tells us if this is the first time or not.
3015: */
3016: void
3017: ath_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
3018: {
3019: if (ic->ic_opmode == IEEE80211_M_MONITOR)
3020: return;
3021: }
3022:
3023: int
3024: ath_getchannels(struct ath_softc *sc, HAL_BOOL outdoor, HAL_BOOL xchanmode)
3025: {
3026: struct ieee80211com *ic = &sc->sc_ic;
3027: struct ifnet *ifp = &ic->ic_if;
3028: struct ath_hal *ah = sc->sc_ah;
3029: HAL_CHANNEL *chans;
3030: int i, ix, nchan;
3031:
3032: sc->sc_nchan = 0;
3033: chans = malloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL),
3034: M_TEMP, M_NOWAIT);
3035: if (chans == NULL) {
3036: printf("%s: unable to allocate channel table\n", ifp->if_xname);
3037: return ENOMEM;
3038: }
3039: if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan,
3040: HAL_MODE_ALL, outdoor, xchanmode)) {
3041: printf("%s: unable to collect channel list from hal\n",
3042: ifp->if_xname);
3043: free(chans, M_TEMP);
3044: return EINVAL;
3045: }
3046:
3047: /*
3048: * Convert HAL channels to ieee80211 ones and insert
3049: * them in the table according to their channel number.
3050: */
3051: for (i = 0; i < nchan; i++) {
3052: HAL_CHANNEL *c = &chans[i];
3053: ix = ieee80211_mhz2ieee(c->channel, c->channelFlags);
3054: if (ix > IEEE80211_CHAN_MAX) {
3055: printf("%s: bad hal channel %u (%u/%x) ignored\n",
3056: ifp->if_xname, ix, c->channel, c->channelFlags);
3057: continue;
3058: }
3059: DPRINTF(ATH_DEBUG_ANY,
3060: ("%s: HAL channel %d/%d freq %d flags %#04x idx %d\n",
3061: sc->sc_dev.dv_xname, i, nchan, c->channel, c->channelFlags,
3062: ix));
3063: /* NB: flags are known to be compatible */
3064: if (ic->ic_channels[ix].ic_freq == 0) {
3065: ic->ic_channels[ix].ic_freq = c->channel;
3066: ic->ic_channels[ix].ic_flags = c->channelFlags;
3067: } else {
3068: /* channels overlap; e.g. 11g and 11b */
3069: ic->ic_channels[ix].ic_flags |= c->channelFlags;
3070: }
3071: /* count valid channels */
3072: sc->sc_nchan++;
3073: }
3074: free(chans, M_TEMP);
3075:
3076: if (sc->sc_nchan < 1) {
3077: printf("%s: no valid channels for regdomain %s(%u)\n",
3078: ifp->if_xname, ieee80211_regdomain2name(ah->ah_regdomain),
3079: ah->ah_regdomain);
3080: return ENOENT;
3081: }
3082:
3083: /* set an initial channel */
3084: ic->ic_ibss_chan = &ic->ic_channels[0];
3085:
3086: return 0;
3087: }
3088:
3089: int
3090: ath_rate_setup(struct ath_softc *sc, u_int mode)
3091: {
3092: struct ath_hal *ah = sc->sc_ah;
3093: struct ieee80211com *ic = &sc->sc_ic;
3094: const HAL_RATE_TABLE *rt;
3095: struct ieee80211_rateset *rs;
3096: int i, maxrates;
3097:
3098: switch (mode) {
3099: case IEEE80211_MODE_11A:
3100: sc->sc_rates[mode] = ath_hal_get_rate_table(ah, HAL_MODE_11A);
3101: break;
3102: case IEEE80211_MODE_11B:
3103: sc->sc_rates[mode] = ath_hal_get_rate_table(ah, HAL_MODE_11B);
3104: break;
3105: case IEEE80211_MODE_11G:
3106: sc->sc_rates[mode] = ath_hal_get_rate_table(ah, HAL_MODE_11G);
3107: break;
3108: case IEEE80211_MODE_TURBO:
3109: sc->sc_rates[mode] = ath_hal_get_rate_table(ah, HAL_MODE_TURBO);
3110: break;
3111: default:
3112: DPRINTF(ATH_DEBUG_ANY,
3113: ("%s: invalid mode %u\n", __func__, mode));
3114: return 0;
3115: }
3116: rt = sc->sc_rates[mode];
3117: if (rt == NULL)
3118: return 0;
3119: if (rt->rateCount > IEEE80211_RATE_MAXSIZE) {
3120: DPRINTF(ATH_DEBUG_ANY,
3121: ("%s: rate table too small (%u > %u)\n",
3122: __func__, rt->rateCount, IEEE80211_RATE_MAXSIZE));
3123: maxrates = IEEE80211_RATE_MAXSIZE;
3124: } else {
3125: maxrates = rt->rateCount;
3126: }
3127: rs = &ic->ic_sup_rates[mode];
3128: for (i = 0; i < maxrates; i++)
3129: rs->rs_rates[i] = rt->info[i].dot11Rate;
3130: rs->rs_nrates = maxrates;
3131: return 1;
3132: }
3133:
3134: void
3135: ath_setcurmode(struct ath_softc *sc, enum ieee80211_phymode mode)
3136: {
3137: const HAL_RATE_TABLE *rt;
3138: int i;
3139:
3140: memset(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap));
3141: rt = sc->sc_rates[mode];
3142: KASSERT(rt != NULL, ("no h/w rate set for phy mode %u", mode));
3143: for (i = 0; i < rt->rateCount; i++)
3144: sc->sc_rixmap[rt->info[i].dot11Rate & IEEE80211_RATE_VAL] = i;
3145: bzero(sc->sc_hwmap, sizeof(sc->sc_hwmap));
3146: for (i = 0; i < 32; i++)
3147: sc->sc_hwmap[i] = rt->info[rt->rateCodeToIndex[i]].dot11Rate;
3148: sc->sc_currates = rt;
3149: sc->sc_curmode = mode;
3150: }
3151:
3152: void
3153: ath_rssadapt_updatenode(void *arg, struct ieee80211_node *ni)
3154: {
3155: struct ath_node *an = ATH_NODE(ni);
3156:
3157: ieee80211_rssadapt_updatestats(&an->an_rssadapt);
3158: }
3159:
3160: void
3161: ath_rssadapt_updatestats(void *arg)
3162: {
3163: struct ath_softc *sc = (struct ath_softc *)arg;
3164: struct ieee80211com *ic = &sc->sc_ic;
3165:
3166: if (ic->ic_opmode == IEEE80211_M_STA) {
3167: ath_rssadapt_updatenode(arg, ic->ic_bss);
3168: } else {
3169: ieee80211_iterate_nodes(ic, ath_rssadapt_updatenode, arg);
3170: }
3171:
3172: timeout_add(&sc->sc_rssadapt_to, hz / 10);
3173: }
3174:
3175: #ifdef AR_DEBUG
3176: void
3177: ath_printrxbuf(struct ath_buf *bf, int done)
3178: {
3179: struct ath_desc *ds;
3180: int i;
3181:
3182: for (i = 0, ds = bf->bf_desc; i < bf->bf_nseg; i++, ds++) {
3183: printf("R%d (%p %p) %08x %08x %08x %08x %08x %08x %c\n",
3184: i, ds, (struct ath_desc *)bf->bf_daddr + i,
3185: ds->ds_link, ds->ds_data,
3186: ds->ds_ctl0, ds->ds_ctl1,
3187: ds->ds_hw[0], ds->ds_hw[1],
3188: !done ? ' ' : (ds->ds_rxstat.rs_status == 0) ? '*' : '!');
3189: }
3190: }
3191:
3192: void
3193: ath_printtxbuf(struct ath_buf *bf, int done)
3194: {
3195: struct ath_desc *ds;
3196: int i;
3197:
3198: for (i = 0, ds = bf->bf_desc; i < bf->bf_nseg; i++, ds++) {
3199: printf("T%d (%p %p) "
3200: "%08x %08x %08x %08x %08x %08x %08x %08x %c\n",
3201: i, ds, (struct ath_desc *)bf->bf_daddr + i,
3202: ds->ds_link, ds->ds_data,
3203: ds->ds_ctl0, ds->ds_ctl1,
3204: ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3],
3205: !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!');
3206: }
3207: }
3208: #endif /* AR_DEBUG */
3209:
3210: int
3211: ath_gpio_attach(struct ath_softc *sc, u_int16_t devid)
3212: {
3213: struct ath_hal *ah = sc->sc_ah;
3214: struct gpiobus_attach_args gba;
3215: int i;
3216:
3217: if (ah->ah_gpio_npins < 1)
3218: return 0;
3219:
3220: /* Initialize gpio pins array */
3221: for (i = 0; i < ah->ah_gpio_npins && i < AR5K_MAX_GPIO; i++) {
3222: sc->sc_gpio_pins[i].pin_num = i;
3223: sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT |
3224: GPIO_PIN_OUTPUT;
3225:
3226: /* Set pin mode to input */
3227: ath_hal_set_gpio_input(ah, i);
3228: sc->sc_gpio_pins[i].pin_flags = GPIO_PIN_INPUT;
3229:
3230: /* Get pin input */
3231: sc->sc_gpio_pins[i].pin_state = ath_hal_get_gpio(ah, i) ?
3232: GPIO_PIN_HIGH : GPIO_PIN_LOW;
3233: }
3234:
3235: /* Enable GPIO-controlled software LED if available */
3236: if ((ah->ah_version == AR5K_AR5211) ||
3237: (devid == PCI_PRODUCT_ATHEROS_AR5212_IBM)) {
3238: sc->sc_softled = 1;
3239: ath_hal_set_gpio_output(ah, AR5K_SOFTLED_PIN);
3240: ath_hal_set_gpio(ah, AR5K_SOFTLED_PIN, AR5K_SOFTLED_OFF);
3241: }
3242:
3243: /* Create gpio controller tag */
3244: sc->sc_gpio_gc.gp_cookie = sc;
3245: sc->sc_gpio_gc.gp_pin_read = ath_gpio_pin_read;
3246: sc->sc_gpio_gc.gp_pin_write = ath_gpio_pin_write;
3247: sc->sc_gpio_gc.gp_pin_ctl = ath_gpio_pin_ctl;
3248:
3249: gba.gba_name = "gpio";
3250: gba.gba_gc = &sc->sc_gpio_gc;
3251: gba.gba_pins = sc->sc_gpio_pins;
3252: gba.gba_npins = ah->ah_gpio_npins;
3253:
3254: #ifdef notyet
3255: #if NGPIO > 0
3256: if (config_found(&sc->sc_dev, &gba, gpiobus_print) == NULL)
3257: return (ENODEV);
3258: #endif
3259: #endif
3260:
3261: return (0);
3262: }
3263:
3264: int
3265: ath_gpio_pin_read(void *arg, int pin)
3266: {
3267: struct ath_softc *sc = arg;
3268: struct ath_hal *ah = sc->sc_ah;
3269: return (ath_hal_get_gpio(ah, pin) ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
3270: }
3271:
3272: void
3273: ath_gpio_pin_write(void *arg, int pin, int value)
3274: {
3275: struct ath_softc *sc = arg;
3276: struct ath_hal *ah = sc->sc_ah;
3277: ath_hal_set_gpio(ah, pin, value ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
3278: }
3279:
3280: void
3281: ath_gpio_pin_ctl(void *arg, int pin, int flags)
3282: {
3283: struct ath_softc *sc = arg;
3284: struct ath_hal *ah = sc->sc_ah;
3285:
3286: if (flags & GPIO_PIN_INPUT) {
3287: ath_hal_set_gpio_input(ah, pin);
3288: } else if (flags & GPIO_PIN_OUTPUT) {
3289: ath_hal_set_gpio_output(ah, pin);
3290: }
3291: }
CVSweb