1 /*
2  * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  *
22  * mac_init_api.c - This file has all the mac level init functions
23  *                   for all the defined threads at system level.
24  * Author:    Dinesh Upadhyay
25  * Date:      04/23/2007
26  * History:-
27  * Date: 04/08/2008       Modified by: Santosh Mandiganal
28  * Modification Information: Code to allocate and free the  memory for DumpTable entry.
29  * --------------------------------------------------------------------------
30  *
31  */
32 /* Standard include files */
33 #include "lim_api.h"             /* lim_cleanup */
34 #include "sir_types.h"
35 #include "sys_entry_func.h"
36 #include "mac_init_api.h"
37 #include "wlan_mlme_main.h"
38 #include "wlan_psoc_mlme_api.h"
39 
40 #ifdef TRACE_RECORD
41 #include "mac_trace.h"
42 #endif
43 
44 #ifdef WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY
45 static struct mac_context *global_mac_context;
46 
mac_allocate_context_buffer(void)47 static inline struct mac_context *mac_allocate_context_buffer(void)
48 {
49 	global_mac_context = qdf_mem_malloc(sizeof(*global_mac_context));
50 
51 	return global_mac_context;
52 }
53 
mac_free_context_buffer(void)54 static inline void mac_free_context_buffer(void)
55 {
56 	qdf_mem_free(global_mac_context);
57 	global_mac_context = NULL;
58 }
59 #else /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
60 static struct mac_context global_mac_context;
61 
mac_allocate_context_buffer(void)62 static inline struct mac_context *mac_allocate_context_buffer(void)
63 {
64 	return &global_mac_context;
65 }
66 
mac_free_context_buffer(void)67 static inline void mac_free_context_buffer(void)
68 {
69 }
70 #endif /* WLAN_ALLOCATE_GLOBAL_BUFFERS_DYNAMICALLY */
71 
mac_start(mac_handle_t mac_handle,struct mac_start_params * params)72 QDF_STATUS mac_start(mac_handle_t mac_handle,
73 		     struct mac_start_params *params)
74 {
75 	QDF_STATUS status = QDF_STATUS_SUCCESS;
76 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
77 
78 	if (!mac || !params) {
79 		QDF_ASSERT(0);
80 		status = QDF_STATUS_E_FAILURE;
81 		return status;
82 	}
83 
84 	mac->gDriverType = params->driver_type;
85 
86 	if (ANI_DRIVER_TYPE(mac) != QDF_DRIVER_TYPE_MFG)
87 		status = pe_start(mac);
88 
89 	return status;
90 }
91 
mac_stop(mac_handle_t mac_handle)92 QDF_STATUS mac_stop(mac_handle_t mac_handle)
93 {
94 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
95 
96 	pe_stop(mac);
97 
98 	return QDF_STATUS_SUCCESS;
99 }
100 
mac_open(struct wlan_objmgr_psoc * psoc,mac_handle_t * mac_handle,hdd_handle_t hdd_handle,struct cds_config_info * cds_cfg)101 QDF_STATUS mac_open(struct wlan_objmgr_psoc *psoc, mac_handle_t *mac_handle,
102 		    hdd_handle_t hdd_handle, struct cds_config_info *cds_cfg)
103 {
104 	struct mac_context *mac;
105 	QDF_STATUS status;
106 	struct wlan_mlme_psoc_ext_obj *mlme_ext_obj;
107 
108 	QDF_BUG(mac_handle);
109 	if (!mac_handle)
110 		return QDF_STATUS_E_FAILURE;
111 
112 	mac = mac_allocate_context_buffer();
113 	if (!mac)
114 		return QDF_STATUS_E_NOMEM;
115 
116 	/*
117 	 * Set various global fields of mac here
118 	 * (Could be platform dependent as some variables in mac are platform
119 	 * dependent)
120 	 */
121 	mac->hdd_handle = hdd_handle;
122 
123 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_LEGACY_MAC_ID);
124 	if (QDF_IS_STATUS_ERROR(status)) {
125 		pe_err("PSOC get ref failure");
126 		goto free_mac_context;
127 	}
128 
129 	mac->psoc = psoc;
130 	mlme_ext_obj = wlan_psoc_mlme_get_ext_hdl(psoc);
131 	if (!mlme_ext_obj) {
132 		pe_err("Failed to get MLME Obj");
133 		status = QDF_STATUS_E_FAILURE;
134 		goto release_psoc_ref;
135 	}
136 	mac->mlme_cfg = &mlme_ext_obj->cfg;
137 
138 	*mac_handle = MAC_HANDLE(mac);
139 
140 	/* For Non-FTM cases this value will be reset during mac_start */
141 	if (cds_cfg->driver_type)
142 		mac->gDriverType = QDF_DRIVER_TYPE_MFG;
143 
144 	sys_init_globals(mac);
145 
146 	/* FW: 0 to 2047 and Host: 2048 to 4095 */
147 	mac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
148 	mac->he_sgi_ltf_cfg_bit_mask = DEF_HE_AUTO_SGI_LTF;
149 	mac->is_usr_cfg_amsdu_enabled = true;
150 
151 	status = pe_open(mac, cds_cfg);
152 	if (QDF_IS_STATUS_ERROR(status)) {
153 		QDF_DEBUG_PANIC("failed to open PE; status: %u", status);
154 		goto release_psoc_ref;
155 	}
156 
157 	return QDF_STATUS_SUCCESS;
158 
159 release_psoc_ref:
160 	wlan_objmgr_psoc_release_ref(psoc, WLAN_LEGACY_MAC_ID);
161 
162 free_mac_context:
163 	mac_free_context_buffer();
164 
165 	return status;
166 }
167 
mac_close(mac_handle_t mac_handle)168 QDF_STATUS mac_close(mac_handle_t mac_handle)
169 {
170 
171 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
172 
173 	if (!mac)
174 		return QDF_STATUS_E_FAILURE;
175 
176 	pe_close(mac);
177 
178 	if (mac->pdev) {
179 		wlan_objmgr_pdev_release_ref(mac->pdev, WLAN_LEGACY_MAC_ID);
180 		mac->pdev = NULL;
181 	}
182 	wlan_objmgr_psoc_release_ref(mac->psoc, WLAN_LEGACY_MAC_ID);
183 	mac->mlme_cfg = NULL;
184 	mac->psoc = NULL;
185 	qdf_mem_zero(mac, sizeof(*mac));
186 	mac_free_context_buffer();
187 
188 	return QDF_STATUS_SUCCESS;
189 }
190 
mac_register_session_open_close_cb(mac_handle_t mac_handle,csr_session_close_cb close_session,csr_roam_complete_cb callback)191 void mac_register_session_open_close_cb(mac_handle_t mac_handle,
192 					csr_session_close_cb close_session,
193 					csr_roam_complete_cb callback)
194 {
195 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
196 
197 	mac->session_close_cb = close_session;
198 	mac->session_roam_complete_cb = callback;
199 }
200 
201 #ifdef WLAN_BCN_RECV_FEATURE
mac_register_bcn_report_send_cb(struct mac_context * mac,beacon_report_cb cb)202 void mac_register_bcn_report_send_cb(struct mac_context *mac,
203 				     beacon_report_cb cb)
204 {
205 	if (!mac) {
206 		pe_err("Invalid MAC");
207 		return;
208 	}
209 
210 	mac->lim.sme_bcn_rcv_callback = cb;
211 }
212 #endif
213 
214