| .. | .. |
|---|
| 6 | 6 | * |
|---|
| 7 | 7 | * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
|---|
| 8 | 8 | * Copyright 2013-2014 Intel Mobile Communications GmbH |
|---|
| 9 | + * Copyright 2018-2020 Intel Corporation |
|---|
| 9 | 10 | */ |
|---|
| 10 | 11 | |
|---|
| 11 | 12 | #include <linux/export.h> |
|---|
| 13 | +#include <linux/bitfield.h> |
|---|
| 12 | 14 | #include <net/cfg80211.h> |
|---|
| 13 | 15 | #include "core.h" |
|---|
| 14 | 16 | #include "rdev-ops.h" |
|---|
| .. | .. |
|---|
| 26 | 28 | return; |
|---|
| 27 | 29 | |
|---|
| 28 | 30 | chandef->chan = chan; |
|---|
| 31 | + chandef->freq1_offset = chan->freq_offset; |
|---|
| 29 | 32 | chandef->center_freq2 = 0; |
|---|
| 30 | 33 | chandef->edmg.bw_config = 0; |
|---|
| 31 | 34 | chandef->edmg.channels = 0; |
|---|
| .. | .. |
|---|
| 138 | 141 | return true; |
|---|
| 139 | 142 | } |
|---|
| 140 | 143 | |
|---|
| 144 | +static int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width) |
|---|
| 145 | +{ |
|---|
| 146 | + int mhz; |
|---|
| 147 | + |
|---|
| 148 | + switch (chan_width) { |
|---|
| 149 | + case NL80211_CHAN_WIDTH_1: |
|---|
| 150 | + mhz = 1; |
|---|
| 151 | + break; |
|---|
| 152 | + case NL80211_CHAN_WIDTH_2: |
|---|
| 153 | + mhz = 2; |
|---|
| 154 | + break; |
|---|
| 155 | + case NL80211_CHAN_WIDTH_4: |
|---|
| 156 | + mhz = 4; |
|---|
| 157 | + break; |
|---|
| 158 | + case NL80211_CHAN_WIDTH_8: |
|---|
| 159 | + mhz = 8; |
|---|
| 160 | + break; |
|---|
| 161 | + case NL80211_CHAN_WIDTH_16: |
|---|
| 162 | + mhz = 16; |
|---|
| 163 | + break; |
|---|
| 164 | + case NL80211_CHAN_WIDTH_5: |
|---|
| 165 | + mhz = 5; |
|---|
| 166 | + break; |
|---|
| 167 | + case NL80211_CHAN_WIDTH_10: |
|---|
| 168 | + mhz = 10; |
|---|
| 169 | + break; |
|---|
| 170 | + case NL80211_CHAN_WIDTH_20: |
|---|
| 171 | + case NL80211_CHAN_WIDTH_20_NOHT: |
|---|
| 172 | + mhz = 20; |
|---|
| 173 | + break; |
|---|
| 174 | + case NL80211_CHAN_WIDTH_40: |
|---|
| 175 | + mhz = 40; |
|---|
| 176 | + break; |
|---|
| 177 | + case NL80211_CHAN_WIDTH_80P80: |
|---|
| 178 | + case NL80211_CHAN_WIDTH_80: |
|---|
| 179 | + mhz = 80; |
|---|
| 180 | + break; |
|---|
| 181 | + case NL80211_CHAN_WIDTH_160: |
|---|
| 182 | + mhz = 160; |
|---|
| 183 | + break; |
|---|
| 184 | + default: |
|---|
| 185 | + WARN_ON_ONCE(1); |
|---|
| 186 | + return -1; |
|---|
| 187 | + } |
|---|
| 188 | + return mhz; |
|---|
| 189 | +} |
|---|
| 190 | + |
|---|
| 191 | +static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c) |
|---|
| 192 | +{ |
|---|
| 193 | + return nl80211_chan_width_to_mhz(c->width); |
|---|
| 194 | +} |
|---|
| 195 | + |
|---|
| 141 | 196 | bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) |
|---|
| 142 | 197 | { |
|---|
| 143 | | - u32 control_freq; |
|---|
| 198 | + u32 control_freq, oper_freq; |
|---|
| 199 | + int oper_width, control_width; |
|---|
| 144 | 200 | |
|---|
| 145 | 201 | if (!chandef->chan) |
|---|
| 202 | + return false; |
|---|
| 203 | + |
|---|
| 204 | + if (chandef->freq1_offset >= 1000) |
|---|
| 146 | 205 | return false; |
|---|
| 147 | 206 | |
|---|
| 148 | 207 | control_freq = chandef->chan->center_freq; |
|---|
| .. | .. |
|---|
| 152 | 211 | case NL80211_CHAN_WIDTH_10: |
|---|
| 153 | 212 | case NL80211_CHAN_WIDTH_20: |
|---|
| 154 | 213 | case NL80211_CHAN_WIDTH_20_NOHT: |
|---|
| 155 | | - if (chandef->center_freq1 != control_freq) |
|---|
| 214 | + if (ieee80211_chandef_to_khz(chandef) != |
|---|
| 215 | + ieee80211_channel_to_khz(chandef->chan)) |
|---|
| 156 | 216 | return false; |
|---|
| 157 | 217 | if (chandef->center_freq2) |
|---|
| 218 | + return false; |
|---|
| 219 | + break; |
|---|
| 220 | + case NL80211_CHAN_WIDTH_1: |
|---|
| 221 | + case NL80211_CHAN_WIDTH_2: |
|---|
| 222 | + case NL80211_CHAN_WIDTH_4: |
|---|
| 223 | + case NL80211_CHAN_WIDTH_8: |
|---|
| 224 | + case NL80211_CHAN_WIDTH_16: |
|---|
| 225 | + if (chandef->chan->band != NL80211_BAND_S1GHZ) |
|---|
| 226 | + return false; |
|---|
| 227 | + |
|---|
| 228 | + control_freq = ieee80211_channel_to_khz(chandef->chan); |
|---|
| 229 | + oper_freq = ieee80211_chandef_to_khz(chandef); |
|---|
| 230 | + control_width = nl80211_chan_width_to_mhz( |
|---|
| 231 | + ieee80211_s1g_channel_width( |
|---|
| 232 | + chandef->chan)); |
|---|
| 233 | + oper_width = cfg80211_chandef_get_width(chandef); |
|---|
| 234 | + |
|---|
| 235 | + if (oper_width < 0 || control_width < 0) |
|---|
| 236 | + return false; |
|---|
| 237 | + if (chandef->center_freq2) |
|---|
| 238 | + return false; |
|---|
| 239 | + |
|---|
| 240 | + if (control_freq + MHZ_TO_KHZ(control_width) / 2 > |
|---|
| 241 | + oper_freq + MHZ_TO_KHZ(oper_width) / 2) |
|---|
| 242 | + return false; |
|---|
| 243 | + |
|---|
| 244 | + if (control_freq - MHZ_TO_KHZ(control_width) / 2 < |
|---|
| 245 | + oper_freq - MHZ_TO_KHZ(oper_width) / 2) |
|---|
| 158 | 246 | return false; |
|---|
| 159 | 247 | break; |
|---|
| 160 | 248 | case NL80211_CHAN_WIDTH_40: |
|---|
| .. | .. |
|---|
| 203 | 291 | return false; |
|---|
| 204 | 292 | } |
|---|
| 205 | 293 | |
|---|
| 294 | + /* channel 14 is only for IEEE 802.11b */ |
|---|
| 295 | + if (chandef->center_freq1 == 2484 && |
|---|
| 296 | + chandef->width != NL80211_CHAN_WIDTH_20_NOHT) |
|---|
| 297 | + return false; |
|---|
| 298 | + |
|---|
| 206 | 299 | if (cfg80211_chandef_is_edmg(chandef) && |
|---|
| 207 | 300 | !cfg80211_edmg_chandef_valid(chandef)) |
|---|
| 208 | 301 | return false; |
|---|
| .. | .. |
|---|
| 245 | 338 | default: |
|---|
| 246 | 339 | WARN_ON_ONCE(1); |
|---|
| 247 | 340 | } |
|---|
| 248 | | -} |
|---|
| 249 | | - |
|---|
| 250 | | -static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c) |
|---|
| 251 | | -{ |
|---|
| 252 | | - int width; |
|---|
| 253 | | - |
|---|
| 254 | | - switch (c->width) { |
|---|
| 255 | | - case NL80211_CHAN_WIDTH_5: |
|---|
| 256 | | - width = 5; |
|---|
| 257 | | - break; |
|---|
| 258 | | - case NL80211_CHAN_WIDTH_10: |
|---|
| 259 | | - width = 10; |
|---|
| 260 | | - break; |
|---|
| 261 | | - case NL80211_CHAN_WIDTH_20: |
|---|
| 262 | | - case NL80211_CHAN_WIDTH_20_NOHT: |
|---|
| 263 | | - width = 20; |
|---|
| 264 | | - break; |
|---|
| 265 | | - case NL80211_CHAN_WIDTH_40: |
|---|
| 266 | | - width = 40; |
|---|
| 267 | | - break; |
|---|
| 268 | | - case NL80211_CHAN_WIDTH_80P80: |
|---|
| 269 | | - case NL80211_CHAN_WIDTH_80: |
|---|
| 270 | | - width = 80; |
|---|
| 271 | | - break; |
|---|
| 272 | | - case NL80211_CHAN_WIDTH_160: |
|---|
| 273 | | - width = 160; |
|---|
| 274 | | - break; |
|---|
| 275 | | - default: |
|---|
| 276 | | - WARN_ON_ONCE(1); |
|---|
| 277 | | - return -1; |
|---|
| 278 | | - } |
|---|
| 279 | | - return width; |
|---|
| 280 | 341 | } |
|---|
| 281 | 342 | |
|---|
| 282 | 343 | const struct cfg80211_chan_def * |
|---|
| .. | .. |
|---|
| 380 | 441 | { |
|---|
| 381 | 442 | u32 start_freq; |
|---|
| 382 | 443 | |
|---|
| 383 | | - if (bandwidth <= 20) |
|---|
| 444 | + bandwidth = MHZ_TO_KHZ(bandwidth); |
|---|
| 445 | + if (bandwidth <= MHZ_TO_KHZ(20)) |
|---|
| 384 | 446 | start_freq = center_freq; |
|---|
| 385 | 447 | else |
|---|
| 386 | | - start_freq = center_freq - bandwidth/2 + 10; |
|---|
| 448 | + start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10); |
|---|
| 387 | 449 | |
|---|
| 388 | 450 | return start_freq; |
|---|
| 389 | 451 | } |
|---|
| .. | .. |
|---|
| 393 | 455 | { |
|---|
| 394 | 456 | u32 end_freq; |
|---|
| 395 | 457 | |
|---|
| 396 | | - if (bandwidth <= 20) |
|---|
| 458 | + bandwidth = MHZ_TO_KHZ(bandwidth); |
|---|
| 459 | + if (bandwidth <= MHZ_TO_KHZ(20)) |
|---|
| 397 | 460 | end_freq = center_freq; |
|---|
| 398 | 461 | else |
|---|
| 399 | | - end_freq = center_freq + bandwidth/2 - 10; |
|---|
| 462 | + end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10); |
|---|
| 400 | 463 | |
|---|
| 401 | 464 | return end_freq; |
|---|
| 402 | 465 | } |
|---|
| .. | .. |
|---|
| 411 | 474 | start_freq = cfg80211_get_start_freq(center_freq, bandwidth); |
|---|
| 412 | 475 | end_freq = cfg80211_get_end_freq(center_freq, bandwidth); |
|---|
| 413 | 476 | |
|---|
| 414 | | - for (freq = start_freq; freq <= end_freq; freq += 20) { |
|---|
| 415 | | - c = ieee80211_get_channel(wiphy, freq); |
|---|
| 477 | + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { |
|---|
| 478 | + c = ieee80211_get_channel_khz(wiphy, freq); |
|---|
| 416 | 479 | if (!c) |
|---|
| 417 | 480 | return -EINVAL; |
|---|
| 418 | 481 | |
|---|
| .. | .. |
|---|
| 443 | 506 | return -EINVAL; |
|---|
| 444 | 507 | |
|---|
| 445 | 508 | ret = cfg80211_get_chans_dfs_required(wiphy, |
|---|
| 446 | | - chandef->center_freq1, |
|---|
| 447 | | - width); |
|---|
| 509 | + ieee80211_chandef_to_khz(chandef), |
|---|
| 510 | + width); |
|---|
| 448 | 511 | if (ret < 0) |
|---|
| 449 | 512 | return ret; |
|---|
| 450 | 513 | else if (ret > 0) |
|---|
| .. | .. |
|---|
| 454 | 517 | return 0; |
|---|
| 455 | 518 | |
|---|
| 456 | 519 | ret = cfg80211_get_chans_dfs_required(wiphy, |
|---|
| 457 | | - chandef->center_freq2, |
|---|
| 458 | | - width); |
|---|
| 520 | + MHZ_TO_KHZ(chandef->center_freq2), |
|---|
| 521 | + width); |
|---|
| 459 | 522 | if (ret < 0) |
|---|
| 460 | 523 | return ret; |
|---|
| 461 | 524 | else if (ret > 0) |
|---|
| .. | .. |
|---|
| 497 | 560 | * DFS_AVAILABLE). Return number of usable channels |
|---|
| 498 | 561 | * (require CAC). Allow DFS and non-DFS channel mix. |
|---|
| 499 | 562 | */ |
|---|
| 500 | | - for (freq = start_freq; freq <= end_freq; freq += 20) { |
|---|
| 501 | | - c = ieee80211_get_channel(wiphy, freq); |
|---|
| 563 | + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { |
|---|
| 564 | + c = ieee80211_get_channel_khz(wiphy, freq); |
|---|
| 502 | 565 | if (!c) |
|---|
| 503 | 566 | return -EINVAL; |
|---|
| 504 | 567 | |
|---|
| .. | .. |
|---|
| 530 | 593 | if (width < 0) |
|---|
| 531 | 594 | return false; |
|---|
| 532 | 595 | |
|---|
| 533 | | - r1 = cfg80211_get_chans_dfs_usable(wiphy, chandef->center_freq1, |
|---|
| 534 | | - width); |
|---|
| 596 | + r1 = cfg80211_get_chans_dfs_usable(wiphy, |
|---|
| 597 | + MHZ_TO_KHZ(chandef->center_freq1), |
|---|
| 598 | + width); |
|---|
| 535 | 599 | |
|---|
| 536 | 600 | if (r1 < 0) |
|---|
| 537 | 601 | return false; |
|---|
| .. | .. |
|---|
| 540 | 604 | case NL80211_CHAN_WIDTH_80P80: |
|---|
| 541 | 605 | WARN_ON(!chandef->center_freq2); |
|---|
| 542 | 606 | r2 = cfg80211_get_chans_dfs_usable(wiphy, |
|---|
| 543 | | - chandef->center_freq2, |
|---|
| 544 | | - width); |
|---|
| 607 | + MHZ_TO_KHZ(chandef->center_freq2), |
|---|
| 608 | + width); |
|---|
| 545 | 609 | if (r2 < 0) |
|---|
| 546 | 610 | return false; |
|---|
| 547 | 611 | break; |
|---|
| .. | .. |
|---|
| 688 | 752 | * If any channel in between is disabled or has not |
|---|
| 689 | 753 | * had gone through CAC return false |
|---|
| 690 | 754 | */ |
|---|
| 691 | | - for (freq = start_freq; freq <= end_freq; freq += 20) { |
|---|
| 692 | | - c = ieee80211_get_channel(wiphy, freq); |
|---|
| 755 | + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { |
|---|
| 756 | + c = ieee80211_get_channel_khz(wiphy, freq); |
|---|
| 693 | 757 | if (!c) |
|---|
| 694 | 758 | return false; |
|---|
| 695 | 759 | |
|---|
| .. | .. |
|---|
| 718 | 782 | if (width < 0) |
|---|
| 719 | 783 | return false; |
|---|
| 720 | 784 | |
|---|
| 721 | | - r = cfg80211_get_chans_dfs_available(wiphy, chandef->center_freq1, |
|---|
| 785 | + r = cfg80211_get_chans_dfs_available(wiphy, |
|---|
| 786 | + MHZ_TO_KHZ(chandef->center_freq1), |
|---|
| 722 | 787 | width); |
|---|
| 723 | 788 | |
|---|
| 724 | 789 | /* If any of channels unavailable for cf1 just return */ |
|---|
| .. | .. |
|---|
| 729 | 794 | case NL80211_CHAN_WIDTH_80P80: |
|---|
| 730 | 795 | WARN_ON(!chandef->center_freq2); |
|---|
| 731 | 796 | r = cfg80211_get_chans_dfs_available(wiphy, |
|---|
| 732 | | - chandef->center_freq2, |
|---|
| 733 | | - width); |
|---|
| 797 | + MHZ_TO_KHZ(chandef->center_freq2), |
|---|
| 798 | + width); |
|---|
| 734 | 799 | break; |
|---|
| 735 | 800 | default: |
|---|
| 736 | 801 | WARN_ON(chandef->center_freq2); |
|---|
| .. | .. |
|---|
| 751 | 816 | start_freq = cfg80211_get_start_freq(center_freq, bandwidth); |
|---|
| 752 | 817 | end_freq = cfg80211_get_end_freq(center_freq, bandwidth); |
|---|
| 753 | 818 | |
|---|
| 754 | | - for (freq = start_freq; freq <= end_freq; freq += 20) { |
|---|
| 755 | | - c = ieee80211_get_channel(wiphy, freq); |
|---|
| 819 | + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { |
|---|
| 820 | + c = ieee80211_get_channel_khz(wiphy, freq); |
|---|
| 756 | 821 | if (!c) |
|---|
| 757 | 822 | return 0; |
|---|
| 758 | 823 | |
|---|
| .. | .. |
|---|
| 784 | 849 | return 0; |
|---|
| 785 | 850 | |
|---|
| 786 | 851 | t1 = cfg80211_get_chans_dfs_cac_time(wiphy, |
|---|
| 787 | | - chandef->center_freq1, |
|---|
| 852 | + MHZ_TO_KHZ(chandef->center_freq1), |
|---|
| 788 | 853 | width); |
|---|
| 789 | 854 | |
|---|
| 790 | 855 | if (!chandef->center_freq2) |
|---|
| 791 | 856 | return t1; |
|---|
| 792 | 857 | |
|---|
| 793 | 858 | t2 = cfg80211_get_chans_dfs_cac_time(wiphy, |
|---|
| 794 | | - chandef->center_freq2, |
|---|
| 859 | + MHZ_TO_KHZ(chandef->center_freq2), |
|---|
| 795 | 860 | width); |
|---|
| 796 | 861 | |
|---|
| 797 | 862 | return max(t1, t2); |
|---|
| .. | .. |
|---|
| 807 | 872 | start_freq = cfg80211_get_start_freq(center_freq, bandwidth); |
|---|
| 808 | 873 | end_freq = cfg80211_get_end_freq(center_freq, bandwidth); |
|---|
| 809 | 874 | |
|---|
| 810 | | - for (freq = start_freq; freq <= end_freq; freq += 20) { |
|---|
| 811 | | - c = ieee80211_get_channel(wiphy, freq); |
|---|
| 875 | + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { |
|---|
| 876 | + c = ieee80211_get_channel_khz(wiphy, freq); |
|---|
| 812 | 877 | if (!c || c->flags & prohibited_flags) |
|---|
| 813 | 878 | return false; |
|---|
| 814 | 879 | } |
|---|
| .. | .. |
|---|
| 877 | 942 | struct ieee80211_sta_vht_cap *vht_cap; |
|---|
| 878 | 943 | struct ieee80211_edmg *edmg_cap; |
|---|
| 879 | 944 | u32 width, control_freq, cap; |
|---|
| 945 | + bool support_80_80 = false; |
|---|
| 880 | 946 | |
|---|
| 881 | 947 | if (WARN_ON(!cfg80211_chandef_valid(chandef))) |
|---|
| 882 | 948 | return false; |
|---|
| .. | .. |
|---|
| 896 | 962 | control_freq = chandef->chan->center_freq; |
|---|
| 897 | 963 | |
|---|
| 898 | 964 | switch (chandef->width) { |
|---|
| 965 | + case NL80211_CHAN_WIDTH_1: |
|---|
| 966 | + width = 1; |
|---|
| 967 | + break; |
|---|
| 968 | + case NL80211_CHAN_WIDTH_2: |
|---|
| 969 | + width = 2; |
|---|
| 970 | + break; |
|---|
| 971 | + case NL80211_CHAN_WIDTH_4: |
|---|
| 972 | + width = 4; |
|---|
| 973 | + break; |
|---|
| 974 | + case NL80211_CHAN_WIDTH_8: |
|---|
| 975 | + width = 8; |
|---|
| 976 | + break; |
|---|
| 977 | + case NL80211_CHAN_WIDTH_16: |
|---|
| 978 | + width = 16; |
|---|
| 979 | + break; |
|---|
| 899 | 980 | case NL80211_CHAN_WIDTH_5: |
|---|
| 900 | 981 | width = 5; |
|---|
| 901 | 982 | break; |
|---|
| .. | .. |
|---|
| 904 | 985 | width = 10; |
|---|
| 905 | 986 | break; |
|---|
| 906 | 987 | case NL80211_CHAN_WIDTH_20: |
|---|
| 907 | | - if (!ht_cap->ht_supported) |
|---|
| 988 | + if (!ht_cap->ht_supported && |
|---|
| 989 | + chandef->chan->band != NL80211_BAND_6GHZ) |
|---|
| 908 | 990 | return false; |
|---|
| 991 | + fallthrough; |
|---|
| 909 | 992 | case NL80211_CHAN_WIDTH_20_NOHT: |
|---|
| 910 | 993 | prohibited_flags |= IEEE80211_CHAN_NO_20MHZ; |
|---|
| 911 | 994 | width = 20; |
|---|
| 912 | 995 | break; |
|---|
| 913 | 996 | case NL80211_CHAN_WIDTH_40: |
|---|
| 914 | 997 | width = 40; |
|---|
| 998 | + if (chandef->chan->band == NL80211_BAND_6GHZ) |
|---|
| 999 | + break; |
|---|
| 915 | 1000 | if (!ht_cap->ht_supported) |
|---|
| 916 | 1001 | return false; |
|---|
| 917 | 1002 | if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || |
|---|
| .. | .. |
|---|
| 925 | 1010 | return false; |
|---|
| 926 | 1011 | break; |
|---|
| 927 | 1012 | case NL80211_CHAN_WIDTH_80P80: |
|---|
| 928 | | - cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; |
|---|
| 929 | | - if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) |
|---|
| 1013 | + cap = vht_cap->cap; |
|---|
| 1014 | + support_80_80 = |
|---|
| 1015 | + (cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) || |
|---|
| 1016 | + (cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ && |
|---|
| 1017 | + cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) || |
|---|
| 1018 | + u32_get_bits(cap, IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) > 1; |
|---|
| 1019 | + if (chandef->chan->band != NL80211_BAND_6GHZ && !support_80_80) |
|---|
| 930 | 1020 | return false; |
|---|
| 1021 | + fallthrough; |
|---|
| 931 | 1022 | case NL80211_CHAN_WIDTH_80: |
|---|
| 932 | | - if (!vht_cap->vht_supported) |
|---|
| 933 | | - return false; |
|---|
| 934 | 1023 | prohibited_flags |= IEEE80211_CHAN_NO_80MHZ; |
|---|
| 935 | 1024 | width = 80; |
|---|
| 1025 | + if (chandef->chan->band == NL80211_BAND_6GHZ) |
|---|
| 1026 | + break; |
|---|
| 1027 | + if (!vht_cap->vht_supported) |
|---|
| 1028 | + return false; |
|---|
| 936 | 1029 | break; |
|---|
| 937 | 1030 | case NL80211_CHAN_WIDTH_160: |
|---|
| 1031 | + prohibited_flags |= IEEE80211_CHAN_NO_160MHZ; |
|---|
| 1032 | + width = 160; |
|---|
| 1033 | + if (chandef->chan->band == NL80211_BAND_6GHZ) |
|---|
| 1034 | + break; |
|---|
| 938 | 1035 | if (!vht_cap->vht_supported) |
|---|
| 939 | 1036 | return false; |
|---|
| 940 | 1037 | cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; |
|---|
| 941 | 1038 | if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ && |
|---|
| 942 | | - cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) |
|---|
| 1039 | + cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ && |
|---|
| 1040 | + !(vht_cap->cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)) |
|---|
| 943 | 1041 | return false; |
|---|
| 944 | | - prohibited_flags |= IEEE80211_CHAN_NO_160MHZ; |
|---|
| 945 | | - width = 160; |
|---|
| 946 | 1042 | break; |
|---|
| 947 | 1043 | default: |
|---|
| 948 | 1044 | WARN_ON_ONCE(1); |
|---|
| .. | .. |
|---|
| 968 | 1064 | prohibited_flags |= IEEE80211_CHAN_NO_OFDM; |
|---|
| 969 | 1065 | |
|---|
| 970 | 1066 | |
|---|
| 971 | | - if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1, |
|---|
| 1067 | + if (!cfg80211_secondary_chans_ok(wiphy, |
|---|
| 1068 | + ieee80211_chandef_to_khz(chandef), |
|---|
| 972 | 1069 | width, prohibited_flags)) |
|---|
| 973 | 1070 | return false; |
|---|
| 974 | 1071 | |
|---|
| 975 | 1072 | if (!chandef->center_freq2) |
|---|
| 976 | 1073 | return true; |
|---|
| 977 | | - return cfg80211_secondary_chans_ok(wiphy, chandef->center_freq2, |
|---|
| 1074 | + return cfg80211_secondary_chans_ok(wiphy, |
|---|
| 1075 | + MHZ_TO_KHZ(chandef->center_freq2), |
|---|
| 978 | 1076 | width, prohibited_flags); |
|---|
| 979 | 1077 | } |
|---|
| 980 | 1078 | EXPORT_SYMBOL(cfg80211_chandef_usable); |
|---|
| .. | .. |
|---|
| 1050 | 1148 | if (chan == other_chan) |
|---|
| 1051 | 1149 | return true; |
|---|
| 1052 | 1150 | |
|---|
| 1053 | | - if (chan->band != NL80211_BAND_5GHZ) |
|---|
| 1151 | + if (chan->band != NL80211_BAND_5GHZ && |
|---|
| 1152 | + chan->band != NL80211_BAND_6GHZ) |
|---|
| 1054 | 1153 | continue; |
|---|
| 1055 | 1154 | |
|---|
| 1056 | 1155 | r1 = cfg80211_get_unii(chan->center_freq); |
|---|