From f438ceb81d424cb90a5a1aad569056bd7c2ab4c5 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 18 Oct 2016 23:12:12 +0300 Subject: mac80211: uapsd_queues is in QoS IE order The uapsd_queue field is in QoS IE order and not in IEEE80211_AC_*'s order. This means that mac80211 would get confused between BK and BE which is certainly not such a big deal but needs to be fixed. Signed-off-by: Emmanuel Grumbach Signed-off-by: Luca Coelho Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/mlme.c | 2 +- net/mac80211/rx.c | 3 ++- net/mac80211/sta_info.c | 13 ++++++++----- net/mac80211/util.c | 7 +++++++ 5 files changed, 20 insertions(+), 7 deletions(-) (limited to 'net/mac80211') diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 42d194a04e1a..b4e2b6cf4099 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -84,6 +84,8 @@ struct ieee80211_local; #define IEEE80211_DEFAULT_MAX_SP_LEN \ IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL +extern const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS]; + #define IEEE80211_DEAUTH_FRAME_LEN (24 /* hdr */ + 2 /* reason */) #define IEEE80211_MAX_NAN_INSTANCE_ID 255 diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7486f2dab4ba..c8d3a9b02fb6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3193,7 +3193,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, uapsd_queues = 0; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) if (sdata->tx_conf[ac].uapsd) - uapsd_queues |= BIT(ac); + uapsd_queues |= ieee80211_ac_to_qos_mask[ac]; } cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len, uapsd_queues); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 837d56261bb2..21a8947651e1 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1401,7 +1401,8 @@ void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *pubsta, u8 tid) * enabled queues, but for now we only implement uAPSD w/o * TSPEC changes to the ACs, so they're always the same. */ - if (!(sta->sta.uapsd_queues & BIT(ac)) && tid != IEEE80211_NUM_TIDS) + if (!(sta->sta.uapsd_queues & ieee80211_ac_to_qos_mask[ac]) && + tid != IEEE80211_NUM_TIDS) return; /* if we are in a service period, do nothing */ diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ab91e1e1b8ec..236d47e76ced 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -709,7 +709,7 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { unsigned long tids; - if (ignore_for_tim & BIT(ac)) + if (ignore_for_tim & ieee80211_ac_to_qos_mask[ac]) continue; indicate_tim |= !skb_queue_empty(&sta->tx_filtered[ac]) || @@ -1389,7 +1389,7 @@ ieee80211_sta_ps_more_data(struct sta_info *sta, u8 ignored_acs, return true; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { - if (ignored_acs & BIT(ac)) + if (ignored_acs & ieee80211_ac_to_qos_mask[ac]) continue; if (!skb_queue_empty(&sta->tx_filtered[ac]) || @@ -1414,7 +1414,7 @@ ieee80211_sta_ps_get_frames(struct sta_info *sta, int n_frames, u8 ignored_acs, for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { unsigned long tids; - if (ignored_acs & BIT(ac)) + if (ignored_acs & ieee80211_ac_to_qos_mask[ac]) continue; tids = ieee80211_tids_for_ac(ac); @@ -1482,7 +1482,7 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, BIT(find_highest_prio_tid(driver_release_tids)); if (skb_queue_empty(&frames) && !driver_release_tids) { - int tid; + int tid, ac; /* * For PS-Poll, this can only happen due to a race condition @@ -1500,7 +1500,10 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, */ /* This will evaluate to 1, 3, 5 or 7. */ - tid = 7 - ((ffs(~ignored_acs) - 1) << 1); + for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) + if (ignored_acs & BIT(ac)) + continue; + tid = 7 - 2 * ac; ieee80211_send_null_response(sta, tid, reason, true, false); } else if (!driver_release_tids) { diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 031273a61d27..7f24bdc68f71 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3452,3 +3452,10 @@ void ieee80211_txq_get_depth(struct ieee80211_txq *txq, *byte_cnt = txqi->tin.backlog_bytes + frag_bytes; } EXPORT_SYMBOL(ieee80211_txq_get_depth); + +const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS] = { + IEEE80211_WMM_IE_STA_QOSINFO_AC_VO, + IEEE80211_WMM_IE_STA_QOSINFO_AC_VI, + IEEE80211_WMM_IE_STA_QOSINFO_AC_BE, + IEEE80211_WMM_IE_STA_QOSINFO_AC_BK +}; -- cgit