Browse Source

qcacmn: Choose SP during STOP-TX in outdoor deployment

In outdoor deployment, when the target sends STOP_TX event, the 6 GHz
AP continues to beacon in the SP power mode, without bringing down the VAP.

In mlme_check_curchan_and_set_ap_pwr_type, since the
afc_power_event_received flag is cleared and set to false during STOP_TX,
the API wlan_reg_get_best_pwr_mode returns LPI as the best power mode.
When LPI is given as input to wlan_reg_set_ap_pwr_and_update_chan_list,
it returns an error as LPI rules are absent in the pdev
(outdoor deployment). But the error status is not handled. Current channel
list also is not updated with the AFC_NOT_FLAG. When the channel list is
sent to the hostapd, NO_IR flag is set based on the presence of the
AFC_NOT_DONE flag in the current channel list. As a result NO_IR flag is
not sent to the hostapd, and the VAP remains in the up state.

To fix this issue, in reg_get_best_pwr_mode_from_eirp_list, skip the
unsupported modes (in this case LPI and VLP), from best power mode
computation. Also, in reg_get_sp_eirp, return the SP EIRP when no rules
other than SP are available.

Also, rename reg_get_eirp_for_non_sp to reg_get_eirp_from_mas_chan_list.
Modify reg_get_sp_eirp to call reg_get_eirp_from_mas_chan_list when
CONFIG_AFC_SUPPORT is not defined.

Change-Id: I1b11bf0580ec6af09ee8f9827bc85fae7930e414
CRs-Fixed: 3436245
Hariharan Basuthkar 2 năm trước cách đây
mục cha
commit
419d6ffcc9
1 tập tin đã thay đổi với 70 bổ sung39 xóa
  1. 70 39
      umac/regulatory/core/src/reg_services_common.c

+ 70 - 39
umac/regulatory/core/src/reg_services_common.c

@@ -9325,7 +9325,7 @@ reg_get_mas_chan_list_for_lookup(struct wlan_objmgr_pdev *pdev,
 }
 
 /**
- * reg_get_eirp_for_non_sp() -  For the given power mode, using the bandwidth
+ * reg_get_eirp_from_mas_chan_list() -  For the given power mode, using the bandwidth
  * and psd(from master channel entry), calculate an EIRP value. The minimum
  * of calculated EIRP and regulatory max EIRP is returned.
  * @pdev: Pointer to pdev
@@ -9339,21 +9339,15 @@ reg_get_mas_chan_list_for_lookup(struct wlan_objmgr_pdev *pdev,
  * Return: EIRP
  */
 static uint8_t
-reg_get_eirp_for_non_sp(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq,
-			uint16_t bw, enum reg_6g_ap_type ap_pwr_type,
-			bool is_client_list_lookup_needed,
-			enum reg_6g_client_type client_type)
+reg_get_eirp_from_mas_chan_list(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq,
+				uint16_t bw, enum reg_6g_ap_type ap_pwr_type,
+				bool is_client_list_lookup_needed,
+				enum reg_6g_client_type client_type)
 {
 	bool is_psd;
 	struct regulatory_channel *master_chan_list = NULL;
 	uint16_t txpower = 0;
 
-	if (!((ap_pwr_type == REG_INDOOR_AP) ||
-	      (ap_pwr_type == REG_VERY_LOW_POWER_AP))) {
-		reg_err("Only LPI and VLP are supported in this function ");
-		return 0;
-	}
-
 	reg_get_mas_chan_list_for_lookup(pdev, &master_chan_list, ap_pwr_type,
 					 is_client_list_lookup_needed,
 					 client_type);
@@ -9611,6 +9605,53 @@ reg_get_sp_eirp_for_punc_chans(struct wlan_objmgr_pdev *pdev,
 	return 0;
 }
 
+/**
+ * reg_get_sp_eirp_before_afc_resp_rx() - Before the AFC response is received
+ * from the target, for a given input frequency and bw, find the EIRP values
+ * based on the deployment type and, the presence of SP AP and VLP AP reg rules.
+ * @pdev: Pointer to pdev
+ * @freq: Frequency in MHz
+ * @bw: Bandwidth in MHz
+ * @is_client_list_lookup_needed: Boolean to indicate if client list lookup is
+ * needed
+ * @client_type: Client power type
+ *
+ * Return: EIRP
+ */
+static uint8_t
+reg_get_sp_eirp_before_afc_resp_rx(struct wlan_objmgr_pdev *pdev,
+				   qdf_freq_t freq,
+				   uint16_t bw,
+				   bool is_client_list_lookup_needed,
+				   enum reg_6g_client_type client_type)
+{
+	enum reg_afc_dev_deploy_type reg_afc_dev_type;
+	struct wlan_objmgr_psoc *psoc;
+	uint8_t num_ap_sp_rules, num_ap_vlp_rules;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+
+	if (!psoc) {
+		reg_err("psoc is NULL");
+		return 0;
+	}
+
+	reg_get_afc_soc_dev_type(psoc, &reg_afc_dev_type);
+	num_ap_sp_rules =
+		reg_get_num_rules_of_ap_pwr_type(pdev, REG_STANDARD_POWER_AP);
+	num_ap_vlp_rules =
+		reg_get_num_rules_of_ap_pwr_type(pdev, REG_VERY_LOW_POWER_AP);
+
+	if (reg_afc_dev_type == AFC_DEPLOYMENT_OUTDOOR && num_ap_sp_rules &&
+	    !num_ap_vlp_rules)
+		return reg_get_eirp_from_mas_chan_list(pdev, freq, bw,
+						       REG_STANDARD_POWER_AP,
+						       is_client_list_lookup_needed,
+						       client_type);
+	else
+		return 0;
+}
+
 /**
  * reg_get_sp_eirp() - For the given power mode, using the bandwidth, find the
  * corresponding EIRP values from the afc power info array. The minimum of found
@@ -9649,7 +9690,9 @@ static uint8_t reg_get_sp_eirp(struct wlan_objmgr_pdev *pdev,
 	}
 
 	if (!reg_is_afc_power_event_received(pdev))
-		return 0;
+		return reg_get_sp_eirp_before_afc_resp_rx(pdev, freq, bw,
+							  is_client_list_lookup_needed,
+							  client_type);
 
 	sp_master_chan_list =
 		pdev_priv_obj->mas_chan_list_6g_ap[REG_STANDARD_POWER_AP];
@@ -9727,29 +9770,9 @@ static uint8_t reg_get_sp_eirp(struct wlan_objmgr_pdev *pdev,
 			       bool is_client_list_lookup_needed,
 			       enum reg_6g_client_type client_type)
 {
-	struct regulatory_channel *sp_master_chan_list = NULL;
-	uint16_t reg_sp_eirp_pwr = 0;
-	bool is_psd;
-
-	reg_get_mas_chan_list_for_lookup(pdev, &sp_master_chan_list,
-					 REG_STANDARD_POWER_AP,
-					 is_client_list_lookup_needed,
-					 client_type);
-	if (!sp_master_chan_list) {
-		reg_err("sp_master_chan_list is NULL");
-		return 0;
-	}
-
-	reg_find_txpower_from_6g_list(freq, sp_master_chan_list,
-				      &reg_sp_eirp_pwr);
-	is_psd = reg_is_6g_psd_power(pdev);
-	if (is_psd)
-		reg_get_eirp_from_psd_and_reg_max_eirp(pdev,
-						       sp_master_chan_list,
-						       freq, bw,
-						       &reg_sp_eirp_pwr);
-
-	return reg_sp_eirp_pwr;
+	return reg_get_eirp_from_mas_chan_list(pdev, freq, bw, REG_STANDARD_POWER_AP,
+					       is_client_list_lookup_needed,
+					       client_type);
 }
 #endif
 
@@ -9765,9 +9788,17 @@ static enum reg_6g_ap_type
 reg_get_best_pwr_mode_from_eirp_list(uint8_t *eirp_list, uint8_t size)
 {
 	uint8_t max = 0, i;
-	enum reg_6g_ap_type best_pwr_mode = REG_INDOOR_AP;
+	enum reg_6g_ap_type best_pwr_mode = REG_CURRENT_MAX_AP_TYPE;
 
 	for (i = 0; i < size; i++) {
+		/* Assuming the eirp = 0 means the mode is not available,
+		 * skip the mode.
+		 * EIRP = 0 may be a valid value. We need to fix this in
+		 * future by setting the min negative value (-128) to
+		 * the channels for which power mode is not available.
+		 */
+		if (!eirp_list[i])
+			continue;
 		if (eirp_list[i] > max) {
 			max = eirp_list[i];
 			best_pwr_mode = i;
@@ -9789,9 +9820,9 @@ uint8_t reg_get_eirp_pwr(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq,
 				       is_client_list_lookup_needed,
 				       client_type);
 
-	return reg_get_eirp_for_non_sp(pdev, freq, bw, ap_pwr_type,
-				       is_client_list_lookup_needed,
-				       client_type);
+	return reg_get_eirp_from_mas_chan_list(pdev, freq, bw, ap_pwr_type,
+					       is_client_list_lookup_needed,
+					       client_type);
 }
 
 enum reg_6g_ap_type reg_get_best_pwr_mode(struct wlan_objmgr_pdev *pdev,