1 /* 2 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /** 19 * DOC: Implements MLME component object creation/initialization/destroy 20 */ 21 22 #include <wlan_objmgr_cmn.h> 23 #include <wlan_objmgr_global_obj.h> 24 #include <wlan_objmgr_vdev_obj.h> 25 #include <wlan_mlme_dbg.h> 26 #include <include/wlan_mlme_cmn.h> 27 #include <include/wlan_vdev_mlme.h> 28 #include <include/wlan_pdev_mlme.h> 29 #include <vdev_mgr/core/src/vdev_mlme_sm.h> 30 #include <wlan_pdev_mlme_api.h> 31 #include <wlan_vdev_mlme_api.h> 32 #include <wlan_serialization_api.h> 33 #include <wlan_utility.h> 34 #include <cdp_txrx_cmn.h> 35 #include <wlan_lmac_if_def.h> 36 #include <target_if_vdev_mgr_tx_ops.h> 37 #include "connection_mgr/core/src/wlan_cm_main.h" 38 #include <wlan_mlo_mgr_public_api.h> 39 mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev * vdev,void * arg)40 static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, 41 void *arg) 42 { 43 struct vdev_mlme_obj *vdev_mlme; 44 struct wlan_objmgr_pdev *pdev; 45 struct wlan_objmgr_psoc *psoc; 46 struct pdev_mlme_obj *pdev_mlme; 47 struct wlan_lmac_if_mlme_tx_ops *txops; 48 QDF_STATUS status; 49 50 if (!vdev) { 51 mlme_err(" VDEV is NULL"); 52 return QDF_STATUS_E_FAILURE; 53 } 54 55 pdev = wlan_vdev_get_pdev(vdev); 56 if (!pdev) { 57 mlme_err(" PDEV is NULL"); 58 return QDF_STATUS_E_FAILURE; 59 } 60 61 /** 62 * 1st check whether for this vdev any vdev commands are pending for 63 * response. 64 */ 65 psoc = wlan_pdev_get_psoc(pdev); 66 if (!psoc) { 67 mlme_err("PSOC is NULL"); 68 return QDF_STATUS_E_FAILURE; 69 } 70 71 txops = wlan_mlme_get_lmac_tx_ops(psoc); 72 if (!txops || !txops->psoc_vdev_rsp_timer_inuse) { 73 mlme_err("Failed to get mlme txrx_ops PSOC_%d", 74 wlan_psoc_get_id(psoc)); 75 return QDF_STATUS_E_FAILURE; 76 } 77 78 status = txops->psoc_vdev_rsp_timer_inuse(psoc, wlan_vdev_get_id(vdev)); 79 if (QDF_IS_STATUS_ERROR(status)) { 80 if (status == QDF_STATUS_E_ALREADY) { 81 mlme_err("Go through, since timer initializes later."); 82 } else { 83 mlme_err("The vdev response is pending for VDEV_%d status:%d", 84 wlan_vdev_get_id(vdev), status); 85 return QDF_STATUS_E_FAILURE; 86 } 87 } 88 89 pdev_mlme = wlan_pdev_mlme_get_cmpt_obj(pdev); 90 if (!pdev_mlme) { 91 mlme_err("PDEV MLME is NULL"); 92 return QDF_STATUS_E_FAILURE; 93 } 94 95 vdev_mlme = qdf_mem_malloc(sizeof(*vdev_mlme)); 96 if (!vdev_mlme) 97 return QDF_STATUS_E_NOMEM; 98 wlan_minidump_log(vdev_mlme, sizeof(*vdev_mlme), psoc, 99 WLAN_MD_OBJMGR_VDEV_MLME, "vdev_mlme"); 100 101 vdev_mlme->vdev = vdev; 102 103 if (pdev_mlme->mlme_register_ops(vdev_mlme) != QDF_STATUS_SUCCESS) { 104 mlme_err("Callbacks registration is failed"); 105 goto init_failed; 106 } 107 108 if (mlme_vdev_sm_create(vdev_mlme) != QDF_STATUS_SUCCESS) { 109 mlme_err("SME creation failed"); 110 goto init_failed; 111 } 112 113 if (QDF_IS_STATUS_ERROR(wlan_cm_init(vdev_mlme))) { 114 mlme_err("CM SM create failed"); 115 goto cm_sm_create_failed; 116 } 117 118 if (mlme_vdev_ops_ext_hdl_create(vdev_mlme) != 119 QDF_STATUS_SUCCESS) { 120 mlme_err("Legacy vdev object creation failed"); 121 goto ext_hdl_create_failed; 122 } 123 124 qdf_timer_init(NULL, &vdev_mlme->ml_reconfig_timer, 125 mlme_vdev_reconfig_timer_cb, (void *)(vdev_mlme), 126 QDF_TIMER_TYPE_WAKE_APPS); 127 128 wlan_objmgr_vdev_component_obj_attach((struct wlan_objmgr_vdev *)vdev, 129 WLAN_UMAC_COMP_MLME, 130 (void *)vdev_mlme, 131 QDF_STATUS_SUCCESS); 132 133 if (mlme_vdev_ops_ext_hdl_post_create(vdev_mlme) != 134 QDF_STATUS_SUCCESS) { 135 mlme_err("Legacy vdev object post creation failed"); 136 goto ext_hdl_post_create_failed; 137 } 138 139 qdf_mem_set(vdev_mlme->mgmt.rate_info.ratemask_params, 140 WLAN_VDEV_RATEMASK_TYPE_MAX * 141 sizeof(struct vdev_ratemask_params), 0xFF); 142 143 return QDF_STATUS_SUCCESS; 144 145 ext_hdl_post_create_failed: 146 qdf_timer_free(&vdev_mlme->ml_reconfig_timer); 147 mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); 148 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 149 vdev_mlme); 150 ext_hdl_create_failed: 151 wlan_cm_deinit(vdev_mlme); 152 cm_sm_create_failed: 153 mlme_vdev_sm_destroy(vdev_mlme); 154 init_failed: 155 wlan_minidump_remove(vdev_mlme, sizeof(*vdev_mlme), psoc, 156 WLAN_MD_OBJMGR_VDEV_MLME, "vdev_mlme"); 157 158 qdf_mem_free(vdev_mlme); 159 return QDF_STATUS_E_FAILURE; 160 } 161 mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev * vdev,void * arg)162 static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, 163 void *arg) 164 { 165 struct vdev_mlme_obj *vdev_mlme; 166 167 if (!vdev) { 168 mlme_err(" VDEV is NULL"); 169 return QDF_STATUS_E_FAILURE; 170 } 171 172 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 173 if (!vdev_mlme) { 174 mlme_info(" VDEV MLME component object is NULL"); 175 return QDF_STATUS_SUCCESS; 176 } 177 178 qdf_timer_free(&vdev_mlme->ml_reconfig_timer); 179 wlan_cm_deinit(vdev_mlme); 180 mlme_vdev_sm_destroy(vdev_mlme); 181 mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); 182 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 183 vdev_mlme); 184 185 wlan_minidump_remove(vdev_mlme, sizeof(*vdev_mlme), 186 wlan_vdev_get_psoc(vdev), 187 WLAN_MD_OBJMGR_VDEV_MLME, "vdev_mlme"); 188 189 qdf_mem_free(vdev_mlme); 190 191 return QDF_STATUS_SUCCESS; 192 } 193 mlme_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev * vdev,union wlan_serialization_rules_info * comp_info,struct wlan_serialization_command * cmd)194 static void mlme_scan_serialization_comp_info_cb( 195 struct wlan_objmgr_vdev *vdev, 196 union wlan_serialization_rules_info *comp_info, 197 struct wlan_serialization_command *cmd) 198 { 199 struct wlan_objmgr_pdev *pdev; 200 struct scan_start_request *scan_start_req = cmd->umac_cmd; 201 QDF_STATUS status; 202 203 if (!comp_info || !vdev) { 204 mlme_err("comp_info or vdev is NULL"); 205 return; 206 } 207 208 pdev = wlan_vdev_get_pdev(vdev); 209 if (!pdev) { 210 mlme_err("pdev is NULL"); 211 return; 212 } 213 214 if (!scan_start_req) { 215 mlme_err("scan start request is null"); 216 return; 217 } 218 219 comp_info->scan_info.is_scan_for_connect = false; 220 221 if (cmd->cmd_type == WLAN_SER_CMD_SCAN && 222 scan_start_req->scan_req.scan_type == SCAN_TYPE_SCAN_FOR_CONNECT) { 223 comp_info->scan_info.is_scan_for_connect = true; 224 } 225 226 comp_info->scan_info.is_mlme_op_in_progress = false; 227 228 status = wlan_util_is_pdev_scan_allowed(pdev, WLAN_MLME_SER_IF_ID); 229 if (status != QDF_STATUS_SUCCESS) 230 comp_info->scan_info.is_mlme_op_in_progress = true; 231 } 232 wlan_mlme_psoc_enable(struct wlan_objmgr_psoc * psoc)233 QDF_STATUS wlan_mlme_psoc_enable(struct wlan_objmgr_psoc *psoc) 234 { 235 QDF_STATUS status; 236 struct wlan_lmac_if_mlme_tx_ops *tx_ops; 237 238 status = mlme_psoc_ext_enable_cb(psoc); 239 if (QDF_IS_STATUS_ERROR(status)) { 240 mlme_err("Failed to register enable mlme ext param handler cb"); 241 return status; 242 } 243 244 status = wlan_serialization_register_comp_info_cb 245 (psoc, 246 WLAN_UMAC_COMP_MLME, 247 WLAN_SER_CMD_SCAN, 248 mlme_scan_serialization_comp_info_cb); 249 if (QDF_IS_STATUS_ERROR(status)) { 250 mlme_err("Serialize scan cmd register failed"); 251 mlme_psoc_ext_disable_cb(psoc); 252 return status; 253 } 254 255 /* Register for WMI events into target_if rx */ 256 tx_ops = wlan_mlme_get_lmac_tx_ops(psoc); 257 if (tx_ops && tx_ops->vdev_mlme_attach) 258 tx_ops->vdev_mlme_attach(psoc); 259 260 return status; 261 } 262 wlan_mlme_psoc_disable(struct wlan_objmgr_psoc * psoc)263 QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc) 264 { 265 QDF_STATUS status; 266 struct wlan_lmac_if_mlme_tx_ops *tx_ops; 267 268 /* Unregister WMI events */ 269 tx_ops = wlan_mlme_get_lmac_tx_ops(psoc); 270 if (tx_ops && tx_ops->vdev_mlme_detach) 271 tx_ops->vdev_mlme_detach(psoc); 272 273 status = wlan_serialization_deregister_comp_info_cb 274 (psoc, 275 WLAN_UMAC_COMP_MLME, 276 WLAN_SER_CMD_SCAN); 277 if (QDF_IS_STATUS_ERROR(status)) 278 mlme_err("Serialize scan cmd deregister failed"); 279 280 status = mlme_psoc_ext_disable_cb(psoc); 281 if (QDF_IS_STATUS_ERROR(status)) 282 mlme_err("Failed to unregister enable mlme ext param hdl cb"); 283 284 return status; 285 } 286 wlan_vdev_mlme_init(void)287 QDF_STATUS wlan_vdev_mlme_init(void) 288 { 289 if (wlan_objmgr_register_vdev_create_handler 290 (WLAN_UMAC_COMP_MLME, 291 mlme_vdev_obj_create_handler, NULL) 292 != QDF_STATUS_SUCCESS) 293 return QDF_STATUS_E_FAILURE; 294 295 if (wlan_objmgr_register_vdev_destroy_handler 296 (WLAN_UMAC_COMP_MLME, 297 mlme_vdev_obj_destroy_handler, NULL) 298 != QDF_STATUS_SUCCESS) { 299 if (wlan_objmgr_unregister_vdev_create_handler 300 (WLAN_UMAC_COMP_MLME, 301 mlme_vdev_obj_create_handler, NULL) 302 != QDF_STATUS_SUCCESS) 303 return QDF_STATUS_E_FAILURE; 304 305 return QDF_STATUS_E_FAILURE; 306 } 307 308 return QDF_STATUS_SUCCESS; 309 } 310 wlan_vdev_mlme_deinit(void)311 QDF_STATUS wlan_vdev_mlme_deinit(void) 312 { 313 if (wlan_objmgr_unregister_vdev_create_handler 314 (WLAN_UMAC_COMP_MLME, 315 mlme_vdev_obj_create_handler, NULL) 316 != QDF_STATUS_SUCCESS) 317 return QDF_STATUS_E_FAILURE; 318 319 if (wlan_objmgr_unregister_vdev_destroy_handler 320 (WLAN_UMAC_COMP_MLME, 321 mlme_vdev_obj_destroy_handler, NULL) 322 != QDF_STATUS_SUCCESS) 323 return QDF_STATUS_E_FAILURE; 324 325 return QDF_STATUS_SUCCESS; 326 } 327 328 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE wlan_vdev_mlme_send_set_mac_addr(struct qdf_mac_addr mac_addr,struct qdf_mac_addr mld_addr,struct wlan_objmgr_vdev * vdev)329 QDF_STATUS wlan_vdev_mlme_send_set_mac_addr(struct qdf_mac_addr mac_addr, 330 struct qdf_mac_addr mld_addr, 331 struct wlan_objmgr_vdev *vdev) 332 { 333 return mlme_vdev_ops_send_set_mac_address(mac_addr, mld_addr, vdev); 334 } 335 wlan_vdev_mlme_notify_set_mac_addr_response(struct wlan_objmgr_vdev * vdev,uint8_t resp_status)336 void wlan_vdev_mlme_notify_set_mac_addr_response(struct wlan_objmgr_vdev *vdev, 337 uint8_t resp_status) 338 { 339 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) { 340 wlan_mlo_mgr_link_switch_set_mac_addr_resp(vdev, resp_status); 341 return; 342 } 343 344 mlme_vdev_mgr_notify_set_mac_addr_response(wlan_vdev_get_id(vdev), 345 resp_status); 346 } 347 #endif 348