[<prev] [next>] [day] [month] [year] [list]
Message-Id: <200612031919.02690.IvDoorn@gmail.com>
Date: Sun, 3 Dec 2006 19:19:02 +0100
From: Ivo van Doorn <ivdoorn@...il.com>
To: "John W. Linville" <linville@...driver.com>
Cc: netdev@...r.kernel.org
Subject: [PATCH 11/26] rt2x00: Put link tuning on workqueue
Put the link tuning in a workqueue, this prevents
the interrupthandlers from being busy for a too long
period and blocking new inetrrupt handling.
To do this correctly we add a link structure containing
all information regarding the link status.
Signed-off-by Ivo van Doorn <IvDoorn@...il.com>
---
diff -rU3 wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
--- wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-12-03 12:46:41.000000000 +0100
+++ wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-12-03 13:25:32.000000000 +0100
@@ -624,12 +624,20 @@
/*
* Link tuning
*/
-static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt2400pci_link_tuner(void *data)
{
+ struct rt2x00_dev *rt2x00dev = data;
u8 reg;
char false_cca_delta;
/*
+ * Don't perform any tuning when it is disabled
+ * in the EEPROM.
+ */
+ if (GET_FLAG(rt2x00dev, CONFIG_DISABLE_LINK_TUNING))
+ return;
+
+ /*
* Read false CCA counter.
*/
rt2x00_bbp_read(rt2x00dev, 39, ®);
@@ -653,6 +661,9 @@
if (reg < 0x20)
rt2x00_bbp_write(rt2x00dev, 13, reg);
}
+
+ queue_delayed_work(rt2x00dev->workqueue, &rt2x00dev->link.work,
+ LINK_TUNE_INTERVAL);
}
/*
@@ -1568,16 +1579,6 @@
rt2x00_desc_write(rxd, 0, word0);
rt2x00_ring_index_inc(ring);
}
-
- /*
- * Tune link for optimal performance.
- */
- rt2400pci_link_tuner(rt2x00dev);
-
- /*
- * Update LED.
- */
- rt2400pci_activity_led(rt2x00dev, 0);
}
static void rt2400pci_txdone(void *data)
@@ -1885,8 +1886,11 @@
* Enable radio when this is the first
* interface that is brought up.
*/
- if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
+ queue_delayed_work(rt2x00dev->workqueue,
+ &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
return rt2400pci_enable_radio(rt2x00dev);
+ }
return 0;
}
@@ -1908,6 +1912,9 @@
*/
rt2x00_remove_interface(&rt2x00dev->interface, conf);
+ cancel_rearming_delayed_workqueue(rt2x00dev->workqueue,
+ &rt2x00dev->link.work);
+
/*
* When this is a non-monitor mode,
* clear the INTERFACE_INITIALIZED FLAG to allow
@@ -2694,6 +2701,11 @@
goto exit;
/*
+ * Initialize configuration work.
+ */
+ INIT_WORK(&rt2x00dev->link.work, rt2400pci_link_tuner, rt2x00dev);
+
+ /*
* Reset current working type.
*/
rt2x00dev->interface.type = -EINVAL;
diff -rU3 wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
--- wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-12-03 12:47:36.000000000 +0100
+++ wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-12-03 13:25:36.000000000 +0100
@@ -698,18 +698,27 @@
/*
* Link tuning
*/
-static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev, char rssi)
+static void rt2500pci_link_tuner(void *data)
{
+ struct rt2x00_dev *rt2x00dev = data;
u32 reg;
+ u32 rssi;
u8 reg_r17;
/*
* Don't perform any tuning when it is disabled
* in the EEPROM.
*/
- if (GET_FLAG(rt2x00dev, CONFIG_DISABLE_BBP_TUNING))
+ if (GET_FLAG(rt2x00dev, CONFIG_DISABLE_LINK_TUNING))
return;
+ /*
+ * Retreive link quality.
+ */
+ rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
+ if (!rssi)
+ goto exit;
+
rt2x00_register_read(rt2x00dev, CSR0, ®);
rt2x00_bbp_read(rt2x00dev, 17, ®_r17);
@@ -719,14 +728,14 @@
if (rssi < 40) {
if (reg_r17 >= 0x41)
rt2x00_bbp_write(rt2x00dev, 17, reg_r17);
- return;
+ goto exit;
} else if (rssi >= 62) {
if (reg_r17 != 0x50)
rt2x00_bbp_write(rt2x00dev, 17, 0x50);
- return;
+ goto exit;
} else if (reg_r17 >= 0x41) {
rt2x00_bbp_write(rt2x00dev, 17, reg_r17);
- return;
+ goto exit;
}
dynamic_cca_tune:
@@ -738,6 +747,16 @@
rt2x00_bbp_write(rt2x00dev, 17, ++reg_r17);
else if (reg < 100 && reg_r17 > 0x32)
rt2x00_bbp_write(rt2x00dev, 17, --reg_r17);
+
+exit:
+ /*
+ * Update noise statistics.
+ */
+ if (reg_r17)
+ rt2x00_update_link_noise(&rt2x00dev->link, reg_r17);
+
+ queue_delayed_work(rt2x00dev->workqueue, &rt2x00dev->link.work,
+ LINK_TUNE_INTERVAL);
}
/*
@@ -1669,14 +1688,6 @@
u32 word0;
u32 word2;
u16 size;
- u8 rssi_count;
- char total_rssi;
-
- /*
- * Initialize variable for average RSSI calculation.
- */
- rssi_count = 0;
- total_rssi = 0;
while (1) {
entry = rt2x00_get_data_entry(ring);
@@ -1721,24 +1732,16 @@
__ieee80211_rx(rt2x00dev->hw,
skb, &rt2x00dev->rx_params);
- rssi_count++;
- total_rssi += rt2x00dev->rx_params.ssi;
+ /*
+ * Update link statistics
+ */
+ rt2x00_update_link_rssi(&rt2x00dev->link,
+ rt2x00dev->rx_params.ssi);
}
rt2x00_set_field32(&word0, RXD_W0_OWNER_NIC, 1);
rt2x00_desc_write(rxd, 0, word0);
rt2x00_ring_index_inc(ring);
}
-
- /*
- * Tune link for optimal performance.
- */
- if (total_rssi && rssi_count)
- rt2500pci_link_tuner(rt2x00dev, total_rssi / rssi_count);
-
- /*
- * Update LED.
- */
- rt2500pci_activity_led(rt2x00dev, 0);
}
static void rt2500pci_txdone(void *data)
@@ -2045,8 +2048,11 @@
* Enable radio when this is the first
* interface that is brought up.
*/
- if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
+ queue_delayed_work(rt2x00dev->workqueue,
+ &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
return rt2500pci_enable_radio(rt2x00dev);
+ }
return 0;
}
@@ -2068,6 +2074,9 @@
*/
rt2x00_remove_interface(&rt2x00dev->interface, conf);
+ cancel_rearming_delayed_workqueue(rt2x00dev->workqueue,
+ &rt2x00dev->link.work);
+
/*
* When this is a non-monitor mode,
* clear the INTERFACE_INITIALIZED FLAG to allow
@@ -2993,6 +3002,11 @@
goto exit;
/*
+ * Initialize configuration work.
+ */
+ INIT_WORK(&rt2x00dev->link.work, rt2500pci_link_tuner, rt2x00dev);
+
+ /*
* Reset current working type.
*/
rt2x00dev->interface.type = -EINVAL;
diff -rU3 wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
--- wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-12-03 12:48:18.000000000 +0100
+++ wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-12-03 13:25:40.000000000 +0100
@@ -710,9 +710,11 @@
/*
* Link tuning
*/
-static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev, char rssi)
+static void rt2500usb_link_tuner(void *data)
{
+ struct rt2x00_dev *rt2x00dev = data;
u16 reg;
+ u32 rssi;
u8 reg_r17;
u8 up_bound;
u8 low_bound;
@@ -721,9 +723,16 @@
* Don't perform any tuning when it is disabled
* in the EEPROM.
*/
- if (GET_FLAG(rt2x00dev, CONFIG_DISABLE_BBP_TUNING))
+ if (GET_FLAG(rt2x00dev, CONFIG_DISABLE_LINK_TUNING))
return;
+ /*
+ * Retreive link quality.
+ */
+ rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
+ if (!rssi)
+ goto exit;
+
low_bound = 0x32;
if (rssi >= 43)
up_bound = 0x40;
@@ -747,18 +756,18 @@
if (rssi > 80) {
if (reg_r17 != 0x60)
rt2x00_bbp_write(rt2x00dev, 17, 0x60);
- return;
+ goto exit;
} else if (rssi >= 62) {
if (reg_r17 != 0x48)
rt2x00_bbp_write(rt2x00dev, 17, 0x48);
- return;
+ goto exit;
} else if (rssi >= 46) {
if (reg_r17 != 0x41)
rt2x00_bbp_write(rt2x00dev, 17, 0x41);
- return;
+ goto exit;
} else if (reg_r17 > up_bound) {
rt2x00_bbp_write(rt2x00dev, 17, up_bound);
- return;
+ goto exit;
}
rt2x00_register_read(rt2x00dev, STA_CSR3, ®);
@@ -767,6 +776,16 @@
rt2x00_bbp_write(rt2x00dev, 17, ++reg_r17);
else if (reg < 100 && reg_r17 > low_bound)
rt2x00_bbp_write(rt2x00dev, 17, --reg_r17);
+
+exit:
+ /*
+ * Update noise statistics.
+ */
+ if (reg_r17)
+ rt2x00_update_link_noise(&rt2x00dev->link, reg_r17);
+
+ queue_delayed_work(rt2x00dev->workqueue, &rt2x00dev->link.work,
+ LINK_TUNE_INTERVAL);
}
/*
@@ -1604,14 +1623,6 @@
u32 word0;
u32 word1;
u16 size;
- u8 rssi_count;
- char total_rssi;
-
- /*
- * Initialize variable for average RSSI calculation.
- */
- rssi_count = 0;
- total_rssi = 0;
while (1) {
entry = rt2x00_get_data_entry(ring);
@@ -1671,8 +1682,11 @@
__ieee80211_rx(rt2x00dev->hw,
skb, &rt2x00dev->rx_params);
- rssi_count++;
- total_rssi += rt2x00dev->rx_params.ssi;
+ /*
+ * Update link statistics
+ */
+ rt2x00_update_link_rssi(&rt2x00dev->link,
+ rt2x00dev->rx_params.ssi);
}
SET_FLAG(entry, ENTRY_OWNER_NIC);
@@ -1680,17 +1694,6 @@
rt2x00_ring_index_inc(ring);
}
-
- /*
- * Tune link for optimal performance.
- */
- if (total_rssi && rssi_count)
- rt2500usb_link_tuner(rt2x00dev, total_rssi / rssi_count);
-
- /*
- * Update LED.
- */
- rt2500usb_activity_led(rt2x00dev, 0);
}
static void rt2500usb_txdone(void *data)
@@ -1939,8 +1942,11 @@
* Enable radio when this is the first
* interface that is brought up.
*/
- if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
+ queue_delayed_work(rt2x00dev->workqueue,
+ &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
return rt2500usb_enable_radio(rt2x00dev);
+ }
return 0;
}
@@ -1962,6 +1968,9 @@
*/
rt2x00_remove_interface(&rt2x00dev->interface, conf);
+ cancel_rearming_delayed_workqueue(rt2x00dev->workqueue,
+ &rt2x00dev->link.work);
+
/*
* When this is a non-monitor mode,
* clear the INTERFACE_INITIALIZED FLAG to allow
@@ -2789,6 +2798,7 @@
*/
INIT_WORK(&rt2x00dev->interface.work,
rt2500usb_interface_update, rt2x00dev);
+ INIT_WORK(&rt2x00dev->link.work, rt2500usb_link_tuner, rt2x00dev);
/*
* Reset current working type.
diff -rU3 wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt2x00.h wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt2x00.h
--- wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt2x00.h 2006-12-03 12:56:07.000000000 +0100
+++ wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt2x00.h 2006-12-03 13:13:46.000000000 +0100
@@ -642,6 +642,65 @@
}
/*
+ * To optimize the quality of the link we need to store
+ * the quality of received frames and periodically
+ * optimize the link.
+ */
+struct link {
+ /*
+ * RSSI statistics.
+ */
+ u32 count_rssi;
+ u32 total_rssi;
+
+ /*
+ * Noise statistics.
+ */
+ u32 curr_noise;
+
+ /*
+ * Work structure for scheduling periodic link tuning.
+ */
+ struct work_struct work;
+};
+
+static inline void rt2x00_start_link_tune(struct link *link)
+{
+ link->count_rssi = 0;
+ link->total_rssi = 0;
+ link->curr_noise = 0;
+}
+
+static inline void rt2x00_update_link_rssi(struct link *link, u32 rssi)
+{
+ link->count_rssi++;
+ link->total_rssi += rssi;
+}
+
+static inline void rt2x00_update_link_noise(struct link *link, u32 noise)
+{
+ link->curr_noise = noise;
+}
+
+static inline u32 rt2x00_get_link_rssi(struct link *link)
+{
+ u32 average = 0;
+
+ if (link->count_rssi && link->total_rssi)
+ average = link->total_rssi / link->count_rssi;
+
+ link->count_rssi = 0;
+ link->total_rssi = 0;
+
+ return average;
+}
+
+static inline u32 rt2x00_get_link_noise(struct link *link)
+{
+ return link->curr_noise;
+}
+
+/*
* Interface structure
* Configuration details about the current interface.
*/
@@ -872,6 +931,11 @@
struct interface interface;
/*
+ * Link quality
+ */
+ struct link link;
+
+ /*
* EEPROM data.
*/
__le16 *eeprom;
diff -rU3 wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt61pci.c wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt61pci.c
--- wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt61pci.c 2006-12-03 13:08:21.000000000 +0100
+++ wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt61pci.c 2006-12-03 13:25:43.000000000 +0100
@@ -922,13 +922,31 @@
/*
* Link tuning
*/
-static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev, char rssi)
+static void rt61pci_link_tuner(void *data)
{
+ struct rt2x00_dev *rt2x00dev = data;
u32 reg;
+ u32 rssi;
u8 reg_r17;
u8 up_bound;
u8 low_bound;
+ /*
+ * Retreive link quality.
+ */
+ rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
+ if (!rssi)
+ goto exit;
+
+
+ /*
+ * Update LED.
+ */
+ rt61pci_activity_led(rt2x00dev, rssi);
+
+ /*
+ * Determine upper and lower limit for BBP17 register.
+ */
if (rt2x00dev->rx_params.phymode == MODE_IEEE80211A) {
up_bound = 0x48;
low_bound = 0x28;
@@ -942,24 +960,24 @@
if (rssi >= 85) {
if (reg_r17 != 0x60)
rt2x00_bbp_write(rt2x00dev, 17, 0x60);
- return;
+ goto exit;
} else if (rssi >= 62) {
if (reg_r17 != up_bound)
rt2x00_bbp_write(rt2x00dev, 17, up_bound);
- return;
+ goto exit;
} else if (rssi >= 54) {
low_bound += 0x10;
if (reg_r17 != low_bound)
rt2x00_bbp_write(rt2x00dev, 17, low_bound);
- return;
+ goto exit;
} else if (rssi >= 46) {
low_bound += 0x08;
if (reg_r17 != low_bound)
rt2x00_bbp_write(rt2x00dev, 17, low_bound);
- return;
+ goto exit;
} else if (reg_r17 >= up_bound) {
rt2x00_bbp_write(rt2x00dev, 17, up_bound);
- return;
+ goto exit;
}
rt2x00_register_read(rt2x00dev, STA_CSR1, ®);
@@ -969,6 +987,13 @@
rt2x00_bbp_write(rt2x00dev, 17, ++reg_r17);
else if (reg < 100 && reg_r17 > low_bound)
rt2x00_bbp_write(rt2x00dev, 17, --reg_r17);
+
+exit:
+ if (reg_r17)
+ rt2x00_update_link_noise(&rt2x00dev->link, reg_r17);
+
+ queue_delayed_work(rt2x00dev->workqueue, &rt2x00dev->link.work,
+ LINK_TUNE_INTERVAL);
}
/*
@@ -2121,14 +2146,6 @@
u32 word0;
u32 word1;
u16 size;
- u8 rssi_count;
- char total_rssi;
-
- /*
- * Initialize variable for average RSSI calculation.
- */
- rssi_count = 0;
- total_rssi = 0;
while (1) {
entry = rt2x00_get_data_entry(ring);
@@ -2172,24 +2189,16 @@
__ieee80211_rx(rt2x00dev->hw,
skb, &rt2x00dev->rx_params);
- rssi_count++;
- total_rssi += rt2x00dev->rx_params.ssi;
+ /*
+ * Update link statistics
+ */
+ rt2x00_update_link_rssi(&rt2x00dev->link,
+ rt2x00dev->rx_params.ssi);
}
rt2x00_set_field32(&word0, RXD_W0_OWNER_NIC, 1);
rt2x00_desc_write(rxd, 0, word0);
rt2x00_ring_index_inc(ring);
}
-
- /*
- * Tune link for optimal performance.
- */
- if (total_rssi && rssi_count)
- rt61pci_link_tuner(rt2x00dev, total_rssi / rssi_count);
-
- /*
- * Update LED.
- */
- rt61pci_activity_led(rt2x00dev, total_rssi);
}
static void rt61pci_txdone_entry(struct data_entry *entry, u32 sta_csr4)
@@ -2526,8 +2535,11 @@
* Enable radio when this is the first
* interface that is brought up.
*/
- if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
+ queue_delayed_work(rt2x00dev->workqueue,
+ &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
return rt61pci_enable_radio(rt2x00dev);
+ }
return 0;
}
@@ -2549,6 +2561,9 @@
*/
rt2x00_remove_interface(&rt2x00dev->interface, conf);
+ cancel_rearming_delayed_workqueue(rt2x00dev->workqueue,
+ &rt2x00dev->link.work);
+
/*
* When this is a non-monitor mode,
* clear the INTERFACE_INITIALIZED FLAG to allow
@@ -3503,6 +3518,11 @@
goto exit;
/*
+ * Initialize configuration work.
+ */
+ INIT_WORK(&rt2x00dev->link.work, rt61pci_link_tuner, rt2x00dev);
+
+ /*
* Reset current working type.
*/
rt2x00dev->interface.type = -EINVAL;
diff -rU3 wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt73usb.c wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt73usb.c
--- wireless-dev-ringindex/drivers/net/wireless/d80211/rt2x00/rt73usb.c 2006-12-03 13:10:11.000000000 +0100
+++ wireless-dev-linktuning/drivers/net/wireless/d80211/rt2x00/rt73usb.c 2006-12-03 13:25:46.000000000 +0100
@@ -812,13 +812,30 @@
/*
* Link tuning
*/
-static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, char rssi)
+static void rt73usb_link_tuner(void *data)
{
+ struct rt2x00_dev *rt2x00dev = data;
u32 reg;
+ u32 rssi;
u8 reg_r17;
u8 up_bound;
u8 low_bound;
+ /*
+ * Retreive link quality.
+ */
+ rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
+ if (!rssi)
+ goto exit;
+
+ /*
+ * Update LED.
+ */
+ rt73usb_activity_led(rt2x00dev, rssi);
+
+ /*
+ * Determine upper and lower limit for BBP17 register.
+ */
if (rt2x00dev->rx_params.phymode == MODE_IEEE80211A) {
up_bound = 0x48;
low_bound = 0x28;
@@ -845,21 +862,21 @@
if (rssi >= 85) {
if (reg_r17 != 0x60)
rt2x00_bbp_write(rt2x00dev, 17, 0x60);
- return;
+ goto exit;
} else if (rssi >= 62) {
if (reg_r17 != up_bound)
rt2x00_bbp_write(rt2x00dev, 17, up_bound);
- return;
+ goto exit;
} else if (rssi >= 54) {
low_bound += 0x10;
if (reg_r17 != low_bound)
rt2x00_bbp_write(rt2x00dev, 17, low_bound);
- return;
+ goto exit;
} else if (rssi >= 46) {
low_bound += 0x08;
if (reg_r17 != low_bound)
rt2x00_bbp_write(rt2x00dev, 17, low_bound);
- return;
+ goto exit;
} else {
up_bound -= 2 * (46 - rssi);
if (up_bound < low_bound)
@@ -867,7 +884,7 @@
if (reg_r17 > up_bound) {
rt2x00_bbp_write(rt2x00dev, 17, up_bound);
- return;
+ goto exit;
}
}
@@ -878,6 +895,13 @@
rt2x00_bbp_write(rt2x00dev, 17, ++reg_r17);
else if (reg < 100 && reg_r17 > low_bound)
rt2x00_bbp_write(rt2x00dev, 17, --reg_r17);
+
+exit:
+ if (reg_r17)
+ rt2x00_update_link_noise(&rt2x00dev->link, reg_r17);
+
+ queue_delayed_work(rt2x00dev->workqueue, &rt2x00dev->link.work,
+ LINK_TUNE_INTERVAL);
}
/*
@@ -1883,14 +1907,6 @@
u32 word0;
u32 word1;
u16 size;
- u8 rssi_count;
- char total_rssi;
-
- /*
- * Initialize variable for average RSSI calculation.
- */
- rssi_count = 0;
- total_rssi = 0;
while (1) {
entry = rt2x00_get_data_entry(ring);
@@ -1946,8 +1962,11 @@
__ieee80211_rx(rt2x00dev->hw,
skb, &rt2x00dev->rx_params);
- rssi_count++;
- total_rssi += rt2x00dev->rx_params.ssi;
+ /*
+ * Update link statistics
+ */
+ rt2x00_update_link_rssi(&rt2x00dev->link,
+ rt2x00dev->rx_params.ssi);
}
SET_FLAG(entry, ENTRY_OWNER_NIC);
@@ -1955,17 +1974,6 @@
rt2x00_ring_index_inc(ring);
}
-
- /*
- * Tune link for optimal performance.
- */
- if (total_rssi && rssi_count)
- rt73usb_link_tuner(rt2x00dev, total_rssi / rssi_count);
-
- /*
- * Update LED.
- */
- rt73usb_activity_led(rt2x00dev, total_rssi);
}
static void rt73usb_txdone(void *data)
@@ -2213,8 +2221,11 @@
* Enable radio when this is the first
* interface that is brought up.
*/
- if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO))
+ if (!GET_FLAG(rt2x00dev, DEVICE_ENABLED_RADIO)) {
+ queue_delayed_work(rt2x00dev->workqueue,
+ &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
return rt73usb_enable_radio(rt2x00dev);
+ }
return 0;
}
@@ -2236,6 +2247,9 @@
*/
rt2x00_remove_interface(&rt2x00dev->interface, conf);
+ cancel_rearming_delayed_workqueue(rt2x00dev->workqueue,
+ &rt2x00dev->link.work);
+
/*
* When this is a non-monitor mode,
* clear the INTERFACE_INITIALIZED FLAG to allow
@@ -3130,6 +3144,7 @@
*/
INIT_WORK(&rt2x00dev->interface.work,
rt73usb_interface_update, rt2x00dev);
+ INIT_WORK(&rt2x00dev->link.work, rt73usb_link_tuner, rt2x00dev);
/*
* Reset current working type.
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists