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 /**
19 * DOC: wlan_twt_objmgr.c
20 * This file defines the APIs of TWT component.
21 */
22 #include "wlan_twt_common.h"
23 #include "wlan_twt_priv.h"
24 #include "wlan_twt_objmgr_handler.h"
25 #include "wlan_objmgr_peer_obj.h"
26 #include "include/wlan_mlme_cmn.h"
27
28 QDF_STATUS
wlan_twt_psoc_obj_create_handler(struct wlan_objmgr_psoc * psoc,void * arg)29 wlan_twt_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
30 {
31 QDF_STATUS status;
32 struct twt_psoc_priv_obj *twt_psoc_obj;
33
34 twt_psoc_obj = qdf_mem_malloc(sizeof(*twt_psoc_obj));
35 if (!twt_psoc_obj)
36 return QDF_STATUS_E_NOMEM;
37
38 twt_psoc_obj->enable_context.context = NULL;
39 twt_psoc_obj->disable_context.context = NULL;
40 twt_psoc_obj->twt_pmo_disabled = 0;
41
42 status = wlan_objmgr_psoc_component_obj_attach(psoc,
43 WLAN_UMAC_COMP_TWT,
44 (void *)twt_psoc_obj,
45 QDF_STATUS_SUCCESS);
46
47 if (QDF_IS_STATUS_ERROR(status)) {
48 qdf_mem_free(twt_psoc_obj);
49 twt_err("Failed to attach twt psoc priv object");
50 return status;
51 }
52
53 twt_debug("twt psoc priv obj attach successful");
54 return status;
55 }
56
57 QDF_STATUS
wlan_twt_psoc_obj_destroy_handler(struct wlan_objmgr_psoc * psoc,void * arg)58 wlan_twt_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, void *arg)
59 {
60 QDF_STATUS status;
61 struct twt_psoc_priv_obj *twt_psoc_obj;
62
63 twt_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
64 WLAN_UMAC_COMP_TWT);
65 if (!twt_psoc_obj) {
66 twt_err("Failed to get twt obj in psoc");
67 return QDF_STATUS_E_FAILURE;
68 }
69
70 status = wlan_objmgr_psoc_component_obj_detach(psoc,
71 WLAN_UMAC_COMP_TWT,
72 twt_psoc_obj);
73
74 if (QDF_IS_STATUS_ERROR(status))
75 twt_err("Failed to detach twt psoc priv object");
76
77 qdf_mem_free(twt_psoc_obj);
78
79 return status;
80 }
81
82 QDF_STATUS
wlan_twt_vdev_obj_create_handler(struct wlan_objmgr_vdev * vdev,void * arg)83 wlan_twt_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, void *arg)
84 {
85 QDF_STATUS status;
86 struct twt_vdev_priv_obj *twt_vdev_obj;
87
88 twt_vdev_obj = qdf_mem_malloc(sizeof(*twt_vdev_obj));
89 if (!twt_vdev_obj)
90 return QDF_STATUS_E_NOMEM;
91
92 twt_vdev_obj->twt_wait_for_notify = false;
93
94 status = wlan_objmgr_vdev_component_obj_attach(vdev,
95 WLAN_UMAC_COMP_TWT,
96 twt_vdev_obj,
97 QDF_STATUS_SUCCESS);
98
99 if (QDF_IS_STATUS_ERROR(status)) {
100 qdf_mem_free(twt_vdev_obj);
101 twt_err("Failed to attach twt vdev priv object");
102 return status;
103 }
104
105 twt_debug("twt vdev priv obj attach successful");
106
107 status = mlme_twt_vdev_create_notification(vdev);
108
109 if (QDF_IS_STATUS_ERROR(status)) {
110 twt_err("vdev create notification failed");
111 return status;
112 }
113
114 return status;
115 }
116
117 QDF_STATUS
wlan_twt_vdev_obj_destroy_handler(struct wlan_objmgr_vdev * vdev,void * arg)118 wlan_twt_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, void *arg)
119 {
120 QDF_STATUS status;
121 struct twt_vdev_priv_obj *twt_vdev_obj;
122
123 status = mlme_twt_vdev_destroy_notification(vdev);
124 if (QDF_IS_STATUS_ERROR(status)) {
125 twt_err("vdev destroy notification failed");
126 return status;
127 }
128
129 twt_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
130 WLAN_UMAC_COMP_TWT);
131 if (!twt_vdev_obj) {
132 twt_err("Failed to get twt obj in vdev");
133 return QDF_STATUS_E_FAILURE;
134 }
135
136 status = wlan_objmgr_vdev_component_obj_detach(vdev,
137 WLAN_UMAC_COMP_TWT,
138 twt_vdev_obj);
139
140 if (QDF_IS_STATUS_ERROR(status))
141 twt_err("Failed to detach twt vdev priv object");
142
143 qdf_mem_free(twt_vdev_obj);
144
145 return status;
146 }
147
148 QDF_STATUS
wlan_twt_peer_obj_create_handler(struct wlan_objmgr_peer * peer,void * arg)149 wlan_twt_peer_obj_create_handler(struct wlan_objmgr_peer *peer, void *arg)
150 {
151 struct twt_peer_priv_obj *twt_peer_obj = NULL;
152 QDF_STATUS status = QDF_STATUS_E_FAILURE;
153
154 if (!peer) {
155 twt_err("peer is NULL");
156 return QDF_STATUS_E_FAILURE;
157 }
158
159 twt_peer_obj = qdf_mem_malloc(sizeof(*twt_peer_obj));
160 if (!twt_peer_obj)
161 return QDF_STATUS_E_NOMEM;
162
163 twt_lock_create(&twt_peer_obj->twt_peer_lock);
164
165 status = wlan_objmgr_peer_component_obj_attach(peer,
166 WLAN_UMAC_COMP_TWT,
167 twt_peer_obj,
168 QDF_STATUS_SUCCESS);
169
170 if (QDF_IS_STATUS_ERROR(status)) {
171 twt_lock_destroy(&twt_peer_obj->twt_peer_lock);
172 qdf_mem_free(twt_peer_obj);
173 twt_err("peer twt object attach failed");
174 return QDF_STATUS_E_FAILURE;
175 }
176
177 twt_debug("twt peer priv obj attach successful");
178 return status;
179 }
180
181 QDF_STATUS
wlan_twt_peer_obj_destroy_handler(struct wlan_objmgr_peer * peer,void * arg)182 wlan_twt_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg)
183 {
184 struct twt_peer_priv_obj *twt_peer_obj;
185 QDF_STATUS status = QDF_STATUS_E_FAILURE;
186
187 if (!peer) {
188 twt_err("peer is NULL");
189 return QDF_STATUS_E_INVAL;
190 }
191
192 twt_peer_obj = wlan_objmgr_peer_get_comp_private_obj(peer,
193 WLAN_UMAC_COMP_TWT);
194 if (!twt_peer_obj) {
195 twt_err("twt_peer_obj is NULL");
196 return QDF_STATUS_E_INVAL;
197 }
198
199 twt_lock_destroy(&twt_peer_obj->twt_peer_lock);
200
201 status = wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_TWT,
202 twt_peer_obj);
203 if (QDF_IS_STATUS_ERROR(status))
204 twt_warn("Failed to detach twt peer priv object");
205
206 qdf_mem_free(twt_peer_obj);
207 twt_debug("peer twt object detached");
208 return QDF_STATUS_SUCCESS;
209 }
210
211 QDF_STATUS
wlan_twt_psoc_set_pmo_disable(struct wlan_objmgr_psoc * psoc,enum twt_disable_reason reason)212 wlan_twt_psoc_set_pmo_disable(struct wlan_objmgr_psoc *psoc,
213 enum twt_disable_reason reason)
214 {
215 struct twt_psoc_priv_obj *twt_psoc_obj;
216
217 twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
218 if (!twt_psoc_obj) {
219 twt_err("twt_psoc_obj is NULL");
220 return QDF_STATUS_E_INVAL;
221 }
222 twt_psoc_obj->twt_pmo_disabled |= reason;
223 twt_debug("Psoc twt_disabled %x", twt_psoc_obj->twt_pmo_disabled);
224
225 return QDF_STATUS_SUCCESS;
226 }
227
228 QDF_STATUS
wlan_twt_psoc_set_pmo_enable(struct wlan_objmgr_psoc * psoc,enum twt_disable_reason reason)229 wlan_twt_psoc_set_pmo_enable(struct wlan_objmgr_psoc *psoc,
230 enum twt_disable_reason reason)
231 {
232 struct twt_psoc_priv_obj *twt_psoc_obj;
233
234 twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
235 if (!twt_psoc_obj) {
236 twt_err("twt_psoc_obj is NULL");
237 return QDF_STATUS_E_INVAL;
238 }
239 twt_psoc_obj->twt_pmo_disabled &= ~reason;
240 twt_debug("Psoc twt_disabled %x", twt_psoc_obj->twt_pmo_disabled);
241
242 return QDF_STATUS_SUCCESS;
243 }
244
245