1 /* 2 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /** 18 * DOC: Implements MLME component object creation/initialization/destroy 19 */ 20 21 #include <wlan_objmgr_cmn.h> 22 #include <wlan_objmgr_global_obj.h> 23 #include <wlan_objmgr_vdev_obj.h> 24 #include <wlan_mlme_dbg.h> 25 #include "include/wlan_mlme_cmn.h" 26 #include "include/wlan_vdev_mlme.h" 27 #include "include/wlan_pdev_mlme.h" 28 #include "vdev_mgr/core/src/vdev_mlme_sm.h" 29 #include "wlan_pdev_mlme_api.h" 30 #include "wlan_vdev_mlme_api.h" 31 #include "wlan_serialization_api.h" 32 #include "wlan_utility.h" 33 #include <cdp_txrx_cmn.h> 34 #include "target_if_vdev_mgr_wake_lock.h" 35 36 static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, 37 void *arg) 38 { 39 struct vdev_mlme_obj *vdev_mlme; 40 struct wlan_objmgr_pdev *pdev; 41 struct pdev_mlme_obj *pdev_mlme; 42 43 if (!vdev) { 44 mlme_err(" VDEV is NULL"); 45 return QDF_STATUS_E_FAILURE; 46 } 47 48 pdev = wlan_vdev_get_pdev(vdev); 49 if (!pdev) { 50 mlme_err(" PDEV is NULL"); 51 return QDF_STATUS_E_FAILURE; 52 } 53 54 pdev_mlme = wlan_pdev_mlme_get_cmpt_obj(pdev); 55 if (!pdev_mlme) { 56 mlme_err(" PDEV MLME is NULL"); 57 return QDF_STATUS_E_FAILURE; 58 } 59 60 vdev_mlme = qdf_mem_malloc(sizeof(*vdev_mlme)); 61 if (!vdev_mlme) 62 return QDF_STATUS_E_NOMEM; 63 64 vdev_mlme->vdev = vdev; 65 66 if (pdev_mlme->mlme_register_ops(vdev_mlme) != QDF_STATUS_SUCCESS) { 67 mlme_err("Callbacks registration is failed"); 68 goto init_failed; 69 } 70 71 if (mlme_vdev_sm_create(vdev_mlme) != QDF_STATUS_SUCCESS) { 72 mlme_err("SME creation failed"); 73 goto init_failed; 74 } 75 76 if (mlme_vdev_ops_ext_hdl_create(vdev_mlme) != 77 QDF_STATUS_SUCCESS) { 78 mlme_err("Legacy vdev object creation failed"); 79 goto ext_hdl_create_failed; 80 } 81 82 wlan_objmgr_vdev_component_obj_attach((struct wlan_objmgr_vdev *)vdev, 83 WLAN_UMAC_COMP_MLME, 84 (void *)vdev_mlme, 85 QDF_STATUS_SUCCESS); 86 87 target_if_wake_lock_init(vdev); 88 if (mlme_vdev_ops_ext_hdl_post_create(vdev_mlme) != 89 QDF_STATUS_SUCCESS) { 90 mlme_err("Legacy vdev object post creation failed"); 91 goto ext_hdl_post_create_failed; 92 } 93 94 return QDF_STATUS_SUCCESS; 95 96 ext_hdl_post_create_failed: 97 mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); 98 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 99 vdev_mlme); 100 ext_hdl_create_failed: 101 mlme_vdev_sm_destroy(vdev_mlme); 102 init_failed: 103 qdf_mem_free(vdev_mlme); 104 105 return QDF_STATUS_E_FAILURE; 106 } 107 108 static void mlme_vdev_obj_timer_deinit( 109 struct vdev_mlme_obj *vdev_mlme) 110 { 111 struct vdev_response_timer *vdev_rsp; 112 113 vdev_rsp = &vdev_mlme->vdev_rt; 114 qdf_timer_free(&vdev_rsp->rsp_timer); 115 } 116 117 static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, 118 void *arg) 119 { 120 struct vdev_mlme_obj *vdev_mlme; 121 struct wlan_objmgr_psoc *psoc; 122 struct cdp_soc_t *soc_txrx_handle; 123 struct cdp_vdev *vdev_txrx_handle; 124 125 if (!vdev) { 126 mlme_err(" VDEV is NULL"); 127 return QDF_STATUS_E_FAILURE; 128 } 129 target_if_wake_lock_deinit(vdev); 130 131 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 132 if (!vdev_mlme) { 133 mlme_info(" VDEV MLME component object is NULL"); 134 return QDF_STATUS_SUCCESS; 135 } 136 137 psoc = wlan_vdev_get_psoc(vdev); 138 soc_txrx_handle = (struct cdp_soc_t *)wlan_psoc_get_dp_handle(psoc); 139 vdev_txrx_handle = wlan_vdev_get_dp_handle(vdev); 140 if (soc_txrx_handle && vdev_txrx_handle) { 141 wlan_vdev_set_dp_handle(vdev, NULL); 142 cdp_vdev_detach(soc_txrx_handle, vdev_txrx_handle, 143 NULL, NULL); 144 } 145 146 mlme_vdev_obj_timer_deinit(vdev_mlme); 147 148 mlme_vdev_sm_destroy(vdev_mlme); 149 150 mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); 151 152 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 153 vdev_mlme); 154 qdf_mem_free(vdev_mlme); 155 156 return QDF_STATUS_SUCCESS; 157 } 158 159 static void mlme_scan_serialization_comp_info_cb( 160 struct wlan_objmgr_vdev *vdev, 161 union wlan_serialization_rules_info *comp_info) 162 { 163 struct wlan_objmgr_pdev *pdev; 164 QDF_STATUS status; 165 166 if (!comp_info || !vdev) { 167 mlme_err("comp_info or vdev is NULL"); 168 return; 169 } 170 171 pdev = wlan_vdev_get_pdev(vdev); 172 if (!pdev) { 173 mlme_err("pdev is NULL"); 174 return; 175 } 176 177 comp_info->scan_info.is_mlme_op_in_progress = false; 178 179 status = wlan_util_is_pdev_scan_allowed(pdev, WLAN_MLME_SER_IF_ID); 180 if (status != QDF_STATUS_SUCCESS) 181 comp_info->scan_info.is_mlme_op_in_progress = true; 182 } 183 184 QDF_STATUS wlan_mlme_psoc_enable(struct wlan_objmgr_psoc *psoc) 185 { 186 QDF_STATUS status; 187 struct wlan_lmac_if_mlme_tx_ops *tx_ops; 188 189 status = wlan_serialization_register_comp_info_cb 190 (psoc, 191 WLAN_UMAC_COMP_MLME, 192 WLAN_SER_CMD_SCAN, 193 mlme_scan_serialization_comp_info_cb); 194 if (status != QDF_STATUS_SUCCESS) { 195 mlme_err("Serialize scan cmd register failed"); 196 return status; 197 } 198 199 /* Register for WMI events into target_if rx */ 200 tx_ops = wlan_mlme_get_lmac_tx_ops(psoc); 201 if (tx_ops && tx_ops->vdev_mlme_attach) 202 tx_ops->vdev_mlme_attach(psoc); 203 204 return QDF_STATUS_SUCCESS; 205 } 206 207 QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc) 208 { 209 QDF_STATUS status; 210 struct wlan_lmac_if_mlme_tx_ops *tx_ops; 211 212 status = wlan_serialization_deregister_comp_info_cb 213 (psoc, 214 WLAN_UMAC_COMP_MLME, 215 WLAN_SER_CMD_SCAN); 216 if (status != QDF_STATUS_SUCCESS) { 217 mlme_err("Serialize scan cmd deregister failed"); 218 return status; 219 } 220 221 /* Unregister WMI events */ 222 tx_ops = wlan_mlme_get_lmac_tx_ops(psoc); 223 if (tx_ops && tx_ops->vdev_mlme_detach) 224 tx_ops->vdev_mlme_detach(psoc); 225 226 return QDF_STATUS_SUCCESS; 227 } 228 229 QDF_STATUS wlan_vdev_mlme_init(void) 230 { 231 if (wlan_objmgr_register_vdev_create_handler 232 (WLAN_UMAC_COMP_MLME, 233 mlme_vdev_obj_create_handler, NULL) 234 != QDF_STATUS_SUCCESS) 235 return QDF_STATUS_E_FAILURE; 236 237 if (wlan_objmgr_register_vdev_destroy_handler 238 (WLAN_UMAC_COMP_MLME, 239 mlme_vdev_obj_destroy_handler, NULL) 240 != QDF_STATUS_SUCCESS) { 241 if (wlan_objmgr_unregister_vdev_create_handler 242 (WLAN_UMAC_COMP_MLME, 243 mlme_vdev_obj_create_handler, NULL) 244 != QDF_STATUS_SUCCESS) 245 return QDF_STATUS_E_FAILURE; 246 247 return QDF_STATUS_E_FAILURE; 248 } 249 250 return QDF_STATUS_SUCCESS; 251 } 252 253 QDF_STATUS wlan_vdev_mlme_deinit(void) 254 { 255 if (wlan_objmgr_unregister_vdev_create_handler 256 (WLAN_UMAC_COMP_MLME, 257 mlme_vdev_obj_create_handler, NULL) 258 != QDF_STATUS_SUCCESS) 259 return QDF_STATUS_E_FAILURE; 260 261 if (wlan_objmgr_unregister_vdev_destroy_handler 262 (WLAN_UMAC_COMP_MLME, 263 mlme_vdev_obj_destroy_handler, NULL) 264 != QDF_STATUS_SUCCESS) 265 return QDF_STATUS_E_FAILURE; 266 267 return QDF_STATUS_SUCCESS; 268 } 269