瀏覽代碼

qcacmn: Check agile frequency forms a valid 80+80 channel

For agile scan request in 80 + 80 MHz check whether the user given
agile frequency forms a valid 80+80 channel.

CRs-Fixed: 2690964
Change-Id: Ia374333118d4f06861a1cfe0a75db349bca9e879
Edayilliam Jayadev 5 年之前
父節點
當前提交
fb564225fb

+ 85 - 0
target_if/spectral/target_if_spectral.c

@@ -3025,6 +3025,74 @@ target_if_spectral_populate_chwidth(struct target_if_spectral *spectral,
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * target_if_spectral_is_valid_80p80_freq() - API to check whether given
+ * (cfreq1, cfreq2) pair forms a valid 80+80 combination
+ * @pdev: pointer to pdev
+ * @cfreq1: center frequency 1
+ * @cfreq2: center frequency 2
+ *
+ * API to check whether given (cfreq1, cfreq2) pair forms a valid 80+80
+ * combination
+ *
+ * Return: true or false
+ */
+static bool
+target_if_spectral_is_valid_80p80_freq(struct wlan_objmgr_pdev *pdev,
+				       uint32_t cfreq1, uint32_t cfreq2)
+{
+	struct ch_params ch_params;
+	enum channel_state chan_state1;
+	enum channel_state chan_state2;
+	struct wlan_objmgr_psoc *psoc;
+
+	qdf_assert_always(pdev);
+	psoc = wlan_pdev_get_psoc(pdev);
+	qdf_assert_always(psoc);
+
+	/* In restricted 80P80 MHz enabled, only one 80+80 MHz
+	 * channel is supported with cfreq=5690 and cfreq=5775.
+	 */
+	if (wlan_psoc_nif_fw_ext_cap_get(
+				psoc, WLAN_SOC_RESTRICTED_80P80_SUPPORT))
+		return CHAN_WITHIN_RESTRICTED_80P80(cfreq1, cfreq2);
+
+	ch_params.center_freq_seg1 = wlan_reg_freq_to_chan(pdev, cfreq2);
+	ch_params.mhz_freq_seg1 = cfreq2;
+	ch_params.ch_width = CH_WIDTH_80P80MHZ;
+	wlan_reg_set_channel_params_for_freq(pdev, cfreq1 - FREQ_OFFSET_10MHZ,
+					     0, &ch_params);
+
+	if (ch_params.ch_width != CH_WIDTH_80P80MHZ)
+		return false;
+
+	if (ch_params.mhz_freq_seg0 != cfreq1 ||
+	    ch_params.mhz_freq_seg1 != cfreq2)
+		return false;
+
+	chan_state1 = wlan_reg_get_5g_bonded_channel_state_for_freq(
+				pdev,
+				ch_params.mhz_freq_seg0 - FREQ_OFFSET_10MHZ,
+				CH_WIDTH_80MHZ);
+	if ((chan_state1 == CHANNEL_STATE_DISABLE) ||
+	    (chan_state1 == CHANNEL_STATE_INVALID))
+		return false;
+
+	chan_state2 = wlan_reg_get_5g_bonded_channel_state_for_freq(
+				pdev,
+				ch_params.mhz_freq_seg1 - FREQ_OFFSET_10MHZ,
+				CH_WIDTH_80MHZ);
+	if ((chan_state2 == CHANNEL_STATE_DISABLE) ||
+	    (chan_state2 == CHANNEL_STATE_INVALID))
+		return false;
+
+	if (abs(ch_params.mhz_freq_seg0 - ch_params.mhz_freq_seg1) <=
+	    FREQ_OFFSET_80MHZ)
+		return false;
+
+	return true;
+}
+
 /**
  * _target_if_set_spectral_config() - Set spectral config
  * @spectral:       Pointer to spectral object
@@ -3275,6 +3343,23 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
 			return QDF_STATUS_E_FAILURE;
 		}
 
+		if (ch_width[smode] == CH_WIDTH_80P80MHZ) {
+			bool is_valid_80p80;
+
+			is_valid_80p80 = target_if_spectral_is_valid_80p80_freq(
+						spectral->pdev_obj,
+						center_freq.cfreq1,
+						center_freq.cfreq2);
+
+			if (!is_valid_80p80) {
+				spectral_err("Agile freq %u, %u is invalid 80+80 combination",
+					     center_freq.cfreq1,
+					     center_freq.cfreq2);
+				*err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
+				return QDF_STATUS_E_FAILURE;
+			}
+		}
+
 		sparams->ss_frequency.cfreq1 = center_freq.cfreq1;
 		sparams->ss_frequency.cfreq2 = center_freq.cfreq2;
 

+ 1 - 0
target_if/spectral/target_if_spectral.h

@@ -44,6 +44,7 @@
 
 #define FREQ_OFFSET_10MHZ (10)
 #define FREQ_OFFSET_40MHZ (40)
+#define FREQ_OFFSET_80MHZ (80)
 #ifndef SPECTRAL_USE_NL_BCAST
 #define SPECTRAL_USE_NL_BCAST  (0)
 #endif

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

@@ -983,6 +983,8 @@ wlan_reg_get_5g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 	return reg_get_5g_bonded_channel_state_for_freq(pdev, freq, bw);
 }
 
+qdf_export_symbol(wlan_reg_get_5g_bonded_channel_state_for_freq);
+
 enum channel_state
 wlan_reg_get_2g_bonded_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 					      qdf_freq_t freq,
@@ -1003,6 +1005,8 @@ void wlan_reg_set_channel_params_for_freq(struct wlan_objmgr_pdev *pdev,
 	reg_set_channel_params_for_freq(pdev, freq, sec_ch_2g_freq, ch_params);
 }
 
+qdf_export_symbol(wlan_reg_set_channel_params_for_freq);
+
 enum channel_state
 wlan_reg_get_channel_state_for_freq(struct wlan_objmgr_pdev *pdev,
 				    qdf_freq_t freq)