All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update
@ 2014-01-31 13:37 ` Stanislaw Gruszka
  0 siblings, 0 replies; 10+ messages in thread
From: Stanislaw Gruszka @ 2014-01-31 13:37 UTC (permalink / raw)
  To: ath9k-devel; +Cc: Oleksij Rempel, linux-wireless

mac80211 ->sta_rc_update() callback must be atomic. Since we have to
take mutex and do other operations that can sleep when sending fimrware
commands to device, the only option to satisfy atomicity requirement of
->sta_rc_update(), that I can see, is introduce work_struct and defer
uploading new rates to that work.

I don't have h/w to test this patch. Since sta_rc_update() calls are
very unlikely, those who would like to test that patch should remove
my previous patch "ath9k_htc: make ->sta_rc_update atomic for most
calls" and possibly even modify mac80211 to call sta_rc_update(),
without actual reason, just to test changed ath9k_htc code.

Thanks
Stanislaw
---
 drivers/net/wireless/ath/ath9k/htc.h          |  2 +
 drivers/net/wireless/ath/ath9k/htc_drv_main.c | 60 +++++++++++++++++----------
 2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 58da346..99a2031 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -262,6 +262,8 @@ enum tid_aggr_state {
 struct ath9k_htc_sta {
 	u8 index;
 	enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
+	struct work_struct rc_update_work;
+	struct ath9k_htc_priv *htc_priv;
 };
 
 #define ATH9K_HTC_RXBUF 256
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index a57af9b..c9254a6 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1270,18 +1270,50 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
 	mutex_unlock(&priv->mutex);
 }
 
+static void ath9k_htc_sta_rc_update_work(struct work_struct *work)
+{
+	struct ath9k_htc_sta *ista =
+	    container_of(work, struct ath9k_htc_sta, rc_update_work);
+	struct ieee80211_sta *sta =
+	    container_of((void *)ista, struct ieee80211_sta, drv_priv);
+	struct ath9k_htc_priv *priv = ista->htc_priv;
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ath9k_htc_target_rate trate;
+
+	mutex_lock(&priv->mutex);
+	ath9k_htc_ps_wakeup(priv);
+
+	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
+	ath9k_htc_setup_rate(priv, sta, &trate);
+	if (!ath9k_htc_send_rate_cmd(priv, &trate))
+		ath_dbg(common, CONFIG,
+			"Supported rates for sta: %pM updated, rate caps: 0x%X\n",
+			sta->addr, be32_to_cpu(trate.capflags));
+	else
+		ath_dbg(common, CONFIG,
+			"Unable to update supported rates for sta: %pM\n",
+			sta->addr);
+
+	ath9k_htc_ps_restore(priv);
+	mutex_unlock(&priv->mutex);
+}
+
 static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
 			     struct ieee80211_vif *vif,
 			     struct ieee80211_sta *sta)
 {
 	struct ath9k_htc_priv *priv = hw->priv;
+	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
 	int ret;
 
 	mutex_lock(&priv->mutex);
 	ath9k_htc_ps_wakeup(priv);
 	ret = ath9k_htc_add_station(priv, vif, sta);
-	if (!ret)
+	if (!ret) {
+		INIT_WORK(&ista->rc_update_work, ath9k_htc_sta_rc_update_work);
+		ista->htc_priv = priv;
 		ath9k_htc_init_rate(priv, sta);
+	}
 	ath9k_htc_ps_restore(priv);
 	mutex_unlock(&priv->mutex);
 
@@ -1293,12 +1325,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
 				struct ieee80211_sta *sta)
 {
 	struct ath9k_htc_priv *priv = hw->priv;
-	struct ath9k_htc_sta *ista;
+	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
 	int ret;
 
+	cancel_work_sync(&ista->rc_update_work);
+
 	mutex_lock(&priv->mutex);
 	ath9k_htc_ps_wakeup(priv);
-	ista = (struct ath9k_htc_sta *) sta->drv_priv;
 	htc_sta_drain(priv->htc, ista->index);
 	ret = ath9k_htc_remove_station(priv, vif, sta);
 	ath9k_htc_ps_restore(priv);
@@ -1311,29 +1344,12 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
 				    struct ieee80211_vif *vif,
 				    struct ieee80211_sta *sta, u32 changed)
 {
-	struct ath9k_htc_priv *priv = hw->priv;
-	struct ath_common *common = ath9k_hw_common(priv->ah);
-	struct ath9k_htc_target_rate trate;
+	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
 
 	if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
 		return;
 
-	mutex_lock(&priv->mutex);
-	ath9k_htc_ps_wakeup(priv);
-
-	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
-	ath9k_htc_setup_rate(priv, sta, &trate);
-	if (!ath9k_htc_send_rate_cmd(priv, &trate))
-		ath_dbg(common, CONFIG,
-			"Supported rates for sta: %pM updated, rate caps: 0x%X\n",
-			sta->addr, be32_to_cpu(trate.capflags));
-	else
-		ath_dbg(common, CONFIG,
-			"Unable to update supported rates for sta: %pM\n",
-			sta->addr);
-
-	ath9k_htc_ps_restore(priv);
-	mutex_unlock(&priv->mutex);
+	schedule_work(&ista->rc_update_work);
 }
 
 static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
-- 
1.7.11.7


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

* [ath9k-devel] [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update
@ 2014-01-31 13:37 ` Stanislaw Gruszka
  0 siblings, 0 replies; 10+ messages in thread
