From aac495a8002bbf20e879572c6cf0789ab2ffb32b Mon Sep 17 00:00:00 2001 From: Stanislav Yakovlev Date: Mon, 14 May 2012 19:06:19 -0400 Subject: net/wireless: ipw2100: Fix WARN_ON occurring in wiphy_register called by ipw2100_pci_init_one The problem was found by Larry Finger: http://marc.info/?l=linux-wireless&m=133702401700614&w=2 The problem is identical to the one for ipw2200 which is already fixed: http://marc.info/?l=linux-wireless&m=133457257407196&w=2 [ 17.766431] ------------[ cut here ]------------ [ 17.766467] WARNING: at net/wireless/core.c:562 wiphy_register+0x34c/0x3c0 [cfg80211]() [ 17.766471] Hardware name: Latitude D600 [ 17.766474] Modules linked in: ipw2100(+) libipw pcmcia cfg80211 ppdev parport_pc yenta_socket sr_mod pcmcia_rsrc parport iTCO_wdt cdrom sg rfkill pcmcia_ core lib80211 tg3 video button battery ac iTCO_vendor_support joydev shpchp pcspkr pciehp pci_hotplug autofs4 radeon ttm drm_kms_helper uhci_hcd ehci_hcd rtc _cmos thermal drm hwmon i2c_algo_bit i2c_core processor usbcore usb_common ata_generic ata_piix ahci libahci libata [ 17.766525] Pid: 474, comm: modprobe Not tainted 3.4.0-rc7-wl+ #6 [ 17.766528] Call Trace: [ 17.766541] [] ? printk+0x28/0x2a [ 17.766552] [] warn_slowpath_common+0x6d/0xa0 [ 17.766563] [] ? wiphy_register+0x34c/0x3c0 [cfg80211] [ 17.766573] [] ? wiphy_register+0x34c/0x3c0 [cfg80211] [ 17.766578] [] warn_slowpath_null+0x1d/0x20 [ 17.766588] [] wiphy_register+0x34c/0x3c0 [cfg80211] [ 17.766605] [] ipw2100_wdev_init+0x196/0x1c0 [ipw2100] [ 17.766616] [] ipw2100_pci_init_one+0x2b2/0x694 [ipw2100] [ 17.766632] [] local_pci_probe+0x42/0xb0 [ 17.766637] [] pci_device_probe+0x60/0x90 [ 17.766645] [] ? sysfs_create_link+0x12/0x20 [ 17.766654] [] really_probe+0x56/0x2e0 [ 17.766659] [] ? create_dir+0x5d/0xa0 [ 17.766667] [] ? pm_runtime_barrier+0x3b/0xa0 [ 17.766672] [] driver_probe_device+0x44/0xa0 [ 17.766677] [] ? pci_match_device+0x97/0xa0 [ 17.766681] [] __driver_attach+0x89/0x90 [ 17.766686] [] ? driver_probe_device+0xa0/0xa0 [ 17.766691] [] bus_for_each_dev+0x3a/0x70 [ 17.766695] [] driver_attach+0x1c/0x30 [ 17.766699] [] ? driver_probe_device+0xa0/0xa0 [ 17.766704] [] bus_add_driver+0x187/0x280 [ 17.766710] [] ? kset_find_obj+0x2d/0x60 [ 17.766715] [] ? pci_device_probe+0x90/0x90 [ 17.766719] [] ? pci_device_probe+0x90/0x90 [ 17.766724] [] driver_register+0x65/0x110 [ 17.766729] [] __pci_register_driver+0x3d/0xa0 [ 17.766738] [] ipw2100_init+0x5c/0x1000 [ipw2100] [ 17.766743] [] do_one_initcall+0x2f/0x170 [ 17.766749] [] ? 0xe09f6fff [ 17.766757] [] sys_init_module+0xa8/0x210 [ 17.766766] [] syscall_call+0x7/0xb [ 17.766769] ---[ end trace 559898c6bb0d1c75 ]--- [ 17.767093] ipw2100: probe of 0000:02:03.0 failed with error -5 This warning appears only if we apply Ben Hutchings' fix http://marc.info/?l=linux-wireless&m=132720204412667&w=2 for the bug reported by Cesare Leonardi http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=656813 with cfg80211 warning during device registration ("cfg80211: failed to add phy80211 symlink to netdev!"). We separate device bring up and registration with network stack to avoid the problem. Signed-off-by: Stanislav Yakovlev Tested-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2100.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 9cfae0c08707..95aa8e1683ec 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1903,14 +1903,6 @@ static void ipw2100_down(struct ipw2100_priv *priv) netif_stop_queue(priv->net_dev); } -/* Called by register_netdev() */ -static int ipw2100_net_init(struct net_device *dev) -{ - struct ipw2100_priv *priv = libipw_priv(dev); - - return ipw2100_up(priv, 1); -} - static int ipw2100_wdev_init(struct net_device *dev) { struct ipw2100_priv *priv = libipw_priv(dev); @@ -6087,7 +6079,6 @@ static const struct net_device_ops ipw2100_netdev_ops = { .ndo_stop = ipw2100_close, .ndo_start_xmit = libipw_xmit, .ndo_change_mtu = libipw_change_mtu, - .ndo_init = ipw2100_net_init, .ndo_tx_timeout = ipw2100_tx_timeout, .ndo_set_mac_address = ipw2100_set_address, .ndo_validate_addr = eth_validate_addr, @@ -6329,6 +6320,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, printk(KERN_INFO DRV_NAME ": Detected Intel PRO/Wireless 2100 Network Connection\n"); + err = ipw2100_up(priv, 1); + if (err) + goto fail; + err = ipw2100_wdev_init(dev); if (err) goto fail; @@ -6338,12 +6333,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, * network device we would call ipw2100_up. This introduced a race * condition with newer hotplug configurations (network was coming * up and making calls before the device was initialized). - * - * If we called ipw2100_up before we registered the device, then the - * device name wasn't registered. So, we instead use the net_dev->init - * member to call a function that then just turns and calls ipw2100_up. - * net_dev->init is called after name allocation but before the - * notifier chain is called */ + */ err = register_netdev(dev); if (err) { printk(KERN_WARNING DRV_NAME -- cgit v1.2.3-59-g8ed1b From 0fde0a8cfd0ede7f310d6a681c8e5a7cb3e32406 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 16 May 2012 11:06:21 +0200 Subject: rtl8187: ->brightness_set can not sleep Fix: BUG: sleeping function called from invalid context at kernel/workqueue.c:2547 in_atomic(): 1, irqs_disabled(): 0, pid: 629, name: wpa_supplicant 2 locks held by wpa_supplicant/629: #0: (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x14/0x20 #1: (&trigger->leddev_list_lock){.+.?..}, at: [] led_trigger_event+0x21/0x80 Pid: 629, comm: wpa_supplicant Not tainted 3.3.0-0.rc3.git5.1.fc17.i686 Call Trace: [] __might_sleep+0x126/0x1d0 [] wait_on_work+0x2c/0x1d0 [] __cancel_work_timer+0x6a/0x120 [] cancel_delayed_work_sync+0x10/0x20 [] rtl8187_led_brightness_set+0x82/0xf0 [rtl8187] [] led_trigger_event+0x5c/0x80 [] ieee80211_led_radio+0x1d/0x40 [mac80211] [] ieee80211_stop_device+0x13/0x230 [mac80211] Removing _sync is ok, because if led_on work is currently running it will be finished before led_off work start to perform, since they are always queued on the same mac80211 local->workqueue. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=795176 Signed-off-by: Stanislaw Gruszka Acked-by: Larry Finger Acked-by: Hin-Tak Leung Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187/leds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/rtl818x/rtl8187/leds.c b/drivers/net/wireless/rtl818x/rtl8187/leds.c index 2e0de2f5f0f9..c2d5b495c179 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187/leds.c @@ -117,7 +117,7 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev, radio_on = true; } else if (radio_on) { radio_on = false; - cancel_delayed_work_sync(&priv->led_on); + cancel_delayed_work(&priv->led_on); ieee80211_queue_delayed_work(hw, &priv->led_off, 0); } } else if (radio_on) { -- cgit v1.2.3-59-g8ed1b From 06cf5c4c5bea549235da1aace86b90d4ad0084f8 Mon Sep 17 00:00:00 2001 From: Qasim Javed Date: Tue, 5 Jun 2012 01:25:44 -0500 Subject: mac80211_hwsim: Set IEEE80211_STAT_ACK flag when userspace indicates that the frame has been acknowledged. The station fail average is not updated correctly since the IEEE80211_STAT_ACK flag is not set when using wmediumd with mac80211_hwsim. Set this flag when wmediumd indicates that the frame was successfully transmitted (eventually). Signed-off-by: Qasim Javed Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 4c9336cee817..a0b7cfd34685 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1555,6 +1555,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, hdr = (struct ieee80211_hdr *) skb->data; mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2); } + txi->flags |= IEEE80211_TX_STAT_ACK; } ieee80211_tx_status_irqsafe(data2->hw, skb); return 0; -- cgit v1.2.3-59-g8ed1b From d2c8b15d0cb486f4938ba7f2af349d9d1220cb10 Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Tue, 5 Jun 2012 20:24:37 +0200 Subject: iwlwifi: use correct supported firmware for 6035 and 6000g2 My patch iwlwifi: use correct released ucode version did not correctly report supported firmware for the 6035 device. This patch fixes it. The minimum supported firmware version for 6035 is v6. Also correct the minimum supported firmware version for the 6000g2 series of devices. Cc: stable@kernel.org Signed-off-by: Meenakshi Venkataraman Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 19f7ee84ae89..e5e8ada4aaf6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -35,17 +35,20 @@ #define IWL6000_UCODE_API_MAX 6 #define IWL6050_UCODE_API_MAX 5 #define IWL6000G2_UCODE_API_MAX 6 +#define IWL6035_UCODE_API_MAX 6 /* Oldest version we won't warn about */ #define IWL6000_UCODE_API_OK 4 #define IWL6000G2_UCODE_API_OK 5 #define IWL6050_UCODE_API_OK 5 #define IWL6000G2B_UCODE_API_OK 6 +#define IWL6035_UCODE_API_OK 6 /* Lowest firmware API version supported */ #define IWL6000_UCODE_API_MIN 4 #define IWL6050_UCODE_API_MIN 4 -#define IWL6000G2_UCODE_API_MIN 4 +#define IWL6000G2_UCODE_API_MIN 5 +#define IWL6035_UCODE_API_MIN 6 /* EEPROM versions */ #define EEPROM_6000_TX_POWER_VERSION (4) @@ -227,9 +230,25 @@ const struct iwl_cfg iwl6030_2bg_cfg = { IWL_DEVICE_6030, }; +#define IWL_DEVICE_6035 \ + .fw_name_pre = IWL6030_FW_PRE, \ + .ucode_api_max = IWL6035_UCODE_API_MAX, \ + .ucode_api_ok = IWL6035_UCODE_API_OK, \ + .ucode_api_min = IWL6035_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6030, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ + .base_params = &iwl6000_g2_base_params, \ + .bt_params = &iwl6000_bt_params, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true + const struct iwl_cfg iwl6035_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", - IWL_DEVICE_6030, + IWL_DEVICE_6035, .ht_params = &iwl6000_ht_params, }; -- cgit v1.2.3-59-g8ed1b From e64add27e1b4874f589e550b4e0ca6715070373f Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 5 Jun 2012 20:39:32 +0200 Subject: b43: do not call ieee80211_unregister_hw if we are not registred this patch fixes kernel Oops on "rmmod b43" if firmware was not loaded: BUG: unable to handle kernel NULL pointer dereference at 0000000000000088 IP: [] drain_workqueue+0x25/0x142 PGD 153ac6067 PUD 153b82067 PMD 0 Oops: 0000 [#1] SMP Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 4 ++++ drivers/net/wireless/b43/main.c | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 67c13af6f206..c06b6cb5c91e 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -877,6 +877,10 @@ struct b43_wl { * 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; + /* We can only have one operating interface (802.11 core) * at a time. General information about this interface follows. */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5a39b226b2e3..acd03a4f9730 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2437,6 +2437,7 @@ start_ieee80211: err = ieee80211_register_hw(wl->hw); if (err) goto err_one_core_detach; + wl->hw_registred = true; b43_leds_register(wl->current_dev); goto out; @@ -5299,6 +5300,7 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) 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); if (is_valid_ether_addr(sprom->et1mac)) @@ -5370,12 +5372,15 @@ static void b43_bcma_remove(struct bcma_device *core) * as the ieee80211 unreg will destroy the workqueue. */ cancel_work_sync(&wldev->restart_work); - /* 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); + 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); + } b43_one_core_detach(wldev->dev); @@ -5446,7 +5451,7 @@ static void b43_ssb_remove(struct ssb_device *sdev) cancel_work_sync(&wldev->restart_work); B43_WARN_ON(!wl); - if (wl->current_dev == wldev) { + 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. */ -- cgit v1.2.3-59-g8ed1b From d6ee27eb13beab94056e0de52d81220058ca2297 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 6 Jun 2012 09:13:36 +0200 Subject: iwlwifi: don't mess up the SCD when removing a key When we remove a key, we put a key index which was supposed to tell the fw that we are actually removing the key. But instead the fw took that index as a valid index and messed up the SRAM of the device. This memory corruption on the device mangled the data of the SCD. The impact on the user is that SCD queue 2 got stuck after having removed keys. The message is the log that was printed is: Queue 2 stuck for 10000ms This doesn't seem to fix the higher queues that get stuck from time to time. Cc: stable@vger.kernel.org [2.6.27+] Reviewed-by: Meenakshi Venkataraman Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index aea07aab3c9e..eb6a8eaf42fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1267,7 +1267,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, key_flags |= STA_KEY_MULTICAST_MSK; sta_cmd.key.key_flags = key_flags; - sta_cmd.key.key_offset = WEP_INVALID_OFFSET; + sta_cmd.key.key_offset = keyconf->hw_key_idx; sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK; sta_cmd.mode = STA_CONTROL_MODIFY_MSK; -- cgit v1.2.3-59-g8ed1b From d012d04e4d6312ea157b6cf19e9689af934f5aa7 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 6 Jun 2012 13:55:02 +0200 Subject: iwlwifi: disable the buggy chain extension feature in HW This feature has been reported to be buggy and enabled by default. We therefore need to disable it manually. Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-prph.h | 1 + drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'drivers/net/wireless') diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 3b1069290fa9..dfd54662e3e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -224,6 +224,7 @@ #define SCD_TXFACT (SCD_BASE + 0x10) #define SCD_ACTIVE (SCD_BASE + 0x14) #define SCD_QUEUECHAIN_SEL (SCD_BASE + 0xe8) +#define SCD_CHAINEXT_EN (SCD_BASE + 0x244) #define SCD_AGGR_SEL (SCD_BASE + 0x248) #define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ec6fb395b84d..79c6b91417f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1058,6 +1058,11 @@ static void iwl_tx_start(struct iwl_trans *trans) iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10); + /* The chain extension of the SCD doesn't work well. This feature is + * enabled by default by the HW, so we need to disable it manually. + */ + iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); + /* Enable DMA channel */ for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), -- cgit v1.2.3-59-g8ed1b