Commit d20c678a authored by Dan Williams's avatar Dan Williams Committed by John W. Linville

[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: default avatarDan Williams <dcbw@redhat.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3ba72b25
......@@ -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");
......
......@@ -588,6 +588,10 @@ struct ipw2100_priv {
struct delayed_work wx_event_work;
struct delayed_work hang_check;
struct delayed_work rf_kill;
struct work_struct scan_event_now;
struct delayed_work scan_event_later;
int user_requested_scan;
u32 interrupts;
int tx_interrupts;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment