All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFT 0/9] ath9k: few updates for virtual wiphy
@ 2009-11-03  3:07 ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

Here are a few fixes for the ath9k virtual wiphy. I thought I was
going to have time to test them all today but that didn't happen
so instead of letting them rot in my queue for a few days I'm
posting them for review.

I was not able to find an easy way to deal with the ah->opmode,
that should be updated based on the currently used ieee80211_vif
but mac80211 doesn't exactly tell us which vif we're using at any
given time -- instead each driver is supposed to support different
modes of operation on different vifs on one wiphy. With ath9k
virtual wiphy we've taken a different approach: two vifs can
have different operating modes but on at least they get to use
their own separate channel.

While we can reap benefits of using a separate channel with the
current implementation there are a few cases where mac80211 makes
it difficult to guess your current hw configuration, mainly because
it wasn't designed for two vifs on separate wiphys on the same hardware.

We'd still need to figure out a way to deal with the ah->opmode but
that varies depending on the used vif, and the rx filter also changes
depending on the vif we're on but we have no way of triggering an
appropriate filter update unless mac80211 does it by chance for us.

Luis R. Rodriguez (9):
  ath9k: fix listening to idle requests
  ath9k: update hw configuration for virtual wiphys
  ath9k: simpify RX by calling ath_get_virt_hw() once
  ath9k: use the passed ieee80211_hw on ath_rx_prepare()
  ath9k: pass the ieee80211_hw on radio enable/disable
  ath9k: use correct hw for tx aggregation TX completion
  ath9k: use the right hw on ath_tx_setup_buffer() for HT
  ath9k: handle low buffer space for virtual wiphys
  ath9k: do not pass the entire descriptor to ath_rx_prepare()

 drivers/net/wireless/ath/ath9k/ath9k.h   |   10 +++-
 drivers/net/wireless/ath/ath9k/main.c    |   51 +++++++++++-----
 drivers/net/wireless/ath/ath9k/recv.c    |   96 ++++++++++++++++-------------
 drivers/net/wireless/ath/ath9k/virtual.c |   79 +++++++++++++++++++++++--
 drivers/net/wireless/ath/ath9k/xmit.c    |   21 ++++--
 5 files changed, 184 insertions(+), 73 deletions(-)


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [ath9k-devel] [RFT 0/9] ath9k: few updates for virtual wiphy
@ 2009-11-03  3:07 ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: ath9k-devel

Here are a few fixes for the ath9k virtual wiphy. I thought I was
going to have time to test them all today but that didn't happen
so instead of letting them rot in my queue for a few days I'm
posting them for review.

I was not able to find an easy way to deal with the ah->opmode,
that should be updated based on the currently used ieee80211_vif
but mac80211 doesn't exactly tell us which vif we're using at any
given time -- instead each driver is supposed to support different
modes of operation on different vifs on one wiphy. With ath9k
virtual wiphy we've taken a different approach: two vifs can
have different operating modes but on at least they get to use
their own separate channel.

While we can reap benefits of using a separate channel with the
current implementation there are a few cases where mac80211 makes
it difficult to guess your current hw configuration, mainly because
it wasn't designed for two vifs on separate wiphys on the same hardware.

We'd still need to figure out a way to deal with the ah->opmode but
that varies depending on the used vif, and the rx filter also changes
depending on the vif we're on but we have no way of triggering an
appropriate filter update unless mac80211 does it by chance for us.

