Преглед изворни кода

qcacmn: Enable static puncture

Driver receive NL80211_CMD_START_AP to get fixed freq, width and
apply puncture_bitmap from EHT ie, disable punctured 20 MHz sub channels
in regulatory component, and send to F/W by vdev start,  update eht op/he
op/vht op in beacon template.

When start ap, apply puncture to regulatory, set is_static_punctured flag
for all 20 MHz sub channels of current bonded channel in master channel
list of pdev, and disable 20 MHz sub channel in current channel list if
is_static_punctured is set.

When stop ap, remove puncture to regulatory, clear is_static_punctured flag
for all 20 MHz sub channels in master channel list of pdev, and don't
disable 20 MHz sub channel in current channel list if is_static_punctured
is not set.

change-Id: Ia97e7a4fa56a66f343bd648b62216347787ba6d0
CRs-Fixed: 3356755
Jianmin Zhu пре 2 година
родитељ
комит
4e0c4422cf

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

@@ -857,6 +857,32 @@ static void reg_modify_chan_list_for_nol_list(
 	}
 }
 
+#ifdef CONFIG_REG_CLIENT
+/**
+ * reg_modify_chan_list_for_static_puncture() - Disable the channel if
+ * static_puncture is set.
+ * @chan_list: Pointer to regulatory channel list.
+ */
+static void
+reg_modify_chan_list_for_static_puncture(struct regulatory_channel *chan_list)
+{
+	enum channel_enum chan_enum;
+
+	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
+		if (chan_list[chan_enum].is_static_punctured) {
+			chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
+			chan_list[chan_enum].chan_flags |=
+				REGULATORY_CHAN_DISABLED;
+		}
+	}
+}
+#else
+static void
+reg_modify_chan_list_for_static_puncture(struct regulatory_channel *chan_list)
+{
+}
+#endif
+
 /**
  * reg_find_low_limit_chan_enum() - Find low limit 2G and 5G channel enums.
  * @chan_list: Pointer to regulatory channel list.
@@ -2924,6 +2950,7 @@ void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj
 					      pdev_priv_obj->dfs_enabled);
 
 	reg_modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list);
+	reg_modify_chan_list_for_static_puncture(pdev_priv_obj->cur_chan_list);
 
 	reg_modify_chan_list_for_indoor_channels(pdev_priv_obj);
 

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

@@ -4833,6 +4833,86 @@ static void reg_update_5g_bonded_channel_state_punc_for_pwrmode(
 	}
 }
 #endif
+
+#ifdef CONFIG_REG_CLIENT
+QDF_STATUS reg_apply_puncture(struct wlan_objmgr_pdev *pdev,
+			      uint16_t puncture_bitmap,
+			      qdf_freq_t freq,
+			      enum phy_ch_width bw,
+			      qdf_freq_t cen320_freq)
+{
+	const struct bonded_channel_freq *bonded_chan;
+	qdf_freq_t chan_cfreq;
+	enum channel_enum chan_enum;
+	struct regulatory_channel *mas_chan_list;
+	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+	bool is_puncture;
+	uint16_t i = 0;
+
+	pdev_priv_obj = reg_get_pdev_obj(pdev);
+
+	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
+		reg_err_rl("pdev reg obj is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mas_chan_list = pdev_priv_obj->mas_chan_list;
+	if (!mas_chan_list) {
+		reg_err_rl("mas chan_list is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	bonded_chan = reg_get_bonded_chan_entry(freq, bw, cen320_freq);
+	if (!bonded_chan) {
+		reg_err_rl("bonded chan fails, freq %d, bw %d, cen320_freq %d",
+			   freq, bw, cen320_freq);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	chan_cfreq = bonded_chan->start_freq;
+	while (chan_cfreq <= bonded_chan->end_freq) {
+		is_puncture = BIT(i) & puncture_bitmap;
+		if (is_puncture) {
+			chan_enum = reg_get_chan_enum_for_freq(chan_cfreq);
+			mas_chan_list[chan_enum].is_static_punctured = true;
+		}
+		i++;
+		chan_cfreq = chan_cfreq + BW_20_MHZ;
+	}
+
+	reg_compute_pdev_current_chan_list(pdev_priv_obj);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS reg_remove_puncture(struct wlan_objmgr_pdev *pdev)
+{
+	enum channel_enum chan_enum;
+	struct regulatory_channel *mas_chan_list;
+	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+
+	pdev_priv_obj = reg_get_pdev_obj(pdev);
+
+	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
+		reg_err_rl("pdev reg obj is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mas_chan_list = pdev_priv_obj->mas_chan_list;
+	if (!mas_chan_list) {
+		reg_err_rl("mas chan_list is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++)
+		if (mas_chan_list[chan_enum].is_static_punctured)
+			mas_chan_list[chan_enum].is_static_punctured = false;
+
+	reg_compute_pdev_current_chan_list(pdev_priv_obj);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 #else
 static void reg_update_5g_bonded_channel_state_punc_for_freq(
 			struct wlan_objmgr_pdev *pdev,

+ 36 - 0
umac/regulatory/core/src/reg_services_common.h

@@ -1233,6 +1233,42 @@ QDF_STATUS reg_extract_puncture_by_bw(enum phy_ch_width ori_bw,
  */
 void reg_set_create_punc_bitmap(struct ch_params *ch_params,
 				bool is_create_punc_bitmap);
