Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 3/4] ath9k: Fix incorrect user ratekbs of MCS15 ShortGI
From: Senthil Balasubramanian @ 2010-07-27 13:46 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Senthil Balasubramanian
In-Reply-To: <1280238394-2565-1-git-send-email-senthilkumar@atheros.com>

The user ratekbs of MCS15 ShortGI is incorrect and can not be lesser
than MCS15 rate. This incorrect rate may affect switching to higher
rates as the rate control algorithm always finds MCS15 is better
than MCS15 ShortGI and results in lower throughput. Fix this by
feeding the correct user ratekbs for MCS15 ShortGI rate.

This issue affects 3 stream case very badly as the 3 stream rates are
not used at all once we scale down to MCS15 from 3 stream rates.

Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
---
 drivers/net/wireless/ath/ath9k/rc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 7b63958..5c9df3b 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -74,7 +74,7 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
 		[24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
 			108300, 15, 15, 4, 23, 54, 25, 55 }, /* 130 Mb */
 		[25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
-			12000, 15, 15, 4, 23, 54, 25, 55 }, /* 144.4 Mb */
+			120000, 15, 15, 4, 23, 54, 25, 55 }, /* 144.4 Mb */
 		[26] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
 			17400, 16, 16, 0, 24, 56, 26, 56 }, /* 19.5 Mb */
 		[27] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/4] ath9k: Add three stream rate control support for AR938X.
From: Senthil Balasubramanian @ 2010-07-27 13:46 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Senthil Balasubramanian
In-Reply-To: <1280238394-2565-1-git-send-email-senthilkumar@atheros.com>

This patch adds 3 stream rate control support for AR938X family
chipsets which supports 3 streams.

Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
---
 drivers/net/wireless/ath/ath9k/rc.c |  528 +++++++++++++++++++++--------------
 drivers/net/wireless/ath/ath9k/rc.h |   63 +++--
 2 files changed, 366 insertions(+), 225 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index f8a4c39..7b63958 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -20,95 +20,145 @@
 #include "ath9k.h"
 
 static const struct ath_rate_table ar5416_11na_ratetable = {
-	43,
+	68,
 	8, /* MCS start */
 	{
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-			5400, 0, 12, 0, 0, 0, 0, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-			7800,  1, 18, 0, 1, 1, 1, 1 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-			10000, 2, 24, 2, 2, 2, 2, 2 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-			13900, 3, 36, 2, 3, 3, 3, 3 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-			17300, 4, 48, 4, 4, 4, 4, 4 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-			23000, 5, 72, 4, 5, 5, 5, 5 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-			27400, 6, 96, 4, 6, 6, 6, 6 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-			29300, 7, 108, 4, 7, 7, 7, 7 },
-		{ RC_HT_SD_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
-			6400, 0, 0, 0, 8, 25, 8, 25 },
-		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
-			12700, 1, 1, 2, 9, 26, 9, 26 },
-		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
-			18800, 2, 2, 2, 10, 27, 10, 27 },
-		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
-			25000, 3, 3, 4, 11, 28, 11, 28 },
-		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
-			36700, 4, 4, 4, 12, 29, 12, 29 },
-		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
-			48100, 5, 5, 4, 13, 30, 13, 30 },
-		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
-			53500, 6, 6, 4, 14, 31, 14, 31 },
-		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
-			59000, 7, 7, 4, 15, 32, 15, 33 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
-			12700, 8, 8, 3, 16, 34, 16, 34 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
-			24800, 9, 9, 2, 17, 35, 17, 35 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
-			36600, 10, 10, 2, 18, 36, 18, 36 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
-			48100, 11, 11, 4, 19, 37, 19, 37 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
-			69500, 12, 12, 4, 20, 38, 20, 38 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
-			89500, 13, 13, 4, 21, 39, 21, 39 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
-			98900, 14, 14, 4, 22, 40, 22, 40 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
-			108300, 15, 15, 4, 23, 41, 24, 42 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 144.4 Mb */
-			12000, 15, 15, 4, 23, 41, 24, 42 },
-		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
-			13200, 0, 0, 0, 8, 25, 25, 25 },
-		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
-			25900, 1, 1, 2, 9, 26, 26, 26 },
-		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
-			38600, 2, 2, 2, 10, 27, 27, 27 },
-		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
-			49800, 3, 3, 4, 11, 28, 28, 28 },
-		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
-			72200, 4, 4, 4, 12, 29, 29, 29 },
-		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
-			92900, 5, 5, 4, 13, 30, 30, 30 },
-		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
-			102700, 6, 6, 4, 14, 31, 31, 31 },
-		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
-			112000, 7, 7, 4, 15, 32, 33, 33 },
-		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
-			122000, 7, 7, 4, 15, 32, 33, 33 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
-			25800, 8, 8, 0, 16, 34, 34, 34 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
-			49800, 9, 9, 2, 17, 35, 35, 35 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
-			71900, 10, 10, 2, 18, 36, 36, 36 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
-			92500, 11, 11, 4, 19, 37, 37, 37 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
-			130300, 12, 12, 4, 20, 38, 38, 38 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
-			162800, 13, 13, 4, 21, 39, 39, 39 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
-			178200, 14, 14, 4, 22, 40, 40, 40 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
-			192100, 15, 15, 4, 23, 41, 42, 42 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
-			207000, 15, 15, 4, 23, 41, 42, 42 },
+		[0] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000,
+			5400, 0, 12, 0, 0, 0, 0, 0 }, /* 6 Mb */
+		[1] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000,
+			7800,  1, 18, 0, 1, 1, 1, 1 }, /* 9 Mb */
+		[2] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000,
+			10000, 2, 24, 2, 2, 2, 2, 2 }, /* 12 Mb */
+		[3] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000,
+			13900, 3, 36, 2, 3, 3, 3, 3 }, /* 18 Mb */
+		[4] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000,
+			17300, 4, 48, 4, 4, 4, 4, 4 }, /* 24 Mb */
+		[5] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000,
+			23000, 5, 72, 4, 5, 5, 5, 5 }, /* 36 Mb */
+		[6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000,
+			27400, 6, 96, 4, 6, 6, 6, 6 }, /* 48 Mb */
+		[7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000,
+			29300, 7, 108, 4, 7, 7, 7, 7 }, /* 54 Mb */
+		[8] = { RC_HT_SDT_2040, WLAN_RC_PHY_HT_20_SS, 6500,
+			6400, 0, 0, 0, 8, 38, 8, 38 }, /* 6.5 Mb */
+		[9] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000,
+			12700, 1, 1, 2, 9, 39, 9, 39 }, /* 13 Mb */
+		[10] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500,
+			18800, 2, 2, 2, 10, 40, 10, 40 }, /* 19.5 Mb */
+		[11] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000,
+			25000, 3, 3, 4, 11, 41, 11, 41 }, /* 26 Mb */
+		[12] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000,
+			36700, 4, 4, 4, 12, 42, 12, 42 }, /* 39 Mb */
+		[13] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000,
+			48100, 5, 5, 4, 13, 43, 13, 43 }, /* 52 Mb */
+		[14] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500,
+			53500, 6, 6, 4, 14, 44, 14, 44 }, /* 58.5 Mb */
+		[15] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000,
+			59000, 7, 7, 4, 15, 45, 16, 46 }, /* 65 Mb */
+		[16] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200,
+			65400, 7, 7, 4, 15, 45, 16, 46 }, /* 75 Mb */
+		[17] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000,
+			12700, 8, 8, 0, 16, 47, 17, 47 }, /* 13 Mb */
+		[18] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000,
+			24800, 9, 9, 2, 17, 48, 18, 48 }, /* 26 Mb */
+		[19] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000,
+			36600, 10, 10, 2, 18, 49, 19, 49 }, /* 39 Mb */
+		[20] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000,
+			48100, 11, 11, 4, 19, 50, 20, 50 }, /* 52 Mb */
+		[21] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000,
+			69500, 12, 12, 4, 20, 51, 21, 51 }, /* 78 Mb */
+		[22] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000,
+			89500, 13, 13, 4, 21, 52, 22, 52 }, /* 104 Mb */
+		[23] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000,
+			98900, 14, 14, 4, 22, 53, 23, 53 }, /* 117 Mb */
+		[24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
+			108300, 15, 15, 4, 23, 54, 25, 55 }, /* 130 Mb */
+		[25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
+			12000, 15, 15, 4, 23, 54, 25, 55 }, /* 144.4 Mb */
+		[26] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
+			17400, 16, 16, 0, 24, 56, 26, 56 }, /* 19.5 Mb */
+		[27] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
+			35100, 17, 17, 2, 25, 57, 27, 57 }, /* 39 Mb */
+		[28] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500,
+			52600, 18, 18, 2, 26, 58, 28, 58 }, /* 58.5 Mb */
+		[29] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000,
+			70400, 19, 19, 4, 27, 59, 29, 59 }, /* 78 Mb */
+		[30] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000,
+			104900, 20, 20, 4, 28, 60, 31, 61 }, /* 117 Mb */
+		[31] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000,
+			115800, 20, 20, 4, 28, 60, 31, 61 }, /* 130 Mb*/
+		[32] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000,
+			137200, 21, 21, 4, 29, 62, 33, 63 }, /* 156 Mb */
+		[33] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300,
+			151100, 21, 21, 4, 29, 62, 33, 63 }, /* 173.3 Mb */
+		[34] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500,
+			152800, 22, 22, 4, 30, 64, 35, 65 }, /* 175.5 Mb */
+		[35] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000,
+			168400, 22, 22, 4, 30, 64, 35, 65 }, /* 195 Mb*/
+		[36] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000,
+			168400, 23, 23, 4, 31, 66, 37, 67 }, /* 195 Mb */
+		[37] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700,
+			185000, 23, 23, 4, 31, 66, 37, 67 }, /* 216.7 Mb */
+		[38] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500,
+			13200, 0, 0, 0, 8, 38, 38, 38 }, /* 13.5 Mb*/
+		[39] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500,
+			25900, 1, 1, 2, 9, 39, 39, 39 }, /* 27.0 Mb*/
+		[40] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500,
+			38600, 2, 2, 2, 10, 40, 40, 40 }, /* 40.5 Mb*/
+		[41] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000,
+			49800, 3, 3, 4, 11, 41, 41, 41 }, /* 54 Mb */
+		[42] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500,
+			72200, 4, 4, 4, 12, 42, 42, 42 }, /* 81 Mb */
+		[43] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000,
+			92900, 5, 5, 4, 13, 43, 43, 43 }, /* 108 Mb */
+		[44] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500,
+			102700, 6, 6, 4, 14, 44, 44, 44 }, /* 121.5 Mb*/
+		[45] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000,
+			112000, 7, 7, 4, 15, 45, 46, 46 }, /* 135 Mb */
+		[46] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000,
+			122000, 7, 7, 4, 15, 45, 46, 46 }, /* 150 Mb */
+		[47] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000,
+			25800, 8, 8, 0, 16, 47, 47, 47 }, /* 27 Mb */
+		[48] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000,
+			49800, 9, 9, 2, 17, 48, 48, 48 }, /* 54 Mb */
+		[49] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000,
+			71900, 10, 10, 2, 18, 49, 49, 49 }, /* 81 Mb */
+		[50] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000,
+			92500, 11, 11, 4, 19, 50, 50, 50 }, /* 108 Mb */
+		[51] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000,
+			130300, 12, 12, 4, 20, 51, 51, 51 }, /* 162 Mb */
+		[52] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000,
+			162800, 13, 13, 4, 21, 52, 52, 52 }, /* 216 Mb */
+		[53] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000,
+			178200, 14, 14, 4, 22, 53, 53, 53 }, /* 243 Mb */
+		[54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000,
+			192100, 15, 15, 4, 23, 54, 55, 55 }, /* 270 Mb */
+		[55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000,
+			207000, 15, 15, 4, 23, 54, 55, 55 }, /* 300 Mb */
+		[56] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500,
+			36100, 16, 16, 0, 24, 56, 56, 56 }, /* 40.5 Mb */
+		[57] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000,
+			72900, 17, 17, 2, 25, 57, 57, 57 }, /* 81 Mb */
+		[58] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500,
+			108300, 18, 18, 2, 26, 58, 58, 58 }, /* 121.5 Mb */
+		[59] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000,
+			142000, 19, 19, 4, 27, 59, 59, 59 }, /*  162 Mb */
+		[60] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
+			205100, 20, 20, 4, 28, 60, 61, 61 }, /*  243 Mb */
+		[61] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
+			224700, 20, 20, 4, 28, 60, 61, 61 }, /*  270 Mb */
+		[62] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
+			263100, 21, 21, 4, 29, 62, 63, 63 }, /*  324 Mb */
+		[63] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
+			288000, 21, 21, 4, 29, 62, 63, 63 }, /*  360 Mb */
+		[64] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500,
+			290700, 22, 22, 4, 30, 64, 65, 65 }, /* 364.5 Mb */
+		[65] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000,
+			317200, 22, 22, 4, 30, 64, 65, 65 }, /* 405 Mb */
+		[66] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000,
+			317200, 23, 23, 4, 31, 66, 67, 67 }, /* 405 Mb */
+		[67] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000,
+			346400, 23, 23, 4, 31, 66, 67, 67 }, /* 450 Mb */
 	},
 	50,  /* probe interval */
 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
