Netdev List
 help / color / mirror / Atom feed
* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Johannes Berg @ 2006-04-13 12:19 UTC (permalink / raw)
  To: Dan Williams; +Cc: Pete Zaitcev, netdev, linville, softmac-dev
In-Reply-To: <1144930375.2372.10.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 1491 bytes --]

On Thu, 2006-04-13 at 08:12 -0400, Dan Williams wrote:

> Maybe it's wrong now, but it's how the CLI tools have operated for quite
> a while AFAIK.

Yes, and they don't seem to care about the netlink messages.

But the question is rather -- should we block the program inside the
kernel and only return from "get scan" after the scan is actually done,
rather than returning "we can't give you anything now, try later". We
could do that too, but then the program would be blocked inside the
kernel without any chance of saying "bah, this takes too long, I'll
ignore it".

> There are two options for tools: (a) request scan and block on GIWSCAN
> until it doesn't return EAGAIN, or (b) request a scan, enter a loop,
> wait for the GIWSCAN netlink message to come back.  The point here is
> that if you have to write a tool with 100 lines of netlink message
> processing code _just_ to get the "scan done!" message, that's a bitch.
> More complicated programs can obviously do this, but simple tools don't
> want or need to.

Yeah, I just implemented that in softmac too (patch 5 of my set), so you
can just request a scan and do nothing until you are notified that the
netlink message came in that scanning is done.

> airo, atmel, and orinoco all do this.  ipw does not, and prism54 does
> not because it does background scanning.  I believe that the patch for
> softmac/bcm43xx EAGAIN is correct.

Good. I hope that these can go in before 2.6.17.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply

* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Dan Williams @ 2006-04-13 12:14 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Pete Zaitcev, Jean Tourrilhes, netdev, softmac-dev
In-Reply-To: <1144920890.4187.50.camel@localhost>

On Thu, 2006-04-13 at 11:34 +0200, Johannes Berg wrote:
> On Thu, 2006-04-13 at 11:06 +0200, Johannes Berg wrote:
> 
> > > It's very likely that tools do indeed loop when they see EAGAIN, but
> > > this is a workaround, not the main mode of operation. It seems obvious
> > > to me that the get method should wait until the scan results are
> > > available. Perhaps the discussion had a specific scenario where
> > > EAGAIN would make sense, but I cannot imagine what it might be.
> > 
> > Right, they do loop, but they don't have a method to indicate
> > completion. Thus we'd have to actually wait for the completion in the
> > kernel. Jean, what is the intended use here?
> 
> Hah, never mind, I guess we're just supposed to send SIOCGIWSCAN. Will
> send a patch in a minute.

No, you should be doing both really.  If you don't do EAGAIN, then tools
like iwlist and other simple ones that don't want to spend 100 lines of
code in netlink message processing just to receive the wireless event
won't work very well.

Dan



^ permalink raw reply

* Re: [patch 5] softmac: report when scanning has finished
From: Dan Williams @ 2006-04-13 12:15 UTC (permalink / raw)
  To: Johannes Berg; +Cc: netdev, John W. Linville, softmac-dev
In-Reply-To: <1144921288.4187.54.camel@localhost>

On Thu, 2006-04-13 at 11:41 +0200, Johannes Berg wrote:
> Make softmac report a scan event when scanning has finished, that way
> userspace can wait for the event to happen instead of polling for the
> results.
> 
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

ACK, good catch.

Signed-off-by: Dan Williams <dcbw@redhat.com>

> ---
> This patch depends on the previous patch 4. If you want, I can resend
> the whole series with proper patch x/5 headers etc. I don't know if
> these can still go in before .17, but it'd be very good if they could,
> they're essentially bug fixes for things I either didn't know or just
> plain bugs :)
> 
> Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_event.c
> ===================================================================
> --- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_event.c	2006-04-13 02:42:59.000000000 +0200
> +++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_event.c	2006-04-13 11:30:59.896998787 +0200
> @@ -152,6 +152,12 @@
>  			wrqu.ap_addr.sa_family = ARPHRD_ETHER;
>  			we_event = SIOCGIWAP;
>  			break;
> +		case IEEE80211SOFTMAC_EVENT_SCAN_FINISHED:
> +			wrqu.data.length = 0;
> +			wrqu.data.flags = 0;
> +			memset(&wrqu, '\0', sizeof (union iwreq_data));
> +			we_event = SIOCGIWSCAN;
> +			break;
>  		default:
>  			msg = event_descriptions[event];
>  			wrqu.data.length = strlen(msg);
> 


^ permalink raw reply

* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Dan Williams @ 2006-04-13 12:12 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: johannes, netdev, linville
In-Reply-To: <20060413020010.2ab16d7b.zaitcev@redhat.com>

On Thu, 2006-04-13 at 02:00 -0700, Pete Zaitcev wrote:
> On Tue, 11 Apr 2006 10:58:06 +0200, johannes@sipsolutions.net wrote:
> 
> > Below patch was developed after discussion with Daniel Drake who
> > mentioned to me that wireless tools expect an EAGAIN return from getscan
> > so that they can wait for the scan to finish before printing out the
> > results.
> 
> This sounds completely wrong. Do you guys remember the Subject: string
> of this discussion by any chance?

Maybe it's wrong now, but it's how the CLI tools have operated for quite
a while AFAIK.

There are two options for tools: (a) request scan and block on GIWSCAN
until it doesn't return EAGAIN, or (b) request a scan, enter a loop,
wait for the GIWSCAN netlink message to come back.  The point here is
that if you have to write a tool with 100 lines of netlink message
processing code _just_ to get the "scan done!" message, that's a bitch.
More complicated programs can obviously do this, but simple tools don't
want or need to.

airo, atmel, and orinoco all do this.  ipw does not, and prism54 does
not because it does background scanning.  I believe that the patch for
softmac/bcm43xx EAGAIN is correct.

Dan



^ permalink raw reply

* [RFC: 2.6 patch] net/core/: possible cleanups
From: Adrian Bunk @ 2006-04-13 11:58 UTC (permalink / raw)
  To: netdev

This patch contains the following possible cleanups:
- make the following needlessly global functions static:
  - skbuff.c: kfree_skbmem()
  - skbuff.c: skb_prepare_seq_read()
  - skbuff.c: skb_seq_read()
  - skbuff.c: skb_abort_seq_read()
- #if 0 the following unused global functions:
  - skbuff.c: alloc_skb_from_cache()
  - skbuff.c: skb_insert()
- make the following trivial wrapper function a static inline:
  - neighbour.c: neigh_parms_destroy()
- remove the following unused EXPORT_SYMBOL's:
  - dev.c: netdev_features_change
  - dev.c: register_gifconf
  - flow.c: flow_cache_genid
  - flow.c: flow_cache_lookup
  - gen_stats.c: gnet_stats_start_copy
  - iovec.c: csum_partial_copy_fromiovecend
  - neighbour.c: neigh_add
  - neighbour.c: neigh_compat_output
  - neighbour.c: neigh_delete
  - neighbour.c: neigh_dump_info
  - neighbour.c: neigh_event_ns
  - neighbour.c: neigh_update_hhs (static inline function!)
  - neighbour.c: neightbl_dump_info
  - neighbour.c: neightbl_set
  - request_sock.c: reqsk_queue_alloc
  - request_sock.c: reqsk_queue_destroy
  - skbuff.c: skb_clone_fraglist (static function!)
  - skbuff.c: skb_split
  - stream.c: sk_stream_wait_memory
  - stream.c: sk_stream_rfree
  - stream.c: __sk_stream_mem_reclaim
  - stream.c: sk_stream_mem_schedule
  - stream.c: sk_stream_kill_queues
- remove the following unused EXPORT_SYMBOL_GPL:
  - sock.c: sk_clone

Signed-off-by: Adrian Bunk <bunk@stusta.de>

---

 include/linux/skbuff.h  |   12 ------------
 include/net/neighbour.h |    6 +++++-
 net/core/dev.c          |    2 --
 net/core/flow.c         |    2 --
 net/core/gen_stats.c    |    1 -
 net/core/iovec.c        |    1 -
 net/core/neighbour.c    |   14 --------------
 net/core/request_sock.c |    3 ---
 net/core/skbuff.c       |   26 ++++++++++++--------------
 net/core/sock.c         |    2 --
 net/core/stream.c       |    9 ---------
 11 files changed, 17 insertions(+), 61 deletions(-)

--- linux-2.6.17-rc1-mm2-full/net/core/dev.c.old	2006-04-13 11:02:21.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/net/core/dev.c	2006-04-13 11:03:13.000000000 +0200
@@ -752,7 +752,6 @@
 {
 	blocking_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
 }
-EXPORT_SYMBOL(netdev_features_change);
 
 /**
  *	netdev_state_change - device changes state
@@ -3398,7 +3397,6 @@
 EXPORT_SYMBOL(netdev_state_change);
 EXPORT_SYMBOL(netif_receive_skb);
 EXPORT_SYMBOL(netif_rx);
-EXPORT_SYMBOL(register_gifconf);
 EXPORT_SYMBOL(register_netdevice);
 EXPORT_SYMBOL(register_netdevice_notifier);
 EXPORT_SYMBOL(skb_checksum_help);
--- linux-2.6.17-rc1-mm2-full/net/core/flow.c.old	2006-04-13 11:04:23.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/net/core/flow.c	2006-04-13 11:04:45.000000000 +0200
@@ -370,5 +370,3 @@
 
 module_init(flow_cache_init);
 
-EXPORT_SYMBOL(flow_cache_genid);
-EXPORT_SYMBOL(flow_cache_lookup);
--- linux-2.6.17-rc1-mm2-full/net/core/gen_stats.c.old	2006-04-13 11:06:35.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/net/core/gen_stats.c	2006-04-13 11:07:05.000000000 +0200
@@ -230,7 +230,6 @@
 }
 
 
-EXPORT_SYMBOL(gnet_stats_start_copy);
 EXPORT_SYMBOL(gnet_stats_start_copy_compat);
 EXPORT_SYMBOL(gnet_stats_copy_basic);
 EXPORT_SYMBOL(gnet_stats_copy_rate_est);
--- linux-2.6.17-rc1-mm2-full/net/core/iovec.c.old	2006-04-13 11:07:56.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/net/core/iovec.c	2006-04-13 11:08:03.000000000 +0200
@@ -233,7 +233,6 @@
 	goto out;
 }
 
-EXPORT_SYMBOL(csum_partial_copy_fromiovecend);
 EXPORT_SYMBOL(memcpy_fromiovec);
 EXPORT_SYMBOL(memcpy_fromiovecend);
 EXPORT_SYMBOL(memcpy_toiovec);
--- linux-2.6.17-rc1-mm2-full/include/net/neighbour.h.old	2006-04-13 11:08:59.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/include/net/neighbour.h	2006-04-13 11:32:05.000000000 +0200
@@ -235,7 +235,6 @@
 
 extern struct neigh_parms	*neigh_parms_alloc(struct net_device *dev, struct neigh_table *tbl);
 extern void			neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms);
-extern void			neigh_parms_destroy(struct neigh_parms *parms);
 extern unsigned long		neigh_rand_reach_time(unsigned long base);
 
 extern void			pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
@@ -279,6 +278,11 @@
 						      ctl_handler *strategy);
 extern void			neigh_sysctl_unregister(struct neigh_parms *p);
 
+static inline void neigh_parms_destroy(struct neigh_parms *parms)
+{
+	kfree(parms);
+}
+
 static inline void __neigh_parms_put(struct neigh_parms *parms)
 {
 	atomic_dec(&parms->refcnt);
--- linux-2.6.17-rc1-mm2-full/net/core/neighbour.c.old	2006-04-13 11:09:19.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/net/core/neighbour.c	2006-04-13 11:14:40.000000000 +0200
@@ -1321,12 +1321,6 @@
 	NEIGH_PRINTK1("neigh_parms_release: not found\n");
 }
 
-void neigh_parms_destroy(struct neigh_parms *parms)
-{
-	kfree(parms);
-}
-
-
 void neigh_table_init(struct neigh_table *tbl)
 {
 	unsigned long now = jiffies;
@@ -2639,15 +2633,10 @@
 #endif	/* CONFIG_SYSCTL */
 
 EXPORT_SYMBOL(__neigh_event_send);