Luis R. Rodriguez (9):
  ath9k: fix listening to idle requests
  ath9k: update hw configuration for virtual wiphys
  ath9k: simpify RX by calling ath_get_virt_hw() once
  ath9k: use the passed ieee80211_hw on ath_rx_prepare()
  ath9k: pass the ieee80211_hw on radio enable/disable
  ath9k: use correct hw for tx aggregation TX completion
  ath9k: use the right hw on ath_tx_setup_buffer() for HT
  ath9k: handle low buffer space for virtual wiphys
  ath9k: do not pass the entire descriptor to ath_rx_prepare()

 drivers/net/wireless/ath/ath9k/ath9k.h   |   10 +++-
 drivers/net/wireless/ath/ath9k/main.c    |   51 +++++++++++-----
 drivers/net/wireless/ath/ath9k/recv.c    |   96 ++++++++++++++++-------------
 drivers/net/wireless/ath/ath9k/virtual.c |   79 +++++++++++++++++++++++--
 drivers/net/wireless/ath/ath9k/xmit.c    |   21 ++++--
 5 files changed, 184 insertions(+), 73 deletions(-)

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFT 1/9] ath9k: fix listening to idle requests
  2009-11-03  3:07 ` [ath9k-devel] " Luis R. Rodriguez
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  -1 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen

The way idle configuration detection was implemented as
busted due to the fact that it assumed the ath9k virtual wiphy,
the aphy, would be marked as inactive if it was not used but
it turns out an aphy is always active if its the only wiphy
present. We need to distinguish between aphy activity and
idleness so we now add an idle bool for the aphy and mark
it as such based on the passed IEEE80211_CONF_CHANGE_IDLE
from mac80211.

Previous to all_wiphys_idle would never be true when using
only one device so we never really were using
IEEE80211_CONF_CHANGE_IDLE -- we never turned the radio
off or on upon IEEE80211_CONF_CHANGE_IDLE changes as radio
changes depended on all_wiphys_idle being true either to
turn the radio on or off. Since it was always false for
one device this code was doing nothing.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Reported-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h   |    2 +
 drivers/net/wireless/ath/ath9k/main.c    |   33 +++++++++++++++++++++++------
 drivers/net/wireless/ath/ath9k/virtual.c |   17 ++++++++++++--
 3 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 13dd020..da53578 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -620,6 +620,7 @@ struct ath_wiphy {
 		ATH_WIPHY_PAUSED,
 		ATH_WIPHY_SCAN,
 	} state;
+	bool idle;
 	int chan_idx;
 	int chan_is_ht;
 };
@@ -691,6 +692,7 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
 bool ath9k_wiphy_scanning(struct ath_softc *sc);
 void ath9k_wiphy_work(struct work_struct *work);
 bool ath9k_all_wiphys_idle(struct ath_softc *sc);
+void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
 
 int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
 #endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 9fefc51..bdce0ab 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2688,22 +2688,37 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ieee80211_conf *conf = &hw->conf;
 	struct ath_hw *ah = sc->sc_ah;
-	bool all_wiphys_idle = false, disable_radio = false;
+	bool disable_radio;
 
 	mutex_lock(&sc->mutex);
 
-	/* Leave this as the first check */
+	/*
+	 * Leave this as the first check because we need to turn on the
+	 * radio if it was disabled before prior to processing the rest
+	 * of the changes. Likewise we must only disable the radio towards
+	 * the end.
+	 */
 	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+		bool enable_radio;
+		bool all_wiphys_idle;
+		bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
 
 		spin_lock_bh(&sc->wiphy_lock);
 		all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
+		ath9k_set_wiphy_idle(aphy, idle);
+
+		if (!idle && all_wiphys_idle)
+			enable_radio = true;
+
+		/*
+		 * After we unlock here its possible another wiphy
+		 * can be re-renabled so to account for that we will
+		 * only disable the radio toward the end of this routine
+		 * if by then all wiphys are still idle.
+		 */
 		spin_unlock_bh(&sc->wiphy_lock);
 
-		if (conf->flags & IEEE80211_CONF_IDLE){
-			if (all_wiphys_idle)
-				disable_radio = true;
-		}
-		else if (all_wiphys_idle) {
+		if (enable_radio) {
 			ath_radio_enable(sc);
 			ath_print(common, ATH_DBG_CONFIG,
 				  "not-idle: enabling radio\n");
@@ -2779,6 +2794,10 @@ skip_chan_change:
 	if (changed & IEEE80211_CONF_CHANGE_POWER)
 		sc->config.txpowlimit = 2 * conf->power_level;
 
+	spin_lock_bh(&sc->wiphy_lock);
+	disable_radio = ath9k_all_wiphys_idle(sc);
+	spin_unlock_bh(&sc->wiphy_lock);
+
 	if (disable_radio) {
 		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
 		ath_radio_disable(sc);
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index bc7d173..e6a50f3 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -668,15 +668,26 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
 bool ath9k_all_wiphys_idle(struct ath_softc *sc)
 {
 	unsigned int i;
-	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
+	if (!sc->pri_wiphy->idle)
 		return false;
-	}
 	for (i = 0; i < sc->num_sec_wiphy; i++) {
 		struct ath_wiphy *aphy = sc->sec_wiphy[i];
 		if (!aphy)
 			continue;
-		if (aphy->state != ATH_WIPHY_INACTIVE)
+		if (!aphy->idle)
 			return false;
 	}
 	return true;
 }
+
+/* caller must hold wiphy_lock */
+void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
+{
+	struct ath_softc *sc = aphy->sc;
+
+	aphy->idle = idle;
+	ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+		  "Marking %s as %s\n",
+		  wiphy_name(aphy->hw->wiphy),
+		  idle ? "idle" : "not-idle");
+}
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ath9k-devel] [RFT 1/9] ath9k: fix listening to idle requests
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: ath9k-devel

The way idle configuration detection was implemented as
busted due to the fact that it assumed the ath9k virtual wiphy,
the aphy, would be marked as inactive if it was not used but
it turns out an aphy is always active if its the only wiphy
present. We need to distinguish between aphy activity and
idleness so we now add an idle bool for the aphy and mark
it as such based on the passed IEEE80211_CONF_CHANGE_IDLE
from mac80211.

Previous to all_wiphys_idle would never be true when using
only one device so we never really were using
IEEE80211_CONF_CHANGE_IDLE -- we never turned the radio
off or on upon IEEE80211_CONF_CHANGE_IDLE changes as radio
changes depended on all_wiphys_idle being true either to
turn the radio on or off. Since it was always false for
one device this code was doing nothing.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Reported-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h   |    2 +
 drivers/net/wireless/ath/ath9k/main.c    |   33 +++++++++++++++++++++++------
 drivers/net/wireless/ath/ath9k/virtual.c |   17 ++++++++++++--
 3 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 13dd020..da53578 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -620,6 +620,7 @@ struct ath_wiphy {
 		ATH_WIPHY_PAUSED,
 		ATH_WIPHY_SCAN,
 	} state;
+	bool idle;
 	int chan_idx;
 	int chan_is_ht;
 };
@@ -691,6 +692,7 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
 bool ath9k_wiphy_scanning(struct ath_softc *sc);
 void ath9k_wiphy_work(struct work_struct *work);
 bool ath9k_all_wiphys_idle(struct ath_softc *sc);
+void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
 
 int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
 #endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 9fefc51..bdce0ab 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2688,22 +2688,37 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ieee80211_conf *conf = &hw->conf;
 	struct ath_hw *ah = sc->sc_ah;
-	bool all_wiphys_idle = false, disable_radio = false;
+	bool disable_radio;
 
 	mutex_lock(&sc->mutex);
 
-	/* Leave this as the first check */
+	/*
+	 * Leave this as the first check because we need to turn on the
+	 * radio if it was disabled before prior to processing the rest
+	 * of the changes. Likewise we must only disable the radio towards
+	 * the end.
+	 */
 	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+		bool enable_radio;
+		bool all_wiphys_idle;
+		bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
 
 		spin_lock_bh(&sc->wiphy_lock);
 		all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
+		ath9k_set_wiphy_idle(aphy, idle);
+
+		if (!idle && all_wiphys_idle)
+			enable_radio = true;
+
+		/*
+		 * After we unlock here its possible another wiphy
+		 * can be re-renabled so to account for that we will
+		 * only disable the radio toward the end of this routine
+		 * if by then all wiphys are still idle.
+		 */
 		spin_unlock_bh(&sc->wiphy_lock);
 
-		if (conf->flags & IEEE80211_CONF_IDLE){
-			if (all_wiphys_idle)
-				disable_radio = true;
-		}
-		else if (all_wiphys_idle) {
+		if (enable_radio) {
 			ath_radio_enable(sc);
 			ath_print(common, ATH_DBG_CONFIG,
 				  "not-idle: enabling radio\n");
@@ -2779,6 +2794,10 @@ skip_chan_change:
 	if (changed & IEEE80211_CONF_CHANGE_POWER)
 		sc->config.txpowlimit = 2 * conf->power_level;
 
+	spin_lock_bh(&sc->wiphy_lock);
+	disable_radio = ath9k_all_wiphys_idle(sc);
+	spin_unlock_bh(&sc->wiphy_lock);
+
 	if (disable_radio) {
 		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
 		ath_radio_disable(sc);
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index bc7d173..e6a50f3 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -668,15 +668,26 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
 bool ath9k_all_wiphys_idle(struct ath_softc *sc)
 {
 	unsigned int i;
-	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
+	if (!sc->pri_wiphy->idle)
 		return false;
-	}
 	for (i = 0; i < sc->num_sec_wiphy; i++) {
 		struct ath_wiphy *aphy = sc->sec_wiphy[i];
 		if (!aphy)
 			continue;
-		if (aphy->state != ATH_WIPHY_INACTIVE)
+		if (!aphy->idle)
 			return false;
 	}
 	return true;
 }
+
+/* caller must hold wiphy_lock */
+void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
+{
+	struct ath_softc *sc = aphy->sc;
+
+	aphy->idle = idle;
+	ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+		  "Marking %s as %s\n",
+		  wiphy_name(aphy->hw->wiphy),
+		  idle ? "idle" : "not-idle");
+}
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 2/9] ath9k: update hw configuration for virtual wiphys
  2009-11-03  3:07 ` [ath9k-devel] " Luis R. Rodriguez
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  -1 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen

ath9k supports its own virtual wiphys. The hardware code
relies on the ieee80211_hw for the present interface but
with recent changes introduced the common->hw was never
updated and is required for virtual wiphys.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/virtual.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index e6a50f3..7678c4a 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -298,6 +298,7 @@ static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
 void ath9k_wiphy_chan_work(struct work_struct *work)
 {
 	struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_wiphy *aphy = sc->next_wiphy;
 
 	if (aphy == NULL)
@@ -313,6 +314,10 @@ void ath9k_wiphy_chan_work(struct work_struct *work)
 	/* XXX: remove me eventually */
 	ath9k_update_ichannel(sc, aphy->hw,
 			      &sc->sc_ah->channels[sc->chan_idx]);
+
+	/* sync hw configuration for hw code */
+	common->hw = aphy->hw;
+
 	ath_update_chainmask(sc, sc->chan_is_ht);
 	if (ath_set_channel(sc, aphy->hw,
 			    &sc->sc_ah->channels[sc->chan_idx]) < 0) {
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ath9k-devel] [RFT 2/9] ath9k: update hw configuration for virtual wiphys
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: ath9k-devel

ath9k supports its own virtual wiphys. The hardware code
relies on the ieee80211_hw for the present interface but
with recent changes introduced the common->hw was never
updated and is required for virtual wiphys.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/virtual.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index e6a50f3..7678c4a 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -298,6 +298,7 @@ static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
 void ath9k_wiphy_chan_work(struct work_struct *work)
 {
 	struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_wiphy *aphy = sc->next_wiphy;
 
 	if (aphy == NULL)
@@ -313,6 +314,10 @@ void ath9k_wiphy_chan_work(struct work_struct *work)
 	/* XXX: remove me eventually */
 	ath9k_update_ichannel(sc, aphy->hw,
 			      &sc->sc_ah->channels[sc->chan_idx]);
+
+	/* sync hw configuration for hw code */
+	common->hw = aphy->hw;
+
 	ath_update_chainmask(sc, sc->chan_is_ht);
 	if (ath_set_channel(sc, aphy->hw,
 			    &sc->sc_ah->channels[sc->chan_idx]) < 0) {
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 3/9] ath9k: simpify RX by calling ath_get_virt_hw() once
  2009-11-03  3:07 ` [ath9k-devel] " Luis R. Rodriguez
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  -1 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen

ath_get_virt_hw() is required on RX to determine for which virtual
wiphy an skb came in for. Instead of searching for the hw twice do
it only once.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/recv.c |   28 ++++++++++++++++++----------
 1 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index c880a55..330cd3b 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -105,23 +105,21 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
  * up the frame up to let mac80211 handle the actual error case, be it no
  * decryption key or real decryption error. This let us keep statistics there.
  */
-static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
+static int ath_rx_prepare(struct ieee80211_hw *hw,
+			  struct sk_buff *skb, struct ath_desc *ds,
 			  struct ieee80211_rx_status *rx_status, bool *decrypt_error,
 			  struct ath_softc *sc)
 {
 	struct ieee80211_hdr *hdr;
 	u8 ratecode;
 	__le16 fc;
-	struct ieee80211_hw *hw;
 	struct ieee80211_sta *sta;
 	struct ath_node *an;
 	int last_rssi = ATH_RSSI_DUMMY_MARKER;
 
-
 	hdr = (struct ieee80211_hdr *)skb->data;
 	fc = hdr->frame_control;
 	memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
-	hw = ath_get_virt_hw(sc, hdr);
 
 	if (ds->ds_rxstat.rs_more) {
 		/*
@@ -615,7 +613,8 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
 	}
 }
 
-static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
+static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
+				    struct ath_softc *sc, struct sk_buff *skb,
 				    struct ieee80211_rx_status *rx_status)
 {
 	struct ieee80211_hdr *hdr;
@@ -647,7 +646,7 @@ static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
 	} else {
 		/* Deliver unicast frames based on receiver address */
 		memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
-		ieee80211_rx(ath_get_virt_hw(sc, hdr), skb);
+		ieee80211_rx(hw, skb);
 	}
 }
 
@@ -663,6 +662,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 	struct ieee80211_rx_status rx_status;
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
+	/*
+	 * The hw can techncically differ from common->hw when using ath9k
+	 * virtual wiphy so to account for that we iterate over the active
+	 * wiphys and find the appropriate wiphy and therefore hw.
+	 */
+	struct ieee80211_hw *hw = NULL;
 	struct ieee80211_hdr *hdr;
 	int hdrlen, padsize, retval;
 	bool decrypt_error = false;
@@ -742,6 +747,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 				sc->rx.bufsize,
 				DMA_FROM_DEVICE);
 
+		hdr = (struct ieee80211_hdr *) skb->data;
+		hw = ath_get_virt_hw(sc, hdr);
+
 		/*
 		 * If we're asked to flush receive queue, directly
 		 * chain it back at the queue without processing it.
@@ -756,7 +764,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
 			goto requeue;
 
-		if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
+		if (!ath_rx_prepare(hw, skb, ds,
+				    &rx_status, &decrypt_error, sc))
 			goto requeue;
 
 		/* Ensure we always have an skb to requeue once we are done
@@ -778,7 +787,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		skb_put(skb, ds->ds_rxstat.rs_datalen);
 
 		/* see if any padding is done by the hw and remove it */
-		hdr = (struct ieee80211_hdr *)skb->data;
 		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
 		fc = hdr->frame_control;
 
@@ -825,7 +833,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 			bf->bf_mpdu = NULL;
 			ath_print(common, ATH_DBG_FATAL,
 				  "dma_mapping_error() on RX\n");
-			ath_rx_send_to_mac80211(sc, skb, &rx_status);
+			ath_rx_send_to_mac80211(hw, sc, skb, &rx_status);
 			break;
 		}
 		bf->bf_dmacontext = bf->bf_buf_addr;
@@ -846,7 +854,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 					     SC_OP_WAIT_FOR_PSPOLL_DATA)))
 			ath_rx_ps(sc, skb);
 
-		ath_rx_send_to_mac80211(sc, skb, &rx_status);
+		ath_rx_send_to_mac80211(hw, sc, skb, &rx_status);
 
 requeue:
 		list_move_tail(&bf->list, &sc->rx.rxbuf);
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ath9k-devel] [RFT 3/9] ath9k: simpify RX by calling ath_get_virt_hw() once
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: ath9k-devel

ath_get_virt_hw() is required on RX to determine for which virtual
wiphy an skb came in for. Instead of searching for the hw twice do
it only once.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/recv.c |   28 ++++++++++++++++++----------
 1 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index c880a55..330cd3b 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -105,23 +105,21 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
  * up the frame up to let mac80211 handle the actual error case, be it no
  * decryption key or real decryption error. This let us keep statistics there.
  */
-static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
+static int ath_rx_prepare(struct ieee80211_hw *hw,
+			  struct sk_buff *skb, struct ath_desc *ds,
 			  struct ieee80211_rx_status *rx_status, bool *decrypt_error,
 			  struct ath_softc *sc)
 {
 	struct ieee80211_hdr *hdr;
 	u8 ratecode;
 	__le16 fc;
-	struct ieee80211_hw *hw;
 	struct ieee80211_sta *sta;
 	struct ath_node *an;
 	int last_rssi = ATH_RSSI_DUMMY_MARKER;
 
-
 	hdr = (struct ieee80211_hdr *)skb->data;
 	fc = hdr->frame_control;
 	memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
-	hw = ath_get_virt_hw(sc, hdr);
 
 	if (ds->ds_rxstat.rs_more) {
 		/*
@@ -615,7 +613,8 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
 	}
 }
 
-static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
+static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
+				    struct ath_softc *sc, struct sk_buff *skb,
 				    struct ieee80211_rx_status *rx_status)
 {
 	struct ieee80211_hdr *hdr;
@@ -647,7 +646,7 @@ static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
 	} else {
 		/* Deliver unicast frames based on receiver address */
 		memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
-		ieee80211_rx(ath_get_virt_hw(sc, hdr), skb);
+		ieee80211_rx(hw, skb);
 	}
 }
 
@@ -663,6 +662,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 	struct ieee80211_rx_status rx_status;
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
+	/*
+	 * The hw can techncically differ from common->hw when using ath9k
+	 * virtual wiphy so to account for that we iterate over the active
+	 * wiphys and find the appropriate wiphy and therefore hw.
+	 */
+	struct ieee80211_hw *hw = NULL;
 	struct ieee80211_hdr *hdr;
 	int hdrlen, padsize, retval;
 	bool decrypt_error = false;
@@ -742,6 +747,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 				sc->rx.bufsize,
 				DMA_FROM_DEVICE);
 
+		hdr = (struct ieee80211_hdr *) skb->data;
+		hw = ath_get_virt_hw(sc, hdr);
+
 		/*
 		 * If we're asked to flush receive queue, directly
 		 * chain it back at the queue without processing it.
@@ -756,7 +764,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
 			goto requeue;
 
-		if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
+		if (!ath_rx_prepare(hw, skb, ds,
+				    &rx_status, &decrypt_error, sc))
 			goto requeue;
 
 		/* Ensure we always have an skb to requeue once we are done
@@ -778,7 +787,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		skb_put(skb, ds->ds_rxstat.rs_datalen);
 
 		/* see if any padding is done by the hw and remove it */
-		hdr = (struct ieee80211_hdr *)skb->data;
 		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
 		fc = hdr->frame_control;
 
@@ -825,7 +833,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 			bf->bf_mpdu = NULL;
 			ath_print(common, ATH_DBG_FATAL,
 				  "dma_mapping_error() on RX\n");
-			ath_rx_send_to_mac80211(sc, skb, &rx_status);
+			ath_rx_send_to_mac80211(hw, sc, skb, &rx_status);
 			break;
 		}
 		bf->bf_dmacontext = bf->bf_buf_addr;
@@ -846,7 +854,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 					     SC_OP_WAIT_FOR_PSPOLL_DATA)))
 			ath_rx_ps(sc, skb);
 
-		ath_rx_send_to_mac80211(sc, skb, &rx_status);
+		ath_rx_send_to_mac80211(hw, sc, skb, &rx_status);
 
 requeue:
 		list_move_tail(&bf->list, &sc->rx.rxbuf);
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 4/9] ath9k: use the passed ieee80211_hw on ath_rx_prepare()
  2009-11-03  3:07 ` [ath9k-devel] " Luis R. Rodriguez
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  -1 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen

this now uses the proper hw which should mean finding the
right sta when using ath9k virtual wiphy stuff.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/recv.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 330cd3b..10decfa 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -200,7 +200,7 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	}
 
 	rcu_read_lock();
-	sta = ieee80211_find_sta(sc->hw, hdr->addr2);
+	sta = ieee80211_find_sta(hw, hdr->addr2);
 	if (sta) {
 		an = (struct ath_node *) sta->drv_priv;
 		if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ath9k-devel] [RFT 4/9] ath9k: use the passed ieee80211_hw on ath_rx_prepare()
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: ath9k-devel

this now uses the proper hw which should mean finding the
right sta when using ath9k virtual wiphy stuff.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/recv.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 330cd3b..10decfa 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -200,7 +200,7 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	}
 
 	rcu_read_lock();
-	sta = ieee80211_find_sta(sc->hw, hdr->addr2);
+	sta = ieee80211_find_sta(hw, hdr->addr2);
 	if (sta) {
 		an = (struct ath_node *) sta->drv_priv;
 		if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 5/9] ath9k: pass the ieee80211_hw on radio enable/disable
  2009-11-03  3:07 ` [ath9k-devel] " Luis R. Rodriguez
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  -1 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen

We use the ieee80211_hw for radio enable/disable but the wrong
structure hw was being used in consideration for virtual wiphys
as each virtual wiphy has its own ieee80211_hw struct.

Just pass the hw struct to ensure we use the right one. This should
fix the hw used and passed for radio enable/disable. This includes
the stoping / starting of the software TX queues so mac80211 doesn't
send us data for a specific virtual wiphy. ath9k already takes care
of pausing virtual wiphys and stopping the respective queues on its
own, but this should handle the idle mac80211 conf calls as well.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h   |    5 +++--
 drivers/net/wireless/ath/ath9k/main.c    |   18 +++++++++---------
 drivers/net/wireless/ath/ath9k/virtual.c |    5 +++--
 3 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index da53578..59ce7ec 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -655,8 +655,9 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
 void ath_update_chainmask(struct ath_softc *sc, int is_ht);
 int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
 		    struct ath9k_channel *hchan);
-void ath_radio_enable(struct ath_softc *sc);
-void ath_radio_disable(struct ath_softc *sc);
+
+void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
 
 #ifdef CONFIG_PCI
 int ath_pci_init(void);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index bdce0ab..11aaa7d 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1200,11 +1200,11 @@ fail:
 	ath_deinit_leds(sc);
 }
 
-void ath_radio_enable(struct ath_softc *sc)
+void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
-	struct ieee80211_channel *channel = sc->hw->conf.channel;
+	struct ieee80211_channel *channel = hw->conf.channel;
 	int r;
 
 	ath9k_ps_wakeup(sc);
@@ -1241,18 +1241,18 @@ void ath_radio_enable(struct ath_softc *sc)
 			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
 	ath9k_hw_set_gpio(ah, ah->led_pin, 0);
 
-	ieee80211_wake_queues(sc->hw);
+	ieee80211_wake_queues(hw);
 	ath9k_ps_restore(sc);
 }
 
-void ath_radio_disable(struct ath_softc *sc)
+void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
-	struct ieee80211_channel *channel = sc->hw->conf.channel;
+	struct ieee80211_channel *channel = hw->conf.channel;
 	int r;
 
 	ath9k_ps_wakeup(sc);
-	ieee80211_stop_queues(sc->hw);
+	ieee80211_stop_queues(hw);
 
 	/* Disable LED */
 	ath9k_hw_set_gpio(ah, ah->led_pin, 1);
@@ -1266,7 +1266,7 @@ void ath_radio_disable(struct ath_softc *sc)
 	ath_flushrecv(sc);		/* flush recv queue */
 
 	if (!ah->curchan)
-		ah->curchan = ath_get_curchannel(sc, sc->hw);
+		ah->curchan = ath_get_curchannel(sc, hw);
 
 	spin_lock_bh(&sc->sc_resetlock);
 	r = ath9k_hw_reset(ah, ah->curchan, false);
@@ -2719,7 +2719,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 		spin_unlock_bh(&sc->wiphy_lock);
 
 		if (enable_radio) {
-			ath_radio_enable(sc);
+			ath_radio_enable(sc, hw);
 			ath_print(common, ATH_DBG_CONFIG,
 				  "not-idle: enabling radio\n");
 		}
@@ -2800,7 +2800,7 @@ skip_chan_change:
 
 	if (disable_radio) {
 		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
-		ath_radio_disable(sc);
+		ath_radio_disable(sc, hw);
 	}
 
 	mutex_unlock(&sc->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 7678c4a..69a871b 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -526,8 +526,9 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
 			 * frame being completed)
 			 */
 			spin_unlock_bh(&sc->wiphy_lock);
-			ath_radio_disable(sc);
-			ath_radio_enable(sc);
+			ath_radio_disable(sc, aphy->hw);
+			ath_radio_enable(sc, aphy->hw);
+			/* Only the primary wiphy hw is used for queuing work */
 			ieee80211_queue_work(aphy->sc->hw,
 				   &aphy->sc->chan_work);
 			return -EBUSY; /* previous select still in progress */
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ath9k-devel] [RFT 5/9] ath9k: pass the ieee80211_hw on radio enable/disable
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: ath9k-devel

We use the ieee80211_hw for radio enable/disable but the wrong
structure hw was being used in consideration for virtual wiphys
as each virtual wiphy has its own ieee80211_hw struct.

Just pass the hw struct to ensure we use the right one. This should
fix the hw used and passed for radio enable/disable. This includes
the stoping / starting of the software TX queues so mac80211 doesn't
send us data for a specific virtual wiphy. ath9k already takes care
of pausing virtual wiphys and stopping the respective queues on its
own, but this should handle the idle mac80211 conf calls as well.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h   |    5 +++--
 drivers/net/wireless/ath/ath9k/main.c    |   18 +++++++++---------
 drivers/net/wireless/ath/ath9k/virtual.c |    5 +++--
 3 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index da53578..59ce7ec 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -655,8 +655,9 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
 void ath_update_chainmask(struct ath_softc *sc, int is_ht);
 int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
 		    struct ath9k_channel *hchan);
-void ath_radio_enable(struct ath_softc *sc);
-void ath_radio_disable(struct ath_softc *sc);
+
+void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
 
 #ifdef CONFIG_PCI
 int ath_pci_init(void);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index bdce0ab..11aaa7d 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1200,11 +1200,11 @@ fail:
 	ath_deinit_leds(sc);
 }
 
-void ath_radio_enable(struct ath_softc *sc)
+void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
-	struct ieee80211_channel *channel = sc->hw->conf.channel;
+	struct ieee80211_channel *channel = hw->conf.channel;
 	int r;
 
 	ath9k_ps_wakeup(sc);
@@ -1241,18 +1241,18 @@ void ath_radio_enable(struct ath_softc *sc)
 			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
 	ath9k_hw_set_gpio(ah, ah->led_pin, 0);
 
-	ieee80211_wake_queues(sc->hw);
+	ieee80211_wake_queues(hw);
 	ath9k_ps_restore(sc);
 }
 
-void ath_radio_disable(struct ath_softc *sc)
+void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
-	struct ieee80211_channel *channel = sc->hw->conf.channel;
+	struct ieee80211_channel *channel = hw->conf.channel;
 	int r;
 
 	ath9k_ps_wakeup(sc);
-	ieee80211_stop_queues(sc->hw);
+	ieee80211_stop_queues(hw);
 
 	/* Disable LED */
 	ath9k_hw_set_gpio(ah, ah->led_pin, 1);
@@ -1266,7 +1266,7 @@ void ath_radio_disable(struct ath_softc *sc)
 	ath_flushrecv(sc);		/* flush recv queue */
 
 	if (!ah->curchan)
-		ah->curchan = ath_get_curchannel(sc, sc->hw);
+		ah->curchan = ath_get_curchannel(sc, hw);
 
 	spin_lock_bh(&sc->sc_resetlock);
 	r = ath9k_hw_reset(ah, ah->curchan, false);
@@ -2719,7 +2719,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 		spin_unlock_bh(&sc->wiphy_lock);
 
 		if (enable_radio) {
-			ath_radio_enable(sc);
+			ath_radio_enable(sc, hw);
 			ath_print(common, ATH_DBG_CONFIG,
 				  "not-idle: enabling radio\n");
 		}
@@ -2800,7 +2800,7 @@ skip_chan_change:
 
 	if (disable_radio) {
 		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
-		ath_radio_disable(sc);
+		ath_radio_disable(sc, hw);
 	}
 
 	mutex_unlock(&sc->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 7678c4a..69a871b 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -526,8 +526,9 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
 			 * frame being completed)
 			 */
 			spin_unlock_bh(&sc->wiphy_lock);
-			ath_radio_disable(sc);
-			ath_radio_enable(sc);
+			ath_radio_disable(sc, aphy->hw);
+			ath_radio_enable(sc, aphy->hw);
+			/* Only the primary wiphy hw is used for queuing work */
 			ieee80211_queue_work(aphy->sc->hw,
 				   &aphy->sc->chan_work);
 			return -EBUSY; /* previous select still in progress */
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 6/9] ath9k: use correct hw for tx aggregation TX completion
  2009-11-03  3:07 ` [ath9k-devel] " Luis R. Rodriguez
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  -1 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen

When ath9k virtual wiphys are used the sc->hw will not always represent
the active hw, instead we need to get it from the skb->cb private
driver area. This ensures the right hw is used to find a sta for
the TX'd skb.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/xmit.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 2a4efcb..5d0851b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -267,7 +267,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	struct ath_node *an = NULL;
 	struct sk_buff *skb;
 	struct ieee80211_sta *sta;
+	struct ieee80211_hw *hw;
 	struct ieee80211_hdr *hdr;
+	struct ieee80211_tx_info *tx_info;
+	struct ath_tx_info_priv *tx_info_priv;
 	struct ath_atx_tid *tid = NULL;
 	struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
 	struct ath_desc *ds = bf_last->bf_desc;
@@ -280,9 +283,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	skb = bf->bf_mpdu;
 	hdr = (struct ieee80211_hdr *)skb->data;
 
+	tx_info = IEEE80211_SKB_CB(skb);
+	tx_info_priv = (struct ath_tx_info_priv *) tx_info->rate_driver_data[0];
+	hw = tx_info_priv->aphy->hw;
+
 	rcu_read_lock();
 
-	sta = ieee80211_find_sta(sc->hw, hdr->addr1);
+	sta = ieee80211_find_sta(hw, hdr->addr1);
 	if (!sta) {
 		rcu_read_unlock();
 		return;
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ath9k-devel] [RFT 6/9] ath9k: use correct hw for tx aggregation TX completion
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: ath9k-devel

When ath9k virtual wiphys are used the sc->hw will not always represent
the active hw, instead we need to get it from the skb->cb private
driver area. This ensures the right hw is used to find a sta for
the TX'd skb.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/xmit.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 2a4efcb..5d0851b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -267,7 +267,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	struct ath_node *an = NULL;
 	struct sk_buff *skb;
 	struct ieee80211_sta *sta;
+	struct ieee80211_hw *hw;
 	struct ieee80211_hdr *hdr;
+	struct ieee80211_tx_info *tx_info;
+	struct ath_tx_info_priv *tx_info_priv;
 	struct ath_atx_tid *tid = NULL;
 	struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
 	struct ath_desc *ds = bf_last->bf_desc;
@@ -280,9 +283,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	skb = bf->bf_mpdu;
 	hdr = (struct ieee80211_hdr *)skb->data;
 
+	tx_info = IEEE80211_SKB_CB(skb);
+	tx_info_priv = (struct ath_tx_info_priv *) tx_info->rate_driver_data[0];
+	hw = tx_info_priv->aphy->hw;
+
 	rcu_read_lock();
 
-	sta = ieee80211_find_sta(sc->hw, hdr->addr1);
+	sta = ieee80211_find_sta(hw, hdr->addr1);
 	if (!sta) {
 		rcu_read_unlock();
 		return;
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 7/9] ath9k: use the right hw on ath_tx_setup_buffer() for HT
  2009-11-03  3:07 ` [ath9k-devel] " Luis R. Rodriguez
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  -1 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen

When using virtual wiphys the base sc->hw was being used, the correct
hw is passed along the caller already so just use that.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/xmit.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 5d0851b..427bd1d 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1575,7 +1575,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
 
 	bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
 
-	if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
+	if (conf_is_ht(&hw->conf) && !is_pae(skb))
 		bf->bf_state.bf_type |= BUF_HT;
 
 	bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ath9k-devel] [RFT 7/9] ath9k: use the right hw on ath_tx_setup_buffer() for HT
@ 2009-11-03  3:07   ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: ath9k-devel

When using virtual wiphys the base sc->hw was being used, the correct
hw is passed along the caller already so just use that.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/xmit.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 5d0851b..427bd1d 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1575,7 +1575,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
 
 	bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
 
-	if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
+	if (conf_is_ht(&hw->conf) && !is_pae(skb))
 		bf->bf_state.bf_type |= BUF_HT;
 
 	bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 8/9] ath9k: handle low buffer space for virtual wiphys
  2009-11-03  3:07 ` [ath9k-devel] " Luis R. Rodriguez
@ 2009-11-03  3:08   ` Luis R. Rodriguez
  -1 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen

ath9k virtual wiphys all share the same internal buffer space
for TX but they do not share the mac80211 skb queues. When
ath9k detects it is running low on buffer space to TX it tells
mac80211 to stop sending it skbs its way but it always does
this only for the primary wiphy. This means mac80211 won't know
its best to avoid sending ath9k more skbs on a separate virtual
wiphy. The same issue is present for reliving the skb queue.

Since ath9k does not keep track of which virtual wiphy is hammering
on TX silence all wiphy's TX when we're low on buffer space. When
we're free on buffer space only bother informing the virtual wiphy
which is active that we have free buffers.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h   |    3 ++
 drivers/net/wireless/ath/ath9k/virtual.c |   52 ++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/xmit.c    |   10 +++---
 3 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 59ce7ec..4169d2b 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -695,5 +695,8 @@ void ath9k_wiphy_work(struct work_struct *work);
 bool ath9k_all_wiphys_idle(struct ath_softc *sc);
 void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
 
+void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
+void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
+
 int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
 #endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 69a871b..0a36b57 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -697,3 +697,55 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
 		  wiphy_name(aphy->hw->wiphy),
 		  idle ? "idle" : "not-idle");
 }
+/* Only bother starting a queue on an active virtual wiphy */
+void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
+{
+	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+	unsigned int i;
+
+	spin_lock_bh(&sc->wiphy_lock);
+
+	/* Start the primary wiphy */
+	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) {
+		ieee80211_wake_queue(hw, skb_queue);
+		goto unlock;
+	}
+
+	/* Now start the secondary wiphy queues */
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (!aphy)
+			continue;
+		if (aphy->state != ATH_WIPHY_ACTIVE)
+			continue;
+
+		hw = aphy->hw;
+		ieee80211_wake_queue(hw, skb_queue);
+		break;
+	}
+
+unlock:
+	spin_unlock_bh(&sc->wiphy_lock);
+}
+
+/* Go ahead and propagate information to all virtual wiphys, it won't hurt */
+void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue)
+{
+	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+	unsigned int i;
+
+	spin_lock_bh(&sc->wiphy_lock);
+
+	/* Stop the primary wiphy */
+	ieee80211_stop_queue(hw, skb_queue);
+
+	/* Now stop the secondary wiphy queues */
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (!aphy)
+			continue;
+		hw = aphy->hw;
+		ieee80211_stop_queue(hw, skb_queue);
+	}
+	spin_unlock_bh(&sc->wiphy_lock);
+}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 427bd1d..40d34ed 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -914,9 +914,10 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
 struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
 {
 	struct ath_txq *txq = NULL;
+	u16 skb_queue = skb_get_queue_mapping(skb);
 	int qnum;
 
-	qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
+	qnum = ath_get_hal_qnum(skb_queue, sc);
 	txq = &sc->tx.txq[qnum];
 
 	spin_lock_bh(&txq->axq_lock);
@@ -925,7 +926,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
 		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT,
 			  "TX queue: %d is full, depth: %d\n",
 			  qnum, txq->axq_depth);
-		ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
+		ath_mac80211_stop_queue(sc, skb_queue);
 		txq->stopped = 1;
 		spin_unlock_bh(&txq->axq_lock);
 		return NULL;
@@ -1704,8 +1705,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 		 * on the queue */
 		spin_lock_bh(&txq->axq_lock);
 		if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
-			ieee80211_stop_queue(sc->hw,
-				skb_get_queue_mapping(skb));
+			ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
 			txq->stopped = 1;
 		}
 		spin_unlock_bh(&txq->axq_lock);
@@ -1945,7 +1945,7 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
 	    sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
 		qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
 		if (qnum != -1) {
-			ieee80211_wake_queue(sc->hw, qnum);
+			ath_mac80211_start_queue(sc, qnum);
 			txq->stopped = 0;
 		}
 	}
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ath9k-devel] [RFT 8/9] ath9k: handle low buffer space for virtual wiphys
@ 2009-11-03  3:08   ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:08 UTC (permalink / raw)
  To: ath9k-devel

ath9k virtual wiphys all share the same internal buffer space
for TX but they do not share the mac80211 skb queues. When
ath9k detects it is running low on buffer space to TX it tells
mac80211 to stop sending it skbs its way but it always does
this only for the primary wiphy. This means mac80211 won't know
its best to avoid sending ath9k more skbs on a separate virtual
wiphy. The same issue is present for reliving the skb queue.

Since ath9k does not keep track of which virtual wiphy is hammering
on TX silence all wiphy's TX when we're low on buffer space. When
we're free on buffer space only bother informing the virtual wiphy
which is active that we have free buffers.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h   |    3 ++
 drivers/net/wireless/ath/ath9k/virtual.c |   52 ++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/xmit.c    |   10 +++---
 3 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 59ce7ec..4169d2b 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -695,5 +695,8 @@ void ath9k_wiphy_work(struct work_struct *work);
 bool ath9k_all_wiphys_idle(struct ath_softc *sc);
 void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
 
+void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
+void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
+
 int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
 #endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 69a871b..0a36b57 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -697,3 +697,55 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
 		  wiphy_name(aphy->hw->wiphy),
 		  idle ? "idle" : "not-idle");
 }
+/* Only bother starting a queue on an active virtual wiphy */
+void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
+{
+	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+	unsigned int i;
+
+	spin_lock_bh(&sc->wiphy_lock);
+
+	/* Start the primary wiphy */
+	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) {
+		ieee80211_wake_queue(hw, skb_queue);
+		goto unlock;
+	}
+
+	/* Now start the secondary wiphy queues */
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (!aphy)
+			continue;
+		if (aphy->state != ATH_WIPHY_ACTIVE)
+			continue;
+
+		hw = aphy->hw;
+		ieee80211_wake_queue(hw, skb_queue);
+		break;
+	}
+
+unlock:
+	spin_unlock_bh(&sc->wiphy_lock);
+}
+
+/* Go ahead and propagate information to all virtual wiphys, it won't hurt */
+void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue)
+{
+	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+	unsigned int i;
+
+	spin_lock_bh(&sc->wiphy_lock);
+
+	/* Stop the primary wiphy */
+	ieee80211_stop_queue(hw, skb_queue);
+
+	/* Now stop the secondary wiphy queues */
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (!aphy)
+			continue;
+		hw = aphy->hw;
+		ieee80211_stop_queue(hw, skb_queue);
+	}
+	spin_unlock_bh(&sc->wiphy_lock);
+}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 427bd1d..40d34ed 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -914,9 +914,10 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
 struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
 {
 	struct ath_txq *txq = NULL;
+	u16 skb_queue = skb_get_queue_mapping(skb);
 	int qnum;
 
-	qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
+	qnum = ath_get_hal_qnum(skb_queue, sc);
 	txq = &sc->tx.txq[qnum];
 
 	spin_lock_bh(&txq->axq_lock);
@@ -925,7 +926,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
 		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT,
 			  "TX queue: %d is full, depth: %d\n",
 			  qnum, txq->axq_depth);
-		ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
+		ath_mac80211_stop_queue(sc, skb_queue);
 		txq->stopped = 1;
 		spin_unlock_bh(&txq->axq_lock);
 		return NULL;
@@ -1704,8 +1705,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 		 * on the queue */
 		spin_lock_bh(&txq->axq_lock);
 		if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
-			ieee80211_stop_queue(sc->hw,
-				skb_get_queue_mapping(skb));
+			ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
 			txq->stopped = 1;
 		}
 		spin_unlock_bh(&txq->axq_lock);
@@ -1945,7 +1945,7 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
 	    sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
 		qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
 		if (qnum != -1) {
-			ieee80211_wake_queue(sc->hw, qnum);
+			ath_mac80211_start_queue(sc, qnum);
 			txq->stopped = 0;
 		}
 	}
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 9/9] ath9k: do not pass the entire descriptor to ath_rx_prepare()
  2009-11-03  3:07 ` [ath9k-devel] " Luis R. Rodriguez
@ 2009-11-03  3:08   ` Luis R. Rodriguez
  -1 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

Its not needed, so just pass the hardware RX status.
We'll be simplfying ath_rx_prepare() with code we can share
between ath9k and ath9k_htc. This will help make that code
easier to read and manage.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/recv.c |   70 +++++++++++++++++----------------
 1 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 10decfa..b36ecb2 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -106,7 +106,7 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
  * decryption key or real decryption error. This let us keep statistics there.
  */
 static int ath_rx_prepare(struct ieee80211_hw *hw,
-			  struct sk_buff *skb, struct ath_desc *ds,
+			  struct sk_buff *skb, struct ath_rx_status *rxstats,
 			  struct ieee80211_rx_status *rx_status, bool *decrypt_error,
 			  struct ath_softc *sc)
 {
@@ -121,7 +121,7 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	fc = hdr->frame_control;
 	memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
 
-	if (ds->ds_rxstat.rs_more) {
+	if (rxstats->rs_more) {
 		/*
 		 * Frame spans multiple descriptors; this cannot happen yet
 		 * as we don't support jumbograms. If not in monitor mode,
@@ -130,22 +130,22 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 		 */
 		if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
 			goto rx_next;
-	} else if (ds->ds_rxstat.rs_status != 0) {
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
+	} else if (rxstats->rs_status != 0) {
+		if (rxstats->rs_status & ATH9K_RXERR_CRC)
 			rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY)
+		if (rxstats->rs_status & ATH9K_RXERR_PHY)
 			goto rx_next;
 
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
+		if (rxstats->rs_status & ATH9K_RXERR_DECRYPT) {
 			*decrypt_error = true;
-		} else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
+		} else if (rxstats->rs_status & ATH9K_RXERR_MIC) {
 			if (ieee80211_is_ctl(fc))
 				/*
 				 * Sometimes, we get invalid
 				 * MIC failures on valid control frames.
 				 * Remove these mic errors.
 				 */
-				ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC;
+				rxstats->rs_status &= ~ATH9K_RXERR_MIC;
 			else
 				rx_status->flag |= RX_FLAG_MMIC_ERROR;
 		}
@@ -155,26 +155,26 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 		 * we also ignore the CRC error.
 		 */
 		if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
-			if (ds->ds_rxstat.rs_status &
+			if (rxstats->rs_status &
 			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
 			      ATH9K_RXERR_CRC))
 				goto rx_next;
 		} else {
-			if (ds->ds_rxstat.rs_status &
+			if (rxstats->rs_status &
 			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
 				goto rx_next;
 			}
 		}
 	}
 
-	ratecode = ds->ds_rxstat.rs_rate;
+	ratecode = rxstats->rs_rate;
 
 	if (ratecode & 0x80) {
 		/* HT rate */
 		rx_status->flag |= RX_FLAG_HT;
-		if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040)
+		if (rxstats->rs_flags & ATH9K_RX_2040)
 			rx_status->flag |= RX_FLAG_40MHZ;
-		if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
+		if (rxstats->rs_flags & ATH9K_RX_GI)
 			rx_status->flag |= RX_FLAG_SHORT_GI;
 		rx_status->rate_idx = ratecode & 0x7f;
 	} else {
@@ -203,31 +203,31 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	sta = ieee80211_find_sta(hw, hdr->addr2);
 	if (sta) {
 		an = (struct ath_node *) sta->drv_priv;
-		if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
-		   !ds->ds_rxstat.rs_moreaggr)
-			ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi);
+		if (rxstats->rs_rssi != ATH9K_RSSI_BAD &&
+		   !rxstats->rs_moreaggr)
+			ATH_RSSI_LPF(an->last_rssi, rxstats->rs_rssi);
 		last_rssi = an->last_rssi;
 	}
 	rcu_read_unlock();
 
 	if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-		ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi,
-					ATH_RSSI_EP_MULTIPLIER);
-	if (ds->ds_rxstat.rs_rssi < 0)
-		ds->ds_rxstat.rs_rssi = 0;
-	else if (ds->ds_rxstat.rs_rssi > 127)
-		ds->ds_rxstat.rs_rssi = 127;
+		rxstats->rs_rssi = ATH_EP_RND(last_rssi,
+					      ATH_RSSI_EP_MULTIPLIER);
+	if (rxstats->rs_rssi < 0)
+		rxstats->rs_rssi = 0;
+	else if (rxstats->rs_rssi > 127)
+		rxstats->rs_rssi = 127;
 
 	/* Update Beacon RSSI, this is used by ANI. */
 	if (ieee80211_is_beacon(fc))
-		sc->sc_ah->stats.avgbrssi = ds->ds_rxstat.rs_rssi;
+		sc->sc_ah->stats.avgbrssi = rxstats->rs_rssi;
 
-	rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
+	rx_status->mactime = ath_extend_tsf(sc, rxstats->rs_tstamp);
 	rx_status->band = hw->conf.channel->band;
 	rx_status->freq = hw->conf.channel->center_freq;
 	rx_status->noise = sc->ani.noise_floor;
-	rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + ds->ds_rxstat.rs_rssi;
-	rx_status->antenna = ds->ds_rxstat.rs_antenna;
+	rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rxstats->rs_rssi;
+	rx_status->antenna = rxstats->rs_antenna;
 
 	/*
 	 * Theory for reporting quality:
@@ -251,9 +251,9 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	 *
 	 */
 	if (conf_is_ht(&hw->conf))
-		rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
+		rx_status->qual =  rxstats->rs_rssi * 100 / 45;
 	else
-		rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 35;
+		rx_status->qual =  rxstats->rs_rssi * 100 / 35;
 
 	/* rssi can be more than 45 though, anything above that
 	 * should be considered at 100% */
@@ -658,6 +658,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 
 	struct ath_buf *bf;
 	struct ath_desc *ds;
+	struct ath_rx_status *rxstats;
 	struct sk_buff *skb = NULL, *requeue_skb;
 	struct ieee80211_rx_status rx_status;
 	struct ath_hw *ah = sc->sc_ah;
@@ -749,6 +750,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 
 		hdr = (struct ieee80211_hdr *) skb->data;
 		hw = ath_get_virt_hw(sc, hdr);
+		rxstats = &ds->ds_rxstat;
 
 		/*
 		 * If we're asked to flush receive queue, directly
@@ -757,14 +759,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		if (flush)
 			goto requeue;
 
-		if (!ds->ds_rxstat.rs_datalen)
+		if (!rxstats->rs_datalen)
 			goto requeue;
 
 		/* The status portion of the descriptor could get corrupted. */
-		if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
+		if (sc->rx.bufsize < rxstats->rs_datalen)
 			goto requeue;
 
-		if (!ath_rx_prepare(hw, skb, ds,
+		if (!ath_rx_prepare(hw, skb, rxstats,
 				    &rx_status, &decrypt_error, sc))
 			goto requeue;
 
@@ -784,7 +786,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 				 sc->rx.bufsize,
 				 DMA_FROM_DEVICE);
 
-		skb_put(skb, ds->ds_rxstat.rs_datalen);
+		skb_put(skb, rxstats->rs_datalen);
 
 		/* see if any padding is done by the hw and remove it */
 		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -804,7 +806,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 			skb_pull(skb, padsize);
 		}
 
-		keyix = ds->ds_rxstat.rs_keyix;
+		keyix = rxstats->rs_keyix;
 
 		if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
 			rx_status.flag |= RX_FLAG_DECRYPTED;
@@ -844,7 +846,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		 */
 		if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
 			if (++sc->rx.rxotherant >= 3)
-				ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
+				ath_setdefantenna(sc, rxstats->rs_antenna);
 		} else {
 			sc->rx.rxotherant = 0;
 		}
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [ath9k-devel] [RFT 9/9] ath9k: do not pass the entire descriptor to ath_rx_prepare()
@ 2009-11-03  3:08   ` Luis R. Rodriguez
  0 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-11-03  3:08 UTC (permalink / raw)
  To: ath9k-devel

Its not needed, so just pass the hardware RX status.
We'll be simplfying ath_rx_prepare() with code we can share
between ath9k and ath9k_htc. This will help make that code
easier to read and manage.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/recv.c |   70 +++++++++++++++++----------------
 1 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 10decfa..b36ecb2 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -106,7 +106,7 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
  * decryption key or real decryption error. This let us keep statistics there.
  */
 static int ath_rx_prepare(struct ieee80211_hw *hw,
-			  struct sk_buff *skb, struct ath_desc *ds,
+			  struct sk_buff *skb, struct ath_rx_status *rxstats,
 			  struct ieee80211_rx_status *rx_status, bool *decrypt_error,
 			  struct ath_softc *sc)
 {
@@ -121,7 +121,7 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	fc = hdr->frame_control;
 	memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
 
-	if (ds->ds_rxstat.rs_more) {
+	if (rxstats->rs_more) {
 		/*
 		 * Frame spans multiple descriptors; this cannot happen yet
 		 * as we don't support jumbograms. If not in monitor mode,
@@ -130,22 +130,22 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 		 */
 		if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
 			goto rx_next;
-	} else if (ds->ds_rxstat.rs_status != 0) {
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
+	} else if (rxstats->rs_status != 0) {
+		if (rxstats->rs_status & ATH9K_RXERR_CRC)
 			rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY)
+		if (rxstats->rs_status & ATH9K_RXERR_PHY)
 			goto rx_next;
 
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
+		if (rxstats->rs_status & ATH9K_RXERR_DECRYPT) {
 			*decrypt_error = true;
-		} else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
+		} else if (rxstats->rs_status & ATH9K_RXERR_MIC) {
 			if (ieee80211_is_ctl(fc))
 				/*
 				 * Sometimes, we get invalid
 				 * MIC failures on valid control frames.
 				 * Remove these mic errors.
 				 */
-				ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC;
+				rxstats->rs_status &= ~ATH9K_RXERR_MIC;
 			else
 				rx_status->flag |= RX_FLAG_MMIC_ERROR;
 		}
@@ -155,26 +155,26 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 		 * we also ignore the CRC error.
 		 */
 		if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
-			if (ds->ds_rxstat.rs_status &
+			if (rxstats->rs_status &
 			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
 			      ATH9K_RXERR_CRC))
 				goto rx_next;
 		} else {
-			if (ds->ds_rxstat.rs_status &
+			if (rxstats->rs_status &
 			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
 				goto rx_next;
 			}
 		}
 	}
 
-	ratecode = ds->ds_rxstat.rs_rate;
+	ratecode = rxstats->rs_rate;
 
 	if (ratecode & 0x80) {
 		/* HT rate */
 		rx_status->flag |= RX_FLAG_HT;
-		if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040)
+		if (rxstats->rs_flags & ATH9K_RX_2040)
 			rx_status->flag |= RX_FLAG_40MHZ;
-		if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
+		if (rxstats->rs_flags & ATH9K_RX_GI)
 			rx_status->flag |= RX_FLAG_SHORT_GI;
 		rx_status->rate_idx = ratecode & 0x7f;
 	} else {
@@ -203,31 +203,31 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	sta = ieee80211_find_sta(hw, hdr->addr2);
 	if (sta) {
 		an = (struct ath_node *) sta->drv_priv;
-		if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
-		   !ds->ds_rxstat.rs_moreaggr)
-			ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi);
+		if (rxstats->rs_rssi != ATH9K_RSSI_BAD &&
+		   !rxstats->rs_moreaggr)
+			ATH_RSSI_LPF(an->last_rssi, rxstats->rs_rssi);
 		last_rssi = an->last_rssi;
 	}
 	rcu_read_unlock();
 
 	if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-		ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi,
-					ATH_RSSI_EP_MULTIPLIER);
-	if (ds->ds_rxstat.rs_rssi < 0)
-		ds->ds_rxstat.rs_rssi = 0;
-	else if (ds->ds_rxstat.rs_rssi > 127)
-		ds->ds_rxstat.rs_rssi = 127;
+		rxstats->rs_rssi = ATH_EP_RND(last_rssi,
+					      ATH_RSSI_EP_MULTIPLIER);
+	if (rxstats->rs_rssi < 0)
+		rxstats->rs_rssi = 0;
+	else if (rxstats->rs_rssi > 127)
+		rxstats->rs_rssi = 127;
 
 	/* Update Beacon RSSI, this is used by ANI. */
 	if (ieee80211_is_beacon(fc))
-		sc->sc_ah->stats.avgbrssi = ds->ds_rxstat.rs_rssi;
+		sc->sc_ah->stats.avgbrssi = rxstats->rs_rssi;
 
-	rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
+	rx_status->mactime = ath_extend_tsf(sc, rxstats->rs_tstamp);
 	rx_status->band = hw->conf.channel->band;
 	rx_status->freq = hw->conf.channel->center_freq;
 	rx_status->noise = sc->ani.noise_floor;
-	rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + ds->ds_rxstat.rs_rssi;
-	rx_status->antenna = ds->ds_rxstat.rs_antenna;
+	rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rxstats->rs_rssi;
+	rx_status->antenna = rxstats->rs_antenna;
 
 	/*
 	 * Theory for reporting quality:
@@ -251,9 +251,9 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	 *
 	 */
 	if (conf_is_ht(&hw->conf))
-		rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
+		rx_status->qual =  rxstats->rs_rssi * 100 / 45;
 	else
-		rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 35;
+		rx_status->qual =  rxstats->rs_rssi * 100 / 35;
 
 	/* rssi can be more than 45 though, anything above that
 	 * should be considered at 100% */
@@ -658,6 +658,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 
 	struct ath_buf *bf;
 	struct ath_desc *ds;
+	struct ath_rx_status *rxstats;
 	struct sk_buff *skb = NULL, *requeue_skb;
 	struct ieee80211_rx_status rx_status;
 	struct ath_hw *ah = sc->sc_ah;
@@ -749,6 +750,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 
 		hdr = (struct ieee80211_hdr *) skb->data;
 		hw = ath_get_virt_hw(sc, hdr);
+		rxstats = &ds->ds_rxstat;
 
 		/*
 		 * If we're asked to flush receive queue, directly
@@ -757,14 +759,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		if (flush)
 			goto requeue;
 
-		if (!ds->ds_rxstat.rs_datalen)
+		if (!rxstats->rs_datalen)
 			goto requeue;
 
 		/* The status portion of the descriptor could get corrupted. */
-		if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
+		if (sc->rx.bufsize < rxstats->rs_datalen)
 			goto requeue;
 
-		if (!ath_rx_prepare(hw, skb, ds,
+		if (!ath_rx_prepare(hw, skb, rxstats,
 				    &rx_status, &decrypt_error, sc))
 			goto requeue;
 
@@ -784,7 +786,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 				 sc->rx.bufsize,
 				 DMA_FROM_DEVICE);
 
-		skb_put(skb, ds->ds_rxstat.rs_datalen);
+		skb_put(skb, rxstats->rs_datalen);
 
 		/* see if any padding is done by the hw and remove it */
 		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -804,7 +806,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 			skb_pull(skb, padsize);
 		}
 
-		keyix = ds->ds_rxstat.rs_keyix;
+		keyix = rxstats->rs_keyix;
 
 		if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
 			rx_status.flag |= RX_FLAG_DECRYPTED;
@@ -844,7 +846,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		 */
 		if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
 			if (++sc->rx.rxotherant >= 3)
-				ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
+				ath_setdefantenna(sc, rxstats->rs_antenna);
 		} else {
 			sc->rx.rxotherant = 0;
 		}
-- 
1.6.5.2.143.g8cc62

^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2009-11-03  3:08 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-03  3:07 [RFT 0/9] ath9k: few updates for virtual wiphy Luis R. Rodriguez
2009-11-03  3:07 ` [ath9k-devel] " Luis R. Rodriguez
2009-11-03  3:07 ` [RFT 1/9] ath9k: fix listening to idle requests Luis R. Rodriguez
2009-11-03  3:07   ` [ath9k-devel] " Luis R. Rodriguez
2009-11-03  3:07 ` [RFT 2/9] ath9k: update hw configuration for virtual wiphys Luis R. Rodriguez
2009-11-03  3:07   ` [ath9k-devel] " Luis R. Rodriguez
2009-11-03  3:07 ` [RFT 3/9] ath9k: simpify RX by calling ath_get_virt_hw() once Luis R. Rodriguez
2009-11-03  3:07   ` [ath9k-devel] " Luis R. Rodriguez
2009-11-03  3:07 ` [RFT 4/9] ath9k: use the passed ieee80211_hw on ath_rx_prepare() Luis R. Rodriguez
2009-11-03  3:07   ` [ath9k-devel] " Luis R. Rodriguez
2009-11-03  3:07 ` [RFT 5/9] ath9k: pass the ieee80211_hw on radio enable/disable Luis R. Rodriguez
2009-11-03  3:07   ` [ath9k-devel] " Luis R. Rodriguez
2009-11-03  3:07 ` [RFT 6/9] ath9k: use correct hw for tx aggregation TX completion Luis R. Rodriguez
2009-11-03  3:07   ` [ath9k-devel] " Luis R. Rodriguez
2009-11-03  3:07 ` [RFT 7/9] ath9k: use the right hw on ath_tx_setup_buffer() for HT Luis R. Rodriguez
2009-11-03  3:07   ` [ath9k-devel] " Luis R. Rodriguez
2009-11-03  3:08 ` [RFT 8/9] ath9k: handle low buffer space for virtual wiphys Luis R. Rodriguez
2009-11-03  3:08   ` [ath9k-devel] " Luis R. Rodriguez
2009-11-03  3:08 ` [RFT 9/9] ath9k: do not pass the entire descriptor to ath_rx_prepare() Luis R. Rodriguez
2009-11-03  3:08   ` [ath9k-devel] " Luis R. Rodriguez

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.