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 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 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 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 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 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 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 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 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