|
@@ -2105,12 +2105,46 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
|
|
|
queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
|
|
|
}
|
|
|
|
|
|
+static void send_scan_event(void *data)
|
|
|
+{
|
|
|
+ struct ipw2100_priv *priv = data;
|
|
|
+ union iwreq_data wrqu;
|
|
|
+
|
|
|
+ wrqu.data.length = 0;
|
|
|
+ wrqu.data.flags = 0;
|
|
|
+ wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
|
|
|
+}
|
|
|
+
|
|
|
+static void ipw2100_scan_event_later(struct work_struct *work)
|
|
|
+{
|
|
|
+ send_scan_event(container_of(work, struct ipw2100_priv,
|
|
|
+ scan_event_later.work));
|
|
|
+}
|
|
|
+
|
|
|
+static void ipw2100_scan_event_now(struct work_struct *work)
|
|
|
+{
|
|
|
+ send_scan_event(container_of(work, struct ipw2100_priv,
|
|
|
+ scan_event_now));
|
|
|
+}
|
|
|
+
|
|
|
static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
|
|
|
{
|
|
|
IPW_DEBUG_SCAN("scan complete\n");
|
|
|
/* Age the scan results... */
|
|
|
priv->ieee->scans++;
|
|
|
priv->status &= ~STATUS_SCANNING;
|
|
|
+
|
|
|
+ /* Only userspace-requested scan completion events go out immediately */
|
|
|
+ if (!priv->user_requested_scan) {
|
|
|
+ if (!delayed_work_pending(&priv->scan_event_later))
|
|
|
+ queue_delayed_work(priv->workqueue,
|
|
|
+ &priv->scan_event_later,
|
|
|
+ round_jiffies(msecs_to_jiffies(4000)));
|
|
|
+ } else {
|
|
|
+ priv->user_requested_scan = 0;
|
|
|
+ cancel_delayed_work(&priv->scan_event_later);
|
|
|
+ queue_work(priv->workqueue, &priv->scan_event_now);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_IPW2100_DEBUG
|
|
@@ -4378,6 +4412,7 @@ static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
|
|
|
cancel_delayed_work(&priv->wx_event_work);
|
|
|
cancel_delayed_work(&priv->hang_check);
|
|
|
cancel_delayed_work(&priv->rf_kill);
|
|
|
+ cancel_delayed_work(&priv->scan_event_later);
|
|
|
destroy_workqueue(priv->workqueue);
|
|
|
priv->workqueue = NULL;
|
|
|
}
|
|
@@ -6121,6 +6156,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
|
|
|
INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
|
|
|
INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check);
|
|
|
INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
|
|
|
+ INIT_WORK(&priv->scan_event_now, ipw2100_scan_event_now);
|
|
|
+ INIT_DELAYED_WORK(&priv->scan_event_later, ipw2100_scan_event_later);
|
|
|
|
|
|
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
|
|
|
ipw2100_irq_tasklet, (unsigned long)priv);
|
|
@@ -7425,6 +7462,8 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
|
|
|
}
|
|
|
|
|
|
IPW_DEBUG_WX("Initiating scan...\n");
|
|
|
+
|
|
|
+ priv->user_requested_scan = 1;
|
|
|
if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
|
|
|
IPW_DEBUG_WX("Start scan failed.\n");
|
|
|
|