diff options
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 2933bf1d74bb..935b76d3ce4f 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -307,8 +307,14 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, | |||
307 | * Initialize TXINFO descriptor | 307 | * Initialize TXINFO descriptor |
308 | */ | 308 | */ |
309 | rt2x00_desc_read(txi, 0, &word); | 309 | rt2x00_desc_read(txi, 0, &word); |
310 | |||
311 | /* | ||
312 | * The size of TXINFO_W0_USB_DMA_TX_PKT_LEN is | ||
313 | * TXWI + 802.11 header + L2 pad + payload + pad, | ||
314 | * so need to decrease size of TXINFO and USB end pad. | ||
315 | */ | ||
310 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, | 316 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, |
311 | entry->skb->len - TXINFO_DESC_SIZE); | 317 | entry->skb->len - TXINFO_DESC_SIZE - 4); |
312 | rt2x00_set_field32(&word, TXINFO_W0_WIV, | 318 | rt2x00_set_field32(&word, TXINFO_W0_WIV, |
313 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); | 319 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); |
314 | rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); | 320 | rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); |
@@ -326,22 +332,29 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry, | |||
326 | skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; | 332 | skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; |
327 | } | 333 | } |
328 | 334 | ||
329 | /* | 335 | static void rt2800usb_write_tx_data(struct queue_entry *entry, |
330 | * TX data initialization | 336 | struct txentry_desc *txdesc) |
331 | */ | ||
332 | static int rt2800usb_get_tx_data_len(struct queue_entry *entry) | ||
333 | { | 337 | { |
334 | int length; | 338 | u8 padding_len; |
335 | 339 | ||
336 | /* | 340 | /* |
337 | * The length _must_ include 4 bytes padding, | 341 | * pad(1~3 bytes) is added after each 802.11 payload. |
338 | * it should always be multiple of 4, | 342 | * USB end pad(4 bytes) is added at each USB bulk out packet end. |
339 | * but it must _not_ be a multiple of the USB packet size. | 343 | * TX frame format is : |
344 | * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad | | ||
345 | * |<------------- tx_pkt_len ------------->| | ||
340 | */ | 346 | */ |
341 | length = roundup(entry->skb->len + 4, 4); | 347 | rt2800_write_tx_data(entry, txdesc); |
342 | length += (4 * !(length % entry->queue->usb_maxpacket)); | 348 | padding_len = roundup(entry->skb->len + 4, 4) - entry->skb->len; |
349 | memset(skb_put(entry->skb, padding_len), 0, padding_len); | ||
350 | } | ||
343 | 351 | ||
344 | return length; | 352 | /* |
353 | * TX data initialization | ||
354 | */ | ||
355 | static int rt2800usb_get_tx_data_len(struct queue_entry *entry) | ||
356 | { | ||
357 | return entry->skb->len; | ||
345 | } | 358 | } |
346 | 359 | ||
347 | /* | 360 | /* |
@@ -579,7 +592,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
579 | .link_tuner = rt2800_link_tuner, | 592 | .link_tuner = rt2800_link_tuner, |
580 | .watchdog = rt2800usb_watchdog, | 593 | .watchdog = rt2800usb_watchdog, |
581 | .write_tx_desc = rt2800usb_write_tx_desc, | 594 | .write_tx_desc = rt2800usb_write_tx_desc, |
582 | .write_tx_data = rt2800_write_tx_data, | 595 | .write_tx_data = rt2800usb_write_tx_data, |
583 | .write_beacon = rt2800_write_beacon, | 596 | .write_beacon = rt2800_write_beacon, |
584 | .get_tx_data_len = rt2800usb_get_tx_data_len, | 597 | .get_tx_data_len = rt2800usb_get_tx_data_len, |
585 | .kick_tx_queue = rt2x00usb_kick_tx_queue, | 598 | .kick_tx_queue = rt2x00usb_kick_tx_queue, |