[PATCH] ath5k: Internalize Atheros Turbo modes

This patch:

* Internalizes Atheros Turbo modes (MODE_ATHEROS_TURBO,
MODE_ATHEROS_TURBOG)

* Internatizes Turbo modulation (MODULATION_TURBO)

* Adds documention for Atheros Turbo modes (MODE_ATHEROS_TURBO,
MODE_ATHEROS_TURBOG), Turbo modulation (MODULATION_TURBO) and XR
modulation (MODULATION_XR)

Changes-licensed-under: BSD
Signed-off-by: Luis R. Rodriguez <mcgrof@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/ath5k.h b/drivers/net/wireless/ath5k.h
index 78d7cb2..f6108a8 100644
--- a/drivers/net/wireless/ath5k.h
+++ b/drivers/net/wireless/ath5k.h
@@ -187,12 +187,72 @@
 
 #define IEEE80211_MAX_LEN       2500
 
-/* TODO Merge this to mac80211 */
-#define MODULATION_XR 		0x00000200 /*XR thingie*/
+/* TODO add support to mac80211 for vendor-specific rates and modes */
 
-#define AR5K_SET_SHORT_PREAMBLE 0x04 /* adding this flag to rate_code
-					enables short preamble, see
-					ar5212_reg.h */
+/*
+ * Some of this information is based on Documentation from:
+ *
+ * http://madwifi.org/wiki/ChipsetFeatures/SuperAG
+ *
+ * Modulation for Atheros' eXtended Range - range enhancing extension that is
+ * supposed to double the distance an Atheros client device can keep a
+ * connection with an Atheros access point. This is achieved by increasing
+ * the receiver sensitivity up to, -105dBm, which is about 20dB above what
+ * the 802.11 specifications demand. In addition, new (proprietary) data rates
+ * are introduced: 3, 2, 1, 0.5 and 0.25 MBit/s.
+ *
+ * Please note that can you either use XR or TURBO but you cannot use both,
+ * they are exclusive.
+ *
+ */
+#define MODULATION_XR 		0x00000200
+/*
+ * Modulation for Atheros' Turbo G and Turbo A, its supposed to provide a
+ * throughput transmission speed up to 40Mbit/s-60Mbit/s at a 108Mbit/s
+ * signaling rate achieved through the bonding of two 54Mbit/s 802.11g
+ * channels. To use this feature your Access Point must also suport it.
+ * There is also a distinction between "static" and "dynamic" turbo modes:
+ *
+ * - Static: is the dumb version: devices set to this mode stick to it until
+ *     the mode is turned off.
+ * - Dynamic: is the intelligent version, the network decides itself if it
+ *     is ok to use turbo. As soon as traffic is detected on adjacent channels
+ *     (which would get used in turbo mode), or when a non-turbo station joins
+ *     the network, turbo mode won't be used until the situation changes again.
+ *     Dynamic mode is achieved by Atheros' Adaptive Radio (AR) feature which
+ *     monitors the used radio band in order to decide whether turbo mode may
+ *     be used or not.
+ *
+ * This article claims Super G sticks to bonding of channels 5 and 6 for
+ * USA:
+ *
+ * http://www.pcworld.com/article/id,113428-page,1/article.html
+ *
+ * The channel bonding seems to be driver specific though. In addition to
+ * deciding what channels will be used, these "Turbo" modes are accomplished
+ * by also enabling the following features:
+ *
+ * - Bursting: allows multiple frames to be sent at once, rather than pausing
+ *     after each frame. Bursting is a standards-compliant feature that can be
+ *     used with any Access Point.
+ * - Fast frames: increases the amount of information that can be sent per
+ *     frame, also resulting in a reduction of transmission overhead. It is a
+ *     proprietary feature that needs to be supported by the Access Point.
+ * - Compression: data frames are compressed in real time using a Lempel Ziv
+ *     algorithm. This is done transparently. Once this feature is enabled,
+ *     compression and decompression takes place inside the chipset, without
+ *     putting additional load on the host CPU.
+ */
+#define MODULATION_TURBO	0x00000080
+
+enum ath5k_vendor_mode {
+	MODE_ATHEROS_TURBO = NUM_IEEE80211_MODES+1,
+	MODE_ATHEROS_TURBOG
+};
+
+/* adding this flag to rate_code enables short preamble, see ar5212_reg.h */
+#define AR5K_SET_SHORT_PREAMBLE 0x04
+
 #define HAS_SHPREAMBLE(_ix) (rt->rates[_ix].modulation == IEEE80211_RATE_CCK_2)
 #define SHPREAMBLE_FLAG(_ix) (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0)
 
