diff options
author | Benoit Papillault <benoit.papillault@free.fr> | 2009-12-04 17:47:06 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-12-21 18:56:39 -0500 |
commit | 5de42f9eeafa7d54ffb833e0526d4828e194fddb (patch) | |
tree | 4e7318d01b6e46e0271c17b347854e5c67712c8c /drivers/net/wireless/rt2x00/rt2800usb.c | |
parent | 9c8427d9deca1c0c2415c8da0e731e13fc89d111 (diff) |
rt2x00: Fix rt2800usb RX frame format and as such L2PAD
According to Ralink source code, the RX frame format is RXINFO + RXWI +
802.11 frame + RXD, including various padding. Before this patch, we
were using RXD + RXWI + 802.11 frame, so RXD was not correct.
Doing this, we fix the L2PAD bit which is now correctly set on received
frames.
Signed-off-by: Benoit Papillault <benoit.papillault@free.fr>
Acked-by: Ivo van Doorn <ivdoorn@gmail.com>
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2800usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 9c4412b42e5b..40295b454ff6 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -571,41 +571,57 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
571 | { | 571 | { |
572 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 572 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
573 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 573 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
574 | __le32 *rxd = (__le32 *)entry->skb->data; | 574 | __le32 *rxi = (__le32 *)entry->skb->data; |
575 | __le32 *rxwi; | 575 | __le32 *rxwi; |
576 | u32 rxd0; | 576 | __le32 *rxd; |
577 | u32 rxi0; | ||
577 | u32 rxwi0; | 578 | u32 rxwi0; |
578 | u32 rxwi1; | 579 | u32 rxwi1; |
579 | u32 rxwi2; | 580 | u32 rxwi2; |
580 | u32 rxwi3; | 581 | u32 rxwi3; |
582 | u32 rxd0; | ||
583 | int rx_pkt_len; | ||
584 | |||
585 | /* | ||
586 | * RX frame format is : | ||
587 | * | RXINFO | RXWI | header | L2 pad | payload | pad | RXD | USB pad | | ||
588 | * |<------------ rx_pkt_len -------------->| | ||
589 | */ | ||
590 | rt2x00_desc_read(rxi, 0, &rxi0); | ||
591 | rx_pkt_len = rt2x00_get_field32(rxi0, RXINFO_W0_USB_DMA_RX_PKT_LEN); | ||
592 | |||
593 | rxwi = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE); | ||
594 | |||
595 | /* | ||
596 | * FIXME : we need to check for rx_pkt_len validity | ||
597 | */ | ||
598 | rxd = (__le32 *)(entry->skb->data + RXINFO_DESC_SIZE + rx_pkt_len); | ||
581 | 599 | ||
582 | /* | 600 | /* |
583 | * Copy descriptor to the skbdesc->desc buffer, making it safe from | 601 | * Copy descriptor to the skbdesc->desc buffer, making it safe from |
584 | * moving of frame data in rt2x00usb. | 602 | * moving of frame data in rt2x00usb. |
585 | */ | 603 | */ |
586 | memcpy(skbdesc->desc, rxd, skbdesc->desc_len); | 604 | memcpy(skbdesc->desc, rxi, skbdesc->desc_len); |
587 | rxd = (__le32 *)skbdesc->desc; | ||
588 | rxwi = &rxd[RXINFO_DESC_SIZE / sizeof(__le32)]; | ||
589 | 605 | ||
590 | /* | 606 | /* |
591 | * It is now safe to read the descriptor on all architectures. | 607 | * It is now safe to read the descriptor on all architectures. |
592 | */ | 608 | */ |
593 | rt2x00_desc_read(rxd, 0, &rxd0); | ||
594 | rt2x00_desc_read(rxwi, 0, &rxwi0); | 609 | rt2x00_desc_read(rxwi, 0, &rxwi0); |
595 | rt2x00_desc_read(rxwi, 1, &rxwi1); | 610 | rt2x00_desc_read(rxwi, 1, &rxwi1); |
596 | rt2x00_desc_read(rxwi, 2, &rxwi2); | 611 | rt2x00_desc_read(rxwi, 2, &rxwi2); |
597 | rt2x00_desc_read(rxwi, 3, &rxwi3); | 612 | rt2x00_desc_read(rxwi, 3, &rxwi3); |
613 | rt2x00_desc_read(rxd, 0, &rxd0); | ||
598 | 614 | ||
599 | if (rt2x00_get_field32(rxd0, RXINFO_W0_CRC_ERROR)) | 615 | if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR)) |
600 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; | 616 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
601 | 617 | ||
602 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { | 618 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { |
603 | rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF); | 619 | rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF); |
604 | rxdesc->cipher_status = | 620 | rxdesc->cipher_status = |
605 | rt2x00_get_field32(rxd0, RXINFO_W0_CIPHER_ERROR); | 621 | rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR); |
606 | } | 622 | } |
607 | 623 | ||
608 | if (rt2x00_get_field32(rxd0, RXINFO_W0_DECRYPTED)) { | 624 | if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) { |
609 | /* | 625 | /* |
610 | * Hardware has stripped IV/EIV data from 802.11 frame during | 626 | * Hardware has stripped IV/EIV data from 802.11 frame during |
611 | * decryption. Unfortunately the descriptor doesn't contain | 627 | * decryption. Unfortunately the descriptor doesn't contain |
@@ -620,10 +636,10 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
620 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; | 636 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; |
621 | } | 637 | } |
622 | 638 | ||
623 | if (rt2x00_get_field32(rxd0, RXINFO_W0_MY_BSS)) | 639 | if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS)) |
624 | rxdesc->dev_flags |= RXDONE_MY_BSS; | 640 | rxdesc->dev_flags |= RXDONE_MY_BSS; |
625 | 641 | ||
626 | if (rt2x00_get_field32(rxd0, RXINFO_W0_L2PAD)) | 642 | if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD)) |
627 | rxdesc->dev_flags |= RXDONE_L2PAD; | 643 | rxdesc->dev_flags |= RXDONE_L2PAD; |
628 | 644 | ||
629 | if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI)) | 645 | if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI)) |