linux/net/mac80211/chan.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * mac80211 - channel management
   4 * Copyright 2020 - 2021 Intel Corporation
   5 */
   6
   7#include <linux/nl80211.h>
   8#include <linux/export.h>
   9#include <linux/rtnetlink.h>
  10#include <net/cfg80211.h>
  11#include "ieee80211_i.h"
  12#include "driver-ops.h"
  13#include "rate.h"
  14
  15static int ieee80211_chanctx_num_assigned(struct ieee80211_local *local,
  16                                          struct ieee80211_chanctx *ctx)
  17{
  18        struct ieee80211_sub_if_data *sdata;
  19        int num = 0;
  20
  21        lockdep_assert_held(&local->chanctx_mtx);
  22
  23        list_for_each_entry(sdata, &ctx->assigned_vifs, assigned_chanctx_list)
  24                num++;
  25
  26        return num;
  27}
  28
  29static int ieee80211_chanctx_num_reserved(struct ieee80211_local *local,
  30                                          struct ieee80211_chanctx *ctx)
  31{
  32        struct ieee80211_sub_if_data *sdata;
  33        int num = 0;
  34
  35        lockdep_assert_held(&local->chanctx_mtx);
  36
  37        list_for_each_entry(sdata, &ctx->reserved_vifs, reserved_chanctx_list)
  38                num++;
  39
  40        return num;
  41}
  42
  43int ieee80211_chanctx_refcount(struct ieee80211_local *local,
  44                               struct ieee80211_chanctx *ctx)
  45{
  46        return ieee80211_chanctx_num_assigned(local, ctx) +
  47               ieee80211_chanctx_num_reserved(local, ctx);
  48}
  49
  50static int ieee80211_num_chanctx(struct ieee80211_local *local)
  51{
  52        struct ieee80211_chanctx *ctx;
  53        int num = 0;
  54
  55        lockdep_assert_held(&local->chanctx_mtx);
  56
  57        list_for_each_entry(ctx, &local->chanctx_list, list)
  58                num++;
  59
  60        return num;
  61}
  62
  63static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local)
  64{
  65        lockdep_assert_held(&local->chanctx_mtx);
  66        return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local);
  67}
  68
  69static struct ieee80211_chanctx *
  70ieee80211_vif_get_chanctx(struct ieee80211_sub_if_data *sdata)
  71{
  72        struct ieee80211_local *local __maybe_unused = sdata->local;
  73        struct ieee80211_chanctx_conf *conf;
  74
  75        conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
  76                                         lockdep_is_held(&local->chanctx_mtx));
  77        if (!conf)
  78                return NULL;
  79
  80        return container_of(conf, struct ieee80211_chanctx, conf);
  81}
  82
  83static const struct cfg80211_chan_def *
  84ieee80211_chanctx_reserved_chandef(struct ieee80211_local *local,
  85                                   struct ieee80211_chanctx *ctx,
  86                                   const struct cfg80211_chan_def *compat)
  87{
  88        struct ieee80211_sub_if_data *sdata;
  89
  90        lockdep_assert_held(&local->chanctx_mtx);
  91
  92        list_for_each_entry(sdata, &ctx->reserved_vifs,
  93                            reserved_chanctx_list) {
  94                if (!compat)
  95                        compat = &sdata->reserved_chandef;
  96
  97                compat = cfg80211_chandef_compatible(&sdata->reserved_chandef,
  98                                                     compat);
  99                if (!compat)
 100                        break;
 101        }
 102
 103        return compat;
 104}
 105
 106static const struct cfg80211_chan_def *
 107ieee80211_chanctx_non_reserved_chandef(struct ieee80211_local *local,
 108                                       struct ieee80211_chanctx *ctx,
 109                                       const struct cfg80211_chan_def *compat)
 110{
 111        struct ieee80211_sub_if_data *sdata;
 112
 113        lockdep_assert_held(&local->chanctx_mtx);
 114
 115        list_for_each_entry(sdata, &ctx->assigned_vifs,
 116                            assigned_chanctx_list) {
 117                if (sdata->reserved_chanctx != NULL)
 118                        continue;
 119
 120                if (!compat)
 121                        compat = &sdata->vif.bss_conf.chandef;
 122
 123                compat = cfg80211_chandef_compatible(
 124                                &sdata->vif.bss_conf.chandef, compat);
 125                if (!compat)
 126                        break;
 127        }
 128
 129        return compat;
 130}
 131
 132static const struct cfg80211_chan_def *
 133ieee80211_chanctx_combined_chandef(struct ieee80211_local *local,
 134                                   struct ieee80211_chanctx *ctx,
 135                                   const struct cfg80211_chan_def *compat)
 136{
 137        lockdep_assert_held(&local->chanctx_mtx);
 138
 139        compat = ieee80211_chanctx_reserved_chandef(local, ctx, compat);
 140        if (!compat)
 141                return NULL;
 142
 143        compat = ieee80211_chanctx_non_reserved_chandef(local, ctx, compat);
 144        if (!compat)
 145                return NULL;
 146
 147        return compat;
 148}
 149
 150static bool
 151ieee80211_chanctx_can_reserve_chandef(struct ieee80211_local *local,
 152                                      struct ieee80211_chanctx *ctx,
 153                                      const struct cfg80211_chan_def *def)
 154{
 155        lockdep_assert_held(&local->chanctx_mtx);
 156
 157        if (ieee80211_chanctx_combined_chandef(local, ctx, def))
 158                return true;
 159
 160        if (!list_empty(&ctx->reserved_vifs) &&
 161            ieee80211_chanctx_reserved_chandef(local, ctx, def))
 162                return true;
 163
 164        return false;
 165}
 166
 167static struct ieee80211_chanctx *
 168ieee80211_find_reservation_chanctx(struct ieee80211_local *local,
 169                                   const struct cfg80211_chan_def *chandef,
 170                                   enum ieee80211_chanctx_mode mode)
 171{
 172        struct ieee80211_chanctx *ctx;
 173
 174        lockdep_assert_held(&local->chanctx_mtx);
 175
 176        if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
 177                return NULL;
 178
 179        list_for_each_entry(ctx, &local->chanctx_list, list) {
 180                if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
 181                        continue;
 182
 183                if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
 184                        continue;
 185
 186                if (!ieee80211_chanctx_can_reserve_chandef(local, ctx,
 187                                                           chandef))
 188                        continue;
 189
 190                return ctx;
 191        }
 192
 193        return NULL;
 194}
 195
 196static enum nl80211_chan_width ieee80211_get_sta_bw(struct sta_info *sta)
 197{
 198        enum ieee80211_sta_rx_bandwidth width = ieee80211_sta_cap_rx_bw(sta);
 199
 200        switch (width) {
 201        case IEEE80211_STA_RX_BW_20:
 202                if (sta->sta.ht_cap.ht_supported)
 203                        return NL80211_CHAN_WIDTH_20;
 204                else
 205                        return NL80211_CHAN_WIDTH_20_NOHT;
 206        case IEEE80211_STA_RX_BW_40:
 207                return NL80211_CHAN_WIDTH_40;
 208        case IEEE80211_STA_RX_BW_80:
 209                return NL80211_CHAN_WIDTH_80;
 210        case IEEE80211_STA_RX_BW_160:
 211                /*
 212                 * This applied for both 160 and 80+80. since we use
 213                 * the returned value to consider degradation of
 214                 * ctx->conf.min_def, we have to make sure to take
 215                 * the bigger one (NL80211_CHAN_WIDTH_160).
 216                 * Otherwise we might try degrading even when not
 217                 * needed, as the max required sta_bw returned (80+80)
 218                 * might be smaller than the configured bw (160).
 219                 */
 220                return NL80211_CHAN_WIDTH_160;
 221        default:
 222                WARN_ON(1);
 223                return NL80211_CHAN_WIDTH_20;
 224        }
 225}
 226
 227static enum nl80211_chan_width
 228ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata)
 229{
 230        enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
 231        struct sta_info *sta;
 232
 233        rcu_read_lock();
 234        list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
 235                if (sdata != sta->sdata &&
 236                    !(sta->sdata->bss && sta->sdata->bss == sdata->bss))
 237                        continue;
 238
 239                max_bw = max(max_bw, ieee80211_get_sta_bw(sta));
 240        }
 241        rcu_read_unlock();
 242
 243        return max_bw;
 244}
 245
 246static enum nl80211_chan_width
 247ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
 248                                      struct ieee80211_chanctx_conf *conf)
 249{
 250        struct ieee80211_sub_if_data *sdata;
 251        enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
 252
 253        rcu_read_lock();
 254        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 255                struct ieee80211_vif *vif = &sdata->vif;
 256                enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT;
 257
 258                if (!ieee80211_sdata_running(sdata))
 259                        continue;
 260
 261                if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
 262                        continue;
 263
 264                switch (vif->type) {
 265                case NL80211_IFTYPE_AP:
 266                case NL80211_IFTYPE_AP_VLAN:
 267                        width = ieee80211_get_max_required_bw(sdata);
 268                        break;
 269                case NL80211_IFTYPE_STATION:
 270                        /*
 271                         * The ap's sta->bandwidth is not set yet at this
 272                         * point, so take the width from the chandef, but
 273                         * account also for TDLS peers
 274                         */
 275                        width = max(vif->bss_conf.chandef.width,
 276                                    ieee80211_get_max_required_bw(sdata));
 277                        break;
 278                case NL80211_IFTYPE_P2P_DEVICE:
 279                case NL80211_IFTYPE_NAN:
 280                        continue;
 281                case NL80211_IFTYPE_ADHOC:
 282                case NL80211_IFTYPE_MESH_POINT:
 283                case NL80211_IFTYPE_OCB:
 284                        width = vif->bss_conf.chandef.width;
 285                        break;
 286                case NL80211_IFTYPE_WDS:
 287                case NL80211_IFTYPE_UNSPECIFIED:
 288                case NUM_NL80211_IFTYPES:
 289                case NL80211_IFTYPE_MONITOR:
 290                case NL80211_IFTYPE_P2P_CLIENT:
 291                case NL80211_IFTYPE_P2P_GO:
 292                        WARN_ON_ONCE(1);
 293                }
 294                max_bw = max(max_bw, width);
 295        }
 296
 297        /* use the configured bandwidth in case of monitor interface */
 298        sdata = rcu_dereference(local->monitor_sdata);
 299        if (sdata && rcu_access_pointer(sdata->vif.chanctx_conf) == conf)
 300                max_bw = max(max_bw, conf->def.width);
 301
 302        rcu_read_unlock();
 303
 304        return max_bw;
 305}
 306
 307/*
 308 * recalc the min required chan width of the channel context, which is
 309 * the max of min required widths of all the interfaces bound to this
 310 * channel context.
 311 */
 312static u32 _ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
 313                                             struct ieee80211_chanctx *ctx)
 314{
 315        enum nl80211_chan_width max_bw;
 316        struct cfg80211_chan_def min_def;
 317
 318        lockdep_assert_held(&local->chanctx_mtx);
 319
 320        /* don't optimize non-20MHz based and radar_enabled confs */
 321        if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
 322            ctx->conf.def.width == NL80211_CHAN_WIDTH_10 ||
 323            ctx->conf.def.width == NL80211_CHAN_WIDTH_1 ||
 324            ctx->conf.def.width == NL80211_CHAN_WIDTH_2 ||
 325            ctx->conf.def.width == NL80211_CHAN_WIDTH_4 ||
 326            ctx->conf.def.width == NL80211_CHAN_WIDTH_8 ||
 327            ctx->conf.def.width == NL80211_CHAN_WIDTH_16 ||
 328            ctx->conf.radar_enabled) {
 329                ctx->conf.min_def = ctx->conf.def;
 330                return 0;
 331        }
 332
 333        max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf);
 334
 335        /* downgrade chandef up to max_bw */
 336        min_def = ctx->conf.def;
 337        while (min_def.width > max_bw)
 338                ieee80211_chandef_downgrade(&min_def);
 339
 340        if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def))
 341                return 0;
 342
 343        ctx->conf.min_def = min_def;
 344        if (!ctx->driver_present)
 345                return 0;
 346
 347        return IEEE80211_CHANCTX_CHANGE_MIN_WIDTH;
 348}
 349
 350/* calling this function is assuming that station vif is updated to
 351 * lates changes by calling ieee80211_vif_update_chandef
 352 */
 353static void ieee80211_chan_bw_change(struct ieee80211_local *local,
 354                                     struct ieee80211_chanctx *ctx,
 355                                     bool narrowed)
 356{
 357        struct sta_info *sta;
 358        struct ieee80211_supported_band *sband =
 359                local->hw.wiphy->bands[ctx->conf.def.chan->band];
 360
 361        rcu_read_lock();
 362        list_for_each_entry_rcu(sta, &local->sta_list,
 363                                list) {
 364                enum ieee80211_sta_rx_bandwidth new_sta_bw;
 365
 366                if (!ieee80211_sdata_running(sta->sdata))
 367                        continue;
 368
 369                if (rcu_access_pointer(sta->sdata->vif.chanctx_conf) !=
 370                    &ctx->conf)
 371                        continue;
 372
 373                new_sta_bw = ieee80211_sta_cur_vht_bw(sta);
 374
 375                /* nothing change */
 376                if (new_sta_bw == sta->sta.bandwidth)
 377                        continue;
 378
 379                /* vif changed to narrow BW and narrow BW for station wasn't
 380                 * requested or vise versa */
 381                if ((new_sta_bw < sta->sta.bandwidth) == !narrowed)
 382                        continue;
 383
 384                sta->sta.bandwidth = new_sta_bw;
 385                rate_control_rate_update(local, sband, sta,
 386                                         IEEE80211_RC_BW_CHANGED);
 387        }
 388        rcu_read_unlock();
 389}
 390
 391/*
 392 * recalc the min required chan width of the channel context, which is
 393 * the max of min required widths of all the interfaces bound to this
 394 * channel context.
 395 */
 396void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
 397                                      struct ieee80211_chanctx *ctx)
 398{
 399        u32 changed = _ieee80211_recalc_chanctx_min_def(local, ctx);
 400
 401        if (!changed)
 402                return;
 403
 404        /* check is BW narrowed */
 405        ieee80211_chan_bw_change(local, ctx, true);
 406
 407        drv_change_chanctx(local, ctx, changed);
 408
 409        /* check is BW wider */
 410        ieee80211_chan_bw_change(local, ctx, false);
 411}
 412
 413static void ieee80211_change_chanctx(struct ieee80211_local *local,
 414                                     struct ieee80211_chanctx *ctx,
 415                                     struct ieee80211_chanctx *old_ctx,
 416                                     const struct cfg80211_chan_def *chandef)
 417{
 418        u32 changed;
 419
 420        /* expected to handle only 20/40/80/160 channel widths */
 421        switch (chandef->width) {
 422        case NL80211_CHAN_WIDTH_20_NOHT:
 423        case NL80211_CHAN_WIDTH_20:
 424        case NL80211_CHAN_WIDTH_40:
 425        case NL80211_CHAN_WIDTH_80:
 426        case NL80211_CHAN_WIDTH_80P80:
 427        case NL80211_CHAN_WIDTH_160:
 428                break;
 429        default:
 430                WARN_ON(1);
 431        }
 432
 433        /* Check maybe BW narrowed - we do this _before_ calling recalc_chanctx_min_def
 434         * due to maybe not returning from it, e.g in case new context was added
 435         * first time with all parameters up to date.
 436         */
 437        ieee80211_chan_bw_change(local, old_ctx, true);
 438
 439        if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) {
 440                ieee80211_recalc_chanctx_min_def(local, ctx);
 441                return;
 442        }
 443
 444        WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
 445
 446        ctx->conf.def = *chandef;
 447
 448        /* check if min chanctx also changed */
 449        changed = IEEE80211_CHANCTX_CHANGE_WIDTH |
 450                  _ieee80211_recalc_chanctx_min_def(local, ctx);
 451        drv_change_chanctx(local, ctx, changed);
 452
 453        if (!local->use_chanctx) {
 454                local->_oper_chandef = *chandef;
 455                ieee80211_hw_config(local, 0);
 456        }
 457
 458        /* check is BW wider */
 459        ieee80211_chan_bw_change(local, old_ctx, false);
 460}
 461
 462static struct ieee80211_chanctx *
 463ieee80211_find_chanctx(struct ieee80211_local *local,
 464                       const struct cfg80211_chan_def *chandef,
 465                       enum ieee80211_chanctx_mode mode)
 466{
 467        struct ieee80211_chanctx *ctx;
 468
 469        lockdep_assert_held(&local->chanctx_mtx);
 470
 471        if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
 472                return NULL;
 473
 474        list_for_each_entry(ctx, &local->chanctx_list, list) {
 475                const struct cfg80211_chan_def *compat;
 476
 477                if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE)
 478                        continue;
 479
 480                if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
 481                        continue;
 482
 483                compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef);
 484                if (!compat)
 485                        continue;
 486
 487                compat = ieee80211_chanctx_reserved_chandef(local, ctx,
 488                                                            compat);
 489                if (!compat)
 490                        continue;
 491
 492                ieee80211_change_chanctx(local, ctx, ctx, compat);
 493
 494                return ctx;
 495        }
 496
 497        return NULL;
 498}
 499
 500bool ieee80211_is_radar_required(struct ieee80211_local *local)
 501{
 502        struct ieee80211_sub_if_data *sdata;
 503
 504        lockdep_assert_held(&local->mtx);
 505
 506        rcu_read_lock();
 507        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 508                if (sdata->radar_required) {
 509                        rcu_read_unlock();
 510                        return true;
 511                }
 512        }
 513        rcu_read_unlock();
 514
 515        return false;
 516}
 517
 518static bool
 519ieee80211_chanctx_radar_required(struct ieee80211_local *local,
 520                                 struct ieee80211_chanctx *ctx)
 521{
 522        struct ieee80211_chanctx_conf *conf = &ctx->conf;
 523        struct ieee80211_sub_if_data *sdata;
 524        bool required = false;
 525
 526        lockdep_assert_held(&local->chanctx_mtx);
 527        lockdep_assert_held(&local->mtx);
 528
 529        rcu_read_lock();
 530        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 531                if (!ieee80211_sdata_running(sdata))
 532                        continue;
 533                if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
 534                        continue;
 535                if (!sdata->radar_required)
 536                        continue;
 537
 538                required = true;
 539                break;
 540        }
 541        rcu_read_unlock();
 542
 543        return required;
 544}
 545
 546static struct ieee80211_chanctx *
 547ieee80211_alloc_chanctx(struct ieee80211_local *local,
 548                        const struct cfg80211_chan_def *chandef,
 549                        enum ieee80211_chanctx_mode mode)
 550{
 551        struct ieee80211_chanctx *ctx;
 552
 553        lockdep_assert_held(&local->chanctx_mtx);
 554
 555        ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL);
 556        if (!ctx)
 557                return NULL;
 558
 559        INIT_LIST_HEAD(&ctx->assigned_vifs);
 560        INIT_LIST_HEAD(&ctx->reserved_vifs);
 561        ctx->conf.def = *chandef;
 562        ctx->conf.rx_chains_static = 1;
 563        ctx->conf.rx_chains_dynamic = 1;
 564        ctx->mode = mode;
 565        ctx->conf.radar_enabled = false;
 566        ieee80211_recalc_chanctx_min_def(local, ctx);
 567
 568        return ctx;
 569}
 570
 571static int ieee80211_add_chanctx(struct ieee80211_local *local,
 572                                 struct ieee80211_chanctx *ctx)
 573{
 574        u32 changed;
 575        int err;
 576
 577        lockdep_assert_held(&local->mtx);
 578        lockdep_assert_held(&local->chanctx_mtx);
 579
 580        if (!local->use_chanctx)
 581                local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
 582
 583        /* turn idle off *before* setting channel -- some drivers need that */
 584        changed = ieee80211_idle_off(local);
 585        if (changed)
 586                ieee80211_hw_config(local, changed);
 587
 588        if (!local->use_chanctx) {
 589                local->_oper_chandef = ctx->conf.def;
 590                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 591        } else {
 592                err = drv_add_chanctx(local, ctx);
 593                if (err) {
 594                        ieee80211_recalc_idle(local);
 595                        return err;
 596                }
 597        }
 598
 599        return 0;
 600}
 601
 602static struct ieee80211_chanctx *
 603ieee80211_new_chanctx(struct ieee80211_local *local,
 604                      const struct cfg80211_chan_def *chandef,
 605                      enum ieee80211_chanctx_mode mode)
 606{
 607        struct ieee80211_chanctx *ctx;
 608        int err;
 609
 610        lockdep_assert_held(&local->mtx);
 611        lockdep_assert_held(&local->chanctx_mtx);
 612
 613        ctx = ieee80211_alloc_chanctx(local, chandef, mode);
 614        if (!ctx)
 615                return ERR_PTR(-ENOMEM);
 616
 617        err = ieee80211_add_chanctx(local, ctx);
 618        if (err) {
 619                kfree(ctx);
 620                return ERR_PTR(err);
 621        }
 622
 623        list_add_rcu(&ctx->list, &local->chanctx_list);
 624        return ctx;
 625}
 626
 627static void ieee80211_del_chanctx(struct ieee80211_local *local,
 628                                  struct ieee80211_chanctx *ctx)
 629{
 630        lockdep_assert_held(&local->chanctx_mtx);
 631
 632        if (!local->use_chanctx) {
 633                struct cfg80211_chan_def *chandef = &local->_oper_chandef;
 634                /* S1G doesn't have 20MHz, so get the correct width for the
 635                 * current channel.
 636                 */
 637                if (chandef->chan->band == NL80211_BAND_S1GHZ)
 638                        chandef->width =
 639                                ieee80211_s1g_channel_width(chandef->chan);
 640                else
 641                        chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
 642                chandef->center_freq1 = chandef->chan->center_freq;
 643                chandef->freq1_offset = chandef->chan->freq_offset;
 644                chandef->center_freq2 = 0;
 645
 646                /* NOTE: Disabling radar is only valid here for
 647                 * single channel context. To be sure, check it ...
 648                 */
 649                WARN_ON(local->hw.conf.radar_enabled &&
 650                        !list_empty(&local->chanctx_list));
 651
 652                local->hw.conf.radar_enabled = false;
 653
 654                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 655        } else {
 656                drv_remove_chanctx(local, ctx);
 657        }
 658
 659        ieee80211_recalc_idle(local);
 660}
 661
 662static void ieee80211_free_chanctx(struct ieee80211_local *local,
 663                                   struct ieee80211_chanctx *ctx)
 664{
 665        lockdep_assert_held(&local->chanctx_mtx);
 666
 667        WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0);
 668
 669        list_del_rcu(&ctx->list);
 670        ieee80211_del_chanctx(local, ctx);
 671        kfree_rcu(ctx, rcu_head);
 672}
 673
 674void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
 675                                       struct ieee80211_chanctx *ctx)
 676{
 677        struct ieee80211_chanctx_conf *conf = &ctx->conf;
 678        struct ieee80211_sub_if_data *sdata;
 679        const struct cfg80211_chan_def *compat = NULL;
 680        struct sta_info *sta;
 681
 682        lockdep_assert_held(&local->chanctx_mtx);
 683
 684        rcu_read_lock();
 685        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 686
 687                if (!ieee80211_sdata_running(sdata))
 688                        continue;
 689                if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
 690                        continue;
 691                if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
 692                        continue;
 693
 694                if (!compat)
 695                        compat = &sdata->vif.bss_conf.chandef;
 696
 697                compat = cfg80211_chandef_compatible(
 698                                &sdata->vif.bss_conf.chandef, compat);
 699                if (WARN_ON_ONCE(!compat))
 700                        break;
 701        }
 702
 703        /* TDLS peers can sometimes affect the chandef width */
 704        list_for_each_entry_rcu(sta, &local->sta_list, list) {
 705                if (!sta->uploaded ||
 706                    !test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW) ||
 707                    !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
 708                    !sta->tdls_chandef.chan)
 709                        continue;
 710
 711                compat = cfg80211_chandef_compatible(&sta->tdls_chandef,
 712                                                     compat);
 713                if (WARN_ON_ONCE(!compat))
 714                        break;
 715        }
 716        rcu_read_unlock();
 717
 718        if (!compat)
 719                return;
 720
 721        ieee80211_change_chanctx(local, ctx, ctx, compat);
 722}
 723
 724static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
 725                                           struct ieee80211_chanctx *chanctx)
 726{
 727        bool radar_enabled;
 728
 729        lockdep_assert_held(&local->chanctx_mtx);
 730        /* for ieee80211_is_radar_required */
 731        lockdep_assert_held(&local->mtx);
 732
 733        radar_enabled = ieee80211_chanctx_radar_required(local, chanctx);
 734
 735        if (radar_enabled == chanctx->conf.radar_enabled)
 736                return;
 737
 738        chanctx->conf.radar_enabled = radar_enabled;
 739
 740        if (!local->use_chanctx) {
 741                local->hw.conf.radar_enabled = chanctx->conf.radar_enabled;
 742                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 743        }
 744
 745        drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR);
 746}
 747
 748static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
 749                                        struct ieee80211_chanctx *new_ctx)
 750{
 751        struct ieee80211_local *local = sdata->local;
 752        struct ieee80211_chanctx_conf *conf;
 753        struct ieee80211_chanctx *curr_ctx = NULL;
 754        int ret = 0;
 755
 756        if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_NAN))
 757                return -ENOTSUPP;
 758
 759        conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
 760                                         lockdep_is_held(&local->chanctx_mtx));
 761
 762        if (conf) {
 763                curr_ctx = container_of(conf, struct ieee80211_chanctx, conf);
 764
 765                drv_unassign_vif_chanctx(local, sdata, curr_ctx);
 766                conf = NULL;
 767                list_del(&sdata->assigned_chanctx_list);
 768        }
 769
 770        if (new_ctx) {
 771                ret = drv_assign_vif_chanctx(local, sdata, new_ctx);
 772                if (ret)
 773                        goto out;
 774
 775                conf = &new_ctx->conf;
 776                list_add(&sdata->assigned_chanctx_list,
 777                         &new_ctx->assigned_vifs);
 778        }
 779
 780out:
 781        rcu_assign_pointer(sdata->vif.chanctx_conf, conf);
 782
 783        sdata->vif.bss_conf.idle = !conf;
 784
 785        if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) {
 786                ieee80211_recalc_chanctx_chantype(local, curr_ctx);
 787                ieee80211_recalc_smps_chanctx(local, curr_ctx);
 788                ieee80211_recalc_radar_chanctx(local, curr_ctx);
 789                ieee80211_recalc_chanctx_min_def(local, curr_ctx);
 790        }
 791
 792        if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
 793                ieee80211_recalc_txpower(sdata, false);
 794                ieee80211_recalc_chanctx_min_def(local, new_ctx);
 795        }
 796
 797        if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
 798            sdata->vif.type != NL80211_IFTYPE_MONITOR)
 799                ieee80211_bss_info_change_notify(sdata,
 800                                                 BSS_CHANGED_IDLE);
 801
 802        ieee80211_check_fast_xmit_iface(sdata);
 803
 804        return ret;
 805}
 806
 807void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
 808                                   struct ieee80211_chanctx *chanctx)
 809{
 810        struct ieee80211_sub_if_data *sdata;
 811        u8 rx_chains_static, rx_chains_dynamic;
 812
 813        lockdep_assert_held(&local->chanctx_mtx);
 814
 815        rx_chains_static = 1;
 816        rx_chains_dynamic = 1;
 817
 818        rcu_read_lock();
 819        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 820                u8 needed_static, needed_dynamic;
 821
 822                if (!ieee80211_sdata_running(sdata))
 823                        continue;
 824
 825                if (rcu_access_pointer(sdata->vif.chanctx_conf) !=
 826                                                &chanctx->conf)
 827                        continue;
 828
 829                switch (sdata->vif.type) {
 830                case NL80211_IFTYPE_P2P_DEVICE:
 831                case NL80211_IFTYPE_NAN:
 832                        continue;
 833                case NL80211_IFTYPE_STATION:
 834                        if (!sdata->u.mgd.associated)
 835                                continue;
 836                        break;
 837                case NL80211_IFTYPE_AP_VLAN:
 838                        continue;
 839                case NL80211_IFTYPE_AP:
 840                case NL80211_IFTYPE_ADHOC:
 841                case NL80211_IFTYPE_MESH_POINT:
 842                case NL80211_IFTYPE_OCB:
 843                        break;
 844                default:
 845                        WARN_ON_ONCE(1);
 846                }
 847
 848                switch (sdata->smps_mode) {
 849                default:
 850                        WARN_ONCE(1, "Invalid SMPS mode %d\n",
 851                                  sdata->smps_mode);
 852                        fallthrough;
 853                case IEEE80211_SMPS_OFF:
 854                        needed_static = sdata->needed_rx_chains;
 855                        needed_dynamic = sdata->needed_rx_chains;
 856                        break;
 857                case IEEE80211_SMPS_DYNAMIC:
 858                        needed_static = 1;
 859                        needed_dynamic = sdata->needed_rx_chains;
 860                        break;
 861                case IEEE80211_SMPS_STATIC:
 862                        needed_static = 1;
 863                        needed_dynamic = 1;
 864                        break;
 865                }
 866
 867                rx_chains_static = max(rx_chains_static, needed_static);
 868                rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic);
 869        }
 870
 871        /* Disable SMPS for the monitor interface */
 872        sdata = rcu_dereference(local->monitor_sdata);
 873        if (sdata &&
 874            rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf)
 875                rx_chains_dynamic = rx_chains_static = local->rx_chains;
 876
 877        rcu_read_unlock();
 878
 879        if (!local->use_chanctx) {
 880                if (rx_chains_static > 1)
 881                        local->smps_mode = IEEE80211_SMPS_OFF;
 882                else if (rx_chains_dynamic > 1)
 883                        local->smps_mode = IEEE80211_SMPS_DYNAMIC;
 884                else
 885                        local->smps_mode = IEEE80211_SMPS_STATIC;
 886                ieee80211_hw_config(local, 0);
 887        }
 888
 889        if (rx_chains_static == chanctx->conf.rx_chains_static &&
 890            rx_chains_dynamic == chanctx->conf.rx_chains_dynamic)
 891                return;
 892
 893        chanctx->conf.rx_chains_static = rx_chains_static;
 894        chanctx->conf.rx_chains_dynamic = rx_chains_dynamic;
 895        drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS);
 896}
 897
 898static void
 899__ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
 900                                      bool clear)
 901{
 902        struct ieee80211_local *local __maybe_unused = sdata->local;
 903        struct ieee80211_sub_if_data *vlan;
 904        struct ieee80211_chanctx_conf *conf;
 905
 906        if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
 907                return;
 908
 909        lockdep_assert_held(&local->mtx);
 910
 911        /* Check that conf exists, even when clearing this function
 912         * must be called with the AP's channel context still there
 913         * as it would otherwise cause VLANs to have an invalid
 914         * channel context pointer for a while, possibly pointing
 915         * to a channel context that has already been freed.
 916         */
 917        conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
 918                                         lockdep_is_held(&local->chanctx_mtx));
 919        WARN_ON(!conf);
 920
 921        if (clear)
 922                conf = NULL;
 923
 924        list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
 925                rcu_assign_pointer(vlan->vif.chanctx_conf, conf);
 926}
 927
 928void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
 929                                         bool clear)
 930{
 931        struct ieee80211_local *local = sdata->local;
 932
 933        mutex_lock(&local->chanctx_mtx);
 934
 935        __ieee80211_vif_copy_chanctx_to_vlans(sdata, clear);
 936
 937        mutex_unlock(&local->chanctx_mtx);
 938}
 939
 940int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata)
 941{
 942        struct ieee80211_chanctx *ctx = sdata->reserved_chanctx;
 943
 944        lockdep_assert_held(&sdata->local->chanctx_mtx);
 945
 946        if (WARN_ON(!ctx))
 947                return -EINVAL;
 948
 949        list_del(&sdata->reserved_chanctx_list);
 950        sdata->reserved_chanctx = NULL;
 951
 952        if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) {
 953                if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
 954                        if (WARN_ON(!ctx->replace_ctx))
 955                                return -EINVAL;
 956
 957                        WARN_ON(ctx->replace_ctx->replace_state !=
 958                                IEEE80211_CHANCTX_WILL_BE_REPLACED);
 959                        WARN_ON(ctx->replace_ctx->replace_ctx != ctx);
 960
 961                        ctx->replace_ctx->replace_ctx = NULL;
 962                        ctx->replace_ctx->replace_state =
 963                                        IEEE80211_CHANCTX_REPLACE_NONE;
 964
 965                        list_del_rcu(&ctx->list);
 966                        kfree_rcu(ctx, rcu_head);
 967                } else {
 968                        ieee80211_free_chanctx(sdata->local, ctx);
 969                }
 970        }
 971
 972        return 0;
 973}
 974
 975int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
 976                                  const struct cfg80211_chan_def *chandef,
 977                                  enum ieee80211_chanctx_mode mode,
 978                                  bool radar_required)
 979{
 980        struct ieee80211_local *local = sdata->local;
 981        struct ieee80211_chanctx *new_ctx, *curr_ctx, *ctx;
 982
 983        lockdep_assert_held(&local->chanctx_mtx);
 984
 985        curr_ctx = ieee80211_vif_get_chanctx(sdata);
 986        if (curr_ctx && local->use_chanctx && !local->ops->switch_vif_chanctx)
 987                return -ENOTSUPP;
 988
 989        new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode);
 990        if (!new_ctx) {
 991                if (ieee80211_can_create_new_chanctx(local)) {
 992                        new_ctx = ieee80211_new_chanctx(local, chandef, mode);
 993                        if (IS_ERR(new_ctx))
 994                                return PTR_ERR(new_ctx);
 995                } else {
 996                        if (!curr_ctx ||
 997                            (curr_ctx->replace_state ==
 998                             IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
 999                            !list_empty(&curr_ctx->reserved_vifs)) {
1000                                /*
1001                                 * Another vif already requested this context
1002                                 * for a reservation. Find another one hoping
1003                                 * all vifs assigned to it will also switch
1004                                 * soon enough.
1005                                 *
1006                                 * TODO: This needs a little more work as some
1007                                 * cases (more than 2 chanctx capable devices)
1008                                 * may fail which could otherwise succeed
1009                                 * provided some channel context juggling was
1010                                 * performed.
1011                                 *
1012                                 * Consider ctx1..3, vif1..6, each ctx has 2
1013                                 * vifs. vif1 and vif2 from ctx1 request new
1014                                 * different chandefs starting 2 in-place
1015                                 * reserations with ctx4 and ctx5 replacing
1016                                 * ctx1 and ctx2 respectively. Next vif5 and
1017                                 * vif6 from ctx3 reserve ctx4. If vif3 and
1018                                 * vif4 remain on ctx2 as they are then this
1019                                 * fails unless `replace_ctx` from ctx5 is
1020                                 * replaced with ctx3.
1021                                 */
1022                                list_for_each_entry(ctx, &local->chanctx_list,
1023                                                    list) {
1024                                        if (ctx->replace_state !=
1025                                            IEEE80211_CHANCTX_REPLACE_NONE)
1026                                                continue;
1027
1028                                        if (!list_empty(&ctx->reserved_vifs))
1029                                                continue;
1030
1031                                        curr_ctx = ctx;
1032                                        break;
1033                                }
1034                        }
1035
1036                        /*
1037                         * If that's true then all available contexts already
1038                         * have reservations and cannot be used.
1039                         */
1040                        if (!curr_ctx ||
1041                            (curr_ctx->replace_state ==
1042                             IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
1043                            !list_empty(&curr_ctx->reserved_vifs))
1044                                return -EBUSY;
1045
1046                        new_ctx = ieee80211_alloc_chanctx(local, chandef, mode);
1047                        if (!new_ctx)
1048                                return -ENOMEM;
1049
1050                        new_ctx->replace_ctx = curr_ctx;
1051                        new_ctx->replace_state =
1052                                        IEEE80211_CHANCTX_REPLACES_OTHER;
1053
1054                        curr_ctx->replace_ctx = new_ctx;
1055                        curr_ctx->replace_state =
1056                                        IEEE80211_CHANCTX_WILL_BE_REPLACED;
1057
1058                        list_add_rcu(&new_ctx->list, &local->chanctx_list);
1059                }
1060        }
1061
1062        list_add(&sdata->reserved_chanctx_list, &new_ctx->reserved_vifs);
1063        sdata->reserved_chanctx = new_ctx;
1064        sdata->reserved_chandef = *chandef;
1065        sdata->reserved_radar_required = radar_required;
1066        sdata->reserved_ready = false;
1067
1068        return 0;
1069}
1070
1071static void
1072ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
1073{
1074        switch (sdata->vif.type) {
1075        case NL80211_IFTYPE_ADHOC:
1076        case NL80211_IFTYPE_AP:
1077        case NL80211_IFTYPE_MESH_POINT:
1078        case NL80211_IFTYPE_OCB:
1079                ieee80211_queue_work(&sdata->local->hw,
1080                                     &sdata->csa_finalize_work);
1081                break;
1082        case NL80211_IFTYPE_STATION:
1083                ieee80211_queue_work(&sdata->local->hw,
1084                                     &sdata->u.mgd.chswitch_work);
1085                break;
1086        case NL80211_IFTYPE_UNSPECIFIED:
1087        case NL80211_IFTYPE_AP_VLAN:
1088        case NL80211_IFTYPE_WDS:
1089        case NL80211_IFTYPE_MONITOR:
1090        case NL80211_IFTYPE_P2P_CLIENT:
1091        case NL80211_IFTYPE_P2P_GO:
1092        case NL80211_IFTYPE_P2P_DEVICE:
1093        case NL80211_IFTYPE_NAN:
1094        case NUM_NL80211_IFTYPES:
1095                WARN_ON(1);
1096                break;
1097        }
1098}
1099
1100static void
1101ieee80211_vif_update_chandef(struct ieee80211_sub_if_data *sdata,
1102                             const struct cfg80211_chan_def *chandef)
1103{
1104        struct ieee80211_sub_if_data *vlan;
1105
1106        sdata->vif.bss_conf.chandef = *chandef;
1107
1108        if (sdata->vif.type != NL80211_IFTYPE_AP)
1109                return;
1110
1111        list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
1112                vlan->vif.bss_conf.chandef = *chandef;
1113}
1114
1115static int
1116ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
1117{
1118        struct ieee80211_local *local = sdata->local;
1119        struct ieee80211_vif_chanctx_switch vif_chsw[1] = {};
1120        struct ieee80211_chanctx *old_ctx, *new_ctx;
1121        const struct cfg80211_chan_def *chandef;
1122        u32 changed = 0;
1123        int err;
1124
1125        lockdep_assert_held(&local->mtx);
1126        lockdep_assert_held(&local->chanctx_mtx);
1127
1128        new_ctx = sdata->reserved_chanctx;
1129        old_ctx = ieee80211_vif_get_chanctx(sdata);
1130
1131        if (WARN_ON(!sdata->reserved_ready))
1132                return -EBUSY;
1133
1134        if (WARN_ON(!new_ctx))
1135                return -EINVAL;
1136
1137        if (WARN_ON(!old_ctx))
1138                return -EINVAL;
1139
1140        if (WARN_ON(new_ctx->replace_state ==
1141                    IEEE80211_CHANCTX_REPLACES_OTHER))
1142                return -EINVAL;
1143
1144        chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1145                                &sdata->reserved_chandef);
1146        if (WARN_ON(!chandef))
1147                return -EINVAL;
1148
1149        if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
1150                changed = BSS_CHANGED_BANDWIDTH;
1151
1152        ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
1153
1154        ieee80211_change_chanctx(local, new_ctx, old_ctx, chandef);
1155
1156        vif_chsw[0].vif = &sdata->vif;
1157        vif_chsw[0].old_ctx = &old_ctx->conf;
1158        vif_chsw[0].new_ctx = &new_ctx->conf;
1159
1160        list_del(&sdata->reserved_chanctx_list);
1161        sdata->reserved_chanctx = NULL;
1162
1163        err = drv_switch_vif_chanctx(local, vif_chsw, 1,
1164                                     CHANCTX_SWMODE_REASSIGN_VIF);
1165        if (err) {
1166                if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1167                        ieee80211_free_chanctx(local, new_ctx);
1168
1169                goto out;
1170        }
1171
1172        list_move(&sdata->assigned_chanctx_list, &new_ctx->assigned_vifs);
1173        rcu_assign_pointer(sdata->vif.chanctx_conf, &new_ctx->conf);
1174
1175        if (sdata->vif.type == NL80211_IFTYPE_AP)
1176                __ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
1177
1178        ieee80211_check_fast_xmit_iface(sdata);
1179
1180        if (ieee80211_chanctx_refcount(local, old_ctx) == 0)
1181                ieee80211_free_chanctx(local, old_ctx);
1182
1183        ieee80211_recalc_chanctx_min_def(local, new_ctx);
1184        ieee80211_recalc_smps_chanctx(local, new_ctx);
1185        ieee80211_recalc_radar_chanctx(local, new_ctx);
1186
1187        if (changed)
1188                ieee80211_bss_info_change_notify(sdata, changed);
1189
1190out:
1191        ieee80211_vif_chanctx_reservation_complete(sdata);
1192        return err;
1193}
1194
1195static int
1196ieee80211_vif_use_reserved_assign(struct ieee80211_sub_if_data *sdata)
1197{
1198        struct ieee80211_local *local = sdata->local;
1199        struct ieee80211_chanctx *old_ctx, *new_ctx;
1200        const struct cfg80211_chan_def *chandef;
1201        int err;
1202
1203        old_ctx = ieee80211_vif_get_chanctx(sdata);
1204        new_ctx = sdata->reserved_chanctx;
1205
1206        if (WARN_ON(!sdata->reserved_ready))
1207                return -EINVAL;
1208
1209        if (WARN_ON(old_ctx))
1210                return -EINVAL;
1211
1212        if (WARN_ON(!new_ctx))
1213                return -EINVAL;
1214
1215        if (WARN_ON(new_ctx->replace_state ==
1216                    IEEE80211_CHANCTX_REPLACES_OTHER))
1217                return -EINVAL;
1218
1219        chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1220                                &sdata->reserved_chandef);
1221        if (WARN_ON(!chandef))
1222                return -EINVAL;
1223
1224        ieee80211_change_chanctx(local, new_ctx, new_ctx, chandef);
1225
1226        list_del(&sdata->reserved_chanctx_list);
1227        sdata->reserved_chanctx = NULL;
1228
1229        err = ieee80211_assign_vif_chanctx(sdata, new_ctx);
1230        if (err) {
1231                if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1232                        ieee80211_free_chanctx(local, new_ctx);
1233
1234                goto out;
1235        }
1236
1237out:
1238        ieee80211_vif_chanctx_reservation_complete(sdata);
1239        return err;
1240}
1241
1242static bool
1243ieee80211_vif_has_in_place_reservation(struct ieee80211_sub_if_data *sdata)
1244{
1245        struct ieee80211_chanctx *old_ctx, *new_ctx;
1246
1247        lockdep_assert_held(&sdata->local->chanctx_mtx);
1248
1249        new_ctx = sdata->reserved_chanctx;
1250        old_ctx = ieee80211_vif_get_chanctx(sdata);
1251
1252        if (!old_ctx)
1253                return false;
1254
1255        if (WARN_ON(!new_ctx))
1256                return false;
1257
1258        if (old_ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1259                return false;
1260
1261        if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1262                return false;
1263
1264        return true;
1265}
1266
1267static int ieee80211_chsw_switch_hwconf(struct ieee80211_local *local,
1268                                        struct ieee80211_chanctx *new_ctx)
1269{
1270        const struct cfg80211_chan_def *chandef;
1271
1272        lockdep_assert_held(&local->mtx);
1273        lockdep_assert_held(&local->chanctx_mtx);
1274
1275        chandef = ieee80211_chanctx_reserved_chandef(local, new_ctx, NULL);
1276        if (WARN_ON(!chandef))
1277                return -EINVAL;
1278
1279        local->hw.conf.radar_enabled = new_ctx->conf.radar_enabled;
1280        local->_oper_chandef = *chandef;
1281        ieee80211_hw_config(local, 0);
1282
1283        return 0;
1284}
1285
1286static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,
1287                                      int n_vifs)
1288{
1289        struct ieee80211_vif_chanctx_switch *vif_chsw;
1290        struct ieee80211_sub_if_data *sdata;
1291        struct ieee80211_chanctx *ctx, *old_ctx;
1292        int i, err;
1293
1294        lockdep_assert_held(&local->mtx);
1295        lockdep_assert_held(&local->chanctx_mtx);
1296
1297        vif_chsw = kcalloc(n_vifs, sizeof(vif_chsw[0]), GFP_KERNEL);
1298        if (!vif_chsw)
1299                return -ENOMEM;
1300
1301        i = 0;
1302        list_for_each_entry(ctx, &local->chanctx_list, list) {
1303                if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1304                        continue;
1305
1306                if (WARN_ON(!ctx->replace_ctx)) {
1307                        err = -EINVAL;
1308                        goto out;
1309                }
1310
1311                list_for_each_entry(sdata, &ctx->reserved_vifs,
1312                                    reserved_chanctx_list) {
1313                        if (!ieee80211_vif_has_in_place_reservation(
1314                                        sdata))
1315                                continue;
1316
1317                        old_ctx = ieee80211_vif_get_chanctx(sdata);
1318                        vif_chsw[i].vif = &sdata->vif;
1319                        vif_chsw[i].old_ctx = &old_ctx->conf;
1320                        vif_chsw[i].new_ctx = &ctx->conf;
1321
1322                        i++;
1323                }
1324        }
1325
1326        err = drv_switch_vif_chanctx(local, vif_chsw, n_vifs,
1327                                     CHANCTX_SWMODE_SWAP_CONTEXTS);
1328
1329out:
1330        kfree(vif_chsw);
1331        return err;
1332}
1333
1334static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local)
1335{
1336        struct ieee80211_chanctx *ctx;
1337        int err;
1338
1339        lockdep_assert_held(&local->mtx);
1340        lockdep_assert_held(&local->chanctx_mtx);
1341
1342        list_for_each_entry(ctx, &local->chanctx_list, list) {
1343                if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1344                        continue;
1345
1346                if (!list_empty(&ctx->replace_ctx->assigned_vifs))
1347                        continue;
1348
1349                ieee80211_del_chanctx(local, ctx->replace_ctx);
1350                err = ieee80211_add_chanctx(local, ctx);
1351                if (err)
1352                        goto err;
1353        }
1354
1355        return 0;
1356
1357err:
1358        WARN_ON(ieee80211_add_chanctx(local, ctx));
1359        list_for_each_entry_continue_reverse(ctx, &local->chanctx_list, list) {
1360                if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1361                        continue;
1362
1363                if (!list_empty(&ctx->replace_ctx->assigned_vifs))
1364                        continue;
1365
1366                ieee80211_del_chanctx(local, ctx);
1367                WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx));
1368        }
1369
1370        return err;
1371}
1372
1373static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
1374{
1375        struct ieee80211_sub_if_data *sdata, *sdata_tmp;
1376        struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
1377        struct ieee80211_chanctx *new_ctx = NULL;
1378        int err, n_assigned, n_reserved, n_ready;
1379        int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0;
1380
1381        lockdep_assert_held(&local->mtx);
1382        lockdep_assert_held(&local->chanctx_mtx);
1383
1384        /*
1385         * If there are 2 independent pairs of channel contexts performing
1386         * cross-switch of their vifs this code will still wait until both are
1387         * ready even though it could be possible to switch one before the
1388         * other is ready.
1389         *
1390         * For practical reasons and code simplicity just do a single huge
1391         * switch.
1392         */
1393
1394        /*
1395         * Verify if the reservation is still feasible.
1396         *  - if it's not then disconnect
1397         *  - if it is but not all vifs necessary are ready then defer
1398         */
1399
1400        list_for_each_entry(ctx, &local->chanctx_list, list) {
1401                if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1402                        continue;
1403
1404                if (WARN_ON(!ctx->replace_ctx)) {
1405                        err = -EINVAL;
1406                        goto err;
1407                }
1408
1409                if (!local->use_chanctx)
1410                        new_ctx = ctx;
1411
1412                n_ctx++;
1413
1414                n_assigned = 0;
1415                n_reserved = 0;
1416                n_ready = 0;
1417
1418                list_for_each_entry(sdata, &ctx->replace_ctx->assigned_vifs,
1419                                    assigned_chanctx_list) {
1420                        n_assigned++;
1421                        if (sdata->reserved_chanctx) {
1422                                n_reserved++;
1423                                if (sdata->reserved_ready)
1424                                        n_ready++;
1425                        }
1426                }
1427
1428                if (n_assigned != n_reserved) {
1429                        if (n_ready == n_reserved) {
1430                                wiphy_info(local->hw.wiphy,
1431                                           "channel context reservation cannot be finalized because some interfaces aren't switching\n");
1432                                err = -EBUSY;
1433                                goto err;
1434                        }
1435
1436                        return -EAGAIN;
1437                }
1438
1439                ctx->conf.radar_enabled = false;
1440                list_for_each_entry(sdata, &ctx->reserved_vifs,
1441                                    reserved_chanctx_list) {
1442                        if (ieee80211_vif_has_in_place_reservation(sdata) &&
1443                            !sdata->reserved_ready)
1444                                return -EAGAIN;
1445
1446                        old_ctx = ieee80211_vif_get_chanctx(sdata);
1447                        if (old_ctx) {
1448                                if (old_ctx->replace_state ==
1449                                    IEEE80211_CHANCTX_WILL_BE_REPLACED)
1450                                        n_vifs_switch++;
1451                                else
1452                                        n_vifs_assign++;
1453                        } else {
1454                                n_vifs_ctxless++;
1455                        }
1456
1457                        if (sdata->reserved_radar_required)
1458                                ctx->conf.radar_enabled = true;
1459                }
1460        }
1461
1462        if (WARN_ON(n_ctx == 0) ||
1463            WARN_ON(n_vifs_switch == 0 &&
1464                    n_vifs_assign == 0 &&
1465                    n_vifs_ctxless == 0) ||
1466            WARN_ON(n_ctx > 1 && !local->use_chanctx) ||
1467            WARN_ON(!new_ctx && !local->use_chanctx)) {
1468                err = -EINVAL;
1469                goto err;
1470        }
1471
1472        /*
1473         * All necessary vifs are ready. Perform the switch now depending on
1474         * reservations and driver capabilities.
1475         */
1476
1477        if (local->use_chanctx) {
1478                if (n_vifs_switch > 0) {
1479                        err = ieee80211_chsw_switch_vifs(local, n_vifs_switch);
1480                        if (err)
1481                                goto err;
1482                }
1483
1484                if (n_vifs_assign > 0 || n_vifs_ctxless > 0) {
1485                        err = ieee80211_chsw_switch_ctxs(local);
1486                        if (err)
1487                                goto err;
1488                }
1489        } else {
1490                err = ieee80211_chsw_switch_hwconf(local, new_ctx);
1491                if (err)
1492                        goto err;
1493        }
1494
1495        /*
1496         * Update all structures, values and pointers to point to new channel
1497         * context(s).
1498         */
1499        list_for_each_entry(ctx, &local->chanctx_list, list) {
1500                if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1501                        continue;
1502
1503                if (WARN_ON(!ctx->replace_ctx)) {
1504                        err = -EINVAL;
1505                        goto err;
1506                }
1507
1508                list_for_each_entry(sdata, &ctx->reserved_vifs,
1509                                    reserved_chanctx_list) {
1510                        u32 changed = 0;
1511
1512                        if (!ieee80211_vif_has_in_place_reservation(sdata))
1513                                continue;
1514
1515                        rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf);
1516
1517                        if (sdata->vif.type == NL80211_IFTYPE_AP)
1518                                __ieee80211_vif_copy_chanctx_to_vlans(sdata,
1519                                                                      false);
1520
1521                        ieee80211_check_fast_xmit_iface(sdata);
1522
1523                        sdata->radar_required = sdata->reserved_radar_required;
1524
1525                        if (sdata->vif.bss_conf.chandef.width !=
1526                            sdata->reserved_chandef.width)
1527                                changed = BSS_CHANGED_BANDWIDTH;
1528
1529                        ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
1530                        if (changed)
1531                                ieee80211_bss_info_change_notify(sdata,
1532                                                                 changed);
1533
1534                        ieee80211_recalc_txpower(sdata, false);
1535                }
1536
1537                ieee80211_recalc_chanctx_chantype(local, ctx);
1538                ieee80211_recalc_smps_chanctx(local, ctx);
1539                ieee80211_recalc_radar_chanctx(local, ctx);
1540                ieee80211_recalc_chanctx_min_def(local, ctx);
1541
1542                list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1543                                         reserved_chanctx_list) {
1544                        if (ieee80211_vif_get_chanctx(sdata) != ctx)
1545                                continue;
1546
1547                        list_del(&sdata->reserved_chanctx_list);
1548                        list_move(&sdata->assigned_chanctx_list,
1549                                  &ctx->assigned_vifs);
1550                        sdata->reserved_chanctx = NULL;
1551
1552                        ieee80211_vif_chanctx_reservation_complete(sdata);
1553                }
1554
1555                /*
1556                 * This context might have been a dependency for an already
1557                 * ready re-assign reservation interface that was deferred. Do
1558                 * not propagate error to the caller though. The in-place
1559                 * reservation for originally requested interface has already
1560                 * succeeded at this point.
1561                 */
1562                list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1563                                         reserved_chanctx_list) {
1564                        if (WARN_ON(ieee80211_vif_has_in_place_reservation(
1565                                        sdata)))
1566                                continue;
1567
1568                        if (WARN_ON(sdata->reserved_chanctx != ctx))
1569                                continue;
1570
1571                        if (!sdata->reserved_ready)
1572                                continue;
1573
1574                        if (ieee80211_vif_get_chanctx(sdata))
1575                                err = ieee80211_vif_use_reserved_reassign(
1576                                                sdata);
1577                        else
1578                                err = ieee80211_vif_use_reserved_assign(sdata);
1579
1580                        if (err) {
1581                                sdata_info(sdata,
1582                                           "failed to finalize (re-)assign reservation (err=%d)\n",
1583                                           err);
1584                                ieee80211_vif_unreserve_chanctx(sdata);
1585                                cfg80211_stop_iface(local->hw.wiphy,
1586                                                    &sdata->wdev,
1587                                                    GFP_KERNEL);
1588                        }
1589                }
1590        }
1591
1592        /*
1593         * Finally free old contexts
1594         */
1595
1596        list_for_each_entry_safe(ctx, ctx_tmp, &local->chanctx_list, list) {
1597                if (ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1598                        continue;
1599
1600                ctx->replace_ctx->replace_ctx = NULL;
1601                ctx->replace_ctx->replace_state =
1602                                IEEE80211_CHANCTX_REPLACE_NONE;
1603
1604                list_del_rcu(&ctx->list);
1605                kfree_rcu(ctx, rcu_head);
1606        }
1607
1608        return 0;
1609
1610err:
1611        list_for_each_entry(ctx, &local->chanctx_list, list) {
1612                if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1613                        continue;
1614
1615                list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1616                                         reserved_chanctx_list) {
1617                        ieee80211_vif_unreserve_chanctx(sdata);
1618                        ieee80211_vif_chanctx_reservation_complete(sdata);
1619                }
1620        }
1621
1622        return err;
1623}
1624
1625static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
1626{
1627        struct ieee80211_local *local = sdata->local;
1628        struct ieee80211_chanctx_conf *conf;
1629        struct ieee80211_chanctx *ctx;
1630        bool use_reserved_switch = false;
1631
1632        lockdep_assert_held(&local->chanctx_mtx);
1633
1634        conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1635                                         lockdep_is_held(&local->chanctx_mtx));
1636        if (!conf)
1637                return;
1638
1639        ctx = container_of(conf, struct ieee80211_chanctx, conf);
1640
1641        if (sdata->reserved_chanctx) {
1642                if (sdata->reserved_chanctx->replace_state ==
1643                    IEEE80211_CHANCTX_REPLACES_OTHER &&
1644                    ieee80211_chanctx_num_reserved(local,
1645                                                   sdata->reserved_chanctx) > 1)
1646                        use_reserved_switch = true;
1647
1648                ieee80211_vif_unreserve_chanctx(sdata);
1649        }
1650
1651        ieee80211_assign_vif_chanctx(sdata, NULL);
1652        if (ieee80211_chanctx_refcount(local, ctx) == 0)
1653                ieee80211_free_chanctx(local, ctx);
1654
1655        sdata->radar_required = false;
1656
1657        /* Unreserving may ready an in-place reservation. */
1658        if (use_reserved_switch)
1659                ieee80211_vif_use_reserved_switch(local);
1660}
1661
1662int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
1663                              const struct cfg80211_chan_def *chandef,
1664                              enum ieee80211_chanctx_mode mode)
1665{
1666        struct ieee80211_local *local = sdata->local;
1667        struct ieee80211_chanctx *ctx;
1668        u8 radar_detect_width = 0;
1669        int ret;
1670
1671        lockdep_assert_held(&local->mtx);
1672
1673        WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
1674
1675        mutex_lock(&local->chanctx_mtx);
1676
1677        ret = cfg80211_chandef_dfs_required(local->hw.wiphy,
1678                                            chandef,
1679                                            sdata->wdev.iftype);
1680        if (ret < 0)
1681                goto out;
1682        if (ret > 0)
1683                radar_detect_width = BIT(chandef->width);
1684
1685        sdata->radar_required = ret;
1686
1687        ret = ieee80211_check_combinations(sdata, chandef, mode,
1688                                           radar_detect_width);
1689        if (ret < 0)
1690                goto out;
1691
1692        __ieee80211_vif_release_channel(sdata);
1693
1694        ctx = ieee80211_find_chanctx(local, chandef, mode);
1695        if (!ctx)
1696                ctx = ieee80211_new_chanctx(local, chandef, mode);
1697        if (IS_ERR(ctx)) {
1698                ret = PTR_ERR(ctx);
1699                goto out;
1700        }
1701
1702        ieee80211_vif_update_chandef(sdata, chandef);
1703
1704        ret = ieee80211_assign_vif_chanctx(sdata, ctx);
1705        if (ret) {
1706                /* if assign fails refcount stays the same */
1707                if (ieee80211_chanctx_refcount(local, ctx) == 0)
1708                        ieee80211_free_chanctx(local, ctx);
1709                goto out;
1710        }
1711
1712        ieee80211_recalc_smps_chanctx(local, ctx);
1713        ieee80211_recalc_radar_chanctx(local, ctx);
1714 out:
1715        if (ret)
1716                sdata->radar_required = false;
1717
1718        mutex_unlock(&local->chanctx_mtx);
1719        return ret;
1720}
1721
1722int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata)
1723{
1724        struct ieee80211_local *local = sdata->local;
1725        struct ieee80211_chanctx *new_ctx;
1726        struct ieee80211_chanctx *old_ctx;
1727        int err;
1728
1729        lockdep_assert_held(&local->mtx);
1730        lockdep_assert_held(&local->chanctx_mtx);
1731
1732        new_ctx = sdata->reserved_chanctx;
1733        old_ctx = ieee80211_vif_get_chanctx(sdata);
1734
1735        if (WARN_ON(!new_ctx))
1736                return -EINVAL;
1737
1738        if (WARN_ON(new_ctx->replace_state ==
1739                    IEEE80211_CHANCTX_WILL_BE_REPLACED))
1740                return -EINVAL;
1741
1742        if (WARN_ON(sdata->reserved_ready))
1743                return -EINVAL;
1744
1745        sdata->reserved_ready = true;
1746
1747        if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) {
1748                if (old_ctx)
1749                        err = ieee80211_vif_use_reserved_reassign(sdata);
1750                else
1751                        err = ieee80211_vif_use_reserved_assign(sdata);
1752
1753                if (err)
1754                        return err;
1755        }
1756
1757        /*
1758         * In-place reservation may need to be finalized now either if:
1759         *  a) sdata is taking part in the swapping itself and is the last one
1760         *  b) sdata has switched with a re-assign reservation to an existing
1761         *     context readying in-place switching of old_ctx
1762         *
1763         * In case of (b) do not propagate the error up because the requested
1764         * sdata already switched successfully. Just spill an extra warning.
1765         * The ieee80211_vif_use_reserved_switch() already stops all necessary
1766         * interfaces upon failure.
1767         */
1768        if ((old_ctx &&
1769             old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
1770            new_ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
1771                err = ieee80211_vif_use_reserved_switch(local);
1772                if (err && err != -EAGAIN) {
1773                        if (new_ctx->replace_state ==
1774                            IEEE80211_CHANCTX_REPLACES_OTHER)
1775                                return err;
1776
1777                        wiphy_info(local->hw.wiphy,
1778                                   "depending in-place reservation failed (err=%d)\n",
1779                                   err);
1780                }
1781        }
1782
1783        return 0;
1784}
1785
1786int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1787                                   const struct cfg80211_chan_def *chandef,
1788                                   u32 *changed)
1789{
1790        struct ieee80211_local *local = sdata->local;
1791        struct ieee80211_chanctx_conf *conf;
1792        struct ieee80211_chanctx *ctx;
1793        const struct cfg80211_chan_def *compat;
1794        int ret;
1795
1796        if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
1797                                     IEEE80211_CHAN_DISABLED))
1798                return -EINVAL;
1799
1800        mutex_lock(&local->chanctx_mtx);
1801        if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) {
1802                ret = 0;
1803                goto out;
1804        }
1805
1806        if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT ||
1807            sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) {
1808                ret = -EINVAL;
1809                goto out;
1810        }
1811
1812        conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1813                                         lockdep_is_held(&local->chanctx_mtx));
1814        if (!conf) {
1815                ret = -EINVAL;
1816                goto out;
1817        }
1818
1819        ctx = container_of(conf, struct ieee80211_chanctx, conf);
1820
1821        compat = cfg80211_chandef_compatible(&conf->def, chandef);
1822        if (!compat) {
1823                ret = -EINVAL;
1824                goto out;
1825        }
1826
1827        switch (ctx->replace_state) {
1828        case IEEE80211_CHANCTX_REPLACE_NONE:
1829                if (!ieee80211_chanctx_reserved_chandef(local, ctx, compat)) {
1830                        ret = -EBUSY;
1831                        goto out;
1832                }
1833                break;
1834        case IEEE80211_CHANCTX_WILL_BE_REPLACED:
1835                /* TODO: Perhaps the bandwidth change could be treated as a
1836                 * reservation itself? */
1837                ret = -EBUSY;
1838                goto out;
1839        case IEEE80211_CHANCTX_REPLACES_OTHER:
1840                /* channel context that is going to replace another channel
1841                 * context doesn't really exist and shouldn't be assigned
1842                 * anywhere yet */
1843                WARN_ON(1);
1844                break;
1845        }
1846
1847        ieee80211_vif_update_chandef(sdata, chandef);
1848
1849        ieee80211_recalc_chanctx_chantype(local, ctx);
1850
1851        *changed |= BSS_CHANGED_BANDWIDTH;
1852        ret = 0;
1853 out:
1854        mutex_unlock(&local->chanctx_mtx);
1855        return ret;
1856}
1857
1858void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
1859{
1860        WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
1861
1862        lockdep_assert_held(&sdata->local->mtx);
1863
1864        mutex_lock(&sdata->local->chanctx_mtx);
1865        __ieee80211_vif_release_channel(sdata);
1866        mutex_unlock(&sdata->local->chanctx_mtx);
1867}
1868
1869void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata)
1870{
1871        struct ieee80211_local *local = sdata->local;
1872        struct ieee80211_sub_if_data *ap;
1873        struct ieee80211_chanctx_conf *conf;
1874
1875        if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->bss))
1876                return;
1877
1878        ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
1879
1880        mutex_lock(&local->chanctx_mtx);
1881
1882        conf = rcu_dereference_protected(ap->vif.chanctx_conf,
1883                                         lockdep_is_held(&local->chanctx_mtx));
1884        rcu_assign_pointer(sdata->vif.chanctx_conf, conf);
1885        mutex_unlock(&local->chanctx_mtx);
1886}
1887
1888void ieee80211_iter_chan_contexts_atomic(
1889        struct ieee80211_hw *hw,
1890        void (*iter)(struct ieee80211_hw *hw,
1891                     struct ieee80211_chanctx_conf *chanctx_conf,
1892                     void *data),
1893        void *iter_data)
1894{
1895        struct ieee80211_local *local = hw_to_local(hw);
1896        struct ieee80211_chanctx *ctx;
1897
1898        rcu_read_lock();
1899        list_for_each_entry_rcu(ctx, &local->chanctx_list, list)
1900                if (ctx->driver_present)
1901                        iter(hw, &ctx->conf, iter_data);
1902        rcu_read_unlock();
1903}
1904EXPORT_SYMBOL_GPL(ieee80211_iter_chan_contexts_atomic);
1905