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(¶ms);
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(¶ms);
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(¶ms);
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(¶ms);
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