summaryrefslogtreecommitdiffstats
path: root/package/mac80211/patches/310-rt2x00_implement_support_for_802.11n.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/mac80211/patches/310-rt2x00_implement_support_for_802.11n.patch')
-rw-r--r--package/mac80211/patches/310-rt2x00_implement_support_for_802.11n.patch396
1 files changed, 396 insertions, 0 deletions
diff --git a/package/mac80211/patches/310-rt2x00_implement_support_for_802.11n.patch b/package/mac80211/patches/310-rt2x00_implement_support_for_802.11n.patch
new file mode 100644
index 000000000..f82144824
--- /dev/null
+++ b/package/mac80211/patches/310-rt2x00_implement_support_for_802.11n.patch
@@ -0,0 +1,396 @@
+From: Ivo van Doorn <IvDoorn@gmail.com>
+Date: Sun, 28 Dec 2008 12:48:46 +0000 (+0100)
+Subject: rt2x00: Implement support for 802.11n
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fivd%2Frt2x00.git;a=commitdiff_plain;h=1ddf4bdad5f51a799ee580e125dda19dd18daa39
+
+rt2x00: Implement support for 802.11n
+
+Extend rt2x00lib capabilities to support 802.11n,
+it still lacks aggregation support, but that can
+be added in the future.
+
+Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+---
+
+--- a/drivers/net/wireless/rt2x00/Makefile
++++ b/drivers/net/wireless/rt2x00/Makefile
+@@ -8,6 +8,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) +=
+ rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o
+ rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
+ rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o
++rt2x00lib-$(CONFIG_RT2X00_LIB_HT) += rt2x00ht.o
+
+ obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o
+ obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
+--- a/drivers/net/wireless/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/rt2x00/rt2x00.h
+@@ -107,6 +107,7 @@
+ */
+ #define ACK_SIZE 14
+ #define IEEE80211_HEADER 24
++#define AGGREGATION_SIZE 3840
+ #define PLCP 48
+ #define BEACON 100
+ #define PREAMBLE 144
+@@ -356,6 +357,7 @@ static inline struct rt2x00_intf* vif_to
+ * for @tx_power_a, @tx_power_bg and @channels.
+ * @channels: Device/chipset specific channel values (See &struct rf_channel).
+ * @channels_info: Additional information for channels (See &struct channel_info).
++ * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
+ */
+ struct hw_mode_spec {
+ unsigned int supported_bands;
+@@ -369,6 +371,8 @@ struct hw_mode_spec {
+ unsigned int num_channels;
+ const struct rf_channel *channels;
+ const struct channel_info *channels_info;
++
++ struct ieee80211_sta_ht_cap ht;
+ };
+
+ /*
+@@ -603,6 +607,7 @@ enum rt2x00_flags {
+ CONFIG_EXTERNAL_LNA_BG,
+ CONFIG_DOUBLE_ANTENNA,
+ CONFIG_DISABLE_LINK_TUNING,
++ CONFIG_CHANNEL_HT40,
+ };
+
+ /*
+--- a/drivers/net/wireless/rt2x00/rt2x00config.c
++++ b/drivers/net/wireless/rt2x00/rt2x00config.c
+@@ -173,6 +173,12 @@ void rt2x00lib_config(struct rt2x00_dev
+ libconf.conf = conf;
+
+ if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
++ if ((conf->ht.channel_type == NL80211_CHAN_HT40MINUS) ||
++ (conf->ht.channel_type == NL80211_CHAN_HT40PLUS))
++ __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
++ else
++ __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
++
+ memcpy(&libconf.rf,
+ &rt2x00dev->spec.channels[conf->channel->hw_value],
+ sizeof(libconf.rf));
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -384,7 +384,9 @@ void rt2x00lib_rxdone(struct rt2x00_dev
+ if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
+ (rate->plcp == rxdesc.signal)) ||
+ ((rxdesc.dev_flags & RXDONE_SIGNAL_BITRATE) &&
+- (rate->bitrate == rxdesc.signal))) {
++ (rate->bitrate == rxdesc.signal)) ||
++ ((rxdesc.dev_flags & RXDONE_SIGNAL_MCS) &&
++ (rate->mcs == rxdesc.signal))) {
+ idx = i;
+ break;
+ }
+@@ -439,72 +441,84 @@ const struct rt2x00_rate rt2x00_supporte
+ .bitrate = 10,
+ .ratemask = BIT(0),
+ .plcp = 0x00,
++ .mcs = RATE_MCS(RATE_MODE_CCK, 0),
+ },
+ {
+ .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
+ .bitrate = 20,
+ .ratemask = BIT(1),
+ .plcp = 0x01,
++ .mcs = RATE_MCS(RATE_MODE_CCK, 1),
+ },
+ {
+ .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
+ .bitrate = 55,
+ .ratemask = BIT(2),
+ .plcp = 0x02,
++ .mcs = RATE_MCS(RATE_MODE_CCK, 2),
+ },
+ {
+ .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
+ .bitrate = 110,
+ .ratemask = BIT(3),
+ .plcp = 0x03,
++ .mcs = RATE_MCS(RATE_MODE_CCK, 3),
+ },
+ {
+ .flags = DEV_RATE_OFDM,
+ .bitrate = 60,
+ .ratemask = BIT(4),
+ .plcp = 0x0b,
++ .mcs = RATE_MCS(RATE_MODE_OFDM, 0),
+ },
+ {
+ .flags = DEV_RATE_OFDM,
+ .bitrate = 90,
+ .ratemask = BIT(5),
+ .plcp = 0x0f,
++ .mcs = RATE_MCS(RATE_MODE_OFDM, 1),
+ },
+ {
+ .flags = DEV_RATE_OFDM,
+ .bitrate = 120,
+ .ratemask = BIT(6),
+ .plcp = 0x0a,
++ .mcs = RATE_MCS(RATE_MODE_OFDM, 2),
+ },
+ {
+ .flags = DEV_RATE_OFDM,
+ .bitrate = 180,
+ .ratemask = BIT(7),
+ .plcp = 0x0e,
++ .mcs = RATE_MCS(RATE_MODE_OFDM, 3),
+ },
+ {
+ .flags = DEV_RATE_OFDM,
+ .bitrate = 240,
+ .ratemask = BIT(8),
+ .plcp = 0x09,
++ .mcs = RATE_MCS(RATE_MODE_OFDM, 4),
+ },
+ {
+ .flags = DEV_RATE_OFDM,
+ .bitrate = 360,
+ .ratemask = BIT(9),
+ .plcp = 0x0d,
++ .mcs = RATE_MCS(RATE_MODE_OFDM, 5),
+ },
+ {
+ .flags = DEV_RATE_OFDM,
+ .bitrate = 480,
+ .ratemask = BIT(10),
+ .plcp = 0x08,
++ .mcs = RATE_MCS(RATE_MODE_OFDM, 6),
+ },
+ {
+ .flags = DEV_RATE_OFDM,
+ .bitrate = 540,
+ .ratemask = BIT(11),
+ .plcp = 0x0c,
++ .mcs = RATE_MCS(RATE_MODE_OFDM, 7),
+ },
+ };
+
+@@ -582,6 +596,8 @@ static int rt2x00lib_probe_hw_modes(stru
+ rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates;
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &rt2x00dev->bands[IEEE80211_BAND_2GHZ];
++ memcpy(&rt2x00dev->bands[IEEE80211_BAND_2GHZ].ht_cap,
++ &spec->ht, sizeof(spec->ht));
+ }
+
+ /*
+@@ -598,6 +614,8 @@ static int rt2x00lib_probe_hw_modes(stru
+ rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4];
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &rt2x00dev->bands[IEEE80211_BAND_5GHZ];
++ memcpy(&rt2x00dev->bands[IEEE80211_BAND_5GHZ].ht_cap,
++ &spec->ht, sizeof(spec->ht));
+ }
+
+ return 0;
+--- /dev/null
++++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
+@@ -0,0 +1,69 @@
++/*
++ Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
++ <http://rt2x00.serialmonkey.com>
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the
++ Free Software Foundation, Inc.,
++ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++/*
++ Module: rt2x00lib
++ Abstract: rt2x00 HT specific routines.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++
++#include "rt2x00.h"
++#include "rt2x00lib.h"
++
++void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
++ struct txentry_desc *txdesc,
++ struct ieee80211_rate *rate)
++{
++ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
++ const struct rt2x00_rate *hwrate = rt2x00_get_rate(rate->hw_value);
++
++ if (tx_info->control.sta)
++ txdesc->mpdu_density =
++ tx_info->control.sta->ht_cap.ampdu_density;
++ else
++ txdesc->mpdu_density = 0;
++
++ txdesc->ba_size = 0; /* FIXME: What value is needed? */
++ txdesc->stbc = 0; /* FIXME: What value is needed? */
++
++ txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
++ if (rt2x00_get_rate_preamble(rate->hw_value))
++ txdesc->mcs |= 0x08;
++
++ /*
++ * Convert flags
++ */
++ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
++ __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
++
++ /*
++ * Determine HT Mix/Greenfield rate mode
++ */
++ if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_MCS)
++ txdesc->rate_mode = RATE_MODE_HT_MIX;
++ if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)
++ txdesc->rate_mode = RATE_MODE_HT_GREENFIELD;
++ if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
++ __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
++ if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
++ __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
++}
+--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
++++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
+@@ -48,6 +48,7 @@ struct rt2x00_rate {
+ unsigned short ratemask;
+
+ unsigned short plcp;
++ unsigned short mcs;
+ };
+
+ extern const struct rt2x00_rate rt2x00_supported_rates[12];
+@@ -68,6 +69,14 @@ static inline int rt2x00_get_rate_preamb
+ return (hw_value & 0xff00);
+ }
+
++#define RATE_MCS(__mode, __mcs) \
++ ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) )
++
++static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
++{
++ return (mcs_value & 0x00ff);
++}
++
+ /*
+ * Radio control handlers.
+ */
+@@ -341,6 +350,21 @@ static inline void rt2x00crypto_rx_inser
+ #endif /* CONFIG_RT2X00_LIB_CRYPTO */
+
+ /*
++ * HT handlers.
++ */
++#ifdef CONFIG_RT2X00_LIB_HT
++void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
++ struct txentry_desc *txdesc,
++ struct ieee80211_rate *rate);
++#else
++static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
++ struct txentry_desc *txdesc,
++ struct ieee80211_rate *rate)
++{
++}
++#endif /* CONFIG_RT2X00_LIB_HT */
++
++/*
+ * RFkill handlers.
+ */
+ #ifdef CONFIG_RT2X00_LIB_RFKILL
+--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
++++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
+@@ -325,6 +325,7 @@ static void rt2x00queue_create_tx_descri
+ * Apply TX descriptor handling by components
+ */
+ rt2x00crypto_create_tx_descriptor(entry, txdesc);
++ rt2x00ht_create_tx_descriptor(entry, txdesc, rate);
+ rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
+ rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, rate);
+ }
+--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
++++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
+@@ -145,6 +145,7 @@ static inline struct skb_frame_desc* get
+ *
+ * @RXDONE_SIGNAL_PLCP: Signal field contains the plcp value.
+ * @RXDONE_SIGNAL_BITRATE: Signal field contains the bitrate value.
++ * @RXDONE_SIGNAL_MCS: Signal field contains the mcs value.
+ * @RXDONE_MY_BSS: Does this frame originate from device's BSS.
+ * @RXDONE_CRYPTO_IV: Driver provided IV/EIV data.
+ * @RXDONE_CRYPTO_ICV: Driver provided ICV data.
+@@ -152,9 +153,10 @@ static inline struct skb_frame_desc* get
+ enum rxdone_entry_desc_flags {
+ RXDONE_SIGNAL_PLCP = 1 << 0,
+ RXDONE_SIGNAL_BITRATE = 1 << 1,
+- RXDONE_MY_BSS = 1 << 2,
+- RXDONE_CRYPTO_IV = 1 << 3,
+- RXDONE_CRYPTO_ICV = 1 << 4,
++ RXDONE_SIGNAL_MCS = 1 << 2,
++ RXDONE_MY_BSS = 1 << 3,
++ RXDONE_CRYPTO_IV = 1 << 4,
++ RXDONE_CRYPTO_ICV = 1 << 5,
+ };
+
+ /**
+@@ -163,7 +165,7 @@ enum rxdone_entry_desc_flags {
+ * from &rxdone_entry_desc to a signal value type.
+ */
+ #define RXDONE_SIGNAL_MASK \
+- ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE )
++ ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE | RXDONE_SIGNAL_MCS )
+
+ /**
+ * struct rxdone_entry_desc: RX Entry descriptor
+@@ -243,6 +245,9 @@ struct txdone_entry_desc {
+ * @ENTRY_TXD_ENCRYPT_PAIRWISE: Use pairwise key table (instead of shared).
+ * @ENTRY_TXD_ENCRYPT_IV: Generate IV/EIV in hardware.
+ * @ENTRY_TXD_ENCRYPT_MMIC: Generate MIC in hardware.
++ * @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU.
++ * @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth.
++ * @ENTRY_TXD_HT_SHORT_GI: Use short GI.
+ */
+ enum txentry_desc_flags {
+ ENTRY_TXD_RTS_FRAME,
+@@ -258,6 +263,9 @@ enum txentry_desc_flags {
+ ENTRY_TXD_ENCRYPT_PAIRWISE,
+ ENTRY_TXD_ENCRYPT_IV,
+ ENTRY_TXD_ENCRYPT_MMIC,
++ ENTRY_TXD_HT_AMPDU,
++ ENTRY_TXD_HT_BW_40,
++ ENTRY_TXD_HT_SHORT_GI,
+ };
+
+ /**
+@@ -271,7 +279,11 @@ enum txentry_desc_flags {
+ * @length_low: PLCP length low word.
+ * @signal: PLCP signal.
+ * @service: PLCP service.
++ * @msc: MCS.
++ * @stbc: STBC.
++ * @ba_size: BA size.
+ * @rate_mode: Rate mode (See @enum rate_modulation).
++ * @mpdu_density: MDPU density.
+ * @retry_limit: Max number of retries.
+ * @aifs: AIFS value.
+ * @ifs: IFS value.
+@@ -291,7 +303,11 @@ struct txentry_desc {
+ u16 signal;
+ u16 service;
+
++ u16 mcs;
++ u16 stbc;
++ u16 ba_size;
+ u16 rate_mode;
++ u16 mpdu_density;
+
+ short retry_limit;
+ short aifs;