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