From: Ben Greear <greearb@candelatech.com>
To: ath9k-devel@lists.ath9k.org
Subject: [ath9k-devel] ath9k, multiple stations, and AMPDUs
Date: Wed, 22 Sep 2010 21:58:38 -0700 [thread overview]
Message-ID: <4C9ADE7E.5070406@candelatech.com> (raw)
In-Reply-To: <4C99BEFC.2060209@openwrt.org>
On 09/22/2010 01:31 AM, Felix Fietkau wrote:
> On 2010-09-22 6:33 AM, Ben Greear wrote:
>> On 09/21/2010 03:41 PM, Felix Fietkau wrote:
>>> As I mentioned in another email: at the time we get the tx status
>>> report, we have to consider the sta pointer stale. It may or may not
>>> still be valid.
>>
>> How about this one. I think it ensures that the sta will never be stale,
> No, it doesn't. At least not in AP mode.
>
>> since it flushes the tx queue on vif removal. Minimal testing shows it
>> working, but of course I might be missing something.
> In AP mode, a vif has multiple sta. And draining the queue when a sta
> gets removed is not a good idea.
Ok, here's another try. It does a lookup each time a tx is completed,
so it's not exactly efficient..
I think it might fail the lookup if NIC manages to change it's MAC
while pkts are in the queue, but at least it mostly works.
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index c5e7af4..9165ac8 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -977,7 +977,11 @@ static void ath9k_process_rssi(struct ath_common *common,
* at least one sdata of a wiphy on mac80211 but with ath9k virtual
* wiphy you'd have to iterate over every wiphy and each sdata.
*/
- sta = ieee80211_find_sta_by_hw(hw, hdr->addr2);
+ if (is_multicast_ether_addr(hdr->addr1))
+ sta = ieee80211_find_sta_by_hw(hw, hdr->addr2, NULL);
+ else
+ sta = ieee80211_find_sta_by_hw(hw, hdr->addr2, hdr->addr1);
+
if (sta) {
an = (struct ath_node *) sta->drv_priv;
if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 85a7323..6543828 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -329,7 +329,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
rcu_read_lock();
/* XXX: use ieee80211_find_sta! */
- sta = ieee80211_find_sta_by_hw(hw, hdr->addr1);
+ sta = ieee80211_find_sta_by_hw(hw, hdr->addr1, hdr->addr2);
if (!sta) {
rcu_read_unlock();
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 12a49f0..1b2840f 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2419,7 +2419,8 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
* ieee80211_find_sta_by_hw - find a station on hardware
*
* @hw: pointer as obtained from ieee80211_alloc_hw()
- * @addr: station's address
+ * @addr: remote station's address
+ * @addr2: local address (vif->sdata->dev->dev_addr). Can be NULL for 'any'.
*
* This function must be called under RCU lock and the
* resulting pointer is only valid under RCU lock as well.
@@ -2434,7 +2435,8 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
* DO NOT USE THIS FUNCTION.
*/
struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
- const u8 *addr);
+ const u8 *addr,
+ const u8 *localaddr);
/**
* ieee80211_sta_block_awake - block station from waking up
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 44e10a9..1ba56a8 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -839,12 +839,18 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
}
struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
- const u8 *addr)
+ const u8 *addr,
+ const u8 *localaddr)
{
struct sta_info *sta, *nxt;
- /* Just return a random station ... first in list ... */
+ /* Just return a random station if localaddr is NULL
+ * ... first in list.
+ */
for_each_sta_info(hw_to_local(hw), addr, sta, nxt) {
+ if (localaddr &&
+ memcmp(sta->sdata->dev->dev_addr, localaddr, ETH_ALEN) != 0)
+ continue;
if (!sta->uploaded)
return NULL;
return &sta->sta;
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
WARNING: multiple messages have this Message-ID (diff)
From: Ben Greear <greearb@candelatech.com>
To: Felix Fietkau <nbd@openwrt.org>
Cc: Johannes Berg <johannes@sipsolutions.net>,
"ath9k-devel@lists.ath9k.org" <ath9k-devel@venema.h4ckr.net>,
"linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>
Subject: Re: [ath9k-devel] ath9k, multiple stations, and AMPDUs
Date: Wed, 22 Sep 2010 21:58:38 -0700 [thread overview]
Message-ID: <4C9ADE7E.5070406@candelatech.com> (raw)
In-Reply-To: <4C99BEFC.2060209@openwrt.org>
On 09/22/2010 01:31 AM, Felix Fietkau wrote:
> On 2010-09-22 6:33 AM, Ben Greear wrote:
>> On 09/21/2010 03:41 PM, Felix Fietkau wrote:
>>> As I mentioned in another email: at the time we get the tx status
>>> report, we have to consider the sta pointer stale. It may or may not
>>> still be valid.
>>
>> How about this one. I think it ensures that the sta will never be stale,
> No, it doesn't. At least not in AP mode.
>
>> since it flushes the tx queue on vif removal. Minimal testing shows it
>> working, but of course I might be missing something.
> In AP mode, a vif has multiple sta. And draining the queue when a sta
> gets removed is not a good idea.
Ok, here's another try. It does a lookup each time a tx is completed,
so it's not exactly efficient..
I think it might fail the lookup if NIC manages to change it's MAC
while pkts are in the queue, but at least it mostly works.
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index c5e7af4..9165ac8 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -977,7 +977,11 @@ static void ath9k_process_rssi(struct ath_common *common,
* at least one sdata of a wiphy on mac80211 but with ath9k virtual
* wiphy you'd have to iterate over every wiphy and each sdata.
*/
- sta = ieee80211_find_sta_by_hw(hw, hdr->addr2);
+ if (is_multicast_ether_addr(hdr->addr1))
+ sta = ieee80211_find_sta_by_hw(hw, hdr->addr2, NULL);
+ else
+ sta = ieee80211_find_sta_by_hw(hw, hdr->addr2, hdr->addr1);
+
if (sta) {
an = (struct ath_node *) sta->drv_priv;
if (rx_stats->rs_rssi != ATH9K_RSSI_BAD &&
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 85a7323..6543828 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -329,7 +329,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
rcu_read_lock();
/* XXX: use ieee80211_find_sta! */
- sta = ieee80211_find_sta_by_hw(hw, hdr->addr1);
+ sta = ieee80211_find_sta_by_hw(hw, hdr->addr1, hdr->addr2);
if (!sta) {
rcu_read_unlock();
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 12a49f0..1b2840f 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2419,7 +2419,8 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
* ieee80211_find_sta_by_hw - find a station on hardware
*
* @hw: pointer as obtained from ieee80211_alloc_hw()
- * @addr: station's address
+ * @addr: remote station's address
+ * @addr2: local address (vif->sdata->dev->dev_addr). Can be NULL for 'any'.
*
* This function must be called under RCU lock and the
* resulting pointer is only valid under RCU lock as well.
@@ -2434,7 +2435,8 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
* DO NOT USE THIS FUNCTION.
*/
struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
- const u8 *addr);
+ const u8 *addr,
+ const u8 *localaddr);
/**
* ieee80211_sta_block_awake - block station from waking up
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 44e10a9..1ba56a8 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -839,12 +839,18 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
}
struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
- const u8 *addr)
+ const u8 *addr,
+ const u8 *localaddr)
{
struct sta_info *sta, *nxt;
- /* Just return a random station ... first in list ... */
+ /* Just return a random station if localaddr is NULL
+ * ... first in list.
+ */
for_each_sta_info(hw_to_local(hw), addr, sta, nxt) {
+ if (localaddr &&
+ memcmp(sta->sdata->dev->dev_addr, localaddr, ETH_ALEN) != 0)
+ continue;
if (!sta->uploaded)
return NULL;
return &sta->sta;
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
next prev parent reply other threads:[~2010-09-23 4:58 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-21 5:25 [ath9k-devel] ath9k, multiple stations, and AMPDUs Ben Greear
2010-09-21 5:25 ` Ben Greear
2010-09-21 10:10 ` [ath9k-devel] " Felix Fietkau
2010-09-21 10:10 ` Felix Fietkau
2010-09-21 12:08 ` Ben Greear
2010-09-21 12:08 ` Ben Greear
2010-09-21 12:19 ` Felix Fietkau
2010-09-21 12:19 ` Felix Fietkau
2010-09-21 12:24 ` Johannes Berg
2010-09-21 12:24 ` Johannes Berg
2010-09-21 12:31 ` Johannes Berg
2010-09-21 12:31 ` Johannes Berg
2010-09-21 17:25 ` Ben Greear
2010-09-21 17:25 ` Ben Greear
2010-09-21 18:00 ` Felix Fietkau
2010-09-21 18:00 ` Felix Fietkau
2010-09-21 18:04 ` Ben Greear
2010-09-21 18:04 ` Ben Greear
2010-09-21 18:06 ` Felix Fietkau
2010-09-21 18:06 ` Felix Fietkau
2010-09-21 19:28 ` Johannes Berg
2010-09-21 19:28 ` Johannes Berg
2010-09-21 19:32 ` Felix Fietkau
2010-09-21 19:32 ` Felix Fietkau
2010-09-21 20:19 ` Ben Greear
2010-09-21 20:19 ` Ben Greear
2010-09-21 22:41 ` Felix Fietkau
2010-09-21 22:41 ` Felix Fietkau
2010-09-22 4:33 ` Ben Greear
2010-09-22 4:33 ` Ben Greear
2010-09-22 8:31 ` Felix Fietkau
2010-09-22 8:31 ` Felix Fietkau
2010-09-23 4:58 ` Ben Greear [this message]
2010-09-23 4:58 ` Ben Greear
2010-09-23 8:33 ` Johannes Berg
2010-09-23 8:33 ` Johannes Berg
2010-09-23 13:56 ` Ben Greear
2010-09-23 13:56 ` Ben Greear
2010-09-23 14:05 ` Johannes Berg
2010-09-23 14:05 ` Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C9ADE7E.5070406@candelatech.com \
--to=greearb@candelatech.com \
--cc=ath9k-devel@lists.ath9k.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.