linux/net/mac80211/tdls.c
<<
>>
Prefs
   1/*
   2 * mac80211 TDLS handling code
   3 *
   4 * Copyright 2006-2010  Johannes Berg <johannes@sipsolutions.net>
   5 * Copyright 2014, Intel Corporation
   6 * Copyright 2014  Intel Mobile Communications GmbH
   7 *
   8 * This file is GPLv2 as found in COPYING.
   9 */
  10
  11#include <linux/ieee80211.h>
  12#include <linux/log2.h>
  13#include <net/cfg80211.h>
  14#include "ieee80211_i.h"
  15#include "driver-ops.h"
  16
  17/* give usermode some time for retries in setting up the TDLS session */
  18#define TDLS_PEER_SETUP_TIMEOUT (15 * HZ)
  19
  20void ieee80211_tdls_peer_del_work(struct work_struct *wk)
  21{
  22        struct ieee80211_sub_if_data *sdata;
  23        struct ieee80211_local *local;
  24
  25        sdata = container_of(wk, struct ieee80211_sub_if_data,
  26                             u.mgd.tdls_peer_del_work.work);
  27        local = sdata->local;
  28
  29        mutex_lock(&local->mtx);
  30        if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer)) {
  31                tdls_dbg(sdata, "TDLS del peer %pM\n", sdata->u.mgd.tdls_peer);
  32                sta_info_destroy_addr(sdata, sdata->u.mgd.tdls_peer);
  33                eth_zero_addr(sdata->u.mgd.tdls_peer);
  34        }
  35        mutex_unlock(&local->mtx);
  36}
  37
  38static void ieee80211_tdls_add_ext_capab(struct ieee80211_local *local,
  39                                         struct sk_buff *skb)
  40{
  41        u8 *pos = (void *)skb_put(skb, 7);
  42        bool chan_switch = local->hw.wiphy->features &
  43                           NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
  44
  45        *pos++ = WLAN_EID_EXT_CAPABILITY;
  46        *pos++ = 5; /* len */
  47        *pos++ = 0x0;
  48        *pos++ = 0x0;
  49        *pos++ = 0x0;
  50        *pos++ = chan_switch ? WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH : 0;
  51        *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED;
  52}
  53
  54static u8
  55ieee80211_tdls_add_subband(struct ieee80211_sub_if_data *sdata,
  56                           struct sk_buff *skb, u16 start, u16 end,
  57                           u16 spacing)
  58{
  59        u8 subband_cnt = 0, ch_cnt = 0;
  60        struct ieee80211_channel *ch;
  61        struct cfg80211_chan_def chandef;
  62        int i, subband_start;
  63        struct wiphy *wiphy = sdata->local->hw.wiphy;
  64
  65        for (i = start; i <= end; i += spacing) {
  66                if (!ch_cnt)
  67                        subband_start = i;
  68
  69                ch = ieee80211_get_channel(sdata->local->hw.wiphy, i);
  70                if (ch) {
  71                        /* we will be active on the channel */
  72                        cfg80211_chandef_create(&chandef, ch,
  73                                                NL80211_CHAN_NO_HT);
  74                        if (cfg80211_reg_can_beacon_relax(wiphy, &chandef,
  75                                                          sdata->wdev.iftype)) {
  76                                ch_cnt++;
  77                                /*
  78                                 * check if the next channel is also part of
  79                                 * this allowed range
  80                                 */
  81                                continue;
  82                        }
  83                }
  84
  85                /*
  86                 * we've reached the end of a range, with allowed channels
  87                 * found
  88                 */
  89                if (ch_cnt) {
  90                        u8 *pos = skb_put(skb, 2);
  91                        *pos++ = ieee80211_frequency_to_channel(subband_start);
  92                        *pos++ = ch_cnt;
  93
  94                        subband_cnt++;
  95                        ch_cnt = 0;
  96                }
  97        }
  98
  99        /* all channels in the requested range are allowed - add them here */
 100        if (ch_cnt) {
 101                u8 *pos = skb_put(skb, 2);
 102                *pos++ = ieee80211_frequency_to_channel(subband_start);
 103                *pos++ = ch_cnt;
 104
 105                subband_cnt++;
 106        }
 107
 108        return subband_cnt;
 109}
 110
 111static void
 112ieee80211_tdls_add_supp_channels(struct ieee80211_sub_if_data *sdata,
 113                                 struct sk_buff *skb)
 114{
 115        /*
 116         * Add possible channels for TDLS. These are channels that are allowed
 117         * to be active.
 118         */
 119        u8 subband_cnt;
 120        u8 *pos = skb_put(skb, 2);
 121
 122        *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
 123
 124        /*
 125         * 5GHz and 2GHz channels numbers can overlap. Ignore this for now, as
 126         * this doesn't happen in real world scenarios.
 127         */
 128
 129        /* 2GHz, with 5MHz spacing */
 130        subband_cnt = ieee80211_tdls_add_subband(sdata, skb, 2412, 2472, 5);
 131
 132        /* 5GHz, with 20MHz spacing */
 133        subband_cnt += ieee80211_tdls_add_subband(sdata, skb, 5000, 5825, 20);
 134
 135        /* length */
 136        *pos = 2 * subband_cnt;
 137}
 138
 139static void ieee80211_tdls_add_oper_classes(struct ieee80211_sub_if_data *sdata,
 140                                            struct sk_buff *skb)
 141{
 142        u8 *pos;
 143        u8 op_class;
 144
 145        if (!ieee80211_chandef_to_operating_class(&sdata->vif.bss_conf.chandef,
 146                                                  &op_class))
 147                return;
 148
 149        pos = skb_put(skb, 4);
 150        *pos++ = WLAN_EID_SUPPORTED_REGULATORY_CLASSES;
 151        *pos++ = 2; /* len */
 152
 153        *pos++ = op_class;
 154        *pos++ = op_class; /* give current operating class as alternate too */
 155}
 156
 157static void ieee80211_tdls_add_bss_coex_ie(struct sk_buff *skb)
 158{
 159        u8 *pos = (void *)skb_put(skb, 3);
 160
 161        *pos++ = WLAN_EID_BSS_COEX_2040;
 162        *pos++ = 1; /* len */
 163
 164        *pos++ = WLAN_BSS_COEX_INFORMATION_REQUEST;
 165}
 166
 167static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata,
 168                                        u16 status_code)
 169{
 170        /* The capability will be 0 when sending a failure code */
 171        if (status_code != 0)
 172                return 0;
 173
 174        if (ieee80211_get_sdata_band(sdata) == IEEE80211_BAND_2GHZ) {
 175                return WLAN_CAPABILITY_SHORT_SLOT_TIME |
 176                       WLAN_CAPABILITY_SHORT_PREAMBLE;
 177        }
 178
 179        return 0;
 180}
 181
 182static void ieee80211_tdls_add_link_ie(struct ieee80211_sub_if_data *sdata,
 183                                       struct sk_buff *skb, const u8 *peer,
 184                                       bool initiator)
 185{
 186        struct ieee80211_tdls_lnkie *lnkid;
 187        const u8 *init_addr, *rsp_addr;
 188
 189        if (initiator) {
 190                init_addr = sdata->vif.addr;
 191                rsp_addr = peer;
 192        } else {
 193                init_addr = peer;
 194                rsp_addr = sdata->vif.addr;
 195        }
 196
 197        lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
 198
 199        lnkid->ie_type = WLAN_EID_LINK_ID;
 200        lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
 201
 202        memcpy(lnkid->bssid, sdata->u.mgd.bssid, ETH_ALEN);
 203        memcpy(lnkid->init_sta, init_addr, ETH_ALEN);
 204        memcpy(lnkid->resp_sta, rsp_addr, ETH_ALEN);
 205}
 206
 207static void
 208ieee80211_tdls_add_aid(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 209{
 210        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 211        u8 *pos = (void *)skb_put(skb, 4);
 212
 213        *pos++ = WLAN_EID_AID;
 214        *pos++ = 2; /* len */
 215        put_unaligned_le16(ifmgd->aid, pos);
 216}
 217
 218/* translate numbering in the WMM parameter IE to the mac80211 notation */
 219static enum ieee80211_ac_numbers ieee80211_ac_from_wmm(int ac)
 220{
 221        switch (ac) {
 222        default:
 223                WARN_ON_ONCE(1);
 224        case 0:
 225                return IEEE80211_AC_BE;
 226        case 1:
 227                return IEEE80211_AC_BK;
 228        case 2:
 229                return IEEE80211_AC_VI;
 230        case 3:
 231                return IEEE80211_AC_VO;
 232        }
 233}
 234
 235static u8 ieee80211_wmm_aci_aifsn(int aifsn, bool acm, int aci)
 236{
 237        u8 ret;
 238
 239        ret = aifsn & 0x0f;
 240        if (acm)
 241                ret |= 0x10;
 242        ret |= (aci << 5) & 0x60;
 243        return ret;
 244}
 245
 246static u8 ieee80211_wmm_ecw(u16 cw_min, u16 cw_max)
 247{
 248        return ((ilog2(cw_min + 1) << 0x0) & 0x0f) |
 249               ((ilog2(cw_max + 1) << 0x4) & 0xf0);
 250}
 251
 252static void ieee80211_tdls_add_wmm_param_ie(struct ieee80211_sub_if_data *sdata,
 253                                            struct sk_buff *skb)
 254{
 255        struct ieee80211_wmm_param_ie *wmm;
 256        struct ieee80211_tx_queue_params *txq;
 257        int i;
 258
 259        wmm = (void *)skb_put(skb, sizeof(*wmm));
 260        memset(wmm, 0, sizeof(*wmm));
 261
 262        wmm->element_id = WLAN_EID_VENDOR_SPECIFIC;
 263        wmm->len = sizeof(*wmm) - 2;
 264
 265        wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */
 266        wmm->oui[1] = 0x50;
 267        wmm->oui[2] = 0xf2;
 268        wmm->oui_type = 2; /* WME */
 269        wmm->oui_subtype = 1; /* WME param */
 270        wmm->version = 1; /* WME ver */
 271        wmm->qos_info = 0; /* U-APSD not in use */
 272
 273        /*
 274         * Use the EDCA parameters defined for the BSS, or default if the AP
 275         * doesn't support it, as mandated by 802.11-2012 section 10.22.4
 276         */
 277        for (i = 0; i < IEEE80211_NUM_ACS; i++) {
 278                txq = &sdata->tx_conf[ieee80211_ac_from_wmm(i)];
 279                wmm->ac[i].aci_aifsn = ieee80211_wmm_aci_aifsn(txq->aifs,
 280                                                               txq->acm, i);
 281                wmm->ac[i].cw = ieee80211_wmm_ecw(txq->cw_min, txq->cw_max);
 282                wmm->ac[i].txop_limit = cpu_to_le16(txq->txop);
 283        }
 284}
 285
 286static void
 287ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
 288                                   struct sk_buff *skb, const u8 *peer,
 289                                   u8 action_code, bool initiator,
 290                                   const u8 *extra_ies, size_t extra_ies_len)
 291{
 292        enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
 293        struct ieee80211_local *local = sdata->local;
 294        struct ieee80211_supported_band *sband;
 295        struct ieee80211_sta_ht_cap ht_cap;
 296        struct ieee80211_sta_vht_cap vht_cap;
 297        struct sta_info *sta = NULL;
 298        size_t offset = 0, noffset;
 299        u8 *pos;
 300
 301        ieee80211_add_srates_ie(sdata, skb, false, band);
 302        ieee80211_add_ext_srates_ie(sdata, skb, false, band);
 303        ieee80211_tdls_add_supp_channels(sdata, skb);
 304
 305        /* add any custom IEs that go before Extended Capabilities */
 306        if (extra_ies_len) {
 307                static const u8 before_ext_cap[] = {
 308                        WLAN_EID_SUPP_RATES,
 309                        WLAN_EID_COUNTRY,
 310                        WLAN_EID_EXT_SUPP_RATES,
 311                        WLAN_EID_SUPPORTED_CHANNELS,
 312                        WLAN_EID_RSN,
 313                };
 314                noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
 315                                             before_ext_cap,
 316                                             ARRAY_SIZE(before_ext_cap),
 317                                             offset);
 318                pos = skb_put(skb, noffset - offset);
 319                memcpy(pos, extra_ies + offset, noffset - offset);
 320                offset = noffset;
 321        }
 322
 323        ieee80211_tdls_add_ext_capab(local, skb);
 324
 325        /* add the QoS element if we support it */
 326        if (local->hw.queues >= IEEE80211_NUM_ACS &&
 327            action_code != WLAN_PUB_ACTION_TDLS_DISCOVER_RES)
 328                ieee80211_add_wmm_info_ie(skb_put(skb, 9), 0); /* no U-APSD */
 329
 330        /* add any custom IEs that go before HT capabilities */
 331        if (extra_ies_len) {
 332                static const u8 before_ht_cap[] = {
 333                        WLAN_EID_SUPP_RATES,
 334                        WLAN_EID_COUNTRY,
 335                        WLAN_EID_EXT_SUPP_RATES,
 336                        WLAN_EID_SUPPORTED_CHANNELS,
 337                        WLAN_EID_RSN,
 338                        WLAN_EID_EXT_CAPABILITY,
 339                        WLAN_EID_QOS_CAPA,
 340                        WLAN_EID_FAST_BSS_TRANSITION,
 341                        WLAN_EID_TIMEOUT_INTERVAL,
 342                        WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
 343                };
 344                noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
 345                                             before_ht_cap,
 346                                             ARRAY_SIZE(before_ht_cap),
 347                                             offset);
 348                pos = skb_put(skb, noffset - offset);
 349                memcpy(pos, extra_ies + offset, noffset - offset);
 350                offset = noffset;
 351        }
 352
 353        rcu_read_lock();
 354
 355        /* we should have the peer STA if we're already responding */
 356        if (action_code == WLAN_TDLS_SETUP_RESPONSE) {
 357                sta = sta_info_get(sdata, peer);
 358                if (WARN_ON_ONCE(!sta)) {
 359                        rcu_read_unlock();
 360                        return;
 361                }
 362        }
 363
 364        ieee80211_tdls_add_oper_classes(sdata, skb);
 365
 366        /*
 367         * with TDLS we can switch channels, and HT-caps are not necessarily
 368         * the same on all bands. The specification limits the setup to a
 369         * single HT-cap, so use the current band for now.
 370         */
 371        sband = local->hw.wiphy->bands[band];
 372        memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
 373
 374        if ((action_code == WLAN_TDLS_SETUP_REQUEST ||
 375             action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) &&
 376            ht_cap.ht_supported) {
 377                ieee80211_apply_htcap_overrides(sdata, &ht_cap);
 378
 379                /* disable SMPS in TDLS initiator */
 380                ht_cap.cap |= WLAN_HT_CAP_SM_PS_DISABLED
 381                                << IEEE80211_HT_CAP_SM_PS_SHIFT;
 382
 383                pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
 384                ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap);
 385        } else if (action_code == WLAN_TDLS_SETUP_RESPONSE &&
 386                   ht_cap.ht_supported && sta->sta.ht_cap.ht_supported) {
 387                /* disable SMPS in TDLS responder */
 388                sta->sta.ht_cap.cap |= WLAN_HT_CAP_SM_PS_DISABLED
 389                                        << IEEE80211_HT_CAP_SM_PS_SHIFT;
 390
 391                /* the peer caps are already intersected with our own */
 392                memcpy(&ht_cap, &sta->sta.ht_cap, sizeof(ht_cap));
 393
 394                pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
 395                ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap);
 396        }
 397
 398        if (ht_cap.ht_supported &&
 399            (ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
 400                ieee80211_tdls_add_bss_coex_ie(skb);
 401
 402        ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
 403
 404        /* add any custom IEs that go before VHT capabilities */
 405        if (extra_ies_len) {
 406                static const u8 before_vht_cap[] = {
 407                        WLAN_EID_SUPP_RATES,
 408                        WLAN_EID_COUNTRY,
 409                        WLAN_EID_EXT_SUPP_RATES,
 410                        WLAN_EID_SUPPORTED_CHANNELS,
 411                        WLAN_EID_RSN,
 412                        WLAN_EID_EXT_CAPABILITY,
 413                        WLAN_EID_QOS_CAPA,
 414                        WLAN_EID_FAST_BSS_TRANSITION,
 415                        WLAN_EID_TIMEOUT_INTERVAL,
 416                        WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
 417                        WLAN_EID_MULTI_BAND,
 418                };
 419                noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
 420                                             before_vht_cap,
 421                                             ARRAY_SIZE(before_vht_cap),
 422                                             offset);
 423                pos = skb_put(skb, noffset - offset);
 424                memcpy(pos, extra_ies + offset, noffset - offset);
 425                offset = noffset;
 426        }
 427
 428        /* build the VHT-cap similarly to the HT-cap */
 429        memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
 430        if ((action_code == WLAN_TDLS_SETUP_REQUEST ||
 431             action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) &&
 432            vht_cap.vht_supported) {
 433                ieee80211_apply_vhtcap_overrides(sdata, &vht_cap);
 434
 435                /* the AID is present only when VHT is implemented */
 436                if (action_code == WLAN_TDLS_SETUP_REQUEST)
 437                        ieee80211_tdls_add_aid(sdata, skb);
 438
 439                pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
 440                ieee80211_ie_build_vht_cap(pos, &vht_cap, vht_cap.cap);
 441        } else if (action_code == WLAN_TDLS_SETUP_RESPONSE &&
 442                   vht_cap.vht_supported && sta->sta.vht_cap.vht_supported) {
 443                /* the peer caps are already intersected with our own */
 444                memcpy(&vht_cap, &sta->sta.vht_cap, sizeof(vht_cap));
 445
 446                /* the AID is present only when VHT is implemented */
 447                ieee80211_tdls_add_aid(sdata, skb);
 448
 449                pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
 450                ieee80211_ie_build_vht_cap(pos, &vht_cap, vht_cap.cap);
 451        }
 452
 453        rcu_read_unlock();
 454
 455        /* add any remaining IEs */
 456        if (extra_ies_len) {
 457                noffset = extra_ies_len;
 458                pos = skb_put(skb, noffset - offset);
 459                memcpy(pos, extra_ies + offset, noffset - offset);
 460        }
 461
 462}
 463
 464static void
 465ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
 466                                 struct sk_buff *skb, const u8 *peer,
 467                                 bool initiator, const u8 *extra_ies,
 468                                 size_t extra_ies_len)
 469{
 470        struct ieee80211_local *local = sdata->local;
 471        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 472        size_t offset = 0, noffset;
 473        struct sta_info *sta, *ap_sta;
 474        enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
 475        u8 *pos;
 476
 477        rcu_read_lock();
 478
 479        sta = sta_info_get(sdata, peer);
 480        ap_sta = sta_info_get(sdata, ifmgd->bssid);
 481        if (WARN_ON_ONCE(!sta || !ap_sta)) {
 482                rcu_read_unlock();
 483                return;
 484        }
 485
 486        /* add any custom IEs that go before the QoS IE */
 487        if (extra_ies_len) {
 488                static const u8 before_qos[] = {
 489                        WLAN_EID_RSN,
 490                };
 491                noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
 492                                             before_qos,
 493                                             ARRAY_SIZE(before_qos),
 494                                             offset);
 495                pos = skb_put(skb, noffset - offset);
 496                memcpy(pos, extra_ies + offset, noffset - offset);
 497                offset = noffset;
 498        }
 499
 500        /* add the QoS param IE if both the peer and we support it */
 501        if (local->hw.queues >= IEEE80211_NUM_ACS && sta->sta.wme)
 502                ieee80211_tdls_add_wmm_param_ie(sdata, skb);
 503
 504        /* add any custom IEs that go before HT operation */
 505        if (extra_ies_len) {
 506                static const u8 before_ht_op[] = {
 507                        WLAN_EID_RSN,
 508                        WLAN_EID_QOS_CAPA,
 509                        WLAN_EID_FAST_BSS_TRANSITION,
 510                        WLAN_EID_TIMEOUT_INTERVAL,
 511                };
 512                noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
 513                                             before_ht_op,
 514                                             ARRAY_SIZE(before_ht_op),
 515                                             offset);
 516                pos = skb_put(skb, noffset - offset);
 517                memcpy(pos, extra_ies + offset, noffset - offset);
 518                offset = noffset;
 519        }
 520
 521        /* if HT support is only added in TDLS, we need an HT-operation IE */
 522        if (!ap_sta->sta.ht_cap.ht_supported && sta->sta.ht_cap.ht_supported) {
 523                pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation));
 524                /* send an empty HT operation IE */
 525                ieee80211_ie_build_ht_oper(pos, &sta->sta.ht_cap,
 526                                           &sdata->vif.bss_conf.chandef, 0);
 527        }
 528
 529        ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
 530
 531        /* only include VHT-operation if not on the 2.4GHz band */
 532        if (band != IEEE80211_BAND_2GHZ && sta->sta.vht_cap.vht_supported) {
 533                pos = skb_put(skb, 2 + sizeof(struct ieee80211_vht_operation));
 534                ieee80211_ie_build_vht_oper(pos, &sta->sta.vht_cap,
 535                                            &sdata->vif.bss_conf.chandef);
 536        }
 537
 538        rcu_read_unlock();
 539
 540        /* add any remaining IEs */
 541        if (extra_ies_len) {
 542                noffset = extra_ies_len;
 543                pos = skb_put(skb, noffset - offset);
 544                memcpy(pos, extra_ies + offset, noffset - offset);
 545        }
 546}
 547
 548static void
 549ieee80211_tdls_add_chan_switch_req_ies(struct ieee80211_sub_if_data *sdata,
 550                                       struct sk_buff *skb, const u8 *peer,
 551                                       bool initiator, const u8 *extra_ies,
 552                                       size_t extra_ies_len, u8 oper_class,
 553                                       struct cfg80211_chan_def *chandef)
 554{
 555        struct ieee80211_tdls_data *tf;
 556        size_t offset = 0, noffset;
 557        u8 *pos;
 558
 559        if (WARN_ON_ONCE(!chandef))
 560                return;
 561
 562        tf = (void *)skb->data;
 563        tf->u.chan_switch_req.target_channel =
 564                ieee80211_frequency_to_channel(chandef->chan->center_freq);
 565        tf->u.chan_switch_req.oper_class = oper_class;
 566
 567        if (extra_ies_len) {
 568                static const u8 before_lnkie[] = {
 569                        WLAN_EID_SECONDARY_CHANNEL_OFFSET,
 570                };
 571                noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
 572                                             before_lnkie,
 573                                             ARRAY_SIZE(before_lnkie),
 574                                             offset);
 575                pos = skb_put(skb, noffset - offset);
 576                memcpy(pos, extra_ies + offset, noffset - offset);
 577                offset = noffset;
 578        }
 579
 580        ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
 581
 582        /* add any remaining IEs */
 583        if (extra_ies_len) {
 584                noffset = extra_ies_len;
 585                pos = skb_put(skb, noffset - offset);
 586                memcpy(pos, extra_ies + offset, noffset - offset);
 587        }
 588}
 589
 590static void
 591ieee80211_tdls_add_chan_switch_resp_ies(struct ieee80211_sub_if_data *sdata,
 592                                        struct sk_buff *skb, const u8 *peer,
 593                                        u16 status_code, bool initiator,
 594                                        const u8 *extra_ies,
 595                                        size_t extra_ies_len)
 596{
 597        if (status_code == 0)
 598                ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
 599
 600        if (extra_ies_len)
 601                memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len);
 602}
 603
 604static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata,
 605                                   struct sk_buff *skb, const u8 *peer,
 606                                   u8 action_code, u16 status_code,
 607                                   bool initiator, const u8 *extra_ies,
 608                                   size_t extra_ies_len, u8 oper_class,
 609                                   struct cfg80211_chan_def *chandef)
 610{
 611        switch (action_code) {
 612        case WLAN_TDLS_SETUP_REQUEST:
 613        case WLAN_TDLS_SETUP_RESPONSE:
 614        case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
 615                if (status_code == 0)
 616                        ieee80211_tdls_add_setup_start_ies(sdata, skb, peer,
 617                                                           action_code,
 618                                                           initiator,
 619                                                           extra_ies,
 620                                                           extra_ies_len);
 621                break;
 622        case WLAN_TDLS_SETUP_CONFIRM:
 623                if (status_code == 0)
 624                        ieee80211_tdls_add_setup_cfm_ies(sdata, skb, peer,
 625                                                         initiator, extra_ies,
 626                                                         extra_ies_len);
 627                break;
 628        case WLAN_TDLS_TEARDOWN:
 629        case WLAN_TDLS_DISCOVERY_REQUEST:
 630                if (extra_ies_len)
 631                        memcpy(skb_put(skb, extra_ies_len), extra_ies,
 632                               extra_ies_len);
 633                if (status_code == 0 || action_code == WLAN_TDLS_TEARDOWN)
 634                        ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
 635                break;
 636        case WLAN_TDLS_CHANNEL_SWITCH_REQUEST:
 637                ieee80211_tdls_add_chan_switch_req_ies(sdata, skb, peer,
 638                                                       initiator, extra_ies,
 639                                                       extra_ies_len,
 640                                                       oper_class, chandef);
 641                break;
 642        case WLAN_TDLS_CHANNEL_SWITCH_RESPONSE:
 643                ieee80211_tdls_add_chan_switch_resp_ies(sdata, skb, peer,
 644                                                        status_code,
 645                                                        initiator, extra_ies,
 646                                                        extra_ies_len);
 647                break;
 648        }
 649
 650}
 651
 652static int
 653ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
 654                               const u8 *peer, u8 action_code, u8 dialog_token,
 655                               u16 status_code, struct sk_buff *skb)
 656{
 657        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 658        struct ieee80211_tdls_data *tf;
 659
 660        tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
 661
 662        memcpy(tf->da, peer, ETH_ALEN);
 663        memcpy(tf->sa, sdata->vif.addr, ETH_ALEN);
 664        tf->ether_type = cpu_to_be16(ETH_P_TDLS);
 665        tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
 666
 667        /* network header is after the ethernet header */
 668        skb_set_network_header(skb, ETH_HLEN);
 669
 670        switch (action_code) {
 671        case WLAN_TDLS_SETUP_REQUEST:
 672                tf->category = WLAN_CATEGORY_TDLS;
 673                tf->action_code = WLAN_TDLS_SETUP_REQUEST;
 674
 675                skb_put(skb, sizeof(tf->u.setup_req));
 676                tf->u.setup_req.dialog_token = dialog_token;
 677                tf->u.setup_req.capability =
 678                        cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
 679                                                                 status_code));
 680                break;
 681        case WLAN_TDLS_SETUP_RESPONSE:
 682                tf->category = WLAN_CATEGORY_TDLS;
 683                tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
 684
 685                skb_put(skb, sizeof(tf->u.setup_resp));
 686                tf->u.setup_resp.status_code = cpu_to_le16(status_code);
 687                tf->u.setup_resp.dialog_token = dialog_token;
 688                tf->u.setup_resp.capability =
 689                        cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
 690                                                                 status_code));
 691                break;
 692        case WLAN_TDLS_SETUP_CONFIRM:
 693                tf->category = WLAN_CATEGORY_TDLS;
 694                tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
 695
 696                skb_put(skb, sizeof(tf->u.setup_cfm));
 697                tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
 698                tf->u.setup_cfm.dialog_token = dialog_token;
 699                break;
 700        case WLAN_TDLS_TEARDOWN:
 701                tf->category = WLAN_CATEGORY_TDLS;
 702                tf->action_code = WLAN_TDLS_TEARDOWN;
 703
 704                skb_put(skb, sizeof(tf->u.teardown));
 705                tf->u.teardown.reason_code = cpu_to_le16(status_code);
 706                break;
 707        case WLAN_TDLS_DISCOVERY_REQUEST:
 708                tf->category = WLAN_CATEGORY_TDLS;
 709                tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
 710
 711                skb_put(skb, sizeof(tf->u.discover_req));
 712                tf->u.discover_req.dialog_token = dialog_token;
 713                break;
 714        case WLAN_TDLS_CHANNEL_SWITCH_REQUEST:
 715                tf->category = WLAN_CATEGORY_TDLS;
 716                tf->action_code = WLAN_TDLS_CHANNEL_SWITCH_REQUEST;
 717
 718                skb_put(skb, sizeof(tf->u.chan_switch_req));
 719                break;
 720        case WLAN_TDLS_CHANNEL_SWITCH_RESPONSE:
 721                tf->category = WLAN_CATEGORY_TDLS;
 722                tf->action_code = WLAN_TDLS_CHANNEL_SWITCH_RESPONSE;
 723
 724                skb_put(skb, sizeof(tf->u.chan_switch_resp));
 725                tf->u.chan_switch_resp.status_code = cpu_to_le16(status_code);
 726                break;
 727        default:
 728                return -EINVAL;
 729        }
 730
 731        return 0;
 732}
 733
 734static int
 735ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
 736                           const u8 *peer, u8 action_code, u8 dialog_token,
 737                           u16 status_code, struct sk_buff *skb)
 738{
 739        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 740        struct ieee80211_mgmt *mgmt;
 741
 742        mgmt = (void *)skb_put(skb, 24);
 743        memset(mgmt, 0, 24);
 744        memcpy(mgmt->da, peer, ETH_ALEN);
 745        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
 746        memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
 747
 748        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 749                                          IEEE80211_STYPE_ACTION);
 750
 751        switch (action_code) {
 752        case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
 753                skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
 754                mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
 755                mgmt->u.action.u.tdls_discover_resp.action_code =
 756                        WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
 757                mgmt->u.action.u.tdls_discover_resp.dialog_token =
 758                        dialog_token;
 759                mgmt->u.action.u.tdls_discover_resp.capability =
 760                        cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
 761                                                                 status_code));
 762                break;
 763        default:
 764                return -EINVAL;
 765        }
 766
 767        return 0;
 768}
 769
 770static struct sk_buff *
 771ieee80211_tdls_build_mgmt_packet_data(struct ieee80211_sub_if_data *sdata,
 772                                      const u8 *peer, u8 action_code,
 773                                      u8 dialog_token, u16 status_code,
 774                                      bool initiator, const u8 *extra_ies,
 775                                      size_t extra_ies_len, u8 oper_class,
 776                                      struct cfg80211_chan_def *chandef)
 777{
 778        struct ieee80211_local *local = sdata->local;
 779        struct sk_buff *skb;
 780        int ret;
 781
 782        skb = netdev_alloc_skb(sdata->dev,
 783                               local->hw.extra_tx_headroom +
 784                               max(sizeof(struct ieee80211_mgmt),
 785                                   sizeof(struct ieee80211_tdls_data)) +
 786                               50 + /* supported rates */
 787                               7 + /* ext capab */
 788                               26 + /* max(WMM-info, WMM-param) */
 789                               2 + max(sizeof(struct ieee80211_ht_cap),
 790                                       sizeof(struct ieee80211_ht_operation)) +
 791                               2 + max(sizeof(struct ieee80211_vht_cap),
 792                                       sizeof(struct ieee80211_vht_operation)) +
 793                               50 + /* supported channels */
 794                               3 + /* 40/20 BSS coex */
 795                               4 + /* AID */
 796                               4 + /* oper classes */
 797                               extra_ies_len +
 798                               sizeof(struct ieee80211_tdls_lnkie));
 799        if (!skb)
 800                return NULL;
 801
 802        skb_reserve(skb, local->hw.extra_tx_headroom);
 803
 804        switch (action_code) {
 805        case WLAN_TDLS_SETUP_REQUEST:
 806        case WLAN_TDLS_SETUP_RESPONSE:
 807        case WLAN_TDLS_SETUP_CONFIRM:
 808        case WLAN_TDLS_TEARDOWN:
 809        case WLAN_TDLS_DISCOVERY_REQUEST:
 810        case WLAN_TDLS_CHANNEL_SWITCH_REQUEST:
 811        case WLAN_TDLS_CHANNEL_SWITCH_RESPONSE:
 812                ret = ieee80211_prep_tdls_encap_data(local->hw.wiphy,
 813                                                     sdata->dev, peer,
 814                                                     action_code, dialog_token,
 815                                                     status_code, skb);
 816                break;
 817        case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
 818                ret = ieee80211_prep_tdls_direct(local->hw.wiphy, sdata->dev,
 819                                                 peer, action_code,
 820                                                 dialog_token, status_code,
 821                                                 skb);
 822                break;
 823        default:
 824                ret = -ENOTSUPP;
 825                break;
 826        }
 827
 828        if (ret < 0)
 829                goto fail;
 830
 831        ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code,
 832                               initiator, extra_ies, extra_ies_len, oper_class,
 833                               chandef);
 834        return skb;
 835
 836fail:
 837        dev_kfree_skb(skb);
 838        return NULL;
 839}
 840
 841static int
 842ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
 843                                const u8 *peer, u8 action_code, u8 dialog_token,
 844                                u16 status_code, u32 peer_capability,
 845                                bool initiator, const u8 *extra_ies,
 846                                size_t extra_ies_len, u8 oper_class,
 847                                struct cfg80211_chan_def *chandef)
 848{
 849        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 850        struct sk_buff *skb = NULL;
 851        struct sta_info *sta;
 852        u32 flags = 0;
 853        int ret = 0;
 854
 855        rcu_read_lock();
 856        sta = sta_info_get(sdata, peer);
 857
 858        /* infer the initiator if we can, to support old userspace */
 859        switch (action_code) {
 860        case WLAN_TDLS_SETUP_REQUEST:
 861                if (sta) {
 862                        set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
 863                        sta->sta.tdls_initiator = false;
 864                }
 865                /* fall-through */
 866        case WLAN_TDLS_SETUP_CONFIRM:
 867        case WLAN_TDLS_DISCOVERY_REQUEST:
 868                initiator = true;
 869                break;
 870        case WLAN_TDLS_SETUP_RESPONSE:
 871                /*
 872                 * In some testing scenarios, we send a request and response.
 873                 * Make the last packet sent take effect for the initiator
 874                 * value.
 875                 */
 876                if (sta) {
 877                        clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
 878                        sta->sta.tdls_initiator = true;
 879                }
 880                /* fall-through */
 881        case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
 882                initiator = false;
 883                break;
 884        case WLAN_TDLS_TEARDOWN:
 885        case WLAN_TDLS_CHANNEL_SWITCH_REQUEST:
 886        case WLAN_TDLS_CHANNEL_SWITCH_RESPONSE:
 887                /* any value is ok */
 888                break;
 889        default:
 890                ret = -ENOTSUPP;
 891                break;
 892        }
 893
 894        if (sta && test_sta_flag(sta, WLAN_STA_TDLS_INITIATOR))
 895                initiator = true;
 896
 897        rcu_read_unlock();
 898        if (ret < 0)
 899                goto fail;
 900
 901        skb = ieee80211_tdls_build_mgmt_packet_data(sdata, peer, action_code,
 902                                                    dialog_token, status_code,
 903                                                    initiator, extra_ies,
 904                                                    extra_ies_len, oper_class,
 905                                                    chandef);
 906        if (!skb) {
 907                ret = -EINVAL;
 908                goto fail;
 909        }
 910
 911        if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
 912                ieee80211_tx_skb(sdata, skb);
 913                return 0;
 914        }
 915
 916        /*
 917         * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise
 918         * we should default to AC_VI.
 919         */
 920        switch (action_code) {
 921        case WLAN_TDLS_SETUP_REQUEST:
 922        case WLAN_TDLS_SETUP_RESPONSE:
 923                skb_set_queue_mapping(skb, IEEE80211_AC_BK);
 924                skb->priority = 2;
 925                break;
 926        default:
 927                skb_set_queue_mapping(skb, IEEE80211_AC_VI);
 928                skb->priority = 5;
 929                break;
 930        }
 931
 932        /*
 933         * Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress.
 934         * Later, if no ACK is returned from peer, we will re-send the teardown
 935         * packet through the AP.
 936         */
 937        if ((action_code == WLAN_TDLS_TEARDOWN) &&
 938            ieee80211_hw_check(&sdata->local->hw, REPORTS_TX_ACK_STATUS)) {
 939                bool try_resend; /* Should we keep skb for possible resend */
 940
 941                /* If not sending directly to peer - no point in keeping skb */
 942                rcu_read_lock();
 943                sta = sta_info_get(sdata, peer);
 944                try_resend = sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
 945                rcu_read_unlock();
 946
 947                spin_lock_bh(&sdata->u.mgd.teardown_lock);
 948                if (try_resend && !sdata->u.mgd.teardown_skb) {
 949                        /* Mark it as requiring TX status callback  */
 950                        flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
 951                                 IEEE80211_TX_INTFL_MLME_CONN_TX;
 952
 953                        /*
 954                         * skb is copied since mac80211 will later set
 955                         * properties that might not be the same as the AP,
 956                         * such as encryption, QoS, addresses, etc.
 957                         *
 958                         * No problem if skb_copy() fails, so no need to check.
 959                         */
 960                        sdata->u.mgd.teardown_skb = skb_copy(skb, GFP_ATOMIC);
 961                        sdata->u.mgd.orig_teardown_skb = skb;
 962                }
 963                spin_unlock_bh(&sdata->u.mgd.teardown_lock);
 964        }
 965
 966        /* disable bottom halves when entering the Tx path */
 967        local_bh_disable();
 968        __ieee80211_subif_start_xmit(skb, dev, flags);
 969        local_bh_enable();
 970
 971        return ret;
 972
 973fail:
 974        dev_kfree_skb(skb);
 975        return ret;
 976}
 977
 978static int
 979ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev,
 980                          const u8 *peer, u8 action_code, u8 dialog_token,
 981                          u16 status_code, u32 peer_capability, bool initiator,
 982                          const u8 *extra_ies, size_t extra_ies_len)
 983{
 984        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 985        struct ieee80211_local *local = sdata->local;
 986        int ret;
 987
 988        mutex_lock(&local->mtx);
 989
 990        /* we don't support concurrent TDLS peer setups */
 991        if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer) &&
 992            !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) {
 993                ret = -EBUSY;
 994                goto out_unlock;
 995        }
 996
 997        /*
 998         * make sure we have a STA representing the peer so we drop or buffer
 999         * non-TDLS-setup frames to the peer. We can't send other packets
1000         * during setup through the AP path.
1001         * Allow error packets to be sent - sometimes we don't even add a STA
1002         * before failing the setup.
1003         */
1004        if (status_code == 0) {
1005                rcu_read_lock();
1006                if (!sta_info_get(sdata, peer)) {
1007                        rcu_read_unlock();
1008                        ret = -ENOLINK;
1009                        goto out_unlock;
1010                }
1011                rcu_read_unlock();
1012        }
1013
1014        ieee80211_flush_queues(local, sdata, false);
1015        memcpy(sdata->u.mgd.tdls_peer, peer, ETH_ALEN);
1016        mutex_unlock(&local->mtx);
1017
1018        /* we cannot take the mutex while preparing the setup packet */
1019        ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
1020                                              dialog_token, status_code,
1021                                              peer_capability, initiator,
1022                                              extra_ies, extra_ies_len, 0,
1023                                              NULL);
1024        if (ret < 0) {
1025                mutex_lock(&local->mtx);
1026                eth_zero_addr(sdata->u.mgd.tdls_peer);
1027                mutex_unlock(&local->mtx);
1028                return ret;
1029        }
1030
1031        ieee80211_queue_delayed_work(&sdata->local->hw,
1032                                     &sdata->u.mgd.tdls_peer_del_work,
1033                                     TDLS_PEER_SETUP_TIMEOUT);
1034        return 0;
1035
1036out_unlock:
1037        mutex_unlock(&local->mtx);
1038        return ret;
1039}
1040
1041static int
1042ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev,
1043                             const u8 *peer, u8 action_code, u8 dialog_token,
1044                             u16 status_code, u32 peer_capability,
1045                             bool initiator, const u8 *extra_ies,
1046                             size_t extra_ies_len)
1047{
1048        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1049        struct ieee80211_local *local = sdata->local;
1050        struct sta_info *sta;
1051        int ret;
1052
1053        /*
1054         * No packets can be transmitted to the peer via the AP during setup -
1055         * the STA is set as a TDLS peer, but is not authorized.
1056         * During teardown, we prevent direct transmissions by stopping the
1057         * queues and flushing all direct packets.
1058         */
1059        ieee80211_stop_vif_queues(local, sdata,
1060                                  IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
1061        ieee80211_flush_queues(local, sdata, false);
1062
1063        ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
1064                                              dialog_token, status_code,
1065                                              peer_capability, initiator,
1066                                              extra_ies, extra_ies_len, 0,
1067                                              NULL);
1068        if (ret < 0)
1069                sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
1070                          ret);
1071
1072        /*
1073         * Remove the STA AUTH flag to force further traffic through the AP. If
1074         * the STA was unreachable, it was already removed.
1075         */
1076        rcu_read_lock();
1077        sta = sta_info_get(sdata, peer);
1078        if (sta)
1079                clear_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
1080        rcu_read_unlock();
1081
1082        ieee80211_wake_vif_queues(local, sdata,
1083                                  IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
1084
1085        return 0;
1086}
1087
1088int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
1089                        const u8 *peer, u8 action_code, u8 dialog_token,
1090                        u16 status_code, u32 peer_capability,
1091                        bool initiator, const u8 *extra_ies,
1092                        size_t extra_ies_len)
1093{
1094        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1095        int ret;
1096
1097        if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
1098                return -ENOTSUPP;
1099
1100        /* make sure we are in managed mode, and associated */
1101        if (sdata->vif.type != NL80211_IFTYPE_STATION ||
1102            !sdata->u.mgd.associated)
1103                return -EINVAL;
1104
1105        switch (action_code) {
1106        case WLAN_TDLS_SETUP_REQUEST:
1107        case WLAN_TDLS_SETUP_RESPONSE:
1108                ret = ieee80211_tdls_mgmt_setup(wiphy, dev, peer, action_code,
1109                                                dialog_token, status_code,
1110                                                peer_capability, initiator,
1111                                                extra_ies, extra_ies_len);
1112                break;
1113        case WLAN_TDLS_TEARDOWN:
1114                ret = ieee80211_tdls_mgmt_teardown(wiphy, dev, peer,
1115                                                   action_code, dialog_token,
1116                                                   status_code,
1117                                                   peer_capability, initiator,
1118                                                   extra_ies, extra_ies_len);
1119                break;
1120        case WLAN_TDLS_DISCOVERY_REQUEST:
1121                /*
1122                 * Protect the discovery so we can hear the TDLS discovery
1123                 * response frame. It is transmitted directly and not buffered
1124                 * by the AP.
1125                 */
1126                drv_mgd_protect_tdls_discover(sdata->local, sdata);
1127                /* fall-through */
1128        case WLAN_TDLS_SETUP_CONFIRM:
1129        case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
1130                /* no special handling */
1131                ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
1132                                                      action_code,
1133                                                      dialog_token,
1134                                                      status_code,
1135                                                      peer_capability,
1136                                                      initiator, extra_ies,
1137                                                      extra_ies_len, 0, NULL);
1138                break;
1139        default:
1140                ret = -EOPNOTSUPP;
1141                break;
1142        }
1143
1144        tdls_dbg(sdata, "TDLS mgmt action %d peer %pM status %d\n",
1145                 action_code, peer, ret);
1146        return ret;
1147}
1148
1149int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
1150                        const u8 *peer, enum nl80211_tdls_operation oper)
1151{
1152        struct sta_info *sta;
1153        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1154        struct ieee80211_local *local = sdata->local;
1155        int ret;
1156
1157        if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
1158                return -ENOTSUPP;
1159
1160        if (sdata->vif.type != NL80211_IFTYPE_STATION)
1161                return -EINVAL;
1162
1163        switch (oper) {
1164        case NL80211_TDLS_ENABLE_LINK:
1165        case NL80211_TDLS_DISABLE_LINK:
1166                break;
1167        case NL80211_TDLS_TEARDOWN:
1168        case NL80211_TDLS_SETUP:
1169        case NL80211_TDLS_DISCOVERY_REQ:
1170                /* We don't support in-driver setup/teardown/discovery */
1171                return -ENOTSUPP;
1172        }
1173
1174        mutex_lock(&local->mtx);
1175        tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
1176
1177        switch (oper) {
1178        case NL80211_TDLS_ENABLE_LINK:
1179                if (sdata->vif.csa_active) {
1180                        tdls_dbg(sdata, "TDLS: disallow link during CSA\n");
1181                        ret = -EBUSY;
1182                        break;
1183                }
1184
1185                rcu_read_lock();
1186                sta = sta_info_get(sdata, peer);
1187                if (!sta) {
1188                        rcu_read_unlock();
1189                        ret = -ENOLINK;
1190                        break;
1191                }
1192
1193                set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
1194                rcu_read_unlock();
1195
1196                WARN_ON_ONCE(is_zero_ether_addr(sdata->u.mgd.tdls_peer) ||
1197                             !ether_addr_equal(sdata->u.mgd.tdls_peer, peer));
1198                ret = 0;
1199                break;
1200        case NL80211_TDLS_DISABLE_LINK:
1201                /*
1202                 * The teardown message in ieee80211_tdls_mgmt_teardown() was
1203                 * created while the queues were stopped, so it might still be
1204                 * pending. Before flushing the queues we need to be sure the
1205                 * message is handled by the tasklet handling pending messages,
1206                 * otherwise we might start destroying the station before
1207                 * sending the teardown packet.
1208                 * Note that this only forces the tasklet to flush pendings -
1209                 * not to stop the tasklet from rescheduling itself.
1210                 */
1211                tasklet_kill(&local->tx_pending_tasklet);
1212                /* flush a potentially queued teardown packet */
1213                ieee80211_flush_queues(local, sdata, false);
1214
1215                ret = sta_info_destroy_addr(sdata, peer);
1216                break;
1217        default:
1218                ret = -ENOTSUPP;
1219                break;
1220        }
1221
1222        if (ret == 0 && ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) {
1223                cancel_delayed_work(&sdata->u.mgd.tdls_peer_del_work);
1224                eth_zero_addr(sdata->u.mgd.tdls_peer);
1225        }
1226
1227        mutex_unlock(&local->mtx);
1228        return ret;
1229}
1230
1231void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
1232                                 enum nl80211_tdls_operation oper,
1233                                 u16 reason_code, gfp_t gfp)
1234{
1235        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1236
1237        if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) {
1238                sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n",
1239                          oper);
1240                return;
1241        }
1242
1243        cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp);
1244}
1245EXPORT_SYMBOL(ieee80211_tdls_oper_request);
1246
1247static void
1248iee80211_tdls_add_ch_switch_timing(u8 *buf, u16 switch_time, u16 switch_timeout)
1249{
1250        struct ieee80211_ch_switch_timing *ch_sw;
1251
1252        *buf++ = WLAN_EID_CHAN_SWITCH_TIMING;
1253        *buf++ = sizeof(struct ieee80211_ch_switch_timing);
1254
1255        ch_sw = (void *)buf;
1256        ch_sw->switch_time = cpu_to_le16(switch_time);
1257        ch_sw->switch_timeout = cpu_to_le16(switch_timeout);
1258}
1259
1260/* find switch timing IE in SKB ready for Tx */
1261static const u8 *ieee80211_tdls_find_sw_timing_ie(struct sk_buff *skb)
1262{
1263        struct ieee80211_tdls_data *tf;
1264        const u8 *ie_start;
1265
1266        /*
1267         * Get the offset for the new location of the switch timing IE.
1268         * The SKB network header will now point to the "payload_type"
1269         * element of the TDLS data frame struct.
1270         */
1271        tf = container_of(skb->data + skb_network_offset(skb),
1272                          struct ieee80211_tdls_data, payload_type);
1273        ie_start = tf->u.chan_switch_req.variable;
1274        return cfg80211_find_ie(WLAN_EID_CHAN_SWITCH_TIMING, ie_start,
1275                                skb->len - (ie_start - skb->data));
1276}
1277
1278static struct sk_buff *
1279ieee80211_tdls_ch_sw_tmpl_get(struct sta_info *sta, u8 oper_class,
1280                              struct cfg80211_chan_def *chandef,
1281                              u32 *ch_sw_tm_ie_offset)
1282{
1283        struct ieee80211_sub_if_data *sdata = sta->sdata;
1284        u8 extra_ies[2 + sizeof(struct ieee80211_sec_chan_offs_ie) +
1285                     2 + sizeof(struct ieee80211_ch_switch_timing)];
1286        int extra_ies_len = 2 + sizeof(struct ieee80211_ch_switch_timing);
1287        u8 *pos = extra_ies;
1288        struct sk_buff *skb;
1289
1290        /*
1291         * if chandef points to a wide channel add a Secondary-Channel
1292         * Offset information element
1293         */
1294        if (chandef->width == NL80211_CHAN_WIDTH_40) {
1295                struct ieee80211_sec_chan_offs_ie *sec_chan_ie;
1296                bool ht40plus;
1297
1298                *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET;
1299                *pos++ = sizeof(*sec_chan_ie);
1300                sec_chan_ie = (void *)pos;
1301
1302                ht40plus = cfg80211_get_chandef_type(chandef) ==
1303                                                        NL80211_CHAN_HT40PLUS;
1304                sec_chan_ie->sec_chan_offs = ht40plus ?
1305                                             IEEE80211_HT_PARAM_CHA_SEC_ABOVE :
1306                                             IEEE80211_HT_PARAM_CHA_SEC_BELOW;
1307                pos += sizeof(*sec_chan_ie);
1308
1309                extra_ies_len += 2 + sizeof(struct ieee80211_sec_chan_offs_ie);
1310        }
1311
1312        /* just set the values to 0, this is a template */
1313        iee80211_tdls_add_ch_switch_timing(pos, 0, 0);
1314
1315        skb = ieee80211_tdls_build_mgmt_packet_data(sdata, sta->sta.addr,
1316                                              WLAN_TDLS_CHANNEL_SWITCH_REQUEST,
1317                                              0, 0, !sta->sta.tdls_initiator,
1318                                              extra_ies, extra_ies_len,
1319                                              oper_class, chandef);
1320        if (!skb)
1321                return NULL;
1322
1323        skb = ieee80211_build_data_template(sdata, skb, 0);
1324        if (IS_ERR(skb)) {
1325                tdls_dbg(sdata, "Failed building TDLS channel switch frame\n");
1326                return NULL;
1327        }
1328
1329        if (ch_sw_tm_ie_offset) {
1330                const u8 *tm_ie = ieee80211_tdls_find_sw_timing_ie(skb);
1331
1332                if (!tm_ie) {
1333                        tdls_dbg(sdata, "No switch timing IE in TDLS switch\n");
1334                        dev_kfree_skb_any(skb);
1335                        return NULL;
1336                }
1337
1338                *ch_sw_tm_ie_offset = tm_ie - skb->data;
1339        }
1340
1341        tdls_dbg(sdata,
1342                 "TDLS channel switch request template for %pM ch %d width %d\n",
1343                 sta->sta.addr, chandef->chan->center_freq, chandef->width);
1344        return skb;
1345}
1346
1347int
1348ieee80211_tdls_channel_switch(struct wiphy *wiphy, struct net_device *dev,
1349                              const u8 *addr, u8 oper_class,
1350                              struct cfg80211_chan_def *chandef)
1351{
1352        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1353        struct ieee80211_local *local = sdata->local;
1354        struct sta_info *sta;
1355        struct sk_buff *skb = NULL;
1356        u32 ch_sw_tm_ie;
1357        int ret;
1358
1359        mutex_lock(&local->sta_mtx);
1360        sta = sta_info_get(sdata, addr);
1361        if (!sta) {
1362                tdls_dbg(sdata,
1363                         "Invalid TDLS peer %pM for channel switch request\n",
1364                         addr);
1365                ret = -ENOENT;
1366                goto out;
1367        }
1368
1369        if (!test_sta_flag(sta, WLAN_STA_TDLS_CHAN_SWITCH)) {
1370                tdls_dbg(sdata, "TDLS channel switch unsupported by %pM\n",
1371                         addr);
1372                ret = -ENOTSUPP;
1373                goto out;
1374        }
1375
1376        skb = ieee80211_tdls_ch_sw_tmpl_get(sta, oper_class, chandef,
1377                                            &ch_sw_tm_ie);
1378        if (!skb) {
1379                ret = -ENOENT;
1380                goto out;
1381        }
1382
1383        ret = drv_tdls_channel_switch(local, sdata, &sta->sta, oper_class,
1384                                      chandef, skb, ch_sw_tm_ie);
1385        if (!ret)
1386                set_sta_flag(sta, WLAN_STA_TDLS_OFF_CHANNEL);
1387
1388out:
1389        mutex_unlock(&local->sta_mtx);
1390        dev_kfree_skb_any(skb);
1391        return ret;
1392}
1393
1394void
1395ieee80211_tdls_cancel_channel_switch(struct wiphy *wiphy,
1396                                     struct net_device *dev,
1397                                     const u8 *addr)
1398{
1399        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1400        struct ieee80211_local *local = sdata->local;
1401        struct sta_info *sta;
1402
1403        mutex_lock(&local->sta_mtx);
1404        sta = sta_info_get(sdata, addr);
1405        if (!sta) {
1406                tdls_dbg(sdata,
1407                         "Invalid TDLS peer %pM for channel switch cancel\n",
1408                         addr);
1409                goto out;
1410        }
1411
1412        if (!test_sta_flag(sta, WLAN_STA_TDLS_OFF_CHANNEL)) {
1413                tdls_dbg(sdata, "TDLS channel switch not initiated by %pM\n",
1414                         addr);
1415                goto out;
1416        }
1417
1418        drv_tdls_cancel_channel_switch(local, sdata, &sta->sta);
1419        clear_sta_flag(sta, WLAN_STA_TDLS_OFF_CHANNEL);
1420
1421out:
1422        mutex_unlock(&local->sta_mtx);
1423}
1424
1425static struct sk_buff *
1426ieee80211_tdls_ch_sw_resp_tmpl_get(struct sta_info *sta,
1427                                   u32 *ch_sw_tm_ie_offset)
1428{
1429        struct ieee80211_sub_if_data *sdata = sta->sdata;
1430        struct sk_buff *skb;
1431        u8 extra_ies[2 + sizeof(struct ieee80211_ch_switch_timing)];
1432
1433        /* initial timing are always zero in the template */
1434        iee80211_tdls_add_ch_switch_timing(extra_ies, 0, 0);
1435
1436        skb = ieee80211_tdls_build_mgmt_packet_data(sdata, sta->sta.addr,
1437                                        WLAN_TDLS_CHANNEL_SWITCH_RESPONSE,
1438                                        0, 0, !sta->sta.tdls_initiator,
1439                                        extra_ies, sizeof(extra_ies), 0, NULL);
1440        if (!skb)
1441                return NULL;
1442
1443        skb = ieee80211_build_data_template(sdata, skb, 0);
1444        if (IS_ERR(skb)) {
1445                tdls_dbg(sdata,
1446                         "Failed building TDLS channel switch resp frame\n");
1447                return NULL;
1448        }
1449
1450        if (ch_sw_tm_ie_offset) {
1451                const u8 *tm_ie = ieee80211_tdls_find_sw_timing_ie(skb);
1452
1453                if (!tm_ie) {
1454                        tdls_dbg(sdata,
1455                                 "No switch timing IE in TDLS switch resp\n");
1456                        dev_kfree_skb_any(skb);
1457                        return NULL;
1458                }
1459
1460                *ch_sw_tm_ie_offset = tm_ie - skb->data;
1461        }
1462
1463        tdls_dbg(sdata, "TDLS get channel switch response template for %pM\n",
1464                 sta->sta.addr);
1465        return skb;
1466}
1467
1468static int
1469ieee80211_process_tdls_channel_switch_resp(struct ieee80211_sub_if_data *sdata,
1470                                           struct sk_buff *skb)
1471{
1472        struct ieee80211_local *local = sdata->local;
1473        struct ieee802_11_elems elems;
1474        struct sta_info *sta;
1475        struct ieee80211_tdls_data *tf = (void *)skb->data;
1476        bool local_initiator;
1477        struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
1478        int baselen = offsetof(typeof(*tf), u.chan_switch_resp.variable);
1479        struct ieee80211_tdls_ch_sw_params params = {};
1480        int ret;
1481
1482        params.action_code = WLAN_TDLS_CHANNEL_SWITCH_RESPONSE;
1483        params.timestamp = rx_status->device_timestamp;
1484
1485        if (skb->len < baselen) {
1486                tdls_dbg(sdata, "TDLS channel switch resp too short: %d\n",
1487                         skb->len);
1488                return -EINVAL;
1489        }
1490
1491        mutex_lock(&local->sta_mtx);
1492        sta = sta_info_get(sdata, tf->sa);
1493        if (!sta || !test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) {
1494                tdls_dbg(sdata, "TDLS chan switch from non-peer sta %pM\n",
1495                         tf->sa);
1496                ret = -EINVAL;
1497                goto out;
1498        }
1499
1500        params.sta = &sta->sta;
1501        params.status = le16_to_cpu(tf->u.chan_switch_resp.status_code);
1502        if (params.status != 0) {
1503                ret = 0;
1504                goto call_drv;
1505        }
1506
1507        ieee802_11_parse_elems(tf->u.chan_switch_resp.variable,
1508                               skb->len - baselen, false, &elems);
1509        if (elems.parse_error) {
1510                tdls_dbg(sdata, "Invalid IEs in TDLS channel switch resp\n");
1511                ret = -EINVAL;
1512                goto out;
1513        }
1514
1515        if (!elems.ch_sw_timing || !elems.lnk_id) {
1516                tdls_dbg(sdata, "TDLS channel switch resp - missing IEs\n");
1517                ret = -EINVAL;
1518                goto out;
1519        }
1520
1521        /* validate the initiator is set correctly */
1522        local_initiator =
1523                !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN);
1524        if (local_initiator == sta->sta.tdls_initiator) {
1525                tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n");
1526                ret = -EINVAL;
1527                goto out;
1528        }
1529
1530        params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time);
1531        params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout);
1532
1533        params.tmpl_skb =
1534                ieee80211_tdls_ch_sw_resp_tmpl_get(sta, &params.ch_sw_tm_ie);
1535        if (!params.tmpl_skb) {
1536                ret = -ENOENT;
1537                goto out;
1538        }
1539
1540call_drv:
1541        drv_tdls_recv_channel_switch(sdata->local, sdata, &params);
1542
1543        tdls_dbg(sdata,
1544                 "TDLS channel switch response received from %pM status %d\n",
1545                 tf->sa, params.status);
1546
1547out:
1548        mutex_unlock(&local->sta_mtx);
1549        dev_kfree_skb_any(params.tmpl_skb);
1550        return ret;
1551}
1552
1553static int
1554ieee80211_process_tdls_channel_switch_req(struct ieee80211_sub_if_data *sdata,
1555                                          struct sk_buff *skb)
1556{
1557        struct ieee80211_local *local = sdata->local;
1558        struct ieee802_11_elems elems;
1559        struct cfg80211_chan_def chandef;
1560        struct ieee80211_channel *chan;
1561        enum nl80211_channel_type chan_type;
1562        int freq;
1563        u8 target_channel, oper_class;
1564        bool local_initiator;
1565        struct sta_info *sta;
1566        enum ieee80211_band band;
1567        struct ieee80211_tdls_data *tf = (void *)skb->data;
1568        struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
1569        int baselen = offsetof(typeof(*tf), u.chan_switch_req.variable);
1570        struct ieee80211_tdls_ch_sw_params params = {};
1571        int ret = 0;
1572
1573        params.action_code = WLAN_TDLS_CHANNEL_SWITCH_REQUEST;
1574        params.timestamp = rx_status->device_timestamp;
1575
1576        if (skb->len < baselen) {
1577                tdls_dbg(sdata, "TDLS channel switch req too short: %d\n",
1578                         skb->len);
1579                return -EINVAL;
1580        }
1581
1582        target_channel = tf->u.chan_switch_req.target_channel;
1583        oper_class = tf->u.chan_switch_req.oper_class;
1584
1585        /*
1586         * We can't easily infer the channel band. The operating class is
1587         * ambiguous - there are multiple tables (US/Europe/JP/Global). The
1588         * solution here is to treat channels with number >14 as 5GHz ones,
1589         * and specifically check for the (oper_class, channel) combinations
1590         * where this doesn't hold. These are thankfully unique according to
1591         * IEEE802.11-2012.
1592         * We consider only the 2GHz and 5GHz bands and 20MHz+ channels as
1593         * valid here.
1594         */
1595        if ((oper_class == 112 || oper_class == 2 || oper_class == 3 ||
1596             oper_class == 4 || oper_class == 5 || oper_class == 6) &&
1597             target_channel < 14)
1598                band = IEEE80211_BAND_5GHZ;
1599        else
1600                band = target_channel < 14 ? IEEE80211_BAND_2GHZ :
1601                                             IEEE80211_BAND_5GHZ;
1602
1603        freq = ieee80211_channel_to_frequency(target_channel, band);
1604        if (freq == 0) {
1605                tdls_dbg(sdata, "Invalid channel in TDLS chan switch: %d\n",
1606                         target_channel);
1607                return -EINVAL;
1608        }
1609
1610        chan = ieee80211_get_channel(sdata->local->hw.wiphy, freq);
1611        if (!chan) {
1612                tdls_dbg(sdata,
1613                         "Unsupported channel for TDLS chan switch: %d\n",
1614                         target_channel);
1615                return -EINVAL;
1616        }
1617
1618        ieee802_11_parse_elems(tf->u.chan_switch_req.variable,
1619                               skb->len - baselen, false, &elems);
1620        if (elems.parse_error) {
1621                tdls_dbg(sdata, "Invalid IEs in TDLS channel switch req\n");
1622                return -EINVAL;
1623        }
1624
1625        if (!elems.ch_sw_timing || !elems.lnk_id) {
1626                tdls_dbg(sdata, "TDLS channel switch req - missing IEs\n");
1627                return -EINVAL;
1628        }
1629
1630        mutex_lock(&local->sta_mtx);
1631        sta = sta_info_get(sdata, tf->sa);
1632        if (!sta || !test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) {
1633                tdls_dbg(sdata, "TDLS chan switch from non-peer sta %pM\n",
1634                         tf->sa);
1635                ret = -EINVAL;
1636                goto out;
1637        }
1638
1639        params.sta = &sta->sta;
1640
1641        /* validate the initiator is set correctly */
1642        local_initiator =
1643                !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN);
1644        if (local_initiator == sta->sta.tdls_initiator) {
1645                tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n");
1646                ret = -EINVAL;
1647                goto out;
1648        }
1649
1650        if (!sta->sta.ht_cap.ht_supported) {
1651                chan_type = NL80211_CHAN_NO_HT;
1652        } else if (!elems.sec_chan_offs) {
1653                chan_type = NL80211_CHAN_HT20;
1654        } else {
1655                switch (elems.sec_chan_offs->sec_chan_offs) {
1656                case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
1657                        chan_type = NL80211_CHAN_HT40PLUS;
1658                        break;
1659                case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
1660                        chan_type = NL80211_CHAN_HT40MINUS;
1661                        break;
1662                default:
1663                        chan_type = NL80211_CHAN_HT20;
1664                        break;
1665                }
1666        }
1667
1668        cfg80211_chandef_create(&chandef, chan, chan_type);
1669        params.chandef = &chandef;
1670
1671        params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time);
1672        params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout);
1673
1674        params.tmpl_skb =
1675                ieee80211_tdls_ch_sw_resp_tmpl_get(sta,
1676                                                   &params.ch_sw_tm_ie);
1677        if (!params.tmpl_skb) {
1678                ret = -ENOENT;
1679                goto out;
1680        }
1681
1682        drv_tdls_recv_channel_switch(sdata->local, sdata, &params);
1683
1684        tdls_dbg(sdata,
1685                 "TDLS ch switch request received from %pM ch %d width %d\n",
1686                 tf->sa, params.chandef->chan->center_freq,
1687                 params.chandef->width);
1688out:
1689        mutex_unlock(&local->sta_mtx);
1690        dev_kfree_skb_any(params.tmpl_skb);
1691        return ret;
1692}
1693
1694void ieee80211_process_tdls_channel_switch(struct ieee80211_sub_if_data *sdata,
1695                                           struct sk_buff *skb)
1696{
1697        struct ieee80211_tdls_data *tf = (void *)skb->data;
1698        struct wiphy *wiphy = sdata->local->hw.wiphy;
1699
1700        /* make sure the driver supports it */
1701        if (!(wiphy->features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
1702                return;
1703
1704        /* we want to access the entire packet */
1705        if (skb_linearize(skb))
1706                return;
1707        /*
1708         * The packet/size was already validated by mac80211 Rx path, only look
1709         * at the action type.
1710         */
1711        switch (tf->action_code) {
1712        case WLAN_TDLS_CHANNEL_SWITCH_REQUEST:
1713                ieee80211_process_tdls_channel_switch_req(sdata, skb);
1714                break;
1715        case WLAN_TDLS_CHANNEL_SWITCH_RESPONSE:
1716                ieee80211_process_tdls_channel_switch_resp(sdata, skb);
1717                break;
1718        default:
1719                WARN_ON_ONCE(1);
1720                return;
1721        }
1722}
1723