From: Stanislaw Gruszka @ 2014-01-31 13:37 UTC (permalink / raw)
  To: ath9k-devel

mac80211 ->sta_rc_update() callback must be atomic. Since we have to
take mutex and do other operations that can sleep when sending fimrware
commands to device, the only option to satisfy atomicity requirement of
->sta_rc_update(), that I can see, is introduce work_struct and defer
uploading new rates to that work.

I don't have h/w to test this patch. Since sta_rc_update() calls are
very unlikely, those who would like to test that patch should remove
my previous patch "ath9k_htc: make ->sta_rc_update atomic for most
calls" and possibly even modify mac80211 to call sta_rc_update(),
without actual reason, just to test changed ath9k_htc code.

Thanks
Stanislaw
---
 drivers/net/wireless/ath/ath9k/htc.h          |  2 +
 drivers/net/wireless/ath/ath9k/htc_drv_main.c | 60 +++++++++++++++++----------
 2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 58da346..99a2031 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -262,6 +262,8 @@ enum tid_aggr_state {
 struct ath9k_htc_sta {
 	u8 index;
 	enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
+	struct work_struct rc_update_work;
+	struct ath9k_htc_priv *htc_priv;
 };
 
 #define ATH9K_HTC_RXBUF 256
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index a57af9b..c9254a6 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1270,18 +1270,50 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
 	mutex_unlock(&priv->mutex);
 }
 
