Linux wireless drivers development
 help / color / mirror / Atom feed
* 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

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

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

On Tue, 2009-08-18 at 06:00 +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().

johannes

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

^ permalink raw reply

* Re: [PATCH v4 32/34] wireless: make mac80211 select cfg80211
From: Johannes Berg @ 2009-08-18  7:15 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Luis Rodriguez, linville@tuxdriver.com,
	linux-wireless@vger.kernel.org, Larry.Finger@lwfinger.net
In-Reply-To: <20090818003550.GG15363@mosca>

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

On Mon, 2009-08-17 at 17:35 -0700, Luis R. Rodriguez wrote:

> From: Luis R. Rodriguez <lrodriguez@atheros.com>
> Subject: [PATCH] wireless: make mac80211 select cfg80211
> 
> This lets us keep mac80211 on the menu map even if cfg80211
> is not enabled. We now remove that pesky comment about this.

>  menuconfig RFKILL
>  	tristate "RF switch subsystem support"
> +	depends on CFG80211 || !CFG80211

That's backwards.

Now you can still have CFG80211=y and RFKILL=m. And RFKILL really
shouldn't depend on one of its users anyway.

Just leave it the way it is please.

johannes

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

^ permalink raw reply

* [PATCH] ath9k: Fix TX poll cancelling
From: Sujith @ 2009-08-18  5:21 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

In ath9k_stop(), tx_complete_work was being cancelled twice.
This patch fixes it. Also, locking sc->mutex should be done
at the beginning.

Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
---
 drivers/net/wireless/ath/ath9k/main.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3e09b9a..c454d19 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2105,6 +2105,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
 
+	mutex_lock(&sc->mutex);
+
 	aphy->state = ATH_WIPHY_INACTIVE;
 
 	cancel_delayed_work_sync(&sc->ath_led_blink_work);
@@ -2117,13 +2119,10 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
 	if (sc->sc_flags & SC_OP_INVALID) {
 		DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
+		mutex_unlock(&sc->mutex);
 		return;
 	}
 
-	mutex_lock(&sc->mutex);
-
-	cancel_delayed_work_sync(&sc->tx_complete_work);
-
 	if (ath9k_wiphy_started(sc)) {
 		mutex_unlock(&sc->mutex);
 		return; /* another wiphy still in use */
-- 
1.6.4


^ permalink raw reply related

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

On Tue, Aug 18, 2009 at 05:52:33AM +0200, Lennert Buytenhek wrote:

> 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().
> 
> Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>

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.)

^ permalink raw reply

* [PATCH 29/29] MAINTAINERS: add information for mwl8k wireless driver
From: Lennert Buytenhek @ 2009-08-18  3:56 UTC (permalink / raw)
  To: linville, linux-wireless

Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
---
 MAINTAINERS |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index cc9ce9e..8d8d495 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3272,6 +3272,12 @@ S:	Supported
 F:	drivers/net/mv643xx_eth.*
 F:	include/linux/mv643xx.h
 
+MARVELL MWL8K WIRELESS DRIVER
+M:	Lennert Buytenhek <buytenh@marvell.com>
+L:	linux-wireless@vger.kernel.org
+S:	Supported
+F:	drivers/net/wireless/mwl8k.c
+
 MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
 M:	Nicolas Pitre <nico@cam.org>
 S:	Maintained
-- 
1.5.6.4

^ permalink raw reply related

* [PATCH 28/29] mwl8k: update copyright and version number
From: Lennert Buytenhek @ 2009-08-18  3:55 UTC (permalink / raw)
  To: linville, linux-wireless

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

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index c8aa552..2150c32 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2,7 +2,7 @@
  * drivers/net/wireless/mwl8k.c
  * Driver for Marvell TOPDOG 802.11 Wireless cards
  *
