aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00queue.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 7f442030f5ad..898cdd7f57d9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -120,6 +120,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
120{ 120{
121 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 121 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
122 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 122 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
123 struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
123 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; 124 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
124 struct ieee80211_rate *rate = 125 struct ieee80211_rate *rate =
125 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); 126 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
@@ -127,6 +128,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
127 unsigned int data_length; 128 unsigned int data_length;
128 unsigned int duration; 129 unsigned int duration;
129 unsigned int residual; 130 unsigned int residual;
131 unsigned long irqflags;
130 132
131 memset(txdesc, 0, sizeof(*txdesc)); 133 memset(txdesc, 0, sizeof(*txdesc));
132 134
@@ -200,6 +202,31 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
200 } 202 }
201 203
202 /* 204 /*
205 * Hardware should insert sequence counter.
206 * FIXME: We insert a software sequence counter first for
207 * hardware that doesn't support hardware sequence counting.
208 *
209 * This is wrong because beacons are not getting sequence
210 * numbers assigned properly.
211 *
212 * A secondary problem exists for drivers that cannot toggle
213 * sequence counting per-frame, since those will override the
214 * sequence counter given by mac80211.
215 */
216 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
217 spin_lock_irqsave(&intf->seqlock, irqflags);
218
219 if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
220 intf->seqno += 0x10;
221 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
222 hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
223
224 spin_unlock_irqrestore(&intf->seqlock, irqflags);
225
226 __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
227 }
228
229 /*
203 * PLCP setup 230 * PLCP setup
204 * Length calculation depends on OFDM/CCK rate. 231 * Length calculation depends on OFDM/CCK rate.
205 */ 232 */
@@ -466,9 +493,12 @@ void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev)
466 if (!rt2x00dev->ops->lib->init_rxentry) 493 if (!rt2x00dev->ops->lib->init_rxentry)
467 return; 494 return;
468 495
469 for (i = 0; i < queue->limit; i++) 496 for (i = 0; i < queue->limit; i++) {
497 queue->entries[i].flags = 0;
498
470 rt2x00dev->ops->lib->init_rxentry(rt2x00dev, 499 rt2x00dev->ops->lib->init_rxentry(rt2x00dev,
471 &queue->entries[i]); 500 &queue->entries[i]);
501 }
472} 502}
473 503
474void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev) 504void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev)
@@ -482,9 +512,12 @@ void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev)
482 if (!rt2x00dev->ops->lib->init_txentry) 512 if (!rt2x00dev->ops->lib->init_txentry)
483 continue; 513 continue;
484 514
485 for (i = 0; i < queue->limit; i++) 515 for (i = 0; i < queue->limit; i++) {
516 queue->entries[i].flags = 0;
517
486 rt2x00dev->ops->lib->init_txentry(rt2x00dev, 518 rt2x00dev->ops->lib->init_txentry(rt2x00dev,
487 &queue->entries[i]); 519 &queue->entries[i]);
520 }
488 } 521 }
489} 522}
490 523