Split link quality calculation up into 2 parts: - calculate once per second the TX and RX success percentage - calculate per frame the total quality based on the TX and RX success percentage and the RSSI of the current frame. Signed-off-by: Ivo van Doorn <IvDoorn@xxxxxxxxx> --- drivers/net/wireless/rt2x00/rt2x00.h | 14 +++++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 65 +++++++++++++++---------------- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index a7527cd..1f5b3cb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -231,8 +231,10 @@ struct link { * * This value should then be checked to not be greated then 100. */ + int rx_percentage; int rx_success; int rx_failed; + int tx_percentage; int tx_success; int tx_failed; #define WEIGHT_RSSI 20 @@ -246,6 +248,18 @@ struct link { }; /* + * Clear all counters inside the link structure. + * This can be easiest achieved by memsetting everything + * except for the work structure at the end. + */ +static inline void rt2x00_clear_link(struct link *link) +{ + memset(link, 0x00, sizeof(*link) - sizeof(link->work)); + link->rx_percentage = 50; + link->tx_percentage = 50; +} + +/* * Update the rssi using the walking average approach. */ static inline void rt2x00_update_link_rssi(struct link *link, int rssi) diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index f2adaf5..09c31e3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -69,14 +69,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_get_ring); */ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) { - rt2x00dev->link.count = 0; - rt2x00dev->link.avg_rssi = 0; - rt2x00dev->link.vgc_level = 0; - rt2x00dev->link.false_cca = 0; - rt2x00dev->link.rx_success = 0; - rt2x00dev->link.rx_failed = 0; - rt2x00dev->link.tx_success = 0; - rt2x00dev->link.tx_failed = 0; + rt2x00_clear_link(&rt2x00dev->link); /* * Reset the link tuner. @@ -184,13 +177,32 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, int enable) rt2x00lib_start_link_tuner(rt2x00dev); } -static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev) +static void rt2x00lib_precalculate_link_signal(struct link *link) +{ + if (link->rx_failed || link->rx_success) + link->rx_percentage = + (link->rx_success * 100) / + (link->rx_failed + link->rx_success); + else + link->rx_percentage = 50; + + if (link->tx_failed || link->tx_success) + link->tx_percentage = + (link->tx_success * 100) / + (link->tx_failed + link->tx_success); + else + link->tx_percentage = 50; + + link->rx_success = 0; + link->rx_failed = 0; + link->tx_success = 0; + link->tx_failed = 0; +} + +static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev, + int rssi) { - struct link *link = &rt2x00dev->link; int rssi_percentage = 0; - int rx_percentage = 0; - int tx_percentage = 0; - int rssi = rt2x00_get_link_rssi(link); int signal; /* @@ -205,22 +217,14 @@ static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev) */ if (rt2x00dev->rssi_offset) rssi_percentage = (rssi * 100) / rt2x00dev->rssi_offset; - if (link->rx_failed || link->rx_success) - rx_percentage = - (link->rx_success * 100) / - (link->rx_failed + link->rx_success); - if (link->tx_failed || link->tx_success) - tx_percentage = - (link->tx_success * 100) / - (link->tx_failed + link->tx_success); /* * Add the individual percentages and use the WEIGHT * defines to calculate the current link signal. */ signal = ((WEIGHT_RSSI * rssi_percentage) + - (WEIGHT_TX * tx_percentage) + - (WEIGHT_RX * rx_percentage)) / 100; + (WEIGHT_TX * rt2x00dev->link.tx_percentage) + + (WEIGHT_RX * rt2x00dev->link.rx_percentage)) / 100; return (signal > 100) ? 100 : signal; } @@ -231,22 +235,15 @@ static void rt2x00lib_link_tuner(struct work_struct *work) container_of(work, struct rt2x00_dev, link.work.work); /* - * Reset statistics. - * This will cause the signal value to be - * based on the statistics of the last second. - */ - rt2x00dev->link.rx_success = 0; - rt2x00dev->link.rx_failed = 0; - rt2x00dev->link.tx_success = 0; - rt2x00dev->link.tx_failed = 0; - - /* * Update statistics. */ rt2x00dev->ops->lib->link_stats(rt2x00dev); + rt2x00dev->low_level_stats.dot11FCSErrorCount += rt2x00dev->link.rx_failed; + rt2x00lib_precalculate_link_signal(&rt2x00dev->link); + /* * Only perform the link tuning when Link tuning * has been enabled (This could have been disabled from the EEPROM). @@ -377,7 +374,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, rt2x00_update_link_rssi(&rt2x00dev->link, rssi); rt2x00dev->link.rx_success++; rx_status->rate = val; - rx_status->signal = rt2x00lib_calculate_link_signal(rt2x00dev); + rx_status->signal = rt2x00lib_calculate_link_signal(rt2x00dev, rssi); rx_status->ssi = rssi; /* -- 1.5.3 - To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html