aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00queue.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index a5664bd8493e..44e5b3279ca7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -148,6 +148,35 @@ 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
151void rt2x00queue_payload_align(struct sk_buff *skb,
152 bool l2pad, unsigned int header_length)
153{
154 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
155 unsigned int frame_length = skb->len;
156 unsigned int align = ALIGN_SIZE(skb, header_length);
157
158 if (!align)
159 return;
160
161 if (l2pad) {
162 if (skbdesc->flags & SKBDESC_L2_PADDED) {
163 /* Remove L2 padding */
164 memmove(skb->data + align, skb->data, header_length);
165 skb_pull(skb, align);
166 skbdesc->flags &= ~SKBDESC_L2_PADDED;
167 } else {
168 /* Add L2 padding */
169 skb_push(skb, align);
170 memmove(skb->data, skb->data + align, header_length);
171 skbdesc->flags |= SKBDESC_L2_PADDED;
172 }
173 } else {
174 /* Generic payload alignment to 4-byte boundary */
175 skb_push(skb, align);
176 memmove(skb->data, skb->data + align, frame_length);
177 }
178}
179
151static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, 180static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
152 struct txentry_desc *txdesc) 181 struct txentry_desc *txdesc)
153{ 182{
@@ -259,6 +288,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
259 txdesc->aifs = entry->queue->aifs; 288 txdesc->aifs = entry->queue->aifs;
260 289
261 /* 290 /*
291 * Header and alignment information.
292 */
293 txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
294 txdesc->l2pad = ALIGN_SIZE(entry->skb, txdesc->header_length);
295
296 /*
262 * Check whether this frame is to be acked. 297 * Check whether this frame is to be acked.
263 */ 298 */
264 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) 299 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
@@ -326,6 +361,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
326 * Apply TX descriptor handling by components 361 * Apply TX descriptor handling by components
327 */ 362 */
328 rt2x00crypto_create_tx_descriptor(entry, txdesc); 363 rt2x00crypto_create_tx_descriptor(entry, txdesc);
364 rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate);
329 rt2x00queue_create_tx_descriptor_seq(entry, txdesc); 365 rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
330 rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); 366 rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
331} 367}
@@ -368,7 +404,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
368 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); 404 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
369 struct txentry_desc txdesc; 405 struct txentry_desc txdesc;
370 struct skb_frame_desc *skbdesc; 406 struct skb_frame_desc *skbdesc;
371 unsigned int iv_len = 0;
372 u8 rate_idx, rate_flags; 407 u8 rate_idx, rate_flags;
373 408
374 if (unlikely(rt2x00queue_full(queue))) 409 if (unlikely(rt2x00queue_full(queue)))
@@ -390,9 +425,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
390 entry->skb = skb; 425 entry->skb = skb;
391 rt2x00queue_create_tx_descriptor(entry, &txdesc); 426 rt2x00queue_create_tx_descriptor(entry, &txdesc);
392 427
393 if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
394 iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
395
396 /* 428 /*
397 * All information is retrieved from the skb->cb array, 429 * All information is retrieved from the skb->cb array,
398 * now we should claim ownership of the driver part of that 430 * now we should claim ownership of the driver part of that
@@ -415,11 +447,15 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
415 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && 447 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
416 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { 448 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
417 if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags)) 449 if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags))
418 rt2x00crypto_tx_copy_iv(skb, iv_len); 450 rt2x00crypto_tx_copy_iv(skb, &txdesc);
419 else 451 else
420 rt2x00crypto_tx_remove_iv(skb, iv_len); 452 rt2x00crypto_tx_remove_iv(skb, &txdesc);
421 } 453 }
422 454
455 if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags))
456 rt2x00queue_payload_align(entry->skb, true,
457 txdesc.header_length);
458
423 /* 459 /*
424 * It could be possible that the queue was corrupted and this 460 * It could be possible that the queue was corrupted and this
425 * call failed. Since we always return NETDEV_TX_OK to mac80211, 461 * call failed. Since we always return NETDEV_TX_OK to mac80211,