@@ -636,14 +696,14 @@
 	255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0,	\
 	7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255,	\
 	255, 255, 255, 255, 255, 255, 255, 255 }, {		\
-	{ 1, IEEE80211_RATE_TURBO, 6000, 11, 140, 0 },	\
-	{ 1, IEEE80211_RATE_TURBO, 9000, 15, 18, 0 },	\
-	{ 1, IEEE80211_RATE_TURBO, 12000, 10, 152, 2 },	\
-	{ 1, IEEE80211_RATE_TURBO, 18000, 14, 36, 2 },	\
-	{ 1, IEEE80211_RATE_TURBO, 24000, 9, 176, 4 },	\
-	{ 1, IEEE80211_RATE_TURBO, 36000, 13, 72, 4 },	\
-	{ 1, IEEE80211_RATE_TURBO, 48000, 8, 96, 4 },	\
-	{ 1, IEEE80211_RATE_TURBO, 54000, 12, 108, 4 } }	\
+	{ 1, MODULATION_TURBO, 6000, 11, 140, 0 },	\
+	{ 1, MODULATION_TURBO, 9000, 15, 18, 0 },	\
+	{ 1, MODULATION_TURBO, 12000, 10, 152, 2 },	\
+	{ 1, MODULATION_TURBO, 18000, 14, 36, 2 },	\
+	{ 1, MODULATION_TURBO, 24000, 9, 176, 4 },	\
+	{ 1, MODULATION_TURBO, 36000, 13, 72, 4 },	\
+	{ 1, MODULATION_TURBO, 48000, 8, 96, 4 },	\
+	{ 1, MODULATION_TURBO, 54000, 12, 108, 4 } }	\
 }
 
 #define AR5K_RATES_XR { 12, {					\
diff --git a/drivers/net/wireless/ath5k_base.c b/drivers/net/wireless/ath5k_base.c
index 0311eb0..fead9a7 100644
--- a/drivers/net/wireless/ath5k_base.c
+++ b/drivers/net/wireless/ath5k_base.c
@@ -1844,7 +1844,7 @@
 		TG = MODE_ATHEROS_TURBOG,
 	};
 
-	BUILD_BUG_ON(ARRAY_SIZE(sc->modes) < 5);
+	BUILD_BUG_ON(ARRAY_SIZE(sc->modes) < 3);
 
 	ah->ah_country_code = countrycode;
 
diff --git a/drivers/net/wireless/ath5k_hw.c b/drivers/net/wireless/ath5k_hw.c
index 07ad127..e4cc307 100644
--- a/drivers/net/wireless/ath5k_hw.c
+++ b/drivers/net/wireless/ath5k_hw.c
@@ -142,6 +142,7 @@
 	 * Calculate the transmission time by operation (PHY) mode
 	 */
 	switch (rate->modulation) {
+	/* Standard rates */
 	case IEEE80211_RATE_CCK:
 		/*
 		 * CCK / DS mode (802.11b)
@@ -160,7 +161,8 @@
 		value = AR5K_OFDM_TX_TIME(rate->rate_kbps, frame_length);
 		break;
 
-	case IEEE80211_RATE_TURBO:
+	/* Vendor-specific rates */
+	case MODULATION_TURBO:
 		/*
 		 * Orthogonal Frequency Division Multiplexing
 		 * Atheros "Turbo Mode" (doubled rates)