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

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

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

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?

johannes

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

^ permalink raw reply

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

On Tuesday 18 August 2009, Johannes Berg wrote:
> On Tue, 2009-08-18 at 19:54 +0200, Ivo van Doorn wrote:
> > The configure_filter() callback function no longer needs
> > to be atomic. Remove the scheduled work structure and
> > call into the driver configure_filter() directly.
> 
> Nice, yeah, I didn't want to do that myself :)
> 
> 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. ;)

Ivo

^ permalink raw reply

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

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

On Tue, 2009-08-18 at 19:54 +0200, Ivo van Doorn wrote:
> The configure_filter() callback function no longer needs
> to be atomic. Remove the scheduled work structure and
> call into the driver configure_filter() directly.

Nice, yeah, I didn't want to do that myself :)

Speaking of which -- bss_info_changed can sleep too, which means you can
remove DRIVER_REQUIRE_SCHEDULED completely I think?

johannes

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

^ permalink raw reply

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

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

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00.h    |    1 -
 drivers/net/wireless/rt2x00/rt2x00dev.c |   10 ----------
 drivers/net/wireless/rt2x00/rt2x00mac.c |    5 +----
 3 files changed, 1 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 39d7d9b..ad70946 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -826,7 +826,6 @@ struct rt2x00_dev {
 	 * due to RTNL locking requirements.
 	 */
 	struct work_struct intf_work;
-	struct work_struct filter_work;
 
 	/*
 	 * Data queue arrays for RX, TX and Beacon.
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 9ab70e4..16b560a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -118,14 +118,6 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
 		rt2x00link_start_tuner(rt2x00dev);
 }
 
-static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
-{
-	struct rt2x00_dev *rt2x00dev =
-	    container_of(work, struct rt2x00_dev, filter_work);
-
-	rt2x00dev->ops->lib->config_filter(rt2x00dev, rt2x00dev->packet_filter);
-}
-
 static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
 					  struct ieee80211_vif *vif)
 {
@@ -859,7 +851,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 	 * Initialize configuration work.
 	 */
 	INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
-	INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
 
 	/*
 	 * Allocate queue array.
@@ -907,7 +898,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Stop all work.
 	 */
-	cancel_work_sync(&rt2x00dev->filter_work);
 	cancel_work_sync(&rt2x00dev->intf_work);
 
 	/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 3011aea..967d3b5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -430,10 +430,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
 		return;
 	rt2x00dev->packet_filter = *total_flags;
 
-	if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
-		rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
-	else
-		ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->filter_work);
+	rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
 
-- 
1.6.4


^ permalink raw reply related

* [PATCH] cfg80211: fix dangling scan request checking
From: Johannes Berg @ 2009-08-18 17:51 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

My patch "cfg80211: fix deadlock" broke the code it
was supposed to fix, the scan request checking. But
it's not trivial to put it back the way it was, since
the original patch had a deadlock.

Now do it in a completely new way: queue the check
off to a work struct, where we can freely lock. But
that has some more complications, like needing to
wait for it to be done before the wiphy/rdev can be
destroyed, so some code is required to handle that.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h |    2 +
 net/wireless/core.c    |   76 ++++++++++++++++++++++++++++++++++++++++---------
 net/wireless/core.h    |    2 +
 3 files changed, 67 insertions(+), 13 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-08-18 19:38:28.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-08-18 19:38:37.000000000 +0200
@@ -1325,6 +1325,8 @@ struct wireless_dev {
 
 	struct mutex mtx;
 
+	struct work_struct cleanup_work;
+
 	/* currently used for IBSS and SME - might be rearranged later */
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
 	u8 ssid_len;
--- wireless-testing.orig/net/wireless/core.c	2009-08-18 19:38:28.000000000 +0200
+++ wireless-testing/net/wireless/core.c	2009-08-18 19:38:29.000000000 +0200
@@ -430,6 +430,8 @@ struct wiphy *wiphy_new(const struct cfg
 	INIT_WORK(&rdev->conn_work, cfg80211_conn_work);
 	INIT_WORK(&rdev->event_work, cfg80211_event_work);
 
+	init_waitqueue_head(&rdev->dev_wait);
+
 	/*
 	 * Initialize wiphy parameters to IEEE 802.11 MIB default values.
 	 * Fragmentation and RTS threshold are disabled by default with the
@@ -574,7 +576,23 @@ void wiphy_unregister(struct wiphy *wiph
 	/* protect the device list */
 	mutex_lock(&cfg80211_mutex);
 
+	wait_event(rdev->dev_wait, ({
+		int __count;
+		mutex_lock(&rdev->devlist_mtx);
+		__count = rdev->opencount;
+		mutex_unlock(&rdev->devlist_mtx);
+		__count == 0;}));
+
+	mutex_lock(&rdev->devlist_mtx);
 	BUG_ON(!list_empty(&rdev->netdev_list));
+	mutex_unlock(&rdev->devlist_mtx);
+
+	/*
+	 * First remove the hardware from everywhere, this makes
+	 * it impossible to find from userspace.
+	 */
+	cfg80211_debugfs_rdev_del(rdev);
+	list_del(&rdev->list);
 
 	/*
 	 * Try to grab rdev->mtx. If a command is still in progress,
@@ -582,26 +600,18 @@ void wiphy_unregister(struct wiphy *wiph
 	 * down the device already. We wait for this command to complete
 	 * before unlinking the item from the list.
 	 * Note: as codified by the BUG_ON above we cannot get here if
-	 * a virtual interface is still associated. Hence, we can only
-	 * get to lock contention here if userspace issues a command
-	 * that identified the hardware by wiphy index.
+	 * a virtual interface is still present. Hence, we can only get
+	 * to lock contention here if userspace issues a command that
+	 * identified the hardware by wiphy index.
 	 */
 	cfg80211_lock_rdev(rdev);
-
-	if (WARN_ON(rdev->scan_req)) {
-		rdev->scan_req->aborted = true;
-		___cfg80211_scan_done(rdev);
-	}
-
+	/* nothing */
 	cfg80211_unlock_rdev(rdev);
 
-	cfg80211_debugfs_rdev_del(rdev);
-
 	/* If this device got a regulatory hint tell core its
 	 * free to listen now to a new shiny device regulatory hint */
 	reg_device_remove(wiphy);
 
-	list_del(&rdev->list);
 	cfg80211_rdev_list_generation++;
 	device_del(&rdev->wiphy.dev);
 	debugfs_remove(rdev->wiphy.debugfsdir);
@@ -640,6 +650,31 @@ void wiphy_rfkill_set_hw_state(struct wi
 }
 EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);
 
+static void wdev_cleanup_work(struct work_struct *work)
+{
+	struct wireless_dev *wdev;
+	struct cfg80211_registered_device *rdev;
+
+	wdev = container_of(work, struct wireless_dev, cleanup_work);
+	rdev = wiphy_to_dev(wdev->wiphy);
+
+	cfg80211_lock_rdev(rdev);
+
+	if (WARN_ON(rdev->scan_req && rdev->scan_req->dev == wdev->netdev)) {
+		rdev->scan_req->aborted = true;
+		___cfg80211_scan_done(rdev);
+	}
+
+	cfg80211_unlock_rdev(rdev);
+
+	mutex_lock(&rdev->devlist_mtx);
+	rdev->opencount--;
+	mutex_unlock(&rdev->devlist_mtx);
+	wake_up(&rdev->dev_wait);
+
+	dev_put(wdev->netdev);
+}
+
 static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
 					 unsigned long state,
 					 void *ndev)
@@ -663,6 +698,7 @@ static int cfg80211_netdev_notifier_call
 		 * are added with nl80211.
 		 */
 		mutex_init(&wdev->mtx);
+		INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work);
 		INIT_LIST_HEAD(&wdev->event_list);
 		spin_lock_init(&wdev->event_lock);
 		mutex_lock(&rdev->devlist_mtx);
@@ -717,8 +753,22 @@ static int cfg80211_netdev_notifier_call
 		default:
 			break;
 		}
+		dev_hold(dev);
+		schedule_work(&wdev->cleanup_work);
 		break;
 	case NETDEV_UP:
+		/*
+		 * If we have a really quick DOWN/UP succession we may
+		 * have this work still pending ... cancel it and see
+		 * if it was pending, in which case we need to account
+		 * for some of the work it would have done.
+		 */
+		if (cancel_work_sync(&wdev->cleanup_work)) {
+			mutex_lock(&rdev->devlist_mtx);
+			rdev->opencount--;
+			mutex_unlock(&rdev->devlist_mtx);
+			dev_put(dev);
+		}
 #ifdef CONFIG_WIRELESS_EXT
 		cfg80211_lock_rdev(rdev);
 		mutex_lock(&rdev->devlist_mtx);
@@ -734,6 +784,7 @@ static int cfg80211_netdev_notifier_call
 			break;
 		}
 		wdev_unlock(wdev);
+		rdev->opencount++;
 		mutex_unlock(&rdev->devlist_mtx);
 		cfg80211_unlock_rdev(rdev);
 #endif
@@ -756,7 +807,6 @@ static int cfg80211_netdev_notifier_call
 			sysfs_remove_link(&dev->dev.kobj, "phy80211");
 			list_del_init(&wdev->list);
 			rdev->devlist_generation++;
-			mutex_destroy(&wdev->mtx);
 #ifdef CONFIG_WIRELESS_EXT
 			kfree(wdev->wext.keys);
 #endif
