aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00usb.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-06-14 20:15:39 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-14 20:15:39 -0400
commit942e7b102a4827fdb69a39c7f07c544542589ef9 (patch)
tree4c47174c91eb76aaa31abc141adbee1acc649987 /drivers/net/wireless/rt2x00/rt2x00usb.c
parent7d06b2e053d2d536348e3a0f6bb02982a41bea37 (diff)
parent87291c0269e77b029282676448fed3706a54211a (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c165
1 files changed, 58 insertions, 107 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 52d12fdc0ccf..68d87f09e054 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -130,16 +130,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
130 struct queue_entry *entry = (struct queue_entry *)urb->context; 130 struct queue_entry *entry = (struct queue_entry *)urb->context;
131 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 131 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
132 struct txdone_entry_desc txdesc; 132 struct txdone_entry_desc txdesc;
133 __le32 *txd = (__le32 *)entry->skb->data;
134 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); 133 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
135 u32 word;
136 134
137 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || 135 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
138 !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 136 !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
139 return; 137 return;
140 138
141 rt2x00_desc_read(txd, 0, &word);
142
143 /* 139 /*
144 * Remove the descriptor data from the buffer. 140 * Remove the descriptor data from the buffer.
145 */ 141 */
@@ -169,124 +165,101 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
169 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); 165 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
170 166
171 /* 167 /*
172 * If the data queue was full before the txdone handler 168 * If the data queue was below the threshold before the txdone
173 * we must make sure the packet queue in the mac80211 stack 169 * handler we must make sure the packet queue in the mac80211 stack
174 * is reenabled when the txdone handler has finished. 170 * is reenabled when the txdone handler has finished.
175 */ 171 */
176 if (!rt2x00queue_full(entry->queue)) 172 if (!rt2x00queue_threshold(entry->queue))
177 ieee80211_wake_queue(rt2x00dev->hw, qid); 173 ieee80211_wake_queue(rt2x00dev->hw, qid);
178} 174}
179 175
180int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, 176int rt2x00usb_write_tx_data(struct queue_entry *entry)
181 struct data_queue *queue, struct sk_buff *skb)
182{ 177{
178 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
183 struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); 179 struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);
184 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
185 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 180 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
186 struct skb_frame_desc *skbdesc; 181 struct skb_frame_desc *skbdesc;
187 struct txentry_desc txdesc;
188 u32 length; 182 u32 length;
189 183
190 if (rt2x00queue_full(queue))
191 return -EINVAL;
192
193 if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
194 ERROR(rt2x00dev,
195 "Arrived at non-free entry in the non-full queue %d.\n"
196 "Please file bug report to %s.\n",
197 entry->queue->qid, DRV_PROJECT);
198 return -EINVAL;
199 }
200
201 /*
202 * Copy all TX descriptor information into txdesc,
203 * after that we are free to use the skb->cb array
204 * for our information.
205 */
206 entry->skb = skb;
207 rt2x00queue_create_tx_descriptor(entry, &txdesc);
208
209 /* 184 /*
210 * Add the descriptor in front of the skb. 185 * Add the descriptor in front of the skb.
211 */ 186 */
212 skb_push(skb, queue->desc_size); 187 skb_push(entry->skb, entry->queue->desc_size);
213 memset(skb->data, 0, queue->desc_size); 188 memset(entry->skb->data, 0, entry->queue->desc_size);
214 189
215 /* 190 /*
216 * Fill in skb descriptor 191 * Fill in skb descriptor
217 */ 192 */
218 skbdesc = get_skb_frame_desc(skb); 193 skbdesc = get_skb_frame_desc(entry->skb);
219 memset(skbdesc, 0, sizeof(*skbdesc)); 194 memset(skbdesc, 0, sizeof(*skbdesc));
220 skbdesc->data = skb->data + queue->desc_size; 195 skbdesc->desc = entry->skb->data;
221 skbdesc->data_len = skb->len - queue->desc_size; 196 skbdesc->desc_len = entry->queue->desc_size;
222 skbdesc->desc = skb->data;
223 skbdesc->desc_len = queue->desc_size;
224 skbdesc->entry = entry; 197 skbdesc->entry = entry;
225 198
226 rt2x00queue_write_tx_descriptor(entry, &txdesc);
227
228 /* 199 /*
229 * USB devices cannot blindly pass the skb->len as the 200 * USB devices cannot blindly pass the skb->len as the
230 * length of the data to usb_fill_bulk_urb. Pass the skb 201 * length of the data to usb_fill_bulk_urb. Pass the skb
231 * to the driver to determine what the length should be. 202 * to the driver to determine what the length should be.
232 */ 203 */
233 length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, skb); 204 length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb);
234 205
235 /* 206 usb_fill_bulk_urb(entry_priv->urb, usb_dev,
236 * Initialize URB and send the frame to the device. 207 usb_sndbulkpipe(usb_dev, 1),
237 */ 208 entry->skb->data, length,
238 __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 209 rt2x00usb_interrupt_txdone, entry);
239 usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1),
240 skb->data, length, rt2x00usb_interrupt_txdone, entry);
241 usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
242
243 rt2x00queue_index_inc(queue, Q_INDEX);
244 210
245 return 0; 211 return 0;
246} 212}
247EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); 213EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data);
248 214
249/* 215static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
250 * RX data handlers.
251 */
252static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue)
253{ 216{
254 struct sk_buff *skb; 217 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
255 unsigned int frame_size;
256 unsigned int reserved_size;
257 218
258 /* 219 if (__test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
259 * The frame size includes descriptor size, because the 220 usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
260 * hardware directly receive the frame into the skbuffer. 221}
261 */ 222
262 frame_size = queue->data_size + queue->desc_size; 223void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
224 const enum data_queue_qid qid)
225{
226 struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
227 unsigned long irqflags;
228 unsigned int index;
229 unsigned int index_done;
230 unsigned int i;
263 231
264 /* 232 /*
265 * For the allocation we should keep a few things in mind: 233 * Only protect the range we are going to loop over,
266 * 1) 4byte alignment of 802.11 payload 234 * if during our loop a extra entry is set to pending
267 * 235 * it should not be kicked during this run, since it
268 * For (1) we need at most 4 bytes to guarentee the correct 236 * is part of another TX operation.
269 * alignment. We are going to optimize the fact that the chance
270 * that the 802.11 header_size % 4 == 2 is much bigger then
271 * anything else. However since we need to move the frame up
272 * to 3 bytes to the front, which means we need to preallocate
273 * 6 bytes.
274 */ 237 */
275 reserved_size = 6; 238 spin_lock_irqsave(&queue->lock, irqflags);
239 index = queue->index[Q_INDEX];
240 index_done = queue->index[Q_INDEX_DONE];
241 spin_unlock_irqrestore(&queue->lock, irqflags);
276 242
277 /* 243 /*
278 * Allocate skbuffer. 244 * Start from the TX done pointer, this guarentees that we will
245 * send out all frames in the correct order.
279 */ 246 */
280 skb = dev_alloc_skb(frame_size + reserved_size); 247 if (index_done < index) {
281 if (!skb) 248 for (i = index_done; i < index; i++)
282 return NULL; 249 rt2x00usb_kick_tx_entry(&queue->entries[i]);
283 250 } else {
284 skb_reserve(skb, reserved_size); 251 for (i = index_done; i < queue->limit; i++)
285 skb_put(skb, frame_size); 252 rt2x00usb_kick_tx_entry(&queue->entries[i]);
286 253
287 return skb; 254 for (i = 0; i < index; i++)
255 rt2x00usb_kick_tx_entry(&queue->entries[i]);
256 }
288} 257}
258EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
289 259
260/*
261 * RX data handlers.
262 */
290static void rt2x00usb_interrupt_rxdone(struct urb *urb) 263static void rt2x00usb_interrupt_rxdone(struct urb *urb)
291{ 264{
292 struct queue_entry *entry = (struct queue_entry *)urb->context; 265 struct queue_entry *entry = (struct queue_entry *)urb->context;
@@ -294,8 +267,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
294 struct sk_buff *skb; 267 struct sk_buff *skb;
295 struct skb_frame_desc *skbdesc; 268 struct skb_frame_desc *skbdesc;
296 struct rxdone_entry_desc rxdesc; 269 struct rxdone_entry_desc rxdesc;
297 unsigned int header_size; 270 u8 rxd[32];
298 unsigned int align;
299 271
300 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || 272 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
301 !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 273 !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
@@ -315,39 +287,18 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
315 skbdesc = get_skb_frame_desc(entry->skb); 287 skbdesc = get_skb_frame_desc(entry->skb);
316 memset(skbdesc, 0, sizeof(*skbdesc)); 288 memset(skbdesc, 0, sizeof(*skbdesc));
317 skbdesc->entry = entry; 289 skbdesc->entry = entry;
290 skbdesc->desc = rxd;
291 skbdesc->desc_len = entry->queue->desc_size;
318 292
319 memset(&rxdesc, 0, sizeof(rxdesc)); 293 memset(&rxdesc, 0, sizeof(rxdesc));
320 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); 294 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
321 295
322 header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
323
324 /*
325 * The data behind the ieee80211 header must be
326 * aligned on a 4 byte boundary. We already reserved
327 * 2 bytes for header_size % 4 == 2 optimization.
328 * To determine the number of bytes which the data
329 * should be moved to the left, we must add these
330 * 2 bytes to the header_size.
331 */
332 align = (header_size + 2) % 4;
333
334 if (align) {
335 skb_push(entry->skb, align);
336 /* Move entire frame in 1 command */
337 memmove(entry->skb->data, entry->skb->data + align,
338 rxdesc.size);
339 }
340
341 /* Update data pointers, trim buffer to correct size */
342 skbdesc->data = entry->skb->data;
343 skb_trim(entry->skb, rxdesc.size);
344
345 /* 296 /*
346 * Allocate a new sk buffer to replace the current one. 297 * Allocate a new sk buffer to replace the current one.
347 * If allocation fails, we should drop the current frame 298 * If allocation fails, we should drop the current frame
348 * so we can recycle the existing sk buffer for the new frame. 299 * so we can recycle the existing sk buffer for the new frame.
349 */ 300 */
350 skb = rt2x00usb_alloc_rxskb(entry->queue); 301 skb = rt2x00queue_alloc_rxskb(entry->queue);
351 if (!skb) 302 if (!skb)
352 goto skip_entry; 303 goto skip_entry;
353 304
@@ -519,7 +470,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
519 */ 470 */
520 entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; 471 entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size;
521 for (i = 0; i < rt2x00dev->rx->limit; i++) { 472 for (i = 0; i < rt2x00dev->rx->limit; i++) {
522 skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx); 473 skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx);
523 if (!skb) 474 if (!skb)
524 goto exit; 475 goto exit;
525 476