- * Copyright (C) 2008 Marvell Semiconductor Inc.
+ * Copyright (C) 2008-2009 Marvell Semiconductor Inc.
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2.  This program is licensed "as is" without any
@@ -25,7 +25,7 @@
 
 #define MWL8K_DESC	"Marvell TOPDOG(R) 802.11 Wireless Network Driver"
 #define MWL8K_NAME	KBUILD_MODNAME
-#define MWL8K_VERSION	"0.9.1"
+#define MWL8K_VERSION	"0.10"
 
 MODULE_DESCRIPTION(MWL8K_DESC);
 MODULE_VERSION(MWL8K_VERSION);
-- 
1.5.6.4

^ permalink raw reply related

* [PATCH 27/29] mwl8k: remove mwl8k_queue_work()
From: Lennert Buytenhek @ 2009-08-18  3:55 UTC (permalink / raw)
  To: linville, linux-wireless

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

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index dea1440..c8aa552 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2425,81 +2425,6 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 	return rc;
 }
 
-struct mwl8k_work_struct {
-	/* Initialized by mwl8k_queue_work().  */
-	struct work_struct wt;
-
-	/* Required field passed in to mwl8k_queue_work().  */
-	struct ieee80211_hw *hw;
-
-	/* Required field passed in to mwl8k_queue_work().  */
-	int (*wfunc)(struct work_struct *w);
-
-	/* Initialized by mwl8k_queue_work().  */
-	struct completion *cmd_wait;
-
-	/* Result code.  */
-	int rc;
-
-	/*
-	 * Whether to sleep for request completion.
-	 */
-	bool sleep;
-};
-
-static void mwl8k_config_thread(struct work_struct *wt)
-{
-	struct mwl8k_work_struct *worker = (struct mwl8k_work_struct *)wt;
-	struct ieee80211_hw *hw = worker->hw;
-	int rc = 0;
-
-	rc = mwl8k_fw_lock(hw);
-	if (!rc) {
-		rc = worker->wfunc(wt);
-		mwl8k_fw_unlock(hw);
-	}
-
-	if (worker->sleep) {
-		worker->rc = rc;
-		complete(worker->cmd_wait);
-	} else {
-		kfree(wt);
-	}
-}
-
-static int mwl8k_queue_work(struct ieee80211_hw *hw,
-				struct mwl8k_work_struct *worker,
-				int (*wfunc)(struct work_struct *w))
-{
-	struct mwl8k_priv *priv = hw->priv;
-	unsigned long timeout = 0;
-	int rc = 0;
-
-	DECLARE_COMPLETION_ONSTACK(cmd_wait);
-
-	worker->hw = hw;
-	worker->cmd_wait = &cmd_wait;
-	worker->rc = 1;
-	worker->wfunc = wfunc;
-
-	INIT_WORK(&worker->wt, mwl8k_config_thread);
-	queue_work(priv->config_wq, &worker->wt);
-
-	if (worker->sleep) {
-		timeout = wait_for_completion_timeout(&cmd_wait,
-			msecs_to_jiffies(10000));
-
-		if (timeout)
-			rc = worker->rc;
-		else {
-			cancel_work_sync(&worker->wt);
-			rc = -ETIMEDOUT;
-		}
-	}
-
-	return rc;
-}
-
 static int mwl8k_start(struct ieee80211_hw *hw)
 {
 	struct mwl8k_priv *priv = hw->priv;
-- 
1.5.6.4

^ permalink raw reply related

* [PATCH 26/29] mwl8k: make mwl8k_configure_filter() use queue_work() directly
From: Lennert Buytenhek @ 2009-08-18  3:55 UTC (permalink / raw)
  To: linville, linux-wireless

mwl8k_configure_filter() was the last remaining user of
mwl8k_queue_work(), which can now be removed in favor of just using
queue_work() on priv->config_wq directly.

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

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index b863b74..dea1440 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2747,27 +2747,26 @@ out:
 }
 
 struct mwl8k_configure_filter_worker {
-	struct mwl8k_work_struct header;
+	struct work_struct wt;
+	struct ieee80211_hw *hw;
 	unsigned int changed_flags;
 	unsigned int total_flags;
 	struct mwl8k_cmd_pkt *set_multicast_adr;
 };
 
