ath9k: fetch survey data for all channels
authorFelix Fietkau <nbd@openwrt.org>
Wed, 29 Sep 2010 15:16:13 +0000 (15:16 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 29 Sep 2010 15:16:13 +0000 (15:16 +0000)
SVN-Revision: 23154

package/mac80211/patches/510-ath9k_htc_remove_ani_nf.patch [new file with mode: 0644]
package/mac80211/patches/511-ath9k_per_chan_nf.patch [new file with mode: 0644]
package/mac80211/patches/512-ath9k_survey_no_bogus_nf.patch [new file with mode: 0644]
package/mac80211/patches/513-ath9k_remove_ani_nf.patch [new file with mode: 0644]
package/mac80211/patches/514-mac80211_survey_chan_in_use.patch [new file with mode: 0644]
package/mac80211/patches/515-ath9k_multi_channel_nf.patch [new file with mode: 0644]

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 (file)
index 0000000..4ef6218
--- /dev/null
@@ -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 (file)
index 0000000..cbf44e6
--- /dev/null
@@ -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 (file)
index 0000000..798e59c
--- /dev/null
@@ -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 (file)
index 0000000..0f1fb21
--- /dev/null
@@ -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 (file)
index 0000000..1f9d446
--- /dev/null
@@ -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 (file)
index 0000000..468da97
--- /dev/null
@@ -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;