@@ -118,103 +168,153 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
  * for HT are the 64K max aggregate limit */
 
 static const struct ath_rate_table ar5416_11ng_ratetable = {
-	47,
+	72,
 	12, /* MCS start */
 	{
-		{ RC_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
-			900, 0, 2, 0, 0, 0, 0, 0 },
-		{ RC_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
-			1900, 1, 4, 1, 1, 1, 1, 1 },
-		{ RC_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
-			4900, 2, 11, 2, 2, 2, 2, 2 },
-		{ RC_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
-			8100, 3, 22, 3, 3, 3, 3, 3 },
-		{ RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-			5400, 4, 12, 4, 4, 4, 4, 4 },
-		{ RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-			7800, 5, 18, 4, 5, 5, 5, 5 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-			10100, 6, 24, 6, 6, 6, 6, 6 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-			14100, 7, 36, 6, 7, 7, 7, 7 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-			17700, 8, 48, 8, 8, 8, 8, 8 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-			23700, 9, 72, 8, 9, 9, 9, 9 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-			27400, 10, 96, 8, 10, 10, 10, 10 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-			30900, 11, 108, 8, 11, 11, 11, 11 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
-			6400, 0, 0, 4, 12, 29, 12, 29 },
-		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
-			12700, 1, 1, 6, 13, 30, 13, 30 },
-		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
-			18800, 2, 2, 6, 14, 31, 14, 31 },
-		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
-			25000, 3, 3, 8, 15, 32, 15, 32 },
-		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
-			36700, 4, 4, 8, 16, 33, 16, 33 },
-		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
-			48100, 5, 5, 8, 17, 34, 17, 34 },
-		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
-			53500, 6, 6, 8, 18, 35, 18, 35 },
-		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
-			59000, 7, 7, 8, 19, 36, 19, 37 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
-			12700, 8, 8, 4, 20, 38, 20, 38 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
-			24800, 9, 9, 6, 21, 39, 21, 39 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
-			36600, 10, 10, 6, 22, 40, 22, 40 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
-			48100, 11, 11, 8, 23, 41, 23, 41 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
-			69500, 12, 12, 8, 24, 42, 24, 42 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
-			89500, 13, 13, 8, 25, 43, 25, 43 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
-			98900, 14, 14, 8, 26, 44, 26, 44 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
-			108300, 15, 15, 8, 27, 45, 28, 46 },
-		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 130 Mb */
-			120000, 15, 15, 8, 27, 45, 28, 46 },
-		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
-			13200, 0, 0, 8, 12, 29, 29, 29 },
-		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
-			25900, 1, 1, 8, 13, 30, 30, 30 },
-		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
-			38600, 2, 2, 8, 14, 31, 31, 31 },
-		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
-			49800, 3, 3, 8,  15, 32, 32, 32 },
-		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
-			72200, 4, 4, 8, 16, 33, 33, 33 },
-		{ RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
-			92900, 5, 5, 8, 17, 34, 34, 34 },
-		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
-			102700, 6, 6, 8, 18, 35, 35, 35 },
-		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
-			112000, 7, 7, 8, 19, 36, 37, 37 },
-		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
-			122000, 7, 7, 8, 19, 36, 37, 37 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
-			25800, 8, 8, 8, 20, 38, 38, 38 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
-			49800, 9, 9, 8, 21, 39, 39, 39 },
-		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
-			71900, 10, 10, 8, 22, 40, 40, 40 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
-			92500, 11, 11, 8, 23, 41, 41, 41 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
-			130300, 12, 12, 8, 24, 42, 42, 42 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
-			162800, 13, 13, 8, 25, 43, 43, 43 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
-			178200, 14, 14, 8, 26, 44, 44, 44 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
-			192100, 15, 15, 8, 27, 45, 46, 46 },
-		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
-			207000, 15, 15, 8, 27, 45, 46, 46 },
+		[0] = { RC_ALL, WLAN_RC_PHY_CCK, 1000,
+			900, 0, 2, 0, 0, 0, 0, 0 }, /* 1 Mb */
+		[1] = { RC_ALL, WLAN_RC_PHY_CCK, 2000,
+			1900, 1, 4, 1, 1, 1, 1, 1 }, /* 2 Mb */
+		[2] = { RC_ALL, WLAN_RC_PHY_CCK, 5500,
+			4900, 2, 11, 2, 2, 2, 2, 2 }, /* 5.5 Mb */
+		[3] = { RC_ALL, WLAN_RC_PHY_CCK, 11000,
+			8100, 3, 22, 3, 3, 3, 3, 3 }, /* 11 Mb */
+		[4] = { RC_INVALID, WLAN_RC_PHY_OFDM, 6000,
+			5400, 4, 12, 4, 4, 4, 4, 4 }, /* 6 Mb */
+		[5] = { RC_INVALID, WLAN_RC_PHY_OFDM, 9000,
+			7800, 5, 18, 4, 5, 5, 5, 5 }, /* 9 Mb */
+		[6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000,
+			10100, 6, 24, 6, 6, 6, 6, 6 }, /* 12 Mb */
+		[7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000,
+			14100, 7, 36, 6, 7, 7, 7, 7 }, /* 18 Mb */
+		[8] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000,
+			17700, 8, 48, 8, 8, 8, 8, 8 }, /* 24 Mb */
+		[9] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000,
+			23700, 9, 72, 8, 9, 9, 9, 9 }, /* 36 Mb */
+		[10] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000,
+			27400, 10, 96, 8, 10, 10, 10, 10 }, /* 48 Mb */
+		[11] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000,
+			30900, 11, 108, 8, 11, 11, 11, 11 }, /* 54 Mb */
+		[12] = { RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500,
+			6400, 0, 0, 4, 12, 42, 12, 42 }, /* 6.5 Mb */
+		[13] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000,
+			12700, 1, 1, 6, 13, 43, 13, 43 }, /* 13 Mb */
+		[14] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500,
+			18800, 2, 2, 6, 14, 44, 14, 44 }, /* 19.5 Mb*/
+		[15] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000,
+			25000, 3, 3, 8, 15, 45, 15, 45 }, /* 26 Mb */
+		[16] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000,
+			36700, 4, 4, 8, 16, 46, 16, 46 }, /* 39 Mb */
+		[17] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000,
+			48100, 5, 5, 8, 17, 47, 17, 47 }, /* 52 Mb */
+		[18] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500,
+			53500, 6, 6, 8, 18, 48, 18, 48 }, /* 58.5 Mb */
+		[19] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000,
+			59000, 7, 7, 8, 19, 49, 20, 50 }, /* 65 Mb */
+		[20] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200,
+			65400, 7, 7, 8, 19, 49, 20, 50 }, /* 65 Mb*/
+		[21] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000,
+			12700, 8, 8, 4, 20, 51, 21, 51 }, /* 13 Mb */
+		[22] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000,
+			24800, 9, 9, 6, 21, 52, 22, 52 }, /* 26 Mb */
+		[23] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000,
+			36600, 10, 10, 6, 22, 53, 23, 53 }, /* 39 Mb */
+		[24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000,
+			48100, 11, 11, 8, 23, 54, 24, 54 }, /* 52 Mb */
+		[25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000,
+			69500, 12, 12, 8, 24, 55, 25, 55 }, /* 78 Mb */
+		[26] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000,
+			89500, 13, 13, 8, 25, 56, 26, 56 }, /* 104 Mb */
+		[27] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000,
+			98900, 14, 14, 8, 26, 57, 27, 57 }, /* 117 Mb */
+		[28] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
+			108300, 15, 15, 8, 27, 58, 29, 59 }, /* 130 Mb */
+		[29] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
+			120000, 15, 15, 8, 27, 58, 29, 59 }, /* 144.4 Mb */
+		[30] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
+			17400, 16, 16, 4, 28, 60, 30, 60 }, /* 19.5 Mb */
+		[31] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
+			35100, 17, 17, 6, 29, 61, 31, 61 }, /* 39 Mb */
+		[32] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500,
+			52600, 18, 18, 6, 30, 62, 32, 62 }, /* 58.5 Mb */
+		[33] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000,
+			70400, 19, 19, 8, 31, 63, 33, 63 }, /* 78 Mb */
+		[34] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000,
+			104900, 20, 20, 8, 32, 64, 35, 65 }, /* 117 Mb */
+		[35] = {  RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000,
+			115800, 20, 20, 8, 32, 64, 35, 65 }, /* 130 Mb */
+		[36] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000,
+			137200, 21, 21, 8, 33, 66, 37, 67 }, /* 156 Mb */
+		[37] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300,
+			151100, 21, 21, 8, 33, 66, 37, 67 }, /* 173.3 Mb */
+		[38] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500,
+			152800, 22, 22, 8, 34, 68, 39, 69 }, /* 175.5 Mb */
+		[39] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000,
+			168400, 22, 22, 8, 34, 68, 39, 69 }, /* 195 Mb */
+		[40] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000,
+			168400, 23, 23, 8, 35, 70, 41, 71 }, /* 195 Mb */
+		[41] = {  RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700,
+			185000, 23, 23, 8, 35, 70, 41, 71 }, /* 216.7 Mb */
+		[42] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500,
+			13200, 0, 0, 8, 12, 42, 42, 42 }, /* 13.5 Mb */
+		[43] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500,
+			25900, 1, 1, 8, 13, 43, 43, 43 }, /* 27.0 Mb */
+		[44] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500,
+			38600, 2, 2, 8, 14, 44, 44, 44 }, /* 40.5 Mb */
+		[45] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000,
+			49800, 3, 3, 8,  15, 45, 45, 45 }, /* 54 Mb */
+		[46] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500,
+			72200, 4, 4, 8, 16, 46, 46, 46 }, /* 81 Mb */
+		[47] = { RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000,
+			92900, 5, 5, 8, 17, 47, 47, 47 }, /* 108 Mb */
+		[48] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500,
+			102700, 6, 6, 8, 18, 48, 48, 48 }, /* 121.5 Mb */
+		[49] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000,
+			112000, 7, 7, 8, 19, 49, 50, 50 }, /* 135 Mb */
+		[50] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000,
+			122000, 7, 7, 8, 19, 49, 50, 50 }, /* 150 Mb */
+		[51] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000,
+			25800, 8, 8, 8, 20, 51, 51, 51 }, /* 27 Mb */
+		[52] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000,
+			49800, 9, 9, 8, 21, 52, 52, 52 }, /* 54 Mb */
+		[53] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000,
+			71900, 10, 10, 8, 22, 53, 53, 53 }, /* 81 Mb */
+		[54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000,
+			92500, 11, 11, 8, 23, 54, 54, 54 }, /* 108 Mb */
+		[55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000,
+			130300, 12, 12, 8, 24, 55, 55, 55 }, /* 162 Mb */
+		[56] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000,
+			162800, 13, 13, 8, 25, 56, 56, 56 }, /* 216 Mb */
+		[57] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000,
+			178200, 14, 14, 8, 26, 57, 57, 57 }, /* 243 Mb */
+		[58] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000,
+			192100, 15, 15, 8, 27, 58, 59, 59 }, /* 270 Mb */
+		[59] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000,
+			207000, 15, 15, 8, 27, 58, 59, 59 }, /* 300 Mb */
+		[60] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500,
+			36100, 16, 16, 8, 28, 60, 60, 60 }, /* 40.5 Mb */
+		[61] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000,
+			72900, 17, 17, 8, 29, 61, 61, 61 }, /* 81 Mb */
+		[62] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500,
+			108300, 18, 18, 8, 30, 62, 62, 62 }, /* 121.5 Mb */
+		[63] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000,
+			142000, 19, 19, 8, 31, 63, 63, 63 }, /* 162 Mb */
+		[64] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
+			205100, 20, 20, 8, 32, 64, 65, 65 }, /* 243 Mb */
+		[65] = {  RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
+			224700, 20, 20, 8, 32, 64, 65, 65 }, /* 170 Mb */
+		[66] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
+			263100, 21, 21, 8, 33, 66, 67, 67 }, /* 324 Mb */
+		[67] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
+			288000, 21, 21, 8, 33, 66, 67, 67 }, /* 360 Mb */
+		[68] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500,
+			290700, 22, 22, 8, 34, 68, 69, 69 }, /* 364.5 Mb */
+		[69] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000,
+			317200, 22, 22, 8, 34, 68, 69, 69 }, /* 405 Mb */
+		[70] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000,
+			317200, 23, 23, 8, 35, 70, 71, 71 }, /* 405 Mb */
+		[71] = {  RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000,
+			346400, 23, 23, 8, 35, 70, 71, 71 }, /* 450 Mb */
 	},
 	50,  /* probe interval */
 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
@@ -224,21 +324,21 @@ static const struct ath_rate_table ar5416_11a_ratetable = {
 	8,
 	0,
 	{
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 0, 12, 0, 0, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800,  1, 18, 0, 1, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
 			10000, 2, 24, 2, 2, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
 			13900, 3, 36, 2, 3, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
 			17300, 4, 48, 4, 4, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
 			23000, 5, 72, 4, 5, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
 			27400, 6, 96, 4, 6, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
 			29300, 7, 108, 4, 7, 0 },
 	},
 	50,  /* probe interval */
