ソースを参照

qcacmn: Add support for TWT enable operation

Add support for TWT enable operation.

Change-Id: I638a4a78bf33d7185d8eab1f6735c3db0abfcd53
CRs-Fixed: 3085373
Srinivas Girigowda 3 年 前
コミット
2d0aea5c1d

+ 69 - 2
os_if/linux/twt/src/osif_twt_req.c

@@ -18,6 +18,7 @@
   *  DOC: osif_twt_req.c
   *  This file contains twt request related osif APIs
   */
+#include <wlan_cfg80211.h>
 #include <osif_twt_req.h>
 #include <osif_twt_util.h>
 #include <wlan_osif_request_manager.h>
@@ -30,13 +31,79 @@
 int osif_twt_requestor_enable(struct wlan_objmgr_psoc *psoc,
 			      struct twt_enable_param *req)
 {
-	return 0;
+	struct osif_request *request;
+	int ret;
+	QDF_STATUS status;
+	struct twt_en_dis_priv *twt_en_priv;
+	void *context;
+	static const struct osif_request_params params = {
+				.priv_size = sizeof(*twt_en_priv),
+				.timeout_ms = TWT_ENABLE_COMPLETE_TIMEOUT,
+	};
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		osif_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	context = osif_request_cookie(request);
+
+	status = ucfg_twt_requestor_enable(psoc, req, context);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		osif_warn("Failed to send TWT requestor enable command");
+		ret = qdf_status_to_os_return(status);
+		goto cleanup;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		osif_warn("TWT Requestor Enable timedout ret:%d", ret);
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+cleanup:
+	osif_request_put(request);
+	return ret;
 }
 
 int osif_twt_responder_enable(struct wlan_objmgr_psoc *psoc,
 			      struct twt_enable_param *req)
 {
-	return 0;
+	struct osif_request *request;
+	int ret;
+	QDF_STATUS status;
+	struct twt_en_dis_priv *twt_en_priv;
+	void *context;
+	static const struct osif_request_params params = {
+				.priv_size = sizeof(*twt_en_priv),
+				.timeout_ms = TWT_ENABLE_COMPLETE_TIMEOUT,
+	};
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		osif_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	context = osif_request_cookie(request);
+
+	status = ucfg_twt_responder_enable(psoc, req, context);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		osif_warn("Failed to send TWT responder enable command");
+		ret = qdf_status_to_os_return(status);
+		goto cleanup;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		osif_warn("TWT Responder Enable timedout ret:%d", ret);
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+cleanup:
+	osif_request_put(request);
+	return ret;
 }
 
 int osif_twt_requestor_disable(struct wlan_objmgr_psoc *psoc,

+ 22 - 0
os_if/linux/twt/src/osif_twt_rsp.c

@@ -19,6 +19,7 @@
  *
  */
 #include <qdf_status.h>
+#include <wlan_cfg80211.h>
 #include <osif_twt_rsp.h>
 #include <osif_twt_util.h>
 #include <wlan_osif_request_manager.h>
@@ -36,6 +37,27 @@ osif_twt_enable_complete_cb(struct wlan_objmgr_psoc *psoc,
 			    struct twt_enable_complete_event_param *event,
 			    void *context)
 {
+	struct twt_en_dis_priv *twt_en_priv;
+	struct osif_request *request = NULL;
+
+	osif_debug("osif_twt_enable_complete_cb");
+	request = osif_request_get(context);
+	if (!request) {
+		osif_err("obsolete request");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	twt_en_priv = osif_request_priv(request);
+	if (!twt_en_priv) {
+		osif_err("obsolete twt_en_priv");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	twt_en_priv->pdev_id = event->pdev_id;
+	twt_en_priv->status = event->status;
+
+	osif_request_complete(request);
+	osif_request_put(request);
 	return QDF_STATUS_SUCCESS;
 }
 

+ 19 - 1
target_if/twt/src/target_if_twt_cmd.c

@@ -27,7 +27,25 @@ QDF_STATUS
 target_if_twt_enable_req(struct wlan_objmgr_psoc *psoc,
 			 struct twt_enable_param *req)
 {
-	return QDF_STATUS_SUCCESS;
+	QDF_STATUS ret;
+	struct wmi_unified *wmi_handle;
+
+	if (!psoc) {
+		target_if_err("null psoc");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("null wmi handle");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wmi_unified_twt_enable_cmd(wmi_handle, req);
+	if (QDF_IS_STATUS_ERROR(ret))
+		target_if_err("Failed to enable TWT(ret=%d)", ret);
+
+	return ret;
 }
 
 QDF_STATUS

+ 42 - 1
target_if/twt/src/target_if_twt_evt.c

@@ -29,7 +29,48 @@ int
 target_if_twt_en_complete_event_handler(ol_scn_t scn,
 					uint8_t *data, uint32_t datalen)
 {
-	return 0;
+	wmi_unified_t wmi_handle;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_lmac_if_twt_rx_ops *rx_ops;
+	struct twt_enable_complete_event_param event;
+	QDF_STATUS status;
+
+	TARGET_IF_ENTER();
+
+	if (!scn || !data) {
+		target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("psoc is null");
+		return -EINVAL;
+	}
+
+	rx_ops = wlan_twt_get_rx_ops(psoc);
+	if (!rx_ops || !rx_ops->twt_enable_comp_cb) {
+		target_if_err("TWT rx_ops is NULL");
+		return -EINVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null");
+		return -EINVAL;
+	}
+
+	status = wmi_extract_twt_enable_comp_event(wmi_handle, data, &event);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("TWT enable extract event failed(status=%d)",
+				status);
+		goto end;
+	}
+
+	status = rx_ops->twt_enable_comp_cb(psoc, &event);
+
+end:
+	return qdf_status_to_os_return(status);
 }
 
 int

+ 117 - 3
umac/twt/core/src/wlan_twt_common.c

@@ -17,11 +17,13 @@
 /**
  *  DOC: wlan_twt_common.c
  */
+#include "include/wlan_mlme_cmn.h"
 #include "wlan_twt_common.h"
 #include "wlan_twt_priv.h"
 #include <wlan_twt_public_structs.h>
 #include <wlan_objmgr_peer_obj.h>
 #include <wlan_twt_tgt_if_tx_api.h>
+#include "twt/core/src/wlan_twt_cfg.h"
 
 QDF_STATUS
 wlan_twt_tgt_caps_get_requestor(struct wlan_objmgr_psoc *psoc, bool *val)
@@ -263,7 +265,45 @@ wlan_twt_requestor_enable(struct wlan_objmgr_psoc *psoc,
 			  struct twt_enable_param *req,
 			  void *context)
 {
-	return QDF_STATUS_SUCCESS;
+	struct twt_psoc_priv_obj *twt_psoc;
+	bool requestor_en = false, twt_bcast_requestor = false;
+
+	if (!psoc) {
+		twt_err("null psoc");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	twt_psoc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+							 WLAN_UMAC_COMP_TWT);
+	if (!twt_psoc) {
+		twt_err("null twt psoc priv obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wlan_twt_cfg_get_requestor(psoc, &requestor_en);
+	if (!requestor_en) {
+		twt_warn("twt requestor ini is not enabled");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	twt_psoc->enable_context.twt_role = TWT_ROLE_REQUESTOR;
+	twt_psoc->enable_context.context = context;
+
+	wlan_twt_cfg_get_congestion_timeout(psoc, &req->sta_cong_timer_ms);
+	wlan_twt_cfg_get_bcast_requestor(psoc, &twt_bcast_requestor);
+	req->b_twt_enable = twt_bcast_requestor;
+	req->twt_role = TWT_ROLE_REQUESTOR;
+	if (twt_bcast_requestor)
+		req->twt_oper = TWT_OPERATION_BROADCAST;
+	else
+		req->twt_oper = TWT_OPERATION_INDIVIDUAL;
+
+	twt_debug("TWT req enable: pdev_id:%d cong:%d bcast:%d",
+		  req->pdev_id, req->sta_cong_timer_ms, req->b_twt_enable);
+	twt_debug("TWT req enable: role:%d ext:%d oper:%d",
+		  req->twt_role, req->ext_conf_present, req->twt_oper);
+
+	return tgt_twt_enable_req_send(psoc, req);
 }
 
 QDF_STATUS
@@ -271,14 +311,88 @@ wlan_twt_responder_enable(struct wlan_objmgr_psoc *psoc,
 			  struct twt_enable_param *req,
 			  void *context)
 {
-	return QDF_STATUS_SUCCESS;
+	struct twt_psoc_priv_obj *twt_psoc;
+	bool responder_en = false, twt_bcast_responder = false;
+
+	if (!psoc) {
+		twt_err("null psoc");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	twt_psoc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+							 WLAN_UMAC_COMP_TWT);
+	if (!twt_psoc) {
+		twt_err("null twt psoc priv obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wlan_twt_cfg_get_responder(psoc, &responder_en);
+	if (!responder_en) {
+		twt_warn("twt responder ini is not enabled");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	twt_psoc->enable_context.twt_role = TWT_ROLE_RESPONDER;
+	twt_psoc->enable_context.context = context;
+
+	wlan_twt_cfg_get_bcast_responder(psoc, &twt_bcast_responder);
+	req->b_twt_enable = twt_bcast_responder;
+	req->twt_role = TWT_ROLE_RESPONDER;
+	if (twt_bcast_responder)
+		req->twt_oper = TWT_OPERATION_BROADCAST;
+	else
+		req->twt_oper = TWT_OPERATION_INDIVIDUAL;
+
+	twt_debug("TWT res enable: pdev_id:%d bcast:%d",
+		  req->pdev_id, req->b_twt_enable);
+	twt_debug("TWT res enable: role:%d ext:%d oper:%d",
+		  req->twt_role, req->ext_conf_present, req->twt_oper);
+
+	return tgt_twt_enable_req_send(psoc, req);
 }
 
 QDF_STATUS
 wlan_twt_enable_event_handler(struct wlan_objmgr_psoc *psoc,
 			      struct twt_enable_complete_event_param *event)
 {
-	return QDF_STATUS_SUCCESS;
+	struct twt_psoc_priv_obj *twt_psoc;
+	struct twt_en_dis_context *twt_context;
+
+	if (!psoc) {
+		twt_err("null psoc");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	twt_psoc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+							 WLAN_UMAC_COMP_TWT);
+	if (!twt_psoc) {
+		twt_err("null twt psoc priv obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	twt_context = &twt_psoc->enable_context;
+
+	twt_debug("pdev_id:%d status:%d twt_role:%d",
+		  event->pdev_id, event->status, twt_context->twt_role);
+	switch (event->status) {
+	case HOST_TWT_ENABLE_STATUS_OK:
+	case HOST_TWT_ENABLE_STATUS_ALREADY_ENABLED:
+		if (twt_context->twt_role == TWT_ROLE_REQUESTOR)
+			wlan_twt_cfg_set_requestor_flag(psoc, true);
+		else if (twt_context->twt_role == TWT_ROLE_RESPONDER)
+			wlan_twt_cfg_set_responder_flag(psoc, true);
+		else
+			twt_err("Invalid role:%d", twt_context->twt_role);
+
+		break;
+
+	default:
+		twt_err("twt enable status:%d", event->status);
+		break;
+	}
+
+	return mlme_twt_osif_enable_complete_ind(psoc, event,
+						 twt_context->context);
 }
 
 QDF_STATUS

+ 17 - 4
umac/twt/core/src/wlan_twt_common.h

@@ -143,7 +143,7 @@ wlan_twt_disable(struct wlan_objmgr_psoc *psoc,
 		 void *context);
 
 /**
- * wlan_twt_enable() - twt enable
+ * wlan_twt_requestor_enable() - twt requestor enable
  * @psoc: psoc handle
  * @req: twt enable request structure
  * @context: context
@@ -151,9 +151,22 @@ wlan_twt_disable(struct wlan_objmgr_psoc *psoc,
  * return: QDF_STATUS
  */
 QDF_STATUS
-wlan_twt_enable(struct wlan_objmgr_psoc *psoc,
-		struct twt_enable_param *req,
-		void *context);
+wlan_twt_requestor_enable(struct wlan_objmgr_psoc *psoc,
+			  struct twt_enable_param *req,
+			  void *context);
+
+/**
+ * wlan_twt_responder_enable() - twt responder enable
+ * @psoc: psoc handle
+ * @req: twt enable request structure
+ * @context: context
+ *
+ * return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_twt_responder_enable(struct wlan_objmgr_psoc *psoc,
+			  struct twt_enable_param *req,
+			  void *context);
 
 /**
  * wlan_twt_enable_event_handler() - twt enable handler

+ 1 - 1
umac/twt/dispatcher/src/wlan_twt_tgt_if_rx_api.c

@@ -31,7 +31,7 @@ static QDF_STATUS
 tgt_twt_enable_complete_resp_handler(struct wlan_objmgr_psoc *psoc,
 			     struct twt_enable_complete_event_param *event)
 {
-	return QDF_STATUS_SUCCESS;
+	return wlan_twt_enable_event_handler(psoc, event);
 }
 
 static QDF_STATUS

+ 28 - 1
umac/twt/dispatcher/src/wlan_twt_tgt_if_tx_api.c

@@ -25,12 +25,39 @@
 #include <wlan_objmgr_psoc_obj.h>
 #include <wlan_twt_public_structs.h>
 #include <wlan_twt_tgt_if_tx_api.h>
+#include <wlan_lmac_if_def.h>
+#include <wlan_twt_api.h>
 
 QDF_STATUS
 tgt_twt_enable_req_send(struct wlan_objmgr_psoc *psoc,
 			struct twt_enable_param *req)
 {
-	return QDF_STATUS_SUCCESS;
+	struct wlan_lmac_if_twt_tx_ops *tx_ops;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		twt_err("null psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!req) {
+		twt_err("Invalid input");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_ops = wlan_twt_get_tx_ops(psoc);
+	if (!tx_ops || !tx_ops->enable_req) {
+		twt_err("twt enable_req tx_ops is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = tx_ops->enable_req(psoc, req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		twt_err("tx_ops enable_req failed (status=%d)", status);
+		return status;
+	}
+
+	return status;
 }
 
 QDF_STATUS