aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
authorHelmut Schaa <helmut.schaa@googlemail.com>2011-03-03 13:42:35 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-03-04 14:06:47 -0500
commit26a1d07f4176099a7b6f45009dad054e6ad5b7e4 (patch)
tree432cabdfd4ffb4dcdd6121e4898598e2a5be842e /drivers/net/wireless/rt2x00
parent7fe7ee77765161217f60ec9facabd9d2b38d98fe (diff)
rt2x00: Optimize TX descriptor handling
HT and no-HT rt2x00 devices use a partly different TX descriptor. Optimize the tx desciptor memory layout by putting the PLCP and HT substructs into a union and introduce a new driver flag to decide which TX desciptor format is used by the device. This saves us the expensive PLCP calculation fOr HT devices and the HT descriptor setup on no-HT devices. Acked-by: Gertjan van Wingerde <gwingerde@gmail.com> Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00ht.c20
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c23
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h27
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c10
12 files changed, 79 insertions, 55 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index d38acf4b65e1..60d75962b805 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1131,19 +1131,21 @@ static void rt2400pci_write_tx_desc(struct queue_entry *entry,
1131 rt2x00_desc_write(txd, 2, word); 1131 rt2x00_desc_write(txd, 2, word);
1132 1132
1133 rt2x00_desc_read(txd, 3, &word); 1133 rt2x00_desc_read(txd, 3, &word);
1134 rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); 1134 rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->u.plcp.signal);
1135 rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); 1135 rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5);
1136 rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); 1136 rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1);
1137 rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); 1137 rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->u.plcp.service);
1138 rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); 1138 rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6);
1139 rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); 1139 rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1);
1140 rt2x00_desc_write(txd, 3, word); 1140 rt2x00_desc_write(txd, 3, word);
1141 1141
1142 rt2x00_desc_read(txd, 4, &word); 1142 rt2x00_desc_read(txd, 4, &word);
1143 rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, txdesc->length_low); 1143 rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW,
1144 txdesc->u.plcp.length_low);
1144 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); 1145 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8);
1145 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); 1146 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1);
1146 rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, txdesc->length_high); 1147 rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH,
1148 txdesc->u.plcp.length_high);
1147 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); 1149 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7);
1148 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); 1150 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1);
1149 rt2x00_desc_write(txd, 4, word); 1151 rt2x00_desc_write(txd, 4, word);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index b00e4d483c58..53ff64e19648 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1287,10 +1287,12 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry,
1287 rt2x00_desc_write(txd, 2, word); 1287 rt2x00_desc_write(txd, 2, word);
1288 1288
1289 rt2x00_desc_read(txd, 3, &word); 1289 rt2x00_desc_read(txd, 3, &word);
1290 rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); 1290 rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->u.plcp.signal);
1291 rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); 1291 rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->u.plcp.service);
1292 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, txdesc->length_low); 1292 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW,
1293 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, txdesc->length_high); 1293 txdesc->u.plcp.length_low);
1294 rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH,
1295 txdesc->u.plcp.length_high);
1294 rt2x00_desc_write(txd, 3, word); 1296 rt2x00_desc_write(txd, 3, word);
1295 1297
1296 rt2x00_desc_read(txd, 10, &word); 1298 rt2x00_desc_read(txd, 10, &word);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index b71df29436e7..ed5bc9c6224f 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1114,10 +1114,12 @@ static void rt2500usb_write_tx_desc(struct queue_entry *entry,
1114 rt2x00_desc_write(txd, 1, word); 1114 rt2x00_desc_write(txd, 1, word);
1115 1115
1116 rt2x00_desc_read(txd, 2, &word); 1116 rt2x00_desc_read(txd, 2, &word);
1117 rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); 1117 rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal);
1118 rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); 1118 rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service);
1119 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); 1119 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW,
1120 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); 1120 txdesc->u.plcp.length_low);
1121 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH,
1122 txdesc->u.plcp.length_high);
1121 rt2x00_desc_write(txd, 2, word); 1123 rt2x00_desc_write(txd, 2, word);
1122 1124
1123 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { 1125 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) {
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index ad90c86810d7..553d4d01a439 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -472,14 +472,15 @@ void rt2800_write_tx_data(struct queue_entry *entry,
472 test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); 472 test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
473 rt2x00_set_field32(&word, TXWI_W0_AMPDU, 473 rt2x00_set_field32(&word, TXWI_W0_AMPDU,
474 test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags)); 474 test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
475 rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density); 475 rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY,
476 rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->txop); 476 txdesc->u.ht.mpdu_density);
477 rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs); 477 rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->u.ht.txop);
478 rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->u.ht.mcs);
478 rt2x00_set_field32(&word, TXWI_W0_BW, 479 rt2x00_set_field32(&word, TXWI_W0_BW,
479 test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags)); 480 test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
480 rt2x00_set_field32(&word, TXWI_W0_SHORT_GI, 481 rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
481 test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags)); 482 test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
482 rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc); 483 rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->u.ht.stbc);
483 rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode); 484 rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
484 rt2x00_desc_write(txwi, 0, word); 485 rt2x00_desc_write(txwi, 0, word);
485 486
@@ -488,7 +489,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
488 test_bit(ENTRY_TXD_ACK, &txdesc->flags)); 489 test_bit(ENTRY_TXD_ACK, &txdesc->flags));
489 rt2x00_set_field32(&word, TXWI_W1_NSEQ, 490 rt2x00_set_field32(&word, TXWI_W1_NSEQ,
490 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); 491 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
491 rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size); 492 rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->u.ht.ba_size);
492 rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, 493 rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
493 test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? 494 test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
494 txdesc->key_idx : 0xff); 495 txdesc->key_idx : 0xff);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 046a7b7d1241..49ea189c9821 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -979,6 +979,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
979 if (!modparam_nohwcrypt) 979 if (!modparam_nohwcrypt)
980 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); 980 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
981 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); 981 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
982 __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags);
982 983
983 /* 984 /*
984 * Set the rssi offset. 985 * Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 5d91561e0de7..f1a92144996f 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -565,6 +565,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
565 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); 565 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
566 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); 566 __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
567 __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); 567 __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
568 __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags);
568 569
569 /* 570 /*
570 * Set the rssi offset. 571 * Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 9067c917c659..81a0f8bed6ae 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -663,6 +663,7 @@ enum rt2x00_flags {
663 DRIVER_REQUIRE_TXSTATUS_FIFO, 663 DRIVER_REQUIRE_TXSTATUS_FIFO,
664 DRIVER_REQUIRE_TASKLET_CONTEXT, 664 DRIVER_REQUIRE_TASKLET_CONTEXT,
665 DRIVER_REQUIRE_SW_SEQNO, 665 DRIVER_REQUIRE_SW_SEQNO,
666 DRIVER_REQUIRE_HT_TX_DESC,
666 667
667 /* 668 /*
668 * Driver features 669 * Driver features
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
index 03d9579da681..78a0e7386a78 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -38,12 +38,12 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
38 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; 38 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
39 39
40 if (tx_info->control.sta) 40 if (tx_info->control.sta)
41 txdesc->mpdu_density = 41 txdesc->u.ht.mpdu_density =
42 tx_info->control.sta->ht_cap.ampdu_density; 42 tx_info->control.sta->ht_cap.ampdu_density;
43 43
44 txdesc->ba_size = 7; /* FIXME: What value is needed? */ 44 txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */
45 45
46 txdesc->stbc = 46 txdesc->u.ht.stbc =
47 (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT; 47 (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT;
48 48
49 /* 49 /*
@@ -51,22 +51,22 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
51 * mcs rate to be used 51 * mcs rate to be used
52 */ 52 */
53 if (txrate->flags & IEEE80211_TX_RC_MCS) { 53 if (txrate->flags & IEEE80211_TX_RC_MCS) {
54 txdesc->mcs = txrate->idx; 54 txdesc->u.ht.mcs = txrate->idx;
55 55
56 /* 56 /*
57 * MIMO PS should be set to 1 for STA's using dynamic SM PS 57 * MIMO PS should be set to 1 for STA's using dynamic SM PS
58 * when using more then one tx stream (>MCS7). 58 * when using more then one tx stream (>MCS7).
59 */ 59 */
60 if (tx_info->control.sta && txdesc->mcs > 7 && 60 if (tx_info->control.sta && txdesc->u.ht.mcs > 7 &&
61 ((tx_info->control.sta->ht_cap.cap & 61 ((tx_info->control.sta->ht_cap.cap &
62 IEEE80211_HT_CAP_SM_PS) >> 62 IEEE80211_HT_CAP_SM_PS) >>
63 IEEE80211_HT_CAP_SM_PS_SHIFT) == 63 IEEE80211_HT_CAP_SM_PS_SHIFT) ==
64 WLAN_HT_CAP_SM_PS_DYNAMIC) 64 WLAN_HT_CAP_SM_PS_DYNAMIC)
65 __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); 65 __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags);
66 } else { 66 } else {
67 txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); 67 txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs);
68 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) 68 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
69 txdesc->mcs |= 0x08; 69 txdesc->u.ht.mcs |= 0x08;
70 } 70 }
71 71
72 /* 72 /*
@@ -105,11 +105,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
105 * for frames not transmitted with TXOP_HTTXOP 105 * for frames not transmitted with TXOP_HTTXOP
106 */ 106 */
107 if (ieee80211_is_mgmt(hdr->frame_control)) 107 if (ieee80211_is_mgmt(hdr->frame_control))
108 txdesc->txop = TXOP_BACKOFF; 108 txdesc->u.ht.txop = TXOP_BACKOFF;
109 else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) 109 else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT))
110 txdesc->txop = TXOP_SIFS; 110 txdesc->u.ht.txop = TXOP_SIFS;
111 else 111 else
112 txdesc->txop = TXOP_HTTXOP; 112 txdesc->u.ht.txop = TXOP_HTTXOP;
113} 113}
114 114
115u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, 115u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index eebb564ee4da..7816c1c39d6e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -270,12 +270,12 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry,
270 * PLCP setup 270 * PLCP setup
271 * Length calculation depends on OFDM/CCK rate. 271 * Length calculation depends on OFDM/CCK rate.
272 */ 272 */
273 txdesc->signal = hwrate->plcp; 273 txdesc->u.plcp.signal = hwrate->plcp;
274 txdesc->service = 0x04; 274 txdesc->u.plcp.service = 0x04;
275 275
276 if (hwrate->flags & DEV_RATE_OFDM) { 276 if (hwrate->flags & DEV_RATE_OFDM) {
277 txdesc->length_high = (data_length >> 6) & 0x3f; 277 txdesc->u.plcp.length_high = (data_length >> 6) & 0x3f;
278 txdesc->length_low = data_length & 0x3f; 278 txdesc->u.plcp.length_low = data_length & 0x3f;
279 } else { 279 } else {
280 /* 280 /*
281 * Convert length to microseconds. 281 * Convert length to microseconds.
@@ -290,18 +290,18 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry,
290 * Check if we need to set the Length Extension 290 * Check if we need to set the Length Extension
291 */ 291 */
292 if (hwrate->bitrate == 110 && residual <= 30) 292 if (hwrate->bitrate == 110 && residual <= 30)
293 txdesc->service |= 0x80; 293 txdesc->u.plcp.service |= 0x80;
294 } 294 }
295 295
296 txdesc->length_high = (duration >> 8) & 0xff; 296 txdesc->u.plcp.length_high = (duration >> 8) & 0xff;
297 txdesc->length_low = duration & 0xff; 297 txdesc->u.plcp.length_low = duration & 0xff;
298 298
299 /* 299 /*
300 * When preamble is enabled we should set the 300 * When preamble is enabled we should set the
301 * preamble bit for the signal. 301 * preamble bit for the signal.
302 */ 302 */
303 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) 303 if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
304 txdesc->signal |= 0x08; 304 txdesc->u.plcp.signal |= 0x08;
305 } 305 }
306} 306}
307 307
@@ -397,9 +397,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
397 * Apply TX descriptor handling by components 397 * Apply TX descriptor handling by components
398 */ 398 */
399 rt2x00crypto_create_tx_descriptor(entry, txdesc); 399 rt2x00crypto_create_tx_descriptor(entry, txdesc);
400 rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate);
401 rt2x00queue_create_tx_descriptor_seq(entry, txdesc); 400 rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
402 rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); 401
402 if (test_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags))
403 rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate);
404 else
405 rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
403} 406}
404 407
405static int rt2x00queue_write_tx_data(struct queue_entry *entry, 408static int rt2x00queue_write_tx_data(struct queue_entry *entry,
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index fab8e2687f29..330552046440 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -305,20 +305,27 @@ struct txentry_desc {
305 u16 length; 305 u16 length;
306 u16 header_length; 306 u16 header_length;
307 307
308 u16 length_high; 308 union {
309 u16 length_low; 309 struct {
310 u16 signal; 310 u16 length_high;
311 u16 service; 311 u16 length_low;
312 312 u16 signal;
313 u16 mcs; 313 u16 service;
314 u16 stbc; 314 } plcp;
315 u16 ba_size; 315
316 struct {
317 u16 mcs;
318 u16 stbc;
319 u16 ba_size;
320 u16 mpdu_density;
321 short txop;
322 } ht;
323 } u;
324
316 u16 rate_mode; 325 u16 rate_mode;
317 u16 mpdu_density;
318 326
319 short retry_limit; 327 short retry_limit;
320 short ifs; 328 short ifs;
321 short txop;
322 329
323 enum cipher cipher; 330 enum cipher cipher;
324 u16 key_idx; 331 u16 key_idx;
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 2ed845b1ea3c..c01b811a50d5 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1898,10 +1898,12 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry,
1898 rt2x00_desc_write(txd, 1, word); 1898 rt2x00_desc_write(txd, 1, word);
1899 1899
1900 rt2x00_desc_read(txd, 2, &word); 1900 rt2x00_desc_read(txd, 2, &word);
1901 rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); 1901 rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal);
1902 rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); 1902 rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service);
1903 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); 1903 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW,
1904 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); 1904 txdesc->u.plcp.length_low);
1905 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH,
1906 txdesc->u.plcp.length_high);
1905 rt2x00_desc_write(txd, 2, word); 1907 rt2x00_desc_write(txd, 2, word);
1906 1908
1907 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { 1909 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) {
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index a799c262c1db..a4c9a3e20ec4 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1499,10 +1499,12 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry,
1499 rt2x00_desc_write(txd, 1, word); 1499 rt2x00_desc_write(txd, 1, word);
1500 1500
1501 rt2x00_desc_read(txd, 2, &word); 1501 rt2x00_desc_read(txd, 2, &word);
1502 rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); 1502 rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal);
1503 rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); 1503 rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service);
1504 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); 1504 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW,
1505 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); 1505 txdesc->u.plcp.length_low);
1506 rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH,
1507 txdesc->u.plcp.length_high);
1506 rt2x00_desc_write(txd, 2, word); 1508 rt2x00_desc_write(txd, 2, word);
1507 1509
1508 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { 1510 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) {