+static void ath9k_htc_sta_rc_update_work(struct work_struct *work)
+{
+	struct ath9k_htc_sta *ista =
+	    container_of(work, struct ath9k_htc_sta, rc_update_work);
+	struct ieee80211_sta *sta =
+	    container_of((void *)ista, struct ieee80211_sta, drv_priv);
+	struct ath9k_htc_priv *priv = ista->htc_priv;
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ath9k_htc_target_rate trate;
+
+	mutex_lock(&priv->mutex);
+	ath9k_htc_ps_wakeup(priv);
+
+	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
+	ath9k_htc_setup_rate(priv, sta, &trate);
+	if (!ath9k_htc_send_rate_cmd(priv, &trate))
+		ath_dbg(common, CONFIG,
+			"Supported rates for sta: %pM updated, rate caps: 0x%X\n",
+			sta->addr, be32_to_cpu(trate.capflags));
+	else
+		ath_dbg(common, CONFIG,
+			"Unable to update supported rates for sta: %pM\n",
+			sta->addr);
+
+	ath9k_htc_ps_restore(priv);
+	mutex_unlock(&priv->mutex);
+}
+
 static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
 			     struct ieee80211_vif *vif,
 			     struct ieee80211_sta *sta)
 {
 	struct ath9k_htc_priv *priv = hw->priv;
+	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
 	int ret;
 
 	mutex_lock(&priv->mutex);
 	ath9k_htc_ps_wakeup(priv);
 	ret = ath9k_htc_add_station(priv, vif, sta);
-	if (!ret)
+	if (!ret) {
+		INIT_WORK(&ista->rc_update_work, ath9k_htc_sta_rc_update_work);
+		ista->htc_priv = priv;
 		ath9k_htc_init_rate(priv, sta);
+	}
 	ath9k_htc_ps_restore(priv);
 	mutex_unlock(&priv->mutex);
 
@@ -1293,12 +1325,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
 				struct ieee80211_sta *sta)
 {
 	struct ath9k_htc_priv *priv = hw->priv;
-	struct ath9k_htc_sta *ista;
+	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
 	int ret;
 
+	cancel_work_sync(&ista->rc_update_work);
+
 	mutex_lock(&priv->mutex);
 	ath9k_htc_ps_wakeup(priv);
-	ista = (struct ath9k_htc_sta *) sta->drv_priv;
 	htc_sta_drain(priv->htc, ista->index);
 	ret = ath9k_htc_remove_station(priv, vif, sta);
 	ath9k_htc_ps_restore(priv);
@@ -1311,29 +1344,12 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
 				    struct ieee80211_vif *vif,
 				    struct ieee80211_sta *sta, u32 changed)
 {
-	struct ath9k_htc_priv *priv = hw->priv;
-	struct ath_common *common = ath9k_hw_common(priv->ah);
-	struct ath9k_htc_target_rate trate;
+	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
 
 	if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
 		return;
 
-	mutex_lock(&priv->mutex);
-	ath9k_htc_ps_wakeup(priv);
-
-	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
-	ath9k_htc_setup_rate(priv, sta, &trate);
-	if (!ath9k_htc_send_rate_cmd(priv, &trate))
-		ath_dbg(common, CONFIG,
-			"Supported rates for sta: %pM updated, rate caps: 0x%X\n",
-			sta->addr, be32_to_cpu(trate.capflags));
-	else
-		ath_dbg(common, CONFIG,
-			"Unable to update supported rates for sta: %pM\n",
-			sta->addr);
-
-	ath9k_htc_ps_restore(priv);
-	mutex_unlock(&priv->mutex);
+	schedule_work(&ista->rc_update_work);
 }
 
 static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
-- 
1.7.11.7

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

* Re: [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update
  2014-01-31 13:37 ` [ath9k-devel] " Stanislaw Gruszka
@ 2014-01-31 18:24   ` Oleksij Rempel
  -1 siblings, 0 replies; 10+ messages in thread
From: Oleksij Rempel @ 2014-01-31 18:24 UTC (permalink / raw)
  To: Stanislaw Gruszka, ath9k-devel; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 5314 bytes --]

I have different HW. How can trigger sta_rc_update?


Am 31.01.2014 14:37, schrieb Stanislaw Gruszka:
> mac80211 ->sta_rc_update() callback must be atomic. Since we have to
> take mutex and do other operations that can sleep when sending fimrware
> commands to device, the only option to satisfy atomicity requirement of
> ->sta_rc_update(), that I can see, is introduce work_struct and defer
> uploading new rates to that work.
> 
> I don't have h/w to test this patch. Since sta_rc_update() calls are
> very unlikely, those who would like to test that patch should remove
> my previous patch "ath9k_htc: make ->sta_rc_update atomic for most
> calls" and possibly even modify mac80211 to call sta_rc_update(),
> without actual reason, just to test changed ath9k_htc code.
> 
> Thanks
> Stanislaw
> ---
>  drivers/net/wireless/ath/ath9k/htc.h          |  2 +
>  drivers/net/wireless/ath/ath9k/htc_drv_main.c | 60 +++++++++++++++++----------
>  2 files changed, 40 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
> index 58da346..99a2031 100644
> --- a/drivers/net/wireless/ath/ath9k/htc.h
> +++ b/drivers/net/wireless/ath/ath9k/htc.h
> @@ -262,6 +262,8 @@ enum tid_aggr_state {
>  struct ath9k_htc_sta {
>  	u8 index;
>  	enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
> +	struct work_struct rc_update_work;
> +	struct ath9k_htc_priv *htc_priv;
>  };
>  
>  #define ATH9K_HTC_RXBUF 256
> diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
> index a57af9b..c9254a6 100644
> --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
> +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
> @@ -1270,18 +1270,50 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
>  	mutex_unlock(&priv->mutex);
>  }
>  
> +static void ath9k_htc_sta_rc_update_work(struct work_struct *work)
> +{
> +	struct ath9k_htc_sta *ista =
> +	    container_of(work, struct ath9k_htc_sta, rc_update_work);
> +	struct ieee80211_sta *sta =
> +	    container_of((void *)ista, struct ieee80211_sta, drv_priv);
> +	struct ath9k_htc_priv *priv = ista->htc_priv;
> +	struct ath_common *common = ath9k_hw_common(priv->ah);
> +	struct ath9k_htc_target_rate trate;
> +
> +	mutex_lock(&priv->mutex);
> +	ath9k_htc_ps_wakeup(priv);
> +
> +	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
> +	ath9k_htc_setup_rate(priv, sta, &trate);
> +	if (!ath9k_htc_send_rate_cmd(priv, &trate))
> +		ath_dbg(common, CONFIG,
> +			"Supported rates for sta: %pM updated, rate caps: 0x%X\n",
> +			sta->addr, be32_to_cpu(trate.capflags));
> +	else
> +		ath_dbg(common, CONFIG,
> +			"Unable to update supported rates for sta: %pM\n",
> +			sta->addr);
> +
> +	ath9k_htc_ps_restore(priv);
> +	mutex_unlock(&priv->mutex);
> +}
> +
>  static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
>  			     struct ieee80211_vif *vif,
>  			     struct ieee80211_sta *sta)
>  {
>  	struct ath9k_htc_priv *priv = hw->priv;
> +	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
>  	int ret;
>  
>  	mutex_lock(&priv->mutex);
>  	ath9k_htc_ps_wakeup(priv);
>  	ret = ath9k_htc_add_station(priv, vif, sta);
> -	if (!ret)
> +	if (!ret) {
> +		INIT_WORK(&ista->rc_update_work, ath9k_htc_sta_rc_update_work);
> +		ista->htc_priv = priv;
>  		ath9k_htc_init_rate(priv, sta);
> +	}
>  	ath9k_htc_ps_restore(priv);
>  	mutex_unlock(&priv->mutex);
>  
> @@ -1293,12 +1325,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
>  				struct ieee80211_sta *sta)
>  {
>  	struct ath9k_htc_priv *priv = hw->priv;
> -	struct ath9k_htc_sta *ista;
> +	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
>  	int ret;
>  
> +	cancel_work_sync(&ista->rc_update_work);
> +
>  	mutex_lock(&priv->mutex);
>  	ath9k_htc_ps_wakeup(priv);
> -	ista = (struct ath9k_htc_sta *) sta->drv_priv;
>  	htc_sta_drain(priv->htc, ista->index);
>  	ret = ath9k_htc_remove_station(priv, vif, sta);
>  	ath9k_htc_ps_restore(priv);
> @@ -1311,29 +1344,12 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
>  				    struct ieee80211_vif *vif,
>  				    struct ieee80211_sta *sta, u32 changed)
>  {
> -	struct ath9k_htc_priv *priv = hw->priv;
> -	struct ath_common *common = ath9k_hw_common(priv->ah);
> -	struct ath9k_htc_target_rate trate;
> +	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
>  
>  	if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
>  		return;
>  
> -	mutex_lock(&priv->mutex);
> -	ath9k_htc_ps_wakeup(priv);
> -
> -	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
> -	ath9k_htc_setup_rate(priv, sta, &trate);
> -	if (!ath9k_htc_send_rate_cmd(priv, &trate))
> -		ath_dbg(common, CONFIG,
> -			"Supported rates for sta: %pM updated, rate caps: 0x%X\n",
> -			sta->addr, be32_to_cpu(trate.capflags));
> -	else
> -		ath_dbg(common, CONFIG,
> -			"Unable to update supported rates for sta: %pM\n",
> -			sta->addr);
> -
> -	ath9k_htc_ps_restore(priv);
> -	mutex_unlock(&priv->mutex);
> +	schedule_work(&ista->rc_update_work);
>  }
>  
>  static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
> 


-- 
Regards,
Oleksij


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 278 bytes --]

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