@@ -249,29 +349,29 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
 	12,
 	0,
 	{
-		{ RC_L_SD, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
 			900, 0, 2, 0, 0, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
 			1900, 1, 4, 1, 1, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
 			4900, 2, 11, 2, 2, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
 			8100, 3, 22, 3, 3, 0 },
 		{ RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 4, 12, 4, 4, 0 },
 		{ RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800, 5, 18, 4, 5, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
 			10000, 6, 24, 6, 6, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
 			13900, 7, 36, 6, 7, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
 			17300, 8, 48, 8, 8, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
 			23000, 9, 72, 8, 9, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
 			27400, 10, 96, 8, 10, 0 },
-		{ RC_L_SD, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+		{ RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
 			29300, 11, 108, 8, 11, 0 },
 	},
 	50,  /* probe interval */
@@ -374,6 +474,8 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
 		return 0;
 	if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
 		return 0;
+	if (WLAN_RC_PHY_TS(phy) && !(capflag & WLAN_RC_TS_FLAG))
+		return 0;
 	if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
 		return 0;
 	if (!ignore_cw && WLAN_RC_PHY_HT(phy))
@@ -583,8 +685,12 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
 	if (rate > (ath_rc_priv->rate_table_size - 1))
 		rate = ath_rc_priv->rate_table_size - 1;
 
-	if (rate_table->info[rate].rate_flags & RC_DS &&
-	    (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
+	if (RC_TS_ONLY(rate_table->info[rate].rate_flags) &&
+	    (ath_rc_priv->ht_cap & WLAN_RC_TS_FLAG))
+		return rate;
+
+	if (RC_DS_OR_LATER(rate_table->info[rate].rate_flags) &&
+	    (ath_rc_priv->ht_cap & (WLAN_RC_DS_FLAG | WLAN_RC_TS_FLAG)))
 		return rate;
 
 	if (RC_SS_OR_LEGACY(rate_table->info[rate].rate_flags))
@@ -1000,12 +1106,19 @@ static void ath_rc_update_ht(struct ath_softc *sc,
 static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
 				struct ieee80211_tx_rate *rate)
 {
-	int rix;
+	int rix = 0, i = 0;
+	int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
 
 	if (!(rate->flags & IEEE80211_TX_RC_MCS))
 		return rate->idx;
 
-	rix = rate->idx + rate_table->mcs_start;
+	while (rate->idx > mcs_rix_off[i] &&
+	      i < sizeof(mcs_rix_off)/sizeof(int)) {
+		rix++; i++;
+	}
+
+	rix += rate->idx + rate_table->mcs_start;
+
 	if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
 	    (rate->flags & IEEE80211_TX_RC_SHORT_GI))
 		rix = rate_table->info[rix].ht_index;
@@ -1013,8 +1126,6 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
 		rix = rate_table->info[rix].sgi_index;
 	else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
 		rix = rate_table->info[rix].cw40index;
-	else
-		rix = rate_table->info[rix].base_index;
 
 	return rix;
 }
@@ -1196,13 +1307,14 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
 
 	if (sta->ht_cap.ht_supported) {
 		caps = WLAN_RC_HT_FLAG;
-		if (sta->ht_cap.mcs.rx_mask[1])
+		if (sta->ht_cap.mcs.rx_mask[1] && sta->ht_cap.mcs.rx_mask[2])
+			caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG;
+		else if (sta->ht_cap.mcs.rx_mask[1])
 			caps |= WLAN_RC_DS_FLAG;
 		if (is_cw40)
 			caps |= WLAN_RC_40_FLAG;
 		if (is_sgi)
 			caps |= WLAN_RC_SGI_FLAG;
-
 	}
 
 	return caps;
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 601803a..e914c33 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -24,7 +24,7 @@
 struct ath_softc;
 
 #define ATH_RATE_MAX     30
-#define RATE_TABLE_SIZE  64
+#define RATE_TABLE_SIZE  72
 #define MAX_TX_RATE_PHY  48
 
 
@@ -36,19 +36,34 @@ struct ath_softc;
 #define RC_HT_20	0x0010
 #define RC_HT_40	0x0020
 
-#define RC_SS_OR_LEGACY(f)     ((f) & (RC_SS | RC_LEGACY))
+#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)
+#define RC_ALL_STREAM		(RC_SS | RC_DS | RC_TS)
 #define RC_L_SD			(RC_LEGACY | RC_SS | RC_DS)
-#define RC_HT_SD_2040		(RC_HT_2040 | 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_SD_20		(RC_HT_20 | RC_SS | RC_DS)
-#define RC_HT_SD_40		(RC_HT_40 | RC_SS | RC_DS)
-#define RC_HT_S_20		(RC_HT_20 | RC_SS)
-#define RC_HT_S_40		(RC_HT_40 | 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 {
@@ -56,12 +71,16 @@ enum {
 	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
 };
 
@@ -69,27 +88,36 @@ enum {
 				|| (_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_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_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_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_DS_FLAG) ? RC_DS : RC_SS)
-
+#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.
@@ -100,9 +128,10 @@ enum {
 	 ((flag & RC_HT_40) && (capflag & WLAN_RC_40_FLAG)))
 
 #define WLAN_RC_DS_FLAG         (0x01)
-#define WLAN_RC_40_FLAG         (0x02)
-#define WLAN_RC_SGI_FLAG        (0x04)
-#define WLAN_RC_HT_FLAG         (0x08)
+#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
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/4] ath9k: Introduce bit masks for valid and valid_single_stream.
From: Senthil Balasubramanian @ 2010-07-27 13:46 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Senthil Balasubramanian

replace valid and valid_single_stream in rate table with bit masks
and reorganize the code so adding 3x3 rate control would be easier.

Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
---
 drivers/net/wireless/ath/ath9k/rc.c |  251 +++++++++++++++++------------------
 drivers/net/wireless/ath/ath9k/rc.h |   47 +++++---
 2 files changed, 153 insertions(+), 145 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 600ee0b..f8a4c39 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -23,91 +23,91 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
 	43,
 	8, /* MCS start */
 	{
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 0, 12, 0, 0, 0, 0, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800,  1, 18, 0, 1, 1, 1, 1 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
 			10000, 2, 24, 2, 2, 2, 2, 2 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
 			13900, 3, 36, 2, 3, 3, 3, 3 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
 			17300, 4, 48, 4, 4, 4, 4, 4 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
 			23000, 5, 72, 4, 5, 5, 5, 5 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
 			27400, 6, 96, 4, 6, 6, 6, 6 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
 			29300, 7, 108, 4, 7, 7, 7, 7 },
-		{ VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
+		{ RC_HT_SD_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
 			6400, 0, 0, 0, 8, 25, 8, 25 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
+		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
 			12700, 1, 1, 2, 9, 26, 9, 26 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
+		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
 			18800, 2, 2, 2, 10, 27, 10, 27 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
+		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
 			25000, 3, 3, 4, 11, 28, 11, 28 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
+		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
 			36700, 4, 4, 4, 12, 29, 12, 29 },
-		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
+		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
 			48100, 5, 5, 4, 13, 30, 13, 30 },
-		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
+		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
 			53500, 6, 6, 4, 14, 31, 14, 31 },
-		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
+		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
 			59000, 7, 7, 4, 15, 32, 15, 33 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
 			12700, 8, 8, 3, 16, 34, 16, 34 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
 			24800, 9, 9, 2, 17, 35, 17, 35 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
 			36600, 10, 10, 2, 18, 36, 18, 36 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
 			48100, 11, 11, 4, 19, 37, 19, 37 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
 			69500, 12, 12, 4, 20, 38, 20, 38 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
 			89500, 13, 13, 4, 21, 39, 21, 39 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
 			98900, 14, 14, 4, 22, 40, 22, 40 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
 			108300, 15, 15, 4, 23, 41, 24, 42 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 144.4 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 144.4 Mb */
 			12000, 15, 15, 4, 23, 41, 24, 42 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
+		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
 			13200, 0, 0, 0, 8, 25, 25, 25 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
+		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
 			25900, 1, 1, 2, 9, 26, 26, 26 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
+		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
 			38600, 2, 2, 2, 10, 27, 27, 27 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
+		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
 			49800, 3, 3, 4, 11, 28, 28, 28 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
+		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
 			72200, 4, 4, 4, 12, 29, 29, 29 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
+		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
 			92900, 5, 5, 4, 13, 30, 30, 30 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
+		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
 			102700, 6, 6, 4, 14, 31, 31, 31 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
+		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
 			112000, 7, 7, 4, 15, 32, 33, 33 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
+		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
 			122000, 7, 7, 4, 15, 32, 33, 33 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
 			25800, 8, 8, 0, 16, 34, 34, 34 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
 			49800, 9, 9, 2, 17, 35, 35, 35 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
 			71900, 10, 10, 2, 18, 36, 36, 36 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
 			92500, 11, 11, 4, 19, 37, 37, 37 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
 			130300, 12, 12, 4, 20, 38, 38, 38 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
 			162800, 13, 13, 4, 21, 39, 39, 39 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
 			178200, 14, 14, 4, 22, 40, 40, 40 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
 			192100, 15, 15, 4, 23, 41, 42, 42 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
 			207000, 15, 15, 4, 23, 41, 42, 42 },
 	},
 	50,  /* probe interval */
@@ -121,99 +121,99 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
 	47,
 	12, /* MCS start */
 	{
-		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
+		{ RC_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
 			900, 0, 2, 0, 0, 0, 0, 0 },
-		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
+		{ RC_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
 			1900, 1, 4, 1, 1, 1, 1, 1 },
-		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
+		{ RC_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
 			4900, 2, 11, 2, 2, 2, 2, 2 },
-		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
+		{ RC_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
 			8100, 3, 22, 3, 3, 3, 3, 3 },
-		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 4, 12, 4, 4, 4, 4, 4 },
-		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800, 5, 18, 4, 5, 5, 5, 5 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
 			10100, 6, 24, 6, 6, 6, 6, 6 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
 			14100, 7, 36, 6, 7, 7, 7, 7 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
 			17700, 8, 48, 8, 8, 8, 8, 8 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
 			23700, 9, 72, 8, 9, 9, 9, 9 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
 			27400, 10, 96, 8, 10, 10, 10, 10 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
 			30900, 11, 108, 8, 11, 11, 11, 11 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
 			6400, 0, 0, 4, 12, 29, 12, 29 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
+		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
 			12700, 1, 1, 6, 13, 30, 13, 30 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
+		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
 			18800, 2, 2, 6, 14, 31, 14, 31 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
+		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
 			25000, 3, 3, 8, 15, 32, 15, 32 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
+		{ RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
 			36700, 4, 4, 8, 16, 33, 16, 33 },
-		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
+		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
 			48100, 5, 5, 8, 17, 34, 17, 34 },
-		{ INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
+		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
 			53500, 6, 6, 8, 18, 35, 18, 35 },
-		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
+		{ RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
 			59000, 7, 7, 8, 19, 36, 19, 37 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
 			12700, 8, 8, 4, 20, 38, 20, 38 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
 			24800, 9, 9, 6, 21, 39, 21, 39 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
 			36600, 10, 10, 6, 22, 40, 22, 40 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
 			48100, 11, 11, 8, 23, 41, 23, 41 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
 			69500, 12, 12, 8, 24, 42, 24, 42 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
 			89500, 13, 13, 8, 25, 43, 25, 43 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
 			98900, 14, 14, 8, 26, 44, 26, 44 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
 			108300, 15, 15, 8, 27, 45, 28, 46 },
-		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 130 Mb */
+		{ RC_HT_D_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 130 Mb */
 			120000, 15, 15, 8, 27, 45, 28, 46 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
+		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
 			13200, 0, 0, 8, 12, 29, 29, 29 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
+		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
 			25900, 1, 1, 8, 13, 30, 30, 30 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
+		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
 			38600, 2, 2, 8, 14, 31, 31, 31 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
+		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
 			49800, 3, 3, 8,  15, 32, 32, 32 },
-		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
+		{ RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
 			72200, 4, 4, 8, 16, 33, 33, 33 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
+		{ RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
 			92900, 5, 5, 8, 17, 34, 34, 34 },
-		{ INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
+		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
 			102700, 6, 6, 8, 18, 35, 35, 35 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
+		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
 			112000, 7, 7, 8, 19, 36, 37, 37 },
-		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
+		{ RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
 			122000, 7, 7, 8, 19, 36, 37, 37 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
 			25800, 8, 8, 8, 20, 38, 38, 38 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
 			49800, 9, 9, 8, 21, 39, 39, 39 },
-		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
 			71900, 10, 10, 8, 22, 40, 40, 40 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
 			92500, 11, 11, 8, 23, 41, 41, 41 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
 			130300, 12, 12, 8, 24, 42, 42, 42 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
 			162800, 13, 13, 8, 25, 43, 43, 43 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
 			178200, 14, 14, 8, 26, 44, 44, 44 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
 			192100, 15, 15, 8, 27, 45, 46, 46 },
