Prechádzať zdrojové kódy

qcacmn: Handle TWT renegotiation failure case

Generally below process should happen in renegotiation failure
case.
1. TWT setup (successful)
2. TWT setup (renegotiation failure)
3. TWT teardown
4. TWT GET STATUS - 0(dialog ID) 0 0 0
5. TWT setup - successful

Since all WMI TWT events gets executed in WMI thread. So when
renegotiation failure case hits, driver sends TWT
teardown to firmware and waits for twt ack in worker thread.
In same worker thread TWT event needs to be processed.
TWT ack event will not process as it's waiting in same worker
thread and it will get timedout.

As part of fix, break the context in renegotiation and
send the teardown in the new worker context.

Change-Id: Id12cb906b780d3013562c1772e276639a056c8f7
CRs-Fixed: 3207537
Jyoti Kumari 3 rokov pred
rodič
commit
4afef82b70

+ 4 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h

@@ -403,6 +403,7 @@ struct wlan_objmgr_vdev_objmgr {
  * @obj_state:      VDEV object state
  * @vdev_lock:      VDEV lock
  * @mlo_dev_ctx:    MLO device context
+ * @twt_work:	    TWT work
  */
 struct wlan_objmgr_vdev {
 	qdf_list_node_t vdev_node;
@@ -416,6 +417,9 @@ struct wlan_objmgr_vdev {
 #ifdef WLAN_FEATURE_11BE_MLO
 	struct wlan_mlo_dev_context *mlo_dev_ctx;
 #endif
+#ifdef WLAN_SUPPORT_TWT
+	qdf_work_t twt_work;
+#endif
 };
 
 /**

+ 35 - 0
umac/mlme/include/wlan_mlme_cmn.h

@@ -210,6 +210,12 @@ struct mlme_twt_ops {
 	QDF_STATUS (*mlme_twt_notify_complete_cb)(
 			struct wlan_objmgr_psoc *psoc,
 			struct twt_notify_event_param *event);
+
+	QDF_STATUS (*mlme_twt_vdev_create_cb)(
+			struct wlan_objmgr_vdev *vdev);
+
+	QDF_STATUS (*mlme_twt_vdev_destroy_cb)(
+			struct wlan_objmgr_vdev *vdev);
 };
 
 /**
@@ -1061,6 +1067,23 @@ QDF_STATUS
 mlme_twt_osif_notify_complete_ind(struct wlan_objmgr_psoc *psoc,
 				  struct twt_notify_event_param *event);
 
+/**
+ * mlme_twt_vdev_create_notification() - vdev create notification to osif
+ * @vdev: vdev pointer
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+mlme_twt_vdev_create_notification(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlme_twt_vdev_destroy_notification() - vdev destroy notification to osif
+ * @vdev: vdev pointer
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+mlme_twt_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev);
 #else
 static inline QDF_STATUS
 mlme_twt_osif_enable_complete_ind(struct wlan_objmgr_psoc *psoc,
@@ -1129,6 +1152,18 @@ mlme_twt_osif_notify_complete_ind(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 
+static inline QDF_STATUS
+mlme_twt_vdev_create_notification(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline QDF_STATUS
+mlme_twt_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
 #endif /* WLAN_SUPPORT_TWT && WLAN_TWT_CONV_SUPPORTED */
 
 #endif

+ 22 - 0
umac/mlme/mlme_objmgr/dispatcher/src/wlan_cmn_mlme_main.c

@@ -774,5 +774,27 @@ mlme_twt_osif_notify_complete_ind(struct wlan_objmgr_psoc *psoc,
 	return ret;
 }
 
+QDF_STATUS
+mlme_twt_vdev_create_notification(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+
+	if (glbl_twt_ops && glbl_twt_ops->mlme_twt_vdev_create_cb)
+		ret = glbl_twt_ops->mlme_twt_vdev_create_cb(vdev);
+
+	return ret;
+}
+
+QDF_STATUS
+mlme_twt_vdev_destroy_notification(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+
+	if (glbl_twt_ops && glbl_twt_ops->mlme_twt_vdev_destroy_cb)
+		ret = glbl_twt_ops->mlme_twt_vdev_destroy_cb(vdev);
+
+	return ret;
+}
+
 #endif
 

+ 15 - 0
umac/twt/core/src/wlan_twt_objmgr.c

@@ -23,6 +23,7 @@
 #include "wlan_twt_priv.h"
 #include "wlan_twt_objmgr_handler.h"
 #include "wlan_objmgr_peer_obj.h"
+#include "include/wlan_mlme_cmn.h"
 
 QDF_STATUS
 wlan_twt_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
@@ -101,6 +102,14 @@ wlan_twt_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, void *arg)
 	}
 
 	twt_debug("twt vdev priv obj attach successful");
+
+	status = mlme_twt_vdev_create_notification(vdev);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		twt_err("vdev create notification failed");
+		return status;
+	}
+
 	return status;
 }
 
@@ -110,6 +119,12 @@ wlan_twt_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, void *arg)
 	QDF_STATUS status;
 	struct twt_vdev_priv_obj *twt_vdev_obj;
 
+	status = mlme_twt_vdev_destroy_notification(vdev);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		twt_err("vdev destroy notification failed");
+		return status;
+	}
+
 	twt_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
 							    WLAN_UMAC_COMP_TWT);
 	if (!twt_vdev_obj) {

+ 6 - 0
umac/twt/core/src/wlan_twt_priv.h

@@ -71,9 +71,15 @@ struct twt_psoc_priv_obj {
 /**
  * struct twt_vdev_priv_obj -
  * @twt_wait_for_notify: wait for notify
+ * @dialog_id: TWT dialog id
+ * @peer_macaddr: Peer mac address
+ * @next_action: next action of TWT worker queue
  */
 struct twt_vdev_priv_obj {
 	bool twt_wait_for_notify;
+	uint32_t dialog_id;
+	struct qdf_mac_addr peer_macaddr;
+	enum HOST_TWT_NEXT_WORK_ACTION next_action;
 };
 
 /**

+ 16 - 0
umac/twt/dispatcher/inc/wlan_twt_public_structs.h

@@ -873,6 +873,22 @@ struct twt_notify_event_param {
 	enum HOST_TWT_NOTIFY_STATUS status;
 };
 
+/* HOST_TWT_NEXT_WORK_ACTION - next action of TWT worker thread
+ * @HOST_TWT_SEND_DELETE_CMD: Send TWT delete command request
+ */
+enum HOST_TWT_NEXT_WORK_ACTION {
+	HOST_TWT_SEND_DELETE_CMD = 1,
+};
+
+/**
+ * struct twt_work_params
+ * @peer_macaddr: peer mac address
+ * @dialog_id: Dialog ID
+ */
+struct twt_work_params {
+	struct qdf_mac_addr peer_macaddr;
+	uint32_t dialog_id;
+};
 #ifdef WLAN_SUPPORT_BCAST_TWT
 /**
  * struct twt_btwt_invite_sta_cmd_param -