* 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
* Re: [PATCH] wl12xx: lock the RCU when accessing sta via ieee80211_find_sta()
From: Luciano Coelho @ 2011-01-13 11:33 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org; +Cc: DE CESCO, Jonathan
In-Reply-To: <1294769241-3118-1-git-send-email-coelho@ti.com>
On Tue, 2011-01-11 at 19:07 +0100, coelho@ti.com wrote:
> From: Luciano Coelho <coelho@ti.com>
>
> We were calling ieee80211_find_sta() and the sta returned by it
> without locking the RCU, which is required by mac80211.
>
> Fix this and reorganize slightly the area of the code where the sta is
> used.
>
> Reported-by: Jonathan DE CESCO <jonathanc@ti.com>
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---
Applied and pushed to wl12xx.
--
Cheers,
Luca.
^ permalink raw reply
* Re: [PATCH] wl12xx: don't join upon disassociation
From: Luciano Coelho @ 2011-01-13 11:33 UTC (permalink / raw)
To: Eliad Peller; +Cc: Luciano Coelho, linux-wireless@vger.kernel.org
In-Reply-To: <1293352070-17513-1-git-send-email-eliad@wizery.com>
On Sun, 2010-12-26 at 09:27 +0100, Eliad Peller wrote:
> wl12xx "rejoins" upon every BSS_CHANGED_BSSID notification.
> However, there is no need to rejoin after disassociation, so just
> filter out the case when the new bssid is 00:00:00:00:00:00.
>
> Signed-off-by: Eliad Peller <eliad@wizery.com>
> ---
Rebased to the latest tree and applied. Thank you!
--
Cheers,
Luca.
^ permalink raw reply
* Re: Mesh join/leave
From: Jouni Malinen @ 2011-01-13 10:50 UTC (permalink / raw)
To: Johannes Berg; +Cc: sbrown, linux-wireless@vger.kernel.org
In-Reply-To: <1294830768.3639.20.camel@jlt3.sipsolutions.net>
On Wed, Jan 12, 2011 at 12:12:48PM +0100, Johannes Berg wrote:
> > > Of course maybe mac80211 should be doings omething like this too:
> > > @@ -2299,6 +2299,11 @@ struct sk_buff *ieee80211_beacon_get_tim
> > > +#ifdef CONFIG_MAC80211_MESH
> > > + if (!sdata->u.mesh.mesh_id_len)
> > > + goto out;
> > > +#endif
> Yeah but evidently ath9k isn't cleanly stopping beaconing, it's still
> attempting to beacon but doesn't get a beacon from mac80211 so can't
> send one.
Sounds like SWBA interrupt should be disabled or at least masked in some
cases when mac80211 indicates some kind of change. I have not looked at
details on what exactly is missing from ath9k. Anyway, yes, it would be
good to make ieee80211_beacon_get_tim() return NULL when mac80211 does
not want any Beacon frames to be transmitted.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* Re: [PATCH v2] mwifiex: remove linked list implementation
From: Johannes Berg @ 2011-01-13 9:19 UTC (permalink / raw)
To: Bing Zhao
Cc: linux-wireless, John W. Linville, Amitkumar Karwar, Kiran Divekar,
Frank Huang
In-Reply-To: <1294895783-26539-1-git-send-email-bzhao@marvell.com>
On Wed, 2011-01-12 at 21:16 -0800, Bing Zhao wrote:
Better,
> + list_del((struct list_head *) tx_ba_tsr_tbl);
but you shouldn't be casting at all. Do list_del(&tx_ba_tsr_tbl->list);
or so instead, so that this works when the list_head isn't the first
item in the struct.
> - mwifiex_util_init_list((struct mwifiex_linked_list *) &priv->
> - tx_ba_stream_tbl_ptr);
> + INIT_LIST_HEAD((struct list_head *) &priv->tx_ba_stream_tbl_ptr);
Same here. Try to get rid of all casts. If you have any specific ones
that you don't know how to get rid of, feel free to ask.
> - 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;
> }
This seems rather dubious. If the list is empty, the for_each_entry
won't do anything? Or is that some other list?
johannes
^ permalink raw reply
* Re: [RFC] ath9k: Handle interface changes properly
From: Rajkumar Manoharan @ 2011-01-13 5:18 UTC (permalink / raw)
To: Felix Fietkau
Cc: Björn Smedman, Rajkumar Manoharan,
linux-wireless@vger.kernel.org
In-Reply-To: <4D2E0653.7040606@openwrt.org>
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.
--
Rajkumar
^ permalink raw reply
* Re: [RFC] ath9k: Handle interface changes properly
From: Rajkumar Manoharan @ 2011-01-13 5:16 UTC (permalink / raw)
To: Björn Smedman
Cc: Sujith, Rajkumar Manoharan, linux-wireless@vger.kernel.org
In-Reply-To: <AANLkTimK2AkRYnZk70TNt5YWEzNPCoPHpT=pu1B6JZPN@mail.gmail.com>
On Thu, Jan 13, 2011 at 12:30:03AM +0530, Björn Smedman wrote:
> 2011/1/12 Sujith <m.sujith@gmail.com>:
> > Björn Smedman wrote:
> >> 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.
> >
> > The opmode should be calculated every time an interface is created/destroyed.
> >
> > If an AP vif is already present when a STA is added, the opmode remains as AP.
> > if a STA vif is changed into AP mode, then the opmode should be changed to AP,
> > along with disabling PS for other STA interfaces.
> > If an AP is present and a STA is added, the beacon interval can't be different.
> > And there are a few other conditions as well...
>
> Thank you Sujith for the clarification. When you lay out the cases it
> makes more sense. But there are still border cases, like e.g. adding
> first a STA and then an AP interface. If I read main.c correctly the
> opmode will then be STA and the AP vif will be broken, right?
Yes. opmode is set to the type of first vif added. Thats wrong. I should
be changed on AP/IBSS type interface addtion.
> Wouldn't it be better to keep counts of number of vifs by type and
> e.g. activate SWBA if (adhocvifs > 0 || apvifs > 0) and similar? Then
> it wouldn't mater in which order vifs are added, removed and changed.
It is not necessary to keep counter for ap/adhoc vifs. instead of that,
I reused nbcnvifs counter.
--
Rajkumar
^ permalink raw reply
* [PATCH v2] mwifiex: remove linked list implementation
From: Bing Zhao @ 2011-01-13 5:16 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>
---
drivers/net/wireless/mwifiex/11n.c | 135 +++-----
drivers/net/wireless/mwifiex/11n.h | 19 +-
drivers/net/wireless/mwifiex/11n_aggr.c | 124 +++++---
drivers/net/wireless/mwifiex/11n_rxreorder.c | 54 ++--
drivers/net/wireless/mwifiex/cmdevt.c | 230 +++++++------
drivers/net/wireless/mwifiex/decl.h | 3 +-
drivers/net/wireless/mwifiex/init.c | 114 ++++---
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 | 452 ++++++++++++++------------
drivers/net/wireless/mwifiex/wmm.h | 37 ++-
16 files changed, 705 insertions(+), 792 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index b1fd5a9..14834ab 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((struct list_head *) tx_ba_tsr_tbl);
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((struct 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,16 @@ 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((struct list_head *) new_node);
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((struct list_head *) new_node,
+ &priv->tx_ba_stream_tbl_ptr);
+ spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
}
exit:
@@ -1376,23 +1345,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 +1375,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 +1393,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 +1415,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..ebd02c8 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((struct list_head *)mbuf_src);
+ } 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((struct list_head *) mbuf_aggr, &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..827011d 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((struct list_head *) rx_reor_tbl_ptr);
+ 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((struct list_head *) new_node);
new_node->tid = tid;
memcpy(new_node->ta, ta, MWIFIEX_MAC_ADDR_LENGTH);
new_node->start_win = seq_num;
@@ -342,9 +340,10 @@ 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((struct list_head *)new_node,
+ &priv->rx_reorder_tbl_ptr);
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
}
exit:
@@ -610,6 +609,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 +641,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 +749,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((struct 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..05b20d8 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((struct list_head *)cmd_node);
+ 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((struct list_head *) cmd_node, &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,14 @@ 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((struct list_head *) cmd_node,
+ &adapter->cmd_pending_q);
+ else
+ list_add((struct list_head *) cmd_node,
+ &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 +779,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 +798,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((struct list_head *) cmd_node);
+ 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 +1105,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 +1122,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((struct list_head *) cmd_node);
+ spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
if (cmd_node->ioctl_buf) {
ioctl_buf =
(struct mwifiex_ioctl_req *) cmd_node->
@@ -1130,18 +1138,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((struct list_head *) cmd_node);
+ 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 +1174,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 +1187,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((struct list_head *) cmd_node);
+ 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((struct list_head *) cmd_node);
+ 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..f5d6bbc 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((struct list_head *) bss_prio);
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((struct list_head *) bss_prio,
+ &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,41 @@ 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((struct list_head *)
+ bssprio_node);
+ 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..f4c4383 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((struct list_head *) cmd_node);
+ 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((struct list_head *) cmd_node);
+ 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((struct list_head *) cmd_node, &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..a6984f4 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((struct list_head *) cmd_node);
+ 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..ba35614 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((struct list_head *) ra_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((struct list_head *)ra_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;
@@ -553,18 +552,14 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
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);
-
+ while (!list_empty(&ra_list->buf_head)) {
+ mbuf = list_first_entry(&ra_list->buf_head,
+ struct mwifiex_buffer, list);
+ list_del((struct list_head *) mbuf);
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 +572,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();
}
@@ -629,20 +616,18 @@ mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv)
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);
-
+ while (!list_empty(&priv->wmm.tid_tbl_ptr[i].ra_list)) {
+ ra_list = list_first_entry(&priv->wmm.tid_tbl_ptr[i]
+ .ra_list,
+ struct mwifiex_ra_list_tbl,
+ list);
+ list_del((struct list_head *)ra_list);
kfree(ra_list);
}
- mwifiex_util_init_list((struct mwifiex_linked_list *)
- &priv->wmm.tid_tbl_ptr[i].ra_list);
+ INIT_LIST_HEAD((struct list_head *) &priv->wmm.tid_tbl_ptr[i]
+ .ra_list);
+
priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
}
@@ -658,22 +643,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 +694,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 +744,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 +767,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((struct list_head *) mbuf, &ra_list->buf_head);
ra_list->total_pkts_size += mbuf->data_len;
@@ -1016,22 +989,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 +1029,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 +1045,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 +1120,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 +1138,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 +1146,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((struct list_head *)mbuf);
+ 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((struct list_head *) mbuf, &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 +1236,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 +1254,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 +1262,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((struct list_head *)mbuf);
+ 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((struct list_head *) mbuf, &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: [RFC] ath9k: Handle interface changes properly
From: Rajkumar Manoharan @ 2011-01-13 5:10 UTC (permalink / raw)
To: Sujith
Cc: Björn Smedman, Rajkumar Manoharan,
linux-wireless@vger.kernel.org
In-Reply-To: <19757.58191.865301.805439@gargle.gargle.HOWL>
On Wed, Jan 12, 2011 at 10:52:23PM +0530, Sujith wrote:
> 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.
>
> The opmode should be calculated every time an interface is created/destroyed.
>
> If an AP vif is already present when a STA is added, the opmode remains as AP.
> if a STA vif is changed into AP mode, then the opmode should be changed to AP,
> along with disabling PS for other STA interfaces.
> If an AP is present and a STA is added, the beacon interval can't be different.
> And there are a few other conditions as well...
>
> And you are right, interface management is not protected with the beacon tasklet...
I dont see a race condition here because SWBA & beacon tasklet is disabled
before accessing beacon slot.
--
Rajkumar
^ permalink raw reply
* Re: [RFC] ath9k: Handle interface changes properly
From: Rajkumar Manoharan @ 2011-01-13 5:08 UTC (permalink / raw)
To: Björn Smedman; +Cc: Rajkumar Manoharan, linux-wireless@vger.kernel.org
In-Reply-To: <AANLkTi=S6TFk88cY27KFZ2q5mCykMMSn17LnH=V95MST@mail.gmail.com>
On Wed, Jan 12, 2011 at 10:36:28PM +0530, 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?
If you look at the patch, while removing/changing AP/IBSS interface,
SWBA interrupt was disabled and beacon tasklet is killed before
releasing beacon slot. The SWBA will enabled again in the presence
of beaconing interface.
>
> 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?
If you have any AP vifs, then opmode will always be AP type. STA mode
will be set only if there is no beaconing interface.
> 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.
If you are changing STA->AP, then opmode also changed to AP type though
you have other STA interfaces.
--
Rajkumar
^ permalink raw reply
* Re: pull request: wireless-2.6 2011-01-12
From: David Miller @ 2011-01-13 2:52 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20110112183754.GC8674@tuxdriver.com>
From: "John W. Linville" <linville@tuxdriver.com>
Date: Wed, 12 Jan 2011 13:37:54 -0500
> This is an initial batch of wireless fixes intended for 2.6.38-rc1.
> Highlights include a number of small ath9k fixes, some documentation
> fixes from Johannes, and an ssb fix that stops loading b44 inadvertently
> when certain b43 devices are present.
>
> Please let me know if there are problems!
Pulled, thanks a lot John.
^ permalink raw reply
* Re: [RFC] ath9k: Handle interface changes properly
From: Sujith @ 2011-01-13 1:56 UTC (permalink / raw)
To: Björn Smedman; +Cc: Rajkumar Manoharan, linux-wireless
In-Reply-To: <AANLkTimK2AkRYnZk70TNt5YWEzNPCoPHpT=pu1B6JZPN@mail.gmail.com>
Björn Smedman wrote:
> Thank you Sujith for the clarification. When you lay out the cases it
> makes more sense. But there are still border cases, like e.g. adding
> first a STA and then an AP interface. If I read main.c correctly the
> opmode will then be STA and the AP vif will be broken, right?
>
> Wouldn't it be better to keep counts of number of vifs by type and
> e.g. activate SWBA if (adhocvifs > 0 || apvifs > 0) and similar? Then
> it wouldn't mater in which order vifs are added, removed and changed.
Yep, individual interface counters have to be maintained, since bringing
down one beaconing interface shouldn't disable SWBA altogether.
Also, we should allow only one IBSS interface, and deny multi-interfaces when
it is present.
Sujith
^ permalink raw reply
* Re: compat-wireless-2.6.37-4 is out
From: Luis R. Rodriguez @ 2011-01-13 1:18 UTC (permalink / raw)
To: linux-wireless; +Cc: Hauke Mehrtens, linux-kernel, linux-bluetooth
In-Reply-To: <AANLkTi=PRg31io9=+i8xYBrn+=ny52tVHW4bLwwiG6tQ@mail.gmail.com>
On Wed, Jan 12, 2011 at 5:11 PM, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
> Thanks to Hauke for his fixes for this release.
>
> http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.37/compat-wireless-2.6.37-4.tar.bz2
> sha1sum: e1b6432ce9e6738e320334b26e4adb68d3dd2a80
>
> http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.37/compat-wireless-2.6.37-4-sn.tar.bz2
> sha1sum: 54b8d777287fdcc7a716d71cfb21884f1ae07157
>
> http://wireless.kernel.org/en/users/Download/stable
Oh and here are the code stats for this release:
compat-wireless code metrics
739767 - Total upstream lines of code being pulled
2153 - backport code changes
1901 - backport code additions
252 - backport code deletions
6386 - backport from compat module
8539 - total backport code
1.1543 - % of code consists of backport work
216 - Code changes brought in from pending-stable
137 - Code additions brought in from pending-stable
79 - Code deletions brought in from pending-stable
0.0292 - % of code being cherry picked from pending-stable
114 - Code changes brought in from linux-next
102 - Code additions brought in from linux-next
12 - Code deletions brought in from linux-next
0.0154 - % of code being cherry picked from linux-next
Base tree: linux-2.6-allstable.git
Base tree version: v2.6.37
compat-wireless release: compat-wireless-v2.6.37-4-sn
Luis
^ permalink raw reply
* compat-wireless-2.6.37-4 is out
From: Luis R. Rodriguez @ 2011-01-13 1:11 UTC (permalink / raw)
To: linux-wireless; +Cc: Hauke Mehrtens, linux-kernel, linux-bluetooth
Thanks to Hauke for his fixes for this release.
http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.37/compat-wireless-2.6.37-4.tar.bz2
sha1sum: e1b6432ce9e6738e320334b26e4adb68d3dd2a80
http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.37/compat-wireless-2.6.37-4-sn.tar.bz2
sha1sum: 54b8d777287fdcc7a716d71cfb21884f1ae07157
http://wireless.kernel.org/en/users/Download/stable
Luis
^ permalink raw reply
* Re: [PATCH 0/3] compat-wireless: some updates to scripts
From: Luis R. Rodriguez @ 2011-01-13 0:59 UTC (permalink / raw)
To: Hauke Mehrtens; +Cc: linux-wireless
In-Reply-To: <1294587141-11353-1-git-send-email-hauke@hauke-m.de>
On Sun, Jan 9, 2011 at 7:32 AM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> The following commit should also go into stable comat-wireless:
> 184c55e4c41b95c01ea5e4152c613b5c79e44466
> [PATCH 1/3] compat-wireless: make NEXT_TREE configurable.
>
> Hauke Mehrtens (3):
> compat-wireless: make NEXT_TREE configurable.
> compat-wireless: update patches in enable-older-kernels
> compat-wireless: do not write git-clone
Thanks! Applied all 3 and pushed.
Luis
^ permalink raw reply
* Re: [PATCH 0/2] compat-wireless-stable-2.6.37
From: Luis R. Rodriguez @ 2011-01-13 0:55 UTC (permalink / raw)
To: Hauke Mehrtens; +Cc: linux-wireless
In-Reply-To: <1294585581-9991-1-git-send-email-hauke@hauke-m.de>
On Sun, Jan 9, 2011 at 7:06 AM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> These two patches should be backported form compat-wireless based on
> linux-next to the stable version 2.6.37 as they are fixing some build
> issues with some kernel version.
>
> Hauke Mehrtens (1):
> compat-wireless: backport power api in atl1c
>
> Luis R. Rodriguez (1):
> compat-wireless: remove 28-pm-qos-params.patch
Thanks, I'll apply and kick out a new *clean* release shortly.
Luis
^ permalink raw reply
* Re: [PATCH] compat: backport pci_wake_from_d3
From: Luis R. Rodriguez @ 2011-01-13 0:45 UTC (permalink / raw)
To: Hauke Mehrtens; +Cc: linux-wireless
In-Reply-To: <1294585234-9806-2-git-send-email-hauke@hauke-m.de>
On Sun, Jan 9, 2011 at 7:00 AM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> This is needed by atl1c.
>
> This is compat-wireless upstream commit:
> 454fb1a4a698bd2935af76800bc17e14b086476a
>
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Applied, thanks!
Luis
^ permalink raw reply
* Re: compat-wireless-2.6.37-3-sn contains wrong files
From: Luis R. Rodriguez @ 2011-01-13 0:43 UTC (permalink / raw)
To: Hauke Mehrtens; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <4D28E94B.1010806@hauke-m.de>
On Sat, Jan 8, 2011 at 2:46 PM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> plusquezero on IRC complained about compat-wireless-2.6.37-3-sn not
> compiling on his system with kernel 2.6.32 (
> http://pastebin.com/bKyZpKSr ). I tried to create such a release and had
> no problems, but the released tar balls at
> http://www.orbit-lab.org/kernel/compat-wireless-2.6-stable/v2.6.37/ are
> containing some extra files. These files are available in
> compat-wireless based on linux-next but not in the version based on
> 2.6.27. Something in the script creating this release went wrong.
>
> Attached is the diffstat beetween compat-wireless-2.6.37-3-sn.tar.bz2
> and the version I generated myself with "./scripts/admin-refresh.sh -s
> -n" from the git branch remotes/origin/linux-2.6.37.y of
> compat-wireless.git and compat.git.
>
> Hauke
>
> hauke@hauke:~/compat-wireless/compat-wireless-2.6.37-3-sn$ diff -Naurx
> .git -x pending-stable -x tmp.patch -x build.sh -x compiletest.sh -x
> scripts . ../compat-wireless-git |diffstat
> code-metrics.txt | 12
> compat/compat-2.6.38.c | 50 --
> compat/kfifo.c | 608 ------------------------------
> compat_base_tree | 2
> include/linux/average.h | 5
> include/linux/kfifo.h | 857
> -------------------------------------------
> include/linux/rfkill.h | 32 -
> include/net/bluetooth/mgmt.h | 87 ----
> net/bluetooth/mgmt.c | 308 ---------------
> net/wireless/mesh.c | 142 -------
> 10 files changed, 7 insertions(+), 2096 deletions(-)
>
Thanks, I likely didn't rm -rf * before regenerating the tarball.
Luis
^ permalink raw reply
* Re: BUG in rt2x00lib_txdone() with 2.6.37-rc8
From: Michele Ballabio @ 2011-01-12 22:34 UTC (permalink / raw)
To: linux-kernel; +Cc: bebarino, htd, linux-wireless, IvDoorn, users
On 01.01.2011, Stephen Boyd wrote:
>On 01/01/11 02:28, Heinz Diehl wrote:
>> On 31.12.2010, Stephen Boyd wrote:
>>
>>> [ 9085.714105] BUG: unable to handle kernel NULL pointer dereference at
>>> 00000000000000a4
>>> [ 9085.714816] IP: [<ffffffffa0025458>] rt2x00lib_txdone+0x36/0x249
>>> [rt2x00lib]
>>> [ 9085.715017] PGD 215fd067 PUD 292f4067 PMD 0
>>> [ 9085.715017] Oops: 0000 [#1] SMP
>>> [ 9085.715017] last sysfs file:
>>> /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
>>> [ 9085.715017] CPU 1
>>> [ 9085.715017] Modules linked in: usb_storage thermal snd_seq_oss
>>> snd_seq_midi snd_seq_dummy snd_pcm_oss snd_mixer_oss snd_hrtimer
>>> snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_event
>>> snd_seq_midi_emul snd_seq scsi_wait_scan powernow_k8 mperf i2c_i801 fuse
>>> fan snd_emu10k1 snd_rawmidi snd_ac97_codec ac97_bus snd_pcm
>>> snd_seq_device snd_timer snd_page_alloc snd_util_mem rt73usb crc_itu_t
>>> rt2x00usb snd_hwdep snd processor r8169 via82cxxx rt2x00lib soundcore
>>> mii button k8temp
>>> [ 9085.715017]
>>> [ 9085.715017] Pid: 11513, comm: kworker/1:0 Not tainted 2.6.37-rc7+ #27
>>> MS-7094/MS-7094
>> [....]
>>
>> I'm not quite shure on this, but it reminds me on this bug here:
>> https://bugzilla.kernel.org/show_bug.cgi?id=24892
>>
>
>I believe I had the latest net tree merged into 2.6.37-rc7 in which case
>the patch mentioned in that bugzilla would already be applied.
I can confirm this bug is present in v2.6.37, and not in v2.6.36.
It seems to trigger quite randomly, I think in less than 2-3 hours after
the boot (sometimes in half an hour), and it leaves no trace in my log
files.
As Stephen said, most of the times the screen shows later oopses triggered
by this one, so it is not easy to identify it either.
^ permalink raw reply
* Re: [PATCH] staging: brcm80211: fix suspend/resume issue in brcmsmac
From: Greg KH @ 2011-01-12 22:41 UTC (permalink / raw)
To: Henry Ptasinski
Cc: Arend Van Spriel, devel@linuxdriverproject.org,
linux-wireless@vger.kernel.org
In-Reply-To: <20110112194438.GJ2466@broadcom.com>
On Wed, Jan 12, 2011 at 11:44:39AM -0800, Henry Ptasinski wrote:
> On Wed, Jan 12, 2011 at 10:08:29AM -0800, Greg KH wrote:
> > On Wed, Jan 12, 2011 at 06:59:27PM +0100, Arend van Spriel wrote:
> > > PCI PM suspend callback took down the interface and resume brought
> > > it back up. In the mac80211 context this is done in subsequent calls.
> > > Rework implementation so that suspend only stores config, and sets
> > > PCI power state. The resume return to full power state (D0), restores
> > > the config, and brings hardware back up. Full bringup is done by
> > > subsequent mac80211 calls.
> >
> > Ah, does this solve the suspend/resume bug that a number of people have
> > reported for the driver since the .36 release? If so, should it go into
> > the kernel now and be backported to older releases?
>
>
> Yes, this should solve the suspend/resume bug that people have reported.
> (It doesn't solve the rfkill issues; Arend is working on a separate fix for
> that.)
>
> It should get backported, but it would be nice to get some confirmation from
> people that it fixes the issues they're seeing first.
Ok, that would be good to have :)
thanks,
greg k-h
^ permalink raw reply
* [PATCH 3/3] staging: brcm80211: Remove unnecessary memset(,0,)
From: Joe Perches @ 2011-01-12 21:21 UTC (permalink / raw)
To: linux-kernel
Cc: Brett Rudley, Henry Ptasinski, Dowan Kim, Roland Vossen,
Arend van Spriel, Greg Kroah-Hartman, linux-wireless, devel
In-Reply-To: <6f6d4a7a705949a3464471f364f77215f1e796f3.1294867098.git.joe@perches.com>
kzalloc'd memory doesn't need a memset to 0.
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
index 991463f..2af0d6a 100644
--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
@@ -703,7 +703,6 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
params = kzalloc(params_size, GFP_KERNEL);
if (unlikely(!params))
return -ENOMEM;
- memset(params, 0, params_size);
BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
wl_iscan_prep(¶ms->params, ssid);
--
1.7.3.3.398.g0b0cd.dirty
^ permalink raw reply related
* Re: TCP connections stall when station re-associates.
From: Ben Greear @ 2011-01-12 21:19 UTC (permalink / raw)
To: NetDev, linux-wireless@vger.kernel.org
In-Reply-To: <4D2CFDB8.3010907@candelatech.com>
On 01/11/2011 05:02 PM, Ben Greear wrote:
>
> We're seeing something funny while testing ath9k and ath5k with
> multiple VIFs. We are using send-to-self routing rules
> and have a TCP connection going between two station interfaces
> connected to the same AP. Kernel is ~2.6.37 (wireless-testing from
> a few days ago, plus some local patches). We tried commercial
> APs and ath9k/ath5k APs running 2.6.37 kernel and hostap with
> similar results.
When the stations re-connect, we re-run dhcp client, which involves
setting IP to zero and then re-acquiring the IP address. We
then set up new routing rules, etc to have it back to the way
it was before the station lost contact with the AP.
The TCP/IP connections are specifically bound to local IP and port.
Maybe it is invalid to expect TCP connections to survive this
IP change?
I'll work on reproducing this DHCP behaviour on some regular
wired interfaces and see if I can reproduce in a simpler test
case.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH] ath9k_hw: disable PLL / Clkreq for ASPM for AR9003
From: Luis R. Rodriguez @ 2011-01-12 21:10 UTC (permalink / raw)
To: linville
Cc: linux-wireless, Luis R. Rodriguez, stable, Jack Lee, Carl Huang,
David Quan, Nael Atallah, Sarvesh Shrivastava
In-Reply-To: <1294796791-2521-1-git-send-email-lrodriguez@atheros.com>
Please hold on
On Tue, Jan 11, 2011 at 5:46 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> This changes the PCIE PHY programming for better interoperability
> with ASPM states. Without this AR9003 chipsets will hang when
> using ASPM. This reproducible against an Apple Airport Extreme AP
> by simply pinging it.
>
> 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>
John, if you have not merged this, please hold on this, I forgot one bit.
Luis
^ permalink raw reply
* Re: [RFC] ath9k: Handle interface changes properly
From: Ben Greear @ 2011-01-12 20:14 UTC (permalink / raw)
To: Felix Fietkau; +Cc: Björn Smedman, Rajkumar Manoharan, linux-wireless
In-Reply-To: <4D2E0653.7040606@openwrt.org>
On 01/12/2011 11:51 AM, 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.
This seems right...I think this is what we did in ath5k.
Just FYI: With current ath9k code, I get almost zero packet throughput to the
IP of the VAP device (ie, if it's serving DHCP) if I have a few STAs also
created & associated with some other AP. Removing the STA interfaces makes the VAP work fine.
With or without the STAs on the VAP machine, vif to vif on vifs associated with the VAP work
fine, so it's some sort of issue with passing the pkts up the stack.
I haven't debugged this further. I think ath5k doesn't have this problem,
but I haven't tested that scenario recently.
Thanks,
Ben
>
> - Felix
> --
> 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
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Compat-wireless release for 2011-01-12 is baked
From: Compat-wireless cronjob account @ 2011-01-12 20:04 UTC (permalink / raw)
To: linux-wireless
>From git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next
5ef1982..4e7a997 history -> origin/history
+ 2cc48ac...4df1d0b master -> origin/master (forced update)
e0e736f..7bc4a4c stable -> origin/stable
* [new tag] next-20110112 -> next-20110112
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-20110112
compat-wireless release: compat-wireless-2011-01-06-pc
^ 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