-#define MWL8K_SUPPORTED_IF_FLAGS	FIF_BCN_PRBRESP_PROMISC
-
-static int mwl8k_configure_filter_wt(struct work_struct *wt)
+static void 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;
+	struct ieee80211_hw *hw = worker->hw;
 	struct mwl8k_priv *priv = hw->priv;
-	int rc = 0;
 
-	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
-		if (total_flags & FIF_BCN_PRBRESP_PROMISC)
-			rc = mwl8k_cmd_set_pre_scan(hw);
+	if (mwl8k_fw_lock(hw))
+		return;
+
+	if (worker->changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+		if (worker->total_flags & FIF_BCN_PRBRESP_PROMISC)
+			mwl8k_cmd_set_pre_scan(hw);
 		else {
 			u8 *bssid;
 
@@ -2775,17 +2774,18 @@ static int mwl8k_configure_filter_wt(struct work_struct *wt)
 			if (priv->vif != NULL)
 				bssid = MWL8K_VIF(priv->vif)->bssid;
 
-			rc = mwl8k_cmd_set_post_scan(hw, bssid);
+			mwl8k_cmd_set_post_scan(hw, bssid);
 		}
 	}
 
 	if (worker->set_multicast_adr != NULL) {
-		if (!rc)
-			rc = mwl8k_post_cmd(hw, worker->set_multicast_adr);
+		mwl8k_post_cmd(hw, worker->set_multicast_adr);
 		kfree(worker->set_multicast_adr);
 	}
 
-	return rc;
+	mwl8k_fw_unlock(hw);
+
+	kfree(worker);
 }
 
 static void mwl8k_configure_filter(struct ieee80211_hw *hw,
@@ -2794,26 +2794,28 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
 				   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 &= MWL8K_SUPPORTED_IF_FLAGS;
+	*total_flags &= FIF_BCN_PRBRESP_PROMISC;
 
-	if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS) && !mc_count)
+	if (!(changed_flags & FIF_BCN_PRBRESP_PROMISC) && !mc_count)
 		return;
 
 	worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
 	if (worker == NULL)
 		return;
 
-	worker->header.sleep = 0;
+	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);
 
-	mwl8k_queue_work(hw, &worker->header, mwl8k_configure_filter_wt);
+	INIT_WORK(&worker->wt, mwl8k_configure_filter_wt);
+	queue_work(priv->config_wq, &worker->wt);
 }
 
 static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
-- 
1.5.6.4

^ permalink raw reply related

* [PATCH 25/29] mwl8k: get rid of mwl8k_get_stats() workqueue use
From: Lennert Buytenhek @ 2009-08-18  3:55 UTC (permalink / raw)
  To: linville, linux-wireless

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

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index d16ba1b..b863b74 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2859,43 +2859,14 @@ static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
 			sizeof(struct ieee80211_tx_queue_stats));
 	}
 	spin_unlock_bh(&priv->tx_lock);
-	return 0;
-}
-
-struct mwl8k_get_stats_worker {
-	struct mwl8k_work_struct header;
-	struct ieee80211_low_level_stats *stats;
-};
 
