rt2x00: simplify txstatus_fifo handling
PATCH 1/10 rt2x00: simplify txstatus_fifo handling
From: Johannes Stezenbach <[email protected]>
--- drivers/net/wireless/rt2x00/rt2800pci.c | 18 ++---------------- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- 2 files changed, 3 insertions(+), 17 deletions(-)
drivers/net/wireless/rt2x00/rt2800pci.c +2 -16
@@ -688,14 +688,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)u32 status;u8 qid; -while (!kfifo_is_empty (&rt2x00dev->txstatus_fifo)) { -/* Now remove the tx status from the FIFO */ -if (kfifo_out (&rt2x00dev->txstatus_fifo, &status, -sizeof (status)) !=sizeof (status)) { -WARN_ON (1 ); -break ; - } - +while (kfifo_get (&rt2x00dev->txstatus_fifo, &status)) { qid =rt2x00_get_field32 (status,TX_STA_FIFO_PID_QUEUE );if (qid >=QID_RX ) {/*
@@ -803,14 +796,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)if (!rt2x00_get_field32 (status,TX_STA_FIFO_VALID ))break ; -if (kfifo_is_full (&rt2x00dev->txstatus_fifo)) { -WARNING (rt2x00dev,"TX status FIFO overrun," -" drop tx status report.\n" ); -break ; - } - -if (kfifo_in (&rt2x00dev->txstatus_fifo, &status, -sizeof (status)) !=sizeof (status)) { +if (!kfifo_put (&rt2x00dev->txstatus_fifo, &status)) {WARNING (rt2x00dev,"TX status FIFO overrun," "drop tx status report.\n" );break ;
drivers/net/wireless/rt2x00/rt2x00.h +1 -1
@@ -908,7 +908,7 @@ struct rt2x00_dev {/* * FIFO for storing tx status reports between isr and tasklet. */ -struct kfifo txstatus_fifo; +DECLARE_KFIFO_PTR (txstatus_fifo, u32);/* * Tasklet for processing tx status reports (rt2800pci).
Signature · 1 line
1.7.2.3
PATCH 2/10 rt2x00: allow txstatus_fifo w/o txstatus_tasklet
From: Johannes Stezenbach <[email protected]>
When DRIVER_REQUIRE_TXSTATUS_FIFO is set, intialize the txstatus_fifo, but initialize rt2x00dev->txstatus_tasklet only when both DRIVER_REQUIRE_TXSTATUS_FIFO and rt2x00dev->ops->lib->txstatus_tasklet are set.
This allows the txstatus_fifo to be used by rt2800usb which does not use txstatus_tasklet.
--- drivers/net/wireless/rt2x00/rt2x00dev.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
drivers/net/wireless/rt2x00/rt2x00dev.c +5 -5
@@ -813,8 +813,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)/* * Allocate tx status FIFO for driver use. */ -if (test_bit (DRIVER_REQUIRE_TXSTATUS_FIFO , &rt2x00dev->flags) && - rt2x00dev->ops->lib->txstatus_tasklet) { +if (test_bit (DRIVER_REQUIRE_TXSTATUS_FIFO , &rt2x00dev->flags)) {/* * Allocate txstatus fifo and tasklet, we use a size of 512 * for the kfifo which is big enough to store 512/4=128 tx
@@ -828,9 +827,10 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)return status;/* tasklet for processing the tx status reports. */ -tasklet_init (&rt2x00dev->txstatus_tasklet, - rt2x00dev->ops->lib->txstatus_tasklet, - (unsigned long )rt2x00dev); +if (rt2x00dev->ops->lib->txstatus_tasklet) +tasklet_init (&rt2x00dev->txstatus_tasklet, + rt2x00dev->ops->lib->txstatus_tasklet, + (unsigned long )rt2x00dev); }
Signature · 1 line
1.7.2.3
PATCH 3/10 rt2x00: Remove intf->bssid field.
From: Gertjan van Wingerde <[email protected]>
The bssid field in struct rt2x00_intf is only written to once, and is never read from.
Remove this field, as it appears to not be needed.
--- drivers/net/wireless/rt2x00/rt2x00.h | 5 ----- drivers/net/wireless/rt2x00/rt2x00mac.c | 11 ----------- 2 files changed, 0 insertions(+), 16 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +0 -5
@@ -365,11 +365,6 @@ struct rt2x00_intf {u8 mac[ETH_ALEN ];/* -* BBSID of the AP to associate with. -*/ -u8 bssid[ETH_ALEN ]; - -/* * beacon->skb must be protected with the mutex. */ struct mutex beacon_skb_mutex;
drivers/net/wireless/rt2x00/rt2x00mac.c +0 -11
@@ -614,17 +614,6 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,if (!test_bit (DEVICE_STATE_PRESENT , &rt2x00dev->flags))return ; -spin_lock (&intf->lock); - -/* -* conf->bssid can be NULL if coming from the internal -* beacon update routine. -*/ -if (changes &BSS_CHANGED_BSSID ) -memcpy (&intf->bssid, bss_conf->bssid,ETH_ALEN ); - -spin_unlock (&intf->lock); -/* * Call rt2x00_config_intf() outside of the spinlock context since * the call will sleep for USB drivers. By using the ieee80211_if_conf
Signature · 1 line
1.7.2.3
PATCH 4/10 rt2x00: remove intf->mac field.
From: Gertjan van Wingerde <[email protected]>
The mac field of the rt2x00_intf structure is written to once and used twice. In both these uses the mac address is available via other means.
Remove this field as it does not appear to be necessary.
--- drivers/net/wireless/rt2x00/rt2x00.h | 5 ----- drivers/net/wireless/rt2x00/rt2x00mac.c | 6 ++---- 2 files changed, 2 insertions(+), 9 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +0 -5
@@ -360,11 +360,6 @@ struct rt2x00_intf {spinlock_t lock;/* -* MAC of the device. -*/ -u8 mac[ETH_ALEN ]; - -/* * beacon->skb must be protected with the mutex. */ struct mutex beacon_skb_mutex;
drivers/net/wireless/rt2x00/rt2x00mac.c +2 -4
@@ -282,9 +282,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,* STA interfaces at this time, since this can cause * invalid behavior in the device. */ -memcpy (&intf->mac, vif->addr,ETH_ALEN );rt2x00lib_config_intf (rt2x00dev, intf, vif->type, - intf->mac,NULL ); + vif->addr,NULL );/* * Some filters depend on the current working mode. We can force
@@ -492,7 +491,6 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key) {struct rt2x00_dev *rt2x00dev = hw->priv; -struct rt2x00_intf *intf =vif_to_intf (vif);int (*set_key) (struct rt2x00_dev *rt2x00dev,struct rt2x00lib_crypto *crypto,struct ieee80211_key_conf *key);
@@ -516,7 +514,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,if (rt2x00dev->intf_sta_count) crypto.bssidx =0 ;else - crypto.bssidx = intf->mac[5 ] & (rt2x00dev->ops->max_ap_intf -1 ); + crypto.bssidx = vif->addr[5 ] & (rt2x00dev->ops->max_ap_intf -1 ); crypto.cipher =rt2x00crypto_key_to_cipher (key);if (crypto.cipher ==CIPHER_NONE )
Signature · 1 line
1.7.2.3
PATCH 5/10 rt2x00: Fix pointer errors.
From: Gertjan van Wingerde <[email protected]>
Fix some pointer errors in the various calls to memcpy, memset and memmove.
Although none of these errors are fatal (the expression used now results in the same pointer value) it is better to use the proper expression. All errors are having to deal with arrays.
--- drivers/net/wireless/rt2x00/rt2x00config.c | 8 ++++---- drivers/net/wireless/rt2x00/rt2x00mac.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
drivers/net/wireless/rt2x00/rt2x00config.c +4 -4
@@ -62,13 +62,13 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,* This will prevent the device being confused when it wants * to ACK frames or consideres itself associated. */ -memset (&conf.mac,0 ,sizeof (conf.mac)); +memset (conf.mac,0 ,sizeof (conf.mac));if (mac) -memcpy (&conf.mac, mac,ETH_ALEN ); +memcpy (conf.mac, mac,ETH_ALEN ); -memset (&conf.bssid,0 ,sizeof (conf.bssid)); +memset (conf.bssid,0 ,sizeof (conf.bssid));if (bssid) -memcpy (&conf.bssid, bssid,ETH_ALEN ); +memcpy (conf.bssid, bssid,ETH_ALEN ); flags |=CONFIG_UPDATE_TYPE ;if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count))
drivers/net/wireless/rt2x00/rt2x00mac.c +4 -4
@@ -471,17 +471,17 @@ EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);static void memcpy_tkip (struct rt2x00lib_crypto *crypto,u8 *key,u8 key_len) {if (key_len >NL80211_TKIP_DATA_OFFSET_ENCR_KEY ) -memcpy (&crypto->key, +memcpy (crypto->key, &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY ],sizeof (crypto->key));if (key_len >NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY ) -memcpy (&crypto->tx_mic, +memcpy (crypto->tx_mic, &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY ],sizeof (crypto->tx_mic));if (key_len >NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY ) -memcpy (&crypto->rx_mic, +memcpy (crypto->rx_mic, &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY ],sizeof (crypto->rx_mic)); }
@@ -532,7 +532,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,if (crypto.cipher ==CIPHER_TKIP )memcpy_tkip (&crypto, &key->key[0 ], key->keylen);else -memcpy (&crypto.key, &key->key[0 ], key->keylen); +memcpy (crypto.key, &key->key[0 ], key->keylen);/* * Each BSS has a maximum of 4 shared keys. * Shared key index values:
Signature · 1 line
1.7.2.3
PATCH 6/10 rt2x00: Fix panic on frame padding for rt2800 usb devices
From: Ismael Luceno <[email protected]>
Backtrace: rt2800usb_write_tx_data rt2x00queue_write_tx_frame rt2x00mac_tx invoke_tx_handlers __ieee80211_tx ieee80211_tx virt_to_head_page ieee80211_xmit ieee80211_tx_skb ieee80211_scan_work schedule ieee80211_scan_work process_one_work ...
It tried to expand the skb past it's end using skb_put. So I replaced it with a call to skb_padto, which takes the issue into account.
--- drivers/net/wireless/rt2x00/rt2800usb.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-)
drivers/net/wireless/rt2x00/rt2800usb.c +12 -4
@@ -369,7 +369,10 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry,static void rt2800usb_write_tx_data (struct queue_entry *entry,struct txentry_desc *txdesc) { -u8 padding_len; +unsigned int len; +int err; + +rt2800_write_tx_data (entry, txdesc);/* * pad(1~3 bytes) is added after each 802.11 payload.
@@ -378,9 +381,14 @@ static void rt2800usb_write_tx_data(struct queue_entry *entry,* | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad | * |<------------- tx_pkt_len ------------->| */ -rt2800_write_tx_data (entry, txdesc); - padding_len =roundup (entry->skb->len +4 ,4 ) - entry->skb->len; -memset (skb_put (entry->skb, padding_len),0 , padding_len); + len =roundup (entry->skb->len,4 ) +4 ; + err =skb_padto (entry->skb, len); +if (unlikely (err)) { +WARNING (entry->queue->rt2x00dev,"TX SKB padding error, out of memory\n" ); +return ; + } + + entry->skb->len = len; }/*
Signature · 1 line
1.7.2.3
PATCH 7/10 rt2x00: Remove superfluous assignment of mpdu_density
From: Helmut Schaa <[email protected]>
The tx desciptor already gets initialized to 0. Hence, there's no need to explicitly assign 0 to mpdu_density here.
--- drivers/net/wireless/rt2x00/rt2x00ht.c | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)
drivers/net/wireless/rt2x00/rt2x00ht.c +0 -2
@@ -40,8 +40,6 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,if (tx_info->control.sta) txdesc->mpdu_density = tx_info->control.sta->ht_cap.ampdu_density; -else - txdesc->mpdu_density =0 ; txdesc->ba_size =7 ;/* FIXME: What value is needed? */
Signature · 1 line
1.7.2.3
PATCH 8/10 rt2x00: Simplify intf->delayed_flags locking
From: Helmut Schaa <[email protected]>
Instead of protecting delayed_flags with a spinlock use atomic bitops to make the code more readable.
--- drivers/net/wireless/rt2x00/rt2x00.h | 7 +++++-- drivers/net/wireless/rt2x00/rt2x00dev.c | 15 +-------------- drivers/net/wireless/rt2x00/rt2x00mac.c | 4 +--- 3 files changed, 7 insertions(+), 19 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +5 -2
@@ -347,6 +347,10 @@ struct link {struct delayed_work watchdog_work; }; +enum rt2x00_delayed_flags { +DELAYED_UPDATE_BEACON , +}; +/* * Interface structure * Per interface configuration details, this structure
@@ -374,8 +378,7 @@ struct rt2x00_intf {/* * Actions that needed rescheduling. */ -unsigned int delayed_flags; -#define DELAYED_UPDATE_BEACON 0x00000001 +unsigned long delayed_flags;/* * Software sequence counter, this is only required
drivers/net/wireless/rt2x00/rt2x00dev.c +1 -14
@@ -110,19 +110,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, {struct rt2x00_dev *rt2x00dev = data;struct rt2x00_intf *intf =vif_to_intf (vif); -int delayed_flags; - -/* -* Copy all data we need during this action under the protection -* of a spinlock. Otherwise race conditions might occur which results -* into an invalid configuration. -*/ -spin_lock (&intf->lock); - - delayed_flags = intf->delayed_flags; - intf->delayed_flags =0 ; - -spin_unlock (&intf->lock);/* * It is possible the radio was disabled while the work had been
@@ -133,7 +120,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,if (!test_bit (DEVICE_STATE_ENABLED_RADIO , &rt2x00dev->flags))return ; -if (delayed_flags &DELAYED_UPDATE_BEACON ) +if (test_and_clear_bit (DELAYED_UPDATE_BEACON , &intf->delayed_flags))rt2x00queue_update_beacon (rt2x00dev, vif, true); }
drivers/net/wireless/rt2x00/rt2x00mac.c +1 -3
@@ -444,9 +444,7 @@ static void rt2x00mac_set_tim_iter(void *data, u8 *mac, vif->type != NL80211_IFTYPE_WDS)return ; -spin_lock (&intf->lock); - intf->delayed_flags |=DELAYED_UPDATE_BEACON ; -spin_unlock (&intf->lock); +set_bit (DELAYED_UPDATE_BEACON , &intf->delayed_flags); } int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
Signature · 1 line
1.7.2.3
PATCH 9/10 rt2x00: Remove unused interface spinlock
From: Helmut Schaa <[email protected]>
Since the last user of intf->lock is gone we can safely remove it.
--- drivers/net/wireless/rt2x00/rt2x00.h | 6 ------ drivers/net/wireless/rt2x00/rt2x00mac.c | 1 - 2 files changed, 0 insertions(+), 7 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +0 -6
@@ -358,12 +358,6 @@ enum rt2x00_delayed_flags {*/ struct rt2x00_intf {/* -* All fields within the rt2x00_intf structure -* must be protected with a spinlock. -*/ -spinlock_t lock; - -/* * beacon->skb must be protected with the mutex. */ struct mutex beacon_skb_mutex;
drivers/net/wireless/rt2x00/rt2x00mac.c +0 -1
@@ -268,7 +268,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,else rt2x00dev->intf_sta_count++; -spin_lock_init (&intf->lock);spin_lock_init (&intf->seqlock);mutex_init (&intf->beacon_skb_mutex); intf->beacon = entry;
Signature · 1 line
1.7.2.3
PATCH 10/10 rt2x00: Fix comment about removed spinlock
From: Helmut Schaa <[email protected]>
The comment doesn't match the code anymore. Fix that.
--- drivers/net/wireless/rt2x00/rt2x00mac.c | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-)
drivers/net/wireless/rt2x00/rt2x00mac.c +1 -4
@@ -610,10 +610,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,return ;/* -* Call rt2x00_config_intf() outside of the spinlock context since -* the call will sleep for USB drivers. By using the ieee80211_if_conf -* values as arguments we make keep access to rt2x00_intf thread safe -* even without the lock. +* Update the BSSID. */ if (changes &BSS_CHANGED_BSSID ) rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
Signature · 1 line
1.7.2.3