diff options
author | David S. Miller <davem@davemloft.net> | 2010-06-17 17:19:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-17 17:19:06 -0400 |
commit | bb9c03d8a6893517737b16fdbeb54be3c73b3023 (patch) | |
tree | 35fa0d1defaaf94641963a49126d7bb475ffa4c6 /drivers/net/wireless/rt2x00 | |
parent | 4de57826810fd2cfeb2ab5c7d003ff9116b8f7ee (diff) | |
parent | abf52f86aa0a49a7377350cafa8f218c4cd227e7 (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.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 56 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 33 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 45 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 3 |
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 | ||
44 | MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); | ||
45 | MODULE_DESCRIPTION("rt2800 library"); | ||
46 | MODULE_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, ®); | 557 | if (crypto->cmd == SET_KEY) { |
562 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB, | 558 | rt2800_register_read(rt2x00dev, offset, ®); |
563 | !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); | 559 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB, |
564 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER, | 560 | !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)); |
565 | (crypto->cmd == SET_KEY) * crypto->cipher); | 561 | /* |
566 | rt2x00_set_field32(®, 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(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher); | 564 | * bit to the value. |
569 | rt2800_register_write(rt2x00dev, offset, reg); | 565 | */ |
566 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER, | ||
567 | (crypto->cipher & 0x7)); | ||
568 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER_EXT, | ||
569 | (crypto->cipher & 0x8) >> 3); | ||
570 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX, | ||
571 | (crypto->bssidx & 0x7)); | ||
572 | rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT, | ||
573 | (crypto->bssidx & 0x8) >> 3); | ||
574 | rt2x00_set_field32(®, 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(®, 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, ®); | 1094 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®); |
@@ -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 | }; |
2751 | EXPORT_SYMBOL_GPL(rt2800_mac80211_ops); | 2772 | EXPORT_SYMBOL_GPL(rt2800_mac80211_ops); |
2773 | |||
2774 | MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz"); | ||
2775 | MODULE_VERSION(DRV_VERSION); | ||
2776 | MODULE_DESCRIPTION("Ralink RT2800 library"); | ||
2777 | MODULE_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 | */ |
54 | static int modparam_nohwcrypt = 1; | 54 | static int modparam_nohwcrypt = 0; |
55 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 55 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); |
56 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 56 | MODULE_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, ®); | 830 | rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); |
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 | */ |
48 | static int modparam_nohwcrypt = 1; | 48 | static int modparam_nohwcrypt = 0; |
49 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 49 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); |
50 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 50 | MODULE_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, ®); | 933 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); |
934 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1); | ||
935 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_STEP, 0); | ||
936 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0); | ||
934 | rt2x00_set_field32(®, TXRX_CSR4_LONG_RETRY_LIMIT, | 937 | rt2x00_set_field32(®, 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(®, TXRX_CSR4_SHORT_RETRY_LIMIT, | 939 | rt2x00_set_field32(®, 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, ®); | 2069 | rt2x00pci_register_read(rt2x00dev, STA_CSR4, ®); |
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, ®); | 818 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, ®); |
819 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_DOWN, 1); | ||
820 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_RATE_STEP, 0); | ||
821 | rt2x00_set_field32(®, TXRX_CSR4_OFDM_TX_FALLBACK_CCK, 0); | ||
819 | rt2x00_set_field32(®, TXRX_CSR4_LONG_RETRY_LIMIT, | 822 | rt2x00_set_field32(®, 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(®, TXRX_CSR4_SHORT_RETRY_LIMIT, | 824 | rt2x00_set_field32(®, TXRX_CSR4_SHORT_RETRY_LIMIT, |