linux/net/wireless/chan.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * This file contains helper code to handle channel
   4 * settings and keeping track of what is possible at
   5 * any point in time.
   6 *
   7 * Copyright 2009       Johannes Berg <johannes@sipsolutions.net>
   8 * Copyright 2013-2014  Intel Mobile Communications GmbH
   9 */
  10
  11#include <linux/export.h>
  12#include <net/cfg80211.h>
  13#include "core.h"
  14#include "rdev-ops.h"
  15
  16void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
  17                             struct ieee80211_channel *chan,
  18                             enum nl80211_channel_type chan_type)
  19{
  20        if (WARN_ON(!chan))
  21                return;
  22
  23        chandef->chan = chan;
  24        chandef->center_freq2 = 0;
  25
  26        switch (chan_type) {
  27        case NL80211_CHAN_NO_HT:
  28                chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
  29                chandef->center_freq1 = chan->center_freq;
  30                break;
  31        case NL80211_CHAN_HT20:
  32                chandef->width = NL80211_CHAN_WIDTH_20;
  33                chandef->center_freq1 = chan->center_freq;
  34                break;
  35        case NL80211_CHAN_HT40PLUS:
  36                chandef->width = NL80211_CHAN_WIDTH_40;
  37                chandef->center_freq1 = chan->center_freq + 10;
  38                break;
  39        case NL80211_CHAN_HT40MINUS:
  40                chandef->width = NL80211_CHAN_WIDTH_40;
  41                chandef->center_freq1 = chan->center_freq - 10;
  42                break;
  43        default:
  44                WARN_ON(1);
  45        }
  46}
  47EXPORT_SYMBOL(cfg80211_chandef_create);
  48
  49bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
  50{
  51        u32 control_freq;
  52
  53        if (!chandef->chan)
  54                return false;
  55
  56        control_freq = chandef->chan->center_freq;
  57
  58        switch (chandef->width) {
  59        case NL80211_CHAN_WIDTH_5:
  60        case NL80211_CHAN_WIDTH_10:
  61        case NL80211_CHAN_WIDTH_20:
  62        case NL80211_CHAN_WIDTH_20_NOHT:
  63                if (chandef->center_freq1 != control_freq)
  64                        return false;
  65                if (chandef->center_freq2)
  66                        return false;
  67                break;
  68        case NL80211_CHAN_WIDTH_40:
  69                if (chandef->center_freq1 != control_freq + 10 &&
  70                    chandef->center_freq1 != control_freq - 10)
  71                        return false;
  72                if (chandef->center_freq2)
  73                        return false;
  74                break;
  75        case NL80211_CHAN_WIDTH_80P80:
  76                if (chandef->center_freq1 != control_freq + 30 &&
  77                    chandef->center_freq1 != control_freq + 10 &&
  78                    chandef->center_freq1 != control_freq - 10 &&
  79                    chandef->center_freq1 != control_freq - 30)
  80                        return false;
  81                if (!chandef->center_freq2)
  82                        return false;
  83                /* adjacent is not allowed -- that's a 160 MHz channel */
  84                if (chandef->center_freq1 - chandef->center_freq2 == 80 ||
  85                    chandef->center_freq2 - chandef->center_freq1 == 80)
  86                        return false;
  87                break;
  88        case NL80211_CHAN_WIDTH_80:
  89                if (chandef->center_freq1 != control_freq + 30 &&
  90                    chandef->center_freq1 != control_freq + 10 &&
  91                    chandef->center_freq1 != control_freq - 10 &&
  92                    chandef->center_freq1 != control_freq - 30)
  93                        return false;
  94                if (chandef->center_freq2)
  95                        return false;
  96                break;
  97        case NL80211_CHAN_WIDTH_160:
  98                if (chandef->center_freq1 != control_freq + 70 &&
  99                    chandef->center_freq1 != control_freq + 50 &&
 100                    chandef->center_freq1 != control_freq + 30 &&
 101                    chandef->center_freq1 != control_freq + 10 &&
 102                    chandef->center_freq1 != control_freq - 10 &&
 103                    chandef->center_freq1 != control_freq - 30 &&
 104                    chandef->center_freq1 != control_freq - 50 &&
 105                    chandef->center_freq1 != control_freq - 70)
 106                        return false;
 107                if (chandef->center_freq2)
 108                        return false;
 109                break;
 110        default:
 111                return false;
 112        }
 113
 114        return true;
 115}
 116EXPORT_SYMBOL(cfg80211_chandef_valid);
 117
 118static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
 119                                  u32 *pri40, u32 *pri80)
 120{
 121        int tmp;
 122
 123        switch (c->width) {
 124        case NL80211_CHAN_WIDTH_40:
 125                *pri40 = c->center_freq1;
 126                *pri80 = 0;
 127                break;
 128        case NL80211_CHAN_WIDTH_80:
 129        case NL80211_CHAN_WIDTH_80P80:
 130                *pri80 = c->center_freq1;
 131                /* n_P20 */
 132                tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
 133                /* n_P40 */
 134                tmp /= 2;
 135                /* freq_P40 */
 136                *pri40 = c->center_freq1 - 20 + 40 * tmp;
 137                break;
 138        case NL80211_CHAN_WIDTH_160:
 139                /* n_P20 */
 140                tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
 141                /* n_P40 */
 142                tmp /= 2;
 143                /* freq_P40 */
 144                *pri40 = c->center_freq1 - 60 + 40 * tmp;
 145                /* n_P80 */
 146                tmp /= 2;
 147                *pri80 = c->center_freq1 - 40 + 80 * tmp;
 148                break;
 149        default:
 150                WARN_ON_ONCE(1);
 151        }
 152}
 153
 154static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
 155{
 156        int width;
 157
 158        switch (c->width) {
 159        case NL80211_CHAN_WIDTH_5:
 160                width = 5;
 161                break;
 162        case NL80211_CHAN_WIDTH_10:
 163                width = 10;
 164                break;
 165        case NL80211_CHAN_WIDTH_20:
 166        case NL80211_CHAN_WIDTH_20_NOHT:
 167                width = 20;
 168                break;
 169        case NL80211_CHAN_WIDTH_40:
 170                width = 40;
 171                break;
 172        case NL80211_CHAN_WIDTH_80P80:
 173        case NL80211_CHAN_WIDTH_80:
 174                width = 80;
 175                break;
 176        case NL80211_CHAN_WIDTH_160:
 177                width = 160;
 178                break;
 179        default:
 180                WARN_ON_ONCE(1);
 181                return -1;
 182        }
 183        return width;
 184}
 185
 186const struct cfg80211_chan_def *
 187cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
 188                            const struct cfg80211_chan_def *c2)
 189{
 190        u32 c1_pri40, c1_pri80, c2_pri40, c2_pri80;
 191
 192        /* If they are identical, return */
 193        if (cfg80211_chandef_identical(c1, c2))
 194                return c1;
 195
 196        /* otherwise, must have same control channel */
 197        if (c1->chan != c2->chan)
 198                return NULL;
 199
 200        /*
 201         * If they have the same width, but aren't identical,
 202         * then they can't be compatible.
 203         */
 204        if (c1->width == c2->width)
 205                return NULL;
 206
 207        /*
 208         * can't be compatible if one of them is 5 or 10 MHz,
 209         * but they don't have the same width.
 210         */
 211        if (c1->width == NL80211_CHAN_WIDTH_5 ||
 212            c1->width == NL80211_CHAN_WIDTH_10 ||
 213            c2->width == NL80211_CHAN_WIDTH_5 ||
 214            c2->width == NL80211_CHAN_WIDTH_10)
 215                return NULL;
 216
 217        if (c1->width == NL80211_CHAN_WIDTH_20_NOHT ||
 218            c1->width == NL80211_CHAN_WIDTH_20)
 219                return c2;
 220
 221        if (c2->width == NL80211_CHAN_WIDTH_20_NOHT ||
 222            c2->width == NL80211_CHAN_WIDTH_20)
 223                return c1;
 224
 225        chandef_primary_freqs(c1, &c1_pri40, &c1_pri80);
 226        chandef_primary_freqs(c2, &c2_pri40, &c2_pri80);
 227
 228        if (c1_pri40 != c2_pri40)
 229                return NULL;
 230
 231        WARN_ON(!c1_pri80 && !c2_pri80);
 232        if (c1_pri80 && c2_pri80 && c1_pri80 != c2_pri80)
 233                return NULL;
 234
 235        if (c1->width > c2->width)
 236                return c1;
 237        return c2;
 238}
 239EXPORT_SYMBOL(cfg80211_chandef_compatible);
 240
 241static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
 242                                         u32 bandwidth,
 243                                         enum nl80211_dfs_state dfs_state)
 244{
 245        struct ieee80211_channel *c;
 246        u32 freq;
 247
 248        for (freq = center_freq - bandwidth/2 + 10;
 249             freq <= center_freq + bandwidth/2 - 10;
 250             freq += 20) {
 251                c = ieee80211_get_channel(wiphy, freq);
 252                if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
 253                        continue;
 254
 255                c->dfs_state = dfs_state;
 256                c->dfs_state_entered = jiffies;
 257        }
 258}
 259
 260void cfg80211_set_dfs_state(struct wiphy *wiphy,
 261                            const struct cfg80211_chan_def *chandef,
 262                            enum nl80211_dfs_state dfs_state)
 263{
 264        int width;
 265
 266        if (WARN_ON(!cfg80211_chandef_valid(chandef)))
 267                return;
 268
 269        width = cfg80211_chandef_get_width(chandef);
 270        if (width < 0)
 271                return;
 272
 273        cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq1,
 274                                     width, dfs_state);
 275
 276        if (!chandef->center_freq2)
 277                return;
 278        cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq2,
 279                                     width, dfs_state);
 280}
 281
 282static u32 cfg80211_get_start_freq(u32 center_freq,
 283                                   u32 bandwidth)
 284{
 285        u32 start_freq;
 286
 287        if (bandwidth <= 20)
 288                start_freq = center_freq;
 289        else
 290                start_freq = center_freq - bandwidth/2 + 10;
 291
 292        return start_freq;
 293}
 294
 295static u32 cfg80211_get_end_freq(u32 center_freq,
 296                                 u32 bandwidth)
 297{
 298        u32 end_freq;
 299
 300        if (bandwidth <= 20)
 301                end_freq = center_freq;
 302        else
 303                end_freq = center_freq + bandwidth/2 - 10;
 304
 305        return end_freq;
 306}
 307
 308static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
 309                                            u32 center_freq,
 310                                            u32 bandwidth)
 311{
 312        struct ieee80211_channel *c;
 313        u32 freq, start_freq, end_freq;
 314
 315        start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
 316        end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
 317
 318        for (freq = start_freq; freq <= end_freq; freq += 20) {
 319                c = ieee80211_get_channel(wiphy, freq);
 320                if (!c)
 321                        return -EINVAL;
 322
 323                if (c->flags & IEEE80211_CHAN_RADAR)
 324                        return 1;
 325        }
 326        return 0;
 327}
 328
 329
 330int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
 331                                  const struct cfg80211_chan_def *chandef,
 332                                  enum nl80211_iftype iftype)
 333{
 334        int width;
 335        int ret;
 336
 337        if (WARN_ON(!cfg80211_chandef_valid(chandef)))
 338                return -EINVAL;
 339
 340        switch (iftype) {
 341        case NL80211_IFTYPE_ADHOC:
 342        case NL80211_IFTYPE_AP:
 343        case NL80211_IFTYPE_P2P_GO:
 344        case NL80211_IFTYPE_MESH_POINT:
 345                width = cfg80211_chandef_get_width(chandef);
 346                if (width < 0)
 347                        return -EINVAL;
 348
 349                ret = cfg80211_get_chans_dfs_required(wiphy,
 350                                                      chandef->center_freq1,
 351                                                      width);
 352                if (ret < 0)
 353                        return ret;
 354                else if (ret > 0)
 355                        return BIT(chandef->width);
 356
 357                if (!chandef->center_freq2)
 358                        return 0;
 359
 360                ret = cfg80211_get_chans_dfs_required(wiphy,
 361                                                      chandef->center_freq2,
 362                                                      width);
 363                if (ret < 0)
 364                        return ret;
 365                else if (ret > 0)
 366                        return BIT(chandef->width);
 367
 368                break;
 369        case NL80211_IFTYPE_STATION:
 370        case NL80211_IFTYPE_OCB:
 371        case NL80211_IFTYPE_P2P_CLIENT:
 372        case NL80211_IFTYPE_MONITOR:
 373        case NL80211_IFTYPE_AP_VLAN:
 374        case NL80211_IFTYPE_WDS:
 375        case NL80211_IFTYPE_P2P_DEVICE:
 376        case NL80211_IFTYPE_NAN:
 377                break;
 378        case NL80211_IFTYPE_UNSPECIFIED:
 379        case NUM_NL80211_IFTYPES:
 380                WARN_ON(1);
 381        }
 382
 383        return 0;
 384}
 385EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
 386
 387static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
 388                                         u32 center_freq,
 389                                         u32 bandwidth)
 390{
 391        struct ieee80211_channel *c;
 392        u32 freq, start_freq, end_freq;
 393        int count = 0;
 394
 395        start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
 396        end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
 397
 398        /*
 399         * Check entire range of channels for the bandwidth.
 400         * Check all channels are DFS channels (DFS_USABLE or
 401         * DFS_AVAILABLE). Return number of usable channels
 402         * (require CAC). Allow DFS and non-DFS channel mix.
 403         */
 404        for (freq = start_freq; freq <= end_freq; freq += 20) {
 405                c = ieee80211_get_channel(wiphy, freq);
 406                if (!c)
 407                        return -EINVAL;
 408
 409                if (c->flags & IEEE80211_CHAN_DISABLED)
 410                        return -EINVAL;
 411
 412                if (c->flags & IEEE80211_CHAN_RADAR) {
 413                        if (c->dfs_state == NL80211_DFS_UNAVAILABLE)
 414                                return -EINVAL;
 415
 416                        if (c->dfs_state == NL80211_DFS_USABLE)
 417                                count++;
 418                }
 419        }
 420
 421        return count;
 422}
 423
 424bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
 425                                 const struct cfg80211_chan_def *chandef)
 426{
 427        int width;
 428        int r1, r2 = 0;
 429
 430        if (WARN_ON(!cfg80211_chandef_valid(chandef)))
 431                return false;
 432
 433        width = cfg80211_chandef_get_width(chandef);
 434        if (width < 0)
 435                return false;
 436
 437        r1 = cfg80211_get_chans_dfs_usable(wiphy, chandef->center_freq1,
 438                                          width);
 439
 440        if (r1 < 0)
 441                return false;
 442
 443        switch (chandef->width) {
 444        case NL80211_CHAN_WIDTH_80P80:
 445                WARN_ON(!chandef->center_freq2);
 446                r2 = cfg80211_get_chans_dfs_usable(wiphy,
 447                                                   chandef->center_freq2,
 448                                                   width);
 449                if (r2 < 0)
 450                        return false;
 451                break;
 452        default:
 453                WARN_ON(chandef->center_freq2);
 454                break;
 455        }
 456
 457        return (r1 + r2 > 0);
 458}
 459
 460/*
 461 * Checks if center frequency of chan falls with in the bandwidth
 462 * range of chandef.
 463 */
 464bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
 465                          struct ieee80211_channel *chan)
 466{
 467        int width;
 468        u32 freq;
 469
 470        if (chandef->chan->center_freq == chan->center_freq)
 471                return true;
 472
 473        width = cfg80211_chandef_get_width(chandef);
 474        if (width <= 20)
 475                return false;
 476
 477        for (freq = chandef->center_freq1 - width / 2 + 10;
 478             freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) {
 479                if (chan->center_freq == freq)
 480                        return true;
 481        }
 482
 483        if (!chandef->center_freq2)
 484                return false;
 485
 486        for (freq = chandef->center_freq2 - width / 2 + 10;
 487             freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) {
 488                if (chan->center_freq == freq)
 489                        return true;
 490        }
 491
 492        return false;
 493}
 494
 495bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev)
 496{
 497        bool active = false;
 498
 499        ASSERT_WDEV_LOCK(wdev);
 500
 501        if (!wdev->chandef.chan)
 502                return false;
 503
 504        switch (wdev->iftype) {
 505        case NL80211_IFTYPE_AP:
 506        case NL80211_IFTYPE_P2P_GO:
 507                active = wdev->beacon_interval != 0;
 508                break;
 509        case NL80211_IFTYPE_ADHOC:
 510                active = wdev->ssid_len != 0;
 511                break;
 512        case NL80211_IFTYPE_MESH_POINT:
 513                active = wdev->mesh_id_len != 0;
 514                break;
 515        case NL80211_IFTYPE_STATION:
 516        case NL80211_IFTYPE_OCB:
 517        case NL80211_IFTYPE_P2P_CLIENT:
 518        case NL80211_IFTYPE_MONITOR:
 519        case NL80211_IFTYPE_AP_VLAN:
 520        case NL80211_IFTYPE_WDS:
 521        case NL80211_IFTYPE_P2P_DEVICE:
 522        /* Can NAN type be considered as beaconing interface? */
 523        case NL80211_IFTYPE_NAN:
 524                break;
 525        case NL80211_IFTYPE_UNSPECIFIED:
 526        case NUM_NL80211_IFTYPES:
 527                WARN_ON(1);
 528        }
 529
 530        return active;
 531}
 532
 533static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
 534                                        struct ieee80211_channel *chan)
 535{
 536        struct wireless_dev *wdev;
 537
 538        list_for_each_entry(wdev, &wiphy->wdev_list, list) {
 539                wdev_lock(wdev);
 540                if (!cfg80211_beaconing_iface_active(wdev)) {
 541                        wdev_unlock(wdev);
 542                        continue;
 543                }
 544
 545                if (cfg80211_is_sub_chan(&wdev->chandef, chan)) {
 546                        wdev_unlock(wdev);
 547                        return true;
 548                }
 549                wdev_unlock(wdev);
 550        }
 551
 552        return false;
 553}
 554
 555bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
 556                                  struct ieee80211_channel *chan)
 557{
 558        struct cfg80211_registered_device *rdev;
 559
 560        ASSERT_RTNL();
 561
 562        if (!(chan->flags & IEEE80211_CHAN_RADAR))
 563                return false;
 564
 565        list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
 566                if (!reg_dfs_domain_same(wiphy, &rdev->wiphy))
 567                        continue;
 568
 569                if (cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan))
 570                        return true;
 571        }
 572
 573        return false;
 574}
 575
 576static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
 577                                             u32 center_freq,
 578                                             u32 bandwidth)
 579{
 580        struct ieee80211_channel *c;
 581        u32 freq, start_freq, end_freq;
 582        bool dfs_offload;
 583
 584        dfs_offload = wiphy_ext_feature_isset(wiphy,
 585                                              NL80211_EXT_FEATURE_DFS_OFFLOAD);
 586
 587        start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
 588        end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
 589
 590        /*
 591         * Check entire range of channels for the bandwidth.
 592         * If any channel in between is disabled or has not
 593         * had gone through CAC return false
 594         */
 595        for (freq = start_freq; freq <= end_freq; freq += 20) {
 596                c = ieee80211_get_channel(wiphy, freq);
 597                if (!c)
 598                        return false;
 599
 600                if (c->flags & IEEE80211_CHAN_DISABLED)
 601                        return false;
 602
 603                if ((c->flags & IEEE80211_CHAN_RADAR) &&
 604                    (c->dfs_state != NL80211_DFS_AVAILABLE) &&
 605                    !(c->dfs_state == NL80211_DFS_USABLE && dfs_offload))
 606                        return false;
 607        }
 608
 609        return true;
 610}
 611
 612static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
 613                                const struct cfg80211_chan_def *chandef)
 614{
 615        int width;
 616        int r;
 617
 618        if (WARN_ON(!cfg80211_chandef_valid(chandef)))
 619                return false;
 620
 621        width = cfg80211_chandef_get_width(chandef);
 622        if (width < 0)
 623                return false;
 624
 625        r = cfg80211_get_chans_dfs_available(wiphy, chandef->center_freq1,
 626                                             width);
 627
 628        /* If any of channels unavailable for cf1 just return */
 629        if (!r)
 630                return r;
 631
 632        switch (chandef->width) {
 633        case NL80211_CHAN_WIDTH_80P80:
 634                WARN_ON(!chandef->center_freq2);
 635                r = cfg80211_get_chans_dfs_available(wiphy,
 636                                                     chandef->center_freq2,
 637                                                     width);
 638                break;
 639        default:
 640                WARN_ON(chandef->center_freq2);
 641                break;
 642        }
 643
 644        return r;
 645}
 646
 647static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
 648                                                    u32 center_freq,
 649                                                    u32 bandwidth)
 650{
 651        struct ieee80211_channel *c;
 652        u32 start_freq, end_freq, freq;
 653        unsigned int dfs_cac_ms = 0;
 654
 655        start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
 656        end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
 657
 658        for (freq = start_freq; freq <= end_freq; freq += 20) {
 659                c = ieee80211_get_channel(wiphy, freq);
 660                if (!c)
 661                        return 0;
 662
 663                if (c->flags & IEEE80211_CHAN_DISABLED)
 664                        return 0;
 665
 666                if (!(c->flags & IEEE80211_CHAN_RADAR))
 667                        continue;
 668
 669                if (c->dfs_cac_ms > dfs_cac_ms)
 670                        dfs_cac_ms = c->dfs_cac_ms;
 671        }
 672
 673        return dfs_cac_ms;
 674}
 675
 676unsigned int
 677cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
 678                              const struct cfg80211_chan_def *chandef)
 679{
 680        int width;
 681        unsigned int t1 = 0, t2 = 0;
 682
 683        if (WARN_ON(!cfg80211_chandef_valid(chandef)))
 684                return 0;
 685
 686        width = cfg80211_chandef_get_width(chandef);
 687        if (width < 0)
 688                return 0;
 689
 690        t1 = cfg80211_get_chans_dfs_cac_time(wiphy,
 691                                             chandef->center_freq1,
 692                                             width);
 693
 694        if (!chandef->center_freq2)
 695                return t1;
 696
 697        t2 = cfg80211_get_chans_dfs_cac_time(wiphy,
 698                                             chandef->center_freq2,
 699                                             width);
 700
 701        return max(t1, t2);
 702}
 703
 704static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
 705                                        u32 center_freq, u32 bandwidth,
 706                                        u32 prohibited_flags)
 707{
 708        struct ieee80211_channel *c;
 709        u32 freq, start_freq, end_freq;
 710
 711        start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
 712        end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
 713
 714        for (freq = start_freq; freq <= end_freq; freq += 20) {
 715                c = ieee80211_get_channel(wiphy, freq);
 716                if (!c || c->flags & prohibited_flags)
 717                        return false;
 718        }
 719
 720        return true;
 721}
 722
 723bool cfg80211_chandef_usable(struct wiphy *wiphy,
 724                             const struct cfg80211_chan_def *chandef,
 725                             u32 prohibited_flags)
 726{
 727        struct ieee80211_sta_ht_cap *ht_cap;
 728        struct ieee80211_sta_vht_cap *vht_cap;
 729        u32 width, control_freq, cap;
 730
 731        if (WARN_ON(!cfg80211_chandef_valid(chandef)))
 732                return false;
 733
 734        ht_cap = &wiphy->bands[chandef->chan->band]->ht_cap;
 735        vht_cap = &wiphy->bands[chandef->chan->band]->vht_cap;
 736
 737        control_freq = chandef->chan->center_freq;
 738
 739        switch (chandef->width) {
 740        case NL80211_CHAN_WIDTH_5:
 741                width = 5;
 742                break;
 743        case NL80211_CHAN_WIDTH_10:
 744                prohibited_flags |= IEEE80211_CHAN_NO_10MHZ;
 745                width = 10;
 746                break;
 747        case NL80211_CHAN_WIDTH_20:
 748                if (!ht_cap->ht_supported)
 749                        return false;
 750        case NL80211_CHAN_WIDTH_20_NOHT:
 751                prohibited_flags |= IEEE80211_CHAN_NO_20MHZ;
 752                width = 20;
 753                break;
 754        case NL80211_CHAN_WIDTH_40:
 755                width = 40;
 756                if (!ht_cap->ht_supported)
 757                        return false;
 758                if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
 759                    ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
 760                        return false;
 761                if (chandef->center_freq1 < control_freq &&
 762                    chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
 763                        return false;
 764                if (chandef->center_freq1 > control_freq &&
 765                    chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
 766                        return false;
 767                break;
 768        case NL80211_CHAN_WIDTH_80P80:
 769                cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
 770                if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
 771                        return false;
 772        case NL80211_CHAN_WIDTH_80:
 773                if (!vht_cap->vht_supported)
 774                        return false;
 775                prohibited_flags |= IEEE80211_CHAN_NO_80MHZ;
 776                width = 80;
 777                break;
 778        case NL80211_CHAN_WIDTH_160:
 779                if (!vht_cap->vht_supported)
 780                        return false;
 781                cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
 782                if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
 783                    cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
 784                        return false;
 785                prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
 786                width = 160;
 787                break;
 788        default:
 789                WARN_ON_ONCE(1);
 790                return false;
 791        }
 792
 793        /*
 794         * TODO: What if there are only certain 80/160/80+80 MHz channels
 795         *       allowed by the driver, or only certain combinations?
 796         *       For 40 MHz the driver can set the NO_HT40 flags, but for
 797         *       80/160 MHz and in particular 80+80 MHz this isn't really
 798         *       feasible and we only have NO_80MHZ/NO_160MHZ so far but
 799         *       no way to cover 80+80 MHz or more complex restrictions.
 800         *       Note that such restrictions also need to be advertised to
 801         *       userspace, for example for P2P channel selection.
 802         */
 803
 804        if (width > 20)
 805                prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
 806
 807        /* 5 and 10 MHz are only defined for the OFDM PHY */
 808        if (width < 20)
 809                prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
 810
 811
 812        if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1,
 813                                         width, prohibited_flags))
 814                return false;
 815
 816        if (!chandef->center_freq2)
 817                return true;
 818        return cfg80211_secondary_chans_ok(wiphy, chandef->center_freq2,
 819                                           width, prohibited_flags);
 820}
 821EXPORT_SYMBOL(cfg80211_chandef_usable);
 822
 823/*
 824 * Check if the channel can be used under permissive conditions mandated by
 825 * some regulatory bodies, i.e., the channel is marked with
 826 * IEEE80211_CHAN_IR_CONCURRENT and there is an additional station interface
 827 * associated to an AP on the same channel or on the same UNII band
 828 * (assuming that the AP is an authorized master).
 829 * In addition allow operation on a channel on which indoor operation is
 830 * allowed, iff we are currently operating in an indoor environment.
 831 */
 832static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
 833                                        enum nl80211_iftype iftype,
 834                                        struct ieee80211_channel *chan)
 835{
 836        struct wireless_dev *wdev;
 837        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 838
 839        ASSERT_RTNL();
 840
 841        if (!IS_ENABLED(CONFIG_CFG80211_REG_RELAX_NO_IR) ||
 842            !(wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR))
 843                return false;
 844
 845        /* only valid for GO and TDLS off-channel (station/p2p-CL) */
 846        if (iftype != NL80211_IFTYPE_P2P_GO &&
 847            iftype != NL80211_IFTYPE_STATION &&
 848            iftype != NL80211_IFTYPE_P2P_CLIENT)
 849                return false;
 850
 851        if (regulatory_indoor_allowed() &&
 852            (chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
 853                return true;
 854
 855        if (!(chan->flags & IEEE80211_CHAN_IR_CONCURRENT))
 856                return false;
 857
 858        /*
 859         * Generally, it is possible to rely on another device/driver to allow
 860         * the IR concurrent relaxation, however, since the device can further
 861         * enforce the relaxation (by doing a similar verifications as this),
 862         * and thus fail the GO instantiation, consider only the interfaces of
 863         * the current registered device.
 864         */
 865        list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
 866                struct ieee80211_channel *other_chan = NULL;
 867                int r1, r2;
 868
 869                wdev_lock(wdev);
 870                if (wdev->iftype == NL80211_IFTYPE_STATION &&
 871                    wdev->current_bss)
 872                        other_chan = wdev->current_bss->pub.channel;
 873
 874                /*
 875                 * If a GO already operates on the same GO_CONCURRENT channel,
 876                 * this one (maybe the same one) can beacon as well. We allow
 877                 * the operation even if the station we relied on with
 878                 * GO_CONCURRENT is disconnected now. But then we must make sure
 879                 * we're not outdoor on an indoor-only channel.
 880                 */
 881                if (iftype == NL80211_IFTYPE_P2P_GO &&
 882                    wdev->iftype == NL80211_IFTYPE_P2P_GO &&
 883                    wdev->beacon_interval &&
 884                    !(chan->flags & IEEE80211_CHAN_INDOOR_ONLY))
 885                        other_chan = wdev->chandef.chan;
 886                wdev_unlock(wdev);
 887
 888                if (!other_chan)
 889                        continue;
 890
 891                if (chan == other_chan)
 892                        return true;
 893
 894                if (chan->band != NL80211_BAND_5GHZ)
 895                        continue;
 896
 897                r1 = cfg80211_get_unii(chan->center_freq);
 898                r2 = cfg80211_get_unii(other_chan->center_freq);
 899
 900                if (r1 != -EINVAL && r1 == r2) {
 901                        /*
 902                         * At some locations channels 149-165 are considered a
 903                         * bundle, but at other locations, e.g., Indonesia,
 904                         * channels 149-161 are considered a bundle while
 905                         * channel 165 is left out and considered to be in a
 906                         * different bundle. Thus, in case that there is a
 907                         * station interface connected to an AP on channel 165,
 908                         * it is assumed that channels 149-161 are allowed for
 909                         * GO operations. However, having a station interface
 910                         * connected to an AP on channels 149-161, does not
 911                         * allow GO operation on channel 165.
 912                         */
 913                        if (chan->center_freq == 5825 &&
 914                            other_chan->center_freq != 5825)
 915                                continue;
 916                        return true;
 917                }
 918        }
 919
 920        return false;
 921}
 922
 923static bool _cfg80211_reg_can_beacon(struct wiphy *wiphy,
 924                                     struct cfg80211_chan_def *chandef,
 925                                     enum nl80211_iftype iftype,
 926                                     bool check_no_ir)
 927{
 928        bool res;
 929        u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
 930                               IEEE80211_CHAN_RADAR;
 931
 932        trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
 933
 934        if (check_no_ir)
 935                prohibited_flags |= IEEE80211_CHAN_NO_IR;
 936
 937        if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 &&
 938            cfg80211_chandef_dfs_available(wiphy, chandef)) {
 939                /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */
 940                prohibited_flags = IEEE80211_CHAN_DISABLED;
 941        }
 942
 943        res = cfg80211_chandef_usable(wiphy, chandef, prohibited_flags);
 944
 945        trace_cfg80211_return_bool(res);
 946        return res;
 947}
 948
 949bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
 950                             struct cfg80211_chan_def *chandef,
 951                             enum nl80211_iftype iftype)
 952{
 953        return _cfg80211_reg_can_beacon(wiphy, chandef, iftype, true);
 954}
 955EXPORT_SYMBOL(cfg80211_reg_can_beacon);
 956
 957bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
 958                                   struct cfg80211_chan_def *chandef,
 959                                   enum nl80211_iftype iftype)
 960{
 961        bool check_no_ir;
 962
 963        ASSERT_RTNL();
 964
 965        /*
 966         * Under certain conditions suggested by some regulatory bodies a
 967         * GO/STA can IR on channels marked with IEEE80211_NO_IR. Set this flag
 968         * only if such relaxations are not enabled and the conditions are not
 969         * met.
 970         */
 971        check_no_ir = !cfg80211_ir_permissive_chan(wiphy, iftype,
 972                                                   chandef->chan);
 973
 974        return _cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
 975}
 976EXPORT_SYMBOL(cfg80211_reg_can_beacon_relax);
 977
 978int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
 979                                 struct cfg80211_chan_def *chandef)
 980{
 981        if (!rdev->ops->set_monitor_channel)
 982                return -EOPNOTSUPP;
 983        if (!cfg80211_has_monitors_only(rdev))
 984                return -EBUSY;
 985
 986        return rdev_set_monitor_channel(rdev, chandef);
 987}
 988
 989void
 990cfg80211_get_chan_state(struct wireless_dev *wdev,
 991                        struct ieee80211_channel **chan,
 992                        enum cfg80211_chan_mode *chanmode,
 993                        u8 *radar_detect)
 994{
 995        int ret;
 996
 997        *chan = NULL;
 998        *chanmode = CHAN_MODE_UNDEFINED;
 999
1000        ASSERT_WDEV_LOCK(wdev);
1001
1002        if (wdev->netdev && !netif_running(wdev->netdev))
1003                return;
1004
1005        switch (wdev->iftype) {
1006        case NL80211_IFTYPE_ADHOC:
1007                if (wdev->current_bss) {
1008                        *chan = wdev->current_bss->pub.channel;
1009                        *chanmode = (wdev->ibss_fixed &&
1010                                     !wdev->ibss_dfs_possible)
1011                                  ? CHAN_MODE_SHARED
1012                                  : CHAN_MODE_EXCLUSIVE;
1013
1014                        /* consider worst-case - IBSS can try to return to the
1015                         * original user-specified channel as creator */
1016                        if (wdev->ibss_dfs_possible)
1017                                *radar_detect |= BIT(wdev->chandef.width);
1018                        return;
1019                }
1020                break;
1021        case NL80211_IFTYPE_STATION:
1022        case NL80211_IFTYPE_P2P_CLIENT:
1023                if (wdev->current_bss) {
1024                        *chan = wdev->current_bss->pub.channel;
1025                        *chanmode = CHAN_MODE_SHARED;
1026                        return;
1027                }
1028                break;
1029        case NL80211_IFTYPE_AP:
1030        case NL80211_IFTYPE_P2P_GO:
1031                if (wdev->cac_started) {
1032                        *chan = wdev->chandef.chan;
1033                        *chanmode = CHAN_MODE_SHARED;
1034                        *radar_detect |= BIT(wdev->chandef.width);
1035                } else if (wdev->beacon_interval) {
1036                        *chan = wdev->chandef.chan;
1037                        *chanmode = CHAN_MODE_SHARED;
1038
1039                        ret = cfg80211_chandef_dfs_required(wdev->wiphy,
1040                                                            &wdev->chandef,
1041                                                            wdev->iftype);
1042                        WARN_ON(ret < 0);
1043                        if (ret > 0)
1044                                *radar_detect |= BIT(wdev->chandef.width);
1045                }
1046                return;
1047        case NL80211_IFTYPE_MESH_POINT:
1048                if (wdev->mesh_id_len) {
1049                        *chan = wdev->chandef.chan;
1050                        *chanmode = CHAN_MODE_SHARED;
1051
1052                        ret = cfg80211_chandef_dfs_required(wdev->wiphy,
1053                                                            &wdev->chandef,
1054                                                            wdev->iftype);
1055                        WARN_ON(ret < 0);
1056                        if (ret > 0)
1057                                *radar_detect |= BIT(wdev->chandef.width);
1058                }
1059                return;
1060        case NL80211_IFTYPE_OCB:
1061                if (wdev->chandef.chan) {
1062                        *chan = wdev->chandef.chan;
1063                        *chanmode = CHAN_MODE_SHARED;
1064                        return;
1065                }
1066                break;
1067        case NL80211_IFTYPE_MONITOR:
1068        case NL80211_IFTYPE_AP_VLAN:
1069        case NL80211_IFTYPE_WDS:
1070        case NL80211_IFTYPE_P2P_DEVICE:
1071        case NL80211_IFTYPE_NAN:
1072                /* these interface types don't really have a channel */
1073                return;
1074        case NL80211_IFTYPE_UNSPECIFIED:
1075        case NUM_NL80211_IFTYPES:
1076                WARN_ON(1);
1077        }
1078}
1079