diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.c | 77 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 71 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 21 |
4 files changed, 113 insertions, 66 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 8d45235ecc36..08e8b0a005a6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -899,10 +899,16 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) | |||
899 | } | 899 | } |
900 | 900 | ||
901 | /** | 901 | /** |
902 | * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. | 902 | * rt2x00queue_alloc_skb - allocate a skb. |
903 | * @queue: The queue for which the skb will be applicable. | 903 | * @queue: The queue for which the skb will be applicable. |
904 | */ | 904 | */ |
905 | struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue); | 905 | struct sk_buff *rt2x00queue_alloc_skb(struct data_queue *queue); |
906 | |||
907 | /** | ||
908 | * rt2x00queue_free_skb - free a skb | ||
909 | * @skb: The skb to free. | ||
910 | */ | ||
911 | void rt2x00queue_free_skb(struct sk_buff *skb); | ||
906 | 912 | ||
907 | /** | 913 | /** |
908 | * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input | 914 | * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index d6138389a5d0..e7e3a459b66a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -74,13 +74,59 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); | |||
74 | /* | 74 | /* |
75 | * TX/RX data handlers. | 75 | * TX/RX data handlers. |
76 | */ | 76 | */ |
77 | static void rt2x00pci_rxdone_entry(struct rt2x00_dev *rt2x00dev, | ||
78 | struct queue_entry *entry) | ||
79 | { | ||
80 | struct sk_buff *skb; | ||
81 | struct skb_frame_desc *skbdesc; | ||
82 | struct rxdone_entry_desc rxdesc; | ||
83 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | ||
84 | |||
85 | /* | ||
86 | * Allocate a new sk_buffer. If no new buffer available, drop the | ||
87 | * received frame and reuse the existing buffer. | ||
88 | */ | ||
89 | skb = rt2x00queue_alloc_skb(entry->queue); | ||
90 | if (!skb) | ||
91 | return; | ||
92 | |||
93 | /* | ||
94 | * Extract the RXD details. | ||
95 | */ | ||
96 | memset(&rxdesc, 0, sizeof(rxdesc)); | ||
97 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | ||
98 | |||
99 | /* | ||
100 | * Copy the received data to the entries' skb. | ||
101 | */ | ||
102 | memcpy(entry->skb->data, entry_priv->data, rxdesc.size); | ||
103 | skb_trim(entry->skb, rxdesc.size); | ||
104 | |||
105 | /* | ||
106 | * Fill in skb descriptor | ||
107 | */ | ||
108 | skbdesc = get_skb_frame_desc(entry->skb); | ||
109 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
110 | skbdesc->desc = entry_priv->desc; | ||
111 | skbdesc->desc_len = entry->queue->desc_size; | ||
112 | skbdesc->entry = entry; | ||
113 | |||
114 | /* | ||
115 | * Send the frame to rt2x00lib for further processing. | ||
116 | */ | ||
117 | rt2x00lib_rxdone(entry, &rxdesc); | ||
118 | |||
119 | /* | ||
120 | * Replace the entries' skb with the newly allocated one. | ||
121 | */ | ||
122 | entry->skb = skb; | ||
123 | } | ||
124 | |||
77 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | 125 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) |
78 | { | 126 | { |
79 | struct data_queue *queue = rt2x00dev->rx; | 127 | struct data_queue *queue = rt2x00dev->rx; |
80 | struct queue_entry *entry; | 128 | struct queue_entry *entry; |
81 | struct queue_entry_priv_pci *entry_priv; | 129 | struct queue_entry_priv_pci *entry_priv; |
82 | struct skb_frame_desc *skbdesc; | ||
83 | struct rxdone_entry_desc rxdesc; | ||
84 | u32 word; | 130 | u32 word; |
85 | 131 | ||
86 | while (1) { | 132 | while (1) { |
@@ -91,32 +137,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
91 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) | 137 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) |
92 | break; | 138 | break; |
93 | 139 | ||
94 | memset(&rxdesc, 0, sizeof(rxdesc)); | 140 | rt2x00pci_rxdone_entry(rt2x00dev, entry); |
95 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | ||
96 | |||
97 | /* | ||
98 | * Allocate the sk_buffer and copy all data into it. | ||
99 | */ | ||
100 | entry->skb = rt2x00queue_alloc_rxskb(queue); | ||
101 | if (!entry->skb) | ||
102 | return; | ||
103 | |||
104 | memcpy(entry->skb->data, entry_priv->data, rxdesc.size); | ||
105 | skb_trim(entry->skb, rxdesc.size); | ||
106 | |||
107 | /* | ||
108 | * Fill in skb descriptor | ||
109 | */ | ||
110 | skbdesc = get_skb_frame_desc(entry->skb); | ||
111 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
112 | skbdesc->desc = entry_priv->desc; | ||
113 | skbdesc->desc_len = queue->desc_size; | ||
114 | skbdesc->entry = entry; | ||
115 | |||
116 | /* | ||
117 | * Send the frame to rt2x00lib for further processing. | ||
118 | */ | ||
119 | rt2x00lib_rxdone(entry, &rxdesc); | ||
120 | 141 | ||
121 | if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { | 142 | if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { |
122 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); | 143 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 15660b588a12..278f1a1ac926 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "rt2x00.h" | 29 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) | 32 | struct sk_buff *rt2x00queue_alloc_skb(struct data_queue *queue) |
33 | { | 33 | { |
34 | struct sk_buff *skb; | 34 | struct sk_buff *skb; |
35 | unsigned int frame_size; | 35 | unsigned int frame_size; |
@@ -42,17 +42,10 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) | |||
42 | frame_size = queue->data_size + queue->desc_size; | 42 | frame_size = queue->data_size + queue->desc_size; |
43 | 43 | ||
44 | /* | 44 | /* |
45 | * For the allocation we should keep a few things in mind: | 45 | * Reserve a few bytes extra headroom to allow drivers some moving |
46 | * 1) 4byte alignment of 802.11 payload | 46 | * space (e.g. for alignment), while keeping the skb aligned. |
47 | * | ||
48 | * For (1) we need at most 4 bytes to guarentee the correct | ||
49 | * alignment. We are going to optimize the fact that the chance | ||
50 | * that the 802.11 header_size % 4 == 2 is much bigger then | ||
51 | * anything else. However since we need to move the frame up | ||
52 | * to 3 bytes to the front, which means we need to preallocate | ||
53 | * 6 bytes. | ||
54 | */ | 47 | */ |
55 | reserved_size = 6; | 48 | reserved_size = 8; |
56 | 49 | ||
57 | /* | 50 | /* |
58 | * Allocate skbuffer. | 51 | * Allocate skbuffer. |
@@ -66,7 +59,13 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) | |||
66 | 59 | ||
67 | return skb; | 60 | return skb; |
68 | } | 61 | } |
69 | EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb); | 62 | EXPORT_SYMBOL_GPL(rt2x00queue_alloc_skb); |
63 | |||
64 | void rt2x00queue_free_skb(struct sk_buff *skb) | ||
65 | { | ||
66 | dev_kfree_skb_any(skb); | ||
67 | } | ||
68 | EXPORT_SYMBOL_GPL(rt2x00queue_free_skb); | ||
70 | 69 | ||
71 | void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | 70 | void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, |
72 | struct txentry_desc *txdesc) | 71 | struct txentry_desc *txdesc) |
@@ -422,12 +421,45 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, | |||
422 | return 0; | 421 | return 0; |
423 | } | 422 | } |
424 | 423 | ||
424 | static void rt2x00queue_free_skbs(struct data_queue *queue) | ||
425 | { | ||
426 | unsigned int i; | ||
427 | |||
428 | if (!queue->entries) | ||
429 | return; | ||
430 | |||
431 | for (i = 0; i < queue->limit; i++) { | ||
432 | if (queue->entries[i].skb) | ||
433 | rt2x00queue_free_skb(queue->entries[i].skb); | ||
434 | } | ||
435 | } | ||
436 | |||
437 | static int rt2x00queue_alloc_skbs(struct data_queue *queue) | ||
438 | { | ||
439 | unsigned int i; | ||
440 | struct sk_buff *skb; | ||
441 | |||
442 | for (i = 0; i < queue->limit; i++) { | ||
443 | skb = rt2x00queue_alloc_skb(queue); | ||
444 | if (!skb) | ||
445 | goto exit; | ||
446 | |||
447 | queue->entries[i].skb = skb; | ||
448 | } | ||
449 | |||
450 | return 0; | ||
451 | |||
452 | exit: | ||
453 | rt2x00queue_free_skbs(queue); | ||
454 | |||
455 | return -ENOMEM; | ||
456 | } | ||
457 | |||
425 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | 458 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) |
426 | { | 459 | { |
427 | struct data_queue *queue; | 460 | struct data_queue *queue; |
428 | int status; | 461 | int status; |
429 | 462 | ||
430 | |||
431 | status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); | 463 | status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); |
432 | if (status) | 464 | if (status) |
433 | goto exit; | 465 | goto exit; |
@@ -442,11 +474,14 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | |||
442 | if (status) | 474 | if (status) |
443 | goto exit; | 475 | goto exit; |
444 | 476 | ||
445 | if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | 477 | if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) { |
446 | return 0; | 478 | status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], |
479 | rt2x00dev->ops->atim); | ||
480 | if (status) | ||
481 | goto exit; | ||
482 | } | ||
447 | 483 | ||
448 | status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], | 484 | status = rt2x00queue_alloc_skbs(rt2x00dev->rx); |
449 | rt2x00dev->ops->atim); | ||
450 | if (status) | 485 | if (status) |
451 | goto exit; | 486 | goto exit; |
452 | 487 | ||
@@ -464,6 +499,8 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
464 | { | 499 | { |
465 | struct data_queue *queue; | 500 | struct data_queue *queue; |
466 | 501 | ||
502 | rt2x00queue_free_skbs(rt2x00dev->rx); | ||
503 | |||
467 | queue_for_each(rt2x00dev, queue) { | 504 | queue_for_each(rt2x00dev, queue) { |
468 | kfree(queue->entries); | 505 | kfree(queue->entries); |
469 | queue->entries = NULL; | 506 | queue->entries = NULL; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index f91901ffda5b..29dba86c8cf0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -300,7 +300,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
300 | * If allocation fails, we should drop the current frame | 300 | * If allocation fails, we should drop the current frame |
301 | * so we can recycle the existing sk buffer for the new frame. | 301 | * so we can recycle the existing sk buffer for the new frame. |
302 | */ | 302 | */ |
303 | skb = rt2x00queue_alloc_rxskb(entry->queue); | 303 | skb = rt2x00queue_alloc_skb(entry->queue); |
304 | if (!skb) | 304 | if (!skb) |
305 | goto skip_entry; | 305 | goto skip_entry; |
306 | 306 | ||
@@ -434,8 +434,6 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, | |||
434 | entry_priv = queue->entries[i].priv_data; | 434 | entry_priv = queue->entries[i].priv_data; |
435 | usb_kill_urb(entry_priv->urb); | 435 | usb_kill_urb(entry_priv->urb); |
436 | usb_free_urb(entry_priv->urb); | 436 | usb_free_urb(entry_priv->urb); |
437 | if (queue->entries[i].skb) | ||
438 | kfree_skb(queue->entries[i].skb); | ||
439 | } | 437 | } |
440 | 438 | ||
441 | /* | 439 | /* |
@@ -457,10 +455,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, | |||
457 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | 455 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) |
458 | { | 456 | { |
459 | struct data_queue *queue; | 457 | struct data_queue *queue; |
460 | struct sk_buff *skb; | 458 | int status; |
461 | unsigned int entry_size; | ||
462 | unsigned int i; | ||
463 | int uninitialized_var(status); | ||
464 | 459 | ||
465 | /* | 460 | /* |
466 | * Allocate DMA | 461 | * Allocate DMA |
@@ -471,18 +466,6 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | |||
471 | goto exit; | 466 | goto exit; |
472 | } | 467 | } |
473 | 468 | ||
474 | /* | ||
475 | * For the RX queue, skb's should be allocated. | ||
476 | */ | ||
477 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; | ||
478 | for (i = 0; i < rt2x00dev->rx->limit; i++) { | ||
479 | skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx); | ||
480 | if (!skb) | ||
481 | goto exit; | ||
482 | |||
483 | rt2x00dev->rx->entries[i].skb = skb; | ||
484 | } | ||
485 | |||
486 | return 0; | 469 | return 0; |
487 | 470 | ||
488 | exit: | 471 | exit: |