aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2014-02-05 23:52:55 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-02-12 15:36:04 -0500
commit9e495a2603334f9c8fcc6802300c22fc8a0eae02 (patch)
treee26922f0ccd4fb01bcaad53500f69977494e4fdc
parent482b30b653e2be8aa1bf70b7aaac56ff0aeb070c (diff)
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: Sujith Manoharan <c_manoha@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig12
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs_debug.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c1494
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h248
9 files changed, 8 insertions, 1771 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 7b96b3e5712d..8fcc029a76a6 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -120,18 +120,6 @@ config ATH9K_WOW
120 This option enables Wake on Wireless LAN support for certain cards. 120 This option enables Wake on Wireless LAN support for certain cards.
121 Currently, AR9462 is supported. 121 Currently, AR9462 is supported.
122 122
123config ATH9K_LEGACY_RATE_CONTROL
124 bool "Atheros ath9k rate control"
125 depends on ATH9K
126 default n
127 ---help---
128 Say Y, if you want to use the ath9k specific rate control
129 module instead of minstrel_ht. Be warned that there are various
130 issues with the ath9k RC and minstrel is a more robust algorithm.
131 Note that even if this option is selected, "ath9k_rate_control"
132 has to be passed to mac80211 using the module parameter,
133 ieee80211_default_rc_algo.
134
135config ATH9K_RFKILL 123config ATH9K_RFKILL
136 bool "Atheros ath9k rfkill support" if EXPERT 124 bool "Atheros ath9k rfkill support" if EXPERT
137 depends on ATH9K 125 depends on ATH9K
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index a40e5c5d7418..747975e1860a 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -8,7 +8,6 @@ ath9k-y += beacon.o \
8 antenna.o 8 antenna.o
9 9
10ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o 10ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
11ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o
12ath9k-$(CONFIG_ATH9K_PCI) += pci.o 11ath9k-$(CONFIG_ATH9K_PCI) += pci.o
13ath9k-$(CONFIG_ATH9K_AHB) += ahb.o 12ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
14ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o 13ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index ff3747c2fc08..21d13bc99c5a 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -30,7 +30,6 @@
30#include "spectral.h" 30#include "spectral.h"
31 31
32struct ath_node; 32struct ath_node;
33struct ath_rate_table;
34 33
35extern struct ieee80211_ops ath9k_ops; 34extern struct ieee80211_ops ath9k_ops;
36extern int ath9k_modparam_nohwcrypt; 35extern int ath9k_modparam_nohwcrypt;
@@ -150,6 +149,11 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
150#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) 149#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e))
151#define IS_OFDM_RATE(rate) ((rate >= 0x8) && (rate <= 0xf)) 150#define IS_OFDM_RATE(rate) ((rate >= 0x8) && (rate <= 0xf))
152 151
152enum {
153 WLAN_RC_PHY_OFDM,
154 WLAN_RC_PHY_CCK,
155};
156
153struct ath_txq { 157struct ath_txq {
154 int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ 158 int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
155 u32 axq_qnum; /* ath9k hardware queue number */ 159 u32 axq_qnum; /* ath9k hardware queue number */
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index cc7a025d833e..559a68c2709c 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -18,7 +18,6 @@
18#define DEBUG_H 18#define DEBUG_H
19 19
20#include "hw.h" 20#include "hw.h"
21#include "rc.h"
22#include "dfs_debug.h" 21#include "dfs_debug.h"
23 22
24struct ath_txq; 23struct ath_txq;
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.h b/drivers/net/wireless/ath/ath9k/dfs_debug.h
index 0a7ddf4c88c9..7936c9126a20 100644
--- a/drivers/net/wireless/ath/ath9k/dfs_debug.h
+++ b/drivers/net/wireless/ath/ath9k/dfs_debug.h
@@ -21,6 +21,8 @@
21 21
22#include "hw.h" 22#include "hw.h"
23 23
24struct ath_softc;
25
24/** 26/**
25 * struct ath_dfs_stats - DFS Statistics per wiphy 27 * struct ath_dfs_stats - DFS Statistics per wiphy
26 * @pulses_total: pulses reported by HW 28 * @pulses_total: pulses reported by HW
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index fbf43c05713f..15b8e783d1a7 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -23,7 +23,6 @@
23 23
24#include "hw.h" 24#include "hw.h"
25#include "hw-ops.h" 25#include "hw-ops.h"
26#include "rc.h"
27#include "ar9003_mac.h" 26#include "ar9003_mac.h"
28#include "ar9003_mci.h" 27#include "ar9003_mci.h"
29#include "ar9003_phy.h" 28#include "ar9003_phy.h"
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 00e0f606a0d3..67411d21c9a5 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -1100,19 +1100,11 @@ static int __init ath9k_init(void)
1100{ 1100{
1101 int error; 1101 int error;
1102 1102
1103 /* Register rate control algorithm */
1104 error = ath_rate_control_register();
1105 if (error != 0) {
1106 pr_err("Unable to register rate control algorithm: %d\n",
1107 error);
1108 goto err_out;
1109 }
1110
1111 error = ath_pci_init(); 1103 error = ath_pci_init();
1112 if (error < 0) { 1104 if (error < 0) {
1113 pr_err("No PCI devices found, driver not installed\n"); 1105 pr_err("No PCI devices found, driver not installed\n");
1114 error = -ENODEV; 1106 error = -ENODEV;
1115 goto err_rate_unregister; 1107 goto err_out;
1116 } 1108 }
1117 1109
1118 error = ath_ahb_init(); 1110 error = ath_ahb_init();
@@ -1125,9 +1117,6 @@ static int __init ath9k_init(void)
1125 1117
1126 err_pci_exit: 1118 err_pci_exit:
1127 ath_pci_exit(); 1119 ath_pci_exit();
1128
1129 err_rate_unregister:
1130 ath_rate_control_unregister();
1131 err_out: 1120 err_out:
1132 return error; 1121 return error;
1133} 1122}
@@ -1138,7 +1127,6 @@ static void __exit ath9k_exit(void)
1138 is_ath9k_unloaded = true; 1127 is_ath9k_unloaded = true;
1139 ath_ahb_exit(); 1128 ath_ahb_exit();
1140 ath_pci_exit(); 1129 ath_pci_exit();
1141 ath_rate_control_unregister();
1142 pr_info("%s: Driver unloaded\n", dev_info); 1130 pr_info("%s: Driver unloaded\n", dev_info);
1143} 1131}
1144module_exit(ath9k_exit); 1132module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
deleted file mode 100644
index 7b5afee141da..000000000000
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ /dev/null
@@ -1,1494 +0,0 @@
1/*
2 * Copyright (c) 2004 Video54 Technologies, Inc.
3 * Copyright (c) 2004-2011 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <linux/slab.h>
19#include <linux/export.h>
20
21#include "ath9k.h"
22
23static const struct ath_rate_table ar5416_11na_ratetable = {
24 68,
25 8, /* MCS start */
26 {
27 [0] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000,
28 5400, 0, 12 }, /* 6 Mb */
29 [1] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000,
30 7800, 1, 18 }, /* 9 Mb */
31 [2] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000,
32 10000, 2, 24 }, /* 12 Mb */
33 [3] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000,
34 13900, 3, 36 }, /* 18 Mb */
35 [4] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000,
36 17300, 4, 48 }, /* 24 Mb */
37 [5] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000,
38 23000, 5, 72 }, /* 36 Mb */
39 [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000,
40 27400, 6, 96 }, /* 48 Mb */
41 [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000,
42 29300, 7, 108 }, /* 54 Mb */
43 [8] = { RC_HT_SDT_2040, WLAN_RC_PHY_HT_20_SS, 6500,
44 6400, 0, 0 }, /* 6.5 Mb */
45 [9] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000,
46 12700, 1, 1 }, /* 13 Mb */
47 [10] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500,
48 18800, 2, 2 }, /* 19.5 Mb */
49 [11] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000,
50 25000, 3, 3 }, /* 26 Mb */
51 [12] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000,
52 36700, 4, 4 }, /* 39 Mb */
53 [13] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000,
54 48100, 5, 5 }, /* 52 Mb */
55 [14] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500,
56 53500, 6, 6 }, /* 58.5 Mb */
57 [15] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000,
58 59000, 7, 7 }, /* 65 Mb */
59 [16] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200,
60 65400, 7, 7 }, /* 75 Mb */
61 [17] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000,
62 12700, 8, 8 }, /* 13 Mb */
63 [18] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000,
64 24800, 9, 9 }, /* 26 Mb */
65 [19] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000,
66 36600, 10, 10 }, /* 39 Mb */
67 [20] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000,
68 48100, 11, 11 }, /* 52 Mb */
69 [21] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000,
70 69500, 12, 12 }, /* 78 Mb */
71 [22] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000,
72 89500, 13, 13 }, /* 104 Mb */
73 [23] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000,
74 98900, 14, 14 }, /* 117 Mb */
75 [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
76 108300, 15, 15 }, /* 130 Mb */
77 [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
78 120000, 15, 15 }, /* 144.4 Mb */
79 [26] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
80 17400, 16, 16 }, /* 19.5 Mb */
81 [27] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
82 35100, 17, 17 }, /* 39 Mb */
83 [28] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500,
84 52600, 18, 18 }, /* 58.5 Mb */
85 [29] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000,
86 70400, 19, 19 }, /* 78 Mb */
87 [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000,
88 104900, 20, 20 }, /* 117 Mb */
89 [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000,
90 115800, 20, 20 }, /* 130 Mb*/
91 [32] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000,
92 137200, 21, 21 }, /* 156 Mb */
93 [33] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300,
94 151100, 21, 21 }, /* 173.3 Mb */
95 [34] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500,
96 152800, 22, 22 }, /* 175.5 Mb */
97 [35] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000,
98 168400, 22, 22 }, /* 195 Mb*/
99 [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000,
100 168400, 23, 23 }, /* 195 Mb */
101 [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700,
102 185000, 23, 23 }, /* 216.7 Mb */
103 [38] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500,
104 13200, 0, 0 }, /* 13.5 Mb*/
105 [39] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500,
106 25900, 1, 1 }, /* 27.0 Mb*/
107 [40] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500,
108 38600, 2, 2 }, /* 40.5 Mb*/
109 [41] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000,
110 49800, 3, 3 }, /* 54 Mb */
111 [42] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500,
112 72200, 4, 4 }, /* 81 Mb */
113 [43] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000,
114 92900, 5, 5 }, /* 108 Mb */
115 [44] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500,
116 102700, 6, 6 }, /* 121.5 Mb*/
117 [45] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000,
118 112000, 7, 7 }, /* 135 Mb */
119 [46] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000,
120 122000, 7, 7 }, /* 150 Mb */
121 [47] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000,
122 25800, 8, 8 }, /* 27 Mb */
123 [48] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000,
124 49800, 9, 9 }, /* 54 Mb */
125 [49] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000,
126 71900, 10, 10 }, /* 81 Mb */
127 [50] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000,
128 92500, 11, 11 }, /* 108 Mb */
129 [51] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000,
130 130300, 12, 12 }, /* 162 Mb */
131 [52] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000,
132 162800, 13, 13 }, /* 216 Mb */
133 [53] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000,
134 178200, 14, 14 }, /* 243 Mb */
135 [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000,
136 192100, 15, 15 }, /* 270 Mb */
137 [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000,
138 207000, 15, 15 }, /* 300 Mb */
139 [56] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500,
140 36100, 16, 16 }, /* 40.5 Mb */
141 [57] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000,
142 72900, 17, 17 }, /* 81 Mb */
143 [58] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500,
144 108300, 18, 18 }, /* 121.5 Mb */
145 [59] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000,
146 142000, 19, 19 }, /* 162 Mb */
147 [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
148 205100, 20, 20 }, /* 243 Mb */
149 [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
150 224700, 20, 20 }, /* 270 Mb */
151 [62] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
152 263100, 21, 21 }, /* 324 Mb */
153 [63] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
154 288000, 21, 21 }, /* 360 Mb */
155 [64] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500,
156 290700, 22, 22 }, /* 364.5 Mb */
157 [65] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000,
158 317200, 22, 22 }, /* 405 Mb */
159 [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000,
160 317200, 23, 23 }, /* 405 Mb */
161 [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000,
162 346400, 23, 23 }, /* 450 Mb */
163 },
164 50, /* probe interval */
165 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
166};
167
168/* 4ms frame limit not used for NG mode. The values filled
169 * for HT are the 64K max aggregate limit */
170
171static const struct ath_rate_table ar5416_11ng_ratetable = {
172 72,
173 12, /* MCS start */
174 {
175 [0] = { RC_ALL, WLAN_RC_PHY_CCK, 1000,
176 900, 0, 2 }, /* 1 Mb */
177 [1] = { RC_ALL, WLAN_RC_PHY_CCK, 2000,
178 1900, 1, 4 }, /* 2 Mb */
179 [2] = { RC_ALL, WLAN_RC_PHY_CCK, 5500,
180 4900, 2, 11 }, /* 5.5 Mb */
181 [3] = { RC_ALL, WLAN_RC_PHY_CCK, 11000,
182 8100, 3, 22 }, /* 11 Mb */
183 [4] = { RC_INVALID, WLAN_RC_PHY_OFDM, 6000,
184 5400, 4, 12 }, /* 6 Mb */
185 [5] = { RC_INVALID, WLAN_RC_PHY_OFDM, 9000,
186 7800, 5, 18 }, /* 9 Mb */
187 [6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000,
188 10100, 6, 24 }, /* 12 Mb */
189 [7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000,
190 14100, 7, 36 }, /* 18 Mb */
191 [8] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000,
192 17700, 8, 48 }, /* 24 Mb */
193 [9] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000,
194 23700, 9, 72 }, /* 36 Mb */
195 [10] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000,
196 27400, 10, 96 }, /* 48 Mb */
197 [11] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000,
198 30900, 11, 108 }, /* 54 Mb */
199 [12] = { RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500,
200 6400, 0, 0 }, /* 6.5 Mb */
201 [13] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000,
202 12700, 1, 1 }, /* 13 Mb */
203 [14] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500,
204 18800, 2, 2 }, /* 19.5 Mb*/
205 [15] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000,
206 25000, 3, 3 }, /* 26 Mb */
207 [16] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000,
208 36700, 4, 4 }, /* 39 Mb */
209 [17] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000,
210 48100, 5, 5 }, /* 52 Mb */
211 [18] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500,
212 53500, 6, 6 }, /* 58.5 Mb */
213 [19] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000,
214 59000, 7, 7 }, /* 65 Mb */
215 [20] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200,
216 65400, 7, 7 }, /* 65 Mb*/
217 [21] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000,
218 12700, 8, 8 }, /* 13 Mb */
219 [22] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000,
220 24800, 9, 9 }, /* 26 Mb */
221 [23] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000,
222 36600, 10, 10 }, /* 39 Mb */
223 [24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000,
224 48100, 11, 11 }, /* 52 Mb */
225 [25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000,
226 69500, 12, 12 }, /* 78 Mb */
227 [26] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000,
228 89500, 13, 13 }, /* 104 Mb */
229 [27] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000,
230 98900, 14, 14 }, /* 117 Mb */
231 [28] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
232 108300, 15, 15 }, /* 130 Mb */
233 [29] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
234 120000, 15, 15 }, /* 144.4 Mb */
235 [30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
236 17400, 16, 16 }, /* 19.5 Mb */
237 [31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
238 35100, 17, 17 }, /* 39 Mb */
239 [32] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500,
240 52600, 18, 18 }, /* 58.5 Mb */
241 [33] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000,
242 70400, 19, 19 }, /* 78 Mb */
243 [34] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000,
244 104900, 20, 20 }, /* 117 Mb */
245 [35] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000,
246 115800, 20, 20 }, /* 130 Mb */
247 [36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000,
248 137200, 21, 21 }, /* 156 Mb */
249 [37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300,
250 151100, 21, 21 }, /* 173.3 Mb */
251 [38] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500,
252 152800, 22, 22 }, /* 175.5 Mb */
253 [39] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000,
254 168400, 22, 22 }, /* 195 Mb */
255 [40] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000,
256 168400, 23, 23 }, /* 195 Mb */
257 [41] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700,
258 185000, 23, 23 }, /* 216.7 Mb */
259 [42] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500,
260 13200, 0, 0 }, /* 13.5 Mb */
261 [43] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500,
262 25900, 1, 1 }, /* 27.0 Mb */
263 [44] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500,
264 38600, 2, 2 }, /* 40.5 Mb */
265 [45] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000,
266 49800, 3, 3 }, /* 54 Mb */
267 [46] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500,
268 72200, 4, 4 }, /* 81 Mb */
269 [47] = { RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000,
270 92900, 5, 5 }, /* 108 Mb */
271 [48] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500,
272 102700, 6, 6 }, /* 121.5 Mb */
273 [49] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000,
274 112000, 7, 7 }, /* 135 Mb */
275 [50] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000,
276 122000, 7, 7 }, /* 150 Mb */
277 [51] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000,
278 25800, 8, 8 }, /* 27 Mb */
279 [52] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000,
280 49800, 9, 9 }, /* 54 Mb */
281 [53] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000,
282 71900, 10, 10 }, /* 81 Mb */
283 [54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000,
284 92500, 11, 11 }, /* 108 Mb */
285 [55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000,
286 130300, 12, 12 }, /* 162 Mb */
287 [56] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000,
288 162800, 13, 13 }, /* 216 Mb */
289 [57] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000,
290 178200, 14, 14 }, /* 243 Mb */
291 [58] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000,
292 192100, 15, 15 }, /* 270 Mb */
293 [59] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000,
294 207000, 15, 15 }, /* 300 Mb */
295 [60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500,
296 36100, 16, 16 }, /* 40.5 Mb */
297 [61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000,
298 72900, 17, 17 }, /* 81 Mb */
299 [62] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500,
300 108300, 18, 18 }, /* 121.5 Mb */
301 [63] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000,
302 142000, 19, 19 }, /* 162 Mb */
303 [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
304 205100, 20, 20 }, /* 243 Mb */
305 [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
306 224700, 20, 20 }, /* 270 Mb */
307 [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
308 263100, 21, 21 }, /* 324 Mb */
309 [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
310 288000, 21, 21 }, /* 360 Mb */
311 [68] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500,
312 290700, 22, 22 }, /* 364.5 Mb */
313 [69] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000,
314 317200, 22, 22 }, /* 405 Mb */
315 [70] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000,
316 317200, 23, 23 }, /* 405 Mb */
317 [71] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000,
318 346400, 23, 23 }, /* 450 Mb */
319 },
320 50, /* probe interval */
321 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
322};
323
324static const struct ath_rate_table ar5416_11a_ratetable = {
325 8,
326 0,
327 {
328 { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
329 5400, 0, 12},
330 { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
331 7800, 1, 18},
332 { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
333 10000, 2, 24},
334 { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
335 13900, 3, 36},
336 { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
337 17300, 4, 48},
338 { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
339 23000, 5, 72},
340 { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
341 27400, 6, 96},
342 { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
343 29300, 7, 108},
344 },
345 50, /* probe interval */
346 0, /* Phy rates allowed initially */
347};
348
349static const struct ath_rate_table ar5416_11g_ratetable = {
350 12,
351 0,
352 {
353 { RC_L_SDT, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
354 900, 0, 2},
355 { RC_L_SDT, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
356 1900, 1, 4},
357 { RC_L_SDT, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
358 4900, 2, 11},
359 { RC_L_SDT, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
360 8100, 3, 22},
361 { RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
362 5400, 4, 12},
363 { RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
364 7800, 5, 18},
365 { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
366 10000, 6, 24},
367 { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
368 13900, 7, 36},
369 { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
370 17300, 8, 48},
371 { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
372 23000, 9, 72},
373 { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
374 27400, 10, 96},
375 { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
376 29300, 11, 108},
377 },
378 50, /* probe interval */
379 0, /* Phy rates allowed initially */
380};
381
382static int ath_rc_get_rateindex(struct ath_rate_priv *ath_rc_priv,
383 struct ieee80211_tx_rate *rate)
384{
385 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
386 int rix, i, idx = 0;
387
388 if (!(rate->flags & IEEE80211_TX_RC_MCS))
389 return rate->idx;
390
391 for (i = 0; i < ath_rc_priv->max_valid_rate; i++) {
392 idx = ath_rc_priv->valid_rate_index[i];
393
394 if (WLAN_RC_PHY_HT(rate_table->info[idx].phy) &&
395 rate_table->info[idx].ratecode == rate->idx)
396 break;
397 }
398
399 rix = idx;
400
401 if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
402 rix++;
403
404 return rix;
405}
406
407static void ath_rc_sort_validrates(struct ath_rate_priv *ath_rc_priv)
408{
409 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
410 u8 i, j, idx, idx_next;
411
412 for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) {
413 for (j = 0; j <= i-1; j++) {
414 idx = ath_rc_priv->valid_rate_index[j];
415 idx_next = ath_rc_priv->valid_rate_index[j+1];
416
417 if (rate_table->info[idx].ratekbps >
418 rate_table->info[idx_next].ratekbps) {
419 ath_rc_priv->valid_rate_index[j] = idx_next;
420 ath_rc_priv->valid_rate_index[j+1] = idx;
421 }
422 }
423 }
424}
425
426static inline
427int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
428 struct ath_rate_priv *ath_rc_priv,
429 u8 cur_valid_txrate,
430 u8 *next_idx)
431{
432 u8 i;
433
434 for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) {
435 if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
436 *next_idx = ath_rc_priv->valid_rate_index[i+1];
437 return 1;
438 }
439 }
440
441 /* No more valid rates */
442 *next_idx = 0;
443
444 return 0;
445}
446
447/* Return true only for single stream */
448
449static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
450{
451 if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
452 return 0;
453 if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
454 return 0;
455 if (WLAN_RC_PHY_TS(phy) && !(capflag & WLAN_RC_TS_FLAG))
456 return 0;
457 if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
458 return 0;
459 if (!ignore_cw && WLAN_RC_PHY_HT(phy))
460 if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
461 return 0;
462 return 1;
463}
464
465static inline int
466ath_rc_get_lower_rix(struct ath_rate_priv *ath_rc_priv,
467 u8 cur_valid_txrate, u8 *next_idx)
468{
469 int8_t i;
470
471 for (i = 1; i < ath_rc_priv->max_valid_rate ; i++) {
472 if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
473 *next_idx = ath_rc_priv->valid_rate_index[i-1];
474 return 1;
475 }
476 }
477
478 return 0;
479}
480
481static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv)
482{
483 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
484 u8 i, hi = 0;
485
486 for (i = 0; i < rate_table->rate_cnt; i++) {
487 if (rate_table->info[i].rate_flags & RC_LEGACY) {
488 u32 phy = rate_table->info[i].phy;
489 u8 valid_rate_count = 0;
490
491 if (!ath_rc_valid_phyrate(phy, ath_rc_priv->ht_cap, 0))
492 continue;
493
494 valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
495
496 ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
497 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
498 ath_rc_priv->valid_rate_index[i] = true;
499 hi = i;
500 }
501 }
502
503 return hi;
504}
505
506static inline bool ath_rc_check_legacy(u8 rate, u8 dot11rate, u16 rate_flags,
507 u32 phy, u32 capflag)
508{
509 if (rate != dot11rate || WLAN_RC_PHY_HT(phy))
510 return false;
511
512 if ((rate_flags & WLAN_RC_CAP_MODE(capflag)) != WLAN_RC_CAP_MODE(capflag))
513 return false;
514
515 if (!(rate_flags & WLAN_RC_CAP_STREAM(capflag)))
516 return false;
517
518 return true;
519}
520
521static inline bool ath_rc_check_ht(u8 rate, u8 dot11rate, u16 rate_flags,
522 u32 phy, u32 capflag)
523{
524 if (rate != dot11rate || !WLAN_RC_PHY_HT(phy))
525 return false;
526
527 if (!WLAN_RC_PHY_HT_VALID(rate_flags, capflag))
528 return false;
529
530 if (!(rate_flags & WLAN_RC_CAP_STREAM(capflag)))
531 return false;
532
533 return true;
534}
535
536static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, bool legacy)
537{
538 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
539 struct ath_rateset *rateset;
540 u32 phy, capflag = ath_rc_priv->ht_cap;
541 u16 rate_flags;
542 u8 i, j, hi = 0, rate, dot11rate, valid_rate_count;
543
544 if (legacy)
545 rateset = &ath_rc_priv->neg_rates;
546 else
547 rateset = &ath_rc_priv->neg_ht_rates;
548
549 for (i = 0; i < rateset->rs_nrates; i++) {
550 for (j = 0; j < rate_table->rate_cnt; j++) {
551 phy = rate_table->info[j].phy;
552 rate_flags = rate_table->info[j].rate_flags;
553 rate = rateset->rs_rates[i];
554 dot11rate = rate_table->info[j].dot11rate;
555
556 if (legacy &&
557 !ath_rc_check_legacy(rate, dot11rate,
558 rate_flags, phy, capflag))
559 continue;
560
561 if (!legacy &&
562 !ath_rc_check_ht(rate, dot11rate,
563 rate_flags, phy, capflag))
564 continue;
565
566 if (!ath_rc_valid_phyrate(phy, capflag, 0))
567 continue;
568
569 valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
570 ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = j;
571 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
572 ath_rc_priv->valid_rate_index[j] = true;
573 hi = max(hi, j);
574 }
575 }
576
577 return hi;
578}
579
580static u8 ath_rc_get_highest_rix(struct ath_rate_priv *ath_rc_priv,
581 int *is_probing)
582{
583 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
584 u32 best_thruput, this_thruput, now_msec;
585 u8 rate, next_rate, best_rate, maxindex, minindex;
586 int8_t index = 0;
587
588 now_msec = jiffies_to_msecs(jiffies);
589 *is_probing = 0;
590 best_thruput = 0;
591 maxindex = ath_rc_priv->max_valid_rate-1;
592 minindex = 0;
593 best_rate = minindex;
594
595 /*
596 * Try the higher rate first. It will reduce memory moving time
597 * if we have very good channel characteristics.
598 */
599 for (index = maxindex; index >= minindex ; index--) {
600 u8 per_thres;
601
602 rate = ath_rc_priv->valid_rate_index[index];
603 if (rate > ath_rc_priv->rate_max_phy)
604 continue;
605
606 /*
607 * For TCP the average collision rate is around 11%,
608 * so we ignore PERs less than this. This is to
609 * prevent the rate we are currently using (whose
610 * PER might be in the 10-15 range because of TCP
611 * collisions) looking worse than the next lower
612 * rate whose PER has decayed close to 0. If we
613 * used to next lower rate, its PER would grow to
614 * 10-15 and we would be worse off then staying
615 * at the current rate.
616 */
617 per_thres = ath_rc_priv->per[rate];
618 if (per_thres < 12)
619 per_thres = 12;
620
621 this_thruput = rate_table->info[rate].user_ratekbps *
622 (100 - per_thres);
623
624 if (best_thruput <= this_thruput) {
625 best_thruput = this_thruput;
626 best_rate = rate;
627 }
628 }
629
630 rate = best_rate;
631
632 /*
633 * Must check the actual rate (ratekbps) to account for
634 * non-monoticity of 11g's rate table
635 */
636
637 if (rate >= ath_rc_priv->rate_max_phy) {
638 rate = ath_rc_priv->rate_max_phy;
639
640 /* Probe the next allowed phy state */
641 if (ath_rc_get_nextvalid_txrate(rate_table,
642 ath_rc_priv, rate, &next_rate) &&
643 (now_msec - ath_rc_priv->probe_time >
644 rate_table->probe_interval) &&
645 (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
646 rate = next_rate;
647 ath_rc_priv->probe_rate = rate;
648 ath_rc_priv->probe_time = now_msec;
649 ath_rc_priv->hw_maxretry_pktcnt = 0;
650 *is_probing = 1;
651 }
652 }
653
654 if (rate > (ath_rc_priv->rate_table_size - 1))
655 rate = ath_rc_priv->rate_table_size - 1;
656
657 if (RC_TS_ONLY(rate_table->info[rate].rate_flags) &&
658 (ath_rc_priv->ht_cap & WLAN_RC_TS_FLAG))
659 return rate;
660
661 if (RC_DS_OR_LATER(rate_table->info[rate].rate_flags) &&
662 (ath_rc_priv->ht_cap & (WLAN_RC_DS_FLAG | WLAN_RC_TS_FLAG)))
663 return rate;
664
665 if (RC_SS_OR_LEGACY(rate_table->info[rate].rate_flags))
666 return rate;
667
668 /* This should not happen */
669 WARN_ON_ONCE(1);
670
671 rate = ath_rc_priv->valid_rate_index[0];
672
673 return rate;
674}
675
676static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
677 struct ieee80211_tx_rate *rate,
678 struct ieee80211_tx_rate_control *txrc,
679 u8 tries, u8 rix, int rtsctsenable)
680{
681 rate->count = tries;
682 rate->idx = rate_table->info[rix].ratecode;
683
684 if (txrc->rts || rtsctsenable)
685 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
686
687 if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) {
688 rate->flags |= IEEE80211_TX_RC_MCS;
689 if (WLAN_RC_PHY_40(rate_table->info[rix].phy) &&
690 conf_is_ht40(&txrc->hw->conf))
691 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
692 if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
693 rate->flags |= IEEE80211_TX_RC_SHORT_GI;
694 }
695}
696
697static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
698 const struct ath_rate_table *rate_table,
699 struct ieee80211_tx_info *tx_info)
700{
701 struct ieee80211_bss_conf *bss_conf;
702
703 if (!tx_info->control.vif)
704 return;
705 /*
706 * For legacy frames, mac80211 takes care of CTS protection.
707 */
708 if (!(tx_info->control.rates[0].flags & IEEE80211_TX_RC_MCS))
709 return;
710
711 bss_conf = &tx_info->control.vif->bss_conf;
712
713 if (!bss_conf->basic_rates)
714 return;
715
716 /*
717 * For now, use the lowest allowed basic rate for HT frames.
718 */
719 tx_info->control.rts_cts_rate_idx = __ffs(bss_conf->basic_rates);
720}
721
722static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
723 struct ieee80211_tx_rate_control *txrc)
724{
725 struct ath_softc *sc = priv;
726 struct ath_rate_priv *ath_rc_priv = priv_sta;
727 const struct ath_rate_table *rate_table;
728 struct sk_buff *skb = txrc->skb;
729 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
730 struct ieee80211_tx_rate *rates = tx_info->control.rates;
731 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
732 __le16 fc = hdr->frame_control;
733 u8 try_per_rate, i = 0, rix;
734 int is_probe = 0;
735
736 if (rate_control_send_low(sta, priv_sta, txrc))
737 return;
738
739 /*
740 * For Multi Rate Retry we use a different number of
741 * retry attempt counts. This ends up looking like this:
742 *
743 * MRR[0] = 4
744 * MRR[1] = 4
745 * MRR[2] = 4
746 * MRR[3] = 8
747 *
748 */
749 try_per_rate = 4;
750
751 rate_table = ath_rc_priv->rate_table;
752 rix = ath_rc_get_highest_rix(ath_rc_priv, &is_probe);
753
754 if (conf_is_ht(&sc->hw->conf) &&
755 (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
756 tx_info->flags |= IEEE80211_TX_CTL_LDPC;
757
758 if (conf_is_ht(&sc->hw->conf) &&
759 (sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC))
760 tx_info->flags |= (1 << IEEE80211_TX_CTL_STBC_SHIFT);
761
762 if (is_probe) {
763 /*
764 * Set one try for probe rates. For the
765 * probes don't enable RTS.
766 */
767 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
768 1, rix, 0);
769 /*
770 * Get the next tried/allowed rate.
771 * No RTS for the next series after the probe rate.
772 */
773 ath_rc_get_lower_rix(ath_rc_priv, rix, &rix);
774 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
775 try_per_rate, rix, 0);
776
777 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
778 } else {
779 /*
780 * Set the chosen rate. No RTS for first series entry.
781 */
782 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
783 try_per_rate, rix, 0);
784 }
785
786 for ( ; i < 4; i++) {
787 /*
788 * Use twice the number of tries for the last MRR segment.
789 */
790 if (i + 1 == 4)
791 try_per_rate = 8;
792
793 ath_rc_get_lower_rix(ath_rc_priv, rix, &rix);
794
795 /*
796 * All other rates in the series have RTS enabled.
797 */
798 ath_rc_rate_set_series(rate_table, &rates[i], txrc,
799 try_per_rate, rix, 1);
800 }
801
802 /*
803 * NB:Change rate series to enable aggregation when operating
804 * at lower MCS rates. When first rate in series is MCS2
805 * in HT40 @ 2.4GHz, series should look like:
806 *
807 * {MCS2, MCS1, MCS0, MCS0}.
808 *
809 * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should
810 * look like:
811 *
812 * {MCS3, MCS2, MCS1, MCS1}
813 *
814 * So, set fourth rate in series to be same as third one for
815 * above conditions.
816 */
817 if ((sc->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) &&
818 (conf_is_ht(&sc->hw->conf))) {
819 u8 dot11rate = rate_table->info[rix].dot11rate;
820 u8 phy = rate_table->info[rix].phy;
821 if (i == 4 &&
822 ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
823 (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
824 rates[3].idx = rates[2].idx;
825 rates[3].flags = rates[2].flags;
826 }
827 }
828
829 /*
830 * Force hardware to use computed duration for next
831 * fragment by disabling multi-rate retry, which
832 * updates duration based on the multi-rate duration table.
833 *
834 * FIXME: Fix duration
835 */
836 if (ieee80211_has_morefrags(fc) ||
837 (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
838 rates[1].count = rates[2].count = rates[3].count = 0;
839 rates[1].idx = rates[2].idx = rates[3].idx = 0;
840 rates[0].count = ATH_TXMAXTRY;
841 }
842
843 ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
844}
845
846static void ath_rc_update_per(struct ath_softc *sc,
847 const struct ath_rate_table *rate_table,
848 struct ath_rate_priv *ath_rc_priv,
849 struct ieee80211_tx_info *tx_info,
850 int tx_rate, int xretries, int retries,
851 u32 now_msec)
852{
853 int count, n_bad_frames;
854 u8 last_per;
855 static const u32 nretry_to_per_lookup[10] = {
856 100 * 0 / 1,
857 100 * 1 / 4,
858 100 * 1 / 2,
859 100 * 3 / 4,
860 100 * 4 / 5,
861 100 * 5 / 6,
862 100 * 6 / 7,
863 100 * 7 / 8,
864 100 * 8 / 9,
865 100 * 9 / 10
866 };
867
868 last_per = ath_rc_priv->per[tx_rate];
869 n_bad_frames = tx_info->status.ampdu_len - tx_info->status.ampdu_ack_len;
870
871 if (xretries) {
872 if (xretries == 1) {
873 ath_rc_priv->per[tx_rate] += 30;
874 if (ath_rc_priv->per[tx_rate] > 100)
875 ath_rc_priv->per[tx_rate] = 100;
876 } else {
877 /* xretries == 2 */
878 count = ARRAY_SIZE(nretry_to_per_lookup);
879 if (retries >= count)
880 retries = count - 1;
881
882 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
883 ath_rc_priv->per[tx_rate] =
884 (u8)(last_per - (last_per >> 3) + (100 >> 3));
885 }
886
887 /* xretries == 1 or 2 */
888
889 if (ath_rc_priv->probe_rate == tx_rate)
890 ath_rc_priv->probe_rate = 0;
891
892 } else { /* xretries == 0 */
893 count = ARRAY_SIZE(nretry_to_per_lookup);
894 if (retries >= count)
895 retries = count - 1;
896
897 if (n_bad_frames) {
898 /* new_PER = 7/8*old_PER + 1/8*(currentPER)
899 * Assuming that n_frames is not 0. The current PER
900 * from the retries is 100 * retries / (retries+1),
901 * since the first retries attempts failed, and the
902 * next one worked. For the one that worked,
903 * n_bad_frames subframes out of n_frames wored,
904 * so the PER for that part is
905 * 100 * n_bad_frames / n_frames, and it contributes
906 * 100 * n_bad_frames / (n_frames * (retries+1)) to
907 * the above PER. The expression below is a
908 * simplified version of the sum of these two terms.
909 */
910 if (tx_info->status.ampdu_len > 0) {
911 int n_frames, n_bad_tries;
912 u8 cur_per, new_per;
913
914 n_bad_tries = retries * tx_info->status.ampdu_len +
915 n_bad_frames;
916 n_frames = tx_info->status.ampdu_len * (retries + 1);
917 cur_per = (100 * n_bad_tries / n_frames) >> 3;
918 new_per = (u8)(last_per - (last_per >> 3) + cur_per);
919 ath_rc_priv->per[tx_rate] = new_per;
920 }
921 } else {
922 ath_rc_priv->per[tx_rate] =
923 (u8)(last_per - (last_per >> 3) +
924 (nretry_to_per_lookup[retries] >> 3));
925 }
926
927
928 /*
929 * If we got at most one retry then increase the max rate if
930 * this was a probe. Otherwise, ignore the probe.
931 */
932 if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
933 if (retries > 0 || 2 * n_bad_frames > tx_info->status.ampdu_len) {
934 /*
935 * Since we probed with just a single attempt,
936 * any retries means the probe failed. Also,
937 * if the attempt worked, but more than half
938 * the subframes were bad then also consider
939 * the probe a failure.
940 */
941 ath_rc_priv->probe_rate = 0;
942 } else {
943 u8 probe_rate = 0;
944
945 ath_rc_priv->rate_max_phy =
946 ath_rc_priv->probe_rate;
947 probe_rate = ath_rc_priv->probe_rate;
948
949 if (ath_rc_priv->per[probe_rate] > 30)
950 ath_rc_priv->per[probe_rate] = 20;
951
952 ath_rc_priv->probe_rate = 0;
953
954 /*
955 * Since this probe succeeded, we allow the next
956 * probe twice as soon. This allows the maxRate
957 * to move up faster if the probes are
958 * successful.
959 */
960 ath_rc_priv->probe_time =
961 now_msec - rate_table->probe_interval / 2;
962 }
963 }
964
965 if (retries > 0) {
966 /*
967 * Don't update anything. We don't know if
968 * this was because of collisions or poor signal.
969 */
970 ath_rc_priv->hw_maxretry_pktcnt = 0;
971 } else {
972 /*
973 * It worked with no retries. First ignore bogus (small)
974 * rssi_ack values.
975 */
976 if (tx_rate == ath_rc_priv->rate_max_phy &&
977 ath_rc_priv->hw_maxretry_pktcnt < 255) {
978 ath_rc_priv->hw_maxretry_pktcnt++;
979 }
980
981 }
982 }
983}
984
985static void ath_rc_update_ht(struct ath_softc *sc,
986 struct ath_rate_priv *ath_rc_priv,
987 struct ieee80211_tx_info *tx_info,
988 int tx_rate, int xretries, int retries)
989{
990 u32 now_msec = jiffies_to_msecs(jiffies);
991 int rate;
992 u8 last_per;
993 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
994 int size = ath_rc_priv->rate_table_size;
995
996 if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
997 return;
998
999 last_per = ath_rc_priv->per[tx_rate];
1000
1001 /* Update PER first */
1002 ath_rc_update_per(sc, rate_table, ath_rc_priv,
1003 tx_info, tx_rate, xretries,
1004 retries, now_msec);
1005
1006 /*
1007 * If this rate looks bad (high PER) then stop using it for
1008 * a while (except if we are probing).
1009 */
1010 if (ath_rc_priv->per[tx_rate] >= 55 && tx_rate > 0 &&
1011 rate_table->info[tx_rate].ratekbps <=
1012 rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
1013 ath_rc_get_lower_rix(ath_rc_priv, (u8)tx_rate,
1014 &ath_rc_priv->rate_max_phy);
1015
1016 /* Don't probe for a little while. */
1017 ath_rc_priv->probe_time = now_msec;
1018 }
1019
1020 /* Make sure the rates below this have lower PER */
1021 /* Monotonicity is kept only for rates below the current rate. */
1022 if (ath_rc_priv->per[tx_rate] < last_per) {
1023 for (rate = tx_rate - 1; rate >= 0; rate--) {
1024
1025 if (ath_rc_priv->per[rate] >
1026 ath_rc_priv->per[rate+1]) {
1027 ath_rc_priv->per[rate] =
1028 ath_rc_priv->per[rate+1];
1029 }
1030 }
1031 }
1032
1033 /* Maintain monotonicity for rates above the current rate */
1034 for (rate = tx_rate; rate < size - 1; rate++) {
1035 if (ath_rc_priv->per[rate+1] <
1036 ath_rc_priv->per[rate])
1037 ath_rc_priv->per[rate+1] =
1038 ath_rc_priv->per[rate];
1039 }
1040
1041 /* Every so often, we reduce the thresholds
1042 * and PER (different for CCK and OFDM). */
1043 if (now_msec - ath_rc_priv->per_down_time >=
1044 rate_table->probe_interval) {
1045 for (rate = 0; rate < size; rate++) {
1046 ath_rc_priv->per[rate] =
1047 7 * ath_rc_priv->per[rate] / 8;
1048 }
1049
1050 ath_rc_priv->per_down_time = now_msec;
1051 }
1052
1053 ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries,
1054 ath_rc_priv->per[tx_rate]);
1055
1056}
1057
1058static void ath_rc_tx_status(struct ath_softc *sc,
1059 struct ath_rate_priv *ath_rc_priv,
1060 struct sk_buff *skb)
1061{
1062 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1063 struct ieee80211_tx_rate *rates = tx_info->status.rates;
1064 struct ieee80211_tx_rate *rate;
1065 int final_ts_idx = 0, xretries = 0, long_retry = 0;
1066 u8 flags;
1067 u32 i = 0, rix;
1068
1069 for (i = 0; i < sc->hw->max_rates; i++) {
1070 rate = &tx_info->status.rates[i];
1071 if (rate->idx < 0 || !rate->count)
1072 break;
1073
1074 final_ts_idx = i;
1075 long_retry = rate->count - 1;
1076 }
1077
1078 if (!(tx_info->flags & IEEE80211_TX_STAT_ACK))
1079 xretries = 1;
1080
1081 /*
1082 * If the first rate is not the final index, there
1083 * are intermediate rate failures to be processed.
1084 */
1085 if (final_ts_idx != 0) {
1086 for (i = 0; i < final_ts_idx ; i++) {
1087 if (rates[i].count != 0 && (rates[i].idx >= 0)) {
1088 flags = rates[i].flags;
1089
1090 /* If HT40 and we have switched mode from
1091 * 40 to 20 => don't update */
1092
1093 if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
1094 !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
1095 return;
1096
1097 rix = ath_rc_get_rateindex(ath_rc_priv, &rates[i]);
1098 ath_rc_update_ht(sc, ath_rc_priv, tx_info,
1099 rix, xretries ? 1 : 2,
1100 rates[i].count);
1101 }
1102 }
1103 }
1104
1105 flags = rates[final_ts_idx].flags;
1106
1107 /* If HT40 and we have switched mode from 40 to 20 => don't update */
1108 if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
1109 !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
1110 return;
1111
1112 rix = ath_rc_get_rateindex(ath_rc_priv, &rates[final_ts_idx]);
1113 ath_rc_update_ht(sc, ath_rc_priv, tx_info, rix, xretries, long_retry);
1114 ath_debug_stat_rc(ath_rc_priv, rix);
1115}
1116
1117static const
1118struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
1119 enum ieee80211_band band,
1120 bool is_ht)
1121{
1122 switch(band) {
1123 case IEEE80211_BAND_2GHZ:
1124 if (is_ht)
1125 return &ar5416_11ng_ratetable;
1126 return &ar5416_11g_ratetable;
1127 case IEEE80211_BAND_5GHZ:
1128 if (is_ht)
1129 return &ar5416_11na_ratetable;
1130 return &ar5416_11a_ratetable;
1131 default:
1132 return NULL;
1133 }
1134}
1135
1136static void ath_rc_init(struct ath_softc *sc,
1137 struct ath_rate_priv *ath_rc_priv)
1138{
1139 const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
1140 struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
1141 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1142 u8 i, j, k, hi = 0, hthi = 0;
1143
1144 ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
1145
1146 for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
1147 ath_rc_priv->per[i] = 0;
1148 ath_rc_priv->valid_rate_index[i] = 0;
1149 }
1150
1151 for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
1152 for (j = 0; j < RATE_TABLE_SIZE; j++)
1153 ath_rc_priv->valid_phy_rateidx[i][j] = 0;
1154 ath_rc_priv->valid_phy_ratecnt[i] = 0;
1155 }
1156
1157 if (!rateset->rs_nrates) {
1158 hi = ath_rc_init_validrates(ath_rc_priv);
1159 } else {
1160 hi = ath_rc_setvalid_rates(ath_rc_priv, true);
1161
1162 if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG)
1163 hthi = ath_rc_setvalid_rates(ath_rc_priv, false);
1164
1165 hi = max(hi, hthi);
1166 }
1167
1168 ath_rc_priv->rate_table_size = hi + 1;
1169 ath_rc_priv->rate_max_phy = 0;
1170 WARN_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE);
1171
1172 for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
1173 for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) {
1174 ath_rc_priv->valid_rate_index[k++] =
1175 ath_rc_priv->valid_phy_rateidx[i][j];
1176 }
1177
1178 if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1) ||
1179 !ath_rc_priv->valid_phy_ratecnt[i])
1180 continue;
1181
1182 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
1183 }
1184 WARN_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE);
1185 WARN_ON(k > RATE_TABLE_SIZE);
1186
1187 ath_rc_priv->max_valid_rate = k;
1188 ath_rc_sort_validrates(ath_rc_priv);
1189 ath_rc_priv->rate_max_phy = (k > 4) ?
1190 ath_rc_priv->valid_rate_index[k-4] :
1191 ath_rc_priv->valid_rate_index[k-1];
1192
1193 ath_dbg(common, CONFIG, "RC Initialized with capabilities: 0x%x\n",
1194 ath_rc_priv->ht_cap);
1195}
1196
1197static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta)
1198{
1199 u8 caps = 0;
1200
1201 if (sta->ht_cap.ht_supported) {
1202 caps = WLAN_RC_HT_FLAG;
1203 if (sta->ht_cap.mcs.rx_mask[1] && sta->ht_cap.mcs.rx_mask[2])
1204 caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG;
1205 else if (sta->ht_cap.mcs.rx_mask[1])
1206 caps |= WLAN_RC_DS_FLAG;
1207 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
1208 caps |= WLAN_RC_40_FLAG;
1209 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
1210 caps |= WLAN_RC_SGI_FLAG;
1211 } else {
1212 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
1213 caps |= WLAN_RC_SGI_FLAG;
1214 }
1215 }
1216
1217 return caps;
1218}
1219
1220static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta,
1221 u8 tidno)
1222{
1223 struct ath_node *an = (struct ath_node *)sta->drv_priv;
1224 struct ath_atx_tid *txtid;
1225
1226 if (!sta->ht_cap.ht_supported)
1227 return false;
1228
1229 txtid = ATH_AN_2_TID(an, tidno);
1230 return !txtid->active;
1231}
1232
1233
1234/***********************************/
1235/* mac80211 Rate Control callbacks */
1236/***********************************/
1237
1238static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1239 struct ieee80211_sta *sta, void *priv_sta,
1240 struct sk_buff *skb)
1241{
1242 struct ath_softc *sc = priv;
1243 struct ath_rate_priv *ath_rc_priv = priv_sta;
1244 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1245 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1246 __le16 fc = hdr->frame_control;
1247
1248 if (!priv_sta || !ieee80211_is_data(fc))
1249 return;
1250
1251 /* This packet was aggregated but doesn't carry status info */
1252 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
1253 !(tx_info->flags & IEEE80211_TX_STAT_AMPDU))
1254 return;
1255
1256 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
1257 return;
1258
1259 ath_rc_tx_status(sc, ath_rc_priv, skb);
1260
1261 /* Check if aggregation has to be enabled for this tid */
1262 if (conf_is_ht(&sc->hw->conf) &&
1263 !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
1264 if (ieee80211_is_data_qos(fc) &&
1265 skb_get_queue_mapping(skb) != IEEE80211_AC_VO) {
1266 u8 *qc, tid;
1267
1268 qc = ieee80211_get_qos_ctl(hdr);
1269 tid = qc[0] & 0xf;
1270
1271 if(ath_tx_aggr_check(sc, sta, tid))
1272 ieee80211_start_tx_ba_session(sta, tid, 0);
1273 }
1274 }
1275}
1276
1277static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1278 struct cfg80211_chan_def *chandef,
1279 struct ieee80211_sta *sta, void *priv_sta)
1280{
1281 struct ath_softc *sc = priv;
1282 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1283 struct ath_rate_priv *ath_rc_priv = priv_sta;
1284 int i, j = 0;
1285 u32 rate_flags = ieee80211_chandef_rate_flags(&sc->hw->conf.chandef);
1286
1287 for (i = 0; i < sband->n_bitrates; i++) {
1288 if (sta->supp_rates[sband->band] & BIT(i)) {
1289 if ((rate_flags & sband->bitrates[i].flags)
1290 != rate_flags)
1291 continue;
1292
1293 ath_rc_priv->neg_rates.rs_rates[j]
1294 = (sband->bitrates[i].bitrate * 2) / 10;
1295 j++;
1296 }
1297 }
1298 ath_rc_priv->neg_rates.rs_nrates = j;
1299
1300 if (sta->ht_cap.ht_supported) {
1301 for (i = 0, j = 0; i < 77; i++) {
1302 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
1303 ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
1304 if (j == ATH_RATE_MAX)
1305 break;
1306 }
1307 ath_rc_priv->neg_ht_rates.rs_nrates = j;
1308 }
1309
1310 ath_rc_priv->rate_table = ath_choose_rate_table(sc, sband->band,
1311 sta->ht_cap.ht_supported);
1312 if (!ath_rc_priv->rate_table) {
1313 ath_err(common, "No rate table chosen\n");
1314 return;
1315 }
1316
1317 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta);
1318 ath_rc_init(sc, priv_sta);
1319}
1320
1321static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1322 struct cfg80211_chan_def *chandef,
1323 struct ieee80211_sta *sta, void *priv_sta,
1324 u32 changed)
1325{
1326 struct ath_softc *sc = priv;
1327 struct ath_rate_priv *ath_rc_priv = priv_sta;
1328
1329 if (changed & IEEE80211_RC_BW_CHANGED) {
1330 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta);
1331 ath_rc_init(sc, priv_sta);
1332
1333 ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG,
1334 "Operating Bandwidth changed to: %d\n",
1335 sc->hw->conf.chandef.width);
1336 }
1337}
1338
1339#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
1340
1341void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
1342{
1343 struct ath_rc_stats *stats;
1344
1345 stats = &rc->rcstats[final_rate];
1346 stats->success++;
1347}
1348
1349void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
1350 int xretries, int retries, u8 per)
1351{
1352 struct ath_rc_stats *stats = &rc->rcstats[rix];
1353
1354 stats->xretries += xretries;
1355 stats->retries += retries;
1356 stats->per = per;
1357}
1358
1359static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
1360 size_t count, loff_t *ppos)
1361{
1362 struct ath_rate_priv *rc = file->private_data;
1363 char *buf;
1364 unsigned int len = 0, max;
1365 int rix;
1366 ssize_t retval;
1367
1368 if (rc->rate_table == NULL)
1369 return 0;
1370
1371 max = 80 + rc->rate_table_size * 1024 + 1;
1372 buf = kmalloc(max, GFP_KERNEL);
1373 if (buf == NULL)
1374 return -ENOMEM;
1375
1376 len += sprintf(buf, "%6s %6s %6s "
1377 "%10s %10s %10s %10s\n",
1378 "HT", "MCS", "Rate",
1379 "Success", "Retries", "XRetries", "PER");
1380
1381 for (rix = 0; rix < rc->max_valid_rate; rix++) {
1382 u8 i = rc->valid_rate_index[rix];
1383 u32 ratekbps = rc->rate_table->info[i].ratekbps;
1384 struct ath_rc_stats *stats = &rc->rcstats[i];
1385 char mcs[5];
1386 char htmode[5];
1387 int used_mcs = 0, used_htmode = 0;
1388
1389 if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) {
1390 used_mcs = scnprintf(mcs, 5, "%d",
1391 rc->rate_table->info[i].ratecode);
1392
1393 if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy))
1394 used_htmode = scnprintf(htmode, 5, "HT40");
1395 else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy))
1396 used_htmode = scnprintf(htmode, 5, "HT20");
1397 else
1398 used_htmode = scnprintf(htmode, 5, "????");
1399 }
1400
1401 mcs[used_mcs] = '\0';
1402 htmode[used_htmode] = '\0';
1403
1404 len += scnprintf(buf + len, max - len,
1405 "%6s %6s %3u.%d: "
1406 "%10u %10u %10u %10u\n",
1407 htmode,
1408 mcs,
1409 ratekbps / 1000,
1410 (ratekbps % 1000) / 100,
1411 stats->success,
1412 stats->retries,
1413 stats->xretries,
1414 stats->per);
1415 }
1416
1417 if (len > max)
1418 len = max;
1419
1420 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1421 kfree(buf);
1422 return retval;
1423}
1424
1425static const struct file_operations fops_rcstat = {
1426 .read = read_file_rcstat,
1427 .open = simple_open,
1428 .owner = THIS_MODULE
1429};
1430
1431static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta,
1432 struct dentry *dir)
1433{
1434 struct ath_rate_priv *rc = priv_sta;
1435 rc->debugfs_rcstats = debugfs_create_file("rc_stats", S_IRUGO,
1436 dir, rc, &fops_rcstat);
1437}
1438
1439static void ath_rate_remove_sta_debugfs(void *priv, void *priv_sta)
1440{
1441 struct ath_rate_priv *rc = priv_sta;
1442 debugfs_remove(rc->debugfs_rcstats);
1443}
1444
1445#endif /* CONFIG_MAC80211_DEBUGFS && CONFIG_ATH9K_DEBUGFS */
1446
1447static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1448{
1449 return hw->priv;
1450}
1451
1452static void ath_rate_free(void *priv)
1453{
1454 return;
1455}
1456
1457static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
1458{
1459 return kzalloc(sizeof(struct ath_rate_priv), gfp);
1460}
1461
1462static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
1463 void *priv_sta)
1464{
1465 struct ath_rate_priv *rate_priv = priv_sta;
1466 kfree(rate_priv);
1467}
1468
1469static const struct rate_control_ops ath_rate_ops = {
1470 .name = "ath9k_rate_control",
1471 .tx_status = ath_tx_status,
1472 .get_rate = ath_get_rate,
1473 .rate_init = ath_rate_init,
1474 .rate_update = ath_rate_update,
1475 .alloc = ath_rate_alloc,
1476 .free = ath_rate_free,
1477 .alloc_sta = ath_rate_alloc_sta,
1478 .free_sta = ath_rate_free_sta,
1479
1480#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
1481 .add_sta_debugfs = ath_rate_add_sta_debugfs,
1482 .remove_sta_debugfs = ath_rate_remove_sta_debugfs,
1483#endif
1484};
1485
1486int ath_rate_control_register(void)
1487{
1488 return ieee80211_rate_control_register(&ath_rate_ops);
1489}
1490
1491void ath_rate_control_unregister(void)
1492{
1493 ieee80211_rate_control_unregister(&ath_rate_ops);
1494}
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
deleted file mode 100644
index b9a87383cb43..000000000000
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ /dev/null
@@ -1,248 +0,0 @@
1/*
2 * Copyright (c) 2004 Sam Leffler, Errno Consulting
3 * Copyright (c) 2004 Video54 Technologies, Inc.
4 * Copyright (c) 2008-2011 Atheros Communications Inc.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#ifndef RC_H
20#define RC_H
21
22#include "hw.h"
23
24struct ath_softc;
25
26#define ATH_RATE_MAX 30
27#define RATE_TABLE_SIZE 72
28
29#define RC_INVALID 0x0000
30#define RC_LEGACY 0x0001
31#define RC_SS 0x0002
32#define RC_DS 0x0004
33#define RC_TS 0x0008
34#define RC_HT_20 0x0010
35#define RC_HT_40 0x0020
36
37#define RC_STREAM_MASK 0xe
38#define RC_DS_OR_LATER(f) ((((f) & RC_STREAM_MASK) == RC_DS) || \
39 (((f) & RC_STREAM_MASK) == (RC_DS | RC_TS)))
40#define RC_TS_ONLY(f) (((f) & RC_STREAM_MASK) == RC_TS)
41#define RC_SS_OR_LEGACY(f) ((f) & (RC_SS | RC_LEGACY))
42
43#define RC_HT_2040 (RC_HT_20 | RC_HT_40)
44#define RC_ALL_STREAM (RC_SS | RC_DS | RC_TS)
45#define RC_L_SD (RC_LEGACY | RC_SS | RC_DS)
46#define RC_L_SDT (RC_LEGACY | RC_SS | RC_DS | RC_TS)
47#define RC_HT_S_20 (RC_HT_20 | RC_SS)
48#define RC_HT_D_20 (RC_HT_20 | RC_DS)
49#define RC_HT_T_20 (RC_HT_20 | RC_TS)
50#define RC_HT_S_40 (RC_HT_40 | RC_SS)
51#define RC_HT_D_40 (RC_HT_40 | RC_DS)
52#define RC_HT_T_40 (RC_HT_40 | RC_TS)
53
54#define RC_HT_SD_20 (RC_HT_20 | RC_SS | RC_DS)
55#define RC_HT_DT_20 (RC_HT_20 | RC_DS | RC_TS)
56#define RC_HT_SD_40 (RC_HT_40 | RC_SS | RC_DS)
57#define RC_HT_DT_40 (RC_HT_40 | RC_DS | RC_TS)
58
59#define RC_HT_SD_2040 (RC_HT_2040 | RC_SS | RC_DS)
60#define RC_HT_SDT_2040 (RC_HT_2040 | RC_SS | RC_DS | RC_TS)
61
62#define RC_HT_SDT_20 (RC_HT_20 | RC_SS | RC_DS | RC_TS)
63#define RC_HT_SDT_40 (RC_HT_40 | RC_SS | RC_DS | RC_TS)
64
65#define RC_ALL (RC_LEGACY | RC_HT_2040 | RC_ALL_STREAM)
66
67enum {
68 WLAN_RC_PHY_OFDM,
69 WLAN_RC_PHY_CCK,
70 WLAN_RC_PHY_HT_20_SS,
71 WLAN_RC_PHY_HT_20_DS,
72 WLAN_RC_PHY_HT_20_TS,
73 WLAN_RC_PHY_HT_40_SS,
74 WLAN_RC_PHY_HT_40_DS,
75 WLAN_RC_PHY_HT_40_TS,
76 WLAN_RC_PHY_HT_20_SS_HGI,
77 WLAN_RC_PHY_HT_20_DS_HGI,
78 WLAN_RC_PHY_HT_20_TS_HGI,
79 WLAN_RC_PHY_HT_40_SS_HGI,
80 WLAN_RC_PHY_HT_40_DS_HGI,
81 WLAN_RC_PHY_HT_40_TS_HGI,
82 WLAN_RC_PHY_MAX
83};
84
85#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
86 || (_phy == WLAN_RC_PHY_HT_40_DS) \
87 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
88 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
89#define WLAN_RC_PHY_TS(_phy) ((_phy == WLAN_RC_PHY_HT_20_TS) \
90 || (_phy == WLAN_RC_PHY_HT_40_TS) \
91 || (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \
92 || (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
93#define WLAN_RC_PHY_20(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS) \
94 || (_phy == WLAN_RC_PHY_HT_20_DS) \
95 || (_phy == WLAN_RC_PHY_HT_20_TS) \
96 || (_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
97 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
98 || (_phy == WLAN_RC_PHY_HT_20_TS_HGI))
99#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \
100 || (_phy == WLAN_RC_PHY_HT_40_DS) \
101 || (_phy == WLAN_RC_PHY_HT_40_TS) \
102 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
103 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \
104 || (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
105#define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
106 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
107 || (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \
108 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
109 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \
110 || (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
111
112#define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS)
113
114#define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \
115 ((capflag & WLAN_RC_40_FLAG) ? RC_HT_40 : RC_HT_20) : RC_LEGACY))
116
117#define WLAN_RC_CAP_STREAM(capflag) (((capflag & WLAN_RC_TS_FLAG) ? \
118 (RC_TS) : ((capflag & WLAN_RC_DS_FLAG) ? RC_DS : RC_SS)))
119
120/* Return TRUE if flag supports HT20 && client supports HT20 or
121 * return TRUE if flag supports HT40 && client supports HT40.
122 * This is used becos some rates overlap between HT20/HT40.
123 */
124#define WLAN_RC_PHY_HT_VALID(flag, capflag) \
125 (((flag & RC_HT_20) && !(capflag & WLAN_RC_40_FLAG)) || \
126 ((flag & RC_HT_40) && (capflag & WLAN_RC_40_FLAG)))
127
128#define WLAN_RC_DS_FLAG (0x01)
129#define WLAN_RC_TS_FLAG (0x02)
130#define WLAN_RC_40_FLAG (0x04)
131#define WLAN_RC_SGI_FLAG (0x08)
132#define WLAN_RC_HT_FLAG (0x10)
133
134/**
135 * struct ath_rate_table - Rate Control table
136 * @rate_cnt: total number of rates for the given wireless mode
137 * @mcs_start: MCS rate index offset
138 * @rate_flags: Rate Control flags
139 * @phy: CCK/OFDM/HT20/HT40
140 * @ratekbps: rate in Kbits per second
141 * @user_ratekbps: user rate in Kbits per second
142 * @ratecode: rate that goes into HW descriptors
143 * @dot11rate: value that goes into supported
144 * rates info element of MLME
145 * @ctrl_rate: Index of next lower basic rate, used for duration computation
146 * @cw40index: Index of rates having 40MHz channel width
147 * @sgi_index: Index of rates having Short Guard Interval
148 * @ht_index: high throughput rates having 40MHz channel width and
149 * Short Guard Interval
150 * @probe_interval: interval for rate control to probe for other rates
151 * @initial_ratemax: initial ratemax value
152 */
153struct ath_rate_table {
154 int rate_cnt;
155 int mcs_start;
156 struct {
157 u16 rate_flags;
158 u8 phy;
159 u32 ratekbps;
160 u32 user_ratekbps;
161 u8 ratecode;
162 u8 dot11rate;
163 } info[RATE_TABLE_SIZE];
164 u32 probe_interval;
165 u8 initial_ratemax;
166};
167
168struct ath_rateset {
169 u8 rs_nrates;
170 u8 rs_rates[ATH_RATE_MAX];
171};
172
173struct ath_rc_stats {
174 u32 success;
175 u32 retries;
176 u32 xretries;
177 u8 per;
178};
179
180/**
181 * struct ath_rate_priv - Rate Control priv data
182 * @state: RC state
183 * @probe_rate: rate we are probing at
184 * @probe_time: msec timestamp for last probe
185 * @hw_maxretry_pktcnt: num of packets since we got HW max retry error
186 * @max_valid_rate: maximum number of valid rate
187 * @per_down_time: msec timestamp for last PER down step
188 * @valid_phy_ratecnt: valid rate count
189 * @rate_max_phy: phy index for the max rate
190 * @per: PER for every valid rate in %
191 * @probe_interval: interval for ratectrl to probe for other rates
192 * @ht_cap: HT capabilities
193 * @neg_rates: Negotatied rates
194 * @neg_ht_rates: Negotiated HT rates
195 */
196struct ath_rate_priv {
197 u8 rate_table_size;
198 u8 probe_rate;
199 u8 hw_maxretry_pktcnt;
200 u8 max_valid_rate;
201 u8 valid_rate_index[RATE_TABLE_SIZE];
202 u8 ht_cap;
203 u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
204 u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
205 u8 rate_max_phy;
206 u8 per[RATE_TABLE_SIZE];
207 u32 probe_time;
208 u32 per_down_time;
209 u32 probe_interval;
210 struct ath_rateset neg_rates;
211 struct ath_rateset neg_ht_rates;
212 const struct ath_rate_table *rate_table;
213
214#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
215 struct dentry *debugfs_rcstats;
216 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
217#endif
218};
219
220#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
221void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate);
222void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
223 int xretries, int retries, u8 per);
224#else
225static inline void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
226{
227}
228static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
229 int xretries, int retries, u8 per)
230{
231}
232#endif
233
234#ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL
235int ath_rate_control_register(void);
236void ath_rate_control_unregister(void);
237#else
238static inline int ath_rate_control_register(void)
239{
240 return 0;
241}
242
243static inline void ath_rate_control_unregister(void)
244{
245}
246#endif
247
248#endif /* RC_H */