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: target_if_twt.c
19  *  This file contains twt component's target related function definitions
20  */
21 #include <target_if_twt.h>
22 #include <target_if_twt_cmd.h>
23 #include <target_if_twt_evt.h>
24 #include <target_if_ext_twt.h>
25 #include "twt/core/src/wlan_twt_common.h"
26 #include "twt/core/src/wlan_twt_priv.h"
27 
28 QDF_STATUS
target_if_twt_register_events(struct wlan_objmgr_psoc * psoc)29 target_if_twt_register_events(struct wlan_objmgr_psoc *psoc)
30 {
31 	QDF_STATUS status;
32 	struct wmi_unified *wmi_handle;
33 
34 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
35 	if (!wmi_handle) {
36 		target_if_err("wmi_handle is null!");
37 		return QDF_STATUS_E_INVAL;
38 	}
39 
40 	status = wmi_unified_register_event_handler(wmi_handle,
41 					wmi_twt_enable_complete_event_id,
42 					target_if_twt_en_complete_event_handler,
43 					WMI_RX_WORK_CTX);
44 	if (QDF_IS_STATUS_ERROR(status)) {
45 		target_if_err("Failed to register twt enable event cb");
46 		if (status ==  QDF_STATUS_E_NOSUPPORT)
47 			status = QDF_STATUS_SUCCESS;
48 		return status;
49 	}
50 
51 	status = wmi_unified_register_event_handler(wmi_handle,
52 				wmi_twt_disable_complete_event_id,
53 				target_if_twt_disable_comp_event_handler,
54 				WMI_RX_WORK_CTX);
55 	if (QDF_IS_STATUS_ERROR(status)) {
56 		target_if_err("Failed to register twt disable event cb");
57 		if (status ==  QDF_STATUS_E_NOSUPPORT)
58 			status = QDF_STATUS_SUCCESS;
59 		return status;
60 	}
61 
62 	status = target_if_twt_register_ext_events(psoc);
63 	if (QDF_IS_STATUS_ERROR(status)) {
64 		target_if_err("Failed to register twt ext events");
65 		if (status ==  QDF_STATUS_E_NOSUPPORT)
66 			status = QDF_STATUS_SUCCESS;
67 		return status;
68 	}
69 
70 	return status;
71 }
72 
73 QDF_STATUS
target_if_twt_deregister_events(struct wlan_objmgr_psoc * psoc)74 target_if_twt_deregister_events(struct wlan_objmgr_psoc *psoc)
75 {
76 	QDF_STATUS status;
77 	struct wmi_unified *wmi_handle;
78 
79 	if (!psoc) {
80 		target_if_err("psoc is NULL!");
81 		return QDF_STATUS_E_INVAL;
82 	}
83 
84 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
85 	if (!wmi_handle) {
86 		target_if_err("wmi_handle is null");
87 		return QDF_STATUS_E_NULL_VALUE;
88 	}
89 
90 	status = wmi_unified_unregister_event_handler(wmi_handle,
91 					wmi_twt_enable_complete_event_id);
92 	if (QDF_IS_STATUS_ERROR(status)) {
93 		target_if_err("Failed to deregister twt enable event cb");
94 		if (status ==  QDF_STATUS_E_NOSUPPORT)
95 			status = QDF_STATUS_SUCCESS;
96 		return status;
97 	}
98 
99 	status = wmi_unified_unregister_event_handler(wmi_handle,
100 					 wmi_twt_disable_complete_event_id);
101 	if (QDF_IS_STATUS_ERROR(status)) {
102 		target_if_err("Failed to deregister twt disable event cb");
103 		if (status ==  QDF_STATUS_E_NOSUPPORT)
104 			status = QDF_STATUS_SUCCESS;
105 		return status;
106 	}
107 
108 	status = target_if_twt_deregister_ext_events(psoc);
109 	if (QDF_IS_STATUS_ERROR(status)) {
110 		target_if_err("Failed to deregister twt ext events");
111 		if (status ==  QDF_STATUS_E_NOSUPPORT)
112 			status = QDF_STATUS_SUCCESS;
113 		return status;
114 	}
115 
116 	return status;
117 }
118 
119 QDF_STATUS
target_if_twt_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)120 target_if_twt_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
121 {
122 	struct wlan_lmac_if_twt_tx_ops *twt_tx_ops;
123 	QDF_STATUS status;
124 
125 	if (!tx_ops) {
126 		target_if_err("txops is NULL");
127 		return QDF_STATUS_E_FAILURE;
128 	}
129 
130 	twt_tx_ops = &tx_ops->twt_tx_ops;
131 	twt_tx_ops->enable_req = target_if_twt_enable_req;
132 	twt_tx_ops->disable_req = target_if_twt_disable_req;
133 	twt_tx_ops->register_events = target_if_twt_register_events;
134 	twt_tx_ops->deregister_events = target_if_twt_deregister_events;
135 
136 	status = target_if_twt_register_ext_tx_ops(twt_tx_ops);
137 	if (QDF_IS_STATUS_ERROR(status)) {
138 		target_if_err("Failed to register twt ext tx ops");
139 		return status;
140 	}
141 
142 	return status;
143 }
144 
145 QDF_STATUS
target_if_twt_set_twt_ack_support(struct wlan_objmgr_psoc * psoc,bool val)146 target_if_twt_set_twt_ack_support(struct wlan_objmgr_psoc *psoc,
147 				  bool val)
148 {
149 	struct twt_psoc_priv_obj *twt_psoc =
150 		wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TWT);
151 	if (!twt_psoc) {
152 		target_if_err("null twt psoc priv obj");
153 		return QDF_STATUS_E_FAILURE;
154 	}
155 
156 	twt_psoc->twt_caps.twt_ack_supported = val;
157 	return QDF_STATUS_SUCCESS;
158 }
159 
160 QDF_STATUS
target_if_twt_fill_tgt_caps(struct wlan_objmgr_psoc * psoc,wmi_unified_t wmi_handle)161 target_if_twt_fill_tgt_caps(struct wlan_objmgr_psoc *psoc,
162 			    wmi_unified_t wmi_handle)
163 {
164 	struct twt_psoc_priv_obj *twt_psoc;
165 	struct twt_tgt_caps *caps = NULL;
166 
167 	if (!psoc || !wmi_handle) {
168 		target_if_err("null wmi_handle or psoc");
169 		return QDF_STATUS_E_FAILURE;
170 	}
171 
172 	twt_psoc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
173 							 WLAN_UMAC_COMP_TWT);
174 	if (!twt_psoc) {
175 		target_if_err("null twt psoc priv obj");
176 		return QDF_STATUS_E_FAILURE;
177 	}
178 
179 	caps = &twt_psoc->twt_caps;
180 
181 	if (wmi_service_enabled(wmi_handle, wmi_service_twt_requestor))
182 		caps->twt_requestor = true;
183 	else
184 		caps->twt_requestor = false;
185 
186 	if (wmi_service_enabled(wmi_handle, wmi_service_twt_responder))
187 		caps->twt_responder = true;
188 	else
189 		caps->twt_responder = false;
190 
191 	if (wmi_service_enabled(wmi_handle, wmi_service_bcast_twt_support))
192 		caps->legacy_bcast_twt_support = true;
193 	else
194 		caps->legacy_bcast_twt_support = false;
195 
196 	if (wmi_service_enabled(wmi_handle, wmi_service_twt_bcast_req_support))
197 		caps->twt_bcast_req_support = true;
198 	else
199 		caps->twt_bcast_req_support = false;
200 
201 	if (wmi_service_enabled(wmi_handle, wmi_service_twt_bcast_resp_support))
202 		caps->twt_bcast_res_support = true;
203 	else
204 		caps->twt_bcast_res_support = false;
205 
206 	if (wmi_service_enabled(wmi_handle, wmi_service_twt_nudge))
207 		caps->twt_nudge_enabled = true;
208 	else
209 		caps->twt_nudge_enabled = false;
210 
211 	if (wmi_service_enabled(wmi_handle, wmi_service_all_twt))
212 		caps->all_twt_enabled = true;
213 	else
214 		caps->all_twt_enabled = false;
215 
216 	if (wmi_service_enabled(wmi_handle, wmi_service_twt_statistics))
217 		caps->twt_stats_enabled = true;
218 	else
219 		caps->twt_stats_enabled = false;
220 
221 	if (wmi_service_enabled(wmi_handle, wmi_service_restricted_twt))
222 		caps->restricted_twt_support = true;
223 	else
224 		caps->restricted_twt_support = false;
225 
226 	target_if_debug("req:%d res:%d legacy_bcast_twt_support:%d",
227 		caps->twt_requestor,
228 		caps->twt_responder,
229 		caps->legacy_bcast_twt_support);
230 	target_if_debug("twt_bcast_req_support:%d twt_bcast_res_support:%d",
231 		caps->twt_bcast_req_support,
232 		caps->twt_bcast_res_support);
233 	target_if_debug("nudge_enabled:%d all_twt_enabled:%d stats_enabled:%d",
234 		caps->twt_nudge_enabled,
235 		caps->all_twt_enabled,
236 		caps->twt_stats_enabled);
237 	target_if_debug("restricted_twt_support:%d",
238 			caps->restricted_twt_support);
239 	return QDF_STATUS_SUCCESS;
240 }
241 
242