浏览代码

qcacld-3.0: Support for TWT SAP get_status query command

Add support for TWT get_status command in SAP

As part of this change, TWT get_status command is supported
if
1. If particular dialog_id and particular mac_addr are
   present
2. If dialog_id = 0 and particular mac_addr are present
3. If no parameter present

Change-Id: I5ce1719da7f9a3988ba6e1f04455a06faf9687c6
CRs-Fixed: 2937999
Deeksha Gupta 3 年之前
父节点
当前提交
565e6a7d76
共有 2 个文件被更改,包括 138 次插入25 次删除
  1. 34 19
      components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c
  2. 104 6
      core/hdd/src/wlan_hdd_twt.c

+ 34 - 19
components/cp_stats/dispatcher/src/wlan_cp_stats_mc_ucfg_api.c

@@ -32,6 +32,9 @@
 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
 #include <wlan_pmo_obj_mgmt_api.h>
 #endif
+#ifdef WLAN_SUPPORT_TWT
+#include <wlan_mlme_twt_public_struct.h>
+#endif
 
 #ifdef WLAN_SUPPORT_TWT
 
@@ -44,9 +47,10 @@
  * @dest_param: Pointer to copy twt session parameters when a peer with
  * given dialog id is found
  *
- * Return: true if stats are copied for a peer with given dialog, else false
+ * Return: Success if stats are copied for a peer with given dialog,
+ * else failure
  */
-static bool
+static QDF_STATUS
 ucfg_twt_get_peer_session_param_by_dlg_id(struct peer_mc_cp_stats *mc_stats,
 					  uint32_t input_dialog_id,
 					  struct wmi_host_twt_session_stats_info
@@ -54,26 +58,33 @@ ucfg_twt_get_peer_session_param_by_dlg_id(struct peer_mc_cp_stats *mc_stats,
 {
 	struct wmi_host_twt_session_stats_info *src_param;
 	uint32_t event_type;
-	int i;
+	int i, num_session = 0;
+	QDF_STATUS qdf_status = QDF_STATUS_E_INVAL;
 
 	if (!mc_stats || !dest_param)
-		return false;
+		return qdf_status;
 
 	for (i = 0; i < TWT_PEER_MAX_SESSIONS; i++) {
 		event_type = mc_stats->twt_param[i].event_type;
 
 		src_param = &mc_stats->twt_param[i];
-		if ((!event_type) || (src_param->dialog_id != input_dialog_id))
+		if (!event_type ||
+		    (src_param->dialog_id != input_dialog_id &&
+		     input_dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID))
 			continue;
 
 		if ((event_type == HOST_TWT_SESSION_SETUP) ||
 		    (event_type == HOST_TWT_SESSION_UPDATE)) {
-			qdf_mem_copy(dest_param, src_param, sizeof(*src_param));
-			return true;
+			qdf_mem_copy(&dest_param[num_session], src_param,
+				     sizeof(*src_param));
+			qdf_status = QDF_STATUS_SUCCESS;
+			num_session += 1;
+			if (num_session >= TWT_PEER_MAX_SESSIONS)
+				break;
 		}
 	}
 
-	return false;
+	return qdf_status;
 }
 
 /**
@@ -114,10 +125,10 @@ ucfg_twt_get_single_peer_session_params(struct wlan_objmgr_psoc *psoc_obj,
 	wlan_cp_stats_peer_obj_lock(peer_cp_stats_priv);
 	peer_mc_stats = peer_cp_stats_priv->peer_stats;
 
-	if (ucfg_twt_get_peer_session_param_by_dlg_id(peer_mc_stats,
-						      dialog_id, params)) {
-		qdf_status = QDF_STATUS_SUCCESS;
-	} else {
+	qdf_status = ucfg_twt_get_peer_session_param_by_dlg_id(peer_mc_stats,
+							       dialog_id,
+							       params);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
 		qdf_err("No TWT session for " QDF_MAC_ADDR_FMT " dialog_id %d",
 			QDF_MAC_ADDR_REF(mac_addr), dialog_id);
 	}
@@ -192,6 +203,9 @@ ucfg_twt_get_all_peer_session_params(struct wlan_objmgr_psoc *psoc_obj,
 	qdf_list_t *obj_list;
 	int i, num_sessions = 0;
 
+	if (!psoc_obj || !params)
+		return qdf_status;
+
 	/* psoc obj lock should be taken before peer list lock */
 	wlan_psoc_obj_lock(psoc_obj);
 	psoc_objmgr = &psoc_obj->soc_objmgr;
@@ -262,18 +276,19 @@ ucfg_twt_get_peer_session_params(struct wlan_objmgr_psoc *psoc_obj,
 	dialog_id = params[0].dialog_id;
 
 	/*
-	 * Currently twt_get_params nl cmd is sending only dialog_id(STA) and
-	 * mac_addr is being filled by driver in STA peer case. When
-	 * twt_get_params adds support for mac_addr and dialog_id of STA/SAP,
-	 * we need handle unicast/multicast macaddr in
-	 * ucfg_twt_get_all_peer_session_params for all active twt sessions
+	 * Currently for STA case, twt_get_params nl is sending only dialog_id
+	 * and mac_addr is being filled by driver in STA peer case.
+	 * For SAP case, twt_get_params nl is sending dialog_id and
+	 * peer mac_addr. When twt_get_params add mac_addr and dialog_id of
+	 * STA/SAP, we need handle unicast/multicast macaddr in
+	 * ucfg_twt_get_peer_session_params.
 	 */
-	if (dialog_id <= TWT_MAX_DIALOG_ID)
+	if (!QDF_IS_ADDR_BROADCAST(mac_addr))
 		return ucfg_twt_get_single_peer_session_params(psoc_obj,
 							       mac_addr,
 							       dialog_id,
 							       params);
-	else if (dialog_id == TWT_GET_ALL_PEER_PARAMS_DIALOG_ID)
+	else
 		return ucfg_twt_get_all_peer_session_params(psoc_obj, params);
 
 	return QDF_STATUS_E_INVAL;

+ 104 - 6
core/hdd/src/wlan_hdd_twt.c

@@ -29,6 +29,7 @@
 #include "wlan_hdd_twt.h"
 #include "wlan_hdd_main.h"
 #include "wlan_hdd_cfg.h"
+#include "wlan_hdd_hostapd.h"
 #include "sme_api.h"
 #include "wma_twt.h"
 #include "osif_sync.h"
@@ -767,15 +768,82 @@ hdd_twt_get_peer_session_params(struct hdd_context *hdd_ctx,
 }
 
 /**
- * hdd_twt_get_session_params() - Parses twt nl attrributes, obtains twt
+ * hdd_sap_twt_get_session_params() - Parses twt nl attrributes, obtains twt
  * session parameters based on dialog_id and returns to user via nl layer
  * @adapter: hdd_adapter
  * @twt_param_attr: twt nl attributes
  *
  * Return: 0 on success, negative value on failure
  */
-static int hdd_twt_get_session_params(struct hdd_adapter *adapter,
-				      struct nlattr *twt_param_attr)
+static int hdd_sap_twt_get_session_params(struct hdd_adapter *adapter,
+					  struct nlattr *twt_param_attr)
+{
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
+	struct wmi_host_twt_session_stats_info
+				params[TWT_PSOC_MAX_SESSIONS] = { {0} };
+	int ret, id, id1;
+	QDF_STATUS qdf_status;
+	struct qdf_mac_addr mac_addr;
+	bool is_associated;
+
+	ret = wlan_cfg80211_nla_parse_nested(
+					tb, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
+					twt_param_attr,
+					qca_wlan_vendor_twt_add_dialog_policy);
+	if (ret)
+		return ret;
+
+	id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID;
+	id1 = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR;
+
+	if (tb[id] && tb[id1]) {
+		params[0].dialog_id = nla_get_u8(tb[id]);
+		nla_memcpy(params[0].peer_mac, tb[id1], QDF_MAC_ADDR_SIZE);
+	} else {
+		hdd_err_rl("TWT: get_params dialog_id or mac_addr is missing");
+		return -EINVAL;
+	}
+
+	if (QDF_IS_ADDR_BROADCAST(params[0].peer_mac) &&
+	    params[0].dialog_id != TWT_ALL_SESSIONS_DIALOG_ID) {
+		hdd_err_rl("TWT: get_params dialog_is is invalid");
+		return -EINVAL;
+	}
+
+	if (!params[0].dialog_id)
+		params[0].dialog_id = TWT_ALL_SESSIONS_DIALOG_ID;
+
+	qdf_mem_copy(mac_addr.bytes, params[0].peer_mac, QDF_MAC_ADDR_SIZE);
+
+	if (!qdf_is_macaddr_broadcast(&mac_addr)) {
+		is_associated = hdd_is_peer_associated(adapter, &mac_addr);
+		if (!is_associated) {
+			hdd_err("TWT: Association doesn't exist for STA: "
+				   QDF_MAC_ADDR_FMT,
+				   QDF_MAC_ADDR_REF(&mac_addr));
+			return -EINVAL;
+		}
+	}
+
+	hdd_debug("TWT: get_params dialog_id %d and mac_addr " QDF_MAC_ADDR_FMT,
+		  params[0].dialog_id, QDF_MAC_ADDR_REF(params[0].peer_mac));
+
+	qdf_status = hdd_twt_get_peer_session_params(adapter->hdd_ctx,
+						     &params[0]);
+
+	return qdf_status_to_os_return(qdf_status);
+}
+
+/**
+ * hdd_sta_twt_get_session_params() - Parses twt nl attrributes, obtains twt
+ * session parameters based on dialog_id and returns to user via nl layer
+ * @adapter: hdd_adapter
+ * @twt_param_attr: twt nl attributes
+ *
+ * Return: 0 on success, negative value on failure
+ */
+static int hdd_sta_twt_get_session_params(struct hdd_adapter *adapter,
+					  struct nlattr *twt_param_attr)
 {
 	struct hdd_station_ctx *hdd_sta_ctx =
 				WLAN_HDD_GET_STATION_CTX_PTR(adapter);
@@ -784,6 +852,7 @@ static int hdd_twt_get_session_params(struct hdd_adapter *adapter,
 				params[TWT_PSOC_MAX_SESSIONS] = { {0} };
 	int ret, id;
 	QDF_STATUS qdf_status;
+	struct qdf_mac_addr bcast_addr = QDF_MAC_ADDR_BCAST_INIT;
 
 	ret = wlan_cfg80211_nla_parse_nested(tb,
 					     QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
@@ -812,10 +881,12 @@ static int hdd_twt_get_session_params(struct hdd_adapter *adapter,
 			     QDF_MAC_ADDR_SIZE);
 		hdd_debug("TWT: get_params peer mac_addr " QDF_MAC_ADDR_FMT,
 			  QDF_MAC_ADDR_REF(params[0].peer_mac));
+	} else {
+		qdf_mem_copy(params[0].peer_mac, &bcast_addr,
+			     QDF_MAC_ADDR_SIZE);
 	}
 
-	if ((adapter->device_mode != QDF_SAP_MODE ||
-	     params[0].dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID) &&
+	if (params[0].dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID &&
 	    !ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc,
 					 &hdd_sta_ctx->conn_info.bssid,
 					 params[0].dialog_id)) {
@@ -826,7 +897,8 @@ static int hdd_twt_get_session_params(struct hdd_adapter *adapter,
 		return qdf_status_to_os_return(qdf_status);
 	}
 
-	hdd_debug("TWT: get_params dialog_id %d", params[0].dialog_id);
+	hdd_debug("TWT: get_params dialog_id %d and mac_addr " QDF_MAC_ADDR_FMT,
+		  params[0].dialog_id, QDF_MAC_ADDR_REF(params[0].peer_mac));
 
 	qdf_status = hdd_twt_get_peer_session_params(adapter->hdd_ctx,
 						     &params[0]);
@@ -834,6 +906,32 @@ static int hdd_twt_get_session_params(struct hdd_adapter *adapter,
 	return qdf_status_to_os_return(qdf_status);
 }
 
+/**
+ * hdd_twt_get_session_params() - Parses twt nl attrributes, obtains twt
+ * session parameters based on dialog_id and returns to user via nl layer
+ * @adapter: hdd_adapter
+ * @twt_param_attr: twt nl attributes
+ *
+ * Return: 0 on success, negative value on failure
+ */
+static int hdd_twt_get_session_params(struct hdd_adapter *adapter,
+				      struct nlattr *twt_param_attr)
+{
+	enum QDF_OPMODE device_mode = adapter->device_mode;
+
+	switch (device_mode) {
+	case QDF_STA_MODE:
+		return hdd_sta_twt_get_session_params(adapter, twt_param_attr);
+	case QDF_SAP_MODE:
+		return hdd_sap_twt_get_session_params(adapter, twt_param_attr);
+	default:
+		hdd_err_rl("TWT terminate is not supported on %s",
+			   qdf_opmode_str(adapter->device_mode));
+	}
+
+	return -EOPNOTSUPP;
+}
+
 /**
  * hdd_get_twt_setup_event_len() - Calculates the length of twt
  * setup nl response