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