aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-10-10 12:28:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-10-18 15:38:24 -0400
commitd20c678a450a25c1c12925f60c1b4cc040acc17d (patch)
treec8209bd0394e5cfb5e7726b07d683dad255abda5
parent3ba72b25211217de195e3f528dd36132b38a205b (diff)
[PATCH] ipw2100: send WEXT scan events
ipw2100 wasn't sending WEXT scan events at all on scan completion. And like ipw2200, the driver aggressively auto-scans, requiring non-user-requested scan events to be batched together and sent at specific intervals instead of many times per seconds. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ipw2100.c39
-rw-r--r--drivers/net/wireless/ipw2100.h4
2 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 2d46a16c0945..2fa8eed86dc1 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -2105,12 +2105,46 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
2105 queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ)); 2105 queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
2106} 2106}
2107 2107
2108static void send_scan_event(void *data)
2109{
2110 struct ipw2100_priv *priv = data;
2111 union iwreq_data wrqu;
2112
2113 wrqu.data.length = 0;
2114 wrqu.data.flags = 0;
2115 wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
2116}
2117
2118static void ipw2100_scan_event_later(struct work_struct *work)
2119{
2120 send_scan_event(container_of(work, struct ipw2100_priv,
2121 scan_event_later.work));
2122}
2123
2124static void ipw2100_scan_event_now(struct work_struct *work)
2125{
2126 send_scan_event(container_of(work, struct ipw2100_priv,
2127 scan_event_now));
2128}
2129
2108static void isr_scan_complete(struct ipw2100_priv *priv, u32 status) 2130static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
2109{ 2131{
2110 IPW_DEBUG_SCAN("scan complete\n"); 2132 IPW_DEBUG_SCAN("scan complete\n");
2111 /* Age the scan results... */ 2133 /* Age the scan results... */
2112 priv->ieee->scans++; 2134 priv->ieee->scans++;
2113 priv->status &= ~STATUS_SCANNING; 2135 priv->status &= ~STATUS_SCANNING;
2136
2137 /* Only userspace-requested scan completion events go out immediately */
2138 if (!priv->user_requested_scan) {
2139 if (!delayed_work_pending(&priv->scan_event_later))
2140 queue_delayed_work(priv->workqueue,
2141 &priv->scan_event_later,
2142 round_jiffies(msecs_to_jiffies(4000)));
2143 } else {
2144 priv->user_requested_scan = 0;
2145 cancel_delayed_work(&priv->scan_event_later);
2146 queue_work(priv->workqueue, &priv->scan_event_now);
2147 }
2114} 2148}
2115 2149
2116#ifdef CONFIG_IPW2100_DEBUG 2150#ifdef CONFIG_IPW2100_DEBUG
@@ -4378,6 +4412,7 @@ static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
4378 cancel_delayed_work(&priv->wx_event_work); 4412 cancel_delayed_work(&priv->wx_event_work);
4379 cancel_delayed_work(&priv->hang_check); 4413 cancel_delayed_work(&priv->hang_check);
4380 cancel_delayed_work(&priv->rf_kill); 4414 cancel_delayed_work(&priv->rf_kill);
4415 cancel_delayed_work(&priv->scan_event_later);
4381 destroy_workqueue(priv->workqueue); 4416 destroy_workqueue(priv->workqueue);
4382 priv->workqueue = NULL; 4417 priv->workqueue = NULL;
4383 } 4418 }
@@ -6121,6 +6156,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); 6156 INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
6122 INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check); 6157 INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check);
6123 INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill); 6158 INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
6159 INIT_WORK(&priv->scan_event_now, ipw2100_scan_event_now);
6160 INIT_DELAYED_WORK(&priv->scan_event_later, ipw2100_scan_event_later);
6124 6161
6125 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 6162 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
6126 ipw2100_irq_tasklet, (unsigned long)priv); 6163 ipw2100_irq_tasklet, (unsigned long)priv);
@@ -7425,6 +7462,8 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
7425 } 7462 }
7426 7463
7427 IPW_DEBUG_WX("Initiating scan...\n"); 7464 IPW_DEBUG_WX("Initiating scan...\n");
7465
7466 priv->user_requested_scan = 1;
7428 if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) { 7467 if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
7429 IPW_DEBUG_WX("Start scan failed.\n"); 7468 IPW_DEBUG_WX("Start scan failed.\n");
7430 7469
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index de7d384d38af..1ee3348aedd9 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -588,6 +588,10 @@ struct ipw2100_priv {
588 struct delayed_work wx_event_work; 588 struct delayed_work wx_event_work;
589 struct delayed_work hang_check; 589 struct delayed_work hang_check;
590 struct delayed_work rf_kill; 590 struct delayed_work rf_kill;
591 struct work_struct scan_event_now;
592 struct delayed_work scan_event_later;
593
594 int user_requested_scan;
591 595
592 u32 interrupts; 596 u32 interrupts;
593 int tx_interrupts; 597 int tx_interrupts;