--- wireless-testing.orig/net/wireless/core.h	2009-08-18 19:38:28.000000000 +0200
+++ wireless-testing/net/wireless/core.h	2009-08-18 19:38:29.000000000 +0200
@@ -50,6 +50,8 @@ struct cfg80211_registered_device {
 	struct mutex devlist_mtx;
 	struct list_head netdev_list;
 	int devlist_generation;
+	int opencount; /* also protected by devlist_mtx */
+	wait_queue_head_t dev_wait;
 
 	/* BSSes/scanning */
 	spinlock_t bss_lock;



^ permalink raw reply

* [PATCH] ipw2x00: fix sparse warnings
From: Reinette Chatre @ 2009-08-18 17:25 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Reinette Chatre, Zhu Yi

From: Reinette Chatre <reinette.chatre@intel.com>

This fixes:

  CHECK   drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/ipw2x00/ipw2100.c:7888:22: warning: symbol 'mode' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2100.c:188:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2100.c:7952:18: warning: symbol 'mode' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2100.c:188:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2100.c:8000:18: warning: symbol 'mode' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2100.c:188:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2100.c:8268:27: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2100.c:8268:27: originally declared here
drivers/net/wireless/ipw2x00/ipw2100.c:8268:27: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2100.c:8268:27: originally declared here
drivers/net/wireless/ipw2x00/ipw2100.c:8268:27: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2100.c:8268:27: originally declared here
  CC [M]  drivers/net/wireless/ipw2x00/ipw2100.o
  CHECK   drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/ipw2x00/ipw2200.c:847:13: warning: symbol 'led' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:92:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:891:13: warning: symbol 'led' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:92:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:935:13: warning: symbol 'led' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:92:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:980:13: warning: symbol 'led' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:92:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:1016:13: warning: symbol 'led' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:92:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:1051:13: warning: symbol 'led' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:92:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:1823:13: warning: symbol 'channel' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:86:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min1' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: warning: symbol '_min2' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:4268:19: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:6228:28: warning: symbol 'channel' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:86:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:6369:20: warning: symbol 'channel' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:86:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:6857:12: warning: symbol 'mode' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:87:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:7964:13: warning: symbol 'channel' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:86:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:8720:12: warning: symbol 'channel' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:86:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:9662:13: warning: symbol 'mode' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:87:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:9720:13: warning: symbol 'mode' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:87:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:9826:13: warning: symbol 'mode' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:87:12: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:10318:21: warning: symbol 'remaining_bytes' shadows an earlier one
drivers/net/wireless/ipw2x00/ipw2200.c:10184:13: originally declared here
drivers/net/wireless/ipw2x00/ipw2200.c:8338:45: warning: cast to restricted __le16
drivers/net/wireless/ipw2x00/ipw2200.c:4414:21: warning: incorrect type in assignment (different base types)
drivers/net/wireless/ipw2x00/ipw2200.c:4414:21:    expected restricted __le16 [usertype] size
drivers/net/wireless/ipw2x00/ipw2200.c:4414:21:    got unsigned short [unsigned] [usertype] <noident>
drivers/net/wireless/ipw2x00/ipw2200.c:6105:33: warning: incorrect type in initializer (different base types)
drivers/net/wireless/ipw2x00/ipw2200.c:6105:33:    expected restricted __le16 [usertype] tx_rates
drivers/net/wireless/ipw2x00/ipw2200.c:6105:33:    got unsigned short [unsigned] [usertype] rates_mask
drivers/net/wireless/ipw2x00/ipw2200.c:6124:29: warning: bad assignment (>>=) to restricted __le16
drivers/net/wireless/ipw2x00/ipw2200.c:6130:31: warning: restricted __le16 degrades to integer
drivers/net/wireless/ipw2x00/ipw2200.c:6140:23: warning: restricted __le16 degrades to integer
drivers/net/wireless/ipw2x00/ipw2200.c:6149:54: warning: restricted __le16 degrades to integer
drivers/net/wireless/ipw2x00/ipw2200.c:6151:37: warning: invalid assignment: &=
drivers/net/wireless/ipw2x00/ipw2200.c:6151:37:    left side has type restricted __le16
drivers/net/wireless/ipw2x00/ipw2200.c:6151:37:    right side has type int
drivers/net/wireless/ipw2x00/ipw2200.c:6154:54: warning: restricted __le16 degrades to integer
drivers/net/wireless/ipw2x00/ipw2200.c:6156:37: warning: invalid assignment: &=
drivers/net/wireless/ipw2x00/ipw2200.c:6156:37:    left side has type restricted __le16
drivers/net/wireless/ipw2x00/ipw2200.c:6156:37:    right side has type int
drivers/net/wireless/ipw2x00/ipw2200.c:6159:55: warning: restricted __le16 degrades to integer
drivers/net/wireless/ipw2x00/ipw2200.c:6161:37: warning: invalid assignment: &=
drivers/net/wireless/ipw2x00/ipw2200.c:6161:37:    left side has type restricted __le16
drivers/net/wireless/ipw2x00/ipw2200.c:6161:37:    right side has type int
drivers/net/wireless/ipw2x00/ipw2200.c:6164:29: warning: invalid assignment: |=
drivers/net/wireless/ipw2x00/ipw2200.c:6164:29:    left side has type restricted __le16
drivers/net/wireless/ipw2x00/ipw2200.c:6164:29:    right side has type unsigned short
drivers/net/wireless/ipw2x00/ipw2200.c:7853:29: warning: incorrect type in assignment (different base types)
drivers/net/wireless/ipw2x00/ipw2200.c:7853:29:    expected signed char [signed] [usertype] [explicitly-signed] rt_dbmnoise
drivers/net/wireless/ipw2x00/ipw2200.c:7853:29:    got restricted __le16 [usertype] noise
drivers/net/wireless/ipw2x00/ipw2200.c:7967:25: warning: incorrect type in initializer (different base types)
drivers/net/wireless/ipw2x00/ipw2200.c:7967:25:    expected signed char [signed] [usertype] [explicitly-signed] noise
drivers/net/wireless/ipw2x00/ipw2200.c:7967:25:    got restricted __le16 [usertype] noise

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Cc: Zhu Yi <yi.zhu@intel.com>
Acked-by: Zhu Yi <yi.zhu@intel.com>
---
After this patch one warning remains:

include/net/inet_sock.h:208:17: warning: do-while statement is not a compound statement

This has already been addressed by upstream patch discussed at
http://thread.gmane.org/gmane.linux.kernel/861983

 drivers/net/wireless/ipw2x00/ipw2100.c |   14 ++++---
 drivers/net/wireless/ipw2x00/ipw2200.c |   73 ++++++++++++++++----------------
 2 files changed, 44 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 7424323..dee50ed 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -185,7 +185,7 @@ MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
 static int debug = 0;
-static int mode = 0;
+static int network_mode = 0;
 static int channel = 0;
 static int associate = 0;
 static int disable = 0;
@@ -195,7 +195,7 @@ static struct ipw2100_fw ipw2100_firmware;
 
 #include <linux/moduleparam.h>
 module_param(debug, int, 0444);
-module_param(mode, int, 0444);
+module_param_named(mode, network_mode, int, 0444);
 module_param(channel, int, 0444);
 module_param(associate, int, 0444);
 module_param(disable, int, 0444);
@@ -2844,7 +2844,7 @@ static int __ipw2100_tx_process(struct ipw2100_priv *priv)
 
 #ifdef CONFIG_IPW2100_DEBUG
 	{
-		int i = txq->oldest;
+		i = txq->oldest;
 		IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
 			     &txq->drv[i],
 			     (u32) (txq->nic + i * sizeof(struct ipw2100_bd)),
@@ -6076,7 +6076,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
 	priv->ieee->ieee802_1x = 1;
 
 	/* Set module parameters */
-	switch (mode) {
+	switch (network_mode) {
 	case 1:
 		priv->ieee->iw_mode = IW_MODE_ADHOC;
 		break;
@@ -8179,10 +8179,11 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
 	int rssi_qual;
 	int tx_qual;
 	int beacon_qual;
+	int quality;
 
 	struct ipw2100_priv *priv = ieee80211_priv(dev);
 	struct iw_statistics *wstats;
-	u32 rssi, quality, tx_retries, missed_beacons, tx_failures;
+	u32 rssi, tx_retries, missed_beacons, tx_failures;
 	u32 ord_len = sizeof(u32);
 
 	if (!priv)
@@ -8265,7 +8266,8 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
 			beacon_qual = (20 - missed_beacons) *
 			    (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
 
-		quality = min(beacon_qual, min(tx_qual, rssi_qual));
+		quality = min(tx_qual, rssi_qual);
+		quality = min(beacon_qual, quality);
 
 #ifdef CONFIG_IPW2100_DEBUG
 		if (beacon_qual == quality)
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 07f171c..8e18d53 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -83,13 +83,13 @@ MODULE_LICENSE("GPL");
 
 static int cmdlog = 0;
 static int debug = 0;
-static int channel = 0;
-static int mode = 0;
+static int default_channel = 0;
+static int network_mode = 0;
 
 static u32 ipw_debug_level;
 static int associate;
 static int auto_create = 1;
-static int led = 0;
+static int led_support = 0;
 static int disable = 0;
 static int bt_coexist = 0;
 static int hwcrypto = 0;
@@ -4265,9 +4265,10 @@ static void ipw_gather_stats(struct ipw_priv *priv)
 	IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
 			signal_quality, rssi);
 
-	quality = min(beacon_quality,
-		      min(rate_quality,
-			  min(tx_quality, min(rx_quality, signal_quality))));
+	quality = min(rx_quality, signal_quality);
+	quality = min(tx_quality, quality);
+	quality = min(rate_quality, quality);
+	quality = min(beacon_quality, quality);
 	if (quality == beacon_quality)
 		IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n",
 				quality);
@@ -4411,7 +4412,6 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 {
 	DECLARE_SSID_BUF(ssid);
 	u16 size = le16_to_cpu(notif->size);
-	notif->size = le16_to_cpu(notif->size);
 
 	IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size);
 
@@ -6101,11 +6101,10 @@ static void ipw_debug_config(struct ipw_priv *priv)
 static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
 {
 	/* TODO: Verify that this works... */
-	struct ipw_fixed_rate fr = {
-		.tx_rates = priv->rates_mask
-	};
+	struct ipw_fixed_rate fr;
 	u32 reg;
 	u16 mask = 0;
+	u16 new_tx_rates = priv->rates_mask;
 
 	/* Identify 'current FW band' and match it with the fixed
 	 * Tx rates */
@@ -6117,54 +6116,56 @@ static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
 			/* Invalid fixed rate mask */
 			IPW_DEBUG_WX
 			    ("invalid fixed rate mask in ipw_set_fixed_rate\n");
-			fr.tx_rates = 0;
+			new_tx_rates = 0;
 			break;
 		}
 
-		fr.tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A;
+		new_tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A;
 		break;
 
 	default:		/* 2.4Ghz or Mixed */
 		/* IEEE_B */
 		if (mode == IEEE_B) {
-			if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
+			if (new_tx_rates & ~IEEE80211_CCK_RATES_MASK) {
 				/* Invalid fixed rate mask */
 				IPW_DEBUG_WX
 				    ("invalid fixed rate mask in ipw_set_fixed_rate\n");
-				fr.tx_rates = 0;
+				new_tx_rates = 0;
 			}
 			break;
 		}
 
 		/* IEEE_G */
-		if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
+		if (new_tx_rates & ~(IEEE80211_CCK_RATES_MASK |
 				    IEEE80211_OFDM_RATES_MASK)) {
 			/* Invalid fixed rate mask */
 			IPW_DEBUG_WX
 			    ("invalid fixed rate mask in ipw_set_fixed_rate\n");
-			fr.tx_rates = 0;
+			new_tx_rates = 0;
 			break;
 		}
 
-		if (IEEE80211_OFDM_RATE_6MB_MASK & fr.tx_rates) {
+		if (IEEE80211_OFDM_RATE_6MB_MASK & new_tx_rates) {
 			mask |= (IEEE80211_OFDM_RATE_6MB_MASK >> 1);
-			fr.tx_rates &= ~IEEE80211_OFDM_RATE_6MB_MASK;
+			new_tx_rates &= ~IEEE80211_OFDM_RATE_6MB_MASK;
 		}
 
-		if (IEEE80211_OFDM_RATE_9MB_MASK & fr.tx_rates) {
+		if (IEEE80211_OFDM_RATE_9MB_MASK & new_tx_rates) {
 			mask |= (IEEE80211_OFDM_RATE_9MB_MASK >> 1);
-			fr.tx_rates &= ~IEEE80211_OFDM_RATE_9MB_MASK;
+			new_tx_rates &= ~IEEE80211_OFDM_RATE_9MB_MASK;
 		}
 
-		if (IEEE80211_OFDM_RATE_12MB_MASK & fr.tx_rates) {
+		if (IEEE80211_OFDM_RATE_12MB_MASK & new_tx_rates) {
 			mask |= (IEEE80211_OFDM_RATE_12MB_MASK >> 1);
-			fr.tx_rates &= ~IEEE80211_OFDM_RATE_12MB_MASK;
+			new_tx_rates &= ~IEEE80211_OFDM_RATE_12MB_MASK;
 		}
 
-		fr.tx_rates |= mask;
+		new_tx_rates |= mask;
 		break;
 	}
 
+	fr.tx_rates = cpu_to_le16(new_tx_rates);
+
 	reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE);
 	ipw_write_reg32(priv, reg, *(u32 *) & fr);
 }
@@ -7850,7 +7851,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
 
 	/* Convert signal to DBM */
 	ipw_rt->rt_dbmsignal = antsignal;
-	ipw_rt->rt_dbmnoise = frame->noise;
+	ipw_rt->rt_dbmnoise = (s8) le16_to_cpu(frame->noise);
 
 	/* Convert the channel data and set the flags */
 	ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
@@ -7964,7 +7965,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
 	u16 channel = frame->received_channel;
 	u8 phy_flags = frame->antennaAndPhy;
 	s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM;
-	s8 noise = frame->noise;
+	s8 noise = (s8) le16_to_cpu(frame->noise);
 	u8 rate = frame->rate;
 	short len = le16_to_cpu(pkt->u.frame.length);
 	struct sk_buff *skb;
@@ -8335,7 +8336,7 @@ static void ipw_rx(struct ipw_priv *priv)
 					.rssi = pkt->u.frame.rssi_dbm -
 					    IPW_RSSI_TO_DBM,
 					.signal =
-					    le16_to_cpu(pkt->u.frame.rssi_dbm) -
+					    pkt->u.frame.rssi_dbm -
 					    IPW_RSSI_TO_DBM + 0x100,
 					.noise =
 					    le16_to_cpu(pkt->u.frame.noise),
@@ -8517,7 +8518,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
 
 	/* We default to disabling the LED code as right now it causes
 	 * too many systems to lock up... */
-	if (!led)
+	if (!led_support)
 		priv->config |= CFG_NO_LED;
 
 	if (associate)
@@ -8539,10 +8540,10 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
 		IPW_DEBUG_INFO("Radio disabled.\n");
 	}
 
-	if (channel != 0) {
+	if (default_channel != 0) {
 		priv->config |= CFG_STATIC_CHANNEL;
-		priv->channel = channel;
-		IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
+		priv->channel = default_channel;
+		IPW_DEBUG_INFO("Bind to static channel %d\n", default_channel);
 		/* TODO: Validate that provided channel is in range */
 	}
 #ifdef CONFIG_IPW2200_QOS
@@ -8550,7 +8551,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
 		     burst_duration_CCK, burst_duration_OFDM);
 #endif				/* CONFIG_IPW2200_QOS */
 
-	switch (mode) {
+	switch (network_mode) {
 	case 1:
 		priv->ieee->iw_mode = IW_MODE_ADHOC;
 		priv->net_dev->type = ARPHRD_ETHER;
@@ -10181,7 +10182,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
 #endif
 	struct clx2_queue *q = &txq->q;
 	u8 id, hdr_len, unicast;
-	u16 remaining_bytes;
 	int fc;
 
 	if (!(priv->status & STATUS_ASSOCIATED))
@@ -10220,7 +10220,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
 
 	tfd->u.data.cmd_id = DINO_CMD_TX;
 	tfd->u.data.len = cpu_to_le16(txb->payload_size);
-	remaining_bytes = txb->payload_size;
 
 	if (priv->assoc_request.ieee_mode == IPW_B_MODE)
 		tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
@@ -11946,13 +11945,13 @@ MODULE_PARM_DESC(associate, "auto associate when scanning (default off)");
 module_param(auto_create, int, 0444);
 MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
 
-module_param(led, int, 0444);
+module_param_named(led, led_support, int, 0444);
 MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)");
 
 module_param(debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
 
-module_param(channel, int, 0444);
+module_param_named(channel, default_channel, int, 0444);
 MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
 
 #ifdef CONFIG_IPW2200_PROMISCUOUS
@@ -11978,10 +11977,10 @@ MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
 #endif				/* CONFIG_IPW2200_QOS */
 
 #ifdef CONFIG_IPW2200_MONITOR
-module_param(mode, int, 0444);
+module_param_named(mode, network_mode, int, 0444);
 MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
 #else
-module_param(mode, int, 0444);
+module_param_named(mode, network_mode, int, 0444);
 MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
 #endif
 
-- 
1.5.6.3


^ permalink raw reply related

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

Larry has started re-checking all current routines against a new
version of the Broadcom MIPS driver. This patch implements the first
round of changes he documented on the specs wiki.

Also remove a few FIXMEs regarding missing initial values for variables
with dynamic initial values where reading the values has been implemented.

Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
---
 drivers/net/wireless/b43/phy_lp.c       |   98 +++++++++++++++++++------------
 drivers/net/wireless/b43/phy_lp.h       |   18 +++---
 drivers/net/wireless/b43/tables_lpphy.c |   12 ++++-
 3 files changed, 82 insertions(+), 46 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 242338f..6c69cdb 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -719,9 +719,39 @@ static void lpphy_set_bb_mult(struct b43_wldev *dev, u8 bb_mult)
 	b43_lptab_write(dev, B43_LPTAB16(0, 87), (u16)bb_mult << 8);
 }
 
-static void lpphy_disable_crs(struct b43_wldev *dev)
+static void lpphy_set_deaf(struct b43_wldev *dev, bool user)
 {
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+
+	if (user)
+		lpphy->crs_usr_disable = 1;
+	else
+		lpphy->crs_sys_disable = 1;
 	b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x80);
+}
+
+static void lpphy_clear_deaf(struct b43_wldev *dev, bool user)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+
+	if (user)
+		lpphy->crs_usr_disable = 0;
+	else
+		lpphy->crs_sys_disable = 0;
+
+	if (!lpphy->crs_usr_disable && !lpphy->crs_sys_disable) {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+			b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL,
+					0xFF1F, 0x60);
+		else
+			b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL,
+					0xFF1F, 0x20);
+	}
+}
+
+static void lpphy_disable_crs(struct b43_wldev *dev, bool user)
+{
+	lpphy_set_deaf(dev, user);
 	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x1);
 	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
 	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB);
