.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * HT handling |
---|
3 | 4 | * |
---|
.. | .. |
---|
8 | 9 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
---|
9 | 10 | * Copyright 2007-2010, Intel Corporation |
---|
10 | 11 | * Copyright 2017 Intel Deutschland GmbH |
---|
11 | | - * |
---|
12 | | - * This program is free software; you can redistribute it and/or modify |
---|
13 | | - * it under the terms of the GNU General Public License version 2 as |
---|
14 | | - * published by the Free Software Foundation. |
---|
| 12 | + * Copyright(c) 2020 Intel Corporation |
---|
15 | 13 | */ |
---|
16 | 14 | |
---|
17 | 15 | #include <linux/ieee80211.h> |
---|
.. | .. |
---|
107 | 105 | __check_htcap_enable(ht_capa, ht_capa_mask, ht_cap, |
---|
108 | 106 | IEEE80211_HT_CAP_40MHZ_INTOLERANT); |
---|
109 | 107 | |
---|
| 108 | + /* Allow user to enable TX STBC bit */ |
---|
| 109 | + __check_htcap_enable(ht_capa, ht_capa_mask, ht_cap, |
---|
| 110 | + IEEE80211_HT_CAP_TX_STBC); |
---|
| 111 | + |
---|
| 112 | + /* Allow user to configure RX STBC bits */ |
---|
| 113 | + if (ht_capa_mask->cap_info & cpu_to_le16(IEEE80211_HT_CAP_RX_STBC)) |
---|
| 114 | + ht_cap->cap |= le16_to_cpu(ht_capa->cap_info) & |
---|
| 115 | + IEEE80211_HT_CAP_RX_STBC; |
---|
| 116 | + |
---|
110 | 117 | /* Allow user to decrease AMPDU factor */ |
---|
111 | 118 | if (ht_capa_mask->ampdu_params_info & |
---|
112 | 119 | IEEE80211_HT_AMPDU_PARM_FACTOR) { |
---|
.. | .. |
---|
138 | 145 | int i, max_tx_streams; |
---|
139 | 146 | bool changed; |
---|
140 | 147 | enum ieee80211_sta_rx_bandwidth bw; |
---|
141 | | - enum ieee80211_smps_mode smps_mode; |
---|
142 | 148 | |
---|
143 | 149 | memset(&ht_cap, 0, sizeof(ht_cap)); |
---|
144 | 150 | |
---|
.. | .. |
---|
244 | 250 | switch (sdata->vif.bss_conf.chandef.width) { |
---|
245 | 251 | default: |
---|
246 | 252 | WARN_ON_ONCE(1); |
---|
247 | | - /* fall through */ |
---|
| 253 | + fallthrough; |
---|
248 | 254 | case NL80211_CHAN_WIDTH_20_NOHT: |
---|
249 | 255 | case NL80211_CHAN_WIDTH_20: |
---|
250 | 256 | bw = IEEE80211_STA_RX_BW_20; |
---|
.. | .. |
---|
264 | 270 | ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? |
---|
265 | 271 | IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20; |
---|
266 | 272 | |
---|
267 | | - switch ((ht_cap.cap & IEEE80211_HT_CAP_SM_PS) |
---|
268 | | - >> IEEE80211_HT_CAP_SM_PS_SHIFT) { |
---|
269 | | - case WLAN_HT_CAP_SM_PS_INVALID: |
---|
270 | | - case WLAN_HT_CAP_SM_PS_STATIC: |
---|
271 | | - smps_mode = IEEE80211_SMPS_STATIC; |
---|
272 | | - break; |
---|
273 | | - case WLAN_HT_CAP_SM_PS_DYNAMIC: |
---|
274 | | - smps_mode = IEEE80211_SMPS_DYNAMIC; |
---|
275 | | - break; |
---|
276 | | - case WLAN_HT_CAP_SM_PS_DISABLED: |
---|
277 | | - smps_mode = IEEE80211_SMPS_OFF; |
---|
278 | | - break; |
---|
| 273 | + if (sta->sdata->vif.type == NL80211_IFTYPE_AP || |
---|
| 274 | + sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { |
---|
| 275 | + enum ieee80211_smps_mode smps_mode; |
---|
| 276 | + |
---|
| 277 | + switch ((ht_cap.cap & IEEE80211_HT_CAP_SM_PS) |
---|
| 278 | + >> IEEE80211_HT_CAP_SM_PS_SHIFT) { |
---|
| 279 | + case WLAN_HT_CAP_SM_PS_INVALID: |
---|
| 280 | + case WLAN_HT_CAP_SM_PS_STATIC: |
---|
| 281 | + smps_mode = IEEE80211_SMPS_STATIC; |
---|
| 282 | + break; |
---|
| 283 | + case WLAN_HT_CAP_SM_PS_DYNAMIC: |
---|
| 284 | + smps_mode = IEEE80211_SMPS_DYNAMIC; |
---|
| 285 | + break; |
---|
| 286 | + case WLAN_HT_CAP_SM_PS_DISABLED: |
---|
| 287 | + smps_mode = IEEE80211_SMPS_OFF; |
---|
| 288 | + break; |
---|
| 289 | + } |
---|
| 290 | + |
---|
| 291 | + if (smps_mode != sta->sta.smps_mode) |
---|
| 292 | + changed = true; |
---|
| 293 | + sta->sta.smps_mode = smps_mode; |
---|
| 294 | + } else { |
---|
| 295 | + sta->sta.smps_mode = IEEE80211_SMPS_OFF; |
---|
279 | 296 | } |
---|
280 | | - |
---|
281 | | - if (smps_mode != sta->sta.smps_mode) |
---|
282 | | - changed = true; |
---|
283 | | - sta->sta.smps_mode = smps_mode; |
---|
284 | | - |
---|
285 | 297 | return changed; |
---|
286 | 298 | } |
---|
287 | 299 | |
---|
.. | .. |
---|
353 | 365 | sta->ampdu_mlme.tid_rx_manage_offl)) |
---|
354 | 366 | ___ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid, |
---|
355 | 367 | IEEE80211_MAX_AMPDU_BUF_HT, |
---|
356 | | - false, true); |
---|
| 368 | + false, true, NULL); |
---|
357 | 369 | |
---|
358 | 370 | if (test_and_clear_bit(tid + IEEE80211_NUM_TIDS, |
---|
359 | 371 | sta->ampdu_mlme.tid_rx_manage_offl)) |
---|
.. | .. |
---|
505 | 517 | case IEEE80211_SMPS_AUTOMATIC: |
---|
506 | 518 | case IEEE80211_SMPS_NUM_MODES: |
---|
507 | 519 | WARN_ON(1); |
---|
508 | | - /* fall through */ |
---|
| 520 | + fallthrough; |
---|
509 | 521 | case IEEE80211_SMPS_OFF: |
---|
510 | 522 | action_frame->u.action.u.ht_smps.smps_control = |
---|
511 | 523 | WLAN_HT_SMPS_CONTROL_DISABLED; |
---|
.. | .. |
---|
538 | 550 | sdata_unlock(sdata); |
---|
539 | 551 | } |
---|
540 | 552 | |
---|
541 | | -void ieee80211_request_smps_ap_work(struct work_struct *work) |
---|
542 | | -{ |
---|
543 | | - struct ieee80211_sub_if_data *sdata = |
---|
544 | | - container_of(work, struct ieee80211_sub_if_data, |
---|
545 | | - u.ap.request_smps_work); |
---|
546 | | - |
---|
547 | | - sdata_lock(sdata); |
---|
548 | | - if (sdata_dereference(sdata->u.ap.beacon, sdata)) |
---|
549 | | - __ieee80211_request_smps_ap(sdata, |
---|
550 | | - sdata->u.ap.driver_smps_mode); |
---|
551 | | - sdata_unlock(sdata); |
---|
552 | | -} |
---|
553 | | - |
---|
554 | 553 | void ieee80211_request_smps(struct ieee80211_vif *vif, |
---|
555 | 554 | enum ieee80211_smps_mode smps_mode) |
---|
556 | 555 | { |
---|
.. | .. |
---|
566 | 565 | sdata->u.mgd.driver_smps_mode = smps_mode; |
---|
567 | 566 | ieee80211_queue_work(&sdata->local->hw, |
---|
568 | 567 | &sdata->u.mgd.request_smps_work); |
---|
569 | | - } else { |
---|
570 | | - /* AUTOMATIC is meaningless in AP mode */ |
---|
571 | | - if (WARN_ON_ONCE(smps_mode == IEEE80211_SMPS_AUTOMATIC)) |
---|
572 | | - return; |
---|
573 | | - if (sdata->u.ap.driver_smps_mode == smps_mode) |
---|
574 | | - return; |
---|
575 | | - sdata->u.ap.driver_smps_mode = smps_mode; |
---|
576 | | - ieee80211_queue_work(&sdata->local->hw, |
---|
577 | | - &sdata->u.ap.request_smps_work); |
---|
578 | 568 | } |
---|
579 | 569 | } |
---|
580 | 570 | /* this might change ... don't want non-open drivers using it */ |
---|