-static int mwl8k_get_stats_wt(struct work_struct *wt)
-{
-	struct mwl8k_get_stats_worker *worker =
-		(struct mwl8k_get_stats_worker *)wt;
-
-	return mwl8k_cmd_802_11_get_stat(worker->header.hw, worker->stats);
+	return 0;
 }
 
 static int mwl8k_get_stats(struct ieee80211_hw *hw,
 			   struct ieee80211_low_level_stats *stats)
 {
-	int rc;
-	struct mwl8k_get_stats_worker *worker;
-
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return -ENOMEM;
-
-	worker->header.sleep = 1;
-	worker->stats = stats;
-	rc = mwl8k_queue_work(hw, &worker->header, mwl8k_get_stats_wt);
-
-	kfree(worker);
-	if (rc == -ETIMEDOUT) {
-		printk(KERN_ERR "%s() timed out\n", __func__);
-		rc = -EINVAL;
-	}
-
-	return rc;
+	return mwl8k_cmd_802_11_get_stat(hw, stats);
 }
 
 static const struct ieee80211_ops mwl8k_ops = {
-- 
1.5.6.4

^ permalink raw reply related

* [PATCH 24/29] mwl8k: get rid of mwl8k_conf_tx() workqueue use
From: Lennert Buytenhek @ 2009-08-18  3:55 UTC (permalink / raw)
  To: linville, linux-wireless

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

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index c8e65c6..d16ba1b 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2821,57 +2821,27 @@ static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 	return mwl8k_rts_threshold(hw, MWL8K_CMD_SET, value);
 }
 
-struct mwl8k_conf_tx_worker {
-	struct mwl8k_work_struct header;
-	u16 queue;
-	const struct ieee80211_tx_queue_params *params;
-};
-
-static int mwl8k_conf_tx_wt(struct work_struct *wt)
-{
-	struct mwl8k_conf_tx_worker *worker =
-	(struct mwl8k_conf_tx_worker *)wt;
-
-	struct ieee80211_hw *hw = worker->header.hw;
-	u16 queue = worker->queue;
-	const struct ieee80211_tx_queue_params *params = worker->params;
-
-	struct mwl8k_priv *priv = hw->priv;
-	int rc = 0;
-
-	if (!priv->wmm_enabled) {
-		if (mwl8k_set_wmm(hw, 1)) {
-			rc = -EINVAL;
-			goto mwl8k_conf_tx_exit;
-		}
-	}
-
-	if (mwl8k_set_edca_params(hw, GET_TXQ(queue), params->cw_min,
-		params->cw_max, params->aifs, params->txop))
-			rc = -EINVAL;
-mwl8k_conf_tx_exit:
-	return rc;
-}
-
 static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
 			 const struct ieee80211_tx_queue_params *params)
 {
+	struct mwl8k_priv *priv = hw->priv;
 	int rc;
-	struct mwl8k_conf_tx_worker *worker;
 
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return -ENOMEM;
+	rc = mwl8k_fw_lock(hw);
+	if (!rc) {
+		if (!priv->wmm_enabled)
+			rc = mwl8k_set_wmm(hw, 1);
 
-	worker->header.sleep = 1;
-	worker->queue = queue;
-	worker->params = params;
-	rc = mwl8k_queue_work(hw, &worker->header, mwl8k_conf_tx_wt);
-	kfree(worker);
-	if (rc == -ETIMEDOUT) {
-		printk(KERN_ERR "%s() timed out\n", __func__);
-		rc = -EINVAL;
+		if (!rc)
+			rc = mwl8k_set_edca_params(hw, queue,
+						   params->cw_min,
+						   params->cw_max,
+						   params->aifs,
+						   params->txop);
+
+		mwl8k_fw_unlock(hw);
 	}
+
 	return rc;
 }
 
-- 
1.5.6.4

^ permalink raw reply related

* [PATCH 23/29] mwl8k: get rid of mwl8k_set_rts_threshold() workqueue use
From: Lennert Buytenhek @ 2009-08-18  3:54 UTC (permalink / raw)
  To: linville, linux-wireless

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

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 927f987..c8e65c6 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1970,7 +1970,7 @@ struct mwl8k_cmd_rts_threshold {
 } __attribute__((packed));
 
 static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
-			       u16 action, u16 *threshold)
+			       u16 action, u16 threshold)
 {
 	struct mwl8k_cmd_rts_threshold *cmd;
 	int rc;
@@ -1982,7 +1982,7 @@ static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
 	cmd->action = cpu_to_le16(action);
-	cmd->threshold = cpu_to_le16(*threshold);
+	cmd->threshold = cpu_to_le16(threshold);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2816,46 +2816,9 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
 	mwl8k_queue_work(hw, &worker->header, mwl8k_configure_filter_wt);
 }
 
