aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/wme.c')
-rw-r--r--net/mac80211/wme.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 3b873989992c..fdf52db95b33 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -54,10 +54,18 @@ static int wme_downgrade_ac(struct sk_buff *skb)
54} 54}
55 55
56static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, 56static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata,
57 struct sk_buff *skb) 57 struct sta_info *sta, struct sk_buff *skb)
58{ 58{
59 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
60
59 /* in case we are a client verify acm is not set for this ac */ 61 /* in case we are a client verify acm is not set for this ac */
60 while (unlikely(sdata->wmm_acm & BIT(skb->priority))) { 62 while (sdata->wmm_acm & BIT(skb->priority)) {
63 int ac = ieee802_1d_to_ac[skb->priority];
64
65 if (ifmgd->tx_tspec[ac].admitted_time &&
66 skb->priority == ifmgd->tx_tspec[ac].up)
67 return ac;
68
61 if (wme_downgrade_ac(skb)) { 69 if (wme_downgrade_ac(skb)) {
62 /* 70 /*
63 * This should not really happen. The AP has marked all 71 * This should not really happen. The AP has marked all
@@ -96,7 +104,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
96 p = ieee80211_get_qos_ctl(hdr); 104 p = ieee80211_get_qos_ctl(hdr);
97 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; 105 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
98 106
99 return ieee80211_downgrade_queue(sdata, skb); 107 return ieee80211_downgrade_queue(sdata, NULL, skb);
100} 108}
101 109
102/* Indicate which queue to use. */ 110/* Indicate which queue to use. */
@@ -108,6 +116,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
108 const u8 *ra = NULL; 116 const u8 *ra = NULL;
109 bool qos = false; 117 bool qos = false;
110 struct mac80211_qos_map *qos_map; 118 struct mac80211_qos_map *qos_map;
119 u16 ret;
111 120
112 if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { 121 if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
113 skb->priority = 0; /* required for correct WPA/11i MIC */ 122 skb->priority = 0; /* required for correct WPA/11i MIC */
@@ -139,6 +148,10 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
139 case NL80211_IFTYPE_ADHOC: 148 case NL80211_IFTYPE_ADHOC:
140 ra = skb->data; 149 ra = skb->data;
141 break; 150 break;
151 case NL80211_IFTYPE_OCB:
152 /* all stations are required to support WME */
153 qos = true;
154 break;
142 default: 155 default:
143 break; 156 break;
144 } 157 }
@@ -148,27 +161,29 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
148 if (sta) 161 if (sta)
149 qos = sta->sta.wme; 162 qos = sta->sta.wme;
150 } 163 }
151 rcu_read_unlock();
152 164
153 if (!qos) { 165 if (!qos) {
154 skb->priority = 0; /* required for correct WPA/11i MIC */ 166 skb->priority = 0; /* required for correct WPA/11i MIC */
155 return IEEE80211_AC_BE; 167 ret = IEEE80211_AC_BE;
168 goto out;
156 } 169 }
157 170
158 if (skb->protocol == sdata->control_port_protocol) { 171 if (skb->protocol == sdata->control_port_protocol) {
159 skb->priority = 7; 172 skb->priority = 7;
160 return ieee80211_downgrade_queue(sdata, skb); 173 goto downgrade;
161 } 174 }
162 175
163 /* use the data classifier to determine what 802.1d tag the 176 /* use the data classifier to determine what 802.1d tag the
164 * data frame has */ 177 * data frame has */
165 rcu_read_lock();
166 qos_map = rcu_dereference(sdata->qos_map); 178 qos_map = rcu_dereference(sdata->qos_map);
167 skb->priority = cfg80211_classify8021d(skb, qos_map ? 179 skb->priority = cfg80211_classify8021d(skb, qos_map ?
168 &qos_map->qos_map : NULL); 180 &qos_map->qos_map : NULL);
169 rcu_read_unlock();
170 181
171 return ieee80211_downgrade_queue(sdata, skb); 182 downgrade:
183 ret = ieee80211_downgrade_queue(sdata, sta, skb);
184 out:
185 rcu_read_unlock();
186 return ret;
172} 187}
173 188
174/** 189/**