From d55fb891f9da8ee17374349ff482b2715623b7e5 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Tue, 24 Nov 2009 11:54:10 -0500 Subject: cfg80211: Clear encryption privacy when key off is done. When the current_bss is not set, 'iwconfig key off' does not clear the private flag. Hence after we connect with WEP to an AP and then try to connect with another non-WEP AP, it does not work. This issue will not be seen if supplicant is used. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- net/wireless/wext-compat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 584eb48..54face3 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -479,6 +479,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, } err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr); } + wdev->wext.connect.privacy = false; /* * Applications using wireless extensions expect to be * able to delete keys that don't exist, so allow that. -- cgit v1.1 From 19deffbeba930030cfaf000b920333c6ba99ad52 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 8 Dec 2009 17:10:13 -0500 Subject: wireless: correctly report signal value for IEEE80211_HW_SIGNAL_UNSPEC This part was missed in "cfg80211: implement get_wireless_stats", probably because sta_set_sinfo already existed and was only handling dBm signals. Cc: stable@kernel.org Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 93ee1fd..6dc3579 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -354,7 +354,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->rx_packets = sta->rx_packets; sinfo->tx_packets = sta->tx_packets; - if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { + if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || + (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { sinfo->filled |= STATION_INFO_SIGNAL; sinfo->signal = (s8)sta->last_signal; } -- cgit v1.1 From 512414b0bed0d376ac4d5ec1dd6f0b1a3551febc Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 25 Nov 2009 17:23:26 -0500 Subject: ath5k: enable EEPROM checksum check Without this we have no gaurantee of the integrity of the EEPROM and are likely to encounter a lot of bogus bug reports due to actual issues on the EEPROM. With the EEPROM checksum check in place we can easily rule those issues out. If you run patch during a revert *you* have a card with a busted EEPROM and only older kernel will support that concoction. This patch is a trade off between not accepitng bogus EEPROMs and avoiding bogus bug reports allowing developers to focus instead on real concrete issues. If stable keeps bogus bug reports because of a possibly busted EEPROM feel free to apply this there too. Tested on an AR5414 Cc: stable@kernel.org Cc: jirislaby@gmail.com Cc: akpm@linux-foundation.org Cc: rjw@sisk.pl Cc: me@bobcopeland.com Cc: david.quan@atheros.com Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/eeprom.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 644962a..7918852 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -97,6 +97,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; int ret; u16 val; + u32 cksum, offset; /* * Read values from EEPROM and store them in the capability structure @@ -111,7 +112,6 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) return 0; -#ifdef notyet /* * Validate the checksum of the EEPROM date. There are some * devices with invalid EEPROMs. @@ -124,7 +124,6 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); return -EIO; } -#endif AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), ee_ant_gain); -- cgit v1.1 From 49d7590ce494a971311ca55d8aaa6ea9a87b108f Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Wed, 9 Dec 2009 14:56:13 -0200 Subject: rtl8187: add radio led and fix warnings on suspend Michael Buesch reports that his rtl8187 gives warnings on suspend ("queueing ieee80211 work while going to suspend" warnings), as rtl8187 can call ieee80211_queue_delayed_work after mac80211 is suspended. This change enhances rtl8187 led code so we can avoid queuing work after mac80211 is suspended: now we register a radio led and make additional checks to ensure led is off/on properly as mac80211 wants. Signed-off-by: Herton Ronaldo Krzesinski Tested-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187.h | 1 + drivers/net/wireless/rtl818x/rtl8187_leds.c | 68 ++++++++++++++++++++--------- drivers/net/wireless/rtl818x/rtl8187_leds.h | 2 + 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h index b1a24de..6af0f3f 100644 --- a/drivers/net/wireless/rtl818x/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187.h @@ -108,6 +108,7 @@ struct rtl8187_priv { struct delayed_work work; struct ieee80211_hw *dev; #ifdef CONFIG_RTL8187_LEDS + struct rtl8187_led led_radio; struct rtl8187_led led_tx; struct rtl8187_led led_rx; struct delayed_work led_on; diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c index cf8a4a4..ded44c0 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.c +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c @@ -105,19 +105,36 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev, struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led, led_dev); struct ieee80211_hw *hw = led->dev; - struct rtl8187_priv *priv = hw->priv; + struct rtl8187_priv *priv; + static bool radio_on; - if (brightness == LED_OFF) { - ieee80211_queue_delayed_work(hw, &priv->led_off, 0); - /* The LED is off for 1/20 sec so that it just blinks. */ - ieee80211_queue_delayed_work(hw, &priv->led_on, HZ / 20); - } else - ieee80211_queue_delayed_work(hw, &priv->led_on, 0); + if (!hw) + return; + priv = hw->priv; + if (led->is_radio) { + if (brightness == LED_FULL) { + ieee80211_queue_delayed_work(hw, &priv->led_on, 0); + radio_on = true; + } else if (radio_on) { + radio_on = false; + cancel_delayed_work_sync(&priv->led_on); + ieee80211_queue_delayed_work(hw, &priv->led_off, 0); + } + } else if (radio_on) { + if (brightness == LED_OFF) { + ieee80211_queue_delayed_work(hw, &priv->led_off, 0); + /* The LED is off for 1/20 sec - it just blinks. */ + ieee80211_queue_delayed_work(hw, &priv->led_on, + HZ / 20); + } else + ieee80211_queue_delayed_work(hw, &priv->led_on, 0); + } } static int rtl8187_register_led(struct ieee80211_hw *dev, struct rtl8187_led *led, const char *name, - const char *default_trigger, u8 ledpin) + const char *default_trigger, u8 ledpin, + bool is_radio) { int err; struct rtl8187_priv *priv = dev->priv; @@ -128,6 +145,7 @@ static int rtl8187_register_led(struct ieee80211_hw *dev, return -EINVAL; led->dev = dev; led->ledpin = ledpin; + led->is_radio = is_radio; strncpy(led->name, name, sizeof(led->name)); led->led_dev.name = led->name; @@ -145,7 +163,11 @@ static int rtl8187_register_led(struct ieee80211_hw *dev, static void rtl8187_unregister_led(struct rtl8187_led *led) { + struct ieee80211_hw *hw = led->dev; + struct rtl8187_priv *priv = hw->priv; + led_classdev_unregister(&led->led_dev); + flush_delayed_work(&priv->led_off); led->dev = NULL; } @@ -183,33 +205,37 @@ void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid) INIT_DELAYED_WORK(&priv->led_off, led_turn_off); snprintf(name, sizeof(name), + "rtl8187-%s::radio", wiphy_name(dev->wiphy)); + err = rtl8187_register_led(dev, &priv->led_radio, name, + ieee80211_get_radio_led_name(dev), ledpin, true); + if (err) + return; + + snprintf(name, sizeof(name), "rtl8187-%s::tx", wiphy_name(dev->wiphy)); err = rtl8187_register_led(dev, &priv->led_tx, name, - ieee80211_get_tx_led_name(dev), ledpin); + ieee80211_get_tx_led_name(dev), ledpin, false); if (err) - goto error; + goto err_tx; + snprintf(name, sizeof(name), "rtl8187-%s::rx", wiphy_name(dev->wiphy)); err = rtl8187_register_led(dev, &priv->led_rx, name, - ieee80211_get_rx_led_name(dev), ledpin); - if (!err) { - ieee80211_queue_delayed_work(dev, &priv->led_on, 0); + ieee80211_get_rx_led_name(dev), ledpin, false); + if (!err) return; - } - /* registration of RX LED failed - unregister TX */ + + /* registration of RX LED failed - unregister */ rtl8187_unregister_led(&priv->led_tx); -error: - /* If registration of either failed, cancel delayed work */ - cancel_delayed_work_sync(&priv->led_off); - cancel_delayed_work_sync(&priv->led_on); +err_tx: + rtl8187_unregister_led(&priv->led_radio); } void rtl8187_leds_exit(struct ieee80211_hw *dev) { struct rtl8187_priv *priv = dev->priv; - /* turn the LED off before exiting */ - ieee80211_queue_delayed_work(dev, &priv->led_off, 0); + rtl8187_unregister_led(&priv->led_radio); rtl8187_unregister_led(&priv->led_rx); rtl8187_unregister_led(&priv->led_tx); cancel_delayed_work_sync(&priv->led_off); diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187_leds.h index a033202..efe8041 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_leds.h +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.h @@ -47,6 +47,8 @@ struct rtl8187_led { u8 ledpin; /* The unique name string for this LED device. */ char name[RTL8187_LED_MAX_NAME_LEN + 1]; + /* If the LED is radio or tx/rx */ + bool is_radio; }; void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code); -- cgit v1.1 From 214ac9a4ead6cb254451c09d9c8234a76693feb1 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 9 Dec 2009 13:25:56 -0600 Subject: b43: Remove reset after fatal DMA error As shown in Kernel Bugzilla #14761, doing a controller restart after a fatal DMA error does not accomplish anything other than consume the CPU on an affected system. Accordingly, substitute a meaningful message for the restart. Signed-off-by: Larry Finger Cc: Stable [2.6.32] Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 077480c..19b4eae 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1784,7 +1784,10 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) dma_reason[0], dma_reason[1], dma_reason[2], dma_reason[3], dma_reason[4], dma_reason[5]); - b43_controller_restart(dev, "DMA error"); + b43err(dev->wl, "This device does not support DMA " + "on your system. Please use PIO instead.\n"); + b43err(dev->wl, "CONFIG_B43_FORCE_PIO must be set in " + "your kernel configuration.\n"); return; } if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { -- cgit v1.1 From 0c3cee72a403e3b4992a5478c9c33d668c246c22 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 9 Dec 2009 20:25:59 +0100 Subject: net/mac80211: Correct size given to memset Memset should be given the size of the structure, not the size of the pointer. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ type T; T *x; expression E; @@ memset(x, E, sizeof( + * x)) // Signed-off-by: Julia Lawall Signed-off-by: John W. Linville --- net/mac80211/mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index c0fe464..6a43314 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -427,7 +427,7 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, char *addr5, char *addr6) { int aelen = 0; - memset(meshhdr, 0, sizeof(meshhdr)); + memset(meshhdr, 0, sizeof(*meshhdr)); meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); sdata->u.mesh.mesh_seqnum++; -- cgit v1.1 From 5d618cb81aeea19879975cd1f9a1e707694dfd7c Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Wed, 9 Dec 2009 18:43:00 -0800 Subject: mac80211: Fixed bug in mesh portal paths Paths to mesh portals were being timed out immediately after each use in intermediate forwarding nodes. mppath->exp_time is set to the expiration time so assigning it to jiffies was marking the path as expired. Signed-off-by: Javier Cardona Signed-off-by: Andrey Yurovsky Cc: stable@kernel.org Signed-off-by: John W. Linville --- net/mac80211/rx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f237df4..9f2807a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1712,7 +1712,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mpp_path_add(proxied_addr, mpp_addr, sdata); } else { spin_lock_bh(&mppath->state_lock); - mppath->exp_time = jiffies; if (compare_ether_addr(mppath->mpp, mpp_addr) != 0) memcpy(mppath->mpp, mpp_addr, ETH_ALEN); spin_unlock_bh(&mppath->state_lock); -- cgit v1.1 From 7b324d28a94dac5a451e8cba66e8d324601e5b9a Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Wed, 9 Dec 2009 18:43:01 -0800 Subject: mac80211: Revert 'Use correct sign for mesh active path refresh' The patch ("mac80211: Use correct sign for mesh active path refresh.") was actually a bug. Reverted it and improved the explanation of how mesh path refresh works. Signed-off-by: Javier Cardona Signed-off-by: Andrey Yurovsky Cc: stable@kernel.org Signed-off-by: John W. Linville --- net/mac80211/mesh.h | 5 +++-- net/mac80211/mesh_hwmp.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 31e1025..85562c5 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -188,8 +188,9 @@ struct mesh_rmc { */ #define MESH_PREQ_MIN_INT 10 #define MESH_DIAM_TRAVERSAL_TIME 50 -/* Paths will be refreshed if they are closer than PATH_REFRESH_TIME to their - * expiration +/* A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds before + * timing out. This way it will remain ACTIVE and no data frames will be + * unnecesarily held in the pending queue. */ #define MESH_PATH_REFRESH_TIME 1000 #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 833b2f3..d28acb6 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -937,7 +937,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb, if (mpath->flags & MESH_PATH_ACTIVE) { if (time_after(jiffies, - mpath->exp_time + + mpath->exp_time - msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && !memcmp(sdata->dev->dev_addr, hdr->addr4, ETH_ALEN) && !(mpath->flags & MESH_PATH_RESOLVING) && -- cgit v1.1 From 65182b9fb004220f250d4269c864cf0f1f372e85 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 9 Dec 2009 15:11:22 -0500 Subject: wireless: update old static regulatory domain rules Update "US" and "JP" for current rules, and replace "EU" rules with the world roaming domain (since it was only a pseudo-domain anyway). Signed-off-by: John W. Linville --- net/wireless/reg.c | 75 ++++++++++++++++++------------------------------------ 1 file changed, 25 insertions(+), 50 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index c01470e..baa898a 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -141,62 +141,35 @@ static const struct ieee80211_regdomain us_regdom = { .reg_rules = { /* IEEE 802.11b/g, channels 1..11 */ REG_RULE(2412-10, 2462+10, 40, 6, 27, 0), - /* IEEE 802.11a, channel 36 */ - REG_RULE(5180-10, 5180+10, 40, 6, 23, 0), - /* IEEE 802.11a, channel 40 */ - REG_RULE(5200-10, 5200+10, 40, 6, 23, 0), - /* IEEE 802.11a, channel 44 */ - REG_RULE(5220-10, 5220+10, 40, 6, 23, 0), + /* IEEE 802.11a, channel 36..48 */ + REG_RULE(5180-10, 5240+10, 40, 6, 17, 0), /* IEEE 802.11a, channels 48..64 */ - REG_RULE(5240-10, 5320+10, 40, 6, 23, 0), + REG_RULE(5260-10, 5320+10, 40, 6, 20, NL80211_RRF_DFS), + /* IEEE 802.11a, channels 100..124 */ + REG_RULE(5500-10, 5590+10, 40, 6, 20, NL80211_RRF_DFS), + /* IEEE 802.11a, channels 132..144 */ + REG_RULE(5660-10, 5700+10, 40, 6, 20, NL80211_RRF_DFS), /* IEEE 802.11a, channels 149..165, outdoor */ REG_RULE(5745-10, 5825+10, 40, 6, 30, 0), } }; static const struct ieee80211_regdomain jp_regdom = { - .n_reg_rules = 3, + .n_reg_rules = 6, .alpha2 = "JP", .reg_rules = { - /* IEEE 802.11b/g, channels 1..14 */ - REG_RULE(2412-10, 2484+10, 40, 6, 20, 0), - /* IEEE 802.11a, channels 34..48 */ - REG_RULE(5170-10, 5240+10, 40, 6, 20, - NL80211_RRF_PASSIVE_SCAN), + /* IEEE 802.11b/g, channels 1..11 */ + REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), + /* IEEE 802.11b/g, channels 12..13 */ + REG_RULE(2467-10, 2472+10, 20, 6, 20, 0), + /* IEEE 802.11b/g, channel 14 */ + REG_RULE(2484-10, 2484+10, 20, 6, 20, NL80211_RRF_NO_OFDM), + /* IEEE 802.11a, channels 36..48 */ + REG_RULE(5180-10, 5240+10, 40, 6, 20, 0), /* IEEE 802.11a, channels 52..64 */ - REG_RULE(5260-10, 5320+10, 40, 6, 20, - NL80211_RRF_NO_IBSS | - NL80211_RRF_DFS), - } -}; - -static const struct ieee80211_regdomain eu_regdom = { - .n_reg_rules = 6, - /* - * This alpha2 is bogus, we leave it here just for stupid - * backward compatibility - */ - .alpha2 = "EU", - .reg_rules = { - /* IEEE 802.11b/g, channels 1..13 */ - REG_RULE(2412-10, 2472+10, 40, 6, 20, 0), - /* IEEE 802.11a, channel 36 */ - REG_RULE(5180-10, 5180+10, 40, 6, 23, - NL80211_RRF_PASSIVE_SCAN), - /* IEEE 802.11a, channel 40 */ - REG_RULE(5200-10, 5200+10, 40, 6, 23, - NL80211_RRF_PASSIVE_SCAN), - /* IEEE 802.11a, channel 44 */ - REG_RULE(5220-10, 5220+10, 40, 6, 23, - NL80211_RRF_PASSIVE_SCAN), - /* IEEE 802.11a, channels 48..64 */ - REG_RULE(5240-10, 5320+10, 40, 6, 20, - NL80211_RRF_NO_IBSS | - NL80211_RRF_DFS), - /* IEEE 802.11a, channels 100..140 */ - REG_RULE(5500-10, 5700+10, 40, 6, 30, - NL80211_RRF_NO_IBSS | - NL80211_RRF_DFS), + REG_RULE(5260-10, 5320+10, 40, 6, 20, NL80211_RRF_DFS), + /* IEEE 802.11a, channels 100..144 */ + REG_RULE(5500-10, 5700+10, 40, 6, 23, NL80211_RRF_DFS), } }; @@ -206,15 +179,17 @@ static const struct ieee80211_regdomain *static_regdom(char *alpha2) return &us_regdom; if (alpha2[0] == 'J' && alpha2[1] == 'P') return &jp_regdom; + /* Use world roaming rules for "EU", since it was a pseudo + domain anyway... */ if (alpha2[0] == 'E' && alpha2[1] == 'U') - return &eu_regdom; - /* Default, as per the old rules */ - return &us_regdom; + return &world_regdom; + /* Default, world roaming rules */ + return &world_regdom; } static bool is_old_static_regdom(const struct ieee80211_regdomain *rd) { - if (rd == &us_regdom || rd == &jp_regdom || rd == &eu_regdom) + if (rd == &us_regdom || rd == &jp_regdom || rd == &world_regdom) return true; return false; } -- cgit v1.1