linux/net/mac80211/ht.c
<<
>>
Prefs
   1/*
   2 * HT handling
   3 *
   4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
   5 * Copyright 2002-2005, Instant802 Networks, Inc.
   6 * Copyright 2005-2006, Devicescape Software, Inc.
   7 * Copyright 2006-2007  Jiri Benc <jbenc@suse.cz>
   8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
   9 * Copyright 2007-2010, Intel Corporation
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 */
  15
  16#include <linux/ieee80211.h>
  17#include <linux/export.h>
  18#include <net/mac80211.h>
  19#include "ieee80211_i.h"
  20#include "rate.h"
  21
  22static void __check_htcap_disable(struct ieee80211_sub_if_data *sdata,
  23                                  struct ieee80211_sta_ht_cap *ht_cap,
  24                                  u16 flag)
  25{
  26        __le16 le_flag = cpu_to_le16(flag);
  27        if (sdata->u.mgd.ht_capa_mask.cap_info & le_flag) {
  28                if (!(sdata->u.mgd.ht_capa.cap_info & le_flag))
  29                        ht_cap->cap &= ~flag;
  30        }
  31}
  32
  33void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
  34                                     struct ieee80211_sta_ht_cap *ht_cap)
  35{
  36        u8 *scaps = (u8 *)(&sdata->u.mgd.ht_capa.mcs.rx_mask);
  37        u8 *smask = (u8 *)(&sdata->u.mgd.ht_capa_mask.mcs.rx_mask);
  38        int i;
  39
  40        if (!ht_cap->ht_supported)
  41                return;
  42
  43        /* NOTE:  If you add more over-rides here, update register_hw
  44         * ht_capa_mod_msk logic in main.c as well.
  45         * And, if this method can ever change ht_cap.ht_supported, fix
  46         * the check in ieee80211_add_ht_ie.
  47         */
  48
  49        /* check for HT over-rides, MCS rates first. */
  50        for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
  51                u8 m = smask[i];
  52                ht_cap->mcs.rx_mask[i] &= ~m; /* turn off all masked bits */
  53                /* Add back rates that are supported */
  54                ht_cap->mcs.rx_mask[i] |= (m & scaps[i]);
  55        }
  56
  57        /* Force removal of HT-40 capabilities? */
  58        __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SUP_WIDTH_20_40);
  59        __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SGI_40);
  60
  61        /* Allow user to disable SGI-20 (SGI-40 is handled above) */
  62        __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_SGI_20);
  63
  64        /* Allow user to disable the max-AMSDU bit. */
  65        __check_htcap_disable(sdata, ht_cap, IEEE80211_HT_CAP_MAX_AMSDU);
  66
  67        /* Allow user to decrease AMPDU factor */
  68        if (sdata->u.mgd.ht_capa_mask.ampdu_params_info &
  69            IEEE80211_HT_AMPDU_PARM_FACTOR) {
  70                u8 n = sdata->u.mgd.ht_capa.ampdu_params_info
  71                        & IEEE80211_HT_AMPDU_PARM_FACTOR;
  72                if (n < ht_cap->ampdu_factor)
  73                        ht_cap->ampdu_factor = n;
  74        }
  75
  76        /* Allow the user to increase AMPDU density. */
  77        if (sdata->u.mgd.ht_capa_mask.ampdu_params_info &
  78            IEEE80211_HT_AMPDU_PARM_DENSITY) {
  79                u8 n = (sdata->u.mgd.ht_capa.ampdu_params_info &
  80                        IEEE80211_HT_AMPDU_PARM_DENSITY)
  81                        >> IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT;
  82                if (n > ht_cap->ampdu_density)
  83                        ht_cap->ampdu_density = n;
  84        }
  85}
  86
  87
  88bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
  89                                       struct ieee80211_supported_band *sband,
  90                                       const struct ieee80211_ht_cap *ht_cap_ie,
  91                                       struct sta_info *sta)
  92{
  93        struct ieee80211_sta_ht_cap ht_cap, own_cap;
  94        u8 ampdu_info, tx_mcs_set_cap;
  95        int i, max_tx_streams;
  96        bool changed;
  97        enum ieee80211_sta_rx_bandwidth bw;
  98        enum ieee80211_smps_mode smps_mode;
  99
 100        memset(&ht_cap, 0, sizeof(ht_cap));
 101
 102        if (!ht_cap_ie || !sband->ht_cap.ht_supported)
 103                goto apply;
 104
 105        ht_cap.ht_supported = true;
 106
 107        own_cap = sband->ht_cap;
 108
 109        /*
 110         * If user has specified capability over-rides, take care
 111         * of that if the station we're setting up is the AP that
 112         * we advertised a restricted capability set to. Override
 113         * our own capabilities and then use those below.
 114         */
 115        if (sdata->vif.type == NL80211_IFTYPE_STATION &&
 116            !test_sta_flag(sta, WLAN_STA_TDLS_PEER))
 117                ieee80211_apply_htcap_overrides(sdata, &own_cap);
 118
 119        /*
 120         * The bits listed in this expression should be
 121         * the same for the peer and us, if the station
 122         * advertises more then we can't use those thus
 123         * we mask them out.
 124         */
 125        ht_cap.cap = le16_to_cpu(ht_cap_ie->cap_info) &
 126                (own_cap.cap | ~(IEEE80211_HT_CAP_LDPC_CODING |
 127                                 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
 128                                 IEEE80211_HT_CAP_GRN_FLD |
 129                                 IEEE80211_HT_CAP_SGI_20 |
 130                                 IEEE80211_HT_CAP_SGI_40 |
 131                                 IEEE80211_HT_CAP_DSSSCCK40));
 132
 133        /*
 134         * The STBC bits are asymmetric -- if we don't have
 135         * TX then mask out the peer's RX and vice versa.
 136         */
 137        if (!(own_cap.cap & IEEE80211_HT_CAP_TX_STBC))
 138                ht_cap.cap &= ~IEEE80211_HT_CAP_RX_STBC;
 139        if (!(own_cap.cap & IEEE80211_HT_CAP_RX_STBC))
 140                ht_cap.cap &= ~IEEE80211_HT_CAP_TX_STBC;
 141
 142        ampdu_info = ht_cap_ie->ampdu_params_info;
 143        ht_cap.ampdu_factor =
 144                ampdu_info & IEEE80211_HT_AMPDU_PARM_FACTOR;
 145        ht_cap.ampdu_density =
 146                (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
 147
 148        /* own MCS TX capabilities */
 149        tx_mcs_set_cap = own_cap.mcs.tx_params;
 150
 151        /* Copy peer MCS TX capabilities, the driver might need them. */
 152        ht_cap.mcs.tx_params = ht_cap_ie->mcs.tx_params;
 153
 154        /* can we TX with MCS rates? */
 155        if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED))
 156                goto apply;
 157
 158        /* Counting from 0, therefore +1 */
 159        if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_RX_DIFF)
 160                max_tx_streams =
 161                        ((tx_mcs_set_cap & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
 162                                >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1;
 163        else
 164                max_tx_streams = IEEE80211_HT_MCS_TX_MAX_STREAMS;
 165
 166        /*
 167         * 802.11n-2009 20.3.5 / 20.6 says:
 168         * - indices 0 to 7 and 32 are single spatial stream
 169         * - 8 to 31 are multiple spatial streams using equal modulation
 170         *   [8..15 for two streams, 16..23 for three and 24..31 for four]
 171         * - remainder are multiple spatial streams using unequal modulation
 172         */
 173        for (i = 0; i < max_tx_streams; i++)
 174                ht_cap.mcs.rx_mask[i] =
 175                        own_cap.mcs.rx_mask[i] & ht_cap_ie->mcs.rx_mask[i];
 176
 177        if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION)
 178                for (i = IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE;
 179                     i < IEEE80211_HT_MCS_MASK_LEN; i++)
 180                        ht_cap.mcs.rx_mask[i] =
 181                                own_cap.mcs.rx_mask[i] &
 182                                        ht_cap_ie->mcs.rx_mask[i];
 183
 184        /* handle MCS rate 32 too */
 185        if (own_cap.mcs.rx_mask[32/8] & ht_cap_ie->mcs.rx_mask[32/8] & 1)
 186                ht_cap.mcs.rx_mask[32/8] |= 1;
 187
 188 apply:
 189        changed = memcmp(&sta->sta.ht_cap, &ht_cap, sizeof(ht_cap));
 190
 191        memcpy(&sta->sta.ht_cap, &ht_cap, sizeof(ht_cap));
 192
 193        switch (sdata->vif.bss_conf.chandef.width) {
 194        default:
 195                WARN_ON_ONCE(1);
 196                /* fall through */
 197        case NL80211_CHAN_WIDTH_20_NOHT:
 198        case NL80211_CHAN_WIDTH_20:
 199                bw = IEEE80211_STA_RX_BW_20;
 200                break;
 201        case NL80211_CHAN_WIDTH_40:
 202        case NL80211_CHAN_WIDTH_80:
 203        case NL80211_CHAN_WIDTH_80P80:
 204        case NL80211_CHAN_WIDTH_160:
 205                bw = ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
 206                                IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20;
 207                break;
 208        }
 209
 210        if (bw != sta->sta.bandwidth)
 211                changed = true;
 212        sta->sta.bandwidth = bw;
 213
 214        sta->cur_max_bandwidth =
 215                ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
 216                                IEEE80211_STA_RX_BW_40 : IEEE80211_STA_RX_BW_20;
 217
 218        switch ((ht_cap.cap & IEEE80211_HT_CAP_SM_PS)
 219                        >> IEEE80211_HT_CAP_SM_PS_SHIFT) {
 220        case WLAN_HT_CAP_SM_PS_INVALID:
 221        case WLAN_HT_CAP_SM_PS_STATIC:
 222                smps_mode = IEEE80211_SMPS_STATIC;
 223                break;
 224        case WLAN_HT_CAP_SM_PS_DYNAMIC:
 225                smps_mode = IEEE80211_SMPS_DYNAMIC;
 226                break;
 227        case WLAN_HT_CAP_SM_PS_DISABLED:
 228                smps_mode = IEEE80211_SMPS_OFF;
 229                break;
 230        }
 231
 232        if (smps_mode != sta->sta.smps_mode)
 233                changed = true;
 234        sta->sta.smps_mode = smps_mode;
 235
 236        return changed;
 237}
 238
 239void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
 240                                         enum ieee80211_agg_stop_reason reason)
 241{
 242        int i;
 243
 244        cancel_work_sync(&sta->ampdu_mlme.work);
 245
 246        for (i = 0; i <  IEEE80211_NUM_TIDS; i++) {
 247                __ieee80211_stop_tx_ba_session(sta, i, reason);
 248                __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
 249                                               WLAN_REASON_QSTA_LEAVE_QBSS,
 250                                               reason != AGG_STOP_DESTROY_STA &&
 251                                               reason != AGG_STOP_PEER_REQUEST);
 252        }
 253}
 254
 255void ieee80211_ba_session_work(struct work_struct *work)
 256{
 257        struct sta_info *sta =
 258                container_of(work, struct sta_info, ampdu_mlme.work);
 259        struct tid_ampdu_tx *tid_tx;
 260        int tid;
 261
 262        /*
 263         * When this flag is set, new sessions should be
 264         * blocked, and existing sessions will be torn
 265         * down by the code that set the flag, so this
 266         * need not run.
 267         */
 268        if (test_sta_flag(sta, WLAN_STA_BLOCK_BA))
 269                return;
 270
 271        mutex_lock(&sta->ampdu_mlme.mtx);
 272        for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) {
 273                if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired))
 274                        ___ieee80211_stop_rx_ba_session(
 275                                sta, tid, WLAN_BACK_RECIPIENT,
 276                                WLAN_REASON_QSTA_TIMEOUT, true);
 277
 278                if (test_and_clear_bit(tid,
 279                                       sta->ampdu_mlme.tid_rx_stop_requested))
 280                        ___ieee80211_stop_rx_ba_session(
 281                                sta, tid, WLAN_BACK_RECIPIENT,
 282                                WLAN_REASON_UNSPECIFIED, true);
 283
 284                tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
 285                if (tid_tx) {
 286                        /*
 287                         * Assign it over to the normal tid_tx array
 288                         * where it "goes live".
 289                         */
 290                        spin_lock_bh(&sta->lock);
 291
 292                        sta->ampdu_mlme.tid_start_tx[tid] = NULL;
 293                        /* could there be a race? */
 294                        if (sta->ampdu_mlme.tid_tx[tid])
 295                                kfree(tid_tx);
 296                        else
 297                                ieee80211_assign_tid_tx(sta, tid, tid_tx);
 298                        spin_unlock_bh(&sta->lock);
 299
 300                        ieee80211_tx_ba_session_handle_start(sta, tid);
 301                        continue;
 302                }
 303
 304                tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 305                if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
 306                                                 &tid_tx->state))
 307                        ___ieee80211_stop_tx_ba_session(sta, tid,
 308                                                        AGG_STOP_LOCAL_REQUEST);
 309        }
 310        mutex_unlock(&sta->ampdu_mlme.mtx);
 311}
 312
 313void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
 314                          const u8 *da, u16 tid,
 315                          u16 initiator, u16 reason_code)
 316{
 317        struct ieee80211_local *local = sdata->local;
 318        struct sk_buff *skb;
 319        struct ieee80211_mgmt *mgmt;
 320        u16 params;
 321
 322        skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
 323        if (!skb)
 324                return;
 325
 326        skb_reserve(skb, local->hw.extra_tx_headroom);
 327        mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
 328        memset(mgmt, 0, 24);
 329        memcpy(mgmt->da, da, ETH_ALEN);
 330        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
 331        if (sdata->vif.type == NL80211_IFTYPE_AP ||
 332            sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
 333            sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
 334                memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
 335        else if (sdata->vif.type == NL80211_IFTYPE_STATION)
 336                memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
 337        else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
 338                memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
 339
 340        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 341                                          IEEE80211_STYPE_ACTION);
 342
 343        skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
 344
 345        mgmt->u.action.category = WLAN_CATEGORY_BACK;
 346        mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
 347        params = (u16)(initiator << 11);        /* bit 11 initiator */
 348        params |= (u16)(tid << 12);             /* bit 15:12 TID number */
 349
 350        mgmt->u.action.u.delba.params = cpu_to_le16(params);
 351        mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
 352
 353        ieee80211_tx_skb_tid(sdata, skb, tid);
 354}
 355
 356void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
 357                             struct sta_info *sta,
 358                             struct ieee80211_mgmt *mgmt, size_t len)
 359{
 360        u16 tid, params;
 361        u16 initiator;
 362
 363        params = le16_to_cpu(mgmt->u.action.u.delba.params);
 364        tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
 365        initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
 366
 367        ht_dbg_ratelimited(sdata, "delba from %pM (%s) tid %d reason code %d\n",
 368                           mgmt->sa, initiator ? "initiator" : "recipient",
 369                           tid,
 370                           le16_to_cpu(mgmt->u.action.u.delba.reason_code));
 371
 372        if (initiator == WLAN_BACK_INITIATOR)
 373                __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0,
 374                                               true);
 375        else
 376                __ieee80211_stop_tx_ba_session(sta, tid, AGG_STOP_PEER_REQUEST);
 377}
 378
 379int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
 380                               enum ieee80211_smps_mode smps, const u8 *da,
 381                               const u8 *bssid)
 382{
 383        struct ieee80211_local *local = sdata->local;
 384        struct sk_buff *skb;
 385        struct ieee80211_mgmt *action_frame;
 386
 387        /* 27 = header + category + action + smps mode */
 388        skb = dev_alloc_skb(27 + local->hw.extra_tx_headroom);
 389        if (!skb)
 390                return -ENOMEM;
 391
 392        skb_reserve(skb, local->hw.extra_tx_headroom);
 393        action_frame = (void *)skb_put(skb, 27);
 394        memcpy(action_frame->da, da, ETH_ALEN);
 395        memcpy(action_frame->sa, sdata->dev->dev_addr, ETH_ALEN);
 396        memcpy(action_frame->bssid, bssid, ETH_ALEN);
 397        action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 398                                                  IEEE80211_STYPE_ACTION);
 399        action_frame->u.action.category = WLAN_CATEGORY_HT;
 400        action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;
 401        switch (smps) {
 402        case IEEE80211_SMPS_AUTOMATIC:
 403        case IEEE80211_SMPS_NUM_MODES:
 404                WARN_ON(1);
 405        case IEEE80211_SMPS_OFF:
 406                action_frame->u.action.u.ht_smps.smps_control =
 407                                WLAN_HT_SMPS_CONTROL_DISABLED;
 408                break;
 409        case IEEE80211_SMPS_STATIC:
 410                action_frame->u.action.u.ht_smps.smps_control =
 411                                WLAN_HT_SMPS_CONTROL_STATIC;
 412                break;
 413        case IEEE80211_SMPS_DYNAMIC:
 414                action_frame->u.action.u.ht_smps.smps_control =
 415                                WLAN_HT_SMPS_CONTROL_DYNAMIC;
 416                break;
 417        }
 418
 419        /* we'll do more on status of this frame */
 420        IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
 421        ieee80211_tx_skb(sdata, skb);
 422
 423        return 0;
 424}
 425
 426void ieee80211_request_smps_work(struct work_struct *work)
 427{
 428        struct ieee80211_sub_if_data *sdata =
 429                container_of(work, struct ieee80211_sub_if_data,
 430                             u.mgd.request_smps_work);
 431
 432        mutex_lock(&sdata->u.mgd.mtx);
 433        __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode);
 434        mutex_unlock(&sdata->u.mgd.mtx);
 435}
 436
 437void ieee80211_request_smps(struct ieee80211_vif *vif,
 438                            enum ieee80211_smps_mode smps_mode)
 439{
 440        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
 441
 442        if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
 443                return;
 444
 445        if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
 446                smps_mode = IEEE80211_SMPS_AUTOMATIC;
 447
 448        if (sdata->u.mgd.driver_smps_mode == smps_mode)
 449                return;
 450
 451        sdata->u.mgd.driver_smps_mode = smps_mode;
 452
 453        ieee80211_queue_work(&sdata->local->hw,
 454                             &sdata->u.mgd.request_smps_work);
 455}
 456/* this might change ... don't want non-open drivers using it */
 457EXPORT_SYMBOL_GPL(ieee80211_request_smps);
 458