2012-07-17 15:12:31

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 3.5] b43: fix crash with OpenFWWF

From: Johannes Berg <[email protected]>

b43 with open firmware crashes mac80211 because
it changes the number of queues at runtime which,
while it was never really supported, now crashes
mac80211 due to the new hardware queue logic.

Fix this by detecting open vs. proprietary fw
earlier and registering with mac80211 with the
right number of queues.

Tested-by: Stefan Lippers-Hollmann <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
---
drivers/net/wireless/b43/b43.h | 7 -------
drivers/net/wireless/b43/main.c | 32 ++++++++++----------------------
2 files changed, 10 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index c06b6cb..7c899fc 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -870,13 +870,6 @@ struct b43_wl {
* handler, only. This basically is just the IRQ mask register. */
spinlock_t hardirq_lock;

- /* The number of queues that were registered with the mac80211 subsystem
- * initially. This is a backup copy of hw->queues in case hw->queues has
- * to be dynamically lowered at runtime (Firmware does not support QoS).
- * hw->queues has to be restored to the original value before unregistering
- * from the mac80211 subsystem. */
- u16 mac80211_initially_registered_queues;
-
/* Set this if we call ieee80211_register_hw() and check if we call
* ieee80211_unregister_hw(). */
bool hw_registred;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index acd03a4..3e5cd8d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2359,6 +2359,8 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
if (err)
goto err_load;

+ fw->opensource = (ctx->req_type == B43_FWTYPE_OPENSOURCE);
+
return 0;

err_no_ucode:
@@ -2434,6 +2436,10 @@ static void b43_request_firmware(struct work_struct *work)
goto out;

start_ieee80211:
+ wl->hw->queues = B43_QOS_QUEUE_NUM;
+ if (!modparam_qos || dev->fw.opensource)
+ wl->hw->queues = 1;
+
err = ieee80211_register_hw(wl->hw);
if (err)
goto err_one_core_detach;
@@ -2537,11 +2543,9 @@ static int b43_upload_microcode(struct b43_wldev *dev)
dev->fw.hdr_format = B43_FW_HDR_410;
else
dev->fw.hdr_format = B43_FW_HDR_351;
- dev->fw.opensource = (fwdate == 0xFFFF);
+ WARN_ON(dev->fw.opensource != (fwdate == 0xFFFF));

- /* Default to use-all-queues. */
- dev->wl->hw->queues = dev->wl->mac80211_initially_registered_queues;
- dev->qos_enabled = !!modparam_qos;
+ dev->qos_enabled = dev->wl->hw->queues > 1;
/* Default to firmware/hardware crypto acceleration. */
dev->hwcrypto_enabled = true;

@@ -2559,14 +2563,8 @@ static int b43_upload_microcode(struct b43_wldev *dev)
/* Disable hardware crypto and fall back to software crypto. */
dev->hwcrypto_enabled = false;
}
- if (!(fwcapa & B43_FWCAPA_QOS)) {
- b43info(dev->wl, "QoS not supported by firmware\n");
- /* Disable QoS. Tweak hw->queues to 1. It will be restored before
- * ieee80211_unregister to make sure the networking core can
- * properly free possible resources. */
- dev->wl->hw->queues = 1;
- dev->qos_enabled = false;
- }
+ /* adding QoS support should use an offline discovery mechanism */
+ WARN(fwcapa & B43_FWCAPA_QOS, "QoS in OpenFW not supported\n");
} else {
b43info(dev->wl, "Loading firmware version %u.%u "
"(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
@@ -5298,8 +5296,6 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)

hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;

- hw->queues = modparam_qos ? B43_QOS_QUEUE_NUM : 1;
- wl->mac80211_initially_registered_queues = hw->queues;
wl->hw_registred = false;
hw->max_rates = 2;
SET_IEEE80211_DEV(hw, dev->dev);
@@ -5374,10 +5370,6 @@ static void b43_bcma_remove(struct bcma_device *core)

B43_WARN_ON(!wl);
if (wl->current_dev == wldev && wl->hw_registred) {
- /* Restore the queues count before unregistering, because firmware detect
- * might have modified it. Restoring is important, so the networking
- * stack can properly free resources. */
- wl->hw->queues = wl->mac80211_initially_registered_queues;
b43_leds_stop(wldev);
ieee80211_unregister_hw(wl->hw);
}
@@ -5452,10 +5444,6 @@ static void b43_ssb_remove(struct ssb_device *sdev)

B43_WARN_ON(!wl);
if (wl->current_dev == wldev && wl->hw_registred) {
- /* Restore the queues count before unregistering, because firmware detect
- * might have modified it. Restoring is important, so the networking
- * stack can properly free resources. */
- wl->hw->queues = wl->mac80211_initially_registered_queues;
b43_leds_stop(wldev);
ieee80211_unregister_hw(wl->hw);
}
--
1.7.10.4





2012-07-17 19:32:56

by Larry Finger

[permalink] [raw]
Subject: Re: [PATCH 3.5] b43: fix crash with OpenFWWF

On 07/17/2012 10:53 AM, Stefan Lippers-Hollmann wrote:
> Hi
>
> On Tuesday 17 July 2012, Johannes Berg wrote:
>> From: Johannes Berg <[email protected]>
>>
>> b43 with open firmware crashes mac80211 because
>> it changes the number of queues at runtime which,
>> while it was never really supported, now crashes
>> mac80211 due to the new hardware queue logic.
>>
>> Fix this by detecting open vs. proprietary fw
>> earlier and registering with mac80211 with the
>> right number of queues.
> […]
>
> Just for completeness' sake, this patch also requires "mac80211: fix
> crash with single-queue drivers"[1] and avoids the following
> 3.4 --> 3.5 regression in mainline (tested on v3.5-rc7-25-ge5254a6,
> current linux.git as of now):
>
> [ 8.386729] b43-pci-bridge 0000:02:00.0: enabling device (0000 -> 0002)
> [ 8.386794] b43-pci-bridge 0000:02:00.0: setting latency timer to 64
> [ 8.386899] ssb: Found chip with id 0x4306, rev 0x03 and package 0x00
> [ 8.386911] ssb: Core 0 found: ChipCommon (cc 0x800, rev 0x04, vendor 0x4243)
> [ 8.386923] ssb: Core 1 found: IEEE 802.11 (cc 0x812, rev 0x05, vendor 0x4243)
> [ 8.386934] ssb: Core 2 found: PCMCIA (cc 0x80D, rev 0x02, vendor 0x4243)
> [ 8.386944] ssb: Core 3 found: V90 (cc 0x807, rev 0x02, vendor 0x4243)
> [ 8.386955] ssb: Core 4 found: PCI (cc 0x804, rev 0x09, vendor 0x4243)
> [ 8.391430] ssb: Sonics Silicon Backplane found on PCI device 0000:02:00.0
> […]
> [ 8.771929] cfg80211: Calling CRDA to update world regulatory domain
> [ 9.359492] b43-phy0: Broadcom 4306 WLAN found (core revision 5)
> [ 9.376528] Broadcom 43xx driver loaded [ Features: PMNLS ]
> [ 10.069906] cfg80211: World regulatory domain updated:
> [ 10.069928] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
> [ 10.069936] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
> [ 10.069943] cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
> [ 10.069949] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
> [ 10.069956] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
> [ 10.069962] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
> [ 10.226906] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
> [ 10.227869] Registered led device: b43-phy0::tx
> [ 10.227924] Registered led device: b43-phy0::rx
> [ 10.227979] Registered led device: b43-phy0::radio
> [ 10.304598] cfg80211: Calling CRDA for country: DE
> [ 10.357706] cfg80211: Regulatory domain changed to country: DE
> [ 10.357727] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
> [ 10.357734] cfg80211: (2400000 KHz - 2483500 KHz @ 40000 KHz), (N/A, 2000 mBm)
> [ 10.357741] cfg80211: (5150000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
> [ 10.357746] cfg80211: (5250000 KHz - 5350000 KHz @ 40000 KHz), (N/A, 2000 mBm)
> [ 10.357752] cfg80211: (5470000 KHz - 5725000 KHz @ 40000 KHz), (N/A, 2698 mBm)
> […]
> [ 20.504102] b43-phy0: Loading OpenSource firmware version 410.31754
> [ 20.504118] b43-phy0: Hardware crypto acceleration not supported by firmware
> [ 20.504123] b43-phy0: QoS not supported by firmware
> [ 20.554909] ------------[ cut here ]------------
> [ 20.555059] WARNING: at /tmp/buildd/linux-aptosid-3.5~rc7/debian/build/source_i386_none/net/mac80211/iface.c:162 ieee80211_check_queues+0x66/0x104 [mac80211]()
> [ 20.555190] Hardware name: Amilo D-Series
> [ 20.555195] Modules linked in: arc4 b43 bcma mac80211 cfg80211 joydev rfkill rng_core ssb mmc_core snd_via82xx snd_ac97_codec ac97_bus snd_mpu401_uart snd_rawmidi snd_seq_device pcmcia via686a psmouse snd_pcm snd_page_alloc snd_timer snd soundcore gameport evdev pcspkr serio_raw microcode shpchp pci_hotplug i2c_viapro yenta_socket pcmcia_rsrc via_agp pcmcia_core battery parport_pc parport ac button processor ext3 mbcache jbd sr_mod sd_mod cdrom crc_t10dif firewire_ohci ata_generic firewire_core pata_acpi tulip crc_itu_t floppy pata_via libata uhci_hcd ehci_hcd usbcore scsi_mod usb_common thermal [last unloaded: scsi_wait_scan]
> [ 20.555374] Pid: 1668, comm: wpa_supplicant Not tainted 3.5-rc7-aptosid-686 #1
> [ 20.555380] Call Trace:
> [ 20.555408] [<c0125c32>] ? warn_slowpath_common+0x7c/0x8f
> [ 20.555482] [<cff41920>] ? ieee80211_check_queues+0x66/0x104 [mac80211]
> [ 20.555554] [<cff41920>] ? ieee80211_check_queues+0x66/0x104 [mac80211]
> [ 20.555565] [<c0125c60>] ? warn_slowpath_null+0x1b/0x1f
> [ 20.555594] [<cff41920>] ? ieee80211_check_queues+0x66/0x104 [mac80211]
> [ 20.555625] [<cff43050>] ? ieee80211_do_open+0x258/0x4ad [mac80211]
> [ 20.555638] [<c013d8fe>] ? notifier_call_chain+0x20/0x42
> [ 20.555651] [<c0311ecd>] ? __dev_open+0x84/0xb8
> [ 20.555660] [<c0311e40>] ? dev_set_rx_mode+0x18/0x21
> [ 20.555670] [<c03120ad>] ? __dev_change_flags+0x93/0x108
> [ 20.555683] [<c01c1baa>] ? full_name_hash+0x13/0x3c
> [ 20.555692] [<c0312181>] ? dev_change_flags+0x10/0x3b
> [ 20.555705] [<c03538c3>] ? devinet_ioctl+0x21d/0x4f2
> [ 20.555729] [<c030e531>] ? dev_name_hash.isra.69+0x1b/0x2c
> [ 20.555741] [<c03010c5>] ? sock_ioctl+0x1ce/0x1f8
> [ 20.555749] [<c0300ef7>] ? sock_fasync+0x68/0x68
> [ 20.555765] [<c01c62d8>] ? vfs_ioctl+0x18/0x21
> [ 20.555775] [<c01c6d70>] ? do_vfs_ioctl+0x3f3/0x433
> [ 20.555791] [<c01bbed9>] ? fget_light+0x28/0x78
> [ 20.555803] [<c0302fc9>] ? sys_recvmsg+0x49/0x52
> [ 20.555813] [<c030344e>] ? sys_socketcall+0x26a/0x2c2
> [ 20.555822] [<c01c6df0>] ? sys_ioctl+0x40/0x60
> [ 20.555839] [<c03bd1df>] ? sysenter_do_call+0x12/0x28
> [ 20.555846] ---[ end trace 937b8f4eefd318a5 ]---
> [ 20.669180] b43-phy0: Loading OpenSource firmware version 410.31754
> [ 20.669197] b43-phy0: Hardware crypto acceleration not supported by firmware
> [ 20.669202] b43-phy0: QoS not supported by firmware
>
> After applying both patches to kernel 3.5, b43 && OpenFWWF 5.2 are
> working fine again; b43 with Broadcom's proprietary firmware was not
> affected.

The patch works here on current (3.5-rc7) wireless-testing without WARN or oops
on my PPC.

Larry


2012-07-17 16:04:32

by Stefan Lippers-Hollmann

[permalink] [raw]
Subject: Re: [PATCH 3.5] b43: fix crash with OpenFWWF

Hi

On Tuesday 17 July 2012, Johannes Berg wrote:
> From: Johannes Berg <[email protected]>
>
> b43 with open firmware crashes mac80211 because
> it changes the number of queues at runtime which,
> while it was never really supported, now crashes
> mac80211 due to the new hardware queue logic.
>
> Fix this by detecting open vs. proprietary fw
> earlier and registering with mac80211 with the
> right number of queues.
[…]

Just for completeness' sake, this patch also requires "mac80211: fix
crash with single-queue drivers"[1] and avoids the following
3.4 --> 3.5 regression in mainline (tested on v3.5-rc7-25-ge5254a6,
current linux.git as of now):

[ 8.386729] b43-pci-bridge 0000:02:00.0: enabling device (0000 -> 0002)
[ 8.386794] b43-pci-bridge 0000:02:00.0: setting latency timer to 64
[ 8.386899] ssb: Found chip with id 0x4306, rev 0x03 and package 0x00
[ 8.386911] ssb: Core 0 found: ChipCommon (cc 0x800, rev 0x04, vendor 0x4243)
[ 8.386923] ssb: Core 1 found: IEEE 802.11 (cc 0x812, rev 0x05, vendor 0x4243)
[ 8.386934] ssb: Core 2 found: PCMCIA (cc 0x80D, rev 0x02, vendor 0x4243)
[ 8.386944] ssb: Core 3 found: V90 (cc 0x807, rev 0x02, vendor 0x4243)
[ 8.386955] ssb: Core 4 found: PCI (cc 0x804, rev 0x09, vendor 0x4243)
[ 8.391430] ssb: Sonics Silicon Backplane found on PCI device 0000:02:00.0
[…]
[ 8.771929] cfg80211: Calling CRDA to update world regulatory domain
[ 9.359492] b43-phy0: Broadcom 4306 WLAN found (core revision 5)
[ 9.376528] Broadcom 43xx driver loaded [ Features: PMNLS ]
[ 10.069906] cfg80211: World regulatory domain updated:
[ 10.069928] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[ 10.069936] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[ 10.069943] cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
[ 10.069949] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
[ 10.069956] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[ 10.069962] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[ 10.226906] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
[ 10.227869] Registered led device: b43-phy0::tx
[ 10.227924] Registered led device: b43-phy0::rx
[ 10.227979] Registered led device: b43-phy0::radio
[ 10.304598] cfg80211: Calling CRDA for country: DE
[ 10.357706] cfg80211: Regulatory domain changed to country: DE
[ 10.357727] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[ 10.357734] cfg80211: (2400000 KHz - 2483500 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 10.357741] cfg80211: (5150000 KHz - 5250000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 10.357746] cfg80211: (5250000 KHz - 5350000 KHz @ 40000 KHz), (N/A, 2000 mBm)
[ 10.357752] cfg80211: (5470000 KHz - 5725000 KHz @ 40000 KHz), (N/A, 2698 mBm)
[…]
[ 20.504102] b43-phy0: Loading OpenSource firmware version 410.31754
[ 20.504118] b43-phy0: Hardware crypto acceleration not supported by firmware
[ 20.504123] b43-phy0: QoS not supported by firmware
[ 20.554909] ------------[ cut here ]------------
[ 20.555059] WARNING: at /tmp/buildd/linux-aptosid-3.5~rc7/debian/build/source_i386_none/net/mac80211/iface.c:162 ieee80211_check_queues+0x66/0x104 [mac80211]()
[ 20.555190] Hardware name: Amilo D-Series
[ 20.555195] Modules linked in: arc4 b43 bcma mac80211 cfg80211 joydev rfkill rng_core ssb mmc_core snd_via82xx snd_ac97_codec ac97_bus snd_mpu401_uart snd_rawmidi snd_seq_device pcmcia via686a psmouse snd_pcm snd_page_alloc snd_timer snd soundcore gameport evdev pcspkr serio_raw microcode shpchp pci_hotplug i2c_viapro yenta_socket pcmcia_rsrc via_agp pcmcia_core battery parport_pc parport ac button processor ext3 mbcache jbd sr_mod sd_mod cdrom crc_t10dif firewire_ohci ata_generic firewire_core pata_acpi tulip crc_itu_t floppy pata_via libata uhci_hcd ehci_hcd usbcore scsi_mod usb_common thermal [last unloaded: scsi_wait_scan]
[ 20.555374] Pid: 1668, comm: wpa_supplicant Not tainted 3.5-rc7-aptosid-686 #1
[ 20.555380] Call Trace:
[ 20.555408] [<c0125c32>] ? warn_slowpath_common+0x7c/0x8f
[ 20.555482] [<cff41920>] ? ieee80211_check_queues+0x66/0x104 [mac80211]
[ 20.555554] [<cff41920>] ? ieee80211_check_queues+0x66/0x104 [mac80211]
[ 20.555565] [<c0125c60>] ? warn_slowpath_null+0x1b/0x1f
[ 20.555594] [<cff41920>] ? ieee80211_check_queues+0x66/0x104 [mac80211]
[ 20.555625] [<cff43050>] ? ieee80211_do_open+0x258/0x4ad [mac80211]
[ 20.555638] [<c013d8fe>] ? notifier_call_chain+0x20/0x42
[ 20.555651] [<c0311ecd>] ? __dev_open+0x84/0xb8
[ 20.555660] [<c0311e40>] ? dev_set_rx_mode+0x18/0x21
[ 20.555670] [<c03120ad>] ? __dev_change_flags+0x93/0x108
[ 20.555683] [<c01c1baa>] ? full_name_hash+0x13/0x3c
[ 20.555692] [<c0312181>] ? dev_change_flags+0x10/0x3b
[ 20.555705] [<c03538c3>] ? devinet_ioctl+0x21d/0x4f2
[ 20.555729] [<c030e531>] ? dev_name_hash.isra.69+0x1b/0x2c
[ 20.555741] [<c03010c5>] ? sock_ioctl+0x1ce/0x1f8
[ 20.555749] [<c0300ef7>] ? sock_fasync+0x68/0x68
[ 20.555765] [<c01c62d8>] ? vfs_ioctl+0x18/0x21
[ 20.555775] [<c01c6d70>] ? do_vfs_ioctl+0x3f3/0x433
[ 20.555791] [<c01bbed9>] ? fget_light+0x28/0x78
[ 20.555803] [<c0302fc9>] ? sys_recvmsg+0x49/0x52
[ 20.555813] [<c030344e>] ? sys_socketcall+0x26a/0x2c2
[ 20.555822] [<c01c6df0>] ? sys_ioctl+0x40/0x60
[ 20.555839] [<c03bd1df>] ? sysenter_do_call+0x12/0x28
[ 20.555846] ---[ end trace 937b8f4eefd318a5 ]---
[ 20.669180] b43-phy0: Loading OpenSource firmware version 410.31754
[ 20.669197] b43-phy0: Hardware crypto acceleration not supported by firmware
[ 20.669202] b43-phy0: QoS not supported by firmware

After applying both patches to kernel 3.5, b43 && OpenFWWF 5.2 are
working fine again; b43 with Broadcom's proprietary firmware was not
affected.

Regards
Stefan Lippers-Hollmann

[1] wireless-next.git: commit a6f38ac3cc853189705006cc1e0f17ce8467a1df
Message-Id: <[email protected]>
http://lkml.kernel.org/r/<[email protected]>