瀏覽代碼

qcacmn: Add support for TWT disable operation

Add support for TWT disable operation.

Change-Id: I302ac6a3898f53ea25030d9a15d8d14988287b27
CRs-Fixed: 3085373
Srinivas Girigowda 3 年之前
父節點
當前提交
fd35443a0a

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

@@ -109,12 +109,78 @@ cleanup:
 int osif_twt_requestor_disable(struct wlan_objmgr_psoc *psoc,
 			       struct twt_disable_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_DISABLE_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_disable(psoc, req, context);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		osif_warn("Failed to send TWT requestor disable command");
+		ret = qdf_status_to_os_return(status);
+		goto cleanup;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		osif_warn("TWT Requestor disable timedout ret:%d", ret);
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+cleanup:
+	osif_request_put(request);
+	return ret;
 }
 
 int osif_twt_responder_disable(struct wlan_objmgr_psoc *psoc,
 			       struct twt_disable_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_DISABLE_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_disable(psoc, req, context);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		osif_warn("Failed to send TWT responder disable command");
+		ret = qdf_status_to_os_return(status);
+		goto cleanup;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		osif_warn("TWT Responder disable timedout ret:%d", ret);
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+cleanup:
+	osif_request_put(request);
+	return ret;
 }
 

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

@@ -74,6 +74,27 @@ osif_twt_disable_complete_cb(struct wlan_objmgr_psoc *psoc,
 			     struct twt_disable_complete_event_param *event,
 			     void *context)
 {
+	struct twt_en_dis_priv *twt_en_priv;
+	struct osif_request *request = NULL;
+
+	osif_debug("osif_handle_twt_disable_complete");
+	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

@@ -52,6 +52,24 @@ QDF_STATUS
 target_if_twt_disable_req(struct wlan_objmgr_psoc *psoc,
 			  struct twt_disable_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_disable_cmd(wmi_handle, req);
+	if (QDF_IS_STATUS_ERROR(ret))
+		target_if_err("Failed to disable TWT(ret=%d)", ret);
+
+	return ret;
 }
 

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

@@ -77,6 +77,47 @@ int
 target_if_twt_disable_comp_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_disable_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_disable_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_disable_comp_event(wmi_handle, data, &event);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		target_if_err("TWT disable extract event failed(status=%d)",
+				status);
+		goto end;
+	}
+
+	status = rx_ops->twt_disable_comp_cb(psoc, &event);
+
+end:
+	return qdf_status_to_os_return(status);
 }
 

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

@@ -249,7 +249,29 @@ wlan_twt_requestor_disable(struct wlan_objmgr_psoc *psoc,
 			   struct twt_disable_param *req,
 			   void *context)
 {
-	return QDF_STATUS_SUCCESS;
+	struct twt_psoc_priv_obj *twt_psoc;
+
+	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_psoc->disable_context.twt_role = TWT_ROLE_REQUESTOR;
+	twt_psoc->disable_context.context = context;
+
+	req->twt_role = TWT_ROLE_REQUESTOR;
+
+	twt_debug("TWT req disable: pdev_id:%d role:%d ext:%d",
+		  req->pdev_id, req->twt_role, req->ext_conf_present);
+
+	return tgt_twt_disable_req_send(psoc, req);
 }
 
 QDF_STATUS
@@ -257,7 +279,29 @@ wlan_twt_responder_disable(struct wlan_objmgr_psoc *psoc,
 			   struct twt_disable_param *req,
 			   void *context)
 {
-	return QDF_STATUS_SUCCESS;
+	struct twt_psoc_priv_obj *twt_psoc;
+
+	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_psoc->disable_context.twt_role = TWT_ROLE_RESPONDER;
+	twt_psoc->disable_context.context = context;
+
+	req->twt_role = TWT_ROLE_RESPONDER;
+
+	twt_debug("TWT res disable: pdev_id:%d role:%d ext:%d",
+		  req->pdev_id, req->twt_role, req->ext_conf_present);
+
+	return tgt_twt_disable_req_send(psoc, req);
 }
 
 QDF_STATUS
@@ -399,6 +443,42 @@ QDF_STATUS
 wlan_twt_disable_event_handler(struct wlan_objmgr_psoc *psoc,
 			       struct twt_disable_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->disable_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_DISABLE_STATUS_OK:
+		if (twt_context->twt_role == TWT_ROLE_REQUESTOR)
+			wlan_twt_cfg_set_requestor_flag(psoc, false);
+		else if (twt_context->twt_role == TWT_ROLE_RESPONDER)
+			wlan_twt_cfg_set_responder_flag(psoc, false);
+		else
+			twt_err("Invalid role:%d", twt_context->twt_role);
+
+		break;
+
+	default:
+		twt_err("twt disable status:%d", event->status);
+		break;
+	}
+
+	return mlme_twt_osif_disable_complete_ind(psoc, event,
+						  twt_context->context);
 }
 

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

@@ -130,7 +130,7 @@ QDF_STATUS wlan_twt_check_all_twt_support(struct wlan_objmgr_psoc *psoc,
 					  uint32_t dialog_id);
 
 /**
- * wlan_twt_disable() - twt disable
+ * wlan_twt_requestor_disable() - twt requestor disable
  * @psoc: psoc handle
  * @req: twt disable request structure
  * @context: context
@@ -138,9 +138,22 @@ QDF_STATUS wlan_twt_check_all_twt_support(struct wlan_objmgr_psoc *psoc,
  * return: QDF_STATUS
  */
 QDF_STATUS
-wlan_twt_disable(struct wlan_objmgr_psoc *psoc,
-		 struct twt_disable_param *req,
-		 void *context);
+wlan_twt_requestor_disable(struct wlan_objmgr_psoc *psoc,
+			   struct twt_disable_param *req,
+			   void *context);
+
+/**
+ * wlan_twt_responder_disable() - twt responder disable
+ * @psoc: psoc handle
+ * @req: twt disable request structure
+ * @context: context
+ *
+ * return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_twt_responder_disable(struct wlan_objmgr_psoc *psoc,
+			   struct twt_disable_param *req,
+			   void *context);
 
 /**
  * wlan_twt_requestor_enable() - twt requestor enable

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

@@ -38,7 +38,7 @@ static QDF_STATUS
 tgt_twt_disable_complete_resp_handler(struct wlan_objmgr_psoc *psoc,
 			     struct twt_disable_complete_event_param *event)
 {
-	return QDF_STATUS_SUCCESS;
+	return wlan_twt_disable_event_handler(psoc, event);
 }
 
 void tgt_twt_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)

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

@@ -64,5 +64,30 @@ QDF_STATUS
 tgt_twt_disable_req_send(struct wlan_objmgr_psoc *psoc,
 			 struct twt_disable_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->disable_req) {
+		twt_err("twt disable_req tx_ops is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = tx_ops->disable_req(psoc, req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		twt_err("tx_ops disable_req failed (status=%d)", status);
+		return status;
+	}
+
+	return status;
 }