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 35 static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, 36 void *arg) 37 { 38 struct vdev_mlme_obj *vdev_mlme; 39 struct wlan_objmgr_pdev *pdev; 40 struct pdev_mlme_obj *pdev_mlme; 41 42 if (!vdev) { 43 mlme_err(" VDEV is NULL"); 44 return QDF_STATUS_E_FAILURE; 45 } 46 47 pdev = wlan_vdev_get_pdev(vdev); 48 if (!pdev) { 49 mlme_err(" PDEV is NULL"); 50 return QDF_STATUS_E_FAILURE; 51 } 52 53 pdev_mlme = wlan_pdev_mlme_get_cmpt_obj(pdev); 54 if (!pdev_mlme) { 55 mlme_err(" PDEV MLME is NULL"); 56 return QDF_STATUS_E_FAILURE; 57 } 58 59 vdev_mlme = qdf_mem_malloc(sizeof(*vdev_mlme)); 60 if (!vdev_mlme) 61 return QDF_STATUS_E_NOMEM; 62 63 vdev_mlme->vdev = vdev; 64 65 if (pdev_mlme->mlme_register_ops(vdev_mlme) != QDF_STATUS_SUCCESS) { 66 mlme_err("Callbacks registration is failed"); 67 goto init_failed; 68 } 69 70 if (mlme_vdev_sm_create(vdev_mlme) != QDF_STATUS_SUCCESS) { 71 mlme_err("SME creation failed"); 72 goto init_failed; 73 } 74 75 if (mlme_vdev_ops_ext_hdl_create(vdev_mlme) != 76 QDF_STATUS_SUCCESS) { 77 mlme_err("Legacy vdev object creation failed"); 78 goto ext_hdl_create_failed; 79 } 80 81 wlan_objmgr_vdev_component_obj_attach((struct wlan_objmgr_vdev *)vdev, 82 WLAN_UMAC_COMP_MLME, 83 (void *)vdev_mlme, 84 QDF_STATUS_SUCCESS); 85 86 if (mlme_vdev_ops_ext_hdl_post_create(vdev_mlme) != 87 QDF_STATUS_SUCCESS) { 88 mlme_err("Legacy vdev object post creation failed"); 89 goto ext_hdl_post_create_failed; 90 } 91 92 return QDF_STATUS_SUCCESS; 93 94 ext_hdl_post_create_failed: 95 mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); 96 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 97 vdev_mlme); 98 ext_hdl_create_failed: 99 mlme_vdev_sm_destroy(vdev_mlme); 100 init_failed: 101 qdf_mem_free(vdev_mlme); 102 103 return QDF_STATUS_E_FAILURE; 104 } 105 106 #ifdef CMN_VDEV_MGR_TGT_IF_ENABLE 107 static void mlme_vdev_obj_timer_deinit( 108 struct vdev_mlme_obj *vdev_mlme) 109 { 110 struct vdev_response_timer *vdev_rsp; 111 112 vdev_rsp = &vdev_mlme->vdev_rt; 113 qdf_timer_free(&vdev_rsp->rsp_timer); 114 } 115 #else 116 static void mlme_vdev_obj_timer_deinit( 117 struct vdev_mlme_obj *vdev_mlme) 118 { 119 } 120 #endif 121 static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, 122 void *arg) 123 { 124 struct vdev_mlme_obj *vdev_mlme; 125 struct wlan_objmgr_psoc *psoc; 126 struct cdp_soc_t *soc_txrx_handle; 127 struct cdp_vdev *vdev_txrx_handle; 128 129 if (!vdev) { 130 mlme_err(" VDEV is NULL"); 131 return QDF_STATUS_E_FAILURE; 132 } 133 134 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 135 if (!vdev_mlme) { 136 mlme_info(" VDEV MLME component object is NULL"); 137 return QDF_STATUS_SUCCESS; 138 } 139 140 psoc = wlan_vdev_get_psoc(vdev); 141 soc_txrx_handle = (struct cdp_soc_t *)wlan_psoc_get_dp_handle(psoc); 142 vdev_txrx_handle = wlan_vdev_get_dp_handle(vdev); 143 if (soc_txrx_handle && vdev_txrx_handle) { 144 wlan_vdev_set_dp_handle(vdev, NULL); 145 cdp_vdev_detach(soc_txrx_handle, vdev_txrx_handle, 146 NULL, NULL); 147 } 148 149 mlme_vdev_obj_timer_deinit(vdev_mlme); 150 151 mlme_vdev_sm_destroy(vdev_mlme); 152 153 mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); 154 155 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 156 vdev_mlme); 157 qdf_mem_free(vdev_mlme); 158 159 return QDF_STATUS_SUCCESS; 160 } 161 162 static void mlme_scan_serialization_comp_info_cb( 163 struct wlan_objmgr_vdev *vdev, 164 union wlan_serialization_rules_info *comp_info) 165 { 166 struct wlan_objmgr_pdev *pdev; 167 QDF_STATUS status; 168 169 if (!comp_info || !vdev) { 170 mlme_err("comp_info or vdev is NULL"); 171 return; 172 } 173 174 pdev = wlan_vdev_get_pdev(vdev); 175 if (!pdev) { 176 mlme_err("pdev is NULL"); 177 return; 178 } 179 180 comp_info->scan_info.is_mlme_op_in_progress = false; 181 182 status = wlan_util_is_pdev_scan_allowed(pdev, WLAN_MLME_SER_IF_ID); 183 if (status != QDF_STATUS_SUCCESS) 184 comp_info->scan_info.is_mlme_op_in_progress = true; 185 } 186 187 QDF_STATUS wlan_mlme_psoc_enable(struct wlan_objmgr_psoc *psoc) 188 { 189 QDF_STATUS status; 190 struct wlan_lmac_if_mlme_tx_ops *tx_ops; 191 192 status = wlan_serialization_register_comp_info_cb 193 (psoc, 194 WLAN_UMAC_COMP_MLME, 195 WLAN_SER_CMD_SCAN, 196 mlme_scan_serialization_comp_info_cb); 197 if (status != QDF_STATUS_SUCCESS) { 198 mlme_err("Serialize scan cmd register failed"); 199 return status; 200 } 201 202 /* Register for WMI events into target_if rx */ 203 tx_ops = wlan_mlme_get_lmac_tx_ops(psoc); 204 if (tx_ops && tx_ops->vdev_mlme_attach) 205 tx_ops->vdev_mlme_attach(psoc); 206 207 return QDF_STATUS_SUCCESS; 208 } 209 210 QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc) 211 { 212 QDF_STATUS status; 213 struct wlan_lmac_if_mlme_tx_ops *tx_ops; 214 215 status = wlan_serialization_deregister_comp_info_cb 216 (psoc, 217 WLAN_UMAC_COMP_MLME, 218 WLAN_SER_CMD_SCAN); 219 if (status != QDF_STATUS_SUCCESS) { 220 mlme_err("Serialize scan cmd deregister failed"); 221 return status; 222 } 223 224 /* Unregister WMI events */ 225 tx_ops = wlan_mlme_get_lmac_tx_ops(psoc); 226 if (tx_ops && tx_ops->vdev_mlme_detach) 227 tx_ops->vdev_mlme_detach(psoc); 228 229 return QDF_STATUS_SUCCESS; 230 } 231 232 QDF_STATUS wlan_vdev_mlme_init(void) 233 { 234 if (wlan_objmgr_register_vdev_create_handler 235 (WLAN_UMAC_COMP_MLME, 236 mlme_vdev_obj_create_handler, NULL) 237 != QDF_STATUS_SUCCESS) 238 return QDF_STATUS_E_FAILURE; 239 240 if (wlan_objmgr_register_vdev_destroy_handler 241 (WLAN_UMAC_COMP_MLME, 242 mlme_vdev_obj_destroy_handler, NULL) 243 != QDF_STATUS_SUCCESS) { 244 if (wlan_objmgr_unregister_vdev_create_handler 245 (WLAN_UMAC_COMP_MLME, 246 mlme_vdev_obj_create_handler, NULL) 247 != QDF_STATUS_SUCCESS) 248 return QDF_STATUS_E_FAILURE; 249 250 return QDF_STATUS_E_FAILURE; 251 } 252 253 return QDF_STATUS_SUCCESS; 254 } 255 256 QDF_STATUS wlan_vdev_mlme_deinit(void) 257 { 258 if (wlan_objmgr_unregister_vdev_create_handler 259 (WLAN_UMAC_COMP_MLME, 260 mlme_vdev_obj_create_handler, NULL) 261 != QDF_STATUS_SUCCESS) 262 return QDF_STATUS_E_FAILURE; 263 264 if (wlan_objmgr_unregister_vdev_destroy_handler 265 (WLAN_UMAC_COMP_MLME, 266 mlme_vdev_obj_destroy_handler, NULL) 267 != QDF_STATUS_SUCCESS) 268 return QDF_STATUS_E_FAILURE; 269 270 return QDF_STATUS_SUCCESS; 271 } 272