* RE: cfg80211 rfkill interface
From: Arend Van Spriel @ 2011-01-14 14:54 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1294688709.3583.25.camel@jlt3.sipsolutions.net>
Hi Johannes,
Thanks for you thoughts on this. Especially the last remark was reason for me to verify several usage scenarios. I ran into a issue with unloading the driver module while it was in blocked rfkill state and polling was active. Turns out the call to ieee80211_unregister_hw takes a loooong time before it returns and dmesg shows message from unregister_netdevice which seems related about refcount not being zero. This is only observed in this scenario. Any suggestion on how to handle this?
Gr. AvS
|-----Original Message-----
|From: Johannes Berg [mailto:johannes@sipsolutions.net]
|Sent: Monday, January 10, 2011 8:45 PM
|To: Arend Van Spriel
|Cc: linux-wireless@vger.kernel.org
|Subject: Re: cfg80211 rfkill interface
|
|Hi Arend,
|
|> I am looking into implementing rfkill into our brcm80211 open-source
|> driver. Our driver detects disable switch by an interrupt, but
|> switching back does not give an interrupt.
|
|Interesting, but I guess it makes some sense.
|
|> For the latter I wanted to use the rfkill_poll callback and
|> wiphy_rfkill_start_polling.
|
|Right, makes sense.
|
|> However, I tried a wiphy_rfkill_stop_polling in the rfkill_poll
|> callback when rf is unblocked, and this resulted in a system hang.
|
|Yeah, I'm not surprised. start_polling will work from anywhere, but
|stop_polling needs to actually completely sync the poll stop so it can't
|be done from within the poll or from within any rfkill callbacks.
|
|> So I moved the wiphy_rfkill_stop_polling to the start callback. Does
|> that make sense or is there another way you would recommend?
|
|I think that makes sense.
|
|However, where do you start polling? You have to poll even if the device
|is not start()ed, I guess?
|
|johannes
|
^ permalink raw reply
* Re: No beacons generated when you bring ath9k AP interface down and up.
From: Brian Prodoehl @ 2011-01-14 14:17 UTC (permalink / raw)
To: Ben Greear; +Cc: Jouni Malinen, linux-wireless@vger.kernel.org
In-Reply-To: <4D304E32.4040806@candelatech.com>
On Fri, Jan 14, 2011 at 8:22 AM, Ben Greear <greearb@candelatech.com> wrote:
> On 01/14/2011 01:12 AM, Jouni Malinen wrote:
>>
>> On Thu, Jan 13, 2011 at 11:13:40PM -0800, Ben Greear wrote:
>>>
>>> If you have an ath9k AP interface running with hostapd, and you
>>> run: ip link set vap0 down; ip link set vap0 up;
>>> then it will disable beaconing.
>>
>> Yes. So what?
>>
>>> I'm not sure where the problem actually lies: Should ath9k
>>> start beaconing automatically on VAP interface add? Is
>>> it up to hostapd to detect the ifdown/ifup and re-set everything
>>> up properly? Or maybe it's just a very bad idea to bounce
>>> a VAP interface with 'ip link set'?
>>
>> I would say it is up to whoever decided to set the interface down to
>> restart hostapd.. There is a proposed patch for hostapd to do this
>> automatically, but I'm yet to fully understand why one would set the
>> interface down in the first place.
>
> My tool automatically downs and ups interfaces when IPs configuration
> changes to clear IP & routing information. It's not so difficult to
> restart hostapd or even not bounce the VAP to begin with.
>
> But, it was quite difficult to figure out
> that the VAP was just *mostly* working. It seems that everything but
> beaconing was working, or at least 70 or so virtual station devices
> could associate and pass traffic, though they did complain about
> not receiving beacons.
>
> I think that we should either change hostapd to fix this up automatically,
> or have hostapd exit on error when this happens, or have some other very
> obvious clue that the VAP is not fully functional.
>
> Thanks,
> Ben
OpenWrt brings the AP interface down after launching hostapd to set
the MAC address every time during network restart, and beaconing
becomes disabled then, too. I created this ticket 6 weeks ago:
https://dev.openwrt.org/ticket/8362
My conclusion was that bringing the interface down with hostapd up is
a terrible thing to do. Some sort of fix beyond "don't do that" would
be really nice, though. It would be great if hostapd would detect
that the interface went down, and reinitialize when the interface
comes back up.
^ permalink raw reply
* Re: No beacons generated when you bring ath9k AP interface down and up.
From: Jorge Boncompte [DTI2] @ 2011-01-14 13:49 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org
In-Reply-To: <20110114091226.GA32344@jm.kir.nu>
El 14/01/2011 10:12, Jouni Malinen escribió:
> On Thu, Jan 13, 2011 at 11:13:40PM -0800, Ben Greear wrote:
>> If you have an ath9k AP interface running with hostapd, and you
>> run: ip link set vap0 down; ip link set vap0 up;
>> then it will disable beaconing.
>
> Yes. So what?
>
>> I'm not sure where the problem actually lies: Should ath9k
>> start beaconing automatically on VAP interface add? Is
>> it up to hostapd to detect the ifdown/ifup and re-set everything
>> up properly? Or maybe it's just a very bad idea to bounce
>> a VAP interface with 'ip link set'?
>
> I would say it is up to whoever decided to set the interface down to
> restart hostapd.. There is a proposed patch for hostapd to do this
> automatically, but I'm yet to fully understand why one would set the
> interface down in the first place.
I usually do it to influence routing from within quagga. Quagga have no
provisions to restart another daemons on interface state change. This is just an
example, I'm sure there are others valid use cases, so I really think that
hostapd should restart beaconing/whatever in this case.
Regards,
Jorge
--
==============================================================
Jorge Boncompte - Ingenieria y Gestion de RED
DTI2 - Desarrollo de la Tecnologia de las Comunicaciones
--------------------------------------------------------------
C/ Abogado Enriquez Barrios, 5 14004 CORDOBA (SPAIN)
Tlf: +34 957 761395 / FAX: +34 957 450380
==============================================================
- There is only so much duct tape you can put on something
before it just becomes a giant ball of duct tape.
==============================================================
^ permalink raw reply
* Re: No beacons generated when you bring ath9k AP interface down and up.
From: Ben Greear @ 2011-01-14 13:22 UTC (permalink / raw)
To: Jouni Malinen; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <20110114091226.GA32344@jm.kir.nu>
On 01/14/2011 01:12 AM, Jouni Malinen wrote:
> On Thu, Jan 13, 2011 at 11:13:40PM -0800, Ben Greear wrote:
>> If you have an ath9k AP interface running with hostapd, and you
>> run: ip link set vap0 down; ip link set vap0 up;
>> then it will disable beaconing.
>
> Yes. So what?
>
>> I'm not sure where the problem actually lies: Should ath9k
>> start beaconing automatically on VAP interface add? Is
>> it up to hostapd to detect the ifdown/ifup and re-set everything
>> up properly? Or maybe it's just a very bad idea to bounce
>> a VAP interface with 'ip link set'?
>
> I would say it is up to whoever decided to set the interface down to
> restart hostapd.. There is a proposed patch for hostapd to do this
> automatically, but I'm yet to fully understand why one would set the
> interface down in the first place.
My tool automatically downs and ups interfaces when IPs configuration
changes to clear IP & routing information. It's not so difficult to
restart hostapd or even not bounce the VAP to begin with.
But, it was quite difficult to figure out
that the VAP was just *mostly* working. It seems that everything but
beaconing was working, or at least 70 or so virtual station devices
could associate and pass traffic, though they did complain about
not receiving beacons.
I think that we should either change hostapd to fix this up automatically,
or have hostapd exit on error when this happens, or have some other very
obvious clue that the VAP is not fully functional.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH] wl12xx: Cleanup PLT mode when module is removed
From: Luciano Coelho @ 2011-01-14 13:16 UTC (permalink / raw)
To: juuso.oikarinen@nokia.com; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1295005726-10323-1-git-send-email-juuso.oikarinen@nokia.com>
Hi Juuso,
On Fri, 2011-01-14 at 12:48 +0100, juuso.oikarinen@nokia.com wrote:
> diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
> index 9076555..863e660 100644
> --- a/drivers/net/wireless/wl12xx/main.c
> +++ b/drivers/net/wireless/wl12xx/main.c
> @@ -917,12 +917,10 @@ out:
> return ret;
> }
>
> -int wl1271_plt_stop(struct wl1271 *wl)
> +int __wl1271_plt_stop(struct wl1271 *wl)
> {
> int ret = 0;
>
> - mutex_lock(&wl->mutex);
> -
> wl1271_notice("power down");
>
> if (wl->state != WL1271_STATE_PLT) {
> @@ -938,12 +936,21 @@ int wl1271_plt_stop(struct wl1271 *wl)
> wl->state = WL1271_STATE_OFF;
> wl->rx_counter = 0;
>
> -out:
> mutex_unlock(&wl->mutex);
> -
> cancel_work_sync(&wl->irq_work);
> cancel_work_sync(&wl->recovery_work);
> + mutex_lock(&wl->mutex);
> +out:
> + return ret;
> +}
Again we have this kind of unlock-lock case. Wouldn't it be better to
move the cancel_work calls outside this function and call them after
__wl1271_plt_stop() has returned? Yeah, there will be duplicate code if
we do this, but I think it's a bit safer, isn't it?
--
Cheers,
Luca.
^ permalink raw reply
* [PATCH] wl12xx: Cleanup PLT mode when module is removed
From: juuso.oikarinen @ 2011-01-14 11:48 UTC (permalink / raw)
To: coelho; +Cc: linux-wireless
From: Juuso Oikarinen <juuso.oikarinen@nokia.com>
PLT mode start/stop is controlled from userspace. When removing module, the
PLT mode state is however not checked, and not cleared. There is the possibility
of some unwanted state to left linger and there is even the possiblity of a
kernel crash if for instance IRQ work is running when the module is removed.
Fix this by stopping PLT mode on module removal, if still running.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
---
drivers/net/wireless/wl12xx/main.c | 20 +++++++++++++++-----
1 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 9076555..863e660 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -917,12 +917,10 @@ out:
return ret;
}
-int wl1271_plt_stop(struct wl1271 *wl)
+int __wl1271_plt_stop(struct wl1271 *wl)
{
int ret = 0;
- mutex_lock(&wl->mutex);
-
wl1271_notice("power down");
if (wl->state != WL1271_STATE_PLT) {
@@ -938,12 +936,21 @@ int wl1271_plt_stop(struct wl1271 *wl)
wl->state = WL1271_STATE_OFF;
wl->rx_counter = 0;
-out:
mutex_unlock(&wl->mutex);
-
cancel_work_sync(&wl->irq_work);
cancel_work_sync(&wl->recovery_work);
+ mutex_lock(&wl->mutex);
+out:
+ return ret;
+}
+
+int wl1271_plt_stop(struct wl1271 *wl)
+{
+ int ret;
+ mutex_lock(&wl->mutex);
+ ret = __wl1271_plt_stop(wl);
+ mutex_unlock(&wl->mutex);
return ret;
}
@@ -3109,6 +3116,9 @@ EXPORT_SYMBOL_GPL(wl1271_register_hw);
void wl1271_unregister_hw(struct wl1271 *wl)
{
+ if (wl->state == WL1271_STATE_PLT)
+ __wl1271_plt_stop(wl);
+
unregister_netdevice_notifier(&wl1271_dev_notifier);
ieee80211_unregister_hw(wl->hw);
wl->mac80211_registered = false;
--
1.7.1
^ permalink raw reply related
* Re: No beacons generated when you bring ath9k AP interface down and up.
From: Jouni Malinen @ 2011-01-14 9:12 UTC (permalink / raw)
To: Ben Greear; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <4D2FF7A4.3070106@candelatech.com>
On Thu, Jan 13, 2011 at 11:13:40PM -0800, Ben Greear wrote:
> If you have an ath9k AP interface running with hostapd, and you
> run: ip link set vap0 down; ip link set vap0 up;
> then it will disable beaconing.
Yes. So what?
> I'm not sure where the problem actually lies: Should ath9k
> start beaconing automatically on VAP interface add? Is
> it up to hostapd to detect the ifdown/ifup and re-set everything
> up properly? Or maybe it's just a very bad idea to bounce
> a VAP interface with 'ip link set'?
I would say it is up to whoever decided to set the interface down to
restart hostapd.. There is a proposed patch for hostapd to do this
automatically, but I'm yet to fully understand why one would set the
interface down in the first place.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* Re: No beacons generated when you bring ath9k AP interface down and up.
From: Johannes Berg @ 2011-01-14 8:26 UTC (permalink / raw)
To: Ben Greear; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <4D2FF7A4.3070106@candelatech.com>
On Thu, 2011-01-13 at 23:13 -0800, Ben Greear wrote:
> Been a long day, but I think I finally see the problem.
>
> If you have an ath9k AP interface running with hostapd, and you
> run: ip link set vap0 down; ip link set vap0 up;
> then it will disable beaconing.
>
> One reason is that the ieee80211_do_open calls the
> ieee80211_bss_info_change_notify before it sets the RUNNING
> flag, so it would disable beaconing. A second is that
> it doesn't set the BEACON_CHANGED flag anyway, so even if you
> hack things to set RUNNING first, it still doesn't work right.
>
> I'm not sure where the problem actually lies: Should ath9k
> start beaconing automatically on VAP interface add? Is
> it up to hostapd to detect the ifdown/ifup and re-set everything
> up properly? Or maybe it's just a very bad idea to bounce
> a VAP interface with 'ip link set'?
Why would that be a good idea? I mean ... why would you want to do
that?!
johannes
^ permalink raw reply
* No beacons generated when you bring ath9k AP interface down and up.
From: Ben Greear @ 2011-01-14 7:13 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org
Been a long day, but I think I finally see the problem.
If you have an ath9k AP interface running with hostapd, and you
run: ip link set vap0 down; ip link set vap0 up;
then it will disable beaconing.
One reason is that the ieee80211_do_open calls the
ieee80211_bss_info_change_notify before it sets the RUNNING
flag, so it would disable beaconing. A second is that
it doesn't set the BEACON_CHANGED flag anyway, so even if you
hack things to set RUNNING first, it still doesn't work right.
I'm not sure where the problem actually lies: Should ath9k
start beaconing automatically on VAP interface add? Is
it up to hostapd to detect the ifdown/ifup and re-set everything
up properly? Or maybe it's just a very bad idea to bounce
a VAP interface with 'ip link set'?
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* ath9k - cannot reconnect few meters from the antenna
From: Tomasz @ 2011-01-13 22:46 UTC (permalink / raw)
To: linux-wireless
Hi All
I've spend a lot of time on this issue and I cannot fix it, thus I am asking for
help
It looks like that:
I am running wireless access point based on:
Ubuntu 10.04 vmlinuz-2.6.32-27-generic
compat-wireless-2010-12-26
hostapd 0.7.3 (wpa/wpa2)
Dnsmasq version 2.52
Zotac Ion board
Minipcie card: ieee80211 phy0: Atheros AR9285 Rev:2
ath9k driver
Single antenna (but the behaviour with two antenna is similar)
Everything works perfectly fine when I am within the few meters from the antenna.
So the clients are connecting and I get 25 mbps data rates.
But if more then 10 meters from the antenna strange things are happening.
- If I am connected to the network and will walk away everything works perfect.
- But if i disconnect (disassociate) when I am away I cannot connect back. -
this also means I cannot connect when turning the notebook on :)
- if I go closer to antenna I am able to connect and while walking away the
connection seems perfectly stable ...
My first idea is the congestion control issue ... But maybe some will have the
better idea.
Regards
Tomasz
--
Tomek
^ permalink raw reply
* [PATCH v3] mwifiex: remove linked list implementation
From: Bing Zhao @ 2011-01-14 3:46 UTC (permalink / raw)
To: linux-wireless
Cc: John W. Linville, Johannes Berg, Amitkumar Karwar, Kiran Divekar,
Frank Huang, Bing Zhao
From: Amitkumar Karwar <akarwar@marvell.com>
Use linked list functions available in include/linux/list.h
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
v3: remove type casting
drivers/net/wireless/mwifiex/11n.c | 134 +++-----
drivers/net/wireless/mwifiex/11n.h | 19 +-
drivers/net/wireless/mwifiex/11n_aggr.c | 124 +++++---
drivers/net/wireless/mwifiex/11n_rxreorder.c | 53 ++--
drivers/net/wireless/mwifiex/cmdevt.c | 228 +++++++------
drivers/net/wireless/mwifiex/decl.h | 3 +-
drivers/net/wireless/mwifiex/init.c | 113 ++++---
drivers/net/wireless/mwifiex/main.c | 32 ++-
drivers/net/wireless/mwifiex/main.h | 56 ++--
drivers/net/wireless/mwifiex/scan.c | 34 ++-
drivers/net/wireless/mwifiex/sta_cmdresp.c | 18 +-
drivers/net/wireless/mwifiex/sta_tx.c | 2 +-
drivers/net/wireless/mwifiex/util.c | 141 --------
drivers/net/wireless/mwifiex/util.h | 46 ---
drivers/net/wireless/mwifiex/wmm.c | 450 ++++++++++++++------------
drivers/net/wireless/mwifiex/wmm.h | 37 ++-
16 files changed, 696 insertions(+), 794 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index b1fd5a9..2922528 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -1073,23 +1073,11 @@ mwifiex_is_tx_ba_stream_ptr_valid(struct mwifiex_private *priv,
ENTER();
- tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- false);
- if (!tx_ba_tsr_tbl) {
- LEAVE();
- return false;
- }
-
- while (tx_ba_tsr_tbl !=
- (struct mwifiex_tx_ba_stream_tbl *)
- &priv->tx_ba_stream_tbl_ptr) {
+ list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
if (tx_ba_tsr_tbl == tx_tbl_ptr) {
LEAVE();
return true;
}
-
- tx_ba_tsr_tbl = tx_ba_tsr_tbl->next;
}
LEAVE();
@@ -1106,26 +1094,19 @@ void
mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl)
{
- unsigned long flags;
-
ENTER();
- spin_lock_irqsave(&priv->tx_ba_stream_tbl_ptr.lock, flags);
-
if (!tx_ba_tsr_tbl &&
mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl))
goto exit;
-
PRINTM(MINFO, "tx_ba_stream_tbl_ptr %p\n", tx_ba_tsr_tbl);
- mwifiex_util_unlink_list(&priv->tx_ba_stream_tbl_ptr,
- (struct mwifiex_linked_list *) tx_ba_tsr_tbl, false);
+ list_del(&tx_ba_tsr_tbl->list);
kfree(tx_ba_tsr_tbl);
exit:
- spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_ptr.lock, flags);
LEAVE();
}
@@ -1137,16 +1118,18 @@ void
mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv)
{
int i;
- struct mwifiex_tx_ba_stream_tbl *del_tbl_ptr;
+ struct mwifiex_tx_ba_stream_tbl *del_tbl_ptr, *tmp_node;
+ unsigned long flags;
ENTER();
- while ((del_tbl_ptr = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr, true)))
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_for_each_entry_safe(del_tbl_ptr, tmp_node,
+ &priv->tx_ba_stream_tbl_ptr, list)
mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, del_tbl_ptr);
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
- mwifiex_util_init_list((struct mwifiex_linked_list *) &priv->
- tx_ba_stream_tbl_ptr);
+ INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
for (i = 0; i < MAX_NUM_TID; ++i) {
priv->aggr_prio_tbl[i].ampdu_ap =
@@ -1165,27 +1148,20 @@ mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv,
enum mwifiex_ba_status ba_status)
{
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+ unsigned long flags;
ENTER();
- tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- true);
- if (!tx_ba_tsr_tbl) {
- LEAVE();
- return NULL;
- }
-
- while (tx_ba_tsr_tbl !=
- (struct mwifiex_tx_ba_stream_tbl *)
- &priv->tx_ba_stream_tbl_ptr) {
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
if (tx_ba_tsr_tbl->ba_status == ba_status) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
+ flags);
LEAVE();
return tx_ba_tsr_tbl;
}
-
- tx_ba_tsr_tbl = tx_ba_tsr_tbl->next;
}
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
return NULL;
@@ -1200,34 +1176,25 @@ mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
int tid, u8 *ra)
{
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+ unsigned long flags;
ENTER();
- tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- true);
- if (!tx_ba_tsr_tbl) {
- LEAVE();
- return NULL;
- }
-
- while (tx_ba_tsr_tbl !=
- (struct mwifiex_tx_ba_stream_tbl *)
- &priv->tx_ba_stream_tbl_ptr) {
-
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
PRINTM(MDAT_D, "get_tx_ba_stream_tbl TID %d\n",
tx_ba_tsr_tbl->tid);
DBG_HEXDUMP(MDAT_D, "RA", tx_ba_tsr_tbl->ra,
MWIFIEX_MAC_ADDR_LENGTH);
-
if ((!memcmp(tx_ba_tsr_tbl->ra, ra, MWIFIEX_MAC_ADDR_LENGTH))
&& (tx_ba_tsr_tbl->tid == tid)) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
+ flags);
LEAVE();
return tx_ba_tsr_tbl;
}
-
- tx_ba_tsr_tbl = tx_ba_tsr_tbl->next;
}
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
return NULL;
@@ -1243,6 +1210,7 @@ mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv,
enum mwifiex_ba_status ba_status)
{
struct mwifiex_tx_ba_stream_tbl *new_node;
+ unsigned long flags;
ENTER();
@@ -1258,15 +1226,15 @@ mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv,
goto exit;
}
- mwifiex_util_init_list((struct mwifiex_linked_list *) new_node);
+ INIT_LIST_HEAD(&new_node->list);
new_node->tid = tid;
new_node->ba_status = ba_status;
memcpy(new_node->ra, ra, MWIFIEX_MAC_ADDR_LENGTH);
- mwifiex_util_enqueue_list_tail(&priv->tx_ba_stream_tbl_ptr,
- (struct mwifiex_linked_list *)
- new_node, true);
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr);
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
}
exit:
@@ -1376,23 +1344,19 @@ mwifiex_11n_update_addba_request(struct mwifiex_private *priv)
{
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+ unsigned long flags;
ENTER();
- tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- true);
- if (!tx_ba_tsr_tbl) {
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ if (list_empty(&priv->tx_ba_stream_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
return;
}
-
- while (tx_ba_tsr_tbl !=
- (struct mwifiex_tx_ba_stream_tbl *)
- &priv->tx_ba_stream_tbl_ptr) {
+ list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list)
mwifiex_send_addba(priv, tx_ba_tsr_tbl->tid, tx_ba_tsr_tbl->ra);
- tx_ba_tsr_tbl = tx_ba_tsr_tbl->next;
- }
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
mwifiex_main_process(priv->adapter);
LEAVE();
@@ -1410,16 +1374,13 @@ mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
struct mwifiex_ds_rx_reorder_tbl *rx_reo_tbl = buf;
struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr;
int count = 0;
+ unsigned long flags;
+
ENTER();
- rx_reorder_tbl_ptr = (struct mwifiex_rx_reorder_tbl *)
- mwifiex_util_peek_list(&priv->rx_reorder_tbl_ptr,
- true);
- if (!rx_reorder_tbl_ptr) {
- LEAVE();
- return count;
- }
- while (rx_reorder_tbl_ptr !=
- (struct mwifiex_rx_reorder_tbl *) &priv->rx_reorder_tbl_ptr) {
+
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_for_each_entry(rx_reorder_tbl_ptr, &priv->rx_reorder_tbl_ptr,
+ list) {
rx_reo_tbl->tid = (u16) rx_reorder_tbl_ptr->tid;
memcpy(rx_reo_tbl->ta, rx_reorder_tbl_ptr->ta,
MWIFIEX_MAC_ADDR_LENGTH);
@@ -1431,13 +1392,14 @@ mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
else
rx_reo_tbl->buffer[i] = false;
}
- rx_reorder_tbl_ptr = rx_reorder_tbl_ptr->next;
rx_reo_tbl++;
count++;
if (count >= MWIFIEX_MAX_RX_BASTREAM_SUPPORTED)
break;
}
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
LEAVE();
return count;
}
@@ -1452,30 +1414,22 @@ mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
struct mwifiex_ds_tx_ba_stream_tbl *rx_reo_tbl = buf;
int count = 0;
+ unsigned long flags;
ENTER();
- tx_ba_tsr_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- true);
- if (!tx_ba_tsr_tbl) {
- LEAVE();
- return count;
- }
-
- while (tx_ba_tsr_tbl !=
- (struct mwifiex_tx_ba_stream_tbl *)
- &priv->tx_ba_stream_tbl_ptr) {
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid;
PRINTM(MDATA, "tid=%d\n", rx_reo_tbl->tid);
memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra,
MWIFIEX_MAC_ADDR_LENGTH);
- tx_ba_tsr_tbl = tx_ba_tsr_tbl->next;
rx_reo_tbl++;
count++;
if (count >= MWIFIEX_MAX_TX_BASTREAM_SUPPORTED)
break;
}
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
return count;
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 65f9ae8..21460c8 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -129,7 +129,7 @@ mwifiex_is_ba_stream_avail(struct mwifiex_private *priv)
if (pmpriv)
ba_stream_num +=
mwifiex_wmm_list_len(priv->adapter,
- (struct mwifiex_list_head
+ (struct list_head
*) &pmpriv->
tx_ba_stream_tbl_ptr);
}
@@ -151,31 +151,22 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv,
int tid;
u8 ret = false;
struct mwifiex_tx_ba_stream_tbl *tx_tbl;
+ unsigned long flags;
ENTER();
- tx_tbl = (struct mwifiex_tx_ba_stream_tbl *)
- mwifiex_util_peek_list(&priv->tx_ba_stream_tbl_ptr,
- true);
- if (!tx_tbl) {
- LEAVE();
- return ret;
- }
-
tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user;
- while (tx_tbl !=
- (struct mwifiex_tx_ba_stream_tbl *)
- &priv->tx_ba_stream_tbl_ptr) {
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+ list_for_each_entry(tx_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
if (tid > priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user) {
tid = priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user;
*ptid = tx_tbl->tid;
memcpy(ra, tx_tbl->ra, MWIFIEX_MAC_ADDR_LENGTH);
ret = true;
}
-
- tx_tbl = tx_tbl->next;
}
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
LEAVE();
return ret;
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index ca24d54..56f4531 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -306,7 +306,7 @@ done:
int
mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
struct mwifiex_ra_list_tbl *pra_list, int headroom,
- int ptrindex, unsigned long flags)
+ int ptrindex, unsigned long ra_list_flags)
__releases(&priv->wmm.ra_list_spinlock)
{
int pkt_size = 0;
@@ -318,53 +318,68 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
struct timeval tstamp;
struct mwifiex_tx_param tx_param;
struct txpd *ptx_pd = NULL;
+ unsigned long ra_list_tbl_flags;
ENTER();
PRINTM(MDAT_D, "Handling Aggr packet\n");
- mbuf_src = (struct mwifiex_buffer *)
- mwifiex_util_peek_list(&pra_list->buf_head,
- true);
- if (mbuf_src) {
- mbuf_aggr = mwifiex_alloc_buffer(adapter->tx_buf_size);
- if (!mbuf_aggr) {
- PRINTM(MERROR,
- "Error allocating struct mwifiex_buffer\n");
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
- return MWIFIEX_STATUS_FAILURE;
- }
+ spin_lock_irqsave(&pra_list->ra_list_tbl_lock, ra_list_tbl_flags);
+ if (list_empty(&pra_list->buf_head)) {
+ spin_unlock_irqrestore(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ goto exit;
+ }
+ mbuf_src = list_first_entry(&pra_list->buf_head,
+ struct mwifiex_buffer, list);
+ spin_unlock_irqrestore(&pra_list->ra_list_tbl_lock, ra_list_tbl_flags);
+
+ mbuf_aggr = mwifiex_alloc_buffer(adapter->tx_buf_size);
+ if (!mbuf_aggr) {
+ PRINTM(MERROR,
+ "Error allocating struct mwifiex_buffer\n");
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ return MWIFIEX_STATUS_FAILURE;
+ }
- data = mbuf_aggr->buffer + headroom;
+ data = mbuf_aggr->buffer + headroom;
- mbuf_aggr->bss_index = mbuf_src->bss_index;
- mbuf_aggr->buf_type = mbuf_src->buf_type;
- mbuf_aggr->priority = mbuf_src->priority;
+ mbuf_aggr->bss_index = mbuf_src->bss_index;
+ mbuf_aggr->buf_type = mbuf_src->buf_type;
+ mbuf_aggr->priority = mbuf_src->priority;
- mbuf_aggr->buffer = data;
- mbuf_aggr->data_offset = 0;
+ mbuf_aggr->buffer = data;
+ mbuf_aggr->data_offset = 0;
- /* Form AMSDU */
- mwifiex_11n_form_amsdu_txpd(priv, mbuf_aggr);
- pkt_size = sizeof(struct txpd);
- if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
- ptx_pd = (struct txpd *)mbuf_aggr->buffer;
- } else {
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
- goto exit;
- }
+ /* Form AMSDU */
+ mwifiex_11n_form_amsdu_txpd(priv, mbuf_aggr);
+ pkt_size = sizeof(struct txpd);
+ if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
+ ptx_pd = (struct txpd *)mbuf_aggr->buffer;
while (mbuf_src && ((pkt_size + (mbuf_src->data_len + LLC_SNAP_LEN)
+ headroom)
<= adapter->tx_buf_size)) {
- mbuf_src = (struct mwifiex_buffer *)
- mwifiex_util_dequeue_list(&pra_list->buf_head, true);
+ spin_lock_irqsave(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ if (!list_empty(&pra_list->buf_head)) {
+ mbuf_src = list_first_entry(&pra_list->buf_head,
+ struct mwifiex_buffer, list);
+ list_del(&mbuf_src->list);
+ } else {
+ mbuf_src = NULL;
+ }
+ spin_unlock_irqrestore(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
pra_list->total_pkts_size -= mbuf_src->data_len;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
pkt_size += mwifiex_11n_form_amsdu_pkt(adapter,
(data + pkt_size),
mbuf_src->buffer +
@@ -377,21 +392,27 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
mwifiex_write_data_complete(adapter, mbuf_src,
MWIFIEX_STATUS_SUCCESS);
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
+ ra_list_flags);
LEAVE();
return MWIFIEX_STATUS_FAILURE;
}
- mbuf_src =
- (struct mwifiex_buffer *)
- mwifiex_util_peek_list(&pra_list->buf_head, true);
+ spin_lock_irqsave(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ if (!list_empty(&pra_list->buf_head))
+ mbuf_src = list_first_entry(&pra_list->buf_head,
+ struct mwifiex_buffer, list);
+ else
+ mbuf_src = NULL;
+ spin_unlock_irqrestore(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
}
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
/* Last AMSDU packet does not need padding */
pkt_size -= pad;
@@ -408,11 +429,10 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
mbuf_aggr, &tx_param);
switch (ret) {
case MWIFIEX_STATUS_RESOURCE:
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
-
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
+ ra_list_flags);
mwifiex_write_data_complete(adapter, mbuf_aggr,
MWIFIEX_STATUS_FAILURE);
LEAVE();
@@ -424,14 +444,18 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
priv->adapter->tx_lock_flag = false;
ptx_pd->flags = 0;
}
- mwifiex_util_enqueue_list_head(&pra_list->buf_head,
- (struct mwifiex_linked_list *)
- mbuf_aggr, true);
+
+ spin_lock_irqsave(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ list_add(&mbuf_aggr->list, &pra_list->buf_head);
+ spin_unlock_irqrestore(&pra_list->ra_list_tbl_lock,
+ ra_list_tbl_flags);
pra_list->total_pkts_size += mbuf_aggr->data_len;
mbuf_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
PRINTM(MDATA, "MWIFIEX_STATUS_RESOURCE is returned\n");
break;
case MWIFIEX_STATUS_FAILURE:
@@ -451,15 +475,19 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
break;
}
if (ret != MWIFIEX_STATUS_RESOURCE) {
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
if (mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
priv->wmm.packets_out[ptrindex]++;
priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list;
}
+ /* Now bss_prio_cur pointer points to next node */
adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
- adapter->bss_prio_tbl[priv->bss_priority]
- .bss_prio_cur->next;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ list_first_entry(
+ &adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_cur->list,
+ struct mwifiex_bss_prio_node, list);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
}
do_gettimeofday(&tstamp);
PRINTM(MDATA, "%lu.%lu : Data => kernel\n",
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index e783a2e..567c93d 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -158,6 +158,8 @@ mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
struct mwifiex_rx_reorder_tbl
*rx_reor_tbl_ptr)
{
+ unsigned long flags;
+
ENTER();
if (!rx_reor_tbl_ptr) {
@@ -173,9 +175,10 @@ mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
del_timer(&rx_reor_tbl_ptr->timer_context.timer);
PRINTM(MDAT_D, "Delete rx_reor_tbl_ptr: %p\n", rx_reor_tbl_ptr);
- mwifiex_util_unlink_list(&priv->rx_reorder_tbl_ptr,
- (struct mwifiex_linked_list *) rx_reor_tbl_ptr,
- true);
+
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_del(&rx_reor_tbl_ptr->list);
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
kfree(rx_reor_tbl_ptr->rx_reorder_ptr);
kfree(rx_reor_tbl_ptr);
@@ -191,27 +194,21 @@ static struct mwifiex_rx_reorder_tbl *
mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta)
{
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+ unsigned long flags;
ENTER();
- rx_reor_tbl_ptr = (struct mwifiex_rx_reorder_tbl *)
- mwifiex_util_peek_list(&priv->rx_reorder_tbl_ptr,
- true);
- if (!rx_reor_tbl_ptr) {
- LEAVE();
- return NULL;
- }
-
- while (rx_reor_tbl_ptr !=
- (struct mwifiex_rx_reorder_tbl *) &priv->rx_reorder_tbl_ptr) {
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) {
if ((!memcmp(rx_reor_tbl_ptr->ta, ta, MWIFIEX_MAC_ADDR_LENGTH))
&& (rx_reor_tbl_ptr->tid == tid)) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
+ flags);
LEAVE();
return rx_reor_tbl_ptr;
}
-
- rx_reor_tbl_ptr = rx_reor_tbl_ptr->next;
}
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
LEAVE();
return NULL;
@@ -276,6 +273,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
int i;
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node;
u16 last_seq = 0;
+ unsigned long flags;
ENTER();
@@ -301,7 +299,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
goto exit;
}
- mwifiex_util_init_list((struct mwifiex_linked_list *) new_node);
+ INIT_LIST_HEAD(&new_node->list);
new_node->tid = tid;
memcpy(new_node->ta, ta, MWIFIEX_MAC_ADDR_LENGTH);
new_node->start_win = seq_num;
@@ -342,9 +340,9 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
for (i = 0; i < win_size; ++i)
new_node->rx_reorder_ptr[i] = NULL;
- mwifiex_util_enqueue_list_tail(&priv->rx_reorder_tbl_ptr,
- (struct mwifiex_linked_list *)
- new_node, true);
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr);
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
}
exit:
@@ -610,6 +608,7 @@ mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid,
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
struct mwifiex_tx_ba_stream_tbl *ptx_tbl;
u8 cleanup_rx_reorder_tbl;
+ unsigned long flags;
ENTER();
@@ -641,7 +640,9 @@ mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid,
return;
}
+ spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, ptx_tbl);
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
}
LEAVE();
@@ -747,17 +748,21 @@ mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
void
mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
{
- struct mwifiex_rx_reorder_tbl *del_tbl_ptr;
+ struct mwifiex_rx_reorder_tbl *del_tbl_ptr, *tmp_node;
+ unsigned long flags;
ENTER();
- while ((del_tbl_ptr = (struct mwifiex_rx_reorder_tbl *)
- mwifiex_util_peek_list(&priv->rx_reorder_tbl_ptr, true))) {
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ list_for_each_entry_safe(del_tbl_ptr, tmp_node,
+ &priv->rx_reorder_tbl_ptr, list) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr);
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
}
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
- mwifiex_util_init_list((struct mwifiex_linked_list *) &priv->
- rx_reorder_tbl_ptr);
+ INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
memset(priv->rx_seq, 0, sizeof(priv->rx_seq));
LEAVE();
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index dee8550..60aeea4 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -70,6 +70,7 @@ static struct cmd_ctrl_node *
mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
{
struct cmd_ctrl_node *cmd_node;
+ unsigned long flags;
ENTER();
@@ -78,15 +79,17 @@ mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
return NULL;
}
- if (mwifiex_util_peek_list(&adapter->cmd_free_q, true)) {
- cmd_node =
- (struct cmd_ctrl_node *)
- mwifiex_util_dequeue_list(&adapter->cmd_free_q, true);
- } else {
+ spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
+ if (list_empty(&adapter->cmd_free_q)) {
PRINTM(MERROR,
"GET_CMD_NODE: struct cmd_ctrl_node is not available\n");
- cmd_node = NULL;
+ spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
+ return NULL;
}
+ cmd_node = list_first_entry(&adapter->cmd_free_q,
+ struct cmd_ctrl_node, list);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
LEAVE();
return cmd_node;
@@ -137,24 +140,22 @@ static struct cmd_ctrl_node *
mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter,
struct mwifiex_ioctl_req *ioctl_req)
{
- struct cmd_ctrl_node *cmd_node = NULL;
+ unsigned long flags;
+ struct cmd_ctrl_node *cmd_node;
ENTER();
- cmd_node = (struct cmd_ctrl_node *)
- mwifiex_util_peek_list(&adapter->cmd_pending_q,
- true);
- if (!cmd_node) {
- LEAVE();
- return NULL;
- }
- while (cmd_node != (struct cmd_ctrl_node *) &adapter->cmd_pending_q) {
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) {
if (cmd_node->ioctl_buf == ioctl_req) {
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ flags);
LEAVE();
return cmd_node;
}
- cmd_node = cmd_node->next;
}
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
LEAVE();
return NULL;
}
@@ -673,6 +674,8 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
struct cmd_ctrl_node *cmd_node)
{
struct mwifiex_ioctl_req *ioctl_req = NULL;
+ unsigned long flags;
+
ENTER();
if (cmd_node == NULL)
@@ -692,9 +695,10 @@ mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
mwifiex_clean_cmd_node(adapter, cmd_node);
/* Insert node into cmd_free_q */
- mwifiex_util_enqueue_list_tail(&adapter->cmd_free_q,
- (struct mwifiex_linked_list *) cmd_node,
- true);
+ spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
+ list_add_tail(&cmd_node->list, &adapter->cmd_free_q);
+ spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
+
done:
LEAVE();
}
@@ -712,6 +716,7 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
{
struct host_cmd_ds_command *host_cmd = NULL;
u16 command;
+ unsigned long flags;
ENTER();
@@ -740,15 +745,12 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
}
}
- if (add_tail) {
- mwifiex_util_enqueue_list_tail(&adapter->cmd_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
- } else {
- mwifiex_util_enqueue_list_head(&adapter->cmd_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
- }
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ if (add_tail)
+ list_add_tail(&cmd_node->list, &adapter->cmd_pending_q);
+ else
+ list_add(&cmd_node->list, &adapter->cmd_pending_q);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
PRINTM(MCMND, "QUEUE_CMD: cmd=0x%x is queued\n", command);
@@ -775,7 +777,8 @@ mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
struct cmd_ctrl_node *cmd_node = NULL;
enum mwifiex_status ret = MWIFIEX_STATUS_SUCCESS;
struct host_cmd_ds_command *host_cmd;
- unsigned long flags;
+ unsigned long cmd_flags;
+ unsigned long cmd_pending_q_flags;
ENTER();
@@ -793,51 +796,55 @@ mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
goto done;
}
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
/* Check if any command is pending */
- cmd_node =
- (struct cmd_ctrl_node *) mwifiex_util_peek_list(&adapter->
- cmd_pending_q,
- true);
-
- if (cmd_node) {
- host_cmd = (struct host_cmd_ds_command *)
- (cmd_node->cmd_buf->buffer +
- cmd_node->cmd_buf->data_offset);
- priv = cmd_node->priv;
-
- if (adapter->ps_state != PS_STATE_AWAKE) {
- PRINTM(MERROR, "Cannot send command in sleep state"
- ", this should not happen\n");
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock,
- flags);
- goto done;
- }
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
+ if (list_empty(&adapter->cmd_pending_q)) {
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+ ret = MWIFIEX_STATUS_SUCCESS;
+ goto done;
+ }
+ cmd_node = list_first_entry(&adapter->cmd_pending_q,
+ struct cmd_ctrl_node, list);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+
+ host_cmd = (struct host_cmd_ds_command *)
+ (cmd_node->cmd_buf->buffer +
+ cmd_node->cmd_buf->data_offset);
+ priv = cmd_node->priv;
+
+ if (adapter->ps_state != PS_STATE_AWAKE) {
+ PRINTM(MERROR, "Cannot send command in sleep state"
+ ", this should not happen\n");
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock,
+ cmd_flags);
+ goto done;
+ }
- mwifiex_util_unlink_list(&adapter->cmd_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
- ret = mwifiex_dnld_cmd_to_fw(priv, cmd_node);
- priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
- /* Any command sent to the firmware when host is in sleep
- mode, should
- de-configure host sleep */
- /* We should skip the host sleep configuration command
- itself though */
- if (priv &&
- (host_cmd->command !=
- cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) {
- if (adapter->hs_activated) {
- adapter->is_hs_configured = false;
- mwifiex_hs_activated_event(priv, false);
- }
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+ ret = mwifiex_dnld_cmd_to_fw(priv, cmd_node);
+ priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ /* Any command sent to the firmware when host is in sleep
+ * mode should de-configure host sleep. We should skip the
+ * host sleep configuration command itself though
+ */
+ if (priv &&
+ (host_cmd->command !=
+ cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) {
+ if (adapter->hs_activated) {
+ adapter->is_hs_configured = false;
+ mwifiex_hs_activated_event(priv, false);
}
- goto done;
- } else {
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
}
- ret = MWIFIEX_STATUS_SUCCESS;
+
done:
LEAVE();
return ret;
@@ -1096,7 +1103,7 @@ exit:
void
mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
{
- struct cmd_ctrl_node *cmd_node = NULL;
+ struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
struct mwifiex_ioctl_req *ioctl_buf = NULL;
unsigned long flags;
@@ -1113,13 +1120,12 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
MWIFIEX_STATUS_FAILURE);
}
/* Cancel all pending command */
- while ((cmd_node =
- (struct cmd_ctrl_node *) mwifiex_util_peek_list(&adapter->
- cmd_pending_q,
- true))) {
- mwifiex_util_unlink_list(&adapter->cmd_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ list_for_each_entry_safe(cmd_node, tmp_node,
+ &adapter->cmd_pending_q, list) {
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
if (cmd_node->ioctl_buf) {
ioctl_buf =
(struct mwifiex_ioctl_req *) cmd_node->
@@ -1130,18 +1136,23 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
cmd_node->ioctl_buf = NULL;
}
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
}
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
/* Cancel all pending scan command */
- while ((cmd_node =
- (struct cmd_ctrl_node *) mwifiex_util_peek_list(&adapter->
- scan_pending_q,
- true))) {
- mwifiex_util_unlink_list(&adapter->scan_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ list_for_each_entry_safe(cmd_node, tmp_node,
+ &adapter->scan_pending_q, list) {
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
cmd_node->ioctl_buf = NULL;
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
}
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
adapter->scan_processing = false;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
@@ -1161,8 +1172,10 @@ void
mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
struct mwifiex_ioctl_req *ioctl_req)
{
- struct cmd_ctrl_node *cmd_node = NULL;
- unsigned long flags;
+ struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
+ unsigned long cmd_flags;
+ unsigned long cmd_pending_q_flags;
+ unsigned long scan_pending_q_flags;
ENTER();
@@ -1172,38 +1185,47 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter,
if ((adapter->curr_cmd) &&
(adapter->curr_cmd->ioctl_buf == ioctl_req)) {
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
cmd_node = adapter->curr_cmd;
cmd_node->ioctl_buf = NULL;
cmd_node->cmd_flag |= CMD_F_CANCELED;
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
}
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
while ((cmd_node =
mwifiex_get_pending_ioctl_cmd(adapter, ioctl_req)) != NULL) {
- mwifiex_util_unlink_list(&adapter->cmd_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
+
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+ cmd_pending_q_flags);
+
cmd_node->ioctl_buf = NULL;
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
}
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
if (ioctl_req->req_id == MWIFIEX_IOCTL_SCAN) {
/* Cancel all pending scan command */
- while ((cmd_node =
- (struct cmd_ctrl_node *)
- mwifiex_util_peek_list(&adapter->scan_pending_q,
- true))) {
- mwifiex_util_unlink_list(&adapter->scan_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
+ list_for_each_entry_safe(cmd_node, tmp_node,
+ &adapter->scan_pending_q, list) {
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
cmd_node->ioctl_buf = NULL;
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
}
- spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ scan_pending_q_flags);
+
+ spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
adapter->scan_processing = false;
- spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+ spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
}
ioctl_req->status_code = MWIFIEX_ERROR_CMD_CANCEL;
mwifiex_ioctl_complete(adapter, ioctl_req, MWIFIEX_STATUS_FAILURE);
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 30d66c0..467eccc 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -150,8 +150,7 @@ struct mwifiex_ioctl_req {
};
struct mwifiex_buffer {
- struct mwifiex_buffer *prev;
- struct mwifiex_buffer *next;
+ struct list_head list;
u32 status_code;
u32 flags;
u32 bss_index;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 7b0b10c..de670c7 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -38,6 +38,7 @@ mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
struct mwifiex_adapter *adapter = priv->adapter;
struct mwifiex_bss_prio_node *bss_prio;
enum mwifiex_status status = MWIFIEX_STATUS_SUCCESS;
+ unsigned long flags;
ENTER();
@@ -49,18 +50,18 @@ mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
}
bss_prio->priv = priv;
-
- mwifiex_util_init_list((struct mwifiex_linked_list *) bss_prio);
-
+ INIT_LIST_HEAD(&bss_prio->list);
if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur)
adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
bss_prio;
- mwifiex_util_enqueue_list_tail(&adapter->
- bss_prio_tbl[priv->bss_priority].
- bss_prio_head,
- (struct mwifiex_linked_list *) bss_prio,
- true);
+ spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_lock, flags);
+ list_add_tail(&bss_prio->list,
+ &adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_head);
+ spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_lock, flags);
exit:
LEAVE();
@@ -366,6 +367,9 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter)
mwifiex_free_buffer(adapter->sleep_cfm);
+ /* Free lock variables */
+ mwifiex_free_lock_list(adapter);
+
LEAVE();
return;
}
@@ -397,28 +401,36 @@ enum mwifiex_status wlan_init_lock_list(struct mwifiex_adapter *adapter)
}
/* Initialize cmd_free_q */
- mwifiex_util_init_list_head(&adapter->cmd_free_q, true);
+ INIT_LIST_HEAD(&adapter->cmd_free_q);
/* Initialize cmd_pending_q */
- mwifiex_util_init_list_head(&adapter->cmd_pending_q, true);
+ INIT_LIST_HEAD(&adapter->cmd_pending_q);
/* Initialize scan_pending_q */
- mwifiex_util_init_list_head(&adapter->scan_pending_q, true);
+ INIT_LIST_HEAD(&adapter->scan_pending_q);
+
+ spin_lock_init(&adapter->cmd_free_q_lock);
+ spin_lock_init(&adapter->cmd_pending_q_lock);
+ spin_lock_init(&adapter->scan_pending_q_lock);
for (i = 0; i < adapter->priv_num; ++i) {
- mwifiex_util_init_list_head(&adapter->bss_prio_tbl[i]
- .bss_prio_head, true);
+ INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
adapter->bss_prio_tbl[i].bss_prio_cur = NULL;
+ spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock);
}
for (i = 0; i < adapter->priv_num; i++) {
if (adapter->priv[i]) {
priv = adapter->priv[i];
- for (j = 0; j < MAX_NUM_TID; ++j)
- mwifiex_util_init_list_head(&priv->wmm
- .tid_tbl_ptr[j].ra_list, true);
- mwifiex_util_init_list_head(&priv->tx_ba_stream_tbl_ptr,
- true);
- mwifiex_util_init_list_head(&priv->rx_reorder_tbl_ptr,
- true);
+ for (j = 0; j < MAX_NUM_TID; ++j) {
+ INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j]
+ .ra_list);
+ spin_lock_init(&priv->wmm.tid_tbl_ptr[j]
+ .tid_tbl_lock);
+ }
+ INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
+ INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
+
+ spin_lock_init(&priv->tx_ba_stream_tbl_lock);
+ spin_lock_init(&priv->rx_reorder_tbl_lock);
}
}
@@ -430,7 +442,7 @@ enum mwifiex_status wlan_init_lock_list(struct mwifiex_adapter *adapter)
* This function releases the lock variables and frees the locks and
* associated locks.
*/
-void wlan_free_lock_list(struct mwifiex_adapter *adapter)
+void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
{
struct mwifiex_private *priv = NULL;
s32 i = 0;
@@ -439,25 +451,20 @@ void wlan_free_lock_list(struct mwifiex_adapter *adapter)
ENTER();
/* Free lists */
- mwifiex_util_free_list_head(&adapter->cmd_free_q);
-
- mwifiex_util_free_list_head(&adapter->cmd_pending_q);
-
- mwifiex_util_free_list_head(&adapter->scan_pending_q);
+ list_del(&adapter->cmd_free_q);
+ list_del(&adapter->cmd_pending_q);
+ list_del(&adapter->scan_pending_q);
for (i = 0; i < adapter->priv_num; i++)
- mwifiex_util_free_list_head(&adapter->bss_prio_tbl[i]
- .bss_prio_head);
+ list_del(&adapter->bss_prio_tbl[i].bss_prio_head);
for (i = 0; i < adapter->priv_num; i++) {
if (adapter->priv[i]) {
priv = adapter->priv[i];
for (j = 0; j < MAX_NUM_TID; ++j)
- mwifiex_util_free_list_head(&priv->wmm
- .tid_tbl_ptr[j].ra_list);
- mwifiex_util_free_list_head(
- &priv->tx_ba_stream_tbl_ptr);
- mwifiex_util_free_list_head(&priv->rx_reorder_tbl_ptr);
+ list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
+ list_del(&priv->tx_ba_stream_tbl_ptr);
+ list_del(&priv->rx_reorder_tbl_ptr);
}
}
@@ -483,6 +490,8 @@ mwifiex_init_fw(struct mwifiex_adapter *adapter)
struct mwifiex_private *priv = NULL;
u8 i = 0;
u8 first_sta = true;
+ int is_cmd_pend_q_empty;
+ unsigned long flags;
ENTER();
@@ -521,7 +530,10 @@ mwifiex_init_fw(struct mwifiex_adapter *adapter)
}
}
- if (mwifiex_util_peek_list(&adapter->cmd_pending_q, true)) {
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+ if (!is_cmd_pend_q_empty) {
/* Send the first command in queue and return */
if (mwifiex_main_process(adapter) != MWIFIEX_STATUS_FAILURE)
ret = MWIFIEX_STATUS_PENDING;
@@ -672,37 +684,40 @@ mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
struct mwifiex_adapter *adapter = priv->adapter;
struct mwifiex_bss_prio_node *bssprio_node = NULL, *tmp_node = NULL,
**cur = NULL;
- struct mwifiex_list_head *head;
+ struct list_head *head;
+ spinlock_t *lock;
+ unsigned long flags;
ENTER();
for (i = 0; i < adapter->priv_num; ++i) {
head = &adapter->bss_prio_tbl[i].bss_prio_head;
cur = &adapter->bss_prio_tbl[i].bss_prio_cur;
+ lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
PRINTM(MINFO, "Delete BSS priority table, index = %d, i = %d, "
"head = %p, cur = %p\n",
priv->bss_index, i, head, *cur);
if (*cur) {
- bssprio_node = (struct mwifiex_bss_prio_node *)
- mwifiex_util_peek_list(head, true);
- while (bssprio_node
- && ((struct mwifiex_list_head *) bssprio_node !=
- head)) {
- tmp_node = bssprio_node->next;
+ spin_lock_irqsave(lock, flags);
+ if (list_empty(head)) {
+ spin_unlock_irqrestore(lock, flags);
+ continue;
+ }
+ bssprio_node = list_first_entry(head,
+ struct mwifiex_bss_prio_node, list);
+ spin_unlock_irqrestore(lock, flags);
+
+ list_for_each_entry_safe(bssprio_node, tmp_node, head,
+ list) {
if (bssprio_node->priv == priv) {
PRINTM(MINFO, "Delete node, node = %p,"
" next = %p\n",
bssprio_node, tmp_node);
- mwifiex_util_unlink_list(head,
- (struct
- mwifiex_linked_list
- *)
- bssprio_node,
- true);
-
+ spin_lock_irqsave(lock, flags);
+ list_del(&bssprio_node->list);
+ spin_unlock_irqrestore(lock, flags);
kfree(bssprio_node);
}
- bssprio_node = tmp_node;
}
*cur = (struct mwifiex_bss_prio_node *)head;
}
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 36bb35d..0f26068 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -160,7 +160,7 @@ error:
PRINTM(MINFO, "Leave mwifiex_register with error\n");
/* Free lock variables */
- wlan_free_lock_list(adapter);
+ mwifiex_free_lock_list(adapter);
for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++)
kfree(adapter->priv[i]);
kfree(adapter);
@@ -177,7 +177,6 @@ exit_register:
*
* The following cleanup operations are performed -
* - Free the timers
- * - Free the locks
* - Free beacon buffers
* - Free private structures
* - Free adapter structure
@@ -191,9 +190,6 @@ mwifiex_unregister(struct mwifiex_adapter *adapter)
del_timer(&adapter->cmd_timer);
- /* Free lock variables */
- wlan_free_lock_list(adapter);
-
/* Free private structures */
for (i = 0; i < adapter->priv_num; i++) {
if (adapter->priv[i]) {
@@ -258,7 +254,7 @@ process_start:
if ((adapter->ps_state == PS_STATE_SLEEP) &&
(adapter->pm_wakeup_card_req &&
!adapter->pm_wakeup_fw_try) &&
- (mwifiex_util_peek_list(&adapter->cmd_pending_q, true)
+ (is_command_pending(adapter)
|| !mwifiex_wmm_lists_empty(adapter))) {
adapter->pm_wakeup_fw_try = true;
adapter->if_ops.wakeup(adapter);
@@ -280,8 +276,7 @@ process_start:
|| mwifiex_wmm_lists_empty(adapter)) {
if (adapter->cmd_sent || adapter->curr_cmd
||
- (!mwifiex_util_peek_list
- (&adapter->cmd_pending_q, true)))
+ (!is_command_pending(adapter)))
break;
}
}
@@ -341,7 +336,7 @@ process_start:
}
if (adapter->delay_null_pkt && !adapter->cmd_sent &&
- !adapter->curr_cmd && !IS_COMMAND_PENDING(adapter)
+ !adapter->curr_cmd && !is_command_pending(adapter)
&& mwifiex_wmm_lists_empty(adapter)) {
if (mwifiex_send_null_packet
(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
@@ -424,8 +419,8 @@ mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **pmwifiex)
/*
* This function frees the adapter structure.
*
- * Additionally, this closes the netlink socket, frees the timers,
- * locks and private structures.
+ * Additionally, this closes the netlink socket, frees the timers
+ * and private structures.
*/
static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
{
@@ -1080,6 +1075,21 @@ void mwifiex_mac2u8(u8 *mac_addr, char *buf)
}
/*
+ * This function check if command is pending.
+ */
+int is_command_pending(struct mwifiex_adapter *adapter)
+{
+ unsigned long flags;
+ int is_cmd_pend_q_empty;
+
+ spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+ is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
+ return !is_cmd_pend_q_empty;
+}
+
+/*
* This function returns the correct private structure pointer based
* upon the BSS number.
*/
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index eb17ced..6c85bf4 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -203,16 +203,20 @@ struct mwifiex_tx_aggr {
};
struct mwifiex_ra_list_tbl {
- struct mwifiex_ra_list_tbl *prev;
- struct mwifiex_ra_list_tbl *next;
- struct mwifiex_list_head buf_head;
+ struct list_head list;
+ struct list_head buf_head;
+ /* spin lock for ra list table */
+ spinlock_t ra_list_tbl_lock;
+
u8 ra[MWIFIEX_MAC_ADDR_LENGTH];
u32 total_pkts_size;
u32 is_11n_enabled;
};
struct mwifiex_tid_tbl {
- struct mwifiex_list_head ra_list;
+ struct list_head ra_list;
+ /* spin lock for tid table */
+ spinlock_t tid_tbl_lock;
struct mwifiex_ra_list_tbl *ra_list_curr;
};
@@ -369,12 +373,16 @@ struct mwifiex_private {
u8 wmm_enabled;
u8 wmm_qosinfo;
struct mwifiex_wmm_desc wmm;
- struct mwifiex_list_head tx_ba_stream_tbl_ptr;
+ struct list_head tx_ba_stream_tbl_ptr;
+ /* spin lock for tx_ba_stream_tbl_ptr queue */
+ spinlock_t tx_ba_stream_tbl_lock;
struct mwifiex_tx_aggr aggr_prio_tbl[MAX_NUM_TID];
u8 addba_reject[MAX_NUM_TID];
struct mwifiex_add_ba_param add_ba_param;
u16 rx_seq[MAX_NUM_TID];
- struct mwifiex_list_head rx_reorder_tbl_ptr;
+ struct list_head rx_reorder_tbl_ptr;
+ /* spin lock for rx_reorder_tbl_ptr queue */
+ spinlock_t rx_reorder_tbl_lock;
/* spin lock for Rx packets */
spinlock_t rx_pkt_lock;
@@ -437,8 +445,7 @@ enum mwifiex_ba_status {
};
struct mwifiex_tx_ba_stream_tbl {
- struct mwifiex_tx_ba_stream_tbl *prev;
- struct mwifiex_tx_ba_stream_tbl *next;
+ struct list_head list;
int tid;
u8 ra[MWIFIEX_MAC_ADDR_LENGTH];
enum mwifiex_ba_status ba_status;
@@ -453,8 +460,7 @@ struct reorder_tmr_cnxt {
};
struct mwifiex_rx_reorder_tbl {
- struct mwifiex_rx_reorder_tbl *prev;
- struct mwifiex_rx_reorder_tbl *next;
+ struct list_head list;
int tid;
u8 ta[MWIFIEX_MAC_ADDR_LENGTH];
int start_win;
@@ -464,19 +470,19 @@ struct mwifiex_rx_reorder_tbl {
};
struct mwifiex_bss_prio_node {
- struct mwifiex_bss_prio_node *prev;
- struct mwifiex_bss_prio_node *next;
+ struct list_head list;
struct mwifiex_private *priv;
};
struct mwifiex_bss_prio_tbl {
- struct mwifiex_list_head bss_prio_head;
+ struct list_head bss_prio_head;
+ /* spin lock for bss priority */
+ spinlock_t bss_prio_lock;
struct mwifiex_bss_prio_node *bss_prio_cur;
};
struct cmd_ctrl_node {
- struct cmd_ctrl_node *prev;
- struct cmd_ctrl_node *next;
+ struct list_head list;
struct mwifiex_private *priv;
u32 cmd_oid;
u32 cmd_flag;
@@ -561,9 +567,15 @@ struct mwifiex_adapter {
u32 num_cmd_timeout;
u16 last_init_cmd;
struct timer_list cmd_timer;
- struct mwifiex_list_head cmd_free_q;
- struct mwifiex_list_head cmd_pending_q;
- struct mwifiex_list_head scan_pending_q;
+ struct list_head cmd_free_q;
+ /* spin lock for cmd_free_q */
+ spinlock_t cmd_free_q_lock;
+ struct list_head cmd_pending_q;
+ /* spin lock for cmd_pending_q */
+ spinlock_t cmd_pending_q_lock;
+ struct list_head scan_pending_q;
+ /* spin lock for scan_pending_q */
+ spinlock_t scan_pending_q_lock;
u32 scan_processing;
u16 region_code;
struct mwifiex_802_11d_domain_reg domain_reg;
@@ -619,7 +631,7 @@ struct mwifiex_adapter {
};
enum mwifiex_status wlan_init_lock_list(struct mwifiex_adapter *adapter);
-void wlan_free_lock_list(struct mwifiex_adapter *adapter);
+void mwifiex_free_lock_list(struct mwifiex_adapter *adapter);
enum mwifiex_status mwifiex_init_fw(struct mwifiex_adapter *adapter);
@@ -855,6 +867,7 @@ enum mwifiex_status mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
enum mwifiex_status mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp,
void *ioctl_buf);
+int is_command_pending(struct mwifiex_adapter *adapter);
/*
* This function checks if the queuing is RA based or not.
@@ -890,11 +903,6 @@ mwifiex_copy_rates(u8 *dest, u32 pos, u8 *src, int len)
return pos;
}
-
-#define IS_COMMAND_PENDING(adapter) ((struct cmd_ctrl_node *)\
- mwifiex_util_peek_list( \
- &adapter->cmd_pending_q, true))
-
/*
* This function returns the correct private structure pointer based
* upon the BSS type and BSS number.
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 83e466e..df4a77c 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -2589,16 +2589,23 @@ mwifiex_scan_networks(struct mwifiex_private *priv,
/* Get scan command from scan_pending_q and put to cmd_pending_q */
if (ret == MWIFIEX_STATUS_SUCCESS) {
- if (mwifiex_util_peek_list(&adapter->scan_pending_q, true)) {
- cmd_node = (struct cmd_ctrl_node *)
- mwifiex_util_dequeue_list(&adapter->
- scan_pending_q, true);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ if (!list_empty(&adapter->scan_pending_q)) {
+ cmd_node = list_first_entry(&adapter->scan_pending_q,
+ struct cmd_ctrl_node, list);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ flags);
+
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
adapter->scan_processing = true;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock,
flags);
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
true);
+ } else {
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ flags);
}
}
@@ -2919,7 +2926,9 @@ mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
/* Update the total number of BSSIDs in the scan table */
adapter->num_in_scan_table = num_in_table;
- if (!mwifiex_util_peek_list(&adapter->scan_pending_q, true)) {
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ if (list_empty(&adapter->scan_pending_q)) {
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
adapter->scan_processing = false;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
@@ -2950,10 +2959,10 @@ mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
} else {
/* Get scan command from scan_pending_q and put to
cmd_pending_q */
- cmd_node =
- (struct cmd_ctrl_node *)
- mwifiex_util_dequeue_list(&adapter->scan_pending_q,
- true);
+ cmd_node = list_first_entry(&adapter->scan_pending_q,
+ struct cmd_ctrl_node, list);
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
}
@@ -3149,15 +3158,16 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
struct cmd_ctrl_node *cmd_node)
{
struct mwifiex_adapter *adapter = priv->adapter;
+ unsigned long flags;
ENTER();
if (cmd_node == NULL)
goto done;
- mwifiex_util_enqueue_list_tail(&adapter->scan_pending_q,
- (struct mwifiex_linked_list *) cmd_node,
- true);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
done:
LEAVE();
}
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index a83c72a..05a869c 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -45,7 +45,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp,
struct mwifiex_ioctl_req *ioctl_buf)
{
- struct cmd_ctrl_node *cmd_node = NULL;
+ struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
struct mwifiex_adapter *adapter = priv->adapter;
unsigned long flags;
@@ -77,16 +77,18 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
break;
case HostCmd_CMD_802_11_SCAN:
/* Cancel all pending scan command */
- while ((cmd_node =
- (struct cmd_ctrl_node *)
- mwifiex_util_peek_list(&adapter->scan_pending_q,
- true))) {
- mwifiex_util_unlink_list(&adapter->scan_pending_q,
- (struct mwifiex_linked_list *)
- cmd_node, true);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ list_for_each_entry_safe(cmd_node, tmp_node,
+ &adapter->scan_pending_q, list) {
+ list_del(&cmd_node->list);
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+ flags);
cmd_node->ioctl_buf = NULL;
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+ spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
}
+ spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
adapter->scan_processing = false;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index b80d245..c4385ef 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -234,7 +234,7 @@ mwifiex_check_last_packet_indication(struct mwifiex_private *priv)
}
if (ret && !adapter->cmd_sent && !adapter->curr_cmd
- && !IS_COMMAND_PENDING(adapter)) {
+ && !is_command_pending(adapter)) {
adapter->delay_null_pkt = false;
ret = true;
} else {
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 55d912d..7e1bc9b 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -63,147 +63,6 @@ mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter)
}
/*
- * This function peeks into a list.
- *
- * A pointer to the next node in the list is returned, but the node
- * is not dequeued.
- */
-struct mwifiex_linked_list *
-mwifiex_util_peek_list(struct mwifiex_list_head *head, u8 lock_required)
-{
- struct mwifiex_linked_list *node = NULL;
- unsigned long flags;
-
- if (lock_required) {
- spin_lock_irqsave(&head->lock, flags);
- if (head->next != (struct mwifiex_linked_list *) head)
- node = head->next;
- spin_unlock_irqrestore(&head->lock, flags);
- } else {
- if (head->next != (struct mwifiex_linked_list *) head)
- node = head->next;
- }
-
- return node;
-}
-
-/*
- * This function initializes a list.
- *
- * It also initializes the associated lock if required.
- */
-inline void
-mwifiex_util_init_list_head(struct mwifiex_list_head *head, u8 lock_required)
-{
- mwifiex_util_init_list((struct mwifiex_linked_list *) head);
- if (lock_required)
- spin_lock_init(&head->lock);
-}
-
-/*
- * This function queues a new node at the list tail.
- */
-inline void
-mwifiex_util_enqueue_list_tail(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node,
- u8 lock_required)
-{
- struct mwifiex_linked_list *old_last;
- unsigned long flags = 0;
-
- if (lock_required)
- spin_lock_irqsave(&head->lock, flags);
-
- old_last = head->prev;
- node->prev = old_last;
- node->next = (struct mwifiex_linked_list *) head;
-
- old_last->next = node;
- head->prev = old_last->next;
-
- if (lock_required)
- spin_unlock_irqrestore(&head->lock, flags);
-}
-
-/*
- * This function queues a new node at the list head.
- */
-inline void
-mwifiex_util_enqueue_list_head(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node,
- u8 lock_required)
-{
- struct mwifiex_linked_list *old_first;
- unsigned long flags = 0;
-
- if (lock_required)
- spin_lock_irqsave(&head->lock, flags);
-
- old_first = head->next;
- node->prev = (struct mwifiex_linked_list *) head;
- node->next = old_first;
-
- old_first->prev = node;
- head->next = old_first->prev;
-
- if (lock_required)
- spin_unlock_irqrestore(&head->lock, flags);
-}
-
-/*
- * This function removes a node from the list.
- *
- * The node can be removed from any location within the list,
- * the other node pointers are adjusted accordingly.
- */
-inline void
-mwifiex_util_unlink_list(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node, u8 lock_required)
-{
- struct mwifiex_linked_list *my_prev;
- struct mwifiex_linked_list *my_next;
- unsigned long flags = 0;
-
- if (lock_required)
- spin_lock_irqsave(&head->lock, flags);
-
- my_prev = node->prev;
- my_next = node->next;
- my_next->prev = my_prev;
- my_prev->next = my_next;
-
- node->prev = NULL;
- node->next = node->prev;
-
- if (lock_required)
- spin_unlock_irqrestore(&head->lock, flags);
-}
-
-/*
- * This function dequeues a node from the list.
- */
-inline struct mwifiex_linked_list *
-mwifiex_util_dequeue_list(struct mwifiex_list_head *head, u8 lock_required)
-{
- struct mwifiex_linked_list *node;
- unsigned long flags = 0;
-
- if (lock_required)
- spin_lock_irqsave(&head->lock, flags);
-
- node = head->next;
- if (node != (struct mwifiex_linked_list *) head)
- mwifiex_util_unlink_list(head, node, false);
- else
- node = NULL;
-
- if (lock_required)
- spin_unlock_irqrestore(&head->lock, flags);
-
- return node;
-}
-
-/*
* IOCTL request handler to send a host command to firmware.
*
* This function prepares the correct firmware command and
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
index 12ba9f9..eaf4b06 100644
--- a/drivers/net/wireless/mwifiex/util.h
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -103,50 +103,4 @@ do { \
mwifiex_print(MHEX_DUMP | MINFO, x, y, z); \
} while (0)
-struct mwifiex_linked_list {
- struct mwifiex_linked_list *prev;
- struct mwifiex_linked_list *next;
-};
-
-struct mwifiex_list_head {
- struct mwifiex_linked_list *prev;
- struct mwifiex_linked_list *next;
- /* spin lock used for linked list operations */
- spinlock_t lock;
-};
-
-void mwifiex_util_init_list_head(struct mwifiex_list_head *head,
- u8 lock_required);
-void mwifiex_util_enqueue_list_tail(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node,
- u8 lock_required);
-void mwifiex_util_unlink_list(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node, u8 lock_required);
-void mwifiex_util_enqueue_list_head(struct mwifiex_list_head *head,
- struct mwifiex_linked_list *node,
- u8 lock_required);
-struct mwifiex_linked_list *mwifiex_util_dequeue_list(struct mwifiex_list_head
- *head, u8 lock_required);
-struct mwifiex_linked_list *mwifiex_util_peek_list(struct mwifiex_list_head
- *head, u8 lock_required);
-
-/*
- * This function initializes a list without locking.
- */
-static inline void
-mwifiex_util_init_list(struct mwifiex_linked_list *head)
-{
- head->next = (struct mwifiex_linked_list *) head;
- head->prev = head->next;
-}
-
-/*
- * This function frees a list and the associated lock.
- */
-static inline void
-mwifiex_util_free_list_head(struct mwifiex_list_head *head)
-{
- head->next = NULL;
- head->prev = head->next;
-}
#endif /* !_MWIFIEX_UTIL_H_ */
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 2a403ae..a0c29b4 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -121,8 +121,9 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
PRINTM(MERROR, "%s: failed to alloc ra_list\n", __func__);
goto done;
}
- mwifiex_util_init_list((struct mwifiex_linked_list *) ra_list);
- mwifiex_util_init_list_head(&ra_list->buf_head, false);
+ INIT_LIST_HEAD(&ra_list->list);
+ INIT_LIST_HEAD(&ra_list->buf_head);
+ spin_lock_init(&ra_list->ra_list_tbl_lock);
memcpy(ra_list->ra, ra, MWIFIEX_MAC_ADDR_LENGTH);
@@ -196,10 +197,8 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
PRINTM(MDATA, "ralist %p: is_11n_enabled=%d\n", ra_list,
ra_list->is_11n_enabled);
- mwifiex_util_enqueue_list_tail(&priv->wmm.tid_tbl_ptr[i].
- ra_list,
- (struct mwifiex_linked_list *)
- ra_list, false);
+ list_add_tail(&ra_list->list,
+ &priv->wmm.tid_tbl_ptr[i].ra_list);
if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr)
priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list;
@@ -548,23 +547,17 @@ static void
mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
struct mwifiex_ra_list_tbl *ra_list)
{
- struct mwifiex_buffer *mbuf;
+ struct mwifiex_buffer *mbuf, *tmp_node;
struct mwifiex_adapter *adapter = priv->adapter;
ENTER();
- while ((mbuf =
- (struct mwifiex_buffer *) mwifiex_util_peek_list(&ra_list->
- buf_head,
- false))) {
- mwifiex_util_unlink_list(&ra_list->buf_head,
- (struct mwifiex_linked_list *) mbuf,
- false);
-
+ list_for_each_entry_safe(mbuf, tmp_node, &ra_list->buf_head, list) {
+ list_del(&mbuf->list);
mwifiex_write_data_complete(adapter, mbuf,
- MWIFIEX_STATUS_FAILURE);
+ MWIFIEX_STATUS_FAILURE);
}
- mwifiex_util_free_list_head(&ra_list->buf_head);
+ list_del(&ra_list->buf_head);
LEAVE();
}
@@ -577,23 +570,15 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
*/
static void
mwifiex_wmm_del_pkts_in_ralist(struct mwifiex_private *priv,
- struct mwifiex_list_head *ra_list_head)
+ struct list_head *ra_list_head)
{
struct mwifiex_ra_list_tbl *ra_list;
ENTER();
- ra_list =
- (struct mwifiex_ra_list_tbl *)
- mwifiex_util_peek_list(ra_list_head, false);
-
- while (ra_list
- && ra_list != (struct mwifiex_ra_list_tbl *) ra_list_head) {
+ list_for_each_entry(ra_list, ra_list_head, list)
mwifiex_wmm_del_pkts_in_ralist_node(priv, ra_list);
- ra_list = ra_list->next;
- }
-
LEAVE();
}
@@ -622,27 +607,21 @@ mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv)
void
mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv)
{
- struct mwifiex_ra_list_tbl *ra_list;
+ struct mwifiex_ra_list_tbl *ra_list, *tmp_node;
int i;
ENTER();
for (i = 0; i < MAX_NUM_TID; ++i) {
PRINTM(MINFO, "RAList: Freeing buffers for TID %d\n", i);
- while ((ra_list =
- (struct mwifiex_ra_list_tbl *)
- mwifiex_util_peek_list(&priv->wmm.tid_tbl_ptr[i].
- ra_list, false))) {
- mwifiex_util_unlink_list(&priv->wmm.tid_tbl_ptr[i].
- ra_list,
- (struct mwifiex_linked_list *)
- ra_list, false);
-
+ list_for_each_entry_safe(ra_list, tmp_node,
+ &priv->wmm.tid_tbl_ptr[i].ra_list, list) {
+ list_del(&ra_list->list);
kfree(ra_list);
}
- mwifiex_util_init_list((struct mwifiex_linked_list *)
- &priv->wmm.tid_tbl_ptr[i].ra_list);
+ INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list);
+
priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
}
@@ -658,22 +637,17 @@ mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid,
u8 *ra_addr)
{
struct mwifiex_ra_list_tbl *ra_list;
+
ENTER();
- ra_list =
- (struct mwifiex_ra_list_tbl *) mwifiex_util_peek_list(&priv->
- wmm.
- tid_tbl_ptr
- [tid].
- ra_list,
- false);
- while (ra_list && (ra_list != (struct mwifiex_ra_list_tbl *)
- &priv->wmm.tid_tbl_ptr[tid].ra_list)) {
+
+ list_for_each_entry(ra_list, &priv->wmm.tid_tbl_ptr[tid].ra_list,
+ list) {
if (!memcmp(ra_list->ra, ra_addr, MWIFIEX_MAC_ADDR_LENGTH)) {
LEAVE();
return ra_list;
}
- ra_list = ra_list->next;
}
+
LEAVE();
return NULL;
}
@@ -714,19 +688,10 @@ mwifiex_is_ralist_valid(struct mwifiex_private *priv,
{
struct mwifiex_ra_list_tbl *rlist;
- rlist = (struct mwifiex_ra_list_tbl *) mwifiex_util_peek_list(&priv->
- wmm.
- tid_tbl_ptr
- [ptr_index].
- ra_list,
- false);
-
- while (rlist && (rlist != (struct mwifiex_ra_list_tbl *)
- &priv->wmm.tid_tbl_ptr[ptr_index].ra_list)) {
+ list_for_each_entry(rlist, &priv->wmm.tid_tbl_ptr[ptr_index].ra_list,
+ list) {
if (rlist == ra_list)
return true;
-
- rlist = rlist->next;
}
return false;
@@ -773,10 +738,14 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
association we just don't have to call get_queue_raptr, we will
have only 1 raptr for a tid in case of infra */
if (!mwifiex_queuing_ra_based(priv)) {
- ra_list =
- (struct mwifiex_ra_list_tbl *)
- mwifiex_util_peek_list(&priv->wmm.tid_tbl_ptr[tid_down].
- ra_list, false);
+ if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list))
+ ra_list = list_first_entry(&priv->wmm
+ .tid_tbl_ptr[tid_down]
+ .ra_list,
+ struct mwifiex_ra_list_tbl,
+ list);
+ else
+ ra_list = NULL;
} else {
memcpy(ra, mbuf->buffer + mbuf->data_offset,
MWIFIEX_MAC_ADDR_LENGTH);
@@ -792,9 +761,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
}
PRINTM(MDAT_D, "Adding pkt to ra_list %p %p\n", ra_list, mbuf);
- mwifiex_util_enqueue_list_tail(&ra_list->buf_head,
- (struct mwifiex_linked_list *) mbuf,
- false);
+ list_add_tail(&mbuf->list, &ra_list->buf_head);
ra_list->total_pkts_size += mbuf->data_len;
@@ -1016,22 +983,31 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
struct mwifiex_ra_list_tbl *ptr, *head;
struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head;
struct mwifiex_tid_tbl *tid_ptr;
+ int is_list_empty;
+ unsigned long flags;
int i, j;
ENTER();
PRINTM(MDAT_D, "POP\n");
for (j = adapter->priv_num - 1; j >= 0; --j) {
- if (!
- (mwifiex_util_peek_list
- (&adapter->bss_prio_tbl[j].bss_prio_head, true)))
+ spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock,
+ flags);
+ is_list_empty = list_empty(&adapter->bss_prio_tbl[j]
+ .bss_prio_head);
+ spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
+ flags);
+ if (is_list_empty)
continue;
if (adapter->bss_prio_tbl[j].bss_prio_cur ==
(struct mwifiex_bss_prio_node *)
&adapter->bss_prio_tbl[j].bss_prio_head) {
bssprio_node =
- adapter->bss_prio_tbl[j].bss_prio_cur->next;
+ list_first_entry(&adapter->bss_prio_tbl[j]
+ .bss_prio_head,
+ struct mwifiex_bss_prio_node,
+ list);
bssprio_head = bssprio_node;
} else {
bssprio_node =
@@ -1047,8 +1023,15 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
tid_ptr =
&(priv_tmp)->wmm.
tid_tbl_ptr[tos_to_tid[i]];
- if (!mwifiex_util_peek_list
- (&tid_ptr->ra_list, true))
+
+ spin_lock_irqsave(&tid_ptr->tid_tbl_lock,
+ flags);
+ is_list_empty =
+ list_empty(&adapter->bss_prio_tbl[j]
+ .bss_prio_head);
+ spin_unlock_irqrestore(&tid_ptr->tid_tbl_lock,
+ flags);
+ if (is_list_empty)
continue;
/*
@@ -1056,38 +1039,64 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
* last time, this way we pick the ra's in
* round robin fashion.
*/
- ptr = tid_ptr->ra_list_curr->next;
+ ptr = list_first_entry(
+ &tid_ptr->ra_list_curr->list,
+ struct mwifiex_ra_list_tbl,
+ list);
+
head = ptr;
if (ptr == (struct mwifiex_ra_list_tbl *)
&tid_ptr->ra_list) {
- ptr = ptr->next;
+ /* Get next ra */
+ ptr = list_first_entry(&ptr->list,
+ struct mwifiex_ra_list_tbl, list);
head = ptr;
}
do {
- if (mwifiex_util_peek_list
- (&ptr->buf_head, true)) {
+ spin_lock_irqsave(
+ &ptr->ra_list_tbl_lock,
+ flags);
+ is_list_empty =
+ list_empty(&ptr->buf_head);
+ spin_unlock_irqrestore(
+ &ptr->ra_list_tbl_lock,
+ flags);
+ if (!is_list_empty) {
*priv = priv_tmp;
*tid = tos_to_tid[i];
LEAVE();
return ptr;
}
- ptr = ptr->next;
+ /* Get next ra */
+ ptr = list_first_entry(&ptr->list,
+ struct mwifiex_ra_list_tbl,
+ list);
if (ptr ==
(struct mwifiex_ra_list_tbl *)
&tid_ptr->ra_list)
- ptr = ptr->next;
+ ptr = list_first_entry(
+ &ptr->list,
+ struct mwifiex_ra_list_tbl,
+ list);
} while (ptr != head);
}
- bssprio_node = bssprio_node->next;
+ /* Get next bss priority node */
+ bssprio_node = list_first_entry(&bssprio_node->list,
+ struct mwifiex_bss_prio_node,
+ list);
+
if (bssprio_node ==
(struct mwifiex_bss_prio_node *)
&adapter->bss_prio_tbl[j].bss_prio_head)
- bssprio_node = bssprio_node->next;
+ /* Get next bss priority node */
+ bssprio_node = list_first_entry(
+ &bssprio_node->list,
+ struct mwifiex_bss_prio_node,
+ list);
} while (bssprio_node != bssprio_head);
}
-
LEAVE();
return NULL;
}
@@ -1105,10 +1114,7 @@ mwifiex_num_pkts_in_txq(struct mwifiex_private *priv,
ENTER();
- for (mbuf = (struct mwifiex_buffer *) ptr->buf_head.next;
- mbuf != (struct mwifiex_buffer *) (&ptr->buf_head);
- mbuf = mbuf->next) {
-
+ list_for_each_entry(mbuf, &ptr->buf_head, list) {
total_size += mbuf->data_len;
if (total_size < max_buf_size)
++count;
@@ -1126,7 +1132,7 @@ mwifiex_num_pkts_in_txq(struct mwifiex_private *priv,
static void
mwifiex_send_single_packet(struct mwifiex_private *priv,
struct mwifiex_ra_list_tbl *ptr, int ptr_index,
- unsigned long flags)
+ unsigned long ra_list_flags)
__releases(&priv->wmm.ra_list_spinlock)
{
struct mwifiex_buffer *mbuf;
@@ -1134,65 +1140,81 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
struct mwifiex_tx_param tx_param;
struct mwifiex_adapter *adapter = priv->adapter;
enum mwifiex_status status = MWIFIEX_STATUS_SUCCESS;
+ unsigned long ra_list_tbl_flags;
ENTER();
- mbuf = (struct mwifiex_buffer *)
- mwifiex_util_dequeue_list(&ptr->buf_head, true);
- if (mbuf) {
- PRINTM(MDATA, "Dequeuing the packet %p %p\n", ptr, mbuf);
+ spin_lock_irqsave(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+ if (list_empty(&ptr->buf_head)) {
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ PRINTM(MDATA, "Nothing to send\n");
+ return;
+ }
+ mbuf = list_first_entry(&ptr->buf_head,
+ struct mwifiex_buffer, list);
+ list_del(&mbuf->list);
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+
+ PRINTM(MDATA, "Dequeuing the packet %p %p\n", ptr, mbuf);
+
+ ptr->total_pkts_size -= mbuf->data_len;
+
+ if (!list_empty(&ptr->buf_head))
+ mbuf_next = list_first_entry(&ptr->buf_head,
+ struct mwifiex_buffer, list);
+ else
+ mbuf_next = NULL;
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ tx_param.next_pkt_len =
+ ((mbuf_next) ? mbuf_next->data_len +
+ sizeof(struct txpd) : 0);
+ status = mwifiex_process_tx(priv, mbuf, &tx_param);
+
+ if (status == MWIFIEX_STATUS_RESOURCE) {
+ /** Queue the packet back at the head */
+ PRINTM(MDAT_D, "Queuing pkt back to raList %p %p\n",
+ ptr, mbuf);
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ spin_unlock_irqrestore(
+ &priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ mwifiex_write_data_complete(adapter, mbuf,
+ MWIFIEX_STATUS_FAILURE);
+ LEAVE();
+ return;
+ }
- ptr->total_pkts_size -= mbuf->data_len;
- mbuf_next =
- (struct mwifiex_buffer *) mwifiex_util_peek_list(&ptr->
- buf_head,
- false);
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ spin_lock_irqsave(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+ list_add(&mbuf->list, &ptr->buf_head);
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock,
+ ra_list_tbl_flags);
- tx_param.next_pkt_len =
- ((mbuf_next) ? mbuf_next->data_len +
- sizeof(struct txpd) : 0);
- status = mwifiex_process_tx(priv, mbuf, &tx_param);
-
- if (status == MWIFIEX_STATUS_RESOURCE) {
- /** Queue the packet back at the head */
- PRINTM(MDAT_D, "Queuing pkt back to raList %p %p\n",
- ptr, mbuf);
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
-
- if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
- spin_unlock_irqrestore(
- &priv->wmm.ra_list_spinlock,
- flags);
- mwifiex_write_data_complete(adapter, mbuf,
- MWIFIEX_STATUS_FAILURE);
- LEAVE();
- return;
- }
- mwifiex_util_enqueue_list_head(&ptr->buf_head,
- (struct mwifiex_linked_list *)
- mbuf, true);
-
- ptr->total_pkts_size += mbuf->data_len;
- mbuf->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
- } else {
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
- if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
- priv->wmm.packets_out[ptr_index]++;
- priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr =
- ptr;
- }
- adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
- adapter->bss_prio_tbl[priv->bss_priority].
- bss_prio_cur->next;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
- }
+ ptr->total_pkts_size += mbuf->data_len;
+ mbuf->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
} else {
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
- PRINTM(MDATA, "Nothing to send\n");
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ priv->wmm.packets_out[ptr_index]++;
+ priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr =
+ ptr;
+ }
+ adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+ list_first_entry(
+ &adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_cur->list,
+ struct mwifiex_bss_prio_node,
+ list);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
}
LEAVE();
@@ -1208,9 +1230,12 @@ mwifiex_is_ptr_processed(struct mwifiex_private *priv,
{
struct mwifiex_buffer *mbuf;
- mbuf = (struct mwifiex_buffer *)
- mwifiex_util_peek_list(&ptr->buf_head, false);
- if (mbuf && (mbuf->flags & MWIFIEX_BUF_FLAG_REQUEUED_PKT))
+ if (list_empty(&ptr->buf_head))
+ return false;
+
+ mbuf = list_first_entry(&ptr->buf_head, struct mwifiex_buffer, list);
+
+ if (mbuf->flags & MWIFIEX_BUF_FLAG_REQUEUED_PKT)
return true;
return false;
@@ -1223,7 +1248,7 @@ mwifiex_is_ptr_processed(struct mwifiex_private *priv,
static void
mwifiex_send_processed_packet(struct mwifiex_private *priv,
struct mwifiex_ra_list_tbl *ptr, int ptr_index,
- unsigned long flags)
+ unsigned long ra_list_flags)
__releases(&priv->wmm.ra_list_spinlock)
{
struct mwifiex_buffer *mbuf_next;
@@ -1231,72 +1256,89 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
struct mwifiex_buffer *mbuf;
struct mwifiex_adapter *adapter = priv->adapter;
enum mwifiex_status ret = MWIFIEX_STATUS_FAILURE;
+ unsigned long ra_list_tbl_flags;
ENTER();
- mbuf = (struct mwifiex_buffer *)
- mwifiex_util_dequeue_list(&ptr->buf_head, true);
- if (mbuf) {
- mbuf_next =
- (struct mwifiex_buffer *) mwifiex_util_peek_list(&ptr->
- buf_head,
- false);
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
- tx_param.next_pkt_len =
- ((mbuf_next) ? mbuf_next->data_len +
- sizeof(struct txpd) : 0);
- ret = adapter->if_ops.host_to_card(adapter,
- MWIFIEX_TYPE_DATA, mbuf,
- &tx_param);
- switch (ret) {
- case MWIFIEX_STATUS_RESOURCE:
- PRINTM(MDATA, "MWIFIEX_STATUS_RESOURCE is returned\n");
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
-
- if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
- spin_unlock_irqrestore(
- &priv->wmm.ra_list_spinlock,
- flags);
- mwifiex_write_data_complete(adapter, mbuf,
- MWIFIEX_STATUS_FAILURE);
- LEAVE();
- return;
- }
- mwifiex_util_enqueue_list_head(&ptr->buf_head,
- (struct mwifiex_linked_list *)
- mbuf, true);
+ spin_lock_irqsave(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+ if (list_empty(&ptr->buf_head)) {
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ return;
+ }
- mbuf->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
- break;
- case MWIFIEX_STATUS_FAILURE:
- adapter->data_sent = false;
- PRINTM(MERROR,
- "Error: mwifiex_write_data failed: 0x%X\n", ret);
- adapter->dbg.num_tx_host_to_card_failure++;
- mwifiex_write_data_complete(adapter, mbuf, ret);
- break;
- case MWIFIEX_STATUS_PENDING:
- adapter->data_sent = false;
- default:
- break;
+ mbuf = list_first_entry(&ptr->buf_head, struct mwifiex_buffer, list);
+
+ list_del(&mbuf->list);
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+
+ if (!list_empty(&ptr->buf_head))
+ mbuf_next = list_first_entry(&ptr->buf_head,
+ struct mwifiex_buffer, list);
+ else
+ mbuf_next = NULL;
+
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ tx_param.next_pkt_len =
+ ((mbuf_next) ? mbuf_next->data_len +
+ sizeof(struct txpd) : 0);
+ ret = adapter->if_ops.host_to_card(adapter,
+ MWIFIEX_TYPE_DATA, mbuf,
+ &tx_param);
+ switch (ret) {
+ case MWIFIEX_STATUS_RESOURCE:
+ PRINTM(MDATA, "MWIFIEX_STATUS_RESOURCE is returned\n");
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+ if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ spin_unlock_irqrestore(
+ &priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ mwifiex_write_data_complete(adapter, mbuf,
+ MWIFIEX_STATUS_FAILURE);
+ LEAVE();
+ return;
}
- if (ret != MWIFIEX_STATUS_RESOURCE) {
- spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
- if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
- priv->wmm.packets_out[ptr_index]++;
- priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr =
- ptr;
- }
- adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
- adapter->bss_prio_tbl[priv->bss_priority].
- bss_prio_cur->next;
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
- flags);
+
+ spin_lock_irqsave(&ptr->ra_list_tbl_lock, ra_list_tbl_flags);
+ list_add(&mbuf->list, &ptr->buf_head);
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock,
+ ra_list_tbl_flags);
+
+ mbuf->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
+ break;
+ case MWIFIEX_STATUS_FAILURE:
+ adapter->data_sent = false;
+ PRINTM(MERROR,
+ "Error: mwifiex_write_data failed: 0x%X\n", ret);
+ adapter->dbg.num_tx_host_to_card_failure++;
+ mwifiex_write_data_complete(adapter, mbuf, ret);
+ break;
+ case MWIFIEX_STATUS_PENDING:
+ adapter->data_sent = false;
+ default:
+ break;
+ }
+ if (ret != MWIFIEX_STATUS_RESOURCE) {
+ spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+ if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+ priv->wmm.packets_out[ptr_index]++;
+ priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr =
+ ptr;
}
- } else {
- spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+ /* Now bss_prio_cur pointer points to next node */
+ adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+ list_first_entry(
+ &adapter->bss_prio_tbl[priv->bss_priority]
+ .bss_prio_cur->list,
+ struct mwifiex_bss_prio_node,
+ list);
+ spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+ ra_list_flags);
}
LEAVE();
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index 88f4480..1dce042 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -28,11 +28,17 @@ mwifiex_get_tid(struct mwifiex_adapter *adapter,
struct mwifiex_ra_list_tbl *ptr)
{
struct mwifiex_buffer *mbuf;
+ unsigned long flags;
ENTER();
- mbuf = (struct mwifiex_buffer *) mwifiex_util_peek_list(&ptr->buf_head,
- true);
+ spin_lock_irqsave(&ptr->ra_list_tbl_lock, flags);
+ if (list_empty(&ptr->buf_head)) {
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock, flags);
+ return 0;
+ }
+ mbuf = list_first_entry(&ptr->buf_head, struct mwifiex_buffer, list);
+ spin_unlock_irqrestore(&ptr->ra_list_tbl_lock, flags);
LEAVE();
return mbuf->priority;
@@ -43,19 +49,15 @@ mwifiex_get_tid(struct mwifiex_adapter *adapter,
*/
static inline int
mwifiex_wmm_list_len(struct mwifiex_adapter *adapter,
- struct mwifiex_list_head *head)
+ struct list_head *head)
{
- struct mwifiex_linked_list *pos;
+ struct list_head *pos;
int count = 0;
ENTER();
- pos = head->next;
-
- while (pos != (struct mwifiex_linked_list *) head) {
+ list_for_each(pos, head)
++count;
- pos = pos->next;
- }
LEAVE();
return count;
@@ -66,17 +68,18 @@ mwifiex_wmm_list_len(struct mwifiex_adapter *adapter,
*/
static inline u8
mwifiex_wmm_is_ra_list_empty(struct mwifiex_adapter *adapter,
- struct mwifiex_list_head *ra_list_hhead)
+ struct list_head *ra_list_hhead)
{
struct mwifiex_ra_list_tbl *ra_list;
-
- ra_list = (struct mwifiex_ra_list_tbl *) ra_list_hhead->next;
-
- while (ra_list != (struct mwifiex_ra_list_tbl *) ra_list_hhead) {
- if (mwifiex_util_peek_list(&ra_list->buf_head, true))
+ int is_list_empty;
+ unsigned long flags;
+
+ list_for_each_entry(ra_list, ra_list_hhead, list) {
+ spin_lock_irqsave(&ra_list->ra_list_tbl_lock, flags);
+ is_list_empty = list_empty(&ra_list->buf_head);
+ spin_unlock_irqrestore(&ra_list->ra_list_tbl_lock, flags);
+ if (!is_list_empty)
return false;
-
- ra_list = (struct mwifiex_ra_list_tbl *) ra_list->next;
}
return true;
--
1.7.0.2
^ permalink raw reply related
* Re: Linux script to enable ASPM / Documentation for ASPM
From: Luis R. Rodriguez @ 2011-01-14 3:15 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-wireless, Martin Mares
In-Reply-To: <AANLkTilcEZDsWTWBjrXIgiIaBPWZN5k-RMhFE6VvVlhc@mail.gmail.com>
On Mon, Jun 21, 2010 at 4:02 PM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
> On Mon, Jun 21, 2010 at 3:58 PM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
>> ASPM was a dark magic when I first started looking at it. Some of it
>> is still dark but what I was able to understand with the help of
>> colleagues at work I've managed to stash here for now:
>>
>> http://wireless.kernel.org/en/users/Documentation/ASPM
>>
>> Then enabling ASPM was also quite a challenge and I always had to go
>> back and revisit the procedures, so to help with that instead I wrote
>> a script to do this for you correctly:
>>
>> http://kernel.org/pub/linux/kernel/people/mcgrof/aspm/enable-aspm
>>
>> Its sha1sum is: f5804fdab512065f219e55addf78c6654f1fc045
>>
>> If any of that looks confusing refer to the documentation above.
>>
>> There's a TODO there, so I'll get to the different items when I can
>> but if you like feel free to send me patches as well:
>>
>> TODO: patches are welcomed to me until we submit to to
>> PCI Utilities upstream.
>>
>> This can be improved by in this order:
>>
>> * Accept arguments for endpoint and root complex address, and
>> desired ASPM settings
>> * Look for your ASPM capabilities by quering your
>> LnkCap register first. Use these values to let you
>> select whether you want to enable only L1 or L1 & L0s
>> * Searching for your root complex for you
>> * Search for your PCI device by using the driver
>> * Disable your driver and ask to reboot ?
>> * Rewrite in C
>> * Write ncurses interface [ wishlist ]
>> * Write GTK/QT interface [ wishlist ]
>> * Submit upstream as aspm.c to the PCI Utilities, which are
>> maintained by Martin Mares <mj@ucw.cz>
>
> Come to think of it, would this be welcomed upstream in the PCI utils
> as is for now?
New version that'll work with new setpci.
http://kernel.org/pub/linux/kernel/people/mcgrof/aspm/enable-aspm
sha1sum:
f2e6e9a36ff7fe3b875229ee237f605d0695b18a
with this diff:
--- enable-aspm.old 2011-01-14 03:13:33.248428802 +0000
+++ enable-aspm 2011-01-14 03:12:51.711354522 +0000
@@ -161,11 +161,11 @@
exit
fi
- SEARCH=$(setpci -s $1 34)
+ SEARCH=$(setpci -s $1 34.b)
# We know on the first search $SEARCH will not be
# 10 but this simplifies the implementation.
while [[ $SEARCH != 10 && $SEARCH_COUNT -le $MAX_SEARCH ]]; do
- END_SEARCH=$(setpci -s $1 $SEARCH)
+ END_SEARCH=$(setpci -s $1 ${SEARCH}.b)
# Convert hex digits to uppercase for bc
SEARCH_UPPER=$(printf "%X" 0x${SEARCH})
@@ -176,7 +176,7 @@
fi
SEARCH=$(echo "obase=16; ibase=16; $SEARCH + 1" | bc)
- SEARCH=$(setpci -s $1 $SEARCH)
+ SEARCH=$(setpci -s $1 ${SEARCH}.b)
let SEARCH_COUNT=$SEARCH_COUNT+1
done
@@ -200,7 +200,7 @@
return 1
fi
- ASPM_BYTE_HEX=$(setpci -s $1 $ASPM_BYTE_ADDRESS)
+ ASPM_BYTE_HEX=$(setpci -s $1 ${ASPM_BYTE_ADDRESS}.b)
ASPM_BYTE_HEX=$(printf "%X" 0x${ASPM_BYTE_HEX})
# setpci doesn't support a mask on the query yet, only on the set,
# so to verify a setting on a mask we have no other optoin but
@@ -228,11 +228,11 @@
fi
# This only writes the last 3 bits
- setpci -s $1 ${ASPM_BYTE_ADDRESS}=${ASPM_SETTING}:3
+ setpci -s $1 ${ASPM_BYTE_ADDRESS}.b=${ASPM_SETTING}:3
sleep 3
- ACTUAL_ASPM_BYTE_HEX=$(setpci -s $1 ${ASPM_BYTE_ADDRESS})
+ ACTUAL_ASPM_BYTE_HEX=$(setpci -s $1 ${ASPM_BYTE_ADDRESS}.b)
ACTUAL_ASPM_BYTE_HEX=$(printf "%X" 0x${ACTUAL_ASPM_BYTE_HEX})
# Do not retry this if it failed, if it failed to set.
^ permalink raw reply
* [PATCH v2] ath9k_hw: ASPM interoperability fix for AR9380/AR9382
From: Luis R. Rodriguez @ 2011-01-14 2:19 UTC (permalink / raw)
To: linville
Cc: linux-wireless, Luis R. Rodriguez, stable, Jack Lee, Carl Huang,
David Quan, Nael Atallah, Sarvesh Shrivastava
There is an interoperability with AR9382/AR9380 in L1 state with a
few root complexes which can cause a hang. This is fixed by
setting some work around bits on the PCIE PHY. We fix by using
a new ini array to modify these bits when the radio is idle.
Cc: stable@kernel.org
Cc: Jack Lee <jack.lee@atheros.com>
Cc: Carl Huang <carl.huang@atheros.com>
Cc: David Quan <david.quan@atheros.com>
Cc: Nael Atallah <nael.atallah@atheros.com>
Cc: Sarvesh Shrivastava <sarvesh.shrivastava@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
.../net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 2 +-
drivers/net/wireless/ath/ath9k/ar9003_hw.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 81f9cf2..9ecca93 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -1842,7 +1842,7 @@ static const u32 ar9300_2p2_soc_preamble[][2] = {
static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
/* Addr allmodes */
- {0x00004040, 0x08212e5e},
+ {0x00004040, 0x0821265e},
{0x00004040, 0x0008003b},
{0x00004044, 0x00000000},
};
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 6137634..06fb2c8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -146,8 +146,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
/* Sleep Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
- ar9300PciePhy_clkreq_enable_L1_2p2,
- ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
+ ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
+ ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
2);
/* Fast clock modal settings */
--
1.7.3.2.90.gd4c43
^ permalink raw reply related
* [PATCH] ath9k_hw: partially revert "fix dma descriptor rx error bit parsing"
From: Felix Fietkau @ 2011-01-13 23:06 UTC (permalink / raw)
To: linux-wireless; +Cc: linville, lrodriguez
The rx error bit parsing was changed to consider PHY errors and various
decryption errors separately. While correct according to the documentation,
this is causing spurious decryption error reports in some situations.
Fix this by restoring the original order of the checks in those places,
where the errors are meant to be mutually exclusive.
If a CRC error is reported, then MIC failure and decryption errors
are irrelevant, and a PHY error is unlikely.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/ar9003_mac.c | 8 ++++----
drivers/net/wireless/ath/ath9k/mac.c | 14 ++++++++++----
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 4ceddbb..038a0cb 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -615,7 +615,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
*/
if (rxsp->status11 & AR_CRCErr)
rxs->rs_status |= ATH9K_RXERR_CRC;
- if (rxsp->status11 & AR_PHYErr) {
+ else if (rxsp->status11 & AR_PHYErr) {
phyerr = MS(rxsp->status11, AR_PHYErrCode);
/*
* If we reach a point here where AR_PostDelimCRCErr is
@@ -638,11 +638,11 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
rxs->rs_phyerr = phyerr;
}
- }
- if (rxsp->status11 & AR_DecryptCRCErr)
+ } else if (rxsp->status11 & AR_DecryptCRCErr)
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
- if (rxsp->status11 & AR_MichaelErr)
+ else if (rxsp->status11 & AR_MichaelErr)
rxs->rs_status |= ATH9K_RXERR_MIC;
+
if (rxsp->status11 & AR_KeyMiss)
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
}
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 180170d..c75d40f 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -690,17 +690,23 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
+ /*
+ * Treat these errors as mutually exclusive to avoid spurious
+ * extra error reports from the hardware. If a CRC error is
+ * reported, then decryption and MIC errors are irrelevant,
+ * the frame is going to be dropped either way
+ */
if (ads.ds_rxstatus8 & AR_CRCErr)
rs->rs_status |= ATH9K_RXERR_CRC;
- if (ads.ds_rxstatus8 & AR_PHYErr) {
+ else if (ads.ds_rxstatus8 & AR_PHYErr) {
rs->rs_status |= ATH9K_RXERR_PHY;
phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
rs->rs_phyerr = phyerr;
- }
- if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
+ } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
rs->rs_status |= ATH9K_RXERR_DECRYPT;
- if (ads.ds_rxstatus8 & AR_MichaelErr)
+ else if (ads.ds_rxstatus8 & AR_MichaelErr)
rs->rs_status |= ATH9K_RXERR_MIC;
+
if (ads.ds_rxstatus8 & AR_KeyMiss)
rs->rs_status |= ATH9K_RXERR_DECRYPT;
}
--
1.7.3.2
^ permalink raw reply related
* RE: [PATCH v2] mwifiex: remove linked list implementation
From: Bing Zhao @ 2011-01-13 22:58 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless@vger.kernel.org, John W. Linville,
Amitkumar Karwar, Kiran Divekar, Frank Huang
In-Reply-To: <1294910380.3725.2.camel@jlt3.sipsolutions.net>
SGkgSm9oYW5uZXMsDQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogSm9o
YW5uZXMgQmVyZyBbbWFpbHRvOmpvaGFubmVzQHNpcHNvbHV0aW9ucy5uZXRdDQo+IFNlbnQ6IFRo
dXJzZGF5LCBKYW51YXJ5IDEzLCAyMDExIDE6MjAgQU0NCj4gVG86IEJpbmcgWmhhbw0KPiBDYzog
bGludXgtd2lyZWxlc3NAdmdlci5rZXJuZWwub3JnOyBKb2huIFcuIExpbnZpbGxlOyBBbWl0a3Vt
YXIgS2Fyd2FyOyBLaXJhbiBEaXZla2FyOyBGcmFuayBIdWFuZw0KPiBTdWJqZWN0OiBSZTogW1BB
VENIIHYyXSBtd2lmaWV4OiByZW1vdmUgbGlua2VkIGxpc3QgaW1wbGVtZW50YXRpb24NCj4gDQo+
IE9uIFdlZCwgMjAxMS0wMS0xMiBhdCAyMToxNiAtMDgwMCwgQmluZyBaaGFvIHdyb3RlOg0KPiAN
Cj4gQmV0dGVyLA0KPiANCj4gPiArCWxpc3RfZGVsKChzdHJ1Y3QgbGlzdF9oZWFkICopIHR4X2Jh
X3Rzcl90YmwpOw0KPiANCj4gYnV0IHlvdSBzaG91bGRuJ3QgYmUgY2FzdGluZyBhdCBhbGwuIERv
IGxpc3RfZGVsKCZ0eF9iYV90c3JfdGJsLT5saXN0KTsNCj4gb3Igc28gaW5zdGVhZCwgc28gdGhh
dCB0aGlzIHdvcmtzIHdoZW4gdGhlIGxpc3RfaGVhZCBpc24ndCB0aGUgZmlyc3QNCj4gaXRlbSBp
biB0aGUgc3RydWN0Lg0KDQpUaGFua3MgYSBsb3QgZm9yIHlvdXIgY29tbWVudHMuIFdpbGwgcmVt
b3ZlIHRoZSBjYXN0aW5nLg0KDQo+IA0KPiA+IC0JbXdpZmlleF91dGlsX2luaXRfbGlzdCgoc3Ry
dWN0IG13aWZpZXhfbGlua2VkX2xpc3QgKikgJnByaXYtPg0KPiA+IC0JCQkgICAgICAgdHhfYmFf
c3RyZWFtX3RibF9wdHIpOw0KPiA+ICsJSU5JVF9MSVNUX0hFQUQoKHN0cnVjdCBsaXN0X2hlYWQg
KikgJnByaXYtPnR4X2JhX3N0cmVhbV90YmxfcHRyKTsNCj4gDQo+IFNhbWUgaGVyZS4gVHJ5IHRv
IGdldCByaWQgb2YgYWxsIGNhc3RzLiBJZiB5b3UgaGF2ZSBhbnkgc3BlY2lmaWMgb25lcw0KPiB0
aGF0IHlvdSBkb24ndCBrbm93IGhvdyB0byBnZXQgcmlkIG9mLCBmZWVsIGZyZWUgdG8gYXNrLg0K
PiANCj4gPiAtCXdoaWxlIChyYV9saXN0ICE9IChzdHJ1Y3QgbXdpZmlleF9yYV9saXN0X3RibCAq
KSByYV9saXN0X2hoZWFkKSB7DQo+ID4gLQkJaWYgKG13aWZpZXhfdXRpbF9wZWVrX2xpc3QoJnJh
X2xpc3QtPmJ1Zl9oZWFkLCB0cnVlKSkNCj4gPiArCWludCBpc19saXN0X2VtcHR5Ow0KPiA+ICsJ
dW5zaWduZWQgbG9uZyBmbGFnczsNCj4gPiArDQo+ID4gKwlsaXN0X2Zvcl9lYWNoX2VudHJ5KHJh
X2xpc3QsIHJhX2xpc3RfaGhlYWQsIGxpc3QpIHsNCj4gPiArCQlzcGluX2xvY2tfaXJxc2F2ZSgm
cmFfbGlzdC0+cmFfbGlzdF90YmxfbG9jaywgZmxhZ3MpOw0KPiA+ICsJCWlzX2xpc3RfZW1wdHkg
PSBsaXN0X2VtcHR5KCZyYV9saXN0LT5idWZfaGVhZCk7DQo+ID4gKwkJc3Bpbl91bmxvY2tfaXJx
cmVzdG9yZSgmcmFfbGlzdC0+cmFfbGlzdF90YmxfbG9jaywgZmxhZ3MpOw0KPiA+ICsJCWlmICgh
aXNfbGlzdF9lbXB0eSkNCj4gPiAgCQkJcmV0dXJuIGZhbHNlOw0KPiA+IC0NCj4gPiAtCQlyYV9s
aXN0ID0gKHN0cnVjdCBtd2lmaWV4X3JhX2xpc3RfdGJsICopIHJhX2xpc3QtPm5leHQ7DQo+ID4g
IAl9DQo+IA0KPiBUaGlzIHNlZW1zIHJhdGhlciBkdWJpb3VzLiBJZiB0aGUgbGlzdCBpcyBlbXB0
eSwgdGhlIGZvcl9lYWNoX2VudHJ5DQo+IHdvbid0IGRvIGFueXRoaW5nPyBPciBpcyB0aGF0IHNv
bWUgb3RoZXIgbGlzdD8NCg0KT24gZWFjaCBlbnRyeSBvZiB0aGUgbGlzdCwgd2UgZG8gZW1wdHkg
Y2hlY2sgZm9yIGFub3RoZXIgbGlzdCAiYnVmX2hlYWQiLg0KVGhlIHN0cnVjdHVyZSBsb29rcyBs
aWtlIHRoaXM6DQoNCnN0cnVjdCBtd2lmaWV4X3JhX2xpc3RfdGJsIHsNCiAgICAgICAgc3RydWN0
IGxpc3RfaGVhZCBsaXN0Ow0KICAgICAgICBzdHJ1Y3QgbGlzdF9oZWFkIGJ1Zl9oZWFkOw0KICAg
ICAgICAvKiBzcGluIGxvY2sgZm9yIHJhIGxpc3QgdGFibGUgKi8NCiAgICAgICAgc3BpbmxvY2tf
dCByYV9saXN0X3RibF9sb2NrOw0KDQoJICAuLi4uLi4NCn07DQoNClRoYW5rcywNCg0KQmluZw0K
DQo+IA0KPiBqb2hhbm5lcw0KDQo=
^ permalink raw reply
* Re: Question on deauth, reason 4, for hostapd.
From: Ben Greear @ 2011-01-13 20:13 UTC (permalink / raw)
To: hostap, linux-wireless@vger.kernel.org
In-Reply-To: <4D2F56DB.50507@candelatech.com>
On 01/13/2011 11:47 AM, Ben Greear wrote:
> I'm trying to figure out why my stations sometimes deauth for
> reason 4 (which I understand to mean 'inactivity').
>
> I instrumented the hostapd logs a bit, and I see this the output
> below. Basically, there appears to be no inactivity problems, and
> as far as I can tell, hostapd isn't forcing the deauth, but is rather
> dealing with it from somewhere else.
Ahh, seems the client side is giving up.
sta6: detected beacon loss from AP - sending probe request
sta7: detected beacon loss from AP - sending probe request
sta8: detected beacon loss from AP - sending probe request
ieee80211 wiphy0: sta10: No ack for nullfunc frame to AP 00:99:99:99:99:01, try 1
net_ratelimit: 200 callbacks suppressed
wlan0: detected beacon loss from AP - sending probe request
sta0: detected beacon loss from AP - sending probe request
sta1: detected beacon loss from AP - sending probe request
sta2: detected beacon loss from AP - sending probe request
sta3: detected beacon loss from AP - sending probe request
sta4: detected beacon loss from AP - sending probe request
sta5: detected beacon loss from AP - sending probe request
sta6: detected beacon loss from AP - sending probe request
sta7: detected beacon loss from AP - sending probe request
sta8: detected beacon loss from AP - sending probe request
ieee80211 wiphy0: sta10: Failed to send nullfunc to AP 00:99:99:99:99:01 after 500ms, disconnecting.
ieee80211 wiphy0: Removed STA 00:99:99:99:99:01
ieee80211 wiphy0: Destroyed STA 00:99:99:99:99:01
start_sw_scan: running-other-vifs: 0 running-station-vifs: 70, associated-stations: 69 scanning current channel: 2437 MHz
sta10: authenticate with 00:99:99:99:99:01 (try 1)
sta10: authenticated
sta10: associate with 00:99:99:99:99:01 (try 1)
sta10: RX ReassocResp from 00:99:99:99:99:01 (capab=0x411 status=0 aid=60)
sta10: associated
ieee80211 wiphy0: Allocated STA 00:99:99:99:99:01
ieee80211 wiphy0: Inserted STA 00:99:99:99:99:01
net_ratelimit: 76 callbacks suppressed
wlan0: detected beacon loss from AP - sending probe request
sta0: detected beacon loss from AP - sending probe request
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Compat-wireless release for 2011-01-13 is baked
From: Compat-wireless cronjob account @ 2011-01-13 20:07 UTC (permalink / raw)
To: linux-wireless
>From git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/compat-wireless-2.6
f236b99..6b436a1 linux-2.6.37.y -> origin/linux-2.6.37.y
69ec1f8..8db1608 master -> origin/master
* [new tag] compat-wireless-v2.6.37-4 -> compat-wireless-v2.6.37-4
>From git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/compat
7010ed0..6e82f90 linux-2.6.37.y -> origin/linux-2.6.37.y
* [new tag] v2.6.37-1 -> v2.6.37-1
* [new tag] v2.6.37-rc1-1 -> v2.6.37-rc1-1
>From git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next
4e7a997..8d4d54a history -> origin/history
+ 4df1d0b...c698755 master -> origin/master (forced update)
7bc4a4c..f878133 stable -> origin/stable
* [new tag] next-20110113 -> next-20110113
compat-wireless code metrics
782547 - Total upstream lines of code being pulled
2103 - backport code changes
1843 - backport code additions
260 - backport code deletions
7279 - backport from compat module
9382 - total backport code
1.1989 - % of code consists of backport work
1531 - Crap changes not yet posted
1488 - Crap additions not yet posted
43 - Crap deletions not yet posted
0.1956 - % of crap code
Base tree: linux-next.git
Base tree version: next-20110113
compat-wireless release: compat-wireless-2011-01-06-3-g8db1608-pc
^ permalink raw reply
* Question on deauth, reason 4, for hostapd.
From: Ben Greear @ 2011-01-13 19:47 UTC (permalink / raw)
To: hostap, linux-wireless@vger.kernel.org
I'm trying to figure out why my stations sometimes deauth for
reason 4 (which I understand to mean 'inactivity').
I instrumented the hostapd logs a bit, and I see this the output
below. Basically, there appears to be no inactivity problems, and
as far as I can tell, hostapd isn't forcing the deauth, but is rather
dealing with it from somewhere else.
This is on latest wireless-testing, with ath9k as both VAP and Stations.
Any ideas for where to look?
1294947307.409263: vap0: Station: 00:0c:42:61:00:1c has been active 0 sec ago
1294947307.409932: vap0: Station: 00:0c:42:61:00:1b has been active 0 sec ago
1294947307.412581: vap0: Station: 00:0c:42:61:00:1a has been active 0 sec ago
1294947307.413316: vap0: Station: 00:0c:42:61:00:19 has been active 0 sec ago
1294947307.417073: vap0: Station: 00:0c:42:61:00:18 has been active 0 sec ago
1294947307.417753: vap0: Station: 00:0c:42:61:00:17 has been active 0 sec ago
1294947307.418725: vap0: Station: 00:0c:42:61:00:16 has been active 0 sec ago
1294947307.421179: vap0: Station: 00:0c:42:61:00:15 has been active 0 sec ago
1294947307.423661: vap0: Station: 00:0c:42:61:00:14 has been active 0 sec ago
1294947307.424647: vap0: Station: 00:0c:42:61:00:13 has been active 0 sec ago
1294947307.428565: vap0: Station: 00:0c:42:61:00:12 has been active 0 sec ago
1294947307.431005: vap0: Station: 00:0c:42:61:00:11 has been active 0 sec ago
1294947307.431826: vap0: Station: 00:0c:42:61:00:10 has been active 0 sec ago
1294947307.434342: vap0: Station: 00:0c:42:61:00:0f has been active 0 sec ago
1294947307.435146: vap0: Station: 00:0c:42:61:00:0e has been active 0 sec ago
1294947307.442511: vap0: Station: 00:0c:42:61:00:0d has been active 0 sec ago
1294947307.443336: vap0: Station: 00:0c:42:61:00:0c has been active 0 sec ago
1294947307.445830: vap0: Station: 00:0c:42:61:00:0b has been active 0 sec ago
1294947307.446537: vap0: Station: 00:0c:42:61:00:0a has been active 0 sec ago
1294947307.449161: vap0: Station: 00:0c:42:61:00:09 has been active 0 sec ago
1294947307.450024: vap0: Station: 00:0c:42:61:00:08 has been active 0 sec ago
1294947307.455319: vap0: Station: 00:0c:42:61:00:07 has been active 0 sec ago
1294947307.562973: vap0: Station: 00:0c:42:61:cf:85 has been active 0 sec ago
1294947314.245006: vap0: Station: 00:0c:42:61:00:03 has been active 0 sec ago
1294947314.245214: vap0: Station: 00:0c:42:61:00:05 has been active 0 sec ago
1294947322.175976: vap0: Station: 00:0c:42:61:00:2e has been active 0 sec ago
1294947325.635492: vap0: Station: 00:0c:42:61:00:2f has been active 0 sec ago
1294947327.247077: vap0: Station: 00:76:56:76:01:03 has been active 0 sec ago
1294947374.830568: vap0: Station: 00:0c:42:61:00:02 has been active 0 sec ago
1294947577.430357: vap0: mgmt::deauth
1294947577.430418: vap0: deauthentication: STA=00:0c:42:61:00:1c reason_code=4
1294947577.430435: vap0: AP-STA-DISCONNECTED 00:0c:42:61:00:1c
1294947577.430473: 1294947577.430508: vap0: wpa_driver_nl80211_set_key: ifindex=15 alg=0 addr=0x95ab720 key_idx=0 set_tx=1 seq_len=0 key_len=0
1294947577.430527: vap0: addr=00:0c:42:61:00:1c
The station machine has these wifi events printed:
2011-01-13 11:39:37.440 sta27 (phy #0): deauth 00:0c:42:61:00:1c -> 00:99:99:99:99:01 reason 4: Disassociated due to inactivity
2011-01-13 11:39:37.440 sta27 (phy #0): disconnected (local request)
2011-01-13 11:39:37.546 sta27 (phy #0): scan started
2011-01-13 11:39:37.743 sta27 (phy #0): scan finished: 2437, ""
2011-01-13 11:39:37.985 sta27 (phy #0): auth 00:99:99:99:99:01 -> 00:0c:42:61:00:1c status: 0: Successful
2011-01-13 11:39:38.003 sta27: new station 00:99:99:99:99:01
2011-01-13 11:39:38.145 sta27 (phy #0): assoc 00:99:99:99:99:01 -> 00:0c:42:61:00:1c status: 0: Successful
2011-01-13 11:39:38.145 sta27 (phy #0): connected to 00:99:99:99:99:01
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [RFC] ath9k: Handle interface changes properly
From: Felix Fietkau @ 2011-01-13 16:49 UTC (permalink / raw)
To: Rajkumar Manoharan; +Cc: Björn Smedman, linux-wireless@vger.kernel.org
In-Reply-To: <20110113163513.GA9291@vmraj-lnx.users.atheros.com>
On 2011-01-13 5:35 PM, Rajkumar Manoharan wrote:
> On Thu, Jan 13, 2011 at 07:53:27PM +0530, Felix Fietkau wrote:
>> On 2011-01-13 6:18 AM, Rajkumar Manoharan wrote:
>> > On Thu, Jan 13, 2011 at 01:21:47AM +0530, Felix Fietkau wrote:
>> >> On 2011-01-12 10:06 AM, Björn Smedman wrote:
>> >> > On Wed, Jan 12, 2011 at 3:30 PM, Rajkumar Manoharan
>> >> > <rmanoharan@atheros.com> wrote:
>> >> >> The commit ""ath9k: Add change_interface callback" was failed
>> >> >> to update of hw opmode, ani and interrupt mask. This leads
>> >> >> to break p2p functionality on ath9k. And the existing add and
>> >> >> remove interface functions are not handling hw opmode and
>> >> >> ANI properly.
>> >> >>
>> >> >> This patch combines the common code in interface callbacks
>> >> >> and also takes care of multi-vif cases.
>> >> >
>> >> > How does your patch handle the race condition between the interface
>> >> > change done in process context and the beacon tasklet triggered by
>> >> > SWBA?
>> >> >
>> >> > Also, perhaps more applicable to the commit log than the patch, how
>> >> > can opmode be properly handled in multi-vif cases? I mean let's say I
>> >> > have two AP vifs and then change one into STA, is the opmode then STA?
>> >> > Compare that to the case where I have two STA vifs and change one into
>> >> > AP; so again I have one AP and one STA vif but this time opmode is AP,
>> >> > right? I can see how I can be wrong about these examples but I can't
>> >> > really see how the opmode concept can be properly handled in multi-vif
>> >> > cases.
>> >> I think opmode should be handled as follows:
>> >> If there is at least one AP interface, opmode should be AP, regardless
>> >> of what the other interfaces are set to.
>> >> If there is no AP vif, opmode can be set to the primary vif type.
>> >>
>> > Correct. this RFC patch does the same.
>> Really? I don't see that being handled properly, it still seems to
>> overwrite ah->opmode based on a single vif type for some types.
>> Also, there is no reason to have a WDS opmode in ath9k_hw. WDS is
>> typically used along with AP mode interfaces, and where it is not, the
>> AP opmode should be used for ath9k_hw anyway.
> Instead of setting opmde as AP for WDS, it is better to handle WDS
> case in ath9k_hw.
Why? Right now I don't even see any NL80211_IFTYPE_WDS handling in
ath9k_hw, and I can't think of anything that should be handled
differently in ath9k_hw compared to the AP opmode.
>> Maybe it would be a good idea to clean this up and first limit the
>> number of different types that we pass to ath9k_hw (i.e. only AP, ADHOC,
>> STA). Later we can make a separate enum for that to avoid passing the
>> type as-is entirely.
> Just to stick with the currently supported interfaces list, WDS also included.
>> I think the mesh point opmode has no place in ath9k_hw. Right now it is
>> treated like ad-hoc, but I think that's completely wrong. Mesh should
>> behave just like AP mode, as no ad-hoc style TSF synchronization should
>> be done by the hardware, and 802.11s mesh nodes do not compete for
>> beacon transmission.
> This is a different issue and it has to be addressed in separate patch.
I agree.
- Felix
^ permalink raw reply
* Re: [RFC] ath9k: Handle interface changes properly
From: Rajkumar Manoharan @ 2011-01-13 16:35 UTC (permalink / raw)
To: Felix Fietkau
Cc: Rajkumar Manoharan, Björn Smedman,
linux-wireless@vger.kernel.org
In-Reply-To: <4D2F0ADF.1040009@openwrt.org>
On Thu, Jan 13, 2011 at 07:53:27PM +0530, Felix Fietkau wrote:
> On 2011-01-13 6:18 AM, Rajkumar Manoharan wrote:
> > On Thu, Jan 13, 2011 at 01:21:47AM +0530, Felix Fietkau wrote:
> >> On 2011-01-12 10:06 AM, Björn Smedman wrote:
> >> > On Wed, Jan 12, 2011 at 3:30 PM, Rajkumar Manoharan
> >> > <rmanoharan@atheros.com> wrote:
> >> >> The commit ""ath9k: Add change_interface callback" was failed
> >> >> to update of hw opmode, ani and interrupt mask. This leads
> >> >> to break p2p functionality on ath9k. And the existing add and
> >> >> remove interface functions are not handling hw opmode and
> >> >> ANI properly.
> >> >>
> >> >> This patch combines the common code in interface callbacks
> >> >> and also takes care of multi-vif cases.
> >> >
> >> > How does your patch handle the race condition between the interface
> >> > change done in process context and the beacon tasklet triggered by
> >> > SWBA?
> >> >
> >> > Also, perhaps more applicable to the commit log than the patch, how
> >> > can opmode be properly handled in multi-vif cases? I mean let's say I
> >> > have two AP vifs and then change one into STA, is the opmode then STA?
> >> > Compare that to the case where I have two STA vifs and change one into
> >> > AP; so again I have one AP and one STA vif but this time opmode is AP,
> >> > right? I can see how I can be wrong about these examples but I can't
> >> > really see how the opmode concept can be properly handled in multi-vif
> >> > cases.
> >> I think opmode should be handled as follows:
> >> If there is at least one AP interface, opmode should be AP, regardless
> >> of what the other interfaces are set to.
> >> If there is no AP vif, opmode can be set to the primary vif type.
> >>
> > Correct. this RFC patch does the same.
> Really? I don't see that being handled properly, it still seems to
> overwrite ah->opmode based on a single vif type for some types.
> Also, there is no reason to have a WDS opmode in ath9k_hw. WDS is
> typically used along with AP mode interfaces, and where it is not, the
> AP opmode should be used for ath9k_hw anyway.
Instead of setting opmde as AP for WDS, it is better to handle WDS
case in ath9k_hw.
> Maybe it would be a good idea to clean this up and first limit the
> number of different types that we pass to ath9k_hw (i.e. only AP, ADHOC,
> STA). Later we can make a separate enum for that to avoid passing the
> type as-is entirely.
Just to stick with the currently supported interfaces list, WDS also included.
> I think the mesh point opmode has no place in ath9k_hw. Right now it is
> treated like ad-hoc, but I think that's completely wrong. Mesh should
> behave just like AP mode, as no ad-hoc style TSF synchronization should
> be done by the hardware, and 802.11s mesh nodes do not compete for
> beacon transmission.
This is a different issue and it has to be addressed in separate patch.
--
Rajkumar
^ permalink raw reply
* RE: What pieces are needed for wl1271..what directories, files, configs, etc..
From: Brzezowski, Karen @ 2011-01-13 16:11 UTC (permalink / raw)
To: Krakowski, Oz; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <AANLkTikgPPvQP7QP5_EvBQapZ78nbcZs51mFPDKBDRoz@mail.gmail.com>
Hi Oz, and Luca, and... !
I'm looking at the
following wiki page: http://linuxwireless.org/en/users/Drivers/wl12xx
the attempt to port your wl1271 driver to our 2.6.31 Linux kernel for
freescale iMX233.
I downloaded the latest driver:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
and the firmware:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git
I am now looking at the:
Porting wl12xx:
Porting the wl12xx driver to a new hardware platform requires following these steps:
1.Modify or create the board-specific configuration. An example on how this should be done can be found under arch/arm/mach-omap2/board-zoom-peripherals.c for the TI Zoom reference boards. This is where you need to set the right mmc port, assign the gpios, adjust the reference clock information, etc.
>>>>>>>> The first arch/arm/mach-omap2/board-zoom-peripherals.c that has any mention of wl12xx is 2.6.37... is this the correct version to look at on what to do for the wl1271 in the arm/arch/mach-mx23 in my case?? I see a couple little things with wl1271 in this file....
not sure what it means....is there any explanation anywhere, and am I doing the right thing?
THANK YOU!
Karen
From: Krakowski, Oz [ozk@ti.com]
Sent: Tuesday, January 11, 2011 8:53 PM
To: Brzezowski, Karen
Cc: linux-wireless@vger.kernel.org
Subject: Re: What pieces are needed for wl1271..what directories, files, configs, etc..
On Tue, Jan 11, 2011 at 1:41 PM, Brzezowski, Karen
<Karen.Brzezowski@pdt.com> wrote:
> ok, so far, I found the Makefile in the wl12xx directory from git clone git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git has 2.6.37-rc6
> in it. so it's the 37-rc6 kernel, correct?
Yes.
>
> Can I use this "stuff" in the 2.6.31 kernel? (I know what's said in the wiki info below..)
Yes, as long as you follow the guidelines described in the wiki page
regarding how to port the driver to older kernel versions - through
compat-wirelss and the additional patches described there.
Compat-wireless is described on the linuxwireless.org website in
length. Check it out here:
http://linuxwireless.org/en/users/Download/stable/
Regards,
Oz.
>
> I just don't know what goes where, how...
>
> :-)
> ________________________________________
> From: linux-wireless-owner@vger.kernel.org [linux-wireless-owner@vger.kernel.org] on behalf of Brzezowski, Karen [Karen.Brzezowski@pdt.com]
> Sent: Tuesday, January 11, 2011 1:05 PM
> To: Krakowski, Oz
> Cc: linux-wireless@vger.kernel.org
> Subject: RE: What pieces are needed for wl1271..what directories, files, configs, etc..
>
> Hi Oz,
>
> Thank you for your response. I have been looking at that web page:
> http://linuxwireless.org/en/users/Drivers/wl12xx
>
> when i get the latest driver at
> git clone git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
>
> Do I take everything that comes in this compressed file and replace it in a Linux kernel?
> Which Linux kernel is this driver code for?
>
> I'm not really sure what the compat-wireless is...we are using the Linux 2.6.31 kernel
> Do I need to get compat-wireless somehow for the 31 kernel?
>
> Then the notes say integrations needs to be gotten for SDIO, Lenient, and platform data pasing..
>
> Then the notes say I need WL127x firmware...
>
> after all that I can build the kernel?
>
> Do you have any example code that uses the interfaces for the wl1271 chip (the APIs)?
>
> I've never ported a driver in Linux before...
> I assumed all it would be is to get the driver directory corresponding to the new chip, adding or replacing it
> in the drivers directory, build it, and voila, i have a driver to test..
>
> I think I should not have assumed that, correct?
>
> ...this is why I'm confused........
> :-)
> thank you for your time!!!!!!!!!!
> Karen
>
> ________________________________________
> From: linux-wireless-owner@vger.kernel.org [linux-wireless-owner@vger.kernel.org] on behalf of Krakowski, Oz [ozk@ti.com]
> Sent: Tuesday, January 11, 2011 12:13 AM
> To: Brzezowski, Karen
> Cc: linux-wireless@vger.kernel.org
> Subject: Re: What pieces are needed for wl1271..what directories, files, configs, etc..
>
> Hi Karen,
>
> On Mon, Jan 10, 2011 at 10:44 AM, Brzezowski, Karen
> <Karen.Brzezowski@pdt.com> wrote:
>>
>> Hello all wireless gurus!!
>>
>> I've been watching the linux-wireless mailings on the wl1271...........
>>
>> I've been trying to figure out how to get the wl1271 working with
>> imx233 processor...
>>
>> I think we are moving to Linux 2.6.35 and android gingerbread (2.3)...
>>
>> I"m very confused as to what files/configs/etc..need to be grabbed to get my task going.......
>>
>> I see spi, sdio...not sure where all changes are made for the wl1271...i'm assuming
>> not just in the ...net/wireless/wl1271 directory.......... i have firmware too...........(.bins..)
>>
>> I'm quite confused about the chip and how each part will work (BT, WLAN, and FM)...
>> Do you have any documentation..(for dummies, that would be me!)
>> that would help me understand about the chip..how it communicates to the processor,
>> how it does it's job with respect to BT, WLAN, and FM, etc..
>>
>> I have NO idea where to begin.......I've been googling and reading and I have downloaded
>> your wl12xx git........
>
> If you haven't done so already, suggest you start by going through the
> following wiki page: http://linuxwireless.org/en/users/Drivers/wl12xx
> This should give you an idea of where to get the latest code, how to
> compile it to your kernel (using compat-wireless) and links to the
> relevant patches needed.
> This will get you started with WLAN.
>
>>
>> If you can help me AT ALL to get me up to speed/ to start, what i need to do to connect
>> the wl1271 to the imx233....if not imx233..that whatever you have........
>
> The wiki page does include some basic information needed in order to
> port to different hardware platforms.
>
> Regards,
> Oz.
> --
> 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
> --
> 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: [RFC] ath9k: Handle interface changes properly
From: Felix Fietkau @ 2011-01-13 14:23 UTC (permalink / raw)
To: Rajkumar Manoharan; +Cc: Björn Smedman, linux-wireless@vger.kernel.org
In-Reply-To: <20110113051849.GD8836@vmraj-lnx.users.atheros.com>
On 2011-01-13 6:18 AM, Rajkumar Manoharan wrote:
> On Thu, Jan 13, 2011 at 01:21:47AM +0530, Felix Fietkau wrote:
>> On 2011-01-12 10:06 AM, Björn Smedman wrote:
>> > On Wed, Jan 12, 2011 at 3:30 PM, Rajkumar Manoharan
>> > <rmanoharan@atheros.com> wrote:
>> >> The commit ""ath9k: Add change_interface callback" was failed
>> >> to update of hw opmode, ani and interrupt mask. This leads
>> >> to break p2p functionality on ath9k. And the existing add and
>> >> remove interface functions are not handling hw opmode and
>> >> ANI properly.
>> >>
>> >> This patch combines the common code in interface callbacks
>> >> and also takes care of multi-vif cases.
>> >
>> > How does your patch handle the race condition between the interface
>> > change done in process context and the beacon tasklet triggered by
>> > SWBA?
>> >
>> > Also, perhaps more applicable to the commit log than the patch, how
>> > can opmode be properly handled in multi-vif cases? I mean let's say I
>> > have two AP vifs and then change one into STA, is the opmode then STA?
>> > Compare that to the case where I have two STA vifs and change one into
>> > AP; so again I have one AP and one STA vif but this time opmode is AP,
>> > right? I can see how I can be wrong about these examples but I can't
>> > really see how the opmode concept can be properly handled in multi-vif
>> > cases.
>> I think opmode should be handled as follows:
>> If there is at least one AP interface, opmode should be AP, regardless
>> of what the other interfaces are set to.
>> If there is no AP vif, opmode can be set to the primary vif type.
>>
> Correct. this RFC patch does the same.
Really? I don't see that being handled properly, it still seems to
overwrite ah->opmode based on a single vif type for some types.
Maybe it would be a good idea to clean this up and first limit the
number of different types that we pass to ath9k_hw (i.e. only AP, ADHOC,
STA). Later we can make a separate enum for that to avoid passing the
type as-is entirely.
I think the mesh point opmode has no place in ath9k_hw. Right now it is
treated like ad-hoc, but I think that's completely wrong. Mesh should
behave just like AP mode, as no ad-hoc style TSF synchronization should
be done by the hardware, and 802.11s mesh nodes do not compete for
beacon transmission.
Also, there is no reason to have a WDS opmode in ath9k_hw. WDS is
typically used along with AP mode interfaces, and where it is not, the
AP opmode should be used for ath9k_hw anyway.
- Felix
^ permalink raw reply
* Re: BUG in rt2x00lib_txdone() with 2.6.37-rc8
From: Helmut Schaa @ 2011-01-13 13:23 UTC (permalink / raw)
To: Ivo Van Doorn; +Cc: Ingo Brunberg, linux-kernel, linux-wireless
In-Reply-To: <m31v4hkmkf.fsf@ingo.homenetwork>
Hi,
Am Donnerstag, 13. Januar 2011 schrieb Ingo Brunberg:
> I also suffer from this bug with 2.6.37. The first time the following
> trace made it into my logs. Hopefully it might help.
Thanks for the trace!
> BUG: unable to handle kernel NULL pointer dereference at 0000000000000090
> IP: [<ffffffffa00983e4>] rt2x00lib_txdone+0x31/0x259 [rt2x00lib]
> PGD a7011067 PUD ab9b2067 PMD 0
> Oops: 0000 [#1] SMP
> last sysfs file: /sys/devices/pci0000:00/0000:00:13.2/usb2/2-3/2-3.4/2-3.4:1.0/firmware/2-3.4:1.0/loading
> CPU 3
> Modules linked in: aes_generic af_packet w83627ehf hwmon_vid ipv6 fbcon font bitblit softcursor dm_mod arc4 ecb crypto_blkcipher cryptomgr aead crypto_algapi rt73usb rt2x00usb rt2x00lib mac80211 cfg80211 usbhid hid radeon snd_hda_codec_realtek ttm r8169 drm_kms_helper sr_mod drm cdrom firewire_ohci snd_hda_intel i2c_piix4 bitrev 8250_pnp processor snd_hda_codec ohci_hcd thermal_sys ehci_hcd usbcore crc32 8250 i2c_algo_bit firewire_core i2c_core sg pata_atiixp crc_itu_t rtc button k10temp evdev hwmon snd_pcm snd_timer cfbcopyarea cfbimgblt snd floppy cfbfillrect serial_core mii nls_base soundcore snd_page_alloc
>
> Pid: 3069, comm: kworker/3:0 Not tainted 2.6.37 #1 M3A785GXH/128M/To Be Filled By O.E.M.
> RIP: 0010:[<ffffffffa00983e4>] [<ffffffffa00983e4>] rt2x00lib_txdone+0x31/0x259 [rt2x00lib]
> RSP: 0018:ffff880094ad3d30 EFLAGS: 00010286
> RAX: 0000000000000030 RBX: ffff88011df79980 RCX: 0000000000000014
> RDX: 0000000000000101 RSI: ffff880094ad3d90 RDI: 0000000000000000
> RBP: ffff88011ec37af8 R08: 0000000000000002 R09: ffffffff00000002
> R10: 0000000000000286 R11: 0000000000000000 R12: 0000000000000000
> R13: 0000000000000028 R14: ffff880094ad3d90 R15: ffff88011df79c10
> FS: 00007fc5bad23710(0000) GS:ffff8800cfd80000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> CR2: 0000000000000090 CR3: 00000000ab985000 CR4: 00000000000006e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Process kworker/3:0 (pid: 3069, threadinfo ffff880094ad2000, task ffff88011ff08b20)
> Stack:
> ffff88011fc7e420 0000000000011000 0000000000000030 0000000000004000
> ffff88011ec37af8 ffff88011dcb3af0 ffff88011df79980 ffff88011dcb3b40
> ffff88011dcb3b40 0000000000000003 ffff88011df79c10 ffffffffa009862e
> Call Trace:
> [<ffffffffa009862e>] ? rt2x00lib_txdone_noinfo+0x22/0x27 [rt2x00lib]
> [<ffffffffa0016316>] ? rt2x00usb_work_txdone+0x3e/0x6d [rt2x00usb]
> [<ffffffffa0016a0d>] ? rt2x00usb_watchdog+0x69/0xe0 [rt2x00usb]
> [<ffffffffa009aed9>] ? rt2x00link_watchdog+0x0/0x4a [rt2x00lib]
> [<ffffffffa009af00>] ? rt2x00link_watchdog+0x27/0x4a [rt2x00lib]
> [<ffffffff8104256e>] ? process_one_work+0x20e/0x34e
> [<ffffffff81042a45>] ? worker_thread+0x1c9/0x340
> [<ffffffff8102612e>] ? __wake_up_common+0x41/0x78
> [<ffffffff8104287c>] ? worker_thread+0x0/0x340
> [<ffffffff8104287c>] ? worker_thread+0x0/0x340
> [<ffffffff810455a9>] ? kthread+0x7a/0x82
> [<ffffffff81002cd4>] ? kernel_thread_helper+0x4/0x10
> [<ffffffff8104552f>] ? kthread+0x0/0x82
> [<ffffffff81002cd0>] ? kernel_thread_helper+0x0/0x10
> Code: f6 41 55 41 54 55 48 89 fd 53 48 83 ec 28 4c 8b 67 10 48 8b 47 08 48 8b 18 49 8d 44 24 30 4c 89 e7 4d 8d 6c 24 28 48 89 44 24 10 <41> 8b 94 24 90 00 00 00 66 89 54 24 1e e8 1b 16 14 00 48 89 ef
> RIP [<ffffffffa00983e4>] rt2x00lib_txdone+0x31/0x259 [rt2x00lib]
> RSP <ffff880094ad3d30>
> CR2: 0000000000000090
> ---[ end trace 2c6843a38ee68ff0 ]---
Just a shot in the dark but since the stack trace shows the newly added
watchdog this might be the result of a race between a regular txdone work
(mac80211 workqueue) vs the watchdog work (global workqueue).
I guess the following situation could happen:
A regular tx done work calls rt2x00lib_txdone which first sets entry->skb to
NULL, calls the driver specific clear_entry and afterwards increases
Q_INDEX_DONE. If the watchdog work calls rt2x00lib_txdone on a different CPU
inbetween the skb might be NULL and cause the above oops.
Ivo, does that sound reasonable?
Helmut
^ permalink raw reply
* Re: [PATCH] wl12xx: change debug_level module param sysfs permissions
From: Luciano Coelho @ 2011-01-13 11:34 UTC (permalink / raw)
To: Guy Eilam; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1294824809-8364-1-git-send-email-guy@wizery.com>
On Wed, 2011-01-12 at 10:33 +0100, Guy Eilam wrote:
> changed the visibility of the debug_level module parameter
> in the filesystem to be readable and writable to the root user.
> It is now accessible under /sys/module/wl12xx/parameters
>
> removed the debug_level debugfs file that was created under
> /sys/kernel/debug/...
>
> Signed-off-by: Guy Eilam <guy@wizery.com>
> ---
Applied and pushed, thanks!
--
Cheers,
Luca.
^ permalink raw reply
* Re: [PATCH] wl12xx: don't modify the global supported band structures
From: Luciano Coelho @ 2011-01-13 11:33 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: arik@wizery.com, johannes@sipsolutions.net
In-Reply-To: <1294766718-2472-1-git-send-email-coelho@ti.com>
On Tue, 2011-01-11 at 18:25 +0100, Coelho, Luciano wrote:
> From: Luciano Coelho <coelho@ti.com>
>
> When 11a is not supported, we were modifying the global structure that
> contains the bands supported by the driver. This causes problems when
> having more one wl12xx device in the same system because they all use
> the same global. This also causes problems when the wl12xx_sdio
> module is removed and the wl12xx module remains.
>
> Fix this problem by copying the band structure into the wl12xx
> instance.
>
> Reported-by: Arik Nemtsov <arik@wizery.com>
> Reported-by: Johannes Berg <johannes@sipsolutions.net>
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---
Applied and pushed to the wl12xx tree.
--
Cheers,
Luca.
^ permalink raw reply
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