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.c67
1 files changed, 61 insertions, 6 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 3ddce538ef4a..7f442030f5ad 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -108,12 +108,15 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
108 108
109void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) 109void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
110{ 110{
111 if (!skb)
112 return;
113
111 rt2x00queue_unmap_skb(rt2x00dev, skb); 114 rt2x00queue_unmap_skb(rt2x00dev, skb);
112 dev_kfree_skb_any(skb); 115 dev_kfree_skb_any(skb);
113} 116}
114 117
115void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, 118static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
116 struct txentry_desc *txdesc) 119 struct txentry_desc *txdesc)
117{ 120{
118 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 121 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
119 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 122 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
@@ -237,10 +240,9 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
237 txdesc->signal |= 0x08; 240 txdesc->signal |= 0x08;
238 } 241 }
239} 242}
240EXPORT_SYMBOL_GPL(rt2x00queue_create_tx_descriptor);
241 243
242void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, 244static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
243 struct txentry_desc *txdesc) 245 struct txentry_desc *txdesc)
244{ 246{
245 struct data_queue *queue = entry->queue; 247 struct data_queue *queue = entry->queue;
246 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; 248 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
@@ -270,7 +272,6 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
270 !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) 272 !test_bit(ENTRY_TXD_BURST, &txdesc->flags))
271 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); 273 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
272} 274}
273EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor);
274 275
275int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) 276int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
276{ 277{
@@ -320,6 +321,60 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
320 return 0; 321 return 0;
321} 322}
322 323
324int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
325 struct ieee80211_vif *vif)
326{
327 struct rt2x00_intf *intf = vif_to_intf(vif);
328 struct skb_frame_desc *skbdesc;
329 struct txentry_desc txdesc;
330 __le32 desc[16];
331
332 if (unlikely(!intf->beacon))
333 return -ENOBUFS;
334
335 intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
336 if (!intf->beacon->skb)
337 return -ENOMEM;
338
339 /*
340 * Copy all TX descriptor information into txdesc,
341 * after that we are free to use the skb->cb array
342 * for our information.
343 */
344 rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
345
346 /*
347 * For the descriptor we use a local array from where the
348 * driver can move it to the correct location required for
349 * the hardware.
350 */
351 memset(desc, 0, sizeof(desc));
352
353 /*
354 * Fill in skb descriptor
355 */
356 skbdesc = get_skb_frame_desc(intf->beacon->skb);
357 memset(skbdesc, 0, sizeof(*skbdesc));
358 skbdesc->desc = desc;
359 skbdesc->desc_len = intf->beacon->queue->desc_size;
360 skbdesc->entry = intf->beacon;
361
362 /*
363 * Write TX descriptor into reserved room in front of the beacon.
364 */
365 rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
366
367 /*
368 * Send beacon to hardware.
369 * Also enable beacon generation, which might have been disabled
370 * by the driver during the config_beacon() callback function.
371 */
372 rt2x00dev->ops->lib->write_beacon(intf->beacon);
373 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
374
375 return 0;
376}
377
323struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, 378struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
324 const enum data_queue_qid queue) 379 const enum data_queue_qid queue)
325{ 380{