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 34 static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, 35 void *arg) 36 { 37 struct vdev_mlme_obj *vdev_mlme; 38 struct wlan_objmgr_pdev *pdev; 39 struct pdev_mlme_obj *pdev_mlme; 40 41 if (!vdev) { 42 mlme_err(" VDEV is NULL"); 43 return QDF_STATUS_E_FAILURE; 44 } 45 46 pdev = wlan_vdev_get_pdev(vdev); 47 if (!pdev) { 48 mlme_err(" PDEV is NULL"); 49 return QDF_STATUS_E_FAILURE; 50 } 51 52 pdev_mlme = wlan_pdev_mlme_get_cmpt_obj(pdev); 53 if (!pdev_mlme) { 54 mlme_err(" PDEV MLME is NULL"); 55 return QDF_STATUS_E_FAILURE; 56 } 57 58 vdev_mlme = qdf_mem_malloc(sizeof(*vdev_mlme)); 59 if (!vdev_mlme) { 60 mlme_err(" MLME component object alloc failed"); 61 return QDF_STATUS_E_NOMEM; 62 } 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 if (mlme_vdev_ops_ext_hdl_post_create(vdev_mlme) != 88 QDF_STATUS_SUCCESS) { 89 mlme_err("Legacy vdev object post creation failed"); 90 goto ext_hdl_post_create_failed; 91 } 92 93 return QDF_STATUS_SUCCESS; 94 95 ext_hdl_post_create_failed: 96 mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); 97 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 98 vdev_mlme); 99 ext_hdl_create_failed: 100 mlme_vdev_sm_destroy(vdev_mlme); 101 init_failed: 102 qdf_mem_free(vdev_mlme); 103 104 return QDF_STATUS_E_FAILURE; 105 } 106 107 static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, 108 void *arg) 109 { 110 struct vdev_mlme_obj *vdev_mlme; 111 112 if (!vdev) { 113 mlme_err(" VDEV is NULL"); 114 return QDF_STATUS_E_FAILURE; 115 } 116 117 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 118 if (!vdev_mlme) { 119 mlme_info(" VDEV MLME component object is NULL"); 120 return QDF_STATUS_SUCCESS; 121 } 122 123 mlme_vdev_sm_destroy(vdev_mlme); 124 125 mlme_vdev_ops_ext_hdl_destroy(vdev_mlme); 126 127 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 128 vdev_mlme); 129 qdf_mem_free(vdev_mlme); 130 131 return QDF_STATUS_SUCCESS; 132 } 133 134 static void mlme_scan_serialization_comp_info_cb( 135 struct wlan_objmgr_vdev *vdev, 136 union wlan_serialization_rules_info *comp_info) 137 { 138 struct wlan_objmgr_pdev *pdev; 139 QDF_STATUS status; 140 141 if (!comp_info || !vdev) { 142 mlme_err("comp_info or vdev is NULL"); 143 return; 144 } 145 146 pdev = wlan_vdev_get_pdev(vdev); 147 if (!pdev) { 148 mlme_err("pdev is NULL"); 149 return; 150 } 151 152 comp_info->scan_info.is_mlme_op_in_progress = false; 153 154 status = wlan_util_is_pdev_scan_allowed(pdev, WLAN_MLME_SER_IF_ID); 155 if (status != QDF_STATUS_SUCCESS) 156 comp_info->scan_info.is_mlme_op_in_progress = true; 157 } 158 159 QDF_STATUS wlan_mlme_psoc_enable(struct wlan_objmgr_psoc *psoc) 160 { 161 QDF_STATUS status; 162 struct wlan_lmac_if_mlme_tx_ops *tx_ops; 163 164 status = wlan_serialization_register_comp_info_cb 165 (psoc, 166 WLAN_UMAC_COMP_MLME, 167 WLAN_SER_CMD_SCAN, 168 mlme_scan_serialization_comp_info_cb); 169 if (status != QDF_STATUS_SUCCESS) { 170 mlme_err("Serialize scan cmd register failed"); 171 return status; 172 } 173 174 /* Register for WMI events into target_if rx */ 175 tx_ops = wlan_mlme_get_lmac_tx_ops(psoc); 176 if (tx_ops && tx_ops->vdev_mlme_attach) 177 tx_ops->vdev_mlme_attach(psoc); 178 179 return QDF_STATUS_SUCCESS; 180 } 181 182 QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc) 183 { 184 QDF_STATUS status; 185 struct wlan_lmac_if_mlme_tx_ops *tx_ops; 186 187 status = wlan_serialization_deregister_comp_info_cb 188 (psoc, 189 WLAN_UMAC_COMP_MLME, 190 WLAN_SER_CMD_SCAN); 191 if (status != QDF_STATUS_SUCCESS) { 192 mlme_err("Serialize scan cmd deregister failed"); 193 return status; 194 } 195 196 /* Unregister WMI events */ 197 tx_ops = wlan_mlme_get_lmac_tx_ops(psoc); 198 if (tx_ops && tx_ops->vdev_mlme_detach) 199 tx_ops->vdev_mlme_detach(psoc); 200 201 return QDF_STATUS_SUCCESS; 202 } 203 204 QDF_STATUS wlan_vdev_mlme_init(void) 205 { 206 if (wlan_objmgr_register_vdev_create_handler 207 (WLAN_UMAC_COMP_MLME, 208 mlme_vdev_obj_create_handler, NULL) 209 != QDF_STATUS_SUCCESS) 210 return QDF_STATUS_E_FAILURE; 211 212 if (wlan_objmgr_register_vdev_destroy_handler 213 (WLAN_UMAC_COMP_MLME, 214 mlme_vdev_obj_destroy_handler, NULL) 215 != QDF_STATUS_SUCCESS) { 216 if (wlan_objmgr_unregister_vdev_create_handler 217 (WLAN_UMAC_COMP_MLME, 218 mlme_vdev_obj_create_handler, NULL) 219 != QDF_STATUS_SUCCESS) 220 return QDF_STATUS_E_FAILURE; 221 222 return QDF_STATUS_E_FAILURE; 223 } 224 225 return QDF_STATUS_SUCCESS; 226 } 227 228 QDF_STATUS wlan_vdev_mlme_deinit(void) 229 { 230 if (wlan_objmgr_unregister_vdev_create_handler 231 (WLAN_UMAC_COMP_MLME, 232 mlme_vdev_obj_create_handler, NULL) 233 != QDF_STATUS_SUCCESS) 234 return QDF_STATUS_E_FAILURE; 235 236 if (wlan_objmgr_unregister_vdev_destroy_handler 237 (WLAN_UMAC_COMP_MLME, 238 mlme_vdev_obj_destroy_handler, NULL) 239 != QDF_STATUS_SUCCESS) 240 return QDF_STATUS_E_FAILURE; 241 242 return QDF_STATUS_SUCCESS; 243 } 244