-struct mwl8k_set_rts_threshold_worker {
-	struct mwl8k_work_struct header;
-	u32 value;
-};
-
-static int mwl8k_set_rts_threshold_wt(struct work_struct *wt)
-{
-	struct mwl8k_set_rts_threshold_worker *worker =
-		(struct mwl8k_set_rts_threshold_worker *)wt;
-
-	struct ieee80211_hw *hw = worker->header.hw;
-	u16 threshold = (u16)(worker->value);
-	int rc;
-
-	rc = mwl8k_rts_threshold(hw, MWL8K_CMD_SET, &threshold);
-
-	return rc;
-}
-
 static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 {
-	int rc;
-	struct mwl8k_set_rts_threshold_worker *worker;
-
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return -ENOMEM;
-
-	worker->header.sleep = 1;
-	worker->value = value;
-
-	rc = mwl8k_queue_work(hw, &worker->header, mwl8k_set_rts_threshold_wt);
-	kfree(worker);
-
-	if (rc == -ETIMEDOUT) {
-		printk(KERN_ERR "%s() timed out\n", __func__);
-		rc = -EINVAL;
-	}
-
-	return rc;
+	return mwl8k_rts_threshold(hw, MWL8K_CMD_SET, value);
 }
 
 struct mwl8k_conf_tx_worker {
-- 
1.5.6.4

^ permalink raw reply related

* [PATCH 22/29] mwl8k: get rid of mwl8k_bss_info_changed() workqueue use
From: Lennert Buytenhek @ 2009-08-18  3:54 UTC (permalink / raw)
  To: linville, linux-wireless

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

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index d03e55b..927f987 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2672,58 +2672,62 @@ out:
 	return rc;
 }
 
-struct mwl8k_bss_info_changed_worker {
-	struct mwl8k_work_struct header;
-	struct ieee80211_vif *vif;
-	struct ieee80211_bss_conf *info;
-	u32 changed;
-};
-
-static int mwl8k_bss_info_changed_wt(struct work_struct *wt)
+static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif,
+				   struct ieee80211_bss_conf *info,
+				   u32 changed)
 {
-	struct mwl8k_bss_info_changed_worker *worker =
-		(struct mwl8k_bss_info_changed_worker *)wt;
-	struct ieee80211_hw *hw = worker->header.hw;
-	struct ieee80211_vif *vif = worker->vif;
-	struct ieee80211_bss_conf *info = worker->info;
-	u32 changed;
-	int rc;
-
 	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+	int rc;
+
+	if (changed & BSS_CHANGED_BSSID)
+		memcpy(mwl8k_vif->bssid, info->bssid, ETH_ALEN);
+
+	if ((changed & BSS_CHANGED_ASSOC) == 0)
+		return;
 
-	changed = worker->changed;
 	priv->capture_beacon = false;
 
+	rc = mwl8k_fw_lock(hw);
+	if (!rc)
+		return;
+
 	if (info->assoc) {
 		memcpy(&mwl8k_vif->bss_info, info,
 			sizeof(struct ieee80211_bss_conf));
 
 		/* Install rates */
-		if (mwl8k_update_rateset(hw, vif))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_update_rateset(hw, vif);
+		if (rc)
+			goto out;
 
 		/* Turn on rate adaptation */
-		if (mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
-			MWL8K_UCAST_RATE, NULL))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
+			MWL8K_UCAST_RATE, NULL);
+		if (rc)
+			goto out;
 
 		/* Set radio preamble */
