Browse Source

qcacld-3.0: Add retries to TWT DEL dialog cmd during ps mode

If power save disable command commes, implicitly driver
teardown the existing TWT session by sending out
TWT_DEL_DIALOG command to fw. In firmware if
command fails due to firmware scan_in_progress or
chan_switch_in_progress then driver should retries
TWT_DEL_DIALOG implicitly.

In driver, add retries logic to the twt del dialog command in
case of power save disable.

CRs-Fixed: 3584286
Change-Id: I71299ea8239f33d194d2b55499f2d8e5946c42ba
Deeksha Gupta 1 year ago
parent
commit
6e303e37aa

+ 5 - 1
components/umac/twt/core/src/wlan_twt_main.c

@@ -2286,6 +2286,7 @@ void wlan_twt_set_work_params(
 			struct wlan_objmgr_vdev *vdev,
 			struct qdf_mac_addr *peer_mac,
 			uint8_t dialog_id,
+			bool is_ps_disabled,
 			uint32_t twt_next_action)
 {
 	struct twt_vdev_priv_obj *twt_vdev_priv;
@@ -2300,10 +2301,12 @@ void wlan_twt_set_work_params(
 
 	qdf_copy_macaddr(&twt_vdev_priv->peer_macaddr, peer_mac);
 	twt_vdev_priv->dialog_id = dialog_id;
+	twt_vdev_priv->is_ps_disabled = is_ps_disabled;
 	twt_vdev_priv->next_action = twt_next_action;
 
-	twt_debug("renego: twt_terminate: dialog_id:%d next_action:%d peer mac_addr  "
+	twt_debug("TWT terminate: dialog_id:%d is_ps_disabled:%d next_action:%d peer mac_addr  "
 		   QDF_MAC_ADDR_FMT, twt_vdev_priv->dialog_id,
+		   twt_vdev_priv->is_ps_disabled,
 		   twt_vdev_priv->next_action,
 		   QDF_MAC_ADDR_REF(twt_vdev_priv->peer_macaddr.bytes));
 }
@@ -2323,5 +2326,6 @@ void wlan_twt_get_work_params(struct wlan_objmgr_vdev *vdev,
 
 	qdf_copy_macaddr(&params->peer_macaddr, &twt_vdev_priv->peer_macaddr);
 	params->dialog_id = twt_vdev_priv->dialog_id;
+	params->is_ps_disabled = twt_vdev_priv->is_ps_disabled;
 	*next_action = twt_vdev_priv->next_action;
 }

+ 2 - 0
components/umac/twt/core/src/wlan_twt_main.h

@@ -295,6 +295,7 @@ bool wlan_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc,
  * @vdev: vdev pointer
  * @peer_mac: mac address of peer
  * @dialog_id: dialog_id of TWT session
+ * @is_ps_disabled: Whether power save is disabled or not
  * @twt_next_action: Set next action to do before work scheduled
  *
  * Return: None
@@ -303,6 +304,7 @@ void wlan_twt_set_work_params(
 			struct wlan_objmgr_vdev *vdev,
 			struct qdf_mac_addr *peer_mac,
 			uint8_t dialog_id,
+			bool is_ps_disabled,
 			uint32_t twt_next_action);
 
 /**

+ 3 - 0
components/umac/twt/dispatcher/inc/wlan_twt_ucfg_ext_api.h

@@ -283,6 +283,7 @@ bool ucfg_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc,
  * @vdev: Vdev pointer
  * @peer_mac: peer mac address
  * @dialog_id: dialog_id
+ * @is_ps_disabled: Whether Power saave is disabled or not
  * @twt_next_action: Set TWT next action to do before work schedule
  *
  * Return: None
@@ -291,6 +292,7 @@ void ucfg_twt_set_work_params(
 		struct wlan_objmgr_vdev *vdev,
 		struct qdf_mac_addr *peer_mac,
 		uint8_t dialog_id,
+		bool is_ps_disabled,
 		uint32_t twt_next_action);
 
 /**
@@ -415,6 +417,7 @@ ucfg_twt_set_work_params(
 		struct wlan_objmgr_vdev *vdev,
 		struct qdf_mac_addr *peer_mac,
 		uint8_t dialog_id,
+		bool is_ps_disabled,
 		uint32_t twt_next_action)
 {
 }

+ 2 - 1
components/umac/twt/dispatcher/src/wlan_twt_ucfg_ext_api.c

@@ -228,10 +228,11 @@ void ucfg_twt_set_work_params(
 		struct wlan_objmgr_vdev *vdev,
 		struct qdf_mac_addr *peer_mac,
 		uint8_t dialog_id,
+		bool is_ps_disabled,
 		uint32_t twt_next_action)
 {
 	return wlan_twt_set_work_params(vdev, peer_mac, dialog_id,
-					twt_next_action);
+					is_ps_disabled, twt_next_action);
 }
 
 void ucfg_twt_get_work_params(

+ 4 - 6
core/hdd/src/wlan_hdd_power.c

@@ -2225,12 +2225,10 @@ int wlan_hdd_set_powersave(struct wlan_hdd_link_info *link_info,
 				hdd_ctx->mac_handle, link_info->vdev_id,
 				allow_power_save, timeout,
 				sta_ctx->ap_supports_immediate_power_save);
-	if (!allow_power_save) {
-		if (adapter->device_mode == QDF_STA_MODE)
-			hdd_twt_del_dialog_in_ps_disable(hdd_ctx,
-						&sta_ctx->conn_info.bssid,
-						link_info->vdev_id);
-	}
+	if (!allow_power_save && adapter->device_mode == QDF_STA_MODE)
+		hdd_twt_del_dialog_in_ps_disable(hdd_ctx,
+						 &sta_ctx->conn_info.bssid,
+						 link_info->vdev_id);
 
 	return qdf_status_to_os_return(status);
 }

+ 41 - 8
os_if/twt/src/osif_twt_ext_req.c

@@ -45,6 +45,7 @@
 #define TWT_SETUP_WAKE_DURATION_MAX             0xFFFF
 #define TWT_SETUP_WAKE_INTVL_EXP_MAX            31
 #define TWT_MAX_NEXT_TWT_SIZE                   3
+#define TWT_DEL_DIALOG_REQ_MAX_RETRY            10
 
 static const struct nla_policy
 qca_wlan_vendor_twt_add_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1] = {
@@ -462,12 +463,13 @@ osif_twt_ack_wait_response(struct wlan_objmgr_psoc *psoc,
 
 static void
 osif_send_twt_delete_cmd(struct wlan_objmgr_vdev *vdev,
-			 struct qdf_mac_addr *peer_mac, uint8_t dialog_id)
+			 struct qdf_mac_addr *peer_mac, uint8_t dialog_id,
+			 bool is_ps_disabled)
 {
 	uint32_t twt_next_action = HOST_TWT_SEND_DELETE_CMD;
 
-	ucfg_twt_set_work_params(vdev, peer_mac,
-				 dialog_id, twt_next_action);
+	ucfg_twt_set_work_params(vdev, peer_mac, dialog_id, is_ps_disabled,
+				 twt_next_action);
 	qdf_sched_work(0, &vdev->twt_work);
 }
 
@@ -531,7 +533,7 @@ osif_send_twt_setup_req(struct wlan_objmgr_vdev *vdev,
 			osif_debug("setup_done set, renego failure");
 			osif_send_twt_delete_cmd(vdev,
 						 &twt_params->peer_macaddr,
-						 twt_params->dialog_id);
+						 twt_params->dialog_id, false);
 		} else {
 			ucfg_twt_init_context(psoc, &twt_params->peer_macaddr,
 					      twt_params->dialog_id);
@@ -959,9 +961,12 @@ void osif_twt_teardown_in_ps_disable(struct wlan_objmgr_psoc *psoc,
 		osif_debug("vdev%d: Terminate existing TWT session %d due to ps disable",
 			  params.vdev_id, params.dialog_id);
 		ret = osif_send_sta_twt_teardown_req(vdev, psoc, &params);
-		if (ret)
+		if (ret) {
 			osif_debug("TWT teardown is failed on vdev: %d",
 				   vdev_id);
+			osif_send_twt_delete_cmd(vdev, mac_addr,
+						 params.dialog_id, true);
+		}
 	}
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TWT_ID);
 }
@@ -1126,7 +1131,7 @@ osif_twt_handle_renego_failure(struct wlan_objmgr_psoc *psoc,
 	}
 
 	osif_send_twt_delete_cmd(vdev, &event->params.peer_macaddr,
-				 event->params.dialog_id);
+				 event->params.dialog_id, false);
 
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_TWT_ID);
 
@@ -2407,6 +2412,25 @@ int osif_twt_set_param(struct wlan_objmgr_vdev *vdev,
 	return ret;
 }
 
+static void osif_twt_teardown_req_retry(struct wlan_objmgr_vdev *vdev,
+					struct wlan_objmgr_psoc *psoc,
+					struct twt_del_dialog_param params)
+{
+	int retries = 1;
+	int ret;
+
+	while (retries < TWT_DEL_DIALOG_REQ_MAX_RETRY) {
+		osif_debug("Implicitly TWT teardown req retry count:%d", retries);
+		ret = osif_send_sta_twt_teardown_req(vdev, psoc, &params);
+		if (ret != -EBUSY)
+			break;
+		retries++;
+	}
+
+	if (retries >= TWT_DEL_DIALOG_REQ_MAX_RETRY)
+		osif_debug("TWT Del Dialog req max retries reached");
+}
+
 void __osif_twt_work_handler(struct wlan_objmgr_vdev *vdev)
 {
 	struct twt_del_dialog_param params = {0};
@@ -2414,6 +2438,7 @@ void __osif_twt_work_handler(struct wlan_objmgr_vdev *vdev)
 	struct wlan_objmgr_psoc *psoc;
 	uint8_t vdev_id;
 	uint32_t next_action;
+	int ret;
 
 	psoc = wlan_vdev_get_psoc(vdev);
 	if (!psoc) {
@@ -2425,7 +2450,7 @@ void __osif_twt_work_handler(struct wlan_objmgr_vdev *vdev)
 	ucfg_twt_get_work_params(vdev, &twt_work_params, &next_action);
 
 	if (next_action != HOST_TWT_SEND_DELETE_CMD) {
-		osif_debug("Do not send STA teardown req as TWT renegotiation work is not scheduled");
+		osif_debug("Do not send STA teardown req as TWT renegotiation or power save work is not scheduled");
 		return;
 	}
 
@@ -2433,7 +2458,15 @@ void __osif_twt_work_handler(struct wlan_objmgr_vdev *vdev)
 	params.dialog_id = twt_work_params.dialog_id;
 	params.vdev_id = vdev_id;
 
-	osif_send_sta_twt_teardown_req(vdev, psoc, &params);
+	ret = osif_send_sta_twt_teardown_req(vdev, psoc, &params);
+
+	/*
+	 * In case of FW returns ack_event with status as scan_in_progress or
+	 * Channel switch in progress and TWT teardown happens due to power
+	 * save disable then host will retry the TWT teardown cmd.
+	 */
+	if (ret == -EBUSY && twt_work_params.is_ps_disabled)
+		osif_twt_teardown_req_retry(vdev, psoc, params);
 }
 
 void osif_twt_work_handler(void *data)