1 /* 2 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 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_vdev_mgr_tgt_if_rx_api.c 22 * 23 * This file provide definition for APIs registered for LMAC MLME Rx Ops 24 */ 25 #include <qdf_types.h> 26 #include <qdf_module.h> 27 #include <wlan_vdev_mgr_tgt_if_rx_defs.h> 28 #include <wlan_vdev_mgr_tgt_if_rx_api.h> 29 #include <include/wlan_vdev_mlme.h> 30 #include <wlan_mlme_dbg.h> 31 #include <wlan_vdev_mlme_api.h> 32 #include <target_if_vdev_mgr_tx_ops.h> 33 #include <wlan_psoc_mlme_main.h> 34 #include <include/wlan_psoc_mlme.h> 35 #include <include/wlan_mlme_cmn.h> 36 #include <wlan_vdev_mgr_utils_api.h> 37 38 void 39 tgt_vdev_mgr_reset_response_timer_info(struct wlan_objmgr_psoc *psoc) 40 { 41 struct psoc_mlme_obj *psoc_mlme; 42 struct vdev_response_timer *vdev_rsp; 43 int i; 44 45 psoc_mlme = mlme_psoc_get_priv(psoc); 46 if (!psoc_mlme) { 47 mlme_err("PSOC_%d PSOC_MLME is NULL", 48 wlan_psoc_get_id(psoc)); 49 return; 50 } 51 52 for (i = 0; i < WLAN_UMAC_PSOC_MAX_VDEVS; i++) { 53 vdev_rsp = &psoc_mlme->psoc_vdev_rt[i]; 54 qdf_atomic_set(&vdev_rsp->rsp_timer_inuse, 0); 55 vdev_rsp->psoc = NULL; 56 } 57 } 58 59 qdf_export_symbol(tgt_vdev_mgr_reset_response_timer_info); 60 61 struct vdev_response_timer * 62 tgt_vdev_mgr_get_response_timer_info(struct wlan_objmgr_psoc *psoc, 63 uint8_t vdev_id) 64 { 65 struct psoc_mlme_obj *psoc_mlme; 66 67 if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { 68 mlme_err("Incorrect vdev_id: %d", vdev_id); 69 return NULL; 70 } 71 72 psoc_mlme = mlme_psoc_get_priv(psoc); 73 if (!psoc_mlme) { 74 mlme_err("VDEV_%d PSOC_%d PSOC_MLME is NULL", vdev_id, 75 wlan_psoc_get_id(psoc)); 76 return NULL; 77 } 78 79 return &psoc_mlme->psoc_vdev_rt[vdev_id]; 80 } 81 82 qdf_export_symbol(tgt_vdev_mgr_get_response_timer_info); 83 84 static QDF_STATUS tgt_vdev_mgr_start_response_handler( 85 struct wlan_objmgr_psoc *psoc, 86 struct vdev_start_response *rsp) 87 { 88 QDF_STATUS status = QDF_STATUS_E_FAILURE; 89 struct vdev_mlme_obj *vdev_mlme; 90 struct wlan_objmgr_vdev *vdev; 91 92 if (!rsp || !psoc) { 93 mlme_err("Invalid input"); 94 return QDF_STATUS_E_INVAL; 95 } 96 97 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->vdev_id, 98 WLAN_VDEV_TARGET_IF_ID); 99 if (!vdev) { 100 mlme_err("VDEV is NULL"); 101 return QDF_STATUS_E_FAILURE; 102 } 103 104 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 105 if (!vdev_mlme) { 106 mlme_err("VDEV_%d PSOC_%d VDEV_MLME is NULL", rsp->vdev_id, 107 wlan_psoc_get_id(psoc)); 108 goto tgt_vdev_mgr_start_response_handler_end; 109 } 110 111 if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_ext_start_rsp) 112 status = vdev_mlme->ops->mlme_vdev_ext_start_rsp( 113 vdev_mlme, 114 rsp); 115 116 tgt_vdev_mgr_start_response_handler_end: 117 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 118 return status; 119 } 120 121 static QDF_STATUS tgt_vdev_mgr_stop_response_handler( 122 struct wlan_objmgr_psoc *psoc, 123 struct vdev_stop_response *rsp) 124 { 125 QDF_STATUS status = QDF_STATUS_E_FAILURE; 126 struct vdev_mlme_obj *vdev_mlme; 127 struct wlan_objmgr_vdev *vdev; 128 129 if (!rsp || !psoc) { 130 mlme_err("Invalid input"); 131 return QDF_STATUS_E_INVAL; 132 } 133 134 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->vdev_id, 135 WLAN_VDEV_TARGET_IF_ID); 136 if (!vdev) { 137 mlme_err("VDEV is NULL"); 138 return QDF_STATUS_E_FAILURE; 139 } 140 141 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 142 if (!vdev_mlme) { 143 mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", rsp->vdev_id, 144 wlan_psoc_get_id(psoc)); 145 goto tgt_vdev_mgr_stop_response_handler_end; 146 } 147 148 if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_ext_stop_rsp) 149 status = vdev_mlme->ops->mlme_vdev_ext_stop_rsp( 150 vdev_mlme, 151 rsp); 152 153 tgt_vdev_mgr_stop_response_handler_end: 154 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 155 return status; 156 } 157 158 static QDF_STATUS tgt_vdev_mgr_delete_response_handler( 159 struct wlan_objmgr_psoc *psoc, 160 struct vdev_delete_response *rsp) 161 { 162 QDF_STATUS status = QDF_STATUS_E_FAILURE; 163 164 status = mlme_vdev_ops_ext_hdl_delete_rsp(psoc, rsp); 165 return status; 166 } 167 168 static QDF_STATUS tgt_vdev_mgr_peer_delete_all_response_handler( 169 struct wlan_objmgr_psoc *psoc, 170 struct peer_delete_all_response *rsp) 171 { 172 QDF_STATUS status = QDF_STATUS_E_FAILURE; 173 struct vdev_mlme_obj *vdev_mlme; 174 struct wlan_objmgr_vdev *vdev; 175 176 if (!rsp || !psoc) { 177 mlme_err("Invalid input"); 178 return QDF_STATUS_E_INVAL; 179 } 180 181 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 182 rsp->vdev_id, 183 WLAN_VDEV_TARGET_IF_ID); 184 if (!vdev) { 185 mlme_err("VDEV is NULL"); 186 return QDF_STATUS_E_FAILURE; 187 } 188 189 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 190 if (!vdev_mlme) { 191 mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", rsp->vdev_id, 192 wlan_psoc_get_id(psoc)); 193 goto tgt_vdev_mgr_peer_delete_all_response_handler_end; 194 } 195 196 if ((vdev_mlme->ops) && 197 vdev_mlme->ops->mlme_vdev_ext_peer_delete_all_rsp) 198 status = vdev_mlme->ops->mlme_vdev_ext_peer_delete_all_rsp( 199 vdev_mlme, 200 rsp); 201 202 tgt_vdev_mgr_peer_delete_all_response_handler_end: 203 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 204 return status; 205 } 206 207 static QDF_STATUS 208 tgt_vdev_mgr_offload_bcn_tx_status_event_handler(uint32_t vdev_id, 209 uint32_t tx_status) 210 { 211 QDF_STATUS status = QDF_STATUS_E_FAILURE; 212 213 return status; 214 } 215 216 static QDF_STATUS 217 tgt_vdev_mgr_tbttoffset_update_handler(uint32_t num_vdevs, bool is_ext) 218 { 219 QDF_STATUS status = QDF_STATUS_E_FAILURE; 220 221 return status; 222 } 223 224 QDF_STATUS 225 tgt_vdev_mgr_ext_tbttoffset_update_handle(uint32_t num_vdevs, bool is_ext) 226 { 227 QDF_STATUS status = QDF_STATUS_E_FAILURE; 228 229 return status; 230 } 231 232 static QDF_STATUS tgt_vdev_mgr_multi_vdev_restart_resp_handler( 233 struct wlan_objmgr_psoc *psoc, 234 struct multi_vdev_restart_resp *resp) 235 { 236 return mlme_vdev_ops_ext_hdl_multivdev_restart_resp(psoc, resp); 237 } 238 239 #ifdef FEATURE_VDEV_OPS_WAKELOCK 240 static struct psoc_mlme_wakelock * 241 tgt_psoc_get_wakelock_info(struct wlan_objmgr_psoc *psoc) 242 { 243 struct psoc_mlme_obj *psoc_mlme; 244 245 psoc_mlme = mlme_psoc_get_priv(psoc); 246 if (!psoc_mlme) { 247 mlme_err("PSOC_MLME is NULL"); 248 return NULL; 249 } 250 251 return &psoc_mlme->psoc_mlme_wakelock; 252 } 253 254 static inline void 255 tgt_psoc_reg_wakelock_info_rx_op(struct wlan_lmac_if_mlme_rx_ops 256 *mlme_rx_ops) 257 { 258 mlme_rx_ops->psoc_get_wakelock_info = tgt_psoc_get_wakelock_info; 259 } 260 #else 261 static inline void 262 tgt_psoc_reg_wakelock_info_rx_op(struct wlan_lmac_if_mlme_rx_ops 263 *mlme_rx_ops) 264 { 265 } 266 #endif 267 268 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 269 static inline void tgt_vdev_mgr_reg_set_mac_address_response( 270 struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops) 271 { 272 mlme_rx_ops->vdev_mgr_set_mac_addr_response = 273 mlme_vdev_mgr_notify_set_mac_addr_response; 274 } 275 #else 276 static inline void tgt_vdev_mgr_reg_set_mac_address_response( 277 struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops) 278 { 279 } 280 #endif 281 282 static void tgt_vdev_mgr_set_max_channel_switch_time( 283 struct wlan_objmgr_psoc *psoc, uint32_t *vdev_ids, 284 uint32_t num_vdevs) 285 { 286 struct wlan_objmgr_vdev *vdev = NULL; 287 struct vdev_mlme_obj *vdev_mlme = NULL; 288 unsigned long current_time = qdf_mc_timer_get_system_time(); 289 uint32_t max_chan_switch_time = 0; 290 int i = 0; 291 QDF_STATUS status; 292 293 /* Compute and populate the max channel switch time and time of the last 294 * beacon sent on the CSA triggered channel for all the vdevs. 295 */ 296 for (i = 0; i < num_vdevs; i++) { 297 vdev = wlan_objmgr_get_vdev_by_id_from_psoc 298 (psoc, vdev_ids[i], WLAN_VDEV_TARGET_IF_ID); 299 if (!vdev) { 300 mlme_err("VDEV is NULL"); 301 continue; 302 } 303 304 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 305 if (!vdev_mlme) { 306 mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", 307 vdev_ids[i], 308 wlan_psoc_get_id(psoc)); 309 wlan_objmgr_vdev_release_ref(vdev, 310 WLAN_VDEV_TARGET_IF_ID); 311 continue; 312 } 313 314 status = wlan_util_vdev_mgr_compute_max_channel_switch_time 315 (vdev, &max_chan_switch_time); 316 if (QDF_IS_STATUS_ERROR(status)) { 317 mlme_err("Failed to get the max channel switch time value"); 318 wlan_objmgr_vdev_release_ref(vdev, 319 WLAN_VDEV_TARGET_IF_ID); 320 continue; 321 } 322 323 vdev_mlme->mgmt.ap.last_bcn_ts_ms = current_time; 324 vdev_mlme->mgmt.ap.max_chan_switch_time = max_chan_switch_time; 325 326 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 327 } 328 } 329 330 #ifdef WLAN_FEATURE_11BE_MLO 331 static QDF_STATUS 332 tgt_vdev_mgr_quiet_offload_handler(struct wlan_objmgr_psoc *psoc, 333 struct vdev_sta_quiet_event *quiet_event) 334 { 335 return wlan_util_vdev_mgr_quiet_offload(psoc, quiet_event); 336 } 337 338 static inline void tgt_vdev_mgr_reg_quiet_offload( 339 struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops) 340 { 341 mlme_rx_ops->vdev_mgr_quiet_offload = 342 tgt_vdev_mgr_quiet_offload_handler; 343 } 344 #else 345 static inline void tgt_vdev_mgr_reg_quiet_offload( 346 struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops) 347 { 348 } 349 #endif 350 351 void tgt_vdev_mgr_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops) 352 { 353 struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops = &rx_ops->mops; 354 355 mlme_rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle = 356 tgt_vdev_mgr_offload_bcn_tx_status_event_handler; 357 mlme_rx_ops->vdev_mgr_tbttoffset_update_handle = 358 tgt_vdev_mgr_tbttoffset_update_handler; 359 mlme_rx_ops->vdev_mgr_start_response = 360 tgt_vdev_mgr_start_response_handler; 361 mlme_rx_ops->vdev_mgr_stop_response = 362 tgt_vdev_mgr_stop_response_handler; 363 mlme_rx_ops->vdev_mgr_delete_response = 364 tgt_vdev_mgr_delete_response_handler; 365 mlme_rx_ops->vdev_mgr_peer_delete_all_response = 366 tgt_vdev_mgr_peer_delete_all_response_handler; 367 mlme_rx_ops->psoc_get_vdev_response_timer_info = 368 tgt_vdev_mgr_get_response_timer_info; 369 mlme_rx_ops->vdev_mgr_multi_vdev_restart_resp = 370 tgt_vdev_mgr_multi_vdev_restart_resp_handler; 371 mlme_rx_ops->vdev_mgr_set_max_channel_switch_time = 372 tgt_vdev_mgr_set_max_channel_switch_time; 373 tgt_psoc_reg_wakelock_info_rx_op(&rx_ops->mops); 374 tgt_vdev_mgr_reg_set_mac_address_response(mlme_rx_ops); 375 tgt_vdev_mgr_reg_quiet_offload(mlme_rx_ops); 376 } 377