0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "common.h"
0018
0019 #define FUDGE 2
0020
0021 static u32 ath9k_get_next_tbtt(struct ath_hw *ah, u64 tsf,
0022 unsigned int interval)
0023 {
0024 unsigned int offset, divisor;
0025
0026 tsf += TU_TO_USEC(FUDGE + ah->config.sw_beacon_response_time);
0027 divisor = TU_TO_USEC(interval);
0028 div_u64_rem(tsf, divisor, &offset);
0029
0030 return (u32) tsf + divisor - offset;
0031 }
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 int ath9k_cmn_beacon_config_sta(struct ath_hw *ah,
0042 struct ath_beacon_config *conf,
0043 struct ath9k_beacon_state *bs)
0044 {
0045 struct ath_common *common = ath9k_hw_common(ah);
0046 int dtim_intval;
0047 u64 tsf;
0048
0049
0050 if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) {
0051 ath_dbg(common, BEACON,
0052 "STA is not yet associated..skipping beacon config\n");
0053 return -EPERM;
0054 }
0055
0056 memset(bs, 0, sizeof(*bs));
0057 conf->intval = conf->beacon_interval;
0058
0059
0060
0061
0062
0063 dtim_intval = conf->intval * conf->dtim_period;
0064
0065
0066
0067
0068
0069 tsf = ath9k_hw_gettsf64(ah);
0070 conf->nexttbtt = ath9k_get_next_tbtt(ah, tsf, conf->intval);
0071
0072 bs->bs_intval = TU_TO_USEC(conf->intval);
0073 bs->bs_dtimperiod = conf->dtim_period * bs->bs_intval;
0074 bs->bs_nexttbtt = conf->nexttbtt;
0075 bs->bs_nextdtim = conf->nexttbtt;
0076 if (conf->dtim_period > 1)
0077 bs->bs_nextdtim = ath9k_get_next_tbtt(ah, tsf, dtim_intval);
0078
0079
0080
0081
0082
0083
0084
0085 bs->bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, conf->intval);
0086 if (bs->bs_bmissthreshold > 15)
0087 bs->bs_bmissthreshold = 15;
0088 else if (bs->bs_bmissthreshold <= 0)
0089 bs->bs_bmissthreshold = 1;
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 bs->bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100),
0101 conf->intval));
0102 if (bs->bs_sleepduration > bs->bs_dtimperiod)
0103 bs->bs_sleepduration = bs->bs_dtimperiod;
0104
0105
0106 bs->bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
0107
0108 ath_dbg(common, BEACON, "bmiss: %u sleep: %u\n",
0109 bs->bs_bmissthreshold, bs->bs_sleepduration);
0110 return 0;
0111 }
0112 EXPORT_SYMBOL(ath9k_cmn_beacon_config_sta);
0113
0114 void ath9k_cmn_beacon_config_adhoc(struct ath_hw *ah,
0115 struct ath_beacon_config *conf)
0116 {
0117 struct ath_common *common = ath9k_hw_common(ah);
0118
0119 conf->intval = TU_TO_USEC(conf->beacon_interval);
0120
0121 if (conf->ibss_creator)
0122 conf->nexttbtt = conf->intval;
0123 else
0124 conf->nexttbtt = ath9k_get_next_tbtt(ah, ath9k_hw_gettsf64(ah),
0125 conf->beacon_interval);
0126
0127 if (conf->enable_beacon)
0128 ah->imask |= ATH9K_INT_SWBA;
0129 else
0130 ah->imask &= ~ATH9K_INT_SWBA;
0131
0132 ath_dbg(common, BEACON,
0133 "IBSS (%s) nexttbtt: %u intval: %u conf_intval: %u\n",
0134 (conf->enable_beacon) ? "Enable" : "Disable",
0135 conf->nexttbtt, conf->intval, conf->beacon_interval);
0136 }
0137 EXPORT_SYMBOL(ath9k_cmn_beacon_config_adhoc);
0138
0139
0140
0141
0142
0143
0144 void ath9k_cmn_beacon_config_ap(struct ath_hw *ah,
0145 struct ath_beacon_config *conf,
0146 unsigned int bc_buf)
0147 {
0148 struct ath_common *common = ath9k_hw_common(ah);
0149
0150
0151 conf->intval = TU_TO_USEC(conf->beacon_interval);
0152 conf->intval /= bc_buf;
0153 conf->nexttbtt = ath9k_get_next_tbtt(ah, ath9k_hw_gettsf64(ah),
0154 conf->beacon_interval);
0155
0156 if (conf->enable_beacon)
0157 ah->imask |= ATH9K_INT_SWBA;
0158 else
0159 ah->imask &= ~ATH9K_INT_SWBA;
0160
0161 ath_dbg(common, BEACON,
0162 "AP (%s) nexttbtt: %u intval: %u conf_intval: %u\n",
0163 (conf->enable_beacon) ? "Enable" : "Disable",
0164 conf->nexttbtt, conf->intval, conf->beacon_interval);
0165 }
0166 EXPORT_SYMBOL(ath9k_cmn_beacon_config_ap);