xref: /wlan-driver/qca-wifi-host-cmn/os_if/linux/twt/src/osif_twt_req.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
3*5113495bSYour Name  *
4*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
5*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
6*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
7*5113495bSYour Name  *
8*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*5113495bSYour Name  */
16*5113495bSYour Name 
17*5113495bSYour Name  /**
18*5113495bSYour Name   *  DOC: osif_twt_req.c
19*5113495bSYour Name   *  This file contains twt request related osif APIs
20*5113495bSYour Name   */
21*5113495bSYour Name #include <wlan_cfg80211.h>
22*5113495bSYour Name #include <osif_twt_req.h>
23*5113495bSYour Name #include <osif_twt_util.h>
24*5113495bSYour Name #include <wlan_osif_request_manager.h>
25*5113495bSYour Name #include <wlan_twt_ucfg_api.h>
26*5113495bSYour Name #include <wlan_twt_ucfg_ext_api.h>
27*5113495bSYour Name 
28*5113495bSYour Name #define TWT_DISABLE_COMPLETE_TIMEOUT 1000
29*5113495bSYour Name #define TWT_ENABLE_COMPLETE_TIMEOUT  1000
30*5113495bSYour Name 
osif_twt_requestor_enable(struct wlan_objmgr_psoc * psoc,struct twt_enable_param * req)31*5113495bSYour Name int osif_twt_requestor_enable(struct wlan_objmgr_psoc *psoc,
32*5113495bSYour Name 			      struct twt_enable_param *req)
33*5113495bSYour Name {
34*5113495bSYour Name 	struct osif_request *request;
35*5113495bSYour Name 	int ret;
36*5113495bSYour Name 	QDF_STATUS status;
37*5113495bSYour Name 	struct twt_en_dis_priv *twt_en_priv;
38*5113495bSYour Name 	void *context;
39*5113495bSYour Name 	static const struct osif_request_params params = {
40*5113495bSYour Name 				.priv_size = sizeof(*twt_en_priv),
41*5113495bSYour Name 				.timeout_ms = TWT_ENABLE_COMPLETE_TIMEOUT,
42*5113495bSYour Name 	};
43*5113495bSYour Name 
44*5113495bSYour Name 	request = osif_request_alloc(&params);
45*5113495bSYour Name 	if (!request) {
46*5113495bSYour Name 		osif_err("Request allocation failure");
47*5113495bSYour Name 		return -ENOMEM;
48*5113495bSYour Name 	}
49*5113495bSYour Name 	context = osif_request_cookie(request);
50*5113495bSYour Name 
51*5113495bSYour Name 	status = ucfg_twt_requestor_enable(psoc, req, context);
52*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
53*5113495bSYour Name 		osif_warn("Failed to send TWT requestor enable command");
54*5113495bSYour Name 		ret = qdf_status_to_os_return(status);
55*5113495bSYour Name 		goto cleanup;
56*5113495bSYour Name 	}
57*5113495bSYour Name 
58*5113495bSYour Name 	ret = osif_request_wait_for_response(request);
59*5113495bSYour Name 	if (ret) {
60*5113495bSYour Name 		osif_warn("TWT Requestor Enable timedout ret:%d", ret);
61*5113495bSYour Name 		ret = -ETIMEDOUT;
62*5113495bSYour Name 		goto cleanup;
63*5113495bSYour Name 	}
64*5113495bSYour Name 
65*5113495bSYour Name 	twt_en_priv = osif_request_priv(request);
66*5113495bSYour Name 	if (twt_en_priv->status != HOST_TWT_ENABLE_STATUS_OK &&
67*5113495bSYour Name 	    twt_en_priv->status != HOST_TWT_ENABLE_STATUS_ALREADY_ENABLED)
68*5113495bSYour Name 		ret = -EBUSY;
69*5113495bSYour Name cleanup:
70*5113495bSYour Name 	osif_request_put(request);
71*5113495bSYour Name 	return ret;
72*5113495bSYour Name }
73*5113495bSYour Name 
osif_twt_responder_enable(struct wlan_objmgr_psoc * psoc,struct twt_enable_param * req)74*5113495bSYour Name int osif_twt_responder_enable(struct wlan_objmgr_psoc *psoc,
75*5113495bSYour Name 			      struct twt_enable_param *req)
76*5113495bSYour Name {
77*5113495bSYour Name 	struct osif_request *request;
78*5113495bSYour Name 	int ret;
79*5113495bSYour Name 	QDF_STATUS status;
80*5113495bSYour Name 	struct twt_en_dis_priv *twt_en_priv;
81*5113495bSYour Name 	void *context;
82*5113495bSYour Name 	static const struct osif_request_params params = {
83*5113495bSYour Name 				.priv_size = sizeof(*twt_en_priv),
84*5113495bSYour Name 				.timeout_ms = TWT_ENABLE_COMPLETE_TIMEOUT,
85*5113495bSYour Name 	};
86*5113495bSYour Name 
87*5113495bSYour Name 	request = osif_request_alloc(&params);
88*5113495bSYour Name 	if (!request) {
89*5113495bSYour Name 		osif_err("Request allocation failure");
90*5113495bSYour Name 		return -ENOMEM;
91*5113495bSYour Name 	}
92*5113495bSYour Name 	context = osif_request_cookie(request);
93*5113495bSYour Name 
94*5113495bSYour Name 	status = ucfg_twt_responder_enable(psoc, req, context);
95*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
96*5113495bSYour Name 		osif_warn("Failed to send TWT responder enable command");
97*5113495bSYour Name 		ret = qdf_status_to_os_return(status);
98*5113495bSYour Name 		goto cleanup;
99*5113495bSYour Name 	}
100*5113495bSYour Name 
101*5113495bSYour Name 	ret = osif_request_wait_for_response(request);
102*5113495bSYour Name 	if (ret) {
103*5113495bSYour Name 		osif_warn("TWT Responder Enable timedout ret:%d", ret);
104*5113495bSYour Name 		ret = -ETIMEDOUT;
105*5113495bSYour Name 		goto cleanup;
106*5113495bSYour Name 	}
107*5113495bSYour Name 
108*5113495bSYour Name cleanup:
109*5113495bSYour Name 	osif_request_put(request);
110*5113495bSYour Name 	return ret;
111*5113495bSYour Name }
112*5113495bSYour Name 
osif_twt_requestor_disable(struct wlan_objmgr_psoc * psoc,struct twt_disable_param * req)113*5113495bSYour Name int osif_twt_requestor_disable(struct wlan_objmgr_psoc *psoc,
114*5113495bSYour Name 			       struct twt_disable_param *req)
115*5113495bSYour Name {
116*5113495bSYour Name 	struct osif_request *request;
117*5113495bSYour Name 	int ret;
118*5113495bSYour Name 	QDF_STATUS status;
119*5113495bSYour Name 	struct twt_en_dis_priv *twt_en_priv;
120*5113495bSYour Name 	void *context;
121*5113495bSYour Name 	static const struct osif_request_params params = {
122*5113495bSYour Name 				.priv_size = sizeof(*twt_en_priv),
123*5113495bSYour Name 				.timeout_ms = TWT_DISABLE_COMPLETE_TIMEOUT,
124*5113495bSYour Name 	};
125*5113495bSYour Name 
126*5113495bSYour Name 	request = osif_request_alloc(&params);
127*5113495bSYour Name 	if (!request) {
128*5113495bSYour Name 		osif_err("Request allocation failure");
129*5113495bSYour Name 		return -ENOMEM;
130*5113495bSYour Name 	}
131*5113495bSYour Name 	context = osif_request_cookie(request);
132*5113495bSYour Name 
133*5113495bSYour Name 	status = ucfg_twt_requestor_disable(psoc, req, context);
134*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
135*5113495bSYour Name 		osif_warn("Failed to send TWT requestor disable command");
136*5113495bSYour Name 		ret = qdf_status_to_os_return(status);
137*5113495bSYour Name 		goto cleanup;
138*5113495bSYour Name 	}
139*5113495bSYour Name 
140*5113495bSYour Name 	ret = osif_request_wait_for_response(request);
141*5113495bSYour Name 	if (ret) {
142*5113495bSYour Name 		osif_warn("TWT Requestor disable timedout ret:%d", ret);
143*5113495bSYour Name 		ret = -ETIMEDOUT;
144*5113495bSYour Name 		goto cleanup;
145*5113495bSYour Name 	}
146*5113495bSYour Name 
147*5113495bSYour Name 	twt_en_priv = osif_request_priv(request);
148*5113495bSYour Name 	if (twt_en_priv->status != HOST_TWT_DISABLE_STATUS_OK)
149*5113495bSYour Name 		ret = -EBUSY;
150*5113495bSYour Name cleanup:
151*5113495bSYour Name 	osif_request_put(request);
152*5113495bSYour Name 	return ret;
153*5113495bSYour Name }
154*5113495bSYour Name 
osif_twt_responder_disable(struct wlan_objmgr_psoc * psoc,struct twt_disable_param * req)155*5113495bSYour Name int osif_twt_responder_disable(struct wlan_objmgr_psoc *psoc,
156*5113495bSYour Name 			       struct twt_disable_param *req)
157*5113495bSYour Name {
158*5113495bSYour Name 	struct osif_request *request;
159*5113495bSYour Name 	int ret;
160*5113495bSYour Name 	QDF_STATUS status;
161*5113495bSYour Name 	struct twt_en_dis_priv *twt_en_priv;
162*5113495bSYour Name 	void *context;
163*5113495bSYour Name 	static const struct osif_request_params params = {
164*5113495bSYour Name 				.priv_size = sizeof(*twt_en_priv),
165*5113495bSYour Name 				.timeout_ms = TWT_DISABLE_COMPLETE_TIMEOUT,
166*5113495bSYour Name 	};
167*5113495bSYour Name 
168*5113495bSYour Name 	request = osif_request_alloc(&params);
169*5113495bSYour Name 	if (!request) {
170*5113495bSYour Name 		osif_err("Request allocation failure");
171*5113495bSYour Name 		return -ENOMEM;
172*5113495bSYour Name 	}
173*5113495bSYour Name 	context = osif_request_cookie(request);
174*5113495bSYour Name 
175*5113495bSYour Name 	status = ucfg_twt_responder_disable(psoc, req, context);
176*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
177*5113495bSYour Name 		osif_warn("Failed to send TWT responder disable command");
178*5113495bSYour Name 		ret = qdf_status_to_os_return(status);
179*5113495bSYour Name 		goto cleanup;
180*5113495bSYour Name 	}
181*5113495bSYour Name 
182*5113495bSYour Name 	ret = osif_request_wait_for_response(request);
183*5113495bSYour Name 	if (ret) {
184*5113495bSYour Name 		osif_warn("TWT Responder disable timedout ret:%d", ret);
185*5113495bSYour Name 		ret = -ETIMEDOUT;
186*5113495bSYour Name 		goto cleanup;
187*5113495bSYour Name 	}
188*5113495bSYour Name 
189*5113495bSYour Name cleanup:
190*5113495bSYour Name 	osif_request_put(request);
191*5113495bSYour Name 	return ret;
192*5113495bSYour Name }
193*5113495bSYour Name 
194