@@ -749,12 +779,9 @@ static void lpphy_disable_crs(struct b43_wldev *dev)
 	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0x3FF);
 }
 
-static void lpphy_restore_crs(struct b43_wldev *dev)
+static void lpphy_restore_crs(struct b43_wldev *dev, bool user)
 {
-	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
-		b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x60);
-	else
-		b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x20);
+	lpphy_clear_deaf(dev, user);
 	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFF80);
 	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFC00);
 }
@@ -800,10 +827,11 @@ static void lpphy_set_tx_gains(struct b43_wldev *dev,
 		b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
 				0xF800, rf_gain);
 	} else {
-		pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x7F00;
+		pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x1FC0;
+		pa_gain <<= 2;
 		b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
 			      (gains.pga << 8) | gains.gm);
-		b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
+		b43_phy_maskset(dev, B43_PHY_OFDM(0xFB),
 				0x8000, gains.pad | pa_gain);
 		b43_phy_write(dev, B43_PHY_OFDM(0xFC),
 			      (gains.pga << 8) | gains.gm);
@@ -817,7 +845,7 @@ static void lpphy_set_tx_gains(struct b43_wldev *dev,
 		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F, 1 << 7);
 		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF, 1 << 14);
 	}
-	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFFBF, 1 << 6);
+	b43_phy_maskset(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF, 1 << 6);
 }
 
 static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain)
