Quellcode durchsuchen

qcacmn: Refine 5g bonded channel state with static puncturing

Refine reg_get_5g_bonded_channel_state_for_freq with static puncturing.
Update channel state as CHANNEL_STATE_DFS or CHANNEL_STATE_ENABLE if
its puncture bitmap is valid with given bandwidth.

Change-Id: I3503c8bcf6094b9c98056809f1c304747ba97667
CRs-Fixed: 3106240
Bing Sun vor 3 Jahren
Ursprung
Commit
fd0ac6014b

+ 238 - 3
umac/regulatory/core/src/reg_services_common.c

@@ -188,6 +188,137 @@ struct bw_bonded_array_pair bw_bonded_array_pair_map[] = {
 		QDF_ARRAY_SIZE(bonded_chan_40mhz_list_freq)},
 };
 
+#ifdef WLAN_FEATURE_11BE
+/** Binary bitmap pattern
+ * 1: Punctured 20Mhz chan 0:non-Punctured 20Mhz Chan
+ *
+ * Band: 80MHz  Puncturing Unit: 20Mhz
+ *  B0001 = 0x1  : BIT(0)
+ *  B0010 = 0x2  : BIT(1)
+ *  B0100 = 0x4  : BIT(2)
+ *  B1000 = 0x8  : BIT(3)
+ *
+ * Band: 160MHz  Puncturing Unit: 20Mhz
+ *  B0000_0001 = 0x01  : BIT(0)
+ *  B0000_0010 = 0x02  : BIT(1)
+ *  B0000_0100 = 0x04  : BIT(2)
+ *  B0000_1000 = 0x08  : BIT(3)
+ *  B0001_0000 = 0x10  : BIT(4)
+ *  B0010_0000 = 0x20  : BIT(5)
+ *  B0100_0000 = 0x40  : BIT(6)
+ *  B1000_0000 = 0x80  : BIT(7)
+ *
+ * Band: 160MHz  Puncturing Unit: 40Mhz
+ *  B0000_0011 = 0x03  : BIT(0) | BIT(1)
+ *  B0000_1100 = 0x0C  : BIT(2) | BIT(3)
+ *  B0011_0000 = 0x30  : BIT(4) | BIT(5)
+ *  B1100_0000 = 0xC0  : BIT(6) | BIT(7)
+ *
+ * Band: 320MHz  Puncturing Unit: 40Mhz
+ *  B0000_0000_0000_0011 = 0x0003  : BIT(0)  | BIT(1)
+ *  B0000_0000_0000_1100 = 0x000C  : BIT(2)  | BIT(3)
+ *  B0000_0000_0011_0000 = 0x0030  : BIT(4)  | BIT(5)
+ *  B0000_0000_1100_0000 = 0x00C0  : BIT(6)  | BIT(7)
+ *  B0000_0011_0000_0000 = 0x0300  : BIT(8)  | BIT(9)
+ *  B0000_1100_0000_0000 = 0x0C00  : BIT(10) | BIT(11)
+ *  B0011_0000_0000_0000 = 0x3000  : BIT(12) | BIT(13)
+ *  B1100_0000_0000_0000 = 0xC000  : BIT(13) | BIT(15)
+ *
+ * Band: 320MHz  Puncturing Unit: 80Mhz
+ *  B0000_0000_0000_1111 = 0x000F  : BIT(0)  | BIT(1) | BIT(2) | BIT(3)
+ *  B0000_0000_1111_0000 = 0x00F0  : BIT(4)  | BIT(5) | BIT(6) | BIT(7)
+ *  B0000_1111_0000_0000 = 0x0F00  : BIT(8)  | BIT(9) | BIT(10) | BIT(11)
+ *  B1111_0000_0000_0000 = 0xF000  : BIT(12) | BIT(13) | BIT(14) | BIT(15)
+ *
+ * Band: 320MHz  Puncturing Unit: 80Mhz+40Mhz (Right 80Mhz punctured)
+ *  B0000_0000_0011_1111 = 0x003F  : BIT(4)  | BIT(5)   [right 80MHz: BIT(0) | BIT(1) | BIT(2) | BIT(3)]
+ *  B0000_0000_1100_1111 = 0x00CF  : BIT(6)  | BIT(7)   [right 80MHz: BIT(0) | BIT(1) | BIT(2) | BIT(3)]
+ *  B0000_0011_0000_1111 = 0x030F  : BIT(8)  | BIT(9)   [right 80MHz: BIT(0) | BIT(1) | BIT(2) | BIT(3)]
+ *  B0000_1100_0000_1111 = 0x0C0F  : BIT(10) | BIT(11)  [right 80MHz: BIT(0) | BIT(1) | BIT(2) | BIT(3)]
+ *  B0011_0000_0000_1111 = 0x300F  : BIT(12) | BIT(13)  [right 80MHz: BIT(0) | BIT(1) | BIT(2) | BIT(3)]
+ *  B1100_0000_0000_1111 = 0xC00F  : BIT(14) | BIT(15)  [right 80MHz: BIT(0) | BIT(1) | BIT(2) | BIT(3)]
+ *
+ * Band: 320MHz  Puncturing Unit: 80Mhz+40Mhz (Left 80Mhz punctured)
+ *  B1111_0000_0000_0011 = 0xF003  : BIT(4)  | BIT(5)   [left 80MHz: BIT(12) | BIT(13) | BIT(14) | BIT(15)]
+ *  B1111_0000_0000_1100 = 0xF00C  : BIT(6)  | BIT(7)   [left 80MHz: BIT(12) | BIT(13) | BIT(14) | BIT(15)]
+ *  B1111_0000_0011_0000 = 0xF030  : BIT(8)  | BIT(9)   [left 80MHz: BIT(12) | BIT(13) | BIT(14) | BIT(15)]
+ *  B1111_0000_1100_0000 = 0xF0C0  : BIT(10) | BIT(11)  [left 80MHz: BIT(12) | BIT(13) | BIT(14) | BIT(15)]
+ *  B1111_0011_0000_0000 = 0xF300  : BIT(12) | BIT(13)  [left 80MHz: BIT(12) | BIT(13) | BIT(14) | BIT(15)]
+ *  B1111_1100_0000_0000 = 0xFC00  : BIT(14) | BIT(15)  [left 80MHz: BIT(12) | BIT(13) | BIT(14) | BIT(15)]
+ */
+static const uint16_t chan_80mhz_puncture_bitmap[] = {
+	/* 20Mhz puncturing pattern */
+	0x1,
+	0x2,
+	0x4,
+	0x8
+};
+
+static const uint16_t chan_160mhz_puncture_bitmap[] = {
+	/* 20Mhz puncturing pattern */
+	0x1,
+	0x2,
+	0x4,
+	0x8,
+	0x10,
+	0x20,
+	0x40,
+	0x80,
+	/* 40Mhz puncturing pattern */
+	0x3,
+	0xc,
+	0x30,
+	0xc0
+};
+
+static const uint16_t chan_320mhz_puncture_bitmap[] = {
+	/* 40Mhz puncturing pattern */
+	0x3,
+	0xc,
+	0x30,
+	0xc0,
+	0x300,
+	0xc00,
+	0x3000,
+	0xc000,
+	/* 80Mhz puncturing pattern */
+	0xf,
+	0xf0,
+	0xf00,
+	0xf000,
+	/* 80+40Mhz puncturing pattern: Right 80MHz punctured */
+	0x3f,
+	0xcf,
+	0x30f,
+	0xc0f,
+	0x300f,
+	0xc00f,
+	/* 80+40Mhz puncturing pattern: Left 80MHz punctured */
+	0xf003,
+	0xf00c,
+	0xf030,
+	0xf0c0,
+	0xf300,
+	0xfc00
+};
+
+struct bw_puncture_bitmap_pair {
+	enum phy_ch_width chwidth;
+	const uint16_t *puncture_bitmap_arr;
+	uint16_t array_size;
+};
+
+static const
+struct bw_puncture_bitmap_pair bw_puncture_bitmap_pair_map[] = {
+	{CH_WIDTH_320MHZ, chan_320mhz_puncture_bitmap,
+		QDF_ARRAY_SIZE(chan_320mhz_puncture_bitmap)},
+	{CH_WIDTH_160MHZ, chan_160mhz_puncture_bitmap,
+		QDF_ARRAY_SIZE(chan_160mhz_puncture_bitmap)},
+	{CH_WIDTH_80MHZ, chan_80mhz_puncture_bitmap,
+		QDF_ARRAY_SIZE(chan_80mhz_puncture_bitmap)},
+};
+#endif /* WLAN_FEATURE_11BE */
+
 const struct bonded_channel_freq *
 reg_get_bonded_chan_entry(qdf_freq_t freq,
 			  enum phy_ch_width chwidth)