* [ath9k-devel] [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update
@ 2014-01-31 18:24   ` Oleksij Rempel
  0 siblings, 0 replies; 10+ messages in thread
From: Oleksij Rempel @ 2014-01-31 18:24 UTC (permalink / raw)
  To: ath9k-devel

I have different HW. How can trigger sta_rc_update?


Am 31.01.2014 14:37, schrieb Stanislaw Gruszka:
> mac80211 ->sta_rc_update() callback must be atomic. Since we have to
> take mutex and do other operations that can sleep when sending fimrware
> commands to device, the only option to satisfy atomicity requirement of
> ->sta_rc_update(), that I can see, is introduce work_struct and defer
> uploading new rates to that work.
> 
> I don't have h/w to test this patch. Since sta_rc_update() calls are
> very unlikely, those who would like to test that patch should remove
> my previous patch "ath9k_htc: make ->sta_rc_update atomic for most
> calls" and possibly even modify mac80211 to call sta_rc_update(),
> without actual reason, just to test changed ath9k_htc code.
> 
> Thanks
> Stanislaw
> ---
>  drivers/net/wireless/ath/ath9k/htc.h          |  2 +
>  drivers/net/wireless/ath/ath9k/htc_drv_main.c | 60 +++++++++++++++++----------
>  2 files changed, 40 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
> index 58da346..99a2031 100644
> --- a/drivers/net/wireless/ath/ath9k/htc.h
> +++ b/drivers/net/wireless/ath/ath9k/htc.h
> @@ -262,6 +262,8 @@ enum tid_aggr_state {
>  struct ath9k_htc_sta {
>  	u8 index;
>  	enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
> +	struct work_struct rc_update_work;
> +	struct ath9k_htc_priv *htc_priv;
>  };
>  
>  #define ATH9K_HTC_RXBUF 256
> diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
> index a57af9b..c9254a6 100644
> --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
> +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
> @@ -1270,18 +1270,50 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
>  	mutex_unlock(&priv->mutex);
>  }
>  
> +static void ath9k_htc_sta_rc_update_work(struct work_struct *work)
> +{
> +	struct ath9k_htc_sta *ista =
> +	    container_of(work, struct ath9k_htc_sta, rc_update_work);
> +	struct ieee80211_sta *sta =
> +	    container_of((void *)ista, struct ieee80211_sta, drv_priv);
> +	struct ath9k_htc_priv *priv = ista->htc_priv;
> +	struct ath_common *common = ath9k_hw_common(priv->ah);
> +	struct ath9k_htc_target_rate trate;
> +
> +	mutex_lock(&priv->mutex);
> +	ath9k_htc_ps_wakeup(priv);
> +
> +	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
> +	ath9k_htc_setup_rate(priv, sta, &trate);
> +	if (!ath9k_htc_send_rate_cmd(priv, &trate))
> +		ath_dbg(common, CONFIG,
> +			"Supported rates for sta: %pM updated, rate caps: 0x%X\n",
> +			sta->addr, be32_to_cpu(trate.capflags));
> +	else
> +		ath_dbg(common, CONFIG,
> +			"Unable to update supported rates for sta: %pM\n",
> +			sta->addr);
> +
> +	ath9k_htc_ps_restore(priv);
> +	mutex_unlock(&priv->mutex);
> +}
> +
>  static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
>  			     struct ieee80211_vif *vif,
>  			     struct ieee80211_sta *sta)
>  {
>  	struct ath9k_htc_priv *priv = hw->priv;
> +	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
>  	int ret;
>  
>  	mutex_lock(&priv->mutex);
>  	ath9k_htc_ps_wakeup(priv);
>  	ret = ath9k_htc_add_station(priv, vif, sta);
> -	if (!ret)
> +	if (!ret) {
> +		INIT_WORK(&ista->rc_update_work, ath9k_htc_sta_rc_update_work);
> +		ista->htc_priv = priv;
>  		ath9k_htc_init_rate(priv, sta);
> +	}
>  	ath9k_htc_ps_restore(priv);
>  	mutex_unlock(&priv->mutex);
>  
> @@ -1293,12 +1325,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
>  				struct ieee80211_sta *sta)
>  {
>  	struct ath9k_htc_priv *priv = hw->priv;
> -	struct ath9k_htc_sta *ista;
> +	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
>  	int ret;
>  
> +	cancel_work_sync(&ista->rc_update_work);
> +
>  	mutex_lock(&priv->mutex);
>  	ath9k_htc_ps_wakeup(priv);
> -	ista = (struct ath9k_htc_sta *) sta->drv_priv;
>  	htc_sta_drain(priv->htc, ista->index);
>  	ret = ath9k_htc_remove_station(priv, vif, sta);
>  	ath9k_htc_ps_restore(priv);
> @@ -1311,29 +1344,12 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
>  				    struct ieee80211_vif *vif,
>  				    struct ieee80211_sta *sta, u32 changed)
>  {
> -	struct ath9k_htc_priv *priv = hw->priv;
> -	struct ath_common *common = ath9k_hw_common(priv->ah);
> -	struct ath9k_htc_target_rate trate;
> +	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
>  
>  	if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
>  		return;
>  
> -	mutex_lock(&priv->mutex);
> -	ath9k_htc_ps_wakeup(priv);
> -
> -	memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
> -	ath9k_htc_setup_rate(priv, sta, &trate);
> -	if (!ath9k_htc_send_rate_cmd(priv, &trate))
> -		ath_dbg(common, CONFIG,
> -			"Supported rates for sta: %pM updated, rate caps: 0x%X\n",
> -			sta->addr, be32_to_cpu(trate.capflags));
> -	else
> -		ath_dbg(common, CONFIG,
> -			"Unable to update supported rates for sta: %pM\n",
> -			sta->addr);
> -
> -	ath9k_htc_ps_restore(priv);
> -	mutex_unlock(&priv->mutex);
> +	schedule_work(&ista->rc_update_work);
>  }
>  
>  static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
> 


-- 
Regards,
Oleksij

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 278 bytes
Desc: OpenPGP digital signature
Url : http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20140131/2bdc2372/attachment.pgp 

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

* Re: [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update
  2014-01-31 18:24   ` [ath9k-devel] " Oleksij Rempel
@ 2014-01-31 19:38     ` Stanislaw Gruszka
  -1 siblings, 0 replies; 10+ messages in thread
From: Stanislaw Gruszka @ 2014-01-31 19:38 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: ath9k-devel, linux-wireless

On Fri, Jan 31, 2014 at 07:24:05PM +0100, Oleksij Rempel wrote:
> I have different HW. How can trigger sta_rc_update?

Below patch should trigger it when any management frame is received
from know sta and print information about it. 

Thanks
Stanislaw

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index c9254a6..5cfc98c 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1346,9 +1346,7 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
 {
 	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
 
-	if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
-		return;
-
+	printk("%s: schedule work\n", __func__);
 	schedule_work(&ista->rc_update_work);
 }
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c24ca0d..642b326 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2847,8 +2847,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
 	rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME;
 	skb_queue_tail(&sdata->skb_queue, rx->skb);
 	ieee80211_queue_work(&rx->local->hw, &sdata->work);
-	if (rx->sta)
+	if (rx->sta) {
 		rx->sta->rx_packets++;
+		drv_sta_rc_update(rx->local, rx->sta->sdata, &rx->sta->sta, 0);
+	}
 
 	return RX_QUEUED;
 }


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

* [ath9k-devel] [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update
@ 2014-01-31 19:38     ` Stanislaw Gruszka
  0 siblings, 0 replies; 10+ messages in thread
From: Stanislaw Gruszka @ 2014-01-31 19:38 UTC (permalink / raw)
  To: ath9k-devel

On Fri, Jan 31, 2014 at 07:24:05PM +0100, Oleksij Rempel wrote:
> I have different HW. How can trigger sta_rc_update?

Below patch should trigger it when any management frame is received
from know sta and print information about it. 

Thanks
Stanislaw

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index c9254a6..5cfc98c 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1346,9 +1346,7 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
 {
 	struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
 
-	if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
-		return;
-
+	printk("%s: schedule work\n", __func__);
 	schedule_work(&ista->rc_update_work);
 }
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c24ca0d..642b326 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2847,8 +2847,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
 	rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME;
 	skb_queue_tail(&sdata->skb_queue, rx->skb);
 	ieee80211_queue_work(&rx->local->hw, &sdata->work);
-	if (rx->sta)
+	if (rx->sta) {
 		rx->sta->rx_packets++;
+		drv_sta_rc_update(rx->local, rx->sta->sdata, &rx->sta->sta, 0);
+	}
 
 	return RX_QUEUED;
 }

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

* Re: [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update
  2014-01-31 19:38     ` [ath9k-devel] " Stanislaw Gruszka
@ 2014-02-02  9:02       ` Oleksij Rempel
  -1 siblings, 0 replies; 10+ messages in thread
From: Oleksij Rempel @ 2014-02-02  9:02 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: ath9k-devel, linux-wireless

[-- Attachment #1: Type: text/plain, Size: 418 bytes --]

Am 31.01.2014 20:38, schrieb Stanislaw Gruszka:
> On Fri, Jan 31, 2014 at 07:24:05PM +0100, Oleksij Rempel wrote:
>> I have different HW. How can trigger sta_rc_update?
> 
> Below patch should trigger it when any management frame is received
> from know sta and print information about it. 

It seems to work,
a least it didn't crashed. I was able to trigger it only in IBSS mode.

-- 
Regards,
Oleksij


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 278 bytes --]

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

* [ath9k-devel] [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update
@ 2014-02-02  9:02       ` Oleksij Rempel
  0 siblings, 0 replies; 10+ messages in thread
From: Oleksij Rempel @ 2014-02-02  9:02 UTC (permalink / raw)
  To: ath9k-devel

Am 31.01.2014 20:38, schrieb Stanislaw Gruszka:
> On Fri, Jan 31, 2014 at 07:24:05PM +0100, Oleksij Rempel wrote:
>> I have different HW. How can trigger sta_rc_update?
> 
> Below patch should trigger it when any management frame is received
> from know sta and print information about it. 

It seems to work,
a least it didn't crashed. I was able to trigger it only in IBSS mode.

-- 
Regards,
Oleksij

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 278 bytes
Desc: OpenPGP digital signature
Url : http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20140202/6865ec30/attachment.pgp 

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

* Re: [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update
  2014-02-02  9:02       ` [ath9k-devel] " Oleksij Rempel
@ 2014-02-03 10:39         ` Stanislaw Gruszka
  -1 siblings, 0 replies; 10+ messages in thread
From: Stanislaw Gruszka @ 2014-02-03 10:39 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: ath9k-devel, linux-wireless

On Sun, Feb 02, 2014 at 10:02:15AM +0100, Oleksij Rempel wrote:
> Am 31.01.2014 20:38, schrieb Stanislaw Gruszka:
> > On Fri, Jan 31, 2014 at 07:24:05PM +0100, Oleksij Rempel wrote:
> >> I have different HW. How can trigger sta_rc_update?
> > 
> > Below patch should trigger it when any management frame is received
> > from know sta and print information about it. 
> 
> It seems to work,
> a least it didn't crashed. I was able to trigger it only in IBSS mode.

Looks ieee80211_rx_h_mgmt with know STA is not used for Managed mode as
frequent as I thought.

Thanks for testing! I'll post the patch shortly.
Stanislaw


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

* [ath9k-devel] [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update
@ 2014-02-03 10:39         ` Stanislaw Gruszka
  0 siblings, 0 replies; 10+ messages in thread
From: Stanislaw Gruszka @ 2014-02-03 10:39 UTC (permalink / raw)
  To: ath9k-devel

On Sun, Feb 02, 2014 at 10:02:15AM +0100, Oleksij Rempel wrote:
> Am 31.01.2014 20:38, schrieb Stanislaw Gruszka:
> > On Fri, Jan 31, 2014 at 07:24:05PM +0100, Oleksij Rempel wrote:
> >> I have different HW. How can trigger sta_rc_update?
> > 
> > Below patch should trigger it when any management frame is received
> > from know sta and print information about it. 
> 
> It seems to work,
> a least it didn't crashed. I was able to trigger it only in IBSS mode.

Looks ieee80211_rx_h_mgmt with know STA is not used for Managed mode as
frequent as I thought.

Thanks for testing! I'll post the patch shortly.
Stanislaw

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

end of thread, other threads:[~2014-02-03 10:39 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-31 13:37 [RFC/RFT] ath9k_htc: avoid scheduling while atomic on sta_rc_update Stanislaw Gruszka
2014-01-31 13:37 ` [ath9k-devel] " Stanislaw Gruszka
2014-01-31 18:24 ` Oleksij Rempel
2014-01-31 18:24   ` [ath9k-devel] " Oleksij Rempel
2014-01-31 19:38   ` Stanislaw Gruszka
2014-01-31 19:38     ` [ath9k-devel] " Stanislaw Gruszka
2014-02-02  9:02     ` Oleksij Rempel
2014-02-02  9:02       ` [ath9k-devel] " Oleksij Rempel
2014-02-03 10:39       ` Stanislaw Gruszka
2014-02-03 10:39         ` [ath9k-devel] " Stanislaw Gruszka

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.