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