diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 42 |
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); |