1 /* 2 * Copyright (c) 2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * DOC: Implements MLME component object creation/initialization/destroy 21 */ 22 23 #include <wlan_objmgr_cmn.h> 24 #include <wlan_objmgr_global_obj.h> 25 #include <wlan_objmgr_vdev_obj.h> 26 #include <wlan_mlme_dbg.h> 27 #include "include/wlan_vdev_mlme.h" 28 #include "vdev_mgr/core/src/vdev_mlme_sm.h" 29 30 static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, 31 void *arg) 32 { 33 struct vdev_mlme_obj *vdev_mlme; 34 struct wlan_objmgr_pdev *pdev; 35 36 if (!vdev) { 37 mlme_err(" VDEV is NULL"); 38 return QDF_STATUS_E_FAILURE; 39 } 40 41 pdev = wlan_vdev_get_pdev(vdev); 42 if (!pdev) { 43 mlme_err(" PDEV is NULL"); 44 return QDF_STATUS_E_FAILURE; 45 } 46 47 vdev_mlme = qdf_mem_malloc(sizeof(*vdev_mlme)); 48 if (!vdev_mlme) { 49 mlme_err(" MLME component object alloc failed"); 50 return QDF_STATUS_E_NOMEM; 51 } 52 53 vdev_mlme->vdev = vdev; 54 55 if (pdev->pdev_mlme.mlme_register_ops(vdev_mlme) 56 != QDF_STATUS_SUCCESS) { 57 mlme_err("Callbacks registration is failed"); 58 goto init_failed; 59 } 60 61 if (mlme_vdev_sm_create(vdev_mlme) != QDF_STATUS_SUCCESS) { 62 mlme_err("SME creation failed"); 63 goto init_failed; 64 } 65 66 if (mlme_vdev_ext_hdl_create(vdev_mlme) != QDF_STATUS_SUCCESS) { 67 mlme_err("Legacy vdev object creation failed"); 68 goto ext_hdl_create_failed; 69 } 70 71 wlan_objmgr_vdev_component_obj_attach((struct wlan_objmgr_vdev *)vdev, 72 WLAN_UMAC_COMP_MLME, 73 (void *)vdev_mlme, 74 QDF_STATUS_SUCCESS); 75 76 if (mlme_vdev_ext_hdl_post_create(vdev_mlme) != QDF_STATUS_SUCCESS) { 77 mlme_err("Legacy vdev object post creation failed"); 78 goto ext_hdl_post_create_failed; 79 } 80 81 return QDF_STATUS_SUCCESS; 82 83 ext_hdl_post_create_failed: 84 mlme_vdev_ext_hdl_destroy(vdev_mlme); 85 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 86 vdev_mlme); 87 ext_hdl_create_failed: 88 mlme_vdev_sm_destroy(vdev_mlme); 89 init_failed: 90 qdf_mem_free(vdev_mlme); 91 92 return QDF_STATUS_E_FAILURE; 93 } 94 95 static QDF_STATUS mlme_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, 96 void *arg) 97 { 98 struct vdev_mlme_obj *vdev_mlme; 99 100 if (!vdev) { 101 mlme_err(" VDEV is NULL"); 102 return QDF_STATUS_E_FAILURE; 103 } 104 105 vdev_mlme = wlan_objmgr_vdev_get_comp_private_obj(vdev, 106 WLAN_UMAC_COMP_MLME); 107 if (!vdev_mlme) { 108 mlme_err(" VDEV MLME component object is NULL"); 109 return QDF_STATUS_E_FAILURE; 110 } 111 112 mlme_vdev_sm_destroy(vdev_mlme); 113 114 mlme_vdev_ext_hdl_destroy(vdev_mlme); 115 116 wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_MLME, 117 vdev_mlme); 118 qdf_mem_free(vdev_mlme); 119 120 return QDF_STATUS_SUCCESS; 121 } 122 123 QDF_STATUS wlan_vdev_mlme_init(void) 124 { 125 if (wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_MLME, 126 mlme_vdev_obj_create_handler, NULL) 127 != QDF_STATUS_SUCCESS) 128 return QDF_STATUS_E_FAILURE; 129 130 if (wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_MLME, 131 mlme_vdev_obj_destroy_handler, NULL) 132 != QDF_STATUS_SUCCESS) { 133 if (wlan_objmgr_unregister_vdev_create_handler( 134 WLAN_UMAC_COMP_MLME, 135 mlme_vdev_obj_create_handler, NULL) 136 != QDF_STATUS_SUCCESS) 137 return QDF_STATUS_E_FAILURE; 138 139 return QDF_STATUS_E_FAILURE; 140 } 141 142 return QDF_STATUS_SUCCESS; 143 } 144 145 QDF_STATUS wlan_vdev_mlme_deinit(void) 146 { 147 if (wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_MLME, 148 mlme_vdev_obj_create_handler, NULL) 149 != QDF_STATUS_SUCCESS) 150 return QDF_STATUS_E_FAILURE; 151 152 if (wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_MLME, 153 mlme_vdev_obj_destroy_handler, NULL) 154 != QDF_STATUS_SUCCESS) 155 return QDF_STATUS_E_FAILURE; 156 157 return QDF_STATUS_SUCCESS; 158 } 159