Please pull 'upstream' branch of rt2x00
Hi John,
Here is the official pull request for the latest rt2x00.git. This contains all patches which I had send last tuesday plus some additional patches intended for 2.6.27.
This series is mostly intended to get the fragmentation done right. Up until now the drivers never behaved that nicely with fragmentation or RTS/CTS-to-sellf which was mostly due because each individual frame forced the queue to be kicked immediately without waiting for the other fragments.
It also contains some front work by Gertjan for reducing DMA requirements in rt2x00 by making use of pci_map_single on skbuffers instead of preallocating a chunk of DMA.
Ivo
P.S. I won't resend the patches I had send last tuesday since nothing has changed with them. So only the 10 new patches will be send seperately. I am not sure if that feature will be ready/stable for 2.6.27 but this preperational work is harmless for normal operations to it is better if that is already in.
---
The following changes since commit ef28eab0c928fe8277d7c3dca234c29f734d7f2e:
Dan Williams (1):
ipw2200: queue direct scans
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/ivd/rt2x00.git/ upstream
Gertjan van Wingerde (5):
rt2x00: Restrict DMA to 32-bit addresses.
rt2x00: Cleanup struct skb_frame_desc.
rt2x00: Centralize RX packet alignment handling in rt2x00lib.
rt2x00: Fix double usage of skb->cb in USB RX path.
rt2x00: Rework alignment check.
Ivo van Doorn (15):
rt2x00: Calculate register offset during compile time
rt2x00: Cleanup/optimize set_state() function callback function
rt2x00: Move led initialization into function
rt2x00: Remove CTS/RTS check in tx()
rt2x00: Removed unused descriptor read in txdone
rt2x00: Don't kill guardian_urb when it wasn't created
rt2x00: Make rt2x00_set/get_field macros
rt2x00: Release rt2x00 2.1.7
rt2x00: Fix queue initialization
rt2x00: Implement rt2x00usb_kick_tx_queue()
rt2x00: Move generic TX frame writing code into rt2x00queue
rt2x00: Don't kick TX queue after each frame
rt2x00: Use __builtin_choose_expr() instead of ?:
rt2x00: Clear IEEE80211_TX_CTL_USE_RTS_CTS flag for RTS frame
rt2x00: Remove unused defines
drivers/net/wireless/rt2x00/rt2400pci.c | 95 ++++++++--------- drivers/net/wireless/rt2x00/rt2400pci.h | 2 - drivers/net/wireless/rt2x00/rt2500pci.c | 91 +++++++-------- drivers/net/wireless/rt2x00/rt2500pci.h | 2 - drivers/net/wireless/rt2x00/rt2500usb.c | 98 ++++++++-------- drivers/net/wireless/rt2x00/rt2500usb.h | 2 - drivers/net/wireless/rt2x00/rt2x00.h | 13 ++- drivers/net/wireless/rt2x00/rt2x00debug.c | 6 +- drivers/net/wireless/rt2x00/rt2x00dev.c | 21 ++++ drivers/net/wireless/rt2x00/rt2x00lib.h | 1 + drivers/net/wireless/rt2x00/rt2x00mac.c | 30 ++---- drivers/net/wireless/rt2x00/rt2x00pci.c | 75 ++++--------- drivers/net/wireless/rt2x00/rt2x00pci.h | 11 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 111 ++++++++++++++++--- drivers/net/wireless/rt2x00/rt2x00queue.h | 27 +++-- drivers/net/wireless/rt2x00/rt2x00reg.h | 134 +++++++++++++--------- drivers/net/wireless/rt2x00/rt2x00usb.c | 170 +++++++++++------------------ drivers/net/wireless/rt2x00/rt2x00usb.h | 22 +++- drivers/net/wireless/rt2x00/rt61pci.c | 111 ++++++++----------- drivers/net/wireless/rt2x00/rt61pci.h | 2 - drivers/net/wireless/rt2x00/rt73usb.c | 112 +++++++++---------- drivers/net/wireless/rt2x00/rt73usb.h | 2 - 22 files changed, 581 insertions(+), 557 deletions(-)
PATCH 1/10 rt2x00: Implement rt2x00usb_kick_tx_queue()
rt2x00usb_kick_tx_queue() will loop over all entries within the INDEX_DONE->INDEX range and kick each entry which is pending to be kicked. This makes the kick_tx_queue approach work the same as with the PCI drivers which will allow for more code generalisation into rt2x00lib.
--- drivers/net/wireless/rt2x00/rt2500usb.c | 4 ++- drivers/net/wireless/rt2x00/rt2x00queue.h | 3 ++ drivers/net/wireless/rt2x00/rt2x00usb.c | 48 ++++++++++++++++++++++++++++- drivers/net/wireless/rt2x00/rt2x00usb.h | 11 ++++++ drivers/net/wireless/rt2x00/rt73usb.c | 4 ++- 5 files changed, 67 insertions(+), 3 deletions(-)
drivers/net/wireless/rt2x00/rt2500usb.c +3 -1
@@ -1116,8 +1116,10 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, {u16 reg; -if (queue !=QID_BEACON ) +if (queue !=QID_BEACON ) { +rt2x00usb_kick_tx_queue (rt2x00dev, queue);return ; + }rt2500usb_register_read (rt2x00dev,TXRX_CSR19 , ®);if (!rt2x00_get_field16 (reg,TXRX_CSR19_BEACON_GEN )) {
drivers/net/wireless/rt2x00/rt2x00queue.h +3 -0
@@ -260,11 +260,14 @@ struct txentry_desc {* @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data * encryption or decryption. The entry should only be touched after * the device has signaled it is done with it. +* @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting +* for the signal to start sending. */ enum queue_entry_flags {ENTRY_BCN_ASSIGNED ,ENTRY_OWNER_DEVICE_DATA ,ENTRY_OWNER_DEVICE_CRYPTO , +ENTRY_DATA_PENDING , };/**
drivers/net/wireless/rt2x00/rt2x00usb.c +47 -1
62 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt2x00usb.h +11 -0
@@ -245,6 +245,17 @@ struct queue_entry_priv_usb_bcn {struct urb *guardian_urb; }; +/** +* rt2x00usb_kick_tx_queue - Kick data queue +* @rt2x00dev: Pointer to &struct rt2x00_dev +* @qid: Data queue to kick +* +* This will walk through all entries of the queue and push all pending +* frames to the hardware as a single burst. +*/ +void rt2x00usb_kick_tx_queue (struct rt2x00_dev *rt2x00dev, +const enum data_queue_qid qid); +/* * Device initialization handlers. */
drivers/net/wireless/rt2x00/rt73usb.c +3 -1
@@ -1350,8 +1350,10 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, {u32 reg; -if (queue !=QID_BEACON ) +if (queue !=QID_BEACON ) { +rt2x00usb_kick_tx_queue (rt2x00dev, queue);return ; + }/* * For Wi-Fi faily generated beacons between participating stations.
Signature · 1 line
1.5.5.3
PATCH 2/10 rt2x00: Move generic TX frame writing code into rt2x00queue
The write_tx_data functions in rt2x00pci and rt2x00usb have a lot in common. This moves that duplicate code into rt2x00queue_write_tx_frame().
--- drivers/net/wireless/rt2x00/rt2x00.h | 3 +- drivers/net/wireless/rt2x00/rt2x00lib.h | 1 + drivers/net/wireless/rt2x00/rt2x00mac.c | 7 +--- drivers/net/wireless/rt2x00/rt2x00pci.c | 43 ++++++++-------------- drivers/net/wireless/rt2x00/rt2x00pci.h | 11 ++++-- drivers/net/wireless/rt2x00/rt2x00queue.c | 37 +++++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00usb.c | 57 +++++++---------------------- drivers/net/wireless/rt2x00/rt2x00usb.h | 11 ++++-- 8 files changed, 85 insertions(+), 85 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +1 -2
@@ -546,8 +546,7 @@ struct rt2x00lib_ops {void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,struct sk_buff *skb,struct txentry_desc *txdesc); -int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, -struct data_queue *queue,struct sk_buff *skb); +int (*write_tx_data) (struct queue_entry *entry);int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev,struct sk_buff *skb); void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
drivers/net/wireless/rt2x00/rt2x00lib.h +1 -0
@@ -101,6 +101,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,/* * Queue handlers. */ +int rt2x00queue_write_tx_frame (struct data_queue *queue,struct sk_buff *skb);void rt2x00queue_init_rx (struct rt2x00_dev *rt2x00dev);void rt2x00queue_init_tx (struct rt2x00_dev *rt2x00dev);int rt2x00queue_initialize (struct rt2x00_dev *rt2x00dev);
drivers/net/wireless/rt2x00/rt2x00mac.c +2 -5
@@ -89,7 +89,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,memset (skbdesc,0 ,sizeof (*skbdesc)); skbdesc->flags |=FRAME_DESC_DRIVER_GENERATED ; -if (rt2x00dev->ops->lib->write_tx_data (rt2x00dev, queue, skb)) { +if (rt2x00queue_write_tx_frame (queue, skb)) {WARNING (rt2x00dev,"Failed to send RTS/CTS frame.\n" );return NETDEV_TX_BUSY ; }
@@ -158,7 +158,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) } } -if (rt2x00dev->ops->lib->write_tx_data (rt2x00dev, queue, skb)) { +if (rt2x00queue_write_tx_frame (queue, skb)) {ieee80211_stop_queue (rt2x00dev->hw, qid);return NETDEV_TX_BUSY ; }
@@ -166,9 +166,6 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)if (rt2x00queue_full (queue))ieee80211_stop_queue (rt2x00dev->hw, qid); -if (rt2x00dev->ops->lib->kick_tx_queue) - rt2x00dev->ops->lib->kick_tx_queue (rt2x00dev, qid); -return NETDEV_TX_OK ; }EXPORT_SYMBOL_GPL (rt2x00mac_tx);
drivers/net/wireless/rt2x00/rt2x00pci.c +16 -27
74 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt2x00pci.h +7 -4
@@ -87,11 +87,14 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,memcpy_toio (rt2x00dev->csr.base + offset, value, length); } -/* -* TX data handlers. +/** +* rt2x00pci_write_tx_data - Initialize data for TX operation +* @entry: The entry where the frame is located +* +* This function will initialize the DMA and skb descriptor +* to prepare the entry for the actual TX operation. */ -int rt2x00pci_write_tx_data (struct rt2x00_dev *rt2x00dev, -struct data_queue *queue,struct sk_buff *skb); +int rt2x00pci_write_tx_data (struct queue_entry *entry);/** * struct queue_entry_priv_pci: Per entry PCI specific information
drivers/net/wireless/rt2x00/rt2x00queue.c +37 -0
@@ -188,6 +188,43 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, }EXPORT_SYMBOL_GPL (rt2x00queue_write_tx_descriptor); +int rt2x00queue_write_tx_frame (struct data_queue *queue,struct sk_buff *skb) +{ +struct queue_entry *entry =rt2x00queue_get_entry (queue,Q_INDEX ); +struct txentry_desc txdesc; + +if (unlikely (rt2x00queue_full (queue))) +return -EINVAL ; + +if (__test_and_set_bit (ENTRY_OWNER_DEVICE_DATA , &entry->flags)) { +ERROR (queue->rt2x00dev, +"Arrived at non-free entry in the non-full queue %d.\n" +"Please file bug report to %s.\n" , + queue->qid,DRV_PROJECT ); +return -EINVAL ; + } + +/* +* Copy all TX descriptor information into txdesc, +* after that we are free to use the skb->cb array +* for our information. +*/ + entry->skb = skb; +rt2x00queue_create_tx_descriptor (entry, &txdesc); + +if (unlikely (queue->rt2x00dev->ops->lib->write_tx_data (entry))) { +__clear_bit (ENTRY_OWNER_DEVICE_DATA , &entry->flags); +return -EIO ; + } + +__set_bit (ENTRY_DATA_PENDING , &entry->flags); + +rt2x00queue_index_inc (queue,Q_INDEX ); +rt2x00queue_write_tx_descriptor (entry, &txdesc); + +return 0 ; +} +struct data_queue *rt2x00queue_get_queue (struct rt2x00_dev *rt2x00dev,const enum data_queue_qid queue) {
drivers/net/wireless/rt2x00/rt2x00usb.c +14 -43
85 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt2x00usb.h +7 -4
@@ -212,11 +212,14 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev,*/ void rt2x00usb_disable_radio (struct rt2x00_dev *rt2x00dev); -/* -* TX data handlers. +/** +* rt2x00usb_write_tx_data - Initialize URB for TX operation +* @entry: The entry where the frame is located +* +* This function will initialize the URB and skb descriptor +* to prepare the entry for the actual TX operation. */ -int rt2x00usb_write_tx_data (struct rt2x00_dev *rt2x00dev, -struct data_queue *queue,struct sk_buff *skb); +int rt2x00usb_write_tx_data (struct queue_entry *entry);/** * struct queue_entry_priv_usb: Per entry USB specific information
Signature · 1 line
1.5.5.3
PATCH 3/10 rt2x00: Don't kick TX queue after each frame
TX queues shouldn't be kicked after each frame that is put into the queue. This could cause problems during RTS and CTS-to-self as well as with fragmentation. In all those cases you want all frames to be send out in a single burst. Off course we shouldn't let the queue fill up entirely, thus we introduce a 10% threshold which, when reached, will force the frames to be send out regardless of the frame.
In addition we should prevent queues to become full in such a way that the tx() handler can fail. Instead of stopping the queue when it is full, we should stop it when it is below the threshold.
--- drivers/net/wireless/rt2x00/rt2400pci.c | 1 - drivers/net/wireless/rt2x00/rt2500pci.c | 1 - drivers/net/wireless/rt2x00/rt2500usb.c | 1 - drivers/net/wireless/rt2x00/rt2x00.h | 2 +- drivers/net/wireless/rt2x00/rt2x00mac.c | 10 +--------- drivers/net/wireless/rt2x00/rt2x00pci.c | 6 +++--- drivers/net/wireless/rt2x00/rt2x00queue.c | 28 +++++++++++++++++----------- drivers/net/wireless/rt2x00/rt2x00queue.h | 19 ++++++++++++++----- drivers/net/wireless/rt2x00/rt2x00usb.c | 6 +++--- drivers/net/wireless/rt2x00/rt61pci.c | 1 - drivers/net/wireless/rt2x00/rt73usb.c | 1 - 11 files changed, 39 insertions(+), 37 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +0 -1
@@ -1507,7 +1507,6 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)*/ skbdesc =get_skb_frame_desc (skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->flags |=FRAME_DESC_DRIVER_GENERATED ; skbdesc->data = skb->data; skbdesc->data_len = skb->len; skbdesc->desc = entry_priv->desc;
drivers/net/wireless/rt2x00/rt2500pci.c +0 -1
@@ -1823,7 +1823,6 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)*/ skbdesc =get_skb_frame_desc (skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->flags |=FRAME_DESC_DRIVER_GENERATED ; skbdesc->data = skb->data; skbdesc->data_len = skb->len; skbdesc->desc = entry_priv->desc;
drivers/net/wireless/rt2x00/rt2500usb.c +0 -1
@@ -1711,7 +1711,6 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)*/ skbdesc =get_skb_frame_desc (skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->flags |=FRAME_DESC_DRIVER_GENERATED ; skbdesc->data = skb->data + intf->beacon->queue->desc_size; skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; skbdesc->desc = skb->data;
drivers/net/wireless/rt2x00/rt2x00.h +1 -1
@@ -826,7 +826,7 @@ struct rt2x00_dev {* The Beacon array also contains the Atim queue * if that is supported by the device. */ -int data_queues; +unsigned int data_queues;struct data_queue *rx;struct data_queue *tx;struct data_queue *bcn;
drivers/net/wireless/rt2x00/rt2x00mac.c +1 -9
@@ -34,7 +34,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, struct sk_buff *frag_skb) {struct ieee80211_tx_info *tx_info =IEEE80211_SKB_CB (frag_skb); -struct skb_frame_desc *skbdesc;struct ieee80211_tx_info *rts_info;struct sk_buff *skb;int size;
@@ -82,13 +81,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, frag_skb->data, size, tx_info, (struct ieee80211_rts *)(skb->data)); -/* -* Initialize skb descriptor -*/ - skbdesc =get_skb_frame_desc (skb); -memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->flags |=FRAME_DESC_DRIVER_GENERATED ; -if (rt2x00queue_write_tx_frame (queue, skb)) {WARNING (rt2x00dev,"Failed to send RTS/CTS frame.\n" );return NETDEV_TX_BUSY ;
@@ -163,7 +155,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)return NETDEV_TX_BUSY ; } -if (rt2x00queue_full (queue)) +if (rt2x00queue_threshold (queue))ieee80211_stop_queue (rt2x00dev->hw, qid);return NETDEV_TX_OK ;
drivers/net/wireless/rt2x00/rt2x00pci.c +3 -3
@@ -170,11 +170,11 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,rt2x00queue_index_inc (entry->queue,Q_INDEX_DONE );/* -* If the data queue was full before the txdone handler -* we must make sure the packet queue in the mac80211 stack +* If the data queue was below the threshold before the txdone +* handler we must make sure the packet queue in the mac80211 stack * is reenabled when the txdone handler has finished. */ -if (!rt2x00queue_full (entry->queue)) +if (!rt2x00queue_threshold (entry->queue))ieee80211_wake_queue (rt2x00dev->hw, qid); }
drivers/net/wireless/rt2x00/rt2x00queue.c +17 -11
@@ -163,8 +163,8 @@ EXPORT_SYMBOL_GPL(rt2x00queue_create_tx_descriptor);void rt2x00queue_write_tx_descriptor (struct queue_entry *entry,struct txentry_desc *txdesc) { -struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; -struct skb_frame_desc *skbdesc =get_skb_frame_desc (entry->skb); +struct data_queue *queue = entry->queue; +struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; rt2x00dev->ops->lib->write_tx_desc (rt2x00dev, entry->skb, txdesc);
@@ -175,16 +175,21 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,rt2x00debug_dump_frame (rt2x00dev,DUMP_FRAME_TX , entry->skb);/* -* We are done writing the frame to the queue entry, -* also kick the queue in case the correct flags are set, -* note that this will automatically filter beacons and -* RTS/CTS frames since those frames don't have this flag -* set. +* Check if we need to kick the queue, there are however a few rules +* 1) Don't kick beacon queue +* 2) Don't kick unless this is the last in frame in a burst. +* When the burst flag is set, this frame is always followed +* by another frame which in some way are related to eachother. +* This is true for fragments, RTS or CTS-to-self frames. +* 3) Rule 2 can be broken when the available entries +* in the queue are less then a certain threshold. */ -if (rt2x00dev->ops->lib->kick_tx_queue && - !(skbdesc->flags &FRAME_DESC_DRIVER_GENERATED )) - rt2x00dev->ops->lib->kick_tx_queue (rt2x00dev, - entry->queue->qid); +if (entry->queue->qid ==QID_BEACON ) +return ; + +if (rt2x00queue_threshold (queue) || + !test_bit (ENTRY_TXD_BURST , &txdesc->flags)) + rt2x00dev->ops->lib->kick_tx_queue (rt2x00dev, queue->qid); }EXPORT_SYMBOL_GPL (rt2x00queue_write_tx_descriptor);
@@ -349,6 +354,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,rt2x00queue_reset (queue); queue->limit = qdesc->entry_num; + queue->threshold =DIV_ROUND_UP (qdesc->entry_num,10 ); queue->data_size = qdesc->data_size; queue->desc_size = qdesc->desc_size;
drivers/net/wireless/rt2x00/rt2x00queue.h +14 -5
@@ -82,12 +82,10 @@ enum data_queue_qid {/** * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc * -* @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver -* and should not be reported back to mac80211 during txdone. */ -enum skb_frame_desc_flags { -FRAME_DESC_DRIVER_GENERATED =1 <<0 , -}; +//enum skb_frame_desc_flags { +// TEMPORARILY EMPTY +//}; /** * struct skb_frame_desc: Descriptor information for the skb buffer
@@ -325,6 +323,7 @@ enum queue_index {* index corruption due to concurrency. * @count: Number of frames handled in the queue. * @limit: Maximum number of entries in the queue. +* @threshold: Minimum number of free entries before queue is kicked by force. * @length: Number of frames in queue. * @index: Index pointers to entry positions in the queue, * use &enum queue_index to get a specific index field.
@@ -343,6 +342,7 @@ struct data_queue {spinlock_t lock;unsigned int count;unsigned short limit; +unsigned short threshold;unsigned short length;unsigned short index[Q_INDEX_MAX ];
@@ -467,6 +467,15 @@ static inline int rt2x00queue_available(struct data_queue *queue) }/** +* rt2x00queue_threshold - Check if the queue is below threshold +* @queue: Queue to check. +*/ +static inline int rt2x00queue_threshold (struct data_queue *queue) +{ +return rt2x00queue_available (queue) < queue->threshold; +} + +/** * rt2x00_desc_read - Read a word from the hardware descriptor. * @desc: Base descriptor address * @word: Word index from where the descriptor should be read.
drivers/net/wireless/rt2x00/rt2x00usb.c +3 -3
@@ -165,11 +165,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)rt2x00queue_index_inc (entry->queue,Q_INDEX_DONE );/* -* If the data queue was full before the txdone handler -* we must make sure the packet queue in the mac80211 stack +* If the data queue was below the threshold before the txdone +* handler we must make sure the packet queue in the mac80211 stack * is reenabled when the txdone handler has finished. */ -if (!rt2x00queue_full (entry->queue)) +if (!rt2x00queue_threshold (entry->queue))ieee80211_wake_queue (rt2x00dev->hw, qid); }
drivers/net/wireless/rt2x00/rt61pci.c +0 -1
@@ -2375,7 +2375,6 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)*/ skbdesc =get_skb_frame_desc (skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->flags |=FRAME_DESC_DRIVER_GENERATED ; skbdesc->data = skb->data; skbdesc->data_len = skb->len; skbdesc->desc = entry_priv->desc;
drivers/net/wireless/rt2x00/rt73usb.c +0 -1
@@ -1980,7 +1980,6 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)*/ skbdesc =get_skb_frame_desc (skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->flags |=FRAME_DESC_DRIVER_GENERATED ; skbdesc->data = skb->data + intf->beacon->queue->desc_size; skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; skbdesc->desc = skb->data;
Signature · 1 line
1.5.5.3
PATCH 4/10 rt2x00: Cleanup struct skb_frame_desc.
From: Gertjan van Wingerde <[email protected]>
The data and data_len fields aren't really necessary in struct skb_frame_desc, as they can be deduced from the skb itself.
--- drivers/net/wireless/rt2x00/rt2400pci.c | 6 ++---- drivers/net/wireless/rt2x00/rt2500pci.c | 2 -- drivers/net/wireless/rt2x00/rt2500usb.c | 7 ++----- drivers/net/wireless/rt2x00/rt2x00debug.c | 6 +++--- drivers/net/wireless/rt2x00/rt2x00pci.c | 4 ---- drivers/net/wireless/rt2x00/rt2x00queue.h | 5 +---- drivers/net/wireless/rt2x00/rt2x00usb.c | 3 --- drivers/net/wireless/rt2x00/rt61pci.c | 8 +++----- drivers/net/wireless/rt2x00/rt73usb.c | 7 ++----- 9 files changed, 13 insertions(+), 35 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +2 -4
@@ -1016,8 +1016,8 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,rt2x00_desc_write (entry_priv->desc,1 , word);rt2x00_desc_read (txd,2 , &word); -rt2x00_set_field32 (&word,TXD_W2_BUFFER_LENGTH , skbdesc->data_len); -rt2x00_set_field32 (&word,TXD_W2_DATABYTE_COUNT , skbdesc->data_len); +rt2x00_set_field32 (&word,TXD_W2_BUFFER_LENGTH , skb->len); +rt2x00_set_field32 (&word,TXD_W2_DATABYTE_COUNT , skb->len);rt2x00_desc_write (txd,2 , word);rt2x00_desc_read (txd,3 , &word);
@@ -1507,8 +1507,6 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)*/ skbdesc =get_skb_frame_desc (skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->data = skb->data; - skbdesc->data_len = skb->len; skbdesc->desc = entry_priv->desc; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon;
drivers/net/wireless/rt2x00/rt2500pci.c +0 -2
@@ -1823,8 +1823,6 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)*/ skbdesc =get_skb_frame_desc (skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->data = skb->data; - skbdesc->data_len = skb->len; skbdesc->desc = entry_priv->desc; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon;
drivers/net/wireless/rt2x00/rt2500usb.c +2 -5
@@ -1088,7 +1088,8 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,rt2x00_set_field32 (&word,TXD_W0_NEW_SEQ ,test_bit (ENTRY_TXD_FIRST_FRAGMENT , &txdesc->flags));rt2x00_set_field32 (&word,TXD_W0_IFS , txdesc->ifs); -rt2x00_set_field32 (&word,TXD_W0_DATABYTE_COUNT , skbdesc->data_len); +rt2x00_set_field32 (&word,TXD_W0_DATABYTE_COUNT , + skb->len - skbdesc->desc_len);rt2x00_set_field32 (&word,TXD_W0_CIPHER ,CIPHER_NONE );rt2x00_desc_write (txd,0 , word); }
@@ -1196,8 +1197,6 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,* Adjust the skb memory window to the frame boundaries. */ skb_trim (entry->skb, rxdesc->size); - skbdesc->data = entry->skb->data; - skbdesc->data_len = rxdesc->size; }/*
@@ -1711,8 +1710,6 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)*/ skbdesc =get_skb_frame_desc (skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->data = skb->data + intf->beacon->queue->desc_size; - skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; skbdesc->desc = skb->data; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon;
drivers/net/wireless/rt2x00/rt2x00debug.c +3 -3
@@ -133,7 +133,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,return ; } - skbcopy =alloc_skb (sizeof (*dump_hdr) + desc->desc_len + desc->data_len, + skbcopy =alloc_skb (sizeof (*dump_hdr) + desc->desc_len + skb->len,GFP_ATOMIC );if (!skbcopy) {DEBUG (rt2x00dev,"Failed to copy skb for dump.\n" );
@@ -144,7 +144,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, dump_hdr->version =cpu_to_le32 (DUMP_HEADER_VERSION ); dump_hdr->header_length =cpu_to_le32 (sizeof (*dump_hdr)); dump_hdr->desc_length =cpu_to_le32 (desc->desc_len); - dump_hdr->data_length =cpu_to_le32 (desc->data_len); + dump_hdr->data_length =cpu_to_le32 (skb->len); dump_hdr->chip_rt =cpu_to_le16 (rt2x00dev->chip.rt); dump_hdr->chip_rf =cpu_to_le16 (rt2x00dev->chip.rf); dump_hdr->chip_rev =cpu_to_le32 (rt2x00dev->chip.rev);
@@ -155,7 +155,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, dump_hdr->timestamp_usec =cpu_to_le32 (timestamp.tv_usec);memcpy (skb_put (skbcopy, desc->desc_len), desc->desc, desc->desc_len); -memcpy (skb_put (skbcopy, desc->data_len), desc->data, desc->data_len); +memcpy (skb_put (skbcopy, skb->len), skb->data, skb->len);skb_queue_tail (&intf->frame_dump_skbqueue, skbcopy);wake_up_interruptible (&intf->frame_dump_waitqueue);
drivers/net/wireless/rt2x00/rt2x00pci.c +0 -4
@@ -61,8 +61,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry)*/ skbdesc =get_skb_frame_desc (entry->skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->data = entry->skb->data; - skbdesc->data_len = entry->skb->len; skbdesc->desc = entry_priv->desc; skbdesc->desc_len = entry->queue->desc_size; skbdesc->entry = entry;
@@ -126,8 +124,6 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)*/ skbdesc =get_skb_frame_desc (entry->skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->data = entry->skb->data; - skbdesc->data_len = entry->skb->len; skbdesc->desc = entry_priv->desc; skbdesc->desc_len = queue->desc_size; skbdesc->entry = entry;
drivers/net/wireless/rt2x00/rt2x00queue.h +1 -4
@@ -105,11 +105,8 @@ enum data_queue_qid {struct skb_frame_desc {unsigned int flags; -unsigned short data_len; -unsigned short desc_len; - -void *data;void *desc; +unsigned int desc_len;struct queue_entry *entry; };
drivers/net/wireless/rt2x00/rt2x00usb.c +0 -3
@@ -192,8 +192,6 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry)*/ skbdesc =get_skb_frame_desc (entry->skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->data = entry->skb->data + entry->queue->desc_size; - skbdesc->data_len = entry->skb->len - entry->queue->desc_size; skbdesc->desc = entry->skb->data; skbdesc->desc_len = entry->queue->desc_size; skbdesc->entry = entry;
@@ -352,7 +350,6 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) }/* Update data pointers, trim buffer to correct size */ - skbdesc->data = entry->skb->data;skb_trim (entry->skb, rxdesc.size);/*
drivers/net/wireless/rt2x00/rt61pci.c +3 -5
@@ -1562,7 +1562,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,if (skbdesc->desc_len >TXINFO_SIZE ) {rt2x00_desc_read (txd,11 , &word); -rt2x00_set_field32 (&word,TXD_W11_BUFFER_LENGTH0 , skbdesc->data_len); +rt2x00_set_field32 (&word,TXD_W11_BUFFER_LENGTH0 , skb->len);rt2x00_desc_write (txd,11 , word); }
@@ -1581,7 +1581,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,rt2x00_set_field32 (&word,TXD_W0_RETRY_MODE ,test_bit (ENTRY_TXD_RETRY_MODE , &txdesc->flags));rt2x00_set_field32 (&word,TXD_W0_TKIP_MIC ,0 ); -rt2x00_set_field32 (&word,TXD_W0_DATABYTE_COUNT , skbdesc->data_len); +rt2x00_set_field32 (&word,TXD_W0_DATABYTE_COUNT , skb->len);rt2x00_set_field32 (&word,TXD_W0_BURST ,test_bit (ENTRY_TXD_BURST , &txdesc->flags));rt2x00_set_field32 (&word,TXD_W0_CIPHER_ALG ,CIPHER_NONE );
@@ -2375,8 +2375,6 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)*/ skbdesc =get_skb_frame_desc (skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->data = skb->data; - skbdesc->data_len = skb->len; skbdesc->desc = entry_priv->desc; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon;
@@ -2401,7 +2399,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) skbdesc->desc, skbdesc->desc_len);rt2x00pci_register_multiwrite (rt2x00dev, beacon_base + skbdesc->desc_len, - skbdesc->data, skbdesc->data_len); + skb->data, skb->len);rt61pci_kick_tx_queue (rt2x00dev,QID_BEACON );return 0 ;
drivers/net/wireless/rt2x00/rt73usb.c +2 -5
@@ -1320,7 +1320,8 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,rt2x00_set_field32 (&word,TXD_W0_RETRY_MODE ,test_bit (ENTRY_TXD_RETRY_MODE , &txdesc->flags));rt2x00_set_field32 (&word,TXD_W0_TKIP_MIC ,0 ); -rt2x00_set_field32 (&word,TXD_W0_DATABYTE_COUNT , skbdesc->data_len); +rt2x00_set_field32 (&word,TXD_W0_DATABYTE_COUNT , + skb->len - skbdesc->desc_len);rt2x00_set_field32 (&word,TXD_W0_BURST2 ,test_bit (ENTRY_TXD_BURST , &txdesc->flags));rt2x00_set_field32 (&word,TXD_W0_CIPHER_ALG ,CIPHER_NONE );
@@ -1466,8 +1467,6 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,*/ skb_pull (entry->skb, entry->queue->desc_size);skb_trim (entry->skb, rxdesc->size); - skbdesc->data = entry->skb->data; - skbdesc->data_len = rxdesc->size; }/*
@@ -1980,8 +1979,6 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)*/ skbdesc =get_skb_frame_desc (skb);memset (skbdesc,0 ,sizeof (*skbdesc)); - skbdesc->data = skb->data + intf->beacon->queue->desc_size; - skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; skbdesc->desc = skb->data; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon;
Signature · 1 line
1.5.5.3
PATCH 5/10 rt2x00: Centralize RX packet alignment handling in rt2x00lib.
From: Gertjan van Wingerde <[email protected]>
When rt2x00pci will be switched over to dynamically mapped skb's instead of statically allocated DMA buffers, it no longer can handle alignment of RX packets in a copy step, and needs to implement the same scheme as rt2x00usb does.
In order to make the patch on dynamically mapped skb's smaller, already centralize the alignment handling into rt2x00lib. This allows us to move more code in rt2x00lib, and thus remove code duplication between rt2x00usb and rt2x00pci.
--- drivers/net/wireless/rt2x00/rt2x00.h | 6 +++ drivers/net/wireless/rt2x00/rt2x00dev.c | 22 ++++++++++ drivers/net/wireless/rt2x00/rt2x00pci.c | 23 ++--------- drivers/net/wireless/rt2x00/rt2x00queue.c | 39 ++++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00usb.c | 63 +--------------------------- 5 files changed, 74 insertions(+), 79 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +6 -0
@@ -930,6 +930,12 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) }/** +* rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. +* @queue: The queue for which the skb will be applicable. +*/ +struct sk_buff *rt2x00queue_alloc_rxskb (struct data_queue *queue); + +/** * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input * @entry: The entry which will be used to transfer the TX frame. * @txdesc: rt2x00 TX descriptor which will be initialized by this function.
drivers/net/wireless/rt2x00/rt2x00dev.c +22 -0
@@ -554,14 +554,36 @@ void rt2x00lib_rxdone(struct queue_entry *entry, {struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; +unsigned int header_size =ieee80211_get_hdrlen_from_skb (entry->skb);struct ieee80211_supported_band *sband;struct ieee80211_hdr *hdr;const struct rt2x00_rate *rate; +unsigned int align;unsigned int i;int idx =-1 ;u16 fc;/* +* The data behind the ieee80211 header must be +* aligned on a 4 byte boundary. We already reserved +* 2 bytes for header_size % 4 == 2 optimization. +* To determine the number of bytes which the data +* should be moved to the left, we must add these +* 2 bytes to the header_size. +*/ + align = (header_size +2 ) %4 ; + +if (align) { +skb_push (entry->skb, align); +/* Move entire frame in 1 command */ +memmove (entry->skb->data, entry->skb->data + align, + rxdesc->size); + } + +/* Update data pointers, trim buffer to correct size */ +skb_trim (entry->skb, rxdesc->size); + +/* * Update RX statistics. */ sband = &rt2x00dev->bands[rt2x00dev->curr_band];
drivers/net/wireless/rt2x00/rt2x00pci.c +4 -19
@@ -79,11 +79,8 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)struct data_queue *queue = rt2x00dev->rx;struct queue_entry *entry;struct queue_entry_priv_pci *entry_priv; -struct ieee80211_hdr *hdr;struct skb_frame_desc *skbdesc;struct rxdone_entry_desc rxdesc; -int header_size; -int align;u32 word;while (1 ) {
@@ -97,27 +94,15 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)memset (&rxdesc,0 ,sizeof (rxdesc)); rt2x00dev->ops->lib->fill_rxdone (entry, &rxdesc); - hdr = (struct ieee80211_hdr *)entry_priv->data; - header_size = -ieee80211_get_hdrlen (le16_to_cpu (hdr->frame_control)); - -/* -* The data behind the ieee80211 header must be -* aligned on a 4 byte boundary. -*/ - align = header_size %4 ; -/* -* Allocate the sk_buffer, initialize it and copy -* all data into it. +* Allocate the sk_buffer and copy all data into it. */ - entry->skb =dev_alloc_skb (rxdesc.size + align); + entry->skb =rt2x00queue_alloc_rxskb (queue);if (!entry->skb)return ; -skb_reserve (entry->skb, align); -memcpy (skb_put (entry->skb, rxdesc.size), - entry_priv->data, rxdesc.size); +memcpy (entry->skb->data, entry_priv->data, rxdesc.size); +skb_trim (entry->skb, rxdesc.size);/* * Fill in skb descriptor
drivers/net/wireless/rt2x00/rt2x00queue.c +39 -0
@@ -29,6 +29,45 @@#include "rt2x00.h" #include "rt2x00lib.h" +struct sk_buff *rt2x00queue_alloc_rxskb (struct data_queue *queue) +{ +struct sk_buff *skb; +unsigned int frame_size; +unsigned int reserved_size; + +/* +* The frame size includes descriptor size, because the +* hardware directly receive the frame into the skbuffer. +*/ + frame_size = queue->data_size + queue->desc_size; + +/* +* For the allocation we should keep a few things in mind: +* 1) 4byte alignment of 802.11 payload +* +* For (1) we need at most 4 bytes to guarentee the correct +* alignment. We are going to optimize the fact that the chance +* that the 802.11 header_size % 4 == 2 is much bigger then +* anything else. However since we need to move the frame up +* to 3 bytes to the front, which means we need to preallocate +* 6 bytes. +*/ + reserved_size =6 ; + +/* +* Allocate skbuffer. +*/ + skb =dev_alloc_skb (frame_size + reserved_size); +if (!skb) +return NULL ; + +skb_reserve (skb, reserved_size); +skb_put (skb, frame_size); + +return skb; +} +EXPORT_SYMBOL_GPL (rt2x00queue_alloc_rxskb); +void rt2x00queue_create_tx_descriptor (struct queue_entry *entry,struct txentry_desc *txdesc) {
drivers/net/wireless/rt2x00/rt2x00usb.c +3 -60
95 lines not on this page · raw message
Signature · 1 line
1.5.5.3
PATCH 6/10 rt2x00: Fix double usage of skb->cb in USB RX path.
From: Gertjan van Wingerde <[email protected]>
It is not safe to use the skb->cb area for both the rxd and skb_frame_desc data at the same time, while they occupy an overlapping piece of memory. This can lead to hard to trace crashes as pointers within skb_frame_desc are pointing into nowhere, or the rxd data is overwritten with non-sense.
Fix it by copying the rxd to a small buffer on the stack.
--- drivers/net/wireless/rt2x00/rt2500usb.c | 10 +++------- drivers/net/wireless/rt2x00/rt2x00usb.c | 8 +++----- drivers/net/wireless/rt2x00/rt73usb.c | 10 +++------- 3 files changed, 9 insertions(+), 19 deletions(-)
drivers/net/wireless/rt2x00/rt2500usb.c +3 -7
@@ -1156,14 +1156,10 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,u32 word1;/* -* Copy descriptor to the skb->cb array, this has 2 benefits: -* 1) Each descriptor word is 4 byte aligned. -* 2) Descriptor is safe from moving of frame data in rt2x00usb. +* Copy descriptor to the skbdesc->desc buffer, making it safe from moving of +* frame data in rt2x00usb. */ - skbdesc->desc_len = -min_t (u16, entry->queue->desc_size,sizeof (entry->skb->cb)); -memcpy (entry->skb->cb, rxd, skbdesc->desc_len); - skbdesc->desc = entry->skb->cb; +memcpy (skbdesc->desc, rxd, skbdesc->desc_len); rxd = (__le32 *)skbdesc->desc;/*
drivers/net/wireless/rt2x00/rt2x00usb.c +3 -5
@@ -267,6 +267,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)struct sk_buff *skb;struct skb_frame_desc *skbdesc;struct rxdone_entry_desc rxdesc; +u8 rxd[32 ];if (!test_bit (DEVICE_ENABLED_RADIO , &rt2x00dev->flags) || !test_and_clear_bit (ENTRY_OWNER_DEVICE_DATA , &entry->flags))
@@ -286,16 +287,13 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) skbdesc =get_skb_frame_desc (entry->skb);memset (skbdesc,0 ,sizeof (*skbdesc)); skbdesc->entry = entry; + skbdesc->desc = rxd; + skbdesc->desc_len = entry->queue->desc_size;memset (&rxdesc,0 ,sizeof (rxdesc)); rt2x00dev->ops->lib->fill_rxdone (entry, &rxdesc);/* -* Trim the skb to the correct size. -*/ -skb_trim (entry->skb, rxdesc.size); - -/* * Allocate a new sk buffer to replace the current one. * If allocation fails, we should drop the current frame * so we can recycle the existing sk buffer for the new frame.
drivers/net/wireless/rt2x00/rt73usb.c +3 -7
@@ -1428,14 +1428,10 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,u32 word1;/* -* Copy descriptor to the skb->cb array, this has 2 benefits: -* 1) Each descriptor word is 4 byte aligned. -* 2) Descriptor is safe from moving of frame data in rt2x00usb. +* Copy descriptor to the skbdesc->desc buffer, making it safe from moving of +* frame data in rt2x00usb. */ - skbdesc->desc_len = -min_t (u16, entry->queue->desc_size,sizeof (entry->skb->cb)); -memcpy (entry->skb->cb, rxd, skbdesc->desc_len); - skbdesc->desc = entry->skb->cb; +memcpy (skbdesc->desc, rxd, skbdesc->desc_len); rxd = (__le32 *)skbdesc->desc;/*
Signature · 1 line
1.5.5.3
PATCH 7/10 rt2x00: Use __builtin_choose_expr() instead of ?:
To really force the FIELD macros to determine
the first bit of the register field we should
use the __builtin_choose_expr() function.
--- drivers/net/wireless/rt2x00/rt2x00reg.h | 22 +++++++++++++--------- 1 files changed, 13 insertions(+), 9 deletions(-)
drivers/net/wireless/rt2x00/rt2x00reg.h +13 -9
@@ -145,23 +145,27 @@ struct rt2x00_field32 {* compile-time rather then run-time. */ #define compile_ffs2 (__x) \ - ( ((__x) & 0x1) ? 0 : 1 ) + __builtin_choose_expr(((__x) & 0x1), 0, 1)#define compile_ffs4 (__x) \ - ( ((__x) & 0x3) ? \ - compile_ffs2(__x) : (compile_ffs2((__x) >> 2) + 2) ) + __builtin_choose_expr(((__x) & 0x3), \ + (compile_ffs2((__x))), \ + (compile_ffs2((__x) >> 2) + 2))#define compile_ffs8 (__x) \ - ( ((__x) & 0xf) ? \ - compile_ffs4(__x) : (compile_ffs4((__x) >> 4) + 4) ) + __builtin_choose_expr(((__x) & 0xf), \ + (compile_ffs4((__x))), \ + (compile_ffs4((__x) >> 4) + 4))#define compile_ffs16 (__x) \ - ( ((__x) & 0xff) ? \ - compile_ffs8(__x) : (compile_ffs8((__x) >> 8) + 8) ) + __builtin_choose_expr(((__x) & 0xff), \ + (compile_ffs8((__x))), \ + (compile_ffs8((__x) >> 8) + 8))#define compile_ffs32 (__x) \ - ( ((__x) & 0xffff) ? \ - compile_ffs16(__x) : (compile_ffs16((__x) >> 16) + 16) ) + __builtin_choose_expr(((__x) & 0xffff), \ + (compile_ffs16((__x))), \ + (compile_ffs16((__x) >> 16) + 16))/* * This macro will check the requirements for the FIELD{8,16,32} macros
Signature · 1 line
1.5.5.3
PATCH 8/10 rt2x00: Clear IEEE80211_TX_CTL_USE_RTS_CTS flag for RTS frame
Quoted 1 line
From
2106feb725364f592646a5b1790fcb9e25238601Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <[email protected]>
Date: Sat, 7 Jun 2008 12:29:05 +0200
Subject: [PATCH] rt2x00: Clear IEEE80211_TX_CTL_USE_RTS_CTS flag for RTS frame
For RTS/CTS-to-self frames the IEEE80211_TX_CTL_USE_RTS_CTS flag should be cleared for the tx_info flags.
--- drivers/net/wireless/rt2x00/rt2x00mac.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/net/wireless/rt2x00/rt2x00mac.c +1 -0
@@ -64,6 +64,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,memcpy (skb->cb, frag_skb->cb,sizeof (skb->cb)); rts_info =IEEE80211_SKB_CB (skb); rts_info->flags |=IEEE80211_TX_CTL_DO_NOT_ENCRYPT ; + rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS ; rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT ; rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS ;
Signature · 1 line
1.5.5.3
Re: [PATCH 09/10] rt2x00: Remove unused defines
MAX_RX_SSI and MAX_NOISE are no longer used,
it is better to remove them entirely.
--- drivers/net/wireless/rt2x00/rt2400pci.h | 2 -- drivers/net/wireless/rt2x00/rt2500pci.h | 2 -- drivers/net/wireless/rt2x00/rt2500usb.h | 2 -- drivers/net/wireless/rt2x00/rt61pci.h | 2 -- drivers/net/wireless/rt2x00/rt73usb.h | 2 -- 5 files changed, 0 insertions(+), 10 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.h +0 -2
@@ -37,8 +37,6 @@* Signal information. * Defaul offset is required for RSSI <-> dBm conversion. */ -#define MAX_SIGNAL 100 -#define MAX_RX_SSI -1#define DEFAULT_RSSI_OFFSET 100/*
drivers/net/wireless/rt2x00/rt2500pci.h +0 -2
@@ -48,8 +48,6 @@* Signal information. * Defaul offset is required for RSSI <-> dBm conversion. */ -#define MAX_SIGNAL 100 -#define MAX_RX_SSI -1#define DEFAULT_RSSI_OFFSET 121/*
drivers/net/wireless/rt2x00/rt2500usb.h +0 -2
@@ -48,8 +48,6 @@* Signal information. * Defaul offset is required for RSSI <-> dBm conversion. */ -#define MAX_SIGNAL 100 -#define MAX_RX_SSI -1#define DEFAULT_RSSI_OFFSET 120/*
drivers/net/wireless/rt2x00/rt61pci.h +0 -2
@@ -39,8 +39,6 @@* Signal information. * Defaul offset is required for RSSI <-> dBm conversion. */ -#define MAX_SIGNAL 100 -#define MAX_RX_SSI -1#define DEFAULT_RSSI_OFFSET 120/*
drivers/net/wireless/rt2x00/rt73usb.h +0 -2
@@ -39,8 +39,6 @@* Signal information. * Defaul offset is required for RSSI <-> dBm conversion. */ -#define MAX_SIGNAL 100 -#define MAX_RX_SSI -1#define DEFAULT_RSSI_OFFSET 120/*
Signature · 1 line
1.5.5.3
Re: [PATCH 10/10] rt2x00: Rework alignment check.
From: Gertjan van Wingerde <[email protected]>
Rework the alignment check in rt2x00dev.c to be independent of any potential alignment measures that may be taken before. Just check whether the payload is aligned based on the pointer addresses.
Note: This is preparatory for the dynamically mapped skb buffers for the PCI drivers, as these need 4-byte alignment instead of the currently enforced offset by 2 bytes.
--- drivers/net/wireless/rt2x00/rt2x00dev.c | 8 ++------ 1 files changed, 2 insertions(+), 6 deletions(-)
drivers/net/wireless/rt2x00/rt2x00dev.c +2 -6
@@ -565,13 +565,9 @@ void rt2x00lib_rxdone(struct queue_entry *entry,/* * The data behind the ieee80211 header must be -* aligned on a 4 byte boundary. We already reserved -* 2 bytes for header_size % 4 == 2 optimization. -* To determine the number of bytes which the data -* should be moved to the left, we must add these -* 2 bytes to the header_size. +* aligned on a 4 byte boundary. */ - align = (header_size +2 ) %4 ; + align = ((unsigned long )(entry->skb->data + header_size)) &3 ;if (align) {skb_push (entry->skb, align);
Signature · 1 line
1.5.5.3