@@ -3525,11 +3656,102 @@ reg_get_5g_bonded_chan_array_for_freq(struct wlan_objmgr_pdev *pdev,
 	return chan_state;
 }
 
+#ifdef WLAN_FEATURE_11BE
+void reg_set_create_punc_bitmap(struct ch_params *ch_params,
+				bool is_create_punc_bitmap)
+{
+	ch_params->is_create_punc_bitmap = is_create_punc_bitmap;
+}
+
+bool reg_is_punc_bitmap_valid(enum phy_ch_width bw, uint16_t puncture_bitmap)
+{
+	int i, num_bws;
+	const uint16_t *bonded_puncture_bitmap = NULL;
+	uint16_t array_size = 0;
+	bool is_punc_bitmap_valid = false;
+
+	num_bws = QDF_ARRAY_SIZE(bw_puncture_bitmap_pair_map);
+	for (i = 0; i < num_bws; i++) {
+		if (bw == bw_puncture_bitmap_pair_map[i].chwidth) {
+			bonded_puncture_bitmap =
+			    bw_puncture_bitmap_pair_map[i].puncture_bitmap_arr;
+			array_size = bw_puncture_bitmap_pair_map[i].array_size;
+			break;
+		}
+	}
+
+	if (array_size && bonded_puncture_bitmap) {
+		for (i = 0; i < array_size; i++) {
+			if (puncture_bitmap == bonded_puncture_bitmap[i]) {
+				is_punc_bitmap_valid = true;
+				break;
+			}
+		}
+	}
+
+	return is_punc_bitmap_valid;
+}
+
+/**
+ * reg_update_5g_bonded_channel_state_punc() - update channel state with
+ *                                             static puncturing feature
+ * @pdev: pointer to pdev
+ * @bonded_chan_ptr: Pointer to bonded_channel_freq.
+ * @ch_params: pointer to ch_params
+ * @chan_state: chan_state to be updated
+ *
+ * Return: void
+ */
+static void reg_update_5g_bonded_channel_state_punc(
+			struct wlan_objmgr_pdev *pdev,
+			const struct bonded_channel_freq *bonded_chan_ptr,
+			struct ch_params *ch_params,
+			enum channel_state *chan_state)
+{
+	qdf_freq_t chan_cfreq;
+	enum channel_state temp_chan_state;
+	uint16_t puncture_bitmap = 0;
+	int i = 0;
+	enum channel_state update_state = CHANNEL_STATE_ENABLE;
+
+	if (!pdev || !bonded_chan_ptr || !ch_params || !chan_state ||
+	    !ch_params->is_create_punc_bitmap)
+		return;
+
+	chan_cfreq =  bonded_chan_ptr->start_freq;
+	while (chan_cfreq <= bonded_chan_ptr->end_freq) {
+		temp_chan_state = reg_get_channel_state_for_freq(pdev,
+								 chan_cfreq);
+		if (!reg_is_state_allowed(temp_chan_state))
+			puncture_bitmap |= BIT(i);
+		/* Remember of any of the sub20 channel is a DFS channel */
+		if (temp_chan_state == CHANNEL_STATE_DFS)
+			update_state = CHANNEL_STATE_DFS;
+		chan_cfreq = chan_cfreq + BW_20_MHZ;
+		i++;
+	}
+	/* Validate puncture bitmap. Update channel state. */
+	if (reg_is_punc_bitmap_valid(ch_params->ch_width, puncture_bitmap)) {
+		*chan_state = update_state;
+		ch_params->reg_punc_bitmap = puncture_bitmap;
+	}
+}
+#else
+static void reg_update_5g_bonded_channel_state_punc(
+			struct wlan_objmgr_pdev *pdev,
+			const struct bonded_channel_freq *bonded_chan_ptr,
+			struct ch_params *ch_params,
+			enum channel_state *chan_state)
+{
+}
+#endif
+
 enum channel_state
 reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 					 qdf_freq_t freq,
-					 enum phy_ch_width bw)
+					 struct ch_params *ch_params)
 {
+	enum phy_ch_width bw;
 	enum channel_enum ch_indx;
 	enum channel_state chan_state;
 	struct regulatory_channel *reg_channels;
@@ -3537,6 +3759,11 @@ reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 	bool bw_enabled = false;
 	const struct bonded_channel_freq *bonded_chan_ptr = NULL;
 
+	if (!ch_params) {
+		reg_err_rl("Invalid ch_params");
+		return CHANNEL_STATE_INVALID;
+	}
+	bw = ch_params->ch_width;
 	if (bw > CH_WIDTH_80P80MHZ) {
 		reg_err_rl("bw (%d) passed is not good", bw);
 		return CHANNEL_STATE_INVALID;
@@ -3545,6 +3772,9 @@ reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 	chan_state = reg_get_5g_bonded_channel_for_freq(pdev, freq, bw,
 							&bonded_chan_ptr);
 
+	reg_update_5g_bonded_channel_state_punc(pdev, bonded_chan_ptr,
+						ch_params, &chan_state);
+
 	if ((chan_state == CHANNEL_STATE_INVALID) ||
 	    (chan_state == CHANNEL_STATE_DISABLE))
 		return chan_state;
@@ -4233,13 +4463,18 @@ static void reg_set_5g_channel_params_for_freq(struct wlan_objmgr_pdev *pdev,
 				&bonded_chan_ptr);
 
 		chan_state = reg_get_5g_bonded_channel_state_for_freq(
-				pdev, freq, ch_params->ch_width);
+				pdev, freq, ch_params);
 
 		if (ch_params->ch_width == CH_WIDTH_80P80MHZ) {
+			struct ch_params temp_ch_params = {0};
+
+			temp_ch_params.ch_width = CH_WIDTH_80MHZ;
+			/* Puncturing patter is not needed for 80+80 */
+			reg_set_create_punc_bitmap(&temp_ch_params, false);
 			chan_state2 = reg_get_5g_bonded_channel_state_for_freq(
 					pdev, ch_params->mhz_freq_seg1 -
 					NEAREST_20MHZ_CHAN_FREQ_OFFSET,
-					CH_WIDTH_80MHZ);
+					&temp_ch_params);
 
 			chan_state = reg_combine_channel_states(
 					chan_state, chan_state2);

+ 26 - 2
umac/regulatory/core/src/reg_services_common.h

@@ -877,14 +877,14 @@ enum channel_state reg_get_channel_state_from_secondary_list_for_freq(
  * 5G bonded channel using the channel frequency
  * @pdev: Pointer to pdev
  * @freq: channel center frequency.
- * @bw: channel band width
+ * @ch_params: channel parameters
  *
  * Return: channel state
  */
 enum channel_state
 reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 					 qdf_freq_t freq,
-					 enum phy_ch_width bw);
+					 struct ch_params *ch_params);
 
 /**
  * reg_get_2g_bonded_channel_state_for_freq() - Get channel state for 2G
@@ -943,6 +943,30 @@ reg_fill_channel_list(struct wlan_objmgr_pdev *pdev,
 		      enum phy_ch_width ch_width,
 		      qdf_freq_t band_center_320,
 		      struct reg_channel_list *chan_list);
+
+/**
+ * reg_is_punc_bitmap_valid() - is puncture bitmap valid or not
+ * @bw: Input channel width.
+ * @puncture_bitmap Input puncture bitmap.
+ *
+ * Return: true if given puncture bitmap is valid
+ */
+bool reg_is_punc_bitmap_valid(enum phy_ch_width bw, uint16_t puncture_bitmap);
+
+/**
+ * reg_set_create_punc_bitmap() - set is_create_punc_bitmap of ch_params
+ * @ch_params: ch_params to set
+ * @is_create_punc_bitmap: is create punc bitmap
+ *
+ * Return: NULL
+ */
+void reg_set_create_punc_bitmap(struct ch_params *ch_params,
+				bool is_create_punc_bitmap);
+#else
+static inline void reg_set_create_punc_bitmap(struct ch_params *ch_params,
+					      bool is_create_punc_bitmap)
+{
+}
 #endif
 /**
  * reg_get_channel_reg_power_for_freq() - Get the txpower for the given channel

+ 4 - 0
umac/regulatory/dispatcher/inc/reg_services_public_struct.h

@@ -637,6 +637,9 @@ struct freq_range {
  * @mhz_freq_seg0: Center frequency for segment 0
  * @mhz_freq_seg1: Center frequency for segment 1
  * @reg_punc_bitmap: Output puncturing bitmap
+ * @is_create_punc_bitmap: Whether puncturing bitmap is to be created or not
+ *                         Parameter 'reg_punc_bitmap' is valid only if
+ *                         is_create_punc_bitmap is true
  */
 struct ch_params {
 	enum phy_ch_width ch_width;
@@ -647,6 +650,7 @@ struct ch_params {
 	qdf_freq_t mhz_freq_seg1;
 #ifdef WLAN_FEATURE_11BE
 	uint16_t reg_punc_bitmap;
+	bool is_create_punc_bitmap;
 #endif
 };
 

+ 25 - 0
umac/regulatory/dispatcher/inc/wlan_reg_services_api.h

@@ -1346,6 +1346,31 @@ void wlan_reg_fill_channel_list(struct wlan_objmgr_pdev *pdev,
 				enum phy_ch_width ch_width,
 				qdf_freq_t band_center_320,
 				struct reg_channel_list *chan_list);
+
+/**
+ * wlan_reg_is_punc_bitmap_valid() - is puncture bitmap valid or not
+ * @bw: Input channel width.
+ * @puncture_bitmap Input puncture bitmap.
+ *
+ * Return: true if given puncture bitmap is valid
+ */
+bool wlan_reg_is_punc_bitmap_valid(enum phy_ch_width bw,
+				   uint16_t puncture_bitmap);
+
+/**
+ * wlan_reg_set_create_punc_bitmap() - set is_create_punc_bitmap of ch_params
+ * @ch_params: ch_params to set
+ * @is_create_punc_bitmap: is create punc bitmap
+ *
+ * Return: NULL
+ */
+void wlan_reg_set_create_punc_bitmap(struct ch_params *ch_params,
+				     bool is_create_punc_bitmap);
+#else
+static inline void wlan_reg_set_create_punc_bitmap(struct ch_params *ch_params,
+						   bool is_create_punc_bitmap)
+{
+}
 #endif
 
 /**

+ 36 - 6
umac/regulatory/dispatcher/src/wlan_reg_services_api.c

@@ -1093,13 +1093,18 @@ wlan_reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 					      qdf_freq_t freq,
 					      enum phy_ch_width bw)
 {
+	struct ch_params params = {0};
+
 	if (bw == CH_WIDTH_320MHZ) {
 		const struct bonded_channel_freq *bonded_chan_ptr_ptr = NULL;
 
 		return reg_get_5g_bonded_channel_for_freq(pdev, freq, bw,
 							  &bonded_chan_ptr_ptr);
 	}
-	return reg_get_5g_bonded_channel_state_for_freq(pdev, freq, bw);
+
+	params.ch_width = bw;
+
+	return reg_get_5g_bonded_channel_state_for_freq(pdev, freq, &params);
 }
 
 qdf_export_symbol(wlan_reg_get_5g_bonded_channel_state_for_freq);
@@ -1111,7 +1116,11 @@ wlan_reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 					      qdf_freq_t freq,
 					      enum phy_ch_width bw)
 {
-	return reg_get_5g_bonded_channel_state_for_freq(pdev, freq, bw);
+	struct ch_params params = {0};
+
+	params.ch_width = bw;
+
+	return reg_get_5g_bonded_channel_state_for_freq(pdev, freq, &params);
 }
 
 qdf_export_symbol(wlan_reg_get_5g_bonded_channel_state_for_freq);
@@ -1150,6 +1159,18 @@ void wlan_reg_fill_channel_list(struct wlan_objmgr_pdev *pdev,
 	reg_fill_channel_list(pdev, freq, sec_ch_2g_freq, ch_width,
 			      band_center_320, chan_list);
 }
+
+bool wlan_reg_is_punc_bitmap_valid(enum phy_ch_width bw,
+				   uint16_t puncture_bitmap)
+{
+	return reg_is_punc_bitmap_valid(bw, puncture_bitmap);
+}
+
+void wlan_reg_set_create_punc_bitmap(struct ch_params *ch_params,
+				     bool is_create_punc_bitmap)
+{
+	reg_set_create_punc_bitmap(ch_params, is_create_punc_bitmap);
+}
 #endif
 
 enum channel_state
@@ -1276,8 +1297,12 @@ wlan_reg_get_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 		return reg_get_5g_bonded_channel_for_freq(pdev, freq, bw,
 							  &bonded_chan_ptr_ptr);
 	} else {
+		struct ch_params params = {0};
+
+		params.ch_width = bw;
+
 		return reg_get_5g_bonded_channel_state_for_freq(pdev, freq,
-								bw);
+								&params);
 	}
 }
 
@@ -1290,12 +1315,17 @@ wlan_reg_get_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 					   enum phy_ch_width bw,
 					   qdf_freq_t sec_freq)
 {
-	if (WLAN_REG_IS_24GHZ_CH_FREQ(freq))
+	if (WLAN_REG_IS_24GHZ_CH_FREQ(freq)) {
 		return reg_get_2g_bonded_channel_state_for_freq(pdev, freq,
 						       sec_freq, bw);
-	else
+	} else {
+		struct ch_params params = {0};
+
+		params.ch_width = bw;
+
 		return reg_get_5g_bonded_channel_state_for_freq(pdev, freq,
-						       bw);
+								&params);
+	}
 }
 
 qdf_export_symbol(wlan_reg_get_5g_bonded_channel_and_state_for_freq);