aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00mac.c
diff options
context:
space:
mode:
authorIvo van Doorn <IvDoorn@gmail.com>2008-02-05 16:42:23 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:19:27 -0500
commit181d6902b6bad978d157e69479c95cc0ff213a76 (patch)
tree7a90b8a949a50bc8db6b7b5b2d76d5671fb9a89e /drivers/net/wireless/rt2x00/rt2x00mac.c
parent811aa9cad1bd927999888ab56ed9592519d2fef6 (diff)
rt2x00: Queue handling overhaul
This introduces a big queue handling overhaul, this also renames "ring" to "queues". Move queue handling into rt2x00queue.c and the matching header, use Kerneldoc to improve rt2x00 library documentation. Access to the queues is now protected under a spinlock, this to prevent race conditions which could corrupt the indexing system of the queue. Each queue entry allocates x bytes for driver/device specific data, this cleans up the queue structure significantly and improves code readability. rt2500usb no longer needs 2 entries in the beacon queue to correctly send out the guardian byte. This is now handled in the entry specific structure. rt61 and rt73 now use the correct descriptor size for beacon frames, since this data is written into the registers not the entire TXD descriptor was used but instead of a subset of it named TXINFO. Finally this also fixes numerous other bugs related to incorrect beacon handling or beacon related code. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00mac.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c55
1 files changed, 28 insertions, 27 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index e638c653e09..411ed5d0859 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -30,7 +30,7 @@
30#include "rt2x00lib.h" 30#include "rt2x00lib.h"
31 31
32static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, 32static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
33 struct data_ring *ring, 33 struct data_queue *queue,
34 struct sk_buff *frag_skb, 34 struct sk_buff *frag_skb,
35 struct ieee80211_tx_control *control) 35 struct ieee80211_tx_control *control)
36{ 36{
@@ -60,7 +60,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
60 frag_skb->data, frag_skb->len, control, 60 frag_skb->data, frag_skb->len, control,
61 (struct ieee80211_rts *)(skb->data)); 61 (struct ieee80211_rts *)(skb->data));
62 62
63 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) { 63 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
64 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); 64 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
65 return NETDEV_TX_BUSY; 65 return NETDEV_TX_BUSY;
66 } 66 }
@@ -73,7 +73,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
73{ 73{
74 struct rt2x00_dev *rt2x00dev = hw->priv; 74 struct rt2x00_dev *rt2x00dev = hw->priv;
75 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; 75 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
76 struct data_ring *ring; 76 struct data_queue *queue;
77 u16 frame_control; 77 u16 frame_control;
78 78
79 /* 79 /*
@@ -88,10 +88,10 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
88 } 88 }
89 89
90 /* 90 /*
91 * Determine which ring to put packet on. 91 * Determine which queue to put packet on.
92 */ 92 */
93 ring = rt2x00lib_get_ring(rt2x00dev, control->queue); 93 queue = rt2x00queue_get_queue(rt2x00dev, control->queue);
94 if (unlikely(!ring)) { 94 if (unlikely(!queue)) {
95 ERROR(rt2x00dev, 95 ERROR(rt2x00dev,
96 "Attempt to send packet over invalid queue %d.\n" 96 "Attempt to send packet over invalid queue %d.\n"
97 "Please file bug report to %s.\n", 97 "Please file bug report to %s.\n",
@@ -110,23 +110,23 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
110 if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && 110 if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) &&
111 (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS | 111 (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS |
112 IEEE80211_TXCTL_USE_CTS_PROTECT))) { 112 IEEE80211_TXCTL_USE_CTS_PROTECT))) {
113 if (rt2x00_ring_free(ring) <= 1) { 113 if (rt2x00queue_available(queue) <= 1) {
114 ieee80211_stop_queue(rt2x00dev->hw, control->queue); 114 ieee80211_stop_queue(rt2x00dev->hw, control->queue);
115 return NETDEV_TX_BUSY; 115 return NETDEV_TX_BUSY;
116 } 116 }
117 117
118 if (rt2x00mac_tx_rts_cts(rt2x00dev, ring, skb, control)) { 118 if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb, control)) {
119 ieee80211_stop_queue(rt2x00dev->hw, control->queue); 119 ieee80211_stop_queue(rt2x00dev->hw, control->queue);
120 return NETDEV_TX_BUSY; 120 return NETDEV_TX_BUSY;
121 } 121 }
122 } 122 }
123 123
124 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) { 124 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
125 ieee80211_stop_queue(rt2x00dev->hw, control->queue); 125 ieee80211_stop_queue(rt2x00dev->hw, control->queue);
126 return NETDEV_TX_BUSY; 126 return NETDEV_TX_BUSY;
127 } 127 }
128 128
129 if (rt2x00_ring_full(ring)) 129 if (rt2x00queue_full(queue))
130 ieee80211_stop_queue(rt2x00dev->hw, control->queue); 130 ieee80211_stop_queue(rt2x00dev->hw, control->queue);
131 131
132 if (rt2x00dev->ops->lib->kick_tx_queue) 132 if (rt2x00dev->ops->lib->kick_tx_queue)
@@ -214,7 +214,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
214 !is_interface_present(intf)) 214 !is_interface_present(intf))
215 return; 215 return;
216 216
217 intf->id = 0; 217 intf->id = NULL;
218 intf->type = IEEE80211_IF_TYPE_INVALID; 218 intf->type = IEEE80211_IF_TYPE_INVALID;
219 memset(&intf->bssid, 0x00, ETH_ALEN); 219 memset(&intf->bssid, 0x00, ETH_ALEN);
220 memset(&intf->mac, 0x00, ETH_ALEN); 220 memset(&intf->mac, 0x00, ETH_ALEN);
@@ -334,9 +334,11 @@ int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
334 struct rt2x00_dev *rt2x00dev = hw->priv; 334 struct rt2x00_dev *rt2x00dev = hw->priv;
335 unsigned int i; 335 unsigned int i;
336 336
337 for (i = 0; i < hw->queues; i++) 337 for (i = 0; i < hw->queues; i++) {
338 memcpy(&stats->data[i], &rt2x00dev->tx[i].stats, 338 stats->data[i].len = rt2x00dev->tx[i].length;
339 sizeof(rt2x00dev->tx[i].stats)); 339 stats->data[i].limit = rt2x00dev->tx[i].limit;
340 stats->data[i].count = rt2x00dev->tx[i].count;
341 }
340 342
341 return 0; 343 return 0;
342} 344}
@@ -380,14 +382,14 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
380} 382}
381EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); 383EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
382 384
383int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, 385int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue_idx,
384 const struct ieee80211_tx_queue_params *params) 386 const struct ieee80211_tx_queue_params *params)
385{ 387{
386 struct rt2x00_dev *rt2x00dev = hw->priv; 388 struct rt2x00_dev *rt2x00dev = hw->priv;
387 struct data_ring *ring; 389 struct data_queue *queue;
388 390
389 ring = rt2x00lib_get_ring(rt2x00dev, queue); 391 queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
390 if (unlikely(!ring)) 392 if (unlikely(!queue))
391 return -EINVAL; 393 return -EINVAL;
392 394
393 /* 395 /*
@@ -395,24 +397,23 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue,
395 * Ralink registers require to know the bit number 'n'. 397 * Ralink registers require to know the bit number 'n'.
396 */ 398 */
397 if (params->cw_min) 399 if (params->cw_min)
398 ring->tx_params.cw_min = fls(params->cw_min); 400 queue->cw_min = fls(params->cw_min);
399 else 401 else
400 ring->tx_params.cw_min = 5; /* cw_min: 2^5 = 32. */ 402 queue->cw_min = 5; /* cw_min: 2^5 = 32. */
401 403
402 if (params->cw_max) 404 if (params->cw_max)
403 ring->tx_params.cw_max = fls(params->cw_max); 405 queue->cw_max = fls(params->cw_max);
404 else 406 else
405 ring->tx_params.cw_max = 10; /* cw_min: 2^10 = 1024. */ 407 queue->cw_max = 10; /* cw_min: 2^10 = 1024. */
406 408
407 if (params->aifs) 409 if (params->aifs)
408 ring->tx_params.aifs = params->aifs; 410 queue->aifs = params->aifs;
409 else 411 else
410 ring->tx_params.aifs = 2; 412 queue->aifs = 2;
411 413
412 INFO(rt2x00dev, 414 INFO(rt2x00dev,
413 "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", 415 "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d.\n",
414 queue, ring->tx_params.cw_min, ring->tx_params.cw_max, 416 queue_idx, queue->cw_min, queue->cw_max, queue->aifs);
415 ring->tx_params.aifs);
416 417
417 return 0; 418 return 0;
418} 419}