* Re: wl1271 status/update
From: Ohad Ben-Cohen @ 2011-01-03 17:23 UTC (permalink / raw)
To: Brzezowski, Karen; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <0826983CC0CB074798C42E77D8ACD07F063277@pdtms1.pdt.com>
Hi Karen,
On Mon, Jan 3, 2011 at 7:00 PM, Brzezowski, Karen
<Karen.Brzezowski@pdt.com> wrote:
...
> I see things about compat-wireless, mac80211, sdio runtime pm support,
> lenient generic runtime pm callbacks,
> etc..
>
> I don't really understand.. do i need all of this for wl1271...
compat-wireless will build you the mac80211 layer and the wl1271
driver as external modules.
Normally that should have been enough, but in order to support the
SDIO interface of the wl1271 we had to change a few stuff in the
kernel (mainly add runtime PM support into the SDIO subsystem).
Those changes were merged into 2.6.37, so users of older kernels have
to backport them manually. Here's the list of items you need:
* SDIO runtime PM (11 patches)
* The "lenient pm callbacks" patch (a really small and trivial patch)
* "wl12xx: add platform data passing support" (that one is not
mentioned in the wiki yet for some reason, here's its link:
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg34839.html)
But if you're using 2.6.31 you may need other stuff too.. E.g. I'm not
sure that SDIO suspend/resume even made it to 2.6.31 at all...
> is there any high level documentation as to how wl1271 fits into linux/android?
Hmm.. the wiki ? :)
Regards,
Ohad.
^ permalink raw reply
* RE: wl1271 status/update
From: Brzezowski, Karen @ 2011-01-03 17:00 UTC (permalink / raw)
To: Ohad Ben-Cohen; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <AANLkTimH1aFuBfgD8g50YJjto9Mx3jRaPJMa5veG1o+z@mail.gmail.com>
Thank you Ohad!
I have been looking at this wiki and am confused as to what i exactly
need...
I see things about compat-wireless, mac80211, sdio runtime pm support,
lenient generic runtime pm callbacks,
etc..
I don't really understand.. do i need all of this for wl1271...
is there any high level documentation as to how wl1271 fits into linux/android?
i understand that wl1271 is a chip from TI that supports WLAN, FM, and BT,
but how that equates to what needs to go into linux/android, I'm not understanding...
:-)
Karen
________________________________________
From: Ohad Ben-Cohen [ohad@wizery.com]
Sent: Monday, January 03, 2011 10:49 AM
To: Brzezowski, Karen
Cc: linux-wireless@vger.kernel.org
Subject: Re: wl1271 status/update
Hi Karen,
On Mon, Jan 3, 2011 at 6:02 PM, Brzezowski, Karen
<Karen.Brzezowski@pdt.com> wrote:
> I'm quite confused as to the status of it...
...
> And I appreciate ANY help/information to get me going......
Check out our wiki - it has lots of status and porting information for
the wl12xx driver:
http://wireless.kernel.org/en/users/Drivers/wl12xx
Regards,
Ohad.
> Thanks!
> Karen
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Email secured by Check Point
^ permalink raw reply
* Re: Fwd: mac80211+iwlwifi bug with HT rates?
From: Johannes Berg @ 2011-01-03 16:53 UTC (permalink / raw)
To: Daniel Halperin; +Cc: ipw3945-devel, linux-wireless
In-Reply-To: <AANLkTind_8HzraBGxyA90ymQ_e3uJV+iykMNKzekRLA9@mail.gmail.com>
On Sun, 2011-01-02 at 23:15 -0800, Daniel Halperin wrote:
> I'm trying to track down an anomaly with a 3-stream 802.11n AP.
> iwlwifi is saying that a single antenna should be sufficient even when
> the AP supports 3 streams. Here's what I've tracked down:
> Code in iwl-agn-rxon.c uses the ht_cap TX MCS parameters to determine
> how many streams the other side supports:
> <http://git.kernel.org/?p=linux/kernel/git/iwlwifi/iwlwifi-2.6.git;a=blob;f=drivers/net/wireless/iwlwifi/iwl-agn-rxon.c;h=d33e4db7e56cab88abc3281d04adf32162b8020e;hb=HEAD#l470>
> Yet, it looks like mac80211 doesn't actually set those variables at
> all! In net/mac80211/ht.c, when converting the IE to the Station HT
> cap:
> <http://git.kernel.org/?p=linux/kernel/git/iwlwifi/iwlwifi-2.6.git;a=blob;f=net/mac80211/ht.c;h=75d679d75e63e92143d55a47601a1dfc1377ba03;hb=HEAD#l21>
> we first zero out the HT CAP (line 30) and then never actually set the
> ht_cap->mcs.tx_params variables at all. Grep says that's the only use
> of mcs.tx_params in that directory, so I'm pretty confident mac80211
> just never does that. Thus iwlwifi thinks it only needs to have 1 RX
> antenna enabled (though it defaults to a minimum of 2 when possible)
> and basically fails to receive 3 stream packets.
> Is this a bug in iwlwifi or mac80211?
It sure looks like a bug. mac80211 should fill the info I guess, but
iwlwifi also shouldn't use this weird calculation anyhow ... I've been
meaning to move the # of chains calculation to mac80211 for a while
now... maybe this is the time to do that.
johannes
^ permalink raw reply
* Re: wl1271 status/update
From: Ohad Ben-Cohen @ 2011-01-03 16:49 UTC (permalink / raw)
To: Brzezowski, Karen; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <0826983CC0CB074798C42E77D8ACD07F0616CB@pdtms1.pdt.com>
Hi Karen,
On Mon, Jan 3, 2011 at 6:02 PM, Brzezowski, Karen
<Karen.Brzezowski@pdt.com> wrote:
> I'm quite confused as to the status of it...
...
> And I appreciate ANY help/information to get me going......
Check out our wiki - it has lots of status and porting information for
the wl12xx driver:
http://wireless.kernel.org/en/users/Drivers/wl12xx
Regards,
Ohad.
> Thanks!
> Karen
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: OOPS at ieee80211_aes_ccm_encrypt()?
From: Johannes Berg @ 2011-01-03 16:46 UTC (permalink / raw)
To: Jussi Kivilinna; +Cc: linux-wireless
In-Reply-To: <20110103001006.13085vt89qfm6pcs@hayate.sektori.org>
On Mon, 2011-01-03 at 00:10 +0200, Jussi Kivilinna wrote:
> While doing stress testing on zd1211rw AP-mode I run into this problem
> that I don't think has that much to do with zd1211rw:
[snip]
> Is key being used after freeing?
It looks like it. Can you reproduce this fairly easily? I wonder if it's
an RCU problem, we do key lookups under RCU but I see no grace period
right now ... try the patch below, I'll look into it in more detail.
johannes
--- wireless-testing.orig/net/mac80211/key.c 2011-01-03 17:44:54.000000000 +0100
+++ wireless-testing/net/mac80211/key.c 2011-01-03 17:45:41.000000000 +0100
@@ -379,6 +379,8 @@ static void __ieee80211_key_destroy(stru
if (!key)
return;
+ synchronize_rcu();
+
if (key->local)
ieee80211_key_disable_hw_accel(key);
^ permalink raw reply
* wl1271 status/update
From: Brzezowski, Karen @ 2011-01-03 16:02 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org
Hi Luca, and all of you working on the wl1271 driver..
I'm quite confused as to the status of it...
I've never used these emailings before and have not
done any porting of drivers to linux.......
I sent an email to Luca and this mailing list a few weeks ago
and lots has been happening with wl1271..but i'm not sure
what to do with all the information...
talk has been about compat-wireless, etc..
Could someone please tell me what I should/need to do
to get the wl1271 driver into our android? it is based on 2.2 android
and 2.6.31 linux(ubuntu) for the imx233....
Sorry to be such a pain. All of you are so smart!!!!!!!!
And I appreciate ANY help/information to get me going......
Thanks!
Karen
^ permalink raw reply
* [PATCH] ath9k_htc: Fix packet injection
From: Sujith @ 2011-01-03 15:52 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Jouni.Malinen
From: Sujith Manoharan <Sujith.Manoharan@atheros.com>
To inject a packet in monitor mode, a dummy station has
to be associated with the monitor interface in the target.
Failing to do this would result in a firmware crash on the device.
Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
---
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 72 ++++++++++++++++++++++---
1 files changed, 64 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index ad3dd31..845b4c9 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -235,16 +235,38 @@ err:
return ret;
}
+static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct ath9k_htc_target_vif hvif;
+ int ret = 0;
+ u8 cmd_rsp;
+
+ memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
+ memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
+ hvif.index = 0; /* Should do for now */
+ WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
+ priv->nvifs--;
+}
+
static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
struct ath9k_htc_target_vif hvif;
+ struct ath9k_htc_target_sta tsta;
int ret = 0;
u8 cmd_rsp;
if (priv->nvifs > 0)
return -ENOBUFS;
+ if (priv->nstations >= ATH9K_HTC_MAX_STA)
+ return -ENOBUFS;
+
+ /*
+ * Add an interface.
+ */
+
memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
@@ -257,23 +279,57 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
return ret;
priv->nvifs++;
+
+ /*
+ * Associate a station with the interface for packet injection.
+ */
+
+ memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
+
+ memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);
+
+ tsta.is_vif_sta = 1;
+ tsta.sta_index = priv->nstations;
+ tsta.vif_index = hvif.index;
+ tsta.maxampdu = 0xffff;
+
+ WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
+ if (ret) {
+ ath_err(common, "Unable to add station entry for monitor mode\n");
+ goto err_vif;
+ }
+
+ priv->nstations++;
+
return 0;
+
+err_vif:
+ /*
+ * Remove the interface from the target.
+ */
+ __ath9k_htc_remove_monitor_interface(priv);
+ return ret;
}
static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
- struct ath9k_htc_target_vif hvif;
int ret = 0;
- u8 cmd_rsp;
+ u8 cmd_rsp, sta_idx;
- memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
- memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
- hvif.index = 0; /* Should do for now */
- WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
- priv->nvifs--;
+ __ath9k_htc_remove_monitor_interface(priv);
- return ret;
+ sta_idx = 0; /* Only single interface, for now */
+
+ WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
+ if (ret) {
+ ath_err(common, "Unable to remove station entry for monitor mode\n");
+ return ret;
+ }
+
+ priv->nstations--;
+
+ return 0;
}
static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH 14/15]include:media:davinci:vpss.h Typo change diable to disable.
From: Justin P. Mattock @ 2011-01-03 15:11 UTC (permalink / raw)
To: Jiri Kosina
Cc: Mauro Carvalho Chehab, linux-m68k, linux-kernel, netdev,
ivtv-devel, linux-media, linux-wireless, linux-scsi,
spi-devel-general, devel, linux-usb
In-Reply-To: <alpine.LNX.2.00.1101031600510.26685@pobox.suse.cz>
On 01/03/2011 07:01 AM, Jiri Kosina wrote:
> On Fri, 31 Dec 2010, Mauro Carvalho Chehab wrote:
>
>> Em 30-12-2010 21:08, Justin P. Mattock escreveu:
>>> The below patch fixes a typo "diable" to "disable". Please let me know if this
>>> is correct or not.
>>>
>>> Signed-off-by: Justin P. Mattock<justinmattock@gmail.com>
>> Acked-by: Mauro Carvalho Chehab<mchehab@redhat.com>
>
> Applied.
>
>>
>> PS.: Next time, please c/c linux-media ONLY on patches related to media
>> drivers (/drivers/video and the corresponding include files). Having to
>> dig into a series of 15 patches to just actually look on 3 patches
>> is not nice.
>
> Absolutely.
>
> Justin, no kernel developer should be afraid of being CCed. But try to
> avoid really unnecessary spamming (which this was).
>
alright..
Justin P. Mattock
^ permalink raw reply
* Re: [PATCH 08/15]drivers:scsi:lpfc:lpfc_init.c Typo change diable to disable.
From: Jiri Kosina @ 2011-01-03 15:09 UTC (permalink / raw)
To: Justin P. Mattock
Cc: linux-m68k, linux-kernel, netdev, ivtv-devel, linux-media,
linux-wireless, linux-scsi, spi-devel-general, devel, linux-usb
In-Reply-To: <1293750484-1161-8-git-send-email-justinmattock@gmail.com>
On Thu, 30 Dec 2010, Justin P. Mattock wrote:
> The below patch fixes a typo "diable" to "disable". Please let me know if this
> is correct or not.
>
> Signed-off-by: Justin P. Mattock <justinmattock@gmail.com>
Folded patched 8, 9, 10 and 13 together and applied.
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
* Re: [PATCH 01/15]arch:m68k:ifpsp060:src:fpsp.S Typo change diable to disable.
From: Jiri Kosina @ 2011-01-03 15:07 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Justin P. Mattock, linux-m68k, linux-kernel, netdev, ivtv-devel,
linux-media, linux-wireless, linux-scsi, spi-devel-general, devel,
linux-usb
In-Reply-To: <AANLkTins7rj1o4rEcEFmVSA2=1yXZSfLdO000gqQP7cg@mail.gmail.com>
On Fri, 31 Dec 2010, Geert Uytterhoeven wrote:
> On Fri, Dec 31, 2010 at 00:07, Justin P. Mattock
> <justinmattock@gmail.com> wrote:
> > The below patch fixes a typo "diable" to "disable". Please let me know if this
> > is correct or not.
> >
> > Signed-off-by: Justin P. Mattock <justinmattock@gmail.com>
>
> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Applied, thanks.
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
* Re: [PATCH 07/15]drivers:net:wireless:iwlwifi Typo change diable to disable.
From: Jiri Kosina @ 2011-01-03 15:06 UTC (permalink / raw)
To: Larry Finger
Cc: Justin P. Mattock, linux-m68k, linux-kernel, netdev, ivtv-devel,
linux-media, linux-wireless, linux-scsi, spi-devel-general, devel,
linux-usb
In-Reply-To: <4D1DF7CA.8040504@lwfinger.net>
On Fri, 31 Dec 2010, Larry Finger wrote:
> On 12/30/2010 05:07 PM, Justin P. Mattock wrote:
> > The below patch fixes a typo "diable" to "disable". Please let me know if this
> > is correct or not.
> >
> > Signed-off-by: Justin P. Mattock <justinmattock@gmail.com>
> >
>
> ACKed-by: Larry Finger <Larry.Finger@lwfinger.net>
Applied, thanks.
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
* Re: Tp-link wn7200nd - cannot associate
From: Chin Shi Hong @ 2011-01-03 15:04 UTC (permalink / raw)
To: Ming-Ching Tiew; +Cc: linux-wireless
In-Reply-To: <651997.51284.qm@web31502.mail.mud.yahoo.com>
On Mon, Jan 3, 2011 at 10:38 AM, Ming-Ching Tiew <mctiew@yahoo.com> wrote:
>
> I have a TP-LINK WN7200ND, I am tested it with Kernel 2.6.36.1 and 2.6.35.10, basically after inserting the USB, the interface is up and it can never associate with any access point.
>
> #lsmod |grep rt2
>
> rt2800usb 7632 0
> rt2800lib 20328 1 rt2800usb
> rt2x00usb 4628 2 rt2800usb,rt2800lib
> rt2x00lib 15408 2 rt2800lib,rt2x00usb
> mac80211 122068 2 rt2x00usb,rt2x00lib
> cfg80211 92252 2 rt2x00lib,mac80211
>
> There are a lot of similar complaints on the net, this is one example :-
>
> http://ubuntuforums.org/showthread.php?t=1530095
>
> There don't seem to be any issue with 'iwlist wlanX scan'. But just can't associate.
>
> Any recommendation ? Any debug information I should provide ?
>
> Regards
>
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Good luck with you. My rt3090 also not work on 64 bit ubuntu but work
on 32 bit ubuntu.
You use Ubuntu is it? Which version? 32-bit or 64-bit version?
And, can you access internet through wired connection?
Regards,
^ permalink raw reply
* Re: [PATCH 11/15]drivers:media:video:cx18:cx23418.h Typo change diable to disable.
From: Jiri Kosina @ 2011-01-03 15:04 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Justin P. Mattock, linux-m68k, linux-kernel, netdev, ivtv-devel,
linux-media, linux-wireless, linux-scsi, spi-devel-general, devel,
linux-usb
In-Reply-To: <4D1DAF2D.5070604@gmail.com>
On Fri, 31 Dec 2010, Mauro Carvalho Chehab wrote:
> Em 30-12-2010 21:08, Justin P. Mattock escreveu:
> > The below patch fixes a typo "diable" to "disable". Please let me know if this
> > is correct or not.
> >
> > Signed-off-by: Justin P. Mattock <justinmattock@gmail.com>
> Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Folded all three 'media' fixes into one and applied with your Ack. Thanks.
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
* Re: [PATCH 14/15]include:media:davinci:vpss.h Typo change diable to disable.
From: Jiri Kosina @ 2011-01-03 15:01 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Justin P. Mattock, linux-m68k, linux-kernel, netdev, ivtv-devel,
linux-media, linux-wireless, linux-scsi, spi-devel-general, devel,
linux-usb
In-Reply-To: <4D1DAFF5.3090108@gmail.com>
On Fri, 31 Dec 2010, Mauro Carvalho Chehab wrote:
> Em 30-12-2010 21:08, Justin P. Mattock escreveu:
> > The below patch fixes a typo "diable" to "disable". Please let me know if this
> > is correct or not.
> >
> > Signed-off-by: Justin P. Mattock <justinmattock@gmail.com>
> Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Applied.
>
> PS.: Next time, please c/c linux-media ONLY on patches related to media
> drivers (/drivers/video and the corresponding include files). Having to
> dig into a series of 15 patches to just actually look on 3 patches
> is not nice.
Absolutely.
Justin, no kernel developer should be afraid of being CCed. But try to
avoid really unnecessary spamming (which this was).
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
* [PATCH 14/32] wireless/ipw2x00: use system_wq instead of dedicated workqueues
From: Tejun Heo @ 2011-01-03 13:49 UTC (permalink / raw)
To: linux-kernel; +Cc: Tejun Heo, John W. Linville, linux-wireless
In-Reply-To: <1294062595-30097-1-git-send-email-tj@kernel.org>
With cmwq, there's no reason to use separate workqueues in ipw2x00
drivers. Drop them and use system_wq instead. All used work items
are sync canceled on driver detach.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
---
Only compile tested. Please feel free to take it into the subsystem
tree or simply ack - I'll route it through the wq tree.
Thanks.
drivers/net/wireless/ipw2x00/ipw2100.c | 70 +++++-------
drivers/net/wireless/ipw2x00/ipw2100.h | 1 -
drivers/net/wireless/ipw2x00/ipw2200.c | 196 ++++++++++++++------------------
drivers/net/wireless/ipw2x00/ipw2200.h | 2 -
4 files changed, 118 insertions(+), 151 deletions(-)
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 61915f3..471a52a 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -706,11 +706,10 @@ static void schedule_reset(struct ipw2100_priv *priv)
netif_stop_queue(priv->net_dev);
priv->status |= STATUS_RESET_PENDING;
if (priv->reset_backoff)
- queue_delayed_work(priv->workqueue, &priv->reset_work,
- priv->reset_backoff * HZ);
+ schedule_delayed_work(&priv->reset_work,
+ priv->reset_backoff * HZ);
else
- queue_delayed_work(priv->workqueue, &priv->reset_work,
- 0);
+ schedule_delayed_work(&priv->reset_work, 0);
if (priv->reset_backoff < MAX_RESET_BACKOFF)
priv->reset_backoff++;
@@ -1474,7 +1473,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
if (priv->stop_hang_check) {
priv->stop_hang_check = 0;
- queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
+ schedule_delayed_work(&priv->hang_check, HZ / 2);
}
fail_up:
@@ -1808,8 +1807,8 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
if (priv->stop_rf_kill) {
priv->stop_rf_kill = 0;
- queue_delayed_work(priv->workqueue, &priv->rf_kill,
- round_jiffies_relative(HZ));
+ schedule_delayed_work(&priv->rf_kill,
+ round_jiffies_relative(HZ));
}
deferred = 1;
@@ -2086,7 +2085,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
priv->status |= STATUS_ASSOCIATING;
priv->connect_start = get_seconds();
- queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10);
+ schedule_delayed_work(&priv->wx_event_work, HZ / 10);
}
static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
@@ -2166,9 +2165,9 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
return;
if (priv->status & STATUS_SECURITY_UPDATED)
- queue_delayed_work(priv->workqueue, &priv->security_work, 0);
+ schedule_delayed_work(&priv->security_work, 0);
- queue_delayed_work(priv->workqueue, &priv->wx_event_work, 0);
+ schedule_delayed_work(&priv->wx_event_work, 0);
}
static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
@@ -2183,8 +2182,7 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
/* Make sure the RF Kill check timer is running */
priv->stop_rf_kill = 0;
cancel_delayed_work(&priv->rf_kill);
- queue_delayed_work(priv->workqueue, &priv->rf_kill,
- round_jiffies_relative(HZ));
+ schedule_delayed_work(&priv->rf_kill, round_jiffies_relative(HZ));
}
static void send_scan_event(void *data)
@@ -2219,13 +2217,12 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
/* Only userspace-requested scan completion events go out immediately */
if (!priv->user_requested_scan) {
if (!delayed_work_pending(&priv->scan_event_later))
- queue_delayed_work(priv->workqueue,
- &priv->scan_event_later,
- round_jiffies_relative(msecs_to_jiffies(4000)));
+ schedule_delayed_work(&priv->scan_event_later,
+ round_jiffies_relative(msecs_to_jiffies(4000)));
} else {
priv->user_requested_scan = 0;
cancel_delayed_work(&priv->scan_event_later);
- queue_work(priv->workqueue, &priv->scan_event_now);
+ schedule_work(&priv->scan_event_now);
}
}
@@ -4329,8 +4326,8 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
/* Make sure the RF_KILL check timer is running */
priv->stop_rf_kill = 0;
cancel_delayed_work(&priv->rf_kill);
- queue_delayed_work(priv->workqueue, &priv->rf_kill,
- round_jiffies_relative(HZ));
+ schedule_delayed_work(&priv->rf_kill,
+ round_jiffies_relative(HZ));
} else
schedule_reset(priv);
}
@@ -4461,20 +4458,17 @@ static void bd_queue_initialize(struct ipw2100_priv *priv,
IPW_DEBUG_INFO("exit\n");
}
-static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
+static void ipw2100_kill_works(struct ipw2100_priv *priv)
{
- if (priv->workqueue) {
- priv->stop_rf_kill = 1;
- priv->stop_hang_check = 1;
- cancel_delayed_work(&priv->reset_work);
- cancel_delayed_work(&priv->security_work);
- cancel_delayed_work(&priv->wx_event_work);
- cancel_delayed_work(&priv->hang_check);
- cancel_delayed_work(&priv->rf_kill);
- cancel_delayed_work(&priv->scan_event_later);
- destroy_workqueue(priv->workqueue);
- priv->workqueue = NULL;
- }
+ priv->stop_rf_kill = 1;
+ priv->stop_hang_check = 1;
+ cancel_delayed_work_sync(&priv->reset_work);
+ cancel_delayed_work_sync(&priv->security_work);
+ cancel_delayed_work_sync(&priv->wx_event_work);
+ cancel_delayed_work_sync(&priv->hang_check);
+ cancel_delayed_work_sync(&priv->rf_kill);
+ cancel_work_sync(&priv->scan_event_now);
+ cancel_delayed_work_sync(&priv->scan_event_later);
}
static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
@@ -6046,7 +6040,7 @@ static void ipw2100_hang_check(struct work_struct *work)
priv->last_rtc = rtc;
if (!priv->stop_hang_check)
- queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
+ schedule_delayed_work(&priv->hang_check, HZ / 2);
spin_unlock_irqrestore(&priv->low_lock, flags);
}
@@ -6062,8 +6056,8 @@ static void ipw2100_rf_kill(struct work_struct *work)
if (rf_kill_active(priv)) {
IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
if (!priv->stop_rf_kill)
- queue_delayed_work(priv->workqueue, &priv->rf_kill,
- round_jiffies_relative(HZ));
+ schedule_delayed_work(&priv->rf_kill,
+ round_jiffies_relative(HZ));
goto exit_unlock;
}
@@ -6209,8 +6203,6 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
INIT_LIST_HEAD(&priv->fw_pend_list);
INIT_STAT(&priv->fw_pend_stat);
- priv->workqueue = create_workqueue(DRV_NAME);
-
INIT_DELAYED_WORK(&priv->reset_work, ipw2100_reset_adapter);
INIT_DELAYED_WORK(&priv->security_work, ipw2100_security_work);
INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
@@ -6410,7 +6402,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
if (dev->irq)
free_irq(dev->irq, priv);
- ipw2100_kill_workqueue(priv);
+ ipw2100_kill_works(priv);
/* These are safe to call even if they weren't allocated */
ipw2100_queues_free(priv);
@@ -6460,9 +6452,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
* first, then close() will crash. */
unregister_netdev(dev);
- /* ipw2100_down will ensure that there is no more pending work
- * in the workqueue's, so we can safely remove them now. */
- ipw2100_kill_workqueue(priv);
+ ipw2100_kill_works(priv);
ipw2100_queues_free(priv);
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.h b/drivers/net/wireless/ipw2x00/ipw2100.h
index 838002b..99cba96 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.h
+++ b/drivers/net/wireless/ipw2x00/ipw2100.h
@@ -580,7 +580,6 @@ struct ipw2100_priv {
struct tasklet_struct irq_tasklet;
- struct workqueue_struct *workqueue;
struct delayed_work reset_work;
struct delayed_work security_work;
struct delayed_work wx_event_work;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 8d6ed5f..7319395 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -894,9 +894,8 @@ static void ipw_led_link_on(struct ipw_priv *priv)
/* If we aren't associated, schedule turning the LED off */
if (!(priv->status & STATUS_ASSOCIATED))
- queue_delayed_work(priv->workqueue,
- &priv->led_link_off,
- LD_TIME_LINK_ON);
+ schedule_delayed_work(&priv->led_link_off,
+ LD_TIME_LINK_ON);
}
spin_unlock_irqrestore(&priv->lock, flags);
@@ -939,8 +938,8 @@ static void ipw_led_link_off(struct ipw_priv *priv)
* turning the LED on (blink while unassociated) */
if (!(priv->status & STATUS_RF_KILL_MASK) &&
!(priv->status & STATUS_ASSOCIATED))
- queue_delayed_work(priv->workqueue, &priv->led_link_on,
- LD_TIME_LINK_OFF);
+ schedule_delayed_work(&priv->led_link_on,
+ LD_TIME_LINK_OFF);
}
@@ -980,13 +979,11 @@ static void __ipw_led_activity_on(struct ipw_priv *priv)
priv->status |= STATUS_LED_ACT_ON;
cancel_delayed_work(&priv->led_act_off);
- queue_delayed_work(priv->workqueue, &priv->led_act_off,
- LD_TIME_ACT_ON);
+ schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON);
} else {
/* Reschedule LED off for full time period */
cancel_delayed_work(&priv->led_act_off);
- queue_delayed_work(priv->workqueue, &priv->led_act_off,
- LD_TIME_ACT_ON);
+ schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON);
}
}
@@ -1795,13 +1792,11 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
if (disable_radio) {
priv->status |= STATUS_RF_KILL_SW;
- if (priv->workqueue) {
- cancel_delayed_work(&priv->request_scan);
- cancel_delayed_work(&priv->request_direct_scan);
- cancel_delayed_work(&priv->request_passive_scan);
- cancel_delayed_work(&priv->scan_event);
- }
- queue_work(priv->workqueue, &priv->down);
+ cancel_delayed_work(&priv->request_scan);
+ cancel_delayed_work(&priv->request_direct_scan);
+ cancel_delayed_work(&priv->request_passive_scan);
+ cancel_delayed_work(&priv->scan_event);
+ schedule_work(&priv->down);
} else {
priv->status &= ~STATUS_RF_KILL_SW;
if (rf_kill_active(priv)) {
@@ -1809,10 +1804,10 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
"disabled by HW switch\n");
/* Make sure the RF_KILL check timer is running */
cancel_delayed_work(&priv->rf_kill);
- queue_delayed_work(priv->workqueue, &priv->rf_kill,
- round_jiffies_relative(2 * HZ));
+ schedule_delayed_work(&priv->rf_kill,
+ round_jiffies_relative(2 * HZ));
} else
- queue_work(priv->workqueue, &priv->up);
+ schedule_work(&priv->up);
}
return 1;
@@ -2056,7 +2051,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
cancel_delayed_work(&priv->request_passive_scan);
cancel_delayed_work(&priv->scan_event);
schedule_work(&priv->link_down);
- queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
+ schedule_delayed_work(&priv->rf_kill, 2 * HZ);
handled |= IPW_INTA_BIT_RF_KILL_DONE;
}
@@ -2096,7 +2091,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
priv->status &= ~STATUS_HCMD_ACTIVE;
wake_up_interruptible(&priv->wait_command_queue);
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
handled |= IPW_INTA_BIT_FATAL_ERROR;
}
@@ -2316,11 +2311,6 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);
}
-/*
- * NOTE: This must be executed from our workqueue as it results in udelay
- * being called which may corrupt the keyboard if executed on default
- * workqueue
- */
static void ipw_adapter_restart(void *adapter)
{
struct ipw_priv *priv = adapter;
@@ -2361,13 +2351,13 @@ static void ipw_scan_check(void *data)
IPW_DEBUG_SCAN("Scan completion watchdog resetting "
"adapter after (%dms).\n",
jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
} else if (priv->status & STATUS_SCANNING) {
IPW_DEBUG_SCAN("Scan completion watchdog aborting scan "
"after (%dms).\n",
jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
ipw_abort_scan(priv);
- queue_delayed_work(priv->workqueue, &priv->scan_check, HZ);
+ schedule_delayed_work(&priv->scan_check, HZ);
}
}
@@ -3936,7 +3926,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
if (priv->status & STATUS_ASSOCIATING) {
IPW_DEBUG_ASSOC("Disassociating while associating.\n");
- queue_work(priv->workqueue, &priv->disassociate);
+ schedule_work(&priv->disassociate);
return;
}
@@ -4353,8 +4343,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
priv->quality = quality;
- queue_delayed_work(priv->workqueue, &priv->gather_stats,
- IPW_STATS_INTERVAL);
+ schedule_delayed_work(&priv->gather_stats, IPW_STATS_INTERVAL);
}
static void ipw_bg_gather_stats(struct work_struct *work)
@@ -4389,10 +4378,10 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
IPW_DL_STATE,
"Aborting scan with missed beacon.\n");
- queue_work(priv->workqueue, &priv->abort_scan);
+ schedule_work(&priv->abort_scan);
}
- queue_work(priv->workqueue, &priv->disassociate);
+ schedule_work(&priv->disassociate);
return;
}
@@ -4418,8 +4407,7 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
if (!(priv->status & STATUS_ROAMING)) {
priv->status |= STATUS_ROAMING;
if (!(priv->status & STATUS_SCANNING))
- queue_delayed_work(priv->workqueue,
- &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
}
return;
}
@@ -4432,7 +4420,7 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
* channels..) */
IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
"Aborting scan with missed beacon.\n");
- queue_work(priv->workqueue, &priv->abort_scan);
+ schedule_work(&priv->abort_scan);
}
IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
@@ -4455,8 +4443,8 @@ static void handle_scan_event(struct ipw_priv *priv)
/* Only userspace-requested scan completion events go out immediately */
if (!priv->user_requested_scan) {
if (!delayed_work_pending(&priv->scan_event))
- queue_delayed_work(priv->workqueue, &priv->scan_event,
- round_jiffies_relative(msecs_to_jiffies(4000)));
+ schedule_delayed_work(&priv->scan_event,
+ round_jiffies_relative(msecs_to_jiffies(4000)));
} else {
union iwreq_data wrqu;
@@ -4509,20 +4497,17 @@ static void ipw_rx_notification(struct ipw_priv *priv,
IPW_DEBUG_ASSOC
("queueing adhoc check\n");
- queue_delayed_work(priv->
- workqueue,
- &priv->
- adhoc_check,
- le16_to_cpu(priv->
- assoc_request.
- beacon_interval));
+ schedule_delayed_work(
+ &priv->adhoc_check,
+ le16_to_cpu(priv->
+ assoc_request.
+ beacon_interval));
break;
}
priv->status &= ~STATUS_ASSOCIATING;
priv->status |= STATUS_ASSOCIATED;
- queue_work(priv->workqueue,
- &priv->system_config);
+ schedule_work(&priv->system_config);
#ifdef CONFIG_IPW2200_QOS
#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
@@ -4785,43 +4770,37 @@ static void ipw_rx_notification(struct ipw_priv *priv,
#ifdef CONFIG_IPW2200_MONITOR
if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
priv->status |= STATUS_SCAN_FORCED;
- queue_delayed_work(priv->workqueue,
- &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
break;
}
priv->status &= ~STATUS_SCAN_FORCED;
#endif /* CONFIG_IPW2200_MONITOR */
/* Do queued direct scans first */
- if (priv->status & STATUS_DIRECT_SCAN_PENDING) {
- queue_delayed_work(priv->workqueue,
- &priv->request_direct_scan, 0);
- }
+ if (priv->status & STATUS_DIRECT_SCAN_PENDING)
+ schedule_delayed_work(&priv->request_direct_scan, 0);
if (!(priv->status & (STATUS_ASSOCIATED |
STATUS_ASSOCIATING |
STATUS_ROAMING |
STATUS_DISASSOCIATING)))
- queue_work(priv->workqueue, &priv->associate);
+ schedule_work(&priv->associate);
else if (priv->status & STATUS_ROAMING) {
if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
/* If a scan completed and we are in roam mode, then
* the scan that completed was the one requested as a
* result of entering roam... so, schedule the
* roam work */
- queue_work(priv->workqueue,
- &priv->roam);
+ schedule_work(&priv->roam);
else
/* Don't schedule if we aborted the scan */
priv->status &= ~STATUS_ROAMING;
} else if (priv->status & STATUS_SCAN_PENDING)
- queue_delayed_work(priv->workqueue,
- &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
else if (priv->config & CFG_BACKGROUND_SCAN
&& priv->status & STATUS_ASSOCIATED)
- queue_delayed_work(priv->workqueue,
- &priv->request_scan,
- round_jiffies_relative(HZ));
+ schedule_delayed_work(&priv->request_scan,
+ round_jiffies_relative(HZ));
/* Send an empty event to user space.
* We don't send the received data on the event because
@@ -5185,7 +5164,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
/* If the pre-allocated buffer pool is dropping low, schedule to
* refill it */
if (rxq->free_count <= RX_LOW_WATERMARK)
- queue_work(priv->workqueue, &priv->rx_replenish);
+ schedule_work(&priv->rx_replenish);
/* If we've added more space for the firmware to place data, tell it */
if (write != rxq->write)
@@ -6126,8 +6105,8 @@ static void ipw_adhoc_check(void *data)
return;
}
- queue_delayed_work(priv->workqueue, &priv->adhoc_check,
- le16_to_cpu(priv->assoc_request.beacon_interval));
+ schedule_delayed_work(&priv->adhoc_check,
+ le16_to_cpu(priv->assoc_request.beacon_interval));
}
static void ipw_bg_adhoc_check(struct work_struct *work)
@@ -6516,8 +6495,7 @@ send_request:
} else
priv->status &= ~STATUS_SCAN_PENDING;
- queue_delayed_work(priv->workqueue, &priv->scan_check,
- IPW_SCAN_CHECK_WATCHDOG);
+ schedule_delayed_work(&priv->scan_check, IPW_SCAN_CHECK_WATCHDOG);
done:
mutex_unlock(&priv->mutex);
return err;
@@ -6987,8 +6965,7 @@ static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
!memcmp(network->ssid,
priv->assoc_network->ssid,
network->ssid_len)) {
- queue_work(priv->workqueue,
- &priv->merge_networks);
+ schedule_work(&priv->merge_networks);
}
}
@@ -7656,7 +7633,7 @@ static int ipw_associate(void *data)
if (priv->status & STATUS_DISASSOCIATING) {
IPW_DEBUG_ASSOC("Not attempting association (in "
"disassociating)\n ");
- queue_work(priv->workqueue, &priv->associate);
+ schedule_work(&priv->associate);
return 0;
}
@@ -7724,12 +7701,10 @@ static int ipw_associate(void *data)
if (!(priv->status & STATUS_SCANNING)) {
if (!(priv->config & CFG_SPEED_SCAN))
- queue_delayed_work(priv->workqueue,
- &priv->request_scan,
- SCAN_INTERVAL);
+ schedule_delayed_work(&priv->request_scan,
+ SCAN_INTERVAL);
else
- queue_delayed_work(priv->workqueue,
- &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
}
return 0;
@@ -8892,7 +8867,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
priv->ieee->iw_mode = wrqu->mode;
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
mutex_unlock(&priv->mutex);
return err;
}
@@ -9591,7 +9566,7 @@ static int ipw_wx_set_scan(struct net_device *dev,
IPW_DEBUG_WX("Start scan\n");
- queue_delayed_work(priv->workqueue, work, 0);
+ schedule_delayed_work(work, 0);
return 0;
}
@@ -9930,7 +9905,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
#else
priv->net_dev->type = ARPHRD_IEEE80211;
#endif
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
}
ipw_set_channel(priv, parms[1]);
@@ -9940,7 +9915,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
return 0;
}
priv->net_dev->type = ARPHRD_ETHER;
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
}
mutex_unlock(&priv->mutex);
return 0;
@@ -9954,7 +9929,7 @@ static int ipw_wx_reset(struct net_device *dev,
{
struct ipw_priv *priv = libipw_priv(dev);
IPW_DEBUG_WX("RESET\n");
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
return 0;
}
@@ -10544,7 +10519,7 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
printk(KERN_INFO "%s: Setting MAC to %pM\n",
priv->net_dev->name, priv->mac_addr);
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
mutex_unlock(&priv->mutex);
return 0;
}
@@ -10677,9 +10652,7 @@ static void ipw_rf_kill(void *adapter)
if (rf_kill_active(priv)) {
IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
- if (priv->workqueue)
- queue_delayed_work(priv->workqueue,
- &priv->rf_kill, 2 * HZ);
+ schedule_delayed_work(&priv->rf_kill, 2 * HZ);
goto exit_unlock;
}
@@ -10690,7 +10663,7 @@ static void ipw_rf_kill(void *adapter)
"device\n");
/* we can not do an adapter restart while inside an irq lock */
- queue_work(priv->workqueue, &priv->adapter_restart);
+ schedule_work(&priv->adapter_restart);
} else
IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
"enabled\n");
@@ -10728,7 +10701,7 @@ static void ipw_link_up(struct ipw_priv *priv)
notify_wx_assoc_event(priv);
if (priv->config & CFG_BACKGROUND_SCAN)
- queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
+ schedule_delayed_work(&priv->request_scan, HZ);
}
static void ipw_bg_link_up(struct work_struct *work)
@@ -10757,7 +10730,7 @@ static void ipw_link_down(struct ipw_priv *priv)
if (!(priv->status & STATUS_EXIT_PENDING)) {
/* Queue up another scan... */
- queue_delayed_work(priv->workqueue, &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
} else
cancel_delayed_work(&priv->scan_event);
}
@@ -10775,7 +10748,6 @@ static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv)
{
int ret = 0;
- priv->workqueue = create_workqueue(DRV_NAME);
init_waitqueue_head(&priv->wait_command_queue);
init_waitqueue_head(&priv->wait_state);
@@ -11332,8 +11304,7 @@ static int ipw_up(struct ipw_priv *priv)
IPW_WARNING("Radio Frequency Kill Switch is On:\n"
"Kill switch must be turned off for "
"wireless networking to work.\n");
- queue_delayed_work(priv->workqueue, &priv->rf_kill,
- 2 * HZ);
+ schedule_delayed_work(&priv->rf_kill, 2 * HZ);
return 0;
}
@@ -11343,8 +11314,7 @@ static int ipw_up(struct ipw_priv *priv)
/* If configure to try and auto-associate, kick
* off a scan. */
- queue_delayed_work(priv->workqueue,
- &priv->request_scan, 0);
+ schedule_delayed_work(&priv->request_scan, 0);
return 0;
}
@@ -11810,7 +11780,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
err = request_irq(pdev->irq, ipw_isr, IRQF_SHARED, DRV_NAME, priv);
if (err) {
IPW_ERROR("Error allocating IRQ %d\n", pdev->irq);
- goto out_destroy_workqueue;
+ goto out_iounmap;
}
SET_NETDEV_DEV(net_dev, &pdev->dev);
@@ -11878,9 +11848,6 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
out_release_irq:
free_irq(pdev->irq, priv);
- out_destroy_workqueue:
- destroy_workqueue(priv->workqueue);
- priv->workqueue = NULL;
out_iounmap:
iounmap(priv->hw_base);
out_pci_release_regions:
@@ -11923,18 +11890,31 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
kfree(priv->cmdlog);
priv->cmdlog = NULL;
}
- /* ipw_down will ensure that there is no more pending work
- * in the workqueue's, so we can safely remove them now. */
- cancel_delayed_work(&priv->adhoc_check);
- cancel_delayed_work(&priv->gather_stats);
- cancel_delayed_work(&priv->request_scan);
- cancel_delayed_work(&priv->request_direct_scan);
- cancel_delayed_work(&priv->request_passive_scan);
- cancel_delayed_work(&priv->scan_event);
- cancel_delayed_work(&priv->rf_kill);
- cancel_delayed_work(&priv->scan_check);
- destroy_workqueue(priv->workqueue);
- priv->workqueue = NULL;
+
+ /* make sure all works are inactive */
+ cancel_delayed_work_sync(&priv->adhoc_check);
+ cancel_work_sync(&priv->associate);
+ cancel_work_sync(&priv->disassociate);
+ cancel_work_sync(&priv->system_config);
+ cancel_work_sync(&priv->rx_replenish);
+ cancel_work_sync(&priv->adapter_restart);
+ cancel_delayed_work_sync(&priv->rf_kill);
+ cancel_work_sync(&priv->up);
+ cancel_work_sync(&priv->down);
+ cancel_delayed_work_sync(&priv->request_scan);
+ cancel_delayed_work_sync(&priv->request_direct_scan);
+ cancel_delayed_work_sync(&priv->request_passive_scan);
+ cancel_delayed_work_sync(&priv->scan_event);
+ cancel_delayed_work_sync(&priv->gather_stats);
+ cancel_work_sync(&priv->abort_scan);
+ cancel_work_sync(&priv->roam);
+ cancel_delayed_work_sync(&priv->scan_check);
+ cancel_work_sync(&priv->link_up);
+ cancel_work_sync(&priv->link_down);
+ cancel_delayed_work_sync(&priv->led_link_on);
+ cancel_delayed_work_sync(&priv->led_link_off);
+ cancel_delayed_work_sync(&priv->led_act_off);
+ cancel_work_sync(&priv->merge_networks);
/* Free MAC hash list for ADHOC */
for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
@@ -12022,7 +12002,7 @@ static int ipw_pci_resume(struct pci_dev *pdev)
priv->suspend_time = get_seconds() - priv->suspend_at;
/* Bring the device back up */
- queue_work(priv->workqueue, &priv->up);
+ schedule_work(&priv->up);
return 0;
}
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h
index d7d049c..0441445 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.h
+++ b/drivers/net/wireless/ipw2x00/ipw2200.h
@@ -1299,8 +1299,6 @@ struct ipw_priv {
u8 direct_scan_ssid[IW_ESSID_MAX_SIZE];
u8 direct_scan_ssid_len;
- struct workqueue_struct *workqueue;
-
struct delayed_work adhoc_check;
struct work_struct associate;
struct work_struct disassociate;
--
1.7.1
^ permalink raw reply related
* [PATCH v3 2/2] wl12xx: BA receiver support
From: Shahar Levi @ 2011-01-03 13:42 UTC (permalink / raw)
To: linux-wireless; +Cc: Luciano Coelho
In-Reply-To: <1294062164-3459-1-git-send-email-shahar_levi@ti.com>
Add new ampdu_action ops to support receiver BA.
The BA initiator session management in FW independently.
Signed-off-by: Shahar Levi <shahar_levi@ti.com>
---
Dependencies:
- BA Initiator patches have a runtime dependency on commit
"[RFC v5] wl1271: BA Initiator support"
Changes from v1:
- Add mutex and (wl->state == WL1271_STATE_OFF) protection
- "BIT(tid)" instead of "BIT(0) << tid"
- Move all event code move to the next patch
Changes from v2:
- Add supported FW version auto detection mechanism
drivers/net/wireless/wl12xx/acx.c | 36 ++++++++++++++++++++++
drivers/net/wireless/wl12xx/acx.h | 21 +++++++++++++
drivers/net/wireless/wl12xx/main.c | 59 ++++++++++++++++++++++++++++++++++++
3 files changed, 116 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 54fd68d..f33ab50 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1359,6 +1359,42 @@ out:
return ret;
}
+/* setup BA session receiver setting in the FW. */
+int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
+ u16 *ssn, u8 policy)
+{
+ struct wl1271_acx_ba_receiver_setup *acx;
+ int ret;
+
+ wl1271_debug(DEBUG_ACX, "acx ba receiver session setting");
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* Single link for now */
+ acx->link_id = 1;
+ acx->tid = tid_index;
+ acx->enable = policy;
+ acx->win_size = 0;
+
+ if (policy)
+ acx->ssn = *ssn;
+
+ ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx,
+ sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("acx ba receiver session failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
+
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
{
struct wl1271_acx_fw_tsf_information *tsf_info;
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index df48468..8fc98b7 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1085,6 +1085,25 @@ struct wl1271_acx_ba_session_policy {
u8 padding[3];
} __packed;
+struct wl1271_acx_ba_receiver_setup {
+ struct acx_header header;
+
+ /* Specifies Link Id, Range 0-31, 0xFF means ANY Link Id */
+ u8 link_id;
+
+ u8 tid;
+
+ u8 enable;
+
+ u8 padding[1];
+
+ /* Windows size in number of packets */
+ u16 win_size;
+
+ /* BA session starting sequence number. RANGE 0-FFF */
+ u16 ssn;
+} __packed;
+
struct wl1271_acx_fw_tsf_information {
struct acx_header header;
@@ -1222,6 +1241,8 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
int wl1271_acx_set_ba_session(struct wl1271 *wl,
enum ieee80211_back_parties direction,
u8 tid_index, u8 policy);
+int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
+ u16 *ssn, u8 policy);
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index c44462d..04b69ab 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2251,6 +2251,64 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
return 0;
}
+int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+{
+ struct wl1271 *wl = hw->priv;
+ int ret;
+
+ mutex_lock(&wl->mutex);
+
+ if (unlikely(wl->state == WL1271_STATE_OFF)) {
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ ret = wl1271_ps_elp_wakeup(wl, false);
+ if (ret < 0)
+ goto out;
+
+ switch (action) {
+ case IEEE80211_AMPDU_RX_START:
+ if ((wl->ba_allowed) && (wl->ba_support)) {
+ ret = wl1271_acx_set_ba_receiver_session(wl, tid, ssn,
+ true);
+ if (!ret)
+ wl->ba_rx_bitmap |= BIT(tid);
+ } else
+ ret = -EPERM;
+ break;
+
+ case IEEE80211_AMPDU_RX_STOP:
+ ret = wl1271_acx_set_ba_receiver_session(wl, tid, ssn, false);
+ if (!ret)
+ wl->ba_rx_bitmap &= ~BIT(tid);
+ break;
+
+ /*
+ * The BA initiator session management in FW independently.
+ * Falling break here on purpose for all TX APDU commands.
+ */
+ case IEEE80211_AMPDU_TX_START:
+ case IEEE80211_AMPDU_TX_STOP:
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
+ ret = -EINVAL;
+ break;
+
+ default:
+ wl1271_error("Incorrect ampdu action id=%x\n", action);
+ ret = -ENODEV;
+ }
+
+ wl1271_ps_elp_sleep(wl);
+
+out:
+ mutex_unlock(&wl->mutex);
+
+ return ret;
+}
+
/* can't be const, mac80211 writes to this */
static struct ieee80211_rate wl1271_rates[] = {
{ .bitrate = 10,
@@ -2497,6 +2555,7 @@ static const struct ieee80211_ops wl1271_ops = {
.conf_tx = wl1271_op_conf_tx,
.get_tsf = wl1271_op_get_tsf,
.get_survey = wl1271_op_get_survey,
+ .ampdu_action = wl1271_op_ampdu_action,
CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
};
--
1.7.0.4
^ permalink raw reply related
* [PATCH 0/2] wl12xx: BA Initiator & receiver support
From: Shahar Levi @ 2011-01-03 13:42 UTC (permalink / raw)
To: linux-wireless; +Cc: Luciano Coelho
That series gather two patches:
[PATCH v5] wl12xx: BA initiator support
[PATCH v3] wl12xx: BA receiver support
Add 80211n BA initiator & receiver session support wl1271 driver.
BA initiator session management included in FW independently.
Include supported FW version auto detection mechanism.
Next step is to implement HW flag that in case of wl12xx driver indicates
mac80211 to use BA win size of 8.
Shahar Levi (2):
wl12xx: BA initiator support
wl12xx: BA receiver support
drivers/net/wireless/wl12xx/acx.c | 86 ++++++++++++++++++++++++++++++++++
drivers/net/wireless/wl12xx/acx.h | 62 +++++++++++++++++++++++-
drivers/net/wireless/wl12xx/boot.c | 41 +++++++++++++++-
drivers/net/wireless/wl12xx/conf.h | 7 +++
drivers/net/wireless/wl12xx/init.c | 50 ++++++++++++++++++++
drivers/net/wireless/wl12xx/main.c | 73 +++++++++++++++++++++++++++--
drivers/net/wireless/wl12xx/wl12xx.h | 15 ++++++-
7 files changed, 323 insertions(+), 11 deletions(-)
^ permalink raw reply
* [PATCH v5 1/2] wl12xx: BA initiator support
From: Shahar Levi @ 2011-01-03 13:42 UTC (permalink / raw)
To: linux-wireless; +Cc: Luciano Coelho
In-Reply-To: <1294062164-3459-1-git-send-email-shahar_levi@ti.com>
Add 80211n BA initiator session support wl1271 driver.
Include BA supported FW version auto detection mechanism.
BA initiator session management included in FW independently.
Signed-off-by: Shahar Levi <shahar_levi@ti.com>
---
Limitation:
- For now only one BA per direction is supported
Changes from v1:
- Remove wl1271_op_ampdu_action()
- set CONF_BA_INACTIVITY_TIMEOUT as configurable value
- Clean to Linux code style.
Changes from v2:
- Two new ACX commands ACX_BA_SESSION_POLICY_CFG & ACX_BA_SESSION_RX_SETUP
- New struct wl1271_acx_ba_session_policy
- Calling wl1271_set_ba_policies() once in init
- Use ieee80211_back_parties
- Rebase to latest
Changes from v3:
- New FW file name due to new FW API
Changes from v4:
- Reverse change of "New FW file name due to new FW API"
- Add supported FW version auto detection mechanism (Parsing fw version once and
use it to validate BA support)
drivers/net/wireless/wl12xx/acx.c | 50 ++++++++++++++++++++++++++++++++++
drivers/net/wireless/wl12xx/acx.h | 41 ++++++++++++++++++++++++++-
drivers/net/wireless/wl12xx/boot.c | 41 +++++++++++++++++++++++++--
drivers/net/wireless/wl12xx/conf.h | 7 +++++
drivers/net/wireless/wl12xx/init.c | 50 ++++++++++++++++++++++++++++++++++
drivers/net/wireless/wl12xx/main.c | 14 ++++++---
drivers/net/wireless/wl12xx/wl12xx.h | 15 +++++++++-
7 files changed, 207 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index cc4068d..54fd68d 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1309,6 +1309,56 @@ out:
return ret;
}
+/* Configure BA session initiator\receiver parameters setting in the FW. */
+int wl1271_acx_set_ba_session(struct wl1271 *wl,
+ enum ieee80211_back_parties direction,
+ u8 tid_index, u8 policy)
+{
+ struct wl1271_acx_ba_session_policy *acx;
+ int ret;
+
+ wl1271_debug(DEBUG_ACX, "acx ba session setting");
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* ANY role */
+ acx->role_id = 0xff;
+ acx->tid = tid_index;
+ acx->enable = policy;
+ acx->win_size = BA_WIN_SIZE;
+ acx->ba_direction = direction;
+
+ switch (direction) {
+ case WLAN_BACK_INITIATOR:
+ acx->inactivity_timeout = wl->conf.ht.inactivity_timeout;
+ break;
+ case WLAN_BACK_RECIPIENT:
+ acx->inactivity_timeout = 0;
+ break;
+ default:
+ wl1271_error("Incorrect acx command id=%x\n", direction);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = wl1271_cmd_configure(wl,
+ ACX_BA_SESSION_POLICY_CFG,
+ acx,
+ sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("acx ba session setting failed: %d", ret);
+ goto out;
+ }
+
+out:
+ kfree(acx);
+ return ret;
+}
+
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
{
struct wl1271_acx_fw_tsf_information *tsf_info;
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 9cbc3f4..df48468 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1051,6 +1051,40 @@ struct wl1271_acx_ht_information {
u8 padding[3];
} __packed;
+#define BA_WIN_SIZE 8
+
+struct wl1271_acx_ba_session_policy {
+ struct acx_header header;
+ /*
+ * Specifies role Id, Range 0-7, 0xFF means ANY role.
+ * Future use. For now this field is irrelevant
+ */
+ u8 role_id;
+ /*
+ * Specifies Link Id, Range 0-31, 0xFF means ANY Link Id.
+ * Not applicable if Role Id is set to ANY.
+ */
+ u8 link_id;
+
+ u8 tid;
+
+ u8 enable;
+
+ /* Windows size in number of packets */
+ u16 win_size;
+
+ /*
+ * As initiator inactivity timeout in time units(TU) of 1024us.
+ * As receiver reserved
+ */
+ u16 inactivity_timeout;
+
+ /* Initiator = 1/Receiver = 0 */
+ u8 ba_direction;
+
+ u8 padding[3];
+} __packed;
+
struct wl1271_acx_fw_tsf_information {
struct acx_header header;
@@ -1113,8 +1147,8 @@ enum {
ACX_RSSI_SNR_WEIGHTS = 0x0052,
ACX_KEEP_ALIVE_MODE = 0x0053,
ACX_SET_KEEP_ALIVE_CONFIG = 0x0054,
- ACX_BA_SESSION_RESPONDER_POLICY = 0x0055,
- ACX_BA_SESSION_INITIATOR_POLICY = 0x0056,
+ ACX_BA_SESSION_POLICY_CFG = 0x0055,
+ ACX_BA_SESSION_RX_SETUP = 0x0056,
ACX_PEER_HT_CAP = 0x0057,
ACX_HT_BSS_OPERATION = 0x0058,
ACX_COEX_ACTIVITY = 0x0059,
@@ -1185,6 +1219,9 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
bool allow_ht_operation);
int wl1271_acx_set_ht_information(struct wl1271 *wl,
u16 ht_operation_mode);
+int wl1271_acx_set_ba_session(struct wl1271 *wl,
+ enum ieee80211_back_parties direction,
+ u8 tid_index, u8 policy);
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index 4a9f929..cd42e12 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -101,6 +101,39 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
}
+static void wl1271_save_fw_ver(struct wl1271 *wl)
+{
+ char fw_ver_str[ETHTOOL_BUSINFO_LEN];
+ char *fw_ver_point;
+ int ret, i;
+
+ /* copy the fw version to temp str */
+ strncpy(fw_ver_str, wl->chip.fw_ver_str, sizeof(fw_ver_str));
+
+ for (i = (WL12XX_NUM_FW_VER - 1); i > 0; --i) {
+ /* find the last '.' */
+ fw_ver_point = strrchr(fw_ver_str, '.');
+
+ /* read version number */
+ ret = strict_strtoul(fw_ver_point+1, 10, &(wl->chip.fw_ver[i]));
+ if (ret < 0) {
+ wl1271_warning("fw version incorrect value");
+ memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
+ return;
+ }
+
+ /* clean '.' */
+ *fw_ver_point = '\0';
+ }
+
+ ret = strict_strtoul(fw_ver_point-1, 10, &(wl->chip.fw_ver[0]));
+ if (ret < 0) {
+ wl1271_warning("fw version incorrect value");
+ memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
+ return;
+ }
+}
+
static void wl1271_boot_fw_version(struct wl1271 *wl)
{
struct wl1271_static_data static_data;
@@ -108,11 +141,13 @@ static void wl1271_boot_fw_version(struct wl1271 *wl)
wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data),
false);
- strncpy(wl->chip.fw_ver, static_data.fw_version,
- sizeof(wl->chip.fw_ver));
+ strncpy(wl->chip.fw_ver_str, static_data.fw_version,
+ sizeof(wl->chip.fw_ver_str));
/* make sure the string is NULL-terminated */
- wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0';
+ wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
+
+ wl1271_save_fw_ver(wl);
}
static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index a16b361..41df771 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -1090,6 +1090,12 @@ struct conf_rf_settings {
u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
};
+#define CONF_BA_INACTIVITY_TIMEOUT 10000
+
+struct conf_ht_setting {
+ u16 inactivity_timeout;
+};
+
struct conf_drv_settings {
struct conf_sg_settings sg;
struct conf_rx_settings rx;
@@ -1100,6 +1106,7 @@ struct conf_drv_settings {
struct conf_roam_trigger_settings roam_trigger;
struct conf_scan_settings scan;
struct conf_rf_settings rf;
+ struct conf_ht_setting ht;
};
#endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index 785a530..5482b85 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -213,6 +213,51 @@ static int wl1271_init_beacon_broadcast(struct wl1271 *wl)
return 0;
}
+static void wl1271_check_ba_support(struct wl1271 *wl)
+{
+
+ /* validate FW cose ver x.x.x.50-60.x */
+ if ((wl->chip.fw_ver[3] >= WL12XX_BA_SUPPORT_FW_COST_VER2_START) &&
+ (wl->chip.fw_ver[3] < WL12XX_BA_SUPPORT_FW_COST_VER2_END)) {
+ wl->ba_support = true;
+ return;
+ }
+
+ /* validate FW sub ver x.x.x.>= 33.339 */
+ if ((wl->chip.fw_ver[4] == WL12XX_BA_SUPPORT_FW_SUB_VER) &&
+ (wl->chip.fw_ver[4] >= WL12XX_BA_SUPPORT_FW_COST_VER1)) {
+ wl->ba_support = true;
+ return;
+ }
+
+ wl->ba_support = false;
+}
+
+static int wl1271_set_ba_policies(struct wl1271 *wl)
+{
+ u8 tid_index;
+ u8 ret = 0;
+
+ /* Reset the BA RX indicators */
+ wl->ba_allowed = true;
+ wl->ba_rx_bitmap = 0;
+
+ /* validate that FW support BA */
+ wl1271_check_ba_support(wl);
+
+ if (wl->ba_support)
+ /* 802.11n initiator BA session setting */
+ for (tid_index = 0; tid_index < CONF_TX_MAX_TID_COUNT;
+ ++tid_index) {
+ ret = wl1271_acx_set_ba_session(wl, WLAN_BACK_INITIATOR,
+ tid_index, true);
+ if (ret < 0)
+ break;
+ }
+
+ return ret;
+}
+
int wl1271_hw_init(struct wl1271 *wl)
{
struct conf_tx_ac_category *conf_ac;
@@ -364,6 +409,11 @@ int wl1271_hw_init(struct wl1271 *wl)
if (ret < 0)
goto out_free_memmap;
+ /* Configure initiator BA sessions policies */
+ ret = wl1271_set_ba_policies(wl);
+ if (ret < 0)
+ goto out_free_memmap;
+
return 0;
out_free_memmap:
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 062247e..c44462d 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -233,7 +233,7 @@ static struct conf_drv_settings default_conf = {
.avg_weight_rssi_beacon = 20,
.avg_weight_rssi_data = 10,
.avg_weight_snr_beacon = 20,
- .avg_weight_snr_data = 10
+ .avg_weight_snr_data = 10,
},
.scan = {
.min_dwell_time_active = 7500,
@@ -252,6 +252,9 @@ static struct conf_drv_settings default_conf = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
},
+ .ht = {
+ .inactivity_timeout = CONF_BA_INACTIVITY_TIMEOUT,
+ },
};
static void __wl1271_op_remove_interface(struct wl1271 *wl);
@@ -827,7 +830,7 @@ int wl1271_plt_start(struct wl1271 *wl)
wl->state = WL1271_STATE_PLT;
wl1271_notice("firmware booted in PLT mode (%s)",
- wl->chip.fw_ver);
+ wl->chip.fw_ver_str);
goto out;
irq_disable:
@@ -1061,11 +1064,11 @@ power_off:
wl->vif = vif;
wl->state = WL1271_STATE_ON;
- wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
+ wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str);
/* update hw/fw version info in wiphy struct */
wiphy->hw_version = wl->chip.id;
- strncpy(wiphy->fw_version, wl->chip.fw_ver,
+ strncpy(wiphy->fw_version, wl->chip.fw_ver_str,
sizeof(wiphy->fw_version));
/*
@@ -2090,7 +2093,8 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
wl1271_warning("Set ht cap true failed %d", ret);
goto out_sleep;
}
- ret = wl1271_acx_set_ht_information(wl,
+
+ ret = wl1271_acx_set_ht_information(wl,
bss_conf->ht_operation_mode);
if (ret < 0) {
wl1271_warning("Set ht information failed %d", ret);
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 01711fe..7b34393 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -38,6 +38,11 @@
#define DRIVER_NAME "wl1271"
#define DRIVER_PREFIX DRIVER_NAME ": "
+#define WL12XX_BA_SUPPORT_FW_SUB_VER 339
+#define WL12XX_BA_SUPPORT_FW_COST_VER1 33
+#define WL12XX_BA_SUPPORT_FW_COST_VER2_START 50
+#define WL12XX_BA_SUPPORT_FW_COST_VER2_END 60
+
enum {
DEBUG_NONE = 0,
DEBUG_IRQ = BIT(0),
@@ -161,10 +166,13 @@ struct wl1271_partition_set {
struct wl1271;
+#define WL12XX_NUM_FW_VER 5
+
/* FIXME: I'm not sure about this structure name */
struct wl1271_chip {
u32 id;
- char fw_ver[21];
+ char fw_ver_str[ETHTOOL_BUSINFO_LEN];
+ unsigned long fw_ver[WL12XX_NUM_FW_VER];
};
struct wl1271_stats {
@@ -399,6 +407,11 @@ struct wl1271 {
/* Most recently reported noise in dBm */
s8 noise;
+
+ /* RX BA constraint value */
+ bool ba_support;
+ u8 ba_allowed;
+ u8 ba_rx_bitmap;
};
int wl1271_plt_start(struct wl1271 *wl);
--
1.7.0.4
^ permalink raw reply related
* Re: Tp-link wn7200nd - cannot associate
From: Rafał Miłecki @ 2011-01-03 10:48 UTC (permalink / raw)
To: Ming-Ching Tiew; +Cc: linux-wireless
In-Reply-To: <651997.51284.qm@web31502.mail.mud.yahoo.com>
2011/1/3 Ming-Ching Tiew <mctiew@yahoo.com>:
>
> I have a TP-LINK WN7200ND, I am tested it with Kernel 2.6.36.1 and 2.6.35.10, basically after inserting the USB, the interface is up and it can never associate with any access point.
>
> #lsmod |grep rt2
>
> rt2800usb 7632 0
> rt2800lib 20328 1 rt2800usb
> rt2x00usb 4628 2 rt2800usb,rt2800lib
> rt2x00lib 15408 2 rt2800lib,rt2x00usb
> mac80211 122068 2 rt2x00usb,rt2x00lib
> cfg80211 92252 2 rt2x00lib,mac80211
>
> There are a lot of similar complaints on the net, this is one example :-
>
> http://ubuntuforums.org/showthread.php?t=1530095
>
> There don't seem to be any issue with 'iwlist wlanX scan'. But just can't associate.
>
> Any recommendation ? Any debug information I should provide ?
Are your networks encrypted? How? What is output of wpa_supplicant? Did you try
nohwcrypt=1
?
--
Rafał
^ permalink raw reply
* Re: [PATCH v3 2/2] ath9k: Fix STA disconnect issue due to received MIC failed bcast frames
From: Senthil Balasubramanian @ 2011-01-03 10:18 UTC (permalink / raw)
To: Ben Greear
Cc: Senthilkumar Balasubramanian, linville@tuxdriver.com,
linux-wireless@vger.kernel.org, Stable
In-Reply-To: <4D1E10AD.4090703@candelatech.com>
On Fri, Dec 31, 2010 at 10:49:41PM +0530, Ben Greear wrote:
> On 12/06/2010 05:39 AM, Senthil Balasubramanian wrote:
> > AR_RxKeyIdxValid will not be set for bcast/mcast frames and so relying
> > this status for MIC failed frames is buggy.
> >
> > Due to this, MIC failure events for broadcast frames are not sent to
> > supplicant resulted in AP disconnecting the STA.
> >
> > Able to pass Wifi Test case 5.2.18 with this fix.
>
> Did this ever make it into wireless-testing? I just did
Yes.. 38852b20c8b6d97618204ac64abbf14f0080393e is the commit sha in the latest
-wl.
> a rebase, and I notice I'm still carrying this patch in my
> local tree?
>
> Thanks,
> Ben
>
> >
> > Cc: Stable<stable@kernel.org> (2.6.36+)
> > Signed-off-by: Senthil Balasubramanian<senthilkumar@atheros.com>
> > ---
> > v2 -- addressed invalid keyix overrun in tkip_keymap.
> > v3 -- fixed setting of rx decrypted flag in case of s/w crypto.
> >
> > drivers/net/wireless/ath/ath9k/mac.c | 3 +--
> > drivers/net/wireless/ath/ath9k/recv.c | 9 ++++++++-
> > 2 files changed, 9 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
> > index b04b37b..7978b27 100644
> > --- a/drivers/net/wireless/ath/ath9k/mac.c
> > +++ b/drivers/net/wireless/ath/ath9k/mac.c
> > @@ -702,8 +702,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
> > rs->rs_phyerr = phyerr;
> > } else if (ads.ds_rxstatus8& AR_DecryptCRCErr)
> > rs->rs_status |= ATH9K_RXERR_DECRYPT;
> > - else if ((ads.ds_rxstatus8& AR_MichaelErr)&&
> > - rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
> > + else if (ads.ds_rxstatus8& AR_MichaelErr)
> > rs->rs_status |= ATH9K_RXERR_MIC;
> > else if (ads.ds_rxstatus8& AR_KeyMiss)
> > rs->rs_status |= ATH9K_RXERR_DECRYPT;
> > diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
> > index 262c815..876aa8f 100644
> > --- a/drivers/net/wireless/ath/ath9k/recv.c
> > +++ b/drivers/net/wireless/ath/ath9k/recv.c
> > @@ -840,6 +840,10 @@ static bool ath9k_rx_accept(struct ath_common *common,
> > struct ath_rx_status *rx_stats,
> > bool *decrypt_error)
> > {
> > +#define is_mc_or_valid_tkip_keyix ((is_mc || \
> > + (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID&& \
> > + test_bit(rx_stats->rs_keyix, common->tkip_keymap))))
> > +
> > struct ath_hw *ah = common->ah;
> > __le16 fc;
> > u8 rx_status_len = ah->caps.rx_status_len;
> > @@ -881,15 +885,18 @@ static bool ath9k_rx_accept(struct ath_common *common,
> > if (rx_stats->rs_status& ATH9K_RXERR_DECRYPT) {
> > *decrypt_error = true;
> > } else if (rx_stats->rs_status& ATH9K_RXERR_MIC) {
> > + bool is_mc;
> > /*
> > * The MIC error bit is only valid if the frame
> > * is not a control frame or fragment, and it was
> > * decrypted using a valid TKIP key.
> > */
> > + is_mc = !!is_multicast_ether_addr(hdr->addr1);
> > +
> > if (!ieee80211_is_ctl(fc)&&
> > !ieee80211_has_morefrags(fc)&&
> > !(le16_to_cpu(hdr->seq_ctrl)& IEEE80211_SCTL_FRAG)&&
> > - test_bit(rx_stats->rs_keyix, common->tkip_keymap))
> > + is_mc_or_valid_tkip_keyix)
> > rxs->flag |= RX_FLAG_MMIC_ERROR;
> > else
> > rx_stats->rs_status&= ~ATH9K_RXERR_MIC;
>
>
> --
> Ben Greear <greearb@candelatech.com>
> Candela Technologies Inc http://www.candelatech.com
>
^ permalink raw reply
* Re: [patch] mac80211: potential null dereference in mesh forwarding
From: Eric Dumazet @ 2011-01-03 7:45 UTC (permalink / raw)
To: Dan Carpenter
Cc: John W. Linville, Johannes Berg, David S. Miller, linux-wireless,
netdev, kernel-janitors
In-Reply-To: <20110103054355.GP1886@bicker>
Le lundi 03 janvier 2011 à 08:43 +0300, Dan Carpenter a écrit :
> The printk() is supposed to be ratelimited but we should always goto out
> when fwd_skb is NULL. Otherwise it gets dereferenced on the next line.
>
> Signed-off-by: Dan Carpenter <error27@gmail.com>
>
> diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> index 5e9d3bc..dc8b566 100644
> --- a/net/mac80211/rx.c
> +++ b/net/mac80211/rx.c
> @@ -1831,8 +1831,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
>
> fwd_skb = skb_copy(skb, GFP_ATOMIC);
>
> - if (!fwd_skb && net_ratelimit()) {
> - printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
> + if (!fwd_skb) {
> + if (net_ratelimit())
> + printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
> sdata->name);
> goto out;
> }
Already discovered/coped by Milton Miller.
^ permalink raw reply
* Re: [PATCH] Revert "ath9k: Parse DTIM period from mac80211"
From: Mohammed Shafi @ 2011-01-03 7:29 UTC (permalink / raw)
To: Kalle Valo
Cc: Jouni Malinen, linux-wireless@vger.kernel.org, Luis Rodriguez,
linville@tuxdriver.com
In-Reply-To: <20110102085300.GA14217@jm.kir.nu>
On Sunday 02 January 2011 02:23 PM, Jouni Malinen wrote:
> On Sat, Jan 01, 2011 at 11:50:50AM +0200, Kalle Valo wrote:
>
>> Mohammed Shafi Shajakhan<mshajakhan@atheros.com> writes:
>>
>>> * Preventing association with broken AP's
>>>
>> How can different dtim value cause problems with association? Power
>> save should not be even enabled during association. Or do you mean
>> there are problems after association, for example during eap
>> negotation?
>>
> It is not the DTIM value, it is the part of having to receive a Beacon
> frame before even trying to associate. This is very much a corner case,
> but well, that behavior did change with the commit.
>
>
>>> * Adds latency in roaming
>>>
>> We should try to solve this problem differently than hardcoding dtim.
>> There are other ways to trigger roaming than just following beacons.
>> And if there's no data, there's no need to roam either.
>>
> This is about the part of waiting for Beacon frame before trying to
> associate, not about hardcoding DTIM for any other purpose.
>
>
>>> So its better to always use the safe value of '1' for dtim period
>>>
>> By hardcoding dtim you increase the power consumption in the case when
>> there is no data traffic, so it's not definitely better in all cases.
>> di
>> I would prefer to fix the real issues instead of hardcoding dtim. And
>> if it's really essential to hardcode it now, please add a big fat
>> warning indicating that this is a temporary solution and should be
>> fixed properly without hardcoding anything.
>>
I agree .In the ath9k we wake up for every beacons, and even
obtaining the DTIM period will not change it, unless we change the wake
up time to be based on DTIM period. I thought of changing it, but was
afraid that it might introduce some other critical problems.
> The real issue (as far as I can tell) was that ath9k was changed to
> require mac80211 to get it DTIM period before association. I'm not aware
> of any need for that with ath9k. It should have no problems updating PS
> parameters after association and as such, should not require mac80211 to
> figure DTIM period out before being able to associate. This change is
> not about hardcoding DTIM period; it is about removing unneeded change
> that added extra latency without any real gain.
>
>
As the power save does not seems to be configured based on this I
thought there wont be no issues in getting the actual DTIM period, but
never had a clue this might have introduced these problems.
^ permalink raw reply
* Fwd: mac80211+iwlwifi bug with HT rates?
From: Daniel Halperin @ 2011-01-03 7:15 UTC (permalink / raw)
To: ipw3945-devel, linux-wireless
In-Reply-To: <AANLkTi=w+EEdROx5NCBEe2fLv6RM-7fGSoNEpQ-tBZYo@mail.gmail.com>
linux-wireless spam filter rejected our school's google appliance
mail, trying again as plain text.
Sorry,
Dan
---------- Forwarded message ----------
From: Daniel Halperin <dhalperi@cs.washington.edu>
Date: Sun, Jan 2, 2011 at 11:13 PM
Subject: mac80211+iwlwifi bug with HT rates?
To: ipw3945-devel@lists.sourceforge.net, linux-wireless@vger.kernel.org
Cc: Swati Rallapalli <swati@cs.utexas.edu>
I'm trying to track down an anomaly with a 3-stream 802.11n AP.
iwlwifi is saying that a single antenna should be sufficient even when
the AP supports 3 streams. Here's what I've tracked down:
Code in iwl-agn-rxon.c uses the ht_cap TX MCS parameters to determine
how many streams the other side supports:
<http://git.kernel.org/?p=linux/kernel/git/iwlwifi/iwlwifi-2.6.git;a=blob;f=drivers/net/wireless/iwlwifi/iwl-agn-rxon.c;h=d33e4db7e56cab88abc3281d04adf32162b8020e;hb=HEAD#l470>
Yet, it looks like mac80211 doesn't actually set those variables at
all! In net/mac80211/ht.c, when converting the IE to the Station HT
cap:
<http://git.kernel.org/?p=linux/kernel/git/iwlwifi/iwlwifi-2.6.git;a=blob;f=net/mac80211/ht.c;h=75d679d75e63e92143d55a47601a1dfc1377ba03;hb=HEAD#l21>
we first zero out the HT CAP (line 30) and then never actually set the
ht_cap->mcs.tx_params variables at all. Grep says that's the only use
of mcs.tx_params in that directory, so I'm pretty confident mac80211
just never does that. Thus iwlwifi thinks it only needs to have 1 RX
antenna enabled (though it defaults to a minimum of 2 when possible)
and basically fails to receive 3 stream packets.
Is this a bug in iwlwifi or mac80211?
Thanks,
Dan
^ permalink raw reply
* [patch -next] ath5k: ath5k_eeprom_mode_from_channel() returns signed
From: Dan Carpenter @ 2011-01-03 5:46 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: Nick Kossifidis, Jiri Slaby, Bob Copeland, John W. Linville,
linux-wireless, ath5k-devel, kernel-janitors
ath5k_eeprom_mode_from_channel() returns -1 on error but we're storing
the result in "ee_mode" which is an unsigned char. This breaks the
error handling. This patch makes "ee_mode" an int.
Signed-off-by: Dan Carpenter <error27@gmail.com>
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 9306d5f..78c26fd 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1916,7 +1916,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
struct ieee80211_channel *channel = ah->ah_current_channel;
bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
bool use_def_for_sg;
- u8 def_ant, tx_ant, ee_mode;
+ int ee_mode;
+ u8 def_ant, tx_ant;
u32 sta_id1 = 0;
/* if channel is not initialized yet we can't set the antennas
@@ -3081,7 +3082,8 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
{
struct ath5k_rate_pcal_info rate_info;
struct ieee80211_channel *curr_channel = ah->ah_current_channel;
- u8 type, ee_mode;
+ int ee_mode;
+ u8 type;
int ret;
if (txpower > AR5K_TUNE_MAX_TXPOWER) {
^ permalink raw reply related
* [patch] mac80211: potential null dereference in mesh forwarding
From: Dan Carpenter @ 2011-01-03 5:43 UTC (permalink / raw)
To: John W. Linville
Cc: Johannes Berg, David S. Miller, linux-wireless, netdev,
kernel-janitors
The printk() is supposed to be ratelimited but we should always goto out
when fwd_skb is NULL. Otherwise it gets dereferenced on the next line.
Signed-off-by: Dan Carpenter <error27@gmail.com>
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5e9d3bc..dc8b566 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1831,8 +1831,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
fwd_skb = skb_copy(skb, GFP_ATOMIC);
- if (!fwd_skb && net_ratelimit()) {
- printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
+ if (!fwd_skb) {
+ if (net_ratelimit())
+ printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
sdata->name);
goto out;
}
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox