1 /* 2 * Copyright (c) 2012-2015, 2020, 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 init/deinit specific apis of connection manager 19 */ 20 21 #include "wlan_cm_main.h" 22 #include "wlan_cm_sm.h" 23 #include "wlan_scan_api.h" 24 #include "wlan_cm_main_api.h" 25 26 #ifdef WLAN_CM_USE_SPINLOCK 27 /** 28 * cm_req_lock_create - Create CM req SM mutex/spinlock 29 * @cm_ctx: connection manager ctx 30 * 31 * Creates CM SM mutex/spinlock 32 * 33 * Return: void 34 */ 35 static inline void 36 cm_req_lock_create(struct cnx_mgr *cm_ctx) 37 { 38 qdf_spinlock_create(&cm_ctx->cm_req_lock); 39 } 40 41 /** 42 * cm_req_lock_destroy - Destroy CM SM mutex/spinlock 43 * @cm_ctx: connection manager ctx 44 * 45 * Destroy CM SM mutex/spinlock 46 * 47 * Return: void 48 */ 49 static inline void 50 cm_req_lock_destroy(struct cnx_mgr *cm_ctx) 51 { 52 qdf_spinlock_destroy(&cm_ctx->cm_req_lock); 53 } 54 #else 55 static inline void 56 cm_req_lock_create(struct cnx_mgr *cm_ctx) 57 { 58 qdf_mutex_create(&cm_ctx->cm_req_lock); 59 } 60 61 static inline void 62 cm_req_lock_destroy(struct cnx_mgr *cm_ctx) 63 { 64 qdf_mutex_destroy(&cm_ctx->cm_req_lock); 65 } 66 #endif /* WLAN_CM_USE_SPINLOCK */ 67 68 QDF_STATUS wlan_cm_init(struct vdev_mlme_obj *vdev_mlme) 69 { 70 struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; 71 enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev); 72 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); 73 QDF_STATUS status; 74 75 if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) 76 return QDF_STATUS_SUCCESS; 77 78 vdev_mlme->cnx_mgr_ctx = qdf_mem_malloc(sizeof(struct cnx_mgr)); 79 if (!vdev_mlme->cnx_mgr_ctx) 80 return QDF_STATUS_E_NOMEM; 81 82 vdev_mlme->cnx_mgr_ctx->vdev = vdev; 83 status = cm_sm_create(vdev_mlme->cnx_mgr_ctx); 84 if (QDF_IS_STATUS_ERROR(status)) { 85 qdf_mem_free(vdev_mlme->cnx_mgr_ctx); 86 vdev_mlme->cnx_mgr_ctx = NULL; 87 return QDF_STATUS_E_NOMEM; 88 } 89 vdev_mlme->cnx_mgr_ctx->max_connect_attempts = 90 CM_MAX_CONNECT_ATTEMPTS; 91 qdf_list_create(&vdev_mlme->cnx_mgr_ctx->req_list, CM_MAX_REQ); 92 cm_req_lock_create(vdev_mlme->cnx_mgr_ctx); 93 94 vdev_mlme->cnx_mgr_ctx->scan_requester_id = 95 wlan_scan_register_requester(psoc, 96 "CM", 97 wlan_cm_scan_cb, 98 vdev_mlme->cnx_mgr_ctx); 99 qdf_event_create(&vdev_mlme->cnx_mgr_ctx->disconnect_complete); 100 101 return QDF_STATUS_SUCCESS; 102 } 103 104 QDF_STATUS wlan_cm_deinit(struct vdev_mlme_obj *vdev_mlme) 105 { 106 struct wlan_objmgr_vdev *vdev = vdev_mlme->vdev; 107 enum QDF_OPMODE op_mode = wlan_vdev_mlme_get_opmode(vdev); 108 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); 109 wlan_scan_requester scan_requester_id; 110 111 if (op_mode != QDF_STA_MODE && op_mode != QDF_P2P_CLIENT_MODE) 112 return QDF_STATUS_SUCCESS; 113 114 qdf_event_destroy(&vdev_mlme->cnx_mgr_ctx->disconnect_complete); 115 scan_requester_id = vdev_mlme->cnx_mgr_ctx->scan_requester_id; 116 wlan_scan_unregister_requester(psoc, 117 scan_requester_id); 118 cm_req_lock_destroy(vdev_mlme->cnx_mgr_ctx); 119 qdf_list_destroy(&vdev_mlme->cnx_mgr_ctx->req_list); 120 cm_sm_destroy(vdev_mlme->cnx_mgr_ctx); 121 qdf_mem_free(vdev_mlme->cnx_mgr_ctx); 122 vdev_mlme->cnx_mgr_ctx = NULL; 123 124 return QDF_STATUS_SUCCESS; 125 } 126