-		if (mwl8k_set_radio_preamble(hw, info->use_short_preamble))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_set_radio_preamble(hw, info->use_short_preamble);
+		if (rc)
+			goto out;
 
 		/* Set slot time */
-		if (mwl8k_cmd_set_slot(hw, info->use_short_slot))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_cmd_set_slot(hw, info->use_short_slot);
+		if (rc)
+			goto out;
 
 		/* Update peer rate info */
-		if (mwl8k_cmd_update_sta_db(hw, vif,
-				MWL8K_STA_DB_MODIFY_ENTRY))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_cmd_update_sta_db(hw, vif,
+				MWL8K_STA_DB_MODIFY_ENTRY);
+		if (rc)
+			goto out;
 
 		/* Set AID */
-		if (mwl8k_cmd_set_aid(hw, vif))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_cmd_set_aid(hw, vif);
+		if (rc)
+			goto out;
 
 		/*
 		 * Finalize the join.  Tell rx handler to process
@@ -2732,44 +2736,14 @@ static int mwl8k_bss_info_changed_wt(struct work_struct *wt)
 		memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN);
 		priv->capture_beacon = true;
 	} else {
-		mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
+		rc = mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
 		memset(&mwl8k_vif->bss_info, 0,
 			sizeof(struct ieee80211_bss_conf));
 		memset(mwl8k_vif->bssid, 0, ETH_ALEN);
 	}
 
-mwl8k_bss_info_changed_exit:
-	rc = 0;
-	return rc;
-}
-
-static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
-				   struct ieee80211_vif *vif,
-				   struct ieee80211_bss_conf *info,
-				   u32 changed)
-{
-	struct mwl8k_bss_info_changed_worker *worker;
-	struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
-	int rc;
-
-	if (changed & BSS_CHANGED_BSSID)
-		memcpy(mv_vif->bssid, info->bssid, ETH_ALEN);
-
-	if ((changed & BSS_CHANGED_ASSOC) == 0)
-		return;
-
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return;
-
-	worker->header.sleep = 1;
-	worker->vif = vif;
-	worker->info = info;
-	worker->changed = changed;
-	rc = mwl8k_queue_work(hw, &worker->header, mwl8k_bss_info_changed_wt);
-	kfree(worker);
-	if (rc == -ETIMEDOUT)
-		printk(KERN_ERR "%s() timed out\n", __func__);
+out:
+	mwl8k_fw_unlock(hw);
 }
 
 struct mwl8k_configure_filter_worker {
-- 
1.5.6.4

^ permalink raw reply related

* [PATCH 21/29] mwl8k: get rid of mwl8k_config() workqueue use
From: Lennert Buytenhek @ 2009-08-18  3:54 UTC (permalink / raw)
  To: linville, linux-wireless

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

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 6b16542..d03e55b 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2633,79 +2633,43 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw,
 	priv->vif = NULL;
 }
 
-struct mwl8k_config_worker {
-	struct mwl8k_work_struct header;
-	u32 changed;
-};
-
-static int mwl8k_config_wt(struct work_struct *wt)
+static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
 {
-	struct mwl8k_config_worker *worker =
-		(struct mwl8k_config_worker *)wt;
-	struct ieee80211_hw *hw = worker->header.hw;
 	struct ieee80211_conf *conf = &hw->conf;
 	struct mwl8k_priv *priv = hw->priv;
-	int rc = 0;
+	int rc;
 
 	if (conf->flags & IEEE80211_CONF_IDLE) {
-		mwl8k_cmd_802_11_radio_disable(hw);
 		priv->current_channel = NULL;
-		rc = 0;
-		goto mwl8k_config_exit;
+		return mwl8k_cmd_802_11_radio_disable(hw);
 	}
 
-	if (mwl8k_cmd_802_11_radio_enable(hw)) {
-		rc = -EINVAL;
-		goto mwl8k_config_exit;
-	}
+	rc = mwl8k_fw_lock(hw);
+	if (rc)
+		return rc;
 
-	priv->current_channel = conf->channel;
+	rc = mwl8k_cmd_802_11_radio_enable(hw);
+	if (rc)
+		goto out;
 
-	if (mwl8k_cmd_set_rf_channel(hw, conf->channel)) {
-		rc = -EINVAL;
-		goto mwl8k_config_exit;
-	}
+	rc = mwl8k_cmd_set_rf_channel(hw, conf->channel);
+	if (rc)
+		goto out;
+
+	priv->current_channel = conf->channel;
 
 	if (conf->power_level > 18)
 		conf->power_level = 18;
-	if (mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level)) {
-		rc = -EINVAL;
-		goto mwl8k_config_exit;
-	}
-
-	if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7))
-		rc = -EINVAL;
-
-mwl8k_config_exit:
-	return rc;
-}
-
-static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
-{
-	int rc = 0;
-	struct mwl8k_config_worker *worker;
-
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return -ENOMEM;
-
-	worker->header.sleep = 1;
-	worker->changed = changed;
+	rc = mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level);
+	if (rc)
+		goto out;
 
-	rc = mwl8k_queue_work(hw, &worker->header, mwl8k_config_wt);
-	if (rc == -ETIMEDOUT) {
-		printk(KERN_ERR "%s() timed out.\n", __func__);
-		rc = -EINVAL;
-	}
+	rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7);
 
-	kfree(worker);
+out:
+	mwl8k_fw_unlock(hw);
 
-	/*
-	 * mac80211 will crash on anything other than -EINVAL on
-	 * error. Looks like wireless extensions which calls mac80211
-	 * may be the actual culprit...
-	 */
-	return rc ? -EINVAL : 0;
+	return rc;
 }
 
 struct mwl8k_bss_info_changed_worker {
-- 
1.5.6.4

^ permalink raw reply related

* [PATCH 20/29] mwl8k: get rid of mwl8k_stop() workqueue use
From: Lennert Buytenhek @ 2009-08-18  3:54 UTC (permalink / raw)
  To: linville, linux-wireless

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

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 69e6879..6b16542 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2551,41 +2551,15 @@ static int mwl8k_start(struct ieee80211_hw *hw)
 	return rc;
 }
 