@@ -857,33 +885,33 @@ static void lpphy_rev2plus_set_rx_gain(struct b43_wldev *dev, u32 gain)
 	}
 }
 
-static void lpphy_enable_rx_gain_override(struct b43_wldev *dev)
+static void lpphy_disable_rx_gain_override(struct b43_wldev *dev)
 {
 	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE);
 	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF);
 	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF);
 	if (dev->phy.rev >= 2) {
 		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF);
-		if (b43_current_band(dev->wl) != IEEE80211_BAND_2GHZ)
-			return;
-		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF);
-		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFFF7);
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+			b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF);
+			b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7);
+		}
 	} else {
 		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF);
 	}
 }
 
-static void lpphy_disable_rx_gain_override(struct b43_wldev *dev)
+static void lpphy_enable_rx_gain_override(struct b43_wldev *dev)
 {
 	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1);
 	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10);
 	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40);
 	if (dev->phy.rev >= 2) {
 		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100);
-		if (b43_current_band(dev->wl) != IEEE80211_BAND_2GHZ)
-			return;
-		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400);
-		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x8);
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+			b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400);
+			b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8);
+		}
 	} else {
 		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200);
 	}
@@ -1002,26 +1030,22 @@ static u32 lpphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
 {
 	u32 quotient, remainder, rbit, roundup, tmp;
 
-	if (divisor == 0) {
-		quotient = 0;
-		remainder = 0;
-	} else {
-		quotient = dividend / divisor;
-		remainder = dividend % divisor;
-	}
+	if (divisor == 0)
+		return 0;
+
+	quotient = dividend / divisor;
+	remainder = dividend % divisor;
 
 	rbit = divisor & 0x1;
 	roundup = (divisor >> 1) + rbit;
-	precision--;
 
-	while (precision != 0xFF) {
+	while (precision != 0) {
 		tmp = remainder - roundup;
 		quotient <<= 1;
-		remainder <<= 1;
-		if (remainder >= roundup) {
+		if (remainder >= roundup)
 			remainder = (tmp << 1) + rbit;
-			quotient--;
-		}
+		else
+			remainder <<= 1;
 		precision--;
 	}
 
@@ -1123,11 +1147,11 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
 	struct b43_phy_lp *lpphy = dev->phy.lp;
 	struct lpphy_iq_est iq_est;
 	struct lpphy_tx_gains tx_gains;
-	static const u32 ideal_pwr_table[22] = {
+	static const u32 ideal_pwr_table[21] = {
 		0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
 		0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
 		0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
-		0x0004c, 0x0002c, 0x0001a, 0xc0006,
+		0x0004c, 0x0002c, 0x0001a,
 	};
 	bool old_txg_ovr;
 	u8 old_bbmult;
@@ -1145,7 +1169,7 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
 		       "RC calib: Failed to switch to channel 7, error = %d",
 		       err);
 	}
-	old_txg_ovr = (b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) >> 6) & 1;
+	old_txg_ovr = !!(b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40);
 	old_bbmult = lpphy_get_bb_mult(dev);
 	if (old_txg_ovr)
 		tx_gains = lpphy_get_tx_gains(dev);
@@ -1160,7 +1184,7 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
 	old_txpctl = lpphy->txpctl_mode;
 
 	lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
-	lpphy_disable_crs(dev);
+	lpphy_disable_crs(dev, true);
 	loopback = lpphy_loopback(dev);
 	if (loopback == -1)
 		goto finish;
@@ -1193,7 +1217,7 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
 	lpphy_stop_ddfs(dev);
 
 finish:
