summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ralink/rt2x00
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ralink/rt2x00')
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800lib.c62
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00.h10
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00config.c1
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00dev.c6
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00mac.c3
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00queue.c1
6 files changed, 59 insertions, 24 deletions
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index fed6d21cd6ce..5264b0a1f098 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -1228,6 +1228,17 @@ static int rt2800_check_hung(struct data_queue *queue)
return queue->wd_count > 16;
}
+static void rt2800_update_survey(struct rt2x00_dev *rt2x00dev)
+{
+ struct ieee80211_channel *chan = rt2x00dev->hw->conf.chandef.chan;
+ struct rt2x00_chan_survey *chan_survey =
+ &rt2x00dev->chan_survey[chan->hw_value];
+
+ chan_survey->time_idle += rt2800_register_read(rt2x00dev, CH_IDLE_STA);
+ chan_survey->time_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA);
+ chan_survey->time_ext_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC);
+}
+
void rt2800_watchdog(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
@@ -1237,6 +1248,8 @@ void rt2800_watchdog(struct rt2x00_dev *rt2x00dev)
if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
return;
+ rt2800_update_survey(rt2x00dev);
+
queue_for_each(rt2x00dev, queue) {
switch (queue->qid) {
case QID_AC_VO:
@@ -5553,6 +5566,12 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev,
rt2800_config_lna_gain(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_CHANNEL) {
+ /*
+ * To provide correct survey data for survey-based ACS algorithm
+ * we have to save survey data for current channel before switching.
+ */
+ rt2800_update_survey(rt2x00dev);
+
rt2800_config_channel(rt2x00dev, libconf->conf,
&libconf->rf, &libconf->channel);
rt2800_config_txpower(rt2x00dev, libconf->conf->chandef.chan,
@@ -10111,12 +10130,20 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
}
/*
- * Create channel information array
+ * Create channel information and survey arrays
*/
info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
+ rt2x00dev->chan_survey =
+ kcalloc(spec->num_channels, sizeof(struct rt2x00_chan_survey),
+ GFP_KERNEL);
+ if (!rt2x00dev->chan_survey) {
+ kfree(info);
+ return -ENOMEM;
+ }
+
spec->channels_info = info;
default_power1 = rt2800_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
@@ -10503,27 +10530,30 @@ int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
- struct ieee80211_conf *conf = &hw->conf;
- u32 idle, busy, busy_ext;
+ struct rt2x00_chan_survey *chan_survey =
+ &rt2x00dev->chan_survey[idx];
+ enum nl80211_band band = NL80211_BAND_2GHZ;
- if (idx != 0)
+ if (idx >= rt2x00dev->bands[band].n_channels) {
+ idx -= rt2x00dev->bands[band].n_channels;
+ band = NL80211_BAND_5GHZ;
+ }
+
+ if (idx >= rt2x00dev->bands[band].n_channels)
return -ENOENT;
- survey->channel = conf->chandef.chan;
+ if (idx == 0)
+ rt2800_update_survey(rt2x00dev);
- idle = rt2800_register_read(rt2x00dev, CH_IDLE_STA);
- busy = rt2800_register_read(rt2x00dev, CH_BUSY_STA);
- busy_ext = rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC);
+ survey->channel = &rt2x00dev->bands[band].channels[idx];
- if (idle || busy) {
- survey->filled = SURVEY_INFO_TIME |
- SURVEY_INFO_TIME_BUSY |
- SURVEY_INFO_TIME_EXT_BUSY;
+ survey->filled = SURVEY_INFO_TIME |
+ SURVEY_INFO_TIME_BUSY |
+ SURVEY_INFO_TIME_EXT_BUSY;
- survey->time = (idle + busy) / 1000;
- survey->time_busy = busy / 1000;
- survey->time_ext_busy = busy_ext / 1000;
- }
+ survey->time = div_u64(chan_survey->time_idle + chan_survey->time_busy, 1000);
+ survey->time_busy = div_u64(chan_survey->time_busy, 1000);
+ survey->time_ext_busy = div_u64(chan_survey->time_ext_busy, 1000);
if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
survey->filled |= SURVEY_INFO_IN_USE;
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
index 780be81863b6..9f6fc40649be 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
@@ -182,6 +182,15 @@ struct rf_channel {
};
/*
+ * Information structure for channel survey.
+ */
+struct rt2x00_chan_survey {
+ u64 time_idle;
+ u64 time_busy;
+ u64 time_ext_busy;
+};
+
+/*
* Channel information structure
*/
struct channel_info {
@@ -752,6 +761,7 @@ struct rt2x00_dev {
*/
struct ieee80211_hw *hw;
struct ieee80211_supported_band bands[NUM_NL80211_BANDS];
+ struct rt2x00_chan_survey *chan_survey;
enum nl80211_band curr_band;
int curr_freq;
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00config.c b/drivers/net/wireless/ralink/rt2x00/rt2x00config.c
index 0ee1813e8453..6bafdd991171 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00config.c
@@ -32,7 +32,6 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
break;
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_MESH_POINT:
- case NL80211_IFTYPE_WDS:
conf.sync = TSF_SYNC_AP_NONE;
break;
case NL80211_IFTYPE_STATION:
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
index b04f76551ca4..61a4f1ad31e2 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
@@ -194,8 +194,7 @@ static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac,
if (vif->type != NL80211_IFTYPE_AP &&
vif->type != NL80211_IFTYPE_ADHOC &&
- vif->type != NL80211_IFTYPE_MESH_POINT &&
- vif->type != NL80211_IFTYPE_WDS)
+ vif->type != NL80211_IFTYPE_MESH_POINT)
return;
/*
@@ -1437,9 +1436,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
-#ifdef CONFIG_WIRELESS_WDS
- BIT(NL80211_IFTYPE_WDS) |
-#endif
BIT(NL80211_IFTYPE_AP);
rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
index 2f68a31072ae..dea5babd30fe 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
@@ -408,8 +408,7 @@ static void rt2x00mac_set_tim_iter(void *data, u8 *mac,
if (vif->type != NL80211_IFTYPE_AP &&
vif->type != NL80211_IFTYPE_ADHOC &&
- vif->type != NL80211_IFTYPE_MESH_POINT &&
- vif->type != NL80211_IFTYPE_WDS)
+ vif->type != NL80211_IFTYPE_MESH_POINT)
return;
set_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags);
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
index 3b6100e6c8f6..d4d389e8f1b4 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
@@ -941,6 +941,7 @@ void rt2x00queue_unpause_queue(struct data_queue *queue)
* receive frames.
*/
queue->rt2x00dev->ops->lib->kick_queue(queue);
+ break;
default:
break;
}