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 | |
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')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.h | 90 |
2 files changed, 97 insertions, 31 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)) |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h index 1e4340a182ef..d1d8ae94b4d4 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.h +++ b/drivers/net/wireless/rt2x00/rt2800usb.h | |||
@@ -79,6 +79,8 @@ | |||
79 | */ | 79 | */ |
80 | #define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) | 80 | #define TXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) |
81 | #define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) | 81 | #define RXINFO_DESC_SIZE ( 1 * sizeof(__le32) ) |
82 | #define RXWI_DESC_SIZE ( 4 * sizeof(__le32) ) | ||
83 | #define RXD_DESC_SIZE ( 1 * sizeof(__le32) ) | ||
82 | 84 | ||
83 | /* | 85 | /* |
84 | * TX Info structure | 86 | * TX Info structure |
@@ -101,6 +103,54 @@ | |||
101 | #define TXINFO_W0_USB_DMA_TX_BURST FIELD32(0x80000000) | 103 | #define TXINFO_W0_USB_DMA_TX_BURST FIELD32(0x80000000) |
102 | 104 | ||
103 | /* | 105 | /* |
106 | * RX Info structure | ||
107 | */ | ||
108 | |||
109 | /* | ||
110 | * Word 0 | ||
111 | */ | ||
112 | |||
113 | #define RXINFO_W0_USB_DMA_RX_PKT_LEN FIELD32(0x0000ffff) | ||
114 | |||
115 | /* | ||
116 | * RX WI structure | ||
117 | */ | ||
118 | |||
119 | /* | ||
120 | * Word0 | ||
121 | */ | ||
122 | #define RXWI_W0_WIRELESS_CLI_ID FIELD32(0x000000ff) | ||
123 | #define RXWI_W0_KEY_INDEX FIELD32(0x00000300) | ||
124 | #define RXWI_W0_BSSID FIELD32(0x00001c00) | ||
125 | #define RXWI_W0_UDF FIELD32(0x0000e000) | ||
126 | #define RXWI_W0_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000) | ||
127 | #define RXWI_W0_TID FIELD32(0xf0000000) | ||
128 | |||
129 | /* | ||
130 | * Word1 | ||
131 | */ | ||
132 | #define RXWI_W1_FRAG FIELD32(0x0000000f) | ||
133 | #define RXWI_W1_SEQUENCE FIELD32(0x0000fff0) | ||
134 | #define RXWI_W1_MCS FIELD32(0x007f0000) | ||
135 | #define RXWI_W1_BW FIELD32(0x00800000) | ||
136 | #define RXWI_W1_SHORT_GI FIELD32(0x01000000) | ||
137 | #define RXWI_W1_STBC FIELD32(0x06000000) | ||
138 | #define RXWI_W1_PHYMODE FIELD32(0xc0000000) | ||
139 | |||
140 | /* | ||
141 | * Word2 | ||
142 | */ | ||
143 | #define RXWI_W2_RSSI0 FIELD32(0x000000ff) | ||
144 | #define RXWI_W2_RSSI1 FIELD32(0x0000ff00) | ||
145 | #define RXWI_W2_RSSI2 FIELD32(0x00ff0000) | ||
146 | |||
147 | /* | ||
148 | * Word3 | ||
149 | */ | ||
150 | #define RXWI_W3_SNR0 FIELD32(0x000000ff) | ||
151 | #define RXWI_W3_SNR1 FIELD32(0x0000ff00) | ||
152 | |||
153 | /* | ||
104 | * RX descriptor format for RX Ring. | 154 | * RX descriptor format for RX Ring. |
105 | */ | 155 | */ |
106 | 156 | ||
@@ -115,25 +165,25 @@ | |||
115 | * AMSDU: rx with 802.3 header, not 802.11 header. | 165 | * AMSDU: rx with 802.3 header, not 802.11 header. |
116 | */ | 166 | */ |
117 | 167 | ||
118 | #define RXINFO_W0_BA FIELD32(0x00000001) | 168 | #define RXD_W0_BA FIELD32(0x00000001) |
119 | #define RXINFO_W0_DATA FIELD32(0x00000002) | 169 | #define RXD_W0_DATA FIELD32(0x00000002) |
120 | #define RXINFO_W0_NULLDATA FIELD32(0x00000004) | 170 | #define RXD_W0_NULLDATA FIELD32(0x00000004) |
121 | #define RXINFO_W0_FRAG FIELD32(0x00000008) | 171 | #define RXD_W0_FRAG FIELD32(0x00000008) |
122 | #define RXINFO_W0_UNICAST_TO_ME FIELD32(0x00000010) | 172 | #define RXD_W0_UNICAST_TO_ME FIELD32(0x00000010) |
123 | #define RXINFO_W0_MULTICAST FIELD32(0x00000020) | 173 | #define RXD_W0_MULTICAST FIELD32(0x00000020) |
124 | #define RXINFO_W0_BROADCAST FIELD32(0x00000040) | 174 | #define RXD_W0_BROADCAST FIELD32(0x00000040) |
125 | #define RXINFO_W0_MY_BSS FIELD32(0x00000080) | 175 | #define RXD_W0_MY_BSS FIELD32(0x00000080) |
126 | #define RXINFO_W0_CRC_ERROR FIELD32(0x00000100) | 176 | #define RXD_W0_CRC_ERROR FIELD32(0x00000100) |
127 | #define RXINFO_W0_CIPHER_ERROR FIELD32(0x00000600) | 177 | #define RXD_W0_CIPHER_ERROR FIELD32(0x00000600) |
128 | #define RXINFO_W0_AMSDU FIELD32(0x00000800) | 178 | #define RXD_W0_AMSDU FIELD32(0x00000800) |
129 | #define RXINFO_W0_HTC FIELD32(0x00001000) | 179 | #define RXD_W0_HTC FIELD32(0x00001000) |
130 | #define RXINFO_W0_RSSI FIELD32(0x00002000) | 180 | #define RXD_W0_RSSI FIELD32(0x00002000) |
131 | #define RXINFO_W0_L2PAD FIELD32(0x00004000) | 181 | #define RXD_W0_L2PAD FIELD32(0x00004000) |
132 | #define RXINFO_W0_AMPDU FIELD32(0x00008000) | 182 | #define RXD_W0_AMPDU FIELD32(0x00008000) |
133 | #define RXINFO_W0_DECRYPTED FIELD32(0x00010000) | 183 | #define RXD_W0_DECRYPTED FIELD32(0x00010000) |
134 | #define RXINFO_W0_PLCP_RSSI FIELD32(0x00020000) | 184 | #define RXD_W0_PLCP_RSSI FIELD32(0x00020000) |
135 | #define RXINFO_W0_CIPHER_ALG FIELD32(0x00040000) | 185 | #define RXD_W0_CIPHER_ALG FIELD32(0x00040000) |
136 | #define RXINFO_W0_LAST_AMSDU FIELD32(0x00080000) | 186 | #define RXD_W0_LAST_AMSDU FIELD32(0x00080000) |
137 | #define RXINFO_W0_PLCP_SIGNAL FIELD32(0xfff00000) | 187 | #define RXD_W0_PLCP_SIGNAL FIELD32(0xfff00000) |
138 | 188 | ||
139 | #endif /* RT2800USB_H */ | 189 | #endif /* RT2800USB_H */ |