-	lpphy_restore_crs(dev);
+	lpphy_restore_crs(dev, true);
 	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, old_rf_ovrval);
 	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, old_rf_ovr);
 	b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVRVAL, old_afe_ovrval);
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h
index 99cb038..e158d1f 100644
--- a/drivers/net/wireless/b43/phy_lp.h
+++ b/drivers/net/wireless/b43/phy_lp.h
@@ -825,11 +825,11 @@ struct b43_phy_lp {
 	enum b43_lpphy_txpctl_mode txpctl_mode;
 
 	/* Transmit isolation medium band */
-	u8 tx_isolation_med_band; /* FIXME initial value? */
+	u8 tx_isolation_med_band;
 	/* Transmit isolation low band */
-	u8 tx_isolation_low_band; /* FIXME initial value? */
+	u8 tx_isolation_low_band;
 	/* Transmit isolation high band */
-	u8 tx_isolation_hi_band; /* FIXME initial value? */
+	u8 tx_isolation_hi_band;
 
 	/* Max transmit power medium band */
 	u16 max_tx_pwr_med_band;
@@ -848,7 +848,7 @@ struct b43_phy_lp {
 	s16 txpa[3], txpal[3], txpah[3];
 
 	/* Receive power offset */
-	u8 rx_pwr_offset; /* FIXME initial value? */
+	u8 rx_pwr_offset;
 
 	/* TSSI transmit count */
 	u16 tssi_tx_count;
@@ -864,16 +864,16 @@ struct b43_phy_lp {
 	s8 tx_pwr_idx_over; /* FIXME initial value? */
 
 	/* RSSI vf */
-	u8 rssi_vf; /* FIXME initial value? */
+	u8 rssi_vf;
 	/* RSSI vc */
-	u8 rssi_vc; /* FIXME initial value? */
+	u8 rssi_vc;
 	/* RSSI gs */
-	u8 rssi_gs; /* FIXME initial value? */
+	u8 rssi_gs;
 
 	/* RC cap */
 	u8 rc_cap; /* FIXME initial value? */
 	/* BX arch */
-	u8 bx_arch; /* FIXME initial value? */
+	u8 bx_arch;
 
 	/* Full calibration channel */
 	u8 full_calib_chan; /* FIXME initial value? */
@@ -885,6 +885,8 @@ struct b43_phy_lp {
 	/* Used for "Save/Restore Dig Filt State" */
 	u16 dig_flt_state[9];
 
+	bool crs_usr_disable, crs_sys_disable;
+
 	unsigned int pdiv;
 };
 
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c
index 2721310..60d472f 100644
--- a/drivers/net/wireless/b43/tables_lpphy.c
+++ b/drivers/net/wireless/b43/tables_lpphy.c
@@ -2367,7 +2367,17 @@ static void lpphy_rev2plus_write_gain_table(struct b43_wldev *dev, int offset,
 	tmp  = data.pad << 16;
 	tmp |= data.pga << 8;
 	tmp |= data.gm;
-	tmp |= 0x7f000000;
+	if (dev->phy.rev >= 3) {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+			tmp |= 0x10 << 24;
+		else
+			tmp |= 0x70 << 24;
+	} else {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+			tmp |= 0x14 << 24;
+		else
+			tmp |= 0x7F << 24;
+	}
 	b43_lptab_write(dev, B43_LPTAB32(7, 0xC0 + offset), tmp);
 	tmp  = data.bb_mult << 20;
 	tmp |= data.dac << 28;
-- 
1.6.2.4




^ permalink raw reply related

* Re: status of AP mode in iwlwifi?
From: reinette chatre @ 2009-08-18 17:06 UTC (permalink / raw)
  To: Andrey Yurovsky; +Cc: linux-wireless
In-Reply-To: <45e8e6c40908171413s72d8a245vfab18283ae85eecf@mail.gmail.com>

Hi Andrey,

On Mon, 2009-08-17 at 14:13 -0700, Andrey Yurovsky wrote:
> Hi folks.  What's the status of AP mode in iwlwifi?  I used it some
> time in the past but I see that it's disabled in wireless-testing now.
>  Is there an issue with AP mode in this driver?  Can it be re-enabled?

Some details can be found in the patch that disabled AP mode (see
below). It cannot be re-enabled until the issues mentioned in this patch
have been addressed ... and the AP mode requirements mentioned in
http://wireless.kernel.org/en/developers/Documentation/mac80211/API
needs to be reviewed also.

commit 44b73f240da0d18a2d17afca488e8c80496d92ca
Author: Johannes Berg <johannes@sipsolutions.net>
Date:   Mon Dec 1 18:50:27 2008 +0100

    iwlwifi: disable AP mode
    
    iwlwifi does not support AP mode in any way. For one, it doesn't even
    buffer multicast/broadcast frames properly. We didn't allow zd1211rw AP
    mode to be enabled without this, so iwlwifi shouldn't be allowed to
    advertise AP mode either.
    
    It also doesn't work at all, it doesn't even answer to probe requests,
    I'm guessing the packet injection code was disabled again.
    
    Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
    Acked-by: Reinette Chatre <reinette.chatre@intel.com>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>


Reinette



^ permalink raw reply

* Re: [PATCH 1/2] rc80211_pid_algo.c: remove unused variable declaration
From: Javier Cardona @ 2009-08-18 16:46 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <1250607232-24870-1-git-send-email-linville@tuxdriver.com>

Thanks, John.

On Tue, Aug 18, 2009 at 7:53 AM, John W. Linville<linville@tuxdriver.com> wrote:
>  CC [M]  net/mac80211/rc80211_pid_algo.o
> net/mac80211/rc80211_pid_algo.c: In function ‘rate_control_pid_rate_init’:
> net/mac80211/rc80211_pid_algo.c:304: warning: unused variable ‘si’
>
> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Acked-by: Javier Cardona <javier@cozybit.com>


> ---
>  net/mac80211/rc80211_pid_algo.c |    1 -
>  1 files changed, 0 insertions(+), 1 deletions(-)
>
> diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
> index f6e25d7..699d3ed 100644
> --- a/net/mac80211/rc80211_pid_algo.c
> +++ b/net/mac80211/rc80211_pid_algo.c
> @@ -301,7 +301,6 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
>        struct rc_pid_sta_info *spinfo = priv_sta;
>        struct rc_pid_info *pinfo = priv;
>        struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
> -       struct sta_info *si;
>        int i, j, tmp;
>        bool s;
>
> --
> 1.6.2.5
>
>



-- 
Javier Cardona
cozybit Inc.
http://www.cozybit.com

^ permalink raw reply

* pull request: wireless-2.6 2009-08-18
From: John W. Linville @ 2009-08-18 15:14 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

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.

Please let me know if there are problems!

John

---

Individual patches are available here:

	http://www.kernel.org/pub/linux/kernel/people/linville/wireless-2.6/

---

The following changes since commit 8cdb045632e5ee22854538619ac6f150eb0a4894:
  Tom Goff (1):
        gre: Fix MTU calculation for bound GRE tunnels

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git master

Johannes Berg (1):
      mac80211: fix todo lock

John W. Linville (1):
      orinoco: correct key bounds check in orinoco_hw_get_tkip_iv

 drivers/net/wireless/orinoco/hw.c |    2 +-
 net/mac80211/key.c                |   28 +++++++++++++++-------------
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 632fac8..b394627 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -70,7 +70,7 @@ int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
 	int err = 0;
 	u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
 
-	if ((key < 0) || (key > 4))
+	if ((key < 0) || (key >= 4))
 		return -EINVAL;
 
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index ce26756..659a42d 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -67,6 +67,8 @@ static DECLARE_WORK(todo_work, key_todo);
  *
  * @key: key to add to do item for
  * @flag: todo flag(s)
+ *
+ * Must be called with IRQs or softirqs disabled.
  */
 static void add_todo(struct ieee80211_key *key, u32 flag)
 {
@@ -140,9 +142,9 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 	ret = drv_set_key(key->local, SET_KEY, &sdata->vif, sta, &key->conf);
 
 	if (!ret) {
-		spin_lock(&todo_lock);
+		spin_lock_bh(&todo_lock);
 		key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
-		spin_unlock(&todo_lock);
+		spin_unlock_bh(&todo_lock);
 	}
 
 	if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP)
@@ -164,12 +166,12 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
 	if (!key || !key->local->ops->set_key)
 		return;
 
-	spin_lock(&todo_lock);
+	spin_lock_bh(&todo_lock);
 	if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
-		spin_unlock(&todo_lock);
+		spin_unlock_bh(&todo_lock);
 		return;
 	}
-	spin_unlock(&todo_lock);
+	spin_unlock_bh(&todo_lock);
 
 	sta = get_sta_for_key(key);
 	sdata = key->sdata;
@@ -188,9 +190,9 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
 		       wiphy_name(key->local->hw.wiphy),
 		       key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
 
-	spin_lock(&todo_lock);
+	spin_lock_bh(&todo_lock);
 	key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
-	spin_unlock(&todo_lock);
+	spin_unlock_bh(&todo_lock);
 }
 
 static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
@@ -437,14 +439,14 @@ void ieee80211_key_link(struct ieee80211_key *key,
 
 	__ieee80211_key_replace(sdata, sta, old_key, key);
 
-	spin_unlock_irqrestore(&sdata->local->key_lock, flags);
-
 	/* free old key later */
 	add_todo(old_key, KEY_FLAG_TODO_DELETE);
 
 	add_todo(key, KEY_FLAG_TODO_ADD_DEBUGFS);
 	if (netif_running(sdata->dev))
 		add_todo(key, KEY_FLAG_TODO_HWACCEL_ADD);
+
+	spin_unlock_irqrestore(&sdata->local->key_lock, flags);
 }
 
 static void __ieee80211_key_free(struct ieee80211_key *key)
@@ -547,7 +549,7 @@ static void __ieee80211_key_todo(void)
 	 */
 	synchronize_rcu();
 
-	spin_lock(&todo_lock);
+	spin_lock_bh(&todo_lock);
 	while (!list_empty(&todo_list)) {
 		key = list_first_entry(&todo_list, struct ieee80211_key, todo);
 		list_del_init(&key->todo);
@@ -558,7 +560,7 @@ static void __ieee80211_key_todo(void)
 					  KEY_FLAG_TODO_HWACCEL_REMOVE |
 					  KEY_FLAG_TODO_DELETE);
 		key->flags &= ~todoflags;
-		spin_unlock(&todo_lock);
+		spin_unlock_bh(&todo_lock);
 
 		work_done = false;
 
@@ -591,9 +593,9 @@ static void __ieee80211_key_todo(void)
 
 		WARN_ON(!work_done);
 
-		spin_lock(&todo_lock);
+		spin_lock_bh(&todo_lock);
 	}
-	spin_unlock(&todo_lock);
+	spin_unlock_bh(&todo_lock);
 }
 
 void ieee80211_key_todo(void)
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply related

* [PATCH 2/2] wl1271: remove print_mac usage
From: John W. Linville @ 2009-08-18 14:55 UTC (permalink / raw)
  To: linux-wireless; +Cc: Luciano Coelho, John W. Linville

  CC [M]  drivers/net/wireless/wl12xx/wl1271_main.o
drivers/net/wireless/wl12xx/wl1271_main.c: In function ‘wl1271_op_add_interface’:
drivers/net/wireless/wl12xx/wl1271_main.c:611: warning: ‘print_mac’ is deprecated (declared at include/linux/if_ether.h:142)

Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
 drivers/net/wireless/wl12xx/wl1271_main.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 754be81..d9169b4 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -605,11 +605,10 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
 				   struct ieee80211_if_init_conf *conf)
 {
 	struct wl1271 *wl = hw->priv;
-	DECLARE_MAC_BUF(mac);
 	int ret = 0;
 
-	wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %s",
-		     conf->type, print_mac(mac, conf->mac_addr));
+	wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
+		     conf->type, conf->mac_addr);
 
 	mutex_lock(&wl->mutex);
 
-- 
1.6.2.5


^ permalink raw reply related

* [PATCH 1/2] rc80211_pid_algo.c: remove unused variable declaration
From: John W. Linville @ 2009-08-18 14:53 UTC (permalink / raw)
  To: linux-wireless; +Cc: Javier Cardona, John W. Linville

  CC [M]  net/mac80211/rc80211_pid_algo.o
net/mac80211/rc80211_pid_algo.c: In function ‘rate_control_pid_rate_init’:
net/mac80211/rc80211_pid_algo.c:304: warning: unused variable ‘si’

Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
 net/mac80211/rc80211_pid_algo.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index f6e25d7..699d3ed 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -301,7 +301,6 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
 	struct rc_pid_sta_info *spinfo = priv_sta;
 	struct rc_pid_info *pinfo = priv;
 	struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
-	struct sta_info *si;
 	int i, j, tmp;
 	bool s;
 
-- 
1.6.2.5


^ permalink raw reply related

* [PATCH] net: wireless: mesh: Add multicast and unicast stat counters
From: Daniel Walker @ 2009-08-18 14:02 UTC (permalink / raw)
  To: John W. Linville
  Cc: Daniel Walker, Johannes Berg, David S. Miller, John W. Linville,
	Luis R. Rodriguez, Andrey Yurovsky, Javier Cardona,
	linux-wireless, Sven-Thorsten Dietrich

