From: "John W. Linville" <linville@tuxdriver.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Michael Buesch <mb@bu3sch.de>, Dan Williams <dcbw@redhat.com>,
Johannes Berg <johannes@sipsolutions.net>,
linux-wireless@vger.kernel.org
Subject: Re: Linux 2.6.24-rc7
Date: Fri, 25 Jan 2008 16:18:15 -0500 [thread overview]
Message-ID: <20080125211815.GF14687@tuxdriver.com> (raw)
In-Reply-To: <20080125195037.GE14687@tuxdriver.com>
On Fri, Jan 25, 2008 at 02:50:37PM -0500, John W. Linville wrote:
> On Fri, Jan 25, 2008 at 02:48:07PM -0500, John W. Linville wrote:
>
> > http://kerneltrap.org/mailarchive/linux-netdev/2007/11/24/442496
> >
> > Quoth Herbert Xu:
> >
> > "OK. Let me clarify this a bit more. We require at least one
> > of the following rules to be met:
> >
> > * the IPv4/IPv6 header is aligned by 8 bytes on reception;
> > * or the platform provides unaligned exception handlers.
>
> > (Hmmm..."aligned by 8 bytes", so our warning and my iwlwifi patch
> > may still not be right...)
>
> http://kerneltrap.org/mailarchive/linux-netdev/2007/11/25/443558
>
> More from Herbert:
>
> "Sorry I was wrong about the 8 bytes requirement. Although the
> IPv6 protocol does try to maintain an 8-byte alignment the Linux
> stack never does anything that requires that.
>
> So 4 bytes is enough."
>
> Phew!
Alright, here is my whack at it... The iwl_handle_data_packet_monitor
bits are untested, as I appear to be too daft to figure-out how to
exercise those paths.
Anyway, this is mostly just so we can scope the driver change required
in absence of a firmware change. Persumably the changes required if
we were to put such code in mac80211 would be similar.
John
-----
From: John W. Linville <linville@tuxdriver.com>
Subject: [PATCH] iwlwifi: move data at CPU to ensure 4-byte alignment for payload
Ugly, but if the firmware won't cooperate...
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 13 ++++++++++---
drivers/net/wireless/iwlwifi/iwl-4965.c | 10 +++++++++-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 10 +++++++++-
drivers/net/wireless/iwlwifi/iwl4965-base.c | 10 +++++++++-
4 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 3a45fe9..06cd28e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -252,6 +252,7 @@ static void iwl3945_handle_data_packet(struct iwl_priv *priv, int is_data,
struct iwl_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
struct iwl_rx_frame_end *rx_end = IWL_RX_END(pkt);
short len = le16_to_cpu(rx_hdr->len);
+ int hdrlen, align;
/* We received data from the HW, so stop the watchdog */
if (unlikely((len + IWL_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
@@ -275,11 +276,17 @@ static void iwl3945_handle_data_packet(struct iwl_priv *priv, int is_data,
return;
}
- skb_reserve(rxb->skb, (void *)rx_hdr->payload - (void *)pkt);
+ hdr = (void *)rx_hdr->payload;
+ hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
+ align = hdrlen & 3;
+
+ skb_reserve(rxb->skb, (void *)rx_hdr->payload - (void *)pkt - align);
/* Set the size of the skb to the size of the frame */
- skb_put(rxb->skb, le16_to_cpu(rx_hdr->len));
+ skb_put(rxb->skb, len);
- hdr = (void *)rxb->skb->data;
+ /* align payload on 4-byte boundary if necessary */
+ if (align)
+ memmove((void *)hdr - align, hdr, len);
if (iwl_param_hwcrypto)
iwl_set_decrypted_flag(priv, rxb->skb,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 891f90d..11eb75b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -3496,6 +3496,7 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
__le32 *rx_end;
unsigned int skblen;
u32 ampdu_status;
+ int hdrlen, align;
if (!include_phy && priv->last_phy_res[0])
rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
@@ -3533,10 +3534,17 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
ampdu_status = le32_to_cpu(*rx_end);
skblen = ((u8 *) rx_end - (u8 *) & pkt->u.raw[0]) + sizeof(u32);
+ hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
+ align = hdrlen & 3;
+
/* start from MAC */
- skb_reserve(rxb->skb, (void *)hdr - (void *)pkt);
+ skb_reserve(rxb->skb, (void *)hdr - (void *)pkt - align);
skb_put(rxb->skb, len); /* end where data ends */
+ /* align payload on 4-byte boundary if necessary */
+ if (align)
+ memmove(rxb->skb->data, hdr, len);
+
/* We only process data packets if the interface is open */
if (unlikely(!priv->is_open)) {
IWL_DEBUG_DROP_LIMIT
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 1a6b0e0..d6018bd 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3056,7 +3056,9 @@ void iwl_handle_data_packet_monitor(struct iwl_priv *priv,
struct ieee80211_rx_status *stats,
u16 phy_flags)
{
+ struct ieee80211_hdr *hdr;
struct iwl_rt_rx_hdr *iwl_rt;
+ int hdrlen, align;
/* First cache any information we need before we overwrite
* the information provided in the skb from the hardware */
@@ -3072,8 +3074,14 @@ void iwl_handle_data_packet_monitor(struct iwl_priv *priv,
return;
}
+ /* determine payload alignment adjustment */
+ hdr = data;
+ hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control))
+ + sizeof(*iwl_rt);
+ align = 4 - (hdrlen & 3); /* invert align since already at skb head */
+
/* copy the frame data to write after where the radiotap header goes */
- iwl_rt = (void *)rxb->skb->data;
+ iwl_rt = (void *)rxb->skb->data + align;
memmove(iwl_rt->payload, data, len);
iwl_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 6cd57c2..9ef9d14 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -3144,7 +3144,9 @@ void iwl_handle_data_packet_monitor(struct iwl_priv *priv,
struct ieee80211_rx_status *stats,
u16 phy_flags)
{
+ struct ieee80211_hdr *hdr;
struct iwl_rt_rx_hdr *iwl_rt;
+ int hdrlen, align;
/* First cache any information we need before we overwrite
* the information provided in the skb from the hardware */
@@ -3160,8 +3162,14 @@ void iwl_handle_data_packet_monitor(struct iwl_priv *priv,
return;
}
+ /* determine payload alignment adjustment */
+ hdr = data;
+ hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control))
+ + sizeof(*iwl_rt);
+ align = 4 - (hdrlen & 3); /* invert align since already at skb head */
+
/* copy the frame data to write after where the radiotap header goes */
- iwl_rt = (void *)rxb->skb->data;
+ iwl_rt = (void *)rxb->skb->data + align;
memmove(iwl_rt->payload, data, len);
iwl_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
--
1.5.3.3
--
John W. Linville
linville@tuxdriver.com
next prev parent reply other threads:[~2008-01-25 21:33 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <alpine.LFD.1.00.0801061410290.3148@woody.linux-foundation.org>
2008-01-07 16:14 ` Linux 2.6.24-rc7 Alejandro Riveira Fernández
2008-01-07 16:24 ` Michael Buesch
2008-01-07 16:52 ` Alejandro Riveira Fernández
2008-01-07 17:30 ` Michael Buesch
2008-01-07 20:23 ` Alejandro Riveira Fernández
2008-01-08 15:30 ` Michael Buesch
2008-01-08 15:55 ` Alejandro Riveira Fernández
2008-01-24 20:27 ` Linus Torvalds
2008-01-24 21:07 ` John W. Linville
2008-01-24 21:34 ` Linus Torvalds
2008-01-25 12:29 ` Johannes Berg
2008-01-25 16:08 ` Linus Torvalds
2008-01-25 16:23 ` Michael Buesch
2008-01-25 16:43 ` Linus Torvalds
2008-01-25 17:27 ` Dan Williams
2008-01-25 17:38 ` Linus Torvalds
2008-01-25 17:42 ` Dan Williams
2008-02-05 20:55 ` Russell S. Senior
2008-01-25 18:22 ` Linus Torvalds
2008-01-25 18:30 ` Michael Buesch
2008-01-25 19:07 ` Linus Torvalds
2008-01-25 19:34 ` Michael Buesch
2008-01-25 19:48 ` John W. Linville
2008-01-25 19:50 ` John W. Linville
2008-01-25 21:18 ` John W. Linville [this message]
2008-01-25 21:56 ` Linus Torvalds
2008-01-25 22:46 ` John W. Linville
2008-01-25 23:20 ` Guy Cohen
2008-01-26 13:53 ` David Miller
2008-01-26 13:47 ` David Miller
2008-01-25 22:02 ` Guy Cohen
2008-01-26 13:40 ` David Miller
2008-01-25 20:28 ` Linus Torvalds
2008-01-26 13:37 ` David Miller
2008-01-27 6:32 ` Linus Torvalds
2008-01-27 7:16 ` Jeff Garzik
2008-01-27 7:24 ` David Miller
2008-01-27 7:54 ` Linus Torvalds
2008-01-28 3:15 ` David Miller
2008-01-25 23:22 ` Jeff Garzik
2008-01-26 13:27 ` David Miller
2008-01-27 6:25 ` Linus Torvalds
2008-01-26 13:22 ` David Miller
2008-01-25 18:21 ` Michael Buesch
2008-01-25 18:34 ` Linus Torvalds
2008-01-25 18:41 ` Michael Buesch
2008-01-25 21:11 ` Inaky Perez-Gonzalez
2008-01-25 21:21 ` Michael Buesch
2008-01-25 21:28 ` Inaky Perez-Gonzalez
2008-01-26 13:42 ` David Miller
2008-01-27 2:26 ` Luis R. Rodriguez
2008-01-29 19:07 ` Inaky Perez-Gonzalez
2008-01-25 21:46 ` John W. Linville
2008-01-25 22:15 ` Michael Buesch
2008-01-25 22:34 ` Tomas Winkler
2008-01-26 13:49 ` David Miller
2008-01-25 21:46 ` Guy Cohen
2008-01-25 21:54 ` Linus Torvalds
2008-01-26 13:46 ` David Miller
2008-01-25 18:34 ` John W. Linville
2008-01-24 22:17 ` Michael Buesch
2008-01-24 22:26 ` Linus Torvalds
2008-01-24 22:33 ` Michael Buesch
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080125211815.GF14687@tuxdriver.com \
--to=linville@tuxdriver.com \
--cc=dcbw@redhat.com \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
--cc=mb@bu3sch.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).