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