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
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 #include <wlan_twt_ext_type.h>
19 #include <wlan_twt_api.h>
20 #include <cfg_ucfg_api.h>
21 #include <cfg_twt.h>
22 #include "wlan_twt_cfg.h"
23 #include "twt/core/src/wlan_twt_priv.h"
24 
wlan_twt_cfg_init(struct wlan_objmgr_psoc * psoc)25 QDF_STATUS wlan_twt_cfg_init(struct wlan_objmgr_psoc *psoc)
26 {
27 	struct twt_psoc_priv_obj *twt_psoc;
28 	psoc_twt_ext_cfg_params_t *twt_cfg;
29 	uint32_t bcast_conf;
30 	uint32_t rtwt_conf;
31 
32 	if (!psoc) {
33 		twt_err("null psoc");
34 		return QDF_STATUS_E_FAILURE;
35 	}
36 
37 	twt_psoc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
38 							 WLAN_UMAC_COMP_TWT);
39 	if (!twt_psoc) {
40 		twt_err("null twt psoc priv obj");
41 		return QDF_STATUS_E_FAILURE;
42 	}
43 
44 	twt_cfg = &twt_psoc->cfg_params;
45 	bcast_conf = cfg_get(psoc, CFG_BCAST_TWT_REQ_RESP);
46 	rtwt_conf = cfg_get(psoc, CFG_RTWT_REQ_RESP);
47 
48 
49 	twt_cfg->enable_twt = cfg_get(psoc, CFG_ENABLE_TWT);
50 	twt_cfg->twt_requestor = cfg_get(psoc, CFG_TWT_REQUESTOR);
51 	twt_cfg->twt_responder = cfg_get(psoc, CFG_TWT_RESPONDER);
52 	twt_cfg->twt_congestion_timeout =
53 				cfg_get(psoc, CFG_TWT_CONGESTION_TIMEOUT);
54 	twt_cfg->bcast_requestor_enabled = CFG_TWT_GET_BCAST_REQ(bcast_conf);
55 	twt_cfg->bcast_responder_enabled = CFG_TWT_GET_BCAST_RES(bcast_conf);
56 	twt_cfg->enable_twt_24ghz = cfg_get(psoc, CFG_ENABLE_TWT_24GHZ);
57 	twt_cfg->flex_twt_sched = cfg_default(CFG_HE_FLEX_TWT_SCHED);
58 	twt_cfg->is_twt_enabled_in_11n = cfg_get(psoc, CFG_TWT_ENABLE_IN_11N);
59 	twt_cfg->req_flag = false;
60 	twt_cfg->res_flag = false;
61 	twt_cfg->rtwt_requestor_enabled = CFG_GET_RTWT_REQ(rtwt_conf);
62 	twt_cfg->rtwt_responder_enabled = CFG_GET_RTWT_RES(rtwt_conf);
63 
64 	twt_debug("req: %d resp: %d", twt_cfg->twt_requestor,
65 		  twt_cfg->twt_responder);
66 
67 	return QDF_STATUS_SUCCESS;
68 }
69 
wlan_twt_cfg_deinit(struct wlan_objmgr_psoc * psoc)70 QDF_STATUS wlan_twt_cfg_deinit(struct wlan_objmgr_psoc *psoc)
71 {
72 	struct twt_psoc_priv_obj *twt_psoc;
73 
74 	if (!psoc) {
75 		twt_err("null psoc");
76 		return QDF_STATUS_E_FAILURE;
77 	}
78 
79 	twt_psoc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
80 							 WLAN_UMAC_COMP_TWT);
81 	if (!twt_psoc) {
82 		twt_err("null twt psoc priv obj");
83 		return QDF_STATUS_E_FAILURE;
84 	}
85 
86 	qdf_mem_zero(&twt_psoc->cfg_params, sizeof(twt_psoc->cfg_params));
87 
88 	return QDF_STATUS_SUCCESS;
89 }
90 
wlan_twt_cfg_update(struct wlan_objmgr_psoc * psoc)91 QDF_STATUS wlan_twt_cfg_update(struct wlan_objmgr_psoc *psoc)
92 {
93 	struct twt_psoc_priv_obj *twt_psoc;
94 	psoc_twt_ext_cfg_params_t *twt_cfg;
95 	struct twt_tgt_caps *tgt_caps;
96 	bool enable_twt;
97 
98 	if (!psoc) {
99 		twt_err("null psoc");
100 		return QDF_STATUS_E_FAILURE;
101 	}
102 
103 	twt_psoc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
104 							 WLAN_UMAC_COMP_TWT);
105 	if (!twt_psoc) {
106 		twt_err("null twt psoc priv obj");
107 		return QDF_STATUS_E_FAILURE;
108 	}
109 
110 	twt_cfg = &twt_psoc->cfg_params;
111 	tgt_caps = &twt_psoc->twt_caps;
112 	enable_twt = twt_cfg->enable_twt;
113 
114 	twt_cfg->twt_requestor = QDF_MIN(tgt_caps->twt_requestor,
115 					(enable_twt && twt_cfg->twt_requestor));
116 	twt_cfg->twt_responder = QDF_MIN(tgt_caps->twt_responder,
117 					(enable_twt && twt_cfg->twt_responder));
118 	twt_cfg->bcast_requestor_enabled =
119 			QDF_MIN((tgt_caps->twt_bcast_req_support ||
120 				tgt_caps->legacy_bcast_twt_support),
121 				(enable_twt &&
122 					twt_cfg->bcast_requestor_enabled));
123 	twt_cfg->bcast_responder_enabled =
124 			QDF_MIN((tgt_caps->twt_bcast_res_support ||
125 				tgt_caps->legacy_bcast_twt_support),
126 				(enable_twt &&
127 					twt_cfg->bcast_responder_enabled));
128 	twt_debug("req: %d resp: %d bcast_req: %d bcast_resp: %d",
129 		  twt_cfg->twt_requestor, twt_cfg->twt_responder,
130 		  twt_cfg->bcast_requestor_enabled,
131 		  twt_cfg->bcast_responder_enabled);
132 	return QDF_STATUS_SUCCESS;
133 }
134 
135 QDF_STATUS
wlan_twt_cfg_get_requestor(struct wlan_objmgr_psoc * psoc,bool * val)136 wlan_twt_cfg_get_requestor(struct wlan_objmgr_psoc *psoc, bool *val)
137 {
138 	struct twt_psoc_priv_obj *twt_psoc_obj;
139 
140 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
141 	if (!twt_psoc_obj) {
142 		*val = cfg_default(CFG_TWT_REQUESTOR);
143 		return QDF_STATUS_E_INVAL;
144 	}
145 
146 	*val = twt_psoc_obj->cfg_params.twt_requestor;
147 
148 	return QDF_STATUS_SUCCESS;
149 }
150 
151 QDF_STATUS
wlan_twt_cfg_get_responder(struct wlan_objmgr_psoc * psoc,bool * val)152 wlan_twt_cfg_get_responder(struct wlan_objmgr_psoc *psoc, bool *val)
153 {
154 	struct twt_psoc_priv_obj *twt_psoc_obj;
155 
156 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
157 	if (!twt_psoc_obj) {
158 		*val = cfg_default(CFG_TWT_RESPONDER);
159 		return QDF_STATUS_E_INVAL;
160 	}
161 
162 	*val = twt_psoc_obj->cfg_params.twt_responder;
163 
164 	return QDF_STATUS_SUCCESS;
165 }
166 
167 QDF_STATUS
wlan_twt_cfg_set_responder(struct wlan_objmgr_psoc * psoc,bool val)168 wlan_twt_cfg_set_responder(struct wlan_objmgr_psoc *psoc, bool val)
169 {
170 	struct twt_psoc_priv_obj *twt_psoc_obj;
171 
172 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
173 	if (!twt_psoc_obj)
174 		return QDF_STATUS_E_INVAL;
175 
176 	twt_psoc_obj->cfg_params.twt_responder = val;
177 
178 	return QDF_STATUS_SUCCESS;
179 }
180 
wlan_twt_cfg_is_twt_enabled(struct wlan_objmgr_psoc * psoc)181 bool wlan_twt_cfg_is_twt_enabled(struct wlan_objmgr_psoc *psoc)
182 {
183 	struct twt_psoc_priv_obj *twt_psoc_obj;
184 
185 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
186 	if (!twt_psoc_obj)
187 		return false;
188 
189 	return twt_psoc_obj->cfg_params.enable_twt;
190 }
191 
192 QDF_STATUS
wlan_twt_cfg_get_congestion_timeout(struct wlan_objmgr_psoc * psoc,uint32_t * val)193 wlan_twt_cfg_get_congestion_timeout(struct wlan_objmgr_psoc *psoc,
194 				    uint32_t *val)
195 {
196 	struct twt_psoc_priv_obj *twt_psoc_obj;
197 
198 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
199 	if (!twt_psoc_obj) {
200 		*val = cfg_default(CFG_TWT_CONGESTION_TIMEOUT);
201 		return QDF_STATUS_E_INVAL;
202 	}
203 
204 	*val = twt_psoc_obj->cfg_params.twt_congestion_timeout;
205 
206 	return QDF_STATUS_SUCCESS;
207 }
208 
209 QDF_STATUS
wlan_twt_cfg_set_congestion_timeout(struct wlan_objmgr_psoc * psoc,uint32_t val)210 wlan_twt_cfg_set_congestion_timeout(struct wlan_objmgr_psoc *psoc, uint32_t val)
211 {
212 	struct twt_psoc_priv_obj *twt_psoc_obj;
213 
214 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
215 	if (!twt_psoc_obj)
216 		return QDF_STATUS_E_INVAL;
217 
218 	twt_psoc_obj->cfg_params.twt_congestion_timeout = val;
219 
220 	return QDF_STATUS_SUCCESS;
221 }
222 
223 QDF_STATUS
wlan_twt_cfg_get_requestor_flag(struct wlan_objmgr_psoc * psoc,bool * val)224 wlan_twt_cfg_get_requestor_flag(struct wlan_objmgr_psoc *psoc, bool *val)
225 {
226 	struct twt_psoc_priv_obj *twt_psoc_obj;
227 
228 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
229 	if (!twt_psoc_obj) {
230 		*val = false;
231 		return QDF_STATUS_E_INVAL;
232 	}
233 
234 	*val = twt_psoc_obj->cfg_params.req_flag;
235 
236 	return QDF_STATUS_SUCCESS;
237 }
238 
239 QDF_STATUS
wlan_twt_cfg_set_requestor_flag(struct wlan_objmgr_psoc * psoc,bool val)240 wlan_twt_cfg_set_requestor_flag(struct wlan_objmgr_psoc *psoc, bool val)
241 {
242 	struct twt_psoc_priv_obj *twt_psoc_obj;
243 
244 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
245 	if (!twt_psoc_obj)
246 		return QDF_STATUS_E_INVAL;
247 
248 	twt_psoc_obj->cfg_params.req_flag = val;
249 
250 	return QDF_STATUS_SUCCESS;
251 }
252 
253 QDF_STATUS
wlan_twt_cfg_get_responder_flag(struct wlan_objmgr_psoc * psoc,bool * val)254 wlan_twt_cfg_get_responder_flag(struct wlan_objmgr_psoc *psoc, bool *val)
255 {
256 	struct twt_psoc_priv_obj *twt_psoc_obj;
257 
258 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
259 	if (!twt_psoc_obj)
260 		return QDF_STATUS_E_INVAL;
261 
262 	*val = twt_psoc_obj->cfg_params.res_flag;
263 
264 	return QDF_STATUS_SUCCESS;
265 }
266 
267 QDF_STATUS
wlan_twt_cfg_set_responder_flag(struct wlan_objmgr_psoc * psoc,bool val)268 wlan_twt_cfg_set_responder_flag(struct wlan_objmgr_psoc *psoc, bool val)
269 {
270 	struct twt_psoc_priv_obj *twt_psoc_obj;
271 
272 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
273 	if (!twt_psoc_obj)
274 		return QDF_STATUS_E_INVAL;
275 
276 	twt_psoc_obj->cfg_params.res_flag = val;
277 
278 	return QDF_STATUS_SUCCESS;
279 }
280 
281 QDF_STATUS
wlan_twt_cfg_get_flex_sched(struct wlan_objmgr_psoc * psoc,bool * val)282 wlan_twt_cfg_get_flex_sched(struct wlan_objmgr_psoc *psoc, bool *val)
283 {
284 	struct twt_psoc_priv_obj *twt_psoc_obj;
285 
286 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
287 	if (!twt_psoc_obj) {
288 		*val = cfg_default(CFG_HE_FLEX_TWT_SCHED);
289 		return QDF_STATUS_E_INVAL;
290 	}
291 
292 	*val = twt_psoc_obj->cfg_params.flex_twt_sched;
293 
294 	return QDF_STATUS_SUCCESS;
295 }
296 
297 QDF_STATUS
wlan_twt_cfg_get_24ghz_enabled(struct wlan_objmgr_psoc * psoc,bool * val)298 wlan_twt_cfg_get_24ghz_enabled(struct wlan_objmgr_psoc *psoc, bool *val)
299 {
300 	struct twt_psoc_priv_obj *twt_psoc_obj;
301 
302 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
303 	if (!twt_psoc_obj) {
304 		*val = cfg_default(CFG_ENABLE_TWT_24GHZ);
305 		return QDF_STATUS_E_INVAL;
306 	}
307 
308 	*val = twt_psoc_obj->cfg_params.enable_twt_24ghz;
309 
310 	return QDF_STATUS_SUCCESS;
311 }
312 
313 QDF_STATUS
wlan_twt_cfg_get_bcast_requestor(struct wlan_objmgr_psoc * psoc,bool * val)314 wlan_twt_cfg_get_bcast_requestor(struct wlan_objmgr_psoc *psoc, bool *val)
315 {
316 	struct twt_psoc_priv_obj *twt_psoc_obj;
317 
318 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
319 	if (!twt_psoc_obj) {
320 		uint32_t b_req_res;
321 
322 		b_req_res = cfg_default(CFG_BCAST_TWT_REQ_RESP);
323 		*val = CFG_TWT_GET_BCAST_REQ(b_req_res);
324 		return QDF_STATUS_E_INVAL;
325 	}
326 
327 	*val = twt_psoc_obj->cfg_params.bcast_requestor_enabled;
328 
329 	return QDF_STATUS_SUCCESS;
330 }
331 
332 QDF_STATUS
wlan_twt_cfg_get_bcast_responder(struct wlan_objmgr_psoc * psoc,bool * val)333 wlan_twt_cfg_get_bcast_responder(struct wlan_objmgr_psoc *psoc, bool *val)
334 {
335 	struct twt_psoc_priv_obj *twt_psoc_obj;
336 
337 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
338 	if (!twt_psoc_obj) {
339 		uint32_t b_req_res;
340 
341 		b_req_res = cfg_default(CFG_BCAST_TWT_REQ_RESP);
342 		*val = CFG_TWT_GET_BCAST_RES(b_req_res);
343 		return QDF_STATUS_E_INVAL;
344 	}
345 
346 	*val = twt_psoc_obj->cfg_params.bcast_responder_enabled;
347 
348 	return QDF_STATUS_SUCCESS;
349 }
350 
351 QDF_STATUS
wlan_twt_cfg_get_rtwt_requestor(struct wlan_objmgr_psoc * psoc,bool * val)352 wlan_twt_cfg_get_rtwt_requestor(struct wlan_objmgr_psoc *psoc, bool *val)
353 {
354 	struct twt_psoc_priv_obj *twt_psoc_obj;
355 
356 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
357 	if (!twt_psoc_obj) {
358 		uint32_t rtwt_req_res;
359 
360 		rtwt_req_res = cfg_default(CFG_RTWT_REQ_RESP);
361 		*val = CFG_GET_RTWT_REQ(rtwt_req_res);
362 		return QDF_STATUS_E_INVAL;
363 	}
364 
365 	*val = twt_psoc_obj->cfg_params.rtwt_requestor_enabled;
366 
367 	return QDF_STATUS_SUCCESS;
368 }
369 
370 QDF_STATUS
wlan_twt_cfg_get_rtwt_responder(struct wlan_objmgr_psoc * psoc,bool * val)371 wlan_twt_cfg_get_rtwt_responder(struct wlan_objmgr_psoc *psoc, bool *val)
372 {
373 	struct twt_psoc_priv_obj *twt_psoc_obj;
374 
375 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
376 	if (!twt_psoc_obj) {
377 		uint32_t rtwt_req_res;
378 
379 		rtwt_req_res = cfg_default(CFG_RTWT_REQ_RESP);
380 		*val = CFG_GET_RTWT_RES(rtwt_req_res);
381 		return QDF_STATUS_E_INVAL;
382 	}
383 
384 	*val = twt_psoc_obj->cfg_params.rtwt_responder_enabled;
385 
386 	return QDF_STATUS_SUCCESS;
387 }
388 
389 QDF_STATUS
wlan_twt_cfg_get_support_in_11n_mode(struct wlan_objmgr_psoc * psoc,bool * val)390 wlan_twt_cfg_get_support_in_11n_mode(struct wlan_objmgr_psoc *psoc,
391 				     bool *val)
392 {
393 	struct twt_psoc_priv_obj *twt_psoc_obj;
394 	psoc_twt_ext_cfg_params_t *twt_cfg;
395 	struct twt_tgt_caps *tgt_caps;
396 	bool enable_twt;
397 
398 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
399 	if (!twt_psoc_obj) {
400 		*val = cfg_default(CFG_TWT_ENABLE_IN_11N);
401 		return QDF_STATUS_E_INVAL;
402 	}
403 
404 	*val = twt_psoc_obj->cfg_params.is_twt_enabled_in_11n;
405 	twt_cfg = &twt_psoc_obj->cfg_params;
406 	tgt_caps = &twt_psoc_obj->twt_caps;
407 	enable_twt = twt_cfg->enable_twt;
408 
409 	*val = QDF_MIN(tgt_caps->twt_requestor,
410 		       (enable_twt && twt_cfg->twt_requestor && *val));
411 
412 	return QDF_STATUS_SUCCESS;
413 }
414 
415 QDF_STATUS
wlan_twt_get_restricted_support(struct wlan_objmgr_psoc * psoc,bool * val)416 wlan_twt_get_restricted_support(struct wlan_objmgr_psoc *psoc, bool *val)
417 {
418 	struct twt_psoc_priv_obj *twt_psoc_obj;
419 	psoc_twt_ext_cfg_params_t *twt_cfg;
420 	struct twt_tgt_caps *tgt_caps;
421 	bool enable_twt;
422 
423 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
424 	if (!twt_psoc_obj) {
425 		*val = cfg_default(CFG_RTWT_REQ_RESP);
426 		return QDF_STATUS_E_INVAL;
427 	}
428 
429 	twt_cfg = &twt_psoc_obj->cfg_params;
430 	tgt_caps = &twt_psoc_obj->twt_caps;
431 	enable_twt = twt_cfg->enable_twt;
432 
433 	*val = QDF_MIN(tgt_caps->twt_bcast_req_support &&
434 		       tgt_caps->restricted_twt_support,
435 		       twt_cfg->bcast_requestor_enabled &&
436 		       twt_cfg->rtwt_requestor_enabled &&
437 		       enable_twt);
438 
439 	return QDF_STATUS_SUCCESS;
440 }
441 
442 bool
wlan_twt_get_pmo_allowed(struct wlan_objmgr_psoc * psoc)443 wlan_twt_get_pmo_allowed(struct wlan_objmgr_psoc *psoc)
444 {
445 	struct twt_psoc_priv_obj *twt_psoc_obj;
446 
447 	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
448 
449 	if (!twt_psoc_obj || twt_psoc_obj->twt_pmo_disabled)
450 		return false;
451 
452 	return true;
453 }
454