From 6f8a7385875333275d4ae07d8e9e2cd6a137d268 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 29 Sep 2010 15:16:13 +0000 Subject: [PATCH] ath9k: fetch survey data for all channels SVN-Revision: 23154 --- .../patches/510-ath9k_htc_remove_ani_nf.patch | 27 ++++++ .../patches/511-ath9k_per_chan_nf.patch | 97 +++++++++++++++++++ .../512-ath9k_survey_no_bogus_nf.patch | 23 +++++ .../patches/513-ath9k_remove_ani_nf.patch | 39 ++++++++ .../514-mac80211_survey_chan_in_use.patch | 46 +++++++++ .../patches/515-ath9k_multi_channel_nf.patch | 40 ++++++++ 6 files changed, 272 insertions(+) create mode 100644 package/mac80211/patches/510-ath9k_htc_remove_ani_nf.patch create mode 100644 package/mac80211/patches/511-ath9k_per_chan_nf.patch create mode 100644 package/mac80211/patches/512-ath9k_survey_no_bogus_nf.patch create mode 100644 package/mac80211/patches/513-ath9k_remove_ani_nf.patch create mode 100644 package/mac80211/patches/514-mac80211_survey_chan_in_use.patch create mode 100644 package/mac80211/patches/515-ath9k_multi_channel_nf.patch diff --git a/package/mac80211/patches/510-ath9k_htc_remove_ani_nf.patch b/package/mac80211/patches/510-ath9k_htc_remove_ani_nf.patch new file mode 100644 index 0000000000..4ef6218531 --- /dev/null +++ b/package/mac80211/patches/510-ath9k_htc_remove_ani_nf.patch @@ -0,0 +1,27 @@ +--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c +@@ -760,23 +760,12 @@ void ath9k_ani_work(struct work_struct * + ath9k_hw_ani_monitor(ah, ah->curchan); + + /* Perform calibration if necessary */ +- if (longcal || shortcal) { ++ if (longcal || shortcal) + common->ani.caldone = + ath9k_hw_calibrate(ah, ah->curchan, + common->rx_chainmask, + longcal); + +- if (longcal) +- common->ani.noise_floor = +- ath9k_hw_getchan_noise(ah, ah->curchan); +- +- ath_print(common, ATH_DBG_ANI, +- " calibrate chan %u/%x nf: %d\n", +- ah->curchan->channel, +- ah->curchan->channelFlags, +- common->ani.noise_floor); +- } +- + ath9k_htc_ps_restore(priv); + } + diff --git a/package/mac80211/patches/511-ath9k_per_chan_nf.patch b/package/mac80211/patches/511-ath9k_per_chan_nf.patch new file mode 100644 index 0000000000..cbf44e6408 --- /dev/null +++ b/package/mac80211/patches/511-ath9k_per_chan_nf.patch @@ -0,0 +1,97 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -342,7 +342,6 @@ struct ath9k_hw_cal_data { + int32_t CalValid; + int8_t iCoff; + int8_t qCoff; +- int16_t rawNoiseFloor; + bool paprd_done; + bool nfcal_pending; + bool nfcal_interference; +@@ -356,6 +355,7 @@ struct ath9k_channel { + u16 channel; + u32 channelFlags; + u32 chanmode; ++ s16 noisefloor; + }; + + #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ +--- a/drivers/net/wireless/ath/ath9k/calib.c ++++ b/drivers/net/wireless/ath/ath9k/calib.c +@@ -346,34 +346,34 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s + struct ieee80211_channel *c = chan->chan; + struct ath9k_hw_cal_data *caldata = ah->caldata; + +- if (!caldata) +- return false; +- + chan->channelFlags &= (~CHANNEL_CW_INT); + if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { + ath_print(common, ATH_DBG_CALIBRATE, + "NF did not complete in calibration window\n"); +- nf = 0; +- caldata->rawNoiseFloor = nf; + return false; +- } else { +- ath9k_hw_do_getnf(ah, nfarray); +- ath9k_hw_nf_sanitize(ah, nfarray); +- nf = nfarray[0]; +- if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) +- && nf > nfThresh) { +- ath_print(common, ATH_DBG_CALIBRATE, +- "noise floor failed detected; " +- "detected %d, threshold %d\n", +- nf, nfThresh); +- chan->channelFlags |= CHANNEL_CW_INT; +- } ++ } ++ ++ ath9k_hw_do_getnf(ah, nfarray); ++ ath9k_hw_nf_sanitize(ah, nfarray); ++ nf = nfarray[0]; ++ if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) ++ && nf > nfThresh) { ++ ath_print(common, ATH_DBG_CALIBRATE, ++ "noise floor failed detected; " ++ "detected %d, threshold %d\n", ++ nf, nfThresh); ++ chan->channelFlags |= CHANNEL_CW_INT; ++ } ++ ++ if (!caldata) { ++ chan->noisefloor = nf; ++ return false; + } + + h = caldata->nfCalHist; + caldata->nfcal_pending = false; + ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray); +- caldata->rawNoiseFloor = h[0].privNF; ++ chan->noisefloor = h[0].privNF; + return true; + } + +@@ -401,10 +401,10 @@ void ath9k_init_nfcal_hist_buffer(struct + + s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) + { +- if (!ah->caldata || !ah->caldata->rawNoiseFloor) ++ if (!ah->curchan || !ah->curchan->noisefloor) + return ath9k_hw_get_default_nf(ah, chan); + +- return ah->caldata->rawNoiseFloor; ++ return ah->curchan->noisefloor; + } + EXPORT_SYMBOL(ath9k_hw_getchan_noise); + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1251,7 +1251,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st + if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) + return -EIO; + +- if (curchan && !ah->chip_fullsleep && ah->caldata) ++ if (curchan && !ah->chip_fullsleep) + ath9k_hw_getnf(ah, curchan); + + ah->caldata = caldata; diff --git a/package/mac80211/patches/512-ath9k_survey_no_bogus_nf.patch b/package/mac80211/patches/512-ath9k_survey_no_bogus_nf.patch new file mode 100644 index 0000000000..798e59c3ab --- /dev/null +++ b/package/mac80211/patches/512-ath9k_survey_no_bogus_nf.patch @@ -0,0 +1,23 @@ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -2005,15 +2005,17 @@ static int ath9k_get_survey(struct ieee8 + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + struct ath_hw *ah = sc->sc_ah; +- struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_conf *conf = &hw->conf; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; +- survey->filled = SURVEY_INFO_NOISE_DBM; +- survey->noise = common->ani.noise_floor; ++ survey->filled = 0; ++ if (ah->curchan && ah->curchan->noisefloor) { ++ survey->filled |= SURVEY_INFO_NOISE_DBM; ++ survey->noise = ah->curchan->noisefloor; ++ } + + return 0; + } diff --git a/package/mac80211/patches/513-ath9k_remove_ani_nf.patch b/package/mac80211/patches/513-ath9k_remove_ani_nf.patch new file mode 100644 index 0000000000..0f1fb21976 --- /dev/null +++ b/package/mac80211/patches/513-ath9k_remove_ani_nf.patch @@ -0,0 +1,39 @@ +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -35,7 +35,6 @@ static const u8 ath_bcast_mac[ETH_ALEN] + + struct ath_ani { + bool caldone; +- int16_t noise_floor; + unsigned int longcal_timer; + unsigned int shortcal_timer; + unsigned int resetcal_timer; +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -507,7 +507,6 @@ static void ath9k_init_misc(struct ath_s + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + int i = 0; + +- common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; + setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); + + sc->config.txpowlimit = ATH_TXPOWER_MAX; +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -460,16 +460,6 @@ void ath_ani_calibrate(unsigned long dat + ah->curchan, + common->rx_chainmask, + longcal); +- +- if (longcal) +- common->ani.noise_floor = ath9k_hw_getchan_noise(ah, +- ah->curchan); +- +- ath_print(common, ATH_DBG_ANI, +- " calibrate chan %u/%x nf: %d\n", +- ah->curchan->channel, +- ah->curchan->channelFlags, +- common->ani.noise_floor); + } + } + diff --git a/package/mac80211/patches/514-mac80211_survey_chan_in_use.patch b/package/mac80211/patches/514-mac80211_survey_chan_in_use.patch new file mode 100644 index 0000000000..1f9d4462e4 --- /dev/null +++ b/package/mac80211/patches/514-mac80211_survey_chan_in_use.patch @@ -0,0 +1,46 @@ +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -294,12 +294,14 @@ struct key_params { + * enum survey_info_flags - survey information flags + * + * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in ++ * @SURVEY_INFO_IN_USE: channel is currently being used + * + * Used by the driver to indicate which info in &struct survey_info + * it has filled in during the get_survey(). + */ + enum survey_info_flags { + SURVEY_INFO_NOISE_DBM = 1<<0, ++ SURVEY_INFO_IN_USE = 1<<1, + }; + + /** +--- a/include/linux/nl80211.h ++++ b/include/linux/nl80211.h +@@ -1400,6 +1400,7 @@ enum nl80211_reg_rule_flags { + * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved + * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel + * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) ++ * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used + * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number + * currently defined + * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use +@@ -1408,6 +1409,7 @@ enum nl80211_survey_info { + __NL80211_SURVEY_INFO_INVALID, + NL80211_SURVEY_INFO_FREQUENCY, + NL80211_SURVEY_INFO_NOISE, ++ NL80211_SURVEY_INFO_IN_USE, + + /* keep last */ + __NL80211_SURVEY_INFO_AFTER_LAST, +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3491,6 +3491,8 @@ static int nl80211_send_survey(struct sk + if (survey->filled & SURVEY_INFO_NOISE_DBM) + NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE, + survey->noise); ++ if (survey->filled & SURVEY_INFO_IN_USE) ++ NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE); + + nla_nest_end(msg, infoattr); + diff --git a/package/mac80211/patches/515-ath9k_multi_channel_nf.patch b/package/mac80211/patches/515-ath9k_multi_channel_nf.patch new file mode 100644 index 0000000000..468da97ef1 --- /dev/null +++ b/package/mac80211/patches/515-ath9k_multi_channel_nf.patch @@ -0,0 +1,40 @@ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1995,16 +1995,31 @@ static int ath9k_get_survey(struct ieee8 + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + struct ath_hw *ah = sc->sc_ah; +- struct ieee80211_conf *conf = &hw->conf; ++ struct ieee80211_supported_band *sband; ++ struct ath9k_channel *chan; + +- if (idx != 0) +- return -ENOENT; ++ sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ]; ++ if (sband && idx >= sband->n_channels) { ++ idx -= sband->n_channels; ++ sband = NULL; ++ } ++ ++ if (!sband) ++ sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ]; ++ ++ if (idx >= sband->n_channels) ++ return -ENOENT; + +- survey->channel = conf->channel; ++ survey->channel = &sband->channels[idx]; ++ chan = &ah->channels[survey->channel->hw_value]; + survey->filled = 0; +- if (ah->curchan && ah->curchan->noisefloor) { ++ ++ if (chan == ah->curchan) ++ survey->filled |= SURVEY_INFO_IN_USE; ++ ++ if (chan->noisefloor) { + survey->filled |= SURVEY_INFO_NOISE_DBM; +- survey->noise = ah->curchan->noisefloor; ++ survey->noise = chan->noisefloor; + } + + return 0; -- 2.30.2