-		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
+		{ RC_HT_D_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
 			207000, 15, 15, 8, 27, 45, 46, 46 },
 	},
 	50,  /* probe interval */
@@ -224,21 +224,21 @@ static const struct ath_rate_table ar5416_11a_ratetable = {
 	8,
 	0,
 	{
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 0, 12, 0, 0, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800,  1, 18, 0, 1, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
 			10000, 2, 24, 2, 2, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
 			13900, 3, 36, 2, 3, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
 			17300, 4, 48, 4, 4, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
 			23000, 5, 72, 4, 5, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
 			27400, 6, 96, 4, 6, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
 			29300, 7, 108, 4, 7, 0 },
 	},
 	50,  /* probe interval */
@@ -249,29 +249,29 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
 	12,
 	0,
 	{
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
 			900, 0, 2, 0, 0, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
 			1900, 1, 4, 1, 1, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
 			4900, 2, 11, 2, 2, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
 			8100, 3, 22, 3, 3, 0 },
-		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 4, 12, 4, 4, 0 },
-		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+		{ RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800, 5, 18, 4, 5, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
 			10000, 6, 24, 6, 6, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
 			13900, 7, 36, 6, 7, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
 			17300, 8, 48, 8, 8, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
 			23000, 9, 72, 8, 9, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
 			27400, 10, 96, 8, 10, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+		{ RC_L_SD, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
 			29300, 11, 108, 8, 11, 0 },
 	},
 	50,  /* probe interval */
@@ -342,7 +342,7 @@ static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
 					   u8 index, int valid_tx_rate)
 {
 	BUG_ON(index > ath_rc_priv->rate_table_size);
-	ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
+	ath_rc_priv->valid_rate_index[index] = !!valid_tx_rate;
 }
 
 static inline
@@ -404,13 +404,9 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
 				 u32 capflag)
 {
 	u8 i, hi = 0;
-	u32 valid;
 
 	for (i = 0; i < rate_table->rate_cnt; i++) {
-		valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
-			 rate_table->info[i].valid_single_stream :
-			 rate_table->info[i].valid);
-		if (valid == 1) {
+		if (rate_table->info[i].rate_flags & RC_LEGACY) {
 			u32 phy = rate_table->info[i].phy;
 			u8 valid_rate_count = 0;
 
@@ -422,7 +418,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
 			ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
 			ath_rc_priv->valid_phy_ratecnt[phy] += 1;
 			ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
-			hi = A_MAX(hi, i);
+			hi = i;
 		}
 	}
 
@@ -440,9 +436,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
 	for (i = 0; i < rateset->rs_nrates; i++) {
 		for (j = 0; j < rate_table->rate_cnt; j++) {
 			u32 phy = rate_table->info[j].phy;
-			u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
-				     rate_table->info[j].valid_single_stream :
-				     rate_table->info[j].valid);
+			u16 rate_flags = rate_table->info[i].rate_flags;
 			u8 rate = rateset->rs_rates[i];
 			u8 dot11rate = rate_table->info[j].dot11rate;
 
@@ -451,8 +445,9 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
 			 * (VALID/VALID_20/VALID_40) flags */
 
 			if ((rate == dot11rate) &&
-			    ((valid & WLAN_RC_CAP_MODE(capflag)) ==
-			     WLAN_RC_CAP_MODE(capflag)) &&
+			    (rate_flags & WLAN_RC_CAP_MODE(capflag)) ==
+			    WLAN_RC_CAP_MODE(capflag) &&
+			    (rate_flags & WLAN_RC_CAP_STREAM(capflag)) &&
 			    !WLAN_RC_PHY_HT(phy)) {
 				u8 valid_rate_count = 0;
 
@@ -486,14 +481,13 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
 	for (i = 0; i < rateset->rs_nrates; i++) {
 		for (j = 0; j < rate_table->rate_cnt; j++) {
 			u32 phy = rate_table->info[j].phy;
-			u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
-				     rate_table->info[j].valid_single_stream :
-				     rate_table->info[j].valid);
+			u16 rate_flags = rate_table->info[j].rate_flags;
 			u8 rate = rateset->rs_rates[i];
 			u8 dot11rate = rate_table->info[j].dot11rate;
 
 			if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) ||
-			    !WLAN_RC_PHY_HT_VALID(valid, capflag))
+			    !(rate_flags & WLAN_RC_CAP_STREAM(capflag)) ||
+			    !WLAN_RC_PHY_HT_VALID(rate_flags, capflag))
 				continue;
 
 			if (!ath_rc_valid_phyrate(phy, capflag, 0))
@@ -589,12 +583,11 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
 	if (rate > (ath_rc_priv->rate_table_size - 1))
 		rate = ath_rc_priv->rate_table_size - 1;
 
-	if (rate_table->info[rate].valid &&
+	if (rate_table->info[rate].rate_flags & RC_DS &&
 	    (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
 		return rate;
 
-	if (rate_table->info[rate].valid_single_stream &&
-	    !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
+	if (RC_SS_OR_LEGACY(rate_table->info[rate].rate_flags))
 		return rate;
 
 	/* This should not happen */
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 3d8d40c..601803a 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -27,17 +27,29 @@ struct ath_softc;
 #define RATE_TABLE_SIZE  64
 #define MAX_TX_RATE_PHY  48
 
-/* VALID_ALL - valid for 20/40/Legacy,
- * VALID - Legacy only,
- * VALID_20 - HT 20 only,
- * VALID_40 - HT 40 only */
-
-#define INVALID    0x0
-#define VALID      0x1
-#define VALID_20   0x2
-#define VALID_40   0x4
-#define VALID_2040 (VALID_20|VALID_40)
-#define VALID_ALL  (VALID_2040|VALID)
+
+#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_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)
+#define RC_L_SD			(RC_LEGACY | RC_SS | RC_DS)
+#define RC_HT_SD_2040		(RC_HT_2040 | RC_SS | RC_DS)
+#define RC_HT_S_20		(RC_HT_20 | RC_SS)
+#define RC_HT_SD_20		(RC_HT_20 | RC_SS | RC_DS)
+#define RC_HT_SD_40		(RC_HT_40 | RC_SS | RC_DS)
+#define RC_HT_S_20		(RC_HT_20 | RC_SS)
+#define RC_HT_S_40		(RC_HT_40 | RC_SS)
+#define RC_HT_D_20		(RC_HT_20 | RC_DS)
+#define RC_HT_D_40		(RC_HT_40 | RC_DS)
+#define RC_ALL			(RC_LEGACY | RC_HT_2040 | RC_ALL_STREAM)
 
 enum {
 	WLAN_RC_PHY_OFDM,
@@ -73,15 +85,19 @@ enum {
 #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) ? VALID_40 : VALID_20 : VALID))
+	((capflag & WLAN_RC_40_FLAG) ? RC_HT_40 : RC_HT_20) : RC_LEGACY))
+
+#define WLAN_RC_CAP_STREAM(capflag) \
+	(((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 & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \
-	 ((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG)))
+	(((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_40_FLAG         (0x02)
@@ -110,8 +126,7 @@ struct ath_rate_table {
 	int rate_cnt;
 	int mcs_start;
 	struct {
-		u8 valid;
-		u8 valid_single_stream;
+		u16 rate_flags;
 		u8 phy;
 		u32 ratekbps;
 		u32 user_ratekbps;
-- 
1.7.1


^ permalink raw reply related

* Re: udevd / ext4 issue mounting 2.6.35-rc5
From: Stefan Bader @ 2010-07-27 12:34 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Daniel J Blueman, Rafael J. Wysocki, Ubuntu Kernel Team,
	linux-ext4, linux-wireless, linux-kernel
In-Reply-To: <AANLkTi=9Y+v6ikUi=UH1BNKgcOFfp13Q1YowjJVrRSA9@mail.gmail.com>

On 07/27/2010 01:43 AM, Luis R. Rodriguez wrote:
> On Fri, Jul 23, 2010 at 10:56 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>> On Fri, Jul 23, 2010 at 9:49 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>>> On Thu, Jul 22, 2010 at 2:10 AM, Daniel J Blueman
>>> <daniel.blueman@gmail.com> wrote:
>>>> On 22 July 2010 02:06, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>>>>> On Wed, Jul 21, 2010 at 1:43 AM, Daniel J Blueman
>>>>> <daniel.blueman@gmail.com> wrote:
>>>>>> Hi Luis,
>>>>>>
>>>>>> On 21 July 2010 01:36, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>>>>>>> I have been reluctant to boot to 2.6.35-rc due to the large set of
>>>>>>> regression list and the amount of work I needed to actually get done
>>>>>>> on 2.6.35. Last I checked the regression list it was getting small so
>>>>>>> I gave it a spin today. No luck. I get some bootup error from udevd
>>>>>>> and ext2/ext3/ext4, something like this:
>>>>>>>
>>>>>>> EXT3-fs (sda1): error: couldn't mount because of unsupported optional
>>>>>>> features (240)
>>>>>>> EXT2-fs (sda1): error: couldn't mount because of unsupported optional
>>>>>>> features (240)
>>>>>>> EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: (null)
>>>>>>
>>>>>> This succeeded.
>>>>>
>>>>> Heh, OK :)
>>>>>
>>>>>>> VFS: Mounted root (ext4 filesystem) readonly on device 8:1
>>>>>>> Freeing unused kernel memory: 708k freed
>>>>>>> Write protecting the kernel read-only data: 102040k
>>>>>>> Freeing unused kernel memory: 764k freed
>>>>>>> Freeing unused kernel memory: 1796k freed
>>>>>>> udevd: failed to create queue file: No such file or directory
>>>>>>> udevd: error creating queue file
>>>>>>
>>>>>> It looks like you need to enable:
>>>>>>
>>>>>> CONFIG_DEVTMPFS
>>>>>> CONFIG_DEVTMPFS_MOUNT
>>>>>
>>>>> Thanks, it also turned out that when I upgraded from Ubuntu 9.10 to
>>>>> Ubuntu 10.04 it replaced my own /sbin/installkernel so this was likely
>>>>> another issue. My /sbin/installkernel changes allow for easy initramfs
>>>>> installation on Debian/Ubuntu but my patches have been ignored my the
>>>>> maintainer.
>>>>>
>>>>> --- installkernel-ubuntu-10.04  2010-07-21 18:03:34.607678010 -0700
>>>>> +++ installkernel       2010-01-29 13:17:10.000000000 -0800
>>>>> @@ -36,7 +36,8 @@
>>>>>  # Create backups of older versions before installing
>>>>>  updatever () {
>>>>>   if [ -f "$dir/$1-$ver" ] ; then
>>>>> -    mv "$dir/$1-$ver" "$dir/$1-$ver.old"
>>>>> +    #mv "$dir/$1-$ver" "$dir/$1-$ver.old"
>>>>> +    rm -f "$dir/$1-$ver" "$dir/$1-$ver.old"
>>>>>   fi
>>>>>
>>>>>   cat "$2" > "$dir/$1-$ver"
>>>>> @@ -75,5 +76,16 @@
>>>>>  if [ -f "$config" ] ; then
>>>>>   updatever config "$config"
>>>>>  fi
>>>>> +
>>>>> +LSB_RED_ID=$(/usr/bin/lsb_release -i -s)
>>>>> +
>>>>> +case $LSB_RED_ID in
>>>>> +"Ubuntu")
>>>>> +       update-initramfs -c -k  $ver
>>>>> +       update-grub
>>>>> +       ;;
>>>>> +*)
>>>>> +       ;;
>>>>> +esac
>>>>>
>>>>>  exit 0
>>>>>
>>>>> But anyway I also now get another boot failure with:
>>>>>
>>>>> mount: mounting /dev on /root/dev failed: No such file or directory
>>>>> mount: mounting /sys on /root/sys failed: No such file or directory
>>>>
>>>> Hmm...the scripts in the initrd are not doing what is expected -
>>>> perhaps if you didn't use:
>>>> linux$ fakeroot make-kpkg --append-to-version -luis1 --initrd kernel-image
>>>
>>> I am not using that to build my kernels I just build my kernels with
>>>
>>> make
>>> sudo make modules_install install
>>>
>>>> ...or if there are eg initrd script modifications on the filesystem
>>>> when it cooked the initd.
>>>
>>> I haven't modified any initrd scripts.
>>>
>>>> You could just try eg:
>>>> http://archive.ubuntu.com/ubuntu/pool/main/l/linux/linux-image-2.6.35-9-generic_2.6.35-9.14_amd64.deb
>>
>> Fun, so that kernel actually works but the one I am building from
>> wireless-testing.git does not. The curious thing is it doesn't boot
>> even if I remove my 802.11 module... so something is fishy. This is
>> likely a config issue. After booting with the above kernel though I
>> generated a new one with
>>
>> make localmodconfig
>>
>> and then enabled my 802.11 modules. Still, no luck.. Going to reset my
>> tree, I had manually merged Linus' latest stuff in but I don't think
>> this should matter.
> 
> That didn't work, but it seems this was just my config, the same
> config worked on older kernels but I am not motivated enough to figure
> out what I actually did enable which fixed this. But just for the
> record
> 
> config which did not work:
> 
> http://bombadil.infradead.org/~mcgrof/configs/2010/config-issue/config-old.txt
> 
> config which worked:
> 
> http://bombadil.infradead.org/~mcgrof/configs/2010/config-issue/config.txt
> 
> The diff:
> 
> http://bombadil.infradead.org/~mcgrof/configs/2010/config-issue/diff-34-35.patch
> 
>   Luis
> 

Hm, I hope I did not miss some info in the threads above, but have you tried to
use the config in /boot/ as a base for your new config with make oldconfig?
I think to remember make modules_install purges all existing modules under
kernel before installing the new ones. So likely there is something essential
going away when rebuilding the initrd. The messages sound like basic root fs is
not there, so it misses all the mount points. But I admit to be too lazy to walk
all the config.

-Stefan

^ permalink raw reply

* Re: [PATCH] mac80211: fix sw scan bracketing
From: Johannes Berg @ 2010-07-27 10:22 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: John Linville, linux-wireless
In-Reply-To: <AANLkTik=1LX_12ZskP5vwkSrTVFO9jH6uu8pyByGmLg6@mail.gmail.com>

On Tue, 2010-07-27 at 02:22 -0700, Luis R. Rodriguez wrote:

> > Yeap, reverting this patch alone today on wireless-testing makes me
> > ath9k happy once again.
> 
> So after some though and review in order to fix this we need a little
> more time and thought. The above patch changes the order in which we
> configure hardware upon a scan complete. It used to be we would
> configure the hardware, configure the filter and then scan complete.
> By then we'd be on the home channel and the filters would be set
> correctly. ath9k's scan complete routine does a few things which
> depend on the channel and will make hardware poo otherwise or do
> stupid things:
> 
>   * start TX poll routine, due to the new latency introduced to
> configure hardware and configure the RX filter the TX polll routine
> now has some extra work done by hardware before it actually starts
> TXing. I don't suspect this could introduce a huge regression but it
> is worth noting.

I don't even understand why this is stopped during scan?

>   * ANI gets started, and the wrong channel is used if we're not yet
> on the home channel. A simple patch to test if this may be causing the
> disconnect issue I am seeing I just tried was to increase the delay
> before starting ANI, this did indeed help.

This really should be done when the channel is configured after scan
anyway.

>   * ath_beacon_config() which I suspect means that if we now scan in
> AP mode/IBSS mode we could potentially be leaking beacons on the last
> channel of a scan, prior to sending them on the actual desired home
> channel.

This should be done by the driver based on mac80211's indication of
whether it should be beaconing or not, not based on the scan callbacks.

I'm starting to think that it was a mistake to add these callbacks to
start with ...

> To address and review all this I need more time and instead I think
> its easier to ask for revert of this patch.

I'm OK with a revert, but *ONLY* if at the same time you remove the
double-scan-detected message from ath9k and stop claiming it's a
mac80211 bug :-)

johannes


^ permalink raw reply

* Re: [PATCH v4 1/3] cfg80211: Add nl80211 antenna configuration
From: Johannes Berg @ 2010-07-27 10:05 UTC (permalink / raw)
  To: Bruno Randolf; +Cc: linville, linux-wireless, lrodriguez
In-Reply-To: <20100727094759.27186.79639.stgit@tt-desk>

On Tue, 2010-07-27 at 18:48 +0900, Bruno Randolf wrote:

> The antenna configuration is defined as a bitmap of allowed antennas to use for
> either receiving or transmitting. Separate bitmaps are used for RX and TX to
> allow configuring different antennas for receiving and transmitting. The bitmap
> is 8 bit long, each bit representing one antenna, starting with antenna 1.
> 
> If multiple receive (RX) antennas are selected, the driver may use diversity or
> multiple 802.11n RX chains, according to the chipset capabilities and
> configuration.

I'm still not convinced that this is the best approach. Can you discuss
this a bit?

johannes


^ permalink raw reply

* Re: [PATCH 2/2] iw: Add antenna configuration commands
From: Johannes Berg @ 2010-07-27 10:04 UTC (permalink / raw)
  To: Bruno Randolf; +Cc: linville, linux-wireless
In-Reply-To: <20100727094937.27300.97445.stgit@tt-desk>

On Tue, 2010-07-27 at 18:49 +0900, Bruno Randolf wrote:

> +	if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
> +	    tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
> +		printf("\tAntenna: TX %d RX %d\n",
> +		       nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]),
> +		       nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]));

That's like the worst possible way to show the info.

johannes


^ permalink raw reply

* [PATCH 2/2] iw: Add antenna configuration commands
From: Bruno Randolf @ 2010-07-27  9:49 UTC (permalink / raw)
  To: johannes, linville; +Cc: linux-wireless
In-Reply-To: <20100727094932.27300.10253.stgit@tt-desk>

Add command to set the antenna configuration (iw phyX set antenna ...) and
include antenna setting in wiphy information (iw phyX info).

Signed-off-by: Bruno Randolf <br1@einfach.org>
---
 info.c |    7 +++++++
 phy.c  |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/info.c b/info.c
index 512e777..dc987c7 100644
--- a/info.c
+++ b/info.c
@@ -167,6 +167,13 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
 		printf("\tCoverage class: %d (up to %dm)\n", coverage, 450 * coverage);
 	}
 
+	if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
+	    tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
+		printf("\tAntenna: TX %d RX %d\n",
+		       nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]),
+		       nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]));
+	}
+
 	if (!tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES])
 		goto commands;
 
