Initial commit
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -1238,6 +1238,8 @@ void rt2800_watchdog(struct rt2x00_dev *
|
||||
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:
|
||||
@@ -1274,6 +1276,18 @@ void rt2800_watchdog(struct rt2x00_dev *
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_watchdog);
|
||||
|
||||
+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);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(rt2800_update_survey);
|
||||
+
|
||||
static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
|
||||
unsigned int index)
|
||||
{
|
||||
@@ -12199,26 +12213,30 @@ int rt2800_get_survey(struct ieee80211_h
|
||||
{
|
||||
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);
|
||||
-
|
||||
- if (idle || 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->channel = &rt2x00dev->bands[band].channels[idx];
|
||||
+
|
||||
+ survey->filled = SURVEY_INFO_TIME |
|
||||
+ SURVEY_INFO_TIME_BUSY |
|
||||
+ SURVEY_INFO_TIME_EXT_BUSY;
|
||||
+
|
||||
+ 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;
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -243,6 +243,7 @@ bool rt2800_txstatus_timeout(struct rt2x
|
||||
bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
void rt2800_watchdog(struct rt2x00_dev *rt2x00dev);
|
||||
+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
|
||||
void rt2800_clear_beacon(struct queue_entry *entry);
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
|
||||
@@ -360,6 +360,7 @@ static const struct rt2x00lib_ops rt2800
|
||||
.gain_calibration = rt2800_gain_calibration,
|
||||
.vco_calibration = rt2800_vco_calibration,
|
||||
.watchdog = rt2800_watchdog,
|
||||
+ .update_survey = rt2800_update_survey,
|
||||
.start_queue = rt2800mmio_start_queue,
|
||||
.kick_queue = rt2800mmio_kick_queue,
|
||||
.stop_queue = rt2800mmio_stop_queue,
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
@@ -214,6 +214,7 @@ static const struct rt2x00lib_ops rt2800
|
||||
.gain_calibration = rt2800_gain_calibration,
|
||||
.vco_calibration = rt2800_vco_calibration,
|
||||
.watchdog = rt2800_watchdog,
|
||||
+ .update_survey = rt2800_update_survey,
|
||||
.start_queue = rt2800mmio_start_queue,
|
||||
.kick_queue = rt2800mmio_kick_queue,
|
||||
.stop_queue = rt2800mmio_stop_queue,
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -183,6 +183,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 {
|
||||
@@ -567,6 +576,7 @@ struct rt2x00lib_ops {
|
||||
* Data queue handlers.
|
||||
*/
|
||||
void (*watchdog) (struct rt2x00_dev *rt2x00dev);
|
||||
+ void (*update_survey) (struct rt2x00_dev *rt2x00dev);
|
||||
void (*start_queue) (struct data_queue *queue);
|
||||
void (*kick_queue) (struct data_queue *queue);
|
||||
void (*stop_queue) (struct data_queue *queue);
|
||||
@@ -755,6 +765,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;
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1054,6 +1054,12 @@ static int rt2x00lib_probe_hw_modes(stru
|
||||
if (!rates)
|
||||
goto exit_free_channels;
|
||||
|
||||
+ rt2x00dev->chan_survey =
|
||||
+ kcalloc(spec->num_channels, sizeof(struct rt2x00_chan_survey),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!rt2x00dev->chan_survey)
|
||||
+ goto exit_free_rates;
|
||||
+
|
||||
/*
|
||||
* Initialize Rate list.
|
||||
*/
|
||||
@@ -1105,6 +1111,8 @@ static int rt2x00lib_probe_hw_modes(stru
|
||||
|
||||
return 0;
|
||||
|
||||
+ exit_free_rates:
|
||||
+ kfree(rates);
|
||||
exit_free_channels:
|
||||
kfree(channels);
|
||||
rt2x00_err(rt2x00dev, "Allocation ieee80211 modes failed\n");
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
|
||||
@@ -317,6 +317,15 @@ int rt2x00mac_config(struct ieee80211_hw
|
||||
return 0;
|
||||
|
||||
/*
|
||||
+ * To provide correct survey data for survey-based ACS algorithm
|
||||
+ * we have to save survey data for current channel before switching.
|
||||
+ */
|
||||
+ if (rt2x00dev->ops->lib->update_survey &&
|
||||
+ (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
|
||||
+ rt2x00dev->ops->lib->update_survey(rt2x00dev);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Some configuration parameters (e.g. channel and antenna values) can
|
||||
* only be set when the radio is enabled, but do require the RX to
|
||||
* be off. During this period we should keep link tuning enabled,
|
||||
Reference in New Issue
Block a user