+
+#ifdef CONFIG_REG_CLIENT
+/**
+ * reg_apply_puncture() - apply puncture to regulatory
+ * @pdev: pdev
+ * @puncture_bitmap: puncture bitmap
+ * @freq: sap operation freq
+ * @bw: band width
+ * @cen320_freq: 320 MHz center freq
+ *
+ * When start ap, apply puncture to regulatory, set static puncture flag
+ * for all 20 MHz sub channels of current bonded channel in master channel list
+ * of pdev, and disable 20 MHz sub channel in current channel list if static
+ * puncture flag is set.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS reg_apply_puncture(struct wlan_objmgr_pdev *pdev,
+			      uint16_t puncture_bitmap,
+			      qdf_freq_t freq,
+			      enum phy_ch_width bw,
+			      qdf_freq_t cen320_freq);
+
+/**
+ * wlan_reg_remove_puncture() - Remove puncture from regulatory
+ * @pdev: pdev
+ *
+ * When stop ap, remove puncture from regulatory, clear static puncture flag
+ * for all 20 MHz sub channels in master channel list of pdev, and don't disable
+ * 20 MHz sub channel in current channel list if static puncture flag is not
+ * set.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS reg_remove_puncture(struct wlan_objmgr_pdev *pdev);
+#endif
 #else
 static inline
 QDF_STATUS reg_extract_puncture_by_bw(enum phy_ch_width ori_bw,

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

@@ -971,6 +971,7 @@ struct get_usable_chan_req_params {
  *                   intolerance.
  * @psd_flag: is PSD channel or not
  * @psd_eirp: PSD power level
+ * @is_static_punctured: is static punctured
  */
 struct regulatory_channel {
 	qdf_freq_t center_freq;
@@ -991,6 +992,9 @@ struct regulatory_channel {
 	bool psd_flag;
 	uint16_t psd_eirp;
 #endif
+#ifdef CONFIG_REG_CLIENT
+	uint8_t is_static_punctured;
+#endif
 };
 
 /** struct ap_cli_pwr_mode_info: AP and client power mode information

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

@@ -1643,6 +1643,58 @@ QDF_STATUS wlan_reg_extract_puncture_by_bw(enum phy_ch_width ori_bw,
  */
 void wlan_reg_set_create_punc_bitmap(struct ch_params *ch_params,
 				     bool is_create_punc_bitmap);
+
+#ifdef CONFIG_REG_CLIENT
+/**
+ * wlan_reg_apply_puncture() - apply puncture to regulatory
+ * @pdev: pdev
+ * @puncture_bitmap: puncture bitmap
+ * @freq: sap operation freq
+ * @bw: band width
+ * @cen320_freq: 320 MHz center freq
+ *
+ * When start ap, apply puncture to regulatory, set static puncture flag
+ * for all 20 MHz sub channels of current bonded channel in master channel list
+ * of pdev, and disable 20 MHz sub channel in current channel list if static
+ * puncture flag is set.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_reg_apply_puncture(struct wlan_objmgr_pdev *pdev,
+				   uint16_t puncture_bitmap,
+				   qdf_freq_t freq,
+				   enum phy_ch_width bw,
+				   qdf_freq_t cen320_freq);
+
+/**
+ * wlan_reg_remove_puncture() - Remove puncture from regulatory
+ * @pdev: pdev
+ *
+ * When stop ap, remove puncture from regulatory, clear static puncture flag
+ * for all 20 MHz sub channels in master channel list of pdev, and don't disable
+ * 20 MHz sub channel in current channel list if static puncture flag is not
+ * set.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_reg_remove_puncture(struct wlan_objmgr_pdev *pdev);
+#else
+static inline
+QDF_STATUS wlan_reg_apply_puncture(struct wlan_objmgr_pdev *pdev,
+				   uint16_t puncture_bitmap,
+				   qdf_freq_t freq,
+				   enum phy_ch_width bw,
+				   qdf_freq_t cen320_freq)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS wlan_reg_remove_puncture(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 #ifdef CONFIG_REG_6G_PWRMODE
 /**
  * wlan_reg_fill_channel_list_for_pwrmode() - Fills the reg_channel_list
@@ -1685,6 +1737,22 @@ static inline void wlan_reg_set_create_punc_bitmap(struct ch_params *ch_params,
 {
 }
 
+static inline
+QDF_STATUS wlan_reg_apply_puncture(struct wlan_objmgr_pdev *pdev,
+				   uint16_t puncture_bitmap,
+				   qdf_freq_t freq,
+				   enum phy_ch_width bw,
+				   qdf_freq_t cen320_freq)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS wlan_reg_remove_puncture(struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
 static inline
 uint16_t wlan_reg_find_nearest_puncture_pattern(enum phy_ch_width bw,
 						uint16_t proposed_bitmap)

+ 17 - 0
umac/regulatory/dispatcher/src/wlan_reg_services_api.c

@@ -1384,6 +1384,23 @@ void wlan_reg_set_create_punc_bitmap(struct ch_params *ch_params,
 {
 	reg_set_create_punc_bitmap(ch_params, is_create_punc_bitmap);
 }
+
+#ifdef CONFIG_REG_CLIENT
+QDF_STATUS wlan_reg_apply_puncture(struct wlan_objmgr_pdev *pdev,
+				   uint16_t puncture_bitmap,
+				   qdf_freq_t freq,
+				   enum phy_ch_width bw,
+				   qdf_freq_t cen320_freq)
+{
+	return reg_apply_puncture(pdev, puncture_bitmap, freq, bw,
+				  cen320_freq);
+}
+
+QDF_STATUS wlan_reg_remove_puncture(struct wlan_objmgr_pdev *pdev)
+{
+	return reg_remove_puncture(pdev);
+}
+#endif
 #endif /* WLAN_FEATURE_11BE */
 
 #ifdef CONFIG_REG_6G_PWRMODE