aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ipw2100.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ipw2100.c')
-rw-r--r--drivers/net/wireless/ipw2100.c72
1 files changed, 41 insertions, 31 deletions
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 2d46a16c0945..a6c7904de282 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -1858,14 +1858,6 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1858 1858
1859 modify_acceptable_latency("ipw2100", INFINITE_LATENCY); 1859 modify_acceptable_latency("ipw2100", INFINITE_LATENCY);
1860 1860
1861#ifdef ACPI_CSTATE_LIMIT_DEFINED
1862 if (priv->config & CFG_C3_DISABLED) {
1863 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
1864 acpi_set_cstate_limit(priv->cstate_limit);
1865 priv->config &= ~CFG_C3_DISABLED;
1866 }
1867#endif
1868
1869 /* We have to signal any supplicant if we are disassociating */ 1861 /* We have to signal any supplicant if we are disassociating */
1870 if (associated) 1862 if (associated)
1871 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); 1863 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
@@ -2091,26 +2083,52 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
2091 /* RF_KILL is now enabled (else we wouldn't be here) */ 2083 /* RF_KILL is now enabled (else we wouldn't be here) */
2092 priv->status |= STATUS_RF_KILL_HW; 2084 priv->status |= STATUS_RF_KILL_HW;
2093 2085
2094#ifdef ACPI_CSTATE_LIMIT_DEFINED
2095 if (priv->config & CFG_C3_DISABLED) {
2096 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
2097 acpi_set_cstate_limit(priv->cstate_limit);
2098 priv->config &= ~CFG_C3_DISABLED;
2099 }
2100#endif
2101
2102 /* Make sure the RF Kill check timer is running */ 2086 /* Make sure the RF Kill check timer is running */
2103 priv->stop_rf_kill = 0; 2087 priv->stop_rf_kill = 0;
2104 cancel_delayed_work(&priv->rf_kill); 2088 cancel_delayed_work(&priv->rf_kill);
2105 queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ)); 2089 queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
2106} 2090}
2107 2091
2092static void send_scan_event(void *data)
2093{
2094 struct ipw2100_priv *priv = data;
2095 union iwreq_data wrqu;
2096
2097 wrqu.data.length = 0;
2098 wrqu.data.flags = 0;
2099 wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
2100}
2101
2102static void ipw2100_scan_event_later(struct work_struct *work)
2103{
2104 send_scan_event(container_of(work, struct ipw2100_priv,
2105 scan_event_later.work));
2106}
2107
2108static void ipw2100_scan_event_now(struct work_struct *work)
2109{
2110 send_scan_event(container_of(work, struct ipw2100_priv,
2111 scan_event_now));
2112}
2113
2108static void isr_scan_complete(struct ipw2100_priv *priv, u32 status) 2114static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
2109{ 2115{
2110 IPW_DEBUG_SCAN("scan complete\n"); 2116 IPW_DEBUG_SCAN("scan complete\n");
2111 /* Age the scan results... */ 2117 /* Age the scan results... */
2112 priv->ieee->scans++; 2118 priv->ieee->scans++;
2113 priv->status &= ~STATUS_SCANNING; 2119 priv->status &= ~STATUS_SCANNING;
2120
2121 /* Only userspace-requested scan completion events go out immediately */
2122 if (!priv->user_requested_scan) {
2123 if (!delayed_work_pending(&priv->scan_event_later))
2124 queue_delayed_work(priv->workqueue,
2125 &priv->scan_event_later,
2126 round_jiffies(msecs_to_jiffies(4000)));
2127 } else {
2128 priv->user_requested_scan = 0;
2129 cancel_delayed_work(&priv->scan_event_later);
2130 queue_work(priv->workqueue, &priv->scan_event_now);
2131 }
2114} 2132}
2115 2133
2116#ifdef CONFIG_IPW2100_DEBUG 2134#ifdef CONFIG_IPW2100_DEBUG
@@ -2329,23 +2347,10 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
2329 u32 match, reg; 2347 u32 match, reg;
2330 int j; 2348 int j;
2331#endif 2349#endif
2332#ifdef ACPI_CSTATE_LIMIT_DEFINED
2333 int limit;
2334#endif
2335 2350
2336 IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n", 2351 IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n",
2337 i * sizeof(struct ipw2100_status)); 2352 i * sizeof(struct ipw2100_status));
2338 2353
2339#ifdef ACPI_CSTATE_LIMIT_DEFINED
2340 IPW_DEBUG_INFO(": Disabling C3 transitions.\n");
2341 limit = acpi_get_cstate_limit();
2342 if (limit > 2) {
2343 priv->cstate_limit = limit;
2344 acpi_set_cstate_limit(2);
2345 priv->config |= CFG_C3_DISABLED;
2346 }
2347#endif
2348
2349#ifdef IPW2100_DEBUG_C3 2354#ifdef IPW2100_DEBUG_C3
2350 /* Halt the fimrware so we can get a good image */ 2355 /* Halt the fimrware so we can get a good image */
2351 write_register(priv->net_dev, IPW_REG_RESET_REG, 2356 write_register(priv->net_dev, IPW_REG_RESET_REG,
@@ -4378,6 +4383,7 @@ static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
4378 cancel_delayed_work(&priv->wx_event_work); 4383 cancel_delayed_work(&priv->wx_event_work);
4379 cancel_delayed_work(&priv->hang_check); 4384 cancel_delayed_work(&priv->hang_check);
4380 cancel_delayed_work(&priv->rf_kill); 4385 cancel_delayed_work(&priv->rf_kill);
4386 cancel_delayed_work(&priv->scan_event_later);
4381 destroy_workqueue(priv->workqueue); 4387 destroy_workqueue(priv->workqueue);
4382 priv->workqueue = NULL; 4388 priv->workqueue = NULL;
4383 } 4389 }
@@ -6041,7 +6047,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6041 * ends up causing problems. So, we just handle 6047 * ends up causing problems. So, we just handle
6042 * the WX extensions through the ipw2100_ioctl interface */ 6048 * the WX extensions through the ipw2100_ioctl interface */
6043 6049
6044 /* memset() puts everything to 0, so we only have explicitely set 6050 /* memset() puts everything to 0, so we only have explicitly set
6045 * those values that need to be something else */ 6051 * those values that need to be something else */
6046 6052
6047 /* If power management is turned on, default to AUTO mode */ 6053 /* If power management is turned on, default to AUTO mode */
@@ -6121,6 +6127,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6121 INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work); 6127 INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
6122 INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check); 6128 INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check);
6123 INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill); 6129 INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
6130 INIT_WORK(&priv->scan_event_now, ipw2100_scan_event_now);
6131 INIT_DELAYED_WORK(&priv->scan_event_later, ipw2100_scan_event_later);
6124 6132
6125 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 6133 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
6126 ipw2100_irq_tasklet, (unsigned long)priv); 6134 ipw2100_irq_tasklet, (unsigned long)priv);
@@ -7425,6 +7433,8 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
7425 } 7433 }
7426 7434
7427 IPW_DEBUG_WX("Initiating scan...\n"); 7435 IPW_DEBUG_WX("Initiating scan...\n");
7436
7437 priv->user_requested_scan = 1;
7428 if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) { 7438 if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
7429 IPW_DEBUG_WX("Start scan failed.\n"); 7439 IPW_DEBUG_WX("Start scan failed.\n");
7430 7440
@@ -7499,7 +7509,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7499 switch (wrqu->power.flags & IW_POWER_MODE) { 7509 switch (wrqu->power.flags & IW_POWER_MODE) {
7500 case IW_POWER_ON: /* If not specified */ 7510 case IW_POWER_ON: /* If not specified */
7501 case IW_POWER_MODE: /* If set all mask */ 7511 case IW_POWER_MODE: /* If set all mask */
7502 case IW_POWER_ALL_R: /* If explicitely state all */ 7512 case IW_POWER_ALL_R: /* If explicitly state all */
7503 break; 7513 break;
7504 default: /* Otherwise we don't support it */ 7514 default: /* Otherwise we don't support it */
7505 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", 7515 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",