I added two new stat counters to count if each forwarded frame is
either multicast or unicast. 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".

CC: Johannes Berg <johannes@sipsolutions.net>
CC: David S. Miller <davem@davemloft.net>
CC: John W. Linville <linville@tuxdriver.com>
CC: Luis R. Rodriguez <lrodriguez@atheros.com>
CC: Andrey Yurovsky <andrey@cozybit.com>
CC: Javier Cardona <javier@cozybit.com>
CC: linux-wireless@vger.kernel.org
CC: Sven-Thorsten Dietrich <sven@thebigcorporation.com>
Signed-off-by: Daniel Walker <dwalker@fifo99.com>
---
 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);
 	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);
 	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);
-- 
1.5.6.3


^ permalink raw reply related

* Re: [PATCH] b43: Fix sparse warnings
From: Michael Buesch @ 2009-08-18 13:12 UTC (permalink / raw)
  To: Pavel Roskin
  Cc: Gábor Stefanik, linux-wireless, bcm43xx-dev, Larry Finger
In-Reply-To: <1250541041.10511.10.camel@mj>

On Monday 17 August 2009 22:30:41 Pavel Roskin wrote:
> On Sat, 2009-08-15 at 12:04 +0200, Michael Buesch wrote:
> 
> > I still do not understand why it does complain about an _explicit_ truncation.
> > That's simply stupid. If I program an explicit truncation I _do_ mean to truncate the value.
> 
> Actually, it's a bug in sparse.  Sparse acts inconsistently.
> 
> This causes a warning:
> 
> void mask(unsigned short mask);
> static void test(void)
> {
>         mask((unsigned short)0xffff0000);
> }
> 
> test.c:4:30: warning: cast truncates bits from constant value (ffff0000
> becomes 0)
> 
> But this is OK:
> 
> void mask(unsigned short mask);
> static void test(void)
> {
>         mask((unsigned short)0xfffff000);
> }
> 
> Moreover, this is OK, even though the cast changes the value of the
> constant:
> 
> void mask(unsigned short mask);
> static void test(void)
> {
>         mask((unsigned short)0xfffff000U);
> }
> 
> I suggest that we take no action until sparse is fixed.  I'm going to
> report the issue to the sparse mailing list now.
> 

Cool, thanks a lot for tracking this down. :)

-- 
Greetings, Michael.

^ permalink raw reply

* Re: [PATCH 00/29] mwl8k update to version 0.10
From: Lennert Buytenhek @ 2009-08-18 10:30 UTC (permalink / raw)
  To: linville, linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20090818034942.GE18639@mail.wantstofly.org>

On Tue, Aug 18, 2009 at 05:49:42AM +0200, Lennert Buytenhek wrote:

> In this series, various mwl8k coding style cleanups, removal of the
> usage of radio_enabled, some minor bug fixes, optimisations, and
> removal of most of the driver's workqueue use.  (Against latest
> wireless-testing.)

Johannes' ->configure_filter rework and ->radio_enabled removal
caused some fallout further in my series, so I've pulled latest
wireless-testing and pushed a new queue to git.marvell.com, with
the following changes from the patch set posted to the list:

- The atomic part of ->configure_filter has been split off into
  ->prepare_multicast(), so use the latter to synthesize our multicast
  firmware command, and then post it in ->configure_filter().

- Exchange the patch that changed the ->radio_enabled check to a
  IEEE80211_CONF_IDLE check for a patch that adds a IEEE80211_CONF_IDLE
  check, since mwl8k's ->radio_enabled check is gone in current
  wireless-testing.

- The patch to switch mwl8k_configure_filter() over to queue_work()
  directly is gone since ->configure_filter() can sleep now, and it's
  been replaced by a patch that just does the firmware command
  issuing (which sleeps) directly in mwl8k_configure_filter().

All in all, this patch set is a 20% reduction in file size, without
loss of functionality.  Please consider pulling.

(A future set of patches will add AP and 11n support, but that needs
some more work still.)



The following changes since commit f0602f40fe362f4ee15aad719d5cf7021de61914:
  Bob Copeland (1):
        wl1251: correct definitions for 0th bit defines

are available in the git repository at:

  git://git.marvell.com/mwl8k.git master

Lennert Buytenhek (29):
      mwl8k: remove various unused struct members and defines
      mwl8k: s/IEEE80211_ADDR_LEN/ETH_ALEN/g
      mwl8k: sort firmware command list by opcode, and trim unused commands
      mwl8k: various coding style cleanups
      mwl8k: remove MWL8K_RADIO_* defines
      mwl8k: remove MWL8K_RADIO_*_PREAMBLE defines
      mwl8k: remove MWL8K_WMM_* defines
      mwl8k: remove MWL8K_*_SLOTTIME defines
      mwl8k: fix mwl8k_configure_filter() parameter lifetime issue
      mwl8k: ->add_interface() is not called for monitor interfaces
      mwl8k: dma header manipulations can't fail
      mwl8k: don't touch 'command done' interrupt during firmware load
      mwl8k: don't hardcode the number of transmit queues
      mwl8k: no need to hold ->tx_lock while setting the hardware interrupt mask
      mwl8k: implement rfkill
      mwl8k: mwl8k_txq_xmit() rework
      mwl8k: mwl8k_queue_work() cleanup
      mwl8k: fix firmware command serialisation
      mwl8k: get rid of mwl8k_start() workqueue use
      mwl8k: get rid of mwl8k_stop() workqueue use
      mwl8k: get rid of mwl8k_config() workqueue use
      mwl8k: get rid of mwl8k_bss_info_changed() workqueue use
      mwl8k: get rid of mwl8k_set_rts_threshold() workqueue use
      mwl8k: get rid of mwl8k_conf_tx() workqueue use
      mwl8k: get rid of mwl8k_get_stats() workqueue use
      mwl8k: get rid of mwl8k_configure_filter() workqueue use
      mwl8k: remove mwl8k_queue_work()
      mwl8k: update copyright and version number
      MAINTAINERS: add information for mwl8k wireless driver

 MAINTAINERS                  |    6 +
 drivers/net/wireless/mwl8k.c | 1545 ++++++++++++------------------------------
 2 files changed, 437 insertions(+), 1114 deletions(-)

^ permalink raw reply

* Re: [PATCH 10/29] mwl8k: fix mwl8k_configure_filter() parameter lifetime issue
From: Lennert Buytenhek @ 2009-08-18  9:54 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linville, linux-wireless
In-Reply-To: <20090818081339.GI18639@mail.wantstofly.org>

On Tue, Aug 18, 2009 at 10:13:39AM +0200, Lennert Buytenhek wrote:

> > > This will clash with:
> > > 
> > > 	http://article.gmane.org/gmane.linux.kernel.wireless.general/38141
> > > 
> > > But that is easy to fix up.  (The easiest would probably be to not
> > > apply the mwl8k part of that patch, and I'll send a followup patch
> > > to implement ->prepare_multicast() for mwl8k.)
> > 
> > It's not quite that easy because that patch changes the arguments to the
> > functions so the multicast list is no longer available in
> > ->configure_filter().
> 
> OK, if my patch set gets applied first, please use the mwl8k
> ->prepare_multicast() implementation that's below in your patch.
> 
> If your patch gets applied first, I'll fix it up in my set.

OK, your patch is already in, as you noted on IRC, so I've replaced
this by:



>From 9145398d5822cf3ed963fb155a2771c4facd1d85 Mon Sep 17 00:00:00 2001
From: Lennert Buytenhek <buytenh@wantstofly.org>
Date: Tue, 18 Aug 2009 03:55:42 +0200
Subject: [PATCH 09/29] mwl8k: fix mwl8k_configure_filter() parameter lifetime issue

mwl8k_configure_filter() passes pointers to total_flags and the
multicast address list to a workqueue function, while there is no
guarantee that those pointers will still be valid by the time the
workqueue function runs.

Solve this by passing total_flags by value, and by passing an
already built multicast address setup command packet to the workqueue
function so that we don't have to look at the multicast address list
itself outside of mwl8k_configure_filter().

