aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-06-17 17:19:06 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-17 17:19:06 -0400
commitbb9c03d8a6893517737b16fdbeb54be3c73b3023 (patch)
tree35fa0d1defaaf94641963a49126d7bb475ffa4c6 /drivers/net/wireless/rt2x00
parent4de57826810fd2cfeb2ab5c7d003ff9116b8f7ee (diff)
parentabf52f86aa0a49a7377350cafa8f218c4cd227e7 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h8
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c56
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c33
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c16
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h9
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c45
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c3
9 files changed, 127 insertions, 54 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 317b7807175e..552f9f4c73d6 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -1436,6 +1436,10 @@ struct mac_iveiv_entry {
1436#define MAC_WCID_ATTRIBUTE_CIPHER FIELD32(0x0000000e) 1436#define MAC_WCID_ATTRIBUTE_CIPHER FIELD32(0x0000000e)
1437#define MAC_WCID_ATTRIBUTE_BSS_IDX FIELD32(0x00000070) 1437#define MAC_WCID_ATTRIBUTE_BSS_IDX FIELD32(0x00000070)
1438#define MAC_WCID_ATTRIBUTE_RX_WIUDF FIELD32(0x00000380) 1438#define MAC_WCID_ATTRIBUTE_RX_WIUDF FIELD32(0x00000380)
1439#define MAC_WCID_ATTRIBUTE_CIPHER_EXT FIELD32(0x00000400)
1440#define MAC_WCID_ATTRIBUTE_BSS_IDX_EXT FIELD32(0x00000800)
1441#define MAC_WCID_ATTRIBUTE_WAPI_MCBC FIELD32(0x00008000)
1442#define MAC_WCID_ATTRIBUTE_WAPI_KEY_IDX FIELD32(0xff000000)
1439 1443
1440/* 1444/*
1441 * SHARED_KEY_MODE: 1445 * SHARED_KEY_MODE:
@@ -1557,7 +1561,9 @@ struct mac_iveiv_entry {
1557 */ 1561 */
1558 1562
1559/* 1563/*
1560 * BBP 1: TX Antenna 1564 * BBP 1: TX Antenna & Power
1565 * POWER: 0 - normal, 1 - drop tx power by 6dBm, 2 - drop tx power by 12dBm,
1566 * 3 - increase tx power by 6dBm
1561 */ 1567 */
1562#define BBP1_TX_POWER FIELD8(0x07) 1568#define BBP1_TX_POWER FIELD8(0x07)
1563#define BBP1_TX_ANTENNA FIELD8(0x18) 1569#define BBP1_TX_ANTENNA FIELD8(0x18)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index ae20e6728b1e..14c361ae87be 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1,9 +1,9 @@
1/* 1/*
2 Copyright (C) 2010 Ivo van Doorn <IvDoorn@gmail.com>
2 Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> 3 Copyright (C) 2009 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
3 Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com> 4 Copyright (C) 2009 Gertjan van Wingerde <gwingerde@gmail.com>
4 5
5 Based on the original rt2800pci.c and rt2800usb.c. 6 Based on the original rt2800pci.c and rt2800usb.c.
6 Copyright (C) 2009 Ivo van Doorn <IvDoorn@gmail.com>
7 Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> 7 Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
8 Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> 8 Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
9 Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> 9 Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
@@ -41,10 +41,6 @@
41#include "rt2800lib.h" 41#include "rt2800lib.h"
42#include "rt2800.h" 42#include "rt2800.h"
43 43
44MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
45MODULE_DESCRIPTION("rt2800 library");
46MODULE_LICENSE("GPL");
47
48/* 44/*
49 * Register access. 45 * Register access.
50 * All access to the CSR registers will go through the methods 46 * All access to the CSR registers will go through the methods
@@ -558,15 +554,28 @@ static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
558 554
559 offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx); 555 offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
560 556
561 rt2800_register_read(rt2x00dev, offset, &reg); 557 if (crypto->cmd == SET_KEY) {
562 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB, 558 rt2800_register_read(rt2x00dev, offset, &reg);
563 !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); 559 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
564 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER, 560 !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
565 (crypto->cmd == SET_KEY) * crypto->cipher); 561 /*
566 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX, 562 * Both the cipher as the BSS Idx numbers are split in a main
567 (crypto->cmd == SET_KEY) * crypto->bssidx); 563 * value of 3 bits, and a extended field for adding one additional
568 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher); 564 * bit to the value.
569 rt2800_register_write(rt2x00dev, offset, reg); 565 */
566 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
567 (crypto->cipher & 0x7));
568 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER_EXT,
569 (crypto->cipher & 0x8) >> 3);
570 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
571 (crypto->bssidx & 0x7));
572 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT,
573 (crypto->bssidx & 0x8) >> 3);
574 rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
575 rt2800_register_write(rt2x00dev, offset, reg);
576 } else {
577 rt2800_register_write(rt2x00dev, offset, 0);
578 }
570 579
571 offset = MAC_IVEIV_ENTRY(key->hw_key_idx); 580 offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
572 581
@@ -1079,7 +1088,7 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
1079 u8 r1; 1088 u8 r1;
1080 1089
1081 rt2800_bbp_read(rt2x00dev, 1, &r1); 1090 rt2800_bbp_read(rt2x00dev, 1, &r1);
1082 rt2x00_set_field8(&reg, BBP1_TX_POWER, 0); 1091 rt2x00_set_field8(&r1, BBP1_TX_POWER, 0);
1083 rt2800_bbp_write(rt2x00dev, 1, r1); 1092 rt2800_bbp_write(rt2x00dev, 1, r1);
1084 1093
1085 rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, &reg); 1094 rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, &reg);
@@ -2497,6 +2506,18 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2497 rt2x00_eeprom_addr(rt2x00dev, 2506 rt2x00_eeprom_addr(rt2x00dev,
2498 EEPROM_MAC_ADDR_0)); 2507 EEPROM_MAC_ADDR_0));
2499 2508
2509 /*
2510 * As rt2800 has a global fallback table we cannot specify
2511 * more then one tx rate per frame but since the hw will
2512 * try several rates (based on the fallback table) we should
2513 * still initialize max_rates to the maximum number of rates
2514 * we are going to try. Otherwise mac80211 will truncate our
2515 * reported tx rates and the rc algortihm will end up with
2516 * incorrect data.
2517 */
2518 rt2x00dev->hw->max_rates = 7;
2519 rt2x00dev->hw->max_rate_tries = 1;
2520
2500 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); 2521 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
2501 2522
2502 /* 2523 /*
@@ -2749,3 +2770,8 @@ const struct ieee80211_ops rt2800_mac80211_ops = {
2749 .rfkill_poll = rt2x00mac_rfkill_poll, 2770 .rfkill_poll = rt2x00mac_rfkill_poll,
2750}; 2771};
2751EXPORT_SYMBOL_GPL(rt2800_mac80211_ops); 2772EXPORT_SYMBOL_GPL(rt2800_mac80211_ops);
2773
2774MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz");
2775MODULE_VERSION(DRV_VERSION);
2776MODULE_DESCRIPTION("Ralink RT2800 library");
2777MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index b5a871eb8881..e5ea670a18db 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -51,7 +51,7 @@
51/* 51/*
52 * Allow hardware encryption to be disabled. 52 * Allow hardware encryption to be disabled.
53 */ 53 */
54static int modparam_nohwcrypt = 1; 54static int modparam_nohwcrypt = 0;
55module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 55module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
56MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 56MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
57 57
@@ -813,29 +813,24 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
813 struct txdone_entry_desc txdesc; 813 struct txdone_entry_desc txdesc;
814 u32 word; 814 u32 word;
815 u32 reg; 815 u32 reg;
816 u32 old_reg;
817 int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; 816 int wcid, ack, pid, tx_wcid, tx_ack, tx_pid;
818 u16 mcs, real_mcs; 817 u16 mcs, real_mcs;
818 int i;
819 819
820 /* 820 /*
821 * During each loop we will compare the freshly read 821 * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO
822 * TX_STA_FIFO register value with the value read from 822 * at most X times and also stop processing once the TX_STA_FIFO_VALID
823 * the previous loop. If the 2 values are equal then 823 * flag is not set anymore.
824 * we should stop processing because the chance it 824 *
825 * quite big that the device has been unplugged and 825 * The legacy drivers use X=TX_RING_SIZE but state in a comment
826 * we risk going into an endless loop. 826 * that the TX_STA_FIFO stack has a size of 16. We stick to our
827 * tx ring size for now.
827 */ 828 */
828 old_reg = 0; 829 for (i = 0; i < TX_ENTRIES; i++) {
829
830 while (1) {
831 rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg); 830 rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
832 if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) 831 if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
833 break; 832 break;
834 833
835 if (old_reg == reg)
836 break;
837 old_reg = reg;
838
839 wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); 834 wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
840 ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); 835 ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
841 pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); 836 pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE);
@@ -903,8 +898,12 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
903 txdesc.retry = 7; 898 txdesc.retry = 7;
904 } 899 }
905 900
906 __set_bit(TXDONE_FALLBACK, &txdesc.flags); 901 /*
907 902 * the frame was retried at least once
903 * -> hw used fallback rates
904 */
905 if (txdesc.retry)
906 __set_bit(TXDONE_FALLBACK, &txdesc.flags);
908 907
909 rt2x00pci_txdone(entry, &txdesc); 908 rt2x00pci_txdone(entry, &txdesc);
910 } 909 }
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index c437960de3ed..f18c12a19cc9 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -45,7 +45,7 @@
45/* 45/*
46 * Allow hardware encryption to be disabled. 46 * Allow hardware encryption to be disabled.
47 */ 47 */
48static int modparam_nohwcrypt = 1; 48static int modparam_nohwcrypt = 0;
49module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 49module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
50MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 50MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
51 51
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 0b8efe8e6785..339cc84bf4fb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -236,8 +236,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
236 */ 236 */
237 success = 237 success =
238 test_bit(TXDONE_SUCCESS, &txdesc->flags) || 238 test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
239 test_bit(TXDONE_UNKNOWN, &txdesc->flags) || 239 test_bit(TXDONE_UNKNOWN, &txdesc->flags);
240 test_bit(TXDONE_FALLBACK, &txdesc->flags);
241 240
242 /* 241 /*
243 * Update TX statistics. 242 * Update TX statistics.
@@ -259,11 +258,22 @@ void rt2x00lib_txdone(struct queue_entry *entry,
259 /* 258 /*
260 * Frame was send with retries, hardware tried 259 * Frame was send with retries, hardware tried
261 * different rates to send out the frame, at each 260 * different rates to send out the frame, at each
262 * retry it lowered the rate 1 step. 261 * retry it lowered the rate 1 step except when the
262 * lowest rate was used.
263 */ 263 */
264 for (i = 0; i < retry_rates && i < IEEE80211_TX_MAX_RATES; i++) { 264 for (i = 0; i < retry_rates && i < IEEE80211_TX_MAX_RATES; i++) {
265 tx_info->status.rates[i].idx = rate_idx - i; 265 tx_info->status.rates[i].idx = rate_idx - i;
266 tx_info->status.rates[i].flags = rate_flags; 266 tx_info->status.rates[i].flags = rate_flags;
267
268 if (rate_idx - i == 0) {
269 /*
270 * The lowest rate (index 0) was used until the
271 * number of max retries was reached.
272 */
273 tx_info->status.rates[i].count = retry_rates - i;
274 i++;
275 break;
276 }
267 tx_info->status.rates[i].count = 1; 277 tx_info->status.rates[i].count = 1;
268 } 278 }
269 if (i < (IEEE80211_TX_MAX_RATES - 1)) 279 if (i < (IEEE80211_TX_MAX_RATES - 1))
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 35858b178e8f..f91637147116 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -353,13 +353,18 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
353 /* 353 /*
354 * Check if more fragments are pending 354 * Check if more fragments are pending
355 */ 355 */
356 if (ieee80211_has_morefrags(hdr->frame_control) || 356 if (ieee80211_has_morefrags(hdr->frame_control)) {
357 (tx_info->flags & IEEE80211_TX_CTL_MORE_FRAMES)) {
358 __set_bit(ENTRY_TXD_BURST, &txdesc->flags); 357 __set_bit(ENTRY_TXD_BURST, &txdesc->flags);
359 __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags); 358 __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags);
360 } 359 }
361 360
362 /* 361 /*
362 * Check if more frames (!= fragments) are pending
363 */
364 if (tx_info->flags & IEEE80211_TX_CTL_MORE_FRAMES)
365 __set_bit(ENTRY_TXD_BURST, &txdesc->flags);
366
367 /*
363 * Beacons and probe responses require the tsf timestamp 368 * Beacons and probe responses require the tsf timestamp
364 * to be inserted into the frame, except for a frame that has been injected 369 * to be inserted into the frame, except for a frame that has been injected
365 * through a monitor interface. This latter is needed for testing a 370 * through a monitor interface. This latter is needed for testing a
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index f79170849add..bd54f55a8cb9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -213,9 +213,16 @@ struct rxdone_entry_desc {
213/** 213/**
214 * enum txdone_entry_desc_flags: Flags for &struct txdone_entry_desc 214 * enum txdone_entry_desc_flags: Flags for &struct txdone_entry_desc
215 * 215 *
216 * Every txdone report has to contain the basic result of the
217 * transmission, either &TXDONE_UNKNOWN, &TXDONE_SUCCESS or
218 * &TXDONE_FAILURE. The flag &TXDONE_FALLBACK can be used in
219 * conjunction with all of these flags but should only be set
220 * if retires > 0. The flag &TXDONE_EXCESSIVE_RETRY can only be used
221 * in conjunction with &TXDONE_FAILURE.
222 *
216 * @TXDONE_UNKNOWN: Hardware could not determine success of transmission. 223 * @TXDONE_UNKNOWN: Hardware could not determine success of transmission.
217 * @TXDONE_SUCCESS: Frame was successfully send 224 * @TXDONE_SUCCESS: Frame was successfully send
218 * @TXDONE_FALLBACK: Frame was successfully send using a fallback rate. 225 * @TXDONE_FALLBACK: Hardware used fallback rates for retries
219 * @TXDONE_FAILURE: Frame was not successfully send 226 * @TXDONE_FAILURE: Frame was not successfully send
220 * @TXDONE_EXCESSIVE_RETRY: In addition to &TXDONE_FAILURE, the 227 * @TXDONE_EXCESSIVE_RETRY: In addition to &TXDONE_FAILURE, the
221 * frame transmission failed due to excessive retries. 228 * frame transmission failed due to excessive retries.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 243df08ae910..7ca383478eeb 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -931,6 +931,9 @@ static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
931 u32 reg; 931 u32 reg;
932 932
933 rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg); 933 rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
934 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1);
935 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_RATE_STEP, 0);
936 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0);
934 rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT, 937 rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT,
935 libconf->conf->long_frame_max_tx_count); 938 libconf->conf->long_frame_max_tx_count);
936 rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT, 939 rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT,
@@ -2049,29 +2052,24 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
2049 struct txdone_entry_desc txdesc; 2052 struct txdone_entry_desc txdesc;
2050 u32 word; 2053 u32 word;
2051 u32 reg; 2054 u32 reg;
2052 u32 old_reg;
2053 int type; 2055 int type;
2054 int index; 2056 int index;
2057 int i;
2055 2058
2056 /* 2059 /*
2057 * During each loop we will compare the freshly read 2060 * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO
2058 * STA_CSR4 register value with the value read from 2061 * at most X times and also stop processing once the TX_STA_FIFO_VALID
2059 * the previous loop. If the 2 values are equal then 2062 * flag is not set anymore.
2060 * we should stop processing because the chance is 2063 *
2061 * quite big that the device has been unplugged and 2064 * The legacy drivers use X=TX_RING_SIZE but state in a comment
2062 * we risk going into an endless loop. 2065 * that the TX_STA_FIFO stack has a size of 16. We stick to our
2066 * tx ring size for now.
2063 */ 2067 */
2064 old_reg = 0; 2068 for (i = 0; i < TX_ENTRIES; i++) {
2065
2066 while (1) {
2067 rt2x00pci_register_read(rt2x00dev, STA_CSR4, &reg); 2069 rt2x00pci_register_read(rt2x00dev, STA_CSR4, &reg);
2068 if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) 2070 if (!rt2x00_get_field32(reg, STA_CSR4_VALID))
2069 break; 2071 break;
2070 2072
2071 if (old_reg == reg)
2072 break;
2073 old_reg = reg;
2074
2075 /* 2073 /*
2076 * Skip this entry when it contains an invalid 2074 * Skip this entry when it contains an invalid
2077 * queue identication number. 2075 * queue identication number.
@@ -2130,6 +2128,13 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
2130 } 2128 }
2131 txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); 2129 txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT);
2132 2130
2131 /*
2132 * the frame was retried at least once
2133 * -> hw used fallback rates
2134 */
2135 if (txdesc.retry)
2136 __set_bit(TXDONE_FALLBACK, &txdesc.flags);
2137
2133 rt2x00pci_txdone(entry, &txdesc); 2138 rt2x00pci_txdone(entry, &txdesc);
2134 } 2139 }
2135} 2140}
@@ -2587,6 +2592,18 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2587 EEPROM_MAC_ADDR_0)); 2592 EEPROM_MAC_ADDR_0));
2588 2593
2589 /* 2594 /*
2595 * As rt61 has a global fallback table we cannot specify
2596 * more then one tx rate per frame but since the hw will
2597 * try several rates (based on the fallback table) we should
2598 * still initialize max_rates to the maximum number of rates
2599 * we are going to try. Otherwise mac80211 will truncate our
2600 * reported tx rates and the rc algortihm will end up with
2601 * incorrect data.
2602 */
2603 rt2x00dev->hw->max_rates = 7;
2604 rt2x00dev->hw->max_rate_tries = 1;
2605
2606 /*
2590 * Initialize hw_mode information. 2607 * Initialize hw_mode information.
2591 */ 2608 */
2592 spec->supported_bands = SUPPORT_BAND_2GHZ; 2609 spec->supported_bands = SUPPORT_BAND_2GHZ;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 113ad690f9d3..d06d90f003e7 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -816,6 +816,9 @@ static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
816 u32 reg; 816 u32 reg;
817 817
818 rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg); 818 rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
819 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1);
820 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_RATE_STEP, 0);
821 rt2x00_set_field32(&reg, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0);
819 rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT, 822 rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT,
820 libconf->conf->long_frame_max_tx_count); 823 libconf->conf->long_frame_max_tx_count);
821 rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT, 824 rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT,