linux/net/mac80211/vht.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * VHT handling
   4 *
   5 * Portions of this file
   6 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
   7 * Copyright (C) 2018 - 2019 Intel Corporation
   8 */
   9
  10#include <linux/ieee80211.h>
  11#include <linux/export.h>
  12#include <net/mac80211.h>
  13#include "ieee80211_i.h"
  14#include "rate.h"
  15
  16
  17static void __check_vhtcap_disable(struct ieee80211_sub_if_data *sdata,
  18                                   struct ieee80211_sta_vht_cap *vht_cap,
  19                                   u32 flag)
  20{
  21        __le32 le_flag = cpu_to_le32(flag);
  22
  23        if (sdata->u.mgd.vht_capa_mask.vht_cap_info & le_flag &&
  24            !(sdata->u.mgd.vht_capa.vht_cap_info & le_flag))
  25                vht_cap->cap &= ~flag;
  26}
  27
  28void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
  29                                      struct ieee80211_sta_vht_cap *vht_cap)
  30{
  31        int i;
  32        u16 rxmcs_mask, rxmcs_cap, rxmcs_n, txmcs_mask, txmcs_cap, txmcs_n;
  33
  34        if (!vht_cap->vht_supported)
  35                return;
  36
  37        if (sdata->vif.type != NL80211_IFTYPE_STATION)
  38                return;
  39
  40        __check_vhtcap_disable(sdata, vht_cap,
  41                               IEEE80211_VHT_CAP_RXLDPC);
  42        __check_vhtcap_disable(sdata, vht_cap,
  43                               IEEE80211_VHT_CAP_SHORT_GI_80);
  44        __check_vhtcap_disable(sdata, vht_cap,
  45                               IEEE80211_VHT_CAP_SHORT_GI_160);
  46        __check_vhtcap_disable(sdata, vht_cap,
  47                               IEEE80211_VHT_CAP_TXSTBC);
  48        __check_vhtcap_disable(sdata, vht_cap,
  49                               IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
  50        __check_vhtcap_disable(sdata, vht_cap,
  51                               IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);
  52        __check_vhtcap_disable(sdata, vht_cap,
  53                               IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN);
  54        __check_vhtcap_disable(sdata, vht_cap,
  55                               IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN);
  56
  57        /* Allow user to decrease AMPDU length exponent */
  58        if (sdata->u.mgd.vht_capa_mask.vht_cap_info &
  59            cpu_to_le32(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK)) {
  60                u32 cap, n;
  61
  62                n = le32_to_cpu(sdata->u.mgd.vht_capa.vht_cap_info) &
  63                        IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
  64                n >>= IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
  65                cap = vht_cap->cap & IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
  66                cap >>= IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
  67
  68                if (n < cap) {
  69                        vht_cap->cap &=
  70                                ~IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
  71                        vht_cap->cap |=
  72                                n << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
  73                }
  74        }
  75
  76        /* Allow the user to decrease MCSes */
  77        rxmcs_mask =
  78                le16_to_cpu(sdata->u.mgd.vht_capa_mask.supp_mcs.rx_mcs_map);
  79        rxmcs_n = le16_to_cpu(sdata->u.mgd.vht_capa.supp_mcs.rx_mcs_map);
  80        rxmcs_n &= rxmcs_mask;
  81        rxmcs_cap = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
  82
  83        txmcs_mask =
  84                le16_to_cpu(sdata->u.mgd.vht_capa_mask.supp_mcs.tx_mcs_map);
  85        txmcs_n = le16_to_cpu(sdata->u.mgd.vht_capa.supp_mcs.tx_mcs_map);
  86        txmcs_n &= txmcs_mask;
  87        txmcs_cap = le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
  88        for (i = 0; i < 8; i++) {
  89                u8 m, n, c;
  90
  91                m = (rxmcs_mask >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
  92                n = (rxmcs_n >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
  93                c = (rxmcs_cap >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
  94
  95                if (m && ((c != IEEE80211_VHT_MCS_NOT_SUPPORTED && n < c) ||
  96                          n == IEEE80211_VHT_MCS_NOT_SUPPORTED)) {
  97                        rxmcs_cap &= ~(3 << 2*i);
  98                        rxmcs_cap |= (rxmcs_n & (3 << 2*i));
  99                }
 100
 101                m = (txmcs_mask >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
 102                n = (txmcs_n >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
 103                c = (txmcs_cap >> 2*i) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
 104
 105                if (m && ((c != IEEE80211_VHT_MCS_NOT_SUPPORTED && n < c) ||
 106                          n == IEEE80211_VHT_MCS_NOT_SUPPORTED)) {
 107                        txmcs_cap &= ~(3 << 2*i);
 108                        txmcs_cap |= (txmcs_n & (3 << 2*i));
 109                }
 110        }
 111        vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(rxmcs_cap);
 112        vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(txmcs_cap);
 113}
 114
 115void
 116ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
 117                                    struct ieee80211_supported_band *sband,
 118                                    const struct ieee80211_vht_cap *vht_cap_ie,
 119                                    struct sta_info *sta)
 120{
 121        struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
 122        struct ieee80211_sta_vht_cap own_cap;
 123        u32 cap_info, i;
 124        bool have_80mhz;
 125
 126        memset(vht_cap, 0, sizeof(*vht_cap));
 127
 128        if (!sta->sta.ht_cap.ht_supported)
 129                return;
 130
 131        if (!vht_cap_ie || !sband->vht_cap.vht_supported)
 132                return;
 133
 134        /* Allow VHT if at least one channel on the sband supports 80 MHz */
 135        have_80mhz = false;
 136        for (i = 0; i < sband->n_channels; i++) {
 137                if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
 138                                                IEEE80211_CHAN_NO_80MHZ))
 139                        continue;
 140
 141                have_80mhz = true;
 142                break;
 143        }
 144
 145        if (!have_80mhz)
 146                return;
 147
 148        /*
 149         * A VHT STA must support 40 MHz, but if we verify that here
 150         * then we break a few things - some APs (e.g. Netgear R6300v2
 151         * and others based on the BCM4360 chipset) will unset this
 152         * capability bit when operating in 20 MHz.
 153         */
 154
 155        vht_cap->vht_supported = true;
 156
 157        own_cap = sband->vht_cap;
 158        /*
 159         * If user has specified capability overrides, take care
 160         * of that if the station we're setting up is the AP that
 161         * we advertised a restricted capability set to. Override
 162         * our own capabilities and then use those below.
 163         */
 164        if (sdata->vif.type == NL80211_IFTYPE_STATION &&
 165            !test_sta_flag(sta, WLAN_STA_TDLS_PEER))
 166                ieee80211_apply_vhtcap_overrides(sdata, &own_cap);
 167
 168        /* take some capabilities as-is */
 169        cap_info = le32_to_cpu(vht_cap_ie->vht_cap_info);
 170        vht_cap->cap = cap_info;
 171        vht_cap->cap &= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 |
 172                        IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
 173                        IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
 174                        IEEE80211_VHT_CAP_RXLDPC |
 175                        IEEE80211_VHT_CAP_VHT_TXOP_PS |
 176                        IEEE80211_VHT_CAP_HTC_VHT |
 177                        IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
 178                        IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB |
 179                        IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB |
 180                        IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
 181                        IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
 182
 183        /* and some based on our own capabilities */
 184        switch (own_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
 185        case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
 186                vht_cap->cap |= cap_info &
 187                                IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
 188                break;
 189        case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
 190                vht_cap->cap |= cap_info &
 191                                IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
 192                break;
 193        default:
 194                /* nothing */
 195                break;
 196        }
 197
 198        /* symmetric capabilities */
 199        vht_cap->cap |= cap_info & own_cap.cap &
 200                        (IEEE80211_VHT_CAP_SHORT_GI_80 |
 201                         IEEE80211_VHT_CAP_SHORT_GI_160);
 202
 203        /* remaining ones */
 204        if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
 205                vht_cap->cap |= cap_info &
 206                                (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
 207                                 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK);
 208
 209        if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
 210                vht_cap->cap |= cap_info &
 211                                (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
 212                                 IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK);
 213
 214        if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
 215                vht_cap->cap |= cap_info &
 216                                IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
 217
 218        if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
 219                vht_cap->cap |= cap_info &
 220                                IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
 221
 222        if (own_cap.cap & IEEE80211_VHT_CAP_TXSTBC)
 223                vht_cap->cap |= cap_info & IEEE80211_VHT_CAP_RXSTBC_MASK;
 224
 225        if (own_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
 226                vht_cap->cap |= cap_info & IEEE80211_VHT_CAP_TXSTBC;
 227
 228        /* Copy peer MCS info, the driver might need them. */
 229        memcpy(&vht_cap->vht_mcs, &vht_cap_ie->supp_mcs,
 230               sizeof(struct ieee80211_vht_mcs_info));
 231
 232        /* copy EXT_NSS_BW Support value or remove the capability */
 233        if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_VHT_EXT_NSS_BW))
 234                vht_cap->cap |= (cap_info & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK);
 235        else
 236                vht_cap->vht_mcs.tx_highest &=
 237                        ~cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
 238
 239        /* but also restrict MCSes */
 240        for (i = 0; i < 8; i++) {
 241                u16 own_rx, own_tx, peer_rx, peer_tx;
 242
 243                own_rx = le16_to_cpu(own_cap.vht_mcs.rx_mcs_map);
 244                own_rx = (own_rx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
 245
 246                own_tx = le16_to_cpu(own_cap.vht_mcs.tx_mcs_map);
 247                own_tx = (own_tx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
 248
 249                peer_rx = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
 250                peer_rx = (peer_rx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
 251
 252                peer_tx = le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
 253                peer_tx = (peer_tx >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
 254
 255                if (peer_tx != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
 256                        if (own_rx == IEEE80211_VHT_MCS_NOT_SUPPORTED)
 257                                peer_tx = IEEE80211_VHT_MCS_NOT_SUPPORTED;
 258                        else if (own_rx < peer_tx)
 259                                peer_tx = own_rx;
 260                }
 261
 262                if (peer_rx != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
 263                        if (own_tx == IEEE80211_VHT_MCS_NOT_SUPPORTED)
 264                                peer_rx = IEEE80211_VHT_MCS_NOT_SUPPORTED;
 265                        else if (own_tx < peer_rx)
 266                                peer_rx = own_tx;
 267                }
 268
 269                vht_cap->vht_mcs.rx_mcs_map &=
 270                        ~cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << i * 2);
 271                vht_cap->vht_mcs.rx_mcs_map |= cpu_to_le16(peer_rx << i * 2);
 272
 273                vht_cap->vht_mcs.tx_mcs_map &=
 274                        ~cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << i * 2);
 275                vht_cap->vht_mcs.tx_mcs_map |= cpu_to_le16(peer_tx << i * 2);
 276        }
 277
 278        /*
 279         * This is a workaround for VHT-enabled STAs which break the spec
 280         * and have the VHT-MCS Rx map filled in with value 3 for all eight
 281         * spacial streams, an example is AR9462.
 282         *
 283         * As per spec, in section 22.1.1 Introduction to the VHT PHY
 284         * A VHT STA shall support at least single spactial stream VHT-MCSs
 285         * 0 to 7 (transmit and receive) in all supported channel widths.
 286         */
 287        if (vht_cap->vht_mcs.rx_mcs_map == cpu_to_le16(0xFFFF)) {
 288                vht_cap->vht_supported = false;
 289                sdata_info(sdata, "Ignoring VHT IE from %pM due to invalid rx_mcs_map\n",
 290                           sta->addr);
 291                return;
 292        }
 293
 294        /* finally set up the bandwidth */
 295        switch (vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
 296        case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
 297        case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
 298                sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160;
 299                break;
 300        default:
 301                sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_80;
 302
 303                if (!(vht_cap->vht_mcs.tx_highest &
 304                                cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE)))
 305                        break;
 306
 307                /*
 308                 * If this is non-zero, then it does support 160 MHz after all,
 309                 * in one form or the other. We don't distinguish here (or even
 310                 * above) between 160 and 80+80 yet.
 311                 */
 312                if (cap_info & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)
 313                        sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160;
 314        }
 315
 316        sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta);
 317
 318        /* If HT IE reported 3839 bytes only, stay with that size. */
 319        if (sta->sta.max_amsdu_len == IEEE80211_MAX_MPDU_LEN_HT_3839)
 320                return;
 321
 322        switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) {
 323        case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
 324                sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454;
 325                break;
 326        case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991:
 327                sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_7991;
 328                break;
 329        case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895:
 330        default:
 331                sta->sta.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_3895;
 332                break;
 333        }
 334}
 335
 336enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta)
 337{
 338        struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
 339        u32 cap_width;
 340
 341        if (!vht_cap->vht_supported)
 342                return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
 343                                IEEE80211_STA_RX_BW_40 :
 344                                IEEE80211_STA_RX_BW_20;
 345
 346        cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
 347
 348        if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ||
 349            cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
 350                return IEEE80211_STA_RX_BW_160;
 351
 352        /*
 353         * If this is non-zero, then it does support 160 MHz after all,
 354         * in one form or the other. We don't distinguish here (or even
 355         * above) between 160 and 80+80 yet.
 356         */
 357        if (vht_cap->cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)
 358                return IEEE80211_STA_RX_BW_160;
 359
 360        return IEEE80211_STA_RX_BW_80;
 361}
 362
 363enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta)
 364{
 365        struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
 366        u32 cap_width;
 367
 368        if (!vht_cap->vht_supported) {
 369                if (!sta->sta.ht_cap.ht_supported)
 370                        return NL80211_CHAN_WIDTH_20_NOHT;
 371
 372                return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
 373                                NL80211_CHAN_WIDTH_40 : NL80211_CHAN_WIDTH_20;
 374        }
 375
 376        cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
 377
 378        if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
 379                return NL80211_CHAN_WIDTH_160;
 380        else if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
 381                return NL80211_CHAN_WIDTH_80P80;
 382
 383        return NL80211_CHAN_WIDTH_80;
 384}
 385
 386enum nl80211_chan_width
 387ieee80211_sta_rx_bw_to_chan_width(struct sta_info *sta)
 388{
 389        enum ieee80211_sta_rx_bandwidth cur_bw = sta->sta.bandwidth;
 390        struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
 391        u32 cap_width;
 392
 393        switch (cur_bw) {
 394        case IEEE80211_STA_RX_BW_20:
 395                if (!sta->sta.ht_cap.ht_supported)
 396                        return NL80211_CHAN_WIDTH_20_NOHT;
 397                else
 398                        return NL80211_CHAN_WIDTH_20;
 399        case IEEE80211_STA_RX_BW_40:
 400                return NL80211_CHAN_WIDTH_40;
 401        case IEEE80211_STA_RX_BW_80:
 402                return NL80211_CHAN_WIDTH_80;
 403        case IEEE80211_STA_RX_BW_160:
 404                cap_width =
 405                        vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
 406
 407                if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
 408                        return NL80211_CHAN_WIDTH_160;
 409
 410                return NL80211_CHAN_WIDTH_80P80;
 411        default:
 412                return NL80211_CHAN_WIDTH_20;
 413        }
 414}
 415
 416enum ieee80211_sta_rx_bandwidth
 417ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
 418{
 419        switch (width) {
 420        case NL80211_CHAN_WIDTH_20_NOHT:
 421        case NL80211_CHAN_WIDTH_20:
 422                return IEEE80211_STA_RX_BW_20;
 423        case NL80211_CHAN_WIDTH_40:
 424                return IEEE80211_STA_RX_BW_40;
 425        case NL80211_CHAN_WIDTH_80:
 426                return IEEE80211_STA_RX_BW_80;
 427        case NL80211_CHAN_WIDTH_160:
 428        case NL80211_CHAN_WIDTH_80P80:
 429                return IEEE80211_STA_RX_BW_160;
 430        default:
 431                WARN_ON_ONCE(1);
 432                return IEEE80211_STA_RX_BW_20;
 433        }
 434}
 435
 436enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta)
 437{
 438        struct ieee80211_sub_if_data *sdata = sta->sdata;
 439        enum ieee80211_sta_rx_bandwidth bw;
 440        enum nl80211_chan_width bss_width = sdata->vif.bss_conf.chandef.width;
 441
 442        bw = ieee80211_sta_cap_rx_bw(sta);
 443        bw = min(bw, sta->cur_max_bandwidth);
 444
 445        /* Don't consider AP's bandwidth for TDLS peers, section 11.23.1 of
 446         * IEEE80211-2016 specification makes higher bandwidth operation
 447         * possible on the TDLS link if the peers have wider bandwidth
 448         * capability.
 449         */
 450        if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
 451            test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW))
 452                return bw;
 453
 454        bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
 455
 456        return bw;
 457}
 458
 459void ieee80211_sta_set_rx_nss(struct sta_info *sta)
 460{
 461        u8 ht_rx_nss = 0, vht_rx_nss = 0;
 462
 463        /* if we received a notification already don't overwrite it */
 464        if (sta->sta.rx_nss)
 465                return;
 466
 467        if (sta->sta.ht_cap.ht_supported) {
 468                if (sta->sta.ht_cap.mcs.rx_mask[0])
 469                        ht_rx_nss++;
 470                if (sta->sta.ht_cap.mcs.rx_mask[1])
 471                        ht_rx_nss++;
 472                if (sta->sta.ht_cap.mcs.rx_mask[2])
 473                        ht_rx_nss++;
 474                if (sta->sta.ht_cap.mcs.rx_mask[3])
 475                        ht_rx_nss++;
 476                /* FIXME: consider rx_highest? */
 477        }
 478
 479        if (sta->sta.vht_cap.vht_supported) {
 480                int i;
 481                u16 rx_mcs_map;
 482
 483                rx_mcs_map = le16_to_cpu(sta->sta.vht_cap.vht_mcs.rx_mcs_map);
 484
 485                for (i = 7; i >= 0; i--) {
 486                        u8 mcs = (rx_mcs_map >> (2 * i)) & 3;
 487
 488                        if (mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
 489                                vht_rx_nss = i + 1;
 490                                break;
 491                        }
 492                }
 493                /* FIXME: consider rx_highest? */
 494        }
 495
 496        ht_rx_nss = max(ht_rx_nss, vht_rx_nss);
 497        sta->sta.rx_nss = max_t(u8, 1, ht_rx_nss);
 498}
 499
 500u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
 501                                  struct sta_info *sta, u8 opmode,
 502                                  enum nl80211_band band)
 503{
 504        enum ieee80211_sta_rx_bandwidth new_bw;
 505        struct sta_opmode_info sta_opmode = {};
 506        u32 changed = 0;
 507        u8 nss;
 508
 509        /* ignore - no support for BF yet */
 510        if (opmode & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)
 511                return 0;
 512
 513        nss = opmode & IEEE80211_OPMODE_NOTIF_RX_NSS_MASK;
 514        nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
 515        nss += 1;
 516
 517        if (sta->sta.rx_nss != nss) {
 518                sta->sta.rx_nss = nss;
 519                sta_opmode.rx_nss = nss;
 520                changed |= IEEE80211_RC_NSS_CHANGED;
 521                sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
 522        }
 523
 524        switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
 525        case IEEE80211_OPMODE_NOTIF_CHANWIDTH_20MHZ:
 526                sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_20;
 527                break;
 528        case IEEE80211_OPMODE_NOTIF_CHANWIDTH_40MHZ:
 529                sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_40;
 530                break;
 531        case IEEE80211_OPMODE_NOTIF_CHANWIDTH_80MHZ:
 532                sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_80;
 533                break;
 534        case IEEE80211_OPMODE_NOTIF_CHANWIDTH_160MHZ:
 535                sta->cur_max_bandwidth = IEEE80211_STA_RX_BW_160;
 536                break;
 537        }
 538
 539        new_bw = ieee80211_sta_cur_vht_bw(sta);
 540        if (new_bw != sta->sta.bandwidth) {
 541                sta->sta.bandwidth = new_bw;
 542                sta_opmode.bw = ieee80211_sta_rx_bw_to_chan_width(sta);
 543                changed |= IEEE80211_RC_BW_CHANGED;
 544                sta_opmode.changed |= STA_OPMODE_MAX_BW_CHANGED;
 545        }
 546
 547        if (sta_opmode.changed)
 548                cfg80211_sta_opmode_change_notify(sdata->dev, sta->addr,
 549                                                  &sta_opmode, GFP_KERNEL);
 550
 551        return changed;
 552}
 553
 554void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata,
 555                                 struct ieee80211_mgmt *mgmt)
 556{
 557        struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
 558
 559        if (!sdata->vif.mu_mimo_owner)
 560                return;
 561
 562        if (!memcmp(mgmt->u.action.u.vht_group_notif.position,
 563                    bss_conf->mu_group.position, WLAN_USER_POSITION_LEN) &&
 564            !memcmp(mgmt->u.action.u.vht_group_notif.membership,
 565                    bss_conf->mu_group.membership, WLAN_MEMBERSHIP_LEN))
 566                return;
 567
 568        memcpy(bss_conf->mu_group.membership,
 569               mgmt->u.action.u.vht_group_notif.membership,
 570               WLAN_MEMBERSHIP_LEN);
 571        memcpy(bss_conf->mu_group.position,
 572               mgmt->u.action.u.vht_group_notif.position,
 573               WLAN_USER_POSITION_LEN);
 574
 575        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_MU_GROUPS);
 576}
 577
 578void ieee80211_update_mu_groups(struct ieee80211_vif *vif,
 579                                const u8 *membership, const u8 *position)
 580{
 581        struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 582
 583        if (WARN_ON_ONCE(!vif->mu_mimo_owner))
 584                return;
 585
 586        memcpy(bss_conf->mu_group.membership, membership, WLAN_MEMBERSHIP_LEN);
 587        memcpy(bss_conf->mu_group.position, position, WLAN_USER_POSITION_LEN);
 588}
 589EXPORT_SYMBOL_GPL(ieee80211_update_mu_groups);
 590
 591void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
 592                                 struct sta_info *sta, u8 opmode,
 593                                 enum nl80211_band band)
 594{
 595        struct ieee80211_local *local = sdata->local;
 596        struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
 597
 598        u32 changed = __ieee80211_vht_handle_opmode(sdata, sta, opmode, band);
 599
 600        if (changed > 0) {
 601                ieee80211_recalc_min_chandef(sdata);
 602                rate_control_rate_update(local, sband, sta, changed);
 603        }
 604}
 605
 606void ieee80211_get_vht_mask_from_cap(__le16 vht_cap,
 607                                     u16 vht_mask[NL80211_VHT_NSS_MAX])
 608{
 609        int i;
 610        u16 mask, cap = le16_to_cpu(vht_cap);
 611
 612        for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
 613                mask = (cap >> i * 2) & IEEE80211_VHT_MCS_NOT_SUPPORTED;
 614                switch (mask) {
 615                case IEEE80211_VHT_MCS_SUPPORT_0_7:
 616                        vht_mask[i] = 0x00FF;
 617                        break;
 618                case IEEE80211_VHT_MCS_SUPPORT_0_8:
 619                        vht_mask[i] = 0x01FF;
 620                        break;
 621                case IEEE80211_VHT_MCS_SUPPORT_0_9:
 622                        vht_mask[i] = 0x03FF;
 623                        break;
 624                case IEEE80211_VHT_MCS_NOT_SUPPORTED:
 625                default:
 626                        vht_mask[i] = 0;
 627                        break;
 628                }
 629        }
 630}
 631