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