* [PATCH] ath9k: This patch fix RX unpadding for any received frame.
@ 2009-11-19 21:19 Benoit Papillault
2009-11-19 21:25 ` John W. Linville
2009-11-20 17:17 ` Luis R. Rodriguez
0 siblings, 2 replies; 8+ messages in thread
From: Benoit Papillault @ 2009-11-19 21:19 UTC (permalink / raw)
To: lrodriguez; +Cc: jmalinen, linux-wireless, ath9k-devel
From: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
It has been tested with a 802.11 frame generator and by checking the FCS field
of each received frame with the value reported by the Atheros hardware. This
patch is useful if you are trying to analyze non standard 802.11 frame going
over the air.
Signed-off-by: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
---
drivers/net/wireless/ath/ath9k/common.c | 19 ++++++++++++++-----
1 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 2f1e161..4a13632 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -231,26 +231,35 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
{
struct ath_hw *ah = common->ah;
struct ieee80211_hdr *hdr;
- int hdrlen, padsize;
+ int hdrlen, padpos, padsize;
u8 keyix;
__le16 fc;
/* see if any padding is done by the hw and remove it */
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ padpos = 24;
fc = hdr->frame_control;
+ if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) ==
+ cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
+ padpos += 6; /* ETH_ALEN */
+ }
+ if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
+ cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
+ padpos += 2;
+ }
/* The MAC header is padded to have 32-bit boundary if the
* packet payload is non-zero. The general calculation for
* padsize would take into account odd header lengths:
- * padsize = (4 - hdrlen % 4) % 4; However, since only
+ * padsize = (4 - padpos % 4) % 4; However, since only
* even-length headers are used, padding can only be 0 or 2
* bytes and we can optimize this a bit. In addition, we must
* not try to remove padding from short control frames that do
* not have payload. */
- padsize = hdrlen & 3;
- if (padsize && hdrlen >= 24) {
- memmove(skb->data + padsize, skb->data, hdrlen);
+ padsize = padpos & 3;
+ if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
+ memmove(skb->data + padsize, skb->data, padpos);
skb_pull(skb, padsize);
}
--
1.6.3.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] ath9k: This patch fix RX unpadding for any received frame.
2009-11-19 21:19 Benoit Papillault
@ 2009-11-19 21:25 ` John W. Linville
2009-11-19 21:36 ` Benoit PAPILLAULT
2009-11-20 17:17 ` Luis R. Rodriguez
1 sibling, 1 reply; 8+ messages in thread
From: John W. Linville @ 2009-11-19 21:25 UTC (permalink / raw)
To: Benoit Papillault; +Cc: lrodriguez, jmalinen, linux-wireless, ath9k-devel
On Thu, Nov 19, 2009 at 10:19:26PM +0100, Benoit Papillault wrote:
> From: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>
> It has been tested with a 802.11 frame generator and by checking the FCS field
> of each received frame with the value reported by the Atheros hardware. This
> patch is useful if you are trying to analyze non standard 802.11 frame going
> over the air.
>
> Signed-off-by: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
Are you sure this is this the email address you want?
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ath9k: This patch fix RX unpadding for any received frame.
2009-11-19 21:25 ` John W. Linville
@ 2009-11-19 21:36 ` Benoit PAPILLAULT
0 siblings, 0 replies; 8+ messages in thread
From: Benoit PAPILLAULT @ 2009-11-19 21:36 UTC (permalink / raw)
To: John W. Linville; +Cc: lrodriguez, jmalinen, linux-wireless, ath9k-devel
John W. Linville a écrit :
> On Thu, Nov 19, 2009 at 10:19:26PM +0100, Benoit Papillault wrote:
>> From: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>>
>> It has been tested with a 802.11 frame generator and by checking the FCS field
>> of each received frame with the value reported by the Atheros hardware. This
>> patch is useful if you are trying to analyze non standard 802.11 frame going
>> over the air.
>>
>> Signed-off-by: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>
> Are you sure this is this the email address you want?
>
No. It should be benoit.papillault@free.fr of course. I configured git a
bit too late (after commit).
Sorry about that,
Benoit
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ath9k: This patch fix RX unpadding for any received frame.
2009-11-19 21:19 Benoit Papillault
2009-11-19 21:25 ` John W. Linville
@ 2009-11-20 17:17 ` Luis R. Rodriguez
2009-11-20 21:22 ` Benoit PAPILLAULT
1 sibling, 1 reply; 8+ messages in thread
From: Luis R. Rodriguez @ 2009-11-20 17:17 UTC (permalink / raw)
To: Benoit Papillault; +Cc: jmalinen, linux-wireless, ath9k-devel
On Thu, Nov 19, 2009 at 1:19 PM, Benoit Papillault
<benoit.papillault@free.fr> wrote:
> From: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>
> It has been tested with a 802.11 frame generator and by checking the FCS field
> of each received frame with the value reported by the Atheros hardware. This
> patch is useful if you are trying to analyze non standard 802.11 frame going
> over the air.
Thank you for your patch! But can you please elaborate on your commit
log entry? This just tells me that you've tested it and how its useful
but it in no way tells me what you found was wrong and also does not
explain how you fixed it.
> Signed-off-by: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
> ---
> drivers/net/wireless/ath/ath9k/common.c | 19 ++++++++++++++-----
> 1 files changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
> index 2f1e161..4a13632 100644
> --- a/drivers/net/wireless/ath/ath9k/common.c
> +++ b/drivers/net/wireless/ath/ath9k/common.c
> @@ -231,26 +231,35 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
> {
> struct ath_hw *ah = common->ah;
> struct ieee80211_hdr *hdr;
> - int hdrlen, padsize;
> + int hdrlen, padpos, padsize;
> u8 keyix;
> __le16 fc;
>
> /* see if any padding is done by the hw and remove it */
> hdr = (struct ieee80211_hdr *) skb->data;
> hdrlen = ieee80211_get_hdrlen_from_skb(skb);
> + padpos = 24;
> fc = hdr->frame_control;
> + if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) ==
> + cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
> + padpos += 6; /* ETH_ALEN */
> + }
How about just using ETH_ALEN then?
> + if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
> + cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
> + padpos += 2;
> + }
>
> /* The MAC header is padded to have 32-bit boundary if the
> * packet payload is non-zero. The general calculation for
> * padsize would take into account odd header lengths:
> - * padsize = (4 - hdrlen % 4) % 4; However, since only
> + * padsize = (4 - padpos % 4) % 4; However, since only
> * even-length headers are used, padding can only be 0 or 2
> * bytes and we can optimize this a bit. In addition, we must
> * not try to remove padding from short control frames that do
> * not have payload. */
> - padsize = hdrlen & 3;
> - if (padsize && hdrlen >= 24) {
> - memmove(skb->data + padsize, skb->data, hdrlen);
> + padsize = padpos & 3;
> + if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
> + memmove(skb->data + padsize, skb->data, padpos);
> skb_pull(skb, padsize);
> }
If the skb->len would have been short ieee80211_get_hdrlen_from_skb()
would have picked up on this and 0 would have been used for hdrlen
therefore skipping this operation. With this patch even if skb->len
was 0 your padsize is always based on some static value. Additionally
its unclear to me how and why you substitute
ieee80211_get_hdrlen_from_skb() to a static 24 + something.
Also the possible static values for padpos are either (24 + 2) or (24
+ 6) right? Well these & 3 will always give true. So you are always
padding and this changes the way this was being implemented.
Unless I'm missing something.
Luis
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] ath9k: This patch fix RX unpadding for any received frame.
2009-11-20 17:17 ` Luis R. Rodriguez
@ 2009-11-20 21:22 ` Benoit PAPILLAULT
0 siblings, 0 replies; 8+ messages in thread
From: Benoit PAPILLAULT @ 2009-11-20 21:22 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: jmalinen, linux-wireless, ath9k-devel
Luis R. Rodriguez a écrit :
> On Thu, Nov 19, 2009 at 1:19 PM, Benoit Papillault
> <benoit.papillault@free.fr> wrote:
>> From: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>>
>> It has been tested with a 802.11 frame generator and by checking the FCS field
>> of each received frame with the value reported by the Atheros hardware. This
>> patch is useful if you are trying to analyze non standard 802.11 frame going
>> over the air.
>
> Thank you for your patch! But can you please elaborate on your commit
> log entry? This just tells me that you've tested it and how its useful
> but it in no way tells me what you found was wrong and also does not
> explain how you fixed it.
Sure. I use a 802.11 frame generator that generates every value for the
first 2 bytes (frame control field) and a varying length. What was wrong
is that using ath9k and a monitor interface, I was getting frames with
padding still inside or unpadding done at the wrong position and as
such, wrong FCS. In order to fix it, I use the FCS field of received
frame and tried every position and size for unpadding. This way I found
a formula that gives me the exact position and size for proper
unpadding. I then put this formula into ath9k. This formula is different
from 802.11 hdrlen.
>
>> Signed-off-by: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>> ---
>> drivers/net/wireless/ath/ath9k/common.c | 19 ++++++++++++++-----
>> 1 files changed, 14 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
>> index 2f1e161..4a13632 100644
>> --- a/drivers/net/wireless/ath/ath9k/common.c
>> +++ b/drivers/net/wireless/ath/ath9k/common.c
>> @@ -231,26 +231,35 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
>> {
>> struct ath_hw *ah = common->ah;
>> struct ieee80211_hdr *hdr;
>> - int hdrlen, padsize;
>> + int hdrlen, padpos, padsize;
>> u8 keyix;
>> __le16 fc;
>>
>> /* see if any padding is done by the hw and remove it */
>> hdr = (struct ieee80211_hdr *) skb->data;
>> hdrlen = ieee80211_get_hdrlen_from_skb(skb);
>> + padpos = 24;
>> fc = hdr->frame_control;
>> + if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) ==
>> + cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
>> + padpos += 6; /* ETH_ALEN */
>> + }
>
> How about just using ETH_ALEN then?
Indeed. I was just in a hurry.
>
>> + if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
>> + cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
>> + padpos += 2;
>> + }
>>
>> /* The MAC header is padded to have 32-bit boundary if the
>> * packet payload is non-zero. The general calculation for
>> * padsize would take into account odd header lengths:
>> - * padsize = (4 - hdrlen % 4) % 4; However, since only
>> + * padsize = (4 - padpos % 4) % 4; However, since only
>> * even-length headers are used, padding can only be 0 or 2
>> * bytes and we can optimize this a bit. In addition, we must
>> * not try to remove padding from short control frames that do
>> * not have payload. */
>> - padsize = hdrlen & 3;
>> - if (padsize && hdrlen >= 24) {
>> - memmove(skb->data + padsize, skb->data, hdrlen);
>> + padsize = padpos & 3;
>> + if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
>> + memmove(skb->data + padsize, skb->data, padpos);
>> skb_pull(skb, padsize);
>> }
>
> If the skb->len would have been short ieee80211_get_hdrlen_from_skb()
> would have picked up on this and 0 would have been used for hdrlen
> therefore skipping this operation. With this patch even if skb->len
> was 0 your padsize is always based on some static value. Additionally
> its unclear to me how and why you substitute
> ieee80211_get_hdrlen_from_skb() to a static 24 + something.
The substitution is indeed the key of this patch. The check about
skb->len is to make sure that the frame is large enough to contain the
computed padding, which cannot be contained in the FCS field itself.
>
> Also the possible static values for padpos are either (24 + 2) or (24
> + 6) right? Well these & 3 will always give true. So you are always
> padding and this changes the way this was being implemented.
It can be 24, 24+6=30, 24+2=26 or 24+6+2=28. With the &3 mask, this
gives : 0 (for 24), 2 (for 30), 2 (for 26) and 0 (for 28).
>
> Unless I'm missing something.
>
> Luis
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Regards,
Benoit
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] ath9k: This patch fix RX unpadding for any received frame.
@ 2009-11-24 14:49 Benoit Papillault
2009-11-24 14:49 ` [PATCH 2/2] ath9k: Proper padding/unpadding for the TX/RX path Benoit Papillault
2009-11-24 14:51 ` [PATCH] ath9k: This patch fix RX unpadding for any received frame Benoit PAPILLAULT
0 siblings, 2 replies; 8+ messages in thread
From: Benoit Papillault @ 2009-11-24 14:49 UTC (permalink / raw)
To: lrodriguez; +Cc: jmalinen, linux-wireless, ath9k-devel
From: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
It has been tested with a 802.11 frame generator and by checking the FCS field
of each received frame with the value reported by the Atheros hardware. This
patch is useful if you are trying to analyze non standard 802.11 frame going
over the air.
Signed-off-by: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
---
drivers/net/wireless/ath/ath9k/common.c | 19 ++++++++++++++-----
1 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 2f1e161..4a13632 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -231,26 +231,35 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
{
struct ath_hw *ah = common->ah;
struct ieee80211_hdr *hdr;
- int hdrlen, padsize;
+ int hdrlen, padpos, padsize;
u8 keyix;
__le16 fc;
/* see if any padding is done by the hw and remove it */
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ padpos = 24;
fc = hdr->frame_control;
+ if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) ==
+ cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
+ padpos += 6; /* ETH_ALEN */
+ }
+ if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
+ cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
+ padpos += 2;
+ }
/* The MAC header is padded to have 32-bit boundary if the
* packet payload is non-zero. The general calculation for
* padsize would take into account odd header lengths:
- * padsize = (4 - hdrlen % 4) % 4; However, since only
+ * padsize = (4 - padpos % 4) % 4; However, since only
* even-length headers are used, padding can only be 0 or 2
* bytes and we can optimize this a bit. In addition, we must
* not try to remove padding from short control frames that do
* not have payload. */
- padsize = hdrlen & 3;
- if (padsize && hdrlen >= 24) {
- memmove(skb->data + padsize, skb->data, hdrlen);
+ padsize = padpos & 3;
+ if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
+ memmove(skb->data + padsize, skb->data, padpos);
skb_pull(skb, padsize);
}
--
1.6.3.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] ath9k: Proper padding/unpadding for the TX/RX path.
2009-11-24 14:49 [PATCH] ath9k: This patch fix RX unpadding for any received frame Benoit Papillault
@ 2009-11-24 14:49 ` Benoit Papillault
2009-11-24 14:51 ` [PATCH] ath9k: This patch fix RX unpadding for any received frame Benoit PAPILLAULT
1 sibling, 0 replies; 8+ messages in thread
From: Benoit Papillault @ 2009-11-24 14:49 UTC (permalink / raw)
To: lrodriguez; +Cc: jmalinen, linux-wireless, ath9k-devel, Benoit Papillault
Software padding is done on the TX path and software unpadding is done on the
RX path. This patch corrects the position where the padding occurs. A specific
function computes the pad position and this function is used in the TX and RX
path. This patch has been tested by generating every possible 802.11 frames
with every possible frame_control field and a varying length. This patch is
useful for analyzing non standard 802.11 frames going over the air
Signed-off-by: Benoit Papillault <benoit.papillault@free.fr>
---
drivers/net/wireless/ath/ath9k/common.c | 24 +++++++++++++++---------
drivers/net/wireless/ath/ath9k/common.h | 2 ++
drivers/net/wireless/ath/ath9k/main.c | 14 ++++++--------
drivers/net/wireless/ath/ath9k/xmit.c | 9 ++++++++-
4 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 4a13632..d363bb3 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -238,16 +238,8 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
/* see if any padding is done by the hw and remove it */
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- padpos = 24;
fc = hdr->frame_control;
- if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) ==
- cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
- padpos += 6; /* ETH_ALEN */
- }
- if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
- cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
- padpos += 2;
- }
+ padpos = ath9k_cmn_padpos(hdr->frame_control);
/* The MAC header is padded to have 32-bit boundary if the
* packet payload is non-zero. The general calculation for
@@ -282,6 +274,20 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
}
EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess);
+int ath9k_cmn_padpos(__le16 frame_control)
+{
+ int padpos = 24;
+ if (ieee80211_has_a4(frame_control)) {
+ padpos += ETH_ALEN;
+ }
+ if (ieee80211_is_data_qos(frame_control)) {
+ padpos += IEEE80211_QOS_CTL_LEN;
+ }
+
+ return padpos;
+}
+EXPORT_SYMBOL(ath9k_cmn_padpos);
+
static int __init ath9k_cmn_init(void)
{
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 4e11760..b188fc3 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -122,3 +122,5 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
struct ath_rx_status *rx_stats,
struct ieee80211_rx_status *rxs,
bool decrypt_error);
+
+int ath9k_cmn_padpos(__le16 frame_control);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index cbf5d2a..df2e2ae 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2394,7 +2394,8 @@ static int ath9k_tx(struct ieee80211_hw *hw,
struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_tx_control txctl;
- int hdrlen, padsize;
+ int padpos, padsize;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
ath_print(common, ATH_DBG_XMIT,
@@ -2404,7 +2405,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
}
if (sc->ps_enabled) {
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
/*
* mac80211 does not set PM field for normal data frames, so we
* need to update that based on the current PS mode.
@@ -2424,7 +2424,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
* power save mode. Need to wake up hardware for the TX to be
* completed and if needed, also for RX of buffered frames.
*/
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
ath9k_ps_wakeup(sc);
ath9k_hw_setrxabort(sc->sc_ah, 0);
if (ieee80211_is_pspoll(hdr->frame_control)) {
@@ -2452,7 +2451,6 @@ static int ath9k_tx(struct ieee80211_hw *hw,
* BSSes.
*/
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
sc->tx.seq_no += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
@@ -2460,13 +2458,13 @@ static int ath9k_tx(struct ieee80211_hw *hw,
}
/* Add the padding after the header if this is not already done */
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- if (hdrlen & 3) {
- padsize = hdrlen % 4;
+ padpos = ath9k_cmn_padpos(hdr->frame_control);
+ padsize = padpos & 3;
+ if (padsize && skb->len>padpos) {
if (skb_headroom(skb) < padsize)
return -1;
skb_push(skb, padsize);
- memmove(skb->data, skb->data + padsize, hdrlen);
+ memmove(skb->data, skb->data + padsize, padpos);
}
/* Check if a tx queue is available */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 745d919..046986e 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1554,6 +1554,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
int hdrlen;
__le16 fc;
+ int padpos, padsize;
tx_info->pad[0] = 0;
switch (txctl->frame_type) {
@@ -1572,7 +1573,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
ATH_TXBUF_RESET(bf);
bf->aphy = aphy;
- bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
+ bf->bf_frmlen = skb->len + FCS_LEN;
+ /* Remove the padding size from bf_frmlen, if any */
+ padpos = ath9k_cmn_padpos(hdr->frame_control);
+ padsize = padpos & 3;
+ if (padsize && skb->len>padpos+padsize) {
+ bf->bf_frmlen -= padsize;
+ }
if (conf_is_ht(&hw->conf) && !is_pae(skb))
bf->bf_state.bf_type |= BUF_HT;
--
1.6.3.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] ath9k: This patch fix RX unpadding for any received frame.
2009-11-24 14:49 [PATCH] ath9k: This patch fix RX unpadding for any received frame Benoit Papillault
2009-11-24 14:49 ` [PATCH 2/2] ath9k: Proper padding/unpadding for the TX/RX path Benoit Papillault
@ 2009-11-24 14:51 ` Benoit PAPILLAULT
1 sibling, 0 replies; 8+ messages in thread
From: Benoit PAPILLAULT @ 2009-11-24 14:51 UTC (permalink / raw)
To: lrodriguez; +Cc: jmalinen, linux-wireless, ath9k-devel
Oops... Disregard this one, it has been already applied.
Regards, Benoit.
Benoit Papillault a écrit :
> From: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
>
> It has been tested with a 802.11 frame generator and by checking the FCS field
> of each received frame with the value reported by the Atheros hardware. This
> patch is useful if you are trying to analyze non standard 802.11 frame going
> over the air.
>
> Signed-off-by: Benoit PAPILLAULT <benoit@benoit-laptop.(none)>
> ---
> drivers/net/wireless/ath/ath9k/common.c | 19 ++++++++++++++-----
> 1 files changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
> index 2f1e161..4a13632 100644
> --- a/drivers/net/wireless/ath/ath9k/common.c
> +++ b/drivers/net/wireless/ath/ath9k/common.c
> @@ -231,26 +231,35 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
> {
> struct ath_hw *ah = common->ah;
> struct ieee80211_hdr *hdr;
> - int hdrlen, padsize;
> + int hdrlen, padpos, padsize;
> u8 keyix;
> __le16 fc;
>
> /* see if any padding is done by the hw and remove it */
> hdr = (struct ieee80211_hdr *) skb->data;
> hdrlen = ieee80211_get_hdrlen_from_skb(skb);
> + padpos = 24;
> fc = hdr->frame_control;
> + if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) ==
> + cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
> + padpos += 6; /* ETH_ALEN */
> + }
> + if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
> + cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
> + padpos += 2;
> + }
>
> /* The MAC header is padded to have 32-bit boundary if the
> * packet payload is non-zero. The general calculation for
> * padsize would take into account odd header lengths:
> - * padsize = (4 - hdrlen % 4) % 4; However, since only
> + * padsize = (4 - padpos % 4) % 4; However, since only
> * even-length headers are used, padding can only be 0 or 2
> * bytes and we can optimize this a bit. In addition, we must
> * not try to remove padding from short control frames that do
> * not have payload. */
> - padsize = hdrlen & 3;
> - if (padsize && hdrlen >= 24) {
> - memmove(skb->data + padsize, skb->data, hdrlen);
> + padsize = padpos & 3;
> + if (padsize && skb->len>=padpos+padsize+FCS_LEN) {
> + memmove(skb->data + padsize, skb->data, padpos);
> skb_pull(skb, padsize);
> }
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-11-24 14:51 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-24 14:49 [PATCH] ath9k: This patch fix RX unpadding for any received frame Benoit Papillault
2009-11-24 14:49 ` [PATCH 2/2] ath9k: Proper padding/unpadding for the TX/RX path Benoit Papillault
2009-11-24 14:51 ` [PATCH] ath9k: This patch fix RX unpadding for any received frame Benoit PAPILLAULT
-- strict thread matches above, loose matches on Subject: below --
2009-11-19 21:19 Benoit Papillault
2009-11-19 21:25 ` John W. Linville
2009-11-19 21:36 ` Benoit PAPILLAULT
2009-11-20 17:17 ` Luis R. Rodriguez
2009-11-20 21:22 ` Benoit PAPILLAULT
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).