aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-07-28 10:21:16 +0200
committerJohn W. Linville <linville@tuxdriver.com>2008-08-01 15:31:34 -0400
commitd4764b29b6e0f1608e397930677928e5a3f62bba (patch)
tree4cea20166052d0aa0af2325861d1c6bb3d65f215 /drivers
parent8d8acd46fb7e962ac04baef5a118d431fae6b0f6 (diff)
downloadkernel_samsung_smdk4412-d4764b29b6e0f1608e397930677928e5a3f62bba.zip
kernel_samsung_smdk4412-d4764b29b6e0f1608e397930677928e5a3f62bba.tar.gz
kernel_samsung_smdk4412-d4764b29b6e0f1608e397930677928e5a3f62bba.tar.bz2
rt2x00: Sequence counter should be protected in irqsave
The sequence counter can be accessed in IRQ context, which means the lock protecting the counter should be irqsave. To prevent making the entire intf->lock irqsave without reason, create a new lock which only protects the sequence counter. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c5
3 files changed, 10 insertions, 2 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index db2dc97..8b10ea4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -368,6 +368,12 @@ struct rt2x00_intf {
#define DELAYED_CONFIG_ERP 0x00000002
#define DELAYED_LED_ASSOC 0x00000004
+ /*
+ * Software sequence counter, this is only required
+ * for hardware which doesn't support hardware
+ * sequence counting.
+ */
+ spinlock_t seqlock;
u16 seqno;
};
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index c3ee4ec..bd422fd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -247,6 +247,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
rt2x00dev->intf_sta_count++;
spin_lock_init(&intf->lock);
+ spin_lock_init(&intf->seqlock);
intf->beacon = entry;
if (conf->type == IEEE80211_IF_TYPE_AP)
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 3b27f6a..898cdd7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -128,6 +128,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
unsigned int data_length;
unsigned int duration;
unsigned int residual;
+ unsigned long irqflags;
memset(txdesc, 0, sizeof(*txdesc));
@@ -213,14 +214,14 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
* sequence counter given by mac80211.
*/
if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- spin_lock(&intf->lock);
+ spin_lock_irqsave(&intf->seqlock, irqflags);
if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
intf->seqno += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
- spin_unlock(&intf->lock);
+ spin_unlock_irqrestore(&intf->seqlock, irqflags);
__set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
}