Jelajahi Sumber

qcacld-3.0: Add support for TWT session state in status query

Add support to include the session state in TWT status query
response. Session state is set to active once setup is
complete and when resume response event is received from
firmware. Session state is suspend when suspend response
event is received from firmware.

Change-Id: I1f47947c05f80bd85199fd81b951dc54deacdc09
CRs-Fixed: 2854500
Pragaspathi Thilagaraj 4 tahun lalu
induk
melakukan
ef10a16a2a

+ 8 - 3
components/mlme/core/inc/wlan_mlme_twt_api.h

@@ -85,23 +85,28 @@ bool mlme_is_twt_setup_done(struct wlan_objmgr_psoc *psoc,
  * mlme_set_twt_session_state() - Set the TWT session state for the given dialog
  * id in TWT context
  * @peer: Pointer to peer object
+ * @peer_mac: Pointer to peer mac address
  * @dialog_id: Dialog id
  * @state: TWT session state
  *
  * Return: None
  */
-void mlme_set_twt_session_state(struct wlan_objmgr_peer *peer,
+void mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc,
+				struct qdf_mac_addr *peer_mac,
 				uint8_t dialog_id,
 				enum wlan_twt_session_state state);
+
 /**
  * mlme_get_twt_session_state()  - Get TWT session state for given dialog id
- * @peer: Pointer to peer object
+ * @psoc: Pointer to psoc object
+ * @peer_mac: Pointer to peer mac address
  * @dialog_id: Dialog id
  *
  * Return:  TWT session state.
  */
 enum wlan_twt_session_state
-mlme_get_twt_session_state(struct wlan_objmgr_peer *peer, uint8_t dialog_id);
+mlme_get_twt_session_state(struct wlan_objmgr_psoc *psoc,
+			   struct qdf_mac_addr *peer_mac, uint8_t dialog_id);
 
 /**
  * mlme_get_twt_peer_capabilities  - Get TWT peer capabilities

+ 30 - 4
components/mlme/core/src/wlan_mlme_twt_api.c

@@ -269,16 +269,26 @@ bool mlme_twt_is_notify_done(struct wlan_objmgr_psoc *psoc,
 	return notify_done;
 }
 
-void mlme_set_twt_session_state(struct wlan_objmgr_peer *peer,
+void mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc,
+				struct qdf_mac_addr *peer_mac,
 				uint8_t dialog_id,
 				enum wlan_twt_session_state state)
 {
+	struct wlan_objmgr_peer *peer;
 	struct peer_mlme_priv_obj *peer_priv;
 	uint8_t i;
 
+	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
+					   WLAN_MLME_NB_ID);
+	if (!peer) {
+		mlme_legacy_err("Peer object not found");
+		return;
+	}
+
 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
 							  WLAN_UMAC_COMP_MLME);
 	if (!peer_priv) {
+		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
 		mlme_err(" peer mlme component object is NULL");
 		return;
 	}
@@ -290,27 +300,43 @@ void mlme_set_twt_session_state(struct wlan_objmgr_peer *peer,
 			break;
 		}
 	}
+
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
 }
 
 enum wlan_twt_session_state
-mlme_get_twt_session_state(struct wlan_objmgr_peer *peer,
-			   uint8_t dialog_id)
+mlme_get_twt_session_state(struct wlan_objmgr_psoc *psoc,
+			   struct qdf_mac_addr *peer_mac, uint8_t dialog_id)
 {
+	struct wlan_objmgr_peer *peer;
 	struct peer_mlme_priv_obj *peer_priv;
 	uint8_t i;
 
+	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac->bytes,
+					   WLAN_MLME_NB_ID);
+	if (!peer) {
+		mlme_legacy_err("Peer object not found");
+		return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
+	}
+
 	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
 							  WLAN_UMAC_COMP_MLME);
 	if (!peer_priv) {
+		wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
 		mlme_legacy_err(" peer mlme object is NULL");
 		return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
 	}
 
 	for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) {
-		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id)
+		if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id &&
+		    dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID) {
+			wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
 			return peer_priv->twt_ctx.session_info[i].state;
+		}
 	}
 
+	wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
+
 	return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
 }
 

+ 49 - 0
components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h

@@ -376,6 +376,40 @@ ucfg_mlme_set_twt_statistics_tgt_cap(struct wlan_objmgr_psoc *psoc, bool val);
  */
 QDF_STATUS
 ucfg_mlme_get_twt_statistics_tgt_cap(struct wlan_objmgr_psoc *psoc, bool *val);
+
+/**
+ * ucfg_mlme_set_twt_session_state()  - Set TWT session state
+ * @psoc: Pointer to global psoc object
+ * @peer_mac:  Pointer to peer mac address
+ * @dialog_id: TWT session dialog id
+ * @state: TWT state
+ *
+ * Return: None
+ */
+static inline
+void ucfg_mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc,
+				     struct qdf_mac_addr *peer_mac,
+				     uint8_t dialog_id,
+				     enum wlan_twt_session_state state)
+{
+	mlme_set_twt_session_state(psoc, peer_mac, dialog_id, state);
+}
+
+/**
+ * ucfg_mlme_get_twt_session_state()  - Get TWT session state
+ * @psoc: Pointer to global psoc object
+ * @peer_mac:  Pointer to peer mac address
+ * @dialog_id: TWT session dialog id
+ *
+ * Return: enum wlan_twt_session_state
+ */
+static inline enum wlan_twt_session_state
+ucfg_mlme_get_twt_session_state(struct wlan_objmgr_psoc *psoc,
+				struct qdf_mac_addr *peer_mac,
+				uint8_t dialog_id)
+{
+	return mlme_get_twt_session_state(psoc, peer_mac, dialog_id);
+}
 #else
 static inline QDF_STATUS
 ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc,
@@ -580,5 +614,20 @@ ucfg_mlme_set_twt_statistics_tgt_cap(struct wlan_objmgr_psoc *psoc, bool val)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }
+
+static inline
+void ucfg_mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc,
+				     struct qdf_mac_addr *peer_mac,
+				     uint8_t dialog_id,
+				     enum wlan_twt_session_state state)
+{}
+
+static inline enum wlan_twt_session_state
+ucfg_mlme_get_twt_session_state(struct wlan_objmgr_psoc *psoc,
+				struct qdf_mac_addr *peer_mac,
+				uint8_t dialog_id)
+{
+	return WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
+}
 #endif /* defined(WLAN_SUPPORT_TWT) && defined(WLAN_FEATURE_11AX) */
 #endif /* _WLAN_MLME_TWT_UCFG_API_H_ */

+ 76 - 13
core/hdd/src/wlan_hdd_twt.c

@@ -458,21 +458,50 @@ static uint32_t hdd_twt_get_params_resp_len(void)
 	/* QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF */
 	len += nla_total_size(sizeof(u64));
 
+	/* QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE */
+	len += nla_total_size(sizeof(u32));
+
 	return len;
 }
 
+/**
+ * hdd_get_converted_twt_state() - Convert the internal twt state
+ * to qca_wlan_twt_setup_state type.
+ * @state: Internal TWT state to be converted.
+ *
+ * Return: qca_wlan_twt_setup_state type state
+ */
+static enum qca_wlan_twt_setup_state
+hdd_get_converted_twt_state(enum wlan_twt_session_state state)
+{
+	switch (state) {
+	case WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED:
+		return QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
+	case WLAN_TWT_SETUP_STATE_ACTIVE:
+		return QCA_WLAN_TWT_SETUP_STATE_ACTIVE;
+	case WLAN_TWT_SETUP_STATE_SUSPEND:
+		return QCA_WLAN_TWT_SETUP_STATE_SUSPEND;
+	default:
+		return QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED;
+	}
+}
+
 /**
  * hdd_twt_pack_get_params_resp_nlmsg()- Packs and sends twt get_params response
+ * @psoc: Pointer to Global psoc
  * @reply_skb: pointer to response skb buffer
  * @params: Ponter to twt peer session parameters
  *
  * Return: QDF_STATUS_SUCCESS on success, else other qdf error values
  */
 static QDF_STATUS
-hdd_twt_pack_get_params_resp_nlmsg(struct sk_buff *reply_skb,
+hdd_twt_pack_get_params_resp_nlmsg(struct wlan_objmgr_psoc *psoc,
+				   struct sk_buff *reply_skb,
 				   struct wmi_host_twt_session_stats_info *params)
 {
 	struct nlattr *config_attr, *nla_params;
+	enum wlan_twt_session_state state;
+	enum qca_wlan_twt_setup_state converted_state;
 	uint64_t tsf_val;
 	int i, attr;
 
@@ -579,6 +608,16 @@ hdd_twt_pack_get_params_resp_nlmsg(struct sk_buff *reply_skb,
 			return QDF_STATUS_E_INVAL;
 		}
 
+		attr = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE;
+		state = ucfg_mlme_get_twt_session_state(
+				psoc, (struct qdf_mac_addr *)params[i].peer_mac,
+				params[i].dialog_id);
+		converted_state = hdd_get_converted_twt_state(state);
+		if (nla_put_u32(reply_skb, attr, converted_state)) {
+			hdd_err("TWT: get_params failed to put TWT state");
+			return QDF_STATUS_E_INVAL;
+		}
+
 		nla_nest_end(reply_skb, nla_params);
 	}
 	nla_nest_end(reply_skb, config_attr);
@@ -619,7 +658,8 @@ hdd_twt_pack_get_params_resp(struct hdd_context *hdd_ctx,
 		return QDF_STATUS_E_NOMEM;
 	}
 
-	qdf_status = hdd_twt_pack_get_params_resp_nlmsg(reply_skb, params);
+	qdf_status = hdd_twt_pack_get_params_resp_nlmsg(hdd_ctx->psoc,
+							reply_skb, params);
 	if (QDF_IS_STATUS_ERROR(qdf_status))
 		goto fail;
 
@@ -632,6 +672,25 @@ fail:
 	return qdf_status;
 }
 
+/**
+ * hdd_send_inactive_session_reply  -  Send session state as inactive for
+ * dialog ID for which setup is not done.
+ * @params: TWT session parameters
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+hdd_send_inactive_session_reply(struct hdd_adapter *adapter,
+				struct wmi_host_twt_session_stats_info *params)
+{
+	QDF_STATUS qdf_status;
+
+	params[0].event_type = HOST_TWT_SESSION_UPDATE;
+	qdf_status = hdd_twt_pack_get_params_resp(adapter->hdd_ctx, params);
+
+	return qdf_status;
+}
+
 /**
  * hdd_twt_get_peer_session_params() - Obtains twt session parameters of a peer
  * and sends response to the user space
@@ -696,24 +755,26 @@ static int hdd_twt_get_session_params(struct hdd_adapter *adapter,
 	else
 		params[0].dialog_id = 0;
 
+	if (params[0].dialog_id <= TWT_MAX_DIALOG_ID) {
+		qdf_mem_copy(params[0].peer_mac,
+			     hdd_sta_ctx->conn_info.bssid.bytes,
+			     QDF_MAC_ADDR_SIZE);
+		hdd_debug("TWT: get_params peer mac_addr " QDF_MAC_ADDR_FMT,
+			  QDF_MAC_ADDR_REF(params[0].peer_mac));
+	}
+
 	if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc,
 					 &hdd_sta_ctx->conn_info.bssid,
 					 params[0].dialog_id)) {
 		hdd_debug("vdev%d: TWT session %d setup incomplete",
 			  adapter->vdev_id, params[0].dialog_id);
-		return -EINVAL;
+		qdf_status = hdd_send_inactive_session_reply(adapter, params);
+
+		return qdf_status_to_os_return(qdf_status);
 	}
 
 	hdd_debug("TWT: get_params dialog_id %d", params[0].dialog_id);
 
-	if (params[0].dialog_id <= TWT_MAX_DIALOG_ID) {
-		qdf_mem_copy(params[0].peer_mac,
-			     hdd_sta_ctx->conn_info.bssid.bytes,
-			     QDF_MAC_ADDR_SIZE);
-		hdd_debug("TWT: get_params peer mac_addr " QDF_MAC_ADDR_FMT,
-			  QDF_MAC_ADDR_REF(params[0].peer_mac));
-	}
-
 	qdf_status = hdd_twt_get_peer_session_params(adapter->hdd_ctx,
 						     &params[0]);
 
@@ -996,6 +1057,7 @@ hdd_twt_setup_pack_resp_nlmsg(struct sk_buff *reply_skb,
 	uint64_t sp_offset_tsf;
 	enum qca_wlan_vendor_twt_status vendor_status;
 	int response_type;
+	uint32_t wake_duration;
 
 	hdd_enter();
 
@@ -1049,8 +1111,10 @@ hdd_twt_setup_pack_resp_nlmsg(struct sk_buff *reply_skb,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	wake_duration = (event->additional_params.wake_dur_us /
+			 TWT_WAKE_DURATION_MULTIPLICATION_FACTOR);
 	if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
-			event->additional_params.wake_dur_us)) {
+			wake_duration)) {
 		hdd_err("TWT: Failed to put wake duration");
 		return QDF_STATUS_E_FAILURE;
 	}
@@ -1446,7 +1510,6 @@ hdd_twt_del_dialog_comp_cb(struct wlan_objmgr_psoc *psoc,
 	mlme_init_twt_context(hdd_ctx->psoc,
 			      (struct qdf_mac_addr *)params->peer_macaddr,
 			      params->dialog_id);
-
 	hdd_exit();
 
 	return;

+ 0 - 1
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -1117,7 +1117,6 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 			session_entry->ap_mu_edca_params[QCA_WLAN_AC_VO] =
 				assoc_rsp->mu_edca.acvo;
 		}
-
 	}
 
 	if (beacon->VHTCaps.present)

+ 30 - 17
core/sme/src/common/sme_api.c

@@ -70,6 +70,7 @@
 #include "wlan_cm_api.h"
 #include "wlan_mlme_twt_public_struct.h"
 #include "wlan_mlme_twt_api.h"
+#include "wlan_mlme_twt_ucfg_api.h"
 #include "parser_api.h"
 #include <../../core/src/wlan_cm_vdev_api.h>
 #include <wlan_mlme_twt_api.h>
@@ -2116,13 +2117,21 @@ sme_process_twt_add_dialog_event(struct mac_context *mac,
 		mac->psoc,
 		(struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr,
 		add_dialog_event->params.dialog_id, WLAN_TWT_SETUP);
-	if (!is_evt_allowed)
+	if (!is_evt_allowed) {
+		sme_debug("add dialog event dropped");
 		return;
+	}
 
 	callback = mac->sme.twt_add_dialog_cb;
 	if (callback)
 		callback(mac->psoc, add_dialog_event);
 
+	ucfg_mlme_set_twt_session_state(
+		mac->psoc,
+		(struct qdf_mac_addr *)add_dialog_event->params.peer_macaddr,
+		add_dialog_event->params.dialog_id,
+		WLAN_TWT_SETUP_STATE_ACTIVE);
+
 	/* Reset the active TWT command to none */
 	mlme_set_twt_command_in_progress(
 		mac->psoc,
@@ -2149,9 +2158,12 @@ sme_process_twt_del_dialog_event(struct mac_context *mac,
 		mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
 		param->dialog_id, WLAN_TWT_TERMINATE);
 	if (!is_evt_allowed &&
+	    param->dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID &&
 	    (param->status != WMI_HOST_DEL_TWT_STATUS_ROAMING ||
-	     param->status != WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN))
+	     param->status != WMI_HOST_DEL_TWT_STATUS_PEER_INIT_TEARDOWN)) {
+		sme_debug("add dialog event dropped");
 		return;
+	}
 
 	callback = mac->sme.twt_del_dialog_cb;
 	if (callback)
@@ -2163,6 +2175,10 @@ sme_process_twt_del_dialog_event(struct mac_context *mac,
 			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
 			true);
 
+	ucfg_mlme_set_twt_session_state(
+			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+			param->dialog_id, WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED);
+
 	/* Reset the active TWT command to none */
 	mlme_set_twt_command_in_progress(
 			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
@@ -2182,18 +2198,15 @@ sme_process_twt_pause_dialog_event(struct mac_context *mac,
 				   struct wmi_twt_pause_dialog_complete_event_param *param)
 {
 	twt_pause_dialog_cb callback;
-	bool is_evt_allowed;
-
-	is_evt_allowed = mlme_twt_is_command_in_progress(
-		mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
-		param->dialog_id, WLAN_TWT_SUSPEND);
-	if (!is_evt_allowed)
-		return;
 
 	callback = mac->sme.twt_pause_dialog_cb;
 	if (callback)
 		callback(mac->psoc, param);
 
+	ucfg_mlme_set_twt_session_state(
+			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+			param->dialog_id, WLAN_TWT_SETUP_STATE_SUSPEND);
+
 	/* Reset the active TWT command to none */
 	mlme_set_twt_command_in_progress(
 		mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
@@ -2219,8 +2232,11 @@ sme_process_twt_nudge_dialog_event(struct mac_context *mac,
 	is_evt_allowed = mlme_twt_is_command_in_progress(
 		mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
 		param->dialog_id, WLAN_TWT_NUDGE);
-	if (!is_evt_allowed)
+	if (!is_evt_allowed &&
+	    param->dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID) {
+		sme_debug("Nudge event dropped");
 		return;
+	}
 
 	callback = mac->sme.twt_nudge_dialog_cb;
 	context = mac->sme.twt_nudge_dialog_context;
@@ -2247,18 +2263,15 @@ sme_process_twt_resume_dialog_event(struct mac_context *mac,
 				    struct wmi_twt_resume_dialog_complete_event_param *param)
 {
 	twt_resume_dialog_cb callback;
-	bool is_evt_allowed;
-
-	is_evt_allowed = mlme_twt_is_command_in_progress(
-		mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
-		param->dialog_id, WLAN_TWT_RESUME);
-	if (!is_evt_allowed)
-		return;
 
 	callback = mac->sme.twt_resume_dialog_cb;
 	if (callback)
 		callback(mac->psoc, param);
 
+	ucfg_mlme_set_twt_session_state(
+			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
+			param->dialog_id, WLAN_TWT_SETUP_STATE_ACTIVE);
+
 	/* Reset the active TWT command to none */
 	mlme_set_twt_command_in_progress(
 			mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,