瀏覽代碼

qcacmn: Fill correct max BW to set channel params

Currently wifi positioning api to update channel bandwidth
info is invoking regulatory component api to set the channel
params with BW as CH_WIDTH_MAX, because of which regulatory
component is returning the maximum BW supported for the current
regdomain which is 160MHz. If target does not support 160MHz in
that case it may lead to undefined behavior.

To address this issue, pass max supported BW by target as
argument to regulatory component so that regulatory component
does not return the BW greater then the target supported BW.

CRs-Fixed: 2730665
Change-Id: I6051336ab2f3ea902a70ed80290e5a5f060de5b9
Ashish Kumar Dhanotiya 5 年之前
父節點
當前提交
dc2d337116

+ 11 - 0
target_if/wifi_pos/inc/target_if_wifi_pos.h

@@ -26,6 +26,7 @@
 
 #include "qdf_types.h"
 #include "qdf_status.h"
+#include "wlan_cmn.h"
 struct oem_data_req;
 struct oem_data_rsp;
 struct wlan_objmgr_psoc;
@@ -61,6 +62,16 @@ QDF_STATUS target_if_wifi_pos_register_events(struct wlan_objmgr_psoc *psoc);
 QDF_STATUS target_if_wifi_pos_deregister_events(struct wlan_objmgr_psoc *psoc);
 
 
+/**
+ * target_if_wifi_pos_get_vht_ch_width: function to get vht channel width
+ * @psoc: pointer to psoc object
+ * @ch_width: pointer to the variable in which output value needs to be filled
+ *
+ * Return: status of operation
+ */
+QDF_STATUS target_if_wifi_pos_get_vht_ch_width(struct wlan_objmgr_psoc *psoc,
+					       enum phy_ch_width *ch_width);
+
 /**
  * target_if_wifi_pos_register_tx_ops: function to register with lmac tx ops
  * @tx_ops: lmac tx ops struct object

+ 29 - 0
target_if/wifi_pos/src/target_if_wifi_pos.c

@@ -320,6 +320,8 @@ void target_if_wifi_pos_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
 		target_if_wifi_pos_convert_pdev_id_host_to_target;
 	wifi_pos_tx_ops->wifi_pos_convert_pdev_id_target_to_host =
 		target_if_wifi_pos_convert_pdev_id_target_to_host;
+	wifi_pos_tx_ops->wifi_pos_get_vht_ch_width =
+		target_if_wifi_pos_get_vht_ch_width;
 
 }
 
@@ -416,6 +418,33 @@ QDF_STATUS target_if_wifi_pos_deregister_events(struct wlan_objmgr_psoc *psoc)
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS target_if_wifi_pos_get_vht_ch_width(struct wlan_objmgr_psoc *psoc,
+					       enum phy_ch_width *ch_width)
+{
+	struct target_psoc_info *tgt_hdl;
+	int vht_cap_info;
+
+	*ch_width = CH_WIDTH_INVALID;
+
+	if (!psoc)
+		return QDF_STATUS_E_INVAL;
+
+	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
+	if (!tgt_hdl)
+		return QDF_STATUS_E_INVAL;
+
+	*ch_width = CH_WIDTH_80MHZ;
+
+	vht_cap_info = target_if_get_vht_cap_info(tgt_hdl);
+
+	if (vht_cap_info & WLAN_VHTCAP_SUP_CHAN_WIDTH_80_160)
+		*ch_width = CH_WIDTH_80P80MHZ;
+	else if (vht_cap_info & WLAN_VHTCAP_SUP_CHAN_WIDTH_160)
+		*ch_width = CH_WIDTH_160MHZ;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 #ifndef CNSS_GENL
 QDF_STATUS target_if_wifi_pos_convert_pdev_id_host_to_target(
 		struct wlan_objmgr_psoc *psoc, uint32_t host_pdev_id,

+ 3 - 0
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -712,6 +712,7 @@ struct wlan_lmac_if_iot_sim_tx_ops {
  * pdev_id from host pdev_id.
  * @wifi_pos_convert_pdev_id_target_to_host: function pointer to get host
  * pdev_id from target pdev_id.
+ * @wifi_pos_get_vht_ch_width: Function pointer to get max supported bw by FW
  */
 struct wlan_lmac_if_wifi_pos_tx_ops {
 	QDF_STATUS (*data_req_tx)(struct wlan_objmgr_pdev *pdev,
@@ -724,6 +725,8 @@ struct wlan_lmac_if_wifi_pos_tx_ops {
 	QDF_STATUS (*wifi_pos_convert_pdev_id_target_to_host)(
 			struct wlan_objmgr_psoc *psoc, uint32_t target_pdev_id,
 			uint32_t *host_pdev_id);
+	QDF_STATUS (*wifi_pos_get_vht_ch_width)(struct wlan_objmgr_psoc *psoc,
+						enum phy_ch_width *ch_width);
 };
 #endif
 

+ 28 - 2
umac/wifi_pos/src/wifi_pos_main.c

@@ -396,6 +396,26 @@ QDF_STATUS wifi_pos_send_report_resp(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
+static QDF_STATUS wifi_pos_get_vht_ch_width(struct wlan_objmgr_psoc *psoc,
+					    enum phy_ch_width *ch_width)
+{
+	struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops;
+
+	tx_ops = wifi_pos_get_tx_ops(psoc);
+	if (!tx_ops) {
+		qdf_print("tx ops null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!tx_ops->wifi_pos_get_vht_ch_width) {
+		wifi_pos_err("wifi pos get vht ch width is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return tx_ops->wifi_pos_get_vht_ch_width(
+			psoc, ch_width);
+}
+
 static void wifi_update_channel_bw_info(struct wlan_objmgr_psoc *psoc,
 					struct wlan_objmgr_pdev *pdev,
 					uint16_t freq,
@@ -406,14 +426,20 @@ static void wifi_update_channel_bw_info(struct wlan_objmgr_psoc *psoc,
 	struct wifi_pos_psoc_priv_obj *wifi_pos_psoc =
 		wifi_pos_get_psoc_priv_obj(psoc);
 	uint32_t phy_mode;
+	QDF_STATUS status;
 
 	if (!wifi_pos_psoc) {
 		wifi_pos_err("wifi_pos priv obj is null");
 		return;
 	}
 
-	/* Passing CH_WIDTH_MAX will give the max bandwidth supported */
-	ch_params.ch_width = CH_WIDTH_MAX;
+	status = wifi_pos_get_vht_ch_width(psoc, &ch_params.ch_width);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wifi_pos_err("can not get vht ch width");
+		return;
+	}
+
 	wlan_reg_set_channel_params_for_freq(pdev, freq,
 					     sec_ch_2g, &ch_params);
 	chan_info->band_center_freq1 = ch_params.mhz_freq_seg0;