瀏覽代碼

qcacmn: Consider freq diff instead of maxbw for autobw correction

Due to the maximun frequency range of reg rule CHAN_5835_5895_1
doesn't support bandwidth 80M, kernel has below check warning:

[ 27.297225] Invalid regulatory domain detected
...
[ 27.297334] __regulatory_set_wiphy_regd+0x168/0x1a0
[ 27.297336] regulatory_set_wiphy_regd+0x28/0x5c
[ 27.297858] hdd_send_wiphy_regd_sync_event+0x284/0x2e0 [wlan]
[ 27.298283] hdd_wlan_startup+0x39c/0x8d8 [wlan]
[ 27.298697] wlan_hdd_pld_probe+0x198/0x2cc [wlan]
[ 27.299106] pld_pcie_probe+0x7c/0xbc [wlan]
[ 27.299122] cnss_pci_call_driver_probe+0xf8/0x504 [cnss2]
[ 27.299136] cnss_pci_dev_powerup+0x1a4/0x24c [cnss2]
[ 27.299149] cnss_pci_register_driver_hdlr+0x4c/0x120 [cnss2]
[ 27.299163] cnss_bus_register_driver_hdlr+0x60/0xb0 [cnss2]
[ 27.299176] cnss_driver_event_work+0x21c/0x6c0 [cnss2]

Fix solution: update the maximum bandwidth of CHAN_5835_5895_1
to 40 and use freq diff instead of maxbw for autobw correction.

Change-Id: I0271f95d565d7789692bd5bfb17a1614f225e9e6
CRs-Fixed: 3082999
Qun Zhang 3 年之前
父節點
當前提交
015424e069
共有 2 個文件被更改,包括 84 次插入0 次删除
  1. 80 0
      umac/regulatory/core/src/reg_build_chan_list.c
  2. 4 0
      umac/regulatory/core/src/reg_db.c

+ 80 - 0
umac/regulatory/core/src/reg_build_chan_list.c

@@ -264,6 +264,85 @@ static void reg_update_max_bw_per_rule(uint32_t num_reg_rules,
 			min(reg_rule_start[count].max_bw, max_bw);
 }
 
+#ifdef CONFIG_REG_CLIENT
+/**
+ * reg_bw_floor() - Calculate floor of a given bandwidth. Find the nearest
+ * bandwidth, from the set = {5, 10, 20, 40, 80, 160, 320}, which is less
+ * than or  equal to the given bandwidth. Any input bandwidth less than 5MHz
+ * is converted to 0.
+ * @in_bw: A positive bandwidth value
+ *
+ * Return: The floor of the given bandwidth.
+ */
+static uint16_t reg_bw_floor(uint16_t in_bw)
+{
+	static const uint16_t chwidth_array[] = {5, 10, 20, 40, 80, 160, 320};
+	int16_t i;
+
+	for (i = QDF_ARRAY_SIZE(chwidth_array) - 1; i >= 0; i--) {
+		if (in_bw >= chwidth_array[i])
+			return chwidth_array[i];
+	}
+	return 0;
+}
+
+/**
+ * reg_find_enhanced_bw() - Given two adjacent reg rules, it first finds the
+ * coalesced bandwidth limited by the country/regulatory domain bandwidth. Then
+ * it finds the nearest discrete bandwidth from the discrete
+ * set = {5, 10, 20, 40, 80, 160, 320} of bandwidths.
+ * @reg_rule_ptr: Pointer to reg rule
+ * @cur_idx: Current index to be considered
+ * @max_reg_bw: Maximum bandwidth of the country/regulatory domain
+ *
+ * Return: Return enhanced bandwidth of the coalesced band
+ */
+static uint16_t reg_find_enhanced_bw(struct cur_reg_rule *reg_rule_ptr,
+				     uint32_t cur_idx,
+				     uint16_t max_reg_bw)
+{
+	uint16_t cur_rule_diff_freq;
+	uint16_t next_rule_diff_freq;
+	uint16_t new_bw;
+	uint16_t enhanced_bw;
+
+	cur_rule_diff_freq = reg_rule_ptr[cur_idx].end_freq -
+			reg_rule_ptr[cur_idx].start_freq;
+	next_rule_diff_freq = reg_rule_ptr[cur_idx + 1].end_freq -
+			reg_rule_ptr[cur_idx + 1].start_freq;
+
+	new_bw = QDF_MIN(max_reg_bw, cur_rule_diff_freq + next_rule_diff_freq);
+	enhanced_bw = reg_bw_floor(new_bw);
+
+	return enhanced_bw;
+}
+
+/**
+ * reg_do_auto_bw_correction() - Calculate and update the maximum bandwidth
+ * value.
+ * @num_reg_rules: Number of regulatory rules.
+ * @reg_rule_ptr: Pointer to regulatory rules.
+ * @max_bw: Maximum bandwidth
+ */
+static void reg_do_auto_bw_correction(uint32_t num_reg_rules,
+				      struct cur_reg_rule *reg_rule_ptr,
+				      uint16_t max_bw)
+{
+	uint32_t count;
+	uint16_t enhanced_bw;
+
+	for (count = 0; count < num_reg_rules - 1; count++) {
+		if (reg_rule_ptr[count].end_freq ==
+		    reg_rule_ptr[count + 1].start_freq) {
+			enhanced_bw = reg_find_enhanced_bw(reg_rule_ptr,
+							   count,
+							   max_bw);
+			reg_rule_ptr[count].max_bw = enhanced_bw;
+			reg_rule_ptr[count + 1].max_bw = enhanced_bw;
+		}
+	}
+}
+#else
 /**
  * reg_do_auto_bw_correction() - Calculate and update the maximum bandwidth
  * value.
@@ -288,6 +367,7 @@ static void reg_do_auto_bw_correction(uint32_t num_reg_rules,
 		}
 	}
 }
+#endif
 
 /**
  * reg_modify_chan_list_for_dfs_channels() - disable the DFS channels if

+ 4 - 0
umac/regulatory/core/src/reg_db.c

@@ -1384,7 +1384,11 @@ const struct regulatory_rule reg_rules_5g[] = {
 	[CHAN_5735_5895_2] = {5735, 5895, 160, 20, REGULATORY_CHAN_NO_IR},
 	[CHAN_5835_5855_1] = {5835, 5855, 20, 30, 0},
 	[CHAN_5835_5855_2] = {5835, 5855, 20, 14, REGULATORY_CHAN_INDOOR_ONLY},
+#ifdef CONFIG_REG_CLIENT
+	[CHAN_5835_5895_1] = {5835, 5895, 40, 30, REGULATORY_CHAN_INDOOR_ONLY},
+#else
 	[CHAN_5835_5895_1] = {5835, 5895, 80, 30, REGULATORY_CHAN_INDOOR_ONLY},
+#endif
 	[CHAN_5850_5925_1] = {5850, 5925, 20, 24, 0},
 	[CHAN_5850_5925_2] = {5850, 5925, 20, 30, 0},
 #if defined(CONFIG_BAND_6GHZ) && defined(COMPILE_REGDB_6G)