-EXPORT_SYMBOL(neigh_add);
 EXPORT_SYMBOL(neigh_changeaddr);
-EXPORT_SYMBOL(neigh_compat_output);
 EXPORT_SYMBOL(neigh_connected_output);
 EXPORT_SYMBOL(neigh_create);
-EXPORT_SYMBOL(neigh_delete);
 EXPORT_SYMBOL(neigh_destroy);
-EXPORT_SYMBOL(neigh_dump_info);
-EXPORT_SYMBOL(neigh_event_ns);
 EXPORT_SYMBOL(neigh_ifdown);
 EXPORT_SYMBOL(neigh_lookup);
 EXPORT_SYMBOL(neigh_lookup_nodev);
@@ -2658,11 +2647,8 @@
 EXPORT_SYMBOL(neigh_table_clear);
 EXPORT_SYMBOL(neigh_table_init);
 EXPORT_SYMBOL(neigh_update);
-EXPORT_SYMBOL(neigh_update_hhs);
 EXPORT_SYMBOL(pneigh_enqueue);
 EXPORT_SYMBOL(pneigh_lookup);
-EXPORT_SYMBOL(neightbl_dump_info);
-EXPORT_SYMBOL(neightbl_set);
 
 #ifdef CONFIG_ARPD
 EXPORT_SYMBOL(neigh_app_ns);
--- linux-2.6.17-rc1-mm2-full/net/core/request_sock.c.old	2006-04-13 11:16:31.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/net/core/request_sock.c	2006-04-13 11:16:50.000000000 +0200
@@ -59,8 +59,6 @@
 	return 0;
 }
 
-EXPORT_SYMBOL(reqsk_queue_alloc);
-
 void reqsk_queue_destroy(struct request_sock_queue *queue)
 {
 	/* make all the listen_opt local to us */
@@ -84,4 +82,3 @@
 	kfree(lopt);
 }
 
-EXPORT_SYMBOL(reqsk_queue_destroy);
--- linux-2.6.17-rc1-mm2-full/include/linux/skbuff.h.old	2006-04-13 11:17:44.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/include/linux/skbuff.h	2006-04-13 11:59:40.000000000 +0200
@@ -320,10 +320,6 @@
 	return __alloc_skb(size, priority, 1);
 }
 
-extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
-					    unsigned int size,
-					    gfp_t priority);
-extern void	       kfree_skbmem(struct sk_buff *skb);
 extern struct sk_buff *skb_clone(struct sk_buff *skb,
 				 gfp_t priority);
 extern struct sk_buff *skb_copy(const struct sk_buff *skb,
@@ -361,13 +357,6 @@
 	__u8		*frag_data;
 };
 
-extern void	      skb_prepare_seq_read(struct sk_buff *skb,
-					   unsigned int from, unsigned int to,
-					   struct skb_seq_state *st);
-extern unsigned int   skb_seq_read(unsigned int consumed, const u8 **data,
-				   struct skb_seq_state *st);
-extern void	      skb_abort_seq_read(struct skb_seq_state *st);
-
 extern unsigned int   skb_find_text(struct sk_buff *skb, unsigned int from,
 				    unsigned int to, struct ts_config *config,
 				    struct ts_state *state);
@@ -685,7 +674,6 @@
 /*
  *	Insert a packet on a list.
  */
-extern void        skb_insert(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list);
 static inline void __skb_insert(struct sk_buff *newsk,
 				struct sk_buff *prev, struct sk_buff *next,
 				struct sk_buff_head *list)
--- linux-2.6.17-rc1-mm2-full/net/core/skbuff.c.old	2006-04-13 11:17:16.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/net/core/skbuff.c	2006-04-13 11:25:13.000000000 +0200
@@ -187,6 +187,7 @@
 	goto out;
 }
 
+#if 0
 /**
  *	alloc_skb_from_cache	-	allocate a network buffer
  *	@cp: kmem_cache from which to allocate the data area
@@ -240,6 +241,7 @@
 	skb = NULL;
 	goto out;
 }
+#endif  /*  0  */
 
 
 static void skb_drop_fraglist(struct sk_buff *skb)
@@ -284,7 +286,7 @@
 /*
  *	Free an skbuff by memory without cleaning the state.
  */
-void kfree_skbmem(struct sk_buff *skb)
+static void kfree_skbmem(struct sk_buff *skb)
 {
 	struct sk_buff *other;
 	atomic_t *fclone_ref;
@@ -1458,6 +1460,8 @@
 }
 
 
+#if 0
+
 /**
  *	skb_insert	-	insert a buffer
  *	@old: buffer to insert before
@@ -1479,7 +1483,6 @@
 	spin_unlock_irqrestore(&list->lock, flags);
 }
 
-#if 0
 /*
  * 	Tune the memory allocator for a new MTU size.
  */
@@ -1490,7 +1493,8 @@
 
 	kmem_add_cache_size(mtu);
 }
-#endif
+
+#endif  /*  0  */
 
 static inline void skb_split_inside_header(struct sk_buff *skb,
 					   struct sk_buff* skb1,
@@ -1580,8 +1584,8 @@
  * Initializes the specified state variable. Must be called before
  * invoking skb_seq_read() for the first time.
  */
-void skb_prepare_seq_read(struct sk_buff *skb, unsigned int from,
-			  unsigned int to, struct skb_seq_state *st)
+static void skb_prepare_seq_read(struct sk_buff *skb, unsigned int from,
+				 unsigned int to, struct skb_seq_state *st)
 {
 	st->lower_offset = from;
 	st->upper_offset = to;
@@ -1615,8 +1619,8 @@
  *       at the moment, state->root_skb could be replaced with
  *       a stack for this purpose.
  */
-unsigned int skb_seq_read(unsigned int consumed, const u8 **data,
-			  struct skb_seq_state *st)
+static unsigned int skb_seq_read(unsigned int consumed, const u8 **data,
+				 struct skb_seq_state *st)
 {
 	unsigned int block_limit, abs_offset = consumed + st->lower_offset;
 	skb_frag_t *frag;
@@ -1678,7 +1682,7 @@
  * Must be called if skb_seq_read() was not called until it
  * returned 0.
  */
-void skb_abort_seq_read(struct skb_seq_state *st)
+static void skb_abort_seq_read(struct skb_seq_state *st)
 {
 	if (st->frag_data)
 		kunmap_skb_frag(st->frag_data);
@@ -1847,7 +1851,6 @@
 EXPORT_SYMBOL(pskb_expand_head);
 EXPORT_SYMBOL(skb_checksum);
 EXPORT_SYMBOL(skb_clone);
-EXPORT_SYMBOL(skb_clone_fraglist);
 EXPORT_SYMBOL(skb_copy);
 EXPORT_SYMBOL(skb_copy_and_csum_bits);
 EXPORT_SYMBOL(skb_copy_and_csum_dev);
@@ -1859,15 +1862,10 @@
 EXPORT_SYMBOL(skb_under_panic);
 EXPORT_SYMBOL(skb_dequeue);
 EXPORT_SYMBOL(skb_dequeue_tail);
-EXPORT_SYMBOL(skb_insert);
 EXPORT_SYMBOL(skb_queue_purge);
 EXPORT_SYMBOL(skb_queue_head);
 EXPORT_SYMBOL(skb_queue_tail);
 EXPORT_SYMBOL(skb_unlink);
 EXPORT_SYMBOL(skb_append);
-EXPORT_SYMBOL(skb_split);
-EXPORT_SYMBOL(skb_prepare_seq_read);
-EXPORT_SYMBOL(skb_seq_read);
-EXPORT_SYMBOL(skb_abort_seq_read);
 EXPORT_SYMBOL(skb_find_text);
 EXPORT_SYMBOL(skb_append_datato_frags);
--- linux-2.6.17-rc1-mm2-full/net/core/sock.c.old	2006-04-13 11:26:25.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/net/core/sock.c	2006-04-13 11:26:34.000000000 +0200
@@ -885,8 +885,6 @@
 	return newsk;
 }
 
-EXPORT_SYMBOL_GPL(sk_clone);
-
 void __init sk_init(void)
 {
 	if (num_physpages <= 4096) {
--- linux-2.6.17-rc1-mm2-full/net/core/stream.c.old	2006-04-13 11:27:43.000000000 +0200
+++ linux-2.6.17-rc1-mm2-full/net/core/stream.c	2006-04-13 11:30:30.000000000 +0200
@@ -170,8 +170,6 @@
 	goto out;
 }
 
-EXPORT_SYMBOL(sk_stream_wait_memory);
-
 void sk_stream_rfree(struct sk_buff *skb)
 {
 	struct sock *sk = skb->sk;
@@ -180,8 +178,6 @@
 	sk->sk_forward_alloc += skb->truesize;
 }
 
-EXPORT_SYMBOL(sk_stream_rfree);
-
 int sk_stream_error(struct sock *sk, int flags, int err)
 {
 	if (err == -EPIPE)
@@ -206,8 +202,6 @@
 	}
 }
 
-EXPORT_SYMBOL(__sk_stream_mem_reclaim);
-
 int sk_stream_mem_schedule(struct sock *sk, int size, int kind)
 {
 	int amt = sk_stream_pages(size);
@@ -266,8 +260,6 @@
 	return 0;
 }
 
-EXPORT_SYMBOL(sk_stream_mem_schedule);
-
 void sk_stream_kill_queues(struct sock *sk)
 {
 	/* First the read buffer. */
@@ -291,4 +283,3 @@
 	 */
 }
 
-EXPORT_SYMBOL(sk_stream_kill_queues);


^ permalink raw reply

* Re: [PATCH] deinline a few large functions in vlan code v2
From: Ingo Oeser @ 2006-04-13 11:32 UTC (permalink / raw)
  To: Dave Dillow
  Cc: Denis Vlasenko, netdev, David S. Miller, linux-kernel, jgarzik
In-Reply-To: <1144862325.18319.32.camel@dillow.idleaire.com>

Hi Dave,

On Wednesday, 12. April 2006 19:18, Dave Dillow wrote:
> you've left the spin_locks in, and have more #ifdefs.

Ok, I can refactor your driver to even remove this and reduce it to exaxtly 
two ifdef sections for your driver. Acceptable?
 
> Regardless, I remain opposed to this particular instance of bloat 
> busting. While both patches have improved in style, they remove a useful 
> feature and make the code less clean, for no net gain.

s/useful feature/unreachable code/g

> On SMP FC4, typhoon.ko has a text size of 68330, so you need to cut 2794 
> bytes to see an actual difference in memory usage for a module. Non-SMP 
> it is 67741, so there you only need to cut 2205 bytes to get a win.

   text    data     bss     dec     hex filename
  62079     973       4   63056    f650 no-vlan/drivers/net/typhoon.o
  62654     973       4   63631    f88f vlan/drivers/net/typhoon.o

with allyesconfig (minus CONFIG_INFO) and my patches applied.
So maybe the uninlining is enough. Gain after this is just 575 bytes here.


Regards

Ingo Oeser

^ permalink raw reply

* [patch 5] softmac: report when scanning has finished
From: Johannes Berg @ 2006-04-13  9:41 UTC (permalink / raw)
  To: netdev; +Cc: John W. Linville, softmac-dev, Dan Williams
In-Reply-To: <20060411085805.949313000@sipsolutions.net>

[-- Attachment #1: Type: text/plain, Size: 1252 bytes --]

Make softmac report a scan event when scanning has finished, that way
userspace can wait for the event to happen instead of polling for the
results.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

---
This patch depends on the previous patch 4. If you want, I can resend
the whole series with proper patch x/5 headers etc. I don't know if
these can still go in before .17, but it'd be very good if they could,
they're essentially bug fixes for things I either didn't know or just
plain bugs :)

Index: wireless-2.6/net/ieee80211/softmac/ieee80211softmac_event.c
===================================================================
--- wireless-2.6.orig/net/ieee80211/softmac/ieee80211softmac_event.c	2006-04-13 02:42:59.000000000 +0200
+++ wireless-2.6/net/ieee80211/softmac/ieee80211softmac_event.c	2006-04-13 11:30:59.896998787 +0200
@@ -152,6 +152,12 @@
 			wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 			we_event = SIOCGIWAP;
 			break;
+		case IEEE80211SOFTMAC_EVENT_SCAN_FINISHED:
+			wrqu.data.length = 0;
+			wrqu.data.flags = 0;
+			memset(&wrqu, '\0', sizeof (union iwreq_data));
+			we_event = SIOCGIWSCAN;
+			break;
 		default:
 			msg = event_descriptions[event];
 			wrqu.data.length = strlen(msg);


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply

* [PATCH] Repost : Convert cassini to pci_iomap
From: Marc Zyngier @ 2006-04-13  9:38 UTC (permalink / raw)
  To: netdev; +Cc: Jeff Garzik

Folks,

This patch (against 2.6.17-rc1) converts the cassini driver to the
pci_iomap API that will do the right thing, so architectures like
PARISC can stop screaming about illegal usage of ioremap() on
non-cacheable regions.

Tested on 64bit PARISC kernel.

Signed-off-by: Marc Zyngier <maz@misterjones.org>

diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index ac48f75..39f36aa 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -4877,7 +4877,7 @@ static int __devinit cas_init_one(struct
 				  const struct pci_device_id *ent)
 {
 	static int cas_version_printed = 0;
-	unsigned long casreg_base, casreg_len;
+	unsigned long casreg_len;
 	struct net_device *dev;
 	struct cas *cp;
 	int i, err, pci_using_dac;
@@ -4972,7 +4972,6 @@ static int __devinit cas_init_one(struct
 		pci_using_dac = 0;
 	}
 
-	casreg_base = pci_resource_start(pdev, 0);
 	casreg_len = pci_resource_len(pdev, 0);
 
 	cp = netdev_priv(dev);
@@ -5024,7 +5023,7 @@ static int __devinit cas_init_one(struct
 	cp->timer_ticks = 0;
 
 	/* give us access to cassini registers */
-	cp->regs = ioremap(casreg_base, casreg_len);
+	cp->regs = pci_iomap(pdev, 0, casreg_len);
 	if (cp->regs == 0UL) {
 		printk(KERN_ERR PFX "Cannot map device registers, "
 		       "aborting.\n");
@@ -5123,7 +5122,7 @@ err_out_iounmap:
 		cas_shutdown(cp);
 	mutex_unlock(&cp->pm_mutex);
 
-	iounmap(cp->regs);
+	pci_iounmap(pdev, cp->regs);
 
 
 err_out_free_res:
@@ -5171,7 +5170,7 @@ static void __devexit cas_remove_one(str
 #endif
 	pci_free_consistent(pdev, sizeof(struct cas_init_block),
 			    cp->init_block, cp->block_dvma);
-	iounmap(cp->regs);
+	pci_iounmap(pdev, cp->regs);
 	free_netdev(dev);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);

-- 
And if you don't know where you're going, any road will take you there...

^ permalink raw reply related

* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Johannes Berg @ 2006-04-13  9:34 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: Jean Tourrilhes, netdev, softmac-dev
In-Reply-To: <1144919176.4187.44.camel@localhost>

[-- Attachment #1: Type: text/plain, Size: 720 bytes --]

On Thu, 2006-04-13 at 11:06 +0200, Johannes Berg wrote:

> > It's very likely that tools do indeed loop when they see EAGAIN, but
> > this is a workaround, not the main mode of operation. It seems obvious
> > to me that the get method should wait until the scan results are
> > available. Perhaps the discussion had a specific scenario where
> > EAGAIN would make sense, but I cannot imagine what it might be.
> 
> Right, they do loop, but they don't have a method to indicate
> completion. Thus we'd have to actually wait for the completion in the
> kernel. Jean, what is the intended use here?

Hah, never mind, I guess we're just supposed to send SIOCGIWSCAN. Will
send a patch in a minute.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply

* [PATCH 18/18] ipw2200: Fix wpa_supplicant association problem
From: Zhu Yi @ 2006-04-13  9:21 UTC (permalink / raw)
  To: netdev, John W. Linville

The new ipw2200 scan completion event feature will cause a potential event
race condition in wpa_supplicant. The patch fixes this problem by move the
ipw_disassociate() to the IW_AUTH_WPA_ENABLED event handling code.

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

ea463b8df2999bc2814935df49aec5be42ad9912
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 1bccf7a..8da5b23 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -6346,8 +6346,6 @@ static void ipw_wpa_assoc_frame(struct i
 {
 	/* make sure WPA is enabled */
 	ipw_wpa_enable(priv, 1);
-
-	ipw_disassociate(priv);
 }
 
 static int ipw_set_rsn_capa(struct ipw_priv *priv,
@@ -6541,6 +6539,7 @@ static int ipw_wx_set_auth(struct net_de
 
 	case IW_AUTH_WPA_ENABLED:
 		ret = ipw_wpa_enable(priv, param->value);
+		ipw_disassociate(priv);
 		break;
 
 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-- 
1.2.6


^ permalink raw reply related

* [PATCH 17/18] ipw2200: remove priv->last_noise reference
From: Zhu Yi @ 2006-04-13  9:21 UTC (permalink / raw)
  To: netdev, John W. Linville

priv->last_noise is not used with the exponential averaging algorithm

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

56992321cbe73f5dbdf93464d6cbe75b83a1e37d
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 62ebec8..7825655 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -7793,9 +7793,6 @@ static void ipw_handle_promiscuous_rx(st
 	if (filter & IPW_PROM_NO_RX)
 		return;
 
-	if (!noise)
-		noise = priv->last_noise;
-
 	/* We received data from the HW, so stop the watchdog */
 	priv->prom_net_dev->trans_start = jiffies;
 
-- 
1.2.6


^ permalink raw reply related

* [PATCH 16/18] ipw2200: rename CONFIG_IEEE80211_RADIOTAP to CONFIG_IPW2200_RADIOTAP
From: Zhu Yi @ 2006-04-13  9:21 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |   12 ++++++------
 drivers/net/wireless/ipw2200.h |    2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

70646d6a1c055a3bbd5b29f471ca49d43c534267
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 426f306..62ebec8 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -58,7 +58,7 @@
 #define VP
 #endif
 
-#ifdef CONFIG_IEEE80211_RADIOTAP
+#ifdef CONFIG_IPW2200_RADIOTAP
 #define VR "r"
 #else
 #define VR
@@ -7586,7 +7586,7 @@ static void ipw_handle_data_packet(struc
 	}
 }
 
-#ifdef CONFIG_IEEE80211_RADIOTAP
+#ifdef CONFIG_IPW2200_RADIOTAP
 static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
 					   struct ipw_rx_mem_buffer *rxb,
 					   struct ieee80211_rx_stats *stats)
@@ -8194,7 +8194,7 @@ static void ipw_rx(struct ipw_priv *priv
 
 #ifdef CONFIG_IPW2200_MONITOR
 				if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
-#ifdef CONFIG_IEEE80211_RADIOTAP
+#ifdef CONFIG_IPW2200_RADIOTAP
 
                 ipw_handle_data_packet_monitor(priv,
 					       rxb,
@@ -8381,7 +8381,7 @@ static int ipw_sw_reset(struct ipw_priv 
 #ifdef CONFIG_IPW2200_MONITOR
 	case 2:
 		priv->ieee->iw_mode = IW_MODE_MONITOR;
-#ifdef CONFIG_IEEE80211_RADIOTAP
+#ifdef CONFIG_IPW2200_RADIOTAP
 		priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
 #else
 		priv->net_dev->type = ARPHRD_IEEE80211;
@@ -8636,7 +8636,7 @@ static int ipw_wx_set_mode(struct net_de
 		priv->net_dev->type = ARPHRD_ETHER;
 
 	if (wrqu->mode == IW_MODE_MONITOR)
-#ifdef CONFIG_IEEE80211_RADIOTAP
+#ifdef CONFIG_IPW2200_RADIOTAP
 		priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
 #else
 		priv->net_dev->type = ARPHRD_IEEE80211;
@@ -9738,7 +9738,7 @@ static int ipw_wx_set_monitor(struct net
 	IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
 	if (enable) {
 		if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
-#ifdef CONFIG_IEEE80211_RADIOTAP
+#ifdef CONFIG_IPW2200_RADIOTAP
 			priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
 #else
 			priv->net_dev->type = ARPHRD_IEEE80211;
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 14fe79a..6044c0b 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1146,7 +1146,7 @@ struct ipw_prom_priv {
 };
 #endif
 
-#if defined(CONFIG_IEEE80211_RADIOTAP) || defined(CONFIG_IPW2200_PROMISCUOUS)
+#if defined(CONFIG_IPW2200_RADIOTAP) || defined(CONFIG_IPW2200_PROMISCUOUS)
 /* Magic struct that slots into the radiotap header -- no reason
  * to build this manually element by element, we can write it much
  * more efficiently than we can parse it. ORDER MATTERS HERE
-- 
1.2.6


^ permalink raw reply related

* [PATCH 15/18] wireless Kconfig add IPW2200_RADIOTAP
From: Zhu Yi @ 2006-04-13  9:20 UTC (permalink / raw)
  To: netdev, John W. Linville

Makefile both IPW2200_RADIOTAP and IPW2200_PROMISCUOUS depend on
IPW2200_MONITOR. Let IPW2200_PROMISCUOUS select IPW2200_RADIOTAP.

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/Kconfig |   52 +++++++++++++++++++++++-------------------
 1 files changed, 28 insertions(+), 24 deletions(-)

d2baa760aa4ba72495da0ada29f877470f687de3
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 073b4a3..2da2833 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -235,6 +235,34 @@ config IPW2200_MONITOR
 	  promiscuous mode via the Wireless Tool's Monitor mode.  While in this
 	  mode, no packets can be sent.
 
+config IPW2200_RADIOTAP
+	bool "Enable radiotap format 802.11 raw packet support"
+	depends on IPW2200_MONITOR
+
+config IPW2200_PROMISCUOUS
+	bool "Enable creation of a RF radiotap promiscuous interface"
+	depends on IPW2200_MONITOR
+	select IPW2200_RADIOTAP
+	---help---
+          Enables the creation of a second interface prefixed 'rtap'. 
+          This second interface will provide every received in radiotap
+	  format.
+
+          This is useful for performing wireless network analysis while
+          maintaining an active association.
+
+          Example usage:
+
+            % modprobe ipw2200 rtap_iface=1
+            % ifconfig rtap0 up
+            % tethereal -i rtap0
+
+          If you do not specify 'rtap_iface=1' as a module parameter then 
+          the rtap interface will not be created and you will need to turn 
+          it on via sysfs:
+	
+            % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
+
 config IPW2200_QOS
         bool "Enable QoS support"
         depends on IPW2200 && EXPERIMENTAL
@@ -263,30 +291,6 @@ config IPW2200_DEBUG
 	  If you are not trying to debug or develop the IPW2200 driver, you 
 	  most likely want to say N here.
 
-config IPW2200_PROMISCUOUS
-	bool "Enable creation of a RF radiotap promiscuous interface."
-	depends on IPW2200
-	select IEEE80211_RADIOTAP
-	---help---
-          Enables the creation of a second interface prefixed 'rtap'. 
-          This second interface will provide every received in radiotap
-	  format.
-
-          This is useful for performing wireless network analysis while
-          maintaining an active association.
-
-          Example usage:
-
-            % modprobe ipw2200 rtap_iface=1
-            % ifconfig rtap0 up
-            % tethereal -i rtap0
-
-          If you do not specify 'rtap_iface=1' as a module parameter then 
-          the rtap interface will not be created and you will need to turn 
-          it on via sysfs:
-	
-            % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
-
 config AIRO
 	tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
  	depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN)
-- 
1.2.6


^ permalink raw reply related

* [PATCH 14/18] ipw2200: rename CONFIG_IPW_QOS to CONFIG_IPW2200_QOS
From: Zhu Yi @ 2006-04-13  9:20 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/Kconfig   |    2 +-
 drivers/net/wireless/ipw2200.c |   42 ++++++++++++++++++++--------------------
 2 files changed, 22 insertions(+), 22 deletions(-)

b483305435de6baed1194ddaff5b437e0810a4c1
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 5cd9c16..073b4a3 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -235,7 +235,7 @@ config IPW2200_MONITOR
 	  promiscuous mode via the Wireless Tool's Monitor mode.  While in this
 	  mode, no packets can be sent.
 
-config IPW_QOS
+config IPW2200_QOS
         bool "Enable QoS support"
         depends on IPW2200 && EXPERIMENTAL
 
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 67e4150..426f306 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -107,7 +107,7 @@ static int rtap_iface = 0;     /* def: 0
 #endif
 
 
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 static int qos_enable = 0;
 static int qos_burst_enable = 0;
 static int qos_no_ack_mask = 0;
@@ -171,7 +171,7 @@ static int ipw_send_qos_params_command(s
 				       *qos_param);
 static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
 				     *qos_param);
-#endif				/* CONFIG_IPW_QOS */
+#endif				/* CONFIG_IPW2200_QOS */
 
 static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);
 static void ipw_remove_current_network(struct ipw_priv *priv);
@@ -4342,7 +4342,7 @@ static void ipw_rx_notification(struct i
 					queue_work(priv->workqueue,
 						   &priv->system_config);
 
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 #define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
 			 le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_ctl))
 					if ((priv->status & STATUS_AUTH) &&
@@ -6682,7 +6682,7 @@ static int ipw_wx_set_mlme(struct net_de
 	return 0;
 }
 
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 
 /* QoS */
 /*
@@ -7148,7 +7148,7 @@ static int ipw_send_qos_info_command(str
 				qos_param);
 }
 
-#endif				/* CONFIG_IPW_QOS */
+#endif				/* CONFIG_IPW2200_QOS */
 
 static int ipw_associate_network(struct ipw_priv *priv,
 				 struct ieee80211_network *network,
@@ -7312,7 +7312,7 @@ static int ipw_associate_network(struct 
 
 	priv->assoc_network = network;
 
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 	ipw_qos_association(priv, network);
 #endif
 
@@ -8367,10 +8367,10 @@ static int ipw_sw_reset(struct ipw_priv 
 		IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
 		/* TODO: Validate that provided channel is in range */
 	}
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 	ipw_qos_init(priv, qos_enable, qos_burst_enable,
 		     burst_duration_CCK, burst_duration_OFDM);
-#endif				/* CONFIG_IPW_QOS */
+#endif				/* CONFIG_IPW2200_QOS */
 
 	switch (mode) {
 	case 1:
@@ -10040,7 +10040,7 @@ static int ipw_tx_skb(struct ipw_priv *p
 	    txb->fragments[0]->data;
 	int i = 0;
 	struct tfd_frame *tfd;
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 	int tx_id = ipw_get_tx_queue_number(priv, pri);
 	struct clx2_tx_queue *txq = &priv->txq[tx_id];
 #else
@@ -10147,10 +10147,10 @@ static int ipw_tx_skb(struct ipw_priv *p
 		/* No hardware encryption */
 		tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;
 
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 	if (fc & IEEE80211_STYPE_QOS_DATA)
 		ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data));
-#endif				/* CONFIG_IPW_QOS */
+#endif				/* CONFIG_IPW2200_QOS */
 
 	/* payload */
 	tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
@@ -10230,12 +10230,12 @@ static int ipw_tx_skb(struct ipw_priv *p
 static int ipw_net_is_queue_full(struct net_device *dev, int pri)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 	int tx_id = ipw_get_tx_queue_number(priv, pri);
 	struct clx2_tx_queue *txq = &priv->txq[tx_id];
 #else
 	struct clx2_tx_queue *txq = &priv->txq[0];
-#endif				/* CONFIG_IPW_QOS */
+#endif				/* CONFIG_IPW2200_QOS */
 
 	if (ipw_queue_space(&txq->q) < txq->q.high_mark)
 		return 1;
@@ -10645,10 +10645,10 @@ static int ipw_setup_deferred_work(struc
 	INIT_WORK(&priv->merge_networks,
 		  (void (*)(void *))ipw_merge_adhoc_network, priv);
 
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 	INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate,
 		  priv);
-#endif				/* CONFIG_IPW_QOS */
+#endif				/* CONFIG_IPW2200_QOS */
 
 	tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
 		     ipw_irq_tasklet, (unsigned long)priv);
@@ -10820,10 +10820,10 @@ static int ipw_config(struct ipw_priv *p
 		if (ipw_send_rts_threshold(priv, priv->rts_threshold))
 			goto error;
 	}
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 	IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");
 	ipw_qos_activate(priv, NULL);
-#endif				/* CONFIG_IPW_QOS */
+#endif				/* CONFIG_IPW2200_QOS */
 
 	if (ipw_set_random_seed(priv))
 		goto error;
@@ -11552,12 +11552,12 @@ static int ipw_pci_probe(struct pci_dev 
 	priv->ieee->set_security = shim__set_security;
 	priv->ieee->is_queue_full = ipw_net_is_queue_full;
 
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 	priv->ieee->is_qos_active = ipw_is_qos_active;
 	priv->ieee->handle_probe_response = ipw_handle_beacon;
 	priv->ieee->handle_beacon = ipw_handle_probe_response;
 	priv->ieee->handle_assoc_response = ipw_handle_assoc_response;
-#endif				/* CONFIG_IPW_QOS */
+#endif				/* CONFIG_IPW2200_QOS */
 
 	priv->ieee->perfect_rssi = -20;
 	priv->ieee->worst_rssi = -85;
@@ -11815,7 +11815,7 @@ module_param(rtap_iface, int, 0444);
 MODULE_PARM_DESC(rtap_iface, "create the rtap interface (1 - create, default 0)");
 #endif
 
-#ifdef CONFIG_IPW_QOS
+#ifdef CONFIG_IPW2200_QOS
 module_param(qos_enable, int, 0444);
 MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
 
@@ -11830,7 +11830,7 @@ MODULE_PARM_DESC(burst_duration_CCK, "se
 
 module_param(burst_duration_OFDM, int, 0444);
 MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
-#endif				/* CONFIG_IPW_QOS */
+#endif				/* CONFIG_IPW2200_QOS */
 
 #ifdef CONFIG_IPW2200_MONITOR
 module_param(mode, int, 0444);
-- 
1.2.6


^ permalink raw reply related

* [PATCH 13/18] ipw2200: update version stamp to 1.1.2
From: Zhu Yi @ 2006-04-13  9:20 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 Documentation/networking/README.ipw2200 |    6 +++---
 drivers/net/wireless/ipw2200.c          |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

dd0f5de1aff491fb0358b7eaf7d22e907fa1e5ee
diff --git a/Documentation/networking/README.ipw2200 b/Documentation/networking/README.ipw2200
index c3504f5..4f2a40f 100644
--- a/Documentation/networking/README.ipw2200
+++ b/Documentation/networking/README.ipw2200
@@ -14,8 +14,8 @@ Copyright (C) 2004-2006, Intel Corporati
 
 README.ipw2200
 
-Version: 1.0.8
-Date   : October 20, 2005
+Version: 1.1.2
+Date   : March 30, 2006
 
 
 Index
@@ -103,7 +103,7 @@ file.
 
 1.1. Overview of Features
 -----------------------------------------------
-The current release (1.0.8) supports the following features:
+The current release (1.1.2) supports the following features:
 
 + BSS mode (Infrastructure, Managed)
 + IBSS mode (Ad-Hoc)
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 8b20d6c..67e4150 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -70,7 +70,7 @@
 #define VQ
 #endif
 
-#define IPW2200_VERSION "1.1.1" VK VD VM VP VR VQ
+#define IPW2200_VERSION "1.1.2" VK VD VM VP VR VQ
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2006 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
-- 
1.2.6


^ permalink raw reply related

* [PATCH 12/18] ipw2200: version string rework
From: Zhu Yi @ 2006-04-13  9:20 UTC (permalink / raw)
  To: netdev, John W. Linville

Added version string fields so the version string indicates what is
configured (ie, you'll see 1.1.1kpmd if you are using a GIT snapshot
(Kernel.. previously -git), promiscuous (p), monitor (m), debug (d) build.

Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |   39 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 38 insertions(+), 1 deletions(-)

c6f5917d6d8a5a5c44d1386a5ca52b1670ba09cb
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index bbf17f6..8b20d6c 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -33,7 +33,44 @@
 #include "ipw2200.h"
 #include <linux/version.h>
 
-#define IPW2200_VERSION "git-1.1.1"
+
+#ifndef KBUILD_EXTMOD
+#define VK "k"
+#else
+#define VK
+#endif
+
+#ifdef CONFIG_IPW2200_DEBUG
+#define VD "d"
+#else
+#define VD
+#endif
+
+#ifdef CONFIG_IPW2200_MONITOR
+#define VM "m"
+#else
+#define VM
+#endif
+
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+#define VP "p"
+#else
+#define VP
+#endif
+
+#ifdef CONFIG_IEEE80211_RADIOTAP
+#define VR "r"
+#else
+#define VR
+#endif
+
+#ifdef CONFIG_IPW2200_QOS
+#define VQ "q"
+#else
+#define VQ
+#endif
+
+#define IPW2200_VERSION "1.1.1" VK VD VM VP VR VQ
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2006 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
-- 
1.2.6


^ permalink raw reply related

* [PATCH 11/18] ipw2200: Enable rtap interface for RF promiscuous mode while associated
From: Zhu Yi @ 2006-04-13  9:20 UTC (permalink / raw)
  To: netdev, John W. Linville

With this patch, a new promiscuous mode is enabled. If the module is loaded
with the rtap_iface=1 module parameter, two interfaces will be created
(instead of just one).

The second interface is prefixed 'rtap' and provides received 802.11 frames
on the current channel to user space in a radiotap header format.

Example usage:

        % modprobe ipw2200 rtap_iface=1
        % iwconfig eth1 essid MyNetwork
        % dhcpcd eth1
        % tcpdump -i rtap0

If you do not specify 'rtap_iface=1' then the rtap interface will
not be created and you will need to turn it on via:

        % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface

You can filter out what type of information is passed to user space via
the rtap_filter sysfs entry.  Currently you can tell the driver to
transmit just the headers (which will provide the RADIOTAP and IEEE
802.11 header but not the payload), to filter based on frame control
type (Management, Control, or Data), and whether to report transmitted
frames, received frames, or both.

The transmit frame reporting is based on a patch by Stefan Rompf.

Filters can be get and set via a sysfs interface. For example, set the
filter to only send headers (0x7), don't report Tx'd frames (0x10), and
don't report data frames (0x100):

        % echo 0x117 > /sys/bus/pci/drivers/ipw2200/*/rtap_filter

All your packets are belong to us:

        % tethereal -n -i rtap0

Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/Kconfig   |   24 ++
 drivers/net/wireless/ipw2200.c |  599 ++++++++++++++++++++++++++++++++++++++--
 drivers/net/wireless/ipw2200.h |   77 +++++
 3 files changed, 673 insertions(+), 27 deletions(-)

02631c88b57c16ae4989d17ae4ca5babb4b3501a
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index e5ea89e..5cd9c16 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -263,6 +263,30 @@ config IPW2200_DEBUG
 	  If you are not trying to debug or develop the IPW2200 driver, you 
 	  most likely want to say N here.
 
+config IPW2200_PROMISCUOUS
+	bool "Enable creation of a RF radiotap promiscuous interface."
+	depends on IPW2200
+	select IEEE80211_RADIOTAP
+	---help---
+          Enables the creation of a second interface prefixed 'rtap'. 
+          This second interface will provide every received in radiotap
+	  format.
+
+          This is useful for performing wireless network analysis while
+          maintaining an active association.
+
+          Example usage:
+
+            % modprobe ipw2200 rtap_iface=1
+            % ifconfig rtap0 up
+            % tethereal -i rtap0
+
+          If you do not specify 'rtap_iface=1' as a module parameter then 
+          the rtap interface will not be created and you will need to turn 
+          it on via sysfs:
+	
+            % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
+
 config AIRO
 	tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
  	depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN)
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 7646def..bbf17f6 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -65,6 +65,11 @@ static const char ipw_modes[] = {
 };
 static int antenna = CFG_SYS_ANTENNA_BOTH;
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+static int rtap_iface = 0;     /* def: 0 -- do not create rtap interface */
+#endif
+
+
 #ifdef CONFIG_IPW_QOS
 static int qos_enable = 0;
 static int qos_burst_enable = 0;
@@ -1272,6 +1277,105 @@ static ssize_t show_cmd_log(struct devic
 
 static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+static void ipw_prom_free(struct ipw_priv *priv);
+static int ipw_prom_alloc(struct ipw_priv *priv);
+static ssize_t store_rtap_iface(struct device *d,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+	int rc = 0;
+
+	if (count < 1)
+		return -EINVAL;
+
+	switch (buf[0]) {
+	case '0':
+		if (!rtap_iface)
+			return count;
+
+		if (netif_running(priv->prom_net_dev)) {
+			IPW_WARNING("Interface is up.  Cannot unregister.\n");
+			return count;
+		}
+
+		ipw_prom_free(priv);
+		rtap_iface = 0;
+		break;
+
+	case '1':
+		if (rtap_iface)
+			return count;
+
+		rc = ipw_prom_alloc(priv);
+		if (!rc)
+			rtap_iface = 1;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if (rc) {
+		IPW_ERROR("Failed to register promiscuous network "
+			  "device (error %d).\n", rc);
+	}
+
+	return count;
+}
+
+static ssize_t show_rtap_iface(struct device *d,
+			struct device_attribute *attr,
+			char *buf)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+	if (rtap_iface)
+		return sprintf(buf, "%s", priv->prom_net_dev->name);
+	else {
+		buf[0] = '-';
+		buf[1] = '1';
+		buf[2] = '\0';
+		return 3;
+	}
+}
+
+static DEVICE_ATTR(rtap_iface, S_IWUSR | S_IRUSR, show_rtap_iface,
+		   store_rtap_iface);
+
+static ssize_t store_rtap_filter(struct device *d,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+
+	if (!priv->prom_priv) {
+		IPW_ERROR("Attempting to set filter without "
+			  "rtap_iface enabled.\n");
+		return -EPERM;
+	}
+
+	priv->prom_priv->filter = simple_strtol(buf, NULL, 0);
+
+	IPW_DEBUG_INFO("Setting rtap filter to " BIT_FMT16 "\n",
+		       BIT_ARG16(priv->prom_priv->filter));
+
+	return count;
+}
+
+static ssize_t show_rtap_filter(struct device *d,
+			struct device_attribute *attr,
+			char *buf)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+	return sprintf(buf, "0x%04X",
+		       priv->prom_priv ? priv->prom_priv->filter : 0);
+}
+
+static DEVICE_ATTR(rtap_filter, S_IWUSR | S_IRUSR, show_rtap_filter,
+		   store_rtap_filter);
+#endif
+
 static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
 			     char *buf)
 {
@@ -2028,16 +2132,11 @@ static int ipw_send_host_complete(struct
 	return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE);
 }
 
-static int ipw_send_system_config(struct ipw_priv *priv,
-				  struct ipw_sys_config *config)
+static int ipw_send_system_config(struct ipw_priv *priv)
 {
-	if (!priv || !config) {
-		IPW_ERROR("Invalid args\n");
-		return -1;
-	}
-
-	return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG, sizeof(*config),
-				config);
+	return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG,
+				sizeof(priv->sys_config),
+				&priv->sys_config);
 }
 
 static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
@@ -3704,7 +3803,17 @@ static void ipw_bg_disassociate(void *da
 static void ipw_system_config(void *data)
 {
 	struct ipw_priv *priv = data;
-	ipw_send_system_config(priv, &priv->sys_config);
+
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+	if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
+		priv->sys_config.accept_all_data_frames = 1;
+		priv->sys_config.accept_non_directed_frames = 1;
+		priv->sys_config.accept_all_mgmt_bcpr = 1;
+		priv->sys_config.accept_all_mgmt_frames = 1;
+	}
+#endif
+
+	ipw_send_system_config(priv);
 }
 
 struct ipw_status_code {
@@ -7141,7 +7250,7 @@ static int ipw_associate_network(struct 
 	else
 		priv->sys_config.answer_broadcast_ssid_probe = 0;
 
-	err = ipw_send_system_config(priv, &priv->sys_config);
+	err = ipw_send_system_config(priv);
 	if (err) {
 		IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
 		return err;
@@ -7457,15 +7566,7 @@ static void ipw_handle_data_packet_monit
 	/* Magic struct that slots into the radiotap header -- no reason
 	 * to build this manually element by element, we can write it much
 	 * more efficiently than we can parse it. ORDER MATTERS HERE */
-	struct ipw_rt_hdr {
-		struct ieee80211_radiotap_header rt_hdr;
-		u8 rt_flags;	/* radiotap packet flags */
-		u8 rt_rate;	/* rate in 500kb/s */
-		u16 rt_channel;	/* channel in mhz */
-		u16 rt_chbitmask;	/* channel bitfield */
-		s8 rt_dbmsignal;	/* signal in dbM, kluged to signed */
-		u8 rt_antenna;	/* antenna number */
-	} *ipw_rt;
+	struct ipw_rt_hdr *ipw_rt;
 
 	short len = le16_to_cpu(pkt->u.frame.length);
 
@@ -7519,9 +7620,11 @@ static void ipw_handle_data_packet_monit
 	/* Big bitfield of all the fields we provide in radiotap */
 	ipw_rt->rt_hdr.it_present =
 	    ((1 << IEEE80211_RADIOTAP_FLAGS) |
+	     (1 << IEEE80211_RADIOTAP_TSFT) |
 	     (1 << IEEE80211_RADIOTAP_RATE) |
 	     (1 << IEEE80211_RADIOTAP_CHANNEL) |
 	     (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
+	     (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
 	     (1 << IEEE80211_RADIOTAP_ANTENNA));
 
 	/* Zero the flags, we'll add to them as we go */
@@ -7607,6 +7710,220 @@ static void ipw_handle_data_packet_monit
 }
 #endif
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+#define ieee80211_is_probe_response(fc) \
+   ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && \
+    (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP )
+
+#define ieee80211_is_management(fc) \
+   ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
+
+#define ieee80211_is_control(fc) \
+   ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL)
+
+#define ieee80211_is_data(fc) \
+   ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
+
+#define ieee80211_is_assoc_request(fc) \
+   ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ)
+
+#define ieee80211_is_reassoc_request(fc) \
+   ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
+
+static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
+				      struct ipw_rx_mem_buffer *rxb,
+				      struct ieee80211_rx_stats *stats)
+{
+	struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
+	struct ipw_rx_frame *frame = &pkt->u.frame;
+	struct ipw_rt_hdr *ipw_rt;
+
+	/* First cache any information we need before we overwrite
+	 * the information provided in the skb from the hardware */
+	struct ieee80211_hdr *hdr;
+	u16 channel = frame->received_channel;
+	u8 phy_flags = frame->antennaAndPhy;
+	s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM;
+	s8 noise = frame->noise;
+	u8 rate = frame->rate;
+	short len = le16_to_cpu(pkt->u.frame.length);
+	u64 tsf = 0;
+	struct sk_buff *skb;
+	int hdr_only = 0;
+	u16 filter = priv->prom_priv->filter;
+
+	/* If the filter is set to not include Rx frames then return */
+	if (filter & IPW_PROM_NO_RX)
+		return;
+
+	if (!noise)
+		noise = priv->last_noise;
+
+	/* We received data from the HW, so stop the watchdog */
+	priv->prom_net_dev->trans_start = jiffies;
+
+	if (unlikely((len + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
+		priv->prom_priv->ieee->stats.rx_errors++;
+		IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
+		return;
+	}
+
+	/* We only process data packets if the interface is open */
+	if (unlikely(!netif_running(priv->prom_net_dev))) {
+		priv->prom_priv->ieee->stats.rx_dropped++;
+		IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
+		return;
+	}
+
+	/* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
+	 * that now */
+	if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
+		/* FIXME: Should alloc bigger skb instead */
+		priv->prom_priv->ieee->stats.rx_dropped++;
+		IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
+		return;
+	}
+
+	hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE;
+	if (ieee80211_is_management(hdr->frame_ctl)) {
+		if (filter & IPW_PROM_NO_MGMT)
+			return;
+		if (filter & IPW_PROM_MGMT_HEADER_ONLY)
+			hdr_only = 1;
+	} else if (ieee80211_is_control(hdr->frame_ctl)) {
+		if (filter & IPW_PROM_NO_CTL)
+			return;
+		if (filter & IPW_PROM_CTL_HEADER_ONLY)
+			hdr_only = 1;
+	} else if (ieee80211_is_data(hdr->frame_ctl)) {
+		if (filter & IPW_PROM_NO_DATA)
+			return;
+		if (filter & IPW_PROM_DATA_HEADER_ONLY)
+			hdr_only = 1;
+	}
+
+	/* Copy the SKB since this is for the promiscuous side */
+	skb = skb_copy(rxb->skb, GFP_ATOMIC);
+	if (skb == NULL) {
+		IPW_ERROR("skb_clone failed for promiscuous copy.\n");
+		return;
+	}
+
+	/* copy the frame data to write after where the radiotap header goes */
+	ipw_rt = (void *)skb->data;
+
+	if (hdr_only)
+		len = ieee80211_get_hdrlen(hdr->frame_ctl);
+
+	memcpy(ipw_rt->payload, hdr, len);
+
+	/* Zero the radiotap static buffer  ...  We only need to zero the bytes
+	 * NOT part of our real header, saves a little time.
+	 *
+	 * No longer necessary since we fill in all our data.  Purge before
+	 * merging patch officially.
+	 * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
+	 *        IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
+	 */
+
+	ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+	ipw_rt->rt_hdr.it_pad = 0;	/* always good to zero */
+	ipw_rt->rt_hdr.it_len = sizeof(*ipw_rt);	/* total header+data */
+
+	/* Set the size of the skb to the size of the frame */
+	skb_put(skb, ipw_rt->rt_hdr.it_len + len);
+
+	/* Big bitfield of all the fields we provide in radiotap */
+	ipw_rt->rt_hdr.it_present =
+	    ((1 << IEEE80211_RADIOTAP_FLAGS) |
+	     (1 << IEEE80211_RADIOTAP_TSFT) |
+	     (1 << IEEE80211_RADIOTAP_RATE) |
+	     (1 << IEEE80211_RADIOTAP_CHANNEL) |
+	     (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
+	     (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
+	     (1 << IEEE80211_RADIOTAP_ANTENNA));
+
+	/* Zero the flags, we'll add to them as we go */
+	ipw_rt->rt_flags = 0;
+
+	ipw_rt->rt_tsf = tsf;
+
+	/* Convert to DBM */
+	ipw_rt->rt_dbmsignal = signal;
+	ipw_rt->rt_dbmnoise = noise;
+
+	/* Convert the channel data and set the flags */
+	ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(channel));
+	if (channel > 14) {	/* 802.11a */
+		ipw_rt->rt_chbitmask =
+		    cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
+	} else if (phy_flags & (1 << 5)) {	/* 802.11b */
+		ipw_rt->rt_chbitmask =
+		    cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
+	} else {		/* 802.11g */
+		ipw_rt->rt_chbitmask =
+		    (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
+	}
+
+	/* set the rate in multiples of 500k/s */
+	switch (rate) {
+	case IPW_TX_RATE_1MB:
+		ipw_rt->rt_rate = 2;
+		break;
+	case IPW_TX_RATE_2MB:
+		ipw_rt->rt_rate = 4;
+		break;
+	case IPW_TX_RATE_5MB:
+		ipw_rt->rt_rate = 10;
+		break;
+	case IPW_TX_RATE_6MB:
+		ipw_rt->rt_rate = 12;
+		break;
+	case IPW_TX_RATE_9MB:
+		ipw_rt->rt_rate = 18;
+		break;
+	case IPW_TX_RATE_11MB:
+		ipw_rt->rt_rate = 22;
+		break;
+	case IPW_TX_RATE_12MB:
+		ipw_rt->rt_rate = 24;
+		break;
+	case IPW_TX_RATE_18MB:
+		ipw_rt->rt_rate = 36;
+		break;
+	case IPW_TX_RATE_24MB:
+		ipw_rt->rt_rate = 48;
+		break;
+	case IPW_TX_RATE_36MB:
+		ipw_rt->rt_rate = 72;
+		break;
+	case IPW_TX_RATE_48MB:
+		ipw_rt->rt_rate = 96;
+		break;
+	case IPW_TX_RATE_54MB:
+		ipw_rt->rt_rate = 108;
+		break;
+	default:
+		ipw_rt->rt_rate = 0;
+		break;
+	}
+
+	/* antenna number */
+	ipw_rt->rt_antenna = (phy_flags & 3);
+
+	/* set the preamble flag if we have it */
+	if (phy_flags & (1 << 6))
+		ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+	IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);
+
+	if (!ieee80211_rx(priv->prom_priv->ieee, skb, stats)) {
+		priv->prom_priv->ieee->stats.rx_errors++;
+		dev_kfree_skb_any(skb);
+	}
+}
+#endif
+
 static int is_network_packet(struct ipw_priv *priv,
 				    struct ieee80211_hdr_4addr *header)
 {
@@ -7833,15 +8150,21 @@ static void ipw_rx(struct ipw_priv *priv
 
 				priv->rx_packets++;
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+	if (priv->prom_net_dev && netif_running(priv->prom_net_dev))
+		ipw_handle_promiscuous_rx(priv, rxb, &stats);
+#endif
+
 #ifdef CONFIG_IPW2200_MONITOR
 				if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
 #ifdef CONFIG_IEEE80211_RADIOTAP
-					ipw_handle_data_packet_monitor(priv,
-								       rxb,
-								       &stats);
+
+                ipw_handle_data_packet_monitor(priv,
+					       rxb,
+					       &stats);
 #else
-					ipw_handle_data_packet(priv, rxb,
-							       &stats);
+		ipw_handle_data_packet(priv, rxb,
+				       &stats);
 #endif
 					break;
 				}
@@ -9883,6 +10206,88 @@ static int ipw_net_is_queue_full(struct 
 	return 0;
 }
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
+				      struct ieee80211_txb *txb)
+{
+	struct ieee80211_rx_stats dummystats;
+	struct ieee80211_hdr *hdr;
+	u8 n;
+	u16 filter = priv->prom_priv->filter;
+	int hdr_only = 0;
+
+	if (filter & IPW_PROM_NO_TX)
+		return;
+
+	memset(&dummystats, 0, sizeof(dummystats));
+
+	/* Filtering of fragment chains is done agains the first fragment */
+	hdr = (void *)txb->fragments[0]->data;
+	if (ieee80211_is_management(hdr->frame_ctl)) {
+		if (filter & IPW_PROM_NO_MGMT)
+			return;
+		if (filter & IPW_PROM_MGMT_HEADER_ONLY)
+			hdr_only = 1;
+	} else if (ieee80211_is_control(hdr->frame_ctl)) {
+		if (filter & IPW_PROM_NO_CTL)
+			return;
+		if (filter & IPW_PROM_CTL_HEADER_ONLY)
+			hdr_only = 1;
+	} else if (ieee80211_is_data(hdr->frame_ctl)) {
+		if (filter & IPW_PROM_NO_DATA)
+			return;
+		if (filter & IPW_PROM_DATA_HEADER_ONLY)
+			hdr_only = 1;
+	}
+
+	for(n=0; n<txb->nr_frags; ++n) {
+		struct sk_buff *src = txb->fragments[n];
+		struct sk_buff *dst;
+		struct ieee80211_radiotap_header *rt_hdr;
+		int len;
+
+		if (hdr_only) {
+			hdr = (void *)src->data;
+			len = ieee80211_get_hdrlen(hdr->frame_ctl);
+		} else
+			len = src->len;
+
+		dst = alloc_skb(
+			len + IEEE80211_RADIOTAP_HDRLEN, GFP_ATOMIC);
+		if (!dst) continue;
+
+		rt_hdr = (void *)skb_put(dst, sizeof(*rt_hdr));
+
+		rt_hdr->it_version = PKTHDR_RADIOTAP_VERSION;
+		rt_hdr->it_pad = 0;
+		rt_hdr->it_present = 0; /* after all, it's just an idea */
+		rt_hdr->it_present |=  (1 << IEEE80211_RADIOTAP_CHANNEL);
+
+		*(u16*)skb_put(dst, sizeof(u16)) = cpu_to_le16(
+			ieee80211chan2mhz(priv->channel));
+		if (priv->channel > 14) 	/* 802.11a */
+			*(u16*)skb_put(dst, sizeof(u16)) =
+				cpu_to_le16(IEEE80211_CHAN_OFDM |
+					     IEEE80211_CHAN_5GHZ);
+		else if (priv->ieee->mode == IEEE_B) /* 802.11b */
+			*(u16*)skb_put(dst, sizeof(u16)) =
+				cpu_to_le16(IEEE80211_CHAN_CCK |
+					     IEEE80211_CHAN_2GHZ);
+		else 		/* 802.11g */
+			*(u16*)skb_put(dst, sizeof(u16)) =
+				cpu_to_le16(IEEE80211_CHAN_OFDM |
+				 IEEE80211_CHAN_2GHZ);
+
+		rt_hdr->it_len = dst->len;
+
+		memcpy(skb_put(dst, len), src->data, len);
+
+		if (!ieee80211_rx(priv->prom_priv->ieee, dst, &dummystats))
+			dev_kfree_skb_any(dst);
+	}
+}
+#endif
+
 static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
 				   struct net_device *dev, int pri)
 {
@@ -9900,6 +10305,11 @@ static int ipw_net_hard_start_xmit(struc
 		goto fail_unlock;
 	}
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+	if (rtap_iface && netif_running(priv->prom_net_dev))
+		ipw_handle_promiscuous_tx(priv, txb);
+#endif
+
 	ret = ipw_tx_skb(priv, txb, pri);
 	if (ret == NETDEV_TX_OK)
 		__ipw_led_activity_on(priv);
@@ -10347,12 +10757,21 @@ static int ipw_config(struct ipw_priv *p
 			    |= CFG_BT_COEXISTENCE_OOB;
 	}
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+	if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
+		priv->sys_config.accept_all_data_frames = 1;
+		priv->sys_config.accept_non_directed_frames = 1;
+		priv->sys_config.accept_all_mgmt_bcpr = 1;
+		priv->sys_config.accept_all_mgmt_frames = 1;
+	}
+#endif
+
 	if (priv->ieee->iw_mode == IW_MODE_ADHOC)
 		priv->sys_config.answer_broadcast_ssid_probe = 1;
 	else
 		priv->sys_config.answer_broadcast_ssid_probe = 0;
 
-	if (ipw_send_system_config(priv, &priv->sys_config))
+	if (ipw_send_system_config(priv))
 		goto error;
 
 	init_supported_rates(priv, &priv->rates);
@@ -10890,6 +11309,10 @@ static struct attribute *ipw_sysfs_entri
 	&dev_attr_led.attr,
 	&dev_attr_speed_scan.attr,
 	&dev_attr_net_stats.attr,
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+	&dev_attr_rtap_iface.attr,
+	&dev_attr_rtap_filter.attr,
+#endif
 	NULL
 };
 
@@ -10898,6 +11321,109 @@ static struct attribute_group ipw_attrib
 	.attrs = ipw_sysfs_entries,
 };
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+static int ipw_prom_open(struct net_device *dev)
+{
+	struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = prom_priv->priv;
+
+	IPW_DEBUG_INFO("prom dev->open\n");
+	netif_carrier_off(dev);
+	netif_stop_queue(dev);
+
+	if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
+		priv->sys_config.accept_all_data_frames = 1;
+		priv->sys_config.accept_non_directed_frames = 1;
+		priv->sys_config.accept_all_mgmt_bcpr = 1;
+		priv->sys_config.accept_all_mgmt_frames = 1;
+
+		ipw_send_system_config(priv);
+	}
+
+	return 0;
+}
+
+static int ipw_prom_stop(struct net_device *dev)
+{
+	struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = prom_priv->priv;
+
+	IPW_DEBUG_INFO("prom dev->stop\n");
+
+	if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
+		priv->sys_config.accept_all_data_frames = 0;
+		priv->sys_config.accept_non_directed_frames = 0;
+		priv->sys_config.accept_all_mgmt_bcpr = 0;
+		priv->sys_config.accept_all_mgmt_frames = 0;
+
+		ipw_send_system_config(priv);
+	}
+
+	return 0;
+}
+
+static int ipw_prom_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	IPW_DEBUG_INFO("prom dev->xmit\n");
+	netif_stop_queue(dev);
+	return -EOPNOTSUPP;
+}
+
+static struct net_device_stats *ipw_prom_get_stats(struct net_device *dev)
+{
+	struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
+	return &prom_priv->ieee->stats;
+}
+
+static int ipw_prom_alloc(struct ipw_priv *priv)
+{
+	int rc = 0;
+
+	if (priv->prom_net_dev)
+		return -EPERM;
+
+	priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv));
+	if (priv->prom_net_dev == NULL)
+		return -ENOMEM;
+
+	priv->prom_priv = ieee80211_priv(priv->prom_net_dev);
+	priv->prom_priv->ieee = netdev_priv(priv->prom_net_dev);
+	priv->prom_priv->priv = priv;
+
+	strcpy(priv->prom_net_dev->name, "rtap%d");
+
+	priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+	priv->prom_net_dev->open = ipw_prom_open;
+	priv->prom_net_dev->stop = ipw_prom_stop;
+	priv->prom_net_dev->get_stats = ipw_prom_get_stats;
+	priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit;
+
+	priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
+
+	rc = register_netdev(priv->prom_net_dev);
+	if (rc) {
+		free_ieee80211(priv->prom_net_dev);
+		priv->prom_net_dev = NULL;
+		return rc;
+	}
+
+	return 0;
+}
+
+static void ipw_prom_free(struct ipw_priv *priv)
+{
+	if (!priv->prom_net_dev)
+		return;
+
+	unregister_netdev(priv->prom_net_dev);
+	free_ieee80211(priv->prom_net_dev);
+
+	priv->prom_net_dev = NULL;
+}
+
+#endif
+
+
 static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	int err = 0;
@@ -11028,6 +11554,18 @@ static int ipw_pci_probe(struct pci_dev 
 		goto out_remove_sysfs;
 	}
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+	if (rtap_iface) {
+	        err = ipw_prom_alloc(priv);
+		if (err) {
+			IPW_ERROR("Failed to register promiscuous network "
+				  "device (error %d).\n", err);
+			unregister_netdev(priv->net_dev);
+			goto out_remove_sysfs;
+		}
+	}
+#endif
+
 	printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg "
 	       "channels, %d 802.11a channels)\n",
 	       priv->ieee->geo.name, priv->ieee->geo.bg_channels,
@@ -11107,6 +11645,10 @@ static void ipw_pci_remove(struct pci_de
 		priv->error = NULL;
 	}
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+	ipw_prom_free(priv);
+#endif
+
 	free_irq(pdev->irq, priv);
 	iounmap(priv->hw_base);
 	pci_release_regions(pdev);
@@ -11231,6 +11773,11 @@ MODULE_PARM_DESC(debug, "debug output ma
 module_param(channel, int, 0444);
 MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+module_param(rtap_iface, int, 0444);
+MODULE_PARM_DESC(rtap_iface, "create the rtap interface (1 - create, default 0)");
+#endif
+
 #ifdef CONFIG_IPW_QOS
 module_param(qos_enable, int, 0444);
 MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 1f2cab3..14fe79a 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -789,7 +789,7 @@ struct ipw_sys_config {
 	u8 bt_coexist_collision_thr;
 	u8 silence_threshold;
 	u8 accept_all_mgmt_bcpr;
-	u8 accept_all_mgtm_frames;
+	u8 accept_all_mgmt_frames;
 	u8 pass_noise_stats_to_host;
 	u8 reserved3;
 } __attribute__ ((packed));
@@ -1122,6 +1122,52 @@ struct ipw_fw_error {
 	u8 payload[0];
 } __attribute__ ((packed));
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+
+enum ipw_prom_filter {
+	IPW_PROM_CTL_HEADER_ONLY = (1 << 0),
+	IPW_PROM_MGMT_HEADER_ONLY = (1 << 1),
+	IPW_PROM_DATA_HEADER_ONLY = (1 << 2),
+	IPW_PROM_ALL_HEADER_ONLY = 0xf, /* bits 0..3 */
+	IPW_PROM_NO_TX = (1 << 4),
+	IPW_PROM_NO_RX = (1 << 5),
+	IPW_PROM_NO_CTL = (1 << 6),
+	IPW_PROM_NO_MGMT = (1 << 7),
+	IPW_PROM_NO_DATA = (1 << 8),
+};
+
+struct ipw_priv;
+struct ipw_prom_priv {
+	struct ipw_priv *priv;
+	struct ieee80211_device *ieee;
+	enum ipw_prom_filter filter;
+	int tx_packets;
+	int rx_packets;
+};
+#endif
+
+#if defined(CONFIG_IEEE80211_RADIOTAP) || defined(CONFIG_IPW2200_PROMISCUOUS)
+/* Magic struct that slots into the radiotap header -- no reason
+ * to build this manually element by element, we can write it much
+ * more efficiently than we can parse it. ORDER MATTERS HERE
+ *
+ * When sent to us via the simulated Rx interface in sysfs, the entire
+ * structure is provided regardless of any bits unset.
+ */
+struct ipw_rt_hdr {
+	struct ieee80211_radiotap_header rt_hdr;
+	u64 rt_tsf;      /* TSF */
+	u8 rt_flags;	/* radiotap packet flags */
+	u8 rt_rate;	/* rate in 500kb/s */
+	u16 rt_channel;	/* channel in mhz */
+	u16 rt_chbitmask;	/* channel bitfield */
+	s8 rt_dbmsignal;	/* signal in dbM, kluged to signed */
+	s8 rt_dbmnoise;
+	u8 rt_antenna;	/* antenna number */
+	u8 payload[0];  /* payload... */
+} __attribute__ ((packed));
+#endif
+
 struct ipw_priv {
 	/* ieee device used by generic ieee processing code */
 	struct ieee80211_device *ieee;
@@ -1133,6 +1179,12 @@ struct ipw_priv {
 	struct pci_dev *pci_dev;
 	struct net_device *net_dev;
 
+#ifdef CONFIG_IPW2200_PROMISCUOUS
+	/* Promiscuous mode */
+	struct ipw_prom_priv *prom_priv;
+	struct net_device *prom_net_dev;
+#endif
+
 	/* pci hardware address support */
 	void __iomem *hw_base;
 	unsigned long hw_len;
@@ -1306,6 +1358,29 @@ struct ipw_priv {
 
 /* debug macros */
 
+/* Debug and printf string expansion helpers for printing bitfields */
+#define BIT_FMT8 "%c%c%c%c-%c%c%c%c"
+#define BIT_FMT16 BIT_FMT8 ":" BIT_FMT8
+#define BIT_FMT32 BIT_FMT16 " " BIT_FMT16
+
+#define BITC(x,y) (((x>>y)&1)?'1':'0')
+#define BIT_ARG8(x) \
+BITC(x,7),BITC(x,6),BITC(x,5),BITC(x,4),\
+BITC(x,3),BITC(x,2),BITC(x,1),BITC(x,0)
+
+#define BIT_ARG16(x) \
+BITC(x,15),BITC(x,14),BITC(x,13),BITC(x,12),\
+BITC(x,11),BITC(x,10),BITC(x,9),BITC(x,8),\
+BIT_ARG8(x)
+
+#define BIT_ARG32(x) \
+BITC(x,31),BITC(x,30),BITC(x,29),BITC(x,28),\
+BITC(x,27),BITC(x,26),BITC(x,25),BITC(x,24),\
+BITC(x,23),BITC(x,22),BITC(x,21),BITC(x,20),\
+BITC(x,19),BITC(x,18),BITC(x,17),BITC(x,16),\
+BIT_ARG16(x)
+
+
 #ifdef CONFIG_IPW2200_DEBUG
 #define IPW_DEBUG(level, fmt, args...) \
 do { if (ipw_debug_level & (level)) \
-- 
1.2.6


^ permalink raw reply related

* [PATCH 10/18] README.ipw2200: rename CONFIG_IPW_DEBUG to CONFIG_IPW2200_DEBUG
From: Zhu Yi @ 2006-04-13  9:20 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 Documentation/networking/README.ipw2200 |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

4836217fd2a5f20600b2c053a19273d75d5e6f4c
diff --git a/Documentation/networking/README.ipw2200 b/Documentation/networking/README.ipw2200
index acb30c5..c3504f5 100644
--- a/Documentation/networking/README.ipw2200
+++ b/Documentation/networking/README.ipw2200
@@ -247,8 +247,8 @@ and can set the contents via echo.  For 
 % cat /sys/bus/pci/drivers/ipw2200/debug_level
 
 Will report the current debug level of the driver's logging subsystem 
-(only available if CONFIG_IPW_DEBUG was configured when the driver was 
-built).
+(only available if CONFIG_IPW2200_DEBUG was configured when the driver
+was built).
 
 You can set the debug level via:
 
-- 
1.2.6


^ permalink raw reply related

* [PATCH 09/18] ipw2200: Fix endian issues with v3.0 fw image format
From: Zhu Yi @ 2006-04-13  9:20 UTC (permalink / raw)
  To: netdev, John W. Linville

This patch corrects endian issues with the v3.0 fw image format.

Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |   23 ++++++++++++-----------
 1 files changed, 12 insertions(+), 11 deletions(-)

cde366e60f266195a1dd6d40b83c9bc97082f1a5
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 4b02920..7646def 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -3107,10 +3107,10 @@ static int ipw_reset_nic(struct ipw_priv
 
 
 struct ipw_fw {
-	u32 ver;
-	u32 boot_size;
-	u32 ucode_size;
-	u32 fw_size;
+	__le32 ver;
+	__le32 boot_size;
+	__le32 ucode_size;
+	__le32 fw_size;
 	u8 data[0];
 };
 
@@ -3134,8 +3134,8 @@ static int ipw_get_fw(struct ipw_priv *p
 
 	fw = (void *)(*raw)->data;
 
-	if ((*raw)->size < sizeof(*fw) +
-	    fw->boot_size + fw->ucode_size + fw->fw_size) {
+	if ((*raw)->size < sizeof(*fw) + le32_to_cpu(fw->boot_size) +
+	    le32_to_cpu(fw->ucode_size) + le32_to_cpu(fw->fw_size)) {
 		IPW_ERROR("%s is too small or corrupt (%zd)\n",
 			  name, (*raw)->size);
 		return -EINVAL;
@@ -3240,8 +3240,9 @@ static int ipw_load(struct ipw_priv *pri
 
 	fw = (void *)raw->data;
 	boot_img = &fw->data[0];
-	ucode_img = &fw->data[fw->boot_size];
-	fw_img = &fw->data[fw->boot_size + fw->ucode_size];
+	ucode_img = &fw->data[le32_to_cpu(fw->boot_size)];
+	fw_img = &fw->data[le32_to_cpu(fw->boot_size) +
+			   le32_to_cpu(fw->ucode_size)];
 
 	if (rc < 0)
 		goto error;
@@ -3275,7 +3276,7 @@ static int ipw_load(struct ipw_priv *pri
 			IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
 
 	/* DMA the initial boot firmware into the device */
-	rc = ipw_load_firmware(priv, boot_img, fw->boot_size);
+	rc = ipw_load_firmware(priv, boot_img, le32_to_cpu(fw->boot_size));
 	if (rc < 0) {
 		IPW_ERROR("Unable to load boot firmware: %d\n", rc);
 		goto error;
@@ -3297,7 +3298,7 @@ static int ipw_load(struct ipw_priv *pri
 	ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
 
 	/* DMA the ucode into the device */
-	rc = ipw_load_ucode(priv, ucode_img, fw->ucode_size);
+	rc = ipw_load_ucode(priv, ucode_img, le32_to_cpu(fw->ucode_size));
 	if (rc < 0) {
 		IPW_ERROR("Unable to load ucode: %d\n", rc);
 		goto error;
@@ -3307,7 +3308,7 @@ static int ipw_load(struct ipw_priv *pri
 	ipw_stop_nic(priv);
 
 	/* DMA bss firmware into the device */
-	rc = ipw_load_firmware(priv, fw_img, fw->fw_size);
+	rc = ipw_load_firmware(priv, fw_img, le32_to_cpu(fw->fw_size));
 	if (rc < 0) {
 		IPW_ERROR("Unable to load firmware: %d\n", rc);
 		goto error;
-- 
1.2.6


^ permalink raw reply related

* [PATCH 08/18] ipw2200: Set the 'fixed' flags in wext get_rate
From: Zhu Yi @ 2006-04-13  9:20 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Jean Tourrilhes <jt@hpl.hp.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

773cfa85e3c221a9d8284da73ff9e087e98dea12
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 057faa0..4b02920 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -8759,6 +8759,7 @@ static int ipw_wx_get_rate(struct net_de
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	mutex_lock(&priv->mutex);
 	wrqu->bitrate.value = priv->last_rate;
+	wrqu->bitrate.fixed = (priv->config & CFG_FIXED_RATE) ? 1 : 0;
 	mutex_unlock(&priv->mutex);
 	IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
 	return 0;
-- 
1.2.6


^ permalink raw reply related

* [PATCH 07/18] ipw2200: turn off signal debug log
From: Zhu Yi @ 2006-04-13  9:19 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

c4613fd635d134e567b64de4d89fe54a7b0f88b2
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index febee43..057faa0 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -4033,7 +4033,7 @@ static void ipw_gather_stats(struct ipw_
 	else if (signal_quality < 1)
 		signal_quality = 0;
 
-	IPW_ERROR("Signal level : %3d%% (%d dBm)\n",
+	IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
 			signal_quality, rssi);
 
 	quality = min(beacon_quality,
-- 
1.2.6


^ permalink raw reply related

* [PATCH 06/18] ipw2200: Do not continue loading the firmware if kmalloc fails
From: Zhu Yi @ 2006-04-13  9:19 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: "Zhu, Yi" <yi.zhu@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>

---

 drivers/net/wireless/ipw2200.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

bb9de6f2888b04991bc634e9700114d3b415cdcb
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index c38fb90..febee43 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -10666,6 +10666,7 @@ static int ipw_up(struct ipw_priv *priv)
 		if (priv->cmdlog == NULL) {
 			IPW_ERROR("Error allocating %d command log entries.\n",
 				  cmdlog);
+			return -ENOMEM;
 		} else {
 			memset(priv->cmdlog, 0, sizeof(*priv->cmdlog) * cmdlog);
 			priv->cmdlog_len = cmdlog;
-- 
1.2.6


^ permalink raw reply related

* [PATCH 05/18] ipw2200: fix compile warning when !CONFIG_IPW2200_DEBUG
From: Zhu Yi @ 2006-04-13  9:19 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

4c418f1f7845ec9d78fe4f3a7346416c13662ace
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 6b8c47b..c38fb90 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -46,7 +46,9 @@ MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
 static int cmdlog = 0;
+#ifdef CONFIG_IPW2200_DEBUG
 static int debug = 0;
+#endif
 static int channel = 0;
 static int mode = 0;
 
-- 
1.2.6


^ permalink raw reply related

* [PATCH 04/18] ipw2200: add module_param support for antenna selection
From: Zhu Yi @ 2006-04-13  9:19 UTC (permalink / raw)
  To: netdev, John W. Linville

Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

cfcb7bc915320b44d0d2825a8554211249c7bbcd
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 536af9f..6b8c47b 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -61,6 +61,7 @@ static int roaming = 1;
 static const char ipw_modes[] = {
 	'a', 'b', 'g', '?'
 };
+static int antenna = CFG_SYS_ANTENNA_BOTH;
 
 #ifdef CONFIG_IPW_QOS
 static int qos_enable = 0;
@@ -9630,7 +9631,9 @@ static  void init_sys_config(struct ipw_
 	sys_config->disable_unicast_decryption = 1;
 	sys_config->exclude_multicast_unencrypted = 0;
 	sys_config->disable_multicast_decryption = 1;
-	sys_config->antenna_diversity = CFG_SYS_ANTENNA_SLOW_DIV;
+	if (antenna < CFG_SYS_ANTENNA_BOTH || antenna > CFG_SYS_ANTENNA_B)
+		antenna = CFG_SYS_ANTENNA_BOTH;
+	sys_config->antenna_diversity = antenna;
 	sys_config->pass_crc_to_host = 0;	/* TODO: See if 1 gives us FCS */
 	sys_config->dot11g_auto_detection = 0;
 	sys_config->enable_cts_to_self = 0;
@@ -11261,5 +11264,8 @@ MODULE_PARM_DESC(cmdlog,
 module_param(roaming, int, 0444);
 MODULE_PARM_DESC(roaming, "enable roaming support (default on)");
 
+module_param(antenna, int, 0444);
+MODULE_PARM_DESC(antenna, "select antenna 1=Main, 3=Aux, default 0 [both], 2=slow_diversity (choose the one with lower background noise)");
+
 module_exit(ipw_exit);
 module_init(ipw_init);
-- 
1.2.6


^ permalink raw reply related

* [PATCH 03/18] ipw2200: generates a scan event after a scan has completed
From: Zhu Yi @ 2006-04-13  9:19 UTC (permalink / raw)
  To: netdev, John W. Linville

The patch make ipw2200 generate the scan event every time a scan has
completed, so that user space know when to get fresh results.
Dan Williams would like to go towards this model in Network Manager
rather than having to poll.

Signed-off-by: Jean Tourrilhes <jt@hpl.hp.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>

---

 drivers/net/wireless/ipw2200.c |   21 ++++++++++++++++++++-
 1 files changed, 20 insertions(+), 1 deletions(-)

edf85b053dafee701cbdda19507485455f97e544
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index a4d8d49..536af9f 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -4489,6 +4489,24 @@ static void ipw_rx_notification(struct i
 				 && priv->status & STATUS_ASSOCIATED)
 				queue_delayed_work(priv->workqueue,
 						   &priv->request_scan, HZ);
+
+			/* Send an empty event to user space.
+			 * We don't send the received data on the event because
+			 * it would require us to do complex transcoding, and
+			 * we want to minimise the work done in the irq handler
+			 * Use a request to extract the data.
+			 * Also, we generate this even for any scan, regardless
+			 * on how the scan was initiated. User space can just
+			 * sync on periodic scan to get fresh data...
+			 * Jean II */
+			if (x->status == SCAN_COMPLETED_STATUS_COMPLETE) {
+				union iwreq_data wrqu;
+
+				wrqu.data.length = 0;
+				wrqu.data.flags = 0;
+				wireless_send_event(priv->net_dev, SIOCGIWSCAN,
+						    &wrqu, NULL);
+			}
 			break;
 		}
 
@@ -8382,7 +8400,8 @@ static int ipw_wx_get_range(struct net_d
 	/* Event capability (kernel + driver) */
 	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
 				IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
-				IW_EVENT_CAPA_MASK(SIOCGIWAP));
+				IW_EVENT_CAPA_MASK(SIOCGIWAP) |
+				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
 	range->event_capa[1] = IW_EVENT_CAPA_K_1;
 
 	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-- 
1.2.6


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox