* Please pull 'upstream' branch of rt2x00
@ 2008-06-08 21:41 Ivo van Doorn
2008-06-08 21:42 ` [PATCH 01/10] rt2x00: Implement rt2x00usb_kick_tx_queue() Ivo van Doorn
0 siblings, 1 reply; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:41 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
Hi John,
Here is the official pull request for the latest rt2x00.git.
This contains all patches which I had send last tuesday
plus some additional patches intended for 2.6.27.
This series is mostly intended to get the fragmentation
done right. Up until now the drivers never behaved that
nicely with fragmentation or RTS/CTS-to-sellf which was
mostly due because each individual frame forced the
queue to be kicked immediately without waiting for the
other fragments.
It also contains some front work by Gertjan for reducing
DMA requirements in rt2x00 by making use of pci_map_single
on skbuffers instead of preallocating a chunk of DMA.
Ivo
P.S. I won't resend the patches I had send last tuesday
since nothing has changed with them. So only the 10
new patches will be send seperately. I am not sure
if that feature will be ready/stable for 2.6.27 but this
preperational work is harmless for normal operations
to it is better if that is already in.
---
The following changes since commit ef28eab0c928fe8277d7c3dca234c29f734d7f2e:
Dan Williams (1):
ipw2200: queue direct scans
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/ivd/rt2x00.git/ upstream
Gertjan van Wingerde (5):
rt2x00: Restrict DMA to 32-bit addresses.
rt2x00: Cleanup struct skb_frame_desc.
rt2x00: Centralize RX packet alignment handling in rt2x00lib.
rt2x00: Fix double usage of skb->cb in USB RX path.
rt2x00: Rework alignment check.
Ivo van Doorn (15):
rt2x00: Calculate register offset during compile time
rt2x00: Cleanup/optimize set_state() function callback function
rt2x00: Move led initialization into function
rt2x00: Remove CTS/RTS check in tx()
rt2x00: Removed unused descriptor read in txdone
rt2x00: Don't kill guardian_urb when it wasn't created
rt2x00: Make rt2x00_set/get_field macros
rt2x00: Release rt2x00 2.1.7
rt2x00: Fix queue initialization
rt2x00: Implement rt2x00usb_kick_tx_queue()
rt2x00: Move generic TX frame writing code into rt2x00queue
rt2x00: Don't kick TX queue after each frame
rt2x00: Use __builtin_choose_expr() instead of ?:
rt2x00: Clear IEEE80211_TX_CTL_USE_RTS_CTS flag for RTS frame
rt2x00: Remove unused defines
drivers/net/wireless/rt2x00/rt2400pci.c | 95 ++++++++---------
drivers/net/wireless/rt2x00/rt2400pci.h | 2 -
drivers/net/wireless/rt2x00/rt2500pci.c | 91 +++++++--------
drivers/net/wireless/rt2x00/rt2500pci.h | 2 -
drivers/net/wireless/rt2x00/rt2500usb.c | 98 ++++++++--------
drivers/net/wireless/rt2x00/rt2500usb.h | 2 -
drivers/net/wireless/rt2x00/rt2x00.h | 13 ++-
drivers/net/wireless/rt2x00/rt2x00debug.c | 6 +-
drivers/net/wireless/rt2x00/rt2x00dev.c | 21 ++++
drivers/net/wireless/rt2x00/rt2x00lib.h | 1 +
drivers/net/wireless/rt2x00/rt2x00mac.c | 30 ++----
drivers/net/wireless/rt2x00/rt2x00pci.c | 75 ++++---------
drivers/net/wireless/rt2x00/rt2x00pci.h | 11 +-
drivers/net/wireless/rt2x00/rt2x00queue.c | 111 ++++++++++++++++---
drivers/net/wireless/rt2x00/rt2x00queue.h | 27 +++--
drivers/net/wireless/rt2x00/rt2x00reg.h | 134 +++++++++++++---------
drivers/net/wireless/rt2x00/rt2x00usb.c | 170 +++++++++++------------------
drivers/net/wireless/rt2x00/rt2x00usb.h | 22 +++-
drivers/net/wireless/rt2x00/rt61pci.c | 111 ++++++++-----------
drivers/net/wireless/rt2x00/rt61pci.h | 2 -
drivers/net/wireless/rt2x00/rt73usb.c | 112 +++++++++----------
drivers/net/wireless/rt2x00/rt73usb.h | 2 -
22 files changed, 581 insertions(+), 557 deletions(-)
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 01/10] rt2x00: Implement rt2x00usb_kick_tx_queue()
2008-06-08 21:41 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
@ 2008-06-08 21:42 ` Ivo van Doorn
2008-06-08 21:43 ` [PATCH 02/10] rt2x00: Move generic TX frame writing code into rt2x00queue Ivo van Doorn
0 siblings, 1 reply; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:42 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
rt2x00usb_kick_tx_queue() will loop over all entries
within the INDEX_DONE->INDEX range and kick each entry
which is pending to be kicked. This makes the kick_tx_queue
approach work the same as with the PCI drivers which
will allow for more code generalisation into rt2x00lib.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2500usb.c | 4 ++-
drivers/net/wireless/rt2x00/rt2x00queue.h | 3 ++
drivers/net/wireless/rt2x00/rt2x00usb.c | 48 ++++++++++++++++++++++++++++-
drivers/net/wireless/rt2x00/rt2x00usb.h | 11 ++++++
drivers/net/wireless/rt2x00/rt73usb.c | 4 ++-
5 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 0d51b74..6abb4c5 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1116,8 +1116,10 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
{
u16 reg;
- if (queue != QID_BEACON)
+ if (queue != QID_BEACON) {
+ rt2x00usb_kick_tx_queue(rt2x00dev, queue);
return;
+ }
rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®);
if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 4d00ced..303d556 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -260,11 +260,14 @@ struct txentry_desc {
* @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data
* encryption or decryption. The entry should only be touched after
* the device has signaled it is done with it.
+ * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting
+ * for the signal to start sending.
*/
enum queue_entry_flags {
ENTRY_BCN_ASSIGNED,
ENTRY_OWNER_DEVICE_DATA,
ENTRY_OWNER_DEVICE_CRYPTO,
+ ENTRY_DATA_PENDING,
};
/**
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 86f1ab7..eff10b9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -232,9 +232,10 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
* Initialize URB and send the frame to the device.
*/
__set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+ __set_bit(ENTRY_DATA_PENDING, &entry->flags);
+
usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1),
skb->data, length, rt2x00usb_interrupt_txdone, entry);
- usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
rt2x00queue_index_inc(queue, Q_INDEX);
@@ -242,6 +243,51 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data);
+static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
+{
+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;
+
+ if (__test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
+ usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+}
+
+void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid)
+{
+ struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
+ unsigned long irqflags;
+ unsigned int index;
+ unsigned int index_done;
+ unsigned int i;
+
+ /*
+ * Only protect the range we are going to loop over,
+ * if during our loop a extra entry is set to pending
+ * it should not be kicked during this run, since it
+ * is part of another TX operation.
+ */
+ spin_lock_irqsave(&queue->lock, irqflags);
+ index = queue->index[Q_INDEX];
+ index_done = queue->index[Q_INDEX_DONE];
+ spin_unlock_irqrestore(&queue->lock, irqflags);
+
+ /*
+ * Start from the TX done pointer, this guarentees that we will
+ * send out all frames in the correct order.
+ */
+ if (index_done < index) {
+ for (i = index_done; i < index; i++)
+ rt2x00usb_kick_tx_entry(&queue->entries[i]);
+ } else {
+ for (i = index_done; i < queue->limit; i++)
+ rt2x00usb_kick_tx_entry(&queue->entries[i]);
+
+ for (i = 0; i < index; i++)
+ rt2x00usb_kick_tx_entry(&queue->entries[i]);
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
+
/*
* RX data handlers.
*/
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 26f53f8..460d32c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -245,6 +245,17 @@ struct queue_entry_priv_usb_bcn {
struct urb *guardian_urb;
};
+/**
+ * rt2x00usb_kick_tx_queue - Kick data queue
+ * @rt2x00dev: Pointer to &struct rt2x00_dev
+ * @qid: Data queue to kick
+ *
+ * This will walk through all entries of the queue and push all pending
+ * frames to the hardware as a single burst.
+ */
+void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid);
+
/*
* Device initialization handlers.
*/
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index db1fc13..5e5f603 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1350,8 +1350,10 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- if (queue != QID_BEACON)
+ if (queue != QID_BEACON) {
+ rt2x00usb_kick_tx_queue(rt2x00dev, queue);
return;
+ }
/*
* For Wi-Fi faily generated beacons between participating stations.
--
1.5.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 02/10] rt2x00: Move generic TX frame writing code into rt2x00queue
2008-06-08 21:42 ` [PATCH 01/10] rt2x00: Implement rt2x00usb_kick_tx_queue() Ivo van Doorn
@ 2008-06-08 21:43 ` Ivo van Doorn
2008-06-08 21:43 ` [PATCH 03/10] rt2x00: Don't kick TX queue after each frame Ivo van Doorn
0 siblings, 1 reply; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:43 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
The write_tx_data functions in rt2x00pci and rt2x00usb have
a lot in common. This moves that duplicate code into
rt2x00queue_write_tx_frame().
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00.h | 3 +-
drivers/net/wireless/rt2x00/rt2x00lib.h | 1 +
drivers/net/wireless/rt2x00/rt2x00mac.c | 7 +---
drivers/net/wireless/rt2x00/rt2x00pci.c | 43 ++++++++--------------
drivers/net/wireless/rt2x00/rt2x00pci.h | 11 ++++--
drivers/net/wireless/rt2x00/rt2x00queue.c | 37 +++++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00usb.c | 57 +++++++----------------------
drivers/net/wireless/rt2x00/rt2x00usb.h | 11 ++++--
8 files changed, 85 insertions(+), 85 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 2f79336..c7da3c2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -546,8 +546,7 @@ struct rt2x00lib_ops {
void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb,
struct txentry_desc *txdesc);
- int (*write_tx_data) (struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue, struct sk_buff *skb);
+ int (*write_tx_data) (struct queue_entry *entry);
int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb);
void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index c4ce534..558f45b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -101,6 +101,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
/*
* Queue handlers.
*/
+int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb);
void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev);
void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev);
int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 97d9095..e7f544c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -89,7 +89,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
- if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {
+ if (rt2x00queue_write_tx_frame(queue, skb)) {
WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
return NETDEV_TX_BUSY;
}
@@ -158,7 +158,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
}
}
- if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {
+ if (rt2x00queue_write_tx_frame(queue, skb)) {
ieee80211_stop_queue(rt2x00dev->hw, qid);
return NETDEV_TX_BUSY;
}
@@ -166,9 +166,6 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (rt2x00queue_full(queue))
ieee80211_stop_queue(rt2x00dev->hw, qid);
- if (rt2x00dev->ops->lib->kick_tx_queue)
- rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid);
-
return NETDEV_TX_OK;
}
EXPORT_SYMBOL_GPL(rt2x00mac_tx);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index d508c80..83a35b1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -34,52 +34,40 @@
/*
* TX data handlers.
*/
-int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue, struct sk_buff *skb)
+int rt2x00pci_write_tx_data(struct queue_entry *entry)
{
- struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc;
- struct txentry_desc txdesc;
u32 word;
- if (rt2x00queue_full(queue))
- return -EINVAL;
-
rt2x00_desc_read(entry_priv->desc, 0, &word);
- if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) ||
- rt2x00_get_field32(word, TXD_ENTRY_VALID)) {
- ERROR(rt2x00dev,
- "Arrived at non-free entry in the non-full queue %d.\n"
+ /*
+ * This should not happen, we already checked the entry
+ * was ours. When the hardware disagrees there has been
+ * a queue corruption!
+ */
+ if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) ||
+ rt2x00_get_field32(word, TXD_ENTRY_VALID))) {
+ ERROR(entry->queue->rt2x00dev,
+ "Corrupt queue %d, accessing entry which is not ours.\n"
"Please file bug report to %s.\n",
entry->queue->qid, DRV_PROJECT);
return -EINVAL;
}
/*
- * Copy all TX descriptor information into txdesc,
- * after that we are free to use the skb->cb array
- * for our information.
- */
- entry->skb = skb;
- rt2x00queue_create_tx_descriptor(entry, &txdesc);
-
- /*
* Fill in skb descriptor
*/
- skbdesc = get_skb_frame_desc(skb);
+ skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = skb->data;
- skbdesc->data_len = skb->len;
+ skbdesc->data = entry->skb->data;
+ skbdesc->data_len = entry->skb->len;
skbdesc->desc = entry_priv->desc;
- skbdesc->desc_len = queue->desc_size;
+ skbdesc->desc_len = entry->queue->desc_size;
skbdesc->entry = entry;
- memcpy(entry_priv->data, skb->data, skb->len);
-
- rt2x00queue_write_tx_descriptor(entry, &txdesc);
- rt2x00queue_index_inc(queue, Q_INDEX);
+ memcpy(entry_priv->data, entry->skb->data, entry->skb->len);
return 0;
}
@@ -178,6 +166,7 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,
rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0);
rt2x00_desc_write(entry_priv->desc, 0, word);
+ __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 37c851e..87c4a0c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -87,11 +87,14 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
memcpy_toio(rt2x00dev->csr.base + offset, value, length);
}
-/*
- * TX data handlers.
+/**
+ * rt2x00pci_write_tx_data - Initialize data for TX operation
+ * @entry: The entry where the frame is located
+ *
+ * This function will initialize the DMA and skb descriptor
+ * to prepare the entry for the actual TX operation.
*/
-int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue, struct sk_buff *skb);
+int rt2x00pci_write_tx_data(struct queue_entry *entry);
/**
* struct queue_entry_priv_pci: Per entry PCI specific information
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 6f3aa0f..f875b7a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -188,6 +188,43 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
}
EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor);
+int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
+{
+ struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
+ struct txentry_desc txdesc;
+
+ if (unlikely(rt2x00queue_full(queue)))
+ return -EINVAL;
+
+ if (__test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
+ ERROR(queue->rt2x00dev,
+ "Arrived at non-free entry in the non-full queue %d.\n"
+ "Please file bug report to %s.\n",
+ queue->qid, DRV_PROJECT);
+ return -EINVAL;
+ }
+
+ /*
+ * Copy all TX descriptor information into txdesc,
+ * after that we are free to use the skb->cb array
+ * for our information.
+ */
+ entry->skb = skb;
+ rt2x00queue_create_tx_descriptor(entry, &txdesc);
+
+ if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) {
+ __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+ return -EIO;
+ }
+
+ __set_bit(ENTRY_DATA_PENDING, &entry->flags);
+
+ rt2x00queue_index_inc(queue, Q_INDEX);
+ rt2x00queue_write_tx_descriptor(entry, &txdesc);
+
+ return 0;
+}
+
struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
const enum data_queue_qid queue)
{
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index eff10b9..0d1be58 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -173,71 +173,42 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
ieee80211_wake_queue(rt2x00dev->hw, qid);
}
-int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue, struct sk_buff *skb)
+int rt2x00usb_write_tx_data(struct queue_entry *entry)
{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);
- struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc;
- struct txentry_desc txdesc;
u32 length;
- if (rt2x00queue_full(queue))
- return -EINVAL;
-
- if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
- ERROR(rt2x00dev,
- "Arrived at non-free entry in the non-full queue %d.\n"
- "Please file bug report to %s.\n",
- entry->queue->qid, DRV_PROJECT);
- return -EINVAL;
- }
-
- /*
- * Copy all TX descriptor information into txdesc,
- * after that we are free to use the skb->cb array
- * for our information.
- */
- entry->skb = skb;
- rt2x00queue_create_tx_descriptor(entry, &txdesc);
-
/*
* Add the descriptor in front of the skb.
*/
- skb_push(skb, queue->desc_size);
- memset(skb->data, 0, queue->desc_size);
+ skb_push(entry->skb, entry->queue->desc_size);
+ memset(entry->skb->data, 0, entry->queue->desc_size);
/*
* Fill in skb descriptor
*/
- skbdesc = get_skb_frame_desc(skb);
+ skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = skb->data + queue->desc_size;
- skbdesc->data_len = skb->len - queue->desc_size;
- skbdesc->desc = skb->data;
- skbdesc->desc_len = queue->desc_size;
+ skbdesc->data = entry->skb->data + entry->queue->desc_size;
+ skbdesc->data_len = entry->skb->len - entry->queue->desc_size;
+ skbdesc->desc = entry->skb->data;
+ skbdesc->desc_len = entry->queue->desc_size;
skbdesc->entry = entry;
- rt2x00queue_write_tx_descriptor(entry, &txdesc);
-
/*
* USB devices cannot blindly pass the skb->len as the
* length of the data to usb_fill_bulk_urb. Pass the skb
* to the driver to determine what the length should be.
*/
- length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, skb);
-
- /*
- * Initialize URB and send the frame to the device.
- */
- __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
- __set_bit(ENTRY_DATA_PENDING, &entry->flags);
+ length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb);
- usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1),
- skb->data, length, rt2x00usb_interrupt_txdone, entry);
-
- rt2x00queue_index_inc(queue, Q_INDEX);
+ usb_fill_bulk_urb(entry_priv->urb, usb_dev,
+ usb_sndbulkpipe(usb_dev, 1),
+ entry->skb->data, length,
+ rt2x00usb_interrupt_txdone, entry);
return 0;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 460d32c..b1187c8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -212,11 +212,14 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev,
*/
void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev);
-/*
- * TX data handlers.
+/**
+ * rt2x00usb_write_tx_data - Initialize URB for TX operation
+ * @entry: The entry where the frame is located
+ *
+ * This function will initialize the URB and skb descriptor
+ * to prepare the entry for the actual TX operation.
*/
-int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue, struct sk_buff *skb);
+int rt2x00usb_write_tx_data(struct queue_entry *entry);
/**
* struct queue_entry_priv_usb: Per entry USB specific information
--
1.5.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 03/10] rt2x00: Don't kick TX queue after each frame
2008-06-08 21:43 ` [PATCH 02/10] rt2x00: Move generic TX frame writing code into rt2x00queue Ivo van Doorn
@ 2008-06-08 21:43 ` Ivo van Doorn
2008-06-08 21:44 ` [PATCH 04/10] rt2x00: Cleanup struct skb_frame_desc Ivo van Doorn
0 siblings, 1 reply; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:43 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
TX queues shouldn't be kicked after each frame that is put into the queue.
This could cause problems during RTS and CTS-to-self as well as
with fragmentation. In all those cases you want all frames to be send
out in a single burst. Off course we shouldn't let the queue fill up
entirely, thus we introduce a 10% threshold which, when reached,
will force the frames to be send out regardless of the frame.
In addition we should prevent queues to become full in such a way that the tx()
handler can fail. Instead of stopping the queue when it is full, we should stop
it when it is below the threshold.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 1 -
drivers/net/wireless/rt2x00/rt2500pci.c | 1 -
drivers/net/wireless/rt2x00/rt2500usb.c | 1 -
drivers/net/wireless/rt2x00/rt2x00.h | 2 +-
drivers/net/wireless/rt2x00/rt2x00mac.c | 10 +---------
drivers/net/wireless/rt2x00/rt2x00pci.c | 6 +++---
drivers/net/wireless/rt2x00/rt2x00queue.c | 28 +++++++++++++++++-----------
drivers/net/wireless/rt2x00/rt2x00queue.h | 19 ++++++++++++++-----
drivers/net/wireless/rt2x00/rt2x00usb.c | 6 +++---
drivers/net/wireless/rt2x00/rt61pci.c | 1 -
drivers/net/wireless/rt2x00/rt73usb.c | 1 -
11 files changed, 39 insertions(+), 37 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 94226b4..b5b0ded 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1507,7 +1507,6 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data;
skbdesc->data_len = skb->len;
skbdesc->desc = entry_priv->desc;
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index c8cf8c1..74b54c9 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1823,7 +1823,6 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data;
skbdesc->data_len = skb->len;
skbdesc->desc = entry_priv->desc;
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 6abb4c5..0762214 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1711,7 +1711,6 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data + intf->beacon->queue->desc_size;
skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
skbdesc->desc = skb->data;
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index c7da3c2..938d375 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -826,7 +826,7 @@ struct rt2x00_dev {
* The Beacon array also contains the Atim queue
* if that is supported by the device.
*/
- int data_queues;
+ unsigned int data_queues;
struct data_queue *rx;
struct data_queue *tx;
struct data_queue *bcn;
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index e7f544c..59f273b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -34,7 +34,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
struct sk_buff *frag_skb)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb);
- struct skb_frame_desc *skbdesc;
struct ieee80211_tx_info *rts_info;
struct sk_buff *skb;
int size;
@@ -82,13 +81,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
frag_skb->data, size, tx_info,
(struct ieee80211_rts *)(skb->data));
- /*
- * Initialize skb descriptor
- */
- skbdesc = get_skb_frame_desc(skb);
- memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
-
if (rt2x00queue_write_tx_frame(queue, skb)) {
WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
return NETDEV_TX_BUSY;
@@ -163,7 +155,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_BUSY;
}
- if (rt2x00queue_full(queue))
+ if (rt2x00queue_threshold(queue))
ieee80211_stop_queue(rt2x00dev->hw, qid);
return NETDEV_TX_OK;
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 83a35b1..945ed71 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -170,11 +170,11 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
/*
- * If the data queue was full before the txdone handler
- * we must make sure the packet queue in the mac80211 stack
+ * If the data queue was below the threshold before the txdone
+ * handler we must make sure the packet queue in the mac80211 stack
* is reenabled when the txdone handler has finished.
*/
- if (!rt2x00queue_full(entry->queue))
+ if (!rt2x00queue_threshold(entry->queue))
ieee80211_wake_queue(rt2x00dev->hw, qid);
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index f875b7a..4930665 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -163,8 +163,8 @@ EXPORT_SYMBOL_GPL(rt2x00queue_create_tx_descriptor);
void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ struct data_queue *queue = entry->queue;
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc);
@@ -175,16 +175,21 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb);
/*
- * We are done writing the frame to the queue entry,
- * also kick the queue in case the correct flags are set,
- * note that this will automatically filter beacons and
- * RTS/CTS frames since those frames don't have this flag
- * set.
+ * Check if we need to kick the queue, there are however a few rules
+ * 1) Don't kick beacon queue
+ * 2) Don't kick unless this is the last in frame in a burst.
+ * When the burst flag is set, this frame is always followed
+ * by another frame which in some way are related to eachother.
+ * This is true for fragments, RTS or CTS-to-self frames.
+ * 3) Rule 2 can be broken when the available entries
+ * in the queue are less then a certain threshold.
*/
- if (rt2x00dev->ops->lib->kick_tx_queue &&
- !(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED))
- rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev,
- entry->queue->qid);
+ if (entry->queue->qid == QID_BEACON)
+ return;
+
+ if (rt2x00queue_threshold(queue) ||
+ !test_bit(ENTRY_TXD_BURST, &txdesc->flags))
+ rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
}
EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor);
@@ -349,6 +354,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
rt2x00queue_reset(queue);
queue->limit = qdesc->entry_num;
+ queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10);
queue->data_size = qdesc->data_size;
queue->desc_size = qdesc->desc_size;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 303d556..623fc27 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -82,12 +82,10 @@ enum data_queue_qid {
/**
* enum skb_frame_desc_flags: Flags for &struct skb_frame_desc
*
- * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver
- * and should not be reported back to mac80211 during txdone.
*/
-enum skb_frame_desc_flags {
- FRAME_DESC_DRIVER_GENERATED = 1 << 0,
-};
+//enum skb_frame_desc_flags {
+// TEMPORARILY EMPTY
+//};
/**
* struct skb_frame_desc: Descriptor information for the skb buffer
@@ -325,6 +323,7 @@ enum queue_index {
* index corruption due to concurrency.
* @count: Number of frames handled in the queue.
* @limit: Maximum number of entries in the queue.
+ * @threshold: Minimum number of free entries before queue is kicked by force.
* @length: Number of frames in queue.
* @index: Index pointers to entry positions in the queue,
* use &enum queue_index to get a specific index field.
@@ -343,6 +342,7 @@ struct data_queue {
spinlock_t lock;
unsigned int count;
unsigned short limit;
+ unsigned short threshold;
unsigned short length;
unsigned short index[Q_INDEX_MAX];
@@ -467,6 +467,15 @@ static inline int rt2x00queue_available(struct data_queue *queue)
}
/**
+ * rt2x00queue_threshold - Check if the queue is below threshold
+ * @queue: Queue to check.
+ */
+static inline int rt2x00queue_threshold(struct data_queue *queue)
+{
+ return rt2x00queue_available(queue) < queue->threshold;
+}
+
+/**
* rt2x00_desc_read - Read a word from the hardware descriptor.
* @desc: Base descriptor address
* @word: Word index from where the descriptor should be read.
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 0d1be58..bed595f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -165,11 +165,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
/*
- * If the data queue was full before the txdone handler
- * we must make sure the packet queue in the mac80211 stack
+ * If the data queue was below the threshold before the txdone
+ * handler we must make sure the packet queue in the mac80211 stack
* is reenabled when the txdone handler has finished.
*/
- if (!rt2x00queue_full(entry->queue))
+ if (!rt2x00queue_threshold(entry->queue))
ieee80211_wake_queue(rt2x00dev->hw, qid);
}
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index aa9ef66..746f87c 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2375,7 +2375,6 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data;
skbdesc->data_len = skb->len;
skbdesc->desc = entry_priv->desc;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 5e5f603..ae50f63 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1980,7 +1980,6 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data + intf->beacon->queue->desc_size;
skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
skbdesc->desc = skb->data;
--
1.5.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 04/10] rt2x00: Cleanup struct skb_frame_desc.
2008-06-08 21:43 ` [PATCH 03/10] rt2x00: Don't kick TX queue after each frame Ivo van Doorn
@ 2008-06-08 21:44 ` Ivo van Doorn
2008-06-08 21:45 ` [PATCH 05/10] rt2x00: Centralize RX packet alignment handling in rt2x00lib Ivo van Doorn
0 siblings, 1 reply; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:44 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
From: Gertjan van Wingerde <gwingerde@wingerd.gvw.nl>
The data and data_len fields aren't really necessary in struct skb_frame_desc,
as they can be deduced from the skb itself.
Signed-off-by: Gertjan van Wingerde <gwingerde@kpnplanet.nl>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 6 ++----
drivers/net/wireless/rt2x00/rt2500pci.c | 2 --
drivers/net/wireless/rt2x00/rt2500usb.c | 7 ++-----
drivers/net/wireless/rt2x00/rt2x00debug.c | 6 +++---
drivers/net/wireless/rt2x00/rt2x00pci.c | 4 ----
drivers/net/wireless/rt2x00/rt2x00queue.h | 5 +----
drivers/net/wireless/rt2x00/rt2x00usb.c | 3 ---
drivers/net/wireless/rt2x00/rt61pci.c | 8 +++-----
drivers/net/wireless/rt2x00/rt73usb.c | 7 ++-----
9 files changed, 13 insertions(+), 35 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index b5b0ded..bb3d835 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1016,8 +1016,8 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(entry_priv->desc, 1, word);
rt2x00_desc_read(txd, 2, &word);
- rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skbdesc->data_len);
- rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skbdesc->data_len);
+ rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skb->len);
+ rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skb->len);
rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 3, &word);
@@ -1507,8 +1507,6 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = skb->data;
- skbdesc->data_len = skb->len;
skbdesc->desc = entry_priv->desc;
skbdesc->desc_len = intf->beacon->queue->desc_size;
skbdesc->entry = intf->beacon;
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 74b54c9..3c956b9 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1823,8 +1823,6 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = skb->data;
- skbdesc->data_len = skb->len;
skbdesc->desc = entry_priv->desc;
skbdesc->desc_len = intf->beacon->queue->desc_size;
skbdesc->entry = intf->beacon;
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 0762214..1bfb68a 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1088,7 +1088,8 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,
test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
- rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT,
+ skb->len - skbdesc->desc_len);
rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE);
rt2x00_desc_write(txd, 0, word);
}
@@ -1196,8 +1197,6 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
* Adjust the skb memory window to the frame boundaries.
*/
skb_trim(entry->skb, rxdesc->size);
- skbdesc->data = entry->skb->data;
- skbdesc->data_len = rxdesc->size;
}
/*
@@ -1711,8 +1710,6 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = skb->data + intf->beacon->queue->desc_size;
- skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
skbdesc->desc = skb->data;
skbdesc->desc_len = intf->beacon->queue->desc_size;
skbdesc->entry = intf->beacon;
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index bd92cb8..300cf06 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -133,7 +133,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
return;
}
- skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + desc->data_len,
+ skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + skb->len,
GFP_ATOMIC);
if (!skbcopy) {
DEBUG(rt2x00dev, "Failed to copy skb for dump.\n");
@@ -144,7 +144,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION);
dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr));
dump_hdr->desc_length = cpu_to_le32(desc->desc_len);
- dump_hdr->data_length = cpu_to_le32(desc->data_len);
+ dump_hdr->data_length = cpu_to_le32(skb->len);
dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev);
@@ -155,7 +155,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
memcpy(skb_put(skbcopy, desc->desc_len), desc->desc, desc->desc_len);
- memcpy(skb_put(skbcopy, desc->data_len), desc->data, desc->data_len);
+ memcpy(skb_put(skbcopy, skb->len), skb->data, skb->len);
skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
wake_up_interruptible(&intf->frame_dump_waitqueue);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 945ed71..8712238 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -61,8 +61,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry)
*/
skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = entry->skb->data;
- skbdesc->data_len = entry->skb->len;
skbdesc->desc = entry_priv->desc;
skbdesc->desc_len = entry->queue->desc_size;
skbdesc->entry = entry;
@@ -126,8 +124,6 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
*/
skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = entry->skb->data;
- skbdesc->data_len = entry->skb->len;
skbdesc->desc = entry_priv->desc;
skbdesc->desc_len = queue->desc_size;
skbdesc->entry = entry;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 623fc27..fcf5252 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -105,11 +105,8 @@ enum data_queue_qid {
struct skb_frame_desc {
unsigned int flags;
- unsigned short data_len;
- unsigned short desc_len;
-
- void *data;
void *desc;
+ unsigned int desc_len;
struct queue_entry *entry;
};
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index bed595f..20c3ce8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -192,8 +192,6 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry)
*/
skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = entry->skb->data + entry->queue->desc_size;
- skbdesc->data_len = entry->skb->len - entry->queue->desc_size;
skbdesc->desc = entry->skb->data;
skbdesc->desc_len = entry->queue->desc_size;
skbdesc->entry = entry;
@@ -352,7 +350,6 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
}
/* Update data pointers, trim buffer to correct size */
- skbdesc->data = entry->skb->data;
skb_trim(entry->skb, rxdesc.size);
/*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 746f87c..5b7267e 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1562,7 +1562,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
if (skbdesc->desc_len > TXINFO_SIZE) {
rt2x00_desc_read(txd, 11, &word);
- rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len);
+ rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skb->len);
rt2x00_desc_write(txd, 11, word);
}
@@ -1581,7 +1581,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
- rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len);
rt2x00_set_field32(&word, TXD_W0_BURST,
test_bit(ENTRY_TXD_BURST, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
@@ -2375,8 +2375,6 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = skb->data;
- skbdesc->data_len = skb->len;
skbdesc->desc = entry_priv->desc;
skbdesc->desc_len = intf->beacon->queue->desc_size;
skbdesc->entry = intf->beacon;
@@ -2401,7 +2399,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
skbdesc->desc, skbdesc->desc_len);
rt2x00pci_register_multiwrite(rt2x00dev,
beacon_base + skbdesc->desc_len,
- skbdesc->data, skbdesc->data_len);
+ skb->data, skb->len);
rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON);
return 0;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index ae50f63..800a1e2 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1320,7 +1320,8 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
- rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT,
+ skb->len - skbdesc->desc_len);
rt2x00_set_field32(&word, TXD_W0_BURST2,
test_bit(ENTRY_TXD_BURST, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
@@ -1466,8 +1467,6 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
*/
skb_pull(entry->skb, entry->queue->desc_size);
skb_trim(entry->skb, rxdesc->size);
- skbdesc->data = entry->skb->data;
- skbdesc->data_len = rxdesc->size;
}
/*
@@ -1980,8 +1979,6 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = skb->data + intf->beacon->queue->desc_size;
- skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
skbdesc->desc = skb->data;
skbdesc->desc_len = intf->beacon->queue->desc_size;
skbdesc->entry = intf->beacon;
--
1.5.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 05/10] rt2x00: Centralize RX packet alignment handling in rt2x00lib.
2008-06-08 21:44 ` [PATCH 04/10] rt2x00: Cleanup struct skb_frame_desc Ivo van Doorn
@ 2008-06-08 21:45 ` Ivo van Doorn
2008-06-08 21:45 ` [PATCH 06/10] rt2x00: Fix double usage of skb->cb in USB RX path Ivo van Doorn
0 siblings, 1 reply; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:45 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
From: Gertjan van Wingerde <gwingerde@kpnplanet.nl>
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>
---
drivers/net/wireless/rt2x00/rt2x00.h | 6 +++
drivers/net/wireless/rt2x00/rt2x00dev.c | 22 ++++++++++
drivers/net/wireless/rt2x00/rt2x00pci.c | 23 ++---------
drivers/net/wireless/rt2x00/rt2x00queue.c | 39 ++++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00usb.c | 63 +---------------------------
5 files changed, 74 insertions(+), 79 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 938d375..0da8f97 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)
}
/**
+ * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
+ * @queue: The queue for which the skb will be applicable.
+ */
+struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue);
+
+/**
* rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input
* @entry: The entry which will be used to transfer the TX frame.
* @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 48f4aec..ce1f7bb 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,
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
+ unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
struct ieee80211_supported_band *sband;
struct ieee80211_hdr *hdr;
const struct rt2x00_rate *rate;
+ unsigned int align;
unsigned int i;
int idx = -1;
u16 fc;
/*
+ * The data behind the ieee80211 header must be
+ * aligned on a 4 byte boundary. We already reserved
+ * 2 bytes for header_size % 4 == 2 optimization.
+ * To determine the number of bytes which the data
+ * should be moved to the left, we must add these
+ * 2 bytes to the header_size.
+ */
+ align = (header_size + 2) % 4;
+
+ if (align) {
+ skb_push(entry->skb, align);
+ /* Move entire frame in 1 command */
+ memmove(entry->skb->data, entry->skb->data + align,
+ rxdesc->size);
+ }
+
+ /* Update data pointers, trim buffer to correct size */
+ skb_trim(entry->skb, rxdesc->size);
+
+ /*
* Update RX statistics.
*/
sband = &rt2x00dev->bands[rt2x00dev->curr_band];
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 8712238..8d6ad18 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)
struct data_queue *queue = rt2x00dev->rx;
struct queue_entry *entry;
struct queue_entry_priv_pci *entry_priv;
- struct ieee80211_hdr *hdr;
struct skb_frame_desc *skbdesc;
struct rxdone_entry_desc rxdesc;
- int header_size;
- int align;
u32 word;
while (1) {
@@ -97,27 +94,15 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
memset(&rxdesc, 0, sizeof(rxdesc));
rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
- hdr = (struct ieee80211_hdr *)entry_priv->data;
- header_size =
- ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
-
- /*
- * The data behind the ieee80211 header must be
- * aligned on a 4 byte boundary.
- */
- align = header_size % 4;
-
/*
- * Allocate the sk_buffer, initialize it and copy
- * all data into it.
+ * Allocate the sk_buffer and copy all data into it.
*/
- entry->skb = dev_alloc_skb(rxdesc.size + align);
+ entry->skb = rt2x00queue_alloc_rxskb(queue);
if (!entry->skb)
return;
- skb_reserve(entry->skb, align);
- memcpy(skb_put(entry->skb, rxdesc.size),
- entry_priv->data, rxdesc.size);
+ memcpy(entry->skb->data, entry_priv->data, rxdesc.size);
+ skb_trim(entry->skb, rxdesc.size);
/*
* Fill in skb descriptor
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 4930665..2f3dd1d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -29,6 +29,45 @@
#include "rt2x00.h"
#include "rt2x00lib.h"
+struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue)
+{
+ struct sk_buff *skb;
+ unsigned int frame_size;
+ unsigned int reserved_size;
+
+ /*
+ * The frame size includes descriptor size, because the
+ * hardware directly receive the frame into the skbuffer.
+ */
+ frame_size = queue->data_size + queue->desc_size;
+
+ /*
+ * For the allocation we should keep a few things in mind:
+ * 1) 4byte alignment of 802.11 payload
+ *
+ * For (1) we need at most 4 bytes to guarentee the correct
+ * alignment. We are going to optimize the fact that the chance
+ * that the 802.11 header_size % 4 == 2 is much bigger then
+ * anything else. However since we need to move the frame up
+ * to 3 bytes to the front, which means we need to preallocate
+ * 6 bytes.
+ */
+ reserved_size = 6;
+
+ /*
+ * Allocate skbuffer.
+ */
+ skb = dev_alloc_skb(frame_size + reserved_size);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, reserved_size);
+ skb_put(skb, frame_size);
+
+ return skb;
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb);
+
void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 20c3ce8..6e22036 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);
/*
* RX data handlers.
*/
-static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue)
-{
- struct sk_buff *skb;
- unsigned int frame_size;
- unsigned int reserved_size;
-
- /*
- * The frame size includes descriptor size, because the
- * hardware directly receive the frame into the skbuffer.
- */
- frame_size = queue->data_size + queue->desc_size;
-
- /*
- * For the allocation we should keep a few things in mind:
- * 1) 4byte alignment of 802.11 payload
- *
- * For (1) we need at most 4 bytes to guarentee the correct
- * alignment. We are going to optimize the fact that the chance
- * that the 802.11 header_size % 4 == 2 is much bigger then
- * anything else. However since we need to move the frame up
- * to 3 bytes to the front, which means we need to preallocate
- * 6 bytes.
- */
- reserved_size = 6;
-
- /*
- * Allocate skbuffer.
- */
- skb = dev_alloc_skb(frame_size + reserved_size);
- if (!skb)
- return NULL;
-
- skb_reserve(skb, reserved_size);
- skb_put(skb, frame_size);
-
- return skb;
-}
-
static void rt2x00usb_interrupt_rxdone(struct urb *urb)
{
struct queue_entry *entry = (struct queue_entry *)urb->context;
@@ -305,8 +267,6 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
struct sk_buff *skb;
struct skb_frame_desc *skbdesc;
struct rxdone_entry_desc rxdesc;
- unsigned int header_size;
- unsigned int align;
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
@@ -330,26 +290,9 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
memset(&rxdesc, 0, sizeof(rxdesc));
rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
- header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
-
/*
- * The data behind the ieee80211 header must be
- * aligned on a 4 byte boundary. We already reserved
- * 2 bytes for header_size % 4 == 2 optimization.
- * To determine the number of bytes which the data
- * should be moved to the left, we must add these
- * 2 bytes to the header_size.
+ * Trim the skb to the correct size.
*/
- align = (header_size + 2) % 4;
-
- if (align) {
- skb_push(entry->skb, align);
- /* Move entire frame in 1 command */
- memmove(entry->skb->data, entry->skb->data + align,
- rxdesc.size);
- }
-
- /* Update data pointers, trim buffer to correct size */
skb_trim(entry->skb, rxdesc.size);
/*
@@ -357,7 +300,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
* If allocation fails, we should drop the current frame
* so we can recycle the existing sk buffer for the new frame.
*/
- skb = rt2x00usb_alloc_rxskb(entry->queue);
+ skb = rt2x00queue_alloc_rxskb(entry->queue);
if (!skb)
goto skip_entry;
@@ -532,7 +475,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
*/
entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size;
for (i = 0; i < rt2x00dev->rx->limit; i++) {
- skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx);
+ skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx);
if (!skb)
goto exit;
--
1.5.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 06/10] rt2x00: Fix double usage of skb->cb in USB RX path.
2008-06-08 21:45 ` [PATCH 05/10] rt2x00: Centralize RX packet alignment handling in rt2x00lib Ivo van Doorn
@ 2008-06-08 21:45 ` Ivo van Doorn
2008-06-08 21:45 ` [PATCH 07/10] rt2x00: Use __builtin_choose_expr() instead of ?: Ivo van Doorn
0 siblings, 1 reply; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:45 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
From: Gertjan van Wingerde <gwingerde@kpnplanet.nl>
It is not safe to use the skb->cb area for both the rxd and skb_frame_desc data at the
same time, while they occupy an overlapping piece of memory. This can lead to hard to
trace crashes as pointers within skb_frame_desc are pointing into nowhere, or the rxd
data is overwritten with non-sense.
Fix it by copying the rxd to a small buffer on the stack.
Signed-off-by: Gertjan van Wingerde <gwingerde@kpnplanet.nl>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2500usb.c | 10 +++-------
drivers/net/wireless/rt2x00/rt2x00usb.c | 8 +++-----
drivers/net/wireless/rt2x00/rt73usb.c | 10 +++-------
3 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 1bfb68a..9851cef 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1156,14 +1156,10 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
u32 word1;
/*
- * Copy descriptor to the skb->cb array, this has 2 benefits:
- * 1) Each descriptor word is 4 byte aligned.
- * 2) Descriptor is safe from moving of frame data in rt2x00usb.
+ * Copy descriptor to the skbdesc->desc buffer, making it safe from moving of
+ * frame data in rt2x00usb.
*/
- skbdesc->desc_len =
- min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb));
- memcpy(entry->skb->cb, rxd, skbdesc->desc_len);
- skbdesc->desc = entry->skb->cb;
+ memcpy(skbdesc->desc, rxd, skbdesc->desc_len);
rxd = (__le32 *)skbdesc->desc;
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 6e22036..3080969 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -267,6 +267,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
struct sk_buff *skb;
struct skb_frame_desc *skbdesc;
struct rxdone_entry_desc rxdesc;
+ u8 rxd[32];
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
@@ -286,16 +287,13 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
skbdesc = get_skb_frame_desc(entry->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->entry = entry;
+ skbdesc->desc = rxd;
+ skbdesc->desc_len = entry->queue->desc_size;
memset(&rxdesc, 0, sizeof(rxdesc));
rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
/*
- * Trim the skb to the correct size.
- */
- skb_trim(entry->skb, rxdesc.size);
-
- /*
* Allocate a new sk buffer to replace the current one.
* If allocation fails, we should drop the current frame
* so we can recycle the existing sk buffer for the new frame.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 800a1e2..505a9f5 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1428,14 +1428,10 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
u32 word1;
/*
- * Copy descriptor to the skb->cb array, this has 2 benefits:
- * 1) Each descriptor word is 4 byte aligned.
- * 2) Descriptor is safe from moving of frame data in rt2x00usb.
+ * Copy descriptor to the skbdesc->desc buffer, making it safe from moving of
+ * frame data in rt2x00usb.
*/
- skbdesc->desc_len =
- min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb));
- memcpy(entry->skb->cb, rxd, skbdesc->desc_len);
- skbdesc->desc = entry->skb->cb;
+ memcpy(skbdesc->desc, rxd, skbdesc->desc_len);
rxd = (__le32 *)skbdesc->desc;
/*
--
1.5.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 07/10] rt2x00: Use __builtin_choose_expr() instead of ?:
2008-06-08 21:45 ` [PATCH 06/10] rt2x00: Fix double usage of skb->cb in USB RX path Ivo van Doorn
@ 2008-06-08 21:45 ` Ivo van Doorn
2008-06-08 21:46 ` [PATCH 08/10] rt2x00: Clear IEEE80211_TX_CTL_USE_RTS_CTS flag for RTS frame Ivo van Doorn
0 siblings, 1 reply; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:45 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
To really force the FIELD macros to determine
the first bit of the register field we should
use the __builtin_choose_expr() function.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00reg.h | 22 +++++++++++++---------
1 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index c3f1202..7e88ce5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -145,23 +145,27 @@ struct rt2x00_field32 {
* compile-time rather then run-time.
*/
#define compile_ffs2(__x) \
- ( ((__x) & 0x1) ? 0 : 1 )
+ __builtin_choose_expr(((__x) & 0x1), 0, 1)
#define compile_ffs4(__x) \
- ( ((__x) & 0x3) ? \
- compile_ffs2(__x) : (compile_ffs2((__x) >> 2) + 2) )
+ __builtin_choose_expr(((__x) & 0x3), \
+ (compile_ffs2((__x))), \
+ (compile_ffs2((__x) >> 2) + 2))
#define compile_ffs8(__x) \
- ( ((__x) & 0xf) ? \
- compile_ffs4(__x) : (compile_ffs4((__x) >> 4) + 4) )
+ __builtin_choose_expr(((__x) & 0xf), \
+ (compile_ffs4((__x))), \
+ (compile_ffs4((__x) >> 4) + 4))
#define compile_ffs16(__x) \
- ( ((__x) & 0xff) ? \
- compile_ffs8(__x) : (compile_ffs8((__x) >> 8) + 8) )
+ __builtin_choose_expr(((__x) & 0xff), \
+ (compile_ffs8((__x))), \
+ (compile_ffs8((__x) >> 8) + 8))
#define compile_ffs32(__x) \
- ( ((__x) & 0xffff) ? \
- compile_ffs16(__x) : (compile_ffs16((__x) >> 16) + 16) )
+ __builtin_choose_expr(((__x) & 0xffff), \
+ (compile_ffs16((__x))), \
+ (compile_ffs16((__x) >> 16) + 16))
/*
* This macro will check the requirements for the FIELD{8,16,32} macros
--
1.5.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 08/10] rt2x00: Clear IEEE80211_TX_CTL_USE_RTS_CTS flag for RTS frame
2008-06-08 21:45 ` [PATCH 07/10] rt2x00: Use __builtin_choose_expr() instead of ?: Ivo van Doorn
@ 2008-06-08 21:46 ` Ivo van Doorn
2008-06-08 21:46 ` [PATCH 09/10] rt2x00: Remove unused defines Ivo van Doorn
0 siblings, 1 reply; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:46 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
>From 2106feb725364f592646a5b1790fcb9e25238601 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Sat, 7 Jun 2008 12:29:05 +0200
Subject: [PATCH] rt2x00: Clear IEEE80211_TX_CTL_USE_RTS_CTS flag for RTS frame
For RTS/CTS-to-self frames the IEEE80211_TX_CTL_USE_RTS_CTS flag
should be cleared for the tx_info flags.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00mac.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 59f273b..c90992f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -64,6 +64,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
rts_info = IEEE80211_SKB_CB(skb);
rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
+ rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS;
rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;
rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
--
1.5.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 09/10] rt2x00: Remove unused defines
2008-06-08 21:46 ` [PATCH 08/10] rt2x00: Clear IEEE80211_TX_CTL_USE_RTS_CTS flag for RTS frame Ivo van Doorn
@ 2008-06-08 21:46 ` Ivo van Doorn
2008-06-08 21:46 ` [PATCH 10/10] rt2x00: Rework alignment check Ivo van Doorn
0 siblings, 1 reply; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:46 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
MAX_RX_SSI and MAX_NOISE are no longer used,
it is better to remove them entirely.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.h | 2 --
drivers/net/wireless/rt2x00/rt2500pci.h | 2 --
drivers/net/wireless/rt2x00/rt2500usb.h | 2 --
drivers/net/wireless/rt2x00/rt61pci.h | 2 --
drivers/net/wireless/rt2x00/rt73usb.h | 2 --
5 files changed, 0 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index e9aa326..bc55642 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -37,8 +37,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
-#define MAX_SIGNAL 100
-#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 100
/*
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index ea93b8f..cb648c3 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -48,8 +48,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
-#define MAX_SIGNAL 100
-#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 121
/*
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 7d50098..3e21fdf 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -48,8 +48,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
-#define MAX_SIGNAL 100
-#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 120
/*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index c5a04b9..1004d5b 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -39,8 +39,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
-#define MAX_SIGNAL 100
-#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 120
/*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 25cdcc9..1484935 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -39,8 +39,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
-#define MAX_SIGNAL 100
-#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 120
/*
--
1.5.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 10/10] rt2x00: Rework alignment check.
2008-06-08 21:46 ` [PATCH 09/10] rt2x00: Remove unused defines Ivo van Doorn
@ 2008-06-08 21:46 ` Ivo van Doorn
0 siblings, 0 replies; 11+ messages in thread
From: Ivo van Doorn @ 2008-06-08 21:46 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
From: Gertjan van Wingerde <gwingerde@kpnplanet.nl>
Rework the alignment check in rt2x00dev.c to be independent of any potential
alignment measures that may be taken before. Just check whether the payload is
aligned based on the pointer addresses.
Note: This is preparatory for the dynamically mapped skb buffers for the PCI
drivers, as these need 4-byte alignment instead of the currently enforced offset
by 2 bytes.
Signed-off-by: Gertjan van Wingerde <gwingerde@kpnplanet.nl>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00dev.c | 8 ++------
1 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index ce1f7bb..9ea6773 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -565,13 +565,9 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
/*
* The data behind the ieee80211 header must be
- * aligned on a 4 byte boundary. We already reserved
- * 2 bytes for header_size % 4 == 2 optimization.
- * To determine the number of bytes which the data
- * should be moved to the left, we must add these
- * 2 bytes to the header_size.
+ * aligned on a 4 byte boundary.
*/
- align = (header_size + 2) % 4;
+ align = ((unsigned long)(entry->skb->data + header_size)) & 3;
if (align) {
skb_push(entry->skb, align);
--
1.5.5.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-06-08 21:37 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-08 21:41 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
2008-06-08 21:42 ` [PATCH 01/10] rt2x00: Implement rt2x00usb_kick_tx_queue() Ivo van Doorn
2008-06-08 21:43 ` [PATCH 02/10] rt2x00: Move generic TX frame writing code into rt2x00queue Ivo van Doorn
2008-06-08 21:43 ` [PATCH 03/10] rt2x00: Don't kick TX queue after each frame Ivo van Doorn
2008-06-08 21:44 ` [PATCH 04/10] rt2x00: Cleanup struct skb_frame_desc Ivo van Doorn
2008-06-08 21:45 ` [PATCH 05/10] rt2x00: Centralize RX packet alignment handling in rt2x00lib Ivo van Doorn
2008-06-08 21:45 ` [PATCH 06/10] rt2x00: Fix double usage of skb->cb in USB RX path Ivo van Doorn
2008-06-08 21:45 ` [PATCH 07/10] rt2x00: Use __builtin_choose_expr() instead of ?: Ivo van Doorn
2008-06-08 21:46 ` [PATCH 08/10] rt2x00: Clear IEEE80211_TX_CTL_USE_RTS_CTS flag for RTS frame Ivo van Doorn
2008-06-08 21:46 ` [PATCH 09/10] rt2x00: Remove unused defines Ivo van Doorn
2008-06-08 21:46 ` [PATCH 10/10] rt2x00: Rework alignment check Ivo van Doorn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).