aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2009-04-26 10:09:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-06 15:14:50 -0400
commit35f00cfcc06bb85e0659f9847400518008d78145 (patch)
treedccebd4dd7cde975d857d1fb3f28dd1e467fa72f /drivers/net
parent9f1661718c7fcf82e25c6aed20b729ee372d9d65 (diff)
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> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig3
-rw-r--r--drivers/net/wireless/rt2x00/Makefile1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c92
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c69
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h24
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h39
9 files changed, 211 insertions, 34 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index bfc5d9cf716e..4338c93d5b63 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -88,6 +88,9 @@ config RT2X00_LIB_USB
88config RT2X00_LIB 88config RT2X00_LIB
89 tristate 89 tristate
90 90
91config RT2X00_LIB_HT
92 boolean
93
91config RT2X00_LIB_FIRMWARE 94config RT2X00_LIB_FIRMWARE
92 boolean 95 boolean
93 select FW_LOADER 96 select FW_LOADER
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index f22d808d8c51..776ec2b8c4e7 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -8,6 +8,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
8rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o 8rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o
9rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o 9rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
10rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o 10rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o
11rt2x00lib-$(CONFIG_RT2X00_LIB_HT) += rt2x00ht.o
11 12
12obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o 13obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o
13obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o 14obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 7c5cbb192a6c..ebe5f276679b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -366,6 +366,7 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
366 * for @tx_power_a, @tx_power_bg and @channels. 366 * for @tx_power_a, @tx_power_bg and @channels.
367 * @channels: Device/chipset specific channel values (See &struct rf_channel). 367 * @channels: Device/chipset specific channel values (See &struct rf_channel).
368 * @channels_info: Additional information for channels (See &struct channel_info). 368 * @channels_info: Additional information for channels (See &struct channel_info).
369 * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
369 */ 370 */
370struct hw_mode_spec { 371struct hw_mode_spec {
371 unsigned int supported_bands; 372 unsigned int supported_bands;
@@ -379,6 +380,8 @@ struct hw_mode_spec {
379 unsigned int num_channels; 380 unsigned int num_channels;
380 const struct rf_channel *channels; 381 const struct rf_channel *channels;
381 const struct channel_info *channels_info; 382 const struct channel_info *channels_info;
383
384 struct ieee80211_sta_ht_cap ht;
382}; 385};
383 386
384/* 387/*
@@ -616,6 +619,7 @@ enum rt2x00_flags {
616 CONFIG_EXTERNAL_LNA_BG, 619 CONFIG_EXTERNAL_LNA_BG,
617 CONFIG_DOUBLE_ANTENNA, 620 CONFIG_DOUBLE_ANTENNA,
618 CONFIG_DISABLE_LINK_TUNING, 621 CONFIG_DISABLE_LINK_TUNING,
622 CONFIG_CHANNEL_HT40,
619}; 623};
620 624
621/* 625/*
@@ -788,6 +792,13 @@ struct rt2x00_dev {
788 u8 freq_offset; 792 u8 freq_offset;
789 793
790 /* 794 /*
795 * Calibration information (for rt2800usb & rt2800pci).
796 * [0] -> BW20
797 * [1] -> BW40
798 */
799 u8 calibration[2];
800
801 /*
791 * Low level statistics which will have 802 * Low level statistics which will have
792 * to be kept up to date while device is running. 803 * to be kept up to date while device is running.
793 */ 804 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 9c2f5517af2a..863e399d4fa6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -173,6 +173,11 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
173 libconf.conf = conf; 173 libconf.conf = conf;
174 174
175 if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { 175 if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
176 if (conf_is_ht40(conf))
177 __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
178 else
179 __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
180
176 memcpy(&libconf.rf, 181 memcpy(&libconf.rf,
177 &rt2x00dev->spec.channels[conf->channel->hw_value], 182 &rt2x00dev->spec.channels[conf->channel->hw_value],
178 sizeof(libconf.rf)); 183 sizeof(libconf.rf));
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index e15086af7278..f2270845072a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -323,19 +323,54 @@ void rt2x00lib_txdone(struct queue_entry *entry,
323} 323}
324EXPORT_SYMBOL_GPL(rt2x00lib_txdone); 324EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
325 325
326static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
327 struct rxdone_entry_desc *rxdesc)
328{
329 struct ieee80211_supported_band *sband;
330 const struct rt2x00_rate *rate;
331 unsigned int i;
332 int signal;
333 int type;
334
335 /*
336 * For non-HT rates the MCS value needs to contain the
337 * actually used rate modulation (CCK or OFDM).
338 */
339 if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
340 signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal);
341 else
342 signal = rxdesc->signal;
343
344 type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
345
346 sband = &rt2x00dev->bands[rt2x00dev->curr_band];
347 for (i = 0; i < sband->n_bitrates; i++) {
348 rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
349
350 if (((type == RXDONE_SIGNAL_PLCP) &&
351 (rate->plcp == signal)) ||
352 ((type == RXDONE_SIGNAL_BITRATE) &&
353 (rate->bitrate == signal)) ||
354 ((type == RXDONE_SIGNAL_MCS) &&
355 (rate->mcs == signal))) {
356 return i;
357 }
358 }
359
360 WARNING(rt2x00dev, "Frame received with unrecognized signal, "
361 "signal=0x%.4x, type=%d.\n", signal, type);
362 return 0;
363}
364
326void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, 365void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
327 struct queue_entry *entry) 366 struct queue_entry *entry)
328{ 367{
329 struct rxdone_entry_desc rxdesc; 368 struct rxdone_entry_desc rxdesc;
330 struct sk_buff *skb; 369 struct sk_buff *skb;
331 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; 370 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
332 struct ieee80211_supported_band *sband;
333 const struct rt2x00_rate *rate;
334 unsigned int header_length; 371 unsigned int header_length;
335 bool l2pad; 372 bool l2pad;
336 unsigned int i; 373 int rate_idx;
337 int idx = -1;
338
339 /* 374 /*
340 * Allocate a new sk_buffer. If no new buffer available, drop the 375 * Allocate a new sk_buffer. If no new buffer available, drop the
341 * received frame and reuse the existing buffer. 376 * received frame and reuse the existing buffer.
@@ -379,26 +414,17 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
379 rt2x00queue_payload_align(entry->skb, l2pad, header_length); 414 rt2x00queue_payload_align(entry->skb, l2pad, header_length);
380 415
381 /* 416 /*
382 * Update RX statistics. 417 * Check if the frame was received using HT. In that case,
418 * the rate is the MCS index and should be passed to mac80211
419 * directly. Otherwise we need to translate the signal to
420 * the correct bitrate index.
383 */ 421 */
384 sband = &rt2x00dev->bands[rt2x00dev->curr_band]; 422 if (rxdesc.rate_mode == RATE_MODE_CCK ||
385 for (i = 0; i < sband->n_bitrates; i++) { 423 rxdesc.rate_mode == RATE_MODE_OFDM) {
386 rate = rt2x00_get_rate(sband->bitrates[i].hw_value); 424 rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
387 425 } else {
388 if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) && 426 rxdesc.flags |= RX_FLAG_HT;
389 (rate->plcp == rxdesc.signal)) || 427 rate_idx = rxdesc.signal;
390 ((rxdesc.dev_flags & RXDONE_SIGNAL_BITRATE) &&
391 (rate->bitrate == rxdesc.signal))) {
392 idx = i;
393 break;
394 }
395 }
396
397 if (idx < 0) {
398 WARNING(rt2x00dev, "Frame received with unrecognized signal,"
399 "signal=0x%.2x, type=%d.\n", rxdesc.signal,
400 (rxdesc.dev_flags & RXDONE_SIGNAL_MASK));
401 idx = 0;
402 } 428 }
403 429
404 /* 430 /*
@@ -408,7 +434,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
408 rt2x00debug_update_crypto(rt2x00dev, &rxdesc); 434 rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
409 435
410 rx_status->mactime = rxdesc.timestamp; 436 rx_status->mactime = rxdesc.timestamp;
411 rx_status->rate_idx = idx; 437 rx_status->rate_idx = rate_idx;
412 rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi); 438 rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
413 rx_status->signal = rxdesc.rssi; 439 rx_status->signal = rxdesc.rssi;
414 rx_status->noise = rxdesc.noise; 440 rx_status->noise = rxdesc.noise;
@@ -443,72 +469,84 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
443 .bitrate = 10, 469 .bitrate = 10,
444 .ratemask = BIT(0), 470 .ratemask = BIT(0),
445 .plcp = 0x00, 471 .plcp = 0x00,
472 .mcs = RATE_MCS(RATE_MODE_CCK, 0),
446 }, 473 },
447 { 474 {
448 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, 475 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
449 .bitrate = 20, 476 .bitrate = 20,
450 .ratemask = BIT(1), 477 .ratemask = BIT(1),
451 .plcp = 0x01, 478 .plcp = 0x01,
479 .mcs = RATE_MCS(RATE_MODE_CCK, 1),
452 }, 480 },
453 { 481 {
454 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, 482 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
455 .bitrate = 55, 483 .bitrate = 55,
456 .ratemask = BIT(2), 484 .ratemask = BIT(2),
457 .plcp = 0x02, 485 .plcp = 0x02,
486 .mcs = RATE_MCS(RATE_MODE_CCK, 2),
458 }, 487 },
459 { 488 {
460 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, 489 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
461 .bitrate = 110, 490 .bitrate = 110,
462 .ratemask = BIT(3), 491 .ratemask = BIT(3),
463 .plcp = 0x03, 492 .plcp = 0x03,
493 .mcs = RATE_MCS(RATE_MODE_CCK, 3),
464 }, 494 },
465 { 495 {
466 .flags = DEV_RATE_OFDM, 496 .flags = DEV_RATE_OFDM,
467 .bitrate = 60, 497 .bitrate = 60,
468 .ratemask = BIT(4), 498 .ratemask = BIT(4),
469 .plcp = 0x0b, 499 .plcp = 0x0b,
500 .mcs = RATE_MCS(RATE_MODE_OFDM, 0),
470 }, 501 },
471 { 502 {
472 .flags = DEV_RATE_OFDM, 503 .flags = DEV_RATE_OFDM,
473 .bitrate = 90, 504 .bitrate = 90,
474 .ratemask = BIT(5), 505 .ratemask = BIT(5),
475 .plcp = 0x0f, 506 .plcp = 0x0f,
507 .mcs = RATE_MCS(RATE_MODE_OFDM, 1),
476 }, 508 },
477 { 509 {
478 .flags = DEV_RATE_OFDM, 510 .flags = DEV_RATE_OFDM,
479 .bitrate = 120, 511 .bitrate = 120,
480 .ratemask = BIT(6), 512 .ratemask = BIT(6),
481 .plcp = 0x0a, 513 .plcp = 0x0a,
514 .mcs = RATE_MCS(RATE_MODE_OFDM, 2),
482 }, 515 },
483 { 516 {
484 .flags = DEV_RATE_OFDM, 517 .flags = DEV_RATE_OFDM,
485 .bitrate = 180, 518 .bitrate = 180,
486 .ratemask = BIT(7), 519 .ratemask = BIT(7),
487 .plcp = 0x0e, 520 .plcp = 0x0e,
521 .mcs = RATE_MCS(RATE_MODE_OFDM, 3),
488 }, 522 },
489 { 523 {
490 .flags = DEV_RATE_OFDM, 524 .flags = DEV_RATE_OFDM,
491 .bitrate = 240, 525 .bitrate = 240,
492 .ratemask = BIT(8), 526 .ratemask = BIT(8),
493 .plcp = 0x09, 527 .plcp = 0x09,
528 .mcs = RATE_MCS(RATE_MODE_OFDM, 4),
494 }, 529 },
495 { 530 {
496 .flags = DEV_RATE_OFDM, 531 .flags = DEV_RATE_OFDM,
497 .bitrate = 360, 532 .bitrate = 360,
498 .ratemask = BIT(9), 533 .ratemask = BIT(9),
499 .plcp = 0x0d, 534 .plcp = 0x0d,
535 .mcs = RATE_MCS(RATE_MODE_OFDM, 5),
500 }, 536 },
501 { 537 {
502 .flags = DEV_RATE_OFDM, 538 .flags = DEV_RATE_OFDM,
503 .bitrate = 480, 539 .bitrate = 480,
504 .ratemask = BIT(10), 540 .ratemask = BIT(10),
505 .plcp = 0x08, 541 .plcp = 0x08,
542 .mcs = RATE_MCS(RATE_MODE_OFDM, 6),
506 }, 543 },
507 { 544 {
508 .flags = DEV_RATE_OFDM, 545 .flags = DEV_RATE_OFDM,
509 .bitrate = 540, 546 .bitrate = 540,
510 .ratemask = BIT(11), 547 .ratemask = BIT(11),
511 .plcp = 0x0c, 548 .plcp = 0x0c,
549 .mcs = RATE_MCS(RATE_MODE_OFDM, 7),
512 }, 550 },
513}; 551};
514 552
@@ -584,6 +622,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
584 rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates; 622 rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates;
585 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 623 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
586 &rt2x00dev->bands[IEEE80211_BAND_2GHZ]; 624 &rt2x00dev->bands[IEEE80211_BAND_2GHZ];
625 memcpy(&rt2x00dev->bands[IEEE80211_BAND_2GHZ].ht_cap,
626 &spec->ht, sizeof(spec->ht));
587 } 627 }
588 628
589 /* 629 /*
@@ -600,6 +640,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
600 rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4]; 640 rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4];
601 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 641 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
602 &rt2x00dev->bands[IEEE80211_BAND_5GHZ]; 642 &rt2x00dev->bands[IEEE80211_BAND_5GHZ];
643 memcpy(&rt2x00dev->bands[IEEE80211_BAND_5GHZ].ht_cap,
644 &spec->ht, sizeof(spec->ht));
603 } 645 }
604 646
605 return 0; 647 return 0;
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
new file mode 100644
index 000000000000..e3cec839e540
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -0,0 +1,69 @@
1/*
2 Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
3 <http://rt2x00.serialmonkey.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*
22 Module: rt2x00lib
23 Abstract: rt2x00 HT specific routines.
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28
29#include "rt2x00.h"
30#include "rt2x00lib.h"
31
32void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
33 struct txentry_desc *txdesc,
34 const struct rt2x00_rate *hwrate)
35{
36 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
37 struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
38
39 if (tx_info->control.sta)
40 txdesc->mpdu_density =
41 tx_info->control.sta->ht_cap.ampdu_density;
42 else
43 txdesc->mpdu_density = 0;
44
45 txdesc->ba_size = 7; /* FIXME: What value is needed? */
46 txdesc->stbc = 0; /* FIXME: What value is needed? */
47
48 txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
49 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
50 txdesc->mcs |= 0x08;
51
52 /*
53 * Convert flags
54 */
55 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
56 __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
57
58 /*
59 * Determine HT Mix/Greenfield rate mode
60 */
61 if (txrate->flags & IEEE80211_TX_RC_MCS)
62 txdesc->rate_mode = RATE_MODE_HT_MIX;
63 if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
64 txdesc->rate_mode = RATE_MODE_HT_GREENFIELD;
65 if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
66 __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
67 if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
68 __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
69}
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index aa284e48d2c2..ccc7ba4f3181 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -48,6 +48,7 @@ struct rt2x00_rate {
48 unsigned short ratemask; 48 unsigned short ratemask;
49 49
50 unsigned short plcp; 50 unsigned short plcp;
51 unsigned short mcs;
51}; 52};
52 53
53extern const struct rt2x00_rate rt2x00_supported_rates[12]; 54extern const struct rt2x00_rate rt2x00_supported_rates[12];
@@ -57,6 +58,14 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value)
57 return &rt2x00_supported_rates[hw_value & 0xff]; 58 return &rt2x00_supported_rates[hw_value & 0xff];
58} 59}
59 60
61#define RATE_MCS(__mode, __mcs) \
62 ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) )
63
64static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
65{
66 return (mcs_value & 0x00ff);
67}
68
60/* 69/*
61 * Radio control handlers. 70 * Radio control handlers.
62 */ 71 */
@@ -360,6 +369,21 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
360#endif /* CONFIG_RT2X00_LIB_CRYPTO */ 369#endif /* CONFIG_RT2X00_LIB_CRYPTO */
361 370
362/* 371/*
372 * HT handlers.
373 */
374#ifdef CONFIG_RT2X00_LIB_HT
375void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
376 struct txentry_desc *txdesc,
377 const struct rt2x00_rate *hwrate);
378#else
379static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
380 struct txentry_desc *txdesc,
381 const struct rt2x00_rate *hwrate)
382{
383}
384#endif /* CONFIG_RT2X00_LIB_HT */
385
386/*
363 * RFkill handlers. 387 * RFkill handlers.
364 */ 388 */
365#ifdef CONFIG_RT2X00_LIB_RFKILL 389#ifdef CONFIG_RT2X00_LIB_RFKILL
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index bc1742c1d51c..44e5b3279ca7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -361,6 +361,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
361 * Apply TX descriptor handling by components 361 * Apply TX descriptor handling by components
362 */ 362 */
363 rt2x00crypto_create_tx_descriptor(entry, txdesc); 363 rt2x00crypto_create_tx_descriptor(entry, txdesc);
364 rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate);
364 rt2x00queue_create_tx_descriptor_seq(entry, txdesc); 365 rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
365 rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); 366 rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
366} 367}
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 13e0ece176a1..b5e06347c8a7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -35,9 +35,12 @@
35 * for USB devices this restriction does not apply, but the value of 35 * for USB devices this restriction does not apply, but the value of
36 * 2432 makes sense since it is big enough to contain the maximum fragment 36 * 2432 makes sense since it is big enough to contain the maximum fragment
37 * size according to the ieee802.11 specs. 37 * size according to the ieee802.11 specs.
38 * The aggregation size depends on support from the driver, but should
39 * be something around 3840 bytes.
38 */ 40 */
39#define DATA_FRAME_SIZE 2432 41#define DATA_FRAME_SIZE 2432
40#define MGMT_FRAME_SIZE 256 42#define MGMT_FRAME_SIZE 256
43#define AGGREGATION_SIZE 3840
41 44
42/** 45/**
43 * DOC: Number of entries per queue 46 * DOC: Number of entries per queue
@@ -148,18 +151,20 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
148 * 151 *
149 * @RXDONE_SIGNAL_PLCP: Signal field contains the plcp value. 152 * @RXDONE_SIGNAL_PLCP: Signal field contains the plcp value.
150 * @RXDONE_SIGNAL_BITRATE: Signal field contains the bitrate value. 153 * @RXDONE_SIGNAL_BITRATE: Signal field contains the bitrate value.
154 * @RXDONE_SIGNAL_MCS: Signal field contains the mcs value.
151 * @RXDONE_MY_BSS: Does this frame originate from device's BSS. 155 * @RXDONE_MY_BSS: Does this frame originate from device's BSS.
152 * @RXDONE_CRYPTO_IV: Driver provided IV/EIV data. 156 * @RXDONE_CRYPTO_IV: Driver provided IV/EIV data.
153 * @RXDONE_CRYPTO_ICV: Driver provided ICV data. 157 * @RXDONE_CRYPTO_ICV: Driver provided ICV data.
154 * @RXDONE_L2PAD: 802.11 payload has been padded to 4-byte boundary. 158 * @RXDONE_L2PAD: 802.11 payload has been padded to 4-byte boundary.
155 */ 159 */
156enum rxdone_entry_desc_flags { 160enum rxdone_entry_desc_flags {
157 RXDONE_SIGNAL_PLCP = 1 << 0, 161 RXDONE_SIGNAL_PLCP = BIT(0),
158 RXDONE_SIGNAL_BITRATE = 1 << 1, 162 RXDONE_SIGNAL_BITRATE = BIT(1),
159 RXDONE_MY_BSS = 1 << 2, 163 RXDONE_SIGNAL_MCS = BIT(2),
160 RXDONE_CRYPTO_IV = 1 << 3, 164 RXDONE_MY_BSS = BIT(3),
161 RXDONE_CRYPTO_ICV = 1 << 4, 165 RXDONE_CRYPTO_IV = BIT(4),
162 RXDONE_L2PAD = 1 << 5, 166 RXDONE_CRYPTO_ICV = BIT(5),
167 RXDONE_L2PAD = BIT(6),
163}; 168};
164 169
165/** 170/**
@@ -168,7 +173,7 @@ enum rxdone_entry_desc_flags {
168 * from &rxdone_entry_desc to a signal value type. 173 * from &rxdone_entry_desc to a signal value type.
169 */ 174 */
170#define RXDONE_SIGNAL_MASK \ 175#define RXDONE_SIGNAL_MASK \
171 ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE ) 176 ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE | RXDONE_SIGNAL_MCS )
172 177
173/** 178/**
174 * struct rxdone_entry_desc: RX Entry descriptor 179 * struct rxdone_entry_desc: RX Entry descriptor
@@ -182,6 +187,7 @@ enum rxdone_entry_desc_flags {
182 * @size: Data size of the received frame. 187 * @size: Data size of the received frame.
183 * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). 188 * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags).
184 * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). 189 * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags).
190 * @rate_mode: Rate mode (See @enum rate_modulation).
185 * @cipher: Cipher type used during decryption. 191 * @cipher: Cipher type used during decryption.
186 * @cipher_status: Decryption status. 192 * @cipher_status: Decryption status.
187 * @iv: IV/EIV data used during decryption. 193 * @iv: IV/EIV data used during decryption.
@@ -195,6 +201,7 @@ struct rxdone_entry_desc {
195 int size; 201 int size;
196 int flags; 202 int flags;
197 int dev_flags; 203 int dev_flags;
204 u16 rate_mode;
198 u8 cipher; 205 u8 cipher;
199 u8 cipher_status; 206 u8 cipher_status;
200 207
@@ -248,6 +255,9 @@ struct txdone_entry_desc {
248 * @ENTRY_TXD_ENCRYPT_PAIRWISE: Use pairwise key table (instead of shared). 255 * @ENTRY_TXD_ENCRYPT_PAIRWISE: Use pairwise key table (instead of shared).
249 * @ENTRY_TXD_ENCRYPT_IV: Generate IV/EIV in hardware. 256 * @ENTRY_TXD_ENCRYPT_IV: Generate IV/EIV in hardware.
250 * @ENTRY_TXD_ENCRYPT_MMIC: Generate MIC in hardware. 257 * @ENTRY_TXD_ENCRYPT_MMIC: Generate MIC in hardware.
258 * @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU.
259 * @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth.
260 * @ENTRY_TXD_HT_SHORT_GI: Use short GI.
251 */ 261 */
252enum txentry_desc_flags { 262enum txentry_desc_flags {
253 ENTRY_TXD_RTS_FRAME, 263 ENTRY_TXD_RTS_FRAME,
@@ -263,6 +273,9 @@ enum txentry_desc_flags {
263 ENTRY_TXD_ENCRYPT_PAIRWISE, 273 ENTRY_TXD_ENCRYPT_PAIRWISE,
264 ENTRY_TXD_ENCRYPT_IV, 274 ENTRY_TXD_ENCRYPT_IV,
265 ENTRY_TXD_ENCRYPT_MMIC, 275 ENTRY_TXD_ENCRYPT_MMIC,
276 ENTRY_TXD_HT_AMPDU,
277 ENTRY_TXD_HT_BW_40,
278 ENTRY_TXD_HT_SHORT_GI,
266}; 279};
267 280
268/** 281/**
@@ -278,7 +291,11 @@ enum txentry_desc_flags {
278 * @length_low: PLCP length low word. 291 * @length_low: PLCP length low word.
279 * @signal: PLCP signal. 292 * @signal: PLCP signal.
280 * @service: PLCP service. 293 * @service: PLCP service.
294 * @msc: MCS.
295 * @stbc: STBC.
296 * @ba_size: BA size.
281 * @rate_mode: Rate mode (See @enum rate_modulation). 297 * @rate_mode: Rate mode (See @enum rate_modulation).
298 * @mpdu_density: MDPU density.
282 * @retry_limit: Max number of retries. 299 * @retry_limit: Max number of retries.
283 * @aifs: AIFS value. 300 * @aifs: AIFS value.
284 * @ifs: IFS value. 301 * @ifs: IFS value.
@@ -302,7 +319,11 @@ struct txentry_desc {
302 u16 signal; 319 u16 signal;
303 u16 service; 320 u16 service;
304 321
322 u16 mcs;
323 u16 stbc;
324 u16 ba_size;
305 u16 rate_mode; 325 u16 rate_mode;
326 u16 mpdu_density;
306 327
307 short retry_limit; 328 short retry_limit;
308 short aifs; 329 short aifs;