diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00queue.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 413 |
1 files changed, 397 insertions, 16 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 659e9f44c40c..7f442030f5ad 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -25,24 +25,370 @@ | |||
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/dma-mapping.h> | ||
28 | 29 | ||
29 | #include "rt2x00.h" | 30 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 31 | #include "rt2x00lib.h" |
31 | 32 | ||
33 | struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, | ||
34 | struct queue_entry *entry) | ||
35 | { | ||
36 | unsigned int frame_size; | ||
37 | unsigned int reserved_size; | ||
38 | struct sk_buff *skb; | ||
39 | struct skb_frame_desc *skbdesc; | ||
40 | |||
41 | /* | ||
42 | * The frame size includes descriptor size, because the | ||
43 | * hardware directly receive the frame into the skbuffer. | ||
44 | */ | ||
45 | frame_size = entry->queue->data_size + entry->queue->desc_size; | ||
46 | |||
47 | /* | ||
48 | * The payload should be aligned to a 4-byte boundary, | ||
49 | * this means we need at least 3 bytes for moving the frame | ||
50 | * into the correct offset. | ||
51 | */ | ||
52 | reserved_size = 4; | ||
53 | |||
54 | /* | ||
55 | * Allocate skbuffer. | ||
56 | */ | ||
57 | skb = dev_alloc_skb(frame_size + reserved_size); | ||
58 | if (!skb) | ||
59 | return NULL; | ||
60 | |||
61 | skb_reserve(skb, reserved_size); | ||
62 | skb_put(skb, frame_size); | ||
63 | |||
64 | /* | ||
65 | * Populate skbdesc. | ||
66 | */ | ||
67 | skbdesc = get_skb_frame_desc(skb); | ||
68 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
69 | skbdesc->entry = entry; | ||
70 | |||
71 | if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) { | ||
72 | skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, | ||
73 | skb->data, | ||
74 | skb->len, | ||
75 | DMA_FROM_DEVICE); | ||
76 | skbdesc->flags |= SKBDESC_DMA_MAPPED_RX; | ||
77 | } | ||
78 | |||
79 | return skb; | ||
80 | } | ||
81 | |||
82 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | ||
83 | { | ||
84 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | ||
85 | |||
86 | skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, | ||
87 | DMA_TO_DEVICE); | ||
88 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; | ||
89 | } | ||
90 | EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); | ||
91 | |||
92 | void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | ||
93 | { | ||
94 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | ||
95 | |||
96 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) { | ||
97 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, | ||
98 | DMA_FROM_DEVICE); | ||
99 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX; | ||
100 | } | ||
101 | |||
102 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { | ||
103 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, | ||
104 | DMA_TO_DEVICE); | ||
105 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | ||
110 | { | ||
111 | if (!skb) | ||
112 | return; | ||
113 | |||
114 | rt2x00queue_unmap_skb(rt2x00dev, skb); | ||
115 | dev_kfree_skb_any(skb); | ||
116 | } | ||
117 | |||
118 | static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | ||
119 | struct txentry_desc *txdesc) | ||
120 | { | ||
121 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
122 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | ||
123 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | ||
124 | struct ieee80211_rate *rate = | ||
125 | ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); | ||
126 | const struct rt2x00_rate *hwrate; | ||
127 | unsigned int data_length; | ||
128 | unsigned int duration; | ||
129 | unsigned int residual; | ||
130 | |||
131 | memset(txdesc, 0, sizeof(*txdesc)); | ||
132 | |||
133 | /* | ||
134 | * Initialize information from queue | ||
135 | */ | ||
136 | txdesc->queue = entry->queue->qid; | ||
137 | txdesc->cw_min = entry->queue->cw_min; | ||
138 | txdesc->cw_max = entry->queue->cw_max; | ||
139 | txdesc->aifs = entry->queue->aifs; | ||
140 | |||
141 | /* Data length should be extended with 4 bytes for CRC */ | ||
142 | data_length = entry->skb->len + 4; | ||
143 | |||
144 | /* | ||
145 | * Check whether this frame is to be acked. | ||
146 | */ | ||
147 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) | ||
148 | __set_bit(ENTRY_TXD_ACK, &txdesc->flags); | ||
149 | |||
150 | /* | ||
151 | * Check if this is a RTS/CTS frame | ||
152 | */ | ||
153 | if (ieee80211_is_rts(hdr->frame_control) || | ||
154 | ieee80211_is_cts(hdr->frame_control)) { | ||
155 | __set_bit(ENTRY_TXD_BURST, &txdesc->flags); | ||
156 | if (ieee80211_is_rts(hdr->frame_control)) | ||
157 | __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags); | ||
158 | else | ||
159 | __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags); | ||
160 | if (tx_info->control.rts_cts_rate_idx >= 0) | ||
161 | rate = | ||
162 | ieee80211_get_rts_cts_rate(rt2x00dev->hw, tx_info); | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Determine retry information. | ||
167 | */ | ||
168 | txdesc->retry_limit = tx_info->control.retry_limit; | ||
169 | if (tx_info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT) | ||
170 | __set_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags); | ||
171 | |||
172 | /* | ||
173 | * Check if more fragments are pending | ||
174 | */ | ||
175 | if (ieee80211_has_morefrags(hdr->frame_control)) { | ||
176 | __set_bit(ENTRY_TXD_BURST, &txdesc->flags); | ||
177 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags); | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * Beacons and probe responses require the tsf timestamp | ||
182 | * to be inserted into the frame. | ||
183 | */ | ||
184 | if (ieee80211_is_beacon(hdr->frame_control) || | ||
185 | ieee80211_is_probe_resp(hdr->frame_control)) | ||
186 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); | ||
187 | |||
188 | /* | ||
189 | * Determine with what IFS priority this frame should be send. | ||
190 | * Set ifs to IFS_SIFS when the this is not the first fragment, | ||
191 | * or this fragment came after RTS/CTS. | ||
192 | */ | ||
193 | if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) { | ||
194 | txdesc->ifs = IFS_SIFS; | ||
195 | } else if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { | ||
196 | __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags); | ||
197 | txdesc->ifs = IFS_BACKOFF; | ||
198 | } else { | ||
199 | txdesc->ifs = IFS_SIFS; | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * PLCP setup | ||
204 | * Length calculation depends on OFDM/CCK rate. | ||
205 | */ | ||
206 | hwrate = rt2x00_get_rate(rate->hw_value); | ||
207 | txdesc->signal = hwrate->plcp; | ||
208 | txdesc->service = 0x04; | ||
209 | |||
210 | if (hwrate->flags & DEV_RATE_OFDM) { | ||
211 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags); | ||
212 | |||
213 | txdesc->length_high = (data_length >> 6) & 0x3f; | ||
214 | txdesc->length_low = data_length & 0x3f; | ||
215 | } else { | ||
216 | /* | ||
217 | * Convert length to microseconds. | ||
218 | */ | ||
219 | residual = get_duration_res(data_length, hwrate->bitrate); | ||
220 | duration = get_duration(data_length, hwrate->bitrate); | ||
221 | |||
222 | if (residual != 0) { | ||
223 | duration++; | ||
224 | |||
225 | /* | ||
226 | * Check if we need to set the Length Extension | ||
227 | */ | ||
228 | if (hwrate->bitrate == 110 && residual <= 30) | ||
229 | txdesc->service |= 0x80; | ||
230 | } | ||
231 | |||
232 | txdesc->length_high = (duration >> 8) & 0xff; | ||
233 | txdesc->length_low = duration & 0xff; | ||
234 | |||
235 | /* | ||
236 | * When preamble is enabled we should set the | ||
237 | * preamble bit for the signal. | ||
238 | */ | ||
239 | if (rt2x00_get_rate_preamble(rate->hw_value)) | ||
240 | txdesc->signal |= 0x08; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | ||
245 | struct txentry_desc *txdesc) | ||
246 | { | ||
247 | struct data_queue *queue = entry->queue; | ||
248 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
249 | |||
250 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); | ||
251 | |||
252 | /* | ||
253 | * All processing on the frame has been completed, this means | ||
254 | * it is now ready to be dumped to userspace through debugfs. | ||
255 | */ | ||
256 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); | ||
257 | |||
258 | /* | ||
259 | * Check if we need to kick the queue, there are however a few rules | ||
260 | * 1) Don't kick beacon queue | ||
261 | * 2) Don't kick unless this is the last in frame in a burst. | ||
262 | * When the burst flag is set, this frame is always followed | ||
263 | * by another frame which in some way are related to eachother. | ||
264 | * This is true for fragments, RTS or CTS-to-self frames. | ||
265 | * 3) Rule 2 can be broken when the available entries | ||
266 | * in the queue are less then a certain threshold. | ||
267 | */ | ||
268 | if (entry->queue->qid == QID_BEACON) | ||
269 | return; | ||
270 | |||
271 | if (rt2x00queue_threshold(queue) || | ||
272 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) | ||
273 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); | ||
274 | } | ||
275 | |||
276 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | ||
277 | { | ||
278 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
279 | struct txentry_desc txdesc; | ||
280 | struct skb_frame_desc *skbdesc; | ||
281 | |||
282 | if (unlikely(rt2x00queue_full(queue))) | ||
283 | return -EINVAL; | ||
284 | |||
285 | if (__test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { | ||
286 | ERROR(queue->rt2x00dev, | ||
287 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
288 | "Please file bug report to %s.\n", | ||
289 | queue->qid, DRV_PROJECT); | ||
290 | return -EINVAL; | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * Copy all TX descriptor information into txdesc, | ||
295 | * after that we are free to use the skb->cb array | ||
296 | * for our information. | ||
297 | */ | ||
298 | entry->skb = skb; | ||
299 | rt2x00queue_create_tx_descriptor(entry, &txdesc); | ||
300 | |||
301 | /* | ||
302 | * skb->cb array is now ours and we are free to use it. | ||
303 | */ | ||
304 | skbdesc = get_skb_frame_desc(entry->skb); | ||
305 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
306 | skbdesc->entry = entry; | ||
307 | |||
308 | if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { | ||
309 | __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
310 | return -EIO; | ||
311 | } | ||
312 | |||
313 | if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags)) | ||
314 | rt2x00queue_map_txskb(queue->rt2x00dev, skb); | ||
315 | |||
316 | __set_bit(ENTRY_DATA_PENDING, &entry->flags); | ||
317 | |||
318 | rt2x00queue_index_inc(queue, Q_INDEX); | ||
319 | rt2x00queue_write_tx_descriptor(entry, &txdesc); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | int 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 | |||
32 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | 378 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, |
33 | const unsigned int queue) | 379 | const enum data_queue_qid queue) |
34 | { | 380 | { |
35 | int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 381 | int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
36 | 382 | ||
37 | if (queue < rt2x00dev->hw->queues && rt2x00dev->tx) | 383 | if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx) |
38 | return &rt2x00dev->tx[queue]; | 384 | return &rt2x00dev->tx[queue]; |
39 | 385 | ||
40 | if (!rt2x00dev->bcn) | 386 | if (!rt2x00dev->bcn) |
41 | return NULL; | 387 | return NULL; |
42 | 388 | ||
43 | if (queue == RT2X00_BCN_QUEUE_BEACON) | 389 | if (queue == QID_BEACON) |
44 | return &rt2x00dev->bcn[0]; | 390 | return &rt2x00dev->bcn[0]; |
45 | else if (queue == RT2X00_BCN_QUEUE_ATIM && atim) | 391 | else if (queue == QID_ATIM && atim) |
46 | return &rt2x00dev->bcn[1]; | 392 | return &rt2x00dev->bcn[1]; |
47 | 393 | ||
48 | return NULL; | 394 | return NULL; |
@@ -96,7 +442,6 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | |||
96 | 442 | ||
97 | spin_unlock_irqrestore(&queue->lock, irqflags); | 443 | spin_unlock_irqrestore(&queue->lock, irqflags); |
98 | } | 444 | } |
99 | EXPORT_SYMBOL_GPL(rt2x00queue_index_inc); | ||
100 | 445 | ||
101 | static void rt2x00queue_reset(struct data_queue *queue) | 446 | static void rt2x00queue_reset(struct data_queue *queue) |
102 | { | 447 | { |
@@ -153,6 +498,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, | |||
153 | rt2x00queue_reset(queue); | 498 | rt2x00queue_reset(queue); |
154 | 499 | ||
155 | queue->limit = qdesc->entry_num; | 500 | queue->limit = qdesc->entry_num; |
501 | queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10); | ||
156 | queue->data_size = qdesc->data_size; | 502 | queue->data_size = qdesc->data_size; |
157 | queue->desc_size = qdesc->desc_size; | 503 | queue->desc_size = qdesc->desc_size; |
158 | 504 | ||
@@ -185,12 +531,41 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, | |||
185 | return 0; | 531 | return 0; |
186 | } | 532 | } |
187 | 533 | ||
534 | static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev, | ||
535 | struct data_queue *queue) | ||
536 | { | ||
537 | unsigned int i; | ||
538 | |||
539 | if (!queue->entries) | ||
540 | return; | ||
541 | |||
542 | for (i = 0; i < queue->limit; i++) { | ||
543 | if (queue->entries[i].skb) | ||
544 | rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb); | ||
545 | } | ||
546 | } | ||
547 | |||
548 | static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev, | ||
549 | struct data_queue *queue) | ||
550 | { | ||
551 | unsigned int i; | ||
552 | struct sk_buff *skb; | ||
553 | |||
554 | for (i = 0; i < queue->limit; i++) { | ||
555 | skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]); | ||
556 | if (!skb) | ||
557 | return -ENOMEM; | ||
558 | queue->entries[i].skb = skb; | ||
559 | } | ||
560 | |||
561 | return 0; | ||
562 | } | ||
563 | |||
188 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | 564 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) |
189 | { | 565 | { |
190 | struct data_queue *queue; | 566 | struct data_queue *queue; |
191 | int status; | 567 | int status; |
192 | 568 | ||
193 | |||
194 | status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); | 569 | status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); |
195 | if (status) | 570 | if (status) |
196 | goto exit; | 571 | goto exit; |
@@ -205,11 +580,14 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | |||
205 | if (status) | 580 | if (status) |
206 | goto exit; | 581 | goto exit; |
207 | 582 | ||
208 | if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | 583 | if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) { |
209 | return 0; | 584 | status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], |
585 | rt2x00dev->ops->atim); | ||
586 | if (status) | ||
587 | goto exit; | ||
588 | } | ||
210 | 589 | ||
211 | status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], | 590 | status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx); |
212 | rt2x00dev->ops->atim); | ||
213 | if (status) | 591 | if (status) |
214 | goto exit; | 592 | goto exit; |
215 | 593 | ||
@@ -227,6 +605,8 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
227 | { | 605 | { |
228 | struct data_queue *queue; | 606 | struct data_queue *queue; |
229 | 607 | ||
608 | rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx); | ||
609 | |||
230 | queue_for_each(rt2x00dev, queue) { | 610 | queue_for_each(rt2x00dev, queue) { |
231 | kfree(queue->entries); | 611 | kfree(queue->entries); |
232 | queue->entries = NULL; | 612 | queue->entries = NULL; |
@@ -255,11 +635,11 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
255 | /* | 635 | /* |
256 | * We need the following queues: | 636 | * We need the following queues: |
257 | * RX: 1 | 637 | * RX: 1 |
258 | * TX: hw->queues | 638 | * TX: ops->tx_queues |
259 | * Beacon: 1 | 639 | * Beacon: 1 |
260 | * Atim: 1 (if required) | 640 | * Atim: 1 (if required) |
261 | */ | 641 | */ |
262 | rt2x00dev->data_queues = 2 + rt2x00dev->hw->queues + req_atim; | 642 | rt2x00dev->data_queues = 2 + rt2x00dev->ops->tx_queues + req_atim; |
263 | 643 | ||
264 | queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL); | 644 | queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL); |
265 | if (!queue) { | 645 | if (!queue) { |
@@ -272,7 +652,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
272 | */ | 652 | */ |
273 | rt2x00dev->rx = queue; | 653 | rt2x00dev->rx = queue; |
274 | rt2x00dev->tx = &queue[1]; | 654 | rt2x00dev->tx = &queue[1]; |
275 | rt2x00dev->bcn = &queue[1 + rt2x00dev->hw->queues]; | 655 | rt2x00dev->bcn = &queue[1 + rt2x00dev->ops->tx_queues]; |
276 | 656 | ||
277 | /* | 657 | /* |
278 | * Initialize queue parameters. | 658 | * Initialize queue parameters. |
@@ -280,7 +660,8 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
280 | * TX: qid = QID_AC_BE + index | 660 | * TX: qid = QID_AC_BE + index |
281 | * TX: cw_min: 2^5 = 32. | 661 | * TX: cw_min: 2^5 = 32. |
282 | * TX: cw_max: 2^10 = 1024. | 662 | * TX: cw_max: 2^10 = 1024. |
283 | * BCN & Atim: qid = QID_MGMT | 663 | * BCN: qid = QID_BEACON |
664 | * ATIM: qid = QID_ATIM | ||
284 | */ | 665 | */ |
285 | rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX); | 666 | rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX); |
286 | 667 | ||
@@ -288,9 +669,9 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
288 | tx_queue_for_each(rt2x00dev, queue) | 669 | tx_queue_for_each(rt2x00dev, queue) |
289 | rt2x00queue_init(rt2x00dev, queue, qid++); | 670 | rt2x00queue_init(rt2x00dev, queue, qid++); |
290 | 671 | ||
291 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_MGMT); | 672 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_BEACON); |
292 | if (req_atim) | 673 | if (req_atim) |
293 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_MGMT); | 674 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_ATIM); |
294 | 675 | ||
295 | return 0; | 676 | return 0; |
296 | } | 677 | } |