Also, since ->configure_filter() can sleep now, wait synchronously
for the worker to finish.

Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
---
 drivers/net/wireless/mwl8k.c |  107 +++++++++++++++--------------------------
 1 files changed, 39 insertions(+), 68 deletions(-)

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index a40434b..a961b69 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1613,38 +1613,39 @@ struct mwl8k_cmd_mac_multicast_adr {
 
 #define MWL8K_ENABLE_RX_MULTICAST 0x000F
 
-static int mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
-					int mc_count,
-					struct dev_addr_list *mclist)
+static struct mwl8k_cmd_pkt *
+__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
+			      int mc_count, struct dev_addr_list *mclist)
 {
+	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_cmd_mac_multicast_adr *cmd;
-	int index = 0;
-	int rc;
-	int size = sizeof(*cmd) + mc_count * ETH_ALEN;
+	int size;
+	int i;
+
+	if (mc_count > priv->num_mcaddrs)
+		mc_count = priv->num_mcaddrs;
+
+	size = sizeof(*cmd) + mc_count * ETH_ALEN;
 
-	cmd = kzalloc(size, GFP_KERNEL);
+	cmd = kzalloc(size, GFP_ATOMIC);
 	if (cmd == NULL)
-		return -ENOMEM;
+		return NULL;
 
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
 	cmd->header.length = cpu_to_le16(size);
 	cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
 	cmd->numaddr = cpu_to_le16(mc_count);
 
-	while (index < mc_count && mclist) {
+	for (i = 0; i < mc_count && mclist; i++) {
 		if (mclist->da_addrlen != ETH_ALEN) {
-			rc = -EINVAL;
-			goto mwl8k_cmd_mac_multicast_adr_exit;
+			kfree(cmd);
+			return NULL;
 		}
-		memcpy(cmd->addr[index++], mclist->da_addr, ETH_ALEN);
+		memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
 		mclist = mclist->next;
 	}
 
-	rc = mwl8k_post_cmd(hw, &cmd->header);
-
-mwl8k_cmd_mac_multicast_adr_exit:
-	kfree(cmd);
-	return rc;
+	return &cmd->header;
 }
 
 /*
@@ -3091,12 +3092,21 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
 		printk(KERN_ERR "%s() timed out\n", __func__);
 }
 
+static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
+				   int mc_count, struct dev_addr_list *mclist)
+{
+	struct mwl8k_cmd_pkt *cmd;
+
+	cmd = __mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
+
+	return (unsigned long)cmd;
+}
+
 struct mwl8k_configure_filter_worker {
 	struct mwl8k_work_struct header;
 	unsigned int changed_flags;
-	unsigned int *total_flags;
-	int mc_count;
-	struct dev_addr_list *mclist;
+	unsigned int total_flags;
+	struct mwl8k_cmd_pkt *multicast_adr_cmd;
 };
 
 #define MWL8K_SUPPORTED_IF_FLAGS	FIF_BCN_PRBRESP_PROMISC
@@ -3105,18 +3115,12 @@ static int mwl8k_configure_filter_wt(struct work_struct *wt)
 {
 	struct mwl8k_configure_filter_worker *worker =
 		(struct mwl8k_configure_filter_worker *)wt;
-
 	struct ieee80211_hw *hw = worker->header.hw;
-	unsigned int changed_flags = worker->changed_flags;
-	unsigned int *total_flags = worker->total_flags;
-	int mc_count = worker->mc_count;
-	struct dev_addr_list *mclist = worker->mclist;
-
 	struct mwl8k_priv *priv = hw->priv;
 	int rc = 0;
 
-	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
-		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+	if (worker->changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+		if (worker->total_flags & FIF_BCN_PRBRESP_PROMISC)
 			rc = mwl8k_cmd_set_pre_scan(hw);
 		else {
 			u8 *bssid;
@@ -3129,54 +3133,20 @@ static int mwl8k_configure_filter_wt(struct work_struct *wt)
 		}
 	}
 
-	if (rc)
-		goto mwl8k_configure_filter_exit;
-	if (mc_count) {
-		if (mc_count > priv->num_mcaddrs)
-			mc_count = priv->num_mcaddrs;
-
-		rc = mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
-		if (rc)
-			printk(KERN_ERR
-			"%s()Error setting multicast addresses\n",
-			__func__);
-	}
+	if (!rc && worker->multicast_adr_cmd != NULL)
+		rc = mwl8k_post_cmd(hw, worker->multicast_adr_cmd);
+	kfree(worker->multicast_adr_cmd);
 
-mwl8k_configure_filter_exit:
 	return rc;
 }
 
-static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
-				   int mc_count, struct dev_addr_list *mclist)
-{
-	struct mwl8k_configure_filter_worker *worker;
-
-	worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
-
-	if (!worker)
-		return 0;
-
-	/*
-	 * XXX: This is _HORRIBLY_ broken!!
-	 *
-	 *	No locking, the mclist pointer might be invalid as soon as this
-	 *	function returns, something in the list might be invalidated
-	 *	once we get to the worker, etc...
-	 */
-	worker->mc_count = mc_count;
-	worker->mclist = mclist;
-
-	return (u64)worker;
-}
-
 static void mwl8k_configure_filter(struct ieee80211_hw *hw,
 				   unsigned int changed_flags,
 				   unsigned int *total_flags,
 				   u64 multicast)
 {
-
-	struct mwl8k_configure_filter_worker *worker = (void *)multicast;
 	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_configure_filter_worker *worker;
 
 	/* Clear unsupported feature flags */
 	*total_flags &= MWL8K_SUPPORTED_IF_FLAGS;
@@ -3184,12 +3154,13 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
 	if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS))
 		return;
 
+	worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
 	if (worker == NULL)
 		return;
 
-	worker->header.options = MWL8K_WQ_QUEUE_ONLY | MWL8K_WQ_TX_WAIT_EMPTY;
 	worker->changed_flags = changed_flags;
-	worker->total_flags = total_flags;
+	worker->total_flags = *total_flags;
+	worker->multicast_adr_cmd = (void *)(unsigned long)multicast;
 
 	mwl8k_queue_work(hw, &worker->header, priv->config_wq,
 			 mwl8k_configure_filter_wt);
-- 
1.5.6.4

^ permalink raw reply related

* Re: [PATCH 09/29] mwl8k: remove usage of deprecated radio_enabled
From: Lennert Buytenhek @ 2009-08-18  9:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linville, linux-wireless
In-Reply-To: <1250583993.30538.3.camel@johannes.local>

On Tue, Aug 18, 2009 at 10:26:33AM +0200, Johannes Berg wrote:

> > The logic is just:
> > 
> > 	if (idle) {
> > 		issue "radio disable" command
> > 	} else {
> > 		issue "radio enable" command
> > 		set channel
> > 		set tx power
> > 		set antenna config
> > 	}
> > 
> > So if a channel change hapens while we are idle, that event won't get
> > lost -- it'll just happen later.
> 
> Ok, yeah, that looks fine.

OK, thanks.

Since your patch is already in, I've replaced this patch by:


>From 1af73ff8d1309b924f6f4accd61245b57374dd78 Mon Sep 17 00:00:00 2001
From: Lennert Buytenhek <buytenh@wantstofly.org>
Date: Mon, 17 Aug 2009 23:59:40 +0200
Subject: [PATCH 15/29] mwl8k: implement rfkill

By checking IEEE80211_CONF_CHANGE_IDLE in mwl8k_config().

Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
---
 drivers/net/wireless/mwl8k.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 177d92f..65eefe8 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2854,6 +2854,12 @@ static int mwl8k_config_wt(struct work_struct *wt)
 	struct mwl8k_priv *priv = hw->priv;
 	int rc = 0;
 
