Commit 9e495a26 authored by Sujith Manoharan's avatar Sujith Manoharan Committed by John W. Linville

ath9k: Remove ath9k rate control

There is no benefit in retaining the legacy rate control module
in the driver codebase.

It is known to be buggy and has less than optimal performance
in real-world environments compared with minstrel. The only
reason that it was kept when we made the switch to minstrel
as default was that it showed higher throughput numbers in a
clean/ideal environment.

This is no longer the case and minstrel can push ath9k to
the same throughput levels. In TCP, with 3-stream cards, more than
295 Mbps can be obtained in open air, with 2-stream cards,
210 Mbps is easily reached. To test performance issues,
instead of using a broken rate control module, it is better
to use the fixed-rate interface provided by mac80211 anyway.

The ath9k RC has not received any bug fixes in years and is
just bit-rotting away - this patch removes it.
Signed-off-by: default avatarSujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 482b30b6
...@@ -120,18 +120,6 @@ config ATH9K_WOW ...@@ -120,18 +120,6 @@ config ATH9K_WOW
This option enables Wake on Wireless LAN support for certain cards. This option enables Wake on Wireless LAN support for certain cards.
Currently, AR9462 is supported. Currently, AR9462 is supported.
config ATH9K_LEGACY_RATE_CONTROL
bool "Atheros ath9k rate control"
depends on ATH9K
default n
---help---
Say Y, if you want to use the ath9k specific rate control
module instead of minstrel_ht. Be warned that there are various
issues with the ath9k RC and minstrel is a more robust algorithm.
Note that even if this option is selected, "ath9k_rate_control"
has to be passed to mac80211 using the module parameter,
ieee80211_default_rc_algo.
config ATH9K_RFKILL config ATH9K_RFKILL
bool "Atheros ath9k rfkill support" if EXPERT bool "Atheros ath9k rfkill support" if EXPERT
depends on ATH9K depends on ATH9K
......
...@@ -8,7 +8,6 @@ ath9k-y += beacon.o \ ...@@ -8,7 +8,6 @@ ath9k-y += beacon.o \
antenna.o antenna.o
ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o
ath9k-$(CONFIG_ATH9K_PCI) += pci.o ath9k-$(CONFIG_ATH9K_PCI) += pci.o
ath9k-$(CONFIG_ATH9K_AHB) += ahb.o ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "spectral.h" #include "spectral.h"
struct ath_node; struct ath_node;
struct ath_rate_table;
extern struct ieee80211_ops ath9k_ops; extern struct ieee80211_ops ath9k_ops;
extern int ath9k_modparam_nohwcrypt; extern int ath9k_modparam_nohwcrypt;
...@@ -150,6 +149,11 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, ...@@ -150,6 +149,11 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) #define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e))
#define IS_OFDM_RATE(rate) ((rate >= 0x8) && (rate <= 0xf)) #define IS_OFDM_RATE(rate) ((rate >= 0x8) && (rate <= 0xf))
enum {
WLAN_RC_PHY_OFDM,
WLAN_RC_PHY_CCK,
};
struct ath_txq { struct ath_txq {
int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
u32 axq_qnum; /* ath9k hardware queue number */ u32 axq_qnum; /* ath9k hardware queue number */
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#define DEBUG_H #define DEBUG_H
#include "hw.h" #include "hw.h"
#include "rc.h"
#include "dfs_debug.h" #include "dfs_debug.h"
struct ath_txq; struct ath_txq;
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include "hw.h" #include "hw.h"
struct ath_softc;
/** /**
* struct ath_dfs_stats - DFS Statistics per wiphy * struct ath_dfs_stats - DFS Statistics per wiphy
* @pulses_total: pulses reported by HW * @pulses_total: pulses reported by HW
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "hw.h" #include "hw.h"
#include "hw-ops.h" #include "hw-ops.h"
#include "rc.h"
#include "ar9003_mac.h" #include "ar9003_mac.h"
#include "ar9003_mci.h" #include "ar9003_mci.h"
#include "ar9003_phy.h" #include "ar9003_phy.h"
......
...@@ -1100,19 +1100,11 @@ static int __init ath9k_init(void) ...@@ -1100,19 +1100,11 @@ static int __init ath9k_init(void)
{ {
int error; int error;
/* Register rate control algorithm */
error = ath_rate_control_register();
if (error != 0) {
pr_err("Unable to register rate control algorithm: %d\n",
error);
goto err_out;
}
error = ath_pci_init(); error = ath_pci_init();
if (error < 0) { if (error < 0) {
pr_err("No PCI devices found, driver not installed\n"); pr_err("No PCI devices found, driver not installed\n");
error = -ENODEV; error = -ENODEV;
goto err_rate_unregister; goto err_out;
} }
error = ath_ahb_init(); error = ath_ahb_init();
...@@ -1125,9 +1117,6 @@ static int __init ath9k_init(void) ...@@ -1125,9 +1117,6 @@ static int __init ath9k_init(void)
err_pci_exit: err_pci_exit:
ath_pci_exit(); ath_pci_exit();
err_rate_unregister:
ath_rate_control_unregister();
err_out: err_out:
return error; return error;
} }
...@@ -1138,7 +1127,6 @@ static void __exit ath9k_exit(void) ...@@ -1138,7 +1127,6 @@ static void __exit ath9k_exit(void)
is_ath9k_unloaded = true; is_ath9k_unloaded = true;
ath_ahb_exit(); ath_ahb_exit();
ath_pci_exit(); ath_pci_exit();
ath_rate_control_unregister();
pr_info("%s: Driver unloaded\n", dev_info); pr_info("%s: Driver unloaded\n", dev_info);
} }
module_exit(ath9k_exit); module_exit(ath9k_exit);
This diff is collapsed.
/*
* Copyright (c) 2004 Sam Leffler, Errno Consulting
* Copyright (c) 2004 Video54 Technologies, Inc.
* Copyright (c) 2008-2011 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef RC_H
#define RC_H
#include "hw.h"
struct ath_softc;
#define ATH_RATE_MAX 30
#define RATE_TABLE_SIZE 72
#define RC_INVALID 0x0000
#define RC_LEGACY 0x0001
#define RC_SS 0x0002
#define RC_DS 0x0004
#define RC_TS 0x0008
#define RC_HT_20 0x0010
#define RC_HT_40 0x0020
#define RC_STREAM_MASK 0xe
#define RC_DS_OR_LATER(f) ((((f) & RC_STREAM_MASK) == RC_DS) || \
(((f) & RC_STREAM_MASK) == (RC_DS | RC_TS)))
#define RC_TS_ONLY(f) (((f) & RC_STREAM_MASK) == RC_TS)
#define RC_SS_OR_LEGACY(f) ((f) & (RC_SS | RC_LEGACY))
#define RC_HT_2040 (RC_HT_20 | RC_HT_40)
#define RC_ALL_STREAM (RC_SS | RC_DS | RC_TS)
#define RC_L_SD (RC_LEGACY | RC_SS | RC_DS)
#define RC_L_SDT (RC_LEGACY | RC_SS | RC_DS | RC_TS)
#define RC_HT_S_20 (RC_HT_20 | RC_SS)
#define RC_HT_D_20 (RC_HT_20 | RC_DS)
#define RC_HT_T_20 (RC_HT_20 | RC_TS)
#define RC_HT_S_40 (RC_HT_40 | RC_SS)
#define RC_HT_D_40 (RC_HT_40 | RC_DS)
#define RC_HT_T_40 (RC_HT_40 | RC_TS)
#define RC_HT_SD_20 (RC_HT_20 | RC_SS | RC_DS)
#define RC_HT_DT_20 (RC_HT_20 | RC_DS | RC_TS)
#define RC_HT_SD_40 (RC_HT_40 | RC_SS | RC_DS)
#define RC_HT_DT_40 (RC_HT_40 | RC_DS | RC_TS)
#define RC_HT_SD_2040 (RC_HT_2040 | RC_SS | RC_DS)
#define RC_HT_SDT_2040 (RC_HT_2040 | RC_SS | RC_DS | RC_TS)
#define RC_HT_SDT_20 (RC_HT_20 | RC_SS | RC_DS | RC_TS)
#define RC_HT_SDT_40 (RC_HT_40 | RC_SS | RC_DS | RC_TS)
#define RC_ALL (RC_LEGACY | RC_HT_2040 | RC_ALL_STREAM)
enum {
WLAN_RC_PHY_OFDM,
WLAN_RC_PHY_CCK,
WLAN_RC_PHY_HT_20_SS,
WLAN_RC_PHY_HT_20_DS,
WLAN_RC_PHY_HT_20_TS,
WLAN_RC_PHY_HT_40_SS,
WLAN_RC_PHY_HT_40_DS,
WLAN_RC_PHY_HT_40_TS,
WLAN_RC_PHY_HT_20_SS_HGI,
WLAN_RC_PHY_HT_20_DS_HGI,
WLAN_RC_PHY_HT_20_TS_HGI,
WLAN_RC_PHY_HT_40_SS_HGI,
WLAN_RC_PHY_HT_40_DS_HGI,
WLAN_RC_PHY_HT_40_TS_HGI,
WLAN_RC_PHY_MAX
};
#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
|| (_phy == WLAN_RC_PHY_HT_40_DS) \
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
#define WLAN_RC_PHY_TS(_phy) ((_phy == WLAN_RC_PHY_HT_20_TS) \
|| (_phy == WLAN_RC_PHY_HT_40_TS) \
|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
#define WLAN_RC_PHY_20(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS) \
|| (_phy == WLAN_RC_PHY_HT_20_DS) \
|| (_phy == WLAN_RC_PHY_HT_20_TS) \
|| (_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI))
#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \
|| (_phy == WLAN_RC_PHY_HT_40_DS) \
|| (_phy == WLAN_RC_PHY_HT_40_TS) \
|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
#define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \
|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
#define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS)
#define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \
((capflag & WLAN_RC_40_FLAG) ? RC_HT_40 : RC_HT_20) : RC_LEGACY))
#define WLAN_RC_CAP_STREAM(capflag) (((capflag & WLAN_RC_TS_FLAG) ? \
(RC_TS) : ((capflag & WLAN_RC_DS_FLAG) ? RC_DS : RC_SS)))
/* Return TRUE if flag supports HT20 && client supports HT20 or
* return TRUE if flag supports HT40 && client supports HT40.
* This is used becos some rates overlap between HT20/HT40.
*/
#define WLAN_RC_PHY_HT_VALID(flag, capflag) \
(((flag & RC_HT_20) && !(capflag & WLAN_RC_40_FLAG)) || \
((flag & RC_HT_40) && (capflag & WLAN_RC_40_FLAG)))
#define WLAN_RC_DS_FLAG (0x01)
#define WLAN_RC_TS_FLAG (0x02)
#define WLAN_RC_40_FLAG (0x04)
#define WLAN_RC_SGI_FLAG (0x08)
#define WLAN_RC_HT_FLAG (0x10)
/**
* struct ath_rate_table - Rate Control table
* @rate_cnt: total number of rates for the given wireless mode
* @mcs_start: MCS rate index offset
* @rate_flags: Rate Control flags
* @phy: CCK/OFDM/HT20/HT40
* @ratekbps: rate in Kbits per second
* @user_ratekbps: user rate in Kbits per second
* @ratecode: rate that goes into HW descriptors
* @dot11rate: value that goes into supported
* rates info element of MLME
* @ctrl_rate: Index of next lower basic rate, used for duration computation
* @cw40index: Index of rates having 40MHz channel width
* @sgi_index: Index of rates having Short Guard Interval
* @ht_index: high throughput rates having 40MHz channel width and
* Short Guard Interval
* @probe_interval: interval for rate control to probe for other rates
* @initial_ratemax: initial ratemax value
*/
struct ath_rate_table {
int rate_cnt;
int mcs_start;
struct {
u16 rate_flags;
u8 phy;
u32 ratekbps;
u32 user_ratekbps;
u8 ratecode;
u8 dot11rate;
} info[RATE_TABLE_SIZE];
u32 probe_interval;
u8 initial_ratemax;
};
struct ath_rateset {
u8 rs_nrates;
u8 rs_rates[ATH_RATE_MAX];
};
struct ath_rc_stats {
u32 success;
u32 retries;
u32 xretries;
u8 per;
};
/**
* struct ath_rate_priv - Rate Control priv data
* @state: RC state
* @probe_rate: rate we are probing at
* @probe_time: msec timestamp for last probe
* @hw_maxretry_pktcnt: num of packets since we got HW max retry error
* @max_valid_rate: maximum number of valid rate
* @per_down_time: msec timestamp for last PER down step
* @valid_phy_ratecnt: valid rate count
* @rate_max_phy: phy index for the max rate
* @per: PER for every valid rate in %
* @probe_interval: interval for ratectrl to probe for other rates
* @ht_cap: HT capabilities
* @neg_rates: Negotatied rates
* @neg_ht_rates: Negotiated HT rates
*/
struct ath_rate_priv {
u8 rate_table_size;
u8 probe_rate;
u8 hw_maxretry_pktcnt;
u8 max_valid_rate;
u8 valid_rate_index[RATE_TABLE_SIZE];
u8 ht_cap;
u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
u8 rate_max_phy;
u8 per[RATE_TABLE_SIZE];
u32 probe_time;
u32 per_down_time;
u32 probe_interval;
struct ath_rateset neg_rates;
struct ath_rateset neg_ht_rates;
const struct ath_rate_table *rate_table;
#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
struct dentry *debugfs_rcstats;
struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
#endif
};
#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate);
void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
int xretries, int retries, u8 per);
#else
static inline void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
{
}
static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
int xretries, int retries, u8 per)
{
}
#endif
#ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL
int ath_rate_control_register(void);
void ath_rate_control_unregister(void);
#else
static inline int ath_rate_control_register(void)
{
return 0;
}
static inline void ath_rate_control_unregister(void)
{
}
#endif
#endif /* RC_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment