From 3290a9818c538b88d4e75b5891fa530e9142c219 Mon Sep 17 00:00:00 2001 From: Veerendranath Jakkam Date: Fri, 28 Aug 2020 08:48:22 +0530 Subject: [PATCH] BACKPORT: cfg80211: Squash of all 6GHz changes Add support for Wi-Fi 6GHz band. squash of commits listed below. ad8b601 BACKPORT: cfg80211: express channels with a KHz component 666ce0c BACKPORT: cfg80211: fix 6 GHz frequencies to kHz a4d60a7 BACKPORT: cfg80211: adapt to new channelization of the 6GHz band 2ed68ba BACKPORT: cfg80211: add a helper to identify 6 GHz PSCs 6f5ad8f BACKPORT: ieee80211: add code to obtain and parse 6 GHz operation field e66b8b1c BACKPORT: ieee80211: add HE ext EIDs and 6 GHz capability defines bc79097 BACKPORT: cfg80211: handle 6 GHz capability of new station e3a7357 BACKPORT: cfg80211: add and expose HE 6 GHz band capabilities b8318c9 BACKPORT: mac80211: add HE 6 GHz Band Capability element df67878 BACKPORT: mac80211: Add HE 6GHz capabilities element to probe request 0403f9c BACKPORT: cfg80211: treat 6 GHz channels as valid regardless of capability 92a570f BACKPORT: cfg80211: reject HT/VHT capabilities on 6 GHz band dd5425c BACKPORT: cfg80211: require HE capabilities for 6 GHz band CRs-Fixed: 2760276 Change-Id: Icecbe2587aba927dcb83bc4a574249dbe408d311 Signed-off-by: Vamsi Krishna Signed-off-by: Raghavendra Rao Ananta Git-commit: 934f4c7dd3a544bb8000f7436f1f0e12e04ebc37 Git-commit: 5e9cf0f0a3e98992184442de24253fe1b9c40f2e Git-commit: d1a1646c0de7b0083d42a1ada72a3ec243bfcc6d Git-commit: afbc9c9e8bfe71e8bd12a8c01bedd969fbab8f0e Git-commit: 821273a5a502eebaae005557907d122d1e9b7b98 Git-commit: 8b30808d9be4183fab17f0b0e68eea88c94ff15a Git-commit: 43e64bf301fd8c54f0082d91c6ffd4de861baf96 Git-commit: 223952177296c34d9c8de9cde33204caffe55725 Git-commit: 24a2042cb22fdfc7feef0df9622f0d9d71b8ced1 Git-commit: 2ad2274c58ee2dcaf9ccde5c63ff30f59b138f77 Git-commit: ba8f6a037f790147438173029799f54c9d3065f2 Git-commit: 461ce35d5535c1479384f67fcf4bfc3f3610edca Git-commit: f438136528482f98535889c9a6f99bbacdd92870 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git Signed-off-by: Veerendranath Jakkam --- android/abi_gki_aarch64_3f413d0ec7.xml | 3953 ++++++++++-------------- android/abi_gki_aarch64_qcom | 4 +- include/linux/ieee80211.h | 80 +- include/net/cfg80211.h | 132 +- include/uapi/linux/nl80211.h | 8 + net/mac80211/ieee80211_i.h | 4 +- net/mac80211/mesh.c | 9 + net/mac80211/mesh.h | 2 + net/mac80211/mesh_plink.c | 4 +- net/mac80211/mlme.c | 3 + net/mac80211/scan.c | 17 +- net/mac80211/util.c | 74 +- net/wireless/chan.c | 90 +- net/wireless/core.c | 17 +- net/wireless/nl80211.c | 27 +- net/wireless/reg.c | 40 +- net/wireless/scan.c | 4 +- net/wireless/trace.h | 21 +- net/wireless/util.c | 38 +- 19 files changed, 2170 insertions(+), 2357 deletions(-) diff --git a/android/abi_gki_aarch64_3f413d0ec7.xml b/android/abi_gki_aarch64_3f413d0ec7.xml index 85b9c6003714..757d6a0d1993 100644 --- a/android/abi_gki_aarch64_3f413d0ec7.xml +++ b/android/abi_gki_aarch64_3f413d0ec7.xml @@ -20,9 +20,9 @@ - - - + + + @@ -315,33 +315,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1174,8 +1174,8 @@ - - + + @@ -1872,7 +1872,7 @@ - + @@ -2634,10 +2634,10 @@ - - - - + + + + @@ -21836,11 +21836,11 @@ - - - - - + + + + + @@ -21893,10 +21893,10 @@ - - - - + + + + @@ -21938,39 +21938,39 @@ - - - - - - + + + + + + - - - - - + + + + + - - - - + + + + - - + + - - - - + + + + @@ -30210,57 +30210,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -30272,14 +30221,6 @@ - - - - - - - - @@ -31034,14 +30975,6 @@ - - - - - - - - @@ -33229,7 +33162,7 @@ - + @@ -39059,7 +38992,7 @@ - + @@ -39067,7 +39000,7 @@ - + @@ -39731,10 +39664,10 @@ - + - + @@ -41331,7 +41264,7 @@ - + @@ -41339,7 +41272,7 @@ - + @@ -48651,7 +48584,7 @@ - + @@ -49401,7 +49334,7 @@ - + @@ -49442,7 +49375,7 @@ - + @@ -49813,7 +49746,7 @@ - + @@ -49841,7 +49774,6 @@ - @@ -49850,7 +49782,6 @@ - @@ -50041,7 +49972,7 @@ - + @@ -50075,23 +50006,6 @@ - - - - - - - - - - - - - - - - - @@ -50767,7 +50681,7 @@ - + @@ -50813,93 +50727,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -51009,17 +50836,6 @@ - - - - - - - - - - - @@ -51280,10 +51096,10 @@ - + - + @@ -52333,7 +52149,7 @@ - + @@ -52350,7 +52166,7 @@ - + @@ -52517,10 +52333,10 @@ - + - + @@ -52533,10 +52349,10 @@ - + - + @@ -53449,7 +53265,7 @@ - + @@ -53597,13 +53413,13 @@ - + - + @@ -56248,7 +56064,7 @@ - + @@ -56989,7 +56805,7 @@ - + @@ -57039,7 +56855,7 @@ - + @@ -57069,7 +56885,7 @@ - + @@ -57081,7 +56897,7 @@ - + @@ -59193,7 +59009,7 @@ - + @@ -59671,7 +59487,7 @@ - + @@ -61395,7 +61211,7 @@ - + @@ -61412,7 +61228,7 @@ - + @@ -61468,7 +61284,7 @@ - + @@ -61504,7 +61320,7 @@ - + @@ -65278,7 +65094,7 @@ - + @@ -67904,7 +67720,7 @@ - + @@ -67931,7 +67747,7 @@ - + @@ -68155,7 +67971,7 @@ - + @@ -68166,7 +67982,7 @@ - + @@ -69155,10 +68971,10 @@ - + - + @@ -69185,7 +69001,7 @@ - + @@ -69442,7 +69258,7 @@ - + @@ -70200,7 +70016,7 @@ - + @@ -70208,7 +70024,7 @@ - + @@ -73792,14 +73608,6 @@ - - - - - - - - @@ -76554,7 +76362,7 @@ - + @@ -76570,7 +76378,7 @@ - + @@ -76654,7 +76462,7 @@ - + @@ -77467,8 +77275,8 @@ - - + + @@ -77482,7 +77290,7 @@ - + @@ -78346,7 +78154,7 @@ - + @@ -78393,7 +78201,7 @@ - + @@ -78441,10 +78249,10 @@ - + - + @@ -79571,7 +79379,7 @@ - + @@ -79592,7 +79400,7 @@ - + @@ -80473,7 +80281,7 @@ - + @@ -80502,7 +80310,7 @@ - + @@ -81239,7 +81047,7 @@ - + @@ -81252,7 +81060,7 @@ - + @@ -81362,7 +81170,7 @@ - + @@ -81469,12 +81277,15 @@ - + - + - + + + + @@ -81499,12 +81310,12 @@ - - - - - - + + + + + + @@ -81805,7 +81616,7 @@ - + @@ -86497,7 +86308,7 @@ - + @@ -86508,7 +86319,7 @@ - + @@ -86599,10 +86410,10 @@ - + - + @@ -86647,7 +86458,7 @@ - + @@ -86988,7 +86799,7 @@ - + @@ -87001,7 +86812,7 @@ - + @@ -87015,7 +86826,7 @@ - + @@ -87140,7 +86951,7 @@ - + @@ -87250,7 +87061,7 @@ - + @@ -87268,12 +87079,12 @@ - + - + - + @@ -87290,7 +87101,7 @@ - + @@ -87320,7 +87131,7 @@ - + @@ -87392,6 +87203,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -87409,6 +87324,17 @@ + + + + + + + + + + + @@ -87597,6 +87523,9 @@ + + + @@ -87661,7 +87590,7 @@ - + @@ -87688,7 +87617,7 @@ - + @@ -87696,7 +87625,7 @@ - + @@ -88050,7 +87979,14 @@ + + + + + + + @@ -88070,7 +88006,7 @@ - + @@ -88095,61 +88031,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -88564,486 +88445,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -89058,46 +88461,31 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - + + + + @@ -89175,16 +88563,6 @@ - - - - - - - - - - @@ -89195,11 +88573,6 @@ - - - - - @@ -89233,6 +88606,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -89325,7 +88739,7 @@ - + @@ -89493,8 +88907,8 @@ - - + + @@ -89627,7 +89041,7 @@ - + @@ -89672,7 +89086,7 @@ - + @@ -89966,7 +89380,7 @@ - + @@ -90311,7 +89725,7 @@ - + @@ -90322,7 +89736,7 @@ - + @@ -90497,7 +89911,7 @@ - + @@ -90562,612 +89976,612 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -91175,132 +90589,132 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -91329,36 +90743,36 @@ - + - + - + - + - + - + - + - + - + - + @@ -91398,144 +90812,150 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + @@ -91546,15 +90966,15 @@ - + - + - + - + @@ -91583,81 +91003,81 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -91674,15 +91094,15 @@ - + - + - + - + @@ -91699,26 +91119,29 @@ - + - + - + + + + - + - + - + - + - + @@ -91749,6 +91172,11 @@ + + + + + @@ -91781,20 +91209,20 @@ - + - + - + @@ -91913,57 +91341,57 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -91972,7 +91400,7 @@ - + @@ -91991,599 +91419,599 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -92597,7 +92025,7 @@ - + @@ -92605,165 +92033,168 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + @@ -92772,506 +92203,506 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -93279,302 +92710,302 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -93583,172 +93014,172 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -93756,18 +93187,18 @@ - + - + - + - + - + @@ -93775,175 +93206,175 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -93951,207 +93382,207 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -94210,6 +93641,8 @@ + + @@ -94367,19 +93800,19 @@ - - + + - - + + - + @@ -95033,7 +94466,7 @@ - + @@ -95066,7 +94499,7 @@ - + @@ -95074,7 +94507,7 @@ - + @@ -95085,9 +94518,9 @@ - + - + @@ -95096,7 +94529,7 @@ - + @@ -95104,10 +94537,10 @@ - + - + @@ -95139,7 +94572,7 @@ - + @@ -95163,7 +94596,7 @@ - + @@ -95171,7 +94604,7 @@ - + @@ -95214,7 +94647,7 @@ - + @@ -95222,7 +94655,7 @@ - + @@ -95378,7 +94811,7 @@ - + @@ -95669,147 +95102,148 @@ - - - + + + + - + - + - + - + - + - + - - - - - - - - - + + + + + + + + + - - - + + + - - - - - + + + + + - - + + - - - - + + + + - - - - - - + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - - - + + + + + + + - - - - - + + + + + - - - - - - + + + + + + - - - + + + - - - - - - + + + + + + - - - + + + - - - - + + + + - - - - + + + + - + @@ -95817,12 +95251,12 @@ - - - + + + - + @@ -95830,39 +95264,39 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -95893,40 +95327,40 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -95940,12 +95374,12 @@ - + - + @@ -95956,7 +95390,7 @@ - + @@ -95970,7 +95404,7 @@ - + @@ -95984,12 +95418,12 @@ - + - + @@ -96003,12 +95437,12 @@ - + - + @@ -96022,29 +95456,29 @@ - + - + - + - + - + - + - + - + @@ -96083,7 +95517,7 @@ - + @@ -96097,7 +95531,7 @@ - + @@ -96105,7 +95539,7 @@ - + @@ -96130,7 +95564,7 @@ - + @@ -96161,7 +95595,7 @@ - + @@ -96427,89 +95861,89 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -96545,7 +95979,7 @@ - + @@ -96569,9 +96003,9 @@ - + - + @@ -96580,7 +96014,7 @@ - + @@ -96588,10 +96022,10 @@ - + - + @@ -96688,21 +96122,21 @@ - - + + - - - + + + - - + + - - + + @@ -96739,10 +96173,10 @@ - + - + @@ -97162,10 +96596,10 @@ - + - + @@ -97184,6 +96618,14 @@ + + + + + + + + @@ -97405,7 +96847,7 @@ - + @@ -97415,21 +96857,21 @@ - + - + - + - + - + @@ -97440,7 +96882,7 @@ - + @@ -97451,7 +96893,7 @@ - + @@ -97496,22 +96938,22 @@ - + - + - + - + - + @@ -97519,7 +96961,7 @@ - + @@ -97527,7 +96969,7 @@ - + @@ -97535,7 +96977,7 @@ - + @@ -98791,7 +98233,7 @@ - + @@ -98908,10 +98350,10 @@ - + - + @@ -100228,7 +99670,7 @@ - + @@ -101431,7 +100873,7 @@ - + @@ -101826,7 +101268,7 @@ - + @@ -101901,3 +101343,8 @@ + + diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index 93117099aa7c..4cc9f34b1551 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -1082,8 +1082,8 @@ idr_preload idr_remove idr_replace - ieee80211_frequency_to_channel - ieee80211_get_channel + ieee80211_freq_khz_to_channel + ieee80211_get_channel_khz ieee80211_hdrlen iget5_locked igrab diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 624d2643bfba..a04858644ca1 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -2060,6 +2060,28 @@ ieee80211_he_ppe_size(u8 ppe_thres_hdr, const u8 *phy_cap_info) #define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR 0x40000000 #define IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED 0x80000000 +/** + * ieee80211_he_6ghz_oper - HE 6 GHz operation Information field + * @primary: primary channel + * @control: control flags + * @ccfs0: channel center frequency segment 0 + * @ccfs1: channel center frequency segment 1 + * @minrate: minimum rate (in 1 Mbps units) + */ +struct ieee80211_he_6ghz_oper { + u8 primary; +#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH 0x3 +#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ 0 +#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ 1 +#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ 2 +#define IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ 3 +#define IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON 0x4 + u8 control; + u8 ccfs0; + u8 ccfs1; + u8 minrate; +} __packed; + /* * ieee80211_he_oper_size - calculate 802.11ax HE Operations IE size * @he_oper_ie: byte data of the He Operations IE, stating from the the byte @@ -2086,7 +2108,7 @@ ieee80211_he_oper_size(const u8 *he_oper_ie) if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS) oper_len++; if (he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO) - oper_len += 4; + oper_len += sizeof(struct ieee80211_he_6ghz_oper); /* Add the first byte (extension ID) to the total length */ oper_len++; @@ -2094,6 +2116,34 @@ ieee80211_he_oper_size(const u8 *he_oper_ie) return oper_len; } +/** + * ieee80211_he_6ghz_oper - obtain 6 GHz operation field + * @he_oper: HE operation element (must be pre-validated for size) + * but may be %NULL + * + * Return: a pointer to the 6 GHz operation field, or %NULL + */ +static inline const struct ieee80211_he_6ghz_oper * +ieee80211_he_6ghz_oper(const struct ieee80211_he_operation *he_oper) +{ + const u8 *ret = (void *)&he_oper->optional; + u32 he_oper_params; + + if (!he_oper) + return NULL; + + he_oper_params = le32_to_cpu(he_oper->he_oper_params); + + if (!(he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO)) + return NULL; + if (he_oper_params & IEEE80211_HE_OPERATION_VHT_OPER_INFO) + ret += 3; + if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS) + ret++; + + return (void *)ret; +} + /* HE Spatial Reuse defines */ #define IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT 0x4 #define IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT 0x8 @@ -2553,9 +2603,19 @@ enum ieee80211_eid_ext { WLAN_EID_EXT_UORA = 37, WLAN_EID_EXT_HE_MU_EDCA = 38, WLAN_EID_EXT_HE_SPR = 39, + WLAN_EID_EXT_NDP_FEEDBACK_REPORT_PARAMSET = 41, + WLAN_EID_EXT_BSS_COLOR_CHG_ANN = 42, + WLAN_EID_EXT_QUIET_TIME_PERIOD_SETUP = 43, + WLAN_EID_EXT_ESS_REPORT = 45, + WLAN_EID_EXT_OPS = 46, + WLAN_EID_EXT_HE_BSS_LOAD = 47, WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME = 52, WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION = 55, WLAN_EID_EXT_NON_INHERITANCE = 56, + WLAN_EID_EXT_KNOWN_BSSID = 57, + WLAN_EID_EXT_SHORT_SSID_LIST = 58, + WLAN_EID_EXT_HE_6GHZ_CAPA = 59, + WLAN_EID_EXT_UL_MU_POWER_CAPA = 60, }; /* Action category code */ @@ -3097,6 +3157,24 @@ struct ieee80211_tspec_ie { __le16 medium_time; } __packed; +struct ieee80211_he_6ghz_capa { + /* uses IEEE80211_HE_6GHZ_CAP_* below */ + __le16 capa; +} __packed; + +/* HE 6 GHz band capabilities */ +/* uses enum ieee80211_min_mpdu_spacing values */ +#define IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START 0x0007 +/* uses enum ieee80211_vht_max_ampdu_length_exp values */ +#define IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP 0x0038 +/* uses IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_* values */ +#define IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN 0x00c0 +/* WLAN_HT_CAP_SM_PS_* values */ +#define IEEE80211_HE_6GHZ_CAP_SM_PS 0x0600 +#define IEEE80211_HE_6GHZ_CAP_RD_RESPONDER 0x0800 +#define IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS 0x1000 +#define IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS 0x2000 + /** * ieee80211_get_qos_ctl - get pointer to qos control bytes * @hdr: the frame diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 4482aa9adb68..152d47c0577a 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -132,6 +132,7 @@ enum ieee80211_channel_flags { * with cfg80211. * * @center_freq: center frequency in MHz + * @freq_offset: offset from @center_freq, in KHz * @hw_value: hardware-specific value for the channel * @flags: channel flags from &enum ieee80211_channel_flags. * @orig_flags: channel flags at registration time, used by regulatory @@ -153,6 +154,7 @@ enum ieee80211_channel_flags { struct ieee80211_channel { enum nl80211_band band; u32 center_freq; + u16 freq_offset; u16 hw_value; u32 flags; int max_antenna_gain; @@ -343,10 +345,13 @@ struct ieee80211_sta_he_cap { * * @types_mask: interface types mask * @he_cap: holds the HE capabilities + * @he_6ghz_capa: HE 6 GHz capabilities, must be filled in for a + * 6 GHz band channel (and 0 may be valid value). */ struct ieee80211_sband_iftype_data { u16 types_mask; struct ieee80211_sta_he_cap he_cap; + struct ieee80211_he_6ghz_capa he_6ghz_capa; }; /** @@ -498,6 +503,26 @@ ieee80211_get_he_sta_cap(const struct ieee80211_supported_band *sband) return ieee80211_get_he_iftype_cap(sband, NL80211_IFTYPE_STATION); } +/** + * ieee80211_get_he_6ghz_capa - return HE 6 GHz capabilities + * @sband: the sband to search for the STA on + * @iftype: the iftype to search for + * + * Return: the 6GHz capabilities + */ +static inline __le16 +ieee80211_get_he_6ghz_capa(const struct ieee80211_supported_band *sband, + enum nl80211_iftype iftype) +{ + const struct ieee80211_sband_iftype_data *data = + ieee80211_get_sband_iftype_data(sband, iftype); + + if (WARN_ON(!data || !data->he_cap.has_he)) + return 0; + + return data->he_6ghz_capa.capa; +} + /** * wiphy_read_of_freq_limits - read frequency limits from device tree * @@ -608,6 +633,7 @@ struct key_params { * If edmg is requested (i.e. the .channels member is non-zero), * chan will define the primary channel and all other * parameters are ignored. + * @freq1_offset: offset from @center_freq1, in KHz */ struct cfg80211_chan_def { struct ieee80211_channel *chan; @@ -615,6 +641,7 @@ struct cfg80211_chan_def { u32 center_freq1; u32 center_freq2; struct ieee80211_edmg edmg; + u16 freq1_offset; }; /** @@ -697,6 +724,7 @@ cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1, return (chandef1->chan == chandef2->chan && chandef1->width == chandef2->width && chandef1->center_freq1 == chandef2->center_freq1 && + chandef1->freq1_offset == chandef2->freq1_offset && chandef1->center_freq2 == chandef2->center_freq2); } @@ -1203,6 +1231,7 @@ struct sta_txpwr { * @he_capa: HE capabilities of station * @he_capa_len: the length of the HE capabilities * @airtime_weight: airtime scheduler weight for this station + * @he_6ghz_capa: HE 6 GHz Band capabilities of station */ struct station_parameters { const u8 *supported_rates; @@ -1235,6 +1264,7 @@ struct station_parameters { u8 he_capa_len; u16 airtime_weight; struct sta_txpwr txpwr; + const struct ieee80211_he_6ghz_capa *he_6ghz_capa; }; /** @@ -5123,30 +5153,107 @@ static inline void *wdev_priv(struct wireless_dev *wdev) * cfg80211 offers a number of utility functions that can be useful. */ +/** + * ieee80211_channel_equal - compare two struct ieee80211_channel + * + * @a: 1st struct ieee80211_channel + * @b: 2nd struct ieee80211_channel + * Return: true if center frequency of @a == @b + */ +static inline bool +ieee80211_channel_equal(struct ieee80211_channel *a, + struct ieee80211_channel *b) +{ + return (a->center_freq == b->center_freq && + a->freq_offset == b->freq_offset); +} + +/** + * ieee80211_channel_to_khz - convert ieee80211_channel to frequency in KHz + * @chan: struct ieee80211_channel to convert + * Return: The corresponding frequency (in KHz) + */ +static inline u32 +ieee80211_channel_to_khz(const struct ieee80211_channel *chan) +{ + return MHZ_TO_KHZ(chan->center_freq) + chan->freq_offset; +} + +/** + * ieee80211_channel_to_freq_khz - convert channel number to frequency + * @chan: channel number + * @band: band, necessary due to channel number overlap + * Return: The corresponding frequency (in KHz), or 0 if the conversion failed. + */ +u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band); + /** * ieee80211_channel_to_frequency - convert channel number to frequency * @chan: channel number * @band: band, necessary due to channel number overlap * Return: The corresponding frequency (in MHz), or 0 if the conversion failed. */ -int ieee80211_channel_to_frequency(int chan, enum nl80211_band band); +static inline int +ieee80211_channel_to_frequency(int chan, enum nl80211_band band) +{ + return KHZ_TO_MHZ(ieee80211_channel_to_freq_khz(chan, band)); +} + +/** + * ieee80211_freq_khz_to_channel - convert frequency to channel number + * @freq: center frequency in KHz + * Return: The corresponding channel, or 0 if the conversion failed. + */ +int ieee80211_freq_khz_to_channel(u32 freq); /** * ieee80211_frequency_to_channel - convert frequency to channel number - * @freq: center frequency + * @freq: center frequency in MHz * Return: The corresponding channel, or 0 if the conversion failed. */ -int ieee80211_frequency_to_channel(int freq); +static inline int +ieee80211_frequency_to_channel(int freq) +{ + return ieee80211_freq_khz_to_channel(MHZ_TO_KHZ(freq)); +} + +/** + * ieee80211_get_channel_khz - get channel struct from wiphy for specified + * frequency + * @wiphy: the struct wiphy to get the channel for + * @freq: the center frequency (in KHz) of the channel + * Return: The channel struct from @wiphy at @freq. + */ +struct ieee80211_channel * +ieee80211_get_channel_khz(struct wiphy *wiphy, u32 freq); /** * ieee80211_get_channel - get channel struct from wiphy for specified frequency * * @wiphy: the struct wiphy to get the channel for - * @freq: the center frequency of the channel - * + * @freq: the center frequency (in MHz) of the channel * Return: The channel struct from @wiphy at @freq. */ -struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq); +static inline struct ieee80211_channel * +ieee80211_get_channel(struct wiphy *wiphy, int freq) +{ + return ieee80211_get_channel_khz(wiphy, MHZ_TO_KHZ(freq)); +} + +/** + * cfg80211_channel_is_psc - Check if the channel is a 6 GHz PSC + * @chan: control channel to check + * + * The Preferred Scanning Channels (PSC) are defined in + * Draft IEEE P802.11ax/D5.0, 26.17.2.3.3 + */ +static inline bool cfg80211_channel_is_psc(struct ieee80211_channel *chan) +{ + if (chan->band != NL80211_BAND_6GHZ) + return false; + + return ieee80211_frequency_to_channel(chan->center_freq) % 16 == 5; +} /** * ieee80211_get_response_rate - get basic rate for a given rate @@ -7170,6 +7277,19 @@ bool ieee80211_operating_class_to_band(u8 operating_class, bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef, u8 *op_class); +/** + * ieee80211_chandef_to_khz - convert chandef to frequency in KHz + * + * @chandef: the chandef to convert + * + * Returns the center frequency of chandef (1st segment) in KHz. + */ +static inline u32 +ieee80211_chandef_to_khz(const struct cfg80211_chan_def *chandef) +{ + return MHZ_TO_KHZ(chandef->center_freq1) + chandef->freq1_offset; +} + /* * cfg80211_tdls_oper_request - request userspace to perform TDLS operation * @dev: the device on which the operation is requested diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 1afbde36ddba..05e7a411cfa0 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2462,6 +2462,9 @@ enum nl80211_commands { * no roaming occurs between the reauth threshold and PMK expiration, * disassociation is still forced. * + * @NL80211_ATTR_HE_6GHZ_CAPABILITY: HE 6 GHz Band Capability element (from + * association request when used with NL80211_CMD_NEW_STATION). + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -2937,6 +2940,8 @@ enum nl80211_attrs { NL80211_ATTR_PMK_LIFETIME, NL80211_ATTR_PMK_REAUTH_THRESHOLD, + NL80211_ATTR_HE_6GHZ_CAPABILITY, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -3515,6 +3520,8 @@ enum nl80211_mpath_info { * defined in HE capabilities IE * @NL80211_BAND_IFTYPE_ATTR_MAX: highest band HE capability attribute currently * defined + * @NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA: HE 6GHz band capabilities (__le16), + * given for all 6 GHz band channels * @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use */ enum nl80211_band_iftype_attr { @@ -3525,6 +3532,7 @@ enum nl80211_band_iftype_attr { NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE, + NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, /* keep last */ __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST, diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 05406e9c05b3..e79cf1f7b0b4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2109,7 +2109,7 @@ enum { IEEE80211_PROBE_FLAG_RANDOM_SN = BIT(2), }; -int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, +int ieee80211_build_preq_ies(struct ieee80211_sub_if_data *sdata, u8 *buffer, size_t buffer_len, struct ieee80211_scan_ies *ie_desc, const u8 *ie, size_t ie_len, @@ -2149,6 +2149,8 @@ u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata, u8 iftype); u8 *ieee80211_ie_build_he_cap(u8 *pos, const struct ieee80211_sta_he_cap *he_cap, u8 *end); +void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb); u8 *ieee80211_ie_build_he_oper(u8 *pos); int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef, const struct ieee80211_supported_band *sband, diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 36978a0e5000..4d7d23e47829 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -587,6 +587,13 @@ int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata, return 0; } +int mesh_add_he_6ghz_cap_ie(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb) +{ + ieee80211_ie_build_he_6ghz_cap(sdata, skb); + return 0; +} + static void ieee80211_mesh_path_timer(struct timer_list *t) { struct ieee80211_sub_if_data *sdata = @@ -766,6 +773,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) 2 + sizeof(struct ieee80211_vht_operation) + ie_len_he_cap + 2 + 1 + sizeof(struct ieee80211_he_operation) + + 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) + ifmsh->ie_len; bcn = kzalloc(sizeof(*bcn) + head_len + tail_len, GFP_KERNEL); @@ -885,6 +893,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) mesh_add_vht_oper_ie(sdata, skb) || mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) || mesh_add_he_oper_ie(sdata, skb) || + mesh_add_he_6ghz_cap_ie(sdata, skb) || mesh_add_vendor_ies(sdata, skb)) goto out_free; diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 953f720754e8..40492d1bd8fd 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -222,6 +222,8 @@ int mesh_add_he_cap_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, u8 ie_len); int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); +int mesh_add_he_6ghz_cap_ie(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb); void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); void ieee80211s_init(void); diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 737c5f4dbf52..3aca89c97f36 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -238,6 +238,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 2 + sizeof(struct ieee80211_vht_operation) + ie_len_he_cap + 2 + 1 + sizeof(struct ieee80211_he_operation) + + 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) + 2 + 8 + /* peering IE */ sdata->u.mesh.ie_len); if (!skb) @@ -328,7 +329,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, mesh_add_vht_cap_ie(sdata, skb) || mesh_add_vht_oper_ie(sdata, skb) || mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) || - mesh_add_he_oper_ie(sdata, skb)) + mesh_add_he_oper_ie(sdata, skb) || + mesh_add_he_6ghz_cap_ie(sdata, skb)) goto free; } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 17a3a1c938be..7820615aa9b7 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -633,6 +633,8 @@ static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata, he_cap->he_cap_elem.phy_cap_info); pos = skb_put(skb, he_cap_size); ieee80211_ie_build_he_cap(pos, he_cap, pos + he_cap_size); + + ieee80211_ie_build_he_6ghz_cap(sdata, skb); } static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) @@ -699,6 +701,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) 2 + 1 + sizeof(struct ieee80211_he_cap_elem) + /* HE */ sizeof(struct ieee80211_he_mcs_nss_supp) + IEEE80211_HE_PPE_THRES_MAX_LEN + + 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) + assoc_data->ie_len + /* extra IEs */ (assoc_data->fils_kek_len ? 16 /* AES-SIV */ : 0) + 9, /* WMM */ diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 4d31d9688dc2..b8ac4df119d5 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -307,8 +307,9 @@ ieee80211_prepare_scan_chandef(struct cfg80211_chan_def *chandef, } /* return false if no more work */ -static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) +static bool ieee80211_prep_hw_scan(struct ieee80211_sub_if_data *sdata) { + struct ieee80211_local *local = sdata->local; struct cfg80211_scan_request *req; struct cfg80211_chan_def chandef; u8 bands_used = 0; @@ -355,7 +356,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) if (req->flags & NL80211_SCAN_FLAG_MIN_PREQ_CONTENT) flags |= IEEE80211_PROBE_FLAG_MIN_CONTENT; - ielen = ieee80211_build_preq_ies(local, + ielen = ieee80211_build_preq_ies(sdata, (u8 *)local->hw_scan_req->req.ie, local->hw_scan_ies_bufsize, &local->hw_scan_req->ies, @@ -395,9 +396,12 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) if (WARN_ON(!local->scan_req)) return; + scan_sdata = rcu_dereference_protected(local->scan_sdata, + lockdep_is_held(&local->mtx)); + if (hw_scan && !aborted && !ieee80211_hw_check(&local->hw, SINGLE_SCAN_ON_ALL_BANDS) && - ieee80211_prep_hw_scan(local)) { + ieee80211_prep_hw_scan(scan_sdata)) { int rc; rc = drv_hw_scan(local, @@ -426,9 +430,6 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) cfg80211_scan_done(scan_req, &local->scan_info); } RCU_INIT_POINTER(local->scan_req, NULL); - - scan_sdata = rcu_dereference_protected(local->scan_sdata, - lockdep_is_held(&local->mtx)); RCU_INIT_POINTER(local->scan_sdata, NULL); local->scanning = 0; @@ -770,7 +771,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, ieee80211_recalc_idle(local); if (hw_scan) { - WARN_ON(!ieee80211_prep_hw_scan(local)); + WARN_ON(!ieee80211_prep_hw_scan(sdata)); rc = drv_hw_scan(local, sdata, local->hw_scan_req); } else { rc = ieee80211_start_sw_scan(local, sdata); @@ -1267,7 +1268,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, ieee80211_prepare_scan_chandef(&chandef, req->scan_width); - ieee80211_build_preq_ies(local, ie, num_bands * iebufsz, + ieee80211_build_preq_ies(sdata, ie, num_bands * iebufsz, &sched_scan_ies, req->ie, req->ie_len, bands_used, rate_masks, &chandef, flags); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index decd46b38393..a27f7aa3f9c9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1630,7 +1630,20 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, } } -static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, +static u8 *ieee80211_write_he_6ghz_cap(u8 *pos, __le16 cap, u8 *end) +{ + if ((end - pos) < 5) + return pos; + + *pos++ = WLAN_EID_EXTENSION; + *pos++ = 1 + sizeof(cap); + *pos++ = WLAN_EID_EXT_HE_6GHZ_CAPA; + memcpy(pos, &cap, sizeof(cap)); + + return pos + 2; +} + +static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata, u8 *buffer, size_t buffer_len, const u8 *ie, size_t ie_len, enum nl80211_band band, @@ -1638,6 +1651,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, struct cfg80211_chan_def *chandef, size_t *offset, u32 flags) { + struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; const struct ieee80211_sta_he_cap *he_cap; u8 *pos = buffer, *end = buffer + buffer_len; @@ -1815,6 +1829,14 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, pos = ieee80211_ie_build_he_cap(pos, he_cap, end); if (!pos) goto out_err; + + if (sband->band == NL80211_BAND_6GHZ) { + enum nl80211_iftype iftype = + ieee80211_vif_type_p2p(&sdata->vif); + __le16 cap = ieee80211_get_he_6ghz_capa(sband, iftype); + + pos = ieee80211_write_he_6ghz_cap(pos, cap, end); + } } /* @@ -1829,7 +1851,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, return pos - buffer; } -int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, +int ieee80211_build_preq_ies(struct ieee80211_sub_if_data *sdata, u8 *buffer, size_t buffer_len, struct ieee80211_scan_ies *ie_desc, const u8 *ie, size_t ie_len, @@ -1844,7 +1866,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, for (i = 0; i < NUM_NL80211_BANDS; i++) { if (bands_used & BIT(i)) { - pos += ieee80211_build_preq_ies_band(local, + pos += ieee80211_build_preq_ies_band(sdata, buffer + pos, buffer_len - pos, ie, ie_len, i, @@ -1906,7 +1928,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, return NULL; rate_masks[chan->band] = ratemask; - ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb), + ies_len = ieee80211_build_preq_ies(sdata, skb_tail_pointer(skb), skb_tailroom(skb), &dummy_ie_desc, ie, ie_len, BIT(chan->band), rate_masks, &chandef, flags); @@ -2806,6 +2828,50 @@ end: return pos; } +void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb) +{ + struct ieee80211_supported_band *sband; + const struct ieee80211_sband_iftype_data *iftd; + enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif); + u8 *pos; + u16 cap; + + sband = ieee80211_get_sband(sdata); + if (!sband) + return; + + iftd = ieee80211_get_sband_iftype_data(sband, iftype); + if (WARN_ON(!iftd)) + return; + + cap = le16_to_cpu(iftd->he_6ghz_capa.capa); + cap &= ~IEEE80211_HE_6GHZ_CAP_SM_PS; + + switch (sdata->smps_mode) { + case IEEE80211_SMPS_AUTOMATIC: + case IEEE80211_SMPS_NUM_MODES: + WARN_ON(1); + /* fall through */ + case IEEE80211_SMPS_OFF: + cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DISABLED, + IEEE80211_HE_6GHZ_CAP_SM_PS); + break; + case IEEE80211_SMPS_STATIC: + cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_STATIC, + IEEE80211_HE_6GHZ_CAP_SM_PS); + break; + case IEEE80211_SMPS_DYNAMIC: + cap |= u16_encode_bits(WLAN_HT_CAP_SM_PS_DYNAMIC, + IEEE80211_HE_6GHZ_CAP_SM_PS); + break; + } + + pos = skb_put(skb, 2 + 1 + sizeof(cap)); + ieee80211_write_he_6ghz_cap(pos, cpu_to_le16(cap), + pos + 2 + 1 + sizeof(cap)); +} + u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, const struct cfg80211_chan_def *chandef, u16 prot_mode, bool rifs_mode) diff --git a/net/wireless/chan.c b/net/wireless/chan.c index fcac5c6366e1..dd8bb88a64df 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -6,7 +6,7 @@ * * Copyright 2009 Johannes Berg * Copyright 2013-2014 Intel Mobile Communications GmbH - * Copyright 2018 Intel Corporation + * Copyright 2018-2020 Intel Corporation */ #include @@ -27,6 +27,7 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef, return; chandef->chan = chan; + chandef->freq1_offset = chan->freq_offset; chandef->center_freq2 = 0; chandef->edmg.bw_config = 0; chandef->edmg.channels = 0; @@ -153,7 +154,8 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) case NL80211_CHAN_WIDTH_10: case NL80211_CHAN_WIDTH_20: case NL80211_CHAN_WIDTH_20_NOHT: - if (chandef->center_freq1 != control_freq) + if (ieee80211_chandef_to_khz(chandef) != + ieee80211_channel_to_khz(chandef->chan)) return false; if (chandef->center_freq2) return false; @@ -386,10 +388,11 @@ static u32 cfg80211_get_start_freq(u32 center_freq, { u32 start_freq; - if (bandwidth <= 20) + bandwidth = MHZ_TO_KHZ(bandwidth); + if (bandwidth <= MHZ_TO_KHZ(20)) start_freq = center_freq; else - start_freq = center_freq - bandwidth/2 + 10; + start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10); return start_freq; } @@ -399,10 +402,11 @@ static u32 cfg80211_get_end_freq(u32 center_freq, { u32 end_freq; - if (bandwidth <= 20) + bandwidth = MHZ_TO_KHZ(bandwidth); + if (bandwidth <= MHZ_TO_KHZ(20)) end_freq = center_freq; else - end_freq = center_freq + bandwidth/2 - 10; + end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10); return end_freq; } @@ -417,8 +421,8 @@ static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy, start_freq = cfg80211_get_start_freq(center_freq, bandwidth); end_freq = cfg80211_get_end_freq(center_freq, bandwidth); - for (freq = start_freq; freq <= end_freq; freq += 20) { - c = ieee80211_get_channel(wiphy, freq); + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { + c = ieee80211_get_channel_khz(wiphy, freq); if (!c) return -EINVAL; @@ -449,8 +453,8 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, return -EINVAL; ret = cfg80211_get_chans_dfs_required(wiphy, - chandef->center_freq1, - width); + ieee80211_chandef_to_khz(chandef), + width); if (ret < 0) return ret; else if (ret > 0) @@ -460,8 +464,8 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, return 0; ret = cfg80211_get_chans_dfs_required(wiphy, - chandef->center_freq2, - width); + MHZ_TO_KHZ(chandef->center_freq2), + width); if (ret < 0) return ret; else if (ret > 0) @@ -503,8 +507,8 @@ static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy, * DFS_AVAILABLE). Return number of usable channels * (require CAC). Allow DFS and non-DFS channel mix. */ - for (freq = start_freq; freq <= end_freq; freq += 20) { - c = ieee80211_get_channel(wiphy, freq); + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { + c = ieee80211_get_channel_khz(wiphy, freq); if (!c) return -EINVAL; @@ -536,8 +540,9 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, if (width < 0) return false; - r1 = cfg80211_get_chans_dfs_usable(wiphy, chandef->center_freq1, - width); + r1 = cfg80211_get_chans_dfs_usable(wiphy, + MHZ_TO_KHZ(chandef->center_freq1), + width); if (r1 < 0) return false; @@ -546,8 +551,8 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, case NL80211_CHAN_WIDTH_80P80: WARN_ON(!chandef->center_freq2); r2 = cfg80211_get_chans_dfs_usable(wiphy, - chandef->center_freq2, - width); + MHZ_TO_KHZ(chandef->center_freq2), + width); if (r2 < 0) return false; break; @@ -694,8 +699,8 @@ static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy, * If any channel in between is disabled or has not * had gone through CAC return false */ - for (freq = start_freq; freq <= end_freq; freq += 20) { - c = ieee80211_get_channel(wiphy, freq); + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { + c = ieee80211_get_channel_khz(wiphy, freq); if (!c) return false; @@ -724,7 +729,8 @@ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy, if (width < 0) return false; - r = cfg80211_get_chans_dfs_available(wiphy, chandef->center_freq1, + r = cfg80211_get_chans_dfs_available(wiphy, + MHZ_TO_KHZ(chandef->center_freq1), width); /* If any of channels unavailable for cf1 just return */ @@ -735,8 +741,8 @@ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy, case NL80211_CHAN_WIDTH_80P80: WARN_ON(!chandef->center_freq2); r = cfg80211_get_chans_dfs_available(wiphy, - chandef->center_freq2, - width); + MHZ_TO_KHZ(chandef->center_freq2), + width); break; default: WARN_ON(chandef->center_freq2); @@ -757,8 +763,8 @@ static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy, start_freq = cfg80211_get_start_freq(center_freq, bandwidth); end_freq = cfg80211_get_end_freq(center_freq, bandwidth); - for (freq = start_freq; freq <= end_freq; freq += 20) { - c = ieee80211_get_channel(wiphy, freq); + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { + c = ieee80211_get_channel_khz(wiphy, freq); if (!c) return 0; @@ -790,14 +796,14 @@ cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, return 0; t1 = cfg80211_get_chans_dfs_cac_time(wiphy, - chandef->center_freq1, + MHZ_TO_KHZ(chandef->center_freq1), width); if (!chandef->center_freq2) return t1; t2 = cfg80211_get_chans_dfs_cac_time(wiphy, - chandef->center_freq2, + MHZ_TO_KHZ(chandef->center_freq2), width); return max(t1, t2); @@ -813,8 +819,8 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, start_freq = cfg80211_get_start_freq(center_freq, bandwidth); end_freq = cfg80211_get_end_freq(center_freq, bandwidth); - for (freq = start_freq; freq <= end_freq; freq += 20) { - c = ieee80211_get_channel(wiphy, freq); + for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) { + c = ieee80211_get_channel_khz(wiphy, freq); if (!c || c->flags & prohibited_flags) return false; } @@ -910,7 +916,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, width = 10; break; case NL80211_CHAN_WIDTH_20: - if (!ht_cap->ht_supported) + if (!ht_cap->ht_supported && + chandef->chan->band != NL80211_BAND_6GHZ) return false; /* fall through */ case NL80211_CHAN_WIDTH_20_NOHT: @@ -919,6 +926,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, break; case NL80211_CHAN_WIDTH_40: width = 40; + if (chandef->chan->band == NL80211_BAND_6GHZ) + break; if (!ht_cap->ht_supported) return false; if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || @@ -933,24 +942,29 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, break; case NL80211_CHAN_WIDTH_80P80: cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; - if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) + if (chandef->chan->band != NL80211_BAND_6GHZ && + cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) return false; /* fall through */ case NL80211_CHAN_WIDTH_80: - if (!vht_cap->vht_supported) - return false; prohibited_flags |= IEEE80211_CHAN_NO_80MHZ; width = 80; + if (chandef->chan->band == NL80211_BAND_6GHZ) + break; + if (!vht_cap->vht_supported) + return false; break; case NL80211_CHAN_WIDTH_160: + prohibited_flags |= IEEE80211_CHAN_NO_160MHZ; + width = 160; + if (chandef->chan->band == NL80211_BAND_6GHZ) + break; if (!vht_cap->vht_supported) return false; cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ && cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) return false; - prohibited_flags |= IEEE80211_CHAN_NO_160MHZ; - width = 160; break; default: WARN_ON_ONCE(1); @@ -976,13 +990,15 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, prohibited_flags |= IEEE80211_CHAN_NO_OFDM; - if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1, + if (!cfg80211_secondary_chans_ok(wiphy, + ieee80211_chandef_to_khz(chandef), width, prohibited_flags)) return false; if (!chandef->center_freq2) return true; - return cfg80211_secondary_chans_ok(wiphy, chandef->center_freq2, + return cfg80211_secondary_chans_ok(wiphy, + MHZ_TO_KHZ(chandef->center_freq2), width, prohibited_flags); } EXPORT_SYMBOL(cfg80211_chandef_usable); diff --git a/net/wireless/core.c b/net/wireless/core.c index ee5bb8d8af04..e52fd39ece70 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -5,7 +5,7 @@ * Copyright 2006-2010 Johannes Berg * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2015-2017 Intel Deutschland GmbH - * Copyright (C) 2018-2019 Intel Corporation + * Copyright (C) 2018-2020 Intel Corporation */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -788,6 +788,7 @@ int wiphy_register(struct wiphy *wiphy) /* sanity check supported bands/channels */ for (band = 0; band < NUM_NL80211_BANDS; band++) { u16 types = 0; + bool have_he = false; sband = wiphy->bands[band]; if (!sband) @@ -804,6 +805,11 @@ int wiphy_register(struct wiphy *wiphy) !sband->n_bitrates)) return -EINVAL; + if (WARN_ON(band == NL80211_BAND_6GHZ && + (sband->ht_cap.ht_supported || + sband->vht_cap.vht_supported))) + return -EINVAL; + /* * Since cfg80211_disable_40mhz_24ghz is global, we can * modify the sband's ht data even if the driver uses a @@ -848,8 +854,17 @@ int wiphy_register(struct wiphy *wiphy) return -EINVAL; types |= iftd->types_mask; + + if (i == 0) + have_he = iftd->he_cap.has_he; + else + have_he = have_he && + iftd->he_cap.has_he; } + if (WARN_ON(!have_he && band == NL80211_BAND_6GHZ)) + return -EINVAL; + have_band = true; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 6c0f34e46cd0..36df826c1939 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -652,6 +652,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG }, [NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1), [NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100), + [NL80211_ATTR_HE_6GHZ_CAPABILITY] = { + .type = NLA_EXACT_LEN, + .len = sizeof(struct ieee80211_he_6ghz_capa), + }, }; /* policy for the key attributes */ @@ -1570,6 +1574,7 @@ static int nl80211_send_coalesce(struct sk_buff *msg, static int nl80211_send_iftype_data(struct sk_buff *msg, + const struct ieee80211_supported_band *sband, const struct ieee80211_sband_iftype_data *iftdata) { const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap; @@ -1593,6 +1598,12 @@ nl80211_send_iftype_data(struct sk_buff *msg, return -ENOBUFS; } + if (sband->band == NL80211_BAND_6GHZ && + nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, + sizeof(iftdata->he_6ghz_capa), + &iftdata->he_6ghz_capa)) + return -ENOBUFS; + return 0; } @@ -1641,7 +1652,7 @@ static int nl80211_send_band_rateinfo(struct sk_buff *msg, if (!iftdata) return -ENOBUFS; - err = nl80211_send_iftype_data(msg, + err = nl80211_send_iftype_data(msg, sband, &sband->iftype_data[i]); if (err) return err; @@ -5967,6 +5978,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]); } + if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]) + params.he_6ghz_capa = + nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]); + if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]) params.airtime_weight = nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]); @@ -6101,6 +6116,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } + if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]) + params.he_6ghz_capa = + nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]); + if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) { params.opmode_notif_used = true; params.opmode_notif = @@ -6145,10 +6164,14 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) params.vht_capa = NULL; /* HE requires WME */ - if (params.he_capa_len) + if (params.he_capa_len || params.he_6ghz_capa) return -EINVAL; } + /* Ensure that HT/VHT capabilities are not set for 6 GHz HE STA */ + if (params.he_6ghz_capa && (params.ht_capa || params.vht_capa)) + return -EINVAL; + /* When you run into this, adjust the code below for the new flag */ BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7); diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 891b9bf95b5e..5bc60a4ce092 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1693,22 +1693,23 @@ static uint32_t reg_rule_to_chan_bw_flags(const struct ieee80211_regdomain *regd const struct ieee80211_channel *chan) { const struct ieee80211_freq_range *freq_range = NULL; - u32 max_bandwidth_khz, bw_flags = 0; + u32 max_bandwidth_khz, center_freq_khz, bw_flags = 0; freq_range = ®_rule->freq_range; max_bandwidth_khz = freq_range->max_bandwidth_khz; + center_freq_khz = ieee80211_channel_to_khz(chan); /* Check if auto calculation requested */ if (reg_rule->flags & NL80211_RRF_AUTO_BW) max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule); /* If we get a reg_rule we can assume that at least 5Mhz fit */ if (!cfg80211_does_bw_fit_range(freq_range, - MHZ_TO_KHZ(chan->center_freq), + center_freq_khz, MHZ_TO_KHZ(10))) bw_flags |= IEEE80211_CHAN_NO_10MHZ; if (!cfg80211_does_bw_fit_range(freq_range, - MHZ_TO_KHZ(chan->center_freq), + center_freq_khz, MHZ_TO_KHZ(20))) bw_flags |= IEEE80211_CHAN_NO_20MHZ; @@ -1745,7 +1746,7 @@ static void handle_channel(struct wiphy *wiphy, flags = chan->orig_flags; - reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq)); + reg_rule = freq_reg_info(wiphy, ieee80211_channel_to_khz(chan)); if (IS_ERR(reg_rule)) { /* * We will disable all channels that do not match our @@ -1764,13 +1765,13 @@ static void handle_channel(struct wiphy *wiphy, if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && request_wiphy && request_wiphy == wiphy && request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) { - pr_debug("Disabling freq %d MHz for good\n", - chan->center_freq); + pr_debug("Disabling freq %d.%03d MHz for good\n", + chan->center_freq, chan->freq_offset); chan->orig_flags |= IEEE80211_CHAN_DISABLED; chan->flags = chan->orig_flags; } else { - pr_debug("Disabling freq %d MHz\n", - chan->center_freq); + pr_debug("Disabling freq %d.%03d MHz\n", + chan->center_freq, chan->freq_offset); chan->flags |= IEEE80211_CHAN_DISABLED; } return; @@ -1971,7 +1972,7 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx, sband = wiphy->bands[reg_beacon->chan.band]; chan = &sband->channels[chan_idx]; - if (likely(chan->center_freq != reg_beacon->chan.center_freq)) + if (likely(!ieee80211_channel_equal(chan, ®_beacon->chan))) return; if (chan->beacon_found) @@ -2304,18 +2305,18 @@ static void handle_channel_custom(struct wiphy *wiphy, u32 bw_flags = 0; const struct ieee80211_reg_rule *reg_rule = NULL; const struct ieee80211_power_rule *power_rule = NULL; - u32 bw; + u32 bw, center_freq_khz; + center_freq_khz = ieee80211_channel_to_khz(chan); for (bw = MHZ_TO_KHZ(20); bw >= min_bw; bw = bw / 2) { - reg_rule = freq_reg_info_regd(MHZ_TO_KHZ(chan->center_freq), - regd, bw); + reg_rule = freq_reg_info_regd(center_freq_khz, regd, bw); if (!IS_ERR(reg_rule)) break; } if (IS_ERR_OR_NULL(reg_rule)) { - pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n", - chan->center_freq); + pr_debug("Disabling freq %d.%03d MHz as custom regd has no rule that fits it\n", + chan->center_freq, chan->freq_offset); if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) { chan->flags |= IEEE80211_CHAN_DISABLED; } else { @@ -3372,8 +3373,8 @@ static bool pending_reg_beacon(struct ieee80211_channel *beacon_chan) struct reg_beacon *pending_beacon; list_for_each_entry(pending_beacon, ®_pending_beacons, list) - if (beacon_chan->center_freq == - pending_beacon->chan.center_freq) + if (ieee80211_channel_equal(beacon_chan, + &pending_beacon->chan)) return true; return false; } @@ -3402,9 +3403,10 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy, if (!reg_beacon) return -ENOMEM; - pr_debug("Found new beacon on frequency: %d MHz (Ch %d) on %s\n", - beacon_chan->center_freq, - ieee80211_frequency_to_channel(beacon_chan->center_freq), + pr_debug("Found new beacon on frequency: %d.%03d MHz (Ch %d) on %s\n", + beacon_chan->center_freq, beacon_chan->freq_offset, + ieee80211_freq_khz_to_channel( + ieee80211_channel_to_khz(beacon_chan)), wiphy_name(wiphy)); memcpy(®_beacon->chan, beacon_chan, diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 328402ab64a3..33b3c990e971 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1323,8 +1323,8 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen, return channel; } - freq = ieee80211_channel_to_frequency(channel_number, channel->band); - alt_channel = ieee80211_get_channel(wiphy, freq); + freq = ieee80211_channel_to_freq_khz(channel_number, channel->band); + alt_channel = ieee80211_get_channel_khz(wiphy, freq); if (!alt_channel) { if (channel->band == NL80211_BAND_2GHZ) { /* diff --git a/net/wireless/trace.h b/net/wireless/trace.h index cee60a4be141..0927dcbcafe5 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -112,24 +112,29 @@ } while (0) #define CHAN_ENTRY __field(enum nl80211_band, band) \ - __field(u32, center_freq) + __field(u32, center_freq) \ + __field(u16, freq_offset) #define CHAN_ASSIGN(chan) \ do { \ if (chan) { \ __entry->band = chan->band; \ __entry->center_freq = chan->center_freq; \ + __entry->freq_offset = chan->freq_offset; \ } else { \ __entry->band = 0; \ __entry->center_freq = 0; \ + __entry->freq_offset = 0; \ } \ } while (0) -#define CHAN_PR_FMT "band: %d, freq: %u" -#define CHAN_PR_ARG __entry->band, __entry->center_freq +#define CHAN_PR_FMT "band: %d, freq: %u.%03u" +#define CHAN_PR_ARG __entry->band, __entry->center_freq, __entry->freq_offset #define CHAN_DEF_ENTRY __field(enum nl80211_band, band) \ __field(u32, control_freq) \ + __field(u32, freq_offset) \ __field(u32, width) \ __field(u32, center_freq1) \ + __field(u32, freq1_offset) \ __field(u32, center_freq2) #define CHAN_DEF_ASSIGN(chandef) \ do { \ @@ -137,21 +142,27 @@ __entry->band = (chandef)->chan->band; \ __entry->control_freq = \ (chandef)->chan->center_freq; \ + __entry->freq_offset = \ + (chandef)->chan->freq_offset; \ __entry->width = (chandef)->width; \ __entry->center_freq1 = (chandef)->center_freq1;\ + __entry->freq1_offset = (chandef)->freq1_offset;\ __entry->center_freq2 = (chandef)->center_freq2;\ } else { \ __entry->band = 0; \ __entry->control_freq = 0; \ + __entry->freq_offset = 0; \ __entry->width = 0; \ __entry->center_freq1 = 0; \ + __entry->freq1_offset = 0; \ __entry->center_freq2 = 0; \ } \ } while (0) #define CHAN_DEF_PR_FMT \ - "band: %d, control freq: %u, width: %d, cf1: %u, cf2: %u" + "band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u" #define CHAN_DEF_PR_ARG __entry->band, __entry->control_freq, \ - __entry->width, __entry->center_freq1, \ + __entry->freq_offset, __entry->width, \ + __entry->center_freq1, __entry->freq1_offset, \ __entry->center_freq2 #define SINFO_ENTRY __field(int, generation) \ diff --git a/net/wireless/util.c b/net/wireless/util.c index 72926f87c913..cfc3ddddf3eb 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -72,7 +72,7 @@ u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband, } EXPORT_SYMBOL(ieee80211_mandatory_rates); -int ieee80211_channel_to_frequency(int chan, enum nl80211_band band) +u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band) { /* see 802.11 17.3.8.3.2 and Annex J * there are overlapping channel numbers in 5GHz and 2GHz bands */ @@ -81,34 +81,39 @@ int ieee80211_channel_to_frequency(int chan, enum nl80211_band band) switch (band) { case NL80211_BAND_2GHZ: if (chan == 14) - return 2484; + return MHZ_TO_KHZ(2484); else if (chan < 14) - return 2407 + chan * 5; + return MHZ_TO_KHZ(2407 + chan * 5); break; case NL80211_BAND_5GHZ: if (chan >= 182 && chan <= 196) - return 4000 + chan * 5; + return MHZ_TO_KHZ(4000 + chan * 5); else - return 5000 + chan * 5; + return MHZ_TO_KHZ(5000 + chan * 5); break; case NL80211_BAND_6GHZ: - /* see 802.11ax D4.1 27.3.22.2 */ + /* see 802.11ax D6.1 27.3.23.2 */ + if (chan == 2) + return MHZ_TO_KHZ(5935); if (chan <= 253) - return 5940 + chan * 5; + return MHZ_TO_KHZ(5950 + chan * 5); break; case NL80211_BAND_60GHZ: if (chan < 7) - return 56160 + chan * 2160; + return MHZ_TO_KHZ(56160 + chan * 2160); break; default: ; } return 0; /* not supported */ } -EXPORT_SYMBOL(ieee80211_channel_to_frequency); +EXPORT_SYMBOL(ieee80211_channel_to_freq_khz); -int ieee80211_frequency_to_channel(int freq) +int ieee80211_freq_khz_to_channel(u32 freq) { + /* TODO: just handle MHz for now */ + freq = KHZ_TO_MHZ(freq); + /* see 802.11 17.3.8.3.2 and Annex J */ if (freq == 2484) return 14; @@ -126,9 +131,10 @@ int ieee80211_frequency_to_channel(int freq) else return 0; } -EXPORT_SYMBOL(ieee80211_frequency_to_channel); +EXPORT_SYMBOL(ieee80211_freq_khz_to_channel); -struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq) +struct ieee80211_channel *ieee80211_get_channel_khz(struct wiphy *wiphy, + u32 freq) { enum nl80211_band band; struct ieee80211_supported_band *sband; @@ -141,14 +147,16 @@ struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq) continue; for (i = 0; i < sband->n_channels; i++) { - if (sband->channels[i].center_freq == freq) - return &sband->channels[i]; + struct ieee80211_channel *chan = &sband->channels[i]; + + if (ieee80211_channel_to_khz(chan) == freq) + return chan; } } return NULL; } -EXPORT_SYMBOL(ieee80211_get_channel); +EXPORT_SYMBOL(ieee80211_get_channel_khz); static void set_mandatory_flags_band(struct ieee80211_supported_band *sband) {