1/*-
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
--- 14 unchanged lines hidden (view full) ---
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 190526 2009-03-29 17:59:14Z sam $");
32
33/*
34 * Driver for the Atheros Wireless LAN controller.
35 *
36 * This software is derived from work of Atsushi Onoe; his contribution
37 * is greatly appreciated.
38 */
39
40#include "opt_inet.h"
41#include "opt_ath.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/sysctl.h>
46#include <sys/mbuf.h>
47#include <sys/malloc.h>
48#include <sys/lock.h>
49#include <sys/mutex.h>
--- 15 unchanged lines hidden (view full) ---
65#include <net/if_media.h>
66#include <net/if_types.h>
67#include <net/if_arp.h>
68#include <net/ethernet.h>
69#include <net/if_llc.h>
70
71#include <net80211/ieee80211_var.h>
72#include <net80211/ieee80211_regdomain.h>
73#ifdef ATH_SUPPORT_TDMA
74#include <net80211/ieee80211_tdma.h>
75#endif
76
77#include <net/bpf.h>
78
79#ifdef INET
80#include <netinet/in.h>
81#include <netinet/if_ether.h>
--- 126 unchanged lines hidden (view full) ---
208static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
209
210static void ath_sysctlattach(struct ath_softc *);
211static int ath_raw_xmit(struct ieee80211_node *,
212 struct mbuf *, const struct ieee80211_bpf_params *);
213static void ath_bpfattach(struct ath_softc *);
214static void ath_announce(struct ath_softc *);
215
216#ifdef ATH_SUPPORT_TDMA
217static void ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt,
218 u_int32_t bintval);
219static void ath_tdma_bintvalsetup(struct ath_softc *sc,
220 const struct ieee80211_tdma_state *tdma);
221static void ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap);
222static void ath_tdma_update(struct ieee80211_node *ni,
223 const struct ieee80211_tdma_param *tdma, int);
224static void ath_tdma_beacon_send(struct ath_softc *sc,
--- 25 unchanged lines hidden (view full) ---
250#define TDMA_LPF(x, y, len) \
251 ((x != TDMA_DUMMY_MARKER) ? (((x) * ((len)-1) + (y)) / (len)) : (y))
252#define TDMA_SAMPLE(x, y) do { \
253 x = TDMA_LPF((x), TDMA_IN(y), TDMA_LPF_LEN); \
254} while (0)
255#define TDMA_EP_RND(x,mul) \
256 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
257#define TDMA_AVG(x) TDMA_EP_RND(x, TDMA_EP_MULTIPLIER)
258#endif /* ATH_SUPPORT_TDMA */
259
260SYSCTL_DECL(_hw_ath);
261
262/* XXX validate sysctl values */
263static int ath_longcalinterval = 30; /* long cals every 30 secs */
264SYSCTL_INT(_hw_ath, OID_AUTO, longcal, CTLFLAG_RW, &ath_longcalinterval,
265 0, "long chip calibration interval (secs)");
266static int ath_shortcalinterval = 100; /* short cals every 100 ms */
--- 386 unchanged lines hidden (view full) ---
653 ic->ic_caps |= IEEE80211_C_BURST;
654 sc->sc_hasbmask = ath_hal_hasbssidmask(ah);
655 sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);
656 if (ath_hal_hasfastframes(ah))
657 ic->ic_caps |= IEEE80211_C_FF;
658 wmodes = ath_hal_getwirelessmodes(ah);
659 if (wmodes & (HAL_MODE_108G|HAL_MODE_TURBO))
660 ic->ic_caps |= IEEE80211_C_TURBOP;
661#ifdef ATH_SUPPORT_TDMA
662 if (ath_hal_macversion(ah) > 0x78) {
663 ic->ic_caps |= IEEE80211_C_TDMA; /* capable of TDMA */
664 ic->ic_tdma_update = ath_tdma_update;
665 }
666#endif
667 /*
668 * Indicate we need the 802.11 header padded to a
669 * 32-bit boundary for 4-address and QoS frames.
--- 212 unchanged lines hidden (view full) ---
882 device_printf(sc->sc_dev,
883 "only 1 ibss vap supported\n");
884 goto bad;
885 }
886 ic_opmode = opmode;
887 needbeacon = 1;
888 break;
889 case IEEE80211_M_AHDEMO:
890#ifdef ATH_SUPPORT_TDMA
891 if (flags & IEEE80211_CLONE_TDMA) {
892 needbeacon = 1;
893 flags |= IEEE80211_CLONE_NOBEACONS;
894 }
895 /* fall thru... */
896#endif
897 case IEEE80211_M_MONITOR:
898 if (sc->sc_nvaps != 0 && ic->ic_opmode != opmode) {
--- 108 unchanged lines hidden (view full) ---
1007 switch (ic_opmode) {
1008 case IEEE80211_M_IBSS:
1009 sc->sc_opmode = HAL_M_IBSS;
1010 break;
1011 case IEEE80211_M_STA:
1012 sc->sc_opmode = HAL_M_STA;
1013 break;
1014 case IEEE80211_M_AHDEMO:
1015#ifdef ATH_SUPPORT_TDMA
1016 if (vap->iv_caps & IEEE80211_C_TDMA) {
1017 sc->sc_tdma = 1;
1018 /* NB: disable tsf adjust */
1019 sc->sc_stagbeacons = 0;
1020 }
1021 /*
1022 * NB: adhoc demo mode is a pseudo mode; to the hal it's
1023 * just ap mode.
--- 89 unchanged lines hidden (view full) ---
1113 if (sc->sc_nstavaps == 0 && sc->sc_swbmiss)
1114 sc->sc_swbmiss = 0;
1115 } else if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
1116 reclaim_address(sc, vap->iv_myaddr);
1117 ath_hal_setbssidmask(ah, sc->sc_hwbssidmask);
1118 }
1119 if (vap->iv_opmode != IEEE80211_M_WDS)
1120 sc->sc_nvaps--;
1121#ifdef ATH_SUPPORT_TDMA
1122 /* TDMA operation ceases when the last vap is destroyed */
1123 if (sc->sc_tdma && sc->sc_nvaps == 0) {
1124 sc->sc_tdma = 0;
1125 sc->sc_swbmiss = 0;
1126 }
1127#endif
1128 ATH_UNLOCK(sc);
1129 free(avp, M_80211_VAP);
--- 144 unchanged lines hidden (view full) ---
1274 } else {
1275 if (status & HAL_INT_SWBA) {
1276 /*
1277 * Software beacon alert--time to send a beacon.
1278 * Handle beacon transmission directly; deferring
1279 * this is too slow to meet timing constraints
1280 * under load.
1281 */
1282#ifdef ATH_SUPPORT_TDMA
1283 if (sc->sc_tdma) {
1284 if (sc->sc_tdmaswba == 0) {
1285 struct ieee80211com *ic = ifp->if_l2com;
1286 struct ieee80211vap *vap =
1287 TAILQ_FIRST(&ic->ic_vaps);
1288 ath_tdma_beacon_send(sc, vap);
1289 sc->sc_tdmaswba =
1290 vap->iv_tdma->tdma_bintval;
--- 330 unchanged lines hidden (view full) ---
1621 if_printf(ifp, "%s: unable to start recv logic\n", __func__);
1622 /*
1623 * We may be doing a reset in response to an ioctl
1624 * that changes the channel so update any state that
1625 * might change as a result.
1626 */
1627 ath_chan_change(sc, ic->ic_curchan);
1628 if (sc->sc_beacons) {
1629#ifdef ATH_SUPPORT_TDMA
1630 if (sc->sc_tdma)
1631 ath_tdma_config(sc, NULL);
1632 else
1633#endif
1634 ath_beacon_config(sc, NULL); /* restart beacons */
1635 }
1636 ath_hal_intrset(ah, sc->sc_imask);
1637
--- 2633 unchanged lines hidden (view full) ---
4271 ni = ieee80211_find_rxnode_withkey(ic,
4272 mtod(m, const struct ieee80211_frame_min *),
4273 rs->rs_keyix == HAL_RXKEYIX_INVALID ?
4274 IEEE80211_KEYIX_NONE : rs->rs_keyix);
4275 if (ni != NULL) {
4276 /*
4277 * Sending station is known, dispatch directly.
4278 */
4279#ifdef ATH_SUPPORT_TDMA
4280 sc->sc_tdmars = rs;
4281#endif
4282 type = ieee80211_input(ni, m,
4283 rs->rs_rssi, nf, rs->rs_tstamp);
4284 ieee80211_free_node(ni);
4285 /*
4286 * Arrange to update the last rx timestamp only for
4287 * frames from our ap when operating in station mode.
--- 158 unchanged lines hidden (view full) ---
4446 struct ifnet *ifp = sc->sc_ifp;
4447 struct ieee80211com *ic = ifp->if_l2com;
4448 struct ath_txq *txq = sc->sc_ac2q[ac];
4449 struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
4450 struct ath_hal *ah = sc->sc_ah;
4451 HAL_TXQ_INFO qi;
4452
4453 ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi);
4454#ifdef ATH_SUPPORT_TDMA
4455 if (sc->sc_tdma) {
4456 /*
4457 * AIFS is zero so there's no pre-transmit wait. The
4458 * burst time defines the slot duration and is configured
4459 * via sysctl. The QCU is setup to not do post-xmit
4460 * back off, lockout all lower-priority QCU's, and fire
4461 * off the DMA beacon alert timer which is setup based
4462 * on the slot configuration.
--- 17 unchanged lines hidden (view full) ---
4480 | HAL_TXQ_TXDESCINT_ENABLE
4481 | HAL_TXQ_TXURNINT_ENABLE
4482 ;
4483 qi.tqi_aifs = wmep->wmep_aifsn;
4484 qi.tqi_cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
4485 qi.tqi_cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
4486 qi.tqi_readyTime = 0;
4487 qi.tqi_burstTime = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
4488#ifdef ATH_SUPPORT_TDMA
4489 }
4490#endif
4491
4492 DPRINTF(sc, ATH_DEBUG_RESET,
4493 "%s: Q%u qflags 0x%x aifs %u cwmin %u cwmax %u burstTime %u\n",
4494 __func__, txq->axq_qnum, qi.tqi_qflags,
4495 qi.tqi_aifs, qi.tqi_cwmin, qi.tqi_cwmax, qi.tqi_burstTime);
4496
--- 173 unchanged lines hidden (view full) ---
4670 * on a s/w only queue and loaded on to the CAB queue in
4671 * the SWBA handler since frames only go out on DTIM and
4672 * to avoid possible races.
4673 */
4674 ATH_TXQ_LOCK(txq);
4675 KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0,
4676 ("busy status 0x%x", bf->bf_flags));
4677 if (txq->axq_qnum != ATH_TXQ_SWQ) {
4678#ifdef ATH_SUPPORT_TDMA
4679 int qbusy;
4680
4681 ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
4682 qbusy = ath_hal_txqenabled(ah, txq->axq_qnum);
4683 if (txq->axq_link == NULL) {
4684 /*
4685 * Be careful writing the address to TXDP. If
4686 * the tx q is enabled then this write will be
--- 53 unchanged lines hidden (view full) ---
4740 txq->axq_depth);
4741 } else {
4742 *txq->axq_link = bf->bf_daddr;
4743 DPRINTF(sc, ATH_DEBUG_XMIT,
4744 "%s: link[%u](%p)=%p (%p) depth %d\n", __func__,
4745 txq->axq_qnum, txq->axq_link,
4746 (caddr_t)bf->bf_daddr, bf->bf_desc, txq->axq_depth);
4747 }
4748#endif /* ATH_SUPPORT_TDMA */
4749 txq->axq_link = &bf->bf_desc[bf->bf_nseg - 1].ds_link;
4750 ath_hal_txstart(ah, txq->axq_qnum);
4751 } else {
4752 if (txq->axq_link != NULL) {
4753 struct ath_buf *last = ATH_TXQ_LAST(txq);
4754 struct ieee80211_frame *wh;
4755
4756 /* mark previous frame */
--- 218 unchanged lines hidden (view full) ---
4975 } else if (pktlen > vap->iv_rtsthreshold &&
4976 (ni->ni_ath_flags & IEEE80211_NODE_FF) == 0) {
4977 flags |= HAL_TXDESC_RTSENA; /* RTS based on frame length */
4978 cix = rt->info[rix].controlRate;
4979 sc->sc_stats.ast_tx_rts++;
4980 }
4981 if (flags & HAL_TXDESC_NOACK) /* NB: avoid double counting */
4982 sc->sc_stats.ast_tx_noack++;
4983#ifdef ATH_SUPPORT_TDMA
4984 if (sc->sc_tdma && (flags & HAL_TXDESC_NOACK) == 0) {
4985 DPRINTF(sc, ATH_DEBUG_TDMA,
4986 "%s: discard frame, ACK required w/ TDMA\n", __func__);
4987 sc->sc_stats.ast_tdma_ack++;
4988 ath_freetx(m0);
4989 return EIO;
4990 }
4991#endif
--- 225 unchanged lines hidden (view full) ---
5217 ath_printtxbuf(sc, bf, txq->axq_qnum, 0,
5218 status == HAL_OK);
5219#endif
5220 if (status == HAL_EINPROGRESS) {
5221 ATH_TXQ_UNLOCK(txq);
5222 break;
5223 }
5224 ATH_TXQ_REMOVE_HEAD(txq, bf_list);
5225#ifdef ATH_SUPPORT_TDMA
5226 if (txq->axq_depth > 0) {
5227 /*
5228 * More frames follow. Mark the buffer busy
5229 * so it's not re-used while the hardware may
5230 * still re-read the link field in the descriptor.
5231 */
5232 bf->bf_flags |= ATH_BUF_BUSY;
5233 } else
--- 694 unchanged lines hidden (view full) ---
5928
5929 DPRINTF(sc, ATH_DEBUG_STATE,
5930 "%s(RUN): iv_flags 0x%08x bintvl %d bssid %s "
5931 "capinfo 0x%04x chan %d\n", __func__,
5932 vap->iv_flags, ni->ni_intval, ether_sprintf(ni->ni_bssid),
5933 ni->ni_capinfo, ieee80211_chan2ieee(ic, ic->ic_curchan));
5934
5935 switch (vap->iv_opmode) {
5936#ifdef ATH_SUPPORT_TDMA
5937 case IEEE80211_M_AHDEMO:
5938 if ((vap->iv_caps & IEEE80211_C_TDMA) == 0)
5939 break;
5940 /* fall thru... */
5941#endif
5942 case IEEE80211_M_HOSTAP:
5943 case IEEE80211_M_IBSS:
5944 /*
--- 17 unchanged lines hidden (view full) ---
5962 * starting an ibss/bss so there's no need to delay;
5963 * if this is the first vap moving to RUN state, then
5964 * beacon state needs to be [re]configured.
5965 */
5966 if (vap->iv_opmode == IEEE80211_M_IBSS &&
5967 ni->ni_tstamp.tsf != 0) {
5968 sc->sc_syncbeacon = 1;
5969 } else if (!sc->sc_beacons) {
5970#ifdef ATH_SUPPORT_TDMA
5971 if (vap->iv_caps & IEEE80211_C_TDMA)
5972 ath_tdma_config(sc, vap);
5973 else
5974#endif
5975 ath_beacon_config(sc, vap);
5976 sc->sc_beacons = 1;
5977 }
5978 break;
--- 51 unchanged lines hidden (view full) ---
6030 */
6031 if (!ath_isanyrunningvaps(vap)) {
6032 sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
6033 /* disable interrupts */
6034 ath_hal_intrset(ah, sc->sc_imask &~ HAL_INT_GLOBAL);
6035 taskqueue_block(sc->sc_tq);
6036 sc->sc_beacons = 0;
6037 }
6038#ifdef ATH_SUPPORT_TDMA
6039 ath_hal_setcca(ah, AH_TRUE);
6040#endif
6041 }
6042bad:
6043 return error;
6044}
6045
6046/*
--- 491 unchanged lines hidden (view full) ---
6538 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
6539 break;
6540 case SIOCGATHSTATS:
6541 /* NB: embed these numbers to get a consistent view */
6542 sc->sc_stats.ast_tx_packets = ifp->if_opackets;
6543 sc->sc_stats.ast_rx_packets = ifp->if_ipackets;
6544 sc->sc_stats.ast_tx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgtxrssi);
6545 sc->sc_stats.ast_rx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgrssi);
6546#ifdef ATH_SUPPORT_TDMA
6547 sc->sc_stats.ast_tdma_tsfadjp = TDMA_AVG(sc->sc_avgtsfdeltap);
6548 sc->sc_stats.ast_tdma_tsfadjm = TDMA_AVG(sc->sc_avgtsfdeltam);
6549#endif
6550 rt = sc->sc_currates;
6551 /* XXX HT rates */
6552 sc->sc_stats.ast_tx_rate =
6553 rt->info[sc->sc_txrix].dot11Rate &~ IEEE80211_RATE_BASIC;
6554 return copyout(&sc->sc_stats,
--- 273 unchanged lines hidden (view full) ---
6828
6829 intmit = ath_hal_getintmit(sc->sc_ah);
6830 error = sysctl_handle_int(oidp, &intmit, 0, req);
6831 if (error || !req->newptr)
6832 return error;
6833 return !ath_hal_setintmit(sc->sc_ah, intmit) ? EINVAL : 0;
6834}
6835
6836#ifdef ATH_SUPPORT_TDMA
6837static int
6838ath_sysctl_setcca(SYSCTL_HANDLER_ARGS)
6839{
6840 struct ath_softc *sc = arg1;
6841 int setcca, error;
6842
6843 setcca = sc->sc_setcca;
6844 error = sysctl_handle_int(oidp, &setcca, 0, req);
6845 if (error || !req->newptr)
6846 return error;
6847 sc->sc_setcca = (setcca != 0);
6848 return 0;
6849}
6850#endif /* ATH_SUPPORT_TDMA */
6851
6852static void
6853ath_sysctlattach(struct ath_softc *sc)
6854{
6855 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
6856 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
6857 struct ath_hal *ah = sc->sc_ah;
6858
--- 82 unchanged lines hidden (view full) ---
6941 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6942 "intmit", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
6943 ath_sysctl_intmit, "I", "interference mitigation");
6944 }
6945 sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC;
6946 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6947 "monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
6948 "mask of error frames to pass when monitoring");
6949#ifdef ATH_SUPPORT_TDMA
6950 if (ath_hal_macversion(ah) > 0x78) {
6951 sc->sc_tdmadbaprep = 2;
6952 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6953 "dbaprep", CTLFLAG_RW, &sc->sc_tdmadbaprep, 0,
6954 "TDMA DBA preparation time");
6955 sc->sc_tdmaswbaprep = 10;
6956 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6957 "swbaprep", CTLFLAG_RW, &sc->sc_tdmaswbaprep, 0,
--- 322 unchanged lines hidden (view full) ---
7280 if_printf(ifp, "Use hw queue %u for beacons\n", sc->sc_bhalq);
7281 }
7282 if (ath_rxbuf != ATH_RXBUF)
7283 if_printf(ifp, "using %u rx buffers\n", ath_rxbuf);
7284 if (ath_txbuf != ATH_TXBUF)
7285 if_printf(ifp, "using %u tx buffers\n", ath_txbuf);
7286}
7287
7288#ifdef ATH_SUPPORT_TDMA
7289static __inline uint32_t
7290ath_hal_getnexttbtt(struct ath_hal *ah)
7291{
7292#define AR_TIMER0 0x8028
7293 return OS_REG_READ(ah, AR_TIMER0);
7294}
7295
7296static __inline void
--- 343 unchanged lines hidden (view full) ---
7640
7641 /*
7642 * Record local TSF for our last send for use
7643 * in arbitrating slot collisions.
7644 */
7645 vap->iv_bss->ni_tstamp.tsf = ath_hal_gettsf64(ah);
7646 }
7647}
7648#endif /* ATH_SUPPORT_TDMA */
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
--- 14 unchanged lines hidden (view full) ---
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath.c 190526 2009-03-29 17:59:14Z sam $");
32
33/*
34 * Driver for the Atheros Wireless LAN controller.
35 *
36 * This software is derived from work of Atsushi Onoe; his contribution
37 * is greatly appreciated.
38 */
39
40#include "opt_inet.h"
41#include "opt_ath.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/sysctl.h>
46#include <sys/mbuf.h>
47#include <sys/malloc.h>
48#include <sys/lock.h>
49#include <sys/mutex.h>
--- 15 unchanged lines hidden (view full) ---
65#include <net/if_media.h>
66#include <net/if_types.h>
67#include <net/if_arp.h>
68#include <net/ethernet.h>
69#include <net/if_llc.h>
70
71#include <net80211/ieee80211_var.h>
72#include <net80211/ieee80211_regdomain.h>
73#ifdef ATH_SUPPORT_TDMA
74#include <net80211/ieee80211_tdma.h>
75#endif
76
77#include <net/bpf.h>
78
79#ifdef INET
80#include <netinet/in.h>
81#include <netinet/if_ether.h>
--- 126 unchanged lines hidden (view full) ---
208static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
209
210static void ath_sysctlattach(struct ath_softc *);
211static int ath_raw_xmit(struct ieee80211_node *,
212 struct mbuf *, const struct ieee80211_bpf_params *);
213static void ath_bpfattach(struct ath_softc *);
214static void ath_announce(struct ath_softc *);
215
216#ifdef ATH_SUPPORT_TDMA
217static void ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt,
218 u_int32_t bintval);
219static void ath_tdma_bintvalsetup(struct ath_softc *sc,
220 const struct ieee80211_tdma_state *tdma);
221static void ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap);
222static void ath_tdma_update(struct ieee80211_node *ni,
223 const struct ieee80211_tdma_param *tdma, int);
224static void ath_tdma_beacon_send(struct ath_softc *sc,
--- 25 unchanged lines hidden (view full) ---
250#define TDMA_LPF(x, y, len) \
251 ((x != TDMA_DUMMY_MARKER) ? (((x) * ((len)-1) + (y)) / (len)) : (y))
252#define TDMA_SAMPLE(x, y) do { \
253 x = TDMA_LPF((x), TDMA_IN(y), TDMA_LPF_LEN); \
254} while (0)
255#define TDMA_EP_RND(x,mul) \
256 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
257#define TDMA_AVG(x) TDMA_EP_RND(x, TDMA_EP_MULTIPLIER)
258#endif /* ATH_SUPPORT_TDMA */
259
260SYSCTL_DECL(_hw_ath);
261
262/* XXX validate sysctl values */
263static int ath_longcalinterval = 30; /* long cals every 30 secs */
264SYSCTL_INT(_hw_ath, OID_AUTO, longcal, CTLFLAG_RW, &ath_longcalinterval,
265 0, "long chip calibration interval (secs)");
266static int ath_shortcalinterval = 100; /* short cals every 100 ms */
--- 386 unchanged lines hidden (view full) ---
653 ic->ic_caps |= IEEE80211_C_BURST;
654 sc->sc_hasbmask = ath_hal_hasbssidmask(ah);
655 sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);
656 if (ath_hal_hasfastframes(ah))
657 ic->ic_caps |= IEEE80211_C_FF;
658 wmodes = ath_hal_getwirelessmodes(ah);
659 if (wmodes & (HAL_MODE_108G|HAL_MODE_TURBO))
660 ic->ic_caps |= IEEE80211_C_TURBOP;
661#ifdef ATH_SUPPORT_TDMA
662 if (ath_hal_macversion(ah) > 0x78) {
663 ic->ic_caps |= IEEE80211_C_TDMA; /* capable of TDMA */
664 ic->ic_tdma_update = ath_tdma_update;
665 }
666#endif
667 /*
668 * Indicate we need the 802.11 header padded to a
669 * 32-bit boundary for 4-address and QoS frames.
--- 212 unchanged lines hidden (view full) ---
882 device_printf(sc->sc_dev,
883 "only 1 ibss vap supported\n");
884 goto bad;
885 }
886 ic_opmode = opmode;
887 needbeacon = 1;
888 break;
889 case IEEE80211_M_AHDEMO:
890#ifdef ATH_SUPPORT_TDMA
891 if (flags & IEEE80211_CLONE_TDMA) {
892 needbeacon = 1;
893 flags |= IEEE80211_CLONE_NOBEACONS;
894 }
895 /* fall thru... */
896#endif
897 case IEEE80211_M_MONITOR:
898 if (sc->sc_nvaps != 0 && ic->ic_opmode != opmode) {
--- 108 unchanged lines hidden (view full) ---
1007 switch (ic_opmode) {
1008 case IEEE80211_M_IBSS:
1009 sc->sc_opmode = HAL_M_IBSS;
1010 break;
1011 case IEEE80211_M_STA:
1012 sc->sc_opmode = HAL_M_STA;
1013 break;
1014 case IEEE80211_M_AHDEMO:
1015#ifdef ATH_SUPPORT_TDMA
1016 if (vap->iv_caps & IEEE80211_C_TDMA) {
1017 sc->sc_tdma = 1;
1018 /* NB: disable tsf adjust */
1019 sc->sc_stagbeacons = 0;
1020 }
1021 /*
1022 * NB: adhoc demo mode is a pseudo mode; to the hal it's
1023 * just ap mode.
--- 89 unchanged lines hidden (view full) ---
1113 if (sc->sc_nstavaps == 0 && sc->sc_swbmiss)
1114 sc->sc_swbmiss = 0;
1115 } else if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
1116 reclaim_address(sc, vap->iv_myaddr);
1117 ath_hal_setbssidmask(ah, sc->sc_hwbssidmask);
1118 }
1119 if (vap->iv_opmode != IEEE80211_M_WDS)
1120 sc->sc_nvaps--;
1121#ifdef ATH_SUPPORT_TDMA
1122 /* TDMA operation ceases when the last vap is destroyed */
1123 if (sc->sc_tdma && sc->sc_nvaps == 0) {
1124 sc->sc_tdma = 0;
1125 sc->sc_swbmiss = 0;
1126 }
1127#endif
1128 ATH_UNLOCK(sc);
1129 free(avp, M_80211_VAP);
--- 144 unchanged lines hidden (view full) ---
1274 } else {
1275 if (status & HAL_INT_SWBA) {
1276 /*
1277 * Software beacon alert--time to send a beacon.
1278 * Handle beacon transmission directly; deferring
1279 * this is too slow to meet timing constraints
1280 * under load.
1281 */
1282#ifdef ATH_SUPPORT_TDMA
1283 if (sc->sc_tdma) {
1284 if (sc->sc_tdmaswba == 0) {
1285 struct ieee80211com *ic = ifp->if_l2com;
1286 struct ieee80211vap *vap =
1287 TAILQ_FIRST(&ic->ic_vaps);
1288 ath_tdma_beacon_send(sc, vap);
1289 sc->sc_tdmaswba =
1290 vap->iv_tdma->tdma_bintval;
--- 330 unchanged lines hidden (view full) ---
1621 if_printf(ifp, "%s: unable to start recv logic\n", __func__);
1622 /*
1623 * We may be doing a reset in response to an ioctl
1624 * that changes the channel so update any state that
1625 * might change as a result.
1626 */
1627 ath_chan_change(sc, ic->ic_curchan);
1628 if (sc->sc_beacons) {
1629#ifdef ATH_SUPPORT_TDMA
1630 if (sc->sc_tdma)
1631 ath_tdma_config(sc, NULL);
1632 else
1633#endif
1634 ath_beacon_config(sc, NULL); /* restart beacons */
1635 }
1636 ath_hal_intrset(ah, sc->sc_imask);
1637
--- 2633 unchanged lines hidden (view full) ---
4271 ni = ieee80211_find_rxnode_withkey(ic,
4272 mtod(m, const struct ieee80211_frame_min *),
4273 rs->rs_keyix == HAL_RXKEYIX_INVALID ?
4274 IEEE80211_KEYIX_NONE : rs->rs_keyix);
4275 if (ni != NULL) {
4276 /*
4277 * Sending station is known, dispatch directly.
4278 */
4279#ifdef ATH_SUPPORT_TDMA
4280 sc->sc_tdmars = rs;
4281#endif
4282 type = ieee80211_input(ni, m,
4283 rs->rs_rssi, nf, rs->rs_tstamp);
4284 ieee80211_free_node(ni);
4285 /*
4286 * Arrange to update the last rx timestamp only for
4287 * frames from our ap when operating in station mode.
--- 158 unchanged lines hidden (view full) ---
4446 struct ifnet *ifp = sc->sc_ifp;
4447 struct ieee80211com *ic = ifp->if_l2com;
4448 struct ath_txq *txq = sc->sc_ac2q[ac];
4449 struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
4450 struct ath_hal *ah = sc->sc_ah;
4451 HAL_TXQ_INFO qi;
4452
4453 ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi);
4454#ifdef ATH_SUPPORT_TDMA
4455 if (sc->sc_tdma) {
4456 /*
4457 * AIFS is zero so there's no pre-transmit wait. The
4458 * burst time defines the slot duration and is configured
4459 * via sysctl. The QCU is setup to not do post-xmit
4460 * back off, lockout all lower-priority QCU's, and fire
4461 * off the DMA beacon alert timer which is setup based
4462 * on the slot configuration.
--- 17 unchanged lines hidden (view full) ---
4480 | HAL_TXQ_TXDESCINT_ENABLE
4481 | HAL_TXQ_TXURNINT_ENABLE
4482 ;
4483 qi.tqi_aifs = wmep->wmep_aifsn;
4484 qi.tqi_cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
4485 qi.tqi_cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
4486 qi.tqi_readyTime = 0;
4487 qi.tqi_burstTime = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
4488#ifdef ATH_SUPPORT_TDMA
4489 }
4490#endif
4491
4492 DPRINTF(sc, ATH_DEBUG_RESET,
4493 "%s: Q%u qflags 0x%x aifs %u cwmin %u cwmax %u burstTime %u\n",
4494 __func__, txq->axq_qnum, qi.tqi_qflags,
4495 qi.tqi_aifs, qi.tqi_cwmin, qi.tqi_cwmax, qi.tqi_burstTime);
4496
--- 173 unchanged lines hidden (view full) ---
4670 * on a s/w only queue and loaded on to the CAB queue in
4671 * the SWBA handler since frames only go out on DTIM and
4672 * to avoid possible races.
4673 */
4674 ATH_TXQ_LOCK(txq);
4675 KASSERT((bf->bf_flags & ATH_BUF_BUSY) == 0,
4676 ("busy status 0x%x", bf->bf_flags));
4677 if (txq->axq_qnum != ATH_TXQ_SWQ) {
4678#ifdef ATH_SUPPORT_TDMA
4679 int qbusy;
4680
4681 ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
4682 qbusy = ath_hal_txqenabled(ah, txq->axq_qnum);
4683 if (txq->axq_link == NULL) {
4684 /*
4685 * Be careful writing the address to TXDP. If
4686 * the tx q is enabled then this write will be
--- 53 unchanged lines hidden (view full) ---
4740 txq->axq_depth);
4741 } else {
4742 *txq->axq_link = bf->bf_daddr;
4743 DPRINTF(sc, ATH_DEBUG_XMIT,
4744 "%s: link[%u](%p)=%p (%p) depth %d\n", __func__,
4745 txq->axq_qnum, txq->axq_link,
4746 (caddr_t)bf->bf_daddr, bf->bf_desc, txq->axq_depth);
4747 }
4748#endif /* ATH_SUPPORT_TDMA */
4749 txq->axq_link = &bf->bf_desc[bf->bf_nseg - 1].ds_link;
4750 ath_hal_txstart(ah, txq->axq_qnum);
4751 } else {
4752 if (txq->axq_link != NULL) {
4753 struct ath_buf *last = ATH_TXQ_LAST(txq);
4754 struct ieee80211_frame *wh;
4755
4756 /* mark previous frame */
--- 218 unchanged lines hidden (view full) ---
4975 } else if (pktlen > vap->iv_rtsthreshold &&
4976 (ni->ni_ath_flags & IEEE80211_NODE_FF) == 0) {
4977 flags |= HAL_TXDESC_RTSENA; /* RTS based on frame length */
4978 cix = rt->info[rix].controlRate;
4979 sc->sc_stats.ast_tx_rts++;
4980 }
4981 if (flags & HAL_TXDESC_NOACK) /* NB: avoid double counting */
4982 sc->sc_stats.ast_tx_noack++;
4983#ifdef ATH_SUPPORT_TDMA
4984 if (sc->sc_tdma && (flags & HAL_TXDESC_NOACK) == 0) {
4985 DPRINTF(sc, ATH_DEBUG_TDMA,
4986 "%s: discard frame, ACK required w/ TDMA\n", __func__);
4987 sc->sc_stats.ast_tdma_ack++;
4988 ath_freetx(m0);
4989 return EIO;
4990 }
4991#endif
--- 225 unchanged lines hidden (view full) ---
5217 ath_printtxbuf(sc, bf, txq->axq_qnum, 0,
5218 status == HAL_OK);
5219#endif
5220 if (status == HAL_EINPROGRESS) {
5221 ATH_TXQ_UNLOCK(txq);
5222 break;
5223 }
5224 ATH_TXQ_REMOVE_HEAD(txq, bf_list);
5225#ifdef ATH_SUPPORT_TDMA
5226 if (txq->axq_depth > 0) {
5227 /*
5228 * More frames follow. Mark the buffer busy
5229 * so it's not re-used while the hardware may
5230 * still re-read the link field in the descriptor.
5231 */
5232 bf->bf_flags |= ATH_BUF_BUSY;
5233 } else
--- 694 unchanged lines hidden (view full) ---
5928
5929 DPRINTF(sc, ATH_DEBUG_STATE,
5930 "%s(RUN): iv_flags 0x%08x bintvl %d bssid %s "
5931 "capinfo 0x%04x chan %d\n", __func__,
5932 vap->iv_flags, ni->ni_intval, ether_sprintf(ni->ni_bssid),
5933 ni->ni_capinfo, ieee80211_chan2ieee(ic, ic->ic_curchan));
5934
5935 switch (vap->iv_opmode) {
5936#ifdef ATH_SUPPORT_TDMA
5937 case IEEE80211_M_AHDEMO:
5938 if ((vap->iv_caps & IEEE80211_C_TDMA) == 0)
5939 break;
5940 /* fall thru... */
5941#endif
5942 case IEEE80211_M_HOSTAP:
5943 case IEEE80211_M_IBSS:
5944 /*
--- 17 unchanged lines hidden (view full) ---
5962 * starting an ibss/bss so there's no need to delay;
5963 * if this is the first vap moving to RUN state, then
5964 * beacon state needs to be [re]configured.
5965 */
5966 if (vap->iv_opmode == IEEE80211_M_IBSS &&
5967 ni->ni_tstamp.tsf != 0) {
5968 sc->sc_syncbeacon = 1;
5969 } else if (!sc->sc_beacons) {
5970#ifdef ATH_SUPPORT_TDMA
5971 if (vap->iv_caps & IEEE80211_C_TDMA)
5972 ath_tdma_config(sc, vap);
5973 else
5974#endif
5975 ath_beacon_config(sc, vap);
5976 sc->sc_beacons = 1;
5977 }
5978 break;
--- 51 unchanged lines hidden (view full) ---
6030 */
6031 if (!ath_isanyrunningvaps(vap)) {
6032 sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
6033 /* disable interrupts */
6034 ath_hal_intrset(ah, sc->sc_imask &~ HAL_INT_GLOBAL);
6035 taskqueue_block(sc->sc_tq);
6036 sc->sc_beacons = 0;
6037 }
6038#ifdef ATH_SUPPORT_TDMA
6039 ath_hal_setcca(ah, AH_TRUE);
6040#endif
6041 }
6042bad:
6043 return error;
6044}
6045
6046/*
--- 491 unchanged lines hidden (view full) ---
6538 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
6539 break;
6540 case SIOCGATHSTATS:
6541 /* NB: embed these numbers to get a consistent view */
6542 sc->sc_stats.ast_tx_packets = ifp->if_opackets;
6543 sc->sc_stats.ast_rx_packets = ifp->if_ipackets;
6544 sc->sc_stats.ast_tx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgtxrssi);
6545 sc->sc_stats.ast_rx_rssi = ATH_RSSI(sc->sc_halstats.ns_avgrssi);
6546#ifdef ATH_SUPPORT_TDMA
6547 sc->sc_stats.ast_tdma_tsfadjp = TDMA_AVG(sc->sc_avgtsfdeltap);
6548 sc->sc_stats.ast_tdma_tsfadjm = TDMA_AVG(sc->sc_avgtsfdeltam);
6549#endif
6550 rt = sc->sc_currates;
6551 /* XXX HT rates */
6552 sc->sc_stats.ast_tx_rate =
6553 rt->info[sc->sc_txrix].dot11Rate &~ IEEE80211_RATE_BASIC;
6554 return copyout(&sc->sc_stats,
--- 273 unchanged lines hidden (view full) ---
6828
6829 intmit = ath_hal_getintmit(sc->sc_ah);
6830 error = sysctl_handle_int(oidp, &intmit, 0, req);
6831 if (error || !req->newptr)
6832 return error;
6833 return !ath_hal_setintmit(sc->sc_ah, intmit) ? EINVAL : 0;
6834}
6835
6836#ifdef ATH_SUPPORT_TDMA
6837static int
6838ath_sysctl_setcca(SYSCTL_HANDLER_ARGS)
6839{
6840 struct ath_softc *sc = arg1;
6841 int setcca, error;
6842
6843 setcca = sc->sc_setcca;
6844 error = sysctl_handle_int(oidp, &setcca, 0, req);
6845 if (error || !req->newptr)
6846 return error;
6847 sc->sc_setcca = (setcca != 0);
6848 return 0;
6849}
6850#endif /* ATH_SUPPORT_TDMA */
6851
6852static void
6853ath_sysctlattach(struct ath_softc *sc)
6854{
6855 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
6856 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
6857 struct ath_hal *ah = sc->sc_ah;
6858
--- 82 unchanged lines hidden (view full) ---
6941 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6942 "intmit", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
6943 ath_sysctl_intmit, "I", "interference mitigation");
6944 }
6945 sc->sc_monpass = HAL_RXERR_DECRYPT | HAL_RXERR_MIC;
6946 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6947 "monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
6948 "mask of error frames to pass when monitoring");
6949#ifdef ATH_SUPPORT_TDMA
6950 if (ath_hal_macversion(ah) > 0x78) {
6951 sc->sc_tdmadbaprep = 2;
6952 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6953 "dbaprep", CTLFLAG_RW, &sc->sc_tdmadbaprep, 0,
6954 "TDMA DBA preparation time");
6955 sc->sc_tdmaswbaprep = 10;
6956 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
6957 "swbaprep", CTLFLAG_RW, &sc->sc_tdmaswbaprep, 0,
--- 322 unchanged lines hidden (view full) ---
7280 if_printf(ifp, "Use hw queue %u for beacons\n", sc->sc_bhalq);
7281 }
7282 if (ath_rxbuf != ATH_RXBUF)
7283 if_printf(ifp, "using %u rx buffers\n", ath_rxbuf);
7284 if (ath_txbuf != ATH_TXBUF)
7285 if_printf(ifp, "using %u tx buffers\n", ath_txbuf);
7286}
7287
7288#ifdef ATH_SUPPORT_TDMA
7289static __inline uint32_t
7290ath_hal_getnexttbtt(struct ath_hal *ah)
7291{
7292#define AR_TIMER0 0x8028
7293 return OS_REG_READ(ah, AR_TIMER0);
7294}
7295
7296static __inline void
--- 343 unchanged lines hidden (view full) ---
7640
7641 /*
7642 * Record local TSF for our last send for use
7643 * in arbitrating slot collisions.
7644 */
7645 vap->iv_bss->ni_tstamp.tsf = ath_hal_gettsf64(ah);
7646 }
7647}
7648#endif /* ATH_SUPPORT_TDMA */