Message ID | 20201012141808.22284-1-shay.bar@celeno.com |
---|---|
State | New |
Headers | show |
Series | mac80211: 160MHz support per IEEE802.11ax standard | expand |
Hi Shay, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on mac80211-next/master] [also build test WARNING on mac80211/master v5.9 next-20201012] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Shay-Bar/mac80211-160MHz-support-per-IEEE802-11ax-standard/20201012-221911 base: https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master config: xtensa-allyesconfig (attached as .config) compiler: xtensa-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/13bd6eb21625512094cdded5c24e9dd314fb00b7 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Shay-Bar/mac80211-160MHz-support-per-IEEE802-11ax-standard/20201012-221911 git checkout 13bd6eb21625512094cdded5c24e9dd314fb00b7 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=xtensa If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> net/mac80211/spectmgmt.c:22:30: warning: no previous prototype for 'ieee80211_vht_get_actual_chwidth' [-Wmissing-prototypes] 22 | enum ieee80211_vht_chanwidth ieee80211_vht_get_actual_chwidth(u8 vht_oper_bw, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> net/mac80211/spectmgmt.c:49:1: warning: no previous prototype for 'ieee80211_get_center_freq_seg1_location' [-Wmissing-prototypes] 49 | ieee80211_get_center_freq_seg1_location(struct ieee80211_sub_if_data *sdata, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vim +/ieee80211_vht_get_actual_chwidth +22 net/mac80211/spectmgmt.c 21 > 22 enum ieee80211_vht_chanwidth ieee80211_vht_get_actual_chwidth(u8 vht_oper_bw, 23 u32 seg0, 24 u32 seg1) 25 { 26 enum ieee80211_vht_chanwidth ret = IEEE80211_VHT_CHANWIDTH_USE_HT; 27 28 if (vht_oper_bw != IEEE80211_VHT_CHANWIDTH_80MHZ) 29 return vht_oper_bw; 30 31 if (!seg1) { 32 return IEEE80211_VHT_CHANWIDTH_80MHZ; 33 } else { 34 int diff; 35 36 diff = abs((int) seg0 - (int) seg1); 37 38 if (diff == 8) 39 return IEEE80211_VHT_CHANWIDTH_160MHZ; 40 41 if (diff > 16) 42 return IEEE80211_VHT_CHANWIDTH_80P80MHZ; 43 } 44 45 return ret; 46 } 47 48 enum ieee80211_center_freq_seg1_location > 49 ieee80211_get_center_freq_seg1_location(struct ieee80211_sub_if_data *sdata, 50 u32 vht_cap_info, 51 u8 actual_chanwidth) 52 { 53 u8 ext_nss_bw_supp = (vht_cap_info & 54 IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) >> 55 IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT; 56 u8 supp_chwidth = (vht_cap_info & 57 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) >> 58 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT; 59 enum ieee80211_center_freq_seg1_location res = 60 IEEE80211_CENTER_FREQ_SEG1_NONE; 61 62 /* The bandwidth is less than 80+80/160MHz */ 63 if (actual_chanwidth < IEEE80211_VHT_CHANWIDTH_160MHZ) 64 return IEEE80211_CENTER_FREQ_SEG1_NONE; 65 66 switch (supp_chwidth) { 67 case 0: 68 if ((ext_nss_bw_supp > 1) || 69 ((ext_nss_bw_supp == 1) && 70 (actual_chanwidth == IEEE80211_VHT_CHANWIDTH_160MHZ))) 71 res = IEEE80211_CENTER_FREQ_SEG1_HT_OPER; /* CCFS2 */ 72 break; 73 case 1: 74 if ((ext_nss_bw_supp > 2) || 75 (actual_chanwidth == IEEE80211_VHT_CHANWIDTH_160MHZ)) 76 res = IEEE80211_CENTER_FREQ_SEG1_VHT_OPER; /* CCFS1 */ 77 else if (ext_nss_bw_supp > 0) 78 res = IEEE80211_CENTER_FREQ_SEG1_HT_OPER; /* CCFS2 */ 79 break; 80 case 2: 81 res = IEEE80211_CENTER_FREQ_SEG1_VHT_OPER; 82 if ((ext_nss_bw_supp > 0) && (ext_nss_bw_supp < 3)) 83 sdata_info(sdata, 84 "Invalid ext_nss_bw_supp %u for chwidth 2", 85 ext_nss_bw_supp); 86 break; 87 default: 88 break; 89 } 90 91 return res; 92 } 93 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Shay, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on mac80211-next/master] [also build test WARNING on mac80211/master v5.9 next-20201012] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Shay-Bar/mac80211-160MHz-support-per-IEEE802-11ax-standard/20201012-221911 base: https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master config: riscv-randconfig-r006-20201012 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 9e72d3eaf38f217698f72cb8fdc969a6e72dad3a) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install riscv cross compiling tool for clang build # apt-get install binutils-riscv64-linux-gnu # https://github.com/0day-ci/linux/commit/13bd6eb21625512094cdded5c24e9dd314fb00b7 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Shay-Bar/mac80211-160MHz-support-per-IEEE802-11ax-standard/20201012-221911 git checkout 13bd6eb21625512094cdded5c24e9dd314fb00b7 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:87:48: note: expanded from macro 'readb_cpu' #define readb_cpu(c) ({ u8 __r = __raw_readb(c); __r; }) ^ In file included from net/mac80211/spectmgmt.c:15: In file included from include/linux/ieee80211.h:19: In file included from include/linux/if_ether.h:19: In file included from include/linux/skbuff.h:31: In file included from include/linux/dma-mapping.h:11: In file included from include/linux/scatterlist.h:9: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:564:9: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] return inw(addr); ^~~~~~~~~ arch/riscv/include/asm/io.h:55:76: note: expanded from macro 'inw' #define inw(c) ({ u16 __v; __io_pbr(); __v = readw_cpu((void*)(PCI_IOBASE + (c))); __io_par(__v); __v; }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:88:76: note: expanded from macro 'readw_cpu' #define readw_cpu(c) ({ u16 __r = le16_to_cpu((__force __le16)__raw_readw(c)); __r; }) ^ include/uapi/linux/byteorder/little_endian.h:36:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from net/mac80211/spectmgmt.c:15: In file included from include/linux/ieee80211.h:19: In file included from include/linux/if_ether.h:19: In file included from include/linux/skbuff.h:31: In file included from include/linux/dma-mapping.h:11: In file included from include/linux/scatterlist.h:9: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:572:9: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] return inl(addr); ^~~~~~~~~ arch/riscv/include/asm/io.h:56:76: note: expanded from macro 'inl' #define inl(c) ({ u32 __v; __io_pbr(); __v = readl_cpu((void*)(PCI_IOBASE + (c))); __io_par(__v); __v; }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:89:76: note: expanded from macro 'readl_cpu' #define readl_cpu(c) ({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; }) ^ include/uapi/linux/byteorder/little_endian.h:34:51: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) ^ In file included from net/mac80211/spectmgmt.c:15: In file included from include/linux/ieee80211.h:19: In file included from include/linux/if_ether.h:19: In file included from include/linux/skbuff.h:31: In file included from include/linux/dma-mapping.h:11: In file included from include/linux/scatterlist.h:9: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:580:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] outb(value, addr); ^~~~~~~~~~~~~~~~~ arch/riscv/include/asm/io.h:58:68: note: expanded from macro 'outb' #define outb(v,c) ({ __io_pbw(); writeb_cpu((v),(void*)(PCI_IOBASE + (c))); __io_paw(); }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:91:52: note: expanded from macro 'writeb_cpu' #define writeb_cpu(v, c) ((void)__raw_writeb((v), (c))) ^ In file included from net/mac80211/spectmgmt.c:15: In file included from include/linux/ieee80211.h:19: In file included from include/linux/if_ether.h:19: In file included from include/linux/skbuff.h:31: In file included from include/linux/dma-mapping.h:11: In file included from include/linux/scatterlist.h:9: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:588:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] outw(value, addr); ^~~~~~~~~~~~~~~~~ arch/riscv/include/asm/io.h:59:68: note: expanded from macro 'outw' #define outw(v,c) ({ __io_pbw(); writew_cpu((v),(void*)(PCI_IOBASE + (c))); __io_paw(); }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:92:76: note: expanded from macro 'writew_cpu' #define writew_cpu(v, c) ((void)__raw_writew((__force u16)cpu_to_le16(v), (c))) ^ In file included from net/mac80211/spectmgmt.c:15: In file included from include/linux/ieee80211.h:19: In file included from include/linux/if_ether.h:19: In file included from include/linux/skbuff.h:31: In file included from include/linux/dma-mapping.h:11: In file included from include/linux/scatterlist.h:9: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:596:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] outl(value, addr); ^~~~~~~~~~~~~~~~~ arch/riscv/include/asm/io.h:60:68: note: expanded from macro 'outl' #define outl(v,c) ({ __io_pbw(); writel_cpu((v),(void*)(PCI_IOBASE + (c))); __io_paw(); }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:93:76: note: expanded from macro 'writel_cpu' #define writel_cpu(v, c) ((void)__raw_writel((__force u32)cpu_to_le32(v), (c))) ^ In file included from net/mac80211/spectmgmt.c:15: In file included from include/linux/ieee80211.h:19: In file included from include/linux/if_ether.h:19: In file included from include/linux/skbuff.h:31: In file included from include/linux/dma-mapping.h:11: In file included from include/linux/scatterlist.h:9: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:1017:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port; ~~~~~~~~~~ ^ >> net/mac80211/spectmgmt.c:22:30: warning: no previous prototype for function 'ieee80211_vht_get_actual_chwidth' [-Wmissing-prototypes] enum ieee80211_vht_chanwidth ieee80211_vht_get_actual_chwidth(u8 vht_oper_bw, ^ net/mac80211/spectmgmt.c:22:1: note: declare 'static' if the function is not intended to be used outside of this translation unit enum ieee80211_vht_chanwidth ieee80211_vht_get_actual_chwidth(u8 vht_oper_bw, ^ static >> net/mac80211/spectmgmt.c:49:1: warning: no previous prototype for function 'ieee80211_get_center_freq_seg1_location' [-Wmissing-prototypes] ieee80211_get_center_freq_seg1_location(struct ieee80211_sub_if_data *sdata, ^ net/mac80211/spectmgmt.c:48:1: note: declare 'static' if the function is not intended to be used outside of this translation unit enum ieee80211_center_freq_seg1_location ^ static 9 warnings generated. vim +/ieee80211_vht_get_actual_chwidth +22 net/mac80211/spectmgmt.c 21 > 22 enum ieee80211_vht_chanwidth ieee80211_vht_get_actual_chwidth(u8 vht_oper_bw, 23 u32 seg0, 24 u32 seg1) 25 { 26 enum ieee80211_vht_chanwidth ret = IEEE80211_VHT_CHANWIDTH_USE_HT; 27 28 if (vht_oper_bw != IEEE80211_VHT_CHANWIDTH_80MHZ) 29 return vht_oper_bw; 30 31 if (!seg1) { 32 return IEEE80211_VHT_CHANWIDTH_80MHZ; 33 } else { 34 int diff; 35 36 diff = abs((int) seg0 - (int) seg1); 37 38 if (diff == 8) 39 return IEEE80211_VHT_CHANWIDTH_160MHZ; 40 41 if (diff > 16) 42 return IEEE80211_VHT_CHANWIDTH_80P80MHZ; 43 } 44 45 return ret; 46 } 47 48 enum ieee80211_center_freq_seg1_location > 49 ieee80211_get_center_freq_seg1_location(struct ieee80211_sub_if_data *sdata, 50 u32 vht_cap_info, 51 u8 actual_chanwidth) 52 { 53 u8 ext_nss_bw_supp = (vht_cap_info & 54 IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) >> 55 IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT; 56 u8 supp_chwidth = (vht_cap_info & 57 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) >> 58 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT; 59 enum ieee80211_center_freq_seg1_location res = 60 IEEE80211_CENTER_FREQ_SEG1_NONE; 61 62 /* The bandwidth is less than 80+80/160MHz */ 63 if (actual_chanwidth < IEEE80211_VHT_CHANWIDTH_160MHZ) 64 return IEEE80211_CENTER_FREQ_SEG1_NONE; 65 66 switch (supp_chwidth) { 67 case 0: 68 if ((ext_nss_bw_supp > 1) || 69 ((ext_nss_bw_supp == 1) && 70 (actual_chanwidth == IEEE80211_VHT_CHANWIDTH_160MHZ))) 71 res = IEEE80211_CENTER_FREQ_SEG1_HT_OPER; /* CCFS2 */ 72 break; 73 case 1: 74 if ((ext_nss_bw_supp > 2) || 75 (actual_chanwidth == IEEE80211_VHT_CHANWIDTH_160MHZ)) 76 res = IEEE80211_CENTER_FREQ_SEG1_VHT_OPER; /* CCFS1 */ 77 else if (ext_nss_bw_supp > 0) 78 res = IEEE80211_CENTER_FREQ_SEG1_HT_OPER; /* CCFS2 */ 79 break; 80 case 2: 81 res = IEEE80211_CENTER_FREQ_SEG1_VHT_OPER; 82 if ((ext_nss_bw_supp > 0) && (ext_nss_bw_supp < 3)) 83 sdata_info(sdata, 84 "Invalid ext_nss_bw_supp %u for chwidth 2", 85 ext_nss_bw_supp); 86 break; 87 default: 88 break; 89 } 90 91 return res; 92 } 93 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index c47f43e65a2f..884b71a96084 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1692,6 +1692,21 @@ enum ieee80211_vht_chanwidth { IEEE80211_VHT_CHANWIDTH_80P80MHZ = 3, }; +/** + * enum ieee80211_center_freq_seg1_location - the location of center + * frequency segment1 + * @IEEE80211_CENTER_FREQ_SEG1_NONE: center freq seg1 is located no where + * @IEEE80211_CENTER_FREQ_SEG1_VHT_OPER: center freq seg1 is located in VHT + * operation IE + * @IEEE80211_CENTER_FREQ_SEG1_HT_OPER: center freq seg1 is located in HT + * operation IE + */ +enum ieee80211_center_freq_seg1_location { + IEEE80211_CENTER_FREQ_SEG1_NONE = 0, + IEEE80211_CENTER_FREQ_SEG1_VHT_OPER = 1, + IEEE80211_CENTER_FREQ_SEG1_HT_OPER = 2, +}; + /** * struct ieee80211_vht_operation - VHT operation IE * diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index ae1cb2c68722..6600e78e2bde 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c @@ -19,6 +19,78 @@ #include "sta_info.h" #include "wme.h" +enum ieee80211_vht_chanwidth ieee80211_vht_get_actual_chwidth(u8 vht_oper_bw, + u32 seg0, + u32 seg1) +{ + enum ieee80211_vht_chanwidth ret = IEEE80211_VHT_CHANWIDTH_USE_HT; + + if (vht_oper_bw != IEEE80211_VHT_CHANWIDTH_80MHZ) + return vht_oper_bw; + + if (!seg1) { + return IEEE80211_VHT_CHANWIDTH_80MHZ; + } else { + int diff; + + diff = abs((int) seg0 - (int) seg1); + + if (diff == 8) + return IEEE80211_VHT_CHANWIDTH_160MHZ; + + if (diff > 16) + return IEEE80211_VHT_CHANWIDTH_80P80MHZ; + } + + return ret; +} + +enum ieee80211_center_freq_seg1_location +ieee80211_get_center_freq_seg1_location(struct ieee80211_sub_if_data *sdata, + u32 vht_cap_info, + u8 actual_chanwidth) +{ + u8 ext_nss_bw_supp = (vht_cap_info & + IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) >> + IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT; + u8 supp_chwidth = (vht_cap_info & + IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) >> + IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_SHIFT; + enum ieee80211_center_freq_seg1_location res = + IEEE80211_CENTER_FREQ_SEG1_NONE; + + /* The bandwidth is less than 80+80/160MHz */ + if (actual_chanwidth < IEEE80211_VHT_CHANWIDTH_160MHZ) + return IEEE80211_CENTER_FREQ_SEG1_NONE; + + switch (supp_chwidth) { + case 0: + if ((ext_nss_bw_supp > 1) || + ((ext_nss_bw_supp == 1) && + (actual_chanwidth == IEEE80211_VHT_CHANWIDTH_160MHZ))) + res = IEEE80211_CENTER_FREQ_SEG1_HT_OPER; /* CCFS2 */ + break; + case 1: + if ((ext_nss_bw_supp > 2) || + (actual_chanwidth == IEEE80211_VHT_CHANWIDTH_160MHZ)) + res = IEEE80211_CENTER_FREQ_SEG1_VHT_OPER; /* CCFS1 */ + else if (ext_nss_bw_supp > 0) + res = IEEE80211_CENTER_FREQ_SEG1_HT_OPER; /* CCFS2 */ + break; + case 2: + res = IEEE80211_CENTER_FREQ_SEG1_VHT_OPER; + if ((ext_nss_bw_supp > 0) && (ext_nss_bw_supp < 3)) + sdata_info(sdata, + "Invalid ext_nss_bw_supp %u for chwidth 2", + ext_nss_bw_supp); + break; + default: + break; + } + + return res; +} + int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, struct ieee802_11_elems *elems, enum nl80211_band current_band, @@ -133,17 +205,30 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, } if (wide_bw_chansw_ie) { + u8 new_channel_width = wide_bw_chansw_ie->new_channel_width; + u8 new_seg0 = wide_bw_chansw_ie->new_center_freq_seg0; + u8 new_seg1 = wide_bw_chansw_ie->new_center_freq_seg1; + enum ieee80211_vht_chanwidth act_chanwidth = + ieee80211_vht_get_actual_chwidth( + new_channel_width, new_seg0, new_seg1); + enum ieee80211_center_freq_seg1_location seg1_location = + ieee80211_get_center_freq_seg1_location(sdata, + vht_cap_info, + act_chanwidth); struct ieee80211_vht_operation vht_oper = { - .chan_width = - wide_bw_chansw_ie->new_channel_width, - .center_freq_seg0_idx = - wide_bw_chansw_ie->new_center_freq_seg0, - .center_freq_seg1_idx = - wide_bw_chansw_ie->new_center_freq_seg1, + .chan_width = new_channel_width, + .center_freq_seg0_idx = new_seg0, /* .basic_mcs_set doesn't matter */ }; struct ieee80211_ht_operation ht_oper = {}; + if (seg1_location == IEEE80211_CENTER_FREQ_SEG1_VHT_OPER) + vht_oper.center_freq_seg1_idx = new_seg1; + else if (seg1_location == IEEE80211_CENTER_FREQ_SEG1_HT_OPER) + ht_oper.operation_mode = + (le16_to_cpu(new_seg1) << + IEEE80211_HT_OP_MODE_CCFS2_SHIFT); + /* default, for the case of IEEE80211_VHT_CHANWIDTH_USE_HT, * to the previously parsed chandef */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5940acbe761c..9644d00cfd2f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2889,6 +2889,21 @@ int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, chandef->edmg.channels = 0; } + if (chandef->width == NL80211_CHAN_WIDTH_80) { + if (chandef->center_freq2) { + int diff = abs(chandef->center_freq1 - + chandef->center_freq2); + + if (diff == 40) + chandef->width = NL80211_CHAN_WIDTH_160; + else if (diff > 80) + chandef->width = NL80211_CHAN_WIDTH_80P80; + + chandef->center_freq1 = chandef->center_freq2; + chandef->center_freq2 = 0; + } + } + if (!cfg80211_chandef_valid(chandef)) { NL_SET_ERR_MSG(extack, "invalid channel definition"); return -EINVAL;