344-v6.3-0001-wifi-cfg80211-move-puncturing-bitmap-validation-from.patch 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. From b25413fed3d43e1ed3340df4d928971bb8639f66 Mon Sep 17 00:00:00 2001
  2. From: Aloka Dixit <quic_alokad@quicinc.com>
  3. Date: Mon, 30 Jan 2023 16:12:24 -0800
  4. Subject: [PATCH] wifi: cfg80211: move puncturing bitmap validation from
  5. mac80211
  6. - Move ieee80211_valid_disable_subchannel_bitmap() from mlme.c to
  7. chan.c, rename it as cfg80211_valid_disable_subchannel_bitmap()
  8. and export it.
  9. - Modify the prototype to include struct cfg80211_chan_def instead
  10. of only bandwidth to support a check which returns false if the
  11. primary channel is punctured.
  12. Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
  13. Link: https://lore.kernel.org/r/20230131001227.25014-2-quic_alokad@quicinc.com
  14. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  15. ---
  16. include/net/cfg80211.h | 12 +++++++
  17. net/mac80211/mlme.c | 73 ++++--------------------------------------
  18. net/wireless/chan.c | 69 +++++++++++++++++++++++++++++++++++++++
  19. 3 files changed, 87 insertions(+), 67 deletions(-)
  20. --- a/include/net/cfg80211.h
  21. +++ b/include/net/cfg80211.h
  22. @@ -8951,4 +8951,16 @@ static inline int cfg80211_color_change_
  23. 0, 0);
  24. }
  25. +/**
  26. + * cfg80211_valid_disable_subchannel_bitmap - validate puncturing bitmap
  27. + * @bitmap: bitmap to be validated
  28. + * @chandef: channel definition
  29. + *
  30. + * Validate the puncturing bitmap.
  31. + *
  32. + * Return: %true if the bitmap is valid. %false otherwise.
  33. + */
  34. +bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
  35. + const struct cfg80211_chan_def *chandef);
  36. +
  37. #endif /* __NET_CFG80211_H */
  38. --- a/net/mac80211/mlme.c
  39. +++ b/net/mac80211/mlme.c
  40. @@ -88,67 +88,6 @@ MODULE_PARM_DESC(probe_wait_ms,
  41. */
  42. #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
  43. -struct ieee80211_per_bw_puncturing_values {
  44. - u8 len;
  45. - const u16 *valid_values;
  46. -};
  47. -
  48. -static const u16 puncturing_values_80mhz[] = {
  49. - 0x8, 0x4, 0x2, 0x1
  50. -};
  51. -
  52. -static const u16 puncturing_values_160mhz[] = {
  53. - 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
  54. -};
  55. -
  56. -static const u16 puncturing_values_320mhz[] = {
  57. - 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
  58. - 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
  59. - 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
  60. -};
  61. -
  62. -#define IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
  63. - { \
  64. - .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
  65. - .valid_values = puncturing_values_ ## _bw ## mhz \
  66. - }
  67. -
  68. -static const struct ieee80211_per_bw_puncturing_values per_bw_puncturing[] = {
  69. - IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(80),
  70. - IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(160),
  71. - IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(320)
  72. -};
  73. -
  74. -static bool ieee80211_valid_disable_subchannel_bitmap(u16 *bitmap,
  75. - enum nl80211_chan_width bw)
  76. -{
  77. - u32 idx, i;
  78. -
  79. - switch (bw) {
  80. - case NL80211_CHAN_WIDTH_80:
  81. - idx = 0;
  82. - break;
  83. - case NL80211_CHAN_WIDTH_160:
  84. - idx = 1;
  85. - break;
  86. - case NL80211_CHAN_WIDTH_320:
  87. - idx = 2;
  88. - break;
  89. - default:
  90. - *bitmap = 0;
  91. - break;
  92. - }
  93. -
  94. - if (!*bitmap)
  95. - return true;
  96. -
  97. - for (i = 0; i < per_bw_puncturing[idx].len; i++)
  98. - if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
  99. - return true;
  100. -
  101. - return false;
  102. -}
  103. -
  104. /*
  105. * Extract from the given disabled subchannel bitmap (raw format
  106. * from the EHT Operation Element) the bits for the subchannel
  107. @@ -206,8 +145,8 @@ ieee80211_handle_puncturing_bitmap(struc
  108. ieee80211_extract_dis_subch_bmap(eht_oper, chandef,
  109. bitmap);
  110. - if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
  111. - chandef->width))
  112. + if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
  113. + chandef))
  114. break;
  115. link->u.mgd.conn_flags |=
  116. ieee80211_chandef_downgrade(chandef);
  117. @@ -5584,8 +5523,8 @@ static bool ieee80211_config_puncturing(
  118. extracted == link->conf->eht_puncturing)
  119. return true;
  120. - if (!ieee80211_valid_disable_subchannel_bitmap(&bitmap,
  121. - link->conf->chandef.width)) {
  122. + if (!cfg80211_valid_disable_subchannel_bitmap(&bitmap,
  123. + &link->conf->chandef)) {
  124. link_info(link,
  125. "Got an invalid disable subchannel bitmap from AP %pM: bitmap = 0x%x, bw = 0x%x. disconnect\n",
  126. link->u.mgd.bssid,
  127. @@ -7072,8 +7011,8 @@ ieee80211_setup_assoc_link(struct ieee80
  128. u16 bitmap;
  129. bitmap = get_unaligned_le16(disable_subchannel_bitmap);
  130. - if (ieee80211_valid_disable_subchannel_bitmap(&bitmap,
  131. - link->conf->chandef.width))
  132. + if (cfg80211_valid_disable_subchannel_bitmap(&bitmap,
  133. + &link->conf->chandef))
  134. ieee80211_handle_puncturing_bitmap(link,
  135. eht_oper,
  136. bitmap,
  137. --- a/net/wireless/chan.c
  138. +++ b/net/wireless/chan.c
  139. @@ -1505,3 +1505,72 @@ struct cfg80211_chan_def *wdev_chandef(s
  140. }
  141. }
  142. EXPORT_SYMBOL(wdev_chandef);
  143. +
  144. +struct cfg80211_per_bw_puncturing_values {
  145. + u8 len;
  146. + const u16 *valid_values;
  147. +};
  148. +
  149. +static const u16 puncturing_values_80mhz[] = {
  150. + 0x8, 0x4, 0x2, 0x1
  151. +};
  152. +
  153. +static const u16 puncturing_values_160mhz[] = {
  154. + 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3
  155. +};
  156. +
  157. +static const u16 puncturing_values_320mhz[] = {
  158. + 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00,
  159. + 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f,
  160. + 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f
  161. +};
  162. +
  163. +#define CFG80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \
  164. + { \
  165. + .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \
  166. + .valid_values = puncturing_values_ ## _bw ## mhz \
  167. + }
  168. +
  169. +static const struct cfg80211_per_bw_puncturing_values per_bw_puncturing[] = {
  170. + CFG80211_PER_BW_VALID_PUNCTURING_VALUES(80),
  171. + CFG80211_PER_BW_VALID_PUNCTURING_VALUES(160),
  172. + CFG80211_PER_BW_VALID_PUNCTURING_VALUES(320)
  173. +};
  174. +
  175. +bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap,
  176. + const struct cfg80211_chan_def *chandef)
  177. +{
  178. + u32 idx, i, start_freq;
  179. +
  180. + switch (chandef->width) {
  181. + case NL80211_CHAN_WIDTH_80:
  182. + idx = 0;
  183. + start_freq = chandef->center_freq1 - 40;
  184. + break;
  185. + case NL80211_CHAN_WIDTH_160:
  186. + idx = 1;
  187. + start_freq = chandef->center_freq1 - 80;
  188. + break;
  189. + case NL80211_CHAN_WIDTH_320:
  190. + idx = 2;
  191. + start_freq = chandef->center_freq1 - 160;
  192. + break;
  193. + default:
  194. + *bitmap = 0;
  195. + break;
  196. + }
  197. +
  198. + if (!*bitmap)
  199. + return true;
  200. +
  201. + /* check if primary channel is punctured */
  202. + if (*bitmap & (u16)BIT((chandef->chan->center_freq - start_freq) / 20))
  203. + return false;
  204. +
  205. + for (i = 0; i < per_bw_puncturing[idx].len; i++)
  206. + if (per_bw_puncturing[idx].valid_values[i] == *bitmap)
  207. + return true;
  208. +
  209. + return false;
  210. +}
  211. +EXPORT_SYMBOL(cfg80211_valid_disable_subchannel_bitmap);