From cf63495d0dbe435b475a44672f5dee150da6471b Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Wed, 24 Nov 2010 20:33:02 +0000 Subject: orinoco: abort scan on interface down This fixes the problem causing the following trace: ------------[ cut here ]------------ WARNING: at linux-2.6.34/net/wireless/core.c:633 wdev_cleanup_work+0xb7/0xe0 [cfg80211]() Hardware name: Latitude C840 Pid: 707, comm: cfg80211 Not tainted 2.6.34.7-0.5-desktop #1 Call Trace: [] try_stack_unwind+0x173/0x190 [] dump_trace+0x3f/0xe0 [] show_trace_log_lvl+0x4b/0x60 [] show_trace+0x18/0x20 [] dump_stack+0x6d/0x72 [] warn_slowpath_common+0x6e/0xb0 [] warn_slowpath_null+0x13/0x20 [] wdev_cleanup_work+0xb7/0xe0 [cfg80211] [] run_workqueue+0x79/0x170 [] worker_thread+0x83/0xe0 [] kthread+0x74/0x80 [] kernel_thread_helper+0x6/0x10 ---[ end trace 3f0348b3b0c6f4ff ]--- Reported by: Giacomo Comes Signed-off-by: David Kilroy Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/main.c | 12 +++++------- drivers/net/wireless/orinoco/scan.c | 8 ++++++++ drivers/net/wireless/orinoco/scan.h | 1 + 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless/orinoco') diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index e8e2d0f4763..fa0cf744958 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -1392,10 +1392,9 @@ static void orinoco_process_scan_results(struct work_struct *work) orinoco_add_hostscan_results(priv, buf, len); kfree(buf); - } else if (priv->scan_request) { + } else { /* Either abort or complete the scan */ - cfg80211_scan_done(priv->scan_request, (len < 0)); - priv->scan_request = NULL; + orinoco_scan_done(priv, (len < 0)); } spin_lock_irqsave(&priv->scan_lock, flags); @@ -1684,6 +1683,8 @@ static int __orinoco_down(struct orinoco_private *priv) hermes_write_regn(hw, EVACK, 0xffff); } + orinoco_scan_done(priv, true); + /* firmware will have to reassociate */ netif_carrier_off(dev); priv->last_linkstatus = 0xffff; @@ -1762,10 +1763,7 @@ void orinoco_reset(struct work_struct *work) orinoco_unlock(priv, &flags); /* Scanning support: Notify scan cancellation */ - if (priv->scan_request) { - cfg80211_scan_done(priv->scan_request, 1); - priv->scan_request = NULL; - } + orinoco_scan_done(priv, true); if (priv->hard_reset) { err = (*priv->hard_reset)(priv); diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index 4300d9db7d8..86cb54c842e 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c @@ -229,3 +229,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv, priv->scan_request = NULL; } } + +void orinoco_scan_done(struct orinoco_private *priv, bool abort) +{ + if (priv->scan_request) { + cfg80211_scan_done(priv->scan_request, abort); + priv->scan_request = NULL; + } +} diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h index 2dc4e046dbd..27281fb0a6d 100644 --- a/drivers/net/wireless/orinoco/scan.h +++ b/drivers/net/wireless/orinoco/scan.h @@ -16,5 +16,6 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, void orinoco_add_hostscan_results(struct orinoco_private *dev, unsigned char *buf, size_t len); +void orinoco_scan_done(struct orinoco_private *priv, bool abort); #endif /* _ORINOCO_SCAN_H_ */ -- cgit v1.2.3 From 229bd792be0bad245b78ed8f119952733a4752e5 Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Tue, 7 Dec 2010 18:50:42 +0000 Subject: orinoco: initialise priv->hw before assigning the interrupt The interrupt handler takes a lock - but since commit bcad6e80f3f this lock goes through an indirection specified in the hermes_t structure. We must therefore initialise the structure before setting up the interrupt handler. Fix orinoco_cs and spectrum_cs Bisected by: Matt Domsch Signed-off by: David Kilroy Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco_cs.c | 14 +++++++------- drivers/net/wireless/orinoco/spectrum_cs.c | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/net/wireless/orinoco') diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 71b3d68b940..32954c4b243 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link) goto failed; } - ret = pcmcia_request_irq(link, orinoco_interrupt); - if (ret) - goto failed; - - /* We initialize the hermes structure before completing PCMCIA - * configuration just in case the interrupt handler gets - * called. */ mem = ioport_map(link->resource[0]->start, resource_size(link->resource[0])); if (!mem) goto failed; + /* We initialize the hermes structure before completing PCMCIA + * configuration just in case the interrupt handler gets + * called. */ hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); + ret = pcmcia_request_irq(link, orinoco_interrupt); + if (ret) + goto failed; + ret = pcmcia_enable_device(link); if (ret) goto failed; diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index fb859a5ad2e..db34c282e59 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c @@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link) goto failed; } - ret = pcmcia_request_irq(link, orinoco_interrupt); - if (ret) - goto failed; - - /* We initialize the hermes structure before completing PCMCIA - * configuration just in case the interrupt handler gets - * called. */ mem = ioport_map(link->resource[0]->start, resource_size(link->resource[0])); if (!mem) goto failed; + /* We initialize the hermes structure before completing PCMCIA + * configuration just in case the interrupt handler gets + * called. */ hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); hw->eeprom_pda = true; + ret = pcmcia_request_irq(link, orinoco_interrupt); + if (ret) + goto failed; + ret = pcmcia_enable_device(link); if (ret) goto failed; -- cgit v1.2.3 From ba34fcee476d11e7c9df95932787a22a96ff6e68 Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Sun, 5 Dec 2010 15:45:58 +0000 Subject: orinoco: clear countermeasure setting on commit ... and interface up. In these situations, you are usually trying to connect to a new AP, so keeping TKIP countermeasures active is confusing. This is already how the driver behaves (inadvertently). However, querying SIOCGIWAUTH may tell userspace that countermeasures are active when they aren't. Clear the setting so that the reporting matches what the driver has done.. Signed-off by: David Kilroy Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/main.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net/wireless/orinoco') diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index fa0cf744958..f3d396e7544 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -1811,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv) struct net_device *dev = priv->ndev; int err = 0; + /* If we've called commit, we are reconfiguring or bringing the + * interface up. Maintaining countermeasures across this would + * be confusing, so note that we've disabled them. The port will + * be enabled later in orinoco_commit or __orinoco_up. */ + priv->tkip_cm_active = 0; + err = orinoco_hw_program_rids(priv); /* FIXME: what about netif_tx_lock */ -- cgit v1.2.3 From 0a54917c3fc295cb61f3fb52373c173fd3b69f48 Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Sun, 5 Dec 2010 15:43:55 +0000 Subject: orinoco: fix TKIP countermeasure behaviour Enable the port when disabling countermeasures, and disable it on enabling countermeasures. This bug causes the response of the system to certain attacks to be ineffective. It also prevents wpa_supplicant from getting scan results, as wpa_supplicant disables countermeasures on startup - preventing the hardware from scanning. wpa_supplicant works with ap_mode=2 despite this bug because the commit handler re-enables the port. The log tends to look like: State: DISCONNECTED -> SCANNING Starting AP scan for wildcard SSID Scan requested (ret=0) - scan timeout 5 seconds EAPOL: disable timer tick EAPOL: Supplicant port status: Unauthorized Scan timeout - try to get results Failed to get scan results Failed to get scan results - try scanning again Setting scan request: 1 sec 0 usec Starting AP scan for wildcard SSID Scan requested (ret=-1) - scan timeout 5 seconds Failed to initiate AP scan. Reported by: Giacomo Comes Signed-off by: David Kilroy Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/wext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/orinoco') diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 93505f93bf9..e5afabee60d 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c @@ -911,10 +911,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev, */ if (param->value) { priv->tkip_cm_active = 1; - ret = hermes_enable_port(hw, 0); + ret = hermes_disable_port(hw, 0); } else { priv->tkip_cm_active = 0; - ret = hermes_disable_port(hw, 0); + ret = hermes_enable_port(hw, 0); } break; -- cgit v1.2.3