diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00crypto.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00lib.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 40 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 193 |
4 files changed, 138 insertions, 114 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index aee9cba13eb3..e9d3ddae2785 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c | |||
@@ -49,9 +49,14 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key) | |||
49 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | 49 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, |
50 | struct txentry_desc *txdesc) | 50 | struct txentry_desc *txdesc) |
51 | { | 51 | { |
52 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
52 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 53 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
53 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | 54 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; |
54 | 55 | ||
56 | if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || | ||
57 | !hw_key || entry->skb->do_not_encrypt) | ||
58 | return; | ||
59 | |||
55 | __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); | 60 | __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); |
56 | 61 | ||
57 | txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key); | 62 | txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key); |
@@ -69,11 +74,17 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | |||
69 | __set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags); | 74 | __set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags); |
70 | } | 75 | } |
71 | 76 | ||
72 | unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) | 77 | unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, |
78 | struct sk_buff *skb) | ||
73 | { | 79 | { |
80 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
74 | struct ieee80211_key_conf *key = tx_info->control.hw_key; | 81 | struct ieee80211_key_conf *key = tx_info->control.hw_key; |
75 | unsigned int overhead = 0; | 82 | unsigned int overhead = 0; |
76 | 83 | ||
84 | if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || | ||
85 | !key || skb->do_not_encrypt) | ||
86 | return overhead; | ||
87 | |||
77 | /* | 88 | /* |
78 | * Extend frame length to include IV/EIV/ICV/MMIC, | 89 | * Extend frame length to include IV/EIV/ICV/MMIC, |
79 | * note that these lengths should only be added when | 90 | * note that these lengths should only be added when |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index fccaffde6f55..5e8df250e50d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -282,7 +282,8 @@ static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, | |||
282 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); | 282 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); |
283 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | 283 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, |
284 | struct txentry_desc *txdesc); | 284 | struct txentry_desc *txdesc); |
285 | unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info); | 285 | unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, |
286 | struct sk_buff *skb); | ||
286 | void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len); | 287 | void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len); |
287 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len); | 288 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len); |
288 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); | 289 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); |
@@ -300,7 +301,8 @@ static inline void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | |||
300 | { | 301 | { |
301 | } | 302 | } |
302 | 303 | ||
303 | static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) | 304 | static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, |
305 | struct sk_buff *skb) | ||
304 | { | 306 | { |
305 | return 0; | 307 | return 0; |
306 | } | 308 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index e6fba830d1d3..bf7755a21645 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -79,8 +79,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
79 | * RTS/CTS frame should use the length of the frame plus any | 79 | * RTS/CTS frame should use the length of the frame plus any |
80 | * encryption overhead that will be added by the hardware. | 80 | * encryption overhead that will be added by the hardware. |
81 | */ | 81 | */ |
82 | if (!frag_skb->do_not_encrypt) | 82 | data_length += rt2x00crypto_tx_overhead(rt2x00dev, skb); |
83 | data_length += rt2x00crypto_tx_overhead(tx_info); | ||
84 | 83 | ||
85 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | 84 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
86 | ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, | 85 | ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, |
@@ -484,6 +483,24 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
484 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); | 483 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); |
485 | 484 | ||
486 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 485 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
486 | static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len) | ||
487 | { | ||
488 | if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY) | ||
489 | memcpy(&crypto->key, | ||
490 | &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY], | ||
491 | sizeof(crypto->key)); | ||
492 | |||
493 | if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) | ||
494 | memcpy(&crypto->tx_mic, | ||
495 | &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], | ||
496 | sizeof(crypto->tx_mic)); | ||
497 | |||
498 | if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY) | ||
499 | memcpy(&crypto->rx_mic, | ||
500 | &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], | ||
501 | sizeof(crypto->rx_mic)); | ||
502 | } | ||
503 | |||
487 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 504 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
488 | const u8 *local_address, const u8 *address, | 505 | const u8 *local_address, const u8 *address, |
489 | struct ieee80211_key_conf *key) | 506 | struct ieee80211_key_conf *key) |
@@ -521,22 +538,9 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
521 | crypto.cmd = cmd; | 538 | crypto.cmd = cmd; |
522 | crypto.address = address; | 539 | crypto.address = address; |
523 | 540 | ||
524 | if (crypto.cipher == CIPHER_TKIP) { | 541 | if (crypto.cipher == CIPHER_TKIP) |
525 | if (key->keylen > NL80211_TKIP_DATA_OFFSET_ENCR_KEY) | 542 | memcpy_tkip(&crypto, &key->key[0], key->keylen); |
526 | memcpy(&crypto.key, | 543 | else |
527 | &key->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY], | ||
528 | sizeof(crypto.key)); | ||
529 | |||
530 | if (key->keylen > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) | ||
531 | memcpy(&crypto.tx_mic, | ||
532 | &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], | ||
533 | sizeof(crypto.tx_mic)); | ||
534 | |||
535 | if (key->keylen > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY) | ||
536 | memcpy(&crypto.rx_mic, | ||
537 | &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], | ||
538 | sizeof(crypto.rx_mic)); | ||
539 | } else | ||
540 | memcpy(&crypto.key, &key->key[0], key->keylen); | 544 | memcpy(&crypto.key, &key->key[0], key->keylen); |
541 | 545 | ||
542 | /* | 546 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 01125563aba3..f4a951338f8f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -148,20 +148,105 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
148 | dev_kfree_skb_any(skb); | 148 | dev_kfree_skb_any(skb); |
149 | } | 149 | } |
150 | 150 | ||
151 | static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | ||
152 | struct txentry_desc *txdesc) | ||
153 | { | ||
154 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | ||
155 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | ||
156 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
157 | unsigned long irqflags; | ||
158 | |||
159 | if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) || | ||
160 | unlikely(!tx_info->control.vif)) | ||
161 | return; | ||
162 | |||
163 | /* | ||
164 | * Hardware should insert sequence counter. | ||
165 | * FIXME: We insert a software sequence counter first for | ||
166 | * hardware that doesn't support hardware sequence counting. | ||
167 | * | ||
168 | * This is wrong because beacons are not getting sequence | ||
169 | * numbers assigned properly. | ||
170 | * | ||
171 | * A secondary problem exists for drivers that cannot toggle | ||
172 | * sequence counting per-frame, since those will override the | ||
173 | * sequence counter given by mac80211. | ||
174 | */ | ||
175 | spin_lock_irqsave(&intf->seqlock, irqflags); | ||
176 | |||
177 | if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) | ||
178 | intf->seqno += 0x10; | ||
179 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
180 | hdr->seq_ctrl |= cpu_to_le16(intf->seqno); | ||
181 | |||
182 | spin_unlock_irqrestore(&intf->seqlock, irqflags); | ||
183 | |||
184 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); | ||
185 | } | ||
186 | |||
187 | static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, | ||
188 | struct txentry_desc *txdesc, | ||
189 | const struct rt2x00_rate *hwrate) | ||
190 | { | ||
191 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
192 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | ||
193 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; | ||
194 | unsigned int data_length; | ||
195 | unsigned int duration; | ||
196 | unsigned int residual; | ||
197 | |||
198 | /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */ | ||
199 | data_length = entry->skb->len + 4; | ||
200 | data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb); | ||
201 | |||
202 | /* | ||
203 | * PLCP setup | ||
204 | * Length calculation depends on OFDM/CCK rate. | ||
205 | */ | ||
206 | txdesc->signal = hwrate->plcp; | ||
207 | txdesc->service = 0x04; | ||
208 | |||
209 | if (hwrate->flags & DEV_RATE_OFDM) { | ||
210 | txdesc->length_high = (data_length >> 6) & 0x3f; | ||
211 | txdesc->length_low = data_length & 0x3f; | ||
212 | } else { | ||
213 | /* | ||
214 | * Convert length to microseconds. | ||
215 | */ | ||
216 | residual = GET_DURATION_RES(data_length, hwrate->bitrate); | ||
217 | duration = GET_DURATION(data_length, hwrate->bitrate); | ||
218 | |||
219 | if (residual != 0) { | ||
220 | duration++; | ||
221 | |||
222 | /* | ||
223 | * Check if we need to set the Length Extension | ||
224 | */ | ||
225 | if (hwrate->bitrate == 110 && residual <= 30) | ||
226 | txdesc->service |= 0x80; | ||
227 | } | ||
228 | |||
229 | txdesc->length_high = (duration >> 8) & 0xff; | ||
230 | txdesc->length_low = duration & 0xff; | ||
231 | |||
232 | /* | ||
233 | * When preamble is enabled we should set the | ||
234 | * preamble bit for the signal. | ||
235 | */ | ||
236 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | ||
237 | txdesc->signal |= 0x08; | ||
238 | } | ||
239 | } | ||
240 | |||
151 | static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | 241 | static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, |
152 | struct txentry_desc *txdesc) | 242 | struct txentry_desc *txdesc) |
153 | { | 243 | { |
154 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 244 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
155 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 245 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
156 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | 246 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; |
157 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; | ||
158 | struct ieee80211_rate *rate = | 247 | struct ieee80211_rate *rate = |
159 | ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); | 248 | ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); |
160 | const struct rt2x00_rate *hwrate; | 249 | const struct rt2x00_rate *hwrate; |
161 | unsigned int data_length; | ||
162 | unsigned int duration; | ||
163 | unsigned int residual; | ||
164 | unsigned long irqflags; | ||
165 | 250 | ||
166 | memset(txdesc, 0, sizeof(*txdesc)); | 251 | memset(txdesc, 0, sizeof(*txdesc)); |
167 | 252 | ||
@@ -173,27 +258,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
173 | txdesc->cw_max = entry->queue->cw_max; | 258 | txdesc->cw_max = entry->queue->cw_max; |
174 | txdesc->aifs = entry->queue->aifs; | 259 | txdesc->aifs = entry->queue->aifs; |
175 | 260 | ||
176 | /* Data length + CRC */ | ||
177 | data_length = entry->skb->len + 4; | ||
178 | |||
179 | /* | 261 | /* |
180 | * Check whether this frame is to be acked. | 262 | * Check whether this frame is to be acked. |
181 | */ | 263 | */ |
182 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) | 264 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) |
183 | __set_bit(ENTRY_TXD_ACK, &txdesc->flags); | 265 | __set_bit(ENTRY_TXD_ACK, &txdesc->flags); |
184 | 266 | ||
185 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) && | ||
186 | !entry->skb->do_not_encrypt) { | ||
187 | /* Apply crypto specific descriptor information */ | ||
188 | rt2x00crypto_create_tx_descriptor(entry, txdesc); | ||
189 | |||
190 | /* | ||
191 | * Extend frame length to include all encryption overhead | ||
192 | * that will be added by the hardware. | ||
193 | */ | ||
194 | data_length += rt2x00crypto_tx_overhead(tx_info); | ||
195 | } | ||
196 | |||
197 | /* | 267 | /* |
198 | * Check if this is a RTS/CTS frame | 268 | * Check if this is a RTS/CTS frame |
199 | */ | 269 | */ |
@@ -237,86 +307,23 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
237 | * Set ifs to IFS_SIFS when the this is not the first fragment, | 307 | * Set ifs to IFS_SIFS when the this is not the first fragment, |
238 | * or this fragment came after RTS/CTS. | 308 | * or this fragment came after RTS/CTS. |
239 | */ | 309 | */ |
240 | if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) { | 310 | if ((tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) && |
241 | txdesc->ifs = IFS_SIFS; | 311 | !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) { |
242 | } else if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { | ||
243 | __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags); | 312 | __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags); |
244 | txdesc->ifs = IFS_BACKOFF; | 313 | txdesc->ifs = IFS_BACKOFF; |
245 | } else { | 314 | } else |
246 | txdesc->ifs = IFS_SIFS; | 315 | txdesc->ifs = IFS_SIFS; |
247 | } | ||
248 | 316 | ||
249 | /* | ||
250 | * Hardware should insert sequence counter. | ||
251 | * FIXME: We insert a software sequence counter first for | ||
252 | * hardware that doesn't support hardware sequence counting. | ||
253 | * | ||
254 | * This is wrong because beacons are not getting sequence | ||
255 | * numbers assigned properly. | ||
256 | * | ||
257 | * A secondary problem exists for drivers that cannot toggle | ||
258 | * sequence counting per-frame, since those will override the | ||
259 | * sequence counter given by mac80211. | ||
260 | */ | ||
261 | if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
262 | if (likely(tx_info->control.vif)) { | ||
263 | struct rt2x00_intf *intf; | ||
264 | |||
265 | intf = vif_to_intf(tx_info->control.vif); | ||
266 | |||
267 | spin_lock_irqsave(&intf->seqlock, irqflags); | ||
268 | |||
269 | if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) | ||
270 | intf->seqno += 0x10; | ||
271 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
272 | hdr->seq_ctrl |= cpu_to_le16(intf->seqno); | ||
273 | |||
274 | spin_unlock_irqrestore(&intf->seqlock, irqflags); | ||
275 | |||
276 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | /* | ||
281 | * PLCP setup | ||
282 | * Length calculation depends on OFDM/CCK rate. | ||
283 | */ | ||
284 | hwrate = rt2x00_get_rate(rate->hw_value); | 317 | hwrate = rt2x00_get_rate(rate->hw_value); |
285 | txdesc->signal = hwrate->plcp; | 318 | if (hwrate->flags & DEV_RATE_OFDM) |
286 | txdesc->service = 0x04; | ||
287 | |||
288 | if (hwrate->flags & DEV_RATE_OFDM) { | ||
289 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags); | 319 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags); |
290 | 320 | ||
291 | txdesc->length_high = (data_length >> 6) & 0x3f; | 321 | /* |
292 | txdesc->length_low = data_length & 0x3f; | 322 | * Apply TX descriptor handling by components |
293 | } else { | 323 | */ |
294 | /* | 324 | rt2x00crypto_create_tx_descriptor(entry, txdesc); |
295 | * Convert length to microseconds. | 325 | rt2x00queue_create_tx_descriptor_seq(entry, txdesc); |
296 | */ | 326 | rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); |
297 | residual = GET_DURATION_RES(data_length, hwrate->bitrate); | ||
298 | duration = GET_DURATION(data_length, hwrate->bitrate); | ||
299 | |||
300 | if (residual != 0) { | ||
301 | duration++; | ||
302 | |||
303 | /* | ||
304 | * Check if we need to set the Length Extension | ||
305 | */ | ||
306 | if (hwrate->bitrate == 110 && residual <= 30) | ||
307 | txdesc->service |= 0x80; | ||
308 | } | ||
309 | |||
310 | txdesc->length_high = (duration >> 8) & 0xff; | ||
311 | txdesc->length_low = duration & 0xff; | ||
312 | |||
313 | /* | ||
314 | * When preamble is enabled we should set the | ||
315 | * preamble bit for the signal. | ||
316 | */ | ||
317 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | ||
318 | txdesc->signal |= 0x08; | ||
319 | } | ||
320 | } | 327 | } |
321 | 328 | ||
322 | static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | 329 | static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, |