* Strange mac80211 oops
@ 2007-12-24 21:37 Michael Buesch
2007-12-24 21:45 ` Johannes Berg
0 siblings, 1 reply; 9+ messages in thread
From: Michael Buesch @ 2007-12-24 21:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Daniel Drake, Johannes Berg, John Linville
I just had a strange exception using the zd1211rw driver on mac80211
from latest wireless-2.6 tree.
I'm not sure what happened.
[ 98.415423] ------------[ cut here ]------------
[ 98.415627] Badness at e221c924 [verbose debug info unavailable]
[ 98.415843] NIP: e221c924 LR: e221c904 CTR: 00000000
[ 98.416030] REGS: c056dcc0 TRAP: 0700 Not tainted (2.6.24-rc5-wl26)
[ 98.416262] MSR: 00029032 <EE,ME,IR,DR> CR: 44000024 XER: 20000000
[ 98.416648] TASK = c052d5d0[0] 'swapper' THREAD: c056c000
[ 98.416844] GPR00: 00000001 c056dd70 c052d5d0 0000001a 00000000 00000000 c056dddc 00000000
[ 98.416877] GPR08: 00000000 e2240000 00000a88 00000018 00000000 00000000 00000000 00000000
[ 98.416886] GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00d85b70 00d87474
[ 98.416895] GPR24: df8409c0 005b7000 c056de20 de564220 df190210 df8409c0 de564220 00000008
[ 98.416905] NIP [e221c924] __ieee80211_rx+0x48c/0xd44 [mac80211]
[ 98.417204] LR [e221c904] __ieee80211_rx+0x46c/0xd44 [mac80211]
[ 98.417458] Call Trace:
[ 98.417562] [c056dd70] [e221d16c] __ieee80211_rx+0xcd4/0xd44 [mac80211] (unreliable)
[ 98.417929] [c056de10] [e220d30c] ieee80211_tasklet_handler+0x74/0xf4 [mac80211]
[ 98.418239] [c056de70] [c00344a0] tasklet_action+0x84/0xe0
[ 98.418504] [c056de80] [c0034560] __do_softirq+0x64/0xd4
[ 98.418755] [c056dea0] [c0006788] do_softirq+0x40/0x58
[ 98.419003] [c056deb0] [c0034158] irq_exit+0x44/0x94
[ 98.419244] [c056dec0] [c0006c78] do_IRQ+0xb0/0xcc
[ 98.419478] [c056ded0] [c0014584] ret_from_except+0x0/0x14
[ 98.419740] --- Exception: 501 at cpu_idle+0x94/0x100
[ 98.419962] LR = cpu_idle+0x94/0x100
[ 98.420112] [c056df90] [c000a05c] cpu_idle+0x48/0x100 (unreliable)
[ 98.420421] [c056dfa0] [c0004454] rest_init+0x74/0xa0
[ 98.420664] [c056dfc0] [c04fa9b0] start_kernel+0x26c/0x280
[ 98.420927] [c056dff0] [00003860] 0x3860
[ 98.421135] Instruction dump:
[ 98.421281] 7c030378 541f073a b0010048 48003d19 801800a0 7c001a14 70090003 41a2002c
[ 98.421800] 3d20e224 80098eb8 7c000034 5400d97e <0f000000> 2f800000 41be0010 38000001
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange mac80211 oops
2007-12-24 21:37 Strange mac80211 oops Michael Buesch
@ 2007-12-24 21:45 ` Johannes Berg
2007-12-24 21:57 ` Johannes Berg
0 siblings, 1 reply; 9+ messages in thread
From: Johannes Berg @ 2007-12-24 21:45 UTC (permalink / raw)
To: Michael Buesch; +Cc: linux-wireless, Daniel Drake, John Linville
[-- Attachment #1: Type: text/plain, Size: 949 bytes --]
> [ 98.415423] ------------[ cut here ]------------
> [ 98.415627] Badness at e221c924 [verbose debug info unavailable]
> [ 98.416905] NIP [e221c924] __ieee80211_rx+0x48c/0xd44 [mac80211]
ieee80211_rx_monitor() is inlined into __ieee80211_rx() and that +0x48c
is quite a high number, so I'm guessing it's this:
/*
* Drivers are required to align the payload data to a four-byte
* boundary, so the last two bits of the address where it starts
* may not be set. The header is required to be directly before
* the payload data, padding like atheros hardware adds which is
* inbetween the 802.11 header and the payload is not supported,
* the driver is required to move the 802.11 header further back
* in that case.
*/
hdrlen = ieee80211_get_hdrlen(rx.fc);
WARN_ON_ONCE(((unsigned long)(skb->data + hdrlen)) & 3);
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange mac80211 oops
2007-12-24 21:45 ` Johannes Berg
@ 2007-12-24 21:57 ` Johannes Berg
2007-12-24 22:28 ` Michael Buesch
0 siblings, 1 reply; 9+ messages in thread
From: Johannes Berg @ 2007-12-24 21:57 UTC (permalink / raw)
To: Michael Buesch; +Cc: linux-wireless, Daniel Drake, John Linville
[-- Attachment #1: Type: text/plain, Size: 1934 bytes --]
On Mon, 2007-12-24 at 22:45 +0100, Johannes Berg wrote:
> > [ 98.415423] ------------[ cut here ]------------
> > [ 98.415627] Badness at e221c924 [verbose debug info unavailable]
>
> > [ 98.416905] NIP [e221c924] __ieee80211_rx+0x48c/0xd44 [mac80211]
>
> ieee80211_rx_monitor() is inlined into __ieee80211_rx() and that +0x48c
> is quite a high number, so I'm guessing it's this:
>
> /*
> * Drivers are required to align the payload data to a four-byte
> * boundary, so the last two bits of the address where it starts
> * may not be set. The header is required to be directly before
> * the payload data, padding like atheros hardware adds which is
> * inbetween the 802.11 header and the payload is not supported,
> * the driver is required to move the 802.11 header further back
> * in that case.
> */
> hdrlen = ieee80211_get_hdrlen(rx.fc);
> WARN_ON_ONCE(((unsigned long)(skb->data + hdrlen)) & 3);
Yup, that's what it is, Michael sent me the assembly, __ieee80211_rx
starts at 0x1990 and we find at 0x1990+0x48c == 0x1e1c
1df8: 48 00 00 01 bl 1df8 <__ieee80211_rx+0x468>
1df8: R_PPC_REL24 ieee80211_get_hdrlen
1dfc: 80 18 00 a0 lwz r0,160(r24)
1e00: 7c 00 1a 14 add r0,r0,r3
1e04: 70 09 00 03 andi. r9,r0,3
1e08: 41 a2 00 2c beq+ 1e34 <__ieee80211_rx+0x4a4>
1e0c: 3d 20 00 00 lis r9,0
1e0e: R_PPC_ADDR16_HA .sbss
1e10: 80 09 00 00 lwz r0,0(r9)
1e12: R_PPC_ADDR16_LO .sbss
1e14: 7c 00 00 34 cntlzw r0,r0
1e18: 54 00 d9 7e rlwinm r0,r0,27,5,31
1e1c: 0f 00 00 00 twnei r0,0
which is exactly the WARN_ON_ONCE above.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange mac80211 oops
2007-12-24 21:57 ` Johannes Berg
@ 2007-12-24 22:28 ` Michael Buesch
2007-12-29 13:32 ` Daniel Drake
0 siblings, 1 reply; 9+ messages in thread
From: Michael Buesch @ 2007-12-24 22:28 UTC (permalink / raw)
To: Daniel Drake; +Cc: Johannes Berg, linux-wireless, John Linville
On Monday 24 December 2007 22:57:03 Johannes Berg wrote:
> On Mon, 2007-12-24 at 22:45 +0100, Johannes Berg wrote:
> > > [ 98.415423] ------------[ cut here ]------------
> > > [ 98.415627] Badness at e221c924 [verbose debug info unavailable]
> >
> > > [ 98.416905] NIP [e221c924] __ieee80211_rx+0x48c/0xd44 [mac80211]
> >
> > ieee80211_rx_monitor() is inlined into __ieee80211_rx() and that +0x48c
> > is quite a high number, so I'm guessing it's this:
> >
> > /*
> > * Drivers are required to align the payload data to a four-byte
> > * boundary, so the last two bits of the address where it starts
> > * may not be set. The header is required to be directly before
> > * the payload data, padding like atheros hardware adds which is
> > * inbetween the 802.11 header and the payload is not supported,
> > * the driver is required to move the 802.11 header further back
> > * in that case.
> > */
> > hdrlen = ieee80211_get_hdrlen(rx.fc);
> > WARN_ON_ONCE(((unsigned long)(skb->data + hdrlen)) & 3);
>
> Yup, that's what it is, Michael sent me the assembly, __ieee80211_rx
> starts at 0x1990 and we find at 0x1990+0x48c == 0x1e1c
>
>
> 1df8: 48 00 00 01 bl 1df8 <__ieee80211_rx+0x468>
> 1df8: R_PPC_REL24 ieee80211_get_hdrlen
> 1dfc: 80 18 00 a0 lwz r0,160(r24)
> 1e00: 7c 00 1a 14 add r0,r0,r3
> 1e04: 70 09 00 03 andi. r9,r0,3
> 1e08: 41 a2 00 2c beq+ 1e34 <__ieee80211_rx+0x4a4>
> 1e0c: 3d 20 00 00 lis r9,0
> 1e0e: R_PPC_ADDR16_HA .sbss
> 1e10: 80 09 00 00 lwz r0,0(r9)
> 1e12: R_PPC_ADDR16_LO .sbss
> 1e14: 7c 00 00 34 cntlzw r0,r0
> 1e18: 54 00 d9 7e rlwinm r0,r0,27,5,31
> 1e1c: 0f 00 00 00 twnei r0,0
>
> which is exactly the WARN_ON_ONCE above.
So zd1211rw-mac80211 is pushing some unaligned data up the RX path, hm.
--
Greetings Michael.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange mac80211 oops
2007-12-24 22:28 ` Michael Buesch
@ 2007-12-29 13:32 ` Daniel Drake
2007-12-29 13:48 ` Johannes Berg
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Drake @ 2007-12-29 13:32 UTC (permalink / raw)
To: Michael Buesch; +Cc: Johannes Berg, linux-wireless, John Linville
Michael Buesch wrote:
> So zd1211rw-mac80211 is pushing some unaligned data up the RX path, hm.
Johannes suggests that this may be due to QoS or WDS frames, which have
headers that are 26 or 30 bytes. I don't recall seeing any logic in
zd1211rw to correctly realign these.
Daniel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange mac80211 oops
2007-12-29 13:32 ` Daniel Drake
@ 2007-12-29 13:48 ` Johannes Berg
2007-12-29 16:24 ` Michael Buesch
0 siblings, 1 reply; 9+ messages in thread
From: Johannes Berg @ 2007-12-29 13:48 UTC (permalink / raw)
To: Daniel Drake; +Cc: Michael Buesch, linux-wireless, John Linville
This might help. Totally untested.
---
drivers/net/wireless/zd1211rw/zd_mac.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- everything.orig/drivers/net/wireless/zd1211rw/zd_mac.c 2007-12-29 14:42:18.292833767 +0100
+++ everything/drivers/net/wireless/zd1211rw/zd_mac.c 2007-12-29 14:47:34.022831923 +0100
@@ -612,6 +612,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
int bad_frame = 0;
int i;
u8 rate;
+ u16 fc;
+ int is_qos, is_4addr;
if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ +
FCS_LEN + sizeof(struct rx_status))
@@ -671,6 +673,16 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
skb = dev_alloc_skb(length);
if (skb == NULL)
return -ENOMEM;
+
+ fc = le16_to_cpu(*((__le16 *) buffer));
+
+ is_qos = !!(fc & IEEE80211_STYPE_QOS_DATA);
+ is_4addr = (fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) ==
+ (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS);
+
+ if (is_qos ^ is_4addr)
+ skb_reserve(skb, 2);
+
memcpy(skb_put(skb, length), buffer, length);
ieee80211_rx_irqsafe(hw, skb, &stats);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange mac80211 oops
2007-12-29 13:48 ` Johannes Berg
@ 2007-12-29 16:24 ` Michael Buesch
2008-01-02 8:48 ` Johannes Berg
0 siblings, 1 reply; 9+ messages in thread
From: Michael Buesch @ 2007-12-29 16:24 UTC (permalink / raw)
To: Daniel Drake; +Cc: Johannes Berg, linux-wireless, John Linville
This patch fixes RX packet alignment issues in the zd1211rw driver.
This is based on a patch by Johannes Berg.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Index: wireless-2.6/drivers/net/wireless/zd1211rw/zd_mac.c
===================================================================
--- wireless-2.6.orig/drivers/net/wireless/zd1211rw/zd_mac.c 2007-12-29 17:14:41.000000000 +0100
+++ wireless-2.6/drivers/net/wireless/zd1211rw/zd_mac.c 2007-12-29 17:15:00.000000000 +0100
@@ -623,6 +623,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
const struct rx_status *status;
struct sk_buff *skb;
int bad_frame = 0;
+ u16 fc;
+ bool is_qos, is_4addr, need_padding;
if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ +
FCS_LEN + sizeof(struct rx_status))
@@ -674,9 +676,22 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
&& !mac->pass_ctrl)
return 0;
- skb = dev_alloc_skb(length);
+ fc = le16_to_cpu(*((__le16 *) buffer));
+
+ is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
+ ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA);
+ is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
+ (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);
+ need_padding = is_qos ^ is_4addr;
+
+ skb = dev_alloc_skb(length + (need_padding ? 2 : 0));
if (skb == NULL)
return -ENOMEM;
+ if (need_padding) {
+ /* Make sure the the payload data is 4 byte aligned. */
+ skb_reserve(skb, 2);
+ }
+
memcpy(skb_put(skb, length), buffer, length);
ieee80211_rx_irqsafe(hw, skb, &stats);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange mac80211 oops
2007-12-29 16:24 ` Michael Buesch
@ 2008-01-02 8:48 ` Johannes Berg
2008-01-02 15:21 ` Michael Buesch
0 siblings, 1 reply; 9+ messages in thread
From: Johannes Berg @ 2008-01-02 8:48 UTC (permalink / raw)
To: Michael Buesch; +Cc: Daniel Drake, linux-wireless, John Linville
[-- Attachment #1: Type: text/plain, Size: 1833 bytes --]
On Sat, 2007-12-29 at 17:24 +0100, Michael Buesch wrote:
> This patch fixes RX packet alignment issues in the zd1211rw driver.
> This is based on a patch by Johannes Berg.
>
> Signed-off-by: Michael Buesch <mb@bu3sch.de>
Looks good to me, I guess you tested it.
Acked-by: Johannes Berg <johannes@sipsolutions.net>
> Index: wireless-2.6/drivers/net/wireless/zd1211rw/zd_mac.c
> ===================================================================
> --- wireless-2.6.orig/drivers/net/wireless/zd1211rw/zd_mac.c 2007-12-29 17:14:41.000000000 +0100
> +++ wireless-2.6/drivers/net/wireless/zd1211rw/zd_mac.c 2007-12-29 17:15:00.000000000 +0100
> @@ -623,6 +623,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
> const struct rx_status *status;
> struct sk_buff *skb;
> int bad_frame = 0;
> + u16 fc;
> + bool is_qos, is_4addr, need_padding;
>
> if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ +
> FCS_LEN + sizeof(struct rx_status))
> @@ -674,9 +676,22 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
> && !mac->pass_ctrl)
> return 0;
>
> - skb = dev_alloc_skb(length);
> + fc = le16_to_cpu(*((__le16 *) buffer));
> +
> + is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
> + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA);
> + is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
> + (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);
> + need_padding = is_qos ^ is_4addr;
> +
> + skb = dev_alloc_skb(length + (need_padding ? 2 : 0));
> if (skb == NULL)
> return -ENOMEM;
> + if (need_padding) {
> + /* Make sure the the payload data is 4 byte aligned. */
> + skb_reserve(skb, 2);
> + }
> +
> memcpy(skb_put(skb, length), buffer, length);
>
> ieee80211_rx_irqsafe(hw, skb, &stats);
>
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange mac80211 oops
2008-01-02 8:48 ` Johannes Berg
@ 2008-01-02 15:21 ` Michael Buesch
0 siblings, 0 replies; 9+ messages in thread
From: Michael Buesch @ 2008-01-02 15:21 UTC (permalink / raw)
To: Johannes Berg; +Cc: Daniel Drake, linux-wireless, John Linville
On Wednesday 02 January 2008 09:48:51 Johannes Berg wrote:
>
> On Sat, 2007-12-29 at 17:24 +0100, Michael Buesch wrote:
> > This patch fixes RX packet alignment issues in the zd1211rw driver.
> > This is based on a patch by Johannes Berg.
> >
> > Signed-off-by: Michael Buesch <mb@bu3sch.de>
>
> Looks good to me, I guess you tested it.
Yes, works fine.
> Acked-by: Johannes Berg <johannes@sipsolutions.net>
>
> > Index: wireless-2.6/drivers/net/wireless/zd1211rw/zd_mac.c
> > ===================================================================
> > --- wireless-2.6.orig/drivers/net/wireless/zd1211rw/zd_mac.c 2007-12-29 17:14:41.000000000 +0100
> > +++ wireless-2.6/drivers/net/wireless/zd1211rw/zd_mac.c 2007-12-29 17:15:00.000000000 +0100
> > @@ -623,6 +623,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
> > const struct rx_status *status;
> > struct sk_buff *skb;
> > int bad_frame = 0;
> > + u16 fc;
> > + bool is_qos, is_4addr, need_padding;
> >
> > if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ +
> > FCS_LEN + sizeof(struct rx_status))
> > @@ -674,9 +676,22 @@ int zd_mac_rx(struct ieee80211_hw *hw, c
> > && !mac->pass_ctrl)
> > return 0;
> >
> > - skb = dev_alloc_skb(length);
> > + fc = le16_to_cpu(*((__le16 *) buffer));
> > +
> > + is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
> > + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA);
> > + is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
> > + (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);
> > + need_padding = is_qos ^ is_4addr;
> > +
> > + skb = dev_alloc_skb(length + (need_padding ? 2 : 0));
> > if (skb == NULL)
> > return -ENOMEM;
> > + if (need_padding) {
> > + /* Make sure the the payload data is 4 byte aligned. */
> > + skb_reserve(skb, 2);
> > + }
> > +
> > memcpy(skb_put(skb, length), buffer, length);
> >
> > ieee80211_rx_irqsafe(hw, skb, &stats);
> >
>
--
Greetings Michael.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2008-01-02 15:22 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-24 21:37 Strange mac80211 oops Michael Buesch
2007-12-24 21:45 ` Johannes Berg
2007-12-24 21:57 ` Johannes Berg
2007-12-24 22:28 ` Michael Buesch
2007-12-29 13:32 ` Daniel Drake
2007-12-29 13:48 ` Johannes Berg
2007-12-29 16:24 ` Michael Buesch
2008-01-02 8:48 ` Johannes Berg
2008-01-02 15:21 ` Michael Buesch
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).