+	if (conf->flags & IEEE80211_CONF_IDLE) {
+		mwl8k_cmd_802_11_radio_disable(hw);
+		priv->current_channel = NULL;
+		goto mwl8k_config_exit;
+	}
+
 	if (mwl8k_cmd_802_11_radio_enable(hw)) {
 		rc = -EINVAL;
 		goto mwl8k_config_exit;
-- 
1.5.6.4

^ permalink raw reply related

* Re: [PATCH] mac80211: Decouple fail_avg stats used by mesh from rate control algorithm.
From: Johannes Berg @ 2009-08-18  8:45 UTC (permalink / raw)
  To: Javier Cardona; +Cc: linux-wireless, andrey, linville, devel
In-Reply-To: <1250554555-32259-1-git-send-email-javier@cozybit.com>

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

On Mon, 2009-08-17 at 17:15 -0700, Javier Cardona wrote:
> Mesh uses the tx failure average to compute the (m)path metric.  This used to
> be done inside the rate control module.  This patch breaks the dependency
> between the mesh stack and the rate control algorithm.  Mesh will now work
> independently of the chosen rate control algorithm.
> 
> The mesh stack keeps a moving average of the average transmission losses for
> each mesh peer station.  If the fail average exceeds a certain threshold, the
> peer link is marked as broken.

Looks good, means it can also work for ath9k etc. eventually.

johannes

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

^ permalink raw reply

* Re: [PATCH 09/29] mwl8k: remove usage of deprecated radio_enabled
From: Johannes Berg @ 2009-08-18  8:26 UTC (permalink / raw)
  To: Lennert Buytenhek; +Cc: linville, linux-wireless
In-Reply-To: <20090818082537.GK18639@mail.wantstofly.org>

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

On Tue, 2009-08-18 at 10:25 +0200, Lennert Buytenhek wrote:

> The logic is just:
> 
> 	if (idle) {
> 		issue "radio disable" command
> 	} else {
> 		issue "radio enable" command
> 		set channel
> 		set tx power
> 		set antenna config
> 	}
> 
> So if a channel change hapens while we are idle, that event won't get
> lost -- it'll just happen later.

Ok, yeah, that looks fine.

johannes

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

^ permalink raw reply

* Re: [PATCH 09/29] mwl8k: remove usage of deprecated radio_enabled
From: Lennert Buytenhek @ 2009-08-18  8:25 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linville, linux-wireless
In-Reply-To: <1250580509.30538.2.camel@johannes.local>

On Tue, Aug 18, 2009 at 09:28:29AM +0200, Johannes Berg wrote:

> > Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
> > ---
> >  drivers/net/wireless/mwl8k.c |    2 +-
> >  1 files changed, 1 insertions(+), 1 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
> > index 9f54204..3a201a2 100644
> > --- a/drivers/net/wireless/mwl8k.c
> > +++ b/drivers/net/wireless/mwl8k.c
> > @@ -2935,7 +2935,7 @@ static int mwl8k_config_wt(struct work_struct *wt)
> >  	struct mwl8k_priv *priv = hw->priv;
> >  	int rc = 0;
> >  
> > -	if (!conf->radio_enabled) {
> > +	if (conf->flags & IEEE80211_CONF_IDLE) {
> >  		mwl8k_cmd_802_11_radio_disable(hw);
> >  		priv->current_channel = NULL;
> >  		rc = 0;
> 
> So I think the return; a little below needs to be removed to allow doing
> other things while the radio is off? I'm not sure which actually happen
> but I never audited the code to make sure nothing happens.

The logic is just:

	if (idle) {
		issue "radio disable" command
	} else {
		issue "radio enable" command
		set channel
		set tx power
		set antenna config
	}

So if a channel change hapens while we are idle, that event won't get
lost -- it'll just happen later.

^ permalink raw reply

* Re: [PATCH 09/29] mwl8k: remove usage of deprecated radio_enabled
From: Lennert Buytenhek @ 2009-08-18  8:24 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linville, linux-wireless
In-Reply-To: <1250580466.30538.1.camel@johannes.local>

On Tue, Aug 18, 2009 at 09:27:46AM +0200, Johannes Berg wrote:

> > Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
> > ---
> >  drivers/net/wireless/mwl8k.c |    2 +-
> >  1 files changed, 1 insertions(+), 1 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
> > index 9f54204..3a201a2 100644
> > --- a/drivers/net/wireless/mwl8k.c
> > +++ b/drivers/net/wireless/mwl8k.c
> > @@ -2935,7 +2935,7 @@ static int mwl8k_config_wt(struct work_struct *wt)
> >  	struct mwl8k_priv *priv = hw->priv;
> >  	int rc = 0;
> >  
> > -	if (!conf->radio_enabled) {
> > +	if (conf->flags & IEEE80211_CONF_IDLE) {
> 
> Ok, I thought about doing this but wasn't sure it would work -- you can
> still accept channel changing commands while the radio is off, for
> instance?

The hardware would accept those commands, but they wouldn't have any
effect, since the radio is off.  If/when we then go out of idle later,
the channel set and power set and antenna config commands will be run,
so we'll end up with the right parameters.

^ permalink raw reply

* Re: [PATCH 10/29] mwl8k: fix mwl8k_configure_filter() parameter lifetime issue
From: Lennert Buytenhek @ 2009-08-18  8:13 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linville, linux-wireless
In-Reply-To: <1250580198.30538.0.camel@johannes.local>

On Tue, Aug 18, 2009 at 09:23:18AM +0200, Johannes Berg wrote:

> > This will clash with:
> > 
> > 	http://article.gmane.org/gmane.linux.kernel.wireless.general/38141
> > 
> > But that is easy to fix up.  (The easiest would probably be to not
> > apply the mwl8k part of that patch, and I'll send a followup patch
> > to implement ->prepare_multicast() for mwl8k.)
> 
> It's not quite that easy because that patch changes the arguments to the
> functions so the multicast list is no longer available in
> ->configure_filter().

OK, if my patch set gets applied first, please use the mwl8k
->prepare_multicast() implementation that's below in your patch.

If your patch gets applied first, I'll fix it up in my set.



diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 2c7c85d..316a728 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2654,26 +2654,33 @@ out:
 	mwl8k_fw_unlock(hw);
 }
 
-struct mwl8k_configure_filter_worker {
-	struct work_struct wt;
-	struct ieee80211_hw *hw;
-	unsigned int changed_flags;
-	unsigned int total_flags;
-	struct mwl8k_cmd_pkt *set_multicast_adr;
-};
+static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
+				   int mc_count, struct dev_addr_list *mclist)
+{
+	struct mwl8k_cmd_pkt *cmd;
+
+	cmd = __mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
 
-static void mwl8k_configure_filter_wt(struct work_struct *wt)
+	return (unsigned long)cmd;
+}
+
+static void mwl8k_configure_filter(struct ieee80211_hw *hw,
+				   unsigned int changed_flags,
+				   unsigned int *total_flags,
+				   u64 multicast)
 {
-	struct mwl8k_configure_filter_worker *worker =
-		(struct mwl8k_configure_filter_worker *)wt;
-	struct ieee80211_hw *hw = worker->hw;
 	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_cmd_pkt *multicast_adr_cmd =
+		(void *)(unsigned long)multicast;
+
+	/* Clear unsupported feature flags */
+	*total_flags &= FIF_BCN_PRBRESP_PROMISC;
 
 	if (mwl8k_fw_lock(hw))
-		return;
+		goto out;
 
-	if (worker->changed_flags & FIF_BCN_PRBRESP_PROMISC) {
-		if (worker->total_flags & FIF_BCN_PRBRESP_PROMISC)
+	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
 			mwl8k_cmd_set_pre_scan(hw);
 		else {
 			u8 *bssid;
@@ -2686,44 +2693,13 @@ static void mwl8k_configure_filter_wt(struct work_struct *wt)
 		}
 	}
 
-	if (worker->set_multicast_adr != NULL) {
-		mwl8k_post_cmd(hw, worker->set_multicast_adr);
-		kfree(worker->set_multicast_adr);
-	}
+	if (multicast_adr_cmd != NULL)
+		mwl8k_post_cmd(hw, multicast_adr_cmd);
 
 	mwl8k_fw_unlock(hw);
 
-	kfree(worker);
-}
-
-static void mwl8k_configure_filter(struct ieee80211_hw *hw,
-				   unsigned int changed_flags,
-				   unsigned int *total_flags,
-				   int mc_count,
-				   struct dev_addr_list *mclist)
-{
-	struct mwl8k_priv *priv = hw->priv;
-	struct mwl8k_configure_filter_worker *worker;
-
-	/* Clear unsupported feature flags */
-	*total_flags &= FIF_BCN_PRBRESP_PROMISC;
-
-	if (!(changed_flags & FIF_BCN_PRBRESP_PROMISC) && !mc_count)
-		return;
-
-	worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
-	if (worker == NULL)
-		return;
-
-	worker->hw = hw;
-	worker->changed_flags = changed_flags;
-	worker->total_flags = *total_flags;
-	if (mc_count)
-		worker->set_multicast_adr =
-			__mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
-
-	INIT_WORK(&worker->wt, mwl8k_configure_filter_wt);
-	queue_work(priv->config_wq, &worker->wt);
+out:
+	kfree(multicast_adr_cmd);
 }
 
 static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
@@ -2787,6 +2763,7 @@ static const struct ieee80211_ops mwl8k_ops = {
 	.remove_interface	= mwl8k_remove_interface,
 	.config			= mwl8k_config,
 	.bss_info_changed	= mwl8k_bss_info_changed,
+	.prepare_multicast	= mwl8k_prepare_multicast,
 	.configure_filter	= mwl8k_configure_filter,
 	.set_rts_threshold	= mwl8k_set_rts_threshold,
 	.conf_tx		= mwl8k_conf_tx,

^ permalink raw reply related

* Re: [PATCH 09/29] mwl8k: remove usage of deprecated radio_enabled
From: Johannes Berg @ 2009-08-18  7:28 UTC (permalink / raw)
  To: Lennert Buytenhek; +Cc: linville, linux-wireless
In-Reply-To: <20090818035220.GN18639@mail.wantstofly.org>

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

On Tue, 2009-08-18 at 05:52 +0200, Lennert Buytenhek wrote:
> Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
> ---
>  drivers/net/wireless/mwl8k.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
> index 9f54204..3a201a2 100644
> --- a/drivers/net/wireless/mwl8k.c
> +++ b/drivers/net/wireless/mwl8k.c
> @@ -2935,7 +2935,7 @@ static int mwl8k_config_wt(struct work_struct *wt)
>  	struct mwl8k_priv *priv = hw->priv;
>  	int rc = 0;
>  
> -	if (!conf->radio_enabled) {
> +	if (conf->flags & IEEE80211_CONF_IDLE) {
>  		mwl8k_cmd_802_11_radio_disable(hw);
>  		priv->current_channel = NULL;
>  		rc = 0;

So I think the return; a little below needs to be removed to allow doing
other things while the radio is off? I'm not sure which actually happen
but I never audited the code to make sure nothing happens.

johannes

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

^ permalink raw reply

* Re: [PATCH 09/29] mwl8k: remove usage of deprecated radio_enabled
From: Johannes Berg @ 2009-08-18  7:27 UTC (permalink / raw)
  To: Lennert Buytenhek; +Cc: linville, linux-wireless
In-Reply-To: <20090818035220.GN18639@mail.wantstofly.org>

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

On Tue, 2009-08-18 at 05:52 +0200, Lennert Buytenhek wrote:
> Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
> ---
>  drivers/net/wireless/mwl8k.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
> index 9f54204..3a201a2 100644
> --- a/drivers/net/wireless/mwl8k.c
> +++ b/drivers/net/wireless/mwl8k.c
> @@ -2935,7 +2935,7 @@ static int mwl8k_config_wt(struct work_struct *wt)
>  	struct mwl8k_priv *priv = hw->priv;
>  	int rc = 0;
>  
> -	if (!conf->radio_enabled) {
> +	if (conf->flags & IEEE80211_CONF_IDLE) {

Ok, I thought about doing this but wasn't sure it would work -- you can
still accept channel changing commands while the radio is off, for
instance?

Anyway, this clashes with the removal of this chunk of code, which
should then just not happen.

johannes

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

^ permalink raw reply


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