aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00queue.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-09-12 16:52:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-15 16:48:25 -0400
commit25d834e16294c8dfd923dae6bdb8a055391a99a5 (patch)
treeb9d756464d89949651e5acd1df97846af3028df0 /drivers/net/wireless/rt2x00/rt2x00queue.c
parent9c31fd635ddfae6eb61712491770befa2ce1fdde (diff)
mac80211: fix virtual interfaces vs. injection
Currently, virtual interface pointers passed to drivers might be from monitor interfaces and as such completely uninitialised because we do not tell the driver about monitor interfaces when those are created. Instead of passing them, we should therefore indicate to the driver that there is no information; do that by passing a NULL value and adjust drivers to cope with it. As a result, some mac80211 API functions also need to cope with a NULL vif pointer so drivers can still call them unconditionally. Also, when injecting frames we really don't want to pass NULL all the time, if we know we are the source address of a frame and have a local interface for that address, we can to use that interface. This also helps with processing the frame correctly for that interface which will help the 802.11w implementation. It's not entirely correct for VLANs or WDS interfaces because there the MAC address isn't unique, but it's already a lot better than what we do now. Finally, when injecting without a matching local interface, don't assign sequence numbers at all. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00queue.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index a5e965068c83..b7f4fe8fba6e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -155,7 +155,6 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
155{ 155{
156 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 156 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
157 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 157 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
158 struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
159 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; 158 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
160 struct ieee80211_rate *rate = 159 struct ieee80211_rate *rate =
161 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); 160 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
@@ -278,16 +277,22 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
278 * sequence counter given by mac80211. 277 * sequence counter given by mac80211.
279 */ 278 */
280 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 279 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
281 spin_lock_irqsave(&intf->seqlock, irqflags); 280 if (likely(tx_info->control.vif)) {
281 struct rt2x00_intf *intf;
282 282
283 if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) 283 intf = vif_to_intf(tx_info->control.vif);
284 intf->seqno += 0x10;
285 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
286 hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
287 284
288 spin_unlock_irqrestore(&intf->seqlock, irqflags); 285 spin_lock_irqsave(&intf->seqlock, irqflags);
289 286
290 __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); 287 if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
288 intf->seqno += 0x10;
289 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
290 hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
291
292 spin_unlock_irqrestore(&intf->seqlock, irqflags);
293
294 __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
295 }
291 } 296 }
292 297
293 /* 298 /*