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