aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 73bbec58341e..eda73ba735a6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1,5 +1,5 @@
1/* 1/*
2 Copyright (C) 2004 - 2009 rt2x00 SourceForge Project 2 Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
3 <http://rt2x00.serialmonkey.com> 3 <http://rt2x00.serialmonkey.com>
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
@@ -25,6 +25,7 @@
25 25
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/slab.h>
28 29
29#include "rt2x00.h" 30#include "rt2x00.h"
30#include "rt2x00lib.h" 31#include "rt2x00lib.h"
@@ -205,6 +206,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
205 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); 206 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
206 unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb); 207 unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
207 u8 rate_idx, rate_flags, retry_rates; 208 u8 rate_idx, rate_flags, retry_rates;
209 u8 skbdesc_flags = skbdesc->flags;
208 unsigned int i; 210 unsigned int i;
209 bool success; 211 bool success;
210 212
@@ -287,12 +289,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,
287 } 289 }
288 290
289 /* 291 /*
290 * Only send the status report to mac80211 when TX status was 292 * Only send the status report to mac80211 when it's a frame
291 * requested by it. If this was a extra frame coming through 293 * that originated in mac80211. If this was a extra frame coming
292 * a mac80211 library call (RTS/CTS) then we should not send the 294 * through a mac80211 library call (RTS/CTS) then we should not
293 * status report back. 295 * send the status report back.
294 */ 296 */
295 if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) 297 if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
296 ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); 298 ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
297 else 299 else
298 dev_kfree_skb_irq(entry->skb); 300 dev_kfree_skb_irq(entry->skb);
@@ -384,9 +386,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
384 memset(&rxdesc, 0, sizeof(rxdesc)); 386 memset(&rxdesc, 0, sizeof(rxdesc));
385 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); 387 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
386 388
387 /* Trim buffer to correct size */
388 skb_trim(entry->skb, rxdesc.size);
389
390 /* 389 /*
391 * The data behind the ieee80211 header must be 390 * The data behind the ieee80211 header must be
392 * aligned on a 4 byte boundary. 391 * aligned on a 4 byte boundary.
@@ -396,18 +395,23 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
396 /* 395 /*
397 * Hardware might have stripped the IV/EIV/ICV data, 396 * Hardware might have stripped the IV/EIV/ICV data,
398 * in that case it is possible that the data was 397 * in that case it is possible that the data was
399 * provided seperately (through hardware descriptor) 398 * provided separately (through hardware descriptor)
400 * in which case we should reinsert the data into the frame. 399 * in which case we should reinsert the data into the frame.
401 */ 400 */
402 if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) && 401 if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) &&
403 (rxdesc.flags & RX_FLAG_IV_STRIPPED)) 402 (rxdesc.flags & RX_FLAG_IV_STRIPPED))
404 rt2x00crypto_rx_insert_iv(entry->skb, header_length, 403 rt2x00crypto_rx_insert_iv(entry->skb, header_length,
405 &rxdesc); 404 &rxdesc);
406 else if (rxdesc.dev_flags & RXDONE_L2PAD) 405 else if (header_length &&
406 (rxdesc.size > header_length) &&
407 (rxdesc.dev_flags & RXDONE_L2PAD))
407 rt2x00queue_remove_l2pad(entry->skb, header_length); 408 rt2x00queue_remove_l2pad(entry->skb, header_length);
408 else 409 else
409 rt2x00queue_align_payload(entry->skb, header_length); 410 rt2x00queue_align_payload(entry->skb, header_length);
410 411
412 /* Trim buffer to correct size */
413 skb_trim(entry->skb, rxdesc.size);
414
411 /* 415 /*
412 * Check if the frame was received using HT. In that case, 416 * Check if the frame was received using HT. In that case,
413 * the rate is the MCS index and should be passed to mac80211 417 * the rate is the MCS index and should be passed to mac80211
@@ -430,7 +434,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
430 434
431 rx_status->mactime = rxdesc.timestamp; 435 rx_status->mactime = rxdesc.timestamp;
432 rx_status->rate_idx = rate_idx; 436 rx_status->rate_idx = rate_idx;
433 rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
434 rx_status->signal = rxdesc.rssi; 437 rx_status->signal = rxdesc.rssi;
435 rx_status->noise = rxdesc.noise; 438 rx_status->noise = rxdesc.noise;
436 rx_status->flag = rxdesc.flags; 439 rx_status->flag = rxdesc.flags;
@@ -684,6 +687,21 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
684 rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues; 687 rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues;
685 688
686 /* 689 /*
690 * Initialize extra TX headroom required.
691 */
692 rt2x00dev->hw->extra_tx_headroom =
693 max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM,
694 rt2x00dev->ops->extra_tx_headroom);
695
696 /*
697 * Take TX headroom required for alignment into account.
698 */
699 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
700 rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE;
701 else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
702 rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;
703
704 /*
687 * Register HW. 705 * Register HW.
688 */ 706 */
689 status = ieee80211_register_hw(rt2x00dev->hw); 707 status = ieee80211_register_hw(rt2x00dev->hw);