* [PATCH 6/9] rt2x00: Push beacon TX descriptor writing to drivers.
From: Gertjan van Wingerde @ 2010-05-11 21:51 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273614705-25118-1-git-send-email-gwingerde@gmail.com>
Not all the devices require a TX descriptor to be written (i.e. rt2800
device don't require them). Push down the creation of the TX descriptor
to the device drivers so that they can decide for themselves whether
a TX descriptor is to be created.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 16 ++++++++++------
drivers/net/wireless/rt2x00/rt2500pci.c | 16 ++++++++++------
drivers/net/wireless/rt2x00/rt2500usb.c | 11 +++++++++++
drivers/net/wireless/rt2x00/rt2800pci.c | 17 +++++++++++++++++
drivers/net/wireless/rt2x00/rt2800usb.c | 17 +++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00debug.c | 1 +
drivers/net/wireless/rt2x00/rt2x00queue.c | 10 +---------
drivers/net/wireless/rt2x00/rt61pci.c | 11 +++++++++++
drivers/net/wireless/rt2x00/rt73usb.c | 11 +++++++++++
9 files changed, 89 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index def3fa4..741c531 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -33,6 +33,7 @@
#include <linux/eeprom_93cx6.h>
#include "rt2x00.h"
+#include "rt2x00lib.h"
#include "rt2x00pci.h"
#include "rt2400pci.h"
@@ -1074,9 +1075,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct queue_entry_priv_pci *entry_priv = entry->priv_data;
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
- u32 word;
u32 reg;
/*
@@ -1089,9 +1087,15 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
rt2x00queue_map_txskb(rt2x00dev, entry->skb);
- rt2x00_desc_read(entry_priv->desc, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
- rt2x00_desc_write(entry_priv->desc, 1, word);
+ /*
+ * Write the TX descriptor for the beacon.
+ */
+ rt2400pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
* Enable beaconing again.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 070c23e..4dc101e 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -33,6 +33,7 @@
#include <linux/eeprom_93cx6.h>
#include "rt2x00.h"
+#include "rt2x00lib.h"
#include "rt2x00pci.h"
#include "rt2500pci.h"
@@ -1231,9 +1232,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct queue_entry_priv_pci *entry_priv = entry->priv_data;
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
- u32 word;
u32 reg;
/*
@@ -1246,9 +1244,15 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
rt2x00queue_map_txskb(rt2x00dev, entry->skb);
- rt2x00_desc_read(entry_priv->desc, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
- rt2x00_desc_write(entry_priv->desc, 1, word);
+ /*
+ * Write the TX descriptor for the beacon.
+ */
+ rt2500pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
* Enable beaconing again.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index b985d8f..4911d1a 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -32,6 +32,7 @@
#include <linux/usb.h>
#include "rt2x00.h"
+#include "rt2x00lib.h"
#include "rt2x00usb.h"
#include "rt2500usb.h"
@@ -1107,6 +1108,16 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
/*
+ * Write the TX descriptor for the beacon.
+ */
+ rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
+
+ /*
* Take the descriptor in front of the skb into account.
*/
skb_push(entry->skb, TXD_DESC_SIZE);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index b2f2327..fcca30c 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -42,6 +42,7 @@
#include <linux/eeprom_93cx6.h>
#include "rt2x00.h"
+#include "rt2x00lib.h"
#include "rt2x00pci.h"
#include "rt2x00soc.h"
#include "rt2800lib.h"
@@ -688,6 +689,7 @@ static void rt2800pci_write_beacon(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);
unsigned int beacon_base;
u32 reg;
@@ -700,9 +702,24 @@ static void rt2800pci_write_beacon(struct queue_entry *entry,
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
/*
+ * Register descriptor details in skb frame descriptor.
+ */
+ skbdesc->desc = entry->skb->data - TXWI_DESC_SIZE;
+ skbdesc->desc_len = TXWI_DESC_SIZE;
+
+ /*
* Add the TXWI for the beacon to the skb.
*/
rt2800_write_txwi(entry->skb, txdesc);
+
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
+
+ /*
+ * Adjust skb to take TXWI into account.
+ */
skb_push(entry->skb, TXWI_DESC_SIZE);
/*
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 1b87daa..9a29f73 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -37,6 +37,7 @@
#include <linux/usb.h>
#include "rt2x00.h"
+#include "rt2x00lib.h"
#include "rt2x00usb.h"
#include "rt2800lib.h"
#include "rt2800.h"
@@ -437,6 +438,7 @@ static void rt2800usb_write_beacon(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);
unsigned int beacon_base;
u32 reg;
@@ -449,9 +451,24 @@ static void rt2800usb_write_beacon(struct queue_entry *entry,
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
/*
+ * Register descriptor details in skb frame descriptor.
+ */
+ skbdesc->desc = entry->skb->data - TXWI_DESC_SIZE;
+ skbdesc->desc_len = TXWI_DESC_SIZE;
+
+ /*
* Add the TXWI for the beacon to the skb.
*/
rt2800_write_txwi(entry->skb, txdesc);
+
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
+
+ /*
+ * Adjust skb to take TXWI into account.
+ */
skb_push(entry->skb, TXWI_DESC_SIZE);
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 9e2eed5..85e9990 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -204,6 +204,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
skb_queue_purge(&intf->frame_dump_skbqueue);
}
+EXPORT_SYMBOL_GPL(rt2x00debug_dump_frame);
static int rt2x00debug_file_open(struct inode *inode, struct file *file)
{
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index e5969a5..9e48bbc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -420,7 +420,6 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
{
struct data_queue *queue = entry->queue;
struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- enum rt2x00_dump_type;
rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc);
@@ -428,9 +427,7 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
* All processing on the frame has been completed, this means
* it is now ready to be dumped to userspace through debugfs.
*/
- dump_type = (txdesc->queue == QID_BEACON) ?
- DUMP_FRAME_BEACON : DUMP_FRAME_TX;
- rt2x00debug_dump_frame(rt2x00dev, dump_type, entry->skb);
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb);
}
static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
@@ -594,11 +591,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
skbdesc->entry = intf->beacon;
/*
- * Write TX descriptor into reserved room in front of the beacon.
- */
- rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
-
- /*
* Send beacon to hardware and enable beacon genaration..
*/
rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 1be1d7d..cf9d507 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -34,6 +34,7 @@
#include <linux/eeprom_93cx6.h>
#include "rt2x00.h"
+#include "rt2x00lib.h"
#include "rt2x00pci.h"
#include "rt61pci.h"
@@ -1872,6 +1873,16 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
/*
+ * Write the TX descriptor for the beacon.
+ */
+ rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
+
+ /*
* Write entire beacon with descriptor to register.
*/
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index fca661c..085f76e 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -33,6 +33,7 @@
#include <linux/usb.h>
#include "rt2x00.h"
+#include "rt2x00lib.h"
#include "rt2x00usb.h"
#include "rt73usb.h"
@@ -1526,6 +1527,16 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
/*
+ * Write the TX descriptor for the beacon.
+ */
+ rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc);
+
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
+
+ /*
* Take the descriptor in front of the skb into account.
*/
skb_push(entry->skb, TXD_DESC_SIZE);
--
1.7.1
^ permalink raw reply related
* [PATCH 4/9] rt2x00: Simplify TXD handling of beacons.
From: Gertjan van Wingerde @ 2010-05-11 21:51 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273614705-25118-1-git-send-email-gwingerde@gmail.com>
The handling of tx descriptors for beacons can be simplified by updating
write_tx_desc implementations of each driver to write directly to the
queue entry descriptor instead of to a provided memory area.
This is also a preparation for further clean ups where descriptors are
properly reserved in the skb instead of fiddling with the skb data
pointer.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 21 +++++++++------------
drivers/net/wireless/rt2x00/rt2500pci.c | 21 +++++++++------------
drivers/net/wireless/rt2x00/rt2500usb.c | 21 ++++++++++++---------
drivers/net/wireless/rt2x00/rt2800pci.c | 14 ++++++++++----
drivers/net/wireless/rt2x00/rt2800usb.c | 8 +++++++-
drivers/net/wireless/rt2x00/rt2x00pci.c | 9 ---------
drivers/net/wireless/rt2x00/rt2x00queue.c | 10 ----------
drivers/net/wireless/rt2x00/rt2x00usb.c | 8 --------
drivers/net/wireless/rt2x00/rt61pci.c | 20 +++++++++++++-------
drivers/net/wireless/rt2x00/rt73usb.c | 21 ++++++++++++---------
10 files changed, 72 insertions(+), 81 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 1eff6ec..def3fa4 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1006,15 +1006,15 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
- __le32 *txd = skbdesc->desc;
+ __le32 *txd = entry_priv->desc;
u32 word;
/*
* Start writing the descriptor words.
*/
- rt2x00_desc_read(entry_priv->desc, 1, &word);
+ rt2x00_desc_read(txd, 1, &word);
rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
- rt2x00_desc_write(entry_priv->desc, 1, word);
+ rt2x00_desc_write(txd, 1, word);
rt2x00_desc_read(txd, 2, &word);
rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, txdesc->length);
@@ -1059,6 +1059,12 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
rt2x00_desc_write(txd, 0, word);
+
+ /*
+ * Register descriptor details in skb frame descriptor.
+ */
+ skbdesc->desc = txd;
+ skbdesc->desc_len = TXD_DESC_SIZE;
}
/*
@@ -1081,15 +1087,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
- /*
- * Replace rt2x00lib allocated descriptor with the
- * pointer to the _real_ hardware descriptor.
- * After that, map the beacon to DMA and update the
- * descriptor.
- */
- memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len);
- skbdesc->desc = entry_priv->desc;
-
rt2x00queue_map_txskb(rt2x00dev, entry->skb);
rt2x00_desc_read(entry_priv->desc, 1, &word);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 8d3e95e..070c23e 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1164,15 +1164,15 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
- __le32 *txd = skbdesc->desc;
+ __le32 *txd = entry_priv->desc;
u32 word;
/*
* Start writing the descriptor words.
*/
- rt2x00_desc_read(entry_priv->desc, 1, &word);
+ rt2x00_desc_read(txd, 1, &word);
rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
- rt2x00_desc_write(entry_priv->desc, 1, word);
+ rt2x00_desc_write(txd, 1, word);
rt2x00_desc_read(txd, 2, &word);
rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER);
@@ -1216,6 +1216,12 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length);
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
rt2x00_desc_write(txd, 0, word);
+
+ /*
+ * Register descriptor details in skb frame descriptor.
+ */
+ skbdesc->desc = txd;
+ skbdesc->desc_len = TXD_DESC_SIZE;
}
/*
@@ -1238,15 +1244,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
- /*
- * Replace rt2x00lib allocated descriptor with the
- * pointer to the _real_ hardware descriptor.
- * After that, map the beacon to DMA and update the
- * descriptor.
- */
- memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len);
- skbdesc->desc = entry_priv->desc;
-
rt2x00queue_map_txskb(rt2x00dev, entry->skb);
rt2x00_desc_read(entry_priv->desc, 1, &word);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 9a915be..b985d8f 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1033,7 +1033,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txd = skbdesc->desc;
+ __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE);
u32 word;
/*
@@ -1075,6 +1075,12 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
_rt2x00_desc_write(txd, 3, skbdesc->iv[0]);
_rt2x00_desc_write(txd, 4, skbdesc->iv[1]);
}
+
+ /*
+ * Register descriptor details in skb frame descriptor.
+ */
+ skbdesc->desc = txd;
+ skbdesc->desc_len = TXD_DESC_SIZE;
}
/*
@@ -1088,19 +1094,11 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
int pipe = usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint);
int length;
u16 reg, reg0;
/*
- * Add the descriptor in front of the skb.
- */
- skb_push(entry->skb, entry->queue->desc_size);
- memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
- skbdesc->desc = entry->skb->data;
-
- /*
* Disable beaconing while we are reloading the beacon data,
* otherwise we might be sending out invalid data.
*/
@@ -1109,6 +1107,11 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
/*
+ * Take the descriptor in front of the skb into account.
+ */
+ skb_push(entry->skb, TXD_DESC_SIZE);
+
+ /*
* 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.
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 7d4778d..b2f2327 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -633,7 +633,8 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txd = skbdesc->desc;
+ struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
+ __le32 *txd = entry_priv->desc;
u32 word;
/*
@@ -657,15 +658,14 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
!test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W1_BURST,
test_bit(ENTRY_TXD_BURST, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W1_SD_LEN0,
- rt2x00dev->ops->extra_tx_headroom);
+ rt2x00_set_field32(&word, TXD_W1_SD_LEN0, TXWI_DESC_SIZE);
rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0);
rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0);
rt2x00_desc_write(txd, 1, word);
rt2x00_desc_read(txd, 2, &word);
rt2x00_set_field32(&word, TXD_W2_SD_PTR1,
- skbdesc->skb_dma + rt2x00dev->ops->extra_tx_headroom);
+ skbdesc->skb_dma + TXWI_DESC_SIZE);
rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 3, &word);
@@ -673,6 +673,12 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W3_QSEL, 2);
rt2x00_desc_write(txd, 3, word);
+
+ /*
+ * Register descriptor details in skb frame descriptor.
+ */
+ skbdesc->desc = txd;
+ skbdesc->desc_len = TXD_DESC_SIZE;
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index d48d705..1b87daa 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -400,7 +400,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txi = skbdesc->desc;
+ __le32 *txi = (__le32 *)(skb->data - TXWI_DESC_SIZE - TXINFO_DESC_SIZE);
u32 word;
/*
@@ -422,6 +422,12 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_BURST,
test_bit(ENTRY_TXD_BURST, &txdesc->flags));
rt2x00_desc_write(txi, 0, word);
+
+ /*
+ * Register descriptor details in skb frame descriptor.
+ */
+ skbdesc->desc = txi;
+ skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 2fe9f29..ff80ef7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -66,8 +66,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct queue_entry_priv_pci *entry_priv = entry->priv_data;
- struct skb_frame_desc *skbdesc;
/*
* This should not happen, we already checked the entry
@@ -82,13 +80,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry,
return -EINVAL;
}
- /*
- * Fill in skb descriptor
- */
- skbdesc = get_skb_frame_desc(entry->skb);
- skbdesc->desc = entry_priv->desc;
- skbdesc->desc_len = entry->queue->desc_size;
-
return 0;
}
EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 97b2c76..891d5f7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -552,7 +552,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf = vif_to_intf(vif);
struct skb_frame_desc *skbdesc;
struct txentry_desc txdesc;
- __le32 desc[16];
if (unlikely(!intf->beacon))
return -ENOBUFS;
@@ -585,19 +584,10 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
/*
- * For the descriptor we use a local array from where the
- * driver can move it to the correct location required for
- * the hardware.
- */
- memset(desc, 0, sizeof(desc));
-
- /*
* Fill in skb descriptor
*/
skbdesc = get_skb_frame_desc(intf->beacon->skb);
memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->desc = desc;
- skbdesc->desc_len = intf->beacon->queue->desc_size;
skbdesc->entry = intf->beacon;
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index acf3282..a4f0551 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -221,7 +221,6 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry,
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
- struct skb_frame_desc *skbdesc;
u32 length;
/*
@@ -231,13 +230,6 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry,
memset(entry->skb->data, 0, entry->queue->desc_size);
/*
- * Fill in skb descriptor
- */
- skbdesc = get_skb_frame_desc(entry->skb);
- skbdesc->desc = entry->skb->data;
- skbdesc->desc_len = entry->queue->desc_size;
-
- /*
* 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.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 55aa010..1be1d7d 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1763,7 +1763,8 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txd = skbdesc->desc;
+ struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
+ __le32 *txd = entry_priv->desc;
u32 word;
/*
@@ -1842,6 +1843,13 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
test_bit(ENTRY_TXD_BURST, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher);
rt2x00_desc_write(txd, 0, word);
+
+ /*
+ * Register descriptor details in skb frame descriptor.
+ */
+ skbdesc->desc = txd;
+ skbdesc->desc_len =
+ (txdesc->queue == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE;
}
/*
@@ -1851,7 +1859,7 @@ static void rt61pci_write_beacon(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 queue_entry_priv_pci *entry_priv = entry->priv_data;
unsigned int beacon_base;
u32 reg;
@@ -1867,11 +1875,9 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
* Write entire beacon with descriptor to register.
*/
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
- rt2x00pci_register_multiwrite(rt2x00dev,
- beacon_base,
- skbdesc->desc, skbdesc->desc_len);
- rt2x00pci_register_multiwrite(rt2x00dev,
- beacon_base + skbdesc->desc_len,
+ rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
+ entry_priv->desc, TXINFO_SIZE);
+ rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE,
entry->skb->data, entry->skb->len);
/*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index fa40d43..fca661c 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1440,7 +1440,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txd = skbdesc->desc;
+ __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE);
u32 word;
/*
@@ -1499,6 +1499,12 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
TXPOWER_TO_DEV(rt2x00dev->tx_power));
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word);
+
+ /*
+ * Register descriptor details in skb frame descriptor.
+ */
+ skbdesc->desc = txd;
+ skbdesc->desc_len = TXD_DESC_SIZE;
}
/*
@@ -1508,18 +1514,10 @@ static void rt73usb_write_beacon(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);
unsigned int beacon_base;
u32 reg;
/*
- * Add the descriptor in front of the skb.
- */
- skb_push(entry->skb, entry->queue->desc_size);
- memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
- skbdesc->desc = entry->skb->data;
-
- /*
* Disable beaconing while we are reloading the beacon data,
* otherwise we might be sending out invalid data.
*/
@@ -1528,6 +1526,11 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
/*
+ * Take the descriptor in front of the skb into account.
+ */
+ skb_push(entry->skb, TXD_DESC_SIZE);
+
+ /*
* Write entire beacon with descriptor to register.
*/
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
--
1.7.1
^ permalink raw reply related
* [PATCH 9/9] rt2x00: Properly reserve room for descriptors in skbs.
From: Gertjan van Wingerde @ 2010-05-11 21:51 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273614705-25118-1-git-send-email-gwingerde@gmail.com>
Instead of fiddling with the skb->data pointer and thereby risking
out of bounds accesses, properly reserve the space needed in an
skb for descriptors.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 2 +-
drivers/net/wireless/rt2x00/rt2500pci.c | 2 +-
drivers/net/wireless/rt2x00/rt2500usb.c | 14 ++++++----
drivers/net/wireless/rt2x00/rt2800lib.c | 3 +-
drivers/net/wireless/rt2x00/rt2800lib.h | 2 +-
drivers/net/wireless/rt2x00/rt2800pci.c | 23 ++++++++--------
drivers/net/wireless/rt2x00/rt2800usb.c | 22 +++++++++------
drivers/net/wireless/rt2x00/rt2x00.h | 7 +++++
drivers/net/wireless/rt2x00/rt2x00dev.c | 5 ---
drivers/net/wireless/rt2x00/rt2x00lib.h | 7 -----
drivers/net/wireless/rt2x00/rt2x00pci.c | 40 +++++++++++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00pci.h | 8 ++++++
drivers/net/wireless/rt2x00/rt2x00queue.c | 24 +----------------
drivers/net/wireless/rt2x00/rt2x00usb.c | 11 +++----
drivers/net/wireless/rt2x00/rt61pci.c | 4 +-
drivers/net/wireless/rt2x00/rt73usb.c | 14 ++++++----
16 files changed, 109 insertions(+), 79 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 741c531..38ee78b 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1228,7 +1228,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
}
txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
- rt2x00lib_txdone(entry, &txdesc);
+ rt2x00pci_txdone(entry, &txdesc);
}
}
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 4dc101e..cc7091c 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1364,7 +1364,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
}
txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
- rt2x00lib_txdone(entry, &txdesc);
+ rt2x00pci_txdone(entry, &txdesc);
}
}
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 4911d1a..b6ccb57 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1034,7 +1034,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE);
+ __le32 *txd = (__le32 *) skb->data;
u32 word;
/*
@@ -1080,6 +1080,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* Register descriptor details in skb frame descriptor.
*/
+ skbdesc->flags |= SKBDESC_DESC_IN_SKB;
skbdesc->desc = txd;
skbdesc->desc_len = TXD_DESC_SIZE;
}
@@ -1108,6 +1109,12 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
/*
+ * Add space for the descriptor in front of the skb.
+ */
+ skb_push(entry->skb, TXD_DESC_SIZE);
+ memset(entry->skb->data, 0, TXD_DESC_SIZE);
+
+ /*
* Write the TX descriptor for the beacon.
*/
rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc);
@@ -1118,11 +1125,6 @@ static void rt2500usb_write_beacon(struct queue_entry *entry,
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
- * Take the descriptor in front of the skb into account.
- */
- skb_push(entry->skb, TXD_DESC_SIZE);
-
- /*
* 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.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 7410ac1..53a3257 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -281,9 +281,8 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
}
EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready);
-void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc)
+void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc)
{
- __le32 *txwi = (__le32 *)(skb->data - TXWI_DESC_SIZE);
u32 word;
/*
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 94de999..0f0a13c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -111,7 +111,7 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
const u8 command, const u8 token,
const u8 arg0, const u8 arg1);
-void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc);
+void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc);
void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc);
extern const struct rt2x00debug rt2800_rt2x00debug;
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index bbd6481..86f7042 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -617,7 +617,7 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
static void rt2800pci_add_tx_datadesc(struct queue_entry* entry,
struct txentry_desc *txdesc)
{
- rt2800_write_txwi(entry->skb, txdesc);
+ rt2800_write_txwi((__le32 *) entry->skb->data, txdesc);
}
@@ -694,15 +694,22 @@ static void rt2800pci_write_beacon(struct queue_entry *entry,
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
/*
+ * Add space for the TXWI in front of the skb.
+ */
+ skb_push(entry->skb, TXWI_DESC_SIZE);
+ memset(entry->skb, 0, TXWI_DESC_SIZE);
+
+ /*
* Register descriptor details in skb frame descriptor.
*/
- skbdesc->desc = entry->skb->data - TXWI_DESC_SIZE;
+ skbdesc->flags |= SKBDESC_DESC_IN_SKB;
+ skbdesc->desc = entry->skb->data;
skbdesc->desc_len = TXWI_DESC_SIZE;
/*
* Add the TXWI for the beacon to the skb.
*/
- rt2800_write_txwi(entry->skb, txdesc);
+ rt2800_write_txwi((__le32 *)entry->skb->data, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -710,11 +717,6 @@ static void rt2800pci_write_beacon(struct queue_entry *entry,
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
- * Adjust skb to take TXWI into account.
- */
- skb_push(entry->skb, TXWI_DESC_SIZE);
-
- /*
* Write entire beacon with TXWI to register.
*/
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
@@ -889,8 +891,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
/* Check if we got a match by looking at WCID/ACK/PID
* fields */
- txwi = (__le32 *)(entry->skb->data -
- rt2x00dev->ops->extra_tx_headroom);
+ txwi = (__le32 *) entry->skb->data;
rt2x00_desc_read(txwi, 1, &word);
tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
@@ -935,7 +936,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
__set_bit(TXDONE_FALLBACK, &txdesc.flags);
- rt2x00lib_txdone(entry, &txdesc);
+ rt2x00pci_txdone(entry, &txdesc);
}
}
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 9a29f73..a8e6e71 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -401,13 +401,14 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txi = (__le32 *)(skb->data - TXWI_DESC_SIZE - TXINFO_DESC_SIZE);
+ __le32 *txi = (__le32 *) skb->data;
+ __le32 *txwi = (__le32 *) (skb->data + TXINFO_DESC_SIZE);
u32 word;
/*
* Initialize TXWI descriptor
*/
- rt2800_write_txwi(skb, txdesc);
+ rt2800_write_txwi(txwi, txdesc);
/*
* Initialize TXINFO descriptor
@@ -427,6 +428,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* Register descriptor details in skb frame descriptor.
*/
+ skbdesc->flags |= SKBDESC_DESC_IN_SKB;
skbdesc->desc = txi;
skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
}
@@ -451,15 +453,22 @@ static void rt2800usb_write_beacon(struct queue_entry *entry,
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
/*
+ * Add space for the TXWI in front of the skb.
+ */
+ skb_push(entry->skb, TXWI_DESC_SIZE);
+ memset(entry->skb, 0, TXWI_DESC_SIZE);
+
+ /*
* Register descriptor details in skb frame descriptor.
*/
- skbdesc->desc = entry->skb->data - TXWI_DESC_SIZE;
+ skbdesc->flags |= SKBDESC_DESC_IN_SKB;
+ skbdesc->desc = entry->skb->data;
skbdesc->desc_len = TXWI_DESC_SIZE;
/*
* Add the TXWI for the beacon to the skb.
*/
- rt2800_write_txwi(entry->skb, txdesc);
+ rt2800_write_txwi((__le32 *) entry->skb->data, txdesc);
/*
* Dump beacon to userspace through debugfs.
@@ -467,11 +476,6 @@ static void rt2800usb_write_beacon(struct queue_entry *entry,
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
- * Adjust skb to take TXWI into account.
- */
- skb_push(entry->skb, TXWI_DESC_SIZE);
-
- /*
* Write entire beacon with descriptor to register.
*/
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 5f2531f..4cb9f87 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1001,6 +1001,13 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev)
void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
/**
+ * rt2x00queue_unmap_skb - Unmap a skb from DMA.
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @skb: The skb to unmap.
+ */
+void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+
+/**
* rt2x00queue_get_queue - Convert queue index to queue pointer
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @queue: rt2x00 queue index (see &enum data_queue_qid).
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 33c2f5f..6790441 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -210,11 +210,6 @@ void rt2x00lib_txdone(struct queue_entry *entry,
bool success;
/*
- * Unmap the skb.
- */
- rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
-
- /*
* Remove L2 padding which was added during
*/
if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index be2e37f..2bffc51 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -107,13 +107,6 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry);
/**
- * rt2x00queue_unmap_skb - Unmap a skb from DMA.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @skb: The skb to unmap.
- */
-void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
-
-/**
* rt2x00queue_free_skb - free a skb
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @skb: The skb to free.
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index cd61d6f..e474629 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -81,11 +81,23 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry,
}
/*
+ * Add the requested extra tx headroom in front of the skb.
+ */
+ skb_push(entry->skb, rt2x00dev->ops->extra_tx_headroom);
+ memset(entry->skb->data, 0, rt2x00dev->ops->extra_tx_headroom);
+
+ /*
* Call the driver's add_tx_datadesc function, if it exists.
*/
if (rt2x00dev->ops->lib->add_tx_datadesc)
rt2x00dev->ops->lib->add_tx_datadesc(entry, txdesc);
+ /*
+ * Map the skb to DMA.
+ */
+ if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
+ rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+
return 0;
}
EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data);
@@ -93,6 +105,34 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data);
/*
* TX/RX data handlers.
*/
+void rt2x00pci_txdone(struct queue_entry *entry,
+ struct txdone_entry_desc *txdesc)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+
+ /*
+ * Unmap the skb.
+ */
+ rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
+
+ /*
+ * Remove the extra tx headroom from the skb.
+ */
+ skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom);
+
+ /*
+ * Signal that the TX descriptor is no longer in the skb.
+ */
+ skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
+
+ /*
+ * Pass on to rt2x00lib.
+ */
+ rt2x00lib_txdone(entry, txdesc);
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_txdone);
+
void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue = rt2x00dev->rx;
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 51bcef3..00528b8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -109,6 +109,14 @@ struct queue_entry_priv_pci {
};
/**
+ * rt2x00pci_txdone - Handle TX done events.
+ * @entry: The queue entry for which a TX done event was received.
+ * @txdesc: The TX done descriptor for the entry.
+ */
+void rt2x00pci_txdone(struct queue_entry *entry,
+ struct txdone_entry_desc *txdesc);
+
+/**
* rt2x00pci_rxdone - Handle RX done events
* @rt2x00dev: Device pointer, see &struct rt2x00_dev.
*/
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 9e48bbc..bcdbf95 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -99,21 +99,8 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- /*
- * If device has requested headroom, we should make sure that
- * is also mapped to the DMA so it can be used for transfering
- * additional descriptor information to the hardware.
- */
- skb_push(skb, rt2x00dev->ops->extra_tx_headroom);
-
skbdesc->skb_dma =
dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
-
- /*
- * Restore data pointer to original location again.
- */
- skb_pull(skb, rt2x00dev->ops->extra_tx_headroom);
-
skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
}
EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
@@ -129,16 +116,12 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
}
if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
- /*
- * Add headroom to the skb length, it has been removed
- * by the driver, but it was actually mapped to DMA.
- */
- dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma,
- skb->len + rt2x00dev->ops->extra_tx_headroom,
+ dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
DMA_TO_DEVICE);
skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
}
}
+EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb);
void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
{
@@ -533,9 +516,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
return -EIO;
}
- if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
- rt2x00queue_map_txskb(queue->rt2x00dev, skb);
-
set_bit(ENTRY_DATA_PENDING, &entry->flags);
rt2x00queue_index_inc(queue, Q_INDEX);
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index e731389..9388e44 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -197,6 +197,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
return;
/*
+ * Remove the descriptor from the front of the skb.
+ */
+ skb_pull(entry->skb, entry->queue->desc_size);
+
+ /*
* Obtain the status about this packet.
* Note that when the status is 0 it does not mean the
* frame was send out correctly. It only means the frame
@@ -242,12 +247,6 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry,
rt2x00usb_interrupt_txdone, entry);
/*
- * Make sure the skb->data pointer points to the frame, not the
- * descriptor.
- */
- skb_pull(entry->skb, entry->queue->desc_size);
-
- /*
* Call the driver's add_tx_datadesc function, if it exists.
*/
if (rt2x00dev->ops->lib->add_tx_datadesc)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index cf9d507..5fd6481 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2109,7 +2109,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
__set_bit(TXDONE_UNKNOWN, &txdesc.flags);
txdesc.retry = 0;
- rt2x00lib_txdone(entry_done, &txdesc);
+ rt2x00pci_txdone(entry_done, &txdesc);
entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
}
@@ -2129,7 +2129,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
}
txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT);
- rt2x00lib_txdone(entry, &txdesc);
+ rt2x00pci_txdone(entry, &txdesc);
}
}
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 085f76e..10893d5 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1441,7 +1441,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE);
+ __le32 *txd = (__le32 *) skb->data;
u32 word;
/*
@@ -1504,6 +1504,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* Register descriptor details in skb frame descriptor.
*/
+ skbdesc->flags |= SKBDESC_DESC_IN_SKB;
skbdesc->desc = txd;
skbdesc->desc_len = TXD_DESC_SIZE;
}
@@ -1527,6 +1528,12 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
/*
+ * Add space for the descriptor in front of the skb.
+ */
+ skb_push(entry->skb, TXD_DESC_SIZE);
+ memset(entry->skb->data, 0, TXD_DESC_SIZE);
+
+ /*
* Write the TX descriptor for the beacon.
*/
rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc);
@@ -1537,11 +1544,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
/*
- * Take the descriptor in front of the skb into account.
- */
- skb_push(entry->skb, TXD_DESC_SIZE);
-
- /*
* Write entire beacon with descriptor to register.
*/
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
--
1.7.1
^ permalink raw reply related
* [PATCH 3/9] rt2x00: Re-order tx descriptor writing code in drivers.
From: Gertjan van Wingerde @ 2010-05-11 21:51 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273614705-25118-1-git-send-email-gwingerde@gmail.com>
Where possible, write the tx descriptor words from start to end, to
follow a logical ordering of words.
Where this is not possible (in rt2400pci, rt2500pci and rt61pci) add
a comment as to why word 0 needs to be written last.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 5 +++
drivers/net/wireless/rt2x00/rt2500pci.c | 5 +++
drivers/net/wireless/rt2x00/rt2500usb.c | 36 +++++++++++-----------
drivers/net/wireless/rt2x00/rt61pci.c | 5 +++
drivers/net/wireless/rt2x00/rt73usb.c | 52 +++++++++++++++---------------
5 files changed, 59 insertions(+), 44 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 4b38451..1eff6ec 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1039,6 +1039,11 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1);
rt2x00_desc_write(txd, 4, word);
+ /*
+ * Writing TXD word 0 must the last to prevent a race condition with
+ * the device, whereby the device may take hold of the TXD before we
+ * finished updating it.
+ */
rt2x00_desc_read(txd, 0, &word);
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
rt2x00_set_field32(&word, TXD_W0_VALID, 1);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index d876c6d..8d3e95e 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1193,6 +1193,11 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags));
rt2x00_desc_write(txd, 10, word);
+ /*
+ * Writing TXD word 0 must the last to prevent a race condition with
+ * the device, whereby the device may take hold of the TXD before we
+ * finished updating it.
+ */
rt2x00_desc_read(txd, 0, &word);
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
rt2x00_set_field32(&word, TXD_W0_VALID, 1);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 30c0544..9a915be 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1039,6 +1039,24 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* Start writing the descriptor words.
*/
+ rt2x00_desc_read(txd, 0, &word);
+ rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit);
+ rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
+ test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_ACK,
+ test_bit(ENTRY_TXD_ACK, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
+ test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_OFDM,
+ (txdesc->rate_mode == RATE_MODE_OFDM));
+ 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, txdesc->length);
+ rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher);
+ rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx);
+ rt2x00_desc_write(txd, 0, word);
+
rt2x00_desc_read(txd, 1, &word);
rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset);
rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs);
@@ -1057,24 +1075,6 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
_rt2x00_desc_write(txd, 3, skbdesc->iv[0]);
_rt2x00_desc_write(txd, 4, skbdesc->iv[1]);
}
-
- rt2x00_desc_read(txd, 0, &word);
- rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit);
- rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
- test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_ACK,
- test_bit(ENTRY_TXD_ACK, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
- test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_OFDM,
- (txdesc->rate_mode == RATE_MODE_OFDM));
- 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, txdesc->length);
- rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher);
- rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx);
- rt2x00_desc_write(txd, 0, word);
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 99c2981..55aa010 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1813,6 +1813,11 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(txd, 11, word);
}
+ /*
+ * Writing TXD word 0 must the last to prevent a race condition with
+ * the device, whereby the device may take hold of the TXD before we
+ * finished updating it.
+ */
rt2x00_desc_read(txd, 0, &word);
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
rt2x00_set_field32(&word, TXD_W0_VALID, 1);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 81f6db1..fa40d43 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1446,6 +1446,32 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* Start writing the descriptor words.
*/
+ rt2x00_desc_read(txd, 0, &word);
+ rt2x00_set_field32(&word, TXD_W0_BURST,
+ test_bit(ENTRY_TXD_BURST, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_VALID, 1);
+ rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
+ test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_ACK,
+ test_bit(ENTRY_TXD_ACK, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
+ test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_OFDM,
+ (txdesc->rate_mode == RATE_MODE_OFDM));
+ rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
+ rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
+ test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_TKIP_MIC,
+ test_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_KEY_TABLE,
+ test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx);
+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length);
+ rt2x00_set_field32(&word, TXD_W0_BURST2,
+ test_bit(ENTRY_TXD_BURST, &txdesc->flags));
+ rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher);
+ rt2x00_desc_write(txd, 0, word);
+
rt2x00_desc_read(txd, 1, &word);
rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue);
rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs);
@@ -1473,32 +1499,6 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
TXPOWER_TO_DEV(rt2x00dev->tx_power));
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word);
-
- rt2x00_desc_read(txd, 0, &word);
- rt2x00_set_field32(&word, TXD_W0_BURST,
- test_bit(ENTRY_TXD_BURST, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_VALID, 1);
- rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
- test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_ACK,
- test_bit(ENTRY_TXD_ACK, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
- test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_OFDM,
- (txdesc->rate_mode == RATE_MODE_OFDM));
- rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
- rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
- test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_TKIP_MIC,
- test_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_KEY_TABLE,
- test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx);
- rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length);
- rt2x00_set_field32(&word, TXD_W0_BURST2,
- test_bit(ENTRY_TXD_BURST, &txdesc->flags));
- rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher);
- rt2x00_desc_write(txd, 0, word);
}
/*
--
1.7.1
^ permalink raw reply related
* [PATCH 0/9] rt2x00: Further fixes and cleanups.
From: Gertjan van Wingerde @ 2010-05-11 21:51 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
Another set of rt2x00 fixes and cleanups.
Most of the patches are working towards a nice cleanup in which rt2x00 starts
properly reserving room in skbs for descriptors instead of fiddling with
pointers.
Also one fix for rt61pci that no-one ever hit, whereby, for beacons, rt61pci
wrote part of the tx descriptor out-of-bounds.
These patches can also be pulled from:
git://git.gwingerde.nl/rt2x00-next-2.6.git
Gertjan van Wingerde (9):
rt2x00: Consistently name skb frame descriptor skbdesc.
rt2x00: Fix beacon descriptor writing for rt61pci.
rt2x00: Re-order tx descriptor writing code in drivers.
rt2x00: Simplify TXD handling of beacons.
rt2x00: Dump beacons under a different identifier than TX frames.
rt2x00: Push beacon TX descriptor writing to drivers.
rt2x00: In debugfs frame dumping allow the TX descriptor to be part
of the skb.
rt2x00: Reverse calling order of bus write_tx_desc and driver
write_tx_desc.
rt2x00: Properly reserve room for descriptors in skbs.
drivers/net/wireless/rt2x00/rt2400pci.c | 42 ++++++++------
drivers/net/wireless/rt2x00/rt2500pci.c | 42 ++++++++------
drivers/net/wireless/rt2x00/rt2500usb.c | 68 ++++++++++++++---------
drivers/net/wireless/rt2x00/rt2800lib.c | 3 +-
drivers/net/wireless/rt2x00/rt2800lib.h | 2 +-
drivers/net/wireless/rt2x00/rt2800pci.c | 59 +++++++++++++-------
drivers/net/wireless/rt2x00/rt2800usb.c | 35 +++++++++++--
drivers/net/wireless/rt2x00/rt2x00.h | 9 +++
drivers/net/wireless/rt2x00/rt2x00debug.c | 22 +++++---
drivers/net/wireless/rt2x00/rt2x00dev.c | 5 --
drivers/net/wireless/rt2x00/rt2x00dump.h | 3 +
drivers/net/wireless/rt2x00/rt2x00lib.h | 7 ---
drivers/net/wireless/rt2x00/rt2x00pci.c | 49 +++++++++++++++--
drivers/net/wireless/rt2x00/rt2x00pci.h | 8 +++
drivers/net/wireless/rt2x00/rt2x00queue.c | 39 +-------------
drivers/net/wireless/rt2x00/rt2x00queue.h | 3 +
drivers/net/wireless/rt2x00/rt2x00usb.c | 19 +++----
drivers/net/wireless/rt2x00/rt61pci.c | 50 ++++++++++++-----
drivers/net/wireless/rt2x00/rt73usb.c | 84 +++++++++++++++++------------
19 files changed, 338 insertions(+), 211 deletions(-)
^ permalink raw reply
* [PATCH 7/9] rt2x00: In debugfs frame dumping allow the TX descriptor to be part of the skb.
From: Gertjan van Wingerde @ 2010-05-11 21:51 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273614705-25118-1-git-send-email-gwingerde@gmail.com>
Preparation for futher cleanups in the area of properly maintaining the skb
data without fiddling with the skb->data pointer.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00debug.c | 14 ++++++++++----
drivers/net/wireless/rt2x00/rt2x00queue.h | 3 +++
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 85e9990..9dd8b7c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -159,6 +159,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skbcopy;
struct rt2x00dump_hdr *dump_hdr;
struct timeval timestamp;
+ u32 data_len;
do_gettimeofday(×tamp);
@@ -170,7 +171,11 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
return;
}
- skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + skb->len,
+ data_len = skb->len;
+ if (skbdesc->flags & SKBDESC_DESC_IN_SKB)
+ data_len -= skbdesc->desc_len;
+
+ skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + data_len,
GFP_ATOMIC);
if (!skbcopy) {
DEBUG(rt2x00dev, "Failed to copy skb for dump.\n");
@@ -181,7 +186,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(skbdesc->desc_len);
- dump_hdr->data_length = cpu_to_le32(skb->len);
+ dump_hdr->data_length = cpu_to_le32(data_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_le16(rt2x00dev->chip.rev);
@@ -191,8 +196,9 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
- memcpy(skb_put(skbcopy, skbdesc->desc_len), skbdesc->desc,
- skbdesc->desc_len);
+ if (!(skbdesc->flags & SKBDESC_DESC_IN_SKB))
+ memcpy(skb_put(skbcopy, skbdesc->desc_len), skbdesc->desc,
+ skbdesc->desc_len);
memcpy(skb_put(skbcopy, skb->len), skb->data, skb->len);
skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 36a957a..f791708 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -94,12 +94,15 @@ enum data_queue_qid {
* mac80211 but was stripped for processing by the driver.
* @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211,
* don't try to pass it back.
+ * @SKBDESC_DESC_IN_SKB: The descriptor is at the start of the
+ * skb, instead of in the desc field.
*/
enum skb_frame_desc_flags {
SKBDESC_DMA_MAPPED_RX = 1 << 0,
SKBDESC_DMA_MAPPED_TX = 1 << 1,
SKBDESC_IV_STRIPPED = 1 << 2,
SKBDESC_NOT_MAC80211 = 1 << 3,
+ SKBDESC_DESC_IN_SKB = 1 << 4,
};
/**
--
1.7.1
^ permalink raw reply related
* [PATCH 2/9] rt2x00: Fix beacon descriptor writing for rt61pci.
From: Gertjan van Wingerde @ 2010-05-11 21:51 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273614705-25118-1-git-send-email-gwingerde@gmail.com>
The buffer address descriptor word is not part of the TXINFO structure
needed for beacons. The current writing of that word for beacons is
therefore an out-of-bounds write.
Fix this by only writing the buffer address descriptor word for TX
queues.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt61pci.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 2436363..99c2981 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1801,12 +1801,12 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word);
- rt2x00_desc_read(txd, 6, &word);
- rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
- skbdesc->skb_dma);
- rt2x00_desc_write(txd, 6, word);
+ if (txdesc->queue != QID_BEACON) {
+ rt2x00_desc_read(txd, 6, &word);
+ rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
+ skbdesc->skb_dma);
+ rt2x00_desc_write(txd, 6, word);
- if (skbdesc->desc_len > TXINFO_SIZE) {
rt2x00_desc_read(txd, 11, &word);
rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0,
txdesc->length);
--
1.7.1
^ permalink raw reply related
* [PATCH 1/9] rt2x00: Consistently name skb frame descriptor skbdesc.
From: Gertjan van Wingerde @ 2010-05-11 21:51 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273614705-25118-1-git-send-email-gwingerde@gmail.com>
The skb frame descriptor is called everywhere skbdesc, except in one
place in rt2x00debug_dump_frame. Change that occurence to have
consistent naming.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00debug.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 70c04c2..9e2eed5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -155,7 +155,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
enum rt2x00_dump_type type, struct sk_buff *skb)
{
struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
- struct skb_frame_desc *desc = get_skb_frame_desc(skb);
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
struct sk_buff *skbcopy;
struct rt2x00dump_hdr *dump_hdr;
struct timeval timestamp;
@@ -170,7 +170,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
return;
}
- skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + skb->len,
+ skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + skb->len,
GFP_ATOMIC);
if (!skbcopy) {
DEBUG(rt2x00dev, "Failed to copy skb for dump.\n");
@@ -180,18 +180,19 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
dump_hdr = (struct rt2x00dump_hdr *)skb_put(skbcopy, sizeof(*dump_hdr));
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->desc_length = cpu_to_le32(skbdesc->desc_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_le16(rt2x00dev->chip.rev);
dump_hdr->type = cpu_to_le16(type);
- dump_hdr->queue_index = desc->entry->queue->qid;
- dump_hdr->entry_index = desc->entry->entry_idx;
+ dump_hdr->queue_index = skbdesc->entry->queue->qid;
+ dump_hdr->entry_index = skbdesc->entry->entry_idx;
dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
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, skbdesc->desc_len), skbdesc->desc,
+ skbdesc->desc_len);
memcpy(skb_put(skbcopy, skb->len), skb->data, skb->len);
skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
--
1.7.1
^ permalink raw reply related
* [PATCHi V4] mac80211: fix paged defragmentation
From: Abhijeet Kolekar @ 2010-05-11 21:51 UTC (permalink / raw)
To: linux-wireless; +Cc: yi.zhu, Abhijeet Kolekar
Paged RX skb patch broke the defragmentation. We need to read hdr again
after linearization.
It fixes following bug
http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2194
Signed-off-by: Zhu, Yi <yi.zhu@intel.com>
Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
---
v2: Changed hdr reading.
v3: Added more comments.
v4: added ACCESS_ONCE
net/mac80211/rx.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9a08f2c..af61aeb 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1253,6 +1253,13 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
if (skb_linearize(rx->skb))
return RX_DROP_UNUSABLE;
+ /*
+ * skb_linearize() might change the skb->data and
+ * previously cached variables (in this case, hdr) need to
+ * be refreshed with the new data. Also make sure compiler won't
+ * do any weird assignments.
+ */
+ hdr = (struct ieee80211_hdr *)ACCESS_ONCE(rx->skb->data);
seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
if (frag == 0) {
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2.6.32 1/1] ar9170usb: add vendor and device ID for Qwest/Actiontec 802AIN Wireless N USB Network Adapter
From: Steve Tanner @ 2010-05-11 21:34 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Christian Lamparter
* add support for the Qwest/Actiontec 802AIN Wireless N USB Network Adapter.
lsusb identifies the device as: "ID 1668:1200 Actiontec Electronics, Inc. [hex]"
usb_modeswitch package and appropriate rules are required to switch
the device from "ID 0ace:20ff ZyDas"
Changes-licensed-under: GPL
Signed-off-by: Steve Tanner <steve.tanner@gmail.com>
---
diff --git a/drivers/net/wireless/ath/ar9170/usb.c
b/drivers/net/wireless/ath/ar9170/usb.c
index f141a4f..1070313 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -94,6 +94,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
{ USB_DEVICE(0x057C, 0x8401) },
/* AVM FRITZ!WLAN USB Stick N 2.4 */
{ USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
+ /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */
+ { USB_DEVICE(0x1668, 0x1200) },
/* terminate */
{}
^ permalink raw reply related
* Re: [PATCH v2 1/2] mac80211: add offload channel switch support
From: Luis R. Rodriguez @ 2010-05-11 20:55 UTC (permalink / raw)
To: Johannes Berg, David Quan, Michael Green, Stephen Chen, Dan Tian,
Kevin Hayes, Cliff Holden
Cc: wey-yi.w.guy, linux-wireless
In-Reply-To: <1273586443.20312.14.camel@jlt3.sipsolutions.net>
On Tue, May 11, 2010 at 7:00 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Thu, 2010-05-06 at 14:58 -0700, Luis R. Rodriguez wrote:
>> On Thu, May 6, 2010 at 8:25 AM, <wey-yi.w.guy@intel.com> wrote:
>> > From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
>> > with this offload approach, driver has more control on how to handle the
>> > channel switch request from AP, also can provide more accurate timing
>> > calculation
>>
>> Is the current timing insufficient, and if so can you provide more
>> details. If the real reason for this callback is not timing
>> considerations is the real reason a firmware API thing? If so it
>> doesn't hurt to just say that to avoid confusing developer in deciding
>> which approach to take.
>
> The current mac80211 approach is flawed, for various reasons which I
> won't get into here, most of which we can fix. However, due to
> regulatory concerns our firmware also wants to have more control, like
> checking that the AP is beaconing again after a channel switch before
> letting us transmit frames.
OK this makes perfect sense if the channel you are switching to is
also a DFS channel, but it sounds like something we can also implement
on mac80211, unless of course firmware can make that guarantee for us
quicker. This is the sort of explanation that I think might be very
useful to the driver developer when choosing which mac80211 CSA
operation to implement -- either the standard mac80211 implementation
or a driver specific one.
I take it this tries to resolve some sort of race condition where the
AP decided to switch to another DFS channel, told the STAs, went to
the other channel, and as it does the swtich gets radar signals and
needs to quite down.
> Timing is obviously also a consideration,
> since the firmware can re-enable transmission quickly after the channel
> switch, regardless of the delay in processing the frame or the timer on
> the host.
Reason for me asking for details about this was because I was
wondering whether the reasons for you guys implementing a separate CSA
callback could be addressed by adjusting the internal existing
mac80211 CSA implementation further. Timing constraints to re-enable
TX seem to be the biggest concern here since checking whether or not
the AP is beaconing *can* certainly be done on mac80211. Is there a
measurable TX drop due to the extra latency introduced by using a host
based implementation?
If a driver developer reads the documentation it would be nice for
them to easily get enough information to decide which approach to take
and to do that the more details we can provide the better. If we
haven't tested a mac80211 enhanced approach why not try that first?
>> > The drivers like to support the channel switch offloading function
>>
>> Maybe: "The drivers that require a dedicated channel switch callback"...
>>
>> > will have
>> > to provide the mactime information (at least for mgmt and action frames)
>>
>> Might be good to specify why, or at least in the documentation code below.
>
> Actually, it's up to them. But if you implement the callback, you'll
> want to know precisely when to expect the channel switch
Right, that was my point, it was not clear that this was the reason
for having it so it might help the developer if the documentation
stated that.
> so you'll want
> to know when the frame that contained the CSA was received, which you
> have to provide to mac80211 in the "mactime" rx status field.
Right, thanks for the details, I was just hoping we could clarify that
to the driver developers a little more on the patch.
>> > +/**
>> > + * ieee80211_chswitch_done - Complete channel switch process
>> > + * @vif: &struct ieee80211_vif pointer from the add_interface callback.
>> > + * @is_seccess: make the channel switch successful or not
>>
>> Typo, is_seccess, not success. Also, I don't get what this is for, can
>> you elaborate?
>
> Channel switching could fail, for instance if the AP doesn't show up on
> the new channel. We don't have a way to handle that yet in mac80211, but
> why not let it know.
Oh definitely I agree, I was just hoping this can be explained ont he
kdoc above, it was not clear from reading the code.
>> I'd appreciate more feedback on the why this is being done. Its not
>> clear to me how we are limited by the current implementation.
>
> Ok like I said -- timing is a big thing. Regulatory enforcement in our
> firmware is another.
Regulatory enforcement is already handled by the mac80211 CSA, the
check for beaconing on the channel we move to *can* be done by
mac80211 as well, so that would only leave timing constraints.
Luis
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2010-05-11
From: David Miller @ 2010-05-11 20:32 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, netdev
In-Reply-To: <20100511190510.GD2400@tuxdriver.com>
From: "John W. Linville" <linville@tuxdriver.com>
Date: Tue, 11 May 2010 15:05:10 -0400
> Another round of bits intended for 2.6.35...mostly driver updates this
> time. The biggest item of note is some continued attention for rt2800
> from the rt2x00 team.
Pulled, thanks John.
^ permalink raw reply
* Re: [PATCH 2/4] ath9k: add debugfs files for reading/writing the rx and tx chainmask
From: Luis R. Rodriguez @ 2010-05-11 20:14 UTC (permalink / raw)
To: Felix Fietkau
Cc: Luis Rodriguez, linux-wireless@vger.kernel.org,
linville@tuxdriver.com
In-Reply-To: <4BE9B61A.2090708@openwrt.org>
On Tue, May 11, 2010 at 12:55:06PM -0700, Felix Fietkau wrote:
> On 2010-05-11 8:15 PM, Luis R. Rodriguez wrote:
> > On Tue, May 11, 2010 at 8:23 AM, Felix Fietkau <nbd@openwrt.org> wrote:
> >> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> >
> > How about we use bruno's patch instead and we help review it for
> > 802.11n? Then this would not be needed?
> I'd like to keep those separate. I've seen cards where the wrong
> chainmask was programmed into the eeprom, this debugfs file is for
> detecting that and trying other settings.
> When Bruno's patch gets implemented for ath9k, the values that it can
> set should be masked by the internal value, while the debugfs file can
> override the internal value.
Fair enough, thanks.
Luis
^ permalink raw reply
* Re: [PATCH 2/4] ath9k: add debugfs files for reading/writing the rx and tx chainmask
From: Felix Fietkau @ 2010-05-11 19:55 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linux-wireless, linville
In-Reply-To: <AANLkTilDwhBErduNt_vZLSsEVVkC1SDMwUPkoumym1o3@mail.gmail.com>
On 2010-05-11 8:15 PM, Luis R. Rodriguez wrote:
> On Tue, May 11, 2010 at 8:23 AM, Felix Fietkau <nbd@openwrt.org> wrote:
>> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
>
> How about we use bruno's patch instead and we help review it for
> 802.11n? Then this would not be needed?
I'd like to keep those separate. I've seen cards where the wrong
chainmask was programmed into the eeprom, this debugfs file is for
detecting that and trying other settings.
When Bruno's patch gets implemented for ath9k, the values that it can
set should be masked by the internal value, while the debugfs file can
override the internal value.
- Felix
^ permalink raw reply
* Re: [PATCH V3] mac80211: fix paged defragmentation
From: John W. Linville @ 2010-05-11 19:43 UTC (permalink / raw)
To: Johannes Berg; +Cc: Abhijeet Kolekar, linux-wireless@vger.kernel.org, Zhu, Yi
In-Reply-To: <1273604696.20312.29.camel@jlt3.sipsolutions.net>
On Tue, May 11, 2010 at 09:04:56PM +0200, Johannes Berg wrote:
> On Tue, 2010-05-11 at 11:52 -0700, Abhijeet Kolekar wrote:
> > Hello John,
> > On Tue, 2010-05-11 at 11:24 -0700, John W. Linville wrote:
> > > On Tue, May 11, 2010 at 11:16:50AM -0700, Abhijeet Kolekar wrote:
> > > > Hello John,
> > > > On Tue, 2010-05-11 at 11:14 -0700, John W. Linville wrote:
> > > > > On Tue, May 11, 2010 at 11:22:11AM -0700, Abhijeet Kolekar wrote:
> > > > > > Paged RX skb patch broke the defragmentation. We need to read hdr again
> > > > > > after linearization.
> > > > > >
> > > > > > It fixes following bug
> > > > > > http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2194
> > > > > >
> > > > > > Signed-off-by: Zhu, Yi <yi.zhu@intel.com>
> > > > > > Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
> > > > > > ---
> > > > > > v2: Changed hdr reading.
> > > > > > v3: Added more comments.
> > > > > > net/mac80211/rx.c | 6 ++++++
> > > > > > 1 files changed, 6 insertions(+), 0 deletions(-)
> > > > > >
> > > > > > diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> > > > > > index 9a08f2c..6e2a7bc 100644
> > > > > > --- a/net/mac80211/rx.c
> > > > > > +++ b/net/mac80211/rx.c
> > > > > > @@ -1253,6 +1253,12 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
> > > > > > if (skb_linearize(rx->skb))
> > > > > > return RX_DROP_UNUSABLE;
> > > > > >
> > > > > > + /*
> > > > > > + * skb_linearize() might change the skb->data and
> > > > > > + * previously cached variables (in this case, hdr) need to
> > > > > > + * be refreshed with the new data.
> > > > > > + */
> > > > > > + hdr = (struct ieee80211_hdr *)rx->skb->data;
> > > > > > seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
> > > > > >
> > > > > > if (frag == 0) {
> > > > >
> > > > > And what about making sure the compiler doesn't optimize this away?
> > > > >
> > > > To avoid the double assignment, there is one more approach is to
> > > > directly read fc and seq_ctrl using skb_data. I will send that in the
> > > > next version.
> > >
> > > I don't think the double assignment is so bad, I just think that a
> > > compiler might decide to ignore the second assignment. Am I wrong?
> > >
> > I don't understand why compiler will ignore the second assignment other
> > than the above reason. What will be the solution in this case?
>
> ACCESS_ONCE()? I have no idea why/if the compiler would actually do this
> though.
I don't know about "if", but "why" might be that as far as the compiler
can see you have two identical assignments without an obvious change to
the data source in between. But maybe passing rx->skb to skb_linearize
is enough information to make the compiler aware that rx->skb->data
might have changed? Any better language lawyers than me around?
I think ACCESS_ONCE would be enough, but maybe it isn't necessary...?
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [PATCH] ar9170usb:add vendor and device ID for Qwest/Actiontec 802AIN Wireless N USB Network Adapter
From: John W. Linville @ 2010-05-11 19:16 UTC (permalink / raw)
To: Steve Tanner; +Cc: linux-wireless, Christian Lamparter
In-Reply-To: <AANLkTilNQBE7zwSaNjcaHG4YPD_zfK63aepIzccWIdSj@mail.gmail.com>
On Tue, May 11, 2010 at 02:19:35AM -0700, Steve Tanner wrote:
> * add support for the Qwest/Actiontec 802AIN Wireless N USB Network Adapter.
>
> lsusb identifies the device as: "ID 1668:1200 Actiontec Electronics, Inc. [hex]"
>
> usb_modeswitch package and appropriate rules are required to switch
> the device from "ID 0ace:20ff ZyDas"
>
> Changes-licensed-under: GPL
Need a "Signed-off-by", please!
http://linux.yyz.us/patch-format.html
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* pull request: wireless-next-2.6 2010-05-11
From: John W. Linville @ 2010-05-11 19:05 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev
Dave,
Another round of bits intended for 2.6.35...mostly driver updates this
time. The biggest item of note is some continued attention for rt2800
from the rt2x00 team.
Please let me know if there are problems!
John
---
The following changes since commit d250fe91ae129bff0968e685cc9c466d3a5e3482:
David S. Miller (1):
Merge branch 'master' of git://git.kernel.org/.../kaber/nf-next-2.6
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6.git for-davem
Christian Lamparter (1):
ar9170usb: remove deprecated aggregation code
Dan Carpenter (4):
iwlwifi: remove stray mutex_unlock()
ath9k/htc_drv_main: null dereference typo
ath9k/htc_drv_main: off by one error
ath5k: several off by one range checks
David Kilroy (1):
orinoco: refactor xmit path
Felix Fietkau (1):
ath9k: fix another source of corrupt frames
Gertjan van Wingerde (9):
rt2x00: Fix setting of txdesc->length field.
rt2x00: Clean up rt2800usb.h.
rt2x00: Don't check whether hardware crypto is enabled when reading RXD.
rt2x00: Factor out TXWI writing to common rt2800 code.
rt2x00: Factor out RXWI processing to common rt2800 code.
rt2x00: Clean up all driver's kick_tx_queue callback functions.
rt2x00: provide beacon's txdesc to write_beacon callback function.
rt2x00: Fix beaconing on rt2800.
rt2x00: Clean up generic procedures on descriptor writing.
Helmut Schaa (3):
rt2x00: rt2800: update initial SIFS values
rt2x00: rt2800: don't overwrite SIFS values on erp changes
rt2x00: rt2800: use correct txop value in tx descriptor
Ivo van Doorn (1):
rt2x00: Fix RF3052 channel initialization
Johannes Berg (3):
mac80211: fix BSS info reconfiguration
cfg80211/mac80211: better channel handling
mac80211: improve HT channel handling
John W. Linville (5):
mac80211: set IEEE80211_TX_CTL_FIRST_FRAGMENT for beacons
rtl8180: assign sequence numbers in the driver
rtl8180: add software-based support for IBSS mode
rtl8180: change PCI DMA mask to DMA_BIT_MASK(32)
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6 into for-davem
Juuso Oikarinen (4):
wl1271: Add sysfs file to retrieve HW PG-version and ROM-version
wl1271: Fix 32 bit register read related endiannes bug
wl1271: Fix to join and channel number handling
wl1271: Reduce PSM entry hang over period from 128 => 1 ms
Luis R. Rodriguez (4):
ath9k_common: move the rate status setting into ath9k_process_rate()
ath9k_common: drop incomming frames with an invalid hardware rate
ath9k_hw: Update initvals for AR9003 for xb113
ath9k_hw: enable PCIe low power mode for AR9003
Randy Dunlap (1):
wireless: depends on NET
Stephen Rothwell (1):
ar9170: fix for driver-core ABI change
Sujith (2):
ath9k_htc: Fix beaconing in IBSS mode
ath9k_htc: Handle IDLE LED properly
Teemu Paasikivi (1):
wl1271: Increase timeout for command event waiting
Xose Vazquez Perez (1):
wireless: rt2x00: rt2800usb: replace X by x
drivers/net/wireless/Kconfig | 1 +
drivers/net/wireless/ath/ar9170/ar9170.h | 52 +--
drivers/net/wireless/ath/ar9170/main.c | 558 +---------------------
drivers/net/wireless/ath/ar9170/usb.c | 5 +-
drivers/net/wireless/ath/ath5k/ani.c | 6 +-
drivers/net/wireless/ath/ath9k/ar9003_initvals.h | 204 ++++----
drivers/net/wireless/ath/ath9k/common.c | 49 ++-
drivers/net/wireless/ath/ath9k/htc.h | 5 +-
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 39 +--
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +-
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 42 +-
drivers/net/wireless/ath/ath9k/hw.c | 20 +
drivers/net/wireless/iwlwifi/iwl-3945.c | 1 -
drivers/net/wireless/libertas/cfg.c | 1 +
drivers/net/wireless/mac80211_hwsim.c | 19 +-
drivers/net/wireless/orinoco/cfg.c | 1 +
drivers/net/wireless/orinoco/main.c | 169 ++++---
drivers/net/wireless/orinoco/orinoco.h | 6 +
drivers/net/wireless/orinoco/orinoco_usb.c | 91 ++--
drivers/net/wireless/rndis_wlan.c | 4 +-
drivers/net/wireless/rt2x00/rt2400pci.c | 22 +-
drivers/net/wireless/rt2x00/rt2500pci.c | 22 +-
drivers/net/wireless/rt2x00/rt2500usb.c | 66 +--
drivers/net/wireless/rt2x00/rt2800lib.c | 178 +++++++-
drivers/net/wireless/rt2x00/rt2800lib.h | 3 +
drivers/net/wireless/rt2x00/rt2800pci.c | 166 ++-----
drivers/net/wireless/rt2x00/rt2800usb.c | 182 ++------
drivers/net/wireless/rt2x00/rt2800usb.h | 40 --
drivers/net/wireless/rt2x00/rt2x00.h | 3 +-
drivers/net/wireless/rt2x00/rt2x00crypto.c | 1 +
drivers/net/wireless/rt2x00/rt2x00ht.c | 17 +
drivers/net/wireless/rt2x00/rt2x00queue.c | 23 +-
drivers/net/wireless/rt2x00/rt2x00queue.h | 2 +
drivers/net/wireless/rt2x00/rt2x00reg.h | 10 +
drivers/net/wireless/rt2x00/rt61pci.c | 41 +-
drivers/net/wireless/rt2x00/rt73usb.c | 51 +--
drivers/net/wireless/rtl818x/rtl8180.h | 11 +
drivers/net/wireless/rtl818x/rtl8180_dev.c | 96 ++++-
drivers/net/wireless/wl12xx/wl1271.h | 4 +-
drivers/net/wireless/wl12xx/wl1271_boot.c | 12 +
drivers/net/wireless/wl12xx/wl1271_boot.h | 3 +
drivers/net/wireless/wl12xx/wl1271_cmd.c | 2 +-
drivers/net/wireless/wl12xx/wl1271_cmd.h | 2 +-
drivers/net/wireless/wl12xx/wl1271_io.h | 4 +-
drivers/net/wireless/wl12xx/wl1271_main.c | 63 +++-
include/linux/nl80211.h | 13 +
include/net/cfg80211.h | 11 +-
include/net/mac80211.h | 6 +
net/mac80211/Makefile | 3 +-
net/mac80211/cfg.c | 58 +++-
net/mac80211/chan.c | 127 +++++
net/mac80211/ibss.c | 5 +-
net/mac80211/ieee80211_i.h | 16 +-
net/mac80211/main.c | 2 +-
net/mac80211/mlme.c | 44 +-
net/mac80211/tx.c | 5 +-
net/mac80211/util.c | 25 +-
net/wireless/chan.c | 56 +--
net/wireless/core.h | 12 +-
net/wireless/ibss.c | 5 -
net/wireless/nl80211.c | 171 +++++--
net/wireless/sme.c | 5 -
net/wireless/wext-compat.c | 15 +-
net/wireless/wext-sme.c | 2 +-
64 files changed, 1369 insertions(+), 1511 deletions(-)
create mode 100644 net/mac80211/chan.c
Omnibus patch available here:
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6-2010-05-11.patch.bz2
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [PATCH V3] mac80211: fix paged defragmentation
From: Johannes Berg @ 2010-05-11 19:04 UTC (permalink / raw)
To: Abhijeet Kolekar
Cc: John W. Linville, linux-wireless@vger.kernel.org, Zhu, Yi
In-Reply-To: <1273603952.5955.45.camel@abhi-desktop>
On Tue, 2010-05-11 at 11:52 -0700, Abhijeet Kolekar wrote:
> Hello John,
> On Tue, 2010-05-11 at 11:24 -0700, John W. Linville wrote:
> > On Tue, May 11, 2010 at 11:16:50AM -0700, Abhijeet Kolekar wrote:
> > > Hello John,
> > > On Tue, 2010-05-11 at 11:14 -0700, John W. Linville wrote:
> > > > On Tue, May 11, 2010 at 11:22:11AM -0700, Abhijeet Kolekar wrote:
> > > > > Paged RX skb patch broke the defragmentation. We need to read hdr again
> > > > > after linearization.
> > > > >
> > > > > It fixes following bug
> > > > > http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2194
> > > > >
> > > > > Signed-off-by: Zhu, Yi <yi.zhu@intel.com>
> > > > > Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
> > > > > ---
> > > > > v2: Changed hdr reading.
> > > > > v3: Added more comments.
> > > > > net/mac80211/rx.c | 6 ++++++
> > > > > 1 files changed, 6 insertions(+), 0 deletions(-)
> > > > >
> > > > > diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> > > > > index 9a08f2c..6e2a7bc 100644
> > > > > --- a/net/mac80211/rx.c
> > > > > +++ b/net/mac80211/rx.c
> > > > > @@ -1253,6 +1253,12 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
> > > > > if (skb_linearize(rx->skb))
> > > > > return RX_DROP_UNUSABLE;
> > > > >
> > > > > + /*
> > > > > + * skb_linearize() might change the skb->data and
> > > > > + * previously cached variables (in this case, hdr) need to
> > > > > + * be refreshed with the new data.
> > > > > + */
> > > > > + hdr = (struct ieee80211_hdr *)rx->skb->data;
> > > > > seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
> > > > >
> > > > > if (frag == 0) {
> > > >
> > > > And what about making sure the compiler doesn't optimize this away?
> > > >
> > > To avoid the double assignment, there is one more approach is to
> > > directly read fc and seq_ctrl using skb_data. I will send that in the
> > > next version.
> >
> > I don't think the double assignment is so bad, I just think that a
> > compiler might decide to ignore the second assignment. Am I wrong?
> >
> I don't understand why compiler will ignore the second assignment other
> than the above reason. What will be the solution in this case?
ACCESS_ONCE()? I have no idea why/if the compiler would actually do this
though.
johannes
^ permalink raw reply
* Re: [PATCH V3] mac80211: fix paged defragmentation
From: Abhijeet Kolekar @ 2010-05-11 18:52 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless@vger.kernel.org, Zhu, Yi
In-Reply-To: <20100511182423.GC2400@tuxdriver.com>
Hello John,
On Tue, 2010-05-11 at 11:24 -0700, John W. Linville wrote:
> On Tue, May 11, 2010 at 11:16:50AM -0700, Abhijeet Kolekar wrote:
> > Hello John,
> > On Tue, 2010-05-11 at 11:14 -0700, John W. Linville wrote:
> > > On Tue, May 11, 2010 at 11:22:11AM -0700, Abhijeet Kolekar wrote:
> > > > Paged RX skb patch broke the defragmentation. We need to read hdr again
> > > > after linearization.
> > > >
> > > > It fixes following bug
> > > > http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2194
> > > >
> > > > Signed-off-by: Zhu, Yi <yi.zhu@intel.com>
> > > > Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
> > > > ---
> > > > v2: Changed hdr reading.
> > > > v3: Added more comments.
> > > > net/mac80211/rx.c | 6 ++++++
> > > > 1 files changed, 6 insertions(+), 0 deletions(-)
> > > >
> > > > diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> > > > index 9a08f2c..6e2a7bc 100644
> > > > --- a/net/mac80211/rx.c
> > > > +++ b/net/mac80211/rx.c
> > > > @@ -1253,6 +1253,12 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
> > > > if (skb_linearize(rx->skb))
> > > > return RX_DROP_UNUSABLE;
> > > >
> > > > + /*
> > > > + * skb_linearize() might change the skb->data and
> > > > + * previously cached variables (in this case, hdr) need to
> > > > + * be refreshed with the new data.
> > > > + */
> > > > + hdr = (struct ieee80211_hdr *)rx->skb->data;
> > > > seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
> > > >
> > > > if (frag == 0) {
> > >
> > > And what about making sure the compiler doesn't optimize this away?
> > >
> > To avoid the double assignment, there is one more approach is to
> > directly read fc and seq_ctrl using skb_data. I will send that in the
> > next version.
>
> I don't think the double assignment is so bad, I just think that a
> compiler might decide to ignore the second assignment. Am I wrong?
>
I don't understand why compiler will ignore the second assignment other
than the above reason. What will be the solution in this case?
Abhijeet
> John
^ permalink raw reply
* Re: [PATCH V3] mac80211: fix paged defragmentation
From: John W. Linville @ 2010-05-11 18:24 UTC (permalink / raw)
To: Abhijeet Kolekar; +Cc: linux-wireless@vger.kernel.org, Zhu, Yi
In-Reply-To: <1273601810.5955.44.camel@abhi-desktop>
On Tue, May 11, 2010 at 11:16:50AM -0700, Abhijeet Kolekar wrote:
> Hello John,
> On Tue, 2010-05-11 at 11:14 -0700, John W. Linville wrote:
> > On Tue, May 11, 2010 at 11:22:11AM -0700, Abhijeet Kolekar wrote:
> > > Paged RX skb patch broke the defragmentation. We need to read hdr again
> > > after linearization.
> > >
> > > It fixes following bug
> > > http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2194
> > >
> > > Signed-off-by: Zhu, Yi <yi.zhu@intel.com>
> > > Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
> > > ---
> > > v2: Changed hdr reading.
> > > v3: Added more comments.
> > > net/mac80211/rx.c | 6 ++++++
> > > 1 files changed, 6 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> > > index 9a08f2c..6e2a7bc 100644
> > > --- a/net/mac80211/rx.c
> > > +++ b/net/mac80211/rx.c
> > > @@ -1253,6 +1253,12 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
> > > if (skb_linearize(rx->skb))
> > > return RX_DROP_UNUSABLE;
> > >
> > > + /*
> > > + * skb_linearize() might change the skb->data and
> > > + * previously cached variables (in this case, hdr) need to
> > > + * be refreshed with the new data.
> > > + */
> > > + hdr = (struct ieee80211_hdr *)rx->skb->data;
> > > seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
> > >
> > > if (frag == 0) {
> >
> > And what about making sure the compiler doesn't optimize this away?
> >
> To avoid the double assignment, there is one more approach is to
> directly read fc and seq_ctrl using skb_data. I will send that in the
> next version.
I don't think the double assignment is so bad, I just think that a
compiler might decide to ignore the second assignment. Am I wrong?
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [RFC PATCH 1/2] mac80211: Add nl80211 antenna configuration
From: Luis R. Rodriguez @ 2010-05-11 18:26 UTC (permalink / raw)
To: Johannes Berg, ic.felix
Cc: Bruno Randolf, linville, linux-wireless, holgerschurig
In-Reply-To: <1273601969.20312.23.camel@jlt3.sipsolutions.net>
On Tue, May 11, 2010 at 11:19 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Tue, 2010-05-11 at 11:14 -0700, Luis R. Rodriguez wrote:
>
>> > Allow setting TX and RX antenna configuration via nl80211/cfg80211.
>>
>> I think we should call this TX / RX chainmask given that with 802.11n
>> hardware this is what this is called.
>
> Well, but even with 11n hw you might be able to select _antennas_ rather
> than chains. I'm convinced we'll need to differentiate that very
> closely, and 11g hw has only antenna, not chain, selection.
Heh you're right, you might have for example 3 antennas but only two
RX chains, for example. I still think it would be good for us to
figure out a way to bring these two notions together on a standard API
for both 11n and legacy, if possible.
Luis
^ permalink raw reply
* [PATCH 1/5] drivers/net/wireless/hostap: Drop memory allocation cast
From: Julia Lawall @ 2010-05-11 18:25 UTC (permalink / raw)
To: Jouni Malinen, John W. Linville, linux-wireless, netdev,
linux-kernel, kernel-janitors
From: Julia Lawall <julia@diku.dk>
Drop cast on the result of kmalloc and similar functions.
The semantic patch that makes this change is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@@
type T;
@@
- (T *)
(\(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|
kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...))
// </smpl>
Signed-off-by: Julia Lawall <julia@diku.dk>
---
drivers/net/wireless/hostap/hostap_80211_rx.c | 3 +--
drivers/net/wireless/hostap/hostap_ioctl.c | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index f4c5612..e0b3e8d 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -355,8 +355,7 @@ static struct hostap_bss_info *__hostap_add_bss(local_info_t *local, u8 *bssid,
list_del(&bss->list);
local->num_bss_info--;
} else {
- bss = (struct hostap_bss_info *)
- kmalloc(sizeof(*bss), GFP_ATOMIC);
+ bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
if (bss == NULL)
return NULL;
}
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 9a08230..a85e43a 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -3039,8 +3039,7 @@ static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p)
p->length > 1024 || !p->pointer)
return -EINVAL;
- param = (struct prism2_download_param *)
- kmalloc(p->length, GFP_KERNEL);
+ param = kmalloc(p->length, GFP_KERNEL);
if (param == NULL)
return -ENOMEM;
^ permalink raw reply related
* Re: [PATCH V3] mac80211: fix paged defragmentation
From: Abhijeet Kolekar @ 2010-05-11 18:16 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless@vger.kernel.org, Zhu, Yi
In-Reply-To: <20100511181439.GB2400@tuxdriver.com>
Hello John,
On Tue, 2010-05-11 at 11:14 -0700, John W. Linville wrote:
> On Tue, May 11, 2010 at 11:22:11AM -0700, Abhijeet Kolekar wrote:
> > Paged RX skb patch broke the defragmentation. We need to read hdr again
> > after linearization.
> >
> > It fixes following bug
> > http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2194
> >
> > Signed-off-by: Zhu, Yi <yi.zhu@intel.com>
> > Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
> > ---
> > v2: Changed hdr reading.
> > v3: Added more comments.
> > net/mac80211/rx.c | 6 ++++++
> > 1 files changed, 6 insertions(+), 0 deletions(-)
> >
> > diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> > index 9a08f2c..6e2a7bc 100644
> > --- a/net/mac80211/rx.c
> > +++ b/net/mac80211/rx.c
> > @@ -1253,6 +1253,12 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
> > if (skb_linearize(rx->skb))
> > return RX_DROP_UNUSABLE;
> >
> > + /*
> > + * skb_linearize() might change the skb->data and
> > + * previously cached variables (in this case, hdr) need to
> > + * be refreshed with the new data.
> > + */
> > + hdr = (struct ieee80211_hdr *)rx->skb->data;
> > seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
> >
> > if (frag == 0) {
>
> And what about making sure the compiler doesn't optimize this away?
>
To avoid the double assignment, there is one more approach is to
directly read fc and seq_ctrl using skb_data. I will send that in the
next version.
Abhijeet
> John
^ permalink raw reply
* Re: [RFC PATCH 1/2] mac80211: Add nl80211 antenna configuration
From: Johannes Berg @ 2010-05-11 18:19 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: Bruno Randolf, linville, linux-wireless, holgerschurig
In-Reply-To: <AANLkTilowwAyqLrIJ0_mlZxnqY-TqSHM3xdXkbO8aH6-@mail.gmail.com>
On Tue, 2010-05-11 at 11:14 -0700, Luis R. Rodriguez wrote:
> > Allow setting TX and RX antenna configuration via nl80211/cfg80211.
>
> I think we should call this TX / RX chainmask given that with 802.11n
> hardware this is what this is called.
Well, but even with 11n hw you might be able to select _antennas_ rather
than chains. I'm convinced we'll need to differentiate that very
closely, and 11g hw has only antenna, not chain, selection.
johannes
^ permalink raw reply
* Re: [RFC PATCH 0/2] mac80211: antenna configuration
From: Luis R. Rodriguez @ 2010-05-11 18:17 UTC (permalink / raw)
To: Bruno Randolf; +Cc: Johannes Berg, linville, linux-wireless, holgerschurig
In-Reply-To: <201005111834.36879.br1@einfach.org>
On Tue, May 11, 2010 at 2:34 AM, Bruno Randolf <br1@einfach.org> wrote:
> On Tuesday 11 May 2010 17:53:19 you wrote:
>> On Tue, 2010-05-11 at 17:38 +0900, Bruno Randolf wrote:
>> > i have followed holger schurig's suggestion to use a bitmap for allowed
>> > antennas. when multiple antennas are selected in the bitmap, the driver
>> > may use diversity. i think that this allows for the most flexible, yet
>> > simple configuration of antennas, and drivers can just reject
>> > configurations they cannot support. i hope that this will also be
>> > generic enough for 802.11n with multiple antennas
>>
>> Not sure ... 11n has antennas and chains, but people mix them up
>> frequently. Does this API even make sense for 11n? Use cases? Should it
>> be about *antennas*, or about *chains*?
>
> thanks for the review! i'll resend tomorrow.
>
> i personally don't know about 802.11n - and what i need is about *antennas* :)
I figured, let us help you with the 11n review.
Luis
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox