Przeglądaj źródła

qcacmn: Add support for AFC payload reset for proxy mode

In the AFC Enterprise mode, the AFC response-payload may need to be
reset from host. The payload reset is done by sending
WMI_SERVICE_AFC_RESET_SUPPORT subtype in the WMI_AFC_CMD to the target.

In response, the target sends the WMI_AFC_EVENT_TIMER_EXPIRY event with
WMI_AFC_EXPIRY_EVENT_SWITCH_TO_LOW_POWER_MODE (in indoor deployment) or
WMI_EXPIRY_EVENT WMI_AFC_EXPIRY_EVENT_STOP_TX (in outdoor deployment)
event subtype to the host.

Earlier, the WMI_AFC_EVENT_TIMER_EXPIRY event was sent only in
non-enterprise mode. Now, since it can be sent for both enterprise and
non-enterprise mode, we need to take care of 'afc_reg no action",
which is mandatory in case of enterprise mode.

Therefore, implement the following changes:

1) Call trigger_acs_for_afc only if afc_reg_no_action is not set.
2) Send the AFC payload reset event during SWITCH_TO_LPI and STOP_TX
   event, and free the AFC payload received from the target.
3) Add APIs to register a callback to send the AFC payload reset event.

Change-Id: Ib5b3a6f51bbdf2061460fd957ca3c0ba66f23fa9
CRs-Fixed: 3462953
Hariharan Basuthkar 2 lat temu
rodzic
commit
b33c5ecbf3

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

@@ -4550,8 +4550,17 @@ reg_process_afc_expiry_event(struct afc_regulatory_info *afc_info)
 		break;
 	case REG_AFC_EXPIRY_EVENT_SWITCH_TO_LPI:
 	case REG_AFC_EXPIRY_EVENT_STOP_TX:
+		/*
+		 * Invalidate the AFC response-payload and associated
+		 * driver memory
+		 */
+		reg_free_afc_pwr_info(pdev_priv_obj);
 		reg_reset_chan_list_and_power_event(pdev_priv_obj);
 		reg_client_afc_populate_channels(psoc, pdev);
+		reg_send_afc_payload_reset_event(pdev);
+		if (wlan_reg_is_noaction_on_afc_pwr_evt(pdev))
+			break;
+
 		if (tx_ops->trigger_acs_for_afc)
 			tx_ops->trigger_acs_for_afc(pdev);
 		break;

+ 1 - 0
umac/regulatory/core/src/reg_priv_objs.c

@@ -472,6 +472,7 @@ reg_free_afc_pwr_info(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
 		qdf_mem_free(power_info->afc_chan_info);
 
 	qdf_mem_free(power_info);
+	pdev_priv_obj->power_info = NULL;
 }
 #endif
 

+ 3 - 0
umac/regulatory/core/src/reg_priv_objs.h

@@ -344,6 +344,8 @@ struct wlan_regulatory_psoc_priv_obj {
  * @afc_cb_obj: The object containing the callback function and opaque argument
  * @afc_pow_evt_cb_obj: The object containing the callback function and opaque
  * argument for the AFC power event
+ * @afc_payload_reset_evt_cb_obj: The object containing the callback function
+ * and opaque argument for the AFC payload reset event
  * @afc_request_id: The last AFC request id received from FW/halphy
  * @is_6g_afc_power_event_received: indicates if the AFC power event is
  * received
@@ -429,6 +431,7 @@ struct wlan_regulatory_pdev_priv_obj {
 	qdf_spinlock_t afc_cb_lock;
 	struct afc_cb_handler afc_cb_obj;
 	struct afc_pow_evt_cb_handler afc_pow_evt_cb_obj;
+	struct afc_payload_reset_evt_cb_handler afc_payload_reset_evt_cb_obj;
 	uint64_t afc_request_id;
 	bool is_6g_afc_power_event_received;
 	bool is_6g_afc_expiry_event_received;

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

@@ -7667,6 +7667,29 @@ QDF_STATUS reg_send_afc_power_event(struct wlan_objmgr_pdev *pdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS reg_send_afc_payload_reset_event(struct wlan_objmgr_pdev *pdev)
+{
+	afc_payload_reset_tx_evt_handler cbf;
+	void *arg;
+	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("pdev reg component is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&pdev_priv_obj->afc_cb_lock);
+	cbf = pdev_priv_obj->afc_payload_reset_evt_cb_obj.func;
+	if (cbf) {
+		arg = pdev_priv_obj->afc_payload_reset_evt_cb_obj.arg;
+		cbf(pdev, arg);
+	}
+	qdf_spin_unlock_bh(&pdev_priv_obj->afc_cb_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS reg_register_afc_req_rx_callback(struct wlan_objmgr_pdev *pdev,
 					    afc_req_rx_evt_handler cbf,
 					    void *arg)
@@ -7757,6 +7780,52 @@ reg_unregister_afc_power_event_callback(struct wlan_objmgr_pdev *pdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS
+reg_register_afc_payload_reset_event_callback(struct wlan_objmgr_pdev *pdev,
+					      afc_payload_reset_tx_evt_handler cbf,
+					      void *arg)
+{
+	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("pdev reg component is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&pdev_priv_obj->afc_cb_lock);
+	pdev_priv_obj->afc_payload_reset_evt_cb_obj.func = cbf;
+	pdev_priv_obj->afc_payload_reset_evt_cb_obj.arg = arg;
+	qdf_spin_unlock_bh(&pdev_priv_obj->afc_cb_lock);
+	reg_debug("afc_payload_reset_event_cb: 0x%pK, arg: 0x%pK", cbf, arg);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+reg_unregister_afc_payload_reset_event_callback(struct wlan_objmgr_pdev *pdev,
+						afc_payload_reset_tx_evt_handler cbf)
+{
+	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("pdev reg component is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_spin_lock_bh(&pdev_priv_obj->afc_cb_lock);
+	if (pdev_priv_obj->afc_payload_reset_evt_cb_obj.func == cbf) {
+		pdev_priv_obj->afc_payload_reset_evt_cb_obj.func = NULL;
+		pdev_priv_obj->afc_payload_reset_evt_cb_obj.arg = NULL;
+	} else {
+		reg_err("cb function=0x%pK not found", cbf);
+	}
+	qdf_spin_unlock_bh(&pdev_priv_obj->afc_cb_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS
 reg_get_afc_dev_deploy_type(struct wlan_objmgr_pdev *pdev,
 			    enum reg_afc_dev_deploy_type *reg_afc_dev_type)

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

@@ -192,6 +192,17 @@ struct afc_pow_evt_cb_handler {
 	void *arg;
 };
 
+/**
+ * struct afc_payload_reset_evt_cb_handler - Structure for afc payload reset
+ * event  handler call back function and argument
+ * @func: handler function pointer
+ * @arg: argument to handler function
+ */
+struct afc_payload_reset_evt_cb_handler {
+	afc_payload_reset_tx_evt_handler func;
+	void *arg;
+};
+
 /**
  * reg_init_freq_range() - Initialize a freq_range object
  * @left: The left frequency range
@@ -1801,6 +1812,32 @@ QDF_STATUS
 reg_unregister_afc_power_event_callback(struct wlan_objmgr_pdev *pdev,
 					afc_power_tx_evt_handler cbf);
 
+/**
+ * reg_register_afc_payload_reset_event_callback() - Add AFC payload reset
+ * event received callback
+ * @pdev: Pointer to pdev
+ * @cbf: Pointer to callback function
+ * @arg: Pointer to opaque argument
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS reg_register_afc_payload_reset_event_callback(
+		struct wlan_objmgr_pdev *pdev,
+		afc_payload_reset_tx_evt_handler cbf,
+		void *arg);
+
+/**
+ * reg_unregister_afc_payload_reset_event_callback() - Remove AFC payload
+ * reset event received callback
+ * @pdev: Pointer to pdev
+ * @cbf: Pointer to callback function
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS reg_unregister_afc_payload_reset_event_callback(
+		struct wlan_objmgr_pdev *pdev,
+		afc_payload_reset_tx_evt_handler cbf);
+
 /**
  * reg_send_afc_power_event() - Send AFC power event to registered
  * recipient
@@ -1812,6 +1849,15 @@ reg_unregister_afc_power_event_callback(struct wlan_objmgr_pdev *pdev,
 QDF_STATUS reg_send_afc_power_event(struct wlan_objmgr_pdev *pdev,
 				    struct reg_fw_afc_power_event *power_info);
 
+/**
+ * reg_send_afc_payload_reset_event() - Send AFC payload reset event to
+ * registered recipient
+ * @pdev: Pointer to pdev
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS reg_send_afc_payload_reset_event(struct wlan_objmgr_pdev *pdev);
+
 /**
  * reg_get_afc_dev_deploy_type() - Get AFC device deployment type
  * @pdev: Pointer to pdev

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

@@ -2334,6 +2334,18 @@ typedef void
 (*afc_power_tx_evt_handler)(struct wlan_objmgr_pdev *pdev,
 			    struct reg_fw_afc_power_event *power_info,
 			    void *arg);
+
+/**
+ * typedef afc_payload_reset_tx_evt_handler() - Function prototype of AFC
+ * payload reset event sent handler
+ * @pdev: Pointer to pdev
+ * @arg: Pointer to void (opaque) argument object
+ *
+ * Return: void
+ */
+typedef void
+(*afc_payload_reset_tx_evt_handler)(struct wlan_objmgr_pdev *pdev,
+				    void *arg);
 #endif
 
 /**

+ 26 - 0
umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h

@@ -389,6 +389,32 @@ ucfg_reg_register_afc_power_event_callback(struct wlan_objmgr_pdev *pdev,
 QDF_STATUS
 ucfg_reg_unregister_afc_power_event_callback(struct wlan_objmgr_pdev *pdev,
 					     afc_power_tx_evt_handler cbf);
+
+/**
+ * ucfg_reg_register_afc_payload_reset_event_callback() - Add AFC payload reset
+ * event received callback
+ * @pdev: Pointer to pdev
+ * @cbf: Pointer to callback function
+ * @arg: Pointer to opaque argument
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_reg_register_afc_payload_reset_event_callback(
+		struct wlan_objmgr_pdev *pdev,
+		afc_payload_reset_tx_evt_handler cbf,
+		void *arg);
+
+/**
+ * ucfg_reg_unregister_afc_payload_reset_event_callback() - Remove AFC payload
+ * reset event received callback
+ * @pdev: Pointer to pdev
+ * @cbf: Pointer to callback function
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_reg_unregister_afc_payload_reset_event_callback(
+		struct wlan_objmgr_pdev *pdev,
+		afc_payload_reset_tx_evt_handler cbf);
 #endif
 
 /**

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

@@ -229,6 +229,23 @@ ucfg_reg_unregister_afc_power_event_callback(struct wlan_objmgr_pdev *pdev,
 	return reg_unregister_afc_power_event_callback(pdev, cbf);
 }
 
+QDF_STATUS
+ucfg_reg_register_afc_payload_reset_event_callback(
+		struct wlan_objmgr_pdev *pdev,
+		afc_payload_reset_tx_evt_handler cbf,
+		void *arg) {
+	return reg_register_afc_payload_reset_event_callback(pdev, cbf, arg);
+}
+
+qdf_export_symbol(ucfg_reg_register_afc_payload_reset_event_callback);
+
+QDF_STATUS ucfg_reg_unregister_afc_payload_reset_event_callback(
+		struct wlan_objmgr_pdev *pdev,
+		afc_payload_reset_tx_evt_handler cbf)
+{
+	return reg_unregister_afc_payload_reset_event_callback(pdev, cbf);
+}
+
 QDF_STATUS ucfg_reg_get_afc_req_info(struct wlan_objmgr_pdev *pdev,
 				     struct wlan_afc_host_request **afc_req,
 				     uint64_t req_id)