aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGertjan van Wingerde <gwingerde@kpnplanet.nl>2008-06-06 16:54:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-14 12:17:57 -0400
commit239c249d06b0c68ae06b10d9d6ad1f8e7f39452b (patch)
tree6d59d08b738406c525f084d043b9dfd91e711fb1
parentd56d453a1dd85aff08fe6965f395049725fdb04e (diff)
rt2x00: Centralize RX packet alignment handling in rt2x00lib.
When rt2x00pci will be switched over to dynamically mapped skb's instead of statically allocated DMA buffers, it no longer can handle alignment of RX packets in a copy step, and needs to implement the same scheme as rt2x00usb does. In order to make the patch on dynamically mapped skb's smaller, already centralize the alignment handling into rt2x00lib. This allows us to move more code in rt2x00lib, and thus remove code duplication between rt2x00usb and rt2x00pci. Signed-off-by: Gertjan van Wingerde <gwingerde@kpnplanet.nl> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c23
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c63
5 files changed, 74 insertions, 79 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 938d375027be..0da8f972a1b2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -930,6 +930,12 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate)
930} 930}
931 931
932/** 932/**
933 * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
934 * @queue: The queue for which the skb will be applicable.
935 */
936struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue);
937
938/**
933 * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input 939 * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input
934 * @entry: The entry which will be used to transfer the TX frame. 940 * @entry: The entry which will be used to transfer the TX frame.
935 * @txdesc: rt2x00 TX descriptor which will be initialized by this function. 941 * @txdesc: rt2x00 TX descriptor which will be initialized by this function.
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 48f4aec1a4d9..ce1f7bbd3d7a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -554,14 +554,36 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
554{ 554{
555 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 555 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
556 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; 556 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
557 unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
557 struct ieee80211_supported_band *sband; 558 struct ieee80211_supported_band *sband;
558 struct ieee80211_hdr *hdr; 559 struct ieee80211_hdr *hdr;
559 const struct rt2x00_rate *rate; 560 const struct rt2x00_rate *rate;
561 unsigned int align;
560 unsigned int i; 562 unsigned int i;
561 int idx = -1; 563 int idx = -1;
562 u16 fc; 564 u16 fc;
563 565
564 /* 566 /*
567 * The data behind the ieee80211 header must be
568 * aligned on a 4 byte boundary. We already reserved
569 * 2 bytes for header_size % 4 == 2 optimization.
570 * To determine the number of bytes which the data
571 * should be moved to the left, we must add these
572 * 2 bytes to the header_size.
573 */
574 align = (header_size + 2) % 4;
575
576 if (align) {
577 skb_push(entry->skb, align);
578 /* Move entire frame in 1 command */
579 memmove(entry->skb->data, entry->skb->data + align,
580 rxdesc->size);
581 }
582
583 /* Update data pointers, trim buffer to correct size */
584 skb_trim(entry->skb, rxdesc->size);
585
586 /*
565 * Update RX statistics. 587 * Update RX statistics.
566 */ 588 */
567 sband = &rt2x00dev->bands[rt2x00dev->curr_band]; 589 sband = &rt2x00dev->bands[rt2x00dev->curr_band];
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index a9819aad5e7d..82e80b69d0be 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -79,11 +79,8 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
79 struct data_queue *queue = rt2x00dev->rx; 79 struct data_queue *queue = rt2x00dev->rx;
80 struct queue_entry *entry; 80 struct queue_entry *entry;
81 struct queue_entry_priv_pci *entry_priv; 81 struct queue_entry_priv_pci *entry_priv;
82 struct ieee80211_hdr *hdr;
83 struct skb_frame_desc *skbdesc; 82 struct skb_frame_desc *skbdesc;
84 struct rxdone_entry_desc rxdesc; 83 struct rxdone_entry_desc rxdesc;
85 int header_size;
86 int align;
87 u32 word; 84 u32 word;
88 85
89 while (1) { 86 while (1) {
@@ -97,27 +94,15 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
97 memset(&rxdesc, 0, sizeof(rxdesc)); 94 memset(&rxdesc, 0, sizeof(rxdesc));
98 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); 95 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
99 96
100 hdr = (struct ieee80211_hdr *)entry_priv->data;
101 header_size =
102 ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
103
104 /*
105 * The data behind the ieee80211 header must be
106 * aligned on a 4 byte boundary.
107 */
108 align = header_size % 4;
109
110 /* 97 /*
111 * Allocate the sk_buffer, initialize it and copy 98 * Allocate the sk_buffer and copy all data into it.
112 * all data into it.
113 */ 99 */
114 entry->skb = dev_alloc_skb(rxdesc.size + align); 100 entry->skb = rt2x00queue_alloc_rxskb(queue);
115 if (!entry->skb) 101 if (!entry->skb)
116 return; 102 return;
117 103
118 skb_reserve(entry->skb, align); 104 memcpy(entry->skb->data, entry_priv->data, rxdesc.size);
119 memcpy(skb_put(entry->skb, rxdesc.size), 105 skb_trim(entry->skb, rxdesc.size);
120 entry_priv->data, rxdesc.size);
121 106
122 /* 107 /*
123 * Fill in skb descriptor 108 * Fill in skb descriptor
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 493066519ef3..2f3dd1d91a12 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -29,6 +29,45 @@
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)
33{
34 struct sk_buff *skb;
35 unsigned int frame_size;
36 unsigned int reserved_size;
37
38 /*
39 * The frame size includes descriptor size, because the
40 * hardware directly receive the frame into the skbuffer.
41 */
42 frame_size = queue->data_size + queue->desc_size;
43
44 /*
45 * For the allocation we should keep a few things in mind:
46 * 1) 4byte alignment of 802.11 payload
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 */
55 reserved_size = 6;
56
57 /*
58 * Allocate skbuffer.
59 */
60 skb = dev_alloc_skb(frame_size + reserved_size);
61 if (!skb)
62 return NULL;
63
64 skb_reserve(skb, reserved_size);
65 skb_put(skb, frame_size);
66
67 return skb;
68}
69EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb);
70
32void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, 71void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
33 struct txentry_desc *txdesc) 72 struct txentry_desc *txdesc)
34{ 73{
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 797023cad947..33833bc6d665 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -260,44 +260,6 @@ EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
260/* 260/*
261 * RX data handlers. 261 * RX data handlers.
262 */ 262 */
263static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue)
264{
265 struct sk_buff *skb;
266 unsigned int frame_size;
267 unsigned int reserved_size;
268
269 /*
270 * The frame size includes descriptor size, because the
271 * hardware directly receive the frame into the skbuffer.
272 */
273 frame_size = queue->data_size + queue->desc_size;
274
275 /*
276 * For the allocation we should keep a few things in mind:
277 * 1) 4byte alignment of 802.11 payload
278 *
279 * For (1) we need at most 4 bytes to guarentee the correct
280 * alignment. We are going to optimize the fact that the chance
281 * that the 802.11 header_size % 4 == 2 is much bigger then
282 * anything else. However since we need to move the frame up
283 * to 3 bytes to the front, which means we need to preallocate
284 * 6 bytes.
285 */
286 reserved_size = 6;
287
288 /*
289 * Allocate skbuffer.
290 */
291 skb = dev_alloc_skb(frame_size + reserved_size);
292 if (!skb)
293 return NULL;
294
295 skb_reserve(skb, reserved_size);
296 skb_put(skb, frame_size);
297
298 return skb;
299}
300
301static void rt2x00usb_interrupt_rxdone(struct urb *urb) 263static void rt2x00usb_interrupt_rxdone(struct urb *urb)
302{ 264{
303 struct queue_entry *entry = (struct queue_entry *)urb->context; 265 struct queue_entry *entry = (struct queue_entry *)urb->context;
@@ -305,8 +267,6 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
305 struct sk_buff *skb; 267 struct sk_buff *skb;
306 struct skb_frame_desc *skbdesc; 268 struct skb_frame_desc *skbdesc;
307 struct rxdone_entry_desc rxdesc; 269 struct rxdone_entry_desc rxdesc;
308 unsigned int header_size;
309 unsigned int align;
310 270
311 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || 271 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
312 !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 272 !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
@@ -330,26 +290,9 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
330 memset(&rxdesc, 0, sizeof(rxdesc)); 290 memset(&rxdesc, 0, sizeof(rxdesc));
331 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); 291 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
332 292
333 header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
334
335 /* 293 /*
336 * The data behind the ieee80211 header must be 294 * Trim the skb to the correct size.
337 * aligned on a 4 byte boundary. We already reserved
338 * 2 bytes for header_size % 4 == 2 optimization.
339 * To determine the number of bytes which the data
340 * should be moved to the left, we must add these
341 * 2 bytes to the header_size.
342 */ 295 */
343 align = (header_size + 2) % 4;
344
345 if (align) {
346 skb_push(entry->skb, align);
347 /* Move entire frame in 1 command */
348 memmove(entry->skb->data, entry->skb->data + align,
349 rxdesc.size);
350 }
351
352 /* Update data pointers, trim buffer to correct size */
353 skb_trim(entry->skb, rxdesc.size); 296 skb_trim(entry->skb, rxdesc.size);
354 297
355 /* 298 /*
@@ -357,7 +300,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
357 * If allocation fails, we should drop the current frame 300 * If allocation fails, we should drop the current frame
358 * 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.
359 */ 302 */
360 skb = rt2x00usb_alloc_rxskb(entry->queue); 303 skb = rt2x00queue_alloc_rxskb(entry->queue);
361 if (!skb) 304 if (!skb)
362 goto skip_entry; 305 goto skip_entry;
363 306
@@ -529,7 +472,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
529 */ 472 */
530 entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; 473 entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size;
531 for (i = 0; i < rt2x00dev->rx->limit; i++) { 474 for (i = 0; i < rt2x00dev->rx->limit; i++) {
532 skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx); 475 skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx);
533 if (!skb) 476 if (!skb)
534 goto exit; 477 goto exit;
535 478