diff options
-rw-r--r-- | net/mac80211/debugfs.c | 94 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 14 | ||||
-rw-r--r-- | net/mac80211/main.c | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 2 | ||||
-rw-r--r-- | net/mac80211/work.c | 4 |
5 files changed, 113 insertions, 3 deletions
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index e4b54093d41b..b3bc32b62a5a 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -158,6 +158,98 @@ static const struct file_operations noack_ops = { | |||
158 | .open = mac80211_open_file_generic | 158 | .open = mac80211_open_file_generic |
159 | }; | 159 | }; |
160 | 160 | ||
161 | static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf, | ||
162 | size_t count, loff_t *ppos) | ||
163 | { | ||
164 | struct ieee80211_local *local = file->private_data; | ||
165 | int res; | ||
166 | char buf[10]; | ||
167 | |||
168 | res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_queues); | ||
169 | |||
170 | return simple_read_from_buffer(user_buf, count, ppos, buf, res); | ||
171 | } | ||
172 | |||
173 | static ssize_t uapsd_queues_write(struct file *file, | ||
174 | const char __user *user_buf, | ||
175 | size_t count, loff_t *ppos) | ||
176 | { | ||
177 | struct ieee80211_local *local = file->private_data; | ||
178 | unsigned long val; | ||
179 | char buf[10]; | ||
180 | size_t len; | ||
181 | int ret; | ||
182 | |||
183 | len = min(count, sizeof(buf) - 1); | ||
184 | if (copy_from_user(buf, user_buf, len)) | ||
185 | return -EFAULT; | ||
186 | buf[len] = '\0'; | ||
187 | |||
188 | ret = strict_strtoul(buf, 0, &val); | ||
189 | |||
190 | if (ret) | ||
191 | return -EINVAL; | ||
192 | |||
193 | if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) | ||
194 | return -ERANGE; | ||
195 | |||
196 | local->uapsd_queues = val; | ||
197 | |||
198 | return count; | ||
199 | } | ||
200 | |||
201 | static const struct file_operations uapsd_queues_ops = { | ||
202 | .read = uapsd_queues_read, | ||
203 | .write = uapsd_queues_write, | ||
204 | .open = mac80211_open_file_generic | ||
205 | }; | ||
206 | |||
207 | static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf, | ||
208 | size_t count, loff_t *ppos) | ||
209 | { | ||
210 | struct ieee80211_local *local = file->private_data; | ||
211 | int res; | ||
212 | char buf[10]; | ||
213 | |||
214 | res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_max_sp_len); | ||
215 | |||
216 | return simple_read_from_buffer(user_buf, count, ppos, buf, res); | ||
217 | } | ||
218 | |||
219 | static ssize_t uapsd_max_sp_len_write(struct file *file, | ||
220 | const char __user *user_buf, | ||
221 | size_t count, loff_t *ppos) | ||
222 | { | ||
223 | struct ieee80211_local *local = file->private_data; | ||
224 | unsigned long val; | ||
225 | char buf[10]; | ||
226 | size_t len; | ||
227 | int ret; | ||
228 | |||
229 | len = min(count, sizeof(buf) - 1); | ||
230 | if (copy_from_user(buf, user_buf, len)) | ||
231 | return -EFAULT; | ||
232 | buf[len] = '\0'; | ||
233 | |||
234 | ret = strict_strtoul(buf, 0, &val); | ||
235 | |||
236 | if (ret) | ||
237 | return -EINVAL; | ||
238 | |||
239 | if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) | ||
240 | return -ERANGE; | ||
241 | |||
242 | local->uapsd_max_sp_len = val; | ||
243 | |||
244 | return count; | ||
245 | } | ||
246 | |||
247 | static const struct file_operations uapsd_max_sp_len_ops = { | ||
248 | .read = uapsd_max_sp_len_read, | ||
249 | .write = uapsd_max_sp_len_write, | ||
250 | .open = mac80211_open_file_generic | ||
251 | }; | ||
252 | |||
161 | static ssize_t queues_read(struct file *file, char __user *user_buf, | 253 | static ssize_t queues_read(struct file *file, char __user *user_buf, |
162 | size_t count, loff_t *ppos) | 254 | size_t count, loff_t *ppos) |
163 | { | 255 | { |
@@ -314,6 +406,8 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
314 | DEBUGFS_ADD(queues); | 406 | DEBUGFS_ADD(queues); |
315 | DEBUGFS_ADD_MODE(reset, 0200); | 407 | DEBUGFS_ADD_MODE(reset, 0200); |
316 | DEBUGFS_ADD(noack); | 408 | DEBUGFS_ADD(noack); |
409 | DEBUGFS_ADD(uapsd_queues); | ||
410 | DEBUGFS_ADD(uapsd_max_sp_len); | ||
317 | 411 | ||
318 | statsd = debugfs_create_dir("statistics", phyd); | 412 | statsd = debugfs_create_dir("statistics", phyd); |
319 | 413 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3468e378509a..c18f576f1848 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -808,6 +808,20 @@ struct ieee80211_local { | |||
808 | int wifi_wme_noack_test; | 808 | int wifi_wme_noack_test; |
809 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ | 809 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ |
810 | 810 | ||
811 | /* | ||
812 | * Bitmask of enabled u-apsd queues, | ||
813 | * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association | ||
814 | * to take effect. | ||
815 | */ | ||
816 | unsigned int uapsd_queues; | ||
817 | |||
818 | /* | ||
819 | * Maximum number of buffered frames AP can deliver during a | ||
820 | * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar. | ||
821 | * Needs a new association to take effect. | ||
822 | */ | ||
823 | unsigned int uapsd_max_sp_len; | ||
824 | |||
811 | bool pspolling; | 825 | bool pspolling; |
812 | bool offchannel_ps_enabled; | 826 | bool offchannel_ps_enabled; |
813 | /* | 827 | /* |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0054bba08ce1..ec8f767ba95b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -384,6 +384,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
384 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; | 384 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; |
385 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; | 385 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; |
386 | local->user_power_level = -1; | 386 | local->user_power_level = -1; |
387 | local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; | ||
388 | local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; | ||
387 | 389 | ||
388 | INIT_LIST_HEAD(&local->interfaces); | 390 | INIT_LIST_HEAD(&local->interfaces); |
389 | mutex_init(&local->iflist_mtx); | 391 | mutex_init(&local->iflist_mtx); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 39c27d83a4f2..2746391248d3 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -581,7 +581,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
581 | return; | 581 | return; |
582 | 582 | ||
583 | if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) | 583 | if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) |
584 | uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; | 584 | uapsd_queues = local->uapsd_queues; |
585 | 585 | ||
586 | count = wmm_param[6] & 0x0f; | 586 | count = wmm_param[6] & 0x0f; |
587 | if (count == ifmgd->wmm_last_param_set) | 587 | if (count == ifmgd->wmm_last_param_set) |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index a74fd6ee0083..81bd5d592bb4 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -376,8 +376,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
376 | 376 | ||
377 | if (wk->assoc.wmm_used && local->hw.queues >= 4) { | 377 | if (wk->assoc.wmm_used && local->hw.queues >= 4) { |
378 | if (wk->assoc.uapsd_used) { | 378 | if (wk->assoc.uapsd_used) { |
379 | qos_info = IEEE80211_DEFAULT_UAPSD_QUEUES; | 379 | qos_info = local->uapsd_queues; |
380 | qos_info |= (IEEE80211_DEFAULT_MAX_SP_LEN << | 380 | qos_info |= (local->uapsd_max_sp_len << |
381 | IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT); | 381 | IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT); |
382 | } else { | 382 | } else { |
383 | qos_info = 0; | 383 | qos_info = 0; |