[PATCHv2] offchannel: Cancel the pending_action TX wait, before starting new one.
From: tkc Before the tx_status is received for the action frame, if we get another request, we respond to that by freeing the memory for pending_action_tx, but we don't cancel the TX wait, so in the kernel the ROC will not be cancelled. Due to above issue, wpa_supplicant assumes that all pending RoC's are cancelled and proceeds with interface creation and connection, where as state in mac80211/driver will be roc_in_progress. This is leading to issues at driver level. Signed-off-by: Chaitanya T K --- V2: Fix 2 from's. Remove the unnecessary braces. --- wpa_supplicant/offchannel.c | 12 +++- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/wpa_supplicant/offchannel.c b/wpa_supplicant/offchannel.c index 6b3f83c..581c5f6 100644 --- a/wpa_supplicant/offchannel.c +++ b/wpa_supplicant/offchannel.c @@ -253,15 +253,9 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq, wpa_s->pending_action_tx_status_cb = tx_cb; - if (wpa_s->pending_action_tx) { - wpa_printf(MSG_DEBUG, "Off-channel: Dropped pending Action " - "frame TX to " MACSTR " (pending_action_tx=%p)", - MAC2STR(wpa_s->pending_action_dst), - wpa_s->pending_action_tx); - wpa_hexdump_buf(MSG_MSGDUMP, "Pending TX frame", - wpa_s->pending_action_tx); - wpabuf_free(wpa_s->pending_action_tx); - } + if (wpa_s->pending_action_tx) + offchannel_send_action_done(wpa_s); + wpa_s->pending_action_tx_done = 0; wpa_s->pending_action_tx = wpabuf_alloc(len); if (wpa_s->pending_action_tx == NULL) { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] offchannel: Cancel the pending_action TX wait, before starting new one.
From: tkc From: Chaitanya T K Before the tx_status is received for the action frame, if we get another request, we respond to that by freeing the memory for pending_action_tx, but we don't cancel the TX wait, so in the kernel the ROC will not be cancelled. Due to above issue, wpa_supplicant assumes that all pending RoC's are cancelled and proceeds with interface creation and connection, where as state in mac80211/driver will be roc_in_progress. This is leading to issues at driver level. Signed-off-by: Chaitanya T K --- wpa_supplicant/offchannel.c |8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/wpa_supplicant/offchannel.c b/wpa_supplicant/offchannel.c index 6b3f83c..bd2f905 100644 --- a/wpa_supplicant/offchannel.c +++ b/wpa_supplicant/offchannel.c @@ -254,13 +254,7 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq, wpa_s->pending_action_tx_status_cb = tx_cb; if (wpa_s->pending_action_tx) { - wpa_printf(MSG_DEBUG, "Off-channel: Dropped pending Action " - "frame TX to " MACSTR " (pending_action_tx=%p)", - MAC2STR(wpa_s->pending_action_dst), - wpa_s->pending_action_tx); - wpa_hexdump_buf(MSG_MSGDUMP, "Pending TX frame", - wpa_s->pending_action_tx); - wpabuf_free(wpa_s->pending_action_tx); + offchannel_send_action_done(wpa_s); } wpa_s->pending_action_tx_done = 0; wpa_s->pending_action_tx = wpabuf_alloc(len); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mac80211: Handle sleep requirements for channel context ops.
From: Chaitanya T K Channel context OPs can sleep, so add might_sleep() and also document sleep requirements for those OPs. Signed-off-by: Chaitanya T K --- include/net/mac80211.h| 6 ++ net/mac80211/driver-ops.c | 2 ++ net/mac80211/driver-ops.h | 10 ++ 3 files changed, 18 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 4b9dd07..3876739 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3170,18 +3170,24 @@ enum ieee80211_reconfig_type { * The callback is optional and can sleep. * * @add_chanctx: Notifies device driver about new channel context creation. + * This callback may sleep. * @remove_chanctx: Notifies device driver about channel context destruction. + * This callback may sleep. * @change_chanctx: Notifies device driver about channel context changes that * may happen when combining different virtual interfaces on the same * channel context with different settings + * This callback may sleep. * @assign_vif_chanctx: Notifies device driver about channel context being bound * to vif. Possible use is for hw queue remapping. + * This callback may sleep. * @unassign_vif_chanctx: Notifies device driver about channel context being * unbound from vif. + * This callback may sleep. * @switch_vif_chanctx: switch a number of vifs from one chanctx to * another, as specified in the list of * @ieee80211_vif_chanctx_switch passed to the driver, according * to the mode defined in &ieee80211_chanctx_switch_mode. + * This callback may sleep. * * @start_ap: Start operation on the AP interface, this is called after all the * information in bss_conf is set and beacon can be retrieved. A channel diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c index a1d5431..578403a 100644 --- a/net/mac80211/driver-ops.c +++ b/net/mac80211/driver-ops.c @@ -192,6 +192,8 @@ int drv_switch_vif_chanctx(struct ieee80211_local *local, int ret = 0; int i; + might_sleep(); + if (!local->ops->switch_vif_chanctx) return -EOPNOTSUPP; diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 3098709..5869bc6 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -871,6 +871,8 @@ static inline int drv_add_chanctx(struct ieee80211_local *local, { int ret = -EOPNOTSUPP; + might_sleep(); + trace_drv_add_chanctx(local, ctx); if (local->ops->add_chanctx) ret = local->ops->add_chanctx(&local->hw, &ctx->conf); @@ -884,6 +886,8 @@ static inline int drv_add_chanctx(struct ieee80211_local *local, static inline void drv_remove_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { + might_sleep(); + if (WARN_ON(!ctx->driver_present)) return; @@ -898,6 +902,8 @@ static inline void drv_change_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *ctx, u32 changed) { + might_sleep(); + trace_drv_change_chanctx(local, ctx, changed); if (local->ops->change_chanctx) { WARN_ON_ONCE(!ctx->driver_present); @@ -912,6 +918,8 @@ static inline int drv_assign_vif_chanctx(struct ieee80211_local *local, { int ret = 0; + might_sleep(); + if (!check_sdata_in_driver(sdata)) return -EIO; @@ -931,6 +939,8 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, struct ieee80211_chanctx *ctx) { + might_sleep(); + if (!check_sdata_in_driver(sdata)) return; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V4] mac80211: minstrel_ht: Handle Dynamic SMPS state of the peer.
In case of Dynamic SMPS enable RTS/CTS for all rates. Signed-off-by: Chaitanya T K --- V4: Updated commit log and fixed indent. V3: Moved the check to set_rate. V2:Fix indent and add signoff. --- net/mac80211/rc80211_minstrel_ht.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 7430a1d..c8753ce 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -867,7 +867,13 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, else idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; - if (offset > 0) { + /* Enable RTS/CTS for below cases. +* 1) To Handle STA's SMPS State, if Nss > 1. +* 2) 2nd and 3rd Rates, as 1st Rate Failed. +*/ + if (offset > 0 && + (mi->sta->smps_mode == IEEE80211_SMPS_DYNAMIC && +group->streams > 1)) { ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; flags |= IEEE80211_TX_RC_USE_RTS_CTS; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3] mac80211: wowlan: suspend: Fix power save state stuck in ACTIVE caused by race between suspend and Tx packet.
From: Chaitanya T K Background: When wowlan is enabled, the chipset stays in low power state maintaining the connection as per the mac80211 power save state. If suspended during TX in progress, there can be race where the driver is put of of power-save due to TX and during suspend dynamic_ps_time is cancelled and TX packet is flushed, leaving the driver in ACTIVE even after resuming until dynamic_ps_time puts driver back in DOZE. (Which only happens if there is another TX). This can lead to high power consumption of chipset during (or) after resuming. Signed-off-by: Chaitanya T K --- V2: Updated Comment and Commit log. --- net/mac80211/pm.c | 16 +++ 1 file changed, 16 insertions(+) diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index ac6ad62..8149a3d 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -76,6 +76,22 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) if (sdata->vif.type != NL80211_IFTYPE_STATION) continue; ieee80211_mgd_quiesce(sdata); + /* If suspended during TX in progress, and wowlan +* is enabled (connection will be active) there +* can be a race where the driver is put out +* of power-save due to TX and during suspend +* dynamic_ps_timer is cancelled and TX packet +* is flushed, leaving the driver in ACTIVE even +* after resuming until dynamic_ps_timer puts +* driver back in DOZE. +*/ + if (sdata->u.mgd.associated && + sdata->u.mgd.powersave && +!(local->hw.conf.flags & IEEE80211_CONF_PS)) { + local->hw.conf.flags |= IEEE80211_CONF_PS; + ieee80211_hw_config(local, + IEEE80211_CONF_CHANGE_PS); + } } err = drv_suspend(local, wowlan); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3] mac80211: minstrel_ht: Handle Dynamic SMPS state of the peer.
In case of Dynamic SMPS enable RTS/CTS for all rates. Signed-off-by: Chaitanya T K --- V3: Moved the check to set_rate. V2: Fix indent and add signoff. --- net/mac80211/rc80211_minstrel_ht.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 7430a1d..600208f 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -867,7 +867,15 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, else idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; - if (offset > 0) { + /* Enable RTS/CTS for below cases. +* 1) Handle STA's SMPS State, if Nss > 1. +*a. Use RTS_CTS, if STA is in Dynamic SMPS Mode +*b. Mark Nss > 1 as unsupported, if STA is in static SMPS mode +* 2) 2nd and 3rd Rates, as 1st Rate Failed. +*/ + if ((mi->sta->smps_mode == IEEE80211_SMPS_DYNAMIC && +group->streams > 1) || +offset > 0) { ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; flags |= IEEE80211_TX_RC_USE_RTS_CTS; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2] mac80211: Minstrel HT: Handle all SMPS states of the peer STA.
From: Chaitanya Tata In case of Dynamic SMPS enable RTS/CTS for all rates. In case of Static SMPS mark the Nss > 1 rates as not supported. Signed-off-by: Chaitanya T K --- V2: Fix the Indent and Sign off missing. --- net/mac80211/rc80211_minstrel_ht.c | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 7430a1d..0889c22 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -1176,9 +1176,16 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, nss = minstrel_mcs_groups[i].streams; - /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */ - if (sta->smps_mode == IEEE80211_SMPS_STATIC && nss > 1) - continue; + /* Handle STA's SMPS State, if Nss > 1. + * a. Use RTS_CTS, if STA is in Dynamic SMPS Mode + * b. Mark Nss > 1 as unsupported, if STA is in static SMPS mode + */ + if (nss > 1) { + if (sta->smps_mode == IEEE80211_SMPS_DYNAMIC) + gflags |= IEEE80211_TX_RC_USE_RTS_CTS; + else if (sta->smps_mode == IEEE80211_SMPS_STATIC) + continue; + } /* HT rate */ if (gflags & IEEE80211_TX_RC_MCS) { -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mac80211: Minstrel HT: Handle all SMPS states of the peer STA.
From: Chaitanya Tata In case of Dynamic SMPS enable RTS/CTS for all rates. In case of Static SMPS mark the Nss > 1 rates as not supported. --- net/mac80211/rc80211_minstrel_ht.c | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 7430a1d..fdc08d0 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -1176,9 +1176,16 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, nss = minstrel_mcs_groups[i].streams; - /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */ - if (sta->smps_mode == IEEE80211_SMPS_STATIC && nss > 1) - continue; + /* Handle STA's SMPS State, if Nss > 1. + * a. Use RTS_CTS, if STA is in Dynamic SMPS Mode + * b. Mark Nss > 1 as unsupported, if STA is in static SMPS mode + */ + if (nss > 1) { + if (sta->smps_mode == IEEE80211_SMPS_DYNAMIC) + gflags |= IEEE80211_TX_RC_USE_RTS_CTS; + else if (sta->smps_mode == IEEE80211_SMPS_STATIC) + continue; + } /* HT rate */ if (gflags & IEEE80211_TX_RC_MCS) { -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2] mac80211: Fix power save state stuck in ACTIVE caused by race between suspend and Tx packet.
From: Chaitanya T K If suspended during TX in progress, there can be race where the driver is put of of power-save due to TX and during suspend dynamic_ps_time is cancelled and TX packet is flushed, leaving the driver in ACTIVE even after resuming until dynamic_ps_time puts driver back in DOZE. (Which only happens if there is another TX). This can lead high power consumption of chipset during (or) after resuming also. Signed-off-by: Chaitanya T K --- V2: Updated Comment and Commit log. --- net/mac80211/pm.c | 15 +++ net/mac80211/pm.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index ac6ad62..cc311be 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -76,6 +76,21 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) if (sdata->vif.type != NL80211_IFTYPE_STATION) continue; ieee80211_mgd_quiesce(sdata); + /* If suspended during TX in progress, there +* can be a race where the driver is put out +* of power-save due to TX and during suspend +* dynamic_ps_timer is cancelled and TX packet +* is flushed, leaving the driver in ACTIVE even +* after resuming until dynamic_ps_timer puts +* driver back in DOZE. +*/ + if (sdata->u.mgd.associated && + sdata->u.mgd.powersave && +!(local->hw.conf.flags & IEEE80211_CONF_PS)) { + local->hw.conf.flags |= IEEE80211_CONF_PS; + ieee80211_hw_config(local, + IEEE80211_CONF_CHANGE_PS); + } } err = drv_suspend(local, wowlan); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mac80211: Fix power save state stuck in ACTIVE caused by race between suspend and Tx packet.
From: Chaitanya T K If we receive suspend after TX path has executed dynamic ps disable work, the driver will be in ACTIVE state during suspend and even after it resumes. As before suspend all data packets are flushed it is safe to put the driver in to sleep for optimal power during suspend or up on resume. Signed-off-by: Chaitanya T K --- net/mac80211/pm.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index ac6ad62..c9d71c2 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -76,6 +76,21 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) if (sdata->vif.type != NL80211_IFTYPE_STATION) continue; ieee80211_mgd_quiesce(sdata); + /* This is to handle a race where suspend +* is invoked after dynamic ps work disables +* power save due to TX. This causes the driver +* to be stuck in ACTIVE during suspend and +* after resume unless there is another TX, +* after which the dynamic ps puts driver +* back to DOZE. +*/ + if (sdata->u.mgd.associated && + sdata->u.mgd.powersave && +!(local->hw.conf.flags & IEEE80211_CONF_PS)) { + local->hw.conf.flags |= IEEE80211_CONF_PS; + ieee80211_hw_config(local, + IEEE80211_CONF_CHANGE_PS); + } } err = drv_suspend(local, wowlan); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] cfg80211: Don't re-use the skb for larger NL messages.
cfg80211 reuses the skb before asking for a fresh on from genl framework, this works efficiently for smaller messages but NLM_F_DUMP is normally used to transport larger data normally > PAGE_SIZE, so if the message occupies more than GOODSIZE its better to ask for a new, saves couple of hanshakes with the driver. This improves the time to get the DUMP response across to user space. Signed-off-by: Chaitanya T K --- V2: no new line, so commit log was cut off. Updated now. --- net/wireless/nl80211.c | 4 1 file changed, 4 insertions(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c264eff..152bd0c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -7636,6 +7636,10 @@ static int nl80211_testmode_dump(struct sk_buff *skb, } genlmsg_end(skb, hdr); + + /* Don't re-use skb, when we know nla_put fails*/ + if (skb->len > NLMSG_GOODSIZE / 2) + break; } err = skb->len; -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] cfg80211: Don't re-use the skb for larger NL messages.
This improves the time to get the DUMP response across to user space. Signed-off-by: Chaitanya T K --- net/wireless/nl80211.c | 4 1 file changed, 4 insertions(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c264eff..152bd0c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -7636,6 +7636,10 @@ static int nl80211_testmode_dump(struct sk_buff *skb, } genlmsg_end(skb, hdr); + + /* Don't re-use skb, when we know nla_put fails*/ + if (skb->len > NLMSG_GOODSIZE / 2) + break; } err = skb->len; -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html