linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

  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).