Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4764b29 authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville
Browse files

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: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8d8acd46
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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;
};

+1 −0
Original line number Diff line number Diff line
@@ -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)
+3 −2
Original line number Diff line number Diff line
@@ -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);
	}