-struct mwl8k_stop_worker {
-	struct mwl8k_work_struct header;
-};
-
-static int mwl8k_stop_wt(struct work_struct *wt)
-{
-	struct mwl8k_stop_worker *worker = (struct mwl8k_stop_worker *)wt;
-	struct ieee80211_hw *hw = worker->header.hw;
-
-	return mwl8k_cmd_802_11_radio_disable(hw);
-}
-
 static void mwl8k_stop(struct ieee80211_hw *hw)
 {
-	int rc;
-	struct mwl8k_stop_worker *worker;
 	struct mwl8k_priv *priv = hw->priv;
 	int i;
 
-	if (priv->vif != NULL)
-		return;
+	mwl8k_cmd_802_11_radio_disable(hw);
 
 	ieee80211_stop_queues(hw);
 
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return;
-
-	worker->header.sleep = 1;
-
-	rc = mwl8k_queue_work(hw, &worker->header, mwl8k_stop_wt);
-	kfree(worker);
-	if (rc == -ETIMEDOUT)
-		printk(KERN_ERR "%s() timed out\n", __func__);
-
 	/* Disable interrupts */
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
 	free_irq(priv->pdev->irq, hw);
-- 
1.5.6.4

^ permalink raw reply related

* [PATCH 19/29] mwl8k: get rid of mwl8k_start() workqueue use
From: Lennert Buytenhek @ 2009-08-18  3:54 UTC (permalink / raw)
  To: linville, linux-wireless

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

diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 5516058..69e6879 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2500,106 +2500,53 @@ static int mwl8k_queue_work(struct ieee80211_hw *hw,
 	return rc;
 }
 
-struct mwl8k_start_worker {
-	struct mwl8k_work_struct header;
-};
-
-static int mwl8k_start_wt(struct work_struct *wt)
-{
-	struct mwl8k_start_worker *worker = (struct mwl8k_start_worker *)wt;
-	struct ieee80211_hw *hw = worker->header.hw;
-	struct mwl8k_priv *priv = hw->priv;
-	int rc = 0;
-
-	if (priv->vif != NULL) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	/* Turn on radio */
-	if (mwl8k_cmd_802_11_radio_enable(hw)) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	/* Purge TX/RX HW queues */
-	if (mwl8k_cmd_set_pre_scan(hw)) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	if (mwl8k_cmd_set_post_scan(hw, "\x00\x00\x00\x00\x00\x00")) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	/* Enable firmware rate adaptation */
-	if (mwl8k_cmd_setrateadaptmode(hw, 0)) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	/* Disable WMM. WMM gets enabled when stack sends WMM parms */
-	if (mwl8k_set_wmm(hw, 0)) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	/* Disable sniffer mode */
-	if (mwl8k_enable_sniffer(hw, 0))
-		rc = -EIO;
-
-mwl8k_start_exit:
-	return rc;
-}
-
 static int mwl8k_start(struct ieee80211_hw *hw)
 {
-	struct mwl8k_start_worker *worker;
 	struct mwl8k_priv *priv = hw->priv;
 	int rc;
 
-	/* Enable tx reclaim tasklet */
-	tasklet_enable(&priv->tx_reclaim_task);
-
 	rc = request_irq(priv->pdev->irq, &mwl8k_interrupt,
 			 IRQF_SHARED, MWL8K_NAME, hw);
 	if (rc) {
 		printk(KERN_ERR "%s: failed to register IRQ handler\n",
 		       priv->name);
-		rc = -EIO;
-		goto mwl8k_start_disable_tasklet;
+		return -EIO;
 	}
 
+	/* Enable tx reclaim tasklet */
+	tasklet_enable(&priv->tx_reclaim_task);
+
 	/* Enable interrupts */
 	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
 
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL) {
-		rc = -ENOMEM;
-		goto mwl8k_start_disable_irq;
-	}
+	rc = mwl8k_fw_lock(hw);
+	if (!rc) {
+		rc = mwl8k_cmd_802_11_radio_enable(hw);
 
-	worker->header.sleep = 1;
+		if (!rc)
+			rc = mwl8k_cmd_set_pre_scan(hw);
 
-	rc = mwl8k_queue_work(hw, &worker->header, mwl8k_start_wt);
-	kfree(worker);
-	if (!rc)
-		return rc;
+		if (!rc)
+			rc = mwl8k_cmd_set_post_scan(hw,
+					"\x00\x00\x00\x00\x00\x00");
 
-	if (rc == -ETIMEDOUT)
-		printk(KERN_ERR "%s() timed out\n", __func__);
+		if (!rc)
+			rc = mwl8k_cmd_setrateadaptmode(hw, 0);
 
-	rc = -EIO;
+		if (!rc)
+			rc = mwl8k_set_wmm(hw, 0);
 
-mwl8k_start_disable_irq:
-	spin_lock_irq(&priv->tx_lock);
-	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
-	spin_unlock_irq(&priv->tx_lock);
-	free_irq(priv->pdev->irq, hw);
+		if (!rc)
+			rc = mwl8k_enable_sniffer(hw, 0);
 
-mwl8k_start_disable_tasklet:
-	tasklet_disable(&priv->tx_reclaim_task);
+		mwl8k_fw_unlock(hw);
+	}
+
+	if (rc) {
+		iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+		free_irq(priv->pdev->irq, hw);
+		tasklet_disable(&priv->tx_reclaim_task);
+	}
 
 	return rc;
 }
-- 
1.5.6.4

^ 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