diff --git a/phy.c b/phy.c
index 1f54ba3..75c80d2 100644
--- a/phy.c
+++ b/phy.c
@@ -306,3 +306,49 @@ COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]",
 COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]",
 	NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_txpower,
 	"Specify transmit power level and setting type.");
+
+static int handle_antenna(struct nl80211_state *state,
+			  struct nl_cb *cb,
+			  struct nl_msg *msg,
+			  int argc, char **argv)
+{
+	char *end;
+	uint8_t tx_ant = 0, rx_ant = 0;
+
+	if (argc == 1) {
+		if (strcmp(*argv, "diversity") == 0) {
+			tx_ant = 0;
+			rx_ant = 0xf;
+		} else {
+			tx_ant = rx_ant = strtoul(argv[0], &end, 10);
+		}
+	}
+	else if (argc == 4) {
+		while (argc) {
+			if (strcmp(*argv, "tx") == 0 ||
+			    strcmp(*argv, "rx") == 0) {
+				if (strcmp(*argv, "tx") == 0)
+					tx_ant = strtoul(argv[1], &end, 10);
+				else
+					rx_ant = strtoul(argv[1], &end, 10);
+			}
+			argv = argv + 2;
+			argc = argc - 2;
+		}
+	}
+
+	if (*end)
+		return 1;
+
+	NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant);
+	NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant);
+
+	return 0;
+
+ nla_put_failure:
+	return -ENOBUFS;
+}
+COMMAND(set, antenna, "<bitmap> | diversity | tx <bitmap> rx <bitmap>",
+	NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_antenna,
+	"Set a bitmap of allowed antennas to use for TX and RX.\n"
+	"The driver may reject antenna configurations it cannot support.");


^ permalink raw reply related

* [PATCH 1/2] iw: Sync nl80211.h with wireless-testing
From: Bruno Randolf @ 2010-07-27  9:49 UTC (permalink / raw)
  To: johannes, linville; +Cc: linux-wireless

Adding antenna attributes.

Signed-off-by: Bruno Randolf <br1@einfach.org>
---
 nl80211.h |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/nl80211.h b/nl80211.h
index 2c87016..b9de53c 100644
--- a/nl80211.h
+++ b/nl80211.h
@@ -731,6 +731,20 @@ enum nl80211_commands {
  *      This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING
  *      for non-automatic settings.
  *
+ * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for transmitting.
+ *	Each bit represents one antenna, starting with antenna 1 at the first
+ *	bit. If the bitmap is zero (0), the TX antenna follows RX diversity.
+ *	If multiple antennas are selected all selected antennas have to be used
+ *	for transmitting (801.11n multiple TX chains).
+ *	Drivers may reject configurations they cannot support.
+ *
+ * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for receiving.
+ *	Each bit represents one antenna, starting with antenna 1 at the first
+ *	bit. If multiple antennas are selected in the bitmap, 802.11n devices
+ *	should use multiple RX chains on these antennas, while non-802.11n
+ *	drivers should use antenna diversity between these antennas.
+ *	Drivers may reject configurations they cannot support.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -891,6 +905,9 @@ enum nl80211_attrs {
 	NL80211_ATTR_WIPHY_TX_POWER_SETTING,
 	NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
 
+	NL80211_ATTR_WIPHY_ANTENNA_TX,
+	NL80211_ATTR_WIPHY_ANTENNA_RX,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,


^ permalink raw reply related

* [PATCH v4 3/3] ath5k: Add support for antenna configuration
From: Bruno Randolf @ 2010-07-27  9:48 UTC (permalink / raw)
  To: johannes, linville; +Cc: linux-wireless, lrodriguez
In-Reply-To: <20100727094732.27186.30900.stgit@tt-desk>

Support setting the antenna configuration via cfg/mac80211. At the moment only
allow the simple pre-defined configurations we already have (fixed antenna A/B
or diversity), but more advanced settings are possible to implement.

Signed-off-by: Bruno Randolf <br1@einfach.org>
---
 drivers/net/wireless/ath/ath5k/base.c |   34 +++++++++++++++++++++++++++++++++
 1 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 0d5de25..9150d1a 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -256,6 +256,8 @@ static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
 static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
 static void ath5k_set_coverage_class(struct ieee80211_hw *hw,
 		u8 coverage_class);
+static int ath5k_set_antenna(struct ieee80211_hw *hw, u8 tx_ant, u8 rx_ant);
+static int ath5k_get_antenna(struct ieee80211_hw *hw, u8 *tx_ant, u8 *rx_ant);
 
 static const struct ieee80211_ops ath5k_hw_ops = {
 	.tx 		= ath5k_tx,
@@ -277,6 +279,8 @@ static const struct ieee80211_ops ath5k_hw_ops = {
 	.sw_scan_start	= ath5k_sw_scan_start,
 	.sw_scan_complete = ath5k_sw_scan_complete,
 	.set_coverage_class = ath5k_set_coverage_class,
+	.set_antenna	= ath5k_set_antenna,
+	.get_antenna	= ath5k_get_antenna,
 };
 
 /*
@@ -3526,3 +3530,33 @@ static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
 	ath5k_hw_set_coverage_class(sc->ah, coverage_class);
 	mutex_unlock(&sc->lock);
 }
+
+static int ath5k_set_antenna(struct ieee80211_hw *hw, u8 tx_ant, u8 rx_ant)
+{
+	struct ath5k_softc *sc = hw->priv;
+
+	if (tx_ant == 1 && rx_ant == 1)
+		ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A);
+	else if (tx_ant == 2 && rx_ant == 2)
+		ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B);
+	else if (tx_ant == 0 && (rx_ant & 3) == 3)
+		ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT);
+	else
+		return -EINVAL;
+	return 0;
+}
+
+static int ath5k_get_antenna(struct ieee80211_hw *hw, u8 *tx_ant, u8 *rx_ant)
+{
+	struct ath5k_softc *sc = hw->priv;
+
+	switch (sc->ah->ah_ant_mode) {
+	case AR5K_ANTMODE_FIXED_A:
+		*tx_ant = 1; *rx_ant = 1; break;
+	case AR5K_ANTMODE_FIXED_B:
+		*tx_ant = 2; *rx_ant = 2; break;
+	case AR5K_ANTMODE_DEFAULT:
+		*tx_ant = 0; *rx_ant = 3; break;
+	}
+	return 0;
+}


^ permalink raw reply related

* [PATCH v4 2/3] mac80211: Add antenna configuration
From: Bruno Randolf @ 2010-07-27  9:48 UTC (permalink / raw)
  To: johannes, linville; +Cc: linux-wireless, lrodriguez
In-Reply-To: <20100727094732.27186.30900.stgit@tt-desk>

Allow antenna configuration by calling driver's function for it.

Signed-off-by: Bruno Randolf <br1@einfach.org>
---
 include/net/mac80211.h      |    2 ++
 net/mac80211/cfg.c          |   16 ++++++++++++++
 net/mac80211/driver-ops.h   |   23 ++++++++++++++++++++
 net/mac80211/driver-trace.h |   50 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 91 insertions(+), 0 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 20d372e..f8e04d1 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1744,6 +1744,8 @@ struct ieee80211_ops {
 	void (*flush)(struct ieee80211_hw *hw, bool drop);
 	void (*channel_switch)(struct ieee80211_hw *hw,
 			       struct ieee80211_channel_switch *ch_switch);
+	int (*set_antenna)(struct ieee80211_hw *hw, u8 tx_ant, u8 rx_ant);
+	int (*get_antenna)(struct ieee80211_hw *hw, u8 *tx_ant, u8 *rx_ant);
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f09a52d..7b99e6a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1598,6 +1598,20 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
 	return 0;
 }
 
+static int ieee80211_set_antenna(struct wiphy *wiphy, u8 tx_ant, u8 rx_ant)
+{
+	struct ieee80211_local *local = wiphy_priv(wiphy);
+
+	return drv_set_antenna(local, tx_ant, rx_ant);
+}
+
+static int ieee80211_get_antenna(struct wiphy *wiphy, u8 *tx_ant, u8 *rx_ant)
+{
+	struct ieee80211_local *local = wiphy_priv(wiphy);
+
+	return drv_get_antenna(local, tx_ant, rx_ant);
+}
+
 struct cfg80211_ops mac80211_config_ops = {
 	.add_virtual_intf = ieee80211_add_iface,
 	.del_virtual_intf = ieee80211_del_iface,
@@ -1649,4 +1663,6 @@ struct cfg80211_ops mac80211_config_ops = {
 	.cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
 	.action = ieee80211_action,
 	.set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
+	.set_antenna = ieee80211_set_antenna,
+	.get_antenna = ieee80211_get_antenna,
 };
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 14123dc..0aa6399 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -414,4 +414,27 @@ static inline void drv_channel_switch(struct ieee80211_local *local,
 	trace_drv_return_void(local);
 }
 
+
+static inline int drv_set_antenna(struct ieee80211_local *local,
+				  u8 tx_ant, u8 rx_ant)
+{
+	int ret = -EOPNOTSUPP;
+	might_sleep();
+	if (local->ops->set_antenna)
+		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
+	trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
+	return ret;
+}
+
+static inline int drv_get_antenna(struct ieee80211_local *local,
+				  u8 *tx_ant, u8 *rx_ant)
+{
+	int ret = -EOPNOTSUPP;
+	might_sleep();
+	if (local->ops->get_antenna)
+		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
+	trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
+	return ret;
+}
+
 #endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 5d5d2a9..3aac91b 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -832,6 +832,56 @@ TRACE_EVENT(drv_channel_switch,
 	)
 );
 
+TRACE_EVENT(drv_set_antenna,
+	TP_PROTO(struct ieee80211_local *local, u8 tx_ant, u8 rx_ant, int ret),
+
+	TP_ARGS(local, tx_ant, rx_ant, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(u8, tx_ant)
+		__field(u8, rx_ant)
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->tx_ant = tx_ant;
+		__entry->rx_ant = rx_ant;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d",
+		LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_get_antenna,
+	TP_PROTO(struct ieee80211_local *local, u8 tx_ant, u8 rx_ant, int ret),
+
+	TP_ARGS(local, tx_ant, rx_ant, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(u8, tx_ant)
+		__field(u8, rx_ant)
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->tx_ant = tx_ant;
+		__entry->rx_ant = rx_ant;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d",
+		LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret
+	)
+);
+
 /*
  * Tracing for API calls that drivers call.
  */


^ permalink raw reply related

* [PATCH v4 1/3] cfg80211: Add nl80211 antenna configuration
From: Bruno Randolf @ 2010-07-27  9:48 UTC (permalink / raw)
  To: johannes, linville; +Cc: linux-wireless, lrodriguez
In-Reply-To: <20100727094732.27186.30900.stgit@tt-desk>

Allow setting TX and RX antenna configuration via nl80211.

The antenna configuration is defined as a bitmap of allowed antennas to use for
either receiving or transmitting. Separate bitmaps are used for RX and TX to
allow configuring different antennas for receiving and transmitting. The bitmap
is 8 bit long, each bit representing one antenna, starting with antenna 1.

If multiple receive (RX) antennas are selected, the driver may use diversity or
multiple 802.11n RX chains, according to the chipset capabilities and
configuration.

If multiple transmit (TX) antennas are selected, the driver has to send on all
selected antennas, making this mode of operation only possible on 802.11n
chipsets with multiple TX chains. If the transmit antenna bitmap is set to the
special value zero (0) the driver should select the TX antenna based on the
antenna which was used for receiving (TX antenna follows RX diversity - this is
the usual mode of 'diversity') for pre 802.11n devices.

Using bitmaps has the benefit of allowing for a flexible configuration
interface which can support many different configurations. Drivers should
reject configurations they cannot support. While covering the standard modes
"fixed antenna 1", "fixed antenna 2" and "diversity" this API also allows more
rare - but useful - configurations as follows:

1) Send on antenna 1, receive on antenna 2 (or vice versa). This can be used to
have a low gain antenna for TX in order to keep within the regulatory
constraints and a high gain antenna for RX in order to receive weaker signals
("speak softly, but listen harder"). This can be useful for building long-shot
outdoor links. Another usage of this setup is having a low-noise pre-amplifier
on antenna 1 and a power amplifier on the other antenna. This way transmit
noise is mostly kept out of the low noise receive channel.
(This would be bitmaps: tx 1 rx 2).

2) Another similar setup is: Use RX diversity on both antennas, but always send
on antenna 1. Again that would allow us to benefit from a higher gain RX
antenna, while staying within the legal limits.
(This would be: tx 0 rx 3).

3) And finally there can be special experimental setups in research and
development where more than 2 antennas are available. It's good to keep the API
flexible.

