1 /*
2  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: wlan_hdd_twt.h
22  *
23  * WLAN Host Device Driver file for TWT (Target Wake Time) support.
24  *
25  */
26 
27 #if !defined(WLAN_HDD_TWT_H)
28 #define WLAN_HDD_TWT_H
29 
30 #include "qdf_types.h"
31 #include "qdf_status.h"
32 #include "qca_vendor.h"
33 #include <net/cfg80211.h>
34 
35 struct hdd_context;
36 struct hdd_adapter;
37 struct wlan_hdd_link_info;
38 struct wma_tgt_cfg;
39 struct wmi_twt_add_dialog_param;
40 struct wmi_twt_del_dialog_param;
41 struct wmi_twt_pause_dialog_cmd_param;
42 struct wmi_twt_resume_dialog_cmd_param;
43 
44 extern const struct nla_policy
45 wlan_hdd_wifi_twt_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
46 
47 #define FEATURE_TWT_VENDOR_EVENTS                                   \
48 [QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT_INDEX] = {                    \
49 	.vendor_id = QCA_NL80211_VENDOR_ID,                         \
50 	.subcmd = QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT,             \
51 },
52 
53 /**
54  * enum twt_role - TWT role definitions
55  * @TWT_REQUESTOR: Individual/Bcast TWT requestor role
56  * @TWT_REQUESTOR_INDV: Individual TWT requestor role
57  * @TWT_REQUESTOR_BCAST: Broadcast TWT requestor role
58  * @TWT_RESPONDER: Individual/Bcast TWT responder role
59  * @TWT_RESPONDER_INDV: Individual TWT responder role
60  * @TWT_RESPONDER_BCAST: Broadcast TWT responder role
61  * @TWT_ROLE_ALL: All TWT roles
62  * @TWT_ROLE_MAX: Place holder for max mode
63  */
64 enum twt_role {
65 	TWT_REQUESTOR,
66 	TWT_REQUESTOR_INDV,
67 	/* Bcast alone cannot be enabled, but can be disabled */
68 	TWT_REQUESTOR_BCAST,
69 	TWT_RESPONDER,
70 	TWT_RESPONDER_INDV,
71 	/* Bcast alone cannot be enabled, but can be disabled */
72 	TWT_RESPONDER_BCAST,
73 	TWT_ROLE_ALL,
74 	TWT_ROLE_MAX,
75 };
76 
77 #ifdef WLAN_SUPPORT_TWT
78 /**
79  * enum twt_status - TWT target state
80  * @TWT_INIT: Init State
81  * @TWT_DISABLED: TWT is disabled
82  * @TWT_FW_TRIGGER_ENABLE_REQUESTED: FW triggered enable requested
83  * @TWT_FW_TRIGGER_ENABLED: FW triggered twt enabled
84  * @TWT_HOST_TRIGGER_ENABLE_REQUESTED: Host triggered TWT requested
85  * @TWT_HOST_TRIGGER_ENABLED: Host triggered TWT enabled
86  * @TWT_DISABLE_REQUESTED: TWT disable requested
87  * @TWT_SUSPEND_REQUESTED: TWT suspend requested
88  * @TWT_SUSPENDED: Successfully suspended TWT
89  * @TWT_RESUME_REQUESTED: TWT Resume requested
90  * @TWT_RESUMED: Successfully resumed TWT
91  * @TWT_CLOSED: Deinitialized TWT feature and closed
92  */
93 enum twt_status {
94 	TWT_INIT,
95 	TWT_DISABLED,
96 	TWT_FW_TRIGGER_ENABLE_REQUESTED,
97 	TWT_FW_TRIGGER_ENABLED,
98 	TWT_HOST_TRIGGER_ENABLE_REQUESTED,
99 	TWT_HOST_TRIGGER_ENABLED,
100 	TWT_DISABLE_REQUESTED,
101 	TWT_SUSPEND_REQUESTED,
102 	TWT_SUSPENDED,
103 	TWT_RESUME_REQUESTED,
104 	TWT_RESUMED,
105 	TWT_CLOSED,
106 };
107 
108 /**
109  * struct twt_conc_arg: TWT concurrency args
110  * @hdd_ctx: pointer to hdd context
111  */
112 struct twt_conc_arg {
113 	struct hdd_context *hdd_ctx;
114 };
115 
116 /**
117  * struct twt_ack_info_priv - twt ack private info
118  * @vdev_id: vdev id
119  * @peer_macaddr: peer mac address
120  * @dialog_id: dialog id
121  * @twt_cmd_ack: twt ack command
122  * @status: twt command status
123  */
124 struct twt_ack_info_priv {
125 	uint32_t vdev_id;
126 	struct qdf_mac_addr peer_macaddr;
127 	uint32_t dialog_id;
128 	uint32_t twt_cmd_ack;
129 	uint32_t status;
130 };
131 
132 /**
133  * wlan_hdd_cfg80211_wifi_twt_config() - Wifi twt configuration
134  * vendor command
135  * @wiphy: wiphy device pointer
136  * @wdev: wireless device pointer
137  * @data: Vendor command data buffer
138  * @data_len: Buffer length
139  *
140  * Handles QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT
141  *
142  * Return: 0 for success, negative errno for failure.
143  */
144 int wlan_hdd_cfg80211_wifi_twt_config(struct wiphy *wiphy,
145 				      struct wireless_dev *wdev,
146 				      const void *data,
147 				      int data_len);
148 
149 /**
150  * hdd_update_tgt_twt_cap() - Update TWT target capabilities
151  * @hdd_ctx: HDD Context
152  * @cfg: Pointer to target configuration
153  *
154  * Return: None
155  */
156 void hdd_update_tgt_twt_cap(struct hdd_context *hdd_ctx,
157 			    struct wma_tgt_cfg *cfg);
158 
159 /**
160  * hdd_send_twt_requestor_enable_cmd() - Send TWT requestor enable command to
161  * target
162  * @hdd_ctx: HDD Context
163  *
164  * Return: QDF_STATUS
165  */
166 QDF_STATUS hdd_send_twt_requestor_enable_cmd(struct hdd_context *hdd_ctx);
167 
168 /**
169  * hdd_send_twt_responder_enable_cmd() - Send TWT responder enable command to
170  * target
171  * @hdd_ctx: HDD Context
172  *
173  * Return: QDF_STATUS
174  */
175 QDF_STATUS hdd_send_twt_responder_enable_cmd(struct hdd_context *hdd_ctx);
176 
177 /**
178  * hdd_send_twt_requestor_disable_cmd() - Send TWT requestor disable command
179  * to target
180  * @hdd_ctx: HDD Context
181  * @reason: Disable reason code
182  *
183  * Return: QDF_STATUS
184  */
185 QDF_STATUS hdd_send_twt_requestor_disable_cmd(struct hdd_context *hdd_ctx,
186 					      uint32_t reason);
187 
188 /**
189  * hdd_send_twt_responder_disable_cmd() - Send TWT responder disable command
190  * to target
191  * @hdd_ctx: HDD Context
192  * @reason: Disable reason code
193  *
194  * Return: QDF_STATUS
195  */
196 QDF_STATUS hdd_send_twt_responder_disable_cmd(struct hdd_context *hdd_ctx,
197 					      uint32_t reason);
198 
199 /**
200  * wlan_hdd_twt_init() - Initialize TWT
201  * @hdd_ctx: pointer to global HDD Context
202  *
203  * Initialize the TWT feature by registering the callbacks
204  * with the lower layers.
205  *
206  * Return: None
207  */
208 void wlan_hdd_twt_init(struct hdd_context *hdd_ctx);
209 
210 /**
211  * wlan_hdd_twt_deinit() - Deinitialize TWT
212  * @hdd_ctx: pointer to global HDD Context
213  *
214  * Deinitialize the TWT feature by deregistering the
215  * callbacks with the lower layers.
216  *
217  * Return: None
218  */
219 void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx);
220 
221 /**
222  * hdd_test_config_twt_setup_session() - Process TWT setup
223  * operation in the received test config vendor command and
224  * send it to firmware
225  * @adapter: adapter pointer
226  * @tb: nl attributes
227  *
228  * Handles QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP
229  *
230  * Return: 0 for Success and negative value for failure
231  */
232 int hdd_test_config_twt_setup_session(struct hdd_adapter *adapter,
233 				      struct nlattr **tb);
234 
235 /**
236  * hdd_test_config_twt_terminate_session() - Process TWT terminate
237  * operation in the received test config vendor command and send
238  * it to firmware
239  * @adapter: adapter pointer
240  * @tb: nl attributes
241  *
242  * Handles QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE
243  *
244  * Return: 0 for Success and negative value for failure
245  */
246 int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter,
247 					  struct nlattr **tb);
248 /**
249  * hdd_send_twt_role_disable_cmd() - Send a specific TWT role
250  * disable to firmware
251  * @hdd_ctx: hdd context pointer
252  * @role : TWT role to be disabled
253  *
254  * Return: None
255  */
256 void hdd_send_twt_role_disable_cmd(struct hdd_context *hdd_ctx,
257 				   enum twt_role role);
258 
259 /**
260  * hdd_send_twt_del_all_sessions_to_userspace() - Terminate all TWT sessions
261  * @link_info: Link info pointer in HDD adapter
262  *
263  * This function checks if association exists and TWT session is setup,
264  * then send the TWT teardown vendor NL event to the user space.
265  *
266  * Return: None
267  */
268 void
269 hdd_send_twt_del_all_sessions_to_userspace(struct wlan_hdd_link_info *link_info);
270 
271 /**
272  * hdd_twt_concurrency_update_on_scc() - Send TWT disable command to fw if
273  * SCC exists in two vdevs
274  * @pdev: pdev pointer
275  * @object: object pointer
276  * @arg: argument pointer
277  *
278  * Return: None
279  */
280 void hdd_twt_concurrency_update_on_scc(struct wlan_objmgr_pdev *pdev,
281 				       void *object, void *arg);
282 
283 /**
284  * hdd_twt_concurrency_update_on_mcc() - Send TWT disable command to fw if
285  * MCC exists in two vdevs
286  * @pdev: pdev pointer
287  * @object: object pointer
288  * @arg: argument pointer
289  *
290  * Return: None
291  */
292 void hdd_twt_concurrency_update_on_mcc(struct wlan_objmgr_pdev *pdev,
293 				       void *object, void *arg);
294 
295 /**
296  * hdd_twt_concurrency_update_on_dbs() - Send TWT enable command to fw if DBS
297  * exists in two vdevs
298  * @pdev: pdev pointer
299  * @object: object pointer
300  * @arg: argument pointer
301  *
302  * Return: None
303  */
304 void hdd_twt_concurrency_update_on_dbs(struct wlan_objmgr_pdev *pdev,
305 				       void *object, void *arg);
306 
307 /**
308  * __hdd_twt_update_work_handler() - TWT work handler to send TWT enable/disable
309  * command to fw
310  * @hdd_ctx: HDD pointer context
311  *
312  * Return: None
313  */
314 void __hdd_twt_update_work_handler(struct hdd_context *hdd_ctx);
315 
316 /**
317  * hdd_twt_update_work_handler() - Wrapper function
318  * @data: data pointer
319  *
320  * Return: None
321  */
322 void hdd_twt_update_work_handler(void *data);
323 
324 /**
325  * wlan_twt_concurrency_update() - Handles twt concurrency in case of SCC/MCC
326  * or DBS
327  * @hdd_ctx: hdd context pointer
328  *
329  * Return: None
330  */
331 void wlan_twt_concurrency_update(struct hdd_context *hdd_ctx);
332 
333 /**
334  * hdd_twt_del_dialog_in_ps_disable() - TWT teardown in case of ps disable
335  * @hdd_ctx: hdd context pointer
336  * @mac_addr: STA mac address
337  * @vdev_id: vdev id
338  *
339  * Return: None
340  */
341 void hdd_twt_del_dialog_in_ps_disable(struct hdd_context *hdd_ctx,
342 				      struct qdf_mac_addr *mac_addr,
343 				      uint8_t vdev_id);
344 
345 #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT                            \
346 {                                                                        \
347 	.info.vendor_id = QCA_NL80211_VENDOR_ID,                         \
348 	.info.subcmd =                                                   \
349 		QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT,                    \
350 	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |                            \
351 		WIPHY_VENDOR_CMD_NEED_NETDEV |                           \
352 		WIPHY_VENDOR_CMD_NEED_RUNNING,                           \
353 	.doit = wlan_hdd_cfg80211_wifi_twt_config,                       \
354 	vendor_command_policy(wlan_hdd_wifi_twt_config_policy,           \
355 			      QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX)       \
356 },
357 
358 /**
359  * hdd_get_twt_requestor() - Get TWT requestor config
360  * @psoc: global psoc object
361  * @val: output variable to store the value
362  *
363  * Return: QDF_STATUS
364  */
365 QDF_STATUS hdd_get_twt_requestor(struct wlan_objmgr_psoc *psoc, bool *val);
366 
367 /**
368  * hdd_get_twt_responder() - Get TWT responder config
369  * @psoc: global psoc object
370  * @val: output variable to store the value
371  *
372  * Return: QDF_STATUS
373  */
374 QDF_STATUS hdd_get_twt_responder(struct wlan_objmgr_psoc *psoc, bool *val);
375 
376 /**
377  * wlan_hdd_resume_pmo_twt() - resume twt worker
378  * @hdd_ctx: hdd context
379  *
380  * Return: None
381  */
382 void wlan_hdd_resume_pmo_twt(struct hdd_context *hdd_ctx);
383 /**
384  * wlan_hdd_suspend_pmo_twt() - suspend twt worker
385  * @hdd_ctx: hdd context
386  *
387  * Return: None
388  */
389 void wlan_hdd_suspend_pmo_twt(struct hdd_context *hdd_ctx);
390 /**
391  * wlan_hdd_is_twt_pmo_allowed() - check twt disabled
392  * @hdd_ctx: hdd context
393  *
394  * Return: true if twt pmo is allowed otherwise false
395  */
396 bool wlan_hdd_is_twt_pmo_allowed(struct hdd_context *hdd_ctx);
397 #else
hdd_update_tgt_twt_cap(struct hdd_context * hdd_ctx,struct wma_tgt_cfg * cfg)398 static inline void hdd_update_tgt_twt_cap(struct hdd_context *hdd_ctx,
399 					  struct wma_tgt_cfg *cfg)
400 {
401 }
402 
403 static inline
hdd_send_twt_requestor_enable_cmd(struct hdd_context * hdd_ctx)404 QDF_STATUS hdd_send_twt_requestor_enable_cmd(struct hdd_context *hdd_ctx)
405 {
406 	return QDF_STATUS_E_NOSUPPORT;
407 }
408 
409 static inline
hdd_send_twt_responder_enable_cmd(struct hdd_context * hdd_ctx)410 QDF_STATUS hdd_send_twt_responder_enable_cmd(struct hdd_context *hdd_ctx)
411 {
412 	return QDF_STATUS_E_NOSUPPORT;
413 }
414 
415 static inline
hdd_send_twt_requestor_disable_cmd(struct hdd_context * hdd_ctx,uint32_t reason)416 QDF_STATUS hdd_send_twt_requestor_disable_cmd(struct hdd_context *hdd_ctx,
417 					      uint32_t reason)
418 {
419 	return QDF_STATUS_E_NOSUPPORT;
420 }
421 
422 static inline
hdd_send_twt_responder_disable_cmd(struct hdd_context * hdd_ctx,uint32_t reason)423 QDF_STATUS hdd_send_twt_responder_disable_cmd(struct hdd_context *hdd_ctx,
424 					      uint32_t reason)
425 {
426 	return QDF_STATUS_E_NOSUPPORT;
427 }
428 
wlan_hdd_twt_init(struct hdd_context * hdd_ctx)429 static inline void wlan_hdd_twt_init(struct hdd_context *hdd_ctx)
430 {
431 }
432 
wlan_hdd_twt_deinit(struct hdd_context * hdd_ctx)433 static inline void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx)
434 {
435 }
436 
437 static inline
hdd_test_config_twt_setup_session(struct hdd_adapter * adapter,struct nlattr ** tb)438 int hdd_test_config_twt_setup_session(struct hdd_adapter *adapter,
439 				      struct nlattr **tb)
440 {
441 	return -EINVAL;
442 }
443 
444 static inline
hdd_test_config_twt_terminate_session(struct hdd_adapter * adapter,struct nlattr ** tb)445 int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter,
446 					  struct nlattr **tb)
447 {
448 	return -EINVAL;
449 }
450 
451 static inline
hdd_send_twt_role_disable_cmd(struct hdd_context * hdd_ctx,enum twt_role role)452 void hdd_send_twt_role_disable_cmd(struct hdd_context *hdd_ctx,
453 				   enum twt_role role)
454 {
455 }
456 
457 static inline void
hdd_send_twt_del_all_sessions_to_userspace(struct wlan_hdd_link_info * link_info)458 hdd_send_twt_del_all_sessions_to_userspace(struct wlan_hdd_link_info *link_info)
459 {
460 }
461 
462 static inline
hdd_twt_concurrency_update_on_scc(struct wlan_objmgr_pdev * pdev,void * object,void * arg)463 void hdd_twt_concurrency_update_on_scc(struct wlan_objmgr_pdev *pdev,
464 				       void *object, void *arg)
465 {
466 }
467 
468 static inline
hdd_twt_concurrency_update_on_mcc(struct wlan_objmgr_pdev * pdev,void * object,void * arg)469 void hdd_twt_concurrency_update_on_mcc(struct wlan_objmgr_pdev *pdev,
470 				       void *object, void *arg)
471 {
472 }
473 
474 static inline
hdd_twt_concurrency_update_on_dbs(struct wlan_objmgr_pdev * pdev,void * object,void * arg)475 void hdd_twt_concurrency_update_on_dbs(struct wlan_objmgr_pdev *pdev,
476 				       void *object, void *arg)
477 {
478 }
479 
480 static inline
__hdd_twt_update_work_handler(struct hdd_context * hdd_ctx)481 void __hdd_twt_update_work_handler(struct hdd_context *hdd_ctx)
482 {
483 }
484 
hdd_twt_update_work_handler(void * data)485 static inline void hdd_twt_update_work_handler(void *data)
486 {
487 }
488 
wlan_twt_concurrency_update(struct hdd_context * hdd_ctx)489 static inline void wlan_twt_concurrency_update(struct hdd_context *hdd_ctx)
490 {
491 }
492 
493 static inline
hdd_twt_del_dialog_in_ps_disable(struct hdd_context * hdd_ctx,struct qdf_mac_addr * mac_addr,uint8_t vdev_id)494 void hdd_twt_del_dialog_in_ps_disable(struct hdd_context *hdd_ctx,
495 				      struct qdf_mac_addr *mac_addr,
496 				      uint8_t vdev_id)
497 {
498 }
499 
500 static inline
hdd_get_twt_requestor(struct wlan_objmgr_psoc * psoc,bool * val)501 QDF_STATUS hdd_get_twt_requestor(struct wlan_objmgr_psoc *psoc, bool *val)
502 {
503 	*val = false;
504 	return QDF_STATUS_E_NOSUPPORT;
505 }
506 
507 static inline
hdd_get_twt_responder(struct wlan_objmgr_psoc * psoc,bool * val)508 QDF_STATUS hdd_get_twt_responder(struct wlan_objmgr_psoc *psoc, bool *val)
509 {
510 	*val = false;
511 	return QDF_STATUS_E_NOSUPPORT;
512 }
513 
wlan_hdd_resume_pmo_twt(struct hdd_context * hdd_ctx)514 static inline void wlan_hdd_resume_pmo_twt(struct hdd_context *hdd_ctx)
515 {
516 }
517 
wlan_hdd_suspend_pmo_twt(struct hdd_context * hdd_ctx)518 static inline void wlan_hdd_suspend_pmo_twt(struct hdd_context *hdd_ctx)
519 {
520 }
521 
wlan_hdd_is_twt_pmo_allowed(struct hdd_context * hdd_ctx)522 static inline bool wlan_hdd_is_twt_pmo_allowed(struct hdd_context *hdd_ctx)
523 {
524 	return true;
525 }
526 
527 #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT
528 
529 #endif
530 
531 #endif /* if !defined(WLAN_HDD_TWT_H)*/
532