1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 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  * DOC:  wlan_hdd_hostapd.c
22  *
23  * WLAN Host Device Driver implementation
24  */
25 
26 /* Include Files */
27 
28 #include <linux/version.h>
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/init.h>
32 #include <linux/wireless.h>
33 #include <linux/semaphore.h>
34 #include <linux/compat.h>
35 #include <cdp_txrx_cmn.h>
36 #include <cds_api.h>
37 #include <cds_sched.h>
38 #include <linux/etherdevice.h>
39 #include "osif_sync.h"
40 #include <linux/ethtool.h>
41 #include <wlan_hdd_includes.h>
42 #include <qc_sap_ioctl.h>
43 #include "osif_sync.h"
44 #include <wlan_hdd_hostapd.h>
45 #include <wlan_hdd_hostapd_wext.h>
46 #include <wlan_hdd_green_ap.h>
47 #include <sap_api.h>
48 #include <sap_internal.h>
49 #include <wlan_hdd_softap_tx_rx.h>
50 #include <wlan_hdd_main.h>
51 #include <wlan_hdd_ioctl.h>
52 #include <wlan_hdd_stats.h>
53 #include <linux/netdevice.h>
54 #include <linux/rtnetlink.h>
55 #include <linux/mmc/sdio_func.h>
56 #include "wlan_hdd_p2p.h"
57 #include <wlan_hdd_ipa.h>
58 #include "wni_cfg.h"
59 #include "wlan_hdd_misc.h"
60 #include <cds_utils.h>
61 #include "pld_common.h"
62 #include "wma.h"
63 #ifdef WLAN_DEBUG
64 #include "wma_api.h"
65 #endif
66 #include "wlan_hdd_trace.h"
67 #include "qdf_str.h"
68 #include "qdf_types.h"
69 #include "qdf_trace.h"
70 #include "qdf_net_if.h"
71 #include "wlan_hdd_cfg.h"
72 #include "wlan_policy_mgr_api.h"
73 #include "wlan_hdd_tsf.h"
74 #include <cdp_txrx_misc.h>
75 #include <cdp_txrx_ctrl.h>
76 #include "wlan_hdd_object_manager.h"
77 #include <qca_vendor.h>
78 #include <cds_api.h>
79 #include "wlan_hdd_he.h"
80 #include "wlan_hdd_eht.h"
81 #include "wlan_dfs_tgt_api.h"
82 #include <wlan_reg_ucfg_api.h>
83 #include "wlan_utility.h"
84 #include <wlan_p2p_ucfg_api.h>
85 #include "sir_api.h"
86 #include "wlan_policy_mgr_ucfg.h"
87 #include "sme_api.h"
88 #include "wlan_hdd_regulatory.h"
89 #include <wlan_ipa_ucfg_api.h>
90 #include <wlan_cp_stats_mc_ucfg_api.h>
91 #include "wlan_mlme_ucfg_api.h"
92 #include "cfg_ucfg_api.h"
93 #include "wlan_crypto_global_api.h"
94 #include "wlan_action_oui_ucfg_api.h"
95 #include "wlan_fwol_ucfg_api.h"
96 #include "nan_ucfg_api.h"
97 #include <wlan_reg_services_api.h>
98 #include "wlan_hdd_sta_info.h"
99 #include "ftm_time_sync_ucfg_api.h"
100 #include <wlan_hdd_dcs.h>
101 #include "wlan_tdls_ucfg_api.h"
102 #include "wlan_mlme_twt_ucfg_api.h"
103 #include "wlan_if_mgr_ucfg_api.h"
104 #include "wlan_if_mgr_public_struct.h"
105 #include "wlan_hdd_bootup_marker.h"
106 #include "wlan_hdd_medium_assess.h"
107 #include "wlan_hdd_scan.h"
108 #ifdef WLAN_FEATURE_11BE_MLO
109 #include <wlan_mlo_mgr_ap.h>
110 #endif
111 #include "spatial_reuse_ucfg_api.h"
112 #include "wlan_hdd_son.h"
113 #include "wlan_hdd_mcc_quota.h"
114 #include "wlan_hdd_wds.h"
115 #include "wlan_hdd_pre_cac.h"
116 #include "wlan_osif_features.h"
117 #include "wlan_pre_cac_ucfg_api.h"
118 #include <wlan_dp_ucfg_api.h>
119 #include "wlan_twt_ucfg_ext_cfg.h"
120 #include "wlan_twt_ucfg_ext_api.h"
121 #include "wlan_twt_ucfg_api.h"
122 #include "wlan_vdev_mgr_ucfg_api.h"
123 #include <wlan_psoc_mlme_ucfg_api.h>
124 #include "wlan_ll_sap_api.h"
125 
126 #define ACS_SCAN_EXPIRY_TIMEOUT_S 4
127 
128 /*
129  * Defines the BIT position of 11bg/11abg/11abgn 802.11 support mode field
130  * of stainfo
131  */
132 #define HDD_80211_MODE_ABGN 0
133 /* Defines the BIT position of 11ac support mode field of stainfo */
134 #define HDD_80211_MODE_AC 1
135 /* Defines the BIT position of 11ax support mode field of stainfo */
136 #define HDD_80211_MODE_AX 2
137 /* Defines the BIT position of 11be support mode field of stainfo */
138 #define HDD_80211_MODE_BE 4
139 
140 #define HDD_MAX_CUSTOM_START_EVENT_SIZE 64
141 
142 #ifdef NDP_SAP_CONCURRENCY_ENABLE
143 #define MAX_SAP_NUM_CONCURRENCY_WITH_NAN 2
144 #else
145 #define MAX_SAP_NUM_CONCURRENCY_WITH_NAN 1
146 #endif
147 #include "../../core/src/reg_priv_objs.h"
148 
149 #ifndef BSS_MEMBERSHIP_SELECTOR_HT_PHY
150 #define BSS_MEMBERSHIP_SELECTOR_HT_PHY  127
151 #endif
152 
153 #ifndef BSS_MEMBERSHIP_SELECTOR_VHT_PHY
154 #define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126
155 #endif
156 
157 #ifndef BSS_MEMBERSHIP_SELECTOR_SAE_H2E
158 #define BSS_MEMBERSHIP_SELECTOR_SAE_H2E 123
159 #endif
160 
161 #ifndef BSS_MEMBERSHIP_SELECTOR_HE_PHY
162 #define BSS_MEMBERSHIP_SELECTOR_HE_PHY  122
163 #endif
164 
165 /*
166  * 11B, 11G Rate table include Basic rate and Extended rate
167  * The IDX field is the rate index
168  * The HI field is the rate when RSSI is strong or being ignored
169  * (in this case we report actual rate)
170  * The MID field is the rate when RSSI is moderate
171  * (in this case we cap 11b rates at 5.5 and 11g rates at 24)
172  * The LO field is the rate when RSSI is low
173  * (in this case we don't report rates, actual current rate used)
174  */
175 static const struct index_data_rate_type supported_data_rate[] = {
176 	/* IDX     HI  HM  LM LO (RSSI-based index */
177 	{2,   { 10,  10, 10, 0} },
178 	{4,   { 20,  20, 10, 0} },
179 	{11,  { 55,  20, 10, 0} },
180 	{12,  { 60,  55, 20, 0} },
181 	{18,  { 90,  55, 20, 0} },
182 	{22,  {110,  55, 20, 0} },
183 	{24,  {120,  90, 60, 0} },
184 	{36,  {180, 120, 60, 0} },
185 	{44,  {220, 180, 60, 0} },
186 	{48,  {240, 180, 90, 0} },
187 	{66,  {330, 180, 90, 0} },
188 	{72,  {360, 240, 90, 0} },
189 	{96,  {480, 240, 120, 0} },
190 	{108, {540, 240, 120, 0} }
191 };
192 
193 /* MCS Based rate table */
194 /* HT MCS parameters with Nss = 1 */
195 static const struct index_data_rate_type supported_mcs_rate_nss1[] = {
196 	/* MCS  L20   L40   S20  S40 */
197 	{0,  { 65,  135,  72,  150} },
198 	{1,  { 130, 270,  144, 300} },
199 	{2,  { 195, 405,  217, 450} },
200 	{3,  { 260, 540,  289, 600} },
201 	{4,  { 390, 810,  433, 900} },
202 	{5,  { 520, 1080, 578, 1200} },
203 	{6,  { 585, 1215, 650, 1350} },
204 	{7,  { 650, 1350, 722, 1500} }
205 };
206 
207 /* HT MCS parameters with Nss = 2 */
208 static const struct index_data_rate_type supported_mcs_rate_nss2[] = {
209 	/* MCS  L20    L40   S20   S40 */
210 	{0,  {130,  270,  144,  300} },
211 	{1,  {260,  540,  289,  600} },
212 	{2,  {390,  810,  433,  900} },
213 	{3,  {520,  1080, 578,  1200} },
214 	{4,  {780,  1620, 867,  1800} },
215 	{5,  {1040, 2160, 1156, 2400} },
216 	{6,  {1170, 2430, 1300, 2700} },
217 	{7,  {1300, 2700, 1444, 3000} }
218 };
219 
220 /* MCS Based VHT rate table */
221 /* MCS parameters with Nss = 1*/
222 static const struct index_vht_data_rate_type supported_vht_mcs_rate_nss1[] = {
223 	/* MCS  L80    S80     L40   S40    L20   S40*/
224 	{0,  {293,  325},  {135,  150},  {65,   72} },
225 	{1,  {585,  650},  {270,  300},  {130,  144} },
226 	{2,  {878,  975},  {405,  450},  {195,  217} },
227 	{3,  {1170, 1300}, {540,  600},  {260,  289} },
228 	{4,  {1755, 1950}, {810,  900},  {390,  433} },
229 	{5,  {2340, 2600}, {1080, 1200}, {520,  578} },
230 	{6,  {2633, 2925}, {1215, 1350}, {585,  650} },
231 	{7,  {2925, 3250}, {1350, 1500}, {650,  722} },
232 	{8,  {3510, 3900}, {1620, 1800}, {780,  867} },
233 	{9,  {3900, 4333}, {1800, 2000}, {780,  867} },
234 	{10, {4388, 4875}, {2025, 2250}, {975, 1083} },
235 	{11, {4875, 5417}, {2250, 2500}, {1083, 1203} }
236 };
237 
238 /*MCS parameters with Nss = 2*/
239 static const struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = {
240 	/* MCS  L80    S80     L40   S40    L20   S40*/
241 	{0,  {585,  650},  {270,  300},  {130,  144} },
242 	{1,  {1170, 1300}, {540,  600},  {260,  289} },
243 	{2,  {1755, 1950}, {810,  900},  {390,  433} },
244 	{3,  {2340, 2600}, {1080, 1200}, {520,  578} },
245 	{4,  {3510, 3900}, {1620, 1800}, {780,  867} },
246 	{5,  {4680, 5200}, {2160, 2400}, {1040, 1156} },
247 	{6,  {5265, 5850}, {2430, 2700}, {1170, 1300} },
248 	{7,  {5850, 6500}, {2700, 3000}, {1300, 1444} },
249 	{8,  {7020, 7800}, {3240, 3600}, {1560, 1733} },
250 	{9,  {7800, 8667}, {3600, 4000}, {1730, 1920} },
251 	{10, {8775, 9750}, {4050, 4500}, {1950, 2167} },
252 	{11, {9750, 10833}, {4500, 5000}, {2167, 2407} }
253 };
254 
255 /* Function definitions */
256 
257 /**
258  * hdd_sap_context_init() - Initialize SAP context.
259  * @hdd_ctx:	HDD context.
260  *
261  * Initialize SAP context.
262  *
263  * Return: 0 on success.
264  */
hdd_sap_context_init(struct hdd_context * hdd_ctx)265 int hdd_sap_context_init(struct hdd_context *hdd_ctx)
266 {
267 	qdf_wake_lock_create(&hdd_ctx->sap_dfs_wakelock, "sap_dfs_wakelock");
268 	atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0);
269 
270 	mutex_init(&hdd_ctx->sap_lock);
271 	qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock");
272 
273 	return 0;
274 }
275 
276 /**
277  * hdd_hostapd_init_sap_session() - To init the sap session completely
278  * @adapter: SAP/GO adapter
279  * @reinit: if called as part of reinit
280  *
281  * This API will do
282  * 1) sap_init_ctx()
283  *
284  * Return: 0 if success else non-zero value.
285  */
286 static struct sap_context *
hdd_hostapd_init_sap_session(struct hdd_adapter * adapter,bool reinit)287 hdd_hostapd_init_sap_session(struct hdd_adapter *adapter, bool reinit)
288 {
289 	struct sap_context *sap_ctx;
290 	QDF_STATUS status;
291 
292 	if (!adapter) {
293 		hdd_err("invalid adapter");
294 		return NULL;
295 	}
296 
297 	sap_ctx = adapter->deflink->session.ap.sap_context;
298 
299 	if (!sap_ctx) {
300 		hdd_err("can't allocate the sap_ctx");
301 		return NULL;
302 	}
303 	status = sap_init_ctx(sap_ctx, adapter->device_mode,
304 			       adapter->mac_addr.bytes,
305 			       adapter->deflink->vdev_id, reinit);
306 	if (QDF_IS_STATUS_ERROR(status)) {
307 		hdd_err("wlansap_start failed!! status: %d", status);
308 		adapter->deflink->session.ap.sap_context = NULL;
309 		goto error;
310 	}
311 	return sap_ctx;
312 error:
313 	wlansap_context_put(sap_ctx);
314 	hdd_err("releasing the sap context for session-id:%d",
315 		adapter->deflink->vdev_id);
316 
317 	return NULL;
318 }
319 
320 /**
321  * hdd_hostapd_deinit_sap_session() - To de-init the sap session completely
322  * @link_info: Pointer of link_info in adapter
323  *
324  * This API will do
325  * 1) sap_init_ctx()
326  * 2) sap_destroy_ctx()
327  *
328  * Return: 0 if success else non-zero value.
329  */
330 static int
hdd_hostapd_deinit_sap_session(struct wlan_hdd_link_info * link_info)331 hdd_hostapd_deinit_sap_session(struct wlan_hdd_link_info *link_info)
332 {
333 	struct sap_context *sap_ctx;
334 	int status = 0;
335 
336 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
337 	if (!sap_ctx) {
338 		hdd_debug("sap context already released, nothing to be done");
339 		return 0;
340 	}
341 
342 	wlan_hdd_undo_acs(link_info);
343 	if (!QDF_IS_STATUS_SUCCESS(sap_deinit_ctx(sap_ctx))) {
344 		hdd_err("Error stopping the sap session");
345 		status = -EINVAL;
346 	}
347 
348 	if (!hdd_sap_destroy_ctx(link_info)) {
349 		hdd_err("Error closing the sap session");
350 		status = -EINVAL;
351 	}
352 
353 	if (!QDF_IS_STATUS_SUCCESS(status))
354 		hdd_debug("sap has issue closing the session");
355 	else
356 		hdd_debug("sap has been closed successfully");
357 
358 
359 	return status;
360 }
361 
362 /**
363  * hdd_hostapd_channel_allow_suspend() - allow suspend in a channel.
364  * Called when, 1. bss stopped, 2. channel switch
365  *
366  * @adapter: pointer to hdd adapter
367  * @chan_freq: channel frequency
368  * @ch_params: channel params
369  *
370  * Return: None
371  */
hdd_hostapd_channel_allow_suspend(struct hdd_adapter * adapter,uint32_t chan_freq,struct ch_params * ch_params)372 static void hdd_hostapd_channel_allow_suspend(struct hdd_adapter *adapter,
373 					      uint32_t chan_freq,
374 					      struct ch_params *ch_params)
375 {
376 
377 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
378 	struct hdd_hostapd_state *hostapd_state =
379 		WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter->deflink);
380 	struct sap_context *sap_ctx;
381 	bool is_dfs;
382 
383 	hdd_debug("bss_state: %d, chan_freq: %d, dfs_ref_cnt: %d",
384 		  hostapd_state->bss_state, chan_freq,
385 		  atomic_read(&hdd_ctx->sap_dfs_ref_cnt));
386 
387 	/* Return if BSS is already stopped */
388 	if (hostapd_state->bss_state == BSS_STOP)
389 		return;
390 
391 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink);
392 	if (!sap_ctx) {
393 		hdd_err("sap ctx null");
394 		return;
395 	}
396 
397 	is_dfs = wlan_mlme_check_chan_param_has_dfs(hdd_ctx->pdev,
398 						    ch_params,
399 						    chan_freq);
400 	if (!is_dfs)
401 		return;
402 
403 	/* Release wakelock when no more DFS channels are used */
404 	if (atomic_dec_and_test(&hdd_ctx->sap_dfs_ref_cnt)) {
405 		hdd_err("DFS: allowing suspend (chan_freq: %d)", chan_freq);
406 		qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock,
407 				      WIFI_POWER_EVENT_WAKELOCK_DFS);
408 		qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.dfs);
409 
410 	}
411 }
412 
413 /**
414  * hdd_hostapd_channel_prevent_suspend() - prevent suspend in a channel.
415  * Called when, 1. bss started, 2. channel switch
416  *
417  * @adapter: pointer to hdd adapter
418  * @chan_freq: channel frequency
419  * @ch_params: channel params
420  *
421  * Return - None
422  */
hdd_hostapd_channel_prevent_suspend(struct hdd_adapter * adapter,uint32_t chan_freq,struct ch_params * ch_params)423 static void hdd_hostapd_channel_prevent_suspend(struct hdd_adapter *adapter,
424 						uint32_t chan_freq,
425 						struct ch_params *ch_params)
426 {
427 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
428 	struct hdd_hostapd_state *hostapd_state =
429 		WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter->deflink);
430 	struct sap_context *sap_ctx;
431 	bool is_dfs;
432 
433 	hdd_debug("bss_state: %d, chan_freq: %d, dfs_ref_cnt: %d",
434 		  hostapd_state->bss_state, chan_freq,
435 		  atomic_read(&hdd_ctx->sap_dfs_ref_cnt));
436 	/* Return if BSS is already started && wakelock is acquired */
437 	if ((hostapd_state->bss_state == BSS_START) &&
438 		(atomic_read(&hdd_ctx->sap_dfs_ref_cnt) >= 1))
439 		return;
440 
441 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink);
442 	if (!sap_ctx) {
443 		hdd_err("sap ctx null");
444 		return;
445 	}
446 
447 	is_dfs = wlan_mlme_check_chan_param_has_dfs(hdd_ctx->pdev,
448 						    &sap_ctx->ch_params,
449 						    chan_freq);
450 	if (!is_dfs)
451 		return;
452 
453 	/* Acquire wakelock if we have at least one DFS channel in use */
454 	if (atomic_inc_return(&hdd_ctx->sap_dfs_ref_cnt) == 1) {
455 		hdd_err("DFS: preventing suspend (chan_freq: %d)", chan_freq);
456 		qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.dfs);
457 		qdf_wake_lock_acquire(&hdd_ctx->sap_dfs_wakelock,
458 				      WIFI_POWER_EVENT_WAKELOCK_DFS);
459 	}
460 }
461 
462 /**
463  * hdd_sap_context_destroy() - Destroy SAP context
464  *
465  * @hdd_ctx:	HDD context.
466  *
467  * Destroy SAP context.
468  *
469  * Return: None
470  */
hdd_sap_context_destroy(struct hdd_context * hdd_ctx)471 void hdd_sap_context_destroy(struct hdd_context *hdd_ctx)
472 {
473 	if (atomic_read(&hdd_ctx->sap_dfs_ref_cnt)) {
474 		qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock,
475 				      WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT);
476 
477 		atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0);
478 		hdd_debug("DFS: Allowing suspend");
479 	}
480 
481 	qdf_wake_lock_destroy(&hdd_ctx->sap_dfs_wakelock);
482 
483 	mutex_destroy(&hdd_ctx->sap_lock);
484 	qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock);
485 }
486 
487 /**
488  * __hdd_hostapd_open() - hdd open function for hostapd interface
489  * This is called in response to ifconfig up
490  * @dev: pointer to net_device structure
491  *
492  * Return - 0 for success non-zero for failure
493  */
__hdd_hostapd_open(struct net_device * dev)494 static int __hdd_hostapd_open(struct net_device *dev)
495 {
496 	struct hdd_adapter *adapter = netdev_priv(dev);
497 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
498 	int ret;
499 
500 	hdd_enter_dev(dev);
501 
502 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
503 		   TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST,
504 		   NO_SESSION, 0);
505 
506 	/* Nothing to be done if device is unloading */
507 	if (cds_is_driver_unloading()) {
508 		hdd_err("Driver is unloading can not open the hdd");
509 		return -EBUSY;
510 	}
511 
512 	if (cds_is_driver_recovering()) {
513 		hdd_err("WLAN is currently recovering; Please try again.");
514 		return -EBUSY;
515 	}
516 
517 	ret = wlan_hdd_validate_context(hdd_ctx);
518 	if (ret)
519 		return ret;
520 
521 	/* ensure the physical soc is up */
522 	ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
523 	if (ret) {
524 		hdd_err("Failed to start WLAN modules return");
525 		return ret;
526 	}
527 
528 	if (!hdd_allow_new_intf(hdd_ctx, adapter->device_mode))
529 		return -EOPNOTSUPP;
530 
531 	ret = hdd_start_adapter(adapter, true);
532 	if (ret) {
533 		hdd_err("Error Initializing the AP mode: %d", ret);
534 		return ret;
535 	}
536 
537 	set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
538 
539 	/* Enable all Tx queues */
540 	hdd_debug("Enabling queues");
541 	wlan_hdd_netif_queue_control(adapter,
542 				   WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
543 				   WLAN_CONTROL_PATH);
544 	hdd_exit();
545 	return 0;
546 }
547 
548 /**
549  * hdd_hostapd_open() - SSR wrapper for __hdd_hostapd_open
550  * @net_dev: pointer to net device
551  *
552  * Return: 0 on success, error number otherwise
553  */
hdd_hostapd_open(struct net_device * net_dev)554 static int hdd_hostapd_open(struct net_device *net_dev)
555 {
556 	int errno;
557 	struct osif_vdev_sync *vdev_sync;
558 
559 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
560 	if (errno)
561 		return errno;
562 
563 	errno = __hdd_hostapd_open(net_dev);
564 	if (!errno)
565 		osif_vdev_cache_command(vdev_sync, NO_COMMAND);
566 	osif_vdev_sync_trans_stop(vdev_sync);
567 
568 	return errno;
569 }
570 
hdd_hostapd_stop_no_trans(struct net_device * dev)571 int hdd_hostapd_stop_no_trans(struct net_device *dev)
572 {
573 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
574 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
575 	int ret;
576 
577 	hdd_enter_dev(dev);
578 
579 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
580 		   TRACE_CODE_HDD_HOSTAPD_STOP_REQUEST,
581 		   NO_SESSION, 0);
582 
583 	ret = wlan_hdd_validate_context(hdd_ctx);
584 	if (ret)
585 		return ret;
586 
587 	/*
588 	 * Some tests requires to do "ifconfig down" only to bring
589 	 * down the SAP/GO without killing hostapd/wpa_supplicant.
590 	 * In such case, user will do "ifconfig up" to bring-back
591 	 * the SAP/GO session. to fulfill this requirement, driver
592 	 * needs to de-init the sap session here and re-init when
593 	 * __hdd_hostapd_open() API
594 	 */
595 	hdd_stop_adapter(hdd_ctx, adapter);
596 	hdd_deinit_adapter(hdd_ctx, adapter, true);
597 	clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
598 	/* Stop all tx queues */
599 	hdd_debug("Disabling queues");
600 	wlan_hdd_netif_queue_control(adapter,
601 				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
602 				     WLAN_CONTROL_PATH);
603 
604 	if (!hdd_is_any_interface_open(hdd_ctx))
605 		hdd_psoc_idle_timer_start(hdd_ctx);
606 
607 	hdd_exit();
608 	return 0;
609 }
610 
611 /**
612  * hdd_hostapd_stop() - SSR wrapper for__hdd_hostapd_stop
613  * @net_dev: pointer to net_device
614  *
615  * This is called in response to ifconfig down
616  *
617  * Return: 0 on success, error number otherwise
618  */
hdd_hostapd_stop(struct net_device * net_dev)619 int hdd_hostapd_stop(struct net_device *net_dev)
620 {
621 	int errno;
622 	struct osif_vdev_sync *vdev_sync;
623 
624 	errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
625 	if (errno) {
626 		if (vdev_sync)
627 			osif_vdev_cache_command(vdev_sync, INTERFACE_DOWN);
628 		return errno;
629 	}
630 
631 	errno = hdd_hostapd_stop_no_trans(net_dev);
632 
633 	osif_vdev_sync_trans_stop(vdev_sync);
634 
635 	return errno;
636 }
637 
638 /**
639  * hdd_hostapd_uninit() - hdd uninit function
640  * @dev: pointer to net_device structure
641  *
642  * This is called during the netdev unregister to uninitialize all data
643  * associated with the device.
644  *
645  * This function must be protected by a transition
646  *
647  * Return: None
648  */
hdd_hostapd_uninit(struct net_device * dev)649 static void hdd_hostapd_uninit(struct net_device *dev)
650 {
651 	struct hdd_adapter *adapter = netdev_priv(dev);
652 	struct hdd_context *hdd_ctx;
653 
654 	hdd_enter_dev(dev);
655 
656 	if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
657 		hdd_err("Invalid magic");
658 		return;
659 	}
660 
661 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
662 	if (!hdd_ctx) {
663 		hdd_err("NULL hdd_ctx");
664 		return;
665 	}
666 
667 	hdd_deinit_adapter(hdd_ctx, adapter, true);
668 
669 	/* after uninit our adapter structure will no longer be valid */
670 	adapter->magic = 0;
671 
672 	hdd_exit();
673 }
674 
675 /**
676  * __hdd_hostapd_change_mtu() - change mtu
677  * @dev: pointer to net_device
678  * @new_mtu: new mtu
679  *
680  * Return: 0 on success, error number otherwise
681  */
__hdd_hostapd_change_mtu(struct net_device * dev,int new_mtu)682 static int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
683 {
684 	hdd_enter_dev(dev);
685 
686 	return 0;
687 }
688 
689 /**
690  * hdd_hostapd_change_mtu() - SSR wrapper for __hdd_hostapd_change_mtu
691  * @net_dev: pointer to net_device
692  * @new_mtu: new mtu
693  *
694  * Return: 0 on success, error number otherwise
695  */
hdd_hostapd_change_mtu(struct net_device * net_dev,int new_mtu)696 static int hdd_hostapd_change_mtu(struct net_device *net_dev, int new_mtu)
697 {
698 	struct osif_vdev_sync *vdev_sync;
699 	int errno;
700 
701 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
702 	if (errno)
703 		return errno;
704 
705 	errno = __hdd_hostapd_change_mtu(net_dev, new_mtu);
706 
707 	osif_vdev_sync_op_stop(vdev_sync);
708 
709 	return errno;
710 }
711 
712 #ifdef QCA_HT_2040_COEX
hdd_set_sap_ht2040_mode(struct hdd_adapter * adapter,uint8_t channel_type)713 QDF_STATUS hdd_set_sap_ht2040_mode(struct hdd_adapter *adapter,
714 				   uint8_t channel_type)
715 {
716 	QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
717 	mac_handle_t mac_handle;
718 
719 	hdd_debug("change HT20/40 mode");
720 
721 	if (QDF_SAP_MODE == adapter->device_mode) {
722 		mac_handle = adapter->hdd_ctx->mac_handle;
723 		if (!mac_handle) {
724 			hdd_err("mac handle is null");
725 			return QDF_STATUS_E_FAULT;
726 		}
727 		qdf_ret_status = sme_set_ht2040_mode(mac_handle,
728 						     adapter->deflink->vdev_id,
729 						     channel_type, true);
730 		if (qdf_ret_status == QDF_STATUS_E_FAILURE) {
731 			hdd_err("Failed to change HT20/40 mode");
732 			return QDF_STATUS_E_FAILURE;
733 		}
734 	}
735 	return QDF_STATUS_SUCCESS;
736 }
737 
hdd_get_sap_ht2040_mode(struct hdd_adapter * adapter,enum eSirMacHTChannelType * channel_type)738 QDF_STATUS hdd_get_sap_ht2040_mode(struct hdd_adapter *adapter,
739 				   enum eSirMacHTChannelType *channel_type)
740 {
741 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
742 	mac_handle_t mac_handle;
743 
744 	hdd_debug("get HT20/40 mode vdev_id %d", adapter->deflink->vdev_id);
745 
746 	if (adapter->device_mode == QDF_SAP_MODE) {
747 		mac_handle = adapter->hdd_ctx->mac_handle;
748 		if (!mac_handle) {
749 			hdd_err("mac handle is null");
750 			return status;
751 		}
752 		status = sme_get_ht2040_mode(mac_handle,
753 					     adapter->deflink->vdev_id,
754 					     channel_type);
755 		if (QDF_IS_STATUS_ERROR(status))
756 			hdd_err("Failed to get HT20/40 mode");
757 	}
758 
759 	return status;
760 }
761 #endif
762 
763 /**
764  * __hdd_hostapd_set_mac_address() -
765  * This function sets the user specified mac address using
766  * the command ifconfig wlanX hw ether <mac address>.
767  *
768  * @dev: pointer to the net device.
769  * @addr: pointer to the sockaddr.
770  *
771  * Return: 0 for success, non zero for failure
772  */
__hdd_hostapd_set_mac_address(struct net_device * dev,void * addr)773 static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
774 {
775 	struct sockaddr *psta_mac_addr = addr;
776 	struct hdd_adapter *adapter, *adapter_temp;
777 	struct hdd_context *hdd_ctx;
778 	int ret = 0;
779 	bool eht_capab;
780 	struct qdf_mac_addr mac_addr, mld_addr;
781 
782 	hdd_enter_dev(dev);
783 
784 	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
785 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
786 	ret = wlan_hdd_validate_context(hdd_ctx);
787 	if (0 != ret)
788 		return ret;
789 
790 	qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
791 	adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
792 	if (adapter_temp) {
793 		if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
794 			return 0;
795 		hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_FMT,
796 			adapter_temp->dev->name,
797 			QDF_MAC_ADDR_REF(mac_addr.bytes));
798 		return -EINVAL;
799 	}
800 
801 	if (qdf_is_macaddr_zero(&mac_addr)) {
802 		hdd_err("MAC is all zero");
803 		return -EINVAL;
804 	}
805 
806 	if (qdf_is_macaddr_broadcast(&mac_addr)) {
807 		hdd_err("MAC is Broadcast");
808 		return -EINVAL;
809 	}
810 
811 	if (qdf_is_macaddr_group(&mac_addr)) {
812 		hdd_err("MAC is Multicast");
813 		return -EINVAL;
814 	}
815 
816 	hdd_debug("Changing MAC to " QDF_MAC_ADDR_FMT " of interface %s ",
817 		  QDF_MAC_ADDR_REF(mac_addr.bytes),
818 		  dev->name);
819 
820 	if (adapter->deflink->vdev) {
821 		if (!hdd_is_dynamic_set_mac_addr_allowed(adapter))
822 			return -ENOTSUPP;
823 
824 		ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
825 		if (eht_capab && hdd_adapter_is_ml_adapter(adapter))
826 			qdf_copy_macaddr(&mld_addr, &mac_addr);
827 		else
828 			qdf_zero_macaddr(&mld_addr);
829 
830 		ret = hdd_dynamic_mac_address_set(adapter->deflink, mac_addr,
831 						  mld_addr, false);
832 		if (ret)
833 			return ret;
834 	}
835 
836 	hdd_set_mld_address(adapter, &mac_addr);
837 
838 	/* Currently for SL-ML-SAP use same MAC for both MLD and link */
839 	hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
840 	ucfg_dp_update_intf_mac(hdd_ctx->psoc, &adapter->mac_addr, &mac_addr,
841 				adapter->deflink->vdev);
842 	memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
843 	qdf_net_update_net_device_dev_addr(dev, psta_mac_addr->sa_data,
844 					   ETH_ALEN);
845 	hdd_exit();
846 	return 0;
847 }
848 
849 /**
850  * hdd_hostapd_set_mac_address() - set mac address
851  * @net_dev: pointer to net_device
852  * @addr: mac address
853  *
854  * Return: 0 on success, error number otherwise
855  */
hdd_hostapd_set_mac_address(struct net_device * net_dev,void * addr)856 static int hdd_hostapd_set_mac_address(struct net_device *net_dev, void *addr)
857 {
858 	struct osif_vdev_sync *vdev_sync;
859 	int errno;
860 
861 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
862 	if (errno)
863 		return errno;
864 
865 	errno = __hdd_hostapd_set_mac_address(net_dev, addr);
866 
867 	osif_vdev_sync_op_stop(vdev_sync);
868 
869 	return errno;
870 }
871 
hdd_clear_sta(struct hdd_adapter * adapter,struct hdd_station_info * sta_info)872 static void hdd_clear_sta(struct hdd_adapter *adapter,
873 			  struct hdd_station_info *sta_info)
874 {
875 	struct hdd_ap_ctx *ap_ctx;
876 	struct csr_del_sta_params del_sta_params;
877 
878 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink);
879 
880 	if (qdf_is_macaddr_broadcast(&sta_info->sta_mac))
881 		return;
882 
883 	wlansap_populate_del_sta_params(sta_info->sta_mac.bytes,
884 					REASON_DEAUTH_NETWORK_LEAVING,
885 					SIR_MAC_MGMT_DISASSOC,
886 					&del_sta_params);
887 
888 	hdd_softap_sta_disassoc(adapter, &del_sta_params);
889 }
890 
hdd_clear_all_sta(struct hdd_adapter * adapter)891 static void hdd_clear_all_sta(struct hdd_adapter *adapter)
892 {
893 	struct hdd_station_info *sta_info, *tmp = NULL;
894 
895 	hdd_enter_dev(adapter->dev);
896 
897 	hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
898 				  STA_INFO_HDD_CLEAR_ALL_STA) {
899 		hdd_clear_sta(adapter, sta_info);
900 		hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
901 				     STA_INFO_HDD_CLEAR_ALL_STA);
902 	}
903 }
904 
hdd_stop_bss_link(struct hdd_adapter * adapter)905 static int hdd_stop_bss_link(struct hdd_adapter *adapter)
906 {
907 	struct hdd_context *hdd_ctx;
908 	int errno;
909 	QDF_STATUS status;
910 
911 	hdd_enter();
912 
913 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
914 	errno = wlan_hdd_validate_context(hdd_ctx);
915 	if (errno)
916 		return errno;
917 
918 	if (test_bit(SOFTAP_BSS_STARTED, &adapter->deflink->link_flags)) {
919 		status = wlansap_stop_bss(
920 			WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink));
921 		if (QDF_IS_STATUS_SUCCESS(status))
922 			hdd_debug("Deleting SAP/P2P link!!!!!!");
923 
924 		clear_bit(SOFTAP_BSS_STARTED, &adapter->deflink->link_flags);
925 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
926 					adapter->device_mode,
927 					adapter->deflink->vdev_id);
928 		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
929 					    false);
930 		errno = (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
931 	}
932 	hdd_exit();
933 	return errno;
934 }
935 
936 #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC)
937 static void
wlan_hdd_set_chandef_320mhz(struct cfg80211_chan_def * chandef,struct wlan_channel * chan)938 wlan_hdd_set_chandef_320mhz(struct cfg80211_chan_def *chandef,
939 			    struct wlan_channel *chan)
940 {
941 	if (chan->ch_width != CH_WIDTH_320MHZ)
942 		return;
943 
944 	chandef->width = NL80211_CHAN_WIDTH_320;
945 	if (chan->ch_cfreq2)
946 		chandef->center_freq1 = chan->ch_cfreq2;
947 }
948 
wlan_hdd_set_chandef_width(struct cfg80211_chan_def * chandef,enum phy_ch_width width)949 static void wlan_hdd_set_chandef_width(struct cfg80211_chan_def *chandef,
950 				       enum phy_ch_width width)
951 {
952 	if (width == CH_WIDTH_320MHZ)
953 		chandef->width = NL80211_CHAN_WIDTH_320;
954 }
955 
wlan_hdd_is_chwidth_320mhz(enum phy_ch_width ch_width)956 static inline bool wlan_hdd_is_chwidth_320mhz(enum phy_ch_width ch_width)
957 {
958 	return ch_width == CH_WIDTH_320MHZ;
959 }
960 
961 static uint16_t
wlan_hdd_get_puncture_bitmap(struct wlan_hdd_link_info * link_info)962 wlan_hdd_get_puncture_bitmap(struct wlan_hdd_link_info *link_info)
963 {
964 	struct hdd_adapter *adapter = link_info->adapter;
965 	struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
966 
967 	if (adapter->device_mode == QDF_SAP_MODE ||
968 	    adapter->device_mode == QDF_P2P_CLIENT_MODE)
969 		return ap_ctx->reg_punc_bitmap;
970 
971 	return 0;
972 }
973 #else /* !WLAN_FEATURE_11BE */
974 static inline
wlan_hdd_set_chandef_320mhz(struct cfg80211_chan_def * chandef,struct wlan_channel * chan)975 void wlan_hdd_set_chandef_320mhz(struct cfg80211_chan_def *chandef,
976 				 struct wlan_channel *chan)
977 {
978 }
979 
wlan_hdd_set_chandef_width(struct cfg80211_chan_def * chandef,enum phy_ch_width width)980 static inline void wlan_hdd_set_chandef_width(struct cfg80211_chan_def *chandef,
981 					      enum phy_ch_width width)
982 {
983 }
984 
wlan_hdd_is_chwidth_320mhz(enum phy_ch_width ch_width)985 static inline bool wlan_hdd_is_chwidth_320mhz(enum phy_ch_width ch_width)
986 {
987 	return false;
988 }
989 
990 static inline uint16_t
wlan_hdd_get_puncture_bitmap(struct wlan_hdd_link_info * link_info)991 wlan_hdd_get_puncture_bitmap(struct wlan_hdd_link_info *link_info)
992 {
993 	return 0;
994 }
995 #endif /* WLAN_FEATURE_11BE */
996 
hdd_create_chandef(struct hdd_adapter * adapter,struct wlan_channel * wlan_chan,struct cfg80211_chan_def * chandef)997 static QDF_STATUS hdd_create_chandef(struct hdd_adapter *adapter,
998 				     struct wlan_channel *wlan_chan,
999 				     struct cfg80211_chan_def *chandef)
1000 {
1001 	struct ieee80211_channel *chan;
1002 	enum nl80211_channel_type channel_type;
1003 	uint32_t freq;
1004 	bool legacy_phymode = true;
1005 
1006 	freq = wlan_chan->ch_freq;
1007 	chan = ieee80211_get_channel(adapter->wdev.wiphy, freq);
1008 	if (!chan) {
1009 		hdd_err("Invalid input frequency %d for channel conversion",
1010 			freq);
1011 		return QDF_STATUS_E_FAILURE;
1012 	}
1013 
1014 	if (IS_WLAN_PHYMODE_HT(wlan_chan->ch_phymode) ||
1015 	    IS_WLAN_PHYMODE_VHT(wlan_chan->ch_phymode) ||
1016 	    IS_WLAN_PHYMODE_HE(wlan_chan->ch_phymode) ||
1017 	    IS_WLAN_PHYMODE_EHT(wlan_chan->ch_phymode))
1018 		legacy_phymode = false;
1019 
1020 	if (legacy_phymode) {
1021 		channel_type = NL80211_CHAN_NO_HT;
1022 	} else {
1023 		if (!wlan_chan->ch_cfreq1 ||
1024 		    wlan_chan->ch_cfreq1 == wlan_chan->ch_freq)
1025 			channel_type = NL80211_CHAN_HT20;
1026 		else if (wlan_chan->ch_cfreq1 > wlan_chan->ch_freq)
1027 			channel_type = NL80211_CHAN_HT40PLUS;
1028 		else
1029 			channel_type = NL80211_CHAN_HT40MINUS;
1030 	}
1031 
1032 	cfg80211_chandef_create(chandef, chan, channel_type);
1033 
1034 	/* cfg80211_chandef_create() does update of width and center_freq1
1035 	 * only for NL80211_CHAN_NO_HT, NL80211_CHAN_HT20, NL80211_CHAN_HT40PLUS
1036 	 * and NL80211_CHAN_HT40MINUS.
1037 	 */
1038 	switch (wlan_chan->ch_width) {
1039 	case CH_WIDTH_80MHZ:
1040 		chandef->width = NL80211_CHAN_WIDTH_80;
1041 		break;
1042 	case CH_WIDTH_80P80MHZ:
1043 		chandef->width = NL80211_CHAN_WIDTH_80P80;
1044 		if (wlan_chan->ch_cfreq2)
1045 			chandef->center_freq2 = wlan_chan->ch_cfreq2;
1046 		break;
1047 	case CH_WIDTH_160MHZ:
1048 		chandef->width = NL80211_CHAN_WIDTH_160;
1049 		if (wlan_chan->ch_cfreq2)
1050 			chandef->center_freq1 = wlan_chan->ch_cfreq2;
1051 		break;
1052 	default:
1053 		break;
1054 	}
1055 
1056 	wlan_hdd_set_chandef_320mhz(chandef, wlan_chan);
1057 
1058 	if (wlan_chan->ch_width == CH_WIDTH_80MHZ ||
1059 	    wlan_chan->ch_width == CH_WIDTH_80P80MHZ) {
1060 		if (wlan_chan->ch_cfreq1)
1061 			chandef->center_freq1 = wlan_chan->ch_cfreq1;
1062 	}
1063 
1064 	return QDF_STATUS_SUCCESS;
1065 }
1066 
hdd_chan_change_notify_update(struct wlan_hdd_link_info * link_info)1067 static void hdd_chan_change_notify_update(struct wlan_hdd_link_info *link_info)
1068 {
1069 	struct hdd_adapter *adapter = link_info->adapter;
1070 	mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
1071 	struct wlan_objmgr_vdev *vdev;
1072 	uint16_t link_id = 0;
1073 	struct hdd_adapter *assoc_adapter;
1074 	struct wlan_channel *chan;
1075 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1076 	struct net_device *dev;
1077 	struct cfg80211_chan_def chandef;
1078 	uint16_t puncture_bitmap = 0;
1079 	uint8_t vdev_id;
1080 
1081 	if (!mac_handle) {
1082 		hdd_err("mac_handle is NULL");
1083 		return;
1084 	}
1085 
1086 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
1087 	if (!vdev)
1088 		return;
1089 
1090 	dev = adapter->dev;
1091 	vdev_id = wlan_vdev_get_id(vdev);
1092 	if (hdd_adapter_is_link_adapter(adapter)) {
1093 		hdd_debug("replace link adapter dev with ml adapter dev");
1094 		assoc_adapter = hdd_adapter_get_mlo_adapter_from_link(adapter);
1095 		if (!assoc_adapter) {
1096 			hdd_err("Assoc adapter is NULL");
1097 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
1098 			return;
1099 		}
1100 		dev = assoc_adapter->dev;
1101 	}
1102 
1103 	mutex_lock(&dev->ieee80211_ptr->mtx);
1104 	if (wlan_vdev_mlme_is_active(vdev) != QDF_STATUS_SUCCESS) {
1105 		hdd_debug("Vdev %d mode %d not UP", vdev_id,
1106 			  adapter->device_mode);
1107 		goto exit;
1108 	}
1109 
1110 	if ((adapter->device_mode == QDF_STA_MODE ||
1111 	     adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
1112 	    !ucfg_cm_is_vdev_active(vdev)) {
1113 		hdd_debug("Vdev %d is not connected", vdev_id);
1114 		goto exit;
1115 	}
1116 
1117 	if (wlan_vdev_mlme_is_mlo_vdev(vdev))
1118 		link_id = wlan_vdev_get_link_id(vdev);
1119 
1120 	chan = wlan_vdev_get_active_channel(vdev);
1121 
1122 	if (!chan)
1123 		goto exit;
1124 
1125 	status = hdd_create_chandef(adapter, chan, &chandef);
1126 	if (QDF_IS_STATUS_ERROR(status)) {
1127 		hdd_debug("Vdev %d failed to create channel def", vdev_id);
1128 		goto exit;
1129 	}
1130 
1131 	puncture_bitmap = wlan_hdd_get_puncture_bitmap(link_info);
1132 
1133 	hdd_debug("notify: vdev %d chan:%d width:%d freq1:%d freq2:%d punct 0x%x",
1134 		  vdev_id, chandef.chan->center_freq, chandef.width,
1135 		  chandef.center_freq1, chandef.center_freq2,
1136 		  puncture_bitmap);
1137 
1138 	wlan_cfg80211_ch_switch_notify(dev, &chandef, link_id, puncture_bitmap);
1139 
1140 exit:
1141 	mutex_unlock(&dev->ieee80211_ptr->mtx);
1142 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
1143 }
1144 
hdd_chan_change_notify_work_handler(void * data)1145 void hdd_chan_change_notify_work_handler(void *data)
1146 {
1147 	struct wlan_hdd_link_info *link_info =
1148 			(struct wlan_hdd_link_info *)data;
1149 
1150 	if (!link_info)
1151 		return;
1152 
1153 	hdd_chan_change_notify_update(link_info);
1154 }
1155 
1156 /**
1157  * hdd_send_radar_event() - Function to send radar events to user space
1158  * @hdd_context:	HDD context
1159  * @event:		Type of radar event
1160  * @dfs_info:		Structure containing DFS channel and country
1161  * @wdev:		Wireless device structure
1162  *
1163  * This function is used to send radar events such as CAC start, CAC
1164  * end etc., to userspace
1165  *
1166  * Return: Success on sending notifying userspace
1167  *
1168  */
hdd_send_radar_event(struct hdd_context * hdd_context,eSapHddEvent event,struct wlan_dfs_info dfs_info,struct wireless_dev * wdev)1169 static QDF_STATUS hdd_send_radar_event(struct hdd_context *hdd_context,
1170 				       eSapHddEvent event,
1171 				       struct wlan_dfs_info dfs_info,
1172 				       struct wireless_dev *wdev)
1173 {
1174 
1175 	struct sk_buff *vendor_event;
1176 	enum qca_nl80211_vendor_subcmds_index index;
1177 	uint32_t freq, ret;
1178 	uint32_t data_size;
1179 
1180 	if (!hdd_context) {
1181 		hdd_err("HDD context is NULL");
1182 		return QDF_STATUS_E_FAILURE;
1183 	}
1184 
1185 	freq = cds_chan_to_freq(dfs_info.channel);
1186 
1187 	switch (event) {
1188 	case eSAP_DFS_CAC_START:
1189 		index =
1190 		    QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX;
1191 		data_size = sizeof(uint32_t);
1192 		break;
1193 	case eSAP_DFS_CAC_END:
1194 		index =
1195 		    QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX;
1196 		data_size = sizeof(uint32_t);
1197 		break;
1198 	case eSAP_DFS_RADAR_DETECT:
1199 		index =
1200 		    QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX;
1201 		data_size = sizeof(uint32_t);
1202 		break;
1203 	default:
1204 		return QDF_STATUS_E_FAILURE;
1205 	}
1206 
1207 	vendor_event = wlan_cfg80211_vendor_event_alloc(hdd_context->wiphy,
1208 							wdev,
1209 							data_size +
1210 							NLMSG_HDRLEN,
1211 							index, GFP_KERNEL);
1212 	if (!vendor_event) {
1213 		hdd_err("wlan_cfg80211_vendor_event_alloc failed for %d",
1214 			index);
1215 		return QDF_STATUS_E_FAILURE;
1216 	}
1217 
1218 	ret = nla_put_u32(vendor_event, NL80211_ATTR_WIPHY_FREQ, freq);
1219 
1220 	if (ret) {
1221 		hdd_err("NL80211_ATTR_WIPHY_FREQ put fail");
1222 		wlan_cfg80211_vendor_free_skb(vendor_event);
1223 		return QDF_STATUS_E_FAILURE;
1224 	}
1225 
1226 	wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1227 	return QDF_STATUS_SUCCESS;
1228 }
1229 
1230 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1231 /**
1232  * hdd_handle_acs_scan_event() - handle acs scan event for SAP
1233  * @sap_event: tpSap_Event
1234  * @adapter: struct hdd_adapter for SAP
1235  *
1236  * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event.
1237  * It will update scan result to cfg80211 and start a timer to flush the
1238  * cached acs scan result.
1239  *
1240  * Return: QDF_STATUS_SUCCESS on success,
1241  *      other value on failure
1242  */
hdd_handle_acs_scan_event(struct sap_event * sap_event,struct hdd_adapter * adapter)1243 static QDF_STATUS hdd_handle_acs_scan_event(struct sap_event *sap_event,
1244 		struct hdd_adapter *adapter)
1245 {
1246 	struct hdd_context *hdd_ctx;
1247 	struct sap_acs_scan_complete_event *comp_evt;
1248 	QDF_STATUS qdf_status;
1249 	int freq_list_size;
1250 
1251 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1252 	if (!hdd_ctx) {
1253 		hdd_err("HDD context is null");
1254 		return QDF_STATUS_E_FAILURE;
1255 	}
1256 	comp_evt = &sap_event->sapevt.sap_acs_scan_comp;
1257 	hdd_ctx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN;
1258 	qdf_spin_lock(&hdd_ctx->acs_skip_lock);
1259 	qdf_mem_free(hdd_ctx->last_acs_freq_list);
1260 	hdd_ctx->last_acs_freq_list = NULL;
1261 	hdd_ctx->num_of_channels = 0;
1262 	/* cache the previous ACS scan channel list .
1263 	 * If the following OBSS scan chan list is covered by ACS chan list,
1264 	 * we can skip OBSS Scan to save SAP starting total time.
1265 	 */
1266 	if (comp_evt->num_of_channels && comp_evt->freq_list) {
1267 		freq_list_size = comp_evt->num_of_channels *
1268 			sizeof(comp_evt->freq_list[0]);
1269 		hdd_ctx->last_acs_freq_list = qdf_mem_malloc(
1270 			freq_list_size);
1271 		if (hdd_ctx->last_acs_freq_list) {
1272 			qdf_mem_copy(hdd_ctx->last_acs_freq_list,
1273 				     comp_evt->freq_list,
1274 				     freq_list_size);
1275 			hdd_ctx->num_of_channels = comp_evt->num_of_channels;
1276 		}
1277 	}
1278 	qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
1279 
1280 	hdd_debug("Reusing Last ACS scan result for %d sec",
1281 		ACS_SCAN_EXPIRY_TIMEOUT_S);
1282 	qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
1283 	qdf_status = qdf_mc_timer_start(&hdd_ctx->skip_acs_scan_timer,
1284 			ACS_SCAN_EXPIRY_TIMEOUT_S * 1000);
1285 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1286 		hdd_err("Failed to start ACS scan expiry timer");
1287 	return QDF_STATUS_SUCCESS;
1288 }
1289 #else
hdd_handle_acs_scan_event(struct sap_event * sap_event,struct hdd_adapter * adapter)1290 static QDF_STATUS hdd_handle_acs_scan_event(struct sap_event *sap_event,
1291 		struct hdd_adapter *adapter)
1292 {
1293 	return QDF_STATUS_SUCCESS;
1294 }
1295 #endif
1296 
1297 /**
1298  * get_max_rate_vht() - calculate max rate for VHT mode
1299  * @nss: num of streams
1300  * @ch_width: channel width
1301  * @sgi: short gi
1302  * @vht_mcs_map: vht mcs map
1303  *
1304  * This function calculate max rate for VHT mode
1305  *
1306  * Return: max rate
1307  */
get_max_rate_vht(int nss,int ch_width,int sgi,int vht_mcs_map)1308 static int get_max_rate_vht(int nss, int ch_width, int sgi, int vht_mcs_map)
1309 {
1310 	const struct index_vht_data_rate_type *supported_vht_mcs_rate;
1311 	enum data_rate_11ac_max_mcs vht_max_mcs;
1312 	int maxrate = 0;
1313 	int maxidx;
1314 
1315 	if (nss == 1) {
1316 		supported_vht_mcs_rate = supported_vht_mcs_rate_nss1;
1317 	} else if (nss == 2) {
1318 		supported_vht_mcs_rate = supported_vht_mcs_rate_nss2;
1319 	} else {
1320 		/* Not Supported */
1321 		hdd_debug("nss %d not supported", nss);
1322 		return maxrate;
1323 	}
1324 
1325 	vht_max_mcs =
1326 		(enum data_rate_11ac_max_mcs)
1327 		(vht_mcs_map & DATA_RATE_11AC_MCS_MASK);
1328 
1329 	if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_7) {
1330 		maxidx = 7;
1331 	} else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_8) {
1332 		maxidx = 8;
1333 	} else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_9) {
1334 		if (ch_width == eHT_CHANNEL_WIDTH_20MHZ)
1335 			/* MCS9 is not valid for VHT20 when nss=1,2 */
1336 			maxidx = 8;
1337 		else
1338 			maxidx = 9;
1339 	} else {
1340 		hdd_err("vht mcs map %x not supported",
1341 			vht_mcs_map & DATA_RATE_11AC_MCS_MASK);
1342 		return maxrate;
1343 	}
1344 
1345 	if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) {
1346 		maxrate =
1347 		supported_vht_mcs_rate[maxidx].supported_VHT20_rate[sgi];
1348 	} else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) {
1349 		maxrate =
1350 		supported_vht_mcs_rate[maxidx].supported_VHT40_rate[sgi];
1351 	} else if (ch_width == eHT_CHANNEL_WIDTH_80MHZ) {
1352 		maxrate =
1353 		supported_vht_mcs_rate[maxidx].supported_VHT80_rate[sgi];
1354 	} else {
1355 		hdd_err("ch_width %d not supported", ch_width);
1356 		return maxrate;
1357 	}
1358 
1359 	return maxrate;
1360 }
1361 
1362 /**
1363  * calculate_max_phy_rate() - calculate maximum phy rate (100kbps)
1364  * @mode: phymode: Legacy, 11a/b/g, HT, VHT
1365  * @nss: num of stream (maximum num is 2)
1366  * @ch_width: channel width
1367  * @sgi: short gi enabled or not
1368  * @supp_idx: max supported idx
1369  * @ext_idx: max extended idx
1370  * @ht_mcs_idx: max mcs index for HT
1371  * @vht_mcs_map: mcs map for VHT
1372  *
1373  * return: maximum phy rate in 100kbps
1374  */
calculate_max_phy_rate(int mode,int nss,int ch_width,int sgi,int supp_idx,int ext_idx,int ht_mcs_idx,int vht_mcs_map)1375 static int calculate_max_phy_rate(int mode, int nss, int ch_width,
1376 				 int sgi, int supp_idx, int ext_idx,
1377 				 int ht_mcs_idx, int vht_mcs_map)
1378 {
1379 	const struct index_data_rate_type *supported_mcs_rate;
1380 	int maxidx = 12; /*default 6M mode*/
1381 	int maxrate = 0, tmprate;
1382 	int i;
1383 
1384 	/* check supported rates */
1385 	if (supp_idx != 0xff && maxidx < supp_idx)
1386 		maxidx = supp_idx;
1387 
1388 	/* check extended rates */
1389 	if (ext_idx != 0xff && maxidx < ext_idx)
1390 		maxidx = ext_idx;
1391 
1392 	for (i = 0; i < QDF_ARRAY_SIZE(supported_data_rate); i++) {
1393 		if (supported_data_rate[i].beacon_rate_index == maxidx)
1394 			maxrate = supported_data_rate[i].supported_rate[0];
1395 	}
1396 
1397 	if (mode == SIR_SME_PHY_MODE_HT) {
1398 		/* check for HT Mode */
1399 		maxidx = ht_mcs_idx;
1400 		if (maxidx > 7) {
1401 			hdd_err("ht_mcs_idx %d is incorrect", ht_mcs_idx);
1402 			return maxrate;
1403 		}
1404 		if (nss == 1) {
1405 			supported_mcs_rate = supported_mcs_rate_nss1;
1406 		} else if (nss == 2) {
1407 			supported_mcs_rate = supported_mcs_rate_nss2;
1408 		} else {
1409 			/* Not Supported */
1410 			hdd_err("nss %d not supported", nss);
1411 			return maxrate;
1412 		}
1413 
1414 		if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) {
1415 			tmprate = sgi ?
1416 				supported_mcs_rate[maxidx].supported_rate[2] :
1417 				supported_mcs_rate[maxidx].supported_rate[0];
1418 		} else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) {
1419 			tmprate = sgi ?
1420 				supported_mcs_rate[maxidx].supported_rate[3] :
1421 				supported_mcs_rate[maxidx].supported_rate[1];
1422 		} else {
1423 			hdd_err("invalid mode %d ch_width %d",
1424 				mode, ch_width);
1425 			return maxrate;
1426 		}
1427 
1428 		if (maxrate < tmprate)
1429 			maxrate = tmprate;
1430 	}
1431 
1432 	if (mode == SIR_SME_PHY_MODE_VHT) {
1433 		/* check for VHT Mode */
1434 		tmprate = get_max_rate_vht(nss, ch_width, sgi, vht_mcs_map);
1435 		if (maxrate < tmprate)
1436 			maxrate = tmprate;
1437 	}
1438 
1439 	return maxrate;
1440 }
1441 
1442 #if SUPPORT_11AX
1443 /**
1444  * hdd_convert_11ax_phymode_to_dot11mode() - get dot11 mode from phymode
1445  * @phymode: phymode of sta associated to SAP
1446  *
1447  * The function is to convert the 11ax phymode to corresponding dot11 mode
1448  *
1449  * Return: dot11mode.
1450  */
1451 static inline enum qca_wlan_802_11_mode
hdd_convert_11ax_phymode_to_dot11mode(int phymode)1452 hdd_convert_11ax_phymode_to_dot11mode(int phymode)
1453 {
1454 	switch (phymode) {
1455 	case MODE_11AX_HE20:
1456 	case MODE_11AX_HE40:
1457 	case MODE_11AX_HE80:
1458 	case MODE_11AX_HE80_80:
1459 	case MODE_11AX_HE160:
1460 	case MODE_11AX_HE20_2G:
1461 	case MODE_11AX_HE40_2G:
1462 	case MODE_11AX_HE80_2G:
1463 		return QCA_WLAN_802_11_MODE_11AX;
1464 	default:
1465 		return QCA_WLAN_802_11_MODE_INVALID;
1466 	}
1467 }
1468 #else
1469 static inline enum qca_wlan_802_11_mode
hdd_convert_11ax_phymode_to_dot11mode(int phymode)1470 hdd_convert_11ax_phymode_to_dot11mode(int phymode)
1471 {
1472 	return QCA_WLAN_802_11_MODE_INVALID;
1473 }
1474 #endif
1475 
hdd_convert_dot11mode_from_phymode(int phymode)1476 enum qca_wlan_802_11_mode hdd_convert_dot11mode_from_phymode(int phymode)
1477 {
1478 
1479 	switch (phymode) {
1480 
1481 	case MODE_11A:
1482 		return QCA_WLAN_802_11_MODE_11A;
1483 
1484 	case MODE_11B:
1485 		return QCA_WLAN_802_11_MODE_11B;
1486 
1487 	case MODE_11G:
1488 	case MODE_11GONLY:
1489 		return QCA_WLAN_802_11_MODE_11G;
1490 
1491 	case MODE_11NA_HT20:
1492 	case MODE_11NG_HT20:
1493 	case MODE_11NA_HT40:
1494 	case MODE_11NG_HT40:
1495 		return QCA_WLAN_802_11_MODE_11N;
1496 
1497 	case MODE_11AC_VHT20:
1498 	case MODE_11AC_VHT40:
1499 	case MODE_11AC_VHT80:
1500 	case MODE_11AC_VHT20_2G:
1501 	case MODE_11AC_VHT40_2G:
1502 	case MODE_11AC_VHT80_2G:
1503 #ifdef CONFIG_160MHZ_SUPPORT
1504 	case MODE_11AC_VHT80_80:
1505 	case MODE_11AC_VHT160:
1506 #endif
1507 		return QCA_WLAN_802_11_MODE_11AC;
1508 	default:
1509 		return hdd_convert_11ax_phymode_to_dot11mode(phymode);
1510 	}
1511 
1512 }
1513 
1514 /**
1515  * hdd_fill_station_info() - fill stainfo once connected
1516  * @adapter: pointer to hdd adapter
1517  * @event: associate/reassociate event received
1518  *
1519  * The function is to update rate stats to stainfo
1520  *
1521  * Return: None.
1522  */
hdd_fill_station_info(struct hdd_adapter * adapter,tSap_StationAssocReassocCompleteEvent * event)1523 static void hdd_fill_station_info(struct hdd_adapter *adapter,
1524 				  tSap_StationAssocReassocCompleteEvent *event)
1525 {
1526 	struct hdd_station_info *stainfo, *cache_sta_info;
1527 	struct hdd_station_info *oldest_disassoc_sta_info = NULL;
1528 	qdf_time_t oldest_disassoc_sta_ts = 0;
1529 	bool is_dot11_mode_abgn;
1530 
1531 	stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
1532 					  event->staMac.bytes,
1533 					  STA_INFO_FILL_STATION_INFO);
1534 
1535 	if (!stainfo) {
1536 		hdd_err("invalid stainfo");
1537 		return;
1538 	}
1539 
1540 	qdf_mem_copy(&stainfo->capability, &event->capability_info,
1541 		     sizeof(uint16_t));
1542 	stainfo->freq = event->chan_info.mhz;
1543 	stainfo->sta_type = event->staType;
1544 	stainfo->dot11_mode =
1545 		hdd_convert_dot11mode_from_phymode(event->chan_info.info);
1546 
1547 	stainfo->nss = event->chan_info.nss;
1548 	stainfo->rate_flags = event->chan_info.rate_flags;
1549 	stainfo->ampdu = event->ampdu;
1550 	stainfo->sgi_enable = event->sgi_enable;
1551 	stainfo->tx_stbc = event->tx_stbc;
1552 	stainfo->rx_stbc = event->rx_stbc;
1553 	stainfo->ch_width = event->ch_width;
1554 	stainfo->mode = event->mode;
1555 	stainfo->max_supp_idx = event->max_supp_idx;
1556 	stainfo->max_ext_idx = event->max_ext_idx;
1557 	stainfo->max_mcs_idx = event->max_mcs_idx;
1558 	stainfo->max_real_mcs_idx = event->max_real_mcs_idx;
1559 	stainfo->rx_mcs_map = event->rx_mcs_map;
1560 	stainfo->tx_mcs_map = event->tx_mcs_map;
1561 	stainfo->assoc_ts = qdf_system_ticks();
1562 	stainfo->max_phy_rate =
1563 		calculate_max_phy_rate(stainfo->mode,
1564 				       stainfo->nss,
1565 				       stainfo->ch_width,
1566 				       stainfo->sgi_enable,
1567 				       stainfo->max_supp_idx,
1568 				       stainfo->max_ext_idx,
1569 				       stainfo->max_mcs_idx,
1570 				       stainfo->rx_mcs_map);
1571 	/* expect max_phy_rate report in kbps */
1572 	stainfo->max_phy_rate *= 100;
1573 
1574 	/*
1575 	 * Connected Peer always supports atleast one of the
1576 	 * 802.11 mode out of 11bg/11abg/11abgn, hence this field
1577 	 * should always be true.
1578 	 */
1579 	is_dot11_mode_abgn = true;
1580 	stainfo->ecsa_capable = event->ecsa_capable;
1581 	stainfo->ext_cap = event->ext_cap;
1582 	stainfo->supported_band = event->supported_band;
1583 
1584 	if (event->vht_caps.present) {
1585 		stainfo->vht_present = true;
1586 		hdd_copy_vht_caps(&stainfo->vht_caps, &event->vht_caps);
1587 		stainfo->support_mode |=
1588 				(stainfo->vht_present << HDD_80211_MODE_AC);
1589 	}
1590 	if (event->ht_caps.present) {
1591 		stainfo->ht_present = true;
1592 		hdd_copy_ht_caps(&stainfo->ht_caps, &event->ht_caps);
1593 	}
1594 
1595 	stainfo->support_mode |=
1596 			(event->he_caps_present << HDD_80211_MODE_AX);
1597 
1598 	if (event->he_caps_present && !(event->vht_caps.present ||
1599 					event->ht_caps.present))
1600 		is_dot11_mode_abgn = false;
1601 
1602 	stainfo->support_mode |=
1603 				(event->eht_caps_present << HDD_80211_MODE_BE);
1604 	stainfo->support_mode |= is_dot11_mode_abgn << HDD_80211_MODE_ABGN;
1605 	/* Initialize DHCP info */
1606 	stainfo->dhcp_phase = DHCP_PHASE_ACK;
1607 	stainfo->dhcp_nego_status = DHCP_NEGO_STOP;
1608 
1609 	/* Save assoc request IEs */
1610 	if (event->ies_len) {
1611 		qdf_mem_free(stainfo->assoc_req_ies.ptr);
1612 		stainfo->assoc_req_ies.len = 0;
1613 		stainfo->assoc_req_ies.ptr = qdf_mem_malloc(event->ies_len);
1614 		if (stainfo->assoc_req_ies.ptr) {
1615 			qdf_mem_copy(stainfo->assoc_req_ies.ptr, event->ies,
1616 				     event->ies_len);
1617 			stainfo->assoc_req_ies.len = event->ies_len;
1618 		}
1619 	}
1620 
1621 	qdf_mem_copy(&stainfo->mld_addr, &event->sta_mld, QDF_MAC_ADDR_SIZE);
1622 
1623 	cache_sta_info =
1624 		hdd_get_sta_info_by_mac(&adapter->cache_sta_info_list,
1625 					event->staMac.bytes,
1626 					STA_INFO_FILL_STATION_INFO);
1627 
1628 	if (!cache_sta_info) {
1629 		cache_sta_info = qdf_mem_malloc(sizeof(*cache_sta_info));
1630 		if (!cache_sta_info)
1631 			goto exit;
1632 
1633 		qdf_mem_copy(cache_sta_info, stainfo, sizeof(*cache_sta_info));
1634 		cache_sta_info->is_attached = 0;
1635 		cache_sta_info->assoc_req_ies.ptr =
1636 				qdf_mem_malloc(event->ies_len);
1637 		if (cache_sta_info->assoc_req_ies.ptr) {
1638 			qdf_mem_copy(cache_sta_info->assoc_req_ies.ptr,
1639 				     event->ies, event->ies_len);
1640 			cache_sta_info->assoc_req_ies.len = event->ies_len;
1641 		}
1642 		qdf_atomic_init(&cache_sta_info->ref_cnt);
1643 
1644 		/*
1645 		 * If cache_sta_info is not present and cache limit is not
1646 		 * reached, then create and attach. Else find the cache that is
1647 		 * the oldest and replace that with the new cache.
1648 		 */
1649 		if (qdf_atomic_read(&adapter->cache_sta_count) <
1650 		    WLAN_MAX_STA_COUNT) {
1651 			hdd_sta_info_attach(&adapter->cache_sta_info_list,
1652 					    cache_sta_info);
1653 			qdf_atomic_inc(&adapter->cache_sta_count);
1654 		} else {
1655 			struct hdd_station_info *temp_sta_info, *tmp = NULL;
1656 			struct hdd_sta_info_obj *sta_list =
1657 						&adapter->cache_sta_info_list;
1658 
1659 			hdd_debug("reached max caching, removing oldest");
1660 
1661 			/* Find the oldest cached station */
1662 			hdd_for_each_sta_ref_safe(adapter->cache_sta_info_list,
1663 						  temp_sta_info, tmp,
1664 						  STA_INFO_FILL_STATION_INFO) {
1665 				if (temp_sta_info->disassoc_ts &&
1666 				    (!oldest_disassoc_sta_ts ||
1667 				    qdf_system_time_after(
1668 				    oldest_disassoc_sta_ts,
1669 				    temp_sta_info->disassoc_ts))) {
1670 					oldest_disassoc_sta_ts =
1671 						temp_sta_info->disassoc_ts;
1672 					oldest_disassoc_sta_info =
1673 						temp_sta_info;
1674 				}
1675 				hdd_put_sta_info_ref(
1676 						sta_list, &temp_sta_info,
1677 						true,
1678 						STA_INFO_FILL_STATION_INFO);
1679 			}
1680 
1681 			/* Remove the oldest and store the current */
1682 			hdd_sta_info_detach(&adapter->cache_sta_info_list,
1683 					    &oldest_disassoc_sta_info);
1684 			hdd_sta_info_attach(&adapter->cache_sta_info_list,
1685 					    cache_sta_info);
1686 		}
1687 	} else {
1688 		qdf_copy_macaddr(&cache_sta_info->sta_mac, &event->staMac);
1689 		qdf_copy_macaddr(&cache_sta_info->mld_addr, &event->sta_mld);
1690 		hdd_put_sta_info_ref(&adapter->cache_sta_info_list,
1691 				     &cache_sta_info, true,
1692 				     STA_INFO_FILL_STATION_INFO);
1693 	}
1694 
1695 	hdd_debug("cap %d %d %d %d %d %d %d %d %d %x %d",
1696 		  stainfo->ampdu,
1697 		  stainfo->sgi_enable,
1698 		  stainfo->tx_stbc,
1699 		  stainfo->rx_stbc,
1700 		  stainfo->is_qos_enabled,
1701 		  stainfo->ch_width,
1702 		  stainfo->mode,
1703 		  event->wmmEnabled,
1704 		  event->chan_info.nss,
1705 		  event->chan_info.rate_flags,
1706 		  stainfo->max_phy_rate);
1707 	hdd_debug("rate info %d %d %d %d %d",
1708 		  stainfo->max_supp_idx,
1709 		  stainfo->max_ext_idx,
1710 		  stainfo->max_mcs_idx,
1711 		  stainfo->rx_mcs_map,
1712 		  stainfo->tx_mcs_map);
1713 exit:
1714 	hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
1715 			     STA_INFO_FILL_STATION_INFO);
1716 	return;
1717 }
1718 
hdd_stop_sap_due_to_invalid_channel(struct work_struct * work)1719 void hdd_stop_sap_due_to_invalid_channel(struct work_struct *work)
1720 {
1721 	struct hdd_adapter *sap_adapter = container_of(work, struct hdd_adapter,
1722 						       sap_stop_bss_work);
1723 	struct osif_vdev_sync *vdev_sync;
1724 	struct sap_context *sap_ctx;
1725 
1726 	if (osif_vdev_sync_op_start(sap_adapter->dev, &vdev_sync))
1727 		return;
1728 
1729 	hdd_debug("work started for sap session[%d]",
1730 		  sap_adapter->deflink->vdev_id);
1731 
1732 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(sap_adapter->deflink);
1733 	wlan_hdd_stop_sap(sap_adapter);
1734 	wlansap_cleanup_cac_timer(sap_ctx);
1735 	hdd_debug("work finished for sap");
1736 
1737 	osif_vdev_sync_op_stop(vdev_sync);
1738 }
1739 
1740 /**
1741  * hdd_hostapd_apply_action_oui() - Check for action_ouis to be applied on peers
1742  * @hdd_ctx: pointer to hdd context
1743  * @adapter: pointer to adapter
1744  * @event: assoc complete params
1745  *
1746  * This function is used to check whether aggressive tx should be disabled
1747  * based on the soft-ap configuration and action_oui ini
1748  * gActionOUIDisableAggressiveTX
1749  *
1750  * Return: None
1751  */
1752 static void
hdd_hostapd_apply_action_oui(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter,tSap_StationAssocReassocCompleteEvent * event)1753 hdd_hostapd_apply_action_oui(struct hdd_context *hdd_ctx,
1754 			     struct hdd_adapter *adapter,
1755 			     tSap_StationAssocReassocCompleteEvent *event)
1756 {
1757 	bool found;
1758 	uint32_t freq;
1759 	tSirMacHTChannelWidth ch_width;
1760 	enum sir_sme_phy_mode mode;
1761 	struct action_oui_search_attr attr = {0};
1762 	QDF_STATUS status;
1763 
1764 	ch_width = event->ch_width;
1765 	if (ch_width != eHT_CHANNEL_WIDTH_20MHZ)
1766 		return;
1767 
1768 	freq = event->chan_info.mhz;
1769 	if (WLAN_REG_IS_24GHZ_CH_FREQ(freq))
1770 		attr.enable_2g = true;
1771 	else if (WLAN_REG_IS_5GHZ_CH_FREQ(freq))
1772 		attr.enable_5g = true;
1773 	else
1774 		return;
1775 
1776 	mode = event->mode;
1777 	if (event->vht_caps.present && mode == SIR_SME_PHY_MODE_VHT)
1778 		attr.vht_cap = true;
1779 	else if (event->ht_caps.present && mode == SIR_SME_PHY_MODE_HT)
1780 		attr.ht_cap = true;
1781 
1782 	attr.mac_addr = (uint8_t *)(&event->staMac);
1783 
1784 	found = ucfg_action_oui_search(hdd_ctx->psoc,
1785 				       &attr,
1786 				       ACTION_OUI_DISABLE_AGGRESSIVE_TX);
1787 	if (!found)
1788 		return;
1789 
1790 	status = sme_set_peer_param(attr.mac_addr,
1791 				    WMI_PEER_PARAM_DISABLE_AGGRESSIVE_TX,
1792 				    true, adapter->deflink->vdev_id);
1793 	if (QDF_IS_STATUS_ERROR(status))
1794 		hdd_err("Failed to disable aggregation for peer");
1795 }
1796 
hdd_hostapd_set_sap_key(struct hdd_adapter * adapter)1797 static void hdd_hostapd_set_sap_key(struct hdd_adapter *adapter)
1798 {
1799 	struct wlan_crypto_key *crypto_key;
1800 	uint8_t key_index;
1801 
1802 	for (key_index = 0; key_index < WLAN_CRYPTO_TOTAL_KEYIDX; ++key_index) {
1803 		crypto_key = wlan_crypto_get_key(adapter->deflink->vdev,
1804 						 key_index);
1805 		if (!crypto_key)
1806 			continue;
1807 
1808 		hdd_debug("key idx %d", key_index);
1809 		ucfg_crypto_set_key_req(adapter->deflink->vdev, crypto_key,
1810 					WLAN_CRYPTO_KEY_TYPE_GROUP);
1811 		wma_update_set_key(adapter->deflink->vdev_id, false, key_index,
1812 				   crypto_key->cipher_type);
1813 	}
1814 }
1815 
1816 #ifdef WLAN_FEATURE_11BE
1817 static void
hdd_fill_channel_change_puncture(struct hdd_ap_ctx * ap_ctx,struct ch_params * sap_ch_param)1818 hdd_fill_channel_change_puncture(struct hdd_ap_ctx *ap_ctx,
1819 				 struct ch_params *sap_ch_param)
1820 {
1821 	ap_ctx->reg_punc_bitmap =
1822 			sap_ch_param->reg_punc_bitmap;
1823 }
1824 #else
1825 static void
hdd_fill_channel_change_puncture(struct hdd_ap_ctx * ap_ctx,struct ch_params * sap_ch_param)1826 hdd_fill_channel_change_puncture(struct hdd_ap_ctx *ap_ctx,
1827 				 struct ch_params *sap_ch_param)
1828 {
1829 }
1830 #endif
1831 
1832 /**
1833  * hdd_hostapd_chan_change() - prepare new operation chan info to kernel
1834  * @link_info: Link info pointer in HDD adapter
1835  * @sap_event: pointer to sap_event
1836  *
1837  * Return: QDF_STATUS
1838  */
hdd_hostapd_chan_change(struct wlan_hdd_link_info * link_info,struct sap_event * sap_event)1839 static QDF_STATUS hdd_hostapd_chan_change(struct wlan_hdd_link_info *link_info,
1840 					  struct sap_event *sap_event)
1841 {
1842 	struct ch_params sap_ch_param = {0};
1843 	eCsrPhyMode phy_mode;
1844 	bool legacy_phymode;
1845 	struct hdd_adapter *adapter = link_info->adapter;
1846 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1847 	struct sap_ch_selected_s *sap_chan_selected;
1848 	struct sap_config *sap_config =
1849 				&link_info->session.ap.sap_config;
1850 	struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
1851 
1852 	if (sap_event->sapHddEventCode == eSAP_CHANNEL_CHANGE_RESP)
1853 		sap_chan_selected =
1854 			&sap_event->sapevt.sap_chan_cng_rsp.sap_ch_selected;
1855 	else
1856 		sap_chan_selected = &sap_event->sapevt.sap_ch_selected;
1857 
1858 	sap_ch_param.ch_width = sap_chan_selected->ch_width;
1859 	sap_ch_param.mhz_freq_seg0 =
1860 		sap_chan_selected->vht_seg0_center_ch_freq;
1861 	sap_ch_param.mhz_freq_seg1 =
1862 		sap_chan_selected->vht_seg1_center_ch_freq;
1863 
1864 	if (sap_phymode_is_eht(sap_config->SapHw_mode))
1865 		wlan_reg_set_create_punc_bitmap(&sap_ch_param, true);
1866 	wlan_reg_set_channel_params_for_pwrmode(
1867 		hdd_ctx->pdev,
1868 		sap_chan_selected->pri_ch_freq,
1869 		sap_chan_selected->ht_sec_ch_freq,
1870 		&sap_ch_param, REG_CURRENT_PWR_MODE);
1871 
1872 	phy_mode = wlan_sap_get_phymode(
1873 			WLAN_HDD_GET_SAP_CTX_PTR(link_info));
1874 
1875 	switch (phy_mode) {
1876 	case eCSR_DOT11_MODE_11n:
1877 	case eCSR_DOT11_MODE_11n_ONLY:
1878 	case eCSR_DOT11_MODE_11ac:
1879 	case eCSR_DOT11_MODE_11ac_ONLY:
1880 	case eCSR_DOT11_MODE_11ax:
1881 	case eCSR_DOT11_MODE_11ax_ONLY:
1882 	case eCSR_DOT11_MODE_11be:
1883 	case eCSR_DOT11_MODE_11be_ONLY:
1884 		legacy_phymode = false;
1885 		break;
1886 	default:
1887 		legacy_phymode = true;
1888 		break;
1889 	}
1890 
1891 	hdd_fill_channel_change_puncture(ap_ctx, &sap_ch_param);
1892 	qdf_sched_work(0, &link_info->chan_change_notify_work);
1893 
1894 	return QDF_STATUS_SUCCESS;
1895 }
1896 
1897 static inline void
hdd_hostapd_update_beacon_country_ie(struct hdd_adapter * adapter)1898 hdd_hostapd_update_beacon_country_ie(struct hdd_adapter *adapter)
1899 {
1900 	struct hdd_station_info *sta_info, *tmp = NULL;
1901 	struct hdd_context *hdd_ctx;
1902 	struct hdd_ap_ctx *ap_ctx;
1903 	struct action_oui_search_attr attr = {0};
1904 	QDF_STATUS status;
1905 	bool found = false;
1906 
1907 	if (!adapter) {
1908 		hdd_err("invalid adapter");
1909 		return;
1910 	}
1911 
1912 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1913 	if (!hdd_ctx) {
1914 		hdd_err("HDD context is null");
1915 		return;
1916 	}
1917 
1918 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink);
1919 
1920 	hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
1921 				  STA_INFO_HOSTAPD_SAP_EVENT_CB) {
1922 		if (!sta_info->assoc_req_ies.len)
1923 			goto release_ref;
1924 
1925 		qdf_mem_zero(&attr, sizeof(struct action_oui_search_attr));
1926 		attr.ie_data = sta_info->assoc_req_ies.ptr;
1927 		attr.ie_length = sta_info->assoc_req_ies.len;
1928 
1929 		found = ucfg_action_oui_search(hdd_ctx->psoc,
1930 					       &attr,
1931 					       ACTION_OUI_TAKE_ALL_BAND_INFO);
1932 		if (found) {
1933 			if (!ap_ctx->country_ie_updated) {
1934 				status = sme_update_beacon_country_ie(
1935 						hdd_ctx->mac_handle,
1936 						adapter->deflink->vdev_id,
1937 						true);
1938 				if (status == QDF_STATUS_SUCCESS)
1939 					ap_ctx->country_ie_updated = true;
1940 				else
1941 					hdd_err("fail to update country ie");
1942 			}
1943 			hdd_put_sta_info_ref(&adapter->sta_info_list,
1944 					     &sta_info, true,
1945 					     STA_INFO_HOSTAPD_SAP_EVENT_CB);
1946 			if (tmp)
1947 				hdd_put_sta_info_ref(
1948 					&adapter->sta_info_list,
1949 					&tmp, true,
1950 					STA_INFO_HOSTAPD_SAP_EVENT_CB);
1951 			return;
1952 		}
1953 release_ref:
1954 		hdd_put_sta_info_ref(&adapter->sta_info_list,
1955 				     &sta_info, true,
1956 				     STA_INFO_HOSTAPD_SAP_EVENT_CB);
1957 	}
1958 
1959 	if (ap_ctx->country_ie_updated) {
1960 		status = sme_update_beacon_country_ie(
1961 					    hdd_ctx->mac_handle,
1962 					    adapter->deflink->vdev_id, false);
1963 		if (status == QDF_STATUS_SUCCESS)
1964 			ap_ctx->country_ie_updated = false;
1965 		else
1966 			hdd_err("fail to update country ie");
1967 	}
1968 }
1969 
1970 #ifdef WLAN_MLD_AP_STA_CONNECT_SUPPORT
1971 static void
hdd_hostapd_sap_fill_peer_ml_info(struct hdd_adapter * adapter,struct station_info * sta_info,uint8_t * peer_mac)1972 hdd_hostapd_sap_fill_peer_ml_info(struct hdd_adapter *adapter,
1973 				  struct station_info *sta_info,
1974 				  uint8_t *peer_mac)
1975 {
1976 	bool is_mlo_vdev;
1977 	QDF_STATUS status;
1978 	struct wlan_objmgr_vdev *vdev;
1979 	struct wlan_objmgr_peer *sta_peer;
1980 
1981 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_ID);
1982 	if (!vdev) {
1983 		hdd_err("Failed to get link id, VDEV NULL");
1984 		return;
1985 	}
1986 
1987 	is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
1988 	if (is_mlo_vdev)
1989 		sta_info->link_id = wlan_vdev_get_link_id(vdev);
1990 	else
1991 		sta_info->link_id = -1;
1992 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
1993 
1994 	if (!is_mlo_vdev)
1995 		return;
1996 
1997 	sta_peer = wlan_objmgr_get_peer_by_mac(adapter->hdd_ctx->psoc,
1998 					       peer_mac, WLAN_OSIF_ID);
1999 
2000 	if (!sta_peer) {
2001 		hdd_err("Peer not found with MAC " QDF_MAC_ADDR_FMT,
2002 			QDF_MAC_ADDR_REF(peer_mac));
2003 		return;
2004 	}
2005 	qdf_mem_copy(sta_info->mld_addr, wlan_peer_mlme_get_mldaddr(sta_peer),
2006 		     ETH_ALEN);
2007 
2008 	status = ucfg_mlme_peer_get_assoc_rsp_ies(
2009 					sta_peer,
2010 					&sta_info->assoc_resp_ies,
2011 					&sta_info->assoc_resp_ies_len);
2012 	wlan_objmgr_peer_release_ref(sta_peer, WLAN_OSIF_ID);
2013 }
2014 #elif defined(CFG80211_MLD_AP_STA_CONNECT_UPSTREAM_SUPPORT)
2015 static void
hdd_hostapd_sap_fill_peer_ml_info(struct hdd_adapter * adapter,struct station_info * sta_info,uint8_t * peer_mac)2016 hdd_hostapd_sap_fill_peer_ml_info(struct hdd_adapter *adapter,
2017 				  struct station_info *sta_info,
2018 				  uint8_t *peer_mac)
2019 {
2020 	bool is_mlo_vdev;
2021 	QDF_STATUS status;
2022 	struct wlan_objmgr_vdev *vdev;
2023 	struct wlan_objmgr_peer *sta_peer;
2024 
2025 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink,
2026 					   WLAN_HDD_ID_OBJ_MGR);
2027 	if (!vdev) {
2028 		hdd_err("Failed to get link id, VDEV NULL");
2029 		return;
2030 	}
2031 
2032 	is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
2033 	if (!is_mlo_vdev) {
2034 		sta_info->assoc_link_id = -1;
2035 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
2036 		return;
2037 	}
2038 
2039 	sta_info->assoc_link_id = wlan_vdev_get_link_id(vdev);
2040 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
2041 
2042 	sta_peer = wlan_objmgr_get_peer_by_mac(adapter->hdd_ctx->psoc,
2043 					       peer_mac, WLAN_HDD_ID_OBJ_MGR);
2044 
2045 	if (!sta_peer) {
2046 		hdd_err("Peer not found with MAC " QDF_MAC_ADDR_FMT,
2047 			QDF_MAC_ADDR_REF(peer_mac));
2048 		return;
2049 	}
2050 	qdf_mem_copy(sta_info->mld_addr, wlan_peer_mlme_get_mldaddr(sta_peer),
2051 		     ETH_ALEN);
2052 
2053 	status = ucfg_mlme_peer_get_assoc_rsp_ies(
2054 					sta_peer,
2055 					&sta_info->assoc_resp_ies,
2056 					&sta_info->assoc_resp_ies_len);
2057 	wlan_objmgr_peer_release_ref(sta_peer, WLAN_HDD_ID_OBJ_MGR);
2058 	sta_info->mlo_params_valid = true;
2059 }
2060 #else
2061 static void
hdd_hostapd_sap_fill_peer_ml_info(struct hdd_adapter * adapter,struct station_info * sta_info,uint8_t * peer_mac)2062 hdd_hostapd_sap_fill_peer_ml_info(struct hdd_adapter *adapter,
2063 				  struct station_info *sta_info,
2064 				  uint8_t *peer_mac)
2065 {
2066 }
2067 #endif
2068 
2069 static void
hdd_hostapd_check_channel_post_csa(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)2070 hdd_hostapd_check_channel_post_csa(struct hdd_context *hdd_ctx,
2071 				   struct hdd_adapter *adapter)
2072 {
2073 	struct hdd_ap_ctx *ap_ctx;
2074 	uint8_t sta_cnt, sap_cnt;
2075 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
2076 	struct sap_context *sap_ctx;
2077 	bool ch_valid;
2078 
2079 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink);
2080 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink);
2081 	if (!sap_ctx) {
2082 		hdd_err("sap ctx is null");
2083 		return;
2084 	}
2085 
2086 	/*
2087 	 * During CSA, it might be possible that ch avoidance event to
2088 	 * avoid the sap frequency is received. So, check after CSA,
2089 	 * whether sap frequency is safe if not restart sap to a safe
2090 	 * channel.
2091 	 */
2092 	ch_valid =
2093 	wlansap_validate_channel_post_csa(hdd_ctx->mac_handle,
2094 					  sap_ctx);
2095 	if (ap_ctx->sap_context->csa_reason ==
2096 	    CSA_REASON_UNSAFE_CHANNEL || !ch_valid)
2097 		qdf_status = hdd_unsafe_channel_restart_sap(hdd_ctx);
2098 	else if (ap_ctx->sap_context->csa_reason == CSA_REASON_DCS)
2099 		qdf_status = hdd_dcs_hostapd_set_chan(
2100 			hdd_ctx, adapter->deflink->vdev_id,
2101 			ap_ctx->operating_chan_freq);
2102 	if (qdf_status == QDF_STATUS_E_PENDING) {
2103 		hdd_debug("csa is pending with reason %d",
2104 			  ap_ctx->sap_context->csa_reason);
2105 		return;
2106 	}
2107 
2108 	/* Added the sta cnt check as we don't support sta+sap+nan
2109 	 * today. But this needs to be re-visited when we start
2110 	 * supporting this combo.
2111 	 */
2112 	sta_cnt = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
2113 							    PM_STA_MODE,
2114 							    NULL);
2115 	if (!sta_cnt)
2116 		qdf_status =
2117 		policy_mgr_nan_sap_post_enable_conc_check(hdd_ctx->psoc);
2118 	if (qdf_status == QDF_STATUS_E_PENDING) {
2119 		hdd_debug("csa is pending by nan sap conc");
2120 		return;
2121 	}
2122 
2123 	qdf_status = policy_mgr_check_sap_go_force_scc(
2124 			hdd_ctx->psoc, adapter->deflink->vdev,
2125 			ap_ctx->sap_context->csa_reason);
2126 	if (qdf_status == QDF_STATUS_E_PENDING) {
2127 		hdd_debug("csa is pending by sap go force scc");
2128 		return;
2129 	}
2130 
2131 	sap_cnt = policy_mgr_get_beaconing_mode_count(hdd_ctx->psoc, NULL);
2132 	if (sap_cnt > 1)
2133 		policy_mgr_check_concurrent_intf_and_restart_sap(
2134 				hdd_ctx->psoc,
2135 				ap_ctx->sap_config.acs_cfg.acs_mode);
2136 }
2137 
hdd_hostapd_sap_event_cb(struct sap_event * sap_event,void * context)2138 QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
2139 				    void *context)
2140 {
2141 	struct hdd_adapter *adapter;
2142 	struct hdd_ap_ctx *ap_ctx;
2143 	struct hdd_hostapd_state *hostapd_state;
2144 	struct net_device *dev;
2145 	eSapHddEvent event_id;
2146 	union iwreq_data wrqu;
2147 	uint8_t *we_custom_event_generic = NULL;
2148 	int we_event = 0;
2149 	uint8_t sta_id;
2150 	QDF_STATUS qdf_status;
2151 	bool bAuthRequired = true;
2152 	char *unknownSTAEvent = NULL;
2153 	char *maxAssocExceededEvent = NULL;
2154 	uint8_t *we_custom_start_event = NULL;
2155 	char *startBssEvent;
2156 	struct hdd_context *hdd_ctx;
2157 	struct iw_michaelmicfailure msg;
2158 	uint8_t ignoreCAC = 0;
2159 	bool cac_state = false;
2160 	struct hdd_config *cfg = NULL;
2161 	struct wlan_dfs_info dfs_info;
2162 	struct hdd_adapter *con_sap_adapter;
2163 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2164 	tSap_StationAssocReassocCompleteEvent *event;
2165 	tSap_StationSetKeyCompleteEvent *key_complete;
2166 	int ret = 0;
2167 	tSap_StationDisassocCompleteEvent *disassoc_comp;
2168 	struct hdd_station_info *stainfo, *cache_stainfo, *tmp = NULL;
2169 	mac_handle_t mac_handle;
2170 	struct sap_config *sap_config;
2171 	struct sap_context *sap_ctx = NULL;
2172 	uint8_t pdev_id;
2173 	bool notify_new_sta = true;
2174 	struct wlan_objmgr_vdev *vdev;
2175 	struct qdf_mac_addr sta_addr = {0};
2176 	qdf_freq_t dfs_freq;
2177 	struct wlan_hdd_link_info *link_info;
2178 	bool alt_pipe;
2179 
2180 	dev = context;
2181 	if (!dev) {
2182 		hdd_err("context is null");
2183 		return QDF_STATUS_E_FAILURE;
2184 	}
2185 
2186 	adapter = netdev_priv(dev);
2187 
2188 	if ((!adapter) ||
2189 	    (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
2190 		hdd_err("invalid adapter or adapter has invalid magic");
2191 		return QDF_STATUS_E_FAILURE;
2192 	}
2193 
2194 	link_info = adapter->deflink;
2195 	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
2196 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
2197 
2198 	if (!sap_event) {
2199 		hdd_err("sap_event is null");
2200 		return QDF_STATUS_E_FAILURE;
2201 	}
2202 
2203 	event_id = sap_event->sapHddEventCode;
2204 	memset(&wrqu, '\0', sizeof(wrqu));
2205 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2206 
2207 	if (!hdd_ctx) {
2208 		hdd_err("HDD context is null");
2209 		return QDF_STATUS_E_FAILURE;
2210 	}
2211 
2212 	cfg = hdd_ctx->config;
2213 
2214 	if (!cfg) {
2215 		hdd_err("HDD config is null");
2216 		return QDF_STATUS_E_FAILURE;
2217 	}
2218 
2219 	mac_handle = hdd_ctx->mac_handle;
2220 	dfs_info.channel = wlan_reg_freq_to_chan(
2221 			hdd_ctx->pdev, ap_ctx->operating_chan_freq);
2222 	wlan_reg_get_cc_and_src(hdd_ctx->psoc, dfs_info.country_code);
2223 	sta_id = sap_event->sapevt.sapStartBssCompleteEvent.staId;
2224 	sap_config = &ap_ctx->sap_config;
2225 
2226 	switch (event_id) {
2227 	case eSAP_START_BSS_EVENT:
2228 		hdd_debug("BSS status = %s, channel = %u, bc sta Id = %d",
2229 		       sap_event->sapevt.sapStartBssCompleteEvent.
2230 		       status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
2231 		       sap_event->sapevt.sapStartBssCompleteEvent.
2232 		       operating_chan_freq,
2233 		       sap_event->sapevt.sapStartBssCompleteEvent.staId);
2234 		ap_ctx->operating_chan_freq =
2235 			sap_event->sapevt.sapStartBssCompleteEvent
2236 			.operating_chan_freq;
2237 
2238 		link_info->vdev_id =
2239 			sap_event->sapevt.sapStartBssCompleteEvent.sessionId;
2240 		sap_config->chan_freq =
2241 			sap_event->sapevt.sapStartBssCompleteEvent.
2242 			operating_chan_freq;
2243 		sap_config->ch_params.ch_width =
2244 			sap_event->sapevt.sapStartBssCompleteEvent.ch_width;
2245 
2246 		hdd_nofl_info("AP started vid %d freq %d BW %d",
2247 			      link_info->vdev_id,
2248 			      ap_ctx->operating_chan_freq,
2249 			      sap_config->ch_params.ch_width);
2250 
2251 		hdd_cp_stats_cstats_sap_go_start_event(link_info, sap_event);
2252 
2253 		sap_config->ch_params = ap_ctx->sap_context->ch_params;
2254 		sap_config->sec_ch_freq = ap_ctx->sap_context->sec_ch_freq;
2255 
2256 		hostapd_state->qdf_status =
2257 			sap_event->sapevt.sapStartBssCompleteEvent.status;
2258 
2259 		qdf_atomic_set(&ap_ctx->ch_switch_in_progress, 0);
2260 		wlansap_get_dfs_ignore_cac(mac_handle, &ignoreCAC);
2261 		if (!policy_mgr_get_dfs_master_dynamic_enabled(
2262 				hdd_ctx->psoc, link_info->vdev_id))
2263 			ignoreCAC = true;
2264 
2265 		wlansap_get_dfs_cac_state(mac_handle, ap_ctx->sap_context,
2266 					  &cac_state);
2267 
2268 		/* DFS requirement: DO NOT transmit during CAC. */
2269 
2270 		/* Indoor channels are also marked DFS, therefore
2271 		 * check if the channel has REGULATORY_CHAN_RADAR
2272 		 * channel flag to identify if the channel is DFS
2273 		 */
2274 		if (!wlan_reg_is_dfs_for_freq(hdd_ctx->pdev,
2275 					      ap_ctx->operating_chan_freq) ||
2276 		    ignoreCAC ||
2277 		    hdd_ctx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE ||
2278 		    !cac_state)
2279 			ap_ctx->dfs_cac_block_tx = false;
2280 		else
2281 			ap_ctx->dfs_cac_block_tx = true;
2282 
2283 		ucfg_ipa_set_dfs_cac_tx(hdd_ctx->pdev,
2284 					ap_ctx->dfs_cac_block_tx);
2285 
2286 		vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID);
2287 		if (vdev) {
2288 			ucfg_dp_set_dfs_cac_tx(vdev, ap_ctx->dfs_cac_block_tx);
2289 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
2290 		}
2291 
2292 		hdd_debug("The value of dfs_cac_block_tx[%d] for ApCtx[%pK]:%d",
2293 				ap_ctx->dfs_cac_block_tx, ap_ctx,
2294 				link_info->vdev_id);
2295 
2296 		if (hostapd_state->qdf_status) {
2297 			hdd_err("startbss event failed!!");
2298 			/*
2299 			 * Make sure to set the event before proceeding
2300 			 * for error handling otherwise caller thread will
2301 			 * wait till 10 secs and no other connection will
2302 			 * go through before that.
2303 			 */
2304 			hostapd_state->bss_state = BSS_STOP;
2305 			vdev = hdd_objmgr_get_vdev_by_user(link_info,
2306 							   WLAN_DP_ID);
2307 			if (vdev) {
2308 				ucfg_dp_set_bss_state_start(vdev, false);
2309 				hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
2310 			}
2311 			qdf_event_set(&hostapd_state->qdf_event);
2312 			goto stopbss;
2313 		} else {
2314 			sme_ch_avoid_update_req(mac_handle);
2315 
2316 			ap_ctx->broadcast_sta_id =
2317 				sap_event->sapevt.sapStartBssCompleteEvent.staId;
2318 
2319 			cdp_hl_fc_set_td_limit(
2320 				cds_get_context(QDF_MODULE_ID_SOC),
2321 				link_info->vdev_id,
2322 				ap_ctx->operating_chan_freq);
2323 
2324 			hdd_register_tx_flow_control(adapter,
2325 				hdd_softap_tx_resume_timer_expired_handler,
2326 				hdd_softap_tx_resume_cb,
2327 				hdd_tx_flow_control_is_pause);
2328 
2329 			hdd_register_hl_netdev_fc_timer(
2330 				adapter,
2331 				hdd_tx_resume_timer_expired_handler);
2332 
2333 			/* @@@ need wep logic here to set privacy bit */
2334 			qdf_status =
2335 				hdd_softap_register_bc_sta(link_info,
2336 							   ap_ctx->privacy);
2337 			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
2338 				hdd_warn("Failed to register BC STA %d",
2339 				       qdf_status);
2340 				hdd_stop_bss_link(adapter);
2341 			}
2342 		}
2343 
2344 		if (ucfg_ipa_is_enabled()) {
2345 			status = hdd_ipa_get_tx_pipe(hdd_ctx, link_info,
2346 						     &alt_pipe);
2347 			if (!QDF_IS_STATUS_SUCCESS(status)) {
2348 				hdd_debug("Failed to get alt pipe for vdev %d",
2349 					  link_info->vdev_id);
2350 				alt_pipe = false;
2351 			}
2352 
2353 			status = ucfg_ipa_wlan_evt(
2354 					hdd_ctx->pdev,
2355 					adapter->dev,
2356 					adapter->device_mode,
2357 					link_info->vdev_id,
2358 					WLAN_IPA_AP_CONNECT,
2359 					adapter->dev->dev_addr,
2360 					alt_pipe);
2361 			if (status)
2362 				hdd_err("WLAN_AP_CONNECT event failed");
2363 		}
2364 
2365 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
2366 		wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
2367 #endif
2368 		hdd_hostapd_channel_prevent_suspend(adapter,
2369 			ap_ctx->operating_chan_freq,
2370 			&sap_config->ch_params);
2371 
2372 		hostapd_state->bss_state = BSS_START;
2373 		vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID);
2374 		if (vdev) {
2375 			ucfg_dp_set_bss_state_start(vdev, true);
2376 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
2377 		}
2378 		hdd_start_tsf_sync(adapter);
2379 
2380 		hdd_hostapd_set_sap_key(adapter);
2381 
2382 		/* Fill the params for sending IWEVCUSTOM Event
2383 		 * with SOFTAP.enabled
2384 		 */
2385 		we_custom_start_event =
2386 				qdf_mem_malloc(HDD_MAX_CUSTOM_START_EVENT_SIZE);
2387 		if (!we_custom_start_event)
2388 			goto stopbss;
2389 
2390 		startBssEvent = "SOFTAP.enabled";
2391 		memset(we_custom_start_event, '\0',
2392 		       sizeof(HDD_MAX_CUSTOM_START_EVENT_SIZE));
2393 		memcpy(we_custom_start_event, startBssEvent,
2394 		       strlen(startBssEvent));
2395 		memset(&wrqu, 0, sizeof(wrqu));
2396 		wrqu.data.length = strlen(startBssEvent);
2397 		we_event = IWEVCUSTOM;
2398 		we_custom_event_generic = we_custom_start_event;
2399 		wlan_hdd_set_tx_flow_info();
2400 		sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
2401 		if (!sap_ctx) {
2402 			hdd_err("sap ctx is null");
2403 			return QDF_STATUS_E_FAILURE;
2404 		}
2405 
2406 		if (sap_ctx->is_chan_change_inprogress) {
2407 			hdd_debug("check for possible hw mode change");
2408 			status = policy_mgr_set_hw_mode_on_channel_switch(
2409 				hdd_ctx->psoc, link_info->vdev_id);
2410 			if (QDF_IS_STATUS_ERROR(status))
2411 				hdd_debug("set hw mode change not done");
2412 		}
2413 
2414 		/*
2415 		 * Enable wds source port learning on the dp vdev in AP mode
2416 		 * when WDS feature is enabled.
2417 		 */
2418 		vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
2419 		if (vdev) {
2420 			if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE)
2421 				hdd_wds_config_dp_repeater_mode(vdev);
2422 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
2423 		}
2424 		/*
2425 		 * set this event at the very end because once this events
2426 		 * get set, caller thread is waiting to do further processing.
2427 		 * so once this event gets set, current worker thread might get
2428 		 * pre-empted by caller thread.
2429 		 */
2430 		qdf_status = qdf_event_set(&hostapd_state->qdf_event);
2431 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
2432 			hdd_err("qdf_event_set failed! status: %d", qdf_status);
2433 			goto stopbss;
2434 		}
2435 
2436 		wlan_hdd_apply_user_mcc_quota(adapter);
2437 		break;          /* Event will be sent after Switch-Case stmt */
2438 
2439 	case eSAP_STOP_BSS_EVENT:
2440 		hdd_debug("BSS stop status = %s",
2441 		       sap_event->sapevt.sapStopBssCompleteEvent.
2442 		       status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
2443 		hdd_cp_stats_cstats_sap_go_stop_event(link_info, sap_event);
2444 
2445 		hdd_hostapd_channel_allow_suspend(adapter,
2446 						  ap_ctx->operating_chan_freq,
2447 						  &ap_ctx->sap_context->ch_params);
2448 
2449 		/* Invalidate the channel info. */
2450 		ap_ctx->operating_chan_freq = 0;
2451 
2452 		qdf_atomic_set(&ap_ctx->ch_switch_in_progress, 0);
2453 
2454 		/* reset the dfs_cac_status and dfs_cac_block_tx flag only when
2455 		 * the last BSS is stopped
2456 		 */
2457 		con_sap_adapter = hdd_get_con_sap_adapter(adapter, true);
2458 		if (!con_sap_adapter) {
2459 			ap_ctx->dfs_cac_block_tx = true;
2460 			hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
2461 			vdev = hdd_objmgr_get_vdev_by_user(link_info,
2462 							   WLAN_DP_ID);
2463 			if (vdev) {
2464 				ucfg_dp_set_dfs_cac_tx(vdev,
2465 						ap_ctx->dfs_cac_block_tx);
2466 				hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
2467 			}
2468 		}
2469 		hdd_nofl_info("Ap stopped vid %d reason=%d",
2470 			      link_info->vdev_id,
2471 			      ap_ctx->bss_stop_reason);
2472 		qdf_status =
2473 			policy_mgr_get_mac_id_by_session_id(
2474 						    hdd_ctx->psoc,
2475 						    link_info->vdev_id,
2476 						    &pdev_id);
2477 		if (QDF_IS_STATUS_SUCCESS(qdf_status))
2478 			hdd_medium_assess_stop_timer(pdev_id, hdd_ctx);
2479 
2480 		/* clear the reason code in case BSS is stopped
2481 		 * in another place
2482 		 */
2483 		ap_ctx->bss_stop_reason = BSS_STOP_REASON_INVALID;
2484 		ap_ctx->ap_active = false;
2485 		goto stopbss;
2486 
2487 	case eSAP_DFS_CAC_START:
2488 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
2489 					WLAN_SVC_DFS_CAC_START_IND,
2490 					    &dfs_info,
2491 					    sizeof(struct wlan_dfs_info));
2492 		hdd_ctx->dev_dfs_cac_status = DFS_CAC_IN_PROGRESS;
2493 
2494 		hdd_cp_stats_cstats_log_sap_go_dfs_event(link_info,
2495 							 eSAP_DFS_CAC_START);
2496 
2497 		if (QDF_STATUS_SUCCESS !=
2498 			hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_START,
2499 				dfs_info, &adapter->wdev)) {
2500 			hdd_err("Unable to indicate CAC start NL event");
2501 		} else {
2502 			hdd_debug("Sent CAC start to user space");
2503 		}
2504 
2505 		qdf_atomic_set(&ap_ctx->ch_switch_in_progress, 0);
2506 		hdd_stop_tsf_sync(adapter);
2507 		break;
2508 	case eSAP_DFS_CAC_INTERRUPTED:
2509 		/*
2510 		 * The CAC timer did not run completely and a radar was detected
2511 		 * during the CAC time. This new state will keep the tx path
2512 		 * blocked since we do not want any transmission on the DFS
2513 		 * channel. CAC end will only be reported here since the user
2514 		 * space applications are waiting on CAC end for their state
2515 		 * management.
2516 		 */
2517 		hdd_cp_stats_cstats_log_sap_go_dfs_event
2518 					(link_info, eSAP_DFS_CAC_INTERRUPTED);
2519 		if (QDF_STATUS_SUCCESS !=
2520 			hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_END,
2521 				dfs_info, &adapter->wdev)) {
2522 			hdd_err("Unable to indicate CAC end (interrupted) event");
2523 		} else {
2524 			hdd_debug("Sent CAC end (interrupted) to user space");
2525 		}
2526 		dfs_freq = wlan_reg_chan_band_to_freq(hdd_ctx->pdev,
2527 						      dfs_info.channel,
2528 						      BIT(REG_BAND_5G));
2529 		hdd_son_deliver_cac_status_event(adapter, dfs_freq, true);
2530 		break;
2531 	case eSAP_DFS_CAC_END:
2532 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
2533 					WLAN_SVC_DFS_CAC_END_IND,
2534 					    &dfs_info,
2535 					    sizeof(struct wlan_dfs_info));
2536 		ap_ctx->dfs_cac_block_tx = false;
2537 		ucfg_ipa_set_dfs_cac_tx(hdd_ctx->pdev,
2538 					ap_ctx->dfs_cac_block_tx);
2539 		vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID);
2540 		if (vdev) {
2541 			ucfg_dp_set_dfs_cac_tx(vdev,
2542 					       ap_ctx->dfs_cac_block_tx);
2543 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
2544 		}
2545 
2546 		hdd_cp_stats_cstats_log_sap_go_dfs_event(link_info,
2547 							 eSAP_DFS_CAC_END);
2548 
2549 		hdd_ctx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
2550 		if (QDF_STATUS_SUCCESS !=
2551 			hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_END,
2552 				dfs_info, &adapter->wdev)) {
2553 			hdd_err("Unable to indicate CAC end NL event");
2554 		} else {
2555 			hdd_debug("Sent CAC end to user space");
2556 		}
2557 		dfs_freq = wlan_reg_chan_band_to_freq(hdd_ctx->pdev,
2558 						      dfs_info.channel,
2559 						      BIT(REG_BAND_5G));
2560 		hdd_son_deliver_cac_status_event(adapter, dfs_freq, false);
2561 		break;
2562 	case eSAP_DFS_RADAR_DETECT:
2563 	{
2564 		int i;
2565 
2566 		hdd_cp_stats_cstats_log_sap_go_dfs_event(link_info,
2567 							 eSAP_DFS_RADAR_DETECT);
2568 		hdd_dfs_indicate_radar(hdd_ctx);
2569 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
2570 					WLAN_SVC_DFS_RADAR_DETECT_IND,
2571 					    &dfs_info,
2572 					    sizeof(struct wlan_dfs_info));
2573 		hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
2574 		for (i = 0; i < sap_config->channel_info_count; i++) {
2575 			if (sap_config->channel_info[i].ieee_chan_number
2576 							== dfs_info.channel)
2577 				sap_config->channel_info[i].flags |=
2578 					IEEE80211_CHAN_RADAR_DFS;
2579 		}
2580 		if (QDF_STATUS_SUCCESS !=
2581 			hdd_send_radar_event(hdd_ctx, eSAP_DFS_RADAR_DETECT,
2582 				dfs_info, &adapter->wdev)) {
2583 			hdd_err("Unable to indicate Radar detect NL event");
2584 		} else {
2585 			hdd_debug("Sent radar detected to user space");
2586 		}
2587 		dfs_freq = wlan_reg_chan_band_to_freq(hdd_ctx->pdev,
2588 						      dfs_info.channel,
2589 						      BIT(REG_BAND_5G));
2590 		hdd_son_deliver_cac_status_event(adapter, dfs_freq, true);
2591 		break;
2592 	}
2593 
2594 	case eSAP_DFS_NO_AVAILABLE_CHANNEL:
2595 		wlan_hdd_send_svc_nlink_msg
2596 			(hdd_ctx->radio_index,
2597 			WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND, &dfs_info,
2598 			sizeof(struct wlan_dfs_info));
2599 		break;
2600 
2601 	case eSAP_STA_SET_KEY_EVENT:
2602 		/* TODO:
2603 		 * forward the message to hostapd once implementation
2604 		 * is done for now just print
2605 		 */
2606 		key_complete = &sap_event->sapevt.sapStationSetKeyCompleteEvent;
2607 		hdd_debug("SET Key: configured status = %s",
2608 			  key_complete->status ?
2609 			  "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
2610 
2611 		if (QDF_IS_STATUS_SUCCESS(key_complete->status)) {
2612 			hdd_softap_change_sta_state(adapter,
2613 						    &key_complete->peerMacAddr,
2614 						    OL_TXRX_PEER_STATE_AUTH);
2615 		status = wlan_hdd_send_sta_authorized_event(
2616 						adapter, hdd_ctx,
2617 						&key_complete->peerMacAddr);
2618 
2619 		}
2620 		return QDF_STATUS_SUCCESS;
2621 	case eSAP_STA_MIC_FAILURE_EVENT:
2622 	{
2623 		memset(&msg, '\0', sizeof(msg));
2624 		msg.src_addr.sa_family = ARPHRD_ETHER;
2625 		memcpy(msg.src_addr.sa_data,
2626 		       &sap_event->sapevt.sapStationMICFailureEvent.
2627 		       staMac, QDF_MAC_ADDR_SIZE);
2628 		hdd_debug("MIC MAC " QDF_MAC_ADDR_FMT,
2629 			  QDF_MAC_ADDR_REF(msg.src_addr.sa_data));
2630 		if (sap_event->sapevt.sapStationMICFailureEvent.
2631 		    multicast == true)
2632 			msg.flags = IW_MICFAILURE_GROUP;
2633 		else
2634 			msg.flags = IW_MICFAILURE_PAIRWISE;
2635 		memset(&wrqu, 0, sizeof(wrqu));
2636 		wrqu.data.length = sizeof(msg);
2637 		we_event = IWEVMICHAELMICFAILURE;
2638 		we_custom_event_generic = (uint8_t *) &msg;
2639 	}
2640 		/* inform mic failure to nl80211 */
2641 		cfg80211_michael_mic_failure(dev,
2642 					     sap_event->
2643 					     sapevt.sapStationMICFailureEvent.
2644 					     staMac.bytes,
2645 					     ((sap_event->sapevt.
2646 					       sapStationMICFailureEvent.
2647 					       multicast ==
2648 					       true) ?
2649 					      NL80211_KEYTYPE_GROUP :
2650 					      NL80211_KEYTYPE_PAIRWISE),
2651 					     sap_event->sapevt.
2652 					     sapStationMICFailureEvent.keyId,
2653 					     sap_event->sapevt.
2654 					     sapStationMICFailureEvent.TSC,
2655 					     GFP_KERNEL);
2656 		break;
2657 
2658 	case eSAP_STA_ASSOC_EVENT:
2659 	case eSAP_STA_REASSOC_EVENT:
2660 		event = &sap_event->sapevt.sapStationAssocReassocCompleteEvent;
2661 		hdd_cp_stats_cstats_log_sap_go_sta_assoc_reassoc_event
2662 							 (link_info, sap_event);
2663 		/* Reset scan reject params on assoc */
2664 		hdd_init_scan_reject_params(hdd_ctx);
2665 		if (eSAP_STATUS_FAILURE == event->status) {
2666 			hdd_info("assoc failure: " QDF_MAC_ADDR_FMT,
2667 				 QDF_MAC_ADDR_REF(wrqu.addr.sa_data));
2668 			hdd_place_marker(adapter, "CLIENT ASSOC FAILURE",
2669 					 wrqu.addr.sa_data);
2670 			break;
2671 		}
2672 
2673 		hdd_hostapd_apply_action_oui(hdd_ctx, adapter, event);
2674 
2675 		wrqu.addr.sa_family = ARPHRD_ETHER;
2676 		memcpy(wrqu.addr.sa_data,
2677 		       &event->staMac, QDF_MAC_ADDR_SIZE);
2678 		hdd_info("associated " QDF_MAC_ADDR_FMT,
2679 			 QDF_MAC_ADDR_REF(wrqu.addr.sa_data));
2680 		hdd_place_marker(adapter, "CLIENT ASSOCIATED",
2681 				 wrqu.addr.sa_data);
2682 		we_event = IWEVREGISTERED;
2683 
2684 		if ((eCSR_ENCRYPT_TYPE_NONE == ap_ctx->encryption_type) ||
2685 		    (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2686 		     ap_ctx->encryption_type)
2687 		    || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2688 			ap_ctx->encryption_type)) {
2689 			bAuthRequired = false;
2690 		}
2691 
2692 		qdf_status = hdd_softap_register_sta(link_info,
2693 						     bAuthRequired,
2694 						     ap_ctx->privacy,
2695 						     (struct qdf_mac_addr *)
2696 						           wrqu.addr.sa_data,
2697 						     event);
2698 		if (QDF_IS_STATUS_SUCCESS(qdf_status))
2699 			hdd_fill_station_info(adapter, event);
2700 		else
2701 			hdd_err("Failed to register STA %d "
2702 				QDF_MAC_ADDR_FMT, qdf_status,
2703 				QDF_MAC_ADDR_REF(wrqu.addr.sa_data));
2704 
2705 		sta_id = event->staId;
2706 
2707 		if (ucfg_ipa_is_enabled()) {
2708 			vdev = link_info->vdev;
2709 
2710 			if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
2711 			    !qdf_is_macaddr_zero(&event->sta_mld))
2712 				qdf_copy_macaddr(&sta_addr, &event->sta_mld);
2713 			else
2714 				qdf_copy_macaddr(&sta_addr, &event->staMac);
2715 
2716 			status = ucfg_ipa_wlan_evt(hdd_ctx->pdev,
2717 						   adapter->dev,
2718 						   adapter->device_mode,
2719 						   link_info->vdev_id,
2720 						   WLAN_IPA_CLIENT_CONNECT_EX,
2721 						   (const uint8_t *)
2722 						   &sta_addr.bytes[0],
2723 						   false);
2724 			if (status)
2725 				hdd_err("WLAN_CLIENT_CONNECT_EX event failed");
2726 		}
2727 
2728 		DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
2729 			link_info->vdev_id,
2730 			QDF_TRACE_DEFAULT_PDEV_ID,
2731 			QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
2732 
2733 		/* start timer in sap/p2p_go */
2734 		if (ap_ctx->ap_active == false) {
2735 			vdev = hdd_objmgr_get_vdev_by_user(link_info,
2736 							   WLAN_DP_ID);
2737 			if (vdev) {
2738 				ucfg_dp_bus_bw_compute_prev_txrx_stats(vdev);
2739 				hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
2740 			}
2741 			ucfg_dp_bus_bw_compute_timer_start(hdd_ctx->psoc);
2742 		}
2743 		ap_ctx->ap_active = true;
2744 
2745 		hdd_hostapd_update_beacon_country_ie(adapter);
2746 
2747 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
2748 		wlan_hdd_auto_shutdown_enable(hdd_ctx, false);
2749 #endif
2750 		cds_host_diag_log_work(&hdd_ctx->sap_wake_lock,
2751 				       HDD_SAP_WAKE_LOCK_DURATION,
2752 				       WIFI_POWER_EVENT_WAKELOCK_SAP);
2753 		qdf_wake_lock_timeout_acquire(&hdd_ctx->sap_wake_lock,
2754 					      HDD_SAP_WAKE_LOCK_DURATION);
2755 		{
2756 			struct station_info *sta_info;
2757 			uint32_t ies_len = event->ies_len;
2758 
2759 			sta_info = qdf_mem_malloc(sizeof(*sta_info));
2760 			if (!sta_info)
2761 				return QDF_STATUS_E_FAILURE;
2762 
2763 			sta_info->assoc_req_ies = event->ies;
2764 			sta_info->assoc_req_ies_len = ies_len;
2765 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
2766 			/*
2767 			 * After Kernel 4.0, it's no longer need to set
2768 			 * STATION_INFO_ASSOC_REQ_IES flag, as it
2769 			 * changed to use assoc_req_ies_len length to
2770 			 * check the existence of request IE.
2771 			 */
2772 			sta_info->filled |= STATION_INFO_ASSOC_REQ_IES;
2773 #endif
2774 			/* For ML clients need to fill assoc resp IEs
2775 			 * and MLD address.
2776 			 * For Legacy clients MLD address will be
2777 			 * NULL MAC address.
2778 			 */
2779 			hdd_hostapd_sap_fill_peer_ml_info(adapter, sta_info,
2780 							  event->staMac.bytes);
2781 
2782 			if (notify_new_sta)
2783 				cfg80211_new_sta(dev,
2784 						 (const u8 *)&event->
2785 						 staMac.bytes[0],
2786 						 sta_info, GFP_KERNEL);
2787 
2788 			if (adapter->device_mode == QDF_SAP_MODE &&
2789 			    ucfg_mlme_get_wds_mode(hdd_ctx->psoc))
2790 				hdd_softap_ind_l2_update(adapter,
2791 							 &event->staMac);
2792 			qdf_mem_free(sta_info);
2793 		}
2794 		/* Lets abort scan to ensure smooth authentication for client */
2795 		if (ucfg_scan_get_vdev_status(link_info->vdev) !=
2796 				SCAN_NOT_IN_PROGRESS) {
2797 			wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
2798 					link_info->vdev_id,
2799 					INVALID_SCAN_ID, false);
2800 		}
2801 		if (adapter->device_mode == QDF_P2P_GO_MODE) {
2802 			/* send peer status indication to oem app */
2803 			hdd_send_peer_status_ind_to_app(
2804 				&event->staMac,
2805 				ePeerConnected,
2806 				event->timingMeasCap,
2807 				link_info->vdev_id,
2808 				&event->chan_info,
2809 				adapter->device_mode);
2810 		}
2811 
2812 		hdd_green_ap_add_sta(hdd_ctx);
2813 		hdd_son_deliver_assoc_disassoc_event(adapter,
2814 						     event->staMac,
2815 						     event->status,
2816 						     ALD_ASSOC_EVENT);
2817 		break;
2818 
2819 	case eSAP_STA_DISASSOC_EVENT:
2820 		disassoc_comp =
2821 			&sap_event->sapevt.sapStationDisassocCompleteEvent;
2822 		memcpy(wrqu.addr.sa_data,
2823 		       &disassoc_comp->staMac, QDF_MAC_ADDR_SIZE);
2824 
2825 		/* Reset scan reject params on disconnect */
2826 		hdd_init_scan_reject_params(hdd_ctx);
2827 		cache_stainfo = hdd_get_sta_info_by_mac(
2828 						&adapter->cache_sta_info_list,
2829 						disassoc_comp->staMac.bytes,
2830 						STA_INFO_HOSTAPD_SAP_EVENT_CB);
2831 		if (cache_stainfo) {
2832 			/* Cache the disassoc info */
2833 			cache_stainfo->rssi = disassoc_comp->rssi;
2834 			cache_stainfo->tx_rate = disassoc_comp->tx_rate;
2835 			cache_stainfo->rx_rate = disassoc_comp->rx_rate;
2836 			cache_stainfo->rx_mc_bc_cnt =
2837 						disassoc_comp->rx_mc_bc_cnt;
2838 			cache_stainfo->rx_retry_cnt =
2839 						disassoc_comp->rx_retry_cnt;
2840 			cache_stainfo->reason_code = disassoc_comp->reason_code;
2841 			cache_stainfo->disassoc_ts = qdf_system_ticks();
2842 			hdd_debug("Cache_stainfo rssi %d txrate %d rxrate %d reason_code %d",
2843 				  cache_stainfo->rssi,
2844 				  cache_stainfo->tx_rate,
2845 				  cache_stainfo->rx_rate,
2846 				  cache_stainfo->reason_code);
2847 			hdd_put_sta_info_ref(&adapter->cache_sta_info_list,
2848 					     &cache_stainfo, true,
2849 					     STA_INFO_HOSTAPD_SAP_EVENT_CB);
2850 		}
2851 		hdd_nofl_info("SAP disassociated " QDF_MAC_ADDR_FMT,
2852 			      QDF_MAC_ADDR_REF(wrqu.addr.sa_data));
2853 		hdd_place_marker(adapter, "CLIENT DISASSOCIATED FROM SAP",
2854 				 wrqu.addr.sa_data);
2855 
2856 		hdd_cp_stats_cstats_log_sap_go_sta_disassoc_event(link_info,
2857 								  sap_event);
2858 
2859 		qdf_status = qdf_event_set(&hostapd_state->qdf_sta_disassoc_event);
2860 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
2861 			hdd_err("Station Deauth event Set failed");
2862 
2863 		if (sap_event->sapevt.sapStationDisassocCompleteEvent.reason ==
2864 		    eSAP_USR_INITATED_DISASSOC)
2865 			hdd_debug(" User initiated disassociation");
2866 		else
2867 			hdd_debug(" MAC initiated disassociation");
2868 		we_event = IWEVEXPIRED;
2869 
2870 		DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
2871 			link_info->vdev_id,
2872 			QDF_TRACE_DEFAULT_PDEV_ID,
2873 			QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC));
2874 
2875 		stainfo = hdd_get_sta_info_by_mac(
2876 						&adapter->sta_info_list,
2877 						disassoc_comp->staMac.bytes,
2878 						STA_INFO_HOSTAPD_SAP_EVENT_CB);
2879 		if (!stainfo) {
2880 			hdd_err("Failed to find the right station");
2881 			return QDF_STATUS_E_INVAL;
2882 		}
2883 
2884 		if (wlan_vdev_mlme_is_mlo_vdev(link_info->vdev) &&
2885 		    !qdf_is_macaddr_zero(&stainfo->mld_addr)) {
2886 			qdf_copy_macaddr(&sta_addr, &stainfo->mld_addr);
2887 		} else {
2888 			/* Copy legacy MAC address on
2889 			 * non-ML type client disassoc.
2890 			 */
2891 			qdf_copy_macaddr(&sta_addr, &disassoc_comp->staMac);
2892 		}
2893 
2894 		vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID);
2895 		if (vdev) {
2896 			ucfg_dp_update_dhcp_state_on_disassoc(vdev,
2897 						      &disassoc_comp->staMac);
2898 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
2899 		}
2900 
2901 		hdd_softap_deregister_sta(adapter, &stainfo);
2902 		hdd_put_sta_info_ref(&adapter->sta_info_list, &stainfo, true,
2903 				     STA_INFO_HOSTAPD_SAP_EVENT_CB);
2904 
2905 		ap_ctx->ap_active = false;
2906 
2907 		hdd_for_each_sta_ref_safe(adapter->sta_info_list, stainfo,
2908 					  tmp, STA_INFO_HOSTAPD_SAP_EVENT_CB) {
2909 			if (!qdf_is_macaddr_broadcast(
2910 			    &stainfo->sta_mac)) {
2911 				ap_ctx->ap_active = true;
2912 				hdd_put_sta_info_ref(
2913 						&adapter->sta_info_list,
2914 						&stainfo, true,
2915 						STA_INFO_HOSTAPD_SAP_EVENT_CB);
2916 				if (tmp)
2917 					hdd_put_sta_info_ref(
2918 						&adapter->sta_info_list,
2919 						&tmp, true,
2920 						STA_INFO_HOSTAPD_SAP_EVENT_CB);
2921 				break;
2922 			}
2923 			hdd_put_sta_info_ref(&adapter->sta_info_list,
2924 					     &stainfo, true,
2925 					     STA_INFO_HOSTAPD_SAP_EVENT_CB);
2926 		}
2927 
2928 		hdd_hostapd_update_beacon_country_ie(adapter);
2929 
2930 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
2931 		wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
2932 #endif
2933 
2934 		cds_host_diag_log_work(&hdd_ctx->sap_wake_lock,
2935 				       HDD_SAP_WAKE_LOCK_DURATION,
2936 				       WIFI_POWER_EVENT_WAKELOCK_SAP);
2937 		qdf_wake_lock_timeout_acquire(&hdd_ctx->sap_wake_lock,
2938 			 HDD_SAP_CLIENT_DISCONNECT_WAKE_LOCK_DURATION);
2939 
2940 		/*
2941 		 * Don't indicate delete station event if P2P GO and
2942 		 * SSR in progress. Since supplicant will change mode
2943 		 * fail and down during this time.
2944 		 */
2945 
2946 		if ((adapter->device_mode != QDF_P2P_GO_MODE) ||
2947 		     (!cds_is_driver_recovering())) {
2948 			cfg80211_del_sta(dev,
2949 					 (const u8 *)&sta_addr.bytes[0],
2950 					 GFP_KERNEL);
2951 			hdd_debug("indicate sta deletion event");
2952 		}
2953 
2954 		/* Update the beacon Interval if it is P2P GO */
2955 		qdf_status = policy_mgr_change_mcc_go_beacon_interval(
2956 			hdd_ctx->psoc, link_info->vdev_id,
2957 			adapter->device_mode);
2958 		if (QDF_STATUS_SUCCESS != qdf_status) {
2959 			hdd_err("Failed to update Beacon interval status: %d",
2960 				qdf_status);
2961 		}
2962 		if (adapter->device_mode == QDF_P2P_GO_MODE) {
2963 			/* send peer status indication to oem app */
2964 			hdd_send_peer_status_ind_to_app(&sap_event->sapevt.
2965 						sapStationDisassocCompleteEvent.
2966 						staMac, ePeerDisconnected,
2967 						0,
2968 						link_info->vdev_id,
2969 						NULL,
2970 						adapter->device_mode);
2971 		}
2972 
2973 		/*stop timer in sap/p2p_go */
2974 		if (ap_ctx->ap_active == false) {
2975 			vdev = hdd_objmgr_get_vdev_by_user(link_info,
2976 							   WLAN_DP_ID);
2977 			if (vdev) {
2978 				ucfg_dp_bus_bw_compute_reset_prev_txrx_stats(vdev);
2979 				hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
2980 			}
2981 			ucfg_dp_bus_bw_compute_timer_try_stop(hdd_ctx->psoc);
2982 		}
2983 		hdd_son_deliver_assoc_disassoc_event(adapter,
2984 						     disassoc_comp->staMac,
2985 						     disassoc_comp->reason_code,
2986 						     ALD_DISASSOC_EVENT);
2987 		hdd_green_ap_del_sta(hdd_ctx);
2988 		break;
2989 
2990 	case eSAP_WPS_PBC_PROBE_REQ_EVENT:
2991 		hdd_debug("WPS PBC probe req");
2992 		return QDF_STATUS_SUCCESS;
2993 
2994 	case eSAP_UNKNOWN_STA_JOIN:
2995 		unknownSTAEvent = qdf_mem_malloc(IW_CUSTOM_MAX + 1);
2996 		if (!unknownSTAEvent)
2997 			return QDF_STATUS_E_NOMEM;
2998 
2999 		snprintf(unknownSTAEvent, IW_CUSTOM_MAX,
3000 			 "JOIN_UNKNOWN_STA-"QDF_MAC_ADDR_FMT,
3001 			 QDF_MAC_ADDR_REF(sap_event->sapevt.sapUnknownSTAJoin.macaddr.bytes));
3002 		we_event = IWEVCUSTOM;  /* Discovered a new node (AP mode). */
3003 		wrqu.data.pointer = unknownSTAEvent;
3004 		wrqu.data.length = strlen(unknownSTAEvent);
3005 		we_custom_event_generic = (uint8_t *) unknownSTAEvent;
3006 		hdd_err("%s", unknownSTAEvent);
3007 		break;
3008 
3009 	case eSAP_MAX_ASSOC_EXCEEDED:
3010 		maxAssocExceededEvent = qdf_mem_malloc(IW_CUSTOM_MAX + 1);
3011 		if (!maxAssocExceededEvent)
3012 			return QDF_STATUS_E_NOMEM;
3013 
3014 		snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX,
3015 			 "Peer "QDF_MAC_ADDR_FMT" denied"
3016 			 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
3017 			 " one or more devices to enable the new device connection",
3018 			 QDF_MAC_ADDR_REF(sap_event->sapevt.sapMaxAssocExceeded.macaddr.bytes));
3019 		we_event = IWEVCUSTOM;  /* Discovered a new node (AP mode). */
3020 		wrqu.data.pointer = maxAssocExceededEvent;
3021 		wrqu.data.length = strlen(maxAssocExceededEvent);
3022 		we_custom_event_generic = (uint8_t *) maxAssocExceededEvent;
3023 		hdd_debug("%s", maxAssocExceededEvent);
3024 		break;
3025 	case eSAP_STA_ASSOC_IND:
3026 		if (sap_event->sapevt.sapAssocIndication.owe_ie) {
3027 			hdd_send_update_owe_info_event(adapter,
3028 			      sap_event->sapevt.sapAssocIndication.staMac.bytes,
3029 			      sap_event->sapevt.sapAssocIndication.owe_ie,
3030 			      sap_event->sapevt.sapAssocIndication.owe_ie_len);
3031 			qdf_mem_free(
3032 				   sap_event->sapevt.sapAssocIndication.owe_ie);
3033 			sap_event->sapevt.sapAssocIndication.owe_ie = NULL;
3034 			sap_event->sapevt.sapAssocIndication.owe_ie_len = 0;
3035 		}
3036 		return QDF_STATUS_SUCCESS;
3037 
3038 	case eSAP_DISCONNECT_ALL_P2P_CLIENT:
3039 		hdd_clear_all_sta(adapter);
3040 		return QDF_STATUS_SUCCESS;
3041 
3042 	case eSAP_MAC_TRIG_STOP_BSS_EVENT:
3043 		ret = hdd_stop_bss_link(adapter);
3044 		if (ret)
3045 			hdd_warn("hdd_stop_bss_link failed %d", ret);
3046 		return QDF_STATUS_SUCCESS;
3047 
3048 	case eSAP_CHANNEL_CHANGE_EVENT:
3049 		if (hostapd_state->bss_state != BSS_STOP) {
3050 			/* Allow suspend for old channel */
3051 			hdd_hostapd_channel_allow_suspend(adapter,
3052 				ap_ctx->sap_context->freq_before_ch_switch,
3053 				&ap_ctx->sap_context->ch_params_before_ch_switch);
3054 			/* Prevent suspend for new channel */
3055 			hdd_hostapd_channel_prevent_suspend(adapter,
3056 				sap_event->sapevt.sap_ch_selected.pri_ch_freq,
3057 				&ap_ctx->sap_context->ch_params);
3058 		}
3059 		/* SME/PE is already updated for new operation
3060 		 * channel. So update HDD layer also here. This
3061 		 * resolves issue in AP-AP mode where AP1 channel is
3062 		 * changed due to RADAR then CAC is going on and
3063 		 * START_BSS on new channel has not come to HDD. At
3064 		 * this case if AP2 is started it needs current
3065 		 * operation channel for MCC DFS restriction
3066 		 */
3067 		ap_ctx->operating_chan_freq =
3068 			sap_event->sapevt.sap_ch_selected.pri_ch_freq;
3069 		ap_ctx->sap_config.acs_cfg.pri_ch_freq =
3070 			sap_event->sapevt.sap_ch_selected.pri_ch_freq;
3071 		ap_ctx->sap_config.acs_cfg.ht_sec_ch_freq =
3072 			sap_event->sapevt.sap_ch_selected.ht_sec_ch_freq;
3073 		ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch_freq =
3074 		sap_event->sapevt.sap_ch_selected.vht_seg0_center_ch_freq;
3075 		ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch_freq =
3076 		sap_event->sapevt.sap_ch_selected.vht_seg1_center_ch_freq;
3077 		ap_ctx->sap_config.acs_cfg.ch_width =
3078 			sap_event->sapevt.sap_ch_selected.ch_width;
3079 
3080 		cdp_hl_fc_set_td_limit(cds_get_context(QDF_MODULE_ID_SOC),
3081 				       link_info->vdev_id,
3082 				       ap_ctx->operating_chan_freq);
3083 		sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
3084 		if (!sap_ctx) {
3085 			hdd_err("sap ctx is null");
3086 			return QDF_STATUS_E_FAILURE;
3087 		}
3088 
3089 		if (sap_ctx->is_chan_change_inprogress) {
3090 			hdd_debug("check for possible hw mode change");
3091 			status = policy_mgr_set_hw_mode_on_channel_switch(
3092 						hdd_ctx->psoc,
3093 						link_info->vdev_id);
3094 			if (QDF_IS_STATUS_ERROR(status))
3095 				hdd_debug("set hw mode change not done");
3096 		}
3097 
3098 		hdd_son_deliver_chan_change_event(
3099 			adapter, sap_event->sapevt.sap_ch_selected.pri_ch_freq);
3100 		return hdd_hostapd_chan_change(link_info, sap_event);
3101 	case eSAP_ACS_SCAN_SUCCESS_EVENT:
3102 		return hdd_handle_acs_scan_event(sap_event, adapter);
3103 
3104 	case eSAP_ACS_CHANNEL_SELECTED:
3105 		hdd_son_deliver_acs_complete_event(adapter);
3106 		ap_ctx->sap_config.acs_cfg.pri_ch_freq =
3107 			sap_event->sapevt.sap_ch_selected.pri_ch_freq;
3108 		ap_ctx->sap_config.acs_cfg.ht_sec_ch_freq =
3109 			sap_event->sapevt.sap_ch_selected.ht_sec_ch_freq;
3110 		ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch_freq =
3111 		sap_event->sapevt.sap_ch_selected.vht_seg0_center_ch_freq;
3112 		ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch_freq =
3113 		sap_event->sapevt.sap_ch_selected.vht_seg1_center_ch_freq;
3114 		ap_ctx->sap_config.acs_cfg.ch_width =
3115 			sap_event->sapevt.sap_ch_selected.ch_width;
3116 		hdd_nofl_info("ACS Completed vid %d freq %d BW %d",
3117 			      link_info->vdev_id,
3118 			      ap_ctx->sap_config.acs_cfg.pri_ch_freq,
3119 			      ap_ctx->sap_config.acs_cfg.ch_width);
3120 
3121 		if (qdf_atomic_read(&ap_ctx->acs_in_progress) &&
3122 		    test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
3123 			hdd_dcs_chan_select_complete(adapter);
3124 		} else {
3125 			wlan_hdd_cfg80211_acs_ch_select_evt(link_info, true);
3126 			wlansap_dcs_set_wlan_interference_mitigation_on_band(
3127 					WLAN_HDD_GET_SAP_CTX_PTR(link_info),
3128 					&ap_ctx->sap_config);
3129 		}
3130 
3131 		return QDF_STATUS_SUCCESS;
3132 	case eSAP_ECSA_CHANGE_CHAN_IND:
3133 		hdd_debug("Channel change indication from peer for channel freq %d",
3134 			  sap_event->sapevt.sap_chan_cng_ind.new_chan_freq);
3135 		wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc,
3136 					    link_info->vdev_id,
3137 					    CSA_REASON_PEER_ACTION_FRAME);
3138 		if (hdd_softap_set_channel_change(dev,
3139 			 sap_event->sapevt.sap_chan_cng_ind.new_chan_freq,
3140 			 CH_WIDTH_MAX, false))
3141 			return QDF_STATUS_E_FAILURE;
3142 		else
3143 			return QDF_STATUS_SUCCESS;
3144 
3145 	case eSAP_DFS_NEXT_CHANNEL_REQ:
3146 		hdd_debug("Sending next channel query to userspace");
3147 		hdd_update_acs_timer_reason(adapter,
3148 				QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS);
3149 		return QDF_STATUS_SUCCESS;
3150 
3151 	case eSAP_STOP_BSS_DUE_TO_NO_CHNL:
3152 		hdd_debug("Stop sap session[%d]",
3153 			  link_info->vdev_id);
3154 		schedule_work(&adapter->sap_stop_bss_work);
3155 		return QDF_STATUS_SUCCESS;
3156 
3157 	case eSAP_CHANNEL_CHANGE_RESP:
3158 		/*
3159 		 * Set the ch_switch_in_progress flag to zero and also enable
3160 		 * roaming once channel change process (success/failure)
3161 		 * is completed
3162 		 */
3163 		qdf_atomic_set(&ap_ctx->ch_switch_in_progress, 0);
3164 		policy_mgr_set_chan_switch_complete_evt(hdd_ctx->psoc);
3165 		wlan_hdd_set_roaming_state(link_info, RSO_SAP_CHANNEL_CHANGE,
3166 					   true);
3167 
3168 		/* Indoor channels are also marked DFS, therefore
3169 		 * check if the channel has REGULATORY_CHAN_RADAR
3170 		 * channel flag to identify if the channel is DFS
3171 		 */
3172 		if (!wlan_reg_is_dfs_for_freq(hdd_ctx->pdev,
3173 					      ap_ctx->operating_chan_freq)) {
3174 			ap_ctx->dfs_cac_block_tx = false;
3175 			vdev = hdd_objmgr_get_vdev_by_user(link_info,
3176 							   WLAN_DP_ID);
3177 			if (vdev) {
3178 				ucfg_dp_set_dfs_cac_tx(vdev,
3179 						ap_ctx->dfs_cac_block_tx);
3180 				hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
3181 			}
3182 		}
3183 
3184 		/* Check any other sap need restart */
3185 		hdd_hostapd_check_channel_post_csa(hdd_ctx, adapter);
3186 
3187 		qdf_status = qdf_event_set(&hostapd_state->qdf_event);
3188 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
3189 			hdd_err("qdf_event_set failed! status: %d",
3190 				qdf_status);
3191 		if (sap_event->sapevt.sap_chan_cng_rsp.ch_change_rsp_status !=
3192 		    eSAP_STATUS_SUCCESS) {
3193 			/* This is much more serious issue, we have to vacate
3194 			 * the channel due to the presence of radar or coex
3195 			 * but our channel change failed, stop the BSS operation
3196 			 * completely and inform hostapd
3197 			 */
3198 			hdd_debug("SAP[vdev%d] channel switch fail, will stop",
3199 				  link_info->vdev_id);
3200 			schedule_work(&adapter->sap_stop_bss_work);
3201 			return QDF_STATUS_SUCCESS;
3202 		} else {
3203 			return hdd_hostapd_chan_change(link_info, sap_event);
3204 		}
3205 	default:
3206 		hdd_debug("SAP message is not handled");
3207 		goto stopbss;
3208 		return QDF_STATUS_SUCCESS;
3209 	}
3210 
3211 	hdd_wext_send_event(dev, we_event, &wrqu,
3212 			    (char *)we_custom_event_generic);
3213 	qdf_mem_free(we_custom_start_event);
3214 	qdf_mem_free(unknownSTAEvent);
3215 	qdf_mem_free(maxAssocExceededEvent);
3216 
3217 	return QDF_STATUS_SUCCESS;
3218 
3219 stopbss:
3220 	{
3221 		uint8_t *we_custom_event;
3222 		char *stopBssEvent = "STOP-BSS.response";       /* 17 */
3223 		int event_len = strlen(stopBssEvent);
3224 
3225 		hdd_debug("BSS stop status = %s",
3226 		       sap_event->sapevt.sapStopBssCompleteEvent.status ?
3227 		       "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
3228 
3229 		/* Change the BSS state now since, as we are shutting
3230 		 * things down, we don't want interfaces to become
3231 		 * re-enabled
3232 		 */
3233 		hostapd_state->bss_state = BSS_STOP;
3234 		vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID);
3235 		if (vdev) {
3236 			ucfg_dp_set_bss_state_start(vdev, false);
3237 			hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
3238 		}
3239 
3240 		hdd_stop_tsf_sync(adapter);
3241 
3242 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
3243 		wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
3244 #endif
3245 
3246 		/* Stop the pkts from n/w stack as we are going to free all of
3247 		 * the TX WMM queues for all STAID's
3248 		 */
3249 		hdd_debug("Disabling queues");
3250 		wlan_hdd_netif_queue_control(adapter,
3251 					WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3252 					WLAN_CONTROL_PATH);
3253 
3254 		/* reclaim all resources allocated to the BSS */
3255 		qdf_status = hdd_softap_stop_bss(adapter);
3256 		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3257 			hdd_debug("hdd_softap_stop_bss failed %d",
3258 				  qdf_status);
3259 			if (ucfg_ipa_is_enabled()) {
3260 				ucfg_ipa_uc_disconnect_ap(hdd_ctx->pdev,
3261 							  adapter->dev);
3262 				ucfg_ipa_cleanup_dev_iface(hdd_ctx->pdev,
3263 							   adapter->dev,
3264 							   link_info->vdev_id);
3265 			}
3266 		}
3267 
3268 		we_custom_event =
3269 			qdf_mem_malloc(HDD_MAX_CUSTOM_START_EVENT_SIZE);
3270 		if (!we_custom_event)
3271 			return QDF_STATUS_E_NOMEM;
3272 
3273 		/* notify userspace that the BSS has stopped */
3274 		memset(we_custom_event, '\0',
3275 		       sizeof(HDD_MAX_CUSTOM_START_EVENT_SIZE));
3276 		memcpy(we_custom_event, stopBssEvent, event_len);
3277 		memset(&wrqu, 0, sizeof(wrqu));
3278 		wrqu.data.length = event_len;
3279 		we_event = IWEVCUSTOM;
3280 		we_custom_event_generic = we_custom_event;
3281 		hdd_wext_send_event(dev, we_event, &wrqu,
3282 				    (char *)we_custom_event_generic);
3283 
3284 		qdf_mem_free(we_custom_start_event);
3285 		qdf_mem_free(unknownSTAEvent);
3286 		qdf_mem_free(maxAssocExceededEvent);
3287 		qdf_mem_free(we_custom_event);
3288 
3289 		/* once the event is set, structure dev/adapter should
3290 		 * not be touched since they are now subject to being deleted
3291 		 * by another thread
3292 		 */
3293 		if (eSAP_STOP_BSS_EVENT == event_id) {
3294 			qdf_event_set(&hostapd_state->qdf_stop_bss_event);
3295 			ucfg_dp_bus_bw_compute_timer_try_stop(hdd_ctx->psoc);
3296 		}
3297 
3298 		wlan_hdd_set_tx_flow_info();
3299 	}
3300 	return QDF_STATUS_SUCCESS;
3301 }
3302 
hdd_softap_unpack_ie(mac_handle_t mac_handle,eCsrEncryptionType * encrypt_type,eCsrEncryptionType * mc_encrypt_type,tCsrAuthList * akm_list,bool * mfp_capable,bool * mfp_required,uint16_t gen_ie_len,uint8_t * gen_ie)3303 static int hdd_softap_unpack_ie(mac_handle_t mac_handle,
3304 				eCsrEncryptionType *encrypt_type,
3305 				eCsrEncryptionType *mc_encrypt_type,
3306 				tCsrAuthList *akm_list,
3307 				bool *mfp_capable,
3308 				bool *mfp_required,
3309 				uint16_t gen_ie_len, uint8_t *gen_ie)
3310 {
3311 	uint32_t ret;
3312 	uint8_t *rsn_ie;
3313 	uint16_t rsn_ie_len, i;
3314 	tDot11fIERSN dot11_rsn_ie = {0};
3315 	tDot11fIEWPA dot11_wpa_ie = {0};
3316 	tDot11fIEWAPI dot11_wapi_ie = {0};
3317 
3318 	if (!mac_handle) {
3319 		hdd_err("NULL mac Handle");
3320 		return -EINVAL;
3321 	}
3322 	/* Validity checks */
3323 	if ((gen_ie_len < QDF_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN))
3324 	    || (gen_ie_len >
3325 		QDF_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)))
3326 		return -EINVAL;
3327 	/* Type check */
3328 	if (gen_ie[0] == DOT11F_EID_RSN) {
3329 		/* Validity checks */
3330 		if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
3331 		    (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
3332 			return QDF_STATUS_E_FAILURE;
3333 		}
3334 		/* Skip past the EID byte and length byte */
3335 		rsn_ie = gen_ie + 2;
3336 		rsn_ie_len = gen_ie_len - 2;
3337 		/* Unpack the RSN IE */
3338 		memset(&dot11_rsn_ie, 0, sizeof(tDot11fIERSN));
3339 		ret = sme_unpack_rsn_ie(mac_handle, rsn_ie, rsn_ie_len,
3340 					&dot11_rsn_ie, false);
3341 		if (!DOT11F_SUCCEEDED(ret)) {
3342 			hdd_err("unpack failed, 0x%x", ret);
3343 			return -EINVAL;
3344 		}
3345 		/* Copy out the encryption and authentication types */
3346 		hdd_debug("pairwise cipher count: %d akm count:%d",
3347 			  dot11_rsn_ie.pwise_cipher_suite_count,
3348 			  dot11_rsn_ie.akm_suite_cnt);
3349 		/*
3350 		 * Translate akms in akm suite
3351 		 */
3352 		for (i = 0; i < dot11_rsn_ie.akm_suite_cnt; i++)
3353 			akm_list->authType[i] =
3354 				hdd_translate_rsn_to_csr_auth_type(
3355 						       dot11_rsn_ie.akm_suite[i]);
3356 		akm_list->numEntries = dot11_rsn_ie.akm_suite_cnt;
3357 		/* dot11_rsn_ie.pwise_cipher_suite_count */
3358 		*encrypt_type =
3359 			hdd_translate_rsn_to_csr_encryption_type(dot11_rsn_ie.
3360 								 pwise_cipher_suites[0]);
3361 		/* dot11_rsn_ie.gp_cipher_suite_count */
3362 		*mc_encrypt_type =
3363 			hdd_translate_rsn_to_csr_encryption_type(dot11_rsn_ie.
3364 								 gp_cipher_suite);
3365 		/* Set the PMKSA ID Cache for this interface */
3366 		*mfp_capable = 0 != (dot11_rsn_ie.RSN_Cap[0] & 0x80);
3367 		*mfp_required = 0 != (dot11_rsn_ie.RSN_Cap[0] & 0x40);
3368 	} else if (gen_ie[0] == DOT11F_EID_WPA) {
3369 		/* Validity checks */
3370 		if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
3371 		    (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
3372 			return QDF_STATUS_E_FAILURE;
3373 		}
3374 		/* Skip past the EID byte and length byte and 4 byte WiFi OUI */
3375 		rsn_ie = gen_ie + 2 + 4;
3376 		rsn_ie_len = gen_ie_len - (2 + 4);
3377 		/* Unpack the WPA IE */
3378 		memset(&dot11_wpa_ie, 0, sizeof(tDot11fIEWPA));
3379 		ret = dot11f_unpack_ie_wpa(MAC_CONTEXT(mac_handle),
3380 					   rsn_ie, rsn_ie_len,
3381 					   &dot11_wpa_ie, false);
3382 		if (!DOT11F_SUCCEEDED(ret)) {
3383 			hdd_err("unpack failed, 0x%x", ret);
3384 			return -EINVAL;
3385 		}
3386 		/* Copy out the encryption and authentication types */
3387 		hdd_debug("WPA unicast cipher suite count: %d akm count: %d",
3388 			  dot11_wpa_ie.unicast_cipher_count,
3389 			  dot11_wpa_ie.auth_suite_count);
3390 		/*
3391 		 * Translate akms in akm suite
3392 		 */
3393 		for (i = 0; i < dot11_wpa_ie.auth_suite_count; i++)
3394 			akm_list->authType[i] =
3395 				hdd_translate_wpa_to_csr_auth_type(
3396 						     dot11_wpa_ie.auth_suites[i]);
3397 		akm_list->numEntries = dot11_wpa_ie.auth_suite_count;
3398 		/* dot11_wpa_ie.unicast_cipher_count */
3399 		*encrypt_type =
3400 			hdd_translate_wpa_to_csr_encryption_type(dot11_wpa_ie.
3401 								 unicast_ciphers[0]);
3402 		/* dot11_wpa_ie.unicast_cipher_count */
3403 		*mc_encrypt_type =
3404 			hdd_translate_wpa_to_csr_encryption_type(dot11_wpa_ie.
3405 								 multicast_cipher);
3406 		*mfp_capable = false;
3407 		*mfp_required = false;
3408 	} else if (gen_ie[0] == DOT11F_EID_WAPI) {
3409 		/* Validity checks */
3410 		if ((gen_ie_len < DOT11F_IE_WAPI_MIN_LEN) ||
3411 		    (gen_ie_len > DOT11F_IE_WAPI_MAX_LEN))
3412 			return QDF_STATUS_E_FAILURE;
3413 
3414 		/* Skip past the EID byte and length byte */
3415 		rsn_ie = gen_ie + 2;
3416 		rsn_ie_len = gen_ie_len - 2;
3417 		/* Unpack the WAPI IE */
3418 		memset(&dot11_wapi_ie, 0, sizeof(tDot11fIEWPA));
3419 		ret = dot11f_unpack_ie_wapi(MAC_CONTEXT(mac_handle),
3420 					    rsn_ie, rsn_ie_len,
3421 					    &dot11_wapi_ie, false);
3422 		if (!DOT11F_SUCCEEDED(ret)) {
3423 			hdd_err("unpack failed, 0x%x", ret);
3424 			return -EINVAL;
3425 		}
3426 		/* Copy out the encryption and authentication types */
3427 		hdd_debug("WAPI unicast cipher suite count: %d akm count: %d",
3428 			  dot11_wapi_ie.unicast_cipher_suite_count,
3429 			  dot11_wapi_ie.akm_suite_count);
3430 		/*
3431 		 * Translate akms in akm suite
3432 		 */
3433 		for (i = 0; i < dot11_wapi_ie.akm_suite_count; i++)
3434 			akm_list->authType[i] =
3435 				hdd_translate_wapi_to_csr_auth_type(
3436 						dot11_wapi_ie.akm_suites[i]);
3437 
3438 		akm_list->numEntries = dot11_wapi_ie.akm_suite_count;
3439 		/* dot11_wapi_ie.akm_suite_count */
3440 		*encrypt_type =
3441 			hdd_translate_wapi_to_csr_encryption_type(
3442 				dot11_wapi_ie.unicast_cipher_suites[0]);
3443 		/* dot11_wapi_ie.unicast_cipher_count */
3444 		*mc_encrypt_type =
3445 			hdd_translate_wapi_to_csr_encryption_type(
3446 				dot11_wapi_ie.multicast_cipher_suite);
3447 		*mfp_capable = false;
3448 		*mfp_required = false;
3449 	} else {
3450 		hdd_err("gen_ie[0]: %d", gen_ie[0]);
3451 		return QDF_STATUS_E_FAILURE;
3452 	}
3453 	return QDF_STATUS_SUCCESS;
3454 }
3455 
hdd_is_any_sta_connecting(struct hdd_context * hdd_ctx)3456 bool hdd_is_any_sta_connecting(struct hdd_context *hdd_ctx)
3457 {
3458 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
3459 	struct hdd_station_ctx *sta_ctx;
3460 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_IS_ANY_STA_CONNECTING;
3461 	struct wlan_hdd_link_info *link_info;
3462 
3463 	if (!hdd_ctx) {
3464 		hdd_err("HDD context is NULL");
3465 		return false;
3466 	}
3467 
3468 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
3469 					   dbgid) {
3470 		if (adapter->device_mode != QDF_STA_MODE &&
3471 		    adapter->device_mode != QDF_P2P_CLIENT_MODE)
3472 			goto next_adapter;
3473 
3474 		hdd_adapter_for_each_active_link_info(adapter, link_info) {
3475 			sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
3476 			if (!hdd_cm_is_connecting(link_info))
3477 				continue;
3478 
3479 			hdd_debug("vdev_id %d: connecting", link_info->vdev_id);
3480 			hdd_adapter_dev_put_debug(adapter, dbgid);
3481 			if (next_adapter)
3482 				hdd_adapter_dev_put_debug(next_adapter, dbgid);
3483 			return true;
3484 		}
3485 next_adapter:
3486 		hdd_adapter_dev_put_debug(adapter, dbgid);
3487 	}
3488 
3489 	return false;
3490 }
3491 
hdd_softap_set_channel_change(struct net_device * dev,int target_chan_freq,enum phy_ch_width target_bw,bool forced)3492 int hdd_softap_set_channel_change(struct net_device *dev, int target_chan_freq,
3493 				  enum phy_ch_width target_bw, bool forced)
3494 {
3495 	QDF_STATUS status;
3496 	int ret = 0;
3497 	struct hdd_adapter *adapter = (netdev_priv(dev));
3498 	struct hdd_beacon_data *beacon = adapter->deflink->session.ap.beacon;
3499 	struct hdd_context *hdd_ctx = NULL;
3500 	struct hdd_adapter *sta_adapter;
3501 	struct hdd_station_ctx *sta_ctx;
3502 	struct sap_context *sap_ctx;
3503 	struct hdd_ap_ctx *ap_ctx;
3504 	uint8_t conc_rule1 = 0;
3505 	uint8_t  sta_sap_scc_on_dfs_chnl;
3506 	bool is_p2p_go_session = false;
3507 	struct wlan_objmgr_vdev *vdev;
3508 	bool strict;
3509 	uint32_t sta_cnt = 0;
3510 	struct ch_params ch_params = {0};
3511 	const u8 *rsn_ie, *rsnxe_ie;
3512 	struct wlan_crypto_params crypto_params = {0};
3513 	bool capable, is_wps;
3514 	int32_t keymgmt;
3515 	struct wlan_hdd_link_info *link_info;
3516 	enum policy_mgr_con_mode pm_con_mode;
3517 
3518 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3519 	ret = wlan_hdd_validate_context(hdd_ctx);
3520 	if (ret)
3521 		return ret;
3522 
3523 	if (adapter->device_mode != QDF_SAP_MODE &&
3524 	    adapter->device_mode != QDF_P2P_GO_MODE)
3525 		return -EINVAL;
3526 
3527 	link_info = adapter->deflink;
3528 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
3529 	if (!sap_ctx)
3530 		return -EINVAL;
3531 
3532 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
3533 	/*
3534 	 * If sta connection is in progress do not allow SAP channel change from
3535 	 * user space as it may change the HW mode requirement, for which sta is
3536 	 * trying to connect.
3537 	 */
3538 	if (hdd_is_any_sta_connecting(hdd_ctx)) {
3539 		hdd_err("STA connection is in progress");
3540 		return -EBUSY;
3541 	}
3542 
3543 	if (wlan_reg_is_6ghz_chan_freq(target_chan_freq) &&
3544 	    !wlan_reg_is_6ghz_band_set(hdd_ctx->pdev)) {
3545 		hdd_err("6 GHz band disabled");
3546 		return -EINVAL;
3547 	}
3548 
3549 	ret = hdd_validate_channel_and_bandwidth(adapter,
3550 						 target_chan_freq, target_bw);
3551 	if (ret) {
3552 		hdd_err("Invalid CH and BW combo");
3553 		return ret;
3554 	}
3555 
3556 	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(target_chan_freq)) {
3557 		rsn_ie = wlan_get_ie_ptr_from_eid(WLAN_EID_RSN,
3558 						  beacon->tail,
3559 						  beacon->tail_len);
3560 		rsnxe_ie = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_RSNXE,
3561 						    beacon->tail,
3562 						    beacon->tail_len);
3563 		if (rsn_ie)
3564 			wlan_crypto_rsnie_check(&crypto_params, rsn_ie);
3565 
3566 		keymgmt = wlan_crypto_get_param(sap_ctx->vdev,
3567 						WLAN_CRYPTO_PARAM_KEY_MGMT);
3568 		if (keymgmt < 0) {
3569 			hdd_err_rl("Invalid keymgmt");
3570 			return -EINVAL;
3571 		}
3572 
3573 		is_wps = adapter->device_mode == QDF_P2P_GO_MODE ? true : false;
3574 		capable = wlan_cm_6ghz_allowed_for_akm(hdd_ctx->psoc, keymgmt,
3575 						       crypto_params.rsn_caps,
3576 						       rsnxe_ie, 0, is_wps);
3577 		if (!capable) {
3578 			hdd_err_rl("6Ghz channel switch not capable");
3579 			return -EINVAL;
3580 		}
3581 	}
3582 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
3583 	ucfg_policy_mgr_get_conc_rule1(hdd_ctx->psoc, &conc_rule1);
3584 	/*
3585 	 * conc_custom_rule1:
3586 	 * Force SCC for SAP + STA
3587 	 * if STA is already connected then we shouldn't allow
3588 	 * channel switch in SAP interface.
3589 	 */
3590 	if (sta_adapter && conc_rule1) {
3591 		sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter->deflink);
3592 		if (hdd_cm_is_vdev_associated(sta_adapter->deflink)) {
3593 			hdd_err("Channel switch not allowed after STA connection with conc_custom_rule1 enabled");
3594 			return -EBUSY;
3595 		}
3596 	}
3597 
3598 	sta_cnt = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
3599 							    PM_STA_MODE,
3600 							    NULL);
3601 	/*
3602 	 * For non-dbs HW, don't allow Channel switch on DFS channel if STA is
3603 	 * not connected and sta_sap_scc_on_dfs_chnl is 1.
3604 	 */
3605 	status = policy_mgr_get_sta_sap_scc_on_dfs_chnl(
3606 				hdd_ctx->psoc, &sta_sap_scc_on_dfs_chnl);
3607 	if (QDF_STATUS_SUCCESS != status) {
3608 		return status;
3609 	}
3610 
3611 	if (!policy_mgr_is_sap_go_interface_allowed_on_indoor(
3612 						hdd_ctx->pdev,
3613 						link_info->vdev_id,
3614 						target_chan_freq)) {
3615 		hdd_debug("Channel switch is not allowed to indoor frequency %d",
3616 			  target_chan_freq);
3617 		return -EINVAL;
3618 	}
3619 
3620 	if (!sta_cnt && !policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) &&
3621 	    (sta_sap_scc_on_dfs_chnl ==
3622 	     PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED) &&
3623 	    (wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, target_chan_freq) ||
3624 	    (wlan_reg_is_5ghz_ch_freq(target_chan_freq) &&
3625 	     target_bw == CH_WIDTH_160MHZ))) {
3626 		hdd_debug("Channel switch not allowed for non-DBS HW on DFS channel %d width %d", target_chan_freq, target_bw);
3627 		return -EINVAL;
3628 	}
3629 
3630 	/*
3631 	 * Set the ch_switch_in_progress flag to mimic channel change
3632 	 * when a radar is found. This will enable synchronizing
3633 	 * SAP and HDD states similar to that of radar indication.
3634 	 * Suspend the netif queues to stop queuing Tx frames
3635 	 * from upper layers.  netif queues will be resumed
3636 	 * once the channel change is completed and SAP will
3637 	 * post eSAP_START_BSS_EVENT success event to HDD.
3638 	 */
3639 	if (qdf_atomic_inc_return(&ap_ctx->ch_switch_in_progress) > 1) {
3640 		hdd_err("Channel switch in progress!!");
3641 		return -EBUSY;
3642 	}
3643 	ch_params.ch_width = target_bw;
3644 	target_bw = wlansap_get_csa_chanwidth_from_phymode(
3645 			sap_ctx, target_chan_freq, &ch_params);
3646 	pm_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(hdd_ctx->psoc,
3647 							   adapter->device_mode,
3648 							   link_info->vdev_id);
3649 	/*
3650 	 * Do SAP concurrency check to cover channel switch case as following:
3651 	 * There is already existing SAP+GO combination but due to upper layer
3652 	 * notifying LTE-COEX event or sending command to move one connection
3653 	 * to different channel. Before moving existing connection to new
3654 	 * channel, check if new channel can co-exist with the other existing
3655 	 * connection. For example, SAP1 is on channel-6 and SAP2 is on
3656 	 * channel-36 and lets say they are doing DBS, and upper layer sends
3657 	 * LTE-COEX to move SAP1 from channel-6 to channel-149. SAP1 and
3658 	 * SAP2 will end up doing MCC which may not be desirable result. It
3659 	 * should will be prevented.
3660 	 */
3661 	if (!policy_mgr_allow_concurrency_csa(hdd_ctx->psoc, pm_con_mode,
3662 					      target_chan_freq,
3663 					      policy_mgr_get_bw(target_bw),
3664 					      link_info->vdev_id, forced,
3665 					      sap_ctx->csa_reason)) {
3666 		hdd_err("Channel switch failed due to concurrency check failure");
3667 		qdf_atomic_set(&ap_ctx->ch_switch_in_progress, 0);
3668 		return -EINVAL;
3669 	}
3670 
3671 	/*
3672 	 * Reject channel change req  if reassoc in progress on any adapter.
3673 	 * sme_is_any_session_in_middle_of_roaming is for LFR2 and
3674 	 * hdd_is_roaming_in_progress is for LFR3
3675 	 */
3676 	if (sme_is_any_session_in_middle_of_roaming(hdd_ctx->mac_handle) ||
3677 	    hdd_is_roaming_in_progress(hdd_ctx)) {
3678 		hdd_info("Channel switch not allowed as reassoc in progress");
3679 		qdf_atomic_set(&ap_ctx->ch_switch_in_progress, 0);
3680 		return -EINVAL;
3681 	}
3682 	/* Disable Roaming on all adapters before doing channel change */
3683 	wlan_hdd_set_roaming_state(link_info, RSO_SAP_CHANNEL_CHANGE, false);
3684 
3685 	/*
3686 	 * Post the Channel Change request to SAP.
3687 	 */
3688 
3689 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
3690 	if (!vdev) {
3691 		qdf_atomic_set(&ap_ctx->ch_switch_in_progress, 0);
3692 		wlan_hdd_set_roaming_state(link_info, RSO_SAP_CHANNEL_CHANGE,
3693 					   true);
3694 		return -EINVAL;
3695 	}
3696 	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
3697 		is_p2p_go_session = true;
3698 	else
3699 		forced = wlansap_override_csa_strict_for_sap(
3700 					hdd_ctx->mac_handle, sap_ctx,
3701 					target_chan_freq, forced);
3702 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
3703 
3704 	strict = is_p2p_go_session;
3705 	strict = strict || forced;
3706 	hdd_place_marker(adapter, "CHANNEL CHANGE", NULL);
3707 	status = wlansap_set_channel_change_with_csa(
3708 		WLAN_HDD_GET_SAP_CTX_PTR(link_info),
3709 		target_chan_freq, target_bw, strict);
3710 
3711 	if (QDF_STATUS_SUCCESS != status) {
3712 		hdd_err("SAP set channel failed for channel freq: %d, bw: %d",
3713 		        target_chan_freq, target_bw);
3714 		/*
3715 		 * If channel change command fails then clear the
3716 		 * radar found flag and also restart the netif
3717 		 * queues.
3718 		 */
3719 		qdf_atomic_set(&ap_ctx->ch_switch_in_progress, 0);
3720 
3721 		/*
3722 		 * If Posting of the Channel Change request fails
3723 		 * enable roaming on all adapters
3724 		 */
3725 		wlan_hdd_set_roaming_state(link_info, RSO_SAP_CHANNEL_CHANGE,
3726 					   true);
3727 
3728 		ret = -EINVAL;
3729 	}
3730 
3731 	return ret;
3732 }
3733 
3734 
3735 #if defined(FEATURE_WLAN_CH_AVOID) && defined(FEATURE_WLAN_CH_AVOID_EXT)
3736 /**
3737  * wlan_hdd_get_sap_restriction_mask() - get restriction mask for sap
3738  * after sap start
3739  * @hdd_ctx: hdd context
3740  *
3741  * Return: Restriction mask
3742  */
3743 static inline
wlan_hdd_get_sap_restriction_mask(struct hdd_context * hdd_ctx)3744 uint32_t wlan_hdd_get_sap_restriction_mask(struct hdd_context *hdd_ctx)
3745 {
3746 	return hdd_ctx->coex_avoid_freq_list.restriction_mask;
3747 }
3748 
3749 #else
3750 static inline
wlan_hdd_get_sap_restriction_mask(struct hdd_context * hdd_ctx)3751 uint32_t wlan_hdd_get_sap_restriction_mask(struct hdd_context *hdd_ctx)
3752 {
3753 	return -EINVAL;
3754 }
3755 #endif
3756 
hdd_stop_sap_set_tx_power(struct wlan_objmgr_psoc * psoc,struct hdd_adapter * adapter)3757 void hdd_stop_sap_set_tx_power(struct wlan_objmgr_psoc *psoc,
3758 			       struct hdd_adapter *adapter)
3759 {
3760 	struct wlan_objmgr_vdev *vdev =
3761 		hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_ID);
3762 	struct wlan_objmgr_pdev *pdev;
3763 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3764 	struct qdf_mac_addr bssid;
3765 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
3766 	int32_t set_tx_power, tx_power = 0;
3767 	struct sap_context *sap_ctx;
3768 	uint32_t restriction_mask;
3769 	int ch_loop, unsafe_chan_count;
3770 	struct unsafe_ch_list *unsafe_ch_list;
3771 	uint32_t chan_freq;
3772 	bool is_valid_txpower = false;
3773 
3774 	if (!vdev)
3775 		return;
3776 	pdev = wlan_vdev_get_pdev(vdev);
3777 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
3778 
3779 	psoc_priv_obj = reg_get_psoc_obj(psoc);
3780 	if (!psoc_priv_obj) {
3781 		reg_err("reg psoc private obj is NULL");
3782 		return;
3783 	}
3784 
3785 	restriction_mask = wlan_hdd_get_sap_restriction_mask(hdd_ctx);
3786 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink);
3787 	chan_freq = sap_ctx->chan_freq;
3788 	unsafe_ch_list = &psoc_priv_obj->unsafe_chan_list;
3789 
3790 	hdd_debug("Restriction_mask %d CSA reason %d ", restriction_mask,
3791 		  sap_ctx->csa_reason);
3792 
3793 	if (sap_ctx->csa_reason == CSA_REASON_UNSAFE_CHANNEL) {
3794 		if (restriction_mask & BIT(QDF_SAP_MODE)) {
3795 			schedule_work(&adapter->sap_stop_bss_work);
3796 		} else {
3797 			unsafe_chan_count = unsafe_ch_list->chan_cnt;
3798 			qdf_copy_macaddr(&bssid, &adapter->mac_addr);
3799 			set_tx_power =
3800 			wlan_reg_get_channel_reg_power_for_freq(pdev,
3801 								chan_freq);
3802 			for (ch_loop = 0; ch_loop < unsafe_chan_count;
3803 			     ch_loop++) {
3804 				if (unsafe_ch_list->chan_freq_list[ch_loop] ==
3805 				    chan_freq) {
3806 					tx_power =
3807 					unsafe_ch_list->txpower[ch_loop];
3808 					is_valid_txpower =
3809 					unsafe_ch_list->is_valid_txpower[ch_loop];
3810 					break;
3811 				}
3812 			}
3813 
3814 			if (is_valid_txpower)
3815 				set_tx_power = QDF_MIN(set_tx_power, tx_power);
3816 
3817 			if (QDF_STATUS_SUCCESS !=
3818 				sme_set_tx_power(hdd_ctx->mac_handle,
3819 						 adapter->deflink->vdev_id,
3820 						 bssid, adapter->device_mode,
3821 						 set_tx_power)) {
3822 				hdd_err("Setting tx power failed");
3823 			}
3824 		}
3825 	}
3826 }
3827 
3828 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
hdd_sap_restart_with_channel_switch(struct wlan_objmgr_psoc * psoc,struct hdd_adapter * ap_adapter,uint32_t target_chan_freq,uint32_t target_bw,bool forced)3829 QDF_STATUS hdd_sap_restart_with_channel_switch(struct wlan_objmgr_psoc *psoc,
3830 					       struct hdd_adapter *ap_adapter,
3831 					       uint32_t target_chan_freq,
3832 					       uint32_t target_bw,
3833 					       bool forced)
3834 {
3835 	struct net_device *dev = ap_adapter->dev;
3836 	int ret;
3837 
3838 	hdd_enter();
3839 
3840 	if (!dev) {
3841 		hdd_err("Invalid dev pointer");
3842 		return QDF_STATUS_E_INVAL;
3843 	}
3844 
3845 	ret = hdd_softap_set_channel_change(dev, target_chan_freq,
3846 					    target_bw, forced);
3847 	if (ret && ret != -EBUSY) {
3848 		hdd_err("channel switch failed");
3849 		hdd_stop_sap_set_tx_power(psoc, ap_adapter);
3850 	}
3851 
3852 	return qdf_status_from_os_return(ret);
3853 }
3854 
hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t ch_freq,uint32_t channel_bw,bool forced)3855 QDF_STATUS hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc,
3856 					  uint8_t vdev_id, uint32_t ch_freq,
3857 					  uint32_t channel_bw, bool forced)
3858 {
3859 	struct wlan_hdd_link_info *link_info;
3860 
3861 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
3862 	if (!link_info) {
3863 		hdd_err("Invalid vdev");
3864 		return QDF_STATUS_E_INVAL;
3865 	}
3866 
3867 	return hdd_sap_restart_with_channel_switch(psoc, link_info->adapter,
3868 						   ch_freq, channel_bw, forced);
3869 }
3870 
wlan_hdd_check_cc_intf_cb(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t * ch_freq)3871 QDF_STATUS wlan_hdd_check_cc_intf_cb(struct wlan_objmgr_psoc *psoc,
3872 				     uint8_t vdev_id, uint32_t *ch_freq)
3873 {
3874 	struct wlan_hdd_link_info *link_info;
3875 	struct sap_context *sap_context;
3876 
3877 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
3878 	if (!link_info) {
3879 		hdd_err("Invalid vdev");
3880 		return QDF_STATUS_E_FAILURE;
3881 	}
3882 
3883 	if (!test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
3884 		hdd_err("SOFTAP_BSS_STARTED not set");
3885 		return QDF_STATUS_E_FAILURE;
3886 	}
3887 
3888 	sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
3889 	if (!sap_context) {
3890 		hdd_err("sap_context is null");
3891 		return QDF_STATUS_E_FAILURE;
3892 	}
3893 
3894 	if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_context))) {
3895 		hdd_err("sap_context is invalid");
3896 		return QDF_STATUS_E_FAILURE;
3897 	}
3898 
3899 	*ch_freq = wlansap_check_cc_intf(sap_context);
3900 	wlansap_context_put(sap_context);
3901 
3902 	return QDF_STATUS_SUCCESS;
3903 }
3904 
wlan_hdd_set_sap_csa_reason(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t reason)3905 void wlan_hdd_set_sap_csa_reason(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
3906 				 uint8_t reason)
3907 {
3908 	struct wlan_hdd_link_info *link_info;
3909 	struct sap_context *sap_ctx;
3910 
3911 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
3912 	if (!link_info) {
3913 		hdd_err("Invalid vdev");
3914 		return;
3915 	}
3916 
3917 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
3918 	if (sap_ctx)
3919 		sap_ctx->csa_reason = reason;
3920 	hdd_nofl_debug("set csa reason %d %s vdev %d",
3921 		       reason, sap_get_csa_reason_str(reason), vdev_id);
3922 }
3923 
wlan_hdd_get_channel_for_sap_restart(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t * ch_freq)3924 QDF_STATUS wlan_hdd_get_channel_for_sap_restart(struct wlan_objmgr_psoc *psoc,
3925 						uint8_t vdev_id,
3926 						uint32_t *ch_freq)
3927 {
3928 	mac_handle_t mac_handle;
3929 	struct hdd_ap_ctx *hdd_ap_ctx;
3930 	struct hdd_context *hdd_ctx;
3931 	uint8_t mcc_to_scc_switch = 0;
3932 	struct ch_params ch_params = {0};
3933 	struct hdd_adapter *ap_adapter;
3934 	struct wlan_hdd_link_info *link_info;
3935 	uint32_t sap_ch_freq, intf_ch_freq, temp_ch_freq;
3936 	struct sap_context *sap_context;
3937 	enum sap_csa_reason_code csa_reason =
3938 		CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL;
3939 	QDF_STATUS status;
3940 	bool use_sap_original_bw = false;
3941 
3942 	if (!ch_freq) {
3943 		hdd_err("Null parameters");
3944 		return QDF_STATUS_E_FAILURE;
3945 	}
3946 
3947 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
3948 	if (!link_info) {
3949 		hdd_err("Invalid vdev");
3950 		return QDF_STATUS_E_FAILURE;
3951 	}
3952 
3953 	ap_adapter = link_info->adapter;
3954 	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
3955 	if (!hdd_ctx) {
3956 		hdd_err("hdd_ctx is NULL");
3957 		return QDF_STATUS_E_FAILURE;
3958 	}
3959 
3960 	if (!test_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags)) {
3961 		hdd_err("SOFTAP_BSS_STARTED not set");
3962 		return QDF_STATUS_E_FAILURE;
3963 	}
3964 
3965 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
3966 	mac_handle = hdd_ctx->mac_handle;
3967 	if (!mac_handle) {
3968 		hdd_err("mac_handle is NULL");
3969 		return QDF_STATUS_E_FAILURE;
3970 	}
3971 	sap_context = hdd_ap_ctx->sap_context;
3972 	if (!sap_context) {
3973 		hdd_err("sap_context is null");
3974 		return QDF_STATUS_E_FAILURE;
3975 	}
3976 	if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_context))) {
3977 		hdd_err("sap_context is invalid");
3978 		return QDF_STATUS_E_FAILURE;
3979 	}
3980 	wlan_hdd_set_sap_csa_reason(psoc, vdev_id, csa_reason);
3981 
3982 	policy_mgr_get_original_bw_for_sap_restart(psoc, &use_sap_original_bw);
3983 	if (use_sap_original_bw)
3984 		ch_params.ch_width = sap_context->ch_width_orig;
3985 	else
3986 		ch_params.ch_width = CH_WIDTH_MAX;
3987 
3988 	if (policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id)) {
3989 		/*
3990 		 * Adding this feature flag temporarily, will remove this once
3991 		 * feature flag is enabled.
3992 		 */
3993 #ifdef WLAN_FEATURE_LL_LT_SAP
3994 		intf_ch_freq =
3995 			wlan_get_ll_lt_sap_restart_freq(hdd_ctx->pdev,
3996 							sap_context->chan_freq,
3997 							sap_context->vdev_id,
3998 							&csa_reason);
3999 #else
4000 		intf_ch_freq = wlansap_get_chan_band_restrict(sap_context,
4001 							      &csa_reason);
4002 #endif
4003 		if (!intf_ch_freq) {
4004 			schedule_work(&ap_adapter->sap_stop_bss_work);
4005 			wlansap_context_put(sap_context);
4006 			hdd_debug("vdev %d stop ll_lt_sap, no channel found for csa",
4007 				  vdev_id);
4008 			return QDF_STATUS_E_FAILURE;
4009 		}
4010 	} else {
4011 		intf_ch_freq = wlansap_get_chan_band_restrict(sap_context,
4012 							      &csa_reason);
4013 	}
4014 	if (intf_ch_freq && intf_ch_freq != sap_context->chan_freq)
4015 		goto sap_restart;
4016 
4017 	/*
4018 	 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
4019 	 * enabled on DFS channel then move the SAP out of DFS channel
4020 	 * as soon as STA gets disconnect.
4021 	 */
4022 	if (policy_mgr_is_sap_restart_required_after_sta_disconnect(
4023 	    psoc, vdev_id, &intf_ch_freq,
4024 	    !!link_info->session.ap.sap_config.acs_cfg.acs_mode)) {
4025 		hdd_debug("Move the sap (vdev %d) to user configured channel %u",
4026 			  vdev_id, intf_ch_freq);
4027 		goto sap_restart;
4028 	}
4029 
4030 	if (ap_adapter->device_mode == QDF_P2P_GO_MODE &&
4031 	    !policy_mgr_go_scc_enforced(psoc)) {
4032 		wlansap_context_put(sap_context);
4033 		hdd_debug("p2p go no scc required");
4034 		return QDF_STATUS_E_FAILURE;
4035 	}
4036 	/*
4037 	 * If liberal mode is enabled. If P2P-Cli is not yet connected
4038 	 * Skipping CSA as this is done as part of set_key
4039 	 */
4040 
4041 	if (ap_adapter->device_mode == QDF_P2P_GO_MODE &&
4042 	    policy_mgr_go_scc_enforced(psoc) &&
4043 	    !policy_mgr_is_go_scc_strict(psoc) &&
4044 	    (wlan_vdev_get_peer_count(sap_context->vdev) == 1)) {
4045 		hdd_debug("p2p go liberal mode enabled. Skipping CSA");
4046 		wlansap_context_put(sap_context);
4047 		return QDF_STATUS_E_FAILURE;
4048 	}
4049 
4050 	ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc,
4051 					   &mcc_to_scc_switch);
4052 	policy_mgr_get_chan_by_session_id(psoc, vdev_id, &sap_ch_freq);
4053 	if (!policy_mgr_is_restart_sap_required(hdd_ctx->psoc, vdev_id,
4054 						sap_ch_freq,
4055 						mcc_to_scc_switch)) {
4056 		wlansap_context_put(sap_context);
4057 		hdd_debug("SAP needn't restart");
4058 		return QDF_STATUS_E_FAILURE;
4059 	}
4060 
4061 	/*
4062 	 * Check if STA's channel is DFS or passive or part of LTE avoided
4063 	 * channel list. In that case move SAP to other band if DBS is
4064 	 * supported, return from here if DBS is not supported.
4065 	 * Need to take care of 3 port cases with 2 STA iface in future.
4066 	 */
4067 	intf_ch_freq = wlansap_check_cc_intf(sap_context);
4068 	hdd_debug("sap_vdev %d intf_ch: %d, orig freq: %d",
4069 		  vdev_id, intf_ch_freq, sap_ch_freq);
4070 
4071 	temp_ch_freq = intf_ch_freq ? intf_ch_freq : sap_ch_freq;
4072 	wlansap_get_csa_chanwidth_from_phymode(sap_context, temp_ch_freq,
4073 					       &ch_params);
4074 	if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION !=
4075 		mcc_to_scc_switch) {
4076 		if (QDF_IS_STATUS_ERROR(
4077 		    policy_mgr_valid_sap_conc_channel_check(
4078 		    hdd_ctx->psoc, &intf_ch_freq, sap_ch_freq, vdev_id,
4079 		    &ch_params))) {
4080 			schedule_work(&ap_adapter->sap_stop_bss_work);
4081 			wlansap_context_put(sap_context);
4082 			hdd_debug("can't move sap to chan(freq): %u, stopping SAP",
4083 				  intf_ch_freq);
4084 			return QDF_STATUS_E_FAILURE;
4085 		}
4086 	}
4087 
4088 sap_restart:
4089 	if (!intf_ch_freq) {
4090 		hdd_debug("Unable to find safe channel, Hence stop the SAP or Set Tx power");
4091 		sap_context->csa_reason = csa_reason;
4092 		hdd_stop_sap_set_tx_power(psoc, ap_adapter);
4093 		wlansap_context_put(sap_context);
4094 		return QDF_STATUS_E_FAILURE;
4095 	} else {
4096 		sap_context->csa_reason = csa_reason;
4097 	}
4098 	if (ch_params.ch_width == CH_WIDTH_MAX)
4099 		wlansap_get_csa_chanwidth_from_phymode(
4100 					sap_context, intf_ch_freq,
4101 					&ch_params);
4102 
4103 	hdd_debug("mhz_freq_seg0: %d, ch_width: %d",
4104 		  ch_params.mhz_freq_seg0, ch_params.ch_width);
4105 	if (sap_context->csa_reason == CSA_REASON_UNSAFE_CHANNEL &&
4106 	    (!policy_mgr_check_bw_with_unsafe_chan_freq(hdd_ctx->psoc,
4107 							ch_params.mhz_freq_seg0,
4108 							ch_params.ch_width))) {
4109 		hdd_debug("SAP bw shrink to 20M for unsafe");
4110 		ch_params.ch_width = CH_WIDTH_20MHZ;
4111 	}
4112 
4113 	hdd_debug("SAP restart orig chan freq: %d, new freq: %d bw %d",
4114 		  hdd_ap_ctx->sap_config.chan_freq, intf_ch_freq,
4115 		  ch_params.ch_width);
4116 	hdd_ap_ctx->bss_stop_reason = BSS_STOP_DUE_TO_MCC_SCC_SWITCH;
4117 	*ch_freq = intf_ch_freq;
4118 	hdd_debug("SAP channel change with CSA/ECSA");
4119 	status = hdd_sap_restart_chan_switch_cb(psoc, vdev_id, *ch_freq,
4120 						ch_params.ch_width, false);
4121 	wlansap_context_put(sap_context);
4122 
4123 	return status;
4124 }
4125 
4126 QDF_STATUS
wlan_get_sap_acs_band(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t * acs_band)4127 wlan_get_sap_acs_band(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
4128 		      uint32_t *acs_band)
4129 {
4130 	struct wlan_hdd_link_info *link_info;
4131 	struct sap_config *sap_config;
4132 
4133 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
4134 	if (!link_info || (link_info->adapter->device_mode != QDF_P2P_GO_MODE &&
4135 			   link_info->adapter->device_mode != QDF_SAP_MODE)) {
4136 		hdd_err("Invalid vdev or device mode");
4137 		return QDF_STATUS_E_FAILURE;
4138 	}
4139 	/*
4140 	 * If acs mode is false, that means acs is disabled and acs band can be
4141 	 * QCA_ACS_MODE_IEEE80211ANY
4142 	 */
4143 	sap_config = &link_info->session.ap.sap_config;
4144 	if (!sap_config->acs_cfg.acs_mode)
4145 		*acs_band = QCA_ACS_MODE_IEEE80211ANY;
4146 	else
4147 		*acs_band = sap_config->acs_cfg.band;
4148 
4149 	return QDF_STATUS_SUCCESS;
4150 }
4151 
4152 QDF_STATUS
wlan_get_ap_prefer_conc_ch_params(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t chan_freq,struct ch_params * ch_params)4153 wlan_get_ap_prefer_conc_ch_params(
4154 		struct wlan_objmgr_psoc *psoc,
4155 		uint8_t vdev_id, uint32_t chan_freq,
4156 		struct ch_params *ch_params)
4157 {
4158 	struct hdd_ap_ctx *hdd_ap_ctx;
4159 	struct sap_context *sap_context;
4160 	struct wlan_hdd_link_info *link_info;
4161 
4162 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
4163 	if (!link_info || (link_info->adapter->device_mode != QDF_P2P_GO_MODE &&
4164 			   link_info->adapter->device_mode != QDF_SAP_MODE)) {
4165 		hdd_err("Invalid vdev or device mode");
4166 		return QDF_STATUS_E_FAILURE;
4167 	}
4168 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
4169 	sap_context = hdd_ap_ctx->sap_context;
4170 	if (!sap_context) {
4171 		hdd_err("sap_context is null");
4172 		return QDF_STATUS_E_FAILURE;
4173 	}
4174 	if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_context))) {
4175 		hdd_err("sap_context is invalid");
4176 		return QDF_STATUS_E_FAILURE;
4177 	}
4178 
4179 	wlansap_get_csa_chanwidth_from_phymode(sap_context,
4180 					       chan_freq,
4181 					       ch_params);
4182 	wlansap_context_put(sap_context);
4183 
4184 	return QDF_STATUS_SUCCESS;
4185 }
4186 
4187 #if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX)
hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)4188 uint32_t hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
4189 {
4190 	struct wlan_objmgr_vdev *vdev;
4191 	int32_t keymgmt;
4192 	struct hdd_adapter *ap_adapter;
4193 	struct wlan_hdd_link_info *link_info;
4194 	struct hdd_ap_ctx *ap_ctx;
4195 	struct sap_context *sap_context;
4196 	struct sap_config *sap_config;
4197 	uint32_t capable = 0;
4198 	enum policy_mgr_con_mode con_mode;
4199 
4200 	if (!psoc) {
4201 		hdd_err("PSOC is NULL");
4202 		return 0;
4203 	}
4204 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
4205 						    WLAN_HDD_ID_OBJ_MGR);
4206 	if (!vdev) {
4207 		hdd_err("vdev is NULL %d", vdev_id);
4208 		return 0;
4209 	}
4210 
4211 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
4212 	if (!link_info) {
4213 		hdd_err("Invalid vdev %d", vdev_id);
4214 		wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
4215 		return 0;
4216 	}
4217 
4218 	ap_adapter = link_info->adapter;
4219 	con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc,
4220 							ap_adapter->device_mode,
4221 							vdev_id);
4222 	if (!policy_mgr_is_beaconing_mode(con_mode) ||
4223 	    !policy_mgr_is_6ghz_conc_mode_supported(psoc, con_mode)) {
4224 		hdd_err("unexpected device mode %d", ap_adapter->device_mode);
4225 		wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
4226 		return 0;
4227 	}
4228 
4229 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
4230 	sap_config = &ap_ctx->sap_config;
4231 	sap_context = ap_ctx->sap_context;
4232 	if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_context))) {
4233 		hdd_err("sap_context is get failed %d", vdev_id);
4234 		wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
4235 		return 0;
4236 	}
4237 	/* SAP is allowed on 6GHz with explicit indication from user space:
4238 	 * a. SAP is started on 6Ghz already.
4239 	 * b. SAP is configured on 6Ghz fixed channel from userspace.
4240 	 * c. SAP is configured by ACS range which includes any 6Ghz channel.
4241 	 */
4242 	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->deflink->link_flags)) {
4243 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(
4244 				ap_ctx->operating_chan_freq))
4245 			capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED;
4246 	} else {
4247 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_config->chan_freq))
4248 			capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED;
4249 		else if (sap_context && WLAN_REG_IS_6GHZ_CHAN_FREQ(
4250 				sap_context->chan_freq))
4251 			capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED;
4252 	}
4253 	if (wlansap_is_6ghz_included_in_acs_range(sap_context))
4254 		capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED;
4255 
4256 	keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
4257 	if (keymgmt < 0) {
4258 		hdd_err("Invalid mgmt cipher");
4259 		wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
4260 		return 0;
4261 	}
4262 
4263 	/*
4264 	 * 6 GHz SAP is allowed in open mode only if the
4265 	 * check_6ghz_security ini is disabled.
4266 	 */
4267 	if (!cfg_get(psoc, CFG_CHECK_6GHZ_SECURITY) &&
4268 	    (!keymgmt || (keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_NONE))))
4269 		capable |= CONN_6GHZ_FLAG_SECURITY_ALLOWED;
4270 
4271 	if ((keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE |
4272 			1 << WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B |
4273 			1 << WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192 |
4274 			1 << WLAN_CRYPTO_KEY_MGMT_OWE |
4275 			1 << WLAN_CRYPTO_KEY_MGMT_SAE_EXT_KEY))) {
4276 		capable |= CONN_6GHZ_FLAG_SECURITY_ALLOWED;
4277 	}
4278 	capable |= CONN_6GHZ_FLAG_VALID;
4279 	hdd_debug("vdev_id %d keymgmt 0x%08x capable 0x%x",
4280 		  vdev_id, keymgmt, capable);
4281 	wlansap_context_put(sap_context);
4282 	wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
4283 
4284 	return capable;
4285 }
4286 #else
hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)4287 uint32_t hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
4288 {
4289 	return 0;
4290 }
4291 #endif
4292 #endif
4293 
4294 #ifdef WLAN_FEATURE_TSF_PTP
4295 static const struct ethtool_ops wlan_hostapd_ethtool_ops = {
4296 	.get_ts_info = wlan_get_ts_info,
4297 };
4298 #endif
4299 
4300 const struct net_device_ops net_ops_struct = {
4301 	.ndo_open = hdd_hostapd_open,
4302 	.ndo_stop = hdd_hostapd_stop,
4303 	.ndo_uninit = hdd_hostapd_uninit,
4304 	.ndo_start_xmit = hdd_softap_hard_start_xmit,
4305 	.ndo_tx_timeout = hdd_softap_tx_timeout,
4306 	.ndo_get_stats = hdd_get_stats,
4307 	.ndo_set_mac_address = hdd_hostapd_set_mac_address,
4308 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
4309 	.ndo_do_ioctl = hdd_ioctl,
4310 #endif
4311 	.ndo_change_mtu = hdd_hostapd_change_mtu,
4312 	.ndo_select_queue = hdd_select_queue,
4313 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
4314 	.ndo_siocdevprivate = hdd_dev_private_ioctl,
4315 #endif
4316 };
4317 
4318 #ifdef WLAN_FEATURE_TSF_PTP
hdd_set_ap_ops(struct net_device * dev)4319 void hdd_set_ap_ops(struct net_device *dev)
4320 {
4321 	dev->netdev_ops = &net_ops_struct;
4322 	dev->ethtool_ops = &wlan_hostapd_ethtool_ops;
4323 }
4324 #else
hdd_set_ap_ops(struct net_device * dev)4325 void hdd_set_ap_ops(struct net_device *dev)
4326 {
4327 	dev->netdev_ops = &net_ops_struct;
4328 }
4329 #endif
4330 
hdd_sap_create_ctx(struct hdd_adapter * adapter)4331 bool hdd_sap_create_ctx(struct hdd_adapter *adapter)
4332 {
4333 	hdd_debug("creating sap context");
4334 	adapter->deflink->session.ap.sap_context = sap_create_ctx();
4335 	if (adapter->deflink->session.ap.sap_context)
4336 		return true;
4337 
4338 	return false;
4339 }
4340 
hdd_sap_destroy_ctx(struct wlan_hdd_link_info * link_info)4341 bool hdd_sap_destroy_ctx(struct wlan_hdd_link_info *link_info)
4342 {
4343 	struct sap_context *sap_ctx = link_info->session.ap.sap_context;
4344 
4345 	if (link_info->session.ap.beacon) {
4346 		qdf_mem_free(link_info->session.ap.beacon);
4347 		link_info->session.ap.beacon = NULL;
4348 	}
4349 
4350 	if (!sap_ctx) {
4351 		hdd_debug("sap context is NULL");
4352 		return true;
4353 	}
4354 
4355 	hdd_debug("destroying sap context");
4356 
4357 	if (QDF_IS_STATUS_ERROR(sap_destroy_ctx(sap_ctx)))
4358 		return false;
4359 
4360 	link_info->session.ap.sap_context = NULL;
4361 
4362 	return true;
4363 }
4364 
hdd_sap_destroy_ctx_all(struct hdd_context * hdd_ctx,bool is_ssr)4365 void hdd_sap_destroy_ctx_all(struct hdd_context *hdd_ctx, bool is_ssr)
4366 {
4367 	struct hdd_adapter *adapter, *next_adapter = NULL;
4368 	struct wlan_hdd_link_info *link_info;
4369 
4370 	/* sap_ctx is not destroyed as it will be leveraged for sap restart */
4371 	if (is_ssr)
4372 		return;
4373 
4374 	hdd_debug("destroying all the sap context");
4375 
4376 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
4377 					   NET_DEV_HOLD_SAP_DESTROY_CTX_ALL) {
4378 		if (adapter->device_mode == QDF_SAP_MODE) {
4379 			hdd_adapter_for_each_active_link_info(adapter,
4380 							      link_info) {
4381 				hdd_sap_destroy_ctx(link_info);
4382 			}
4383 		}
4384 		hdd_adapter_dev_put_debug(adapter,
4385 					  NET_DEV_HOLD_SAP_DESTROY_CTX_ALL);
4386 	}
4387 }
4388 
4389 static void
hdd_indicate_peers_deleted(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)4390 hdd_indicate_peers_deleted(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
4391 {
4392 	struct wlan_hdd_link_info *link_info;
4393 
4394 	if (!psoc) {
4395 		hdd_err("psoc obj is NULL");
4396 		return;
4397 	}
4398 
4399 	link_info = wlan_hdd_get_link_info_from_vdev(psoc, vdev_id);
4400 	if (!link_info || hdd_validate_adapter(link_info->adapter)) {
4401 		hdd_err("invalid vdev or adapter");
4402 		return;
4403 	}
4404 
4405 	hdd_sap_indicate_disconnect_for_sta(link_info->adapter);
4406 }
4407 
hdd_init_ap_mode(struct hdd_adapter * adapter,bool reinit,bool rtnl_held)4408 QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter,
4409 			    bool reinit,
4410 			    bool rtnl_held)
4411 {
4412 	struct hdd_hostapd_state *phostapdBuf;
4413 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4414 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
4415 	struct sap_context *sap_ctx;
4416 	int ret;
4417 	enum dfs_mode acs_dfs_mode;
4418 	bool acs_with_more_param = 0;
4419 	uint8_t enable_sifs_burst = 0;
4420 	bool is_6g_sap_fd_enabled = 0;
4421 	struct wlan_objmgr_vdev *vdev;
4422 
4423 	hdd_enter();
4424 
4425 	hdd_debug("SSR in progress: %d", reinit);
4426 	qdf_atomic_init(&adapter->deflink->session.ap.acs_in_progress);
4427 
4428 	sap_ctx = hdd_hostapd_init_sap_session(adapter, reinit);
4429 	if (!sap_ctx) {
4430 		hdd_err("Invalid sap_ctx");
4431 		goto error_release_vdev;
4432 	}
4433 
4434 	if (!reinit) {
4435 		adapter->deflink->session.ap.sap_config.chan_freq =
4436 					      hdd_ctx->acs_policy.acs_chan_freq;
4437 		acs_dfs_mode = hdd_ctx->acs_policy.acs_dfs_mode;
4438 		adapter->deflink->session.ap.sap_config.acs_dfs_mode =
4439 			wlan_hdd_get_dfs_mode(acs_dfs_mode);
4440 	}
4441 
4442 	status = ucfg_mlme_get_acs_with_more_param(hdd_ctx->psoc,
4443 						   &acs_with_more_param);
4444 	if (!QDF_IS_STATUS_SUCCESS(status))
4445 		hdd_err("can't get sap acs with more param, use def");
4446 
4447 	wlan_sap_set_acs_with_more_param(hdd_ctx->mac_handle,
4448 					 acs_with_more_param);
4449 
4450 	/* Allocate the Wireless Extensions state structure */
4451 	phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter->deflink);
4452 
4453 	/* Zero the memory.  This zeros the profile structure. */
4454 	memset(phostapdBuf, 0, sizeof(struct hdd_hostapd_state));
4455 
4456 	status = qdf_event_create(&phostapdBuf->qdf_event);
4457 	if (!QDF_IS_STATUS_SUCCESS(status)) {
4458 		hdd_err("Hostapd HDD qdf event init failed!!");
4459 		goto error_deinit_sap_session;
4460 	}
4461 
4462 	status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event);
4463 	if (!QDF_IS_STATUS_SUCCESS(status)) {
4464 		hdd_err("Hostapd HDD stop bss event init failed!!");
4465 		goto error_deinit_sap_session;
4466 	}
4467 
4468 	status = qdf_event_create(&phostapdBuf->qdf_sta_disassoc_event);
4469 	if (!QDF_IS_STATUS_SUCCESS(status)) {
4470 		hdd_err("Hostapd HDD sta disassoc event init failed!!");
4471 		goto error_deinit_sap_session;
4472 	}
4473 
4474 	status = qdf_event_create(&phostapdBuf->qdf_sta_eap_frm_done_event);
4475 	if (!QDF_IS_STATUS_SUCCESS(status)) {
4476 		hdd_err("Hostapd HDD sta eap frm done event init failed!!");
4477 		goto error_deinit_sap_session;
4478 	}
4479 
4480 	/* Register as a wireless device */
4481 	hdd_register_hostapd_wext(adapter->dev);
4482 
4483 	/* Cache station count initialize to zero */
4484 	qdf_atomic_init(&adapter->cache_sta_count);
4485 
4486 	status = hdd_wmm_adapter_init(adapter);
4487 	if (!QDF_IS_STATUS_SUCCESS(status)) {
4488 		hdd_err("hdd_wmm_adapter_init() failed code: %08d [x%08x]",
4489 		       status, status);
4490 		goto error_release_softap_tx_rx;
4491 	}
4492 
4493 	set_bit(WMM_INIT_DONE, &adapter->event_flags);
4494 
4495 	status = ucfg_get_enable_sifs_burst(hdd_ctx->psoc, &enable_sifs_burst);
4496 	if (!QDF_IS_STATUS_SUCCESS(status))
4497 		hdd_err("Failed to get sifs burst value, use default");
4498 
4499 	ret = wma_cli_set_command(adapter->deflink->vdev_id,
4500 				  wmi_pdev_param_burst_enable,
4501 				  enable_sifs_burst,
4502 				  PDEV_CMD);
4503 	if (0 != ret)
4504 		hdd_err("wmi_pdev_param_burst_enable set failed: %d", ret);
4505 
4506 
4507 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_ID);
4508 	ucfg_mlme_is_6g_sap_fd_enabled(hdd_ctx->psoc, &is_6g_sap_fd_enabled);
4509 	hdd_debug("6g sap fd enabled %d", is_6g_sap_fd_enabled);
4510 	if (is_6g_sap_fd_enabled && vdev)
4511 		wlan_vdev_mlme_feat_ext_cap_set(vdev,
4512 						WLAN_VDEV_FEXT_FILS_DISC_6G_SAP);
4513 
4514 	if (vdev)
4515 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
4516 
4517 	hdd_set_netdev_flags(adapter);
4518 
4519 	if (!reinit) {
4520 		adapter->deflink->session.ap.sap_config.acs_cfg.acs_mode =
4521 									false;
4522 		wlansap_dcs_set_vdev_wlan_interference_mitigation(sap_ctx,
4523 								  false);
4524 		wlansap_dcs_set_vdev_starting(sap_ctx, false);
4525 		qdf_mem_zero(&adapter->deflink->session.ap.sap_config.acs_cfg,
4526 			     sizeof(struct sap_acs_cfg));
4527 	}
4528 
4529 	sme_set_del_peers_ind_callback(hdd_ctx->mac_handle,
4530 				       &hdd_indicate_peers_deleted);
4531 	/* rcpi info initialization */
4532 	qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
4533 
4534 	hdd_tsf_auto_report_init(adapter);
4535 	hdd_exit();
4536 
4537 	return status;
4538 
4539 error_release_softap_tx_rx:
4540 	hdd_wext_unregister(adapter->dev, rtnl_held);
4541 error_deinit_sap_session:
4542 	hdd_hostapd_deinit_sap_session(adapter->deflink);
4543 error_release_vdev:
4544 	hdd_exit();
4545 	return status;
4546 }
4547 
hdd_deinit_ap_mode(struct wlan_hdd_link_info * link_info)4548 void hdd_deinit_ap_mode(struct wlan_hdd_link_info *link_info)
4549 {
4550 	struct hdd_ap_ctx *ap_ctx;
4551 	struct hdd_adapter *adapter = link_info->adapter;
4552 
4553 	hdd_enter_dev(adapter->dev);
4554 
4555 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
4556 	if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
4557 		hdd_wmm_adapter_close(adapter);
4558 		clear_bit(WMM_INIT_DONE, &adapter->event_flags);
4559 	}
4560 
4561 	qdf_atomic_set(&ap_ctx->acs_in_progress, 0);
4562 	if (qdf_atomic_read(&ap_ctx->ch_switch_in_progress)) {
4563 		qdf_atomic_set(&ap_ctx->ch_switch_in_progress, 0);
4564 		policy_mgr_set_chan_switch_complete_evt(adapter->hdd_ctx->psoc);
4565 
4566 		/* Re-enable roaming on all connected STA vdev */
4567 		wlan_hdd_set_roaming_state(link_info,
4568 					   RSO_SAP_CHANNEL_CHANGE, true);
4569 	}
4570 
4571 	if (hdd_hostapd_deinit_sap_session(link_info))
4572 		hdd_err("Failed:hdd_hostapd_deinit_sap_session");
4573 
4574 	hdd_exit();
4575 }
4576 
4577 /**
4578  * hdd_wlan_create_ap_dev() - create an AP-mode device
4579  * @hdd_ctx: Global HDD context
4580  * @mac_addr: MAC address to assign to the interface
4581  * @name_assign_type: the name of assign type of the netdev
4582  * @iface_name: User-visible name of the interface
4583  *
4584  * This function will allocate a Linux net_device and configuration it
4585  * for an AP mode of operation.  Note that the device is NOT actually
4586  * registered with the kernel at this time.
4587  *
4588  * Return: A pointer to the private data portion of the net_device if
4589  * the allocation and initialization was successful, NULL otherwise.
4590  */
hdd_wlan_create_ap_dev(struct hdd_context * hdd_ctx,tSirMacAddr mac_addr,unsigned char name_assign_type,uint8_t * iface_name)4591 struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx,
4592 				      tSirMacAddr mac_addr,
4593 				      unsigned char name_assign_type,
4594 				      uint8_t *iface_name)
4595 {
4596 	struct net_device *dev;
4597 	struct hdd_adapter *adapter;
4598 
4599 	hdd_debug("iface_name = %s", iface_name);
4600 
4601 	dev = alloc_netdev_mqs(sizeof(struct hdd_adapter), iface_name,
4602 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
4603 			       name_assign_type,
4604 #endif
4605 			       ether_setup, NUM_TX_QUEUES, NUM_RX_QUEUES);
4606 
4607 	if (!dev)
4608 		return NULL;
4609 
4610 	adapter = netdev_priv(dev);
4611 
4612 	/* Init the net_device structure */
4613 	ether_setup(dev);
4614 
4615 	/* Initialize the adapter context to zeros. */
4616 	qdf_mem_zero(adapter, sizeof(struct hdd_adapter));
4617 	adapter->dev = dev;
4618 	adapter->deflink = &adapter->link_info[WLAN_HDD_DEFLINK_IDX];
4619 	adapter->hdd_ctx = hdd_ctx;
4620 	adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
4621 	qdf_atomic_set_bit(WLAN_HDD_DEFLINK_IDX, &adapter->active_links);
4622 
4623 	hdd_debug("dev = %pK, adapter = %pK, concurrency_mode=0x%x",
4624 		dev, adapter,
4625 		(int)policy_mgr_get_concurrency_mode(hdd_ctx->psoc));
4626 
4627 	/* Init the net_device structure */
4628 	strlcpy(dev->name, (const char *)iface_name, IFNAMSIZ);
4629 
4630 	hdd_set_ap_ops(dev);
4631 
4632 	dev->watchdog_timeo = HDD_TX_TIMEOUT;
4633 	dev->mtu = HDD_DEFAULT_MTU;
4634 	dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
4635 
4636 	qdf_net_update_net_device_dev_addr(dev, mac_addr, sizeof(tSirMacAddr));
4637 	qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr));
4638 
4639 	hdd_update_dynamic_tsf_sync(adapter);
4640 	hdd_dev_setup_destructor(dev);
4641 	dev->ieee80211_ptr = &adapter->wdev;
4642 	adapter->wdev.wiphy = hdd_ctx->wiphy;
4643 	adapter->wdev.netdev = dev;
4644 
4645 	SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
4646 	spin_lock_init(&adapter->pause_map_lock);
4647 	adapter->start_time = adapter->last_time = qdf_system_ticks();
4648 
4649 	qdf_atomic_init(&adapter->deflink->session.ap.ch_switch_in_progress);
4650 
4651 	return adapter;
4652 }
4653 
4654 /**
4655  * wlan_hdd_rate_is_11g() - check if rate is 11g rate or not
4656  * @rate: Rate to be checked
4657  *
4658  * Return: true if rate if 11g else false
4659  */
wlan_hdd_rate_is_11g(u8 rate)4660 static bool wlan_hdd_rate_is_11g(u8 rate)
4661 {
4662 	static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72,
4663 					 96, 108}; /* actual rate * 2 */
4664 	u8 i;
4665 
4666 	for (i = 0; i < 8; i++) {
4667 		if (rate == gRateArray[i])
4668 			return true;
4669 	}
4670 	return false;
4671 }
4672 
4673 #ifdef QCA_HT_2040_COEX
4674 /**
4675  * wlan_hdd_get_sap_obss() - Get SAP OBSS enable config based on HT_CAPAB IE
4676  * @link_info: Pointer to link info in adapter
4677  *
4678  * Return: HT support channel width config value
4679  */
wlan_hdd_get_sap_obss(struct wlan_hdd_link_info * link_info)4680 static bool wlan_hdd_get_sap_obss(struct wlan_hdd_link_info *link_info)
4681 {
4682 	uint32_t ret;
4683 	const uint8_t *ie;
4684 	uint8_t ht_cap_ie[DOT11F_IE_HTCAPS_MAX_LEN];
4685 	mac_handle_t mac_handle;
4686 	tDot11fIEHTCaps dot11_ht_cap_ie = {0};
4687 	struct hdd_beacon_data *beacon = link_info->session.ap.beacon;
4688 
4689 	mac_handle = hdd_adapter_get_mac_handle(link_info->adapter);
4690 	if (!mac_handle) {
4691 		hdd_debug("NULL MAC context");
4692 		return false;
4693 	}
4694 
4695 	ie = wlan_get_ie_ptr_from_eid(WLAN_EID_HT_CAPABILITY,
4696 				      beacon->tail, beacon->tail_len);
4697 	if (ie && ie[1] && (ie[1] <= DOT11F_IE_HTCAPS_MAX_LEN)) {
4698 		qdf_mem_copy(ht_cap_ie, &ie[2], ie[1]);
4699 		ret = dot11f_unpack_ie_ht_caps(MAC_CONTEXT(mac_handle),
4700 					       ht_cap_ie, ie[1],
4701 					       &dot11_ht_cap_ie, false);
4702 		if (DOT11F_FAILED(ret)) {
4703 			hdd_err("unpack failed, ret: 0x%x", ret);
4704 			return false;
4705 		}
4706 		return dot11_ht_cap_ie.supportedChannelWidthSet;
4707 	}
4708 
4709 	return false;
4710 }
4711 #else
wlan_hdd_get_sap_obss(struct wlan_hdd_link_info * link_info)4712 static inline bool wlan_hdd_get_sap_obss(struct wlan_hdd_link_info *link_info)
4713 {
4714 	return false;
4715 }
4716 #endif
4717 /**
4718  * wlan_hdd_set_channel() - set channel in sap mode
4719  * @wiphy: Pointer to wiphy structure
4720  * @dev: Pointer to net_device structure
4721  * @chandef: Pointer to channel definition structure
4722  * @channel_type: Channel type
4723  *
4724  * Return: 0 for success non-zero for failure
4725  */
wlan_hdd_set_channel(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_chan_def * chandef,enum nl80211_channel_type channel_type)4726 int wlan_hdd_set_channel(struct wiphy *wiphy, struct net_device *dev,
4727 			 struct cfg80211_chan_def *chandef,
4728 			 enum nl80211_channel_type channel_type)
4729 {
4730 	struct hdd_adapter *adapter = NULL;
4731 	uint32_t num_ch = 0;
4732 	int channel_seg2 = 0;
4733 	struct hdd_context *hdd_ctx;
4734 	int status;
4735 	mac_handle_t mac_handle;
4736 	struct sme_config_params *sme_config;
4737 	struct sap_config *sap_config;
4738 	struct hdd_ap_ctx *ap_ctx;
4739 	struct wlan_hdd_link_info *link_info;
4740 
4741 	if (!dev) {
4742 		hdd_err("Called with dev = NULL");
4743 		return -ENODEV;
4744 	}
4745 	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4746 	link_info = adapter->deflink;
4747 
4748 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
4749 		   TRACE_CODE_HDD_CFG80211_SET_CHANNEL,
4750 		   link_info->vdev_id, channel_type);
4751 
4752 	hdd_debug("Dev_mode %s(%d) freq %d, ch_bw %d ccfs1 %d ccfs2 %d",
4753 		  qdf_opmode_str(adapter->device_mode),
4754 		  adapter->device_mode, chandef->chan->center_freq,
4755 		  chandef->width, chandef->center_freq1, chandef->center_freq2);
4756 
4757 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4758 	status = wlan_hdd_validate_context(hdd_ctx);
4759 	if (status)
4760 		return status;
4761 
4762 	mac_handle = hdd_ctx->mac_handle;
4763 
4764 	/* Check freq range */
4765 	if ((wlan_reg_min_chan_freq() >
4766 	     chandef->chan->center_freq) ||
4767 	    (wlan_reg_max_chan_freq() < chandef->chan->center_freq)) {
4768 		hdd_err("channel: %d is outside valid freq range",
4769 			chandef->chan->center_freq);
4770 		return -EINVAL;
4771 	}
4772 
4773 	if (NL80211_CHAN_WIDTH_80P80 == chandef->width) {
4774 		if ((wlan_reg_min_chan_freq() > chandef->center_freq2) ||
4775 		    (wlan_reg_max_chan_freq() < chandef->center_freq2)) {
4776 			hdd_err("center_freq2: %d is outside valid freq range",
4777 				chandef->center_freq2);
4778 			return -EINVAL;
4779 		}
4780 
4781 		if (chandef->center_freq2)
4782 			channel_seg2 = ieee80211_frequency_to_channel(
4783 				chandef->center_freq2);
4784 		else
4785 			hdd_err("Invalid center_freq2");
4786 	}
4787 
4788 	num_ch = CFG_VALID_CHANNEL_LIST_LEN;
4789 
4790 	if (QDF_STATUS_SUCCESS !=
4791 	    wlan_hdd_validate_operation_channel(hdd_ctx,
4792 						chandef->chan->center_freq)) {
4793 		hdd_err("Invalid freq: %d", chandef->chan->center_freq);
4794 		return -EINVAL;
4795 	}
4796 
4797 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink);
4798 	sap_config = &ap_ctx->sap_config;
4799 	sap_config->chan_freq = chandef->chan->center_freq;
4800 	sap_config->ch_params.center_freq_seg1 = channel_seg2;
4801 	sap_config->ch_params.center_freq_seg0 =
4802 			ieee80211_frequency_to_channel(chandef->center_freq1);
4803 
4804 	if (QDF_SAP_MODE == adapter->device_mode) {
4805 		/* set channel to what hostapd configured */
4806 		sap_config->chan_freq = chandef->chan->center_freq;
4807 		sap_config->ch_params.center_freq_seg1 = channel_seg2;
4808 
4809 		sme_config = qdf_mem_malloc(sizeof(*sme_config));
4810 		if (!sme_config)
4811 			return -ENOMEM;
4812 
4813 		sme_get_config_param(mac_handle, sme_config);
4814 		switch (channel_type) {
4815 		case NL80211_CHAN_HT20:
4816 		case NL80211_CHAN_NO_HT:
4817 			sme_config->csr_config.obssEnabled = false;
4818 			sap_config->sec_ch_freq = 0;
4819 			break;
4820 		case NL80211_CHAN_HT40MINUS:
4821 			sap_config->sec_ch_freq =
4822 				sap_config->chan_freq - 20;
4823 			break;
4824 		case NL80211_CHAN_HT40PLUS:
4825 			sap_config->sec_ch_freq =
4826 				sap_config->chan_freq + 20;
4827 			break;
4828 		default:
4829 			hdd_err("Error!!! Invalid HT20/40 mode !");
4830 			qdf_mem_free(sme_config);
4831 			return -EINVAL;
4832 		}
4833 		sme_config->csr_config.obssEnabled =
4834 					wlan_hdd_get_sap_obss(link_info);
4835 
4836 		sme_update_config(mac_handle, sme_config);
4837 		qdf_mem_free(sme_config);
4838 	}
4839 
4840 	return status;
4841 }
4842 
4843 /**
4844  * wlan_hdd_check_11gmode() - check for 11g mode
4845  * @ie: Pointer to IE
4846  * @require_ht: Pointer to require ht
4847  * @require_vht: Pointer to require vht
4848  * @pCheckRatesfor11g: Pointer to check rates for 11g mode
4849  * @pSapHw_mode: SAP HW mode
4850  *
4851  * Check for 11g rate and set proper 11g only mode
4852  *
4853  * Return: none
4854  */
wlan_hdd_check_11gmode(const u8 * ie,u8 * require_ht,u8 * require_vht,u8 * pCheckRatesfor11g,eCsrPhyMode * pSapHw_mode)4855 static void wlan_hdd_check_11gmode(const u8 *ie, u8 *require_ht,
4856 				   u8 *require_vht, u8 *pCheckRatesfor11g,
4857 				   eCsrPhyMode *pSapHw_mode)
4858 {
4859 	u8 i, num_rates = ie[0];
4860 
4861 	ie += 1;
4862 	for (i = 0; i < num_rates; i++) {
4863 		if (*pCheckRatesfor11g
4864 		    && (true == wlan_hdd_rate_is_11g(ie[i] & RATE_MASK))) {
4865 			/* If rate set have 11g rate than change the mode
4866 			 * to 11G
4867 			 */
4868 			*pSapHw_mode = eCSR_DOT11_MODE_11g;
4869 			if (ie[i] & BASIC_RATE_MASK) {
4870 				/* If we have 11g rate as  basic rate, it
4871 				 * means mode is 11g only mode.
4872 				 */
4873 				*pSapHw_mode = eCSR_DOT11_MODE_11g_ONLY;
4874 				*pCheckRatesfor11g = false;
4875 			}
4876 		} else {
4877 			if ((BASIC_RATE_MASK |
4878 			     BSS_MEMBERSHIP_SELECTOR_HT_PHY) == ie[i])
4879 				*require_ht = true;
4880 			else if ((BASIC_RATE_MASK |
4881 				  BSS_MEMBERSHIP_SELECTOR_VHT_PHY) == ie[i])
4882 				*require_vht = true;
4883 		}
4884 	}
4885 }
4886 
4887 /**
4888  * wlan_hdd_check_h2e() - check SAE/H2E require flag from support rate sets
4889  * @rs: support rate or extended support rate set
4890  * @require_h2e: pointer to store require h2e flag
4891  *
4892  * Return: none
4893  */
wlan_hdd_check_h2e(const tSirMacRateSet * rs,bool * require_h2e)4894 static void wlan_hdd_check_h2e(const tSirMacRateSet *rs, bool *require_h2e)
4895 {
4896 	uint8_t i;
4897 
4898 	if (!rs || !require_h2e)
4899 		return;
4900 
4901 	for (i = 0; i < rs->numRates; i++) {
4902 		if (rs->rate[i] == (BASIC_RATE_MASK |
4903 				    BSS_MEMBERSHIP_SELECTOR_SAE_H2E))
4904 			*require_h2e = true;
4905 	}
4906 }
4907 
4908 #ifdef WLAN_FEATURE_11AX
4909 /**
4910  * wlan_hdd_add_extn_ie() - add extension IE
4911  * @link_info: Link info pointer in adapter
4912  * @genie: Pointer to ie to be added
4913  * @total_ielen: Pointer to store total ie length
4914  * @oui: Pointer to oui
4915  * @oui_size: Size of oui
4916  *
4917  * Return: 0 for success non-zero for failure
4918  */
wlan_hdd_add_extn_ie(struct wlan_hdd_link_info * link_info,uint8_t * genie,uint16_t * total_ielen,uint8_t * oui,uint8_t oui_size)4919 static int wlan_hdd_add_extn_ie(struct wlan_hdd_link_info *link_info,
4920 				uint8_t *genie, uint16_t *total_ielen,
4921 				uint8_t *oui, uint8_t oui_size)
4922 {
4923 	const uint8_t *ie;
4924 	uint16_t ielen = 0;
4925 	struct hdd_beacon_data *beacon = link_info->session.ap.beacon;
4926 
4927 	ie = wlan_get_ext_ie_ptr_from_ext_id(oui, oui_size,
4928 					     beacon->tail,
4929 					     beacon->tail_len);
4930 	if (ie) {
4931 		ielen = ie[1] + 2;
4932 		if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
4933 			qdf_mem_copy(&genie[*total_ielen], ie, ielen);
4934 		} else {
4935 			hdd_err("**Ie Length is too big***");
4936 			return -EINVAL;
4937 		}
4938 		*total_ielen += ielen;
4939 	}
4940 	return 0;
4941 }
4942 #endif
4943 
4944 /**
4945  * wlan_hdd_add_hostapd_conf_vsie() - configure Vendor IE in sap mode
4946  * @link_info: Index of link_info in HDD adapter
4947  * @genie: Pointer to Vendor IE
4948  * @total_ielen: Pointer to store total ie length
4949  *
4950  * Return: none
4951  */
wlan_hdd_add_hostapd_conf_vsie(struct wlan_hdd_link_info * link_info,uint8_t * genie,uint16_t * total_ielen)4952 static void wlan_hdd_add_hostapd_conf_vsie(struct wlan_hdd_link_info *link_info,
4953 					   uint8_t *genie,
4954 					   uint16_t *total_ielen)
4955 {
4956 	struct hdd_beacon_data *beacon = link_info->session.ap.beacon;
4957 	int left = beacon->tail_len;
4958 	uint8_t *ptr = beacon->tail;
4959 	uint8_t elem_id, elem_len;
4960 	uint16_t ielen = 0;
4961 	bool skip_ie;
4962 
4963 	if (!ptr || 0 == left)
4964 		return;
4965 
4966 	while (left >= 2) {
4967 		elem_id = ptr[0];
4968 		elem_len = ptr[1];
4969 		left -= 2;
4970 		if (elem_len > left) {
4971 			hdd_err("**Invalid IEs eid: %d elem_len: %d left: %d**",
4972 				elem_id, elem_len, left);
4973 			return;
4974 		}
4975 		if (WLAN_ELEMID_VENDOR == elem_id) {
4976 			/*
4977 			 * skipping the Vendor IE's which we don't want to
4978 			 * include or it will be included by existing code.
4979 			 */
4980 			if (elem_len >= WPS_OUI_TYPE_SIZE &&
4981 			    (!qdf_mem_cmp(&ptr[2], ALLOWLIST_OUI_TYPE,
4982 					  WPA_OUI_TYPE_SIZE) ||
4983 			     !qdf_mem_cmp(&ptr[2], DENYLIST_OUI_TYPE,
4984 					  WPA_OUI_TYPE_SIZE) ||
4985 			     !qdf_mem_cmp(&ptr[2], "\x00\x50\xf2\x02",
4986 					  WPA_OUI_TYPE_SIZE) ||
4987 			     !qdf_mem_cmp(&ptr[2], WPA_OUI_TYPE,
4988 					  WPA_OUI_TYPE_SIZE)))
4989 				skip_ie = true;
4990 			else
4991 				skip_ie = false;
4992 
4993 			if (!skip_ie) {
4994 				ielen = ptr[1] + 2;
4995 				if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
4996 					qdf_mem_copy(&genie[*total_ielen], ptr,
4997 						     ielen);
4998 					*total_ielen += ielen;
4999 				} else {
5000 					hdd_err("IE Length is too big IEs eid: %d elem_len: %d total_ie_lent: %d",
5001 					       elem_id, elem_len, *total_ielen);
5002 				}
5003 			}
5004 		}
5005 
5006 		left -= elem_len;
5007 		ptr += (elem_len + 2);
5008 	}
5009 }
5010 
5011 /**
5012  * wlan_hdd_add_extra_ie() - add extra ies in beacon
5013  * @link_info: Pointer to link_info in adapter
5014  * @genie: Pointer to extra ie
5015  * @total_ielen: Pointer to store total ie length
5016  * @temp_ie_id: ID of extra ie
5017  *
5018  * Return: none
5019  */
wlan_hdd_add_extra_ie(struct wlan_hdd_link_info * link_info,uint8_t * genie,uint16_t * total_ielen,uint8_t temp_ie_id)5020 static void wlan_hdd_add_extra_ie(struct wlan_hdd_link_info *link_info,
5021 				  uint8_t *genie, uint16_t *total_ielen,
5022 				  uint8_t temp_ie_id)
5023 {
5024 	struct hdd_beacon_data *beacon = link_info->session.ap.beacon;
5025 	int left = beacon->tail_len;
5026 	uint8_t *ptr = beacon->tail;
5027 	uint8_t elem_id, elem_len;
5028 	uint16_t ielen = 0;
5029 
5030 	if (!ptr || 0 == left)
5031 		return;
5032 
5033 	while (left >= 2) {
5034 		elem_id = ptr[0];
5035 		elem_len = ptr[1];
5036 		left -= 2;
5037 		if (elem_len > left) {
5038 			hdd_err("**Invalid IEs eid: %d elem_len: %d left: %d**",
5039 			       elem_id, elem_len, left);
5040 			return;
5041 		}
5042 
5043 		if (temp_ie_id == elem_id) {
5044 			ielen = ptr[1] + 2;
5045 			if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
5046 				qdf_mem_copy(&genie[*total_ielen], ptr, ielen);
5047 				*total_ielen += ielen;
5048 			} else {
5049 				hdd_err("IE Length is too big IEs eid: %d elem_len: %d total_ie_len: %d",
5050 				       elem_id, elem_len, *total_ielen);
5051 			}
5052 		}
5053 
5054 		left -= elem_len;
5055 		ptr += (elem_len + 2);
5056 	}
5057 }
5058 
5059 /**
5060  * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode
5061  * @link_info: Pointer to link_info in hostapd adapter
5062  * @out_beacon: Location to store newly allocated beacon data
5063  * @params: Pointer to beacon parameters
5064  * @dtim_period: DTIM period
5065  *
5066  * Return: 0 for success non-zero for failure
5067  */
5068 static int
wlan_hdd_cfg80211_alloc_new_beacon(struct wlan_hdd_link_info * link_info,struct hdd_beacon_data ** out_beacon,struct cfg80211_beacon_data * params,int dtim_period)5069 wlan_hdd_cfg80211_alloc_new_beacon(struct wlan_hdd_link_info *link_info,
5070 				   struct hdd_beacon_data **out_beacon,
5071 				   struct cfg80211_beacon_data *params,
5072 				   int dtim_period)
5073 {
5074 	int size;
5075 	struct hdd_beacon_data *beacon = NULL;
5076 	struct hdd_beacon_data *old = NULL;
5077 	int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
5078 	const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
5079 
5080 	hdd_enter();
5081 	if (params->head && !params->head_len) {
5082 		hdd_err("head_len is NULL");
5083 		return -EINVAL;
5084 	}
5085 
5086 	old = link_info->session.ap.beacon;
5087 	if (!params->head && !old) {
5088 		hdd_err("session: %d old and new heads points to NULL",
5089 		       link_info->vdev_id);
5090 		return -EINVAL;
5091 	}
5092 
5093 	if (params->head) {
5094 		head_len = params->head_len;
5095 		head = params->head;
5096 	} else {
5097 		head_len = old->head_len;
5098 		head = old->head;
5099 	}
5100 
5101 	if (params->tail || !old) {
5102 		tail_len = params->tail_len;
5103 		tail = params->tail;
5104 	} else {
5105 		tail_len = old->tail_len;
5106 		tail = old->tail;
5107 	}
5108 
5109 	if (params->proberesp_ies || !old) {
5110 		proberesp_ies_len = params->proberesp_ies_len;
5111 		proberesp_ies = params->proberesp_ies;
5112 	} else {
5113 		proberesp_ies_len = old->proberesp_ies_len;
5114 		proberesp_ies = old->proberesp_ies;
5115 	}
5116 
5117 	if (params->assocresp_ies || !old) {
5118 		assocresp_ies_len = params->assocresp_ies_len;
5119 		assocresp_ies = params->assocresp_ies;
5120 	} else {
5121 		assocresp_ies_len = old->assocresp_ies_len;
5122 		assocresp_ies = old->assocresp_ies;
5123 	}
5124 
5125 	size = sizeof(struct hdd_beacon_data) + head_len + tail_len +
5126 		proberesp_ies_len + assocresp_ies_len;
5127 
5128 	beacon = qdf_mem_malloc(size);
5129 	if (!beacon)
5130 		return -ENOMEM;
5131 
5132 	if (dtim_period)
5133 		beacon->dtim_period = dtim_period;
5134 	else if (old)
5135 		beacon->dtim_period = old->dtim_period;
5136 	/* -----------------------------------------------
5137 	 * | head | tail | proberesp_ies | assocresp_ies |
5138 	 * -----------------------------------------------
5139 	 */
5140 	beacon->head = ((u8 *) beacon) + sizeof(struct hdd_beacon_data);
5141 	beacon->tail = beacon->head + head_len;
5142 	beacon->proberesp_ies = beacon->tail + tail_len;
5143 	beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
5144 
5145 	beacon->head_len = head_len;
5146 	beacon->tail_len = tail_len;
5147 	beacon->proberesp_ies_len = proberesp_ies_len;
5148 	beacon->assocresp_ies_len = assocresp_ies_len;
5149 
5150 	if (head && head_len)
5151 		memcpy(beacon->head, head, head_len);
5152 	if (tail && tail_len)
5153 		memcpy(beacon->tail, tail, tail_len);
5154 	if (proberesp_ies && proberesp_ies_len)
5155 		memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
5156 	if (assocresp_ies && assocresp_ies_len)
5157 		memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
5158 
5159 	*out_beacon = beacon;
5160 
5161 	link_info->session.ap.beacon = NULL;
5162 	qdf_mem_free(old);
5163 
5164 	return 0;
5165 
5166 }
5167 
5168 #ifdef QCA_HT_2040_COEX
wlan_hdd_add_sap_obss_scan_ie(struct wlan_hdd_link_info * link_info,uint8_t * ie_buf,uint16_t * ie_len)5169 static void wlan_hdd_add_sap_obss_scan_ie(struct wlan_hdd_link_info *link_info,
5170 					  uint8_t *ie_buf, uint16_t *ie_len)
5171 {
5172 	if (QDF_SAP_MODE != link_info->adapter->device_mode ||
5173 	    !wlan_hdd_get_sap_obss(link_info))
5174 		return;
5175 
5176 	wlan_hdd_add_extra_ie(link_info, ie_buf, ie_len,
5177 			      WLAN_EID_OVERLAP_BSS_SCAN_PARAM);
5178 }
5179 #else
5180 static inline void
wlan_hdd_add_sap_obss_scan_ie(struct wlan_hdd_link_info * link_info,uint8_t * ie_buf,uint16_t * ie_len)5181 wlan_hdd_add_sap_obss_scan_ie(struct wlan_hdd_link_info *link_info,
5182 			      uint8_t *ie_buf, uint16_t *ie_len)
5183 {
5184 }
5185 #endif
5186 
5187 /**
5188  * hdd_update_11ax_apies() - update ap mode 11ax ies
5189  * @link_info: Pointer to link_info in adapter
5190  * @genie: generic IE buffer
5191  * @total_ielen: out param to update total ielen
5192  *
5193  * Return: 0 for success non-zero for failure
5194  */
5195 
5196 #ifdef WLAN_FEATURE_11AX
hdd_update_11ax_apies(struct wlan_hdd_link_info * link_info,uint8_t * genie,uint16_t * total_ielen)5197 static int hdd_update_11ax_apies(struct wlan_hdd_link_info *link_info,
5198 				 uint8_t *genie, uint16_t *total_ielen)
5199 {
5200 	if (wlan_hdd_add_extn_ie(link_info, genie, total_ielen,
5201 				 HE_CAP_OUI_TYPE, HE_CAP_OUI_SIZE)) {
5202 		hdd_err("Adding HE Cap ie failed");
5203 		return -EINVAL;
5204 	}
5205 
5206 	if (wlan_hdd_add_extn_ie(link_info, genie, total_ielen,
5207 				 HE_OP_OUI_TYPE, HE_OP_OUI_SIZE)) {
5208 		hdd_err("Adding HE Op ie failed");
5209 		return -EINVAL;
5210 	}
5211 
5212 	return 0;
5213 }
5214 #else
hdd_update_11ax_apies(struct wlan_hdd_link_info * link_info,uint8_t * genie,uint16_t * total_ielen)5215 static int hdd_update_11ax_apies(struct wlan_hdd_link_info *link_info,
5216 				 uint8_t *genie, uint16_t *total_ielen)
5217 {
5218 	return 0;
5219 }
5220 #endif
5221 
5222 #ifdef WLAN_FEATURE_11BE
hdd_update_11be_apies(struct wlan_hdd_link_info * link_info,uint8_t * genie,uint16_t * total_ielen)5223 static int hdd_update_11be_apies(struct wlan_hdd_link_info *link_info,
5224 				 uint8_t *genie, uint16_t *total_ielen)
5225 {
5226 	if (wlan_hdd_add_extn_ie(link_info, genie, total_ielen,
5227 				 EHT_OP_OUI_TYPE, EHT_OP_OUI_SIZE)) {
5228 		hdd_err("Adding EHT Cap IE failed");
5229 		return -EINVAL;
5230 	}
5231 
5232 	if (wlan_hdd_add_extn_ie(link_info, genie, total_ielen,
5233 				 EHT_CAP_OUI_TYPE, EHT_CAP_OUI_SIZE)) {
5234 		hdd_err("Adding EHT Op IE failed");
5235 		return -EINVAL;
5236 	}
5237 
5238 	return 0;
5239 }
5240 #else
hdd_update_11be_apies(struct wlan_hdd_link_info * link_info,uint8_t * genie,uint16_t * total_ielen)5241 static int hdd_update_11be_apies(struct wlan_hdd_link_info *link_info,
5242 				 uint8_t *genie, uint16_t *total_ielen)
5243 {
5244 	return 0;
5245 }
5246 #endif
5247 
5248 int
wlan_hdd_cfg80211_update_apies(struct wlan_hdd_link_info * link_info)5249 wlan_hdd_cfg80211_update_apies(struct wlan_hdd_link_info *link_info)
5250 {
5251 	uint8_t *genie;
5252 	uint16_t total_ielen = 0;
5253 	int ret = 0;
5254 	struct sap_config *config;
5255 	tSirUpdateIE update_ie;
5256 	struct hdd_beacon_data *beacon = NULL;
5257 	uint16_t proberesp_ies_len;
5258 	uint8_t *proberesp_ies = NULL;
5259 	mac_handle_t mac_handle;
5260 	struct hdd_adapter *adapter = link_info->adapter;
5261 
5262 	config = &link_info->session.ap.sap_config;
5263 	beacon = link_info->session.ap.beacon;
5264 	if (!beacon) {
5265 		hdd_err("Beacon is NULL !");
5266 		return -EINVAL;
5267 	}
5268 
5269 	mac_handle = hdd_adapter_get_mac_handle(adapter);
5270 	if (!mac_handle) {
5271 		hdd_debug("NULL MAC context");
5272 		return -EINVAL;
5273 	}
5274 
5275 	genie = qdf_mem_malloc(MAX_GENIE_LEN);
5276 	if (!genie)
5277 		return -ENOMEM;
5278 
5279 	/* Extract and add the extended capabilities and interworking IE */
5280 	wlan_hdd_add_extra_ie(link_info, genie, &total_ielen,
5281 			      WLAN_EID_EXT_CAPABILITY);
5282 
5283 	wlan_hdd_add_extra_ie(link_info, genie, &total_ielen,
5284 			      WLAN_EID_INTERWORKING);
5285 	wlan_hdd_add_extra_ie(link_info, genie, &total_ielen,
5286 			      WLAN_EID_ADVERTISEMENT_PROTOCOL);
5287 	wlan_hdd_add_extra_ie(link_info, genie,
5288 			      &total_ielen, WLAN_ELEMID_RSNXE);
5289 	wlan_hdd_add_extra_ie(link_info, genie, &total_ielen,
5290 			      WLAN_ELEMID_MOBILITY_DOMAIN);
5291 #ifdef FEATURE_WLAN_WAPI
5292 	if (QDF_SAP_MODE == adapter->device_mode) {
5293 		wlan_hdd_add_extra_ie(link_info, genie, &total_ielen,
5294 				      WLAN_ELEMID_WAPI);
5295 	}
5296 #endif
5297 	/* extract and add rrm ie from hostapd */
5298 	wlan_hdd_add_extra_ie(link_info, genie,
5299 			      &total_ielen, WLAN_ELEMID_RRM);
5300 
5301 	wlan_hdd_add_hostapd_conf_vsie(link_info, genie,
5302 				       &total_ielen);
5303 
5304 	ret = hdd_update_11ax_apies(link_info, genie, &total_ielen);
5305 	if (ret)
5306 		goto done;
5307 
5308 	ret = hdd_update_11be_apies(link_info, genie, &total_ielen);
5309 	if (ret)
5310 		goto done;
5311 
5312 	wlan_hdd_add_sap_obss_scan_ie(link_info, genie, &total_ielen);
5313 
5314 	qdf_copy_macaddr(&update_ie.bssid, &adapter->mac_addr);
5315 	update_ie.vdev_id = link_info->vdev_id;
5316 
5317 	/* Added for Probe Response IE */
5318 	proberesp_ies = qdf_mem_malloc(beacon->proberesp_ies_len +
5319 				      MAX_GENIE_LEN);
5320 	if (!proberesp_ies) {
5321 		ret = -EINVAL;
5322 		goto done;
5323 	}
5324 	qdf_mem_copy(proberesp_ies, beacon->proberesp_ies,
5325 		    beacon->proberesp_ies_len);
5326 	proberesp_ies_len = beacon->proberesp_ies_len;
5327 
5328 	wlan_hdd_add_sap_obss_scan_ie(link_info, proberesp_ies,
5329 				      &proberesp_ies_len);
5330 	wlan_hdd_add_extra_ie(link_info, proberesp_ies,
5331 			      &proberesp_ies_len, WLAN_ELEMID_RSNXE);
5332 	wlan_hdd_add_extra_ie(link_info, proberesp_ies,
5333 			      &proberesp_ies_len, WLAN_ELEMID_MOBILITY_DOMAIN);
5334 
5335 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
5336 		update_ie.ieBufferlength = proberesp_ies_len;
5337 		update_ie.pAdditionIEBuffer = proberesp_ies;
5338 		update_ie.append = false;
5339 		update_ie.notify = false;
5340 		if (sme_update_add_ie(mac_handle,
5341 				      &update_ie,
5342 				      eUPDATE_IE_PROBE_RESP) ==
5343 		    QDF_STATUS_E_FAILURE) {
5344 			hdd_err("Could not pass on PROBE_RESP add Ie data");
5345 			ret = -EINVAL;
5346 			goto done;
5347 		}
5348 		wlansap_reset_sap_config_add_ie(config, eUPDATE_IE_PROBE_RESP);
5349 	} else {
5350 		wlansap_update_sap_config_add_ie(config,
5351 						 proberesp_ies,
5352 						 proberesp_ies_len,
5353 						 eUPDATE_IE_PROBE_RESP);
5354 	}
5355 
5356 	/* Assoc resp Add ie Data */
5357 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
5358 		update_ie.ieBufferlength = beacon->assocresp_ies_len;
5359 		update_ie.pAdditionIEBuffer = (uint8_t *) beacon->assocresp_ies;
5360 		update_ie.append = false;
5361 		update_ie.notify = false;
5362 		if (sme_update_add_ie(mac_handle,
5363 				      &update_ie,
5364 				      eUPDATE_IE_ASSOC_RESP) ==
5365 		    QDF_STATUS_E_FAILURE) {
5366 			hdd_err("Could not pass on Add Ie Assoc Response data");
5367 			ret = -EINVAL;
5368 			goto done;
5369 		}
5370 		wlansap_reset_sap_config_add_ie(config, eUPDATE_IE_ASSOC_RESP);
5371 	} else {
5372 		wlansap_update_sap_config_add_ie(config,
5373 						 beacon->assocresp_ies,
5374 						 beacon->assocresp_ies_len,
5375 						 eUPDATE_IE_ASSOC_RESP);
5376 	}
5377 
5378 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
5379 		update_ie.ieBufferlength = total_ielen;
5380 		update_ie.pAdditionIEBuffer = genie;
5381 		update_ie.append = false;
5382 		update_ie.notify = true;
5383 		if (sme_update_add_ie(mac_handle,
5384 				      &update_ie,
5385 				      eUPDATE_IE_PROBE_BCN) ==
5386 		    QDF_STATUS_E_FAILURE) {
5387 			hdd_err("Could not pass on Add Ie probe beacon data");
5388 			ret = -EINVAL;
5389 			goto done;
5390 		}
5391 		wlansap_reset_sap_config_add_ie(config, eUPDATE_IE_PROBE_BCN);
5392 	} else {
5393 		wlansap_update_sap_config_add_ie(config, genie, total_ielen,
5394 						 eUPDATE_IE_PROBE_BCN);
5395 	}
5396 
5397 done:
5398 	qdf_mem_free(genie);
5399 	qdf_mem_free(proberesp_ies);
5400 	return ret;
5401 }
5402 
5403 /**
5404  * wlan_hdd_set_sap_hwmode() - set sap hw mode
5405  * @link_info: Pointer to link_info in hostapd adapter
5406  *
5407  * Return: none
5408  */
wlan_hdd_set_sap_hwmode(struct wlan_hdd_link_info * link_info)5409 static void wlan_hdd_set_sap_hwmode(struct wlan_hdd_link_info *link_info)
5410 {
5411 	struct sap_config *config = &link_info->session.ap.sap_config;
5412 	struct hdd_beacon_data *beacon = link_info->session.ap.beacon;
5413 	struct ieee80211_mgmt *mgmt_frame =
5414 		(struct ieee80211_mgmt *)beacon->head;
5415 	u8 checkRatesfor11g = true;
5416 	u8 require_ht = false, require_vht = false;
5417 	const u8 *ie;
5418 	ssize_t size;
5419 
5420 	config->SapHw_mode = eCSR_DOT11_MODE_11b;
5421 
5422 	size = beacon->head_len - sizeof(mgmt_frame->u.beacon) -
5423 	      (sizeof(*mgmt_frame) - sizeof(mgmt_frame->u));
5424 
5425 	if (size <= 0) {
5426 		hdd_err_rl("Invalid length: %zu", size);
5427 		return;
5428 	}
5429 
5430 	ie = wlan_get_ie_ptr_from_eid(WLAN_EID_SUPP_RATES,
5431 				      &mgmt_frame->u.beacon.variable[0],
5432 				      size);
5433 	if (ie) {
5434 		ie += 1;
5435 		wlan_hdd_check_11gmode(ie, &require_ht, &require_vht,
5436 			&checkRatesfor11g, &config->SapHw_mode);
5437 	}
5438 
5439 	ie = wlan_get_ie_ptr_from_eid(WLAN_EID_EXT_SUPP_RATES,
5440 				      beacon->tail, beacon->tail_len);
5441 	if (ie) {
5442 		ie += 1;
5443 		wlan_hdd_check_11gmode(ie, &require_ht, &require_vht,
5444 			&checkRatesfor11g, &config->SapHw_mode);
5445 	}
5446 
5447 	if (WLAN_REG_IS_5GHZ_CH_FREQ(config->chan_freq))
5448 		config->SapHw_mode = eCSR_DOT11_MODE_11a;
5449 
5450 	ie = wlan_get_ie_ptr_from_eid(WLAN_EID_HT_CAPABILITY,
5451 				      beacon->tail, beacon->tail_len);
5452 	if (ie) {
5453 		config->SapHw_mode = eCSR_DOT11_MODE_11n;
5454 		if (require_ht)
5455 			config->SapHw_mode = eCSR_DOT11_MODE_11n_ONLY;
5456 	}
5457 
5458 	ie = wlan_get_ie_ptr_from_eid(WLAN_EID_VHT_CAPABILITY,
5459 				      beacon->tail, beacon->tail_len);
5460 	if (ie) {
5461 		config->SapHw_mode = eCSR_DOT11_MODE_11ac;
5462 		if (require_vht)
5463 			config->SapHw_mode = eCSR_DOT11_MODE_11ac_ONLY;
5464 	}
5465 
5466 	wlan_hdd_check_11ax_support(beacon, config);
5467 
5468 	wlan_hdd_check_11be_support(beacon, config);
5469 
5470 	hdd_debug("SAP hw_mode: %d", config->SapHw_mode);
5471 }
5472 
5473 /**
5474  * wlan_hdd_config_acs() - config ACS needed parameters
5475  * @hdd_ctx: HDD context
5476  * @adapter: Adapter pointer
5477  *
5478  * This function get ACS related INI parameters and populated
5479  * sap config and smeConfig for ACS needed configurations.
5480  *
5481  * Return: The QDF_STATUS code associated with performing the operation.
5482  */
wlan_hdd_config_acs(struct hdd_context * hdd_ctx,struct hdd_adapter * adapter)5483 QDF_STATUS wlan_hdd_config_acs(struct hdd_context *hdd_ctx,
5484 			       struct hdd_adapter *adapter)
5485 {
5486 	struct sap_config *sap_config;
5487 	struct hdd_config *ini_config;
5488 	mac_handle_t mac_handle;
5489 
5490 	mac_handle = hdd_ctx->mac_handle;
5491 	sap_config = &adapter->deflink->session.ap.sap_config;
5492 	ini_config = hdd_ctx->config;
5493 
5494 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
5495 	hdd_debug("HDD_ACS_SKIP_STATUS = %d", hdd_ctx->skip_acs_scan_status);
5496 	if (hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) {
5497 		struct hdd_adapter *con_sap_adapter;
5498 		struct sap_config *con_sap_config = NULL;
5499 
5500 		con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
5501 
5502 		if (con_sap_adapter)
5503 			con_sap_config =
5504 				&con_sap_adapter->deflink->session.ap.sap_config;
5505 
5506 		sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN;
5507 
5508 		if (con_sap_config &&
5509 			con_sap_config->acs_cfg.acs_mode == true &&
5510 			hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN &&
5511 			con_sap_config->acs_cfg.hw_mode ==
5512 						sap_config->acs_cfg.hw_mode) {
5513 			uint32_t con_sap_st_ch_freq, con_sap_end_ch_freq;
5514 			uint32_t cur_sap_st_ch_freq, cur_sap_end_ch_freq;
5515 			uint32_t bandStartChannel, bandEndChannel;
5516 
5517 			con_sap_st_ch_freq =
5518 					con_sap_config->acs_cfg.start_ch_freq;
5519 			con_sap_end_ch_freq =
5520 					con_sap_config->acs_cfg.end_ch_freq;
5521 			cur_sap_st_ch_freq =
5522 					sap_config->acs_cfg.start_ch_freq;
5523 			cur_sap_end_ch_freq =
5524 					sap_config->acs_cfg.end_ch_freq;
5525 
5526 			wlansap_extend_to_acs_range(
5527 					mac_handle, &cur_sap_st_ch_freq,
5528 					&cur_sap_end_ch_freq,
5529 					&bandStartChannel, &bandEndChannel);
5530 
5531 			wlansap_extend_to_acs_range(
5532 					mac_handle, &con_sap_st_ch_freq,
5533 					&con_sap_end_ch_freq,
5534 					&bandStartChannel, &bandEndChannel);
5535 
5536 			if (con_sap_st_ch_freq <= cur_sap_st_ch_freq &&
5537 			    con_sap_end_ch_freq >= cur_sap_end_ch_freq) {
5538 				sap_config->acs_cfg.skip_scan_status =
5539 							eSAP_SKIP_ACS_SCAN;
5540 
5541 			} else if (con_sap_st_ch_freq >= cur_sap_st_ch_freq &&
5542 				   con_sap_end_ch_freq >=
5543 						cur_sap_end_ch_freq) {
5544 				sap_config->acs_cfg.skip_scan_status =
5545 							eSAP_DO_PAR_ACS_SCAN;
5546 
5547 				sap_config->acs_cfg.skip_scan_range1_stch =
5548 							cur_sap_st_ch_freq;
5549 				sap_config->acs_cfg.skip_scan_range1_endch =
5550 							con_sap_st_ch_freq - 5;
5551 				sap_config->acs_cfg.skip_scan_range2_stch =
5552 							0;
5553 				sap_config->acs_cfg.skip_scan_range2_endch =
5554 							0;
5555 
5556 			} else if (con_sap_st_ch_freq <= cur_sap_st_ch_freq &&
5557 				   con_sap_end_ch_freq <=
5558 						cur_sap_end_ch_freq) {
5559 				sap_config->acs_cfg.skip_scan_status =
5560 							eSAP_DO_PAR_ACS_SCAN;
5561 
5562 				sap_config->acs_cfg.skip_scan_range1_stch =
5563 							con_sap_end_ch_freq + 5;
5564 				sap_config->acs_cfg.skip_scan_range1_endch =
5565 							cur_sap_end_ch_freq;
5566 				sap_config->acs_cfg.skip_scan_range2_stch =
5567 							0;
5568 				sap_config->acs_cfg.skip_scan_range2_endch =
5569 							0;
5570 
5571 			} else if (con_sap_st_ch_freq >= cur_sap_st_ch_freq &&
5572 				   con_sap_end_ch_freq <=
5573 						cur_sap_end_ch_freq) {
5574 				sap_config->acs_cfg.skip_scan_status =
5575 							eSAP_DO_PAR_ACS_SCAN;
5576 
5577 				sap_config->acs_cfg.skip_scan_range1_stch =
5578 							cur_sap_st_ch_freq;
5579 				sap_config->acs_cfg.skip_scan_range1_endch =
5580 							con_sap_st_ch_freq - 5;
5581 				sap_config->acs_cfg.skip_scan_range2_stch =
5582 							con_sap_end_ch_freq;
5583 				sap_config->acs_cfg.skip_scan_range2_endch =
5584 						cur_sap_end_ch_freq + 5;
5585 
5586 			} else
5587 				sap_config->acs_cfg.skip_scan_status =
5588 							eSAP_DO_NEW_ACS_SCAN;
5589 
5590 			if (sap_config->acs_cfg.skip_scan_status ==
5591 			    eSAP_DO_PAR_ACS_SCAN &&
5592 			    (sap_config->acs_cfg.start_ch_freq >
5593 			    sap_config->acs_cfg.skip_scan_range1_endch ||
5594 			    sap_config->acs_cfg.end_ch_freq <
5595 			    sap_config->acs_cfg.skip_scan_range1_stch) &&
5596 			    ((!sap_config->acs_cfg.skip_scan_range2_stch &&
5597 			    !sap_config->acs_cfg.skip_scan_range2_endch) ||
5598 			    (sap_config->acs_cfg.start_ch_freq >
5599 			    sap_config->acs_cfg.skip_scan_range2_endch ||
5600 			    sap_config->acs_cfg.end_ch_freq <
5601 			    sap_config->acs_cfg.skip_scan_range2_stch))) {
5602 				hdd_debug("Skip partial scan range1/2 out of ACS");
5603 				sap_config->acs_cfg.skip_scan_status =
5604 					eSAP_SKIP_ACS_SCAN;
5605 			}
5606 
5607 			hdd_debug("SecAP ACS Skip=%d, ACS CH RANGE=%d-%d, %d-%d",
5608 				  sap_config->acs_cfg.skip_scan_status,
5609 				  sap_config->acs_cfg.skip_scan_range1_stch,
5610 				  sap_config->acs_cfg.skip_scan_range1_endch,
5611 				  sap_config->acs_cfg.skip_scan_range2_stch,
5612 				  sap_config->acs_cfg.skip_scan_range2_endch);
5613 		}
5614 	}
5615 #endif
5616 
5617 	return QDF_STATUS_SUCCESS;
5618 }
5619 
5620 /**
5621  * wlan_hdd_sap_p2p_11ac_overrides: API to overwrite 11ac config in case of
5622  * SAP or p2p go
5623  * @ap_adapter: pointer to adapter
5624  *
5625  * This function overrides SAP / P2P Go configuration based on driver INI
5626  * parameters for 11AC override and ACS. This overrides are done to support
5627  * android legacy configuration method.
5628  *
5629  * NOTE: Non android platform supports concurrency and these overrides shall
5630  * not be used. Also future driver based overrides shall be consolidated in this
5631  * function only. Avoid random overrides in other location based on ini.
5632  *
5633  * Return: 0 for Success or Negative error codes.
5634  */
wlan_hdd_sap_p2p_11ac_overrides(struct hdd_adapter * ap_adapter)5635 static int wlan_hdd_sap_p2p_11ac_overrides(struct hdd_adapter *ap_adapter)
5636 {
5637 	struct sap_config *sap_cfg =
5638 			&ap_adapter->deflink->session.ap.sap_config;
5639 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
5640 	uint8_t ch_width;
5641 	uint8_t sub_20_chan_width;
5642 	QDF_STATUS status;
5643 	bool sap_force_11n_for_11ac = 0;
5644 	bool go_force_11n_for_11ac = 0;
5645 	uint32_t channel_bonding_mode;
5646 	bool go_11ac_override = 0;
5647 	bool sap_11ac_override = 0;
5648 
5649 	/*
5650 	 * No need to override for Go/Sap on 6 GHz band
5651 	 */
5652 	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_cfg->chan_freq))
5653 		return 0;
5654 
5655 	ucfg_mlme_get_sap_force_11n_for_11ac(hdd_ctx->psoc,
5656 					     &sap_force_11n_for_11ac);
5657 	ucfg_mlme_get_go_force_11n_for_11ac(hdd_ctx->psoc,
5658 					    &go_force_11n_for_11ac);
5659 
5660 	/* Fixed channel 11AC override:
5661 	 * 11AC override in qcacld is introduced for following reasons:
5662 	 * 1. P2P GO also follows start_bss and since p2p GO could not be
5663 	 *    configured to setup VHT channel width in wpa_supplicant
5664 	 * 2. Android UI does not provide advanced configuration options for SAP
5665 	 *
5666 	 * Default override enabled (for android). MDM shall disable this in ini
5667 	 */
5668 	/*
5669 	 * sub_20 MHz channel width is incompatible with 11AC rates, hence do
5670 	 * not allow 11AC rates or more than 20 MHz channel width when
5671 	 * enable_sub_20_channel_width is non zero
5672 	 */
5673 	status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
5674 						 &sub_20_chan_width);
5675 	if (QDF_IS_STATUS_ERROR(status)) {
5676 		hdd_err("Failed to get sub_20_chan_width config");
5677 		return -EIO;
5678 	}
5679 
5680 	ucfg_mlme_is_go_11ac_override(hdd_ctx->psoc,
5681 				      &go_11ac_override);
5682 	ucfg_mlme_is_sap_11ac_override(hdd_ctx->psoc,
5683 				       &sap_11ac_override);
5684 
5685 	if (!sub_20_chan_width &&
5686 	    (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
5687 	    sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
5688 	    sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY ||
5689 	    sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ax ||
5690 	    sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ax_ONLY) &&
5691 	    ((ap_adapter->device_mode == QDF_SAP_MODE &&
5692 	    !sap_force_11n_for_11ac &&
5693 	    sap_11ac_override) ||
5694 	    (ap_adapter->device_mode == QDF_P2P_GO_MODE &&
5695 	    !go_force_11n_for_11ac &&
5696 	    go_11ac_override))) {
5697 		hdd_debug("** Driver force 11AC override for SAP/Go **");
5698 
5699 		/* 11n only shall not be overridden since it may be on purpose*/
5700 		if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n)
5701 			sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
5702 
5703 		if (!WLAN_REG_IS_24GHZ_CH_FREQ(sap_cfg->chan_freq)) {
5704 			status =
5705 			    ucfg_mlme_get_vht_channel_width(hdd_ctx->psoc,
5706 							    &ch_width);
5707 			if (!QDF_IS_STATUS_SUCCESS(status))
5708 				hdd_err("Failed to set channel_width");
5709 			sap_cfg->ch_width_orig = ch_width;
5710 		} else {
5711 			/*
5712 			 * Allow 40 Mhz in 2.4 Ghz only if indicated by
5713 			 * supplicant after OBSS scan and if 2.4 Ghz channel
5714 			 * bonding is set in INI
5715 			 */
5716 			ucfg_mlme_get_channel_bonding_24ghz(
5717 				hdd_ctx->psoc, &channel_bonding_mode);
5718 			if (sap_cfg->ch_width_orig >= CH_WIDTH_40MHZ &&
5719 			    channel_bonding_mode)
5720 				sap_cfg->ch_width_orig =
5721 					CH_WIDTH_40MHZ;
5722 			else
5723 				sap_cfg->ch_width_orig =
5724 					CH_WIDTH_20MHZ;
5725 		}
5726 	}
5727 
5728 	return 0;
5729 }
5730 
5731 /**
5732  * wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
5733  * @ap_adapter: pointer to adapter struct
5734  *
5735  * This function overrides SAP / P2P Go configuration based on driver INI
5736  * parameters for 11AC override and ACS. These overrides are done to support
5737  * android legacy configuration method.
5738  *
5739  * NOTE: Non android platform supports concurrency and these overrides shall
5740  * not be used. Also future driver based overrides shall be consolidated in this
5741  * function only. Avoid random overrides in other location based on ini.
5742  *
5743  * Return: 0 for Success or Negative error codes.
5744  */
wlan_hdd_setup_driver_overrides(struct hdd_adapter * ap_adapter)5745 static int wlan_hdd_setup_driver_overrides(struct hdd_adapter *ap_adapter)
5746 {
5747 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
5748 	QDF_STATUS qdf_status;
5749 	bool is_vendor_acs_support =
5750 		cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
5751 
5752 	qdf_status = ucfg_mlme_get_vendor_acs_support(hdd_ctx->psoc,
5753 						      &is_vendor_acs_support);
5754 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
5755 		hdd_err("get_vendor_acs_support failed, set default");
5756 
5757 	if (!is_vendor_acs_support)
5758 		return wlan_hdd_sap_p2p_11ac_overrides(ap_adapter);
5759 	else
5760 		return 0;
5761 }
5762 
5763 void
hdd_check_and_disconnect_sta_on_invalid_channel(struct hdd_context * hdd_ctx,enum wlan_reason_code reason)5764 hdd_check_and_disconnect_sta_on_invalid_channel(struct hdd_context *hdd_ctx,
5765 						enum wlan_reason_code reason)
5766 {
5767 	struct hdd_adapter *sta_adapter;
5768 	uint32_t sta_chan_freq;
5769 	struct wlan_hdd_link_info *link_info;
5770 
5771 	sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
5772 
5773 	if (!sta_adapter) {
5774 		hdd_err("STA adapter does not exist");
5775 		return;
5776 	}
5777 
5778 	hdd_adapter_for_each_active_link_info(sta_adapter, link_info) {
5779 		sta_chan_freq = hdd_get_link_info_home_channel(link_info);
5780 		if (!sta_chan_freq)
5781 			continue;
5782 
5783 		hdd_err("VDEV-%d STA connected on %d",
5784 			link_info->vdev_id, sta_chan_freq);
5785 
5786 		if (sme_is_channel_valid(hdd_ctx->mac_handle, sta_chan_freq))
5787 			continue;
5788 
5789 		hdd_err("chan %d not valid, issue disconnect", sta_chan_freq);
5790 		wlan_hdd_cm_issue_disconnect(link_info, reason, false);
5791 	}
5792 }
5793 
5794 /**
5795  * hdd_handle_acs_2g_preferred_sap_conc() - Handle 2G pereferred SAP
5796  * concurrency with GO
5797  * @psoc: soc object
5798  * @adapter: SAP adapter
5799  * @sap_config: sap config
5800  *
5801  * In GO+STA+SAP concurrency, if GO is started on 2G and SAP is doing ACS
5802  * with 2G preferred channel list, then we will move GO to 2G SCC
5803  * channel of STA if present.
5804  * The purpose is to avoid SAP start failure on 2G because we don't
5805  * support 3 home channels in same mac.
5806  *
5807  * Return: void
5808  */
5809 void
hdd_handle_acs_2g_preferred_sap_conc(struct wlan_objmgr_psoc * psoc,struct hdd_adapter * adapter,struct sap_config * sap_config)5810 hdd_handle_acs_2g_preferred_sap_conc(struct wlan_objmgr_psoc *psoc,
5811 				     struct hdd_adapter *adapter,
5812 				     struct sap_config *sap_config)
5813 {
5814 	uint32_t i;
5815 	int ret;
5816 	QDF_STATUS status;
5817 	uint32_t *ch_freq_list;
5818 	struct sap_acs_cfg *acs_cfg;
5819 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
5820 	uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
5821 	uint8_t vdev_num;
5822 	uint8_t sta_vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
5823 	uint32_t sta_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
5824 	uint8_t sta_vdev_num;
5825 	struct hdd_hostapd_state *hostapd_state;
5826 	uint8_t go_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
5827 	qdf_freq_t go_ch_freq = 0, go_new_ch_freq = 0;
5828 	struct wlan_hdd_link_info *go_link_info;
5829 	enum phy_ch_width go_bw;
5830 
5831 	if (adapter->device_mode != QDF_SAP_MODE)
5832 		return;
5833 	if (!policy_mgr_is_hw_dbs_capable(psoc))
5834 		return;
5835 
5836 	acs_cfg = &sap_config->acs_cfg;
5837 	if (!acs_cfg->master_ch_list_count)
5838 		return;
5839 	ch_freq_list = acs_cfg->master_freq_list;
5840 	for (i = 0; i < acs_cfg->master_ch_list_count; i++)
5841 		if (!WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i]))
5842 			return;
5843 
5844 	/* Move existing GO interface to SCC channel of 2G STA */
5845 	vdev_num = policy_mgr_get_mode_specific_conn_info(
5846 			psoc, freq_list, vdev_id_list,
5847 			PM_P2P_GO_MODE);
5848 	if (!vdev_num || vdev_num > 1)
5849 		return;
5850 	for (i = 0; i < vdev_num; i++) {
5851 		if (WLAN_REG_IS_24GHZ_CH_FREQ(freq_list[i])) {
5852 			go_vdev_id = vdev_id_list[i];
5853 			go_ch_freq = freq_list[i];
5854 			break;
5855 		}
5856 	}
5857 	if (!go_ch_freq)
5858 		return;
5859 	sta_vdev_num = policy_mgr_get_mode_specific_conn_info(
5860 			psoc, sta_freq_list, sta_vdev_id_list,
5861 			PM_STA_MODE);
5862 	for (i = 0; i < sta_vdev_num; i++) {
5863 		if (go_ch_freq == sta_freq_list[i])
5864 			return;
5865 		if (WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[i]))
5866 			go_new_ch_freq = sta_freq_list[i];
5867 	}
5868 
5869 	if (!go_new_ch_freq)
5870 		return;
5871 
5872 	go_link_info = hdd_get_link_info_by_vdev(adapter->hdd_ctx, go_vdev_id);
5873 	if (!go_link_info || hdd_validate_adapter(go_link_info->adapter))
5874 		return;
5875 
5876 	wlan_hdd_set_sap_csa_reason(psoc, go_vdev_id,
5877 				    CSA_REASON_SAP_ACS);
5878 	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(go_link_info);
5879 	qdf_event_reset(&hostapd_state->qdf_event);
5880 	go_bw = wlansap_get_chan_width(WLAN_HDD_GET_SAP_CTX_PTR(go_link_info));
5881 	ret = hdd_softap_set_channel_change(go_link_info->adapter->dev,
5882 					    go_new_ch_freq, go_bw,
5883 					    false);
5884 	if (ret) {
5885 		hdd_err("CSA failed to %d, ret %d", go_new_ch_freq, ret);
5886 		return;
5887 	}
5888 
5889 	status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
5890 					       SME_CMD_START_BSS_TIMEOUT);
5891 	if (!QDF_IS_STATUS_SUCCESS(status))
5892 		hdd_err("wait for qdf_event failed!!");
5893 }
5894 
5895 /**
5896  * hdd_handle_p2p_go_for_3rd_ap_conc() - Move P2P GO to other band if
5897  * SAP starting
5898  * @hdd_ctx: Global HDD context pointer
5899  * @sap_ch_freq: sap channel frequency
5900  *
5901  * In GO+STA+SAP concurrency, if GO is MCC with STA, the new SAP
5902  * will not be allowed in same MAC. FW doesn't support MCC in same
5903  * MAC for 3 or more vdevs. Move GO to other band to avoid SAP
5904  * starting failed.
5905  *
5906  * Return: true if GO is moved to other band successfully.
5907  */
5908 static bool
hdd_handle_p2p_go_for_3rd_ap_conc(struct hdd_context * hdd_ctx,uint32_t sap_ch_freq)5909 hdd_handle_p2p_go_for_3rd_ap_conc(struct hdd_context *hdd_ctx,
5910 				  uint32_t sap_ch_freq)
5911 {
5912 	uint32_t i;
5913 	int ret;
5914 	QDF_STATUS status;
5915 	struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
5916 	uint8_t go_vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
5917 	uint32_t go_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
5918 	uint8_t go_vdev_num;
5919 	uint8_t sta_vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
5920 	uint32_t sta_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
5921 	uint8_t sta_vdev_num;
5922 	struct hdd_hostapd_state *hostapd_state;
5923 	uint8_t go_vdev_id;
5924 	qdf_freq_t go_ch_freq, go_new_ch_freq;
5925 	struct wlan_hdd_link_info *go_link_info;
5926 
5927 	if (!policy_mgr_is_hw_dbs_capable(psoc))
5928 		return false;
5929 	go_vdev_num = policy_mgr_get_mode_specific_conn_info(
5930 			psoc, go_freq_list, go_vdev_id_list,
5931 			PM_P2P_GO_MODE);
5932 	if (!go_vdev_num || go_vdev_num > 1)
5933 		return false;
5934 
5935 	if (!policy_mgr_2_freq_always_on_same_mac(
5936 			psoc, go_freq_list[0], sap_ch_freq))
5937 		return false;
5938 
5939 	sta_vdev_num = policy_mgr_get_mode_specific_conn_info(
5940 			psoc, sta_freq_list, sta_vdev_id_list,
5941 			PM_STA_MODE);
5942 	if (!sta_vdev_num)
5943 		return false;
5944 	for (i = 0; i < sta_vdev_num; i++) {
5945 		if (go_freq_list[0] != sta_freq_list[i] &&
5946 		    policy_mgr_2_freq_always_on_same_mac(
5947 				psoc, go_freq_list[0], sta_freq_list[i]))
5948 			break;
5949 	}
5950 	if (i == sta_vdev_num)
5951 		return false;
5952 	go_ch_freq = go_freq_list[0];
5953 	go_vdev_id = go_vdev_id_list[0];
5954 	go_new_ch_freq =
5955 		policy_mgr_get_alternate_channel_for_sap(psoc,
5956 							 go_vdev_id,
5957 							 go_ch_freq,
5958 							 REG_BAND_UNKNOWN);
5959 	if (!go_new_ch_freq) {
5960 		hdd_debug("no alternate GO channel");
5961 		return false;
5962 	}
5963 	if (go_new_ch_freq != sta_freq_list[i] &&
5964 	    policy_mgr_3_freq_always_on_same_mac(
5965 			psoc, sap_ch_freq, go_new_ch_freq, sta_freq_list[i])) {
5966 		hdd_debug("no alternate GO channel to avoid 3vif MCC");
5967 		return false;
5968 	}
5969 
5970 	go_link_info = hdd_get_link_info_by_vdev(hdd_ctx, go_vdev_id);
5971 	if (!go_link_info || hdd_validate_adapter(go_link_info->adapter))
5972 		return false;
5973 
5974 	wlan_hdd_set_sap_csa_reason(psoc, go_vdev_id,
5975 				    CSA_REASON_SAP_FIX_CH_CONC_WITH_GO);
5976 	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(go_link_info);
5977 	qdf_event_reset(&hostapd_state->qdf_event);
5978 
5979 	ret = hdd_softap_set_channel_change(go_link_info->adapter->dev,
5980 					    go_new_ch_freq, CH_WIDTH_80MHZ,
5981 					    false);
5982 	if (ret) {
5983 		hdd_err("CSA failed to %d, ret %d", go_new_ch_freq, ret);
5984 		return false;
5985 	}
5986 
5987 	status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
5988 					       SME_CMD_START_BSS_TIMEOUT);
5989 	if (!QDF_IS_STATUS_SUCCESS(status))
5990 		hdd_err("wait for qdf_event failed!!");
5991 
5992 	return true;
5993 }
5994 
5995 #ifdef DISABLE_CHANNEL_LIST
5996 /**
5997  * wlan_hdd_get_wiphy_channel() - Get wiphy channel
5998  * @wiphy: Pointer to wiphy structure
5999  * @freq: Frequency of the channel for which the wiphy hw value is required
6000  *
6001  * Return: wiphy channel for valid frequency else return NULL
6002  */
wlan_hdd_get_wiphy_channel(struct wiphy * wiphy,uint32_t freq)6003 static struct ieee80211_channel *wlan_hdd_get_wiphy_channel(
6004 						struct wiphy *wiphy,
6005 						uint32_t freq)
6006 {
6007 	uint32_t band_num, channel_num;
6008 	struct ieee80211_channel *wiphy_channel = NULL;
6009 
6010 	for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
6011 		if (!wiphy->bands[band_num]) {
6012 			hdd_debug("Band %d not part of wiphy", band_num);
6013 			continue;
6014 		}
6015 		for (channel_num = 0; channel_num <
6016 				wiphy->bands[band_num]->n_channels;
6017 				channel_num++) {
6018 			wiphy_channel = &(wiphy->bands[band_num]->
6019 							channels[channel_num]);
6020 			if (wiphy_channel->center_freq == freq)
6021 				return wiphy_channel;
6022 		}
6023 	}
6024 	return wiphy_channel;
6025 }
6026 
wlan_hdd_restore_channels(struct hdd_context * hdd_ctx)6027 int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx)
6028 {
6029 	struct hdd_cache_channels *cache_chann;
6030 	struct wiphy *wiphy;
6031 	int freq, status;
6032 	int i;
6033 	struct ieee80211_channel *wiphy_channel = NULL;
6034 
6035 	hdd_enter();
6036 
6037 	if (!hdd_ctx) {
6038 		hdd_err("HDD Context is NULL");
6039 		return -EINVAL;
6040 	}
6041 
6042 	wiphy = hdd_ctx->wiphy;
6043 	if (!wiphy) {
6044 		hdd_err("Wiphy is NULL");
6045 		return -EINVAL;
6046 	}
6047 
6048 	qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
6049 
6050 	cache_chann = hdd_ctx->original_channels;
6051 
6052 	if (!cache_chann || !cache_chann->num_channels) {
6053 		qdf_mutex_release(&hdd_ctx->cache_channel_lock);
6054 		hdd_nofl_debug("channel list is NULL or num channels are zero");
6055 		return -EINVAL;
6056 	}
6057 
6058 	for (i = 0; i < cache_chann->num_channels; i++) {
6059 		freq = cache_chann->channel_info[i].freq;
6060 		if (!freq)
6061 			continue;
6062 
6063 		wiphy_channel = wlan_hdd_get_wiphy_channel(wiphy, freq);
6064 		if (!wiphy_channel)
6065 			continue;
6066 		/*
6067 		 * Restore the original states of the channels
6068 		 * only if we have cached non zero values
6069 		 */
6070 		wiphy_channel->flags =
6071 				cache_chann->channel_info[i].wiphy_status;
6072 
6073 		hdd_debug("Restore channel_freq %d reg_stat %d wiphy_stat 0x%x",
6074 			  cache_chann->channel_info[i].freq,
6075 			  cache_chann->channel_info[i].reg_status,
6076 			  wiphy_channel->flags);
6077 	}
6078 
6079 	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
6080 
6081 	ucfg_reg_restore_cached_channels(hdd_ctx->pdev);
6082 	status = sme_update_channel_list(hdd_ctx->mac_handle);
6083 	if (status)
6084 		hdd_err("Can't Restore channel list");
6085 	else
6086 		/*
6087 		 * Free the cache channels when the
6088 		 * disabled channels are restored
6089 		 */
6090 		wlan_hdd_free_cache_channels(hdd_ctx);
6091 	hdd_exit();
6092 	return 0;
6093 }
6094 
wlan_hdd_disable_channels(struct hdd_context * hdd_ctx)6095 int wlan_hdd_disable_channels(struct hdd_context *hdd_ctx)
6096 {
6097 	struct hdd_cache_channels *cache_chann;
6098 	struct wiphy *wiphy;
6099 	int freq, status;
6100 	int i;
6101 	struct ieee80211_channel *wiphy_channel = NULL;
6102 
6103 	hdd_enter();
6104 
6105 	if (!hdd_ctx) {
6106 		hdd_err("HDD Context is NULL");
6107 		return -EINVAL;
6108 	}
6109 
6110 	wiphy = hdd_ctx->wiphy;
6111 	if (!wiphy) {
6112 		hdd_err("Wiphy is NULL");
6113 		return -EINVAL;
6114 	}
6115 
6116 	qdf_mutex_acquire(&hdd_ctx->cache_channel_lock);
6117 	cache_chann = hdd_ctx->original_channels;
6118 
6119 	if (!cache_chann || !cache_chann->num_channels) {
6120 		qdf_mutex_release(&hdd_ctx->cache_channel_lock);
6121 		hdd_err("channel list is NULL or num channels are zero");
6122 		return -EINVAL;
6123 	}
6124 
6125 	for (i = 0; i < cache_chann->num_channels; i++) {
6126 		freq = cache_chann->channel_info[i].freq;
6127 		if (!freq)
6128 			continue;
6129 		wiphy_channel = wlan_hdd_get_wiphy_channel(wiphy, freq);
6130 		if (!wiphy_channel)
6131 			continue;
6132 		/*
6133 		 * Cache the current states of
6134 		 * the channels
6135 		 */
6136 		cache_chann->channel_info[i].reg_status =
6137 			wlan_reg_get_channel_state_from_secondary_list_for_freq(
6138 							hdd_ctx->pdev,
6139 							freq);
6140 		cache_chann->channel_info[i].wiphy_status =
6141 							wiphy_channel->flags;
6142 		hdd_debug("Disable channel_freq %d reg_stat %d wiphy_stat 0x%x",
6143 			  cache_chann->channel_info[i].freq,
6144 			  cache_chann->channel_info[i].reg_status,
6145 			  wiphy_channel->flags);
6146 
6147 		wiphy_channel->flags |= IEEE80211_CHAN_DISABLED;
6148 	}
6149 
6150 	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
6151 	 ucfg_reg_disable_cached_channels(hdd_ctx->pdev);
6152 	status = sme_update_channel_list(hdd_ctx->mac_handle);
6153 
6154 	hdd_exit();
6155 	return status;
6156 }
6157 #else
wlan_hdd_disable_channels(struct hdd_context * hdd_ctx)6158 int wlan_hdd_disable_channels(struct hdd_context *hdd_ctx)
6159 {
6160 	return 0;
6161 }
6162 
wlan_hdd_restore_channels(struct hdd_context * hdd_ctx)6163 int wlan_hdd_restore_channels(struct hdd_context *hdd_ctx)
6164 {
6165 	return 0;
6166 }
6167 #endif
6168 
6169 #ifdef DHCP_SERVER_OFFLOAD
6170 static void
wlan_hdd_set_dhcp_server_offload(struct wlan_hdd_link_info * link_info)6171 wlan_hdd_set_dhcp_server_offload(struct wlan_hdd_link_info *link_info)
6172 {
6173 	struct hdd_context *hdd_ctx;
6174 	struct dhcp_offload_info_params dhcp_srv_info;
6175 	uint8_t num_entries = 0;
6176 	uint8_t *srv_ip;
6177 	uint8_t num;
6178 	uint32_t temp;
6179 	uint32_t dhcp_max_num_clients;
6180 	mac_handle_t mac_handle;
6181 	QDF_STATUS status;
6182 
6183 	hdd_ctx = link_info->adapter->hdd_ctx;
6184 	if (!hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid)
6185 		return;
6186 
6187 	srv_ip = hdd_ctx->config->dhcp_server_ip.dhcp_server_ip;
6188 	dhcp_srv_info.vdev_id = link_info->vdev_id;
6189 	dhcp_srv_info.dhcp_offload_enabled = true;
6190 
6191 	status = ucfg_fwol_get_dhcp_max_num_clients(hdd_ctx->psoc,
6192 						    &dhcp_max_num_clients);
6193 	if (QDF_IS_STATUS_ERROR(status))
6194 		return;
6195 
6196 	dhcp_srv_info.dhcp_client_num = dhcp_max_num_clients;
6197 
6198 	if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
6199 		hdd_err("Invalid IP address (%d)! It could NOT be multicast IP address!",
6200 			srv_ip[0]);
6201 		return;
6202 	}
6203 
6204 	if (srv_ip[IPADDR_NUM_ENTRIES - 1] >= 100) {
6205 		hdd_err("Invalid IP address (%d)! The last field must be less than 100!",
6206 			srv_ip[IPADDR_NUM_ENTRIES - 1]);
6207 		return;
6208 	}
6209 
6210 	dhcp_srv_info.dhcp_srv_addr = 0;
6211 	for (num = 0; num < num_entries; num++) {
6212 		temp = srv_ip[num];
6213 		dhcp_srv_info.dhcp_srv_addr |= (temp << (8 * num));
6214 	}
6215 
6216 	mac_handle = hdd_ctx->mac_handle;
6217 	status = sme_set_dhcp_srv_offload(mac_handle, &dhcp_srv_info);
6218 	if (QDF_IS_STATUS_SUCCESS(status))
6219 		hdd_debug("enable DHCP Server offload successfully!");
6220 	else
6221 		hdd_err("sme_set_dhcp_srv_offload fail!");
6222 }
6223 
6224 /**
6225  * wlan_hdd_dhcp_offload_enable: Enable DHCP offload
6226  * @link_info: Pointer of link_info in adapter
6227  *
6228  * Enables the DHCP Offload feature in firmware if it has been configured.
6229  *
6230  * Return: None
6231  */
wlan_hdd_dhcp_offload_enable(struct wlan_hdd_link_info * link_info)6232 static void wlan_hdd_dhcp_offload_enable(struct wlan_hdd_link_info *link_info)
6233 {
6234 	bool enable_dhcp_server_offload;
6235 	QDF_STATUS status;
6236 	struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx;
6237 
6238 	status = ucfg_fwol_get_enable_dhcp_server_offload(
6239 						hdd_ctx->psoc,
6240 						&enable_dhcp_server_offload);
6241 	if (QDF_IS_STATUS_ERROR(status))
6242 		return;
6243 
6244 	if (enable_dhcp_server_offload)
6245 		wlan_hdd_set_dhcp_server_offload(link_info);
6246 }
6247 #else
6248 static inline void
wlan_hdd_dhcp_offload_enable(struct wlan_hdd_link_info * link_info)6249 wlan_hdd_dhcp_offload_enable(struct wlan_hdd_link_info *link_info)
6250 {
6251 }
6252 #endif /* DHCP_SERVER_OFFLOAD */
6253 
6254 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
wlan_hdd_set_sap_mcc_chnl_avoid(struct hdd_context * hdd_ctx)6255 static void wlan_hdd_set_sap_mcc_chnl_avoid(struct hdd_context *hdd_ctx)
6256 {
6257 	uint8_t sap_mcc_avoid = 0;
6258 	QDF_STATUS status;
6259 
6260 	status = ucfg_mlme_get_sap_mcc_chnl_avoid(hdd_ctx->psoc,
6261 						  &sap_mcc_avoid);
6262 	if (!QDF_IS_STATUS_SUCCESS(status))
6263 		hdd_err("can't get sap mcc chnl avoid, use def");
6264 	wlan_sap_set_channel_avoidance(hdd_ctx->mac_handle, sap_mcc_avoid);
6265 }
6266 #else
wlan_hdd_set_sap_mcc_chnl_avoid(struct hdd_context * hdd_ctx)6267 static void wlan_hdd_set_sap_mcc_chnl_avoid(struct hdd_context *hdd_ctx)
6268 {
6269 }
6270 #endif
6271 
6272 #ifdef WLAN_FEATURE_11BE_MLO
6273 /**
6274  * wlan_hdd_mlo_update() - handle mlo scenario for start bss
6275  * @link_info: Pointer to hostapd adapter
6276  *
6277  * Return: QDF_STATUS
6278  */
wlan_hdd_mlo_update(struct wlan_hdd_link_info * link_info)6279 static QDF_STATUS wlan_hdd_mlo_update(struct wlan_hdd_link_info *link_info)
6280 {
6281 	bool is_ml_ap;
6282 	uint8_t link_id = 0, num_link = 0;
6283 	struct hdd_context *hdd_ctx = link_info->adapter->hdd_ctx;
6284 	struct sap_config *config = &link_info->session.ap.sap_config;
6285 	struct hdd_beacon_data *beacon = link_info->session.ap.beacon;
6286 
6287 	if (config->SapHw_mode == eCSR_DOT11_MODE_11be ||
6288 	    config->SapHw_mode == eCSR_DOT11_MODE_11be_ONLY) {
6289 		wlan_hdd_get_mlo_link_id(beacon, &link_id, &num_link);
6290 		hdd_debug("MLO SAP vdev id %d, link id %d total link %d",
6291 			  link_info->vdev_id, link_id, num_link);
6292 		if (!num_link || !link_info->vdev->mlo_dev_ctx ||
6293 		    !link_info->vdev->mlo_dev_ctx->ap_ctx) {
6294 			hdd_debug("start 11be AP without mlo");
6295 			return QDF_STATUS_SUCCESS;
6296 		}
6297 		if (!mlo_ap_vdev_attach(link_info->vdev, link_id, num_link)) {
6298 			hdd_err("MLO SAP attach fails");
6299 			return QDF_STATUS_E_INVAL;
6300 		}
6301 
6302 		config->mlo_sap = true;
6303 		config->link_id = link_id;
6304 		config->num_link = num_link;
6305 	}
6306 
6307 	is_ml_ap = wlan_vdev_mlme_is_mlo_ap(link_info->vdev);
6308 	if (!policy_mgr_is_mlo_sap_concurrency_allowed(hdd_ctx->psoc,
6309 						       is_ml_ap,
6310 						       wlan_vdev_get_id(link_info->vdev))) {
6311 		hdd_err("MLO SAP concurrency check fails");
6312 		return QDF_STATUS_E_INVAL;
6313 	}
6314 
6315 	return QDF_STATUS_SUCCESS;
6316 }
6317 
wlan_hdd_mlo_reset(struct wlan_hdd_link_info * link_info)6318 void wlan_hdd_mlo_reset(struct wlan_hdd_link_info *link_info)
6319 {
6320 	struct sap_config *sap_config;
6321 
6322 	if (!wlan_vdev_mlme_is_mlo_ap(link_info->vdev))
6323 		return;
6324 
6325 	sap_config = &link_info->session.ap.sap_config;
6326 	sap_config->mlo_sap = false;
6327 	sap_config->link_id = 0;
6328 	sap_config->num_link = 0;
6329 	mlo_ap_vdev_detach(link_info->vdev);
6330 }
6331 #else
6332 static inline QDF_STATUS
wlan_hdd_mlo_update(struct wlan_hdd_link_info * link_info)6333 wlan_hdd_mlo_update(struct wlan_hdd_link_info *link_info)
6334 {
6335 	return QDF_STATUS_SUCCESS;
6336 }
6337 #endif
6338 
6339 static void
hdd_softap_update_pasn_vdev_params(struct hdd_context * hdd_ctx,uint8_t vdev_id,struct hdd_beacon_data * beacon,bool mfp_capable,bool mfp_required)6340 hdd_softap_update_pasn_vdev_params(struct hdd_context *hdd_ctx,
6341 				   uint8_t vdev_id,
6342 				   struct hdd_beacon_data *beacon,
6343 				   bool mfp_capable, bool mfp_required)
6344 {
6345 	uint32_t pasn_vdev_param = 0;
6346 	const uint8_t *rsnx_ie, *rsnxe_cap;
6347 	uint8_t cap_len;
6348 
6349 	if (mfp_capable)
6350 		pasn_vdev_param |= WLAN_CRYPTO_MFPC;
6351 
6352 	if (mfp_required)
6353 		pasn_vdev_param |= WLAN_CRYPTO_MFPR;
6354 
6355 	rsnx_ie = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_RSNXE,
6356 					   beacon->tail, beacon->tail_len);
6357 	if (!rsnx_ie)
6358 		return;
6359 
6360 	rsnxe_cap = wlan_crypto_parse_rsnxe_ie(rsnx_ie, &cap_len);
6361 	if (rsnxe_cap && *rsnxe_cap & WLAN_CRYPTO_RSNX_CAP_URNM_MFPR)
6362 		pasn_vdev_param |= WLAN_CRYPTO_URNM_MFPR;
6363 
6364 	wlan_crypto_vdev_set_param(hdd_ctx->psoc, vdev_id,
6365 				   wmi_vdev_param_11az_security_config,
6366 				   pasn_vdev_param);
6367 }
6368 
6369 #ifdef QCA_MULTIPASS_SUPPORT
6370 static void
wlan_hdd_set_multipass(struct wlan_objmgr_vdev * vdev)6371 wlan_hdd_set_multipass(struct wlan_objmgr_vdev *vdev)
6372 {
6373 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
6374 	cdp_config_param_type vdev_param;
6375 	uint8_t vdev_id;
6376 
6377 	vdev_id = wlan_vdev_get_id(vdev);
6378 	vdev_param.cdp_vdev_param_update_multipass = true;
6379 	cdp_txrx_set_vdev_param(soc, vdev_id, CDP_UPDATE_MULTIPASS, vdev_param);
6380 }
6381 #else
6382 static void
wlan_hdd_set_multipass(struct wlan_objmgr_vdev * vdev)6383 wlan_hdd_set_multipass(struct wlan_objmgr_vdev *vdev)
6384 {
6385 }
6386 #endif
6387 
wlan_hdd_update_ll_lt_sap_configs(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct sap_config * config)6388 static void wlan_hdd_update_ll_lt_sap_configs(struct wlan_objmgr_psoc *psoc,
6389 					      uint8_t vdev_id,
6390 					      struct sap_config *config)
6391 {
6392 	if (!policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id))
6393 		return;
6394 
6395 	config->SapHw_mode = eCSR_DOT11_MODE_11n;
6396 	config->ch_width_orig = CH_WIDTH_20MHZ;
6397 }
6398 
6399 /**
6400  * wlan_hdd_cfg80211_start_bss() - start bss
6401  * @link_info: Link info pointer in HDD adapter
6402  * @params: Pointer to start bss beacon parameters
6403  * @ssid: Pointer ssid
6404  * @ssid_len: Length of ssid
6405  * @hidden_ssid: Hidden SSID parameter
6406  * @check_for_concurrency: Flag to indicate if check for concurrency is needed
6407  *
6408  * Return: 0 for success non-zero for failure
6409  */
wlan_hdd_cfg80211_start_bss(struct wlan_hdd_link_info * link_info,struct cfg80211_beacon_data * params,const u8 * ssid,size_t ssid_len,enum nl80211_hidden_ssid hidden_ssid,bool check_for_concurrency)6410 int wlan_hdd_cfg80211_start_bss(struct wlan_hdd_link_info *link_info,
6411 				struct cfg80211_beacon_data *params,
6412 				const u8 *ssid, size_t ssid_len,
6413 				enum nl80211_hidden_ssid hidden_ssid,
6414 				bool check_for_concurrency)
6415 {
6416 	struct hdd_adapter *adapter = link_info->adapter;
6417 	struct sap_config *config;
6418 	struct hdd_beacon_data *beacon = NULL;
6419 	struct ieee80211_mgmt *mgmt_frame;
6420 	struct ieee80211_mgmt mgmt;
6421 	const uint8_t *ie = NULL;
6422 	eCsrEncryptionType rsn_encrypt_type;
6423 	eCsrEncryptionType mc_rsn_encrypt_type;
6424 	uint16_t capab_info;
6425 	int status = QDF_STATUS_SUCCESS, ret;
6426 	int qdf_status = QDF_STATUS_SUCCESS;
6427 	sap_event_cb sap_event_callback;
6428 	struct hdd_hostapd_state *hostapd_state;
6429 	mac_handle_t mac_handle;
6430 	int32_t i;
6431 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6432 	uint8_t mcc_to_scc_switch = 0, conc_rule1 = 0;
6433 	struct sme_config_params *sme_config = NULL;
6434 	bool mfp_capable = false;
6435 	bool mfp_required = false;
6436 	uint16_t prev_rsn_length = 0;
6437 	enum dfs_mode mode;
6438 	bool ignore_cac = 0;
6439 	uint8_t beacon_fixed_len, indoor_chnl_marking = 0;
6440 	bool sap_force_11n_for_11ac = 0;
6441 	bool go_force_11n_for_11ac = 0;
6442 	bool bval = false;
6443 	bool enable_dfs_scan = true;
6444 	bool deliver_start_evt = true;
6445 	enum reg_phymode reg_phy_mode, updated_phy_mode;
6446 	struct sap_context *sap_ctx;
6447 	struct wlan_objmgr_vdev *vdev;
6448 	uint32_t user_config_freq = 0;
6449 	struct hdd_ap_ctx *ap_ctx;
6450 	enum policy_mgr_con_mode pm_con_mode;
6451 
6452 	hdd_enter();
6453 
6454 	ret = wlan_hdd_validate_context(hdd_ctx);
6455 	if (ret != 0)
6456 		return ret;
6457 
6458 	if (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))
6459 		return -EINVAL;
6460 
6461 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_HDD_ID_OBJ_MGR);
6462 	if (!vdev)
6463 		return -EINVAL;
6464 
6465 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
6466 	ucfg_mlme_get_sap_force_11n_for_11ac(hdd_ctx->psoc,
6467 					     &sap_force_11n_for_11ac);
6468 	ucfg_mlme_get_go_force_11n_for_11ac(hdd_ctx->psoc,
6469 					    &go_force_11n_for_11ac);
6470 
6471 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags))
6472 		deliver_start_evt = false;
6473 
6474 	if (deliver_start_evt) {
6475 		status = ucfg_if_mgr_deliver_event(
6476 					vdev, WLAN_IF_MGR_EV_AP_START_BSS,
6477 					NULL);
6478 		if (!QDF_IS_STATUS_SUCCESS(status)) {
6479 			hdd_err("start bss failed!!");
6480 			ret = -EINVAL;
6481 			goto deliver_start_err;
6482 		}
6483 	}
6484 
6485 	/*
6486 	 * For STA+SAP/GO concurrency support from GUI, In case if
6487 	 * START AP/GO request comes just before the SAE authentication
6488 	 * completion on STA, SAE AUTH REQ waits for START AP RSP and
6489 	 * START AP RSP waits to complete SAE AUTH REQ.
6490 	 * Driver completes START AP RSP only upon SAE AUTH REQ timeout(5 sec)
6491 	 * as start ap will be in serialization pending queue, and SAE auth
6492 	 * sequence cannot complete as hostap thread is blocked in start ap
6493 	 * cfg80211 ops.
6494 	 * To avoid above deadlock until SAE timeout, abort the SAE connection
6495 	 * immediately and complete START AP/GO asap so that the upper layer
6496 	 * can trigger a fresh connection after START AP/GO completion.
6497 	 */
6498 	hdd_abort_ongoing_sta_sae_connection(hdd_ctx);
6499 
6500 	mac_handle = hdd_ctx->mac_handle;
6501 
6502 	sme_config = qdf_mem_malloc(sizeof(*sme_config));
6503 	if (!sme_config) {
6504 		ret = -ENOMEM;
6505 		goto free;
6506 	}
6507 
6508 	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(link_info);
6509 
6510 	config = &ap_ctx->sap_config;
6511 	if (!config->chan_freq) {
6512 		hdd_err("Invalid channel");
6513 		ret = -EINVAL;
6514 		goto free;
6515 	}
6516 
6517 	user_config_freq = config->chan_freq;
6518 
6519 	if (QDF_STATUS_SUCCESS !=
6520 	    ucfg_policy_mgr_get_indoor_chnl_marking(hdd_ctx->psoc,
6521 						    &indoor_chnl_marking))
6522 		hdd_err("can't get indoor channel marking, using default");
6523 	/* Mark the indoor channel (passive) to disable */
6524 	if (indoor_chnl_marking && adapter->device_mode == QDF_SAP_MODE) {
6525 		hdd_update_indoor_channel(hdd_ctx, true);
6526 		if (QDF_IS_STATUS_ERROR(
6527 		    sme_update_channel_list(mac_handle))) {
6528 			hdd_update_indoor_channel(hdd_ctx, false);
6529 			hdd_err("Can't start BSS: update channel list failed");
6530 			ret = -EINVAL;
6531 			goto free;
6532 		}
6533 
6534 		/* check if STA is on indoor channel*/
6535 		if (policy_mgr_is_force_scc(hdd_ctx->psoc))
6536 			hdd_check_and_disconnect_sta_on_invalid_channel(
6537 					hdd_ctx,
6538 					REASON_OPER_CHANNEL_DISABLED_INDOOR);
6539 	}
6540 
6541 	beacon = ap_ctx->beacon;
6542 
6543 	/*
6544 	 * beacon_fixed_len is the fixed length of beacon
6545 	 * frame which includes only mac header length and
6546 	 * beacon manadatory fields like timestamp,
6547 	 * beacon_int and capab_info.
6548 	 * (From the reference of struct ieee80211_mgmt)
6549 	 */
6550 	beacon_fixed_len = sizeof(mgmt) - sizeof(mgmt.u) +
6551 			   sizeof(mgmt.u.beacon);
6552 	if (beacon->head_len < beacon_fixed_len) {
6553 		hdd_err("Invalid beacon head len");
6554 		ret = -EINVAL;
6555 		goto error;
6556 	}
6557 
6558 	mgmt_frame = (struct ieee80211_mgmt *)beacon->head;
6559 
6560 	config->beacon_int = mgmt_frame->u.beacon.beacon_int;
6561 	config->dfs_cac_offload = hdd_ctx->dfs_cac_offload;
6562 	config->dtim_period = beacon->dtim_period;
6563 
6564 	if (config->acs_cfg.acs_mode == true) {
6565 		hdd_debug("acs_chan_freq %u, acs_dfs_mode %u",
6566 			  hdd_ctx->acs_policy.acs_chan_freq,
6567 			  hdd_ctx->acs_policy.acs_dfs_mode);
6568 
6569 		if (hdd_ctx->acs_policy.acs_chan_freq)
6570 			config->chan_freq = hdd_ctx->acs_policy.acs_chan_freq;
6571 		mode = hdd_ctx->acs_policy.acs_dfs_mode;
6572 		config->acs_dfs_mode = wlan_hdd_get_dfs_mode(mode);
6573 	}
6574 	ucfg_util_vdev_mgr_set_acs_mode_for_vdev(vdev,
6575 						 config->acs_cfg.acs_mode);
6576 
6577 	ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc, &mcc_to_scc_switch);
6578 
6579 	wlan_hdd_set_sap_beacon_protection(hdd_ctx, link_info, beacon);
6580 
6581 	/* Overwrite second AP's channel with first only when:
6582 	 * 1. If operating mode is single mac
6583 	 * 2. or if 2nd AP is coming up on 5G band channel
6584 	 */
6585 	ret = 0;
6586 	if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) ||
6587 	    !WLAN_REG_IS_24GHZ_CH_FREQ(config->chan_freq)) {
6588 		ret = wlan_hdd_sap_cfg_dfs_override(adapter);
6589 		if (ret < 0)
6590 			goto error;
6591 	}
6592 
6593 	config->chan_freq = wlan_ll_lt_sap_override_freq(hdd_ctx->psoc,
6594 							 link_info->vdev_id,
6595 							 config->chan_freq);
6596 
6597 	if (!ret && wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, config->chan_freq))
6598 		hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
6599 
6600 	if (QDF_STATUS_SUCCESS !=
6601 	    wlan_hdd_validate_operation_channel(hdd_ctx, config->chan_freq)) {
6602 		hdd_err("Invalid Ch_freq: %d", config->chan_freq);
6603 		ret = -EINVAL;
6604 		goto error;
6605 	}
6606 	ucfg_scan_cfg_get_dfs_chan_scan_allowed(hdd_ctx->psoc,
6607 						&enable_dfs_scan);
6608 
6609 	/* reject SAP if DFS channel scan is not allowed */
6610 	if (!enable_dfs_scan &&
6611 	    CHANNEL_STATE_DFS ==
6612 	    wlan_reg_get_channel_state_from_secondary_list_for_freq(hdd_ctx->pdev,
6613 								    config->chan_freq)) {
6614 		hdd_err("No SAP start on DFS channel");
6615 		ret = -EOPNOTSUPP;
6616 		goto error;
6617 	}
6618 
6619 	status = ucfg_mlme_get_dfs_ignore_cac(hdd_ctx->psoc, &ignore_cac);
6620 	if (!QDF_IS_STATUS_SUCCESS(status))
6621 		hdd_err("can't get ignore cac flag");
6622 
6623 	wlansap_set_dfs_ignore_cac(mac_handle, ignore_cac);
6624 	wlansap_set_dfs_preferred_channel_location(mac_handle);
6625 	wlan_hdd_set_sap_mcc_chnl_avoid(hdd_ctx);
6626 
6627 	tgt_dfs_set_tx_leakage_threshold(hdd_ctx->pdev);
6628 
6629 	capab_info = mgmt_frame->u.beacon.capab_info;
6630 
6631 	config->privacy = (mgmt_frame->u.beacon.capab_info &
6632 			    WLAN_CAPABILITY_PRIVACY) ? true : false;
6633 
6634 	ap_ctx->privacy = config->privacy;
6635 
6636 	/*Set wps station to configured */
6637 	ie = wlan_hdd_get_wps_ie_ptr(beacon->tail, beacon->tail_len);
6638 
6639 	if (ie) {
6640 		/* To access ie[15], length needs to be at least 14 */
6641 		if (ie[1] < 14) {
6642 			hdd_err("Wps Ie Length(%hhu) is too small",
6643 				ie[1]);
6644 			ret = -EINVAL;
6645 			goto error;
6646 		} else if (memcmp(&ie[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) ==
6647 			   0) {
6648 			hdd_debug("WPS IE(len %d)", (ie[1] + 2));
6649 			/* Check 15 bit of WPS IE as it contain information for
6650 			 * wps state
6651 			 */
6652 			if (SAP_WPS_ENABLED_UNCONFIGURED == ie[15]) {
6653 				config->wps_state =
6654 					SAP_WPS_ENABLED_UNCONFIGURED;
6655 			} else if (SAP_WPS_ENABLED_CONFIGURED == ie[15]) {
6656 				config->wps_state = SAP_WPS_ENABLED_CONFIGURED;
6657 			}
6658 		}
6659 	} else {
6660 		config->wps_state = SAP_WPS_DISABLED;
6661 	}
6662 
6663 	ap_ctx->encryption_type = eCSR_ENCRYPT_TYPE_NONE;
6664 	config->RSNWPAReqIELength = 0;
6665 	memset(&config->RSNWPAReqIE[0], 0, sizeof(config->RSNWPAReqIE));
6666 	ie = wlan_get_ie_ptr_from_eid(WLAN_EID_RSN, beacon->tail,
6667 				      beacon->tail_len);
6668 	/* the RSN and WAPI are not coexisting, so we can check the
6669 	 * WAPI IE if the RSN IE is not set.
6670 	 */
6671 	if (!ie)
6672 		ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_WAPI, beacon->tail,
6673 					      beacon->tail_len);
6674 
6675 	if (ie && ie[1]) {
6676 		config->RSNWPAReqIELength = ie[1] + 2;
6677 		if (config->RSNWPAReqIELength < sizeof(config->RSNWPAReqIE))
6678 			memcpy(&config->RSNWPAReqIE[0], ie,
6679 			       config->RSNWPAReqIELength);
6680 		else
6681 			hdd_err("RSN/WPA/WAPI IE MAX Length exceeded; length =%d",
6682 			       config->RSNWPAReqIELength);
6683 		/* The actual processing may eventually be more extensive than
6684 		 * this. Right now, just consume any PMKIDs that are sent in
6685 		 * by the app.
6686 		 */
6687 		status =
6688 			hdd_softap_unpack_ie(cds_get_context
6689 						     (QDF_MODULE_ID_SME),
6690 					     &rsn_encrypt_type,
6691 					     &mc_rsn_encrypt_type,
6692 					     &config->akm_list,
6693 					     &mfp_capable,
6694 					     &mfp_required,
6695 					     config->RSNWPAReqIE[1] + 2,
6696 					     config->RSNWPAReqIE);
6697 		if (status != QDF_STATUS_SUCCESS) {
6698 			ret = -EINVAL;
6699 			goto error;
6700 		} else {
6701 			/* Now copy over all the security attributes you have
6702 			 * parsed out. Use the cipher type in the RSN IE
6703 			 */
6704 			ap_ctx->encryption_type = rsn_encrypt_type;
6705 			hdd_debug("CSR Encryption: %d mcEncryption: %d num_akm_suites:%d",
6706 				  rsn_encrypt_type, mc_rsn_encrypt_type,
6707 				  config->akm_list.numEntries);
6708 			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
6709 					   QDF_TRACE_LEVEL_DEBUG,
6710 					   config->akm_list.authType,
6711 					   config->akm_list.numEntries);
6712 
6713 			hdd_softap_update_pasn_vdev_params(
6714 					hdd_ctx, link_info->vdev_id,
6715 					beacon, mfp_capable, mfp_required);
6716 		}
6717 	}
6718 
6719 	ie = wlan_get_vendor_ie_ptr_from_oui(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
6720 					     beacon->tail, beacon->tail_len);
6721 
6722 	if (ie && ie[1] && (ie[0] == DOT11F_EID_WPA)) {
6723 		if (config->RSNWPAReqIE[0]) {
6724 			/*Mixed mode WPA/WPA2 */
6725 			prev_rsn_length = config->RSNWPAReqIELength;
6726 			config->RSNWPAReqIELength += ie[1] + 2;
6727 			if (config->RSNWPAReqIELength <
6728 			    sizeof(config->RSNWPAReqIE))
6729 				memcpy(&config->RSNWPAReqIE[0] +
6730 				       prev_rsn_length, ie, ie[1] + 2);
6731 			else
6732 				hdd_err("RSNWPA IE MAX Length exceeded; length: %d",
6733 				       config->RSNWPAReqIELength);
6734 		} else {
6735 			config->RSNWPAReqIELength = ie[1] + 2;
6736 			if (config->RSNWPAReqIELength <
6737 			    sizeof(config->RSNWPAReqIE))
6738 				memcpy(&config->RSNWPAReqIE[0], ie,
6739 				       config->RSNWPAReqIELength);
6740 			else
6741 				hdd_err("RSNWPA IE MAX Length exceeded; length: %d",
6742 				       config->RSNWPAReqIELength);
6743 			status = hdd_softap_unpack_ie
6744 					(cds_get_context(QDF_MODULE_ID_SME),
6745 					 &rsn_encrypt_type,
6746 					 &mc_rsn_encrypt_type,
6747 					 &config->akm_list,
6748 					 &mfp_capable, &mfp_required,
6749 					 config->RSNWPAReqIE[1] + 2,
6750 					 config->RSNWPAReqIE);
6751 
6752 			if (status != QDF_STATUS_SUCCESS) {
6753 				ret = -EINVAL;
6754 				goto error;
6755 			} else {
6756 				ap_ctx->encryption_type = rsn_encrypt_type;
6757 				hdd_debug("CSR Encryption: %d mcEncryption: %d num_akm_suites:%d",
6758 					  rsn_encrypt_type, mc_rsn_encrypt_type,
6759 					  config->akm_list.numEntries);
6760 				QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
6761 						   QDF_TRACE_LEVEL_DEBUG,
6762 						   config->akm_list.authType,
6763 						   config->akm_list.numEntries);
6764 			}
6765 		}
6766 	}
6767 
6768 	if (config->RSNWPAReqIELength > sizeof(config->RSNWPAReqIE)) {
6769 		hdd_err("RSNWPAReqIELength is too large");
6770 		ret = -EINVAL;
6771 		goto error;
6772 	}
6773 
6774 	config->SSIDinfo.ssidHidden = false;
6775 
6776 	if (ssid) {
6777 		qdf_mem_copy(config->SSIDinfo.ssid.ssId, ssid, ssid_len);
6778 		config->SSIDinfo.ssid.length = ssid_len;
6779 
6780 		switch (hidden_ssid) {
6781 		case NL80211_HIDDEN_SSID_NOT_IN_USE:
6782 			config->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
6783 			break;
6784 		case NL80211_HIDDEN_SSID_ZERO_LEN:
6785 			hdd_debug("HIDDEN_SSID_ZERO_LEN");
6786 			config->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
6787 			break;
6788 		case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
6789 			hdd_debug("HIDDEN_SSID_ZERO_CONTENTS");
6790 			config->SSIDinfo.ssidHidden =
6791 				eHIDDEN_SSID_ZERO_CONTENTS;
6792 			break;
6793 		default:
6794 			hdd_err("Wrong hidden_ssid param: %d", hidden_ssid);
6795 			break;
6796 		}
6797 	}
6798 
6799 	wlan_hdd_set_multipass(vdev);
6800 
6801 	qdf_mem_copy(config->self_macaddr.bytes,
6802 		     adapter->mac_addr.bytes,
6803 		     QDF_MAC_ADDR_SIZE);
6804 
6805 	/* default value */
6806 	config->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
6807 	config->num_accept_mac = 0;
6808 	config->num_deny_mac = 0;
6809 	status = ucfg_policy_mgr_get_conc_rule1(hdd_ctx->psoc, &conc_rule1);
6810 	if (!QDF_IS_STATUS_SUCCESS(status))
6811 		hdd_err("can't get ucfg_policy_mgr_get_conc_rule1, use def");
6812 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
6813 	/*
6814 	 * We don't want P2PGO to follow STA's channel
6815 	 * so lets limit the logic for SAP only.
6816 	 * Later if we decide to make p2pgo follow STA's
6817 	 * channel then remove this check.
6818 	 */
6819 	if ((0 == conc_rule1) ||
6820 	    (conc_rule1 && (QDF_SAP_MODE == adapter->device_mode)))
6821 		config->cc_switch_mode = mcc_to_scc_switch;
6822 #endif
6823 
6824 	if (!(ssid && qdf_str_len(PRE_CAC_SSID) == ssid_len &&
6825 	      (0 == qdf_mem_cmp(ssid, PRE_CAC_SSID, ssid_len)))) {
6826 		uint16_t beacon_data_len;
6827 
6828 		beacon_data_len = beacon->head_len - beacon_fixed_len;
6829 
6830 		ie = wlan_get_ie_ptr_from_eid(WLAN_EID_SUPP_RATES,
6831 					&mgmt_frame->u.beacon.variable[0],
6832 					beacon_data_len);
6833 
6834 		if (ie) {
6835 			ie++;
6836 			if (ie[0] > WLAN_SUPPORTED_RATES_IE_MAX_LEN) {
6837 				hdd_err("Invalid supported rates %d",
6838 					ie[0]);
6839 				ret = -EINVAL;
6840 				goto error;
6841 			}
6842 			config->supported_rates.numRates = ie[0];
6843 			ie++;
6844 			for (i = 0;
6845 			     i < config->supported_rates.numRates; i++) {
6846 				if (ie[i])
6847 					config->supported_rates.rate[i] = ie[i];
6848 			}
6849 			hdd_debug("Configured Num Supported rates: %d",
6850 				  config->supported_rates.numRates);
6851 			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
6852 					   QDF_TRACE_LEVEL_DEBUG,
6853 					   config->supported_rates.rate,
6854 					   config->supported_rates.numRates);
6855 		}
6856 		ie = wlan_get_ie_ptr_from_eid(WLAN_EID_EXT_SUPP_RATES,
6857 					      beacon->tail,
6858 					      beacon->tail_len);
6859 		if (ie) {
6860 			ie++;
6861 			if (ie[0] > WLAN_SUPPORTED_RATES_IE_MAX_LEN) {
6862 				hdd_err("Invalid supported rates %d",
6863 					ie[0]);
6864 				ret = -EINVAL;
6865 				goto error;
6866 			}
6867 			config->extended_rates.numRates = ie[0];
6868 			ie++;
6869 			for (i = 0; i < config->extended_rates.numRates; i++) {
6870 				if (ie[i])
6871 					config->extended_rates.rate[i] = ie[i];
6872 			}
6873 
6874 			hdd_debug("Configured Num Extended rates: %d",
6875 				  config->extended_rates.numRates);
6876 			QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD,
6877 					   QDF_TRACE_LEVEL_DEBUG,
6878 					   config->extended_rates.rate,
6879 					   config->extended_rates.numRates);
6880 		}
6881 
6882 		config->require_h2e = false;
6883 		wlan_hdd_check_h2e(&config->supported_rates,
6884 				   &config->require_h2e);
6885 		wlan_hdd_check_h2e(&config->extended_rates,
6886 				   &config->require_h2e);
6887 	}
6888 
6889 	if (!cds_is_sub_20_mhz_enabled())
6890 		wlan_hdd_set_sap_hwmode(link_info);
6891 
6892 	qdf_status = wlan_hdd_mlo_update(link_info);
6893 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
6894 		ret = -EINVAL;
6895 		goto error;
6896 	}
6897 
6898 	qdf_status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &bval);
6899 	if (QDF_IS_STATUS_ERROR(qdf_status))
6900 		hdd_err("Failed to get vht_for_24ghz");
6901 
6902 	if (WLAN_REG_IS_24GHZ_CH_FREQ(config->chan_freq) && bval &&
6903 	    (config->SapHw_mode == eCSR_DOT11_MODE_11n ||
6904 	    config->SapHw_mode == eCSR_DOT11_MODE_11n_ONLY))
6905 		config->SapHw_mode = eCSR_DOT11_MODE_11ac;
6906 
6907 	if (((adapter->device_mode == QDF_SAP_MODE) &&
6908 	     (sap_force_11n_for_11ac)) ||
6909 	     ((adapter->device_mode == QDF_P2P_GO_MODE) &&
6910 	     (go_force_11n_for_11ac))) {
6911 		if (config->SapHw_mode == eCSR_DOT11_MODE_11ac ||
6912 		    config->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)
6913 			config->SapHw_mode = eCSR_DOT11_MODE_11n;
6914 	}
6915 
6916 	wlan_hdd_update_ll_lt_sap_configs(hdd_ctx->psoc,
6917 					  link_info->vdev_id, config);
6918 
6919 	config->sap_orig_hw_mode = config->SapHw_mode;
6920 	reg_phy_mode = csr_convert_to_reg_phy_mode(config->SapHw_mode,
6921 						   config->chan_freq);
6922 	updated_phy_mode = wlan_reg_get_max_phymode(hdd_ctx->pdev, reg_phy_mode,
6923 						    config->chan_freq);
6924 	config->SapHw_mode = csr_convert_from_reg_phy_mode(updated_phy_mode);
6925 	if (config->sap_orig_hw_mode != config->SapHw_mode)
6926 		hdd_info("orig phymode %d new phymode %d",
6927 			 config->sap_orig_hw_mode, config->SapHw_mode);
6928 	qdf_mem_zero(sme_config, sizeof(*sme_config));
6929 	sme_get_config_param(mac_handle, sme_config);
6930 	/* Override hostapd.conf wmm_enabled only for 11n and 11AC configs (IOT)
6931 	 * As per spec 11N/AC STA are QOS STA and may not connect or throughput
6932 	 * may not be good with non QOS 11N AP
6933 	 * Default: enable QOS for SAP unless WMM IE not present for 11bga
6934 	 */
6935 	sme_config->csr_config.WMMSupportMode = WMM_USER_MODE_AUTO;
6936 	ie = wlan_get_vendor_ie_ptr_from_oui(WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE,
6937 					     beacon->tail, beacon->tail_len);
6938 	if (!ie && (config->SapHw_mode == eCSR_DOT11_MODE_11a ||
6939 		config->SapHw_mode == eCSR_DOT11_MODE_11g ||
6940 		config->SapHw_mode == eCSR_DOT11_MODE_11b))
6941 		sme_config->csr_config.WMMSupportMode = WMM_USER_MODE_NO_QOS;
6942 	sme_update_config(mac_handle, sme_config);
6943 
6944 	if ((adapter->device_mode == QDF_SAP_MODE && sap_force_11n_for_11ac) ||
6945 	    (adapter->device_mode == QDF_P2P_GO_MODE && go_force_11n_for_11ac)) {
6946 		if (config->ch_width_orig > CH_WIDTH_40MHZ)
6947 			config->ch_width_orig = CH_WIDTH_40MHZ;
6948 	}
6949 
6950 	if (wlan_hdd_setup_driver_overrides(adapter)) {
6951 		ret = -EINVAL;
6952 		goto error;
6953 	}
6954 
6955 	config->ch_params.ch_width = config->ch_width_orig;
6956 	if (sap_phymode_is_eht(config->SapHw_mode))
6957 		wlan_reg_set_create_punc_bitmap(&config->ch_params, true);
6958 	if ((config->ch_params.ch_width == CH_WIDTH_80P80MHZ) &&
6959 	    ucfg_mlme_get_restricted_80p80_bw_supp(hdd_ctx->psoc)) {
6960 		if (!((config->ch_params.center_freq_seg0 == 138 &&
6961 		    config->ch_params.center_freq_seg1 == 155) ||
6962 		    (config->ch_params.center_freq_seg1 == 138 &&
6963 		     config->ch_params.center_freq_seg0 == 155))) {
6964 			hdd_debug("Falling back to 80 from 80p80 as non supported freq_seq0 %d and freq_seq1 %d",
6965 				  config->ch_params.mhz_freq_seg0,
6966 				  config->ch_params.mhz_freq_seg1);
6967 			config->ch_params.center_freq_seg1 = 0;
6968 			config->ch_params.mhz_freq_seg1 = 0;
6969 			config->ch_width_orig = CH_WIDTH_80MHZ;
6970 			config->ch_params.ch_width = config->ch_width_orig;
6971 		}
6972 	}
6973 
6974 	wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev,
6975 						config->chan_freq,
6976 						config->sec_ch_freq,
6977 						&config->ch_params,
6978 						REG_CURRENT_PWR_MODE);
6979 	if (0 != wlan_hdd_cfg80211_update_apies(link_info)) {
6980 		hdd_err("SAP Not able to set AP IEs");
6981 		ret = -EINVAL;
6982 		goto error;
6983 	}
6984 
6985 	hdd_nofl_debug("SAP mac:" QDF_MAC_ADDR_FMT " SSID: " QDF_SSID_FMT " BCNINTV:%d Freq:%d freq_seg0:%d freq_seg1:%d ch_width:%d HW mode:%d privacy:%d akm:%d acs_mode:%d acs_dfs_mode %d dtim period:%d MFPC %d, MFPR %d",
6986 		       QDF_MAC_ADDR_REF(adapter->mac_addr.bytes),
6987 		       QDF_SSID_REF(config->SSIDinfo.ssid.length,
6988 				    config->SSIDinfo.ssid.ssId),
6989 		       (int)config->beacon_int,
6990 		       config->chan_freq, config->ch_params.mhz_freq_seg0,
6991 		       config->ch_params.mhz_freq_seg1,
6992 		       config->ch_params.ch_width,
6993 		       config->SapHw_mode, config->privacy,
6994 		       config->authType, config->acs_cfg.acs_mode,
6995 		       config->acs_dfs_mode, config->dtim_period,
6996 		       mfp_capable, mfp_required);
6997 
6998 	mutex_lock(&hdd_ctx->sap_lock);
6999 	if (cds_is_driver_unloading()) {
7000 		mutex_unlock(&hdd_ctx->sap_lock);
7001 
7002 		hdd_err("The driver is unloading, ignore the bss starting");
7003 		ret = -EINVAL;
7004 		goto error;
7005 	}
7006 
7007 	if (test_bit(SOFTAP_BSS_STARTED, &link_info->link_flags)) {
7008 		mutex_unlock(&hdd_ctx->sap_lock);
7009 
7010 		wlansap_reset_sap_config_add_ie(config, eUPDATE_IE_ALL);
7011 		/* Bss already started. just return. */
7012 		/* TODO Probably it should update some beacon params. */
7013 		hdd_debug("Bss Already started...Ignore the request");
7014 		hdd_exit();
7015 		ret = 0;
7016 		goto free;
7017 	}
7018 	pm_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(hdd_ctx->psoc,
7019 							   adapter->device_mode,
7020 							   link_info->vdev_id);
7021 
7022 	if (check_for_concurrency) {
7023 		if (!policy_mgr_allow_concurrency(
7024 				hdd_ctx->psoc,
7025 				pm_con_mode,
7026 				config->chan_freq, HW_MODE_20_MHZ,
7027 				policy_mgr_get_conc_ext_flags(vdev, false),
7028 				link_info->vdev_id)) {
7029 			mutex_unlock(&hdd_ctx->sap_lock);
7030 
7031 			hdd_err("This concurrency combination is not allowed");
7032 			ret = -EINVAL;
7033 			goto error;
7034 		}
7035 	}
7036 
7037 	if (!hdd_set_connection_in_progress(true)) {
7038 		mutex_unlock(&hdd_ctx->sap_lock);
7039 
7040 		hdd_err("Can't start BSS: set connection in progress failed");
7041 		ret = -EINVAL;
7042 		goto error;
7043 	}
7044 
7045 	config->persona = adapter->device_mode;
7046 
7047 	sap_event_callback = hdd_hostapd_sap_event_cb;
7048 
7049 	ap_ctx->dfs_cac_block_tx = true;
7050 	set_bit(SOFTAP_INIT_DONE, &link_info->link_flags);
7051 
7052 	ucfg_dp_set_dfs_cac_tx(vdev, true);
7053 
7054 	qdf_event_reset(&hostapd_state->qdf_event);
7055 
7056 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
7057 	if (!sap_ctx) {
7058 		ret = -EINVAL;
7059 		goto error;
7060 	}
7061 
7062 	status = wlansap_start_bss(sap_ctx, sap_event_callback, config,
7063 				   adapter->dev);
7064 	if (!QDF_IS_STATUS_SUCCESS(status)) {
7065 		mutex_unlock(&hdd_ctx->sap_lock);
7066 
7067 		hdd_set_connection_in_progress(false);
7068 		hdd_err("SAP Start Bss fail");
7069 		ret = -EINVAL;
7070 		goto error;
7071 	}
7072 
7073 	qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event,
7074 					SME_CMD_START_BSS_TIMEOUT);
7075 
7076 	wlansap_reset_sap_config_add_ie(config, eUPDATE_IE_ALL);
7077 
7078 	if (QDF_IS_STATUS_ERROR(qdf_status) ||
7079 	    QDF_IS_STATUS_ERROR(hostapd_state->qdf_status)) {
7080 		mutex_unlock(&hdd_ctx->sap_lock);
7081 		if (QDF_IS_STATUS_ERROR(qdf_status))
7082 			hdd_err("Wait for start BSS failed status %d",
7083 				qdf_status);
7084 		else
7085 			hdd_err("Start BSS failed status %d",
7086 				hostapd_state->qdf_status);
7087 		hdd_set_connection_in_progress(false);
7088 		sme_get_command_q_status(mac_handle);
7089 		wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(link_info));
7090 		if (!cds_is_driver_recovering())
7091 			QDF_ASSERT(0);
7092 		ret = -EINVAL;
7093 		goto error;
7094 	}
7095 	/* Successfully started Bss update the state bit. */
7096 	set_bit(SOFTAP_BSS_STARTED, &link_info->link_flags);
7097 
7098 	mutex_unlock(&hdd_ctx->sap_lock);
7099 
7100 	/* Initialize WMM configuration */
7101 	hdd_wmm_dscp_initial_state(adapter);
7102 	if (hostapd_state->bss_state == BSS_START) {
7103 		policy_mgr_incr_active_session(hdd_ctx->psoc,
7104 					adapter->device_mode,
7105 					link_info->vdev_id);
7106 
7107 		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
7108 					    true);
7109 		wlan_set_sap_user_config_freq(vdev, user_config_freq);
7110 	}
7111 
7112 	wlan_hdd_dhcp_offload_enable(link_info);
7113 	ucfg_p2p_status_start_bss(vdev);
7114 
7115 	/* Check and restart SAP if it is on unsafe channel */
7116 	hdd_unsafe_channel_restart_sap(hdd_ctx);
7117 
7118 	ucfg_ftm_time_sync_update_bss_state(vdev,
7119 					    FTM_TIME_SYNC_BSS_STARTED);
7120 
7121 	hdd_set_connection_in_progress(false);
7122 	policy_mgr_process_force_scc_for_nan(hdd_ctx->psoc);
7123 	ret = 0;
7124 	goto free;
7125 
7126 error:
7127 	wlan_hdd_mlo_reset(link_info);
7128 	/* Revert the indoor to passive marking if START BSS fails */
7129 	if (indoor_chnl_marking && adapter->device_mode == QDF_SAP_MODE) {
7130 		hdd_update_indoor_channel(hdd_ctx, false);
7131 		sme_update_channel_list(mac_handle);
7132 	}
7133 	clear_bit(SOFTAP_INIT_DONE, &link_info->link_flags);
7134 	qdf_atomic_set(&ap_ctx->acs_in_progress, 0);
7135 	wlansap_reset_sap_config_add_ie(config, eUPDATE_IE_ALL);
7136 
7137 free:
7138 	wlan_twt_concurrency_update(hdd_ctx);
7139 	if (deliver_start_evt) {
7140 		struct if_mgr_event_data evt_data;
7141 
7142 		evt_data.status = QDF_STATUS_SUCCESS;
7143 		if (ret < 0)
7144 			evt_data.status = QDF_STATUS_E_FAILURE;
7145 
7146 		status = ucfg_if_mgr_deliver_event(
7147 				vdev, WLAN_IF_MGR_EV_AP_START_BSS_COMPLETE,
7148 				&evt_data);
7149 		if (!QDF_IS_STATUS_SUCCESS(status)) {
7150 			hdd_err("start bss complete failed!!");
7151 			ret = -EINVAL;
7152 		}
7153 	}
7154 	qdf_mem_free(sme_config);
7155 deliver_start_err:
7156 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
7157 
7158 	return ret;
7159 }
7160 
hdd_destroy_acs_timer(struct hdd_adapter * adapter)7161 int hdd_destroy_acs_timer(struct hdd_adapter *adapter)
7162 {
7163 	struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink);
7164 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
7165 
7166 	if (!ap_ctx->vendor_acs_timer_initialized)
7167 		return 0;
7168 
7169 	ap_ctx->vendor_acs_timer_initialized = false;
7170 
7171 	clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->deflink->link_flags);
7172 	if (QDF_TIMER_STATE_RUNNING == ap_ctx->vendor_acs_timer.state) {
7173 		qdf_status = qdf_mc_timer_stop(&ap_ctx->vendor_acs_timer);
7174 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
7175 			hdd_err("Failed to stop ACS timer");
7176 	}
7177 
7178 	if (ap_ctx->vendor_acs_timer.user_data)
7179 		qdf_mem_free(ap_ctx->vendor_acs_timer.user_data);
7180 
7181 	qdf_mc_timer_destroy(&ap_ctx->vendor_acs_timer);
7182 
7183 	return 0;
7184 }
7185 
7186 /**
7187  * __wlan_hdd_cfg80211_stop_ap() - stop soft ap
7188  * @wiphy: Pointer to wiphy structure
7189  * @dev: Pointer to net_device structure
7190  *
7191  * Return: 0 for success non-zero for failure
7192  */
__wlan_hdd_cfg80211_stop_ap(struct wiphy * wiphy,struct net_device * dev)7193 static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7194 					struct net_device *dev)
7195 {
7196 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7197 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
7198 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
7199 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
7200 	tSirUpdateIE update_ie;
7201 	int ret;
7202 	mac_handle_t mac_handle;
7203 	struct hdd_ap_ctx *ap_ctx;
7204 
7205 	hdd_enter_dev(dev);
7206 
7207 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter->deflink);
7208 
7209 	ret = wlan_hdd_validate_context(hdd_ctx);
7210 	/*
7211 	 * In case of SSR and other FW down cases, validate context will
7212 	 * fail. But return success to upper layer so that it can clean up
7213 	 * kernel variables like beacon interval. If the failure status
7214 	 * is returned then next set beacon command will fail as beacon
7215 	 * interval in not reset.
7216 	 */
7217 	if (ret)
7218 		goto exit;
7219 
7220 	if (hdd_ctx->is_wiphy_suspended) {
7221 		hdd_debug("wiphy is suspended");
7222 		return -EINVAL;
7223 	}
7224 
7225 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
7226 		hdd_err("Command not allowed in FTM mode");
7227 		goto exit;
7228 	}
7229 
7230 	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
7231 		hdd_err("Driver module is closed; dropping request");
7232 		goto exit;
7233 	}
7234 
7235 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
7236 		goto exit;
7237 
7238 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
7239 		   TRACE_CODE_HDD_CFG80211_STOP_AP,
7240 		   adapter->deflink->vdev_id, adapter->device_mode);
7241 
7242 	if (!(adapter->device_mode == QDF_SAP_MODE ||
7243 	      adapter->device_mode == QDF_P2P_GO_MODE)) {
7244 		hdd_err("stop ap is given on device modes other than SAP/GO. Hence return");
7245 		goto exit;
7246 	}
7247 
7248 	/*
7249 	 * Reset sap mandatory channel list.If band is changed then
7250 	 * frequencies of new selected band can be removed in pcl
7251 	 * modification based on sap mandatory channel list.
7252 	 */
7253 	status = policy_mgr_reset_sap_mandatory_channels(hdd_ctx->psoc);
7254 	/* Don't go to exit in case of failure. Clean up & stop BSS */
7255 	if (QDF_IS_STATUS_ERROR(status))
7256 		hdd_err("failed to reset mandatory channels");
7257 
7258 	/*
7259 	 * For STA+SAP/GO concurrency support from GUI, In case if
7260 	 * STOP AP/GO request comes just before the SAE authentication
7261 	 * completion on STA, SAE AUTH REQ waits for STOP AP RSP and
7262 	 * STOP AP RSP waits to complete SAE AUTH REQ.
7263 	 * Driver completes STOP AP RSP only upon SAE AUTH REQ timeout(5 sec)
7264 	 * as stop ap will be in serialization pending queue, and SAE auth
7265 	 * sequence cannot complete as hostap thread is blocked in stop ap
7266 	 * cfg80211 ops.
7267 	 * To avoid above deadlock until SAE timeout, abort the SAE connection
7268 	 * immediately and complete STOP AP/GO asap so that the upper layer
7269 	 * can trigger a fresh connection after STOP AP/GO completion.
7270 	 */
7271 	hdd_abort_ongoing_sta_sae_connection(hdd_ctx);
7272 
7273 	/* Clear SOFTAP_INIT_DONE flag to mark stop_ap deinit. So that we do
7274 	 * not restart SAP after SSR as SAP is already stopped from user space.
7275 	 * This update is moved to start of this function to resolve stop_ap
7276 	 * call during SSR case. Adapter gets cleaned up as part of SSR.
7277 	 */
7278 	clear_bit(SOFTAP_INIT_DONE, &adapter->deflink->link_flags);
7279 	hdd_debug("Event flags 0x%lx(%s) Device_mode %s(%d)",
7280 		  adapter->event_flags, (adapter->dev)->name,
7281 		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
7282 
7283 	if (adapter->device_mode == QDF_SAP_MODE) {
7284 		wlan_hdd_del_station(adapter, NULL);
7285 		mac_handle = hdd_ctx->mac_handle;
7286 		status = wlan_hdd_flush_pmksa_cache(adapter->deflink);
7287 	}
7288 
7289 	cds_flush_work(&adapter->sap_stop_bss_work);
7290 	ap_ctx->sap_config.acs_cfg.acs_mode = false;
7291 	hdd_dcs_clear(adapter);
7292 	qdf_atomic_set(&ap_ctx->acs_in_progress, 0);
7293 	hdd_debug("Disabling queues");
7294 	wlan_hdd_netif_queue_control(adapter,
7295 				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
7296 				     WLAN_CONTROL_PATH);
7297 
7298 	wlan_hdd_cleanup_actionframe(adapter->deflink);
7299 	wlan_hdd_cleanup_remain_on_channel_ctx(adapter->deflink);
7300 	mutex_lock(&hdd_ctx->sap_lock);
7301 	if (test_bit(SOFTAP_BSS_STARTED, &adapter->deflink->link_flags)) {
7302 		struct hdd_hostapd_state *hostapd_state =
7303 			WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter->deflink);
7304 
7305 		hdd_place_marker(adapter, "TRY TO STOP", NULL);
7306 		qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
7307 		status = wlansap_stop_bss(ap_ctx->sap_context);
7308 		if (QDF_IS_STATUS_SUCCESS(status)) {
7309 			qdf_status =
7310 				qdf_wait_single_event(&hostapd_state->
7311 					qdf_stop_bss_event,
7312 					SME_CMD_STOP_BSS_TIMEOUT);
7313 
7314 			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
7315 				hdd_err("qdf wait for single_event failed!!");
7316 				hdd_place_marker(adapter, "STOP with FAILURE",
7317 						 NULL);
7318 				hdd_sap_indicate_disconnect_for_sta(adapter);
7319 				QDF_ASSERT(0);
7320 			}
7321 		}
7322 		clear_bit(SOFTAP_BSS_STARTED, &adapter->deflink->link_flags);
7323 
7324 		/*BSS stopped, clear the active sessions for this device mode*/
7325 		policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
7326 						adapter->device_mode,
7327 						adapter->deflink->vdev_id);
7328 		hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
7329 					    false);
7330 		wlan_twt_concurrency_update(hdd_ctx);
7331 		wlan_set_sap_user_config_freq(adapter->deflink->vdev, 0);
7332 		status = ucfg_if_mgr_deliver_event(
7333 				adapter->deflink->vdev,
7334 				WLAN_IF_MGR_EV_AP_STOP_BSS_COMPLETE, NULL);
7335 		if (!QDF_IS_STATUS_SUCCESS(status)) {
7336 			hdd_err("Stopping the BSS failed");
7337 			goto exit;
7338 		}
7339 		qdf_mem_free(ap_ctx->beacon);
7340 		ap_ctx->beacon = NULL;
7341 	} else {
7342 		hdd_debug("SAP already down");
7343 		mutex_unlock(&hdd_ctx->sap_lock);
7344 		goto exit;
7345 	}
7346 
7347 	mutex_unlock(&hdd_ctx->sap_lock);
7348 
7349 	mac_handle = hdd_ctx->mac_handle;
7350 
7351 	if (ucfg_pre_cac_is_active(hdd_ctx->psoc))
7352 		ucfg_pre_cac_clean_up(hdd_ctx->psoc);
7353 
7354 	if (status != QDF_STATUS_SUCCESS) {
7355 		hdd_err("Stopping the BSS");
7356 		goto exit;
7357 	}
7358 
7359 	qdf_copy_macaddr(&update_ie.bssid, &adapter->mac_addr);
7360 	update_ie.vdev_id = adapter->deflink->vdev_id;
7361 	update_ie.ieBufferlength = 0;
7362 	update_ie.pAdditionIEBuffer = NULL;
7363 	update_ie.append = true;
7364 	update_ie.notify = true;
7365 	if (sme_update_add_ie(mac_handle,
7366 			      &update_ie,
7367 			      eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) {
7368 		hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
7369 	}
7370 
7371 	if (sme_update_add_ie(mac_handle,
7372 			      &update_ie,
7373 			      eUPDATE_IE_ASSOC_RESP) == QDF_STATUS_E_FAILURE) {
7374 		hdd_err("Could not pass on ASSOC_RSP data to PE");
7375 	}
7376 	/* Reset WNI_CFG_PROBE_RSP Flags */
7377 	wlan_hdd_reset_prob_rspies(adapter->deflink);
7378 	hdd_destroy_acs_timer(adapter);
7379 
7380 	ucfg_p2p_status_stop_bss(adapter->deflink->vdev);
7381 	ucfg_ftm_time_sync_update_bss_state(adapter->deflink->vdev,
7382 					    FTM_TIME_SYNC_BSS_STOPPED);
7383 
7384 exit:
7385 	qdf_mem_free(ap_ctx->beacon);
7386 	ap_ctx->beacon = NULL;
7387 	if (QDF_IS_STATUS_SUCCESS(status))
7388 		hdd_place_marker(adapter, "STOP with SUCCESS", NULL);
7389 	else
7390 		hdd_place_marker(adapter, "STOP with FAILURE", NULL);
7391 
7392 	hdd_exit();
7393 
7394 	return 0;
7395 }
7396 
7397 #ifdef CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT
wlan_hdd_cfg80211_stop_ap(struct wiphy * wiphy,struct net_device * dev,unsigned int link_id)7398 int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
7399 			      unsigned int link_id)
7400 #else
7401 int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
7402 #endif
7403 {
7404 	int errno;
7405 	struct osif_vdev_sync *vdev_sync;
7406 
7407 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
7408 	/*
7409 	 * The stop_ap can be called in the same context through
7410 	 * wlan_hdd_del_virtual_intf. As vdev_trans is already taking place as
7411 	 * part of the del_vitrtual_intf, this vdev_op cannot start.
7412 	 * Return 0 in case op is not started so that the kernel frees the
7413 	 * beacon memory properly.
7414 	 */
7415 	if (errno)
7416 		return 0;
7417 
7418 	errno = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7419 
7420 	osif_vdev_sync_op_stop(vdev_sync);
7421 
7422 	return errno;
7423 }
7424 
7425 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
7426 /*
7427  * Beginning with 4.7 struct ieee80211_channel uses enum nl80211_band
7428  * ieee80211_channel_band() - return channel band
7429  * chan: channel
7430  *
7431  * Return: channel band
7432  */
7433 static inline
ieee80211_channel_band(const struct ieee80211_channel * chan)7434 enum nl80211_band ieee80211_channel_band(const struct ieee80211_channel *chan)
7435 {
7436 	return chan->band;
7437 }
7438 #else
7439 /*
7440  * Prior to 4.7 struct ieee80211_channel used enum ieee80211_band. However the
7441  * ieee80211_band enum values are assigned from enum nl80211_band so we can
7442  * safely typecast one to another.
7443  */
7444 static inline
ieee80211_channel_band(const struct ieee80211_channel * chan)7445 enum nl80211_band ieee80211_channel_band(const struct ieee80211_channel *chan)
7446 {
7447 	enum ieee80211_band band = chan->band;
7448 
7449 	return (enum nl80211_band)band;
7450 }
7451 #endif
7452 
7453 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) || \
7454 	defined(CFG80211_BEACON_TX_RATE_CUSTOM_BACKPORT)
7455 /**
7456  * hdd_get_data_rate_from_rate_mask() - convert mask to rate
7457  * @wiphy: Pointer to wiphy
7458  * @band: band
7459  * @bit_rate_mask: pointer to bit_rake_mask
7460  *
7461  * This function takes band and bit_rate_mask as input and
7462  * derives the beacon_tx_rate based on the supported rates
7463  * published as part of wiphy register.
7464  *
7465  * Return: data rate for success or zero for failure
7466  */
hdd_get_data_rate_from_rate_mask(struct wiphy * wiphy,enum nl80211_band band,struct cfg80211_bitrate_mask * bit_rate_mask)7467 static uint16_t hdd_get_data_rate_from_rate_mask(struct wiphy *wiphy,
7468 		enum nl80211_band band,
7469 		struct cfg80211_bitrate_mask *bit_rate_mask)
7470 {
7471 	struct ieee80211_supported_band *sband = wiphy->bands[band];
7472 	int sband_n_bitrates;
7473 	struct ieee80211_rate *sband_bitrates;
7474 	int i;
7475 
7476 	if (sband) {
7477 		sband_bitrates = sband->bitrates;
7478 		sband_n_bitrates = sband->n_bitrates;
7479 		for (i = 0; i < sband_n_bitrates; i++) {
7480 			if (bit_rate_mask->control[band].legacy == (1 << i))
7481 				return sband_bitrates[i].bitrate;
7482 		}
7483 	}
7484 	return 0;
7485 }
7486 
7487 /**
7488  * hdd_update_beacon_rate() - Update beacon tx rate
7489  * @link_info: Pointer to link_info in adapter
7490  * @wiphy: Pointer to wiphy
7491  * @params: Pointet to cfg80211_ap_settings
7492  *
7493  * This function updates the beacon tx rate which is provided
7494  * as part of cfg80211_ap_settions in to the sap_config
7495  * structure
7496  *
7497  * Return: none
7498  */
7499 static void
hdd_update_beacon_rate(struct wlan_hdd_link_info * link_info,struct wiphy * wiphy,struct cfg80211_ap_settings * params)7500 hdd_update_beacon_rate(struct wlan_hdd_link_info *link_info,
7501 		       struct wiphy *wiphy, struct cfg80211_ap_settings *params)
7502 {
7503 	struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
7504 	struct cfg80211_bitrate_mask *beacon_rate_mask;
7505 	enum nl80211_band band;
7506 
7507 	band = ieee80211_channel_band(params->chandef.chan);
7508 	beacon_rate_mask = &params->beacon_rate;
7509 	if (beacon_rate_mask->control[band].legacy) {
7510 		ap_ctx->sap_config.beacon_tx_rate =
7511 			hdd_get_data_rate_from_rate_mask(wiphy, band,
7512 					beacon_rate_mask);
7513 		hdd_debug("beacon mask value %u, rate %hu",
7514 			  params->beacon_rate.control[0].legacy,
7515 			  ap_ctx->sap_config.beacon_tx_rate);
7516 	}
7517 }
7518 #else
7519 static inline void
hdd_update_beacon_rate(struct wlan_hdd_link_info * link_info,struct wiphy * wiphy,struct cfg80211_ap_settings * params)7520 hdd_update_beacon_rate(struct wlan_hdd_link_info *link_info,
7521 		       struct wiphy *wiphy, struct cfg80211_ap_settings *params)
7522 {
7523 }
7524 #endif
7525 
7526 /**
7527  * wlan_hdd_get_sap_ch_params() - Get channel parameters of SAP
7528  * @hdd_ctx: HDD context pointer
7529  * @vdev_id: vdev id
7530  * @freq: channel frequency (MHz)
7531  * @ch_params: pointer to channel parameters
7532  *
7533  * The function gets channel parameters of SAP by vdev id.
7534  *
7535  * Return: QDF_STATUS_SUCCESS if get channel parameters successful
7536  */
7537 static QDF_STATUS
wlan_hdd_get_sap_ch_params(struct hdd_context * hdd_ctx,uint8_t vdev_id,uint32_t freq,struct ch_params * ch_params)7538 wlan_hdd_get_sap_ch_params(struct hdd_context *hdd_ctx,
7539 			   uint8_t vdev_id, uint32_t freq,
7540 			   struct ch_params *ch_params)
7541 {
7542 	struct wlan_hdd_link_info *link_info;
7543 
7544 	if (!hdd_ctx || !ch_params) {
7545 		hdd_err("invalid hdd_ctx or ch_params");
7546 		return QDF_STATUS_E_INVAL;
7547 	}
7548 
7549 	link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
7550 	if (!link_info)
7551 		return QDF_STATUS_E_INVAL;
7552 
7553 	if (!wlan_sap_get_ch_params(WLAN_HDD_GET_SAP_CTX_PTR(link_info),
7554 				    ch_params))
7555 		wlan_reg_set_channel_params_for_pwrmode(hdd_ctx->pdev, freq, 0,
7556 							ch_params,
7557 							REG_CURRENT_PWR_MODE);
7558 	return QDF_STATUS_SUCCESS;
7559 }
7560 
7561 /**
7562  * wlan_hdd_is_ap_ap_force_scc_override() - force Same band SCC chan override
7563  * @link_info: Link info pointer in HDD adapter
7564  * @chandef: SAP starting channel
7565  * @new_chandef: new override SAP channel
7566  *
7567  * The function will override the second SAP chan to the first SAP's home
7568  * channel if the FW doesn't support MCC and force SCC enabled in INI.
7569  *
7570  * Return: true if channel override
7571  */
7572 static bool
wlan_hdd_is_ap_ap_force_scc_override(struct wlan_hdd_link_info * link_info,struct cfg80211_chan_def * chandef,struct cfg80211_chan_def * new_chandef)7573 wlan_hdd_is_ap_ap_force_scc_override(struct wlan_hdd_link_info *link_info,
7574 				     struct cfg80211_chan_def *chandef,
7575 				     struct cfg80211_chan_def *new_chandef)
7576 {
7577 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
7578 	struct ch_params ch_params = {0};
7579 	enum nl80211_channel_type channel_type;
7580 	uint8_t con_vdev_id = WLAN_INVALID_VDEV_ID;
7581 	uint32_t con_freq = 0;
7582 	struct ieee80211_channel *ieee_chan;
7583 	uint32_t freq;
7584 	QDF_STATUS status;
7585 	struct wlan_objmgr_vdev *vdev;
7586 	enum QDF_OPMODE opmode;
7587 
7588 	if (!hdd_ctx || !chandef) {
7589 		hdd_err("hdd context or chandef is NULL");
7590 		return false;
7591 	}
7592 	freq = chandef->chan->center_freq;
7593 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
7594 	if (!vdev) {
7595 		hdd_err("failed to get vdev");
7596 		return false;
7597 	}
7598 	if (policy_mgr_is_ap_ap_mcc_allow(
7599 			hdd_ctx->psoc, hdd_ctx->pdev, vdev, freq,
7600 			hdd_map_nl_chan_width(chandef->width),
7601 			&con_vdev_id, &con_freq)) {
7602 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
7603 		return false;
7604 	}
7605 
7606 	opmode = wlan_vdev_mlme_get_opmode(vdev);
7607 
7608 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
7609 
7610 	if (opmode == QDF_SAP_MODE &&
7611 	    hdd_handle_p2p_go_for_3rd_ap_conc(hdd_ctx, freq))
7612 		return false;
7613 	if (!con_freq)
7614 		return false;
7615 	ieee_chan = ieee80211_get_channel(hdd_ctx->wiphy,
7616 					  con_freq);
7617 	if (!ieee_chan) {
7618 		hdd_err("channel conversion failed");
7619 		return false;
7620 	}
7621 
7622 	status = wlan_hdd_get_sap_ch_params(hdd_ctx, con_vdev_id, con_freq,
7623 					    &ch_params);
7624 	if (QDF_IS_STATUS_ERROR(status))
7625 		return false;
7626 
7627 	switch (ch_params.sec_ch_offset) {
7628 	case PHY_SINGLE_CHANNEL_CENTERED:
7629 		channel_type = NL80211_CHAN_HT20;
7630 		break;
7631 	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
7632 		channel_type = NL80211_CHAN_HT40MINUS;
7633 		break;
7634 	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
7635 		channel_type = NL80211_CHAN_HT40PLUS;
7636 		break;
7637 	default:
7638 		channel_type = NL80211_CHAN_NO_HT;
7639 		break;
7640 	}
7641 	cfg80211_chandef_create(new_chandef, ieee_chan, channel_type);
7642 	switch (ch_params.ch_width) {
7643 	case CH_WIDTH_80MHZ:
7644 		new_chandef->width = NL80211_CHAN_WIDTH_80;
7645 		break;
7646 	case CH_WIDTH_80P80MHZ:
7647 		new_chandef->width = NL80211_CHAN_WIDTH_80P80;
7648 		if (ch_params.mhz_freq_seg1)
7649 			new_chandef->center_freq2 = ch_params.mhz_freq_seg1;
7650 		break;
7651 	case CH_WIDTH_160MHZ:
7652 		new_chandef->width = NL80211_CHAN_WIDTH_160;
7653 		break;
7654 	default:
7655 		break;
7656 	}
7657 
7658 	wlan_hdd_set_chandef_width(new_chandef, ch_params.ch_width);
7659 
7660 	if ((ch_params.ch_width == CH_WIDTH_80MHZ) ||
7661 	    (ch_params.ch_width == CH_WIDTH_80P80MHZ) ||
7662 	    (ch_params.ch_width == CH_WIDTH_160MHZ) ||
7663 	    wlan_hdd_is_chwidth_320mhz(ch_params.ch_width)) {
7664 		if (ch_params.mhz_freq_seg0)
7665 			new_chandef->center_freq1 = ch_params.mhz_freq_seg0;
7666 	}
7667 
7668 	hdd_debug("override AP freq %d to first AP(vdev_id %d) center_freq:%d width:%d freq1:%d freq2:%d ",
7669 		  freq, con_vdev_id, new_chandef->chan->center_freq,
7670 		  new_chandef->width, new_chandef->center_freq1,
7671 		  new_chandef->center_freq2);
7672 	return true;
7673 }
7674 
7675 #ifdef NDP_SAP_CONCURRENCY_ENABLE
7676 /**
7677  * hdd_sap_nan_check_and_disable_unsupported_ndi: Wrapper function for
7678  * ucfg_nan_check_and_disable_unsupported_ndi
7679  * @psoc: pointer to psoc object
7680  * @force: When set forces NDI disable
7681  *
7682  * Return: QDF_STATUS
7683  */
7684 static inline QDF_STATUS
hdd_sap_nan_check_and_disable_unsupported_ndi(struct wlan_objmgr_psoc * psoc,bool force)7685 hdd_sap_nan_check_and_disable_unsupported_ndi(struct wlan_objmgr_psoc *psoc,
7686 					      bool force)
7687 {
7688 	return QDF_STATUS_SUCCESS;
7689 }
7690 #else
7691 static inline QDF_STATUS
hdd_sap_nan_check_and_disable_unsupported_ndi(struct wlan_objmgr_psoc * psoc,bool force)7692 hdd_sap_nan_check_and_disable_unsupported_ndi(struct wlan_objmgr_psoc *psoc,
7693 					      bool force)
7694 {
7695 	return  ucfg_nan_check_and_disable_unsupported_ndi(psoc, force);
7696 }
7697 #endif
7698 
7699 #if defined(WLAN_SUPPORT_TWT) && \
7700 	((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) || \
7701 	  defined(CFG80211_TWT_RESPONDER_SUPPORT))
7702 #ifdef WLAN_TWT_CONV_SUPPORTED
wlan_hdd_configure_twt_responder(struct hdd_context * hdd_ctx,bool twt_responder)7703 void wlan_hdd_configure_twt_responder(struct hdd_context *hdd_ctx,
7704 				      bool twt_responder)
7705 {
7706 	bool twt_res_svc_cap, enable_twt, twt_res_cfg;
7707 	uint32_t reason;
7708 
7709 	enable_twt = ucfg_twt_cfg_is_twt_enabled(hdd_ctx->psoc);
7710 	ucfg_twt_get_responder(hdd_ctx->psoc, &twt_res_svc_cap);
7711 	ucfg_twt_cfg_get_responder(hdd_ctx->psoc, &twt_res_cfg);
7712 	if (!twt_res_cfg && !twt_responder) {
7713 		hdd_debug("TWT responder already disable, skip");
7714 		return;
7715 	}
7716 	ucfg_twt_cfg_set_responder(hdd_ctx->psoc,
7717 				   QDF_MIN(twt_res_svc_cap,
7718 					   (enable_twt &&
7719 					    twt_responder)));
7720 	hdd_debug("cfg80211 TWT responder:%d", twt_responder);
7721 	if (enable_twt && twt_responder) {
7722 		hdd_send_twt_responder_enable_cmd(hdd_ctx);
7723 	} else {
7724 		reason = HOST_TWT_DISABLE_REASON_NONE;
7725 		hdd_send_twt_responder_disable_cmd(hdd_ctx, reason);
7726 	}
7727 
7728 }
7729 
7730 static void
wlan_hdd_update_twt_responder(struct hdd_adapter * adapter,struct cfg80211_ap_settings * params)7731 wlan_hdd_update_twt_responder(struct hdd_adapter *adapter,
7732 			      struct cfg80211_ap_settings *params)
7733 {
7734 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7735 
7736 	adapter->deflink->session.ap.sap_config.cfg80211_twt_responder =
7737 							params->twt_responder;
7738 	wlan_hdd_configure_twt_responder(hdd_ctx, params->twt_responder);
7739 }
7740 
7741 #else
wlan_hdd_configure_twt_responder(struct hdd_context * hdd_ctx,bool twt_responder)7742 void wlan_hdd_configure_twt_responder(struct hdd_context *hdd_ctx,
7743 				      bool twt_responder)
7744 {
7745 	bool twt_res_svc_cap, enable_twt;
7746 	uint32_t reason;
7747 
7748 	enable_twt = ucfg_mlme_is_twt_enabled(hdd_ctx->psoc);
7749 	ucfg_mlme_get_twt_res_service_cap(hdd_ctx->psoc, &twt_res_svc_cap);
7750 	ucfg_mlme_set_twt_responder(hdd_ctx->psoc,
7751 				    QDF_MIN(twt_res_svc_cap,
7752 					    (enable_twt && twt_responder)));
7753 	hdd_debug("cfg80211 TWT responder:%d", twt_responder);
7754 	if (enable_twt && twt_responder) {
7755 		hdd_send_twt_responder_enable_cmd(hdd_ctx);
7756 	} else {
7757 		reason = HOST_TWT_DISABLE_REASON_NONE;
7758 		hdd_send_twt_responder_disable_cmd(hdd_ctx, reason);
7759 	}
7760 }
7761 
7762 static void
wlan_hdd_update_twt_responder(struct hdd_adapter * adapter,struct cfg80211_ap_settings * params)7763 wlan_hdd_update_twt_responder(struct hdd_adapter *adapter,
7764 			      struct cfg80211_ap_settings *params)
7765 {
7766 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7767 
7768 	adapter->deflink->session.ap.sap_config.cfg80211_twt_responder =
7769 							params->twt_responder;
7770 	wlan_hdd_configure_twt_responder(hdd_ctx, params->twt_responder);
7771 }
7772 #endif
7773 #else
7774 static inline void
wlan_hdd_update_twt_responder(struct hdd_adapter * adapter,struct cfg80211_ap_settings * params)7775 wlan_hdd_update_twt_responder(struct hdd_adapter *adapter,
7776 			      struct cfg80211_ap_settings *params)
7777 {}
7778 
wlan_hdd_configure_twt_responder(struct hdd_context * hdd_ctx,bool twt_responder)7779 void wlan_hdd_configure_twt_responder(struct hdd_context *hdd_ctx,
7780 				      bool twt_responder)
7781 {}
7782 #endif
7783 
7784 #ifdef CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT
7785 static inline struct cfg80211_chan_def
wlan_util_get_chan_def(struct wireless_dev * wdev,unsigned int link_id)7786 wlan_util_get_chan_def(struct wireless_dev *wdev, unsigned int link_id)
7787 {
7788 	return wdev->links[link_id].ap.chandef;
7789 }
7790 #else
7791 static inline struct cfg80211_chan_def
wlan_util_get_chan_def(struct wireless_dev * wdev,unsigned int link_id)7792 wlan_util_get_chan_def(struct wireless_dev *wdev, unsigned int link_id)
7793 {
7794 	return wdev->chandef;
7795 }
7796 #endif
7797 
7798 #if defined(WLAN_FEATURE_SR) && \
7799 	(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
7800 /**
7801  * hdd_update_he_obss_pd() - Enable or disable spatial reuse
7802  * based on user space input and concurrency combination.
7803  * @link_info:  Pointer to link_info in hostapd adapter
7804  * @params: Pointer to AP configuration from cfg80211
7805  *
7806  * Return: void
7807  */
hdd_update_he_obss_pd(struct wlan_hdd_link_info * link_info,struct cfg80211_ap_settings * params)7808 static void hdd_update_he_obss_pd(struct wlan_hdd_link_info *link_info,
7809 				  struct cfg80211_ap_settings *params)
7810 {
7811 	struct wlan_objmgr_vdev *vdev;
7812 	struct ieee80211_he_obss_pd *obss_pd;
7813 	uint8_t sr_device_modes;
7814 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
7815 
7816 	ucfg_mlme_get_sr_enable_modes(hdd_ctx->psoc, &sr_device_modes);
7817 	if (!(sr_device_modes & (1 << link_info->adapter->device_mode))) {
7818 		hdd_debug("SR operation not allowed for mode %d",
7819 			  link_info->adapter->device_mode);
7820 		return;
7821 	}
7822 
7823 	if (!params || !params->he_obss_pd.enable)
7824 		return;
7825 
7826 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
7827 	if (!vdev)
7828 		return;
7829 
7830 	obss_pd = &params->he_obss_pd;
7831 	ucfg_spatial_reuse_set_sr_config(vdev, obss_pd->sr_ctrl,
7832 					 obss_pd->non_srg_max_offset);
7833 	ucfg_spatial_reuse_set_sr_enable(vdev, obss_pd->enable);
7834 	hdd_debug("obss_pd_enable: %d, sr_ctrl: %d, non_srg_max_offset: %d",
7835 		  obss_pd->enable, obss_pd->sr_ctrl,
7836 		  obss_pd->non_srg_max_offset);
7837 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
7838 }
7839 #else
hdd_update_he_obss_pd(struct wlan_hdd_link_info * link_info,struct cfg80211_ap_settings * params)7840 static inline void hdd_update_he_obss_pd(struct wlan_hdd_link_info *link_info,
7841 					 struct cfg80211_ap_settings *params)
7842 {
7843 }
7844 #endif
7845 
hdd_update_param_chandef(struct wlan_hdd_link_info * link_info,struct cfg80211_chan_def * chandef)7846 static void hdd_update_param_chandef(struct wlan_hdd_link_info *link_info,
7847 				     struct cfg80211_chan_def *chandef)
7848 {
7849 	struct wlan_channel *chan;
7850 
7851 	chan = wlan_vdev_get_active_channel(link_info->vdev);
7852 	if (!chan)
7853 		return;
7854 
7855 	hdd_create_chandef(link_info->adapter, chan, chandef);
7856 }
7857 
7858 /**
7859  * __wlan_hdd_cfg80211_start_ap() - start soft ap mode
7860  * @wiphy: Pointer to wiphy structure
7861  * @dev: Pointer to net_device structure
7862  * @params: Pointer to AP settings parameters
7863  *
7864  * Return: 0 for success non-zero for failure
7865  */
__wlan_hdd_cfg80211_start_ap(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_ap_settings * params)7866 static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7867 					struct net_device *dev,
7868 					struct cfg80211_ap_settings *params)
7869 {
7870 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7871 	struct hdd_context *hdd_ctx;
7872 	enum hw_mode_bandwidth channel_width;
7873 	int status;
7874 	struct sme_sta_inactivity_timeout  *sta_inactivity_timer;
7875 	uint8_t mandt_chnl_list = 0;
7876 	qdf_freq_t freq;
7877 	uint16_t sta_cnt, sap_cnt;
7878 	bool val;
7879 	struct cfg80211_chan_def new_chandef;
7880 	struct cfg80211_chan_def *chandef;
7881 	bool srd_channel_allowed, disable_nan = true;
7882 	enum QDF_OPMODE vdev_opmode;
7883 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS], i;
7884 	enum policy_mgr_con_mode intf_pm_mode;
7885 	struct wlan_objmgr_vdev *vdev;
7886 	uint16_t link_id = 0;
7887 	struct sap_config *sap_config;
7888 	struct hdd_ap_ctx *ap_ctx;
7889 	struct wlan_hdd_link_info *link_info = adapter->deflink;
7890 
7891 	hdd_enter();
7892 
7893 	clear_bit(SOFTAP_INIT_DONE, &link_info->link_flags);
7894 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
7895 		hdd_err("Command not allowed in FTM mode");
7896 		return -EINVAL;
7897 	}
7898 
7899 	if (wlan_hdd_validate_vdev_id(link_info->vdev_id))
7900 		return -EINVAL;
7901 
7902 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
7903 		   TRACE_CODE_HDD_CFG80211_START_AP,
7904 		   link_info->vdev_id, params->beacon_interval);
7905 
7906 	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
7907 		hdd_err("HDD adapter magic is invalid");
7908 		return -ENODEV;
7909 	}
7910 
7911 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7912 	status = wlan_hdd_validate_context(hdd_ctx);
7913 	if (0 != status)
7914 		return status;
7915 
7916 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
7917 	sap_config = &ap_ctx->sap_config;
7918 
7919 	hdd_nofl_info("%s(vdevid-%d): START AP: mode %s(%d) %d bw %d sub20 %d",
7920 		      dev->name, link_info->vdev_id,
7921 		      qdf_opmode_str(adapter->device_mode),
7922 		      adapter->device_mode,
7923 		      params->chandef.chan->center_freq,
7924 		      params->chandef.width,
7925 		      cds_is_sub_20_mhz_enabled());
7926 	if (policy_mgr_is_hw_mode_change_in_progress(hdd_ctx->psoc)) {
7927 		status = policy_mgr_wait_for_connection_update(
7928 			hdd_ctx->psoc);
7929 		if (!QDF_IS_STATUS_SUCCESS(status)) {
7930 			hdd_err("qdf wait for event failed!!");
7931 			return -EINVAL;
7932 		}
7933 	}
7934 
7935 	hdd_reg_wait_for_country_change(hdd_ctx);
7936 
7937 	channel_width = wlan_hdd_get_channel_bw(params->chandef.width);
7938 	freq = (qdf_freq_t)params->chandef.chan->center_freq;
7939 
7940 	if (wlan_reg_is_6ghz_chan_freq(freq) &&
7941 	    !wlan_reg_is_6ghz_band_set(hdd_ctx->pdev)) {
7942 		hdd_err("6 GHz band disabled.");
7943 		return -EINVAL;
7944 	}
7945 
7946 	chandef = &params->chandef;
7947 	if ((adapter->device_mode == QDF_SAP_MODE ||
7948 	     adapter->device_mode == QDF_P2P_GO_MODE) &&
7949 	    wlan_hdd_is_ap_ap_force_scc_override(link_info,
7950 						 chandef, &new_chandef)) {
7951 		chandef = &new_chandef;
7952 		freq = (qdf_freq_t)chandef->chan->center_freq;
7953 		channel_width = wlan_hdd_get_channel_bw(chandef->width);
7954 	}
7955 
7956 	if (QDF_STATUS_SUCCESS !=
7957 	    ucfg_policy_mgr_get_sap_mandt_chnl(hdd_ctx->psoc, &mandt_chnl_list))
7958 		hdd_err("can't get mandatory channel list");
7959 	if (mandt_chnl_list && adapter->device_mode == QDF_SAP_MODE)
7960 		policy_mgr_init_sap_mandatory_chan(hdd_ctx->psoc,
7961 						   chandef->chan->center_freq);
7962 
7963 	sap_config->ch_params.center_freq_seg0 =
7964 				cds_freq_to_chan(chandef->center_freq1);
7965 	sap_config->ch_params.center_freq_seg1 =
7966 				cds_freq_to_chan(chandef->center_freq2);
7967 	sap_config->ch_params.mhz_freq_seg0 = chandef->center_freq1;
7968 	sap_config->ch_params.mhz_freq_seg1 = chandef->center_freq2;
7969 
7970 	status = policy_mgr_is_sap_allowed_on_dfs_freq(
7971 						hdd_ctx->pdev,
7972 						link_info->vdev_id,
7973 						chandef->chan->center_freq);
7974 	if (!status)
7975 		return -EINVAL;
7976 
7977 	status = policy_mgr_is_sap_go_interface_allowed_on_indoor(
7978 						hdd_ctx->pdev,
7979 						link_info->vdev_id,
7980 						chandef->chan->center_freq);
7981 	if (!status) {
7982 		hdd_debug("SAP start not allowed on indoor channel %d",
7983 			  chandef->chan->center_freq);
7984 		return -EINVAL;
7985 	}
7986 
7987 	intf_pm_mode =
7988 		policy_mgr_qdf_opmode_to_pm_con_mode(hdd_ctx->psoc,
7989 						     adapter->device_mode,
7990 						     adapter->deflink->vdev_id);
7991 	status = policy_mgr_is_multi_sap_allowed_on_same_band(
7992 				hdd_ctx->pdev,
7993 				intf_pm_mode,
7994 				chandef->chan->center_freq);
7995 	if (!status)
7996 		return -EINVAL;
7997 
7998 	vdev_opmode = wlan_vdev_mlme_get_opmode(link_info->vdev);
7999 	ucfg_mlme_get_srd_master_mode_for_vdev(hdd_ctx->psoc, vdev_opmode,
8000 					       &srd_channel_allowed);
8001 
8002 	if (!srd_channel_allowed &&
8003 	    wlan_reg_is_etsi_srd_chan_for_freq(hdd_ctx->pdev, freq)) {
8004 		hdd_err("vdev opmode %d not allowed on SRD channel.",
8005 			vdev_opmode);
8006 		return -EINVAL;
8007 	}
8008 	if (cds_is_sub_20_mhz_enabled()) {
8009 		enum channel_state ch_state;
8010 		enum phy_ch_width sub_20_ch_width = CH_WIDTH_INVALID;
8011 		struct ch_params ch_params;
8012 
8013 		if (CHANNEL_STATE_DFS ==
8014 		    wlan_reg_get_channel_state_from_secondary_list_for_freq(
8015 								hdd_ctx->pdev,
8016 								freq)) {
8017 			hdd_err("Can't start SAP-DFS (channel=%d)with sub 20 MHz ch wd",
8018 				freq);
8019 			return -EINVAL;
8020 		}
8021 		if (channel_width != HW_MODE_20_MHZ) {
8022 			hdd_err("Hostapd (20+ MHz) conflits with config.ini (sub 20 MHz)");
8023 			return -EINVAL;
8024 		}
8025 		if (cds_is_5_mhz_enabled())
8026 			sub_20_ch_width = CH_WIDTH_5MHZ;
8027 		if (cds_is_10_mhz_enabled())
8028 			sub_20_ch_width = CH_WIDTH_10MHZ;
8029 		qdf_mem_zero(&ch_params, sizeof(ch_params));
8030 		ch_params.ch_width = sub_20_ch_width;
8031 		if (WLAN_REG_IS_5GHZ_CH_FREQ(freq))
8032 			ch_state =
8033 			wlan_reg_get_5g_bonded_channel_state_for_pwrmode(
8034 						hdd_ctx->pdev, freq, &ch_params,
8035 						REG_CURRENT_PWR_MODE);
8036 		else
8037 			ch_state = wlan_reg_get_2g_bonded_channel_state_for_freq(hdd_ctx->pdev, freq,
8038 										 sub_20_ch_width, 0);
8039 		if (CHANNEL_STATE_DISABLE == ch_state) {
8040 			hdd_err("Given ch width not supported by reg domain");
8041 			return -EINVAL;
8042 		}
8043 		sap_config->SapHw_mode = eCSR_DOT11_MODE_abg;
8044 	}
8045 
8046 	sta_cnt = policy_mgr_get_mode_specific_conn_info(hdd_ctx->psoc, NULL,
8047 							 vdev_id_list,
8048 							 PM_STA_MODE);
8049 	sap_cnt = policy_mgr_get_sap_mode_info(hdd_ctx->psoc, NULL,
8050 					       &vdev_id_list[sta_cnt]);
8051 
8052 	/* Disable NAN Disc before starting P2P GO or STA+SAP or SAP+SAP */
8053 	if (adapter->device_mode == QDF_P2P_GO_MODE || sta_cnt ||
8054 	    (sap_cnt > (MAX_SAP_NUM_CONCURRENCY_WITH_NAN - 1))) {
8055 		hdd_debug("Invalid NAN concurrency. SAP: %d STA: %d P2P_GO: %d",
8056 			  sap_cnt, sta_cnt,
8057 			  (adapter->device_mode == QDF_P2P_GO_MODE));
8058 		for (i = 0; i < sta_cnt + sap_cnt; i++)
8059 			if (vdev_id_list[i] == link_info->vdev_id)
8060 				disable_nan = false;
8061 		if (disable_nan)
8062 			ucfg_nan_disable_concurrency(hdd_ctx->psoc);
8063 	}
8064 
8065 	/* NDI + SAP conditional supported */
8066 	hdd_sap_nan_check_and_disable_unsupported_ndi(hdd_ctx->psoc, true);
8067 
8068 	if (policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
8069 						      PM_NAN_DISC_MODE, NULL) &&
8070 	    !policy_mgr_nan_sap_pre_enable_conc_check(hdd_ctx->psoc,
8071 						      PM_SAP_MODE, freq))
8072 		hdd_debug("NAN disabled due to concurrency constraints");
8073 
8074 	/* check if concurrency is allowed */
8075 	if (!policy_mgr_allow_concurrency(
8076 			hdd_ctx->psoc, intf_pm_mode, freq, channel_width,
8077 			policy_mgr_get_conc_ext_flags(link_info->vdev,
8078 						      false),
8079 			link_info->vdev_id)) {
8080 		hdd_err("Connection failed due to concurrency check failure");
8081 		return -EINVAL;
8082 	}
8083 
8084 	status = policy_mgr_reset_connection_update(hdd_ctx->psoc);
8085 	if (!QDF_IS_STATUS_SUCCESS(status))
8086 		hdd_err("ERR: clear event failed");
8087 
8088 	/*
8089 	 * For Start Ap, the driver checks whether the SAP comes up in a
8090 	 * different or same band( whether we require DBS or Not).
8091 	 * If we dont require DBS, then the driver does nothing assuming
8092 	 * the state would be already in non DBS mode, and just continues
8093 	 * with vdev up on same MAC, by stopping the opportunistic timer,
8094 	 * which results in a connection of 1x1 if already the state was in
8095 	 * DBS. So first stop timer, and check the current hw mode.
8096 	 * If the SAP comes up in band different from STA, DBS mode is already
8097 	 * set. IF not, then well check for upgrade, and shift the connection
8098 	 * back to single MAC 2x2 (if initial was 2x2).
8099 	 */
8100 
8101 	policy_mgr_checkn_update_hw_mode_single_mac_mode(hdd_ctx->psoc, freq);
8102 
8103 	status = policy_mgr_current_connections_update(
8104 			hdd_ctx->psoc, link_info->vdev_id,
8105 			freq,
8106 			POLICY_MGR_UPDATE_REASON_START_AP,
8107 			POLICY_MGR_DEF_REQ_ID);
8108 	if (status == QDF_STATUS_E_FAILURE) {
8109 		hdd_err("ERROR: connections update failed!!");
8110 		return -EINVAL;
8111 	}
8112 
8113 	if (QDF_STATUS_SUCCESS == status) {
8114 		status = policy_mgr_wait_for_connection_update(hdd_ctx->psoc);
8115 		if (!QDF_IS_STATUS_SUCCESS(status)) {
8116 			hdd_err("qdf wait for event failed!!");
8117 			return -EINVAL;
8118 		}
8119 	}
8120 
8121 	if (adapter->device_mode == QDF_P2P_GO_MODE) {
8122 		struct hdd_adapter  *p2p_adapter;
8123 		struct wlan_hdd_link_info *p2p_link_info;
8124 
8125 		p2p_adapter = hdd_get_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE);
8126 		if (p2p_adapter) {
8127 			hdd_debug("Cleanup active p2p device ROC before GO starting");
8128 			p2p_link_info = p2p_adapter->deflink;
8129 			wlan_hdd_cleanup_remain_on_channel_ctx(p2p_link_info);
8130 		}
8131 	}
8132 
8133 	if ((adapter->device_mode == QDF_SAP_MODE)
8134 	    || (adapter->device_mode == QDF_P2P_GO_MODE)
8135 	    ) {
8136 		struct hdd_beacon_data *old, *new;
8137 		enum nl80211_channel_type channel_type;
8138 
8139 		old = ap_ctx->beacon;
8140 		if (old)
8141 			return -EALREADY;
8142 
8143 		status =
8144 			wlan_hdd_cfg80211_alloc_new_beacon(link_info, &new,
8145 							   &params->beacon,
8146 							   params->dtim_period);
8147 
8148 		if (status != 0) {
8149 			hdd_err("Error!!! Allocating the new beacon");
8150 			return -EINVAL;
8151 		}
8152 		ap_ctx->beacon = new;
8153 
8154 		if (chandef->width < NL80211_CHAN_WIDTH_80)
8155 			channel_type = cfg80211_get_chandef_type(chandef);
8156 		else
8157 			channel_type = NL80211_CHAN_HT40PLUS;
8158 
8159 
8160 		wlan_hdd_set_channel(wiphy, dev, chandef, channel_type);
8161 
8162 		hdd_update_beacon_rate(link_info, wiphy, params);
8163 
8164 		/* set authentication type */
8165 		switch (params->auth_type) {
8166 		case NL80211_AUTHTYPE_OPEN_SYSTEM:
8167 			sap_config->authType = eSAP_OPEN_SYSTEM;
8168 			break;
8169 		case NL80211_AUTHTYPE_SHARED_KEY:
8170 			sap_config->authType = eSAP_SHARED_KEY;
8171 			break;
8172 		default:
8173 			sap_config->authType = eSAP_AUTO_SWITCH;
8174 		}
8175 		sap_config->ch_width_orig =
8176 					hdd_map_nl_chan_width(chandef->width);
8177 
8178 		/*
8179 		 * Enable/disable TWT responder based on
8180 		 * the twt_responder flag
8181 		 */
8182 		wlan_hdd_update_twt_responder(adapter, params);
8183 
8184 		/* Enable/disable non-srg obss pd spatial reuse */
8185 		hdd_update_he_obss_pd(link_info, params);
8186 
8187 		hdd_place_marker(adapter, "TRY TO START", NULL);
8188 		status = wlan_hdd_cfg80211_start_bss(link_info, &params->beacon,
8189 						     params->ssid,
8190 						     params->ssid_len,
8191 						     params->hidden_ssid, true);
8192 
8193 		if (status != 0) {
8194 			hdd_err("Error Start bss Failed");
8195 			goto err_start_bss;
8196 		}
8197 		vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_ID);
8198 		if (!vdev)
8199 			return -EINVAL;
8200 
8201 		if (wlan_vdev_mlme_is_mlo_vdev(vdev))
8202 			link_id = wlan_vdev_get_link_id(vdev);
8203 
8204 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
8205 
8206 		if (wlan_get_operation_chan_freq(link_info->vdev) !=
8207 				params->chandef.chan->center_freq)
8208 			hdd_update_param_chandef(link_info, &params->chandef);
8209 
8210 		/*
8211 		 * If Do_Not_Break_Stream enabled send avoid channel list
8212 		 * to application.
8213 		 */
8214 		if (sap_config->chan_freq &&
8215 		    policy_mgr_is_dnsc_set(link_info->vdev))
8216 			wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx,
8217 							  sap_config->chan_freq);
8218 
8219 		ucfg_mlme_get_sap_inactivity_override(hdd_ctx->psoc, &val);
8220 		if (val) {
8221 			sta_inactivity_timer = qdf_mem_malloc(
8222 					sizeof(*sta_inactivity_timer));
8223 			if (!sta_inactivity_timer) {
8224 				status = QDF_STATUS_E_FAILURE;
8225 				goto err_start_bss;
8226 			}
8227 			sta_inactivity_timer->session_id =
8228 						link_info->vdev_id;
8229 			sta_inactivity_timer->sta_inactivity_timeout =
8230 						params->inactivity_timeout;
8231 			sme_update_sta_inactivity_timeout(hdd_ctx->mac_handle,
8232 							  sta_inactivity_timer);
8233 			qdf_mem_free(sta_inactivity_timer);
8234 		}
8235 	}
8236 
8237 	goto success;
8238 
8239 err_start_bss:
8240 	hdd_place_marker(adapter, "START with FAILURE", NULL);
8241 	qdf_mem_free(ap_ctx->beacon);
8242 	ap_ctx->beacon = NULL;
8243 
8244 success:
8245 	if (QDF_IS_STATUS_SUCCESS(status))
8246 		hdd_place_marker(adapter, "START with SUCCESS", NULL);
8247 	hdd_exit();
8248 	return status;
8249 }
8250 
8251 /**
8252  * wlan_hdd_cfg80211_start_ap() - start sap
8253  * @wiphy: Pointer to wiphy
8254  * @dev: Pointer to netdev
8255  * @params: Pointer to start ap configuration parameters
8256  *
8257  * Return: zero for success non-zero for failure
8258  */
wlan_hdd_cfg80211_start_ap(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_ap_settings * params)8259 int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8260 				struct net_device *dev,
8261 				struct cfg80211_ap_settings *params)
8262 {
8263 	int errno;
8264 	struct osif_vdev_sync *vdev_sync;
8265 
8266 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
8267 	if (errno)
8268 		return errno;
8269 
8270 	errno = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8271 
8272 	osif_vdev_sync_op_stop(vdev_sync);
8273 
8274 	return errno;
8275 }
8276 
8277 /**
8278  * __wlan_hdd_cfg80211_change_beacon() - change beacon for sofatap/p2p go
8279  * @wiphy: Pointer to wiphy structure
8280  * @dev: Pointer to net_device structure
8281  * @params: Pointer to change beacon parameters
8282  *
8283  * Return: 0 for success non-zero for failure
8284  */
__wlan_hdd_cfg80211_change_beacon(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_beacon_data * params)8285 static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8286 					struct net_device *dev,
8287 					struct cfg80211_beacon_data *params)
8288 {
8289 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8290 	struct hdd_context *hdd_ctx;
8291 	struct hdd_beacon_data *old, *new;
8292 	int status;
8293 	struct wlan_hdd_link_info *link_info = adapter->deflink;
8294 
8295 	hdd_enter();
8296 
8297 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
8298 		hdd_err("Command not allowed in FTM mode");
8299 		return -EINVAL;
8300 	}
8301 
8302 	if (wlan_hdd_validate_vdev_id(link_info->vdev_id))
8303 		return -EINVAL;
8304 
8305 	qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
8306 		   TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8307 		   link_info->vdev_id, adapter->device_mode);
8308 
8309 	hdd_debug("Device_mode %s(%d)",
8310 		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
8311 
8312 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8313 	status = wlan_hdd_validate_context(hdd_ctx);
8314 
8315 	if (0 != status)
8316 		return status;
8317 
8318 	if (!(adapter->device_mode == QDF_SAP_MODE ||
8319 	      adapter->device_mode == QDF_P2P_GO_MODE)) {
8320 		return -EOPNOTSUPP;
8321 	}
8322 
8323 	old = link_info->session.ap.beacon;
8324 
8325 	if (!old) {
8326 		hdd_err("session id: %d beacon data points to NULL",
8327 		       link_info->vdev_id);
8328 		return -EINVAL;
8329 	}
8330 
8331 	status = wlan_hdd_cfg80211_alloc_new_beacon(link_info, &new, params, 0);
8332 
8333 	if (status != QDF_STATUS_SUCCESS) {
8334 		hdd_err("new beacon alloc failed");
8335 		return -EINVAL;
8336 	}
8337 
8338 	link_info->session.ap.beacon = new;
8339 	hdd_debug("update beacon for P2P GO/SAP");
8340 	status = wlan_hdd_cfg80211_start_bss(link_info, params,
8341 					     NULL, 0, 0, false);
8342 
8343 	hdd_exit();
8344 	return status;
8345 }
8346 
8347 /**
8348  * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode
8349  * @wiphy: Pointer to wiphy
8350  * @dev: Pointer to netdev
8351  * @params: Pointer to change beacon parameters
8352  *
8353  * Return: zero for success non-zero for failure
8354  */
wlan_hdd_cfg80211_change_beacon(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_beacon_data * params)8355 int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8356 				struct net_device *dev,
8357 				struct cfg80211_beacon_data *params)
8358 {
8359 	int errno;
8360 	struct osif_vdev_sync *vdev_sync;
8361 
8362 	errno = osif_vdev_sync_op_start(dev, &vdev_sync);
8363 	if (errno)
8364 		return errno;
8365 
8366 	errno = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8367 
8368 	osif_vdev_sync_op_stop(vdev_sync);
8369 
8370 	return errno;
8371 }
8372 
8373 /**
8374  * hdd_sap_indicate_disconnect_for_sta() - Indicate disconnect indication
8375  * to supplicant, if there any clients connected to SAP interface.
8376  * @adapter: sap adapter context
8377  *
8378  * Return:   nothing
8379  */
hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter * adapter)8380 void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter)
8381 {
8382 	struct sap_event sap_event;
8383 	struct sap_context *sap_ctx;
8384 	struct hdd_station_info *sta_info, *tmp = NULL;
8385 
8386 	hdd_enter();
8387 
8388 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter->deflink);
8389 	if (!sap_ctx) {
8390 		hdd_err("invalid sap context");
8391 		return;
8392 	}
8393 
8394 	hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
8395 				  STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA) {
8396 		hdd_debug("sta_mac: " QDF_MAC_ADDR_FMT,
8397 			  QDF_MAC_ADDR_REF(sta_info->sta_mac.bytes));
8398 
8399 		if (qdf_is_macaddr_broadcast(&sta_info->sta_mac)) {
8400 			hdd_softap_deregister_sta(adapter, &sta_info);
8401 			hdd_put_sta_info_ref(
8402 				&adapter->sta_info_list,
8403 				&sta_info, true,
8404 				STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA);
8405 			continue;
8406 		}
8407 
8408 		sap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
8409 
8410 		qdf_mem_copy(
8411 		     &sap_event.sapevt.sapStationDisassocCompleteEvent.staMac,
8412 		     &sta_info->sta_mac, sizeof(struct qdf_mac_addr));
8413 		hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
8414 				     STA_INFO_SAP_INDICATE_DISCONNECT_FOR_STA);
8415 
8416 		sap_event.sapevt.sapStationDisassocCompleteEvent.reason =
8417 				eSAP_MAC_INITATED_DISASSOC;
8418 		sap_event.sapevt.sapStationDisassocCompleteEvent.status_code =
8419 				QDF_STATUS_E_RESOURCES;
8420 		hdd_hostapd_sap_event_cb(&sap_event, sap_ctx->user_context);
8421 	}
8422 
8423 	hdd_exit();
8424 }
8425 
hdd_is_peer_associated(struct hdd_adapter * adapter,struct qdf_mac_addr * mac_addr)8426 bool hdd_is_peer_associated(struct hdd_adapter *adapter,
8427 			    struct qdf_mac_addr *mac_addr)
8428 {
8429 	bool is_associated = false;
8430 	struct hdd_station_info *sta_info, *tmp = NULL;
8431 
8432 	if (!adapter || !mac_addr) {
8433 		hdd_err("Invalid adapter or mac_addr");
8434 		return false;
8435 	}
8436 
8437 	hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
8438 				  STA_INFO_IS_PEER_ASSOCIATED) {
8439 		if (!qdf_mem_cmp(&sta_info->sta_mac, mac_addr,
8440 				 QDF_MAC_ADDR_SIZE)) {
8441 			is_associated = true;
8442 			hdd_put_sta_info_ref(&adapter->sta_info_list,
8443 					     &sta_info, true,
8444 					     STA_INFO_IS_PEER_ASSOCIATED);
8445 			if (tmp)
8446 				hdd_put_sta_info_ref(
8447 						&adapter->sta_info_list,
8448 						&tmp, true,
8449 						STA_INFO_IS_PEER_ASSOCIATED);
8450 			break;
8451 		}
8452 		hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
8453 				     STA_INFO_IS_PEER_ASSOCIATED);
8454 	}
8455 
8456 	return is_associated;
8457 }
8458 
8459 #ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE
hdd_sap_is_acs_in_progress(struct wlan_objmgr_vdev * vdev)8460 bool hdd_sap_is_acs_in_progress(struct wlan_objmgr_vdev *vdev)
8461 {
8462 	struct wlan_hdd_link_info *link_info;
8463 	bool in_progress = false;
8464 
8465 	if (!vdev) {
8466 		hdd_err("vdev is NULL");
8467 		return in_progress;
8468 	}
8469 
8470 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
8471 	if (!link_info) {
8472 		hdd_err("null adapter");
8473 		return in_progress;
8474 	}
8475 
8476 	if (!hdd_adapter_is_ap(link_info->adapter)) {
8477 		hdd_err("vdev id %d is not AP", link_info->vdev_id);
8478 		return in_progress;
8479 	}
8480 
8481 	in_progress = qdf_atomic_read(&link_info->session.ap.acs_in_progress);
8482 
8483 	return in_progress;
8484 }
8485 #endif
8486 
8487 #ifdef WLAN_CHIPSET_STATS
8488 void
hdd_cp_stats_cstats_sap_go_start_event(struct wlan_hdd_link_info * link_info,struct sap_event * sap_event)8489 hdd_cp_stats_cstats_sap_go_start_event(struct wlan_hdd_link_info *link_info,
8490 				       struct sap_event *sap_event)
8491 {
8492 	struct sap_config *sap_config;
8493 	struct hdd_ap_ctx *ap_ctx;
8494 	struct wlan_objmgr_vdev *vdev;
8495 	struct cstats_sap_go_start stat = {0};
8496 
8497 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
8498 
8499 	sap_config = &ap_ctx->sap_config;
8500 
8501 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_HDD_ID_OBJ_MGR);
8502 	if (!vdev) {
8503 		hdd_err("vdev is NULL");
8504 		return;
8505 	}
8506 
8507 	stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_SAP_GO_START_EVENT_ID;
8508 	stat.cmn.hdr.length = sizeof(struct cstats_sap_go_start) -
8509 			      sizeof(struct cstats_hdr);
8510 	stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
8511 	stat.cmn.vdev_id =
8512 			sap_event->sapevt.sapStartBssCompleteEvent.sessionId;
8513 	stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
8514 	stat.cmn.time_tick = qdf_get_log_timestamp();
8515 
8516 	stat.status = sap_event->sapevt.sapStartBssCompleteEvent.status;
8517 	stat.operating_chan_freq =
8518 		sap_event->sapevt.sapStartBssCompleteEvent.operating_chan_freq;
8519 	stat.ch_width = sap_event->sapevt.sapStartBssCompleteEvent.ch_width;
8520 	stat.staId = sap_event->sapevt.sapStartBssCompleteEvent.staId;
8521 
8522 	stat.ssid_len = sap_config->SSIDinfo.ssid.length;
8523 	qdf_mem_copy(stat.ssid, sap_config->SSIDinfo.ssid.ssId,
8524 		     sap_config->SSIDinfo.ssid.length);
8525 	CSTATS_MAC_COPY(stat.bssid, sap_config->self_macaddr.bytes);
8526 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
8527 
8528 	wlan_cstats_host_stats(sizeof(struct cstats_sap_go_start), &stat);
8529 }
8530 
hdd_cp_stats_cstats_sap_go_stop_event(struct wlan_hdd_link_info * link_info,struct sap_event * sap_event)8531 void hdd_cp_stats_cstats_sap_go_stop_event(struct wlan_hdd_link_info *link_info,
8532 					   struct sap_event *sap_event)
8533 {
8534 	struct sap_config *sap_config;
8535 	struct hdd_ap_ctx *ap_ctx;
8536 	struct wlan_objmgr_vdev *vdev;
8537 	struct cstats_sap_go_stop stat = {0};
8538 
8539 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
8540 
8541 	sap_config = &ap_ctx->sap_config;
8542 
8543 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_HDD_ID_OBJ_MGR);
8544 	if (!vdev) {
8545 		hdd_err("vdev is NULL");
8546 		return;
8547 	}
8548 
8549 	stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_SAP_GO_STOP_EVENT_ID;
8550 	stat.cmn.hdr.length = sizeof(struct cstats_sap_go_stop) -
8551 			      sizeof(struct cstats_hdr);
8552 	stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
8553 	stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
8554 	stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
8555 	stat.cmn.time_tick = qdf_get_log_timestamp();
8556 	stat.status = sap_event->sapevt.sapStopBssCompleteEvent.status;
8557 	CSTATS_MAC_COPY(stat.bssid, sap_config->self_macaddr.bytes);
8558 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
8559 
8560 	wlan_cstats_host_stats(sizeof(struct cstats_sap_go_stop), &stat);
8561 }
8562 
8563 void
hdd_cp_stats_cstats_log_sap_go_sta_disassoc_event(struct wlan_hdd_link_info * li,struct sap_event * sap_evt)8564 hdd_cp_stats_cstats_log_sap_go_sta_disassoc_event(struct wlan_hdd_link_info *li,
8565 						  struct sap_event *sap_evt)
8566 {
8567 	struct sap_config *sap_config;
8568 	struct hdd_ap_ctx *ap_ctx;
8569 	struct wlan_objmgr_vdev *vdev;
8570 	tSap_StationDisassocCompleteEvent *disassoc_comp;
8571 	struct cstats_sap_go_sta_disassoc stat = {0};
8572 
8573 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(li);
8574 
8575 	sap_config = &ap_ctx->sap_config;
8576 
8577 	vdev = hdd_objmgr_get_vdev_by_user(li, WLAN_HDD_ID_OBJ_MGR);
8578 	if (!vdev) {
8579 		hdd_err("vdev is NULL");
8580 		return;
8581 	}
8582 
8583 	disassoc_comp = &sap_evt->sapevt.sapStationDisassocCompleteEvent;
8584 
8585 	stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_SAP_GO_STA_DISASSOC_EVENT_ID;
8586 	stat.cmn.hdr.length = sizeof(struct cstats_sap_go_sta_disassoc) -
8587 			      sizeof(struct cstats_hdr);
8588 	stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
8589 	stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
8590 	stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
8591 	stat.cmn.time_tick = qdf_get_log_timestamp();
8592 
8593 	stat.sta_id = disassoc_comp->staId;
8594 	stat.status = disassoc_comp->status;
8595 	stat.status_code = disassoc_comp->status_code;
8596 	stat.reason = disassoc_comp->reason;
8597 	stat.reason_code = disassoc_comp->reason_code;
8598 	CSTATS_MAC_COPY(stat.bssid, sap_config->self_macaddr.bytes);
8599 	CSTATS_MAC_COPY(stat.sta_mac, disassoc_comp->staMac.bytes);
8600 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
8601 
8602 	wlan_cstats_host_stats(sizeof(struct cstats_sap_go_sta_disassoc),
8603 			       &stat);
8604 }
8605 
hdd_cp_stats_cstats_log_sap_go_sta_assoc_reassoc_event(struct wlan_hdd_link_info * li,struct sap_event * sap_evt)8606 void hdd_cp_stats_cstats_log_sap_go_sta_assoc_reassoc_event(
8607 		struct wlan_hdd_link_info *li, struct sap_event *sap_evt)
8608 {
8609 	struct sap_config *sap_config;
8610 	struct hdd_ap_ctx *ap_ctx;
8611 	struct wlan_objmgr_vdev *vdev;
8612 	tSap_StationAssocReassocCompleteEvent *event;
8613 	struct cstats_sap_go_sta_assoc_reassoc stat = {0};
8614 
8615 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(li);
8616 
8617 	sap_config = &ap_ctx->sap_config;
8618 
8619 	vdev = hdd_objmgr_get_vdev_by_user(li, WLAN_HDD_ID_OBJ_MGR);
8620 	if (!vdev) {
8621 		hdd_err("vdev is NULL");
8622 		return;
8623 	}
8624 
8625 	event = &sap_evt->sapevt.sapStationAssocReassocCompleteEvent;
8626 
8627 	stat.cmn.hdr.evt_id =
8628 			WLAN_CHIPSET_STATS_SAP_GO_STA_ASSOC_REASSOC_EVENT_ID;
8629 	stat.cmn.hdr.length = sizeof(struct cstats_sap_go_sta_assoc_reassoc) -
8630 			      sizeof(struct cstats_hdr);
8631 	stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
8632 	stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
8633 	stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
8634 	stat.cmn.time_tick = qdf_get_log_timestamp();
8635 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
8636 
8637 	stat.sta_id = event->staId;
8638 	stat.status = event->status;
8639 	stat.status_code = event->status_code;
8640 	CSTATS_MAC_COPY(stat.sta_mac, event->staMac.bytes);
8641 	CSTATS_MAC_COPY(stat.bssid, sap_config->self_macaddr.bytes);
8642 
8643 	wlan_cstats_host_stats(sizeof(struct cstats_sap_go_sta_assoc_reassoc),
8644 			       &stat);
8645 }
8646 
hdd_cp_stats_cstats_log_sap_go_dfs_event(struct wlan_hdd_link_info * li,eSapHddEvent event_id)8647 void hdd_cp_stats_cstats_log_sap_go_dfs_event(struct wlan_hdd_link_info *li,
8648 					      eSapHddEvent event_id)
8649 {
8650 	struct sap_config *sap_config;
8651 	struct hdd_ap_ctx *ap_ctx;
8652 	struct wlan_objmgr_vdev *vdev;
8653 	struct cstats_sap_go_dfs_evt stat = {0};
8654 
8655 	ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(li);
8656 
8657 	sap_config = &ap_ctx->sap_config;
8658 
8659 	vdev = hdd_objmgr_get_vdev_by_user(li, WLAN_HDD_ID_OBJ_MGR);
8660 	if (!vdev) {
8661 		hdd_err("vdev is NULL");
8662 		return;
8663 	}
8664 
8665 	if (event_id == eSAP_DFS_CAC_START) {
8666 		stat.cmn.hdr.evt_id =
8667 				   WLAN_CHIPSET_STATS_SAP_GO_CAC_START_EVENT_ID;
8668 	} else if (event_id == eSAP_DFS_CAC_END) {
8669 		stat.cmn.hdr.evt_id =
8670 				     WLAN_CHIPSET_STATS_SAP_GO_CAC_END_EVENT_ID;
8671 	} else if (event_id == eSAP_DFS_RADAR_DETECT) {
8672 		stat.cmn.hdr.evt_id =
8673 			      WLAN_CHIPSET_STATS_SAP_GO_RADAR_DETECTED_EVENT_ID;
8674 	} else if (event_id == eSAP_DFS_CAC_INTERRUPTED) {
8675 		stat.cmn.hdr.evt_id =
8676 			     WLAN_CHIPSET_STATS_SAP_GO_CAC_INTERRUPTED_EVENT_ID;
8677 	} else {
8678 		hdd_err("Invalid Event");
8679 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
8680 		return;
8681 	}
8682 
8683 	stat.cmn.hdr.length = sizeof(struct cstats_sap_go_dfs_evt) -
8684 			      sizeof(struct cstats_hdr);
8685 	stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
8686 	stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
8687 	stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
8688 	stat.cmn.time_tick = qdf_get_log_timestamp();
8689 
8690 	CSTATS_MAC_COPY(stat.bssid, sap_config->self_macaddr.bytes);
8691 	stat.freq = ap_ctx->operating_chan_freq;
8692 	wlan_reg_get_cc_and_src(wlan_vdev_get_psoc(vdev), stat.cc);
8693 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_HDD_ID_OBJ_MGR);
8694 
8695 	wlan_cstats_host_stats(sizeof(struct cstats_sap_go_dfs_evt), &stat);
8696 }
8697 #endif /* WLAN_CHIPSET_STATS */
8698