linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ipw2100: send WEXT scan events
@ 2007-10-10 16:28 Dan Williams
  2007-10-22  8:20 ` Zhu Yi
  0 siblings, 1 reply; 4+ messages in thread
From: Dan Williams @ 2007-10-10 16:28 UTC (permalink / raw)
  To: linux-wireless; +Cc: yi.zhu, ipw2100-devel

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>

diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 8990585..e690609 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -2102,12 +2102,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
@@ -4376,6 +4410,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;
 	}
@@ -6118,6 +6153,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);
@@ -7427,6 +7464,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");
 
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index de7d384..1ee3348 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -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;


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] ipw2100: send WEXT scan events
  2007-10-10 16:28 [PATCH] ipw2100: send WEXT scan events Dan Williams
@ 2007-10-22  8:20 ` Zhu Yi
  2007-10-22 15:46   ` Dan Williams
  0 siblings, 1 reply; 4+ messages in thread
From: Zhu Yi @ 2007-10-22  8:20 UTC (permalink / raw)
  To: Dan Williams; +Cc: linux-wireless, ipw2100-devel


On Wed, 2007-10-10 at 12:28 -0400, Dan Williams wrote:
> 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>

Sorry for the late response. Please see my comments below.

> +                       queue_delayed_work(priv->workqueue,
> +                                       &priv->scan_event_later,
> +                              round_jiffies(msecs_to_jiffies(4000)));

round_jiffies_relative instead?

> @@ -6118,6 +6153,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);

Except the work vs. delayed_work, they are doing the same thing. So you
can replace scan_event_now by scan_event_later with delay = 0.

Thanks,
-yi
 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] ipw2100: send WEXT scan events
  2007-10-22  8:20 ` Zhu Yi
@ 2007-10-22 15:46   ` Dan Williams
  0 siblings, 0 replies; 4+ messages in thread
From: Dan Williams @ 2007-10-22 15:46 UTC (permalink / raw)
  To: Zhu Yi; +Cc: linux-wireless, ipw2100-devel

On Mon, 2007-10-22 at 16:20 +0800, Zhu Yi wrote:
> On Wed, 2007-10-10 at 12:28 -0400, Dan Williams wrote:
> > 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>
> 
> Sorry for the late response. Please see my comments below.
> 
> > +                       queue_delayed_work(priv->workqueue,
> > +                                       &priv->scan_event_later,
> > +                              round_jiffies(msecs_to_jiffies(4000)));
> 
> round_jiffies_relative instead?

Yeah, that patch hit after I posted mine.  Can fix up.

> > @@ -6118,6 +6153,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);
> 
> Except the work vs. delayed_work, they are doing the same thing. So you
> can replace scan_event_now by scan_event_later with delay = 0.

Good catch, will post update.

Thanks!
Dan



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] ipw2100: send WEXT scan events
  2007-10-26 21:04                       ` [PATCH] zd1201: avoid null ptr access of skb->dev John W. Linville
@ 2007-10-26 21:04                         ` John W. Linville
  0 siblings, 0 replies; 4+ messages in thread
From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw)
  To: stable; +Cc: linux-wireless, Dan Williams, John W. Linville

From: Dan Williams <dcbw@redhat.com>

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>
---
 drivers/net/wireless/ipw2100.c |   39 +++++++++++++++++++++++++++++++++++++++
 drivers/net/wireless/ipw2100.h |    4 ++++
 2 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 8990585..e690609 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -2102,12 +2102,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
@@ -4376,6 +4410,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;
 	}
@@ -6118,6 +6153,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);
@@ -7427,6 +7464,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");
 
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index de7d384..1ee3348 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -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;
-- 
1.5.2.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-10-26 21:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-10 16:28 [PATCH] ipw2100: send WEXT scan events Dan Williams
2007-10-22  8:20 ` Zhu Yi
2007-10-22 15:46   ` Dan Williams
  -- strict thread matches above, loose matches on Subject: below --
2007-10-26 21:04 [PATCH] Add get_unaligned to ieee80211_get_radiotap_len John W. Linville
2007-10-26 21:04 ` [PATCH] Improve sanity checks on injected packets John W. Linville
2007-10-26 21:04   ` [PATCH] mac80211: filter locally-originated multicast frames John W. Linville
2007-10-26 21:04     ` [PATCH] libertas: fix endianness breakage John W. Linville
2007-10-26 21:04       ` [PATCH] libertas: more " John W. Linville
2007-10-26 21:04         ` [PATCH] ieee80211: fix TKIP QoS bug John W. Linville
2007-10-26 21:04           ` [PATCH] mac80211: reorder association debug output John W. Linville
2007-10-26 21:04             ` [PATCH] mac80211: store channel info in sta_bss_list John W. Linville
2007-10-26 21:04               ` [PATCH] mac80211: store SSID " John W. Linville
2007-10-26 21:04                 ` [PATCH] mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl John W. Linville
2007-10-26 21:04                   ` [PATCH] mac80211: only honor IW_SCAN_THIS_ESSID in STA, IBSS, and AP modes John W. Linville
2007-10-26 21:04                     ` [PATCH] mac80211: make ieee802_11_parse_elems return void John W. Linville
2007-10-26 21:04                       ` [PATCH] zd1201: avoid null ptr access of skb->dev John W. Linville
2007-10-26 21:04                         ` [PATCH] ipw2100: send WEXT scan events John W. Linville

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).