aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c77
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c71
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c21
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 */
905struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue); 905struct 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 */
911void 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 */
77static 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
77void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) 125void 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
32struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) 32struct 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}
69EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb); 62EXPORT_SYMBOL_GPL(rt2x00queue_alloc_skb);
63
64void rt2x00queue_free_skb(struct sk_buff *skb)
65{
66 dev_kfree_skb_any(skb);
67}
68EXPORT_SYMBOL_GPL(rt2x00queue_free_skb);
70 69
71void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, 70void 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
424static 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
437static 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
452exit:
453 rt2x00queue_free_skbs(queue);
454
455 return -ENOMEM;
456}
457
425int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) 458int 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,
457int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) 455int 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
488exit: 471exit: