Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH] net: wireless: mesh: Add multicast and unicast stat counters
From: Javier Cardona @ 2009-08-18 18:08 UTC (permalink / raw)
  To: Daniel Walker
  Cc: John W. Linville, Johannes Berg, David S. Miller,
	Luis R. Rodriguez, Andrey Yurovsky, linux-wireless,
	Sven-Thorsten Dietrich
In-Reply-To: <1250604146-10140-1-git-send-email-dwalker@fifo99.com>

Daniel,

Thanks for the patch, that's useful.
I've reworked it so it can be applied to the HEAD of wireless-testing.
 Comments in line and reworked patch in a follow-up email.
Cheers,

Javier

> ---
>  net/mac80211/debugfs_netdev.c |    6 ++++++
>  net/mac80211/ieee80211_i.h    |    6 +++++-
>  net/mac80211/mesh_hwmp.c      |    4 ++++
>  net/mac80211/rx.c             |    9 +++++++--
>  4 files changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
> index e9ec6ca..00f7c6e 100644
> --- a/net/mac80211/debugfs_netdev.c
> +++ b/net/mac80211/debugfs_netdev.c
> @@ -116,6 +116,8 @@ IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
>
>  #ifdef CONFIG_MAC80211_MESH
>  /* Mesh stats attributes */
> +IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
> +IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
>  IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
>  IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
>  IEEE80211_IF_FILE(dropped_frames_no_route,
> @@ -205,6 +207,8 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
>  {
>        sdata->mesh_stats_dir = debugfs_create_dir("mesh_stats",
>                                sdata->debugfsdir);
> +       MESHSTATS_ADD(mcast_frames);
> +       MESHSTATS_ADD(unicast_frames);

mcast_frames -> fwded_mcast
unicast_frames -> fwded_unicast

>        MESHSTATS_ADD(fwded_frames);
>        MESHSTATS_ADD(dropped_frames_ttl);
>        MESHSTATS_ADD(dropped_frames_no_route);
> @@ -327,6 +331,8 @@ static void del_monitor_files(struct ieee80211_sub_if_data *sdata)
>
>  static void del_mesh_stats(struct ieee80211_sub_if_data *sdata)
>  {
> +       MESHSTATS_DEL(mcast_frames);
> +       MESHSTATS_DEL(unicast_frames);

Same as previous comment.

>        MESHSTATS_DEL(fwded_frames);
>        MESHSTATS_DEL(dropped_frames_ttl);
>        MESHSTATS_DEL(dropped_frames_no_route);
> diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
> index d6bd7dd..82c39d9 100644
> --- a/net/mac80211/ieee80211_i.h
> +++ b/net/mac80211/ieee80211_i.h
> @@ -212,7 +212,9 @@ struct ieee80211_if_vlan {
>  };
>
>  struct mesh_stats {
> -       __u32 fwded_frames;             /* Mesh forwarded frames */
> +       __u32 fwded_mcast;              /* Mesh forwarded multicast frames */
> +       __u32 fwded_unicast;            /* Mesh forwarded unicast frames */
> +       __u32 fwded_frames;             /* Mesh total forwarded frames */
>        __u32 dropped_frames_ttl;       /* Not transmitted since mesh_ttl == 0*/
>        __u32 dropped_frames_no_route;  /* Not transmitted, no route found */
>        atomic_t estab_plinks;
> @@ -506,6 +508,8 @@ struct ieee80211_sub_if_data {
>  #ifdef CONFIG_MAC80211_MESH
>        struct dentry *mesh_stats_dir;
>        struct {
> +               struct dentry *fwded_mcast;
> +               struct dentry *fwded_unicast;
>                struct dentry *fwded_frames;
>                struct dentry *dropped_frames_ttl;
>                struct dentry *dropped_frames_no_route;
> diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
> index e1a763e..593ea64 100644
> --- a/net/mac80211/mesh_hwmp.c
> +++ b/net/mac80211/mesh_hwmp.c
> @@ -478,6 +478,8 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
>                                hopcount, ttl, cpu_to_le32(lifetime),
>                                cpu_to_le32(metric), cpu_to_le32(preq_id),
>                                sdata);
> +
> +               ifmsh->mshstats.fwded_mcast++;
>                ifmsh->mshstats.fwded_frames++;
>        }
>  }
> @@ -536,6 +538,8 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
>                cpu_to_le32(lifetime), cpu_to_le32(metric),
>                0, sdata);
>        rcu_read_unlock();
> +
> +       sdata->u.mesh.mshstats.fwded_unicast++;
>        sdata->u.mesh.mshstats.fwded_frames++;
>        return;
>
> diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> index 25a669c..cf21f57 100644
> --- a/net/mac80211/rx.c
> +++ b/net/mac80211/rx.c
> @@ -1543,16 +1543,21 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
>                        info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
>                        info->control.vif = &rx->sdata->vif;
>                        ieee80211_select_queue(local, fwd_skb);
> -                       if (is_multicast_ether_addr(fwd_hdr->addr3))
> +                       if (is_multicast_ether_addr(fwd_hdr->addr3)) {
>                                memcpy(fwd_hdr->addr1, fwd_hdr->addr3,
>                                                ETH_ALEN);
> -                       else {
> +                               IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
> +                                                            fwded_mcast);
> +                       } else {
>                                int err = mesh_nexthop_lookup(fwd_skb, sdata);
>                                /* Failed to immediately resolve next hop:
>                                 * fwded frame was dropped or will be added
>                                 * later to the pending skb queue.  */
>                                if (err)
>                                        return RX_DROP_MONITOR;
> +
> +                               IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
> +                                                            fwded_unicast);
>                        }
>                        IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
>                                                     fwded_frames);

Hunk will fail due to recent changes to multicast frame format.

^ permalink raw reply

* [PATCH] mac80211: New stat counters for multicast and unicast forwarded frames
From: Javier Cardona @ 2009-08-18 17:59 UTC (permalink / raw)
  To: linux-wireless
  Cc: Daniel Walker, Javier Cardona, andrey, johannes, linville, devel
In-Reply-To: <445f43ac0908181108g490934c1ib0c805859cba1e44@mail.gmail.com>

From: Daniel Walker <dwalker@fifo99.com>

This expands on the current fwded_frames stat counter which should be equal to
the total of these two new counters.  The new counters are called "fwded_mcast"
and "fwded_unicast".

Signed-off-by: Daniel Walker <dwalker@fifo99.com>
Signed-off-by: Javier Cardona <javier@cozybit.com>
---
 net/mac80211/debugfs_netdev.c |    6 ++++++
 net/mac80211/ieee80211_i.h    |    6 +++++-
 net/mac80211/mesh_hwmp.c      |    3 +++
 net/mac80211/rx.c             |    8 +++++++-
 4 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index e9ec6ca..61234e7 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -116,6 +116,8 @@ IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
 
 #ifdef CONFIG_MAC80211_MESH
 /* Mesh stats attributes */
+IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
+IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
 IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
 IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
 IEEE80211_IF_FILE(dropped_frames_no_route,
@@ -205,6 +207,8 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
 {
 	sdata->mesh_stats_dir = debugfs_create_dir("mesh_stats",
 				sdata->debugfsdir);
+	MESHSTATS_ADD(fwded_mcast);
+	MESHSTATS_ADD(fwded_unicast);
 	MESHSTATS_ADD(fwded_frames);
 	MESHSTATS_ADD(dropped_frames_ttl);
 	MESHSTATS_ADD(dropped_frames_no_route);
@@ -327,6 +331,8 @@ static void del_monitor_files(struct ieee80211_sub_if_data *sdata)
 
 static void del_mesh_stats(struct ieee80211_sub_if_data *sdata)
 {
+	MESHSTATS_DEL(fwded_mcast);
+	MESHSTATS_DEL(fwded_unicast);
 	MESHSTATS_DEL(fwded_frames);
 	MESHSTATS_DEL(dropped_frames_ttl);
 	MESHSTATS_DEL(dropped_frames_no_route);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a07f017..93e618a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -212,7 +212,9 @@ struct ieee80211_if_vlan {
 };
 
 struct mesh_stats {
-	__u32 fwded_frames;		/* Mesh forwarded frames */
+	__u32 fwded_mcast;		/* Mesh forwarded multicast frames */
+	__u32 fwded_unicast;		/* Mesh forwarded unicast frames */
+	__u32 fwded_frames;		/* Mesh total forwarded frames */
 	__u32 dropped_frames_ttl;	/* Not transmitted since mesh_ttl == 0*/
 	__u32 dropped_frames_no_route;	/* Not transmitted, no route found */
 	atomic_t estab_plinks;
@@ -506,6 +508,8 @@ struct ieee80211_sub_if_data {
 #ifdef CONFIG_MAC80211_MESH
 	struct dentry *mesh_stats_dir;
 	struct {
+		struct dentry *fwded_mcast;
+		struct dentry *fwded_unicast;
 		struct dentry *fwded_frames;
 		struct dentry *dropped_frames_ttl;
 		struct dentry *dropped_frames_no_route;
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 7aeba00..e12a786 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -497,6 +497,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
 				hopcount, ttl, cpu_to_le32(lifetime),
 				cpu_to_le32(metric), cpu_to_le32(preq_id),
 				sdata);
+		ifmsh->mshstats.fwded_mcast++;
 		ifmsh->mshstats.fwded_frames++;
 	}
 }
@@ -555,6 +556,8 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
 		cpu_to_le32(lifetime), cpu_to_le32(metric),
 		0, sdata);
 	rcu_read_unlock();
+
+	sdata->u.mesh.mshstats.fwded_unicast++;
 	sdata->u.mesh.mshstats.fwded_frames++;
 	return;
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 4cd9e45..7065fd7 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1550,7 +1550,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 			info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
 			info->control.vif = &rx->sdata->vif;
 			ieee80211_select_queue(local, fwd_skb);
-			if (!is_multicast_ether_addr(fwd_hdr->addr1)) {
+			if (is_multicast_ether_addr(fwd_hdr->addr1))
+				IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
+								fwded_mcast);
+			else {
 				int err;
 				/*
 				 * Save TA to addr1 to send TA a path error if a
@@ -1564,6 +1567,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 				 * later to the pending skb queue.  */
 				if (err)
 					return RX_DROP_MONITOR;
+
+				IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
+								fwded_unicast);
 			}
 			IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
 						     fwded_frames);
-- 
1.5.4.3


^ permalink raw reply related

* Re: Need rc6 posted to orbit-lab
From: Philip A. Prindeville @ 2009-08-18 18:18 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: wireless
In-Reply-To: <4A88766A.1050609@redfish-solutions.com>

Philip A. Prindeville wrote:
> Can you please send out an announcement when rc6 hits orbit-lab?
>
> Thanks.
>   

Or maybe I'll just wait until rc7 comes out... :-O


^ permalink raw reply

* Re: [PATCH] mac80211: New stat counters for multicast and unicast forwarded frames
From: Daniel Walker @ 2009-08-18 18:19 UTC (permalink / raw)
  To: Javier Cardona; +Cc: linux-wireless, andrey, johannes, linville, devel
In-Reply-To: <1250618340-32129-1-git-send-email-javier@cozybit.com>

On Tue, 2009-08-18 at 10:59 -0700, Javier Cardona wrote:
> From: Daniel Walker <dwalker@fifo99.com>
> 
> This expands on the current fwded_frames stat counter which should be equal to
> the total of these two new counters.  The new counters are called "fwded_mcast"
> and "fwded_unicast".
> 
> Signed-off-by: Daniel Walker <dwalker@fifo99.com>
> Signed-off-by: Javier Cardona <javier@cozybit.com>
> ---

Might have been nice for you to wait for me to review the new version
before adding my sign off , but it looks fine.

Signed-off-by: Daniel Walker <dwalker@fifo99.com>


^ permalink raw reply

* Re: [PATCH] mac80211: New stat counters for multicast and unicast forwarded frames
From: Javier Cardona @ 2009-08-18 18:25 UTC (permalink / raw)
  To: Daniel Walker; +Cc: linux-wireless, andrey, johannes, linville, devel
In-Reply-To: <1250619585.4742.1929.camel@desktop>

Daniel,

On Tue, Aug 18, 2009 at 11:19 AM, Daniel Walker<dwalker@fifo99.com> wrote:
> On Tue, 2009-08-18 at 10:59 -0700, Javier Cardona wrote:
>> From: Daniel Walker <dwalker@fifo99.com>
>>
>> This expands on the current fwded_frames stat counter which should be equal to
>> the total of these two new counters.  The new counters are called "fwded_mcast"
>> and "fwded_unicast".
>>
>> Signed-off-by: Daniel Walker <dwalker@fifo99.com>
>> Signed-off-by: Javier Cardona <javier@cozybit.com>
>> ---
>
> Might have been nice for you to wait for me to review the new version
> before adding my sign off , but it looks fine.

You are right.  Sorry for that.

Thanks,

Javier

^ permalink raw reply

* Re: [PATCH] rt2x00: configure_filter() callback is allowed to sleep
From: Ivo van Doorn @ 2009-08-18 18:27 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John Linville, linux-wireless
In-Reply-To: <1250618853.7887.0.camel@johannes.local>

On Tuesday 18 August 2009, Johannes Berg wrote:
> On Tue, 2009-08-18 at 20:04 +0200, Ivo van Doorn wrote:
> 
> > > Speaking of which -- bss_info_changed can sleep too, which means you can
> > > remove DRIVER_REQUIRE_SCHEDULED completely I think?
> > 
> > Seriously, that would be great. Patch coming up in a few minutes. ;)
> 
> Cool.
> 
> Hey, sorry it took so long to make it possible :)
>
> I wonder if drivers now ever have a reason to queue work on the mac80211
> workqueue? Some periodic calibration tasks maybe?

Well after the removal of DRIVER_REQUIRE_SCHEDULED I only have 1
workqueue structure left: Updating beacons.

During the update it needs to iterate through all interfaces using
ieee80211_iterate_active_interfaces_atomic(), during the actual update
a mutex is required because USB device access is required. And not in the least
the function is called by the set_tim() callback function.

Ivo



^ permalink raw reply

* Re: [PATCH] rt2x00: configure_filter() callback is allowed to sleep
From: Luis R. Rodriguez @ 2009-08-18 18:24 UTC (permalink / raw)
  To: Johannes Berg, Jouni.Malinen; +Cc: Ivo van Doorn, John Linville, linux-wireless
In-Reply-To: <1250618853.7887.0.camel@johannes.local>

On Tue, Aug 18, 2009 at 11:07 AM, Johannes
Berg<johannes@sipsolutions.net> wrote:
> On Tue, 2009-08-18 at 20:04 +0200, Ivo van Doorn wrote:
>
>> > Speaking of which -- bss_info_changed can sleep too, which means you can
>> > remove DRIVER_REQUIRE_SCHEDULED completely I think?
>>
>> Seriously, that would be great. Patch coming up in a few minutes. ;)
>
> Cool.
>
> Hey, sorry it took so long to make it possible :)
>
> I wonder if drivers now ever have a reason to queue work on the mac80211
> workqueue? Some periodic calibration tasks maybe?

ath9k just has the virtual wiphy stuff and that uses the mac80211
workqueue.  Maybe we can review this stuff at the summit in
consideration for how we may want this eventually on
mac80211/cfg80211.

  Luis

^ permalink raw reply

* [PATCH] rt2x00: bss_info_changed() callback is allowed to sleep
From: Ivo van Doorn @ 2009-08-18 18:33 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, users, Johannes Berg

The bss_info_changed() callback function no longer needs
to be atomic. Remove the scheduled work structure and
call into the driver directly.

Additionaly this makes the DRIVER_REQUIRE_SCHEDULED
flag redundant so it can be removed.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2500usb.c |    1 -
 drivers/net/wireless/rt2x00/rt2800usb.c |    1 -
 drivers/net/wireless/rt2x00/rt2x00.h    |    3 ---
 drivers/net/wireless/rt2x00/rt2x00dev.c |    8 --------
 drivers/net/wireless/rt2x00/rt2x00mac.c |   14 +++-----------
 drivers/net/wireless/rt2x00/rt73usb.c   |    1 -
 6 files changed, 3 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 09a5894..b04f59b 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1874,7 +1874,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 	 */
 	__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
 	__set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
 	if (!modparam_nohwcrypt) {
 		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
 		__set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 45e02f1..639dc6c 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -2634,7 +2634,6 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 	 * This device requires firmware.
 	 */
 	__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
 	__set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
 	if (!modparam_nohwcrypt)
 		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 2d0b6b0..f5978a6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -356,8 +356,6 @@ struct rt2x00_intf {
 	 */
 	unsigned int delayed_flags;
 #define DELAYED_UPDATE_BEACON		0x00000001
-#define DELAYED_CONFIG_ERP		0x00000002
-#define DELAYED_LED_ASSOC		0x00000004
 
 	/*
 	 * Software sequence counter, this is only required
@@ -620,7 +618,6 @@ enum rt2x00_flags {
 	DRIVER_REQUIRE_FIRMWARE,
 	DRIVER_REQUIRE_BEACON_GUARD,
 	DRIVER_REQUIRE_ATIM_QUEUE,
-	DRIVER_REQUIRE_SCHEDULED,
 	DRIVER_REQUIRE_DMA,
 	DRIVER_REQUIRE_COPY_IV,
 	DRIVER_REQUIRE_L2PAD,
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 16b560a..3f8c70e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -123,7 +123,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
 {
 	struct rt2x00_dev *rt2x00dev = data;
 	struct rt2x00_intf *intf = vif_to_intf(vif);
-	struct ieee80211_bss_conf conf;
 	int delayed_flags;
 
 	/*
@@ -133,7 +132,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
 	 */
 	spin_lock(&intf->lock);
 
-	memcpy(&conf, &vif->bss_conf, sizeof(conf));
 	delayed_flags = intf->delayed_flags;
 	intf->delayed_flags = 0;
 
@@ -150,12 +148,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
 
 	if (delayed_flags & DELAYED_UPDATE_BEACON)
 		rt2x00queue_update_beacon(rt2x00dev, vif, true);
-
-	if (delayed_flags & DELAYED_CONFIG_ERP)
-		rt2x00lib_config_erp(rt2x00dev, intf, &conf);
-
-	if (delayed_flags & DELAYED_LED_ASSOC)
-		rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
 }
 
 static void rt2x00lib_intf_scheduled(struct work_struct *work)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 967d3b5..a91f316 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -636,23 +636,15 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
 		else
 			rt2x00dev->intf_associated--;
 
-		if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
-			rt2x00leds_led_assoc(rt2x00dev,
-					     !!rt2x00dev->intf_associated);
-		else
-			delayed |= DELAYED_LED_ASSOC;
+		rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
 	}
 
 	/*
 	 * When the erp information has changed, we should perform
 	 * additional configuration steps. For all other changes we are done.
 	 */
-	if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) {
-		if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
-			rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
-		else
-			delayed |= DELAYED_CONFIG_ERP;
-	}
+	if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT))
+		rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
 
 	spin_lock(&intf->lock);
 	if (delayed) {
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 4d94b65..90e1172 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2151,7 +2151,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 	 * This device requires firmware.
 	 */
 	__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
 	if (!modparam_nohwcrypt)
 		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
 
-- 
1.6.4


^ permalink raw reply related

* Re: [PATCH] rt2x00: configure_filter() callback is allowed to sleep
From: Kalle Valo @ 2009-08-18 19:30 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Ivo van Doorn, John Linville, linux-wireless
In-Reply-To: <1250618853.7887.0.camel@johannes.local>

Johannes Berg <johannes@sipsolutions.net> writes:

> I wonder if drivers now ever have a reason to queue work on the mac80211
> workqueue? Some periodic calibration tasks maybe?

wl1251 and wl1271 queue tx frames to a workqueue. This is because they
use synchronous spi interface. This might change if we switch
asynchronous interface in the future. No idea how this affects sdio,
though.

-- 
Kalle Valo

^ permalink raw reply

* [PATCH] b43: LP-PHY: Two small spec updates
From: Gábor Stefanik @ 2009-08-18 20:08 UTC (permalink / raw)
  To: John Linville, Michael Buesch, Larry Finger
  Cc: Mark Huijgen, Broadcom Wireless, linux-wireless

The specs are beginning to support rev3 LP-PHYs - implement one of
the changes needed for rev3 support.
Also, in the new MIPS driver, the "Japan TX filter" was renamed to
"analog TX filter init" - however, calling it "init" is confusing,
so name it "set analog filter", with a comment for easier future
identification.

Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
---
 drivers/net/wireless/b43/phy_lp.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 6c69cdb..65f0010 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -609,9 +609,14 @@ static void lpphy_2063_init(struct b43_wldev *dev)
 	b43_radio_write(dev, B2063_PA_SP7, 0);
 	b43_radio_write(dev, B2063_TX_RF_SP6, 0x20);
 	b43_radio_write(dev, B2063_TX_RF_SP9, 0x40);
-	b43_radio_write(dev, B2063_PA_SP3, 0xa0);
-	b43_radio_write(dev, B2063_PA_SP4, 0xa0);
-	b43_radio_write(dev, B2063_PA_SP2, 0x18);
+	if (dev->phy.rev == 2) {
+		b43_radio_write(dev, B2063_PA_SP3, 0xa0);
+		b43_radio_write(dev, B2063_PA_SP4, 0xa0);
+		b43_radio_write(dev, B2063_PA_SP2, 0x18);
+	} else {
+		b43_radio_write(dev, B2063_PA_SP3, 0x20);
+		b43_radio_write(dev, B2063_PA_SP2, 0x20);
+	}
 }
 
 struct lpphy_stx_table_entry {
@@ -1996,7 +2001,9 @@ static int lpphy_b2062_tune(struct b43_wldev *dev,
 	return err;
 }
 
-static void lpphy_japan_filter(struct b43_wldev *dev, int channel)
+
+/* This was previously called lpphy_japan_filter */
+static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel)
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
 	u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter!
@@ -2165,7 +2172,7 @@ static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
 		err = lpphy_b2062_tune(dev, new_channel);
 		if (err)
 			return err;
-		lpphy_japan_filter(dev, new_channel);
+		lpphy_set_analog_filter(dev, new_channel);
 		lpphy_adjust_gain_table(dev, channel2freq_lp(new_channel));
 	}
 
-- 
1.6.2.4




^ permalink raw reply related

* [ANN] b43 LP-PHY support (BCM4310/4312/4315) now ready for testing!
From: Gábor Stefanik @ 2009-08-18 20:29 UTC (permalink / raw)
  To: Broadcom Wireless, linux-wireless

Hello World!

Great news for Broadcom BCM4310/4312/4315 (PCI 14e4:4315) users:
LP-PHY support is now at the point where it can be tested for functionality!

There are still problems with channel switching (a few patches ago,
only 802.11b/g channels 7 and 8 were working - no tests have been
performed since then) & TX is untested, but Larry has reported that he
can get scan results from channels 7 and 8. He doesn't have any AP on
these channels, so can't test if association works, but it should be
working too. It's also possible that recent patches have fixed the
channel switching bug, as the codepaths for channel switching have
been touched extensively, probably fixing a major miscalculation issue
("Qdiv roundup" was completely wrong).

So, go ahead, give it a try, and let's rock!

Note that the code in wireless-testing is enough to start testing,
however it's recommended that you apply the following 2 pending fixes:
http://marc.info/?l=linux-wireless&m=125061590101156&w=2 and
http://marc.info/?l=linux-wireless&m=125062611720517&w=2

Tomorrow's compat-wireless tarball, together with the above patches,
should also be good for testing. Not sure about today's tarball.

--Gábor

-- 
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)

^ permalink raw reply

* Re: [PATCH 2/3] Add rfkill support to compal-laptop
From: Alan Jenkins @ 2009-08-18 21:08 UTC (permalink / raw)
  To: Mario Limonciello
  Cc: johannes@sipsolutions.net, Marcel Holtmann, cezary.jackiewicz,
	linux-acpi, linux-kernel, linux-wireless@vger.kernel.org
In-Reply-To: <4A8AE459.8060102@dell.com>

On 8/18/09, Mario Limonciello <mario_limonciello@dell.com> wrote:
> Hi Alan & Marcel:
>
> Alan Jenkins wrote:
>> Also, you're missing the calls to rfkill_destroy() here.
>>
>> Whew, I think that's everything.  I hope you find the feedback useful,
>> despite it being a little fragmented.
>>
>>
> Thanks for all the feedback.  I think i've addressed all of the concerns
> that were pointed out.  I appreciate the pointer to scripts/cleanpatch,
> that does significantly help in finding whitespace problems that the
> naked eye just browses over.
>
> I'm attaching the updated patch (sorry, git send-email seems to still
> not be very graceful with line breaks when the SMTP implementation is
> exchange from what i've seen)

> +static void compal_rfkill_poll(struct rfkill *rfkill, void *data)
> +{
> +	unsigned long radio = (unsigned long) data;
> +	u8 result;
> +	bool hw_blocked;
> +	bool sw_blocked;
> +
> +	ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
> +
> +	hw_blocked = !(result & KILLSWITCH_MASK);
> +	sw_blocked = (!hw_blocked && !(result & radio));
> +
> +	rfkill_set_states(rfkill, sw_blocked, hw_blocked);
> +}

I assume you have good reason for having sw_block depend on hw_block.
I.e. you can't read sw_blocked while hw_blocked is set, right?

If KILLSWITCH is toggled on and off, will the hardware "forget" any
prior soft-blocks?

It would also be nice to know if hardware/firmware ever changes
sw_blocked, e.g. in response to a button press.

Johannes, I think I'm confusing myself here.  Can you have a look at
this code?  I remember the rfkill rewrite was designed to help with
something like this, but I don't know how exactly.

Thanks
Alan

^ permalink raw reply

* Re: [PATCH 2/3] Add rfkill support to compal-laptop
From: Johannes Berg @ 2009-08-18 21:31 UTC (permalink / raw)
  To: Alan Jenkins
  Cc: Mario Limonciello, Marcel Holtmann, cezary.jackiewicz, linux-acpi,
	linux-kernel, linux-wireless@vger.kernel.org
In-Reply-To: <9b2b86520908181408v5f7875b6sea31d8d95cc08c0b@mail.gmail.com>

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

Hi everyone,

> > I'm attaching the updated patch (sorry, git send-email seems to still
> > not be very graceful with line breaks when the SMTP implementation is
> > exchange from what i've seen)
> 
> > +static void compal_rfkill_poll(struct rfkill *rfkill, void *data)
> > +{
> > +	unsigned long radio = (unsigned long) data;
> > +	u8 result;
> > +	bool hw_blocked;
> > +	bool sw_blocked;
> > +
> > +	ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
> > +
> > +	hw_blocked = !(result & KILLSWITCH_MASK);
> > +	sw_blocked = (!hw_blocked && !(result & radio));
> > +
> > +	rfkill_set_states(rfkill, sw_blocked, hw_blocked);
> > +}
> 
> I assume you have good reason for having sw_block depend on hw_block.
> I.e. you can't read sw_blocked while hw_blocked is set, right?
> 
> If KILLSWITCH is toggled on and off, will the hardware "forget" any
> prior soft-blocks?

That's a bit strange indeed, but I haven't seen the rest of the code.

Does the 'soft block' bit change based on user input, like pressing a
button?

If not, you shouldn't poll that bit at all, but just set it based on
what rfkill gives you as the return value of set_hw_state().

hth,
johannes

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

^ permalink raw reply

* Re: [PATCH 2/3] Add rfkill support to compal-laptop
From: Mario Limonciello @ 2009-08-18 22:00 UTC (permalink / raw)
  To: Johannes Berg, Alan Jenkins
  Cc: Marcel Holtmann, cezary.jackiewicz, linux-acpi, linux-kernel,
	linux-wireless@vger.kernel.org
In-Reply-To: <1250631063.16393.14.camel@johannes.local>


[-- Attachment #1.1: Type: text/plain, Size: 846 bytes --]

Hi Guys:

Johannes Berg wrote:
> Hi everyone,
>
> That's a bit strange indeed, but I haven't seen the rest of the code.
>
> Does the 'soft block' bit change based on user input, like pressing a
> button?
>
> If not, you shouldn't poll that bit at all, but just set it based on
> what rfkill gives you as the return value of set_hw_state().
>
>   
No it doesn't, so i've followed your advice in an updated patch, Thanks.


Alan Jenkins wrote:

> ... but you *do* need to unregister wifi_rfkill here, before you go on
> to destroy it.
>
> +err_wifi:
> +	rfkill_destroy(wifi_rfkill);
> +
> +	return ret;
> +}
>
> Regards
> Alan
>   
I think I've addressed this properly now and only go through each of the error handlers as necessary.

-- 
Mario Limonciello
*Dell | Linux Engineering*
mario_limonciello@dell.com

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 02_add_rfkill_support.diff --]
[-- Type: text/x-patch; name="02_add_rfkill_support.diff", Size: 3274 bytes --]

--- compal-laptop.c.old	2009-08-18 05:23:39.668669312 -0500
+++ compal-laptop.c	2009-08-18 05:49:00.098015155 -0500
@@ -52,6 +52,7 @@
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
 #include <linux/autoconf.h>
+#include <linux/rfkill.h>
 
 #define COMPAL_DRIVER_VERSION "0.2.6"
 
@@ -64,6 +65,10 @@
 #define WLAN_MASK	0x01
 #define BT_MASK 	0x02
 
+static struct rfkill *wifi_rfkill;
+static struct rfkill *bt_rfkill;
+static struct platform_device *compal_device;
+
 static int force;
 module_param(force, bool, 0);
 MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
@@ -89,6 +94,84 @@
 	return (int) result;
 }
 
+static void compal_rfkill_poll(struct rfkill *rfkill, void *data)
+{
+	unsigned long radio = (unsigned long) data;
+	u8 result;
+	bool hw_blocked;
+	bool sw_blocked;
+
+	ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
+
+	hw_blocked = !(result & (KILLSWITCH_MASK | radio));
+	sw_blocked = rfkill_set_hw_state(rfkill, hw_blocked);
+
+	rfkill_set_sw_state(rfkill, sw_blocked);
+}
+
+static int compal_rfkill_set(void *data, bool blocked)
+{
+	unsigned long radio = (unsigned long) data;
+	u8 result, value;
+
+	ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
+
+	if ((result & KILLSWITCH_MASK) == 0)
+		return -EINVAL;
+
+	if (!blocked)
+		value = (u8) (result | radio);
+	else
+		value = (u8) (result & ~radio);
+	ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
+
+	return 0;
+}
+
+static const struct rfkill_ops compal_rfkill_ops = {
+	.poll = compal_rfkill_poll,
+	.set_block = compal_rfkill_set,
+};
+
+static int setup_rfkill(void)
+{
+	int ret;
+
+	wifi_rfkill = rfkill_alloc("compal-wifi", &compal_device->dev, 
+				RFKILL_TYPE_WLAN, &compal_rfkill_ops, 
+				(void *) WLAN_MASK);
+	if (!wifi_rfkill)
+		return -ENOMEM;
+
+	ret = rfkill_register(wifi_rfkill);
+	if (ret)
+		goto err_wifi;
+
+	bt_rfkill = rfkill_alloc("compal-bluetooth", &compal_device->dev, 
+				RFKILL_TYPE_BLUETOOTH, &compal_rfkill_ops, 
+				(void *) BT_MASK);
+	if (!bt_rfkill) {
+		ret = -ENOMEM;
+		goto err_allocate_bt;
+	}
+	ret = rfkill_register(bt_rfkill);
+	if (ret)
+		goto err_register_bt;
+
+	return 0;
+
+err_register_bt:
+	rfkill_destroy(bt_rfkill);
+
+err_allocate_bt:
+	rfkill_unregister(wifi_rfkill);
+
+err_wifi:
+	rfkill_destroy(wifi_rfkill);
+
+	return ret;
+}
+
 static int set_wlan_state(int state)
 {
 	u8 result, value;
@@ -258,8 +341,6 @@
 	}
 };
 
-static struct platform_device *compal_device;
-
 /* Initialization */
 
 static int dmi_check_cb(const struct dmi_system_id *id)
@@ -397,6 +478,10 @@
 	if (ret)
 		goto fail_platform_device2;
 
+	ret = setup_rfkill();
+	if (ret)
+		printk(KERN_WARNING "compal-laptop: Unable to setup rfkill\n");
+
 	printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION
 		" successfully loaded.\n");
 
@@ -428,6 +513,10 @@
 	platform_device_unregister(compal_device);
 	platform_driver_unregister(&compal_driver);
 	backlight_device_unregister(compalbl_device);
+	rfkill_unregister(wifi_rfkill);
+	rfkill_destroy(wifi_rfkill);
+	rfkill_unregister(bt_rfkill);
+	rfkill_destroy(bt_rfkill);
 
 	printk(KERN_INFO "compal-laptop: driver unloaded.\n");
 }

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

^ permalink raw reply

* bug? sme.c:610 __cfg80211_disconnected
From: ASIC Felix @ 2009-08-18 22:14 UTC (permalink / raw)
  To: linux-wireless

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

Hi,

found three of these in dmesg, wireless-testing kernel master-2009-08-18

wlan0: deauthenticating by local choice (reason=3)
------------[ cut here ]------------
WARNING: at net/wireless/sme.c:610 __cfg80211_disconnected+0x1bc/0x210
[cfg80211]()
Hardware name: 1875DLU
deauth failed: -67

Any ideas? Seems relatively recent, complete trace in attachment.

Cheers,
Felix

[-- Attachment #2: dmesg_sme.txt --]
[-- Type: text/plain, Size: 5064 bytes --]

th9k: RX filter 0x0 bssid 00:0b:85:6f:20:8c aid 0x0
ath9k: BSS Changed PREAMBLE 1
ath9k: BSS Changed ASSOC 1
ath9k: Bss Info ASSOC 13, bssid: 00:0b:85:6f:20:8c
ath9k: Set HW Key
ath9k: Set HW Key
ath9k: Set HW RX filter: 0x0
ath9k: Set HW RX filter: 0x0
ath9k: Set HW RX filter: 0x0
ath9k: Set HW RX filter: 0x0
ath9k: Set HW RX filter: 0x0
ath9k: Set HW RX filter: 0x0
ath9k: Set HW Key
ath9k: Set HW Key
ath9k: Set HW Key
ath9k: Set HW Key
wlan0: deauthenticated from 00:0b:85:6f:20:8c (Reason: 1)
ath9k: Configure tx [queue/halq] [0/3],  aifs: 2, cw_min: 3, cw_max: 7, txop: 47
ath9k: Configure tx [queue/halq] [1/2],  aifs: 2, cw_min: 7, cw_max: 15, txop: 94
ath9k: Configure tx [queue/halq] [2/1],  aifs: 3, cw_min: 15, cw_max: 1023, txop: 0
ath9k: Configure tx [queue/halq] [3/0],  aifs: 7, cw_min: 15, cw_max: 1023, txop: 0
ath9k: BSS Changed PREAMBLE 0
ath9k: BSS Changed CTS PROT 0
ath9k: BSS Changed ASSOC 0
ath9k: Bss Info DISASSOC
ath9k: Set HW Key
wlan0: deauthenticating by local choice (reason=3)
------------[ cut here ]------------
WARNING: at net/wireless/sme.c:610 __cfg80211_disconnected+0x1bc/0x210 [cfg80211]()
Hardware name: 1875DLU
deauth failed: -67
Modules linked in: xt_time xt_connlimit xt_realm iptable_raw xt_comment ipt_ULOG ipt_REJECT ipt_REDIRECT ipt_NETMAP ipt_MASQUERADE ipt_LOG ipt_ECN ipt_ecn ipt_ah ipt_addrtype nf_nat_tftp nf_nat_snmp_basic nf_nat_sip nf_nat_pptp nf_nat_proto_gre nf_nat_irc nf_nat_h323 nf_nat_ftp nf_nat_amanda ts_kmp nf_conntrack_amanda nf_conntrack_tftp nf_conntrack_sip nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_netlink nf_conntrack_netbios_ns nf_conntrack_irc nf_conntrack_h323 nf_conntrack_ftp xt_tcpmss xt_recent xt_pkttype xt_physdev xt_owner xt_NFQUEUE xt_NFLOG nfnetlink_log xt_multiport xt_MARK xt_mark xt_mac xt_limit xt_length xt_iprange xt_helper xt_hashlimit xt_DSCP xt_dscp xt_dccp xt_conntrack xt_CONNMARK xt_connmark xt_CLASSIFY xt_tcpudp xt_state iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack aes_i586 aes_generic iptable_mangle nfnetlink iptable_filter ip_tables x_tables i915 drm i2c_algo_bit af_packet bridge stp llc bnep sco rfcomm l2cap bluetooth ipv6 binfmt_misc loop fuse cpufreq_ondemand cpufreq_conservative cpufreq_powersave acpi_cpufreq freq_table snd_intel8x0 arc4 snd_ac97_codec ac97_bus ecb snd_seq_dummy ath9k mac80211 snd_seq_oss snd_seq_midi_event ath cfg80211 snd_seq snd_seq_device snd_pcm_oss snd_pcm snd_timer snd_mixer_oss thinkpad_acpi tg3 processor intel_agp snd ac soundcore thermal rfkill led_class button sg joydev iTCO_wdt iTCO_vendor_support ehci_hcd video output i2c_i801 i2c_core libphy yenta_socket rsrc_nonstatic pcmcia_core snd_page_alloc battery agpgart nvram nsc_ircc irda pcspkr sr_mod evdev rtc_cmos uhci_hcd crc_ccitt usbcore ata_generic ide_pci_generic ide_gd_mod ide_core pata_acpi ata_piix ahci libata sd_mod scsi_mod crc_t10dif ext3 jbd
Pid: 1186, comm: phy0 Tainted: G   M       2.6.31-rc6-wl-mnbStrip-31586-g80289f0 #65
Call Trace:
 [<f82b56ac>] ? __cfg80211_disconnected+0x1bc/0x210 [cfg80211]
 [<f82b56ac>] ? __cfg80211_disconnected+0x1bc/0x210 [cfg80211]
 [<c013c53c>] warn_slowpath_common+0x6c/0xc0
 [<f82b56ac>] ? __cfg80211_disconnected+0x1bc/0x210 [cfg80211]
 [<c013c5d6>] warn_slowpath_fmt+0x26/0x30
 [<f82b56ac>] __cfg80211_disconnected+0x1bc/0x210 [cfg80211]
 [<f82b1bf1>] ? nl80211_send_deauth+0x21/0x30 [cfg80211]
 [<f82b2dfc>] __cfg80211_send_deauth+0x21c/0x260 [cfg80211]
 [<f83d02c0>] ? ieee80211_set_disassoc+0x180/0x1e0 [mac80211]
 [<f82b2e9e>] cfg80211_send_deauth+0x5e/0x70 [cfg80211]
 [<f83d1feb>] ieee80211_sta_work+0xa0b/0x1850 [mac80211]
 [<c01412d8>] ? tasklet_action+0x58/0xc0
 [<c017d988>] ? handle_IRQ_event+0x58/0x140
 [<c011bf3e>] ? ack_apic_level+0x7e/0x270
 [<c01300c0>] ? rq_online_rt+0x50/0x70
 [<c0138745>] ? dequeue_task_fair+0x295/0x2a0
 [<c0128a2e>] ? dequeue_task+0x10e/0x160
 [<c010256a>] ? __switch_to+0xba/0x1a0
 [<c0133296>] ? finish_task_switch+0x56/0xc0
 [<c03a9af4>] ? schedule+0x4a4/0xa50
 [<c015377a>] ? prepare_to_wait+0x3a/0x70
 [<c014edd1>] worker_thread+0x141/0x210
 [<f83d15e0>] ? ieee80211_sta_work+0x0/0x1850 [mac80211]
 [<c0153530>] ? autoremove_wake_function+0x0/0x50
 [<c014ec90>] ? worker_thread+0x0/0x210
 [<c01531dc>] kthread+0x7c/0x90
 [<c0153160>] ? kthread+0x0/0x90
 [<c0104657>] kernel_thread_helper+0x7/0x10
---[ end trace fbfa3ea19c5aff5f ]---
ath9k: Set HW Key
ath9k: Set HW RX filter: 0x10
ath9k: Set channel: 2412 MHz
ath9k: tx chmask: 1, rx chmask: 1
ath9k: (2462 MHz) -> (2412 MHz), chanwidth: 0
ath9k: Set channel: 2417 MHz
ath9k: tx chmask: 1, rx chmask: 1
ath9k: (2412 MHz) -> (2417 MHz), chanwidth: 0
ath9k: Set channel: 2422 MHz
ath9k: tx chmask: 1, rx chmask: 1
ath9k: (2417 MHz) -> (2422 MHz), chanwidth: 0
ath9k: Set channel: 2427 MHz
ath9k: tx chmask: 1, rx chmask: 1
ath9k: (2422 MHz) -> (2427 MHz), chanwidth: 0
ath9k: Set channel: 2432 MHz
ath9k: tx chmask: 1, rx chmask: 1
ath9k: (2427 MHz) -> (2432 MHz), chanwidth: 0
ath9k: Set channel: 2437 MHz
ath9k: tx chmask: 1, rx chmask: 1
ath9k: (2432 MHz) -> (2437 MHz), chanwidth: 0


^ permalink raw reply

* [PATCH] ar9170: refactor configure_filter
From: Christian Lamparter @ 2009-08-18 23:26 UTC (permalink / raw)
  To: linux-wireless; +Cc: John Linville

Thanks to "mac80211: allow configure_filter callback to sleep",
we no longer have to defer the work to the workqueue.

Signed-off-by: Christian Lamparter <chunkeey@web.de>
---
please test!
---
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index e6c3ee3..9c4d43c 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -184,10 +184,8 @@ struct ar9170 {
 	bool disable_offload;
 
 	/* filter settings */
-	struct work_struct filter_config_work;
-	u64 cur_mc_hash, want_mc_hash;
-	u32 cur_filter, want_filter;
-	unsigned long filter_changed;
+	u64 cur_mc_hash;
+	u32 cur_filter;
 	unsigned int filter_state;
 	bool sniffer_enabled;
 
@@ -261,10 +259,6 @@ struct ar9170_tx_info {
 #define IS_STARTED(a)		(((struct ar9170 *)a)->state >= AR9170_STARTED)
 #define IS_ACCEPTING_CMD(a)	(((struct ar9170 *)a)->state >= AR9170_IDLE)
 
-#define AR9170_FILTER_CHANGED_MODE		BIT(0)
-#define AR9170_FILTER_CHANGED_MULTICAST		BIT(1)
-#define AR9170_FILTER_CHANGED_FRAMEFILTER	BIT(2)
-
 /* exported interface */
 void *ar9170_alloc(size_t priv_size);
 int ar9170_register(struct ar9170 *ar, struct device *pdev);
@@ -278,8 +272,8 @@ int ar9170_nag_limiter(struct ar9170 *ar);
 int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
 int ar9170_init_mac(struct ar9170 *ar);
 int ar9170_set_qos(struct ar9170 *ar);
-int ar9170_update_multicast(struct ar9170 *ar);
-int ar9170_update_frame_filter(struct ar9170 *ar);
+int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
+int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter);
 int ar9170_set_operating_mode(struct ar9170 *ar);
 int ar9170_set_beacon_timers(struct ar9170 *ar);
 int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
index d9f1f46..6004936 100644
--- a/drivers/net/wireless/ath/ar9170/mac.c
+++ b/drivers/net/wireless/ath/ar9170/mac.c
@@ -238,39 +238,31 @@ static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
 	return ar9170_regwrite_result();
 }
 
-int ar9170_update_multicast(struct ar9170 *ar)
+int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
 {
 	int err;
 
 	ar9170_regwrite_begin(ar);
-	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H,
-		ar->want_mc_hash >> 32);
-	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L,
-		ar->want_mc_hash);
-
+	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
+	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
 	ar9170_regwrite_finish();
 	err = ar9170_regwrite_result();
-
 	if (err)
 		return err;
 
-	ar->cur_mc_hash = ar->want_mc_hash;
-
+	ar->cur_mc_hash = mc_hash;
 	return 0;
 }
 
-int ar9170_update_frame_filter(struct ar9170 *ar)
+int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter)
 {
 	int err;
 
-	err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER,
-			       ar->want_filter);
-
+	err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, filter);
 	if (err)
 		return err;
 
-	ar->cur_filter = ar->want_filter;
-
+	ar->cur_filter = filter;
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 6a9462e..0d91f43 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -1232,8 +1232,6 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
 
 	mutex_lock(&ar->mutex);
 
-	ar->filter_changed = 0;
-
 	/* reinitialize queues statistics */
 	memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
 	for (i = 0; i < __AR9170_NUM_TXQ; i++)
@@ -1296,7 +1294,6 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
 #ifdef CONFIG_AR9170_LEDS
 	cancel_delayed_work_sync(&ar->led_work);
 #endif
-	cancel_work_sync(&ar->filter_config_work);
 	cancel_work_sync(&ar->beacon_work);
 
 	mutex_lock(&ar->mutex);
@@ -1973,8 +1970,7 @@ static int ar9170_op_add_interface(struct ieee80211_hw *hw,
 	}
 
 	ar->cur_filter = 0;
-	ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
-	err = ar9170_update_frame_filter(ar);
+	err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
 	if (err)
 		goto unlock;
 
@@ -1992,8 +1988,7 @@ static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
 
 	mutex_lock(&ar->mutex);
 	ar->vif = NULL;
-	ar->want_filter = 0;
-	ar9170_update_frame_filter(ar);
+	ar9170_update_frame_filter(ar, 0);
 	ar9170_set_beacon_timers(ar);
 	dev_kfree_skb(ar->beacon);
 	ar->beacon = NULL;
@@ -2065,41 +2060,6 @@ out:
 	return err;
 }
 
-static void ar9170_set_filters(struct work_struct *work)
-{
-	struct ar9170 *ar = container_of(work, struct ar9170,
-					 filter_config_work);
-	int err;
-
-	if (unlikely(!IS_STARTED(ar)))
-		return ;
-
-	mutex_lock(&ar->mutex);
-	if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
-			       &ar->filter_changed)) {
-		err = ar9170_set_operating_mode(ar);
-		if (err)
-			goto unlock;
-	}
-
-	if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST,
-			       &ar->filter_changed)) {
-		err = ar9170_update_multicast(ar);
-		if (err)
-			goto unlock;
-	}
-
-	if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
-			       &ar->filter_changed)) {
-		err = ar9170_update_frame_filter(ar);
-		if (err)
-			goto unlock;
-	}
-
-unlock:
-	mutex_unlock(&ar->mutex);
-}
-
 static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
 				       struct dev_addr_list *mclist)
 {
@@ -2126,6 +2086,11 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
 {
 	struct ar9170 *ar = hw->priv;
 
+	if (unlikely(!IS_STARTED(ar)))
+		return ;
+
+	mutex_lock(&ar->mutex);
+
 	/* mask supported flags */
 	*new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
 		      FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
@@ -2136,12 +2101,10 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
 	 */
 
 	if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
-			multicast = ~0ULL;
+		multicast = ~0ULL;
 
-	if (multicast != ar->want_mc_hash) {
-		ar->want_mc_hash = multicast;
-		set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
-	}
+	if (multicast != ar->cur_mc_hash)
+		ar9170_update_multicast(ar, multicast);
 
 	if (changed_flags & FIF_CONTROL) {
 		u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
@@ -2152,24 +2115,21 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
 			     AR9170_MAC_REG_FTF_CFE_ACK;
 
 		if (*new_flags & FIF_CONTROL)
-			ar->want_filter = ar->cur_filter | filter;
+			filter |= ar->cur_filter;
 		else
-			ar->want_filter = ar->cur_filter & ~filter;
+			filter &= (~ar->cur_filter);
 
-		set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
-			&ar->filter_changed);
+		ar9170_update_frame_filter(ar, filter);
 	}
 
 	if (changed_flags & FIF_PROMISC_IN_BSS) {
 		ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
-		set_bit(AR9170_FILTER_CHANGED_MODE,
-			&ar->filter_changed);
+		ar9170_set_operating_mode(ar);
 	}
 
-	if (likely(IS_STARTED(ar)))
-		ieee80211_queue_work(ar->hw, &ar->filter_config_work);
+	mutex_unlock(&ar->mutex);
 }
 
 static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
 				       struct ieee80211_vif *vif,
 				       struct ieee80211_bss_conf *bss_conf,
@@ -2423,9 +2384,6 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw,
 	default:
 		break;
 	}
-
-	if (IS_STARTED(ar) && ar->filter_changed)
-		ieee80211_queue_work(ar->hw, &ar->filter_config_work);
 }
 
 static int ar9170_get_stats(struct ieee80211_hw *hw,
@@ -2596,7 +2554,6 @@ void *ar9170_alloc(size_t priv_size)
 		skb_queue_head_init(&ar->tx_pending[i]);
 	}
 	ar9170_rx_reset_rx_mpdu(ar);
-	INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
 	INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
 	INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
 	INIT_LIST_HEAD(&ar->tx_ampdu_list);

^ permalink raw reply related

* Re: pull request: wireless-2.6 2009-08-18
From: David Miller @ 2009-08-18 23:29 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20090818151436.GA2768@tuxdriver.com>

From: "John W. Linville" <linville@tuxdriver.com>
Date: Tue, 18 Aug 2009 11:14:37 -0400

> Dave,
> 
> Two more for 2.6.31...
> 
> The one from Johannes is actually already in net-next-2.6, but it has
> since been reported to cause a possible irq lock inversion dependency in
> 2.6.31-rc6, as described here:
> 
> 	http://marc.info/?l=linux-wireless&m=125052198303537&w=2
> 
> The one from me fixes a minor bounds checking problem in orinoco, as
> reported by Dan Carpenter.  It is simple and obvious.

Pulled, thanks John.

^ permalink raw reply

* Re: [PATCH] Don't build PCMCIA modules when PCMCIA isn't present
From: Luis R. Rodriguez @ 2009-08-18 23:34 UTC (permalink / raw)
  To: Philip A. Prindeville; +Cc: John Linville, wireless, Pavel Roskin
In-Reply-To: <4A864BB1.8020307@redfish-solutions.com>

On Fri, Aug 14, 2009 at 10:46 PM, Philip A.
Prindeville<philipp@redfish-solutions.com> wrote:
> From: Philip A Prindeville <philipp@redfish-solutions.com>
>
> If you're building for a platform that has (for example) no PCMCIA/
> Cardbus, then having a single knob to turn to disable this is a
> major win.  Especially if more devices get add later that are
> PCMCIA-based.

Applied, thanks Phillip.

  Luis

^ permalink raw reply

* Re: [ANN] b43 LP-PHY support (BCM4310/4312/4315) now ready for testing!
From: Luis R. Rodriguez @ 2009-08-18 23:41 UTC (permalink / raw)
  To: Gábor Stefanik; +Cc: Broadcom Wireless, linux-wireless, linux-kernel
In-Reply-To: <69e28c910908181329r4b6b7cc8w3c9c0d79dda3730c@mail.gmail.com>

2009/8/18 Gábor Stefanik <netrolller.3d@gmail.com>:
> Hello World!
>
> Great news for Broadcom BCM4310/4312/4315 (PCI 14e4:4315) users:
> LP-PHY support is now at the point where it can be tested for functionality!

Hey great stuff :)

> There are still problems with channel switching (a few patches ago,
> only 802.11b/g channels 7 and 8 were working - no tests have been
> performed since then) & TX is untested, but Larry has reported that he
> can get scan results from channels 7 and 8. He doesn't have any AP on
> these channels, so can't test if association works, but it should be
> working too. It's also possible that recent patches have fixed the
> channel switching bug, as the codepaths for channel switching have
> been touched extensively, probably fixing a major miscalculation issue
> ("Qdiv roundup" was completely wrong).
>
> So, go ahead, give it a try, and let's rock!
>
> Note that the code in wireless-testing is enough to start testing,
> however it's recommended that you apply the following 2 pending fixes:
> http://marc.info/?l=linux-wireless&m=125061590101156&w=2 and
> http://marc.info/?l=linux-wireless&m=125062611720517&w=2
>
> Tomorrow's compat-wireless tarball, together with the above patches,
> should also be good for testing. Not sure about today's tarball.

Except CONFIG_B43_PHY_LP was not enabled on compat-wireless. But now
it is. I kicked the cronjob and enabled CONFIG_B43_PHY_LP on
config.mk, please report any issues.

http://wireless.kernel.org/en/users/Download/

BTW I think it would be nice for those users looking only for b43 for
us to update scripts/driver-select to have b43 as just one driver
option. Should be easy to add but I don't have time right now. Patch
is greatly welcomed though.

  Luis

^ permalink raw reply

* Re: [ANN] b43 LP-PHY support (BCM4310/4312/4315) now ready for testing!
From: Luis R. Rodriguez @ 2009-08-18 23:42 UTC (permalink / raw)
  To: Gábor Stefanik; +Cc: Broadcom Wireless, linux-wireless, linux-kernel
In-Reply-To: <43e72e890908181641s2455e7f1me9b4d3bc277f197e@mail.gmail.com>

2009/8/18 Luis R. Rodriguez <mcgrof@gmail.com>:
> 2009/8/18 Gábor Stefanik <netrolller.3d@gmail.com>:
>> Hello World!
>>
>> Great news for Broadcom BCM4310/4312/4315 (PCI 14e4:4315) users:
>> LP-PHY support is now at the point where it can be tested for functionality!
>
> Hey great stuff :)
>
>> There are still problems with channel switching (a few patches ago,
>> only 802.11b/g channels 7 and 8 were working - no tests have been
>> performed since then) & TX is untested, but Larry has reported that he
>> can get scan results from channels 7 and 8. He doesn't have any AP on
>> these channels, so can't test if association works, but it should be
>> working too. It's also possible that recent patches have fixed the
>> channel switching bug, as the codepaths for channel switching have
>> been touched extensively, probably fixing a major miscalculation issue
>> ("Qdiv roundup" was completely wrong).
>>
>> So, go ahead, give it a try, and let's rock!
>>
>> Note that the code in wireless-testing is enough to start testing,
>> however it's recommended that you apply the following 2 pending fixes:
>> http://marc.info/?l=linux-wireless&m=125061590101156&w=2 and
>> http://marc.info/?l=linux-wireless&m=125062611720517&w=2
>>
>> Tomorrow's compat-wireless tarball, together with the above patches,
>> should also be good for testing. Not sure about today's tarball.
>
> Except CONFIG_B43_PHY_LP was not enabled on compat-wireless. But now
> it is. I kicked the cronjob and enabled CONFIG_B43_PHY_LP on
> config.mk, please report any issues.
>
> http://wireless.kernel.org/en/users/Download/


Oh and I forgot the release info:

Origin remote URL:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
git-describe for wireless-testing.git says: v2.6.31-rc6-31586-g80289f0
This is a bleeding edge compat-wireless release based on: master-2009-08-18
This is compat-release: master-2009-08-18

  Luis

^ permalink raw reply

* [PATCH] cfg80211: fix leaks of wdev->conn->ie
From: David Kilroy @ 2009-08-18 23:43 UTC (permalink / raw)
  To: linux-wireless; +Cc: David Kilroy, Johannes Berg

This only occurs in the following error situations:
 - driver calls connect_result with failure
 - error scheduling authentication on connect
 - error initiating scan (to get BSSID and channel) on
   connect
 - userspace calls disconnect while in the SCANNING or
   SCAN_AGAIN states

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
---

I came across this while looking at my orinoco scanning issue. It's
possible I'm wrong...

---

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

diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 6fb6a70..9ddc00e 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -395,6 +395,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
 
 	if (status != WLAN_STATUS_SUCCESS) {
 		wdev->sme_state = CFG80211_SME_IDLE;
+		if (wdev->conn)
+			kfree(wdev->conn->ie);
 		kfree(wdev->conn);
 		wdev->conn = NULL;
 		kfree(wdev->connect_keys);
@@ -779,6 +781,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
 			}
 		}
 		if (err) {
+			kfree(wdev->conn->ie);
 			kfree(wdev->conn);
 			wdev->conn = NULL;
 			wdev->sme_state = CFG80211_SME_IDLE;
@@ -848,6 +851,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
 		    (wdev->conn->state == CFG80211_CONN_SCANNING ||
 		     wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)) {
 			wdev->sme_state = CFG80211_SME_IDLE;
+			kfree(wdev->conn->ie);
 			kfree(wdev->conn);
 			wdev->conn = NULL;
 			wdev->ssid_len = 0;
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH] orinoco: remove spare whitespace
From: David Kilroy @ 2009-08-18 23:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: David Kilroy

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---

Noticed while investigating false positive sparse complaint.
Really trivial.

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

diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 3e56f76..7698fdd 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -1291,7 +1291,7 @@ static int orinoco_ioctl_setibssport(struct net_device *dev,
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
 
-	priv->ibss_port = val ;
+	priv->ibss_port = val;
 
 	/* Actually update the mode we are using */
 	set_port_type(priv);
-- 
1.6.3.3


^ permalink raw reply related

* [RFC v2 0/5] orinoco: use cfg80211 for key manipulation
From: David Kilroy @ 2009-08-19  0:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy

This series basically works (at least after the last patch is applied)
with wpa_supplicant in wext mode.

I had tested with wpa_supplicant in nl80211 mode, but hadn't realised
it wasn't using connect - I'll need to pick up Zhu Yis' patch and redo
some testing.

Anyway, the nl80211 interface has a small hole which patch 5 partially
papers over. I'm not that happy with the way it hijacks the AUTH/ASSOC
state machine, but it works.

Other outstanding issues:
 - It looks like I haven't quite got the connect_roamed callback right:
   I've got a WARNING I need to investigate in my logs
 - On disconnecting and reconnecting the card I have to restart
   wpa_supplicant for things to work. I'm guessing I have to look at
   driver shutdown, and ensure we send a disconnected event.

Dave.

---
David Kilroy (5):
  orinoco: add cfg80211 connect and disconnect
  orinoco: add cfg80211 join_ibss and leave_ibss
  orinoco: implement cfg80211 key manipulation functions
  orinoco: do WE via cfg80211
  cfg80211: scan before connect if we don't have the bss

 drivers/net/wireless/orinoco/cfg.c     |  497 ++++++++++++++++++++++
 drivers/net/wireless/orinoco/main.c    |  172 +++++----
 drivers/net/wireless/orinoco/orinoco.h |    1 +
 drivers/net/wireless/orinoco/wext.c    |  726 +-------------------------------
 net/wireless/sme.c                     |  150 +++++--
 5 files changed, 717 insertions(+), 829 deletions(-)


^ permalink raw reply

* [RFC 1/5] orinoco: add cfg80211 connect and disconnect
From: David Kilroy @ 2009-08-19  0:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy
In-Reply-To: <1250640253-18434-1-git-send-email-kilroyd@googlemail.com>

Basic station mode support.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/cfg.c     |  244 ++++++++++++++++++++++++++++++++
 drivers/net/wireless/orinoco/main.c    |  164 ++++++++++++----------
 drivers/net/wireless/orinoco/orinoco.h |    1 +
 3 files changed, 333 insertions(+), 76 deletions(-)

diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 27f2d33..09b38e9 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -196,8 +196,252 @@ static int orinoco_set_channel(struct wiphy *wiphy,
 	return err;
 }
 
+/* Helper to ensure all keys are valid for the current encoding
+   algorithm */
+static void orinoco_set_encoding(struct orinoco_private *priv,
+				 enum orinoco_alg encoding)
+{
+	if (priv->encode_alg &&
+	    priv->encode_alg != encoding) {
+		int i;
+
+		for (i = 0; i < ORINOCO_MAX_KEYS; i++) {
+			kfree(priv->keys[i].key);
+			kfree(priv->keys[i].seq);
+			priv->keys[i].key = NULL;
+			priv->keys[i].seq = NULL;
+			priv->keys[i].key_len = 0;
+			priv->keys[i].seq_len = 0;
+			priv->keys[i].cipher = 0;
+		}
+
+		if (priv->encode_alg == ORINOCO_ALG_TKIP &&
+		    priv->has_wpa) {
+			(void) orinoco_clear_tkip_key(priv, i);
+			(void) orinoco_clear_tkip_key(priv, i);
+			(void) orinoco_clear_tkip_key(priv, i);
+			(void) orinoco_clear_tkip_key(priv, i);
+		} else if (priv->encode_alg == ORINOCO_ALG_WEP)
+			__orinoco_hw_setup_wepkeys(priv);
+	}
+	priv->encode_alg = encoding;
+}
+
+/* Helper routine to record keys
+ * Do not call from interrupt context */
+static int orinoco_set_key(struct orinoco_private *priv, int index,
+			   enum orinoco_alg alg, const u8 *key, int key_len,
+			   const u8 *seq, int seq_len)
+{
+	kzfree(priv->keys[index].key);
+	kzfree(priv->keys[index].seq);
+
+	if (key_len) {
+		priv->keys[index].key = kzalloc(key_len, GFP_KERNEL);
+		if (!priv->keys[index].key)
+			goto nomem;
+	} else
+		priv->keys[index].key = NULL;
+
+	if (seq_len) {
+		priv->keys[index].seq = kzalloc(seq_len, GFP_KERNEL);
+		if (!priv->keys[index].seq)
+			goto free_key;
+	} else
+		priv->keys[index].seq = NULL;
+
+	priv->keys[index].key_len = key_len;
+	priv->keys[index].seq_len = seq_len;
+
+	if (key_len)
+		memcpy(priv->keys[index].key, key, key_len);
+	if (seq_len)
+		memcpy(priv->keys[index].seq, seq, seq_len);
+
+
+	switch (alg) {
+	case ORINOCO_ALG_TKIP:
+		priv->keys[index].cipher = WLAN_CIPHER_SUITE_TKIP;
+		break;
+
+	case ORINOCO_ALG_WEP:
+		priv->keys[index].cipher = (key_len > SMALL_KEY_SIZE) ?
+			WLAN_CIPHER_SUITE_WEP104 : WLAN_CIPHER_SUITE_WEP40;
+		break;
+
+	case ORINOCO_ALG_NONE:
+	default:
+		priv->keys[index].cipher = 0;
+		break;
+	}
+
+	return 0;
+
+free_key:
+	kfree(priv->keys[index].key);
+	priv->keys[index].key = NULL;
+
+nomem:
+	priv->keys[index].key_len = 0;
+	priv->keys[index].seq_len = 0;
+	priv->keys[index].cipher = 0;
+
+	return -ENOMEM;
+}
+
+/* Setup channel, SSID and BSSID */
+static int __orinoco_connect(struct wiphy *wiphy,
+			     struct ieee80211_channel *channel,
+			     const u8 *bssid, const u8 *ssid,
+			     u8 ssid_len)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+
+	if (channel) {
+		int chan;
+
+		chan = ieee80211_freq_to_dsss_chan(channel->center_freq);
+
+		if ((chan > 0) && (chan < NUM_CHANNELS) &&
+		    (priv->channel_mask & (1 << chan)))
+			priv->channel = chan;
+	}
+
+	memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
+	if (ssid)
+		memcpy(priv->desired_essid, ssid, ssid_len);
+
+	if (bssid) {
+		/* Intersil firmware hangs if you try to roam manually
+		 * without an SSID set. We should always get one in
+		 * this call, but just check.
+		 */
+		BUG_ON(ssid_len == 0);
+
+		memcpy(priv->desired_bssid, bssid, ETH_ALEN);
+		priv->bssid_fixed = 1;
+	} else {
+		memset(priv->desired_bssid, 0, ETH_ALEN);
+		priv->bssid_fixed = 0;
+	}
+
+	return 0;
+}
+
+static int orinoco_connect(struct wiphy *wiphy, struct net_device *dev,
+			   struct cfg80211_connect_params *sme)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	enum orinoco_alg encode_alg;
+	unsigned long lock;
+	int err;
+
+	if (orinoco_lock(priv, &lock) != 0)
+		return -EBUSY;
+
+	/* Setup the requested parameters in priv. If the card is not
+	 * capable, then the driver will just ignore the settings that
+	 * it can't do. */
+	err = __orinoco_connect(wiphy, sme->channel, sme->bssid,
+				sme->ssid, sme->ssid_len);
+	if (err)
+		goto out;
+
+	switch (sme->auth_type) {
+	case NL80211_AUTHTYPE_OPEN_SYSTEM:
+		priv->wep_restrict = 0;
+		break;
+	case NL80211_AUTHTYPE_SHARED_KEY:
+		priv->wep_restrict = 1;
+		break;
+	default:
+		/* Can't handle anything else */
+		err = -EINVAL;
+		goto out;
+	}
+
+	switch (sme->crypto.cipher_group) {
+	case WLAN_CIPHER_SUITE_TKIP:
+		encode_alg = ORINOCO_ALG_TKIP;
+		priv->wpa_enabled = 1;
+		break;
+
+	case WLAN_CIPHER_SUITE_WEP40:
+	case WLAN_CIPHER_SUITE_WEP104:
+		encode_alg = ORINOCO_ALG_WEP;
+		priv->wpa_enabled = 0;
+		break;
+
+	default:
+		encode_alg = ORINOCO_ALG_NONE;
+		priv->wpa_enabled = 0;
+	}
+
+	orinoco_set_encoding(priv, encode_alg);
+
+	/* What are we supposed to do with multiple AKM suites? */
+	if (sme->crypto.n_akm_suites > 0)
+		priv->key_mgmt = sme->crypto.akm_suites[0] & 7;
+
+	/* Finally, set WEP key */
+	if (encode_alg == ORINOCO_ALG_WEP) {
+		err = orinoco_set_key(priv, sme->key_idx, encode_alg,
+				      &sme->key[0], sme->key_len, NULL, 0);
+		if (err)
+			goto out;
+
+		priv->tx_key = sme->key_idx;
+	}
+
+	/* Enable cfg80211 notification */
+	priv->connect_commanded = 1;
+
+	err = orinoco_commit(priv);
+
+out:
+	orinoco_unlock(priv, &lock);
+
+	return err;
+}
+
+static int orinoco_disconnect(struct wiphy *wiphy, struct net_device *dev,
+			      u16 reason_code)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	unsigned long lock;
+	u8 addr[ETH_ALEN];
+	int err;
+
+	if (orinoco_lock(priv, &lock) != 0)
+		return -EBUSY;
+
+	memset(priv->desired_bssid, 0, ETH_ALEN);
+	memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
+
+	err = orinoco_hw_get_current_bssid(priv, &addr[0]);
+
+	if (!err) {
+		err = orinoco_hw_disassociate(priv, &addr[0],
+					      reason_code);
+	}
+
+	priv->wpa_enabled = 0;
+
+	/* Disable cfg80211 notification */
+	priv->connect_commanded = 0;
+
+	if (err)
+		err = orinoco_commit(priv);
+
+	orinoco_unlock(priv, &lock);
+
+	return err;
+}
+
 const struct cfg80211_ops orinoco_cfg_ops = {
 	.change_virtual_intf = orinoco_change_vif,
 	.set_channel = orinoco_set_channel,
 	.scan = orinoco_scan,
+	.connect = orinoco_connect,
+	.disconnect = orinoco_disconnect,
 };
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 2c7dc65..5542173 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -1188,98 +1188,109 @@ static void orinoco_join_ap(struct work_struct *work)
 	kfree(buf);
 }
 
-/* Send new BSSID to userspace */
-static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
-{
-	struct net_device *dev = priv->ndev;
-	struct hermes *hw = &priv->hw;
-	union iwreq_data wrqu;
-	int err;
-
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
-			      ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
-	if (err != 0)
-		return;
-
-	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-
-	/* Send event to user space */
-	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
-}
-
-static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
+static void orinoco_send_wevents(struct work_struct *work)
 {
-	struct net_device *dev = priv->ndev;
-	struct hermes *hw = &priv->hw;
-	union iwreq_data wrqu;
+	struct orinoco_private *priv =
+		container_of(work, struct orinoco_private, wevent_work);
+	hermes_t *hw = &priv->hw;
+	unsigned long flags;
+	u8 req_buf[88];
+	u8 resp_buf[88];
+	u8 bssid[ETH_ALEN];
+	size_t req_len = 0;
+	size_t resp_len = 0;
+	u8 *req_ie = NULL;
+	u8 *resp_ie = NULL;
+	enum nl80211_iftype  iw_mode;
+	u16 linkstatus;
 	int err;
-	u8 buf[88];
-	u8 *ie;
 
-	if (!priv->has_wpa)
+	if (orinoco_lock(priv, &flags) != 0)
 		return;
 
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
-			      sizeof(buf), NULL, &buf);
-	if (err != 0)
-		return;
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
+			      ETH_ALEN, NULL, &bssid[0]);
+	if (err)
+		goto out;
 
-	ie = orinoco_get_wpa_ie(buf, sizeof(buf));
-	if (ie) {
-		int rem = sizeof(buf) - (ie - &buf[0]);
-		wrqu.data.length = ie[1] + 2;
-		if (wrqu.data.length > rem)
-			wrqu.data.length = rem;
+	if (priv->has_wpa) {
+		err = hermes_read_ltv(hw, USER_BAP,
+				      HERMES_RID_CURRENT_ASSOC_REQ_INFO,
+				      sizeof(req_buf), NULL, &req_buf);
+		if (!err) {
+			req_ie = orinoco_get_wpa_ie(req_buf,
+						    sizeof(req_buf));
+			if (req_ie) {
+				int rem = sizeof(req_buf) -
+					(req_ie - &req_buf[0]);
+				req_len = req_ie[1] + 2;
+				if (req_len > rem)
+					req_len = rem;
+			}
+		}
 
-		if (wrqu.data.length)
-			/* Send event to user space */
-			wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
+		err = hermes_read_ltv(hw, USER_BAP,
+				      HERMES_RID_CURRENT_ASSOC_RESP_INFO,
+				      sizeof(resp_buf), NULL, &resp_buf);
+		if (!err) {
+			resp_ie = orinoco_get_wpa_ie(resp_buf,
+						     sizeof(resp_buf));
+			if (resp_ie) {
+				int rem = sizeof(resp_buf) -
+					(resp_ie - &resp_buf[0]);
+				resp_len = resp_ie[1] + 2;
+				if (resp_len > rem)
+					resp_len = rem;
+			}
+		}
 	}
-}
-
-static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
-{
-	struct net_device *dev = priv->ndev;
-	struct hermes *hw = &priv->hw;
-	union iwreq_data wrqu;
-	int err;
-	u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
-	u8 *ie;
 
-	if (!priv->has_wpa)
-		return;
+	iw_mode = priv->iw_mode;
+	linkstatus = priv->last_linkstatus;
 
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
-			      sizeof(buf), NULL, &buf);
-	if (err != 0)
-		return;
+	if (!priv->connect_commanded)
+		goto out;
 
-	ie = orinoco_get_wpa_ie(buf, sizeof(buf));
-	if (ie) {
-		int rem = sizeof(buf) - (ie - &buf[0]);
-		wrqu.data.length = ie[1] + 2;
-		if (wrqu.data.length > rem)
-			wrqu.data.length = rem;
+	orinoco_unlock(priv, &flags);
 
-		if (wrqu.data.length)
-			/* Send event to user space */
-			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
-	}
-}
+	switch (iw_mode) {
+	case NL80211_IFTYPE_STATION:
 
-static void orinoco_send_wevents(struct work_struct *work)
-{
-	struct orinoco_private *priv =
-		container_of(work, struct orinoco_private, wevent_work);
-	unsigned long flags;
+		switch (linkstatus) {
+		case HERMES_LINKSTATUS_CONNECTED:
+		case HERMES_LINKSTATUS_AP_IN_RANGE:
+			cfg80211_connect_result(priv->ndev, bssid,
+						req_ie, req_len,
+						resp_ie, resp_len,
+						WLAN_STATUS_SUCCESS,
+						GFP_KERNEL);
+			break;
 
-	if (orinoco_lock(priv, &flags) != 0)
-		return;
+		case HERMES_LINKSTATUS_DISCONNECTED:
+		case HERMES_LINKSTATUS_NOT_CONNECTED:
+		case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
+		case HERMES_LINKSTATUS_AP_CHANGE:
+			cfg80211_roamed(priv->ndev, bssid, req_ie, req_len,
+					resp_ie, resp_len, GFP_KERNEL);
+			break;
 
-	orinoco_send_assocreqie_wevent(priv);
-	orinoco_send_assocrespie_wevent(priv);
-	orinoco_send_bssid_wevent(priv);
+		case HERMES_LINKSTATUS_ASSOC_FAILED:
+			cfg80211_connect_result(priv->ndev, bssid,
+						req_ie, req_len,
+						resp_ie, resp_len,
+						WLAN_STATUS_ASSOC_DENIED_UNSPEC,
+						GFP_KERNEL);
+			break;
+		}
+		break;
+	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_MONITOR:
+	default:
+		break;
+	}
 
+	return;
+ out:
 	orinoco_unlock(priv, &flags);
 }
 
@@ -2050,6 +2061,7 @@ int orinoco_init(struct orinoco_private *priv)
 	set_port_type(priv);
 	priv->channel = 0; /* use firmware default */
 
+	priv->connect_commanded = 0;
 	priv->promiscuous = 0;
 	priv->encode_alg = ORINOCO_ALG_NONE;
 	priv->tx_key = 0;
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 9ac6f1d..57ce581 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -78,6 +78,7 @@ struct orinoco_private {
 
 	/* driver state */
 	int open;
+	int connect_commanded;
 	u16 last_linkstatus;
 	struct work_struct join_work;
 	struct work_struct wevent_work;
-- 
1.6.3.3


^ permalink raw reply related

* [RFC 2/5] orinoco: add cfg80211 join_ibss and leave_ibss
From: David Kilroy @ 2009-08-19  0:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: orinoco-devel, David Kilroy
In-Reply-To: <1250640253-18434-1-git-send-email-kilroyd@googlemail.com>

Basic ad-hoc support.

Signed-off-by: David Kilroy <kilroyd@googlemail.com>
---
 drivers/net/wireless/orinoco/cfg.c  |   57 +++++++++++++++++++++++++++++++++++
 drivers/net/wireless/orinoco/main.c |   12 +++++++
 2 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 09b38e9..253cb4e 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -438,10 +438,67 @@ static int orinoco_disconnect(struct wiphy *wiphy, struct net_device *dev,
 	return err;
 }
 
+static int orinoco_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+			     struct cfg80211_ibss_params *params)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	unsigned long lock;
+	int err;
+
+	if (orinoco_lock(priv, &lock) != 0)
+		return -EBUSY;
+
+	/* Setup the requested parameters in priv. If the card is not
+	 * capable, then the driver will just ignore the settings that
+	 * it can't do. */
+
+	err = __orinoco_connect(wiphy, params->channel, params->bssid,
+				params->ssid, params->ssid_len);
+	if (err)
+		goto out;
+
+	/* Ignore information elements and beacon interval */
+
+	/* Enable cfg80211 notification */
+	priv->connect_commanded = 1;
+
+	err = orinoco_commit(priv);
+ out:
+	orinoco_unlock(priv, &lock);
+
+	return err;
+}
+
+static int orinoco_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	unsigned long lock;
+	int err;
+
+	if (orinoco_lock(priv, &lock) != 0)
+		return -EBUSY;
+
+	/* Do we need to disassociate as well? */
+
+	memset(priv->desired_bssid, 0, ETH_ALEN);
+	memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
+
+	/* Disable cfg80211 notification */
+	priv->connect_commanded = 0;
+
+	err = orinoco_commit(priv);
+
+	orinoco_unlock(priv, &lock);
+
+	return err;
+}
+
 const struct cfg80211_ops orinoco_cfg_ops = {
 	.change_virtual_intf = orinoco_change_vif,
 	.set_channel = orinoco_set_channel,
 	.scan = orinoco_scan,
 	.connect = orinoco_connect,
 	.disconnect = orinoco_disconnect,
+	.join_ibss = orinoco_join_ibss,
+	.leave_ibss = orinoco_leave_ibss,
 };
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 5542173..78ef22e 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -1283,7 +1283,19 @@ static void orinoco_send_wevents(struct work_struct *work)
 			break;
 		}
 		break;
+
 	case NL80211_IFTYPE_ADHOC:
+		switch (linkstatus) {
+		case HERMES_LINKSTATUS_CONNECTED:
+		case HERMES_LINKSTATUS_AP_IN_RANGE:
+			cfg80211_ibss_joined(priv->ndev, bssid, GFP_KERNEL);
+			break;
+
+		default:
+			break;
+		}
+		break;
+
 	case NL80211_IFTYPE_MONITOR:
 	default:
 		break;
-- 
1.6.3.3


^ 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