1 /* 2 * Copyright (c) 2018-2021 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 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 39 static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, 40 void *arg) 41 { 42 struct vdev_mlme_obj *vdev_mlme; 43 struct wlan_objmgr_pdev *pdev; 44 struct wlan_objmgr_psoc *psoc; 45 struct pdev_mlme_obj *pdev_mlme; 46 struct wlan_lmac_if_mlme_tx_ops *txops; 47 QDF_STATUS status; 48 49 if (!vdev) { 50 mlme_err(" VDEV is NULL"); 51 return QDF_STATUS_E_FAILURE; 52 } 53 54 pdev = wlan_vdev_get_pdev(vdev); 55 if (!pdev) { 56 mlme_err(" PDEV is NULL"); 57 return QDF_STATUS_E_FAILURE; 58 } 59 60 /** 61 * 1st check whether for this vdev any vdev commands are pending for 62 * response. 63 */ 64 psoc = wlan_pdev_get_psoc(pdev); 65 if (!psoc) { 66 mlme_err("PSOC is NULL"); 67 return QDF_STATUS_E_FAILURE; 68 } 69 70 txops = wlan_mlme_get_lmac_tx_ops(psoc); 71 if (!txops || !txops->psoc_vdev_rsp_timer_inuse) { 72 mlme_err("Failed to get mlme txrx_ops PSOC_%d", 73 wlan_psoc_get_id(psoc)); 74 return QDF_STATUS_E_FAILURE; 75 } 76 77 status = txops->psoc_vdev_rsp_timer_inuse(psoc, wlan_vdev_get_id(vdev)); 78 if (QDF_IS_STATUS_ERROR(status)) { 79 mlme_err("The vdev response is pending for VDEV_%d status:%d", 80 wlan_vdev_get_id(vdev), status); 81 return QDF_STATUS_E_FAILURE; 82 } 83 84 pdev_mlme = wlan_pdev_mlme_get_cmpt_obj(pdev); 85 if (!pdev_mlme) { 86 mlme_err("PDEV MLME is NULL"); 87 return QDF_STATUS_E_FAILURE; 88 } 89 90 vdev_mlme = qdf_mem_malloc(sizeof(*vdev_mlme)); 91 if (!vdev_mlme) 92 return QDF_STATUS_E_NOMEM; 93 wlan_minidump_log(vdev_mlme, sizeof(*vdev_mlme), psoc, 94 WLAN_MD_OBJMGR_VDEV_MLME, "vdev_mlme"); 95 96 vdev_mlme->vdev = vdev; 97 98 if (pdev_mlme->mlme_register_ops(vdev_mlme) != QDF_STATUS_SUCCESS) { 99 mlme_err("Callbacks registration is failed"); 100 goto init_failed; 101 } 102 103 if (mlme_vdev_sm_create(vdev_mlme) != QDF_STATUS_SUCCESS) { 104 mlme_err("SME creation failed"); 105 goto init_failed; 106 } 107 108 if (QDF_IS_STATUS_ERROR(wlan_cm_init(vdev_mlme))) { 109 mlme_err("CM SM create failed"); 110 goto cm_sm_create_failed; 111 } 112 113 if (mlme_vdev_ops_ext_hdl_create(vdev_mlme) != 114 QDF_STATUS_SUCCESS) { 115 mlme_err("Legacy vdev object creation failed"); 116 goto ext_hdl_create_failed; 117 } 118 119 qdf_timer_init(NULL, &vdev_mlme->ml_reconfig_timer, 120 mlme_vdev_reconfig_timer_cb, (void *)(vdev_mlme), 121 QDF_TIMER_TYPE_WAKE_APPS); 122 123 wlan_objmgr_vdev_component_obj_attach((struct wlan_objmgr_vdev *)vdev, 124 WLAN_UMAC_COMP_MLME, 125 (void *)vdev_mlme, 126 QDF_STATUS_SUCCESS); 127 128 if (mlme_vdev_ops_ext_hdl_post_create(vdev_mlme) != 129 QDF_STATUS_SUCCESS) { 130 mlme_err("Legacy vdev object post creation failed"); 131 goto ext_hdl_post_create_failed; 132 } 133 134 qdf_mem_set(vdev_mlme->mgmt.rate_info.ratemask_params, 135 WLAN_VDEV_RATEMASK_TYPE_MAX * 136 sizeof(struct vdev_ratemask_params), 0xFF); 137 138 return QDF_STATUS_SUCCESS; 139 140 ext_hdl_post_create_failed: 141 qdf_timer_free(&vdev_mlme->ml_reconfig_timer); 142 mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); 143 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 144 vdev_mlme); 145 ext_hdl_create_failed: 146 wlan_cm_deinit(vdev_mlme); 147 cm_sm_create_failed: 148 mlme_vdev_sm_destroy(vdev_mlme); 149 init_failed: 150 wlan_minidump_remove(vdev_mlme, sizeof(*vdev_mlme), psoc, 151 WLAN_MD_OBJMGR_VDEV_MLME, "vdev_mlme"); 152 153 qdf_mem_free(vdev_mlme); 154 return QDF_STATUS_E_FAILURE; 155 } 156 157 static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, 158 void *arg) 159 { 160 struct vdev_mlme_obj *vdev_mlme; 161 162 if (!vdev) { 163 mlme_err(" VDEV is NULL"); 164 return QDF_STATUS_E_FAILURE; 165 } 166 167 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 168 if (!vdev_mlme) { 169 mlme_info(" VDEV MLME component object is NULL"); 170 return QDF_STATUS_SUCCESS; 171 } 172 173 qdf_timer_free(&vdev_mlme->ml_reconfig_timer); 174 wlan_cm_deinit(vdev_mlme); 175 mlme_vdev_sm_destroy(vdev_mlme); 176 mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); 177 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 178 vdev_mlme); 179 180 wlan_minidump_remove(vdev_mlme, sizeof(*vdev_mlme), 181 wlan_vdev_get_psoc(vdev), 182 WLAN_MD_OBJMGR_VDEV_MLME, "vdev_mlme"); 183 184 qdf_mem_free(vdev_mlme); 185 186 return QDF_STATUS_SUCCESS; 187 } 188 189 static void mlme_scan_serialization_comp_info_cb( 190 struct wlan_objmgr_vdev *vdev, 191 union wlan_serialization_rules_info *comp_info, 192 struct wlan_serialization_command *cmd) 193 { 194 struct wlan_objmgr_pdev *pdev; 195 struct scan_start_request *scan_start_req = cmd->umac_cmd; 196 QDF_STATUS status; 197 198 if (!comp_info || !vdev) { 199 mlme_err("comp_info or vdev is NULL"); 200 return; 201 } 202 203 pdev = wlan_vdev_get_pdev(vdev); 204 if (!pdev) { 205 mlme_err("pdev is NULL"); 206 return; 207 } 208 209 if (!scan_start_req) { 210 mlme_err("scan start request is null"); 211 return; 212 } 213 214 comp_info->scan_info.is_scan_for_connect = false; 215 216 if (cmd->cmd_type == WLAN_SER_CMD_SCAN && 217 scan_start_req->scan_req.scan_type == SCAN_TYPE_SCAN_FOR_CONNECT) { 218 comp_info->scan_info.is_scan_for_connect = true; 219 } 220 221 comp_info->scan_info.is_mlme_op_in_progress = false; 222 223 status = wlan_util_is_pdev_scan_allowed(pdev, WLAN_MLME_SER_IF_ID); 224 if (status != QDF_STATUS_SUCCESS) 225 comp_info->scan_info.is_mlme_op_in_progress = true; 226 } 227 228 QDF_STATUS wlan_mlme_psoc_enable(struct wlan_objmgr_psoc *psoc) 229 { 230 QDF_STATUS status; 231 struct wlan_lmac_if_mlme_tx_ops *tx_ops; 232 233 status = wlan_serialization_register_comp_info_cb 234 (psoc, 235 WLAN_UMAC_COMP_MLME, 236 WLAN_SER_CMD_SCAN, 237 mlme_scan_serialization_comp_info_cb); 238 if (status != QDF_STATUS_SUCCESS) { 239 mlme_err("Serialize scan cmd register failed"); 240 return status; 241 } 242 243 /* Register for WMI events into target_if rx */ 244 tx_ops = wlan_mlme_get_lmac_tx_ops(psoc); 245 if (tx_ops && tx_ops->vdev_mlme_attach) 246 tx_ops->vdev_mlme_attach(psoc); 247 248 return QDF_STATUS_SUCCESS; 249 } 250 251 QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc) 252 { 253 QDF_STATUS status; 254 struct wlan_lmac_if_mlme_tx_ops *tx_ops; 255 256 status = wlan_serialization_deregister_comp_info_cb 257 (psoc, 258 WLAN_UMAC_COMP_MLME, 259 WLAN_SER_CMD_SCAN); 260 if (status != QDF_STATUS_SUCCESS) { 261 mlme_err("Serialize scan cmd deregister failed"); 262 return status; 263 } 264 265 /* Unregister WMI events */ 266 tx_ops = wlan_mlme_get_lmac_tx_ops(psoc); 267 if (tx_ops && tx_ops->vdev_mlme_detach) 268 tx_ops->vdev_mlme_detach(psoc); 269 270 return QDF_STATUS_SUCCESS; 271 } 272 273 QDF_STATUS wlan_vdev_mlme_init(void) 274 { 275 if (wlan_objmgr_register_vdev_create_handler 276 (WLAN_UMAC_COMP_MLME, 277 mlme_vdev_obj_create_handler, NULL) 278 != QDF_STATUS_SUCCESS) 279 return QDF_STATUS_E_FAILURE; 280 281 if (wlan_objmgr_register_vdev_destroy_handler 282 (WLAN_UMAC_COMP_MLME, 283 mlme_vdev_obj_destroy_handler, NULL) 284 != QDF_STATUS_SUCCESS) { 285 if (wlan_objmgr_unregister_vdev_create_handler 286 (WLAN_UMAC_COMP_MLME, 287 mlme_vdev_obj_create_handler, NULL) 288 != QDF_STATUS_SUCCESS) 289 return QDF_STATUS_E_FAILURE; 290 291 return QDF_STATUS_E_FAILURE; 292 } 293 294 return QDF_STATUS_SUCCESS; 295 } 296 297 QDF_STATUS wlan_vdev_mlme_deinit(void) 298 { 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 if (wlan_objmgr_unregister_vdev_destroy_handler 306 (WLAN_UMAC_COMP_MLME, 307 mlme_vdev_obj_destroy_handler, NULL) 308 != QDF_STATUS_SUCCESS) 309 return QDF_STATUS_E_FAILURE; 310 311 return QDF_STATUS_SUCCESS; 312 } 313 314 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 315 QDF_STATUS wlan_vdev_mlme_send_set_mac_addr(struct qdf_mac_addr mac_addr, 316 struct qdf_mac_addr mld_addr, 317 struct wlan_objmgr_vdev *vdev) 318 { 319 return mlme_vdev_ops_send_set_mac_address(mac_addr, mld_addr, vdev); 320 } 321 #endif 322