905-ath11k-remove-intersection-support-for-regulatory-ru.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. From abdd0985a36189ef2cc0e393b027276e86137ace Mon Sep 17 00:00:00 2001
  2. From: Aditya Kumar Singh <quic_adisi@quicinc.com>
  3. Date: Tue, 11 Apr 2023 20:08:49 +0200
  4. Subject: [PATCH] ath11k: remove intersection support for regulatory rules
  5. Currently, regulatory rules from new country settings is intersected with
  6. rules from default country settings(during initialisation) in order to prevent
  7. users to bypass their default country settings such as power limits, channel
  8. flags, etc.
  9. However, the country setting in the BDF will take higher higher precendence
  10. and FW will protect it. Therefore, there is no need to handle intersection
  11. on the driver side now.
  12. Remove regulatory rules intersection logic support.
  13. Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
  14. ---
  15. drivers/net/wireless/ath/ath11k/reg.c | 168 +++-----------------------
  16. drivers/net/wireless/ath/ath11k/reg.h | 2 +-
  17. drivers/net/wireless/ath/ath11k/wmi.c | 24 +---
  18. 3 files changed, 16 insertions(+), 178 deletions(-)
  19. --- a/drivers/net/wireless/ath/ath11k/reg.c
  20. +++ b/drivers/net/wireless/ath/ath11k/reg.c
  21. @@ -352,129 +352,6 @@ static u32 ath11k_map_fw_reg_flags(u16 r
  22. return flags;
  23. }
  24. -static bool
  25. -ath11k_reg_can_intersect(struct ieee80211_reg_rule *rule1,
  26. - struct ieee80211_reg_rule *rule2)
  27. -{
  28. - u32 start_freq1, end_freq1;
  29. - u32 start_freq2, end_freq2;
  30. -
  31. - start_freq1 = rule1->freq_range.start_freq_khz;
  32. - start_freq2 = rule2->freq_range.start_freq_khz;
  33. -
  34. - end_freq1 = rule1->freq_range.end_freq_khz;
  35. - end_freq2 = rule2->freq_range.end_freq_khz;
  36. -
  37. - if ((start_freq1 >= start_freq2 &&
  38. - start_freq1 < end_freq2) ||
  39. - (start_freq2 > start_freq1 &&
  40. - start_freq2 < end_freq1))
  41. - return true;
  42. -
  43. - /* TODO: Should we restrict intersection feasibility
  44. - * based on min bandwidth of the intersected region also,
  45. - * say the intersected rule should have a min bandwidth
  46. - * of 20MHz?
  47. - */
  48. -
  49. - return false;
  50. -}
  51. -
  52. -static void ath11k_reg_intersect_rules(struct ieee80211_reg_rule *rule1,
  53. - struct ieee80211_reg_rule *rule2,
  54. - struct ieee80211_reg_rule *new_rule)
  55. -{
  56. - u32 start_freq1, end_freq1;
  57. - u32 start_freq2, end_freq2;
  58. - u32 freq_diff, max_bw;
  59. -
  60. - start_freq1 = rule1->freq_range.start_freq_khz;
  61. - start_freq2 = rule2->freq_range.start_freq_khz;
  62. -
  63. - end_freq1 = rule1->freq_range.end_freq_khz;
  64. - end_freq2 = rule2->freq_range.end_freq_khz;
  65. -
  66. - new_rule->freq_range.start_freq_khz = max_t(u32, start_freq1,
  67. - start_freq2);
  68. - new_rule->freq_range.end_freq_khz = min_t(u32, end_freq1, end_freq2);
  69. -
  70. - freq_diff = new_rule->freq_range.end_freq_khz -
  71. - new_rule->freq_range.start_freq_khz;
  72. - max_bw = min_t(u32, rule1->freq_range.max_bandwidth_khz,
  73. - rule2->freq_range.max_bandwidth_khz);
  74. - new_rule->freq_range.max_bandwidth_khz = min_t(u32, max_bw, freq_diff);
  75. -
  76. - new_rule->power_rule.max_antenna_gain =
  77. - min_t(u32, rule1->power_rule.max_antenna_gain,
  78. - rule2->power_rule.max_antenna_gain);
  79. -
  80. - new_rule->power_rule.max_eirp = min_t(u32, rule1->power_rule.max_eirp,
  81. - rule2->power_rule.max_eirp);
  82. -
  83. - /* Use the flags of both the rules */
  84. - new_rule->flags = rule1->flags | rule2->flags;
  85. -
  86. - /* To be safe, lts use the max cac timeout of both rules */
  87. - new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms,
  88. - rule2->dfs_cac_ms);
  89. -}
  90. -
  91. -static struct ieee80211_regdomain *
  92. -ath11k_regd_intersect(struct ieee80211_regdomain *default_regd,
  93. - struct ieee80211_regdomain *curr_regd)
  94. -{
  95. - u8 num_old_regd_rules, num_curr_regd_rules, num_new_regd_rules;
  96. - struct ieee80211_reg_rule *old_rule, *curr_rule, *new_rule;
  97. - struct ieee80211_regdomain *new_regd = NULL;
  98. - u8 i, j, k;
  99. -
  100. - num_old_regd_rules = default_regd->n_reg_rules;
  101. - num_curr_regd_rules = curr_regd->n_reg_rules;
  102. - num_new_regd_rules = 0;
  103. -
  104. - /* Find the number of intersecting rules to allocate new regd memory */
  105. - for (i = 0; i < num_old_regd_rules; i++) {
  106. - old_rule = default_regd->reg_rules + i;
  107. - for (j = 0; j < num_curr_regd_rules; j++) {
  108. - curr_rule = curr_regd->reg_rules + j;
  109. -
  110. - if (ath11k_reg_can_intersect(old_rule, curr_rule))
  111. - num_new_regd_rules++;
  112. - }
  113. - }
  114. -
  115. - if (!num_new_regd_rules)
  116. - return NULL;
  117. -
  118. - new_regd = kzalloc(sizeof(*new_regd) + (num_new_regd_rules *
  119. - sizeof(struct ieee80211_reg_rule)),
  120. - GFP_ATOMIC);
  121. -
  122. - if (!new_regd)
  123. - return NULL;
  124. -
  125. - /* We set the new country and dfs region directly and only trim
  126. - * the freq, power, antenna gain by intersecting with the
  127. - * default regdomain. Also MAX of the dfs cac timeout is selected.
  128. - */
  129. - new_regd->n_reg_rules = num_new_regd_rules;
  130. - memcpy(new_regd->alpha2, curr_regd->alpha2, sizeof(new_regd->alpha2));
  131. - new_regd->dfs_region = curr_regd->dfs_region;
  132. - new_rule = new_regd->reg_rules;
  133. -
  134. - for (i = 0, k = 0; i < num_old_regd_rules; i++) {
  135. - old_rule = default_regd->reg_rules + i;
  136. - for (j = 0; j < num_curr_regd_rules; j++) {
  137. - curr_rule = curr_regd->reg_rules + j;
  138. -
  139. - if (ath11k_reg_can_intersect(old_rule, curr_rule))
  140. - ath11k_reg_intersect_rules(old_rule, curr_rule,
  141. - (new_rule + k++));
  142. - }
  143. - }
  144. - return new_regd;
  145. -}
  146. -
  147. static const char *
  148. ath11k_reg_get_regdom_str(enum nl80211_dfs_regions dfs_region)
  149. {
  150. @@ -609,9 +486,9 @@ ath11k_reg_update_weather_radar_band(str
  151. struct ieee80211_regdomain *
  152. ath11k_reg_build_regd(struct ath11k_base *ab,
  153. - struct cur_regulatory_info *reg_info, bool intersect)
  154. + struct cur_regulatory_info *reg_info)
  155. {
  156. - struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
  157. + struct ieee80211_regdomain *new_regd = NULL;
  158. struct cur_reg_rule *reg_rule;
  159. u8 i = 0, j = 0, k = 0;
  160. u8 num_rules;
  161. @@ -628,26 +505,26 @@ ath11k_reg_build_regd(struct ath11k_base
  162. num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
  163. if (!num_rules)
  164. - goto ret;
  165. + return new_regd;
  166. /* Add max additional rules to accommodate weather radar band */
  167. if (reg_info->dfs_region == ATH11K_DFS_REG_ETSI)
  168. num_rules += 2;
  169. - tmp_regd = kzalloc(sizeof(*tmp_regd) +
  170. + new_regd = kzalloc(sizeof(*new_regd) +
  171. (num_rules * sizeof(struct ieee80211_reg_rule)),
  172. GFP_ATOMIC);
  173. - if (!tmp_regd)
  174. - goto ret;
  175. + if (!new_regd)
  176. + return new_regd;
  177. - memcpy(tmp_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
  178. + memcpy(new_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
  179. memcpy(alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
  180. alpha2[2] = '\0';
  181. - tmp_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region);
  182. + new_regd->dfs_region = ath11k_map_fw_dfs_region(reg_info->dfs_region);
  183. ath11k_dbg(ab, ATH11K_DBG_REG,
  184. "Country %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n",
  185. - alpha2, ath11k_reg_get_regdom_str(tmp_regd->dfs_region),
  186. + alpha2, ath11k_reg_get_regdom_str(new_regd->dfs_region),
  187. reg_info->dfs_region, num_rules);
  188. /* Update reg_rules[] below. Firmware is expected to
  189. * send these rules in order(2 GHz rules first and then 5 GHz)
  190. @@ -686,7 +563,7 @@ ath11k_reg_build_regd(struct ath11k_base
  191. flags |= ath11k_map_fw_reg_flags(reg_rule->flags);
  192. - ath11k_reg_update_rule(tmp_regd->reg_rules + i,
  193. + ath11k_reg_update_rule(new_regd->reg_rules + i,
  194. reg_rule->start_freq,
  195. reg_rule->end_freq, max_bw,
  196. reg_rule->ant_gain, reg_rule->reg_power,
  197. @@ -701,7 +578,7 @@ ath11k_reg_build_regd(struct ath11k_base
  198. reg_info->dfs_region == ATH11K_DFS_REG_ETSI &&
  199. (reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_LOW &&
  200. reg_rule->start_freq < ETSI_WEATHER_RADAR_BAND_HIGH)){
  201. - ath11k_reg_update_weather_radar_band(ab, tmp_regd,
  202. + ath11k_reg_update_weather_radar_band(ab, new_regd,
  203. reg_rule, &i,
  204. flags, max_bw);
  205. continue;
  206. @@ -712,37 +589,20 @@ ath11k_reg_build_regd(struct ath11k_base
  207. "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n",
  208. i + 1, reg_rule->start_freq, reg_rule->end_freq,
  209. max_bw, reg_rule->ant_gain, reg_rule->reg_power,
  210. - tmp_regd->reg_rules[i].dfs_cac_ms, flags,
  211. + new_regd->reg_rules[i].dfs_cac_ms, flags,
  212. reg_rule->psd_flag, reg_rule->psd_eirp);
  213. } else {
  214. ath11k_dbg(ab, ATH11K_DBG_REG,
  215. "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
  216. i + 1, reg_rule->start_freq, reg_rule->end_freq,
  217. max_bw, reg_rule->ant_gain, reg_rule->reg_power,
  218. - tmp_regd->reg_rules[i].dfs_cac_ms,
  219. + new_regd->reg_rules[i].dfs_cac_ms,
  220. flags);
  221. }
  222. }
  223. - tmp_regd->n_reg_rules = i;
  224. -
  225. - if (intersect) {
  226. - default_regd = ab->default_regd[reg_info->phy_id];
  227. -
  228. - /* Get a new regd by intersecting the received regd with
  229. - * our default regd.
  230. - */
  231. - new_regd = ath11k_regd_intersect(default_regd, tmp_regd);
  232. - kfree(tmp_regd);
  233. - if (!new_regd) {
  234. - ath11k_warn(ab, "Unable to create intersected regdomain\n");
  235. - goto ret;
  236. - }
  237. - } else {
  238. - new_regd = tmp_regd;
  239. - }
  240. + new_regd->n_reg_rules = i;
  241. -ret:
  242. return new_regd;
  243. }
  244. --- a/drivers/net/wireless/ath/ath11k/reg.h
  245. +++ b/drivers/net/wireless/ath/ath11k/reg.h
  246. @@ -30,7 +30,7 @@ void ath11k_reg_free(struct ath11k_base
  247. void ath11k_regd_update_work(struct work_struct *work);
  248. struct ieee80211_regdomain *
  249. ath11k_reg_build_regd(struct ath11k_base *ab,
  250. - struct cur_regulatory_info *reg_info, bool intersect);
  251. + struct cur_regulatory_info *reg_info);
  252. int ath11k_regd_update(struct ath11k *ar);
  253. int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait);
  254. #endif
  255. --- a/drivers/net/wireless/ath/ath11k/wmi.c
  256. +++ b/drivers/net/wireless/ath/ath11k/wmi.c
  257. @@ -6996,24 +6996,12 @@ static void ath11k_wmi_htc_tx_complete(s
  258. wake_up(&wmi->tx_ce_desc_wq);
  259. }
  260. -static bool ath11k_reg_is_world_alpha(char *alpha)
  261. -{
  262. - if (alpha[0] == '0' && alpha[1] == '0')
  263. - return true;
  264. -
  265. - if (alpha[0] == 'n' && alpha[1] == 'a')
  266. - return true;
  267. -
  268. - return false;
  269. -}
  270. -
  271. static int ath11k_reg_chan_list_event(struct ath11k_base *ab,
  272. struct sk_buff *skb,
  273. enum wmi_reg_chan_list_cmd_type id)
  274. {
  275. struct cur_regulatory_info *reg_info = NULL;
  276. struct ieee80211_regdomain *regd = NULL;
  277. - bool intersect = false;
  278. int ret = 0, pdev_idx, i, j;
  279. struct ath11k *ar;
  280. @@ -7075,17 +7063,7 @@ static int ath11k_reg_chan_list_event(st
  281. (char *)reg_info->alpha2, 2))
  282. goto mem_free;
  283. - /* Intersect new rules with default regd if a new country setting was
  284. - * requested, i.e a default regd was already set during initialization
  285. - * and the regd coming from this event has a valid country info.
  286. - */
  287. - if (ab->default_regd[pdev_idx] &&
  288. - !ath11k_reg_is_world_alpha((char *)
  289. - ab->default_regd[pdev_idx]->alpha2) &&
  290. - !ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
  291. - intersect = true;
  292. -
  293. - regd = ath11k_reg_build_regd(ab, reg_info, intersect);
  294. + regd = ath11k_reg_build_regd(ab, reg_info);
  295. if (!regd) {
  296. ath11k_warn(ab, "failed to build regd from reg_info\n");
  297. goto fallback;