Signed-off-by: Bruno Randolf <br1@einfach.org>
---
 include/linux/nl80211.h |   17 +++++++++++++++++
 include/net/cfg80211.h  |    3 +++
 net/wireless/nl80211.c  |   30 +++++++++++++++++++++++++++++-
 3 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 2c87016..b9de53c 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -731,6 +731,20 @@ enum nl80211_commands {
  *      This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING
  *      for non-automatic settings.
  *
+ * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for transmitting.
+ *	Each bit represents one antenna, starting with antenna 1 at the first
+ *	bit. If the bitmap is zero (0), the TX antenna follows RX diversity.
+ *	If multiple antennas are selected all selected antennas have to be used
+ *	for transmitting (801.11n multiple TX chains).
+ *	Drivers may reject configurations they cannot support.
+ *
+ * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for receiving.
+ *	Each bit represents one antenna, starting with antenna 1 at the first
+ *	bit. If multiple antennas are selected in the bitmap, 802.11n devices
+ *	should use multiple RX chains on these antennas, while non-802.11n
+ *	drivers should use antenna diversity between these antennas.
+ *	Drivers may reject configurations they cannot support.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -891,6 +905,9 @@ enum nl80211_attrs {
 	NL80211_ATTR_WIPHY_TX_POWER_SETTING,
 	NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
 
+	NL80211_ATTR_WIPHY_ANTENNA_TX,
+	NL80211_ATTR_WIPHY_ANTENNA_RX,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f68ae54..7dc0e8d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1184,6 +1184,9 @@ struct cfg80211_ops {
 	int	(*set_cqm_rssi_config)(struct wiphy *wiphy,
 				       struct net_device *dev,
 				       s32 rssi_thold, u32 rssi_hyst);
+
+	int	(*set_antenna)(struct wiphy *wiphy, u8 tx_ant, u8 rx_ant);
+	int	(*get_antenna)(struct wiphy *wiphy, u8 *tx_ant, u8 *rx_ant);
 };
 
 /*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cea595e..62fc5fe 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -156,6 +156,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
 
 	[NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
 	[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
+
+	[NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U8 },
+	[NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U8 },
 };
 
 /* policy for the attributes */
@@ -458,7 +461,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 		    dev->wiphy.rts_threshold);
 	NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
 		    dev->wiphy.coverage_class);
-
 	NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
 		   dev->wiphy.max_scan_ssids);
 	NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
@@ -471,6 +473,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 	NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
 		   dev->wiphy.max_num_pmkids);
 
+	if (dev->ops->get_antenna) {
+		u8 tx_ant = 0, rx_ant = 0;
+		int res;
+		res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant);
+		if (!res) {
+			NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant);
+			NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant);
+		}
+	}
+
 	nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
 	if (!nl_modes)
 		goto nla_put_failure;
@@ -900,6 +912,22 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
 			goto bad_res;
 	}
 
+	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
+	    info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
+		u8 tx_ant, rx_ant;
+		if (!rdev->ops->set_antenna) {
+			result = -EOPNOTSUPP;
+			goto bad_res;
+		}
+
+		tx_ant = nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
+		rx_ant = nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
+
+		result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
+		if (result)
+			goto bad_res;
+	}
+
 	changed = 0;
 
 	if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {


^ permalink raw reply related

* [PATCH v4 0/3] Antenna configuration
From: Bruno Randolf @ 2010-07-27  9:47 UTC (permalink / raw)
  To: johannes, linville; +Cc: linux-wireless, lrodriguez

Sorry for the long delay in following this up.

This is version 4 of my tries to some antenna configuration interface accepted - now using get/set thru the wiphy as Johannes has suggested.

Please see the first patch for a longer description.

bruno
---

Bruno Randolf (3):
      cfg80211: Add nl80211 antenna configuration
      mac80211: Add antenna configuration
      ath5k: Add support for antenna configuration


 drivers/net/wireless/ath/ath5k/base.c |   34 ++++++++++++++++++++++
 include/linux/nl80211.h               |   17 +++++++++++
 include/net/cfg80211.h                |    3 ++
 include/net/mac80211.h                |    2 +
 net/mac80211/cfg.c                    |   16 +++++++++++
 net/mac80211/driver-ops.h             |   23 +++++++++++++++
 net/mac80211/driver-trace.h           |   50 +++++++++++++++++++++++++++++++++
 net/wireless/nl80211.c                |   30 +++++++++++++++++++-
 8 files changed, 174 insertions(+), 1 deletions(-)

-- 
Signature

^ permalink raw reply

* Re: [ath5k-devel] [PATCH v3] ath5k: disable ASPM
From: Maxim Levitsky @ 2010-07-27  9:35 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: Luis R. Rodriguez, ath5k-devel@lists.ath5k.org,
	linux-wireless@vger.kernel.org, David Quan, Luis R. Rodriguez,
	linux-kernel, kernel-team@lists.ubuntu.com, Luis Rodriguez,
	Jussi Kivilinna, tim.gardner@canonical.com
In-Reply-To: <20100726225057.GA7268@srcf.ucam.org>

On Mon, 2010-07-26 at 23:50 +0100, Matthew Garrett wrote: 
> On Mon, Jul 26, 2010 at 03:43:04PM -0700, Luis R. Rodriguez wrote:
> 
> > I see.. thanks Mathew... in that case since L1 works on all devices we
> > could just force enable L1 for all PCIE devices. What do you think?
> 
> Works for me.
> 

On the second thought, there is no 'pci_enable_link_state' :-)
I afraid that if I add it, I might not do that right for all cases, thus
do more harm that good...

Best regards,
Maxim Levitsky


^ permalink raw reply

* Re: [PATCH] mac80211: fix sw scan bracketing
From: Luis R. Rodriguez @ 2010-07-27  9:31 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John Linville, linux-wireless
In-Reply-To: <AANLkTimB7awehpFh035hMqeazvv0ArHoKMQgrQfPSRhw@mail.gmail.com>

On Tue, Jul 27, 2010 at 2:30 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
> On Tue, Jul 27, 2010 at 2:22 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>> On Tue, Jul 27, 2010 at 1:27 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>>> On Tue, Jul 27, 2010 at 1:04 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>>>> On Fri, Jun 18, 2010 at 3:32 AM, Johannes Berg
>>>> <johannes@sipsolutions.net> wrote:
>>>>> From: Johannes Berg <johannes.berg@intel.com>
>>>>>
>>>>> Currently, detection in hwsim and ath9k can
>>>>> detect that two sw scans are in flight at the
>>>>> same time, which isn't really true. It is
>>>>> caused by a race condition, because the scan
>>>>> complete callback is called too late, after
>>>>> the lock has been dropped, so that a new scan
>>>>> can be started before it is called.
>>>>>
>>>>> It is also called too early semantically, as
>>>>> it is currently called _after_ the return to
>>>>> the operating channel -- it should be before
>>>>> so that drivers know this is the operating
>>>>> channel again.
>>>>>
>>>>> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
>>>>> ---
>>>>>  net/mac80211/scan.c |    4 ++--
>>>>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>>>>
>>>>> --- wireless-testing.orig/net/mac80211/scan.c   2010-06-18 12:22:56.000000000 +0200
>>>>> +++ wireless-testing/net/mac80211/scan.c        2010-06-18 12:23:25.000000000 +0200
>>>>> @@ -287,6 +287,8 @@ void ieee80211_scan_completed(struct iee
>>>>>        local->scanning = 0;
>>>>>        local->scan_channel = NULL;
>>>>>
>>>>> +       drv_sw_scan_complete(local);
>>>>> +
>>>>>        /* we only have to protect scan_req and hw/sw scan */
>>>>>        mutex_unlock(&local->scan_mtx);
>>>>>
>>>>> @@ -296,8 +298,6 @@ void ieee80211_scan_completed(struct iee
>>>>>
>>>>>        ieee80211_configure_filter(local);
>>>>>
>>>>> -       drv_sw_scan_complete(local);
>>>>> -
>>>>>        ieee80211_offchannel_return(local, true);
>>>>>
>>>>>  done:
>>>>
>>>> Leaving the entire patch in the e-mail reply as the patch is small to
>>>> help with context.
>>>>
>>>> Turns out this patch broke ath9k in the sense that right after a scan
>>>> we get disconnected from the AP. I just bisected wireless-testing by
>>>> master-tag dates and found 2010-06-18 to be where we hit poo in. I
>>>> reverted this patch and its cured. I'm going to test a recent
>>>> wireless-testing now and then just try reverting this to see if its OK
>>>> even on a recent wireless-testing, and then see if we can fix this
>>>> properly on ath9k or whatever.
>>>
>>> Yeap, reverting this patch alone today on wireless-testing makes me
>>> ath9k happy once again.
>>
>> So after some though and review in order to fix this we need a little
>> more time and thought. The above patch changes the order in which we
>> configure hardware upon a scan complete. It used to be we would
>> configure the hardware, configure the filter and then scan complete.
>> By then we'd be on the home channel and the filters would be set
>> correctly. ath9k's scan complete routine does a few things which
>> depend on the channel and will make hardware poo otherwise or do
>> stupid things:
>>
>>  * start TX poll routine, due to the new latency introduced to
>> configure hardware and configure the RX filter the TX polll routine
>> now has some extra work done by hardware before it actually starts
>> TXing. I don't suspect this could introduce a huge regression but it
>> is worth noting.
>>  * ANI gets started, and the wrong channel is used if we're not yet
>> on the home channel. A simple patch to test if this may be causing the
>> disconnect issue I am seeing I just tried was to increase the delay
>> before starting ANI, this did indeed help.
>
> Oh and having the right filters set up for ANI processing is important too.
>
> At first I thought trying to detect upon hw config the home channel
> would be a good place to move the ani start, but then we'd also need
> to move the beacon config and test that.. at this point there are just
> too many unknowns on possible regressions introduced by this.

I'm also a bit surprised there are no other drivers with issues due to this too.

  Luis

^ permalink raw reply

* Re: [PATCH v2 00/20] native support for wl1271 on ZOOM
From: Ohad Ben-Cohen @ 2010-07-27  9:32 UTC (permalink / raw)
  To: John W. Linville
  Cc: linux-wireless, linux-mmc, linux-omap, linux-arm-kernel, linux,
	Chikkature Rajashekar Madhusudhan, Luciano Coelho, akpm,
	San Mehat, Roger Quadros, Tony Lindgren, Nicolas Pitre,
	Pandita Vikram, Kalle Valo
In-Reply-To: <20100726193028.GG3903@tuxdriver.com>

On Mon, Jul 26, 2010 at 10:30 PM, John W. Linville
<linville@tuxdriver.com> wrote:
> On Wed, Jul 21, 2010 at 08:33:34PM +0300, Ohad Ben-Cohen wrote:
>> This patch series adds native support for wl1271 on ZOOM.
>
> Just for the record, I'm fine with the wl1271 bits here going through
> the omap tree with the rest of the series.

Thanks, John.

>
> John
> --
> John W. Linville                Someday the world will need a hero, and you
> linville@tuxdriver.com                  might be all we have.  Be ready.
>

^ permalink raw reply

* Re: [PATCH] mac80211: fix sw scan bracketing
From: Luis R. Rodriguez @ 2010-07-27  9:30 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John Linville, linux-wireless
In-Reply-To: <AANLkTik=1LX_12ZskP5vwkSrTVFO9jH6uu8pyByGmLg6@mail.gmail.com>

On Tue, Jul 27, 2010 at 2:22 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
> On Tue, Jul 27, 2010 at 1:27 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>> On Tue, Jul 27, 2010 at 1:04 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>>> On Fri, Jun 18, 2010 at 3:32 AM, Johannes Berg
>>> <johannes@sipsolutions.net> wrote:
>>>> From: Johannes Berg <johannes.berg@intel.com>
>>>>
>>>> Currently, detection in hwsim and ath9k can
>>>> detect that two sw scans are in flight at the
>>>> same time, which isn't really true. It is
>>>> caused by a race condition, because the scan
>>>> complete callback is called too late, after
>>>> the lock has been dropped, so that a new scan
>>>> can be started before it is called.
>>>>
>>>> It is also called too early semantically, as
>>>> it is currently called _after_ the return to
>>>> the operating channel -- it should be before
>>>> so that drivers know this is the operating
>>>> channel again.
>>>>
>>>> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
>>>> ---
>>>>  net/mac80211/scan.c |    4 ++--
>>>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>>>
>>>> --- wireless-testing.orig/net/mac80211/scan.c   2010-06-18 12:22:56.000000000 +0200
>>>> +++ wireless-testing/net/mac80211/scan.c        2010-06-18 12:23:25.000000000 +0200
>>>> @@ -287,6 +287,8 @@ void ieee80211_scan_completed(struct iee
>>>>        local->scanning = 0;
>>>>        local->scan_channel = NULL;
>>>>
>>>> +       drv_sw_scan_complete(local);
>>>> +
>>>>        /* we only have to protect scan_req and hw/sw scan */
>>>>        mutex_unlock(&local->scan_mtx);
>>>>
>>>> @@ -296,8 +298,6 @@ void ieee80211_scan_completed(struct iee
>>>>
>>>>        ieee80211_configure_filter(local);
>>>>
>>>> -       drv_sw_scan_complete(local);
>>>> -
>>>>        ieee80211_offchannel_return(local, true);
>>>>
>>>>  done:
>>>
>>> Leaving the entire patch in the e-mail reply as the patch is small to
>>> help with context.
>>>
>>> Turns out this patch broke ath9k in the sense that right after a scan
>>> we get disconnected from the AP. I just bisected wireless-testing by
>>> master-tag dates and found 2010-06-18 to be where we hit poo in. I
>>> reverted this patch and its cured. I'm going to test a recent
>>> wireless-testing now and then just try reverting this to see if its OK
>>> even on a recent wireless-testing, and then see if we can fix this
>>> properly on ath9k or whatever.
>>
>> Yeap, reverting this patch alone today on wireless-testing makes me
>> ath9k happy once again.
>
> So after some though and review in order to fix this we need a little
> more time and thought. The above patch changes the order in which we
> configure hardware upon a scan complete. It used to be we would
> configure the hardware, configure the filter and then scan complete.
> By then we'd be on the home channel and the filters would be set
> correctly. ath9k's scan complete routine does a few things which
> depend on the channel and will make hardware poo otherwise or do
> stupid things:
>
>  * start TX poll routine, due to the new latency introduced to
> configure hardware and configure the RX filter the TX polll routine
> now has some extra work done by hardware before it actually starts
> TXing. I don't suspect this could introduce a huge regression but it
> is worth noting.
>  * ANI gets started, and the wrong channel is used if we're not yet
> on the home channel. A simple patch to test if this may be causing the
> disconnect issue I am seeing I just tried was to increase the delay
> before starting ANI, this did indeed help.

Oh and having the right filters set up for ANI processing is important too.

At first I thought trying to detect upon hw config the home channel
would be a good place to move the ani start, but then we'd also need
to move the beacon config and test that.. at this point there are just
too many unknowns on possible regressions introduced by this.

>  * ath_beacon_config() which I suspect means that if we now scan in
> AP mode/IBSS mode we could potentially be leaking beacons on the last
> channel of a scan, prior to sending them on the actual desired home
> channel.
>
> To address and review all this I need more time and instead I think
> its easier to ask for revert of this patch. I think we should more
> carefully address these issues acanll together in one patch to avoid
> these regressions. Right now ath9k is just completely useless with
> this. It disconnects upon every scan, so for network manager users
> this is every 60 seconds.

  Luis

^ permalink raw reply

* Re: [PATCH] mac80211: fix sw scan bracketing
From: Luis R. Rodriguez @ 2010-07-27  9:22 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John Linville, linux-wireless
In-Reply-To: <AANLkTinch-sygnRmB6LKi6xLNYVKY6Ap3YL4_PMNdmKQ@mail.gmail.com>

On Tue, Jul 27, 2010 at 1:27 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
> On Tue, Jul 27, 2010 at 1:04 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>> On Fri, Jun 18, 2010 at 3:32 AM, Johannes Berg
>> <johannes@sipsolutions.net> wrote:
>>> From: Johannes Berg <johannes.berg@intel.com>
>>>
>>> Currently, detection in hwsim and ath9k can
>>> detect that two sw scans are in flight at the
>>> same time, which isn't really true. It is
>>> caused by a race condition, because the scan
>>> complete callback is called too late, after
>>> the lock has been dropped, so that a new scan
>>> can be started before it is called.
>>>
>>> It is also called too early semantically, as
>>> it is currently called _after_ the return to
>>> the operating channel -- it should be before
>>> so that drivers know this is the operating
>>> channel again.
>>>
>>> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
>>> ---
>>>  net/mac80211/scan.c |    4 ++--
>>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> --- wireless-testing.orig/net/mac80211/scan.c   2010-06-18 12:22:56.000000000 +0200
>>> +++ wireless-testing/net/mac80211/scan.c        2010-06-18 12:23:25.000000000 +0200
>>> @@ -287,6 +287,8 @@ void ieee80211_scan_completed(struct iee
>>>        local->scanning = 0;
>>>        local->scan_channel = NULL;
>>>
>>> +       drv_sw_scan_complete(local);
>>> +
>>>        /* we only have to protect scan_req and hw/sw scan */
>>>        mutex_unlock(&local->scan_mtx);
>>>
>>> @@ -296,8 +298,6 @@ void ieee80211_scan_completed(struct iee
>>>
>>>        ieee80211_configure_filter(local);
>>>
>>> -       drv_sw_scan_complete(local);
>>> -
>>>        ieee80211_offchannel_return(local, true);
>>>
>>>  done:
>>
>> Leaving the entire patch in the e-mail reply as the patch is small to
>> help with context.
>>
>> Turns out this patch broke ath9k in the sense that right after a scan
>> we get disconnected from the AP. I just bisected wireless-testing by
>> master-tag dates and found 2010-06-18 to be where we hit poo in. I
>> reverted this patch and its cured. I'm going to test a recent
>> wireless-testing now and then just try reverting this to see if its OK
>> even on a recent wireless-testing, and then see if we can fix this
>> properly on ath9k or whatever.
>
> Yeap, reverting this patch alone today on wireless-testing makes me
> ath9k happy once again.

So after some though and review in order to fix this we need a little
more time and thought. The above patch changes the order in which we
configure hardware upon a scan complete. It used to be we would
configure the hardware, configure the filter and then scan complete.
By then we'd be on the home channel and the filters would be set
correctly. ath9k's scan complete routine does a few things which
depend on the channel and will make hardware poo otherwise or do
stupid things:

  * start TX poll routine, due to the new latency introduced to
configure hardware and configure the RX filter the TX polll routine
now has some extra work done by hardware before it actually starts
TXing. I don't suspect this could introduce a huge regression but it
is worth noting.
  * ANI gets started, and the wrong channel is used if we're not yet
on the home channel. A simple patch to test if this may be causing the
disconnect issue I am seeing I just tried was to increase the delay
before starting ANI, this did indeed help.
  * ath_beacon_config() which I suspect means that if we now scan in
AP mode/IBSS mode we could potentially be leaking beacons on the last
channel of a scan, prior to sending them on the actual desired home
channel.

To address and review all this I need more time and instead I think
its easier to ask for revert of this patch. I think we should more
carefully address these issues acanll together in one patch to avoid
these regressions. Right now ath9k is just completely useless with
this. It disconnects upon every scan, so for network manager users
this is every 60 seconds.

  Luis

^ permalink raw reply

* Re: [WIP] mac80211: AMPDU rx reorder timeout timer
From: Johannes Berg @ 2010-07-27  8:37 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: linux-wireless
In-Reply-To: <201007270820.25347.chunkeey@googlemail.com>

On Tue, 2010-07-27 at 08:20 +0200, Christian Lamparter wrote:
> This (rather _unfinished_ :-D ) patch adds a timer which
> if trigger schedules the automatic release of all expired
> A-MPDU frames. This implementation has the advantage that
> all queued-up MPDU will now arrive in the network core
> within a timely manner.
> 
> In my "experiments", the patch helped to ironed out the
> sudden throughput drops that have been _killing_ my
> average tcp performance ever since I can remember.

But why is your BA session so damaged to start with? This is not a
normal situtation!

> But there is a catch: The logs will quickly fill up with:
> "release an RX reorder frame due to timeout on earlier frames".
> and the package loss will goes through the roof...
> 
> Now, I can think of several reasons why this could happen:
> 	1. we don't wait long enough for the HT peer to
> 		finish their _retry_ procedure?
> 
> 	2. previously - when the stream simply _stopped_ - we had
> 		to wait until the tcp retry kick in again. So we had
> 		some "silent" periods and therefore less noise from
> 		the reordering code?
> 
> 	3. ->bugs<- but where are they?

I'm having a hard time understanding this patch, can you split out the
no-op code reorg parts or explain what it does?

johannes


^ permalink raw reply

* Re: [PATCH] mac80211: fix sw scan bracketing
From: Luis R. Rodriguez @ 2010-07-27  8:27 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John Linville, linux-wireless
In-Reply-To: <AANLkTinHXxhwrOmhRxveekG7_C7WeydUdSBL2R7DwOvJ@mail.gmail.com>

On Tue, Jul 27, 2010 at 1:04 AM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
> On Fri, Jun 18, 2010 at 3:32 AM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
>> From: Johannes Berg <johannes.berg@intel.com>
>>
>> Currently, detection in hwsim and ath9k can
>> detect that two sw scans are in flight at the
>> same time, which isn't really true. It is
>> caused by a race condition, because the scan
>> complete callback is called too late, after
>> the lock has been dropped, so that a new scan
>> can be started before it is called.
>>
>> It is also called too early semantically, as
>> it is currently called _after_ the return to
>> the operating channel -- it should be before
>> so that drivers know this is the operating
>> channel again.
>>
>> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
>> ---
>>  net/mac80211/scan.c |    4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> --- wireless-testing.orig/net/mac80211/scan.c   2010-06-18 12:22:56.000000000 +0200
>> +++ wireless-testing/net/mac80211/scan.c        2010-06-18 12:23:25.000000000 +0200
>> @@ -287,6 +287,8 @@ void ieee80211_scan_completed(struct iee
>>        local->scanning = 0;
>>        local->scan_channel = NULL;
>>
>> +       drv_sw_scan_complete(local);
>> +
>>        /* we only have to protect scan_req and hw/sw scan */
>>        mutex_unlock(&local->scan_mtx);
>>
>> @@ -296,8 +298,6 @@ void ieee80211_scan_completed(struct iee
>>
>>        ieee80211_configure_filter(local);
>>
>> -       drv_sw_scan_complete(local);
>> -
>>        ieee80211_offchannel_return(local, true);
>>
>>  done:
>
> Leaving the entire patch in the e-mail reply as the patch is small to
> help with context.
>
> Turns out this patch broke ath9k in the sense that right after a scan
> we get disconnected from the AP. I just bisected wireless-testing by
> master-tag dates and found 2010-06-18 to be where we hit poo in. I
> reverted this patch and its cured. I'm going to test a recent
> wireless-testing now and then just try reverting this to see if its OK
> even on a recent wireless-testing, and then see if we can fix this
> properly on ath9k or whatever.

Yeap, reverting this patch alone today on wireless-testing makes me
ath9k happy once again.

 Luis

^ permalink raw reply

* Re: [PATCH] mac80211: fix sw scan bracketing
From: Luis R. Rodriguez @ 2010-07-27  8:04 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John Linville, linux-wireless
In-Reply-To: <1276857140.3638.22.camel@jlt3.sipsolutions.net>

On Fri, Jun 18, 2010 at 3:32 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> From: Johannes Berg <johannes.berg@intel.com>
>
> Currently, detection in hwsim and ath9k can
> detect that two sw scans are in flight at the
> same time, which isn't really true. It is
> caused by a race condition, because the scan
> complete callback is called too late, after
> the lock has been dropped, so that a new scan
> can be started before it is called.
>
> It is also called too early semantically, as
> it is currently called _after_ the return to
> the operating channel -- it should be before
> so that drivers know this is the operating
> channel again.
>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
>  net/mac80211/scan.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> --- wireless-testing.orig/net/mac80211/scan.c   2010-06-18 12:22:56.000000000 +0200
> +++ wireless-testing/net/mac80211/scan.c        2010-06-18 12:23:25.000000000 +0200
> @@ -287,6 +287,8 @@ void ieee80211_scan_completed(struct iee
>        local->scanning = 0;
>        local->scan_channel = NULL;
>
> +       drv_sw_scan_complete(local);
> +
>        /* we only have to protect scan_req and hw/sw scan */
>        mutex_unlock(&local->scan_mtx);
>
> @@ -296,8 +298,6 @@ void ieee80211_scan_completed(struct iee
>
>        ieee80211_configure_filter(local);
>
> -       drv_sw_scan_complete(local);
> -
>        ieee80211_offchannel_return(local, true);
>
>  done:

Leaving the entire patch in the e-mail reply as the patch is small to
help with context.

Turns out this patch broke ath9k in the sense that right after a scan
we get disconnected from the AP. I just bisected wireless-testing by
master-tag dates and found 2010-06-18 to be where we hit poo in. I
reverted this patch and its cured. I'm going to test a recent
wireless-testing now and then just try reverting this to see if its OK
even on a recent wireless-testing, and then see if we can fix this
properly on ath9k or whatever.

  Luis

^ permalink raw reply

* Re: ath9k: /proc/net/wireless always shows status of 0
From: Luis R. Rodriguez @ 2010-07-27  6:54 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Ben Greear, linux-wireless
In-Reply-To: <1280213303.19098.3.camel@jlt3.sipsolutions.net>

On Mon, Jul 26, 2010 at 11:48 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Mon, 2010-07-26 at 16:36 -0700, Ben Greear wrote:
>
>> > You can use nl28011 and register for netlink multicast messages which
>> > broadcast device state changes like the ones you mentioned. These come
>> > in on iw via event.c, see print_event() and see the case statements
>> > for NL80211_CMD_ASSOCIATE, NL80211_CMD_DEAUTHENTICATE,
>> > NL80211_CMD_DISASSOCIATE, etc, you even get reason codes parsed for
>> > you too.
>>
>> Ahhh, that is the kind of thing I'm looking for.  I'll check out that
>> code in detail tomorrow.
>
> Keep in mind though that not all drivers can give you the difference
> between AUTH and ASSOC, and will ONLY report "CONNECTED" events. This is
> those drivers that do roaming and all that in firmware rather than in
> mac80211. Therefore, generally speaking, you cannot get the states
> you're after.

FWIW I think he's on ath9k.

  Luis

^ permalink raw reply

* Re: ath9k: /proc/net/wireless always shows status of 0
From: Johannes Berg @ 2010-07-27  6:48 UTC (permalink / raw)
  To: Ben Greear; +Cc: Luis R. Rodriguez, linux-wireless
In-Reply-To: <4C4E1C0B.9040608@candelatech.com>

On Mon, 2010-07-26 at 16:36 -0700, Ben Greear wrote:

> > You can use nl28011 and register for netlink multicast messages which
> > broadcast device state changes like the ones you mentioned. These come
> > in on iw via event.c, see print_event() and see the case statements
> > for NL80211_CMD_ASSOCIATE, NL80211_CMD_DEAUTHENTICATE,
> > NL80211_CMD_DISASSOCIATE, etc, you even get reason codes parsed for
> > you too.
> 
> Ahhh, that is the kind of thing I'm looking for.  I'll check out that
> code in detail tomorrow.

Keep in mind though that not all drivers can give you the difference
between AUTH and ASSOC, and will ONLY report "CONNECTED" events. This is
those drivers that do roaming and all that in firmware rather than in
mac80211. Therefore, generally speaking, you cannot get the states
you're after.

johannes


^ permalink raw reply

* Re: [PATCH] mac80211: Fix key freeing to handle unlinked keys
From: Johannes Berg @ 2010-07-27  6:38 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: John Linville, linux-wireless
In-Reply-To: <20100726225203.GA31787@jm.kir.nu>

On Mon, 2010-07-26 at 15:52 -0700, Jouni Malinen wrote:
> Key locking simplification removed key->sdata != NULL verification from
> ieee80211_key_free(). While that is fine for most use cases, there is one
> path where this function can be called with an unlinked key (i.e.,
> key->sdata == NULL && key->local == NULL). This results in a NULL pointer
> dereference with the current implementation. This is known to happen at
> least with FT protocol when wpa_supplicant tries to configure the key
> before association.
> 
> Avoid the issue by passing in the local pointer to
> ieee80211_key_free(). In addition, do not clear the key from hw_accel
> or debugfs if it has not yet been added. At least the hw_accel one could
> trigger another NULL pointer dereference.
> 
> Signed-off-by: Jouni Malinen <j@w1.fi>

Reviewed-by: Johannes Berg <johannes@sipsolutions.net>

> ---
>  net/mac80211/cfg.c      |    6 +++---
>  net/mac80211/key.c      |   13 ++++++-------
>  net/mac80211/key.h      |    3 ++-
>  net/mac80211/sta_info.c |    2 +-
>  4 files changed, 12 insertions(+), 12 deletions(-)
> 
> (Note: The reference to key locking simplification is to the commit
> ad0e2b5a00dbec303e4682b403bb6703d11dcdb2 which is not yet in linux-2.6.)


Yes, this is because it's in wireless-next-2.6, the commit ID should
still be stable.

johannes

> --- wireless-testing.orig/net/mac80211/cfg.c	2010-07-26 14:44:01.000000000 -0700
> +++ wireless-testing/net/mac80211/cfg.c	2010-07-26 14:44:43.000000000 -0700
> @@ -158,7 +158,7 @@ static int ieee80211_add_key(struct wiph
>  	if (mac_addr) {
>  		sta = sta_info_get_bss(sdata, mac_addr);
>  		if (!sta) {
> -			ieee80211_key_free(key);
> +			ieee80211_key_free(sdata->local, key);
>  			err = -ENOENT;
>  			goto out_unlock;
>  		}
> @@ -192,7 +192,7 @@ static int ieee80211_del_key(struct wiph
>  			goto out_unlock;
>  
>  		if (sta->key) {
> -			ieee80211_key_free(sta->key);
> +			ieee80211_key_free(sdata->local, sta->key);
>  			WARN_ON(sta->key);
>  			ret = 0;
>  		}
> @@ -205,7 +205,7 @@ static int ieee80211_del_key(struct wiph
>  		goto out_unlock;
>  	}
>  
> -	ieee80211_key_free(sdata->keys[key_idx]);
> +	ieee80211_key_free(sdata->local, sdata->keys[key_idx]);
>  	WARN_ON(sdata->keys[key_idx]);
>  
>  	ret = 0;
> --- wireless-testing.orig/net/mac80211/key.c	2010-07-26 14:43:07.000000000 -0700
> +++ wireless-testing/net/mac80211/key.c	2010-07-26 14:44:43.000000000 -0700
> @@ -323,13 +323,15 @@ static void __ieee80211_key_destroy(stru
>  	if (!key)
>  		return;
>  
> -	ieee80211_key_disable_hw_accel(key);
> +	if (key->local)
> +		ieee80211_key_disable_hw_accel(key);
>  
>  	if (key->conf.alg == ALG_CCMP)
>  		ieee80211_aes_key_free(key->u.ccmp.tfm);
>  	if (key->conf.alg == ALG_AES_CMAC)
>  		ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
> -	ieee80211_debugfs_key_remove(key);
> +	if (key->local)
> +		ieee80211_debugfs_key_remove(key);
>  
>  	kfree(key);
>  }
> @@ -410,15 +412,12 @@ static void __ieee80211_key_free(struct 
>  	__ieee80211_key_destroy(key);
>  }
>  
> -void ieee80211_key_free(struct ieee80211_key *key)
> +void ieee80211_key_free(struct ieee80211_local *local,
> +			struct ieee80211_key *key)
>  {
> -	struct ieee80211_local *local;
> -
>  	if (!key)
>  		return;
>  
> -	local = key->sdata->local;
> -
>  	mutex_lock(&local->key_mtx);
>  	__ieee80211_key_free(key);
>  	mutex_unlock(&local->key_mtx);
> --- wireless-testing.orig/net/mac80211/key.h	2010-07-26 14:43:07.000000000 -0700
> +++ wireless-testing/net/mac80211/key.h	2010-07-26 14:44:43.000000000 -0700
> @@ -135,7 +135,8 @@ struct ieee80211_key *ieee80211_key_allo
>  void ieee80211_key_link(struct ieee80211_key *key,
>  			struct ieee80211_sub_if_data *sdata,
>  			struct sta_info *sta);
> -void ieee80211_key_free(struct ieee80211_key *key);
> +void ieee80211_key_free(struct ieee80211_local *local,
> +			struct ieee80211_key *key);
>  void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx);
>  void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
>  				    int idx);
> --- wireless-testing.orig/net/mac80211/sta_info.c	2010-07-26 14:43:07.000000000 -0700
> +++ wireless-testing/net/mac80211/sta_info.c	2010-07-26 14:44:43.000000000 -0700
> @@ -647,7 +647,7 @@ static int __must_check __sta_info_destr
>  		return ret;
>  
>  	if (sta->key) {
> -		ieee80211_key_free(sta->key);
> +		ieee80211_key_free(local, sta->key);
>  		WARN_ON(sta->key);
>  	}
>  



^ permalink raw reply

* Re: iwlwifi connection problems
From: Johannes Berg @ 2010-07-27  6:37 UTC (permalink / raw)
  To: Alex Romosan; +Cc: Guy, Wey-Yi, linux-wireless@vger.kernel.org
In-Reply-To: <87mxtd5xlq.fsf@sycorax.lbl.gov>

On Mon, 2010-07-26 at 21:59 -0700, Alex Romosan wrote:

> any ideas on how i can debug this? i tried to do a git-bisect but i
> didn't get anywhere. i have the driver compiled in the kernel if that
> makes any difference. as i played with the later kernels (after 2.6.34)
> i discovered that if kept bringing the interface down and then up again
> eventually i would get "cfg80211: Calling CRDA to update world
> regulatory domain" the antenna light on the laptop (i have a thinkpad
> t61) would go off and then at the next ifup the driver connected. looks
> like some kind of reset/initialization problem to me.

So is the issue maybe the channel the AP is no, not the fact that it's
hidden? or something like that?

johannes


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox