Kaynağa Gözat

qcacmn: Return the status of regulatory init_cc handlers

When setting the country from user space, the thread sleeps and waits for
the init_cc event to awake. Right now the thread is woken up only in 2
case:
(i) when the country configuration is success from FW and regulatory and,
(ii) when country configuration failed in FW.

The thread is not woken up if there is failure in regulatory. This is
leading to timeout which will assert the kernel. In order to handle all the
return errors from the regulatory init_cc event handler should execute and
the status should be returned to thread waiting for the init_cc event
irrespective of the status of the init_cc handler. In order to achieve
this, the following actions are taken:
(i) Introduce a new regulatory tx_ops set_wait_for_init_cc_response_event()
that will wake up the thread waiting for init_cc response and return the
status of the init_cc response handler.
(ii) Remove the tx_ops set_country_failed() which just sends the failure
status to the thread waiting for init_cc event. This will be handled by the
new tx_ops.
(iii) Send the status of init_cc handler using the new regulatory tx_ops.

Change-Id: I1b29651682e9b7219d428c13d6d0ea299d6f81ba
CRs-Fixed: 3552823
uvignesh 1 yıl önce
ebeveyn
işleme
2bd93270d4

+ 1 - 1
target_if/regulatory/src/target_if_reg.c

@@ -1404,7 +1404,7 @@ QDF_STATUS target_if_register_regulatory_tx_ops(
 
 	reg_ops->fill_umac_legacy_chanlist = NULL;
 
-	reg_ops->set_country_failed = NULL;
+	reg_ops->set_wait_for_init_cc_response_event = NULL;
 
 	target_if_register_acs_trigger_for_afc(reg_ops);
 

+ 4 - 2
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -1106,13 +1106,14 @@ struct wlan_lmac_if_ftm_rx_ops {
  * @unregister_master_ext_handler: pointer to unregister ext event handler
  * @set_country_code:
  * @fill_umac_legacy_chanlist:
+ * @set_wait_for_init_cc_response_event: Wake up the thread that is waiting for
+ * the init cc response event.
  * @register_11d_new_cc_handler: pointer to register 11d cc event handler
  * @unregister_11d_new_cc_handler:  pointer to unregister 11d cc event handler
  * @start_11d_scan:
  * @stop_11d_scan:
  * @is_there_serv_ready_extn:
  * @set_user_country_code:
- * @set_country_failed:
  * @register_ch_avoid_event_handler:
  * @unregister_ch_avoid_event_handler:
  * @send_ctl_info: call-back function to send CTL info to firmware
@@ -1145,6 +1146,8 @@ struct wlan_lmac_if_reg_tx_ops {
 						  void *arg);
 	QDF_STATUS (*unregister_master_ext_handler)
 				(struct wlan_objmgr_psoc *psoc, void *arg);
+	void (*set_wait_for_init_cc_response_event)
+			(struct wlan_objmgr_pdev *pdev, QDF_STATUS status);
 	QDF_STATUS (*set_country_code)(struct wlan_objmgr_psoc *psoc,
 						void *arg);
 	QDF_STATUS (*fill_umac_legacy_chanlist)(struct wlan_objmgr_pdev *pdev,
@@ -1161,7 +1164,6 @@ struct wlan_lmac_if_reg_tx_ops {
 	QDF_STATUS (*set_user_country_code)(struct wlan_objmgr_psoc *psoc,
 					    uint8_t pdev_id,
 					    struct cc_regdmn_s *rd);
-	QDF_STATUS (*set_country_failed)(struct wlan_objmgr_pdev *pdev);
 	QDF_STATUS (*register_ch_avoid_event_handler)(
 			struct wlan_objmgr_psoc *psoc, void *arg);
 	QDF_STATUS (*unregister_ch_avoid_event_handler)(

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

@@ -3867,9 +3867,6 @@ reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj *soc_reg,
  *	when there is a failure
  * @status_code: status code of CC setting event
  * @soc_reg: soc private object for regulatory
- * @tx_ops: send operations for regulatory component
- * @psoc: pointer to PSOC object
- * @dbg_id: object manager reference debug ID
  * @phy_id: physical ID
  *
  * Return: QDF_STATUS
@@ -3877,28 +3874,12 @@ reg_send_ctl_info(struct wlan_regulatory_psoc_priv_obj *soc_reg,
 static QDF_STATUS
 reg_soc_vars_reset_on_failure(enum cc_setting_code status_code,
 			      struct wlan_regulatory_psoc_priv_obj *soc_reg,
-			      struct wlan_lmac_if_reg_tx_ops *tx_ops,
-			      struct wlan_objmgr_psoc *psoc,
-			      wlan_objmgr_ref_dbgid dbg_id,
 			      uint8_t phy_id)
 {
-	struct wlan_objmgr_pdev *pdev;
-
 	if (status_code != REG_SET_CC_STATUS_PASS) {
 		reg_err("Set country code failed, status code %d",
 			status_code);
 
-		pdev = wlan_objmgr_get_pdev_by_id(psoc, phy_id, dbg_id);
-		if (!pdev) {
-			reg_err("pdev is NULL");
-			return QDF_STATUS_E_FAILURE;
-		}
-
-		if (tx_ops->set_country_failed)
-			tx_ops->set_country_failed(pdev);
-
-		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
-
 		if (status_code != REG_CURRENT_ALPHA2_NOT_FOUND)
 			return QDF_STATUS_E_FAILURE;
 
@@ -4532,8 +4513,8 @@ QDF_STATUS reg_validate_master_chan_list_ext(
 	return QDF_STATUS_SUCCESS;
 }
 
-QDF_STATUS reg_process_master_chan_list_ext(
-		struct cur_regulatory_info *regulat_info)
+static QDF_STATUS
+__reg_process_master_chan_list_ext(struct cur_regulatory_info *regulat_info)
 {
 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
 	uint32_t i, j;
@@ -4591,8 +4572,7 @@ QDF_STATUS reg_process_master_chan_list_ext(
 	}
 
 	status = reg_soc_vars_reset_on_failure(regulat_info->status_code,
-					       soc_reg, tx_ops, psoc, dbg_id,
-					       phy_id);
+					       soc_reg, phy_id);
 
 	if (!QDF_IS_STATUS_SUCCESS(status))
 		return status;
@@ -4655,6 +4635,62 @@ QDF_STATUS reg_process_master_chan_list_ext(
 	return QDF_STATUS_SUCCESS;
 }
 
+struct wlan_objmgr_pdev *
+reg_get_pdev_from_phy_id(struct wlan_objmgr_psoc *psoc, uint8_t phy_id,
+			 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops,
+			 bool is_reg_offload,
+			 wlan_objmgr_ref_dbgid *dbg_id)
+{
+	uint8_t pdev_id;
+	struct wlan_objmgr_pdev *pdev;
+	enum direction dir;
+
+	if (reg_tx_ops->get_pdev_id_from_phy_id)
+		reg_tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id);
+	else
+		pdev_id = phy_id;
+
+	if (is_reg_offload) {
+		*dbg_id = WLAN_REGULATORY_NB_ID;
+		dir = NORTHBOUND;
+	} else {
+		*dbg_id = WLAN_REGULATORY_SB_ID;
+		dir = SOUTHBOUND;
+	}
+
+	pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, *dbg_id);
+
+	return pdev;
+}
+
+QDF_STATUS reg_process_master_chan_list_ext(
+				struct cur_regulatory_info *regulat_info)
+{
+	QDF_STATUS status;
+	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	wlan_objmgr_ref_dbgid dbg_id;
+
+	status =  __reg_process_master_chan_list_ext(regulat_info);
+	psoc = regulat_info->psoc;
+	reg_tx_ops = reg_get_psoc_tx_ops(psoc);
+	if (!reg_tx_ops->set_wait_for_init_cc_response_event)
+		return status;
+
+	pdev = reg_get_pdev_from_phy_id(psoc, regulat_info->phy_id, reg_tx_ops,
+					regulat_info->offload_enabled,
+					&dbg_id);
+	if (!pdev) {
+		reg_err("pdev obj is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	reg_tx_ops->set_wait_for_init_cc_response_event(pdev, status);
+
+	wlan_objmgr_pdev_release_ref(pdev, dbg_id);
+	return status;
+}
+
 QDF_STATUS reg_get_6g_ap_master_chan_list(struct wlan_objmgr_pdev *pdev,
 					  enum reg_6g_ap_type ap_pwr_type,
 					  struct regulatory_channel *chan_list)
@@ -5690,8 +5726,8 @@ const char *reg_get_power_string(enum reg_6g_ap_type power_type)
 #endif
 #endif /* CONFIG_BAND_6GHZ */
 
-QDF_STATUS reg_process_master_chan_list(
-		struct cur_regulatory_info *regulat_info)
+static QDF_STATUS
+__reg_process_master_chan_list(struct cur_regulatory_info *regulat_info)
 {
 	struct wlan_regulatory_psoc_priv_obj *soc_reg;
 	uint32_t num_2g_reg_rules, num_5g_reg_rules;
@@ -5744,8 +5780,7 @@ QDF_STATUS reg_process_master_chan_list(
 	}
 
 	status = reg_soc_vars_reset_on_failure(regulat_info->status_code,
-					       soc_reg, tx_ops, psoc, dbg_id,
-					       phy_id);
+					       soc_reg, phy_id);
 
 	if (!QDF_IS_STATUS_SUCCESS(status))
 		return status;
@@ -5903,6 +5938,35 @@ QDF_STATUS reg_process_master_chan_list(
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS reg_process_master_chan_list(
+				struct cur_regulatory_info *regulat_info)
+{
+	QDF_STATUS status;
+	struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	wlan_objmgr_ref_dbgid dbg_id;
+
+	status = __reg_process_master_chan_list(regulat_info);
+	psoc = regulat_info->psoc;
+	reg_tx_ops = reg_get_psoc_tx_ops(psoc);
+	if (!reg_tx_ops->set_wait_for_init_cc_response_event)
+		return status;
+
+	pdev = reg_get_pdev_from_phy_id(psoc, regulat_info->phy_id, reg_tx_ops,
+					regulat_info->offload_enabled,
+					&dbg_id);
+	if (!pdev) {
+		reg_err("pdev obj is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	reg_tx_ops->set_wait_for_init_cc_response_event(pdev, status);
+
+	wlan_objmgr_pdev_release_ref(pdev, dbg_id);
+	return status;
+}
+
 QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
 				     struct regulatory_channel *chan_list)
 {

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

@@ -3088,4 +3088,22 @@ bool reg_is_dev_supports_80p80(struct wlan_objmgr_pdev *pdev)
 	return false;
 }
 #endif
+
+/**
+ * reg_get_pdev_from_phy_id() - Get pdev from phy id.
+ * @psoc: Psoc object.
+ * @phy_id: Phy id of the pdev.
+ * @reg_tx_ops: Regulatory tx ops to get pdev id.
+ * @is_reg_offload: Is offloaded regulatory or not.
+ * @dbg_id: Debug id used to get pdev and used to release reference in the
+ * caller.
+ *
+ * Note: The caller should release reference to the pdev.
+ * Return: Pdev object.
+ */
+struct wlan_objmgr_pdev *
+reg_get_pdev_from_phy_id(struct wlan_objmgr_psoc *psoc, uint8_t phy_id,
+			 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops,
+			 bool is_reg_offload,
+			 wlan_objmgr_ref_dbgid *dbg_id);
 #endif