xref: /wlan-driver/qcacld-3.0/core/sap/src/sap_fsm.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 
22*5113495bSYour Name 			s a p F s m . C
23*5113495bSYour Name 
24*5113495bSYour Name    OVERVIEW:
25*5113495bSYour Name 
26*5113495bSYour Name    This software unit holds the implementation of the WLAN SAP Finite
27*5113495bSYour Name    State Machine modules
28*5113495bSYour Name 
29*5113495bSYour Name    DEPENDENCIES:
30*5113495bSYour Name 
31*5113495bSYour Name    Are listed for each API below.
32*5113495bSYour Name    ===========================================================================*/
33*5113495bSYour Name 
34*5113495bSYour Name /*----------------------------------------------------------------------------
35*5113495bSYour Name  * Include Files
36*5113495bSYour Name  * -------------------------------------------------------------------------*/
37*5113495bSYour Name #include "sap_internal.h"
38*5113495bSYour Name #include <wlan_dfs_tgt_api.h>
39*5113495bSYour Name #include <wlan_dfs_utils_api.h>
40*5113495bSYour Name #include <wlan_dfs_public_struct.h>
41*5113495bSYour Name #include <wlan_reg_services_api.h>
42*5113495bSYour Name /* Pick up the SME API definitions */
43*5113495bSYour Name #include "sme_api.h"
44*5113495bSYour Name /* Pick up the PMC API definitions */
45*5113495bSYour Name #include "cds_utils.h"
46*5113495bSYour Name #include "cds_ieee80211_common_i.h"
47*5113495bSYour Name #include "cds_reg_service.h"
48*5113495bSYour Name #include "qdf_util.h"
49*5113495bSYour Name #include "wlan_policy_mgr_api.h"
50*5113495bSYour Name #include <wlan_objmgr_pdev_obj.h>
51*5113495bSYour Name #include <wlan_objmgr_vdev_obj.h>
52*5113495bSYour Name #include <wlan_utility.h>
53*5113495bSYour Name #include <linux/netdevice.h>
54*5113495bSYour Name #include <net/cfg80211.h>
55*5113495bSYour Name #include <qca_vendor.h>
56*5113495bSYour Name #include <wlan_scan_api.h>
57*5113495bSYour Name #include "wlan_reg_services_api.h"
58*5113495bSYour Name #include "wlan_mlme_ucfg_api.h"
59*5113495bSYour Name #include "wlan_policy_mgr_ucfg.h"
60*5113495bSYour Name #include "cfg_ucfg_api.h"
61*5113495bSYour Name #include "wlan_mlme_vdev_mgr_interface.h"
62*5113495bSYour Name #include "wlan_vdev_mgr_utils_api.h"
63*5113495bSYour Name #include "wlan_pre_cac_api.h"
64*5113495bSYour Name #include <wlan_cmn_ieee80211.h>
65*5113495bSYour Name #include <target_if.h>
66*5113495bSYour Name #include "wlan_ll_sap_api.h"
67*5113495bSYour Name 
68*5113495bSYour Name /*----------------------------------------------------------------------------
69*5113495bSYour Name  * Preprocessor Definitions and Constants
70*5113495bSYour Name  * -------------------------------------------------------------------------*/
71*5113495bSYour Name 
72*5113495bSYour Name /*----------------------------------------------------------------------------
73*5113495bSYour Name  * Type Declarations
74*5113495bSYour Name  * -------------------------------------------------------------------------*/
75*5113495bSYour Name 
76*5113495bSYour Name /*----------------------------------------------------------------------------
77*5113495bSYour Name  * Global Data Definitions
78*5113495bSYour Name  * -------------------------------------------------------------------------*/
79*5113495bSYour Name 
80*5113495bSYour Name /*----------------------------------------------------------------------------
81*5113495bSYour Name  *  External declarations for global context
82*5113495bSYour Name  * -------------------------------------------------------------------------*/
83*5113495bSYour Name /*----------------------------------------------------------------------------
84*5113495bSYour Name  * Static Variable Definitions
85*5113495bSYour Name  * -------------------------------------------------------------------------*/
86*5113495bSYour Name 
87*5113495bSYour Name /*----------------------------------------------------------------------------
88*5113495bSYour Name  * Static Function Declarations and Definitions
89*5113495bSYour Name  * -------------------------------------------------------------------------*/
90*5113495bSYour Name #ifdef SOFTAP_CHANNEL_RANGE
91*5113495bSYour Name static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx,
92*5113495bSYour Name 				    uint32_t **freq_list,
93*5113495bSYour Name 				    uint8_t *num_ch);
94*5113495bSYour Name #endif
95*5113495bSYour Name 
96*5113495bSYour Name /*==========================================================================
97*5113495bSYour Name    FUNCTION    sapStopDfsCacTimer
98*5113495bSYour Name 
99*5113495bSYour Name    DESCRIPTION
100*5113495bSYour Name     Function to sttop the DFS CAC timer when SAP is stopped
101*5113495bSYour Name    DEPENDENCIES
102*5113495bSYour Name     NA.
103*5113495bSYour Name 
104*5113495bSYour Name    PARAMETERS
105*5113495bSYour Name 
106*5113495bSYour Name     IN
107*5113495bSYour Name     sap_ctx: SAP Context
108*5113495bSYour Name    RETURN VALUE
109*5113495bSYour Name     DFS Timer start status
110*5113495bSYour Name    SIDE EFFECTS
111*5113495bSYour Name    ============================================================================*/
112*5113495bSYour Name 
113*5113495bSYour Name static int sap_stop_dfs_cac_timer(struct sap_context *sap_ctx);
114*5113495bSYour Name 
115*5113495bSYour Name /*==========================================================================
116*5113495bSYour Name    FUNCTION    sapStartDfsCacTimer
117*5113495bSYour Name 
118*5113495bSYour Name    DESCRIPTION
119*5113495bSYour Name     Function to start the DFS CAC timer when SAP is started on DFS Channel
120*5113495bSYour Name    DEPENDENCIES
121*5113495bSYour Name     NA.
122*5113495bSYour Name 
123*5113495bSYour Name    PARAMETERS
124*5113495bSYour Name 
125*5113495bSYour Name     IN
126*5113495bSYour Name     sap_ctx: SAP Context
127*5113495bSYour Name    RETURN VALUE
128*5113495bSYour Name     DFS Timer start status
129*5113495bSYour Name    SIDE EFFECTS
130*5113495bSYour Name    ============================================================================*/
131*5113495bSYour Name 
132*5113495bSYour Name static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx);
133*5113495bSYour Name 
134*5113495bSYour Name /** sap_hdd_event_to_string() - convert hdd event to string
135*5113495bSYour Name  * @event: eSapHddEvent event type
136*5113495bSYour Name  *
137*5113495bSYour Name  * This function converts eSapHddEvent into string
138*5113495bSYour Name  *
139*5113495bSYour Name  * Return: string for the @event.
140*5113495bSYour Name  */
sap_hdd_event_to_string(eSapHddEvent event)141*5113495bSYour Name static uint8_t *sap_hdd_event_to_string(eSapHddEvent event)
142*5113495bSYour Name {
143*5113495bSYour Name 	switch (event) {
144*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_START_BSS_EVENT);
145*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_STOP_BSS_EVENT);
146*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_STA_ASSOC_IND);
147*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_STA_ASSOC_EVENT);
148*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_STA_REASSOC_EVENT);
149*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_STA_DISASSOC_EVENT);
150*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_STA_SET_KEY_EVENT);
151*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_STA_MIC_FAILURE_EVENT);
152*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_WPS_PBC_PROBE_REQ_EVENT);
153*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_DISCONNECT_ALL_P2P_CLIENT);
154*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_MAC_TRIG_STOP_BSS_EVENT);
155*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_UNKNOWN_STA_JOIN);
156*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_MAX_ASSOC_EXCEEDED);
157*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_CHANNEL_CHANGE_EVENT);
158*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_DFS_CAC_START);
159*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_DFS_CAC_INTERRUPTED);
160*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_DFS_CAC_END);
161*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT);
162*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_DFS_NO_AVAILABLE_CHANNEL);
163*5113495bSYour Name #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
164*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_ACS_SCAN_SUCCESS_EVENT);
165*5113495bSYour Name #endif
166*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_ACS_CHANNEL_SELECTED);
167*5113495bSYour Name 	CASE_RETURN_STRING(eSAP_ECSA_CHANGE_CHAN_IND);
168*5113495bSYour Name 	default:
169*5113495bSYour Name 		return "eSAP_HDD_EVENT_UNKNOWN";
170*5113495bSYour Name 	}
171*5113495bSYour Name }
172*5113495bSYour Name 
173*5113495bSYour Name #ifdef QCA_DFS_BW_PUNCTURE
174*5113495bSYour Name /**
175*5113495bSYour Name  * sap_is_chan_change_needed() - Check if SAP channel change needed
176*5113495bSYour Name  * @sap_ctx: sap context.
177*5113495bSYour Name  *
178*5113495bSYour Name  * Even some 20 MHz sub channel disabled for nol, if puncture pattern is valid,
179*5113495bSYour Name  * SAP still can keep current channel width and primary channel, don't need
180*5113495bSYour Name  * change channel.
181*5113495bSYour Name  *
182*5113495bSYour Name  * Return: bool, true: channel change needed
183*5113495bSYour Name  */
184*5113495bSYour Name static bool
sap_is_chan_change_needed(struct sap_context * sap_ctx)185*5113495bSYour Name sap_is_chan_change_needed(struct sap_context *sap_ctx)
186*5113495bSYour Name {
187*5113495bSYour Name 	uint8_t ch_wd;
188*5113495bSYour Name 	uint16_t pri_freq_puncture = 0;
189*5113495bSYour Name 	struct ch_params *ch_params;
190*5113495bSYour Name 	QDF_STATUS status;
191*5113495bSYour Name 	struct mac_context *mac_ctx;
192*5113495bSYour Name 
193*5113495bSYour Name 	if (!sap_phymode_is_eht(sap_ctx->phyMode)) {
194*5113495bSYour Name 		sap_debug("phy mode: 0x%x", sap_ctx->phyMode);
195*5113495bSYour Name 		return true;
196*5113495bSYour Name 	}
197*5113495bSYour Name 
198*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
199*5113495bSYour Name 	if (!mac_ctx) {
200*5113495bSYour Name 		sap_err("Invalid MAC context");
201*5113495bSYour Name 		return true;
202*5113495bSYour Name 	}
203*5113495bSYour Name 
204*5113495bSYour Name 	ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
205*5113495bSYour Name 	if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) {
206*5113495bSYour Name 		ch_wd = sap_ctx->ch_width_orig;
207*5113495bSYour Name 		mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd;
208*5113495bSYour Name 	} else {
209*5113495bSYour Name 		ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth;
210*5113495bSYour Name 	}
211*5113495bSYour Name 
212*5113495bSYour Name 	ch_params->ch_width = ch_wd;
213*5113495bSYour Name 
214*5113495bSYour Name 	if (sap_phymode_is_eht(sap_ctx->phyMode))
215*5113495bSYour Name 		wlan_reg_set_create_punc_bitmap(ch_params, true);
216*5113495bSYour Name 	wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
217*5113495bSYour Name 						sap_ctx->chan_freq,
218*5113495bSYour Name 						0,
219*5113495bSYour Name 						ch_params,
220*5113495bSYour Name 						REG_CURRENT_PWR_MODE);
221*5113495bSYour Name 	if (ch_params->ch_width == sap_ctx->ch_params.ch_width) {
222*5113495bSYour Name 		status = wlan_reg_extract_puncture_by_bw(ch_params->ch_width,
223*5113495bSYour Name 							 ch_params->reg_punc_bitmap,
224*5113495bSYour Name 							 sap_ctx->chan_freq,
225*5113495bSYour Name 							 ch_params->mhz_freq_seg1,
226*5113495bSYour Name 							 CH_WIDTH_20MHZ,
227*5113495bSYour Name 							 &pri_freq_puncture);
228*5113495bSYour Name 		if (QDF_IS_STATUS_SUCCESS(status) && !pri_freq_puncture) {
229*5113495bSYour Name 			sap_debug("Eht valid puncture : 0x%x, keep freq %d",
230*5113495bSYour Name 				  ch_params->reg_punc_bitmap,
231*5113495bSYour Name 				  sap_ctx->chan_freq);
232*5113495bSYour Name 			mac_ctx->sap.SapDfsInfo.new_chanWidth =
233*5113495bSYour Name 						ch_params->ch_width;
234*5113495bSYour Name 			return false;
235*5113495bSYour Name 		}
236*5113495bSYour Name 	}
237*5113495bSYour Name 
238*5113495bSYour Name 	return true;
239*5113495bSYour Name }
240*5113495bSYour Name #else
241*5113495bSYour Name static inline bool
sap_is_chan_change_needed(struct sap_context * sap_ctx)242*5113495bSYour Name sap_is_chan_change_needed(struct sap_context *sap_ctx)
243*5113495bSYour Name {
244*5113495bSYour Name 	return true;
245*5113495bSYour Name }
246*5113495bSYour Name #endif
247*5113495bSYour Name 
248*5113495bSYour Name #ifdef DFS_COMPONENT_ENABLE
249*5113495bSYour Name /**
250*5113495bSYour Name  * sap_random_channel_sel() - This function randomly pick up an available
251*5113495bSYour Name  * channel
252*5113495bSYour Name  * @sap_ctx: sap context.
253*5113495bSYour Name  *
254*5113495bSYour Name  * This function first eliminates invalid channel, then selects random channel
255*5113495bSYour Name  * using following algorithm:
256*5113495bSYour Name  *
257*5113495bSYour Name  * Return: channel frequency picked
258*5113495bSYour Name  */
sap_random_channel_sel(struct sap_context * sap_ctx)259*5113495bSYour Name static qdf_freq_t sap_random_channel_sel(struct sap_context *sap_ctx)
260*5113495bSYour Name {
261*5113495bSYour Name 	uint16_t chan_freq;
262*5113495bSYour Name 	uint8_t ch_wd;
263*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev = NULL;
264*5113495bSYour Name 	struct ch_params *ch_params;
265*5113495bSYour Name 	uint32_t hw_mode, flag  = 0;
266*5113495bSYour Name 	struct mac_context *mac_ctx;
267*5113495bSYour Name 	struct dfs_acs_info acs_info = {0};
268*5113495bSYour Name 
269*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
270*5113495bSYour Name 	if (!mac_ctx) {
271*5113495bSYour Name 		sap_err("Invalid MAC context");
272*5113495bSYour Name 		return 0;
273*5113495bSYour Name 	}
274*5113495bSYour Name 
275*5113495bSYour Name 	pdev = mac_ctx->pdev;
276*5113495bSYour Name 	if (!pdev) {
277*5113495bSYour Name 		sap_err("null pdev");
278*5113495bSYour Name 		return 0;
279*5113495bSYour Name 	}
280*5113495bSYour Name 
281*5113495bSYour Name 	ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
282*5113495bSYour Name 	if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) {
283*5113495bSYour Name 		ch_wd = sap_ctx->ch_width_orig;
284*5113495bSYour Name 		mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd;
285*5113495bSYour Name 	} else {
286*5113495bSYour Name 		ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth;
287*5113495bSYour Name 	}
288*5113495bSYour Name 
289*5113495bSYour Name 	ch_params->ch_width = ch_wd;
290*5113495bSYour Name 	if (sap_ctx->acs_cfg) {
291*5113495bSYour Name 		acs_info.acs_mode = sap_ctx->acs_cfg->acs_mode;
292*5113495bSYour Name 		acs_info.chan_freq_list = sap_ctx->acs_cfg->master_freq_list;
293*5113495bSYour Name 		acs_info.num_of_channel =
294*5113495bSYour Name 					sap_ctx->acs_cfg->master_ch_list_count;
295*5113495bSYour Name 	} else {
296*5113495bSYour Name 		acs_info.acs_mode = false;
297*5113495bSYour Name 	}
298*5113495bSYour Name 
299*5113495bSYour Name 	if (mac_ctx->mlme_cfg->dfs_cfg.dfs_prefer_non_dfs)
300*5113495bSYour Name 		flag |= DFS_RANDOM_CH_FLAG_NO_DFS_CH;
301*5113495bSYour Name 	if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_japan_w53)
302*5113495bSYour Name 		flag |= DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH;
303*5113495bSYour Name 	if (mac_ctx->sap.SapDfsInfo.sap_operating_chan_preferred_location
304*5113495bSYour Name 	    == 1)
305*5113495bSYour Name 		flag |= DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH;
306*5113495bSYour Name 	else if (mac_ctx->sap.SapDfsInfo.
307*5113495bSYour Name 		 sap_operating_chan_preferred_location == 2)
308*5113495bSYour Name 		flag |= DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH;
309*5113495bSYour Name 
310*5113495bSYour Name 	/*
311*5113495bSYour Name 	 * Dont choose 6ghz channel currently as legacy clients won't be able to
312*5113495bSYour Name 	 * scan them. In future create an ini if any customer wants 6ghz freq
313*5113495bSYour Name 	 * to be prioritize over 5ghz/2.4ghz.
314*5113495bSYour Name 	 * Currently for SAP there is a high chance of 6ghz being selected as
315*5113495bSYour Name 	 * an op frequency as PCL will have only 5, 6ghz freq as preferred for
316*5113495bSYour Name 	 * standalone SAP, and 6ghz channels being high in number.
317*5113495bSYour Name 	 */
318*5113495bSYour Name 	flag |= DFS_RANDOM_CH_FLAG_NO_6GHZ_CH;
319*5113495bSYour Name 
320*5113495bSYour Name 	if (sap_ctx->candidate_freq &&
321*5113495bSYour Name 	    sap_ctx->chan_freq != sap_ctx->candidate_freq &&
322*5113495bSYour Name 	    !utils_dfs_is_freq_in_nol(pdev, sap_ctx->candidate_freq)) {
323*5113495bSYour Name 		chan_freq = sap_ctx->candidate_freq;
324*5113495bSYour Name 		if (sap_phymode_is_eht(sap_ctx->phyMode))
325*5113495bSYour Name 			wlan_reg_set_create_punc_bitmap(ch_params, true);
326*5113495bSYour Name 		wlan_reg_set_channel_params_for_pwrmode(pdev, chan_freq, 0,
327*5113495bSYour Name 							ch_params,
328*5113495bSYour Name 							REG_CURRENT_PWR_MODE);
329*5113495bSYour Name 		sap_debug("random chan select candidate freq=%d", chan_freq);
330*5113495bSYour Name 		sap_ctx->candidate_freq = 0;
331*5113495bSYour Name 	} else if (QDF_IS_STATUS_ERROR(
332*5113495bSYour Name 				utils_dfs_get_vdev_random_channel_for_freq(
333*5113495bSYour Name 					pdev, sap_ctx->vdev, flag, ch_params,
334*5113495bSYour Name 					&hw_mode, &chan_freq, &acs_info))) {
335*5113495bSYour Name 		/* No available channel found */
336*5113495bSYour Name 		sap_err("No available channel found!!!");
337*5113495bSYour Name 		sap_signal_hdd_event(sap_ctx, NULL,
338*5113495bSYour Name 				     eSAP_DFS_NO_AVAILABLE_CHANNEL,
339*5113495bSYour Name 				     (void *)eSAP_STATUS_SUCCESS);
340*5113495bSYour Name 		return 0;
341*5113495bSYour Name 	}
342*5113495bSYour Name 
343*5113495bSYour Name 	mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_params->ch_width;
344*5113495bSYour Name 	sap_ctx->ch_params.ch_width = ch_params->ch_width;
345*5113495bSYour Name 	sap_ctx->ch_params.sec_ch_offset = ch_params->sec_ch_offset;
346*5113495bSYour Name 	sap_ctx->ch_params.center_freq_seg0 = ch_params->center_freq_seg0;
347*5113495bSYour Name 	sap_ctx->ch_params.center_freq_seg1 = ch_params->center_freq_seg1;
348*5113495bSYour Name 	return chan_freq;
349*5113495bSYour Name }
350*5113495bSYour Name #else
sap_random_channel_sel(struct sap_context * sap_ctx)351*5113495bSYour Name static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx)
352*5113495bSYour Name {
353*5113495bSYour Name 	return 0;
354*5113495bSYour Name }
355*5113495bSYour Name #endif
356*5113495bSYour Name 
357*5113495bSYour Name /**
358*5113495bSYour Name  * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding.
359*5113495bSYour Name  * @sap_ctx: sap context.
360*5113495bSYour Name  * @chan_freq: chan frequency
361*5113495bSYour Name  * @ch_params: pointer to ch_params
362*5113495bSYour Name  *
363*5113495bSYour Name  * Check if given channel and channel params are bonded to weather radar
364*5113495bSYour Name  * channel in ETSI domain.
365*5113495bSYour Name  *
366*5113495bSYour Name  * Return: True if bonded to weather channel in ETSI
367*5113495bSYour Name  */
368*5113495bSYour Name static bool
sap_is_channel_bonding_etsi_weather_channel(struct sap_context * sap_ctx,qdf_freq_t chan_freq,struct ch_params * ch_params)369*5113495bSYour Name sap_is_channel_bonding_etsi_weather_channel(struct sap_context *sap_ctx,
370*5113495bSYour Name 					    qdf_freq_t chan_freq,
371*5113495bSYour Name 					    struct ch_params *ch_params)
372*5113495bSYour Name {
373*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(sap_ctx->vdev);
374*5113495bSYour Name 
375*5113495bSYour Name 	if (IS_CH_BONDING_WITH_WEATHER_CH(wlan_reg_freq_to_chan(pdev,
376*5113495bSYour Name 								chan_freq)) &&
377*5113495bSYour Name 	    ch_params->ch_width != CH_WIDTH_20MHZ)
378*5113495bSYour Name 		return true;
379*5113495bSYour Name 
380*5113495bSYour Name 	return false;
381*5113495bSYour Name }
382*5113495bSYour Name 
383*5113495bSYour Name /*
384*5113495bSYour Name  * sap_get_bonding_channels() - get bonding channels from primary channel.
385*5113495bSYour Name  * @sap_ctx: Handle to SAP context.
386*5113495bSYour Name  * @chan_freq: Channel frequency to get bonded channels.
387*5113495bSYour Name  * @freq_list: Bonded channel frequency list
388*5113495bSYour Name  * @size: Max bonded channels
389*5113495bSYour Name  * @chanBondState: The channel bonding mode of the passed channel.
390*5113495bSYour Name  *
391*5113495bSYour Name  * Return: Number of sub channels
392*5113495bSYour Name  */
sap_get_bonding_channels(struct sap_context * sap_ctx,qdf_freq_t chan_freq,qdf_freq_t * freq_list,uint8_t size,ePhyChanBondState chanBondState)393*5113495bSYour Name static uint8_t sap_get_bonding_channels(struct sap_context *sap_ctx,
394*5113495bSYour Name 					qdf_freq_t chan_freq,
395*5113495bSYour Name 					qdf_freq_t *freq_list, uint8_t size,
396*5113495bSYour Name 					ePhyChanBondState chanBondState)
397*5113495bSYour Name {
398*5113495bSYour Name 	uint8_t num_freq;
399*5113495bSYour Name 
400*5113495bSYour Name 	if (!freq_list)
401*5113495bSYour Name 		return 0;
402*5113495bSYour Name 
403*5113495bSYour Name 	if (size < MAX_BONDED_CHANNELS)
404*5113495bSYour Name 		return 0;
405*5113495bSYour Name 
406*5113495bSYour Name 	switch (chanBondState) {
407*5113495bSYour Name 	case PHY_SINGLE_CHANNEL_CENTERED:
408*5113495bSYour Name 		num_freq = 1;
409*5113495bSYour Name 		freq_list[0] = chan_freq;
410*5113495bSYour Name 		break;
411*5113495bSYour Name 	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
412*5113495bSYour Name 		num_freq = 2;
413*5113495bSYour Name 		freq_list[0] = chan_freq - 20;
414*5113495bSYour Name 		freq_list[1] = chan_freq;
415*5113495bSYour Name 		break;
416*5113495bSYour Name 	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
417*5113495bSYour Name 		num_freq = 2;
418*5113495bSYour Name 		freq_list[0] = chan_freq;
419*5113495bSYour Name 		freq_list[1] = chan_freq + 20;
420*5113495bSYour Name 		break;
421*5113495bSYour Name 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
422*5113495bSYour Name 		num_freq = 4;
423*5113495bSYour Name 		freq_list[0] = chan_freq;
424*5113495bSYour Name 		freq_list[1] = chan_freq + 20;
425*5113495bSYour Name 		freq_list[2] = chan_freq + 40;
426*5113495bSYour Name 		freq_list[3] = chan_freq + 60;
427*5113495bSYour Name 		break;
428*5113495bSYour Name 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
429*5113495bSYour Name 		num_freq = 4;
430*5113495bSYour Name 		freq_list[0] = chan_freq - 20;
431*5113495bSYour Name 		freq_list[1] = chan_freq;
432*5113495bSYour Name 		freq_list[2] = chan_freq + 20;
433*5113495bSYour Name 		freq_list[3] = chan_freq + 40;
434*5113495bSYour Name 		break;
435*5113495bSYour Name 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
436*5113495bSYour Name 		num_freq = 4;
437*5113495bSYour Name 		freq_list[0] = chan_freq - 40;
438*5113495bSYour Name 		freq_list[1] = chan_freq - 20;
439*5113495bSYour Name 		freq_list[2] = chan_freq;
440*5113495bSYour Name 		freq_list[3] = chan_freq + 20;
441*5113495bSYour Name 		break;
442*5113495bSYour Name 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
443*5113495bSYour Name 		num_freq = 4;
444*5113495bSYour Name 		freq_list[0] = chan_freq - 60;
445*5113495bSYour Name 		freq_list[1] = chan_freq - 40;
446*5113495bSYour Name 		freq_list[2] = chan_freq - 20;
447*5113495bSYour Name 		freq_list[3] = chan_freq;
448*5113495bSYour Name 		break;
449*5113495bSYour Name 	default:
450*5113495bSYour Name 		num_freq = 1;
451*5113495bSYour Name 		freq_list[0] = chan_freq;
452*5113495bSYour Name 		break;
453*5113495bSYour Name 	}
454*5113495bSYour Name 
455*5113495bSYour Name 	return num_freq;
456*5113495bSYour Name }
457*5113495bSYour Name 
458*5113495bSYour Name /**
459*5113495bSYour Name  * sap_ch_params_to_bonding_channels() - get bonding channels from channel param
460*5113495bSYour Name  * @ch_params: channel params ( bw, pri and sec channel info)
461*5113495bSYour Name  * @freq_list: bonded channel frequency list
462*5113495bSYour Name  *
463*5113495bSYour Name  * Return: Number of sub channel frequencies
464*5113495bSYour Name  */
sap_ch_params_to_bonding_channels(struct ch_params * ch_params,qdf_freq_t * freq_list)465*5113495bSYour Name static uint8_t sap_ch_params_to_bonding_channels(
466*5113495bSYour Name 		struct ch_params *ch_params,
467*5113495bSYour Name 		qdf_freq_t *freq_list)
468*5113495bSYour Name {
469*5113495bSYour Name 	qdf_freq_t center_freq = ch_params->mhz_freq_seg0;
470*5113495bSYour Name 	uint8_t num_freq = 0;
471*5113495bSYour Name 
472*5113495bSYour Name 	switch (ch_params->ch_width) {
473*5113495bSYour Name 	case CH_WIDTH_160MHZ:
474*5113495bSYour Name 		num_freq = 8;
475*5113495bSYour Name 		center_freq = ch_params->mhz_freq_seg1;
476*5113495bSYour Name 		freq_list[0] = center_freq - 70;
477*5113495bSYour Name 		freq_list[1] = center_freq - 50;
478*5113495bSYour Name 		freq_list[2] = center_freq - 30;
479*5113495bSYour Name 		freq_list[3] = center_freq - 10;
480*5113495bSYour Name 		freq_list[4] = center_freq + 10;
481*5113495bSYour Name 		freq_list[5] = center_freq + 30;
482*5113495bSYour Name 		freq_list[6] = center_freq + 50;
483*5113495bSYour Name 		freq_list[7] = center_freq + 70;
484*5113495bSYour Name 		break;
485*5113495bSYour Name 	case CH_WIDTH_80P80MHZ:
486*5113495bSYour Name 		num_freq = 8;
487*5113495bSYour Name 		freq_list[0] = center_freq - 30;
488*5113495bSYour Name 		freq_list[1] = center_freq - 10;
489*5113495bSYour Name 		freq_list[2] = center_freq + 10;
490*5113495bSYour Name 		freq_list[3] = center_freq + 30;
491*5113495bSYour Name 
492*5113495bSYour Name 		center_freq = ch_params->mhz_freq_seg1;
493*5113495bSYour Name 		freq_list[4] = center_freq - 30;
494*5113495bSYour Name 		freq_list[5] = center_freq - 10;
495*5113495bSYour Name 		freq_list[6] = center_freq + 10;
496*5113495bSYour Name 		freq_list[7] = center_freq + 30;
497*5113495bSYour Name 		break;
498*5113495bSYour Name 	case CH_WIDTH_80MHZ:
499*5113495bSYour Name 		num_freq = 4;
500*5113495bSYour Name 		freq_list[0] = center_freq - 30;
501*5113495bSYour Name 		freq_list[1] = center_freq - 10;
502*5113495bSYour Name 		freq_list[2] = center_freq + 10;
503*5113495bSYour Name 		freq_list[3] = center_freq + 30;
504*5113495bSYour Name 		break;
505*5113495bSYour Name 	case CH_WIDTH_40MHZ:
506*5113495bSYour Name 		num_freq = 2;
507*5113495bSYour Name 		freq_list[0] = center_freq - 10;
508*5113495bSYour Name 		freq_list[1] = center_freq + 10;
509*5113495bSYour Name 		break;
510*5113495bSYour Name 	default:
511*5113495bSYour Name 		num_freq = 1;
512*5113495bSYour Name 		freq_list[0] = center_freq;
513*5113495bSYour Name 		break;
514*5113495bSYour Name 	}
515*5113495bSYour Name 
516*5113495bSYour Name 	return num_freq;
517*5113495bSYour Name }
518*5113495bSYour Name 
519*5113495bSYour Name /**
520*5113495bSYour Name  * sap_operating_on_dfs() - check current sap operating on dfs
521*5113495bSYour Name  * @mac_ctx: mac ctx
522*5113495bSYour Name  * @sap_ctx: SAP context
523*5113495bSYour Name  *
524*5113495bSYour Name  * Return: true if any sub channel is dfs channel
525*5113495bSYour Name  */
526*5113495bSYour Name static
sap_operating_on_dfs(struct mac_context * mac_ctx,struct sap_context * sap_ctx)527*5113495bSYour Name bool sap_operating_on_dfs(struct mac_context *mac_ctx,
528*5113495bSYour Name 			  struct sap_context *sap_ctx)
529*5113495bSYour Name {
530*5113495bSYour Name 	struct wlan_channel *chan;
531*5113495bSYour Name 
532*5113495bSYour Name 	if (!sap_ctx->vdev) {
533*5113495bSYour Name 		sap_debug("vdev invalid");
534*5113495bSYour Name 		return false;
535*5113495bSYour Name 	}
536*5113495bSYour Name 
537*5113495bSYour Name 	chan = wlan_vdev_get_active_channel(sap_ctx->vdev);
538*5113495bSYour Name 	if (!chan) {
539*5113495bSYour Name 		sap_debug("Couldn't get vdev active channel");
540*5113495bSYour Name 		return false;
541*5113495bSYour Name 	}
542*5113495bSYour Name 
543*5113495bSYour Name 	if (chan->ch_flagext & (IEEE80211_CHAN_DFS |
544*5113495bSYour Name 				IEEE80211_CHAN_DFS_CFREQ2))
545*5113495bSYour Name 		return true;
546*5113495bSYour Name 
547*5113495bSYour Name 	return false;
548*5113495bSYour Name }
549*5113495bSYour Name 
sap_plus_sap_cac_skip(struct mac_context * mac,struct sap_context * sap_ctx,qdf_freq_t chan_freq)550*5113495bSYour Name bool sap_plus_sap_cac_skip(struct mac_context *mac,
551*5113495bSYour Name 			   struct sap_context *sap_ctx,
552*5113495bSYour Name 			   qdf_freq_t chan_freq)
553*5113495bSYour Name {
554*5113495bSYour Name 	uint8_t intf;
555*5113495bSYour Name 
556*5113495bSYour Name 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
557*5113495bSYour Name 		struct sap_context *sap_context =
558*5113495bSYour Name 			mac->sap.sapCtxList[intf].sap_context;
559*5113495bSYour Name 
560*5113495bSYour Name 		if (!sap_context || sap_context == sap_ctx)
561*5113495bSYour Name 			continue;
562*5113495bSYour Name 		if (mac->sap.sapCtxList[intf].sapPersona != QDF_SAP_MODE &&
563*5113495bSYour Name 		    mac->sap.sapCtxList[intf].sapPersona != QDF_P2P_GO_MODE)
564*5113495bSYour Name 			continue;
565*5113495bSYour Name 		if (sap_context->isCacEndNotified &&
566*5113495bSYour Name 		    sap_context->chan_freq == chan_freq &&
567*5113495bSYour Name 		    sap_operating_on_dfs(mac, sap_context)) {
568*5113495bSYour Name 			sap_debug("SAP vid %d CAC can skip due to CAC completed on other SAP vid %d",
569*5113495bSYour Name 				  sap_ctx->sessionId, sap_context->sessionId);
570*5113495bSYour Name 			return true;
571*5113495bSYour Name 		}
572*5113495bSYour Name 	}
573*5113495bSYour Name 
574*5113495bSYour Name 	return false;
575*5113495bSYour Name }
576*5113495bSYour Name 
577*5113495bSYour Name /**
578*5113495bSYour Name  * is_wlansap_cac_required_for_chan() - Is cac required for given channel
579*5113495bSYour Name  * @mac_ctx: mac ctx
580*5113495bSYour Name  * @sap_ctx: sap context
581*5113495bSYour Name  * @chan_freq: given channel
582*5113495bSYour Name  * @ch_params: pointer to ch_params
583*5113495bSYour Name  *
584*5113495bSYour Name  * Return: True if cac is required for given channel
585*5113495bSYour Name  */
586*5113495bSYour Name static bool
is_wlansap_cac_required_for_chan(struct mac_context * mac_ctx,struct sap_context * sap_ctx,qdf_freq_t chan_freq,struct ch_params * ch_params)587*5113495bSYour Name is_wlansap_cac_required_for_chan(struct mac_context *mac_ctx,
588*5113495bSYour Name 				 struct sap_context *sap_ctx,
589*5113495bSYour Name 				 qdf_freq_t chan_freq,
590*5113495bSYour Name 				 struct ch_params *ch_params)
591*5113495bSYour Name {
592*5113495bSYour Name 	bool is_ch_dfs = false;
593*5113495bSYour Name 	bool cac_required;
594*5113495bSYour Name 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
595*5113495bSYour Name 	uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
596*5113495bSYour Name 	uint8_t sta_cnt, i;
597*5113495bSYour Name 	eSapDfsCACState_t cac_state = eSAP_DFS_DO_NOT_SKIP_CAC;
598*5113495bSYour Name 
599*5113495bSYour Name 	if (ch_params->ch_width == CH_WIDTH_160MHZ) {
600*5113495bSYour Name 		wlan_reg_set_create_punc_bitmap(ch_params, true);
601*5113495bSYour Name 		if (wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac_ctx->pdev,
602*5113495bSYour Name 								     chan_freq,
603*5113495bSYour Name 								     ch_params,
604*5113495bSYour Name 								     REG_CURRENT_PWR_MODE) ==
605*5113495bSYour Name 		    CHANNEL_STATE_DFS)
606*5113495bSYour Name 			is_ch_dfs = true;
607*5113495bSYour Name 	} else if (ch_params->ch_width == CH_WIDTH_80P80MHZ) {
608*5113495bSYour Name 		if (wlan_reg_get_channel_state_for_pwrmode(
609*5113495bSYour Name 						mac_ctx->pdev,
610*5113495bSYour Name 						chan_freq,
611*5113495bSYour Name 						REG_CURRENT_PWR_MODE) ==
612*5113495bSYour Name 		    CHANNEL_STATE_DFS ||
613*5113495bSYour Name 		    wlan_reg_get_channel_state_for_pwrmode(
614*5113495bSYour Name 					mac_ctx->pdev,
615*5113495bSYour Name 					ch_params->mhz_freq_seg1,
616*5113495bSYour Name 					REG_CURRENT_PWR_MODE) ==
617*5113495bSYour Name 				CHANNEL_STATE_DFS)
618*5113495bSYour Name 			is_ch_dfs = true;
619*5113495bSYour Name 	} else {
620*5113495bSYour Name 		/* Indoor channels are also marked DFS, therefore
621*5113495bSYour Name 		 * check if the channel has REGULATORY_CHAN_RADAR
622*5113495bSYour Name 		 * channel flag to identify if the channel is DFS
623*5113495bSYour Name 		 */
624*5113495bSYour Name 		if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev, chan_freq))
625*5113495bSYour Name 			is_ch_dfs = true;
626*5113495bSYour Name 	}
627*5113495bSYour Name 	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))
628*5113495bSYour Name 		is_ch_dfs = false;
629*5113495bSYour Name 	if (is_ch_dfs && sap_plus_sap_cac_skip(mac_ctx, sap_ctx, chan_freq))
630*5113495bSYour Name 		cac_state = eSAP_DFS_SKIP_CAC;
631*5113495bSYour Name 	sap_debug("vdev id %d chan %d is_ch_dfs %d pre_cac_complete %d ignore_cac %d cac_state %d",
632*5113495bSYour Name 		  sap_ctx->sessionId, chan_freq, is_ch_dfs,
633*5113495bSYour Name 		  wlan_pre_cac_complete_get(sap_ctx->vdev),
634*5113495bSYour Name 		  mac_ctx->sap.SapDfsInfo.ignore_cac,
635*5113495bSYour Name 		  cac_state);
636*5113495bSYour Name 
637*5113495bSYour Name 	if (!is_ch_dfs || wlan_pre_cac_complete_get(sap_ctx->vdev) ||
638*5113495bSYour Name 	    mac_ctx->sap.SapDfsInfo.ignore_cac ||
639*5113495bSYour Name 	    cac_state == eSAP_DFS_SKIP_CAC)
640*5113495bSYour Name 		cac_required = false;
641*5113495bSYour Name 	else
642*5113495bSYour Name 		cac_required = true;
643*5113495bSYour Name 
644*5113495bSYour Name 	if (cac_required) {
645*5113495bSYour Name 		sta_cnt =
646*5113495bSYour Name 		  policy_mgr_get_mode_specific_conn_info(mac_ctx->psoc,
647*5113495bSYour Name 							 freq_list,
648*5113495bSYour Name 							 vdev_id_list,
649*5113495bSYour Name 							 PM_STA_MODE);
650*5113495bSYour Name 
651*5113495bSYour Name 		for (i = 0; i < sta_cnt; i++) {
652*5113495bSYour Name 			if (chan_freq == freq_list[i]) {
653*5113495bSYour Name 				sap_debug("STA vdev id %d exists, ignore CAC",
654*5113495bSYour Name 					  vdev_id_list[i]);
655*5113495bSYour Name 				cac_required = false;
656*5113495bSYour Name 			}
657*5113495bSYour Name 		}
658*5113495bSYour Name 	}
659*5113495bSYour Name 
660*5113495bSYour Name 	return cac_required;
661*5113495bSYour Name }
662*5113495bSYour Name 
sap_get_cac_dur_dfs_region(struct sap_context * sap_ctx,uint32_t * cac_duration_ms,uint32_t * dfs_region,qdf_freq_t chan_freq,struct ch_params * ch_params)663*5113495bSYour Name void sap_get_cac_dur_dfs_region(struct sap_context *sap_ctx,
664*5113495bSYour Name 				uint32_t *cac_duration_ms,
665*5113495bSYour Name 				uint32_t *dfs_region,
666*5113495bSYour Name 				qdf_freq_t chan_freq,
667*5113495bSYour Name 				struct ch_params *ch_params)
668*5113495bSYour Name {
669*5113495bSYour Name 	int i;
670*5113495bSYour Name 	qdf_freq_t freq_list[MAX_BONDED_CHANNELS];
671*5113495bSYour Name 	uint8_t num_freq;
672*5113495bSYour Name 	struct mac_context *mac;
673*5113495bSYour Name 	bool cac_required;
674*5113495bSYour Name 
675*5113495bSYour Name 	*cac_duration_ms = 0;
676*5113495bSYour Name 	if (!sap_ctx) {
677*5113495bSYour Name 		sap_err("null sap_ctx");
678*5113495bSYour Name 		return;
679*5113495bSYour Name 	}
680*5113495bSYour Name 
681*5113495bSYour Name 	mac = sap_get_mac_context();
682*5113495bSYour Name 	if (!mac) {
683*5113495bSYour Name 		sap_err("Invalid MAC context");
684*5113495bSYour Name 		return;
685*5113495bSYour Name 	}
686*5113495bSYour Name 
687*5113495bSYour Name 	wlan_reg_get_dfs_region(mac->pdev, dfs_region);
688*5113495bSYour Name 	cac_required = is_wlansap_cac_required_for_chan(mac, sap_ctx,
689*5113495bSYour Name 							chan_freq, ch_params);
690*5113495bSYour Name 
691*5113495bSYour Name 	if (!cac_required) {
692*5113495bSYour Name 		sap_debug("cac is not required");
693*5113495bSYour Name 		return;
694*5113495bSYour Name 	}
695*5113495bSYour Name 	*cac_duration_ms = DEFAULT_CAC_TIMEOUT;
696*5113495bSYour Name 
697*5113495bSYour Name 	if (*dfs_region != DFS_ETSI_REGION) {
698*5113495bSYour Name 		sap_debug("sapdfs: default cac duration");
699*5113495bSYour Name 		return;
700*5113495bSYour Name 	}
701*5113495bSYour Name 
702*5113495bSYour Name 	if (sap_is_channel_bonding_etsi_weather_channel(sap_ctx, chan_freq,
703*5113495bSYour Name 							ch_params)) {
704*5113495bSYour Name 		*cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT;
705*5113495bSYour Name 		sap_debug("sapdfs: bonding_etsi_weather_channel");
706*5113495bSYour Name 		return;
707*5113495bSYour Name 	}
708*5113495bSYour Name 
709*5113495bSYour Name 	qdf_mem_zero(freq_list, sizeof(freq_list));
710*5113495bSYour Name 	num_freq = sap_ch_params_to_bonding_channels(ch_params, freq_list);
711*5113495bSYour Name 	for (i = 0; i < num_freq; i++) {
712*5113495bSYour Name 		if (IS_ETSI_WEATHER_FREQ(freq_list[i])) {
713*5113495bSYour Name 			*cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT;
714*5113495bSYour Name 			sap_debug("sapdfs: ch freq=%d is etsi weather channel",
715*5113495bSYour Name 				  freq_list[i]);
716*5113495bSYour Name 			return;
717*5113495bSYour Name 		}
718*5113495bSYour Name 	}
719*5113495bSYour Name 
720*5113495bSYour Name }
721*5113495bSYour Name 
sap_dfs_set_current_channel(void * ctx)722*5113495bSYour Name void sap_dfs_set_current_channel(void *ctx)
723*5113495bSYour Name {
724*5113495bSYour Name 	struct sap_context *sap_ctx = ctx;
725*5113495bSYour Name 	uint8_t vht_seg0 = sap_ctx->ch_params.center_freq_seg0;
726*5113495bSYour Name 	uint8_t vht_seg1 = sap_ctx->ch_params.center_freq_seg1;
727*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
728*5113495bSYour Name 	struct mac_context *mac_ctx;
729*5113495bSYour Name 	uint32_t use_nol = 0;
730*5113495bSYour Name 	int error;
731*5113495bSYour Name 	bool is_dfs;
732*5113495bSYour Name 
733*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
734*5113495bSYour Name 	if (!mac_ctx) {
735*5113495bSYour Name 		sap_err("Invalid MAC context");
736*5113495bSYour Name 		return;
737*5113495bSYour Name 	}
738*5113495bSYour Name 
739*5113495bSYour Name 	pdev = mac_ctx->pdev;
740*5113495bSYour Name 	if (!pdev) {
741*5113495bSYour Name 		sap_err("null pdev");
742*5113495bSYour Name 		return;
743*5113495bSYour Name 	}
744*5113495bSYour Name 
745*5113495bSYour Name 	is_dfs = wlan_mlme_check_chan_param_has_dfs(pdev,
746*5113495bSYour Name 						    &sap_ctx->ch_params,
747*5113495bSYour Name 						    sap_ctx->chan_freq);
748*5113495bSYour Name 
749*5113495bSYour Name 	sap_debug("freq=%d, dfs %d seg0=%d, seg1=%d, bw %d",
750*5113495bSYour Name 		  sap_ctx->chan_freq, is_dfs, vht_seg0, vht_seg1,
751*5113495bSYour Name 		  sap_ctx->ch_params.ch_width);
752*5113495bSYour Name 
753*5113495bSYour Name 	if (is_dfs) {
754*5113495bSYour Name 		if (policy_mgr_concurrent_beaconing_sessions_running(
755*5113495bSYour Name 		    mac_ctx->psoc)) {
756*5113495bSYour Name 			uint16_t con_ch_freq;
757*5113495bSYour Name 			mac_handle_t handle = MAC_HANDLE(mac_ctx);
758*5113495bSYour Name 
759*5113495bSYour Name 			con_ch_freq =
760*5113495bSYour Name 				sme_get_beaconing_concurrent_operation_channel(
761*5113495bSYour Name 					handle, sap_ctx->sessionId);
762*5113495bSYour Name 			if (!con_ch_freq ||
763*5113495bSYour Name 			    !wlan_reg_is_dfs_for_freq(pdev,
764*5113495bSYour Name 							con_ch_freq))
765*5113495bSYour Name 				tgt_dfs_get_radars(pdev);
766*5113495bSYour Name 		} else {
767*5113495bSYour Name 			tgt_dfs_get_radars(pdev);
768*5113495bSYour Name 		}
769*5113495bSYour Name 		tgt_dfs_set_phyerr_filter_offload(pdev);
770*5113495bSYour Name 
771*5113495bSYour Name 		if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_channel_switch)
772*5113495bSYour Name 			tgt_dfs_control(pdev, DFS_SET_USENOL, &use_nol,
773*5113495bSYour Name 					sizeof(uint32_t), NULL, NULL, &error);
774*5113495bSYour Name 	}
775*5113495bSYour Name }
776*5113495bSYour Name 
777*5113495bSYour Name #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
778*5113495bSYour Name /**
779*5113495bSYour Name  * sap_check_in_avoid_ch_list() - checks if given channel present is channel
780*5113495bSYour Name  * avoidance list
781*5113495bSYour Name  *
782*5113495bSYour Name  * @sap_ctx:        sap context.
783*5113495bSYour Name  * @channel:        channel to be checked in sap_ctx's avoid ch list
784*5113495bSYour Name  *
785*5113495bSYour Name  * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
786*5113495bSYour Name  * which MDM device's AP with MCC was detected. This function checks if given
787*5113495bSYour Name  * channel is present in that list.
788*5113495bSYour Name  *
789*5113495bSYour Name  * Return: true, if channel was present, false othersie.
790*5113495bSYour Name  */
sap_check_in_avoid_ch_list(struct sap_context * sap_ctx,uint8_t channel)791*5113495bSYour Name bool sap_check_in_avoid_ch_list(struct sap_context *sap_ctx, uint8_t channel)
792*5113495bSYour Name {
793*5113495bSYour Name 	uint8_t i = 0;
794*5113495bSYour Name 	struct sap_avoid_channels_info *ie_info =
795*5113495bSYour Name 		&sap_ctx->sap_detected_avoid_ch_ie;
796*5113495bSYour Name 	for (i = 0; i < sizeof(ie_info->channels); i++)
797*5113495bSYour Name 		if (ie_info->channels[i] == channel)
798*5113495bSYour Name 			return true;
799*5113495bSYour Name 	return false;
800*5113495bSYour Name }
801*5113495bSYour Name #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
802*5113495bSYour Name 
803*5113495bSYour Name /**
804*5113495bSYour Name  * sap_dfs_is_channel_in_nol_list() - given bonded channel is available
805*5113495bSYour Name  * @sap_context: Handle to SAP context.
806*5113495bSYour Name  * @channel_freq: Channel freq on which availability should be checked.
807*5113495bSYour Name  * @chan_bondState: The channel bonding mode of the passed channel.
808*5113495bSYour Name  *
809*5113495bSYour Name  * This function Checks if a given bonded channel is available or
810*5113495bSYour Name  * usable for DFS operation.
811*5113495bSYour Name  *
812*5113495bSYour Name  * Return: false if channel is available, true if channel is in NOL.
813*5113495bSYour Name  */
814*5113495bSYour Name bool
sap_dfs_is_channel_in_nol_list(struct sap_context * sap_context,qdf_freq_t channel_freq,ePhyChanBondState chan_bondState)815*5113495bSYour Name sap_dfs_is_channel_in_nol_list(struct sap_context *sap_context,
816*5113495bSYour Name 			       qdf_freq_t channel_freq,
817*5113495bSYour Name 			       ePhyChanBondState chan_bondState)
818*5113495bSYour Name {
819*5113495bSYour Name 	int i;
820*5113495bSYour Name 	struct mac_context *mac_ctx;
821*5113495bSYour Name 	qdf_freq_t freq_list[MAX_BONDED_CHANNELS];
822*5113495bSYour Name 	uint8_t num_ch_freq;
823*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev = NULL;
824*5113495bSYour Name 	enum channel_state ch_state;
825*5113495bSYour Name 	qdf_freq_t ch_freq;
826*5113495bSYour Name 
827*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
828*5113495bSYour Name 	if (!mac_ctx) {
829*5113495bSYour Name 		sap_err("Invalid MAC context");
830*5113495bSYour Name 		return false;
831*5113495bSYour Name 	}
832*5113495bSYour Name 
833*5113495bSYour Name 	pdev = mac_ctx->pdev;
834*5113495bSYour Name 	if (!pdev) {
835*5113495bSYour Name 		sap_err("null pdev");
836*5113495bSYour Name 		return false;
837*5113495bSYour Name 	}
838*5113495bSYour Name 
839*5113495bSYour Name 	sap_context->ch_params.mhz_freq_seg0 =
840*5113495bSYour Name 			wlan_reg_legacy_chan_to_freq(
841*5113495bSYour Name 				pdev,
842*5113495bSYour Name 				sap_context->ch_params.center_freq_seg0);
843*5113495bSYour Name 	sap_context->ch_params.mhz_freq_seg1 =
844*5113495bSYour Name 			wlan_reg_legacy_chan_to_freq(
845*5113495bSYour Name 				pdev,
846*5113495bSYour Name 				sap_context->ch_params.center_freq_seg1);
847*5113495bSYour Name 
848*5113495bSYour Name 	/* get the bonded channels */
849*5113495bSYour Name 	if (channel_freq == sap_context->chan_freq &&
850*5113495bSYour Name 	    chan_bondState >= PHY_CHANNEL_BONDING_STATE_MAX)
851*5113495bSYour Name 		num_ch_freq = sap_ch_params_to_bonding_channels(
852*5113495bSYour Name 					&sap_context->ch_params, freq_list);
853*5113495bSYour Name 	else
854*5113495bSYour Name 		num_ch_freq = sap_get_bonding_channels(
855*5113495bSYour Name 					sap_context, channel_freq,
856*5113495bSYour Name 					freq_list, MAX_BONDED_CHANNELS,
857*5113495bSYour Name 					chan_bondState);
858*5113495bSYour Name 
859*5113495bSYour Name 	/* check for NOL, first on will break the loop */
860*5113495bSYour Name 	for (i = 0; i < num_ch_freq; i++) {
861*5113495bSYour Name 		ch_freq = freq_list[i];
862*5113495bSYour Name 
863*5113495bSYour Name 		ch_state =
864*5113495bSYour Name 			wlan_reg_get_channel_state_from_secondary_list_for_freq(
865*5113495bSYour Name 								pdev, ch_freq);
866*5113495bSYour Name 		if (CHANNEL_STATE_ENABLE != ch_state &&
867*5113495bSYour Name 		    CHANNEL_STATE_DFS != ch_state) {
868*5113495bSYour Name 			sap_err_rl("Invalid ch freq = %d, ch state=%d", ch_freq,
869*5113495bSYour Name 				   ch_state);
870*5113495bSYour Name 			return true;
871*5113495bSYour Name 		}
872*5113495bSYour Name 	} /* loop for bonded channels */
873*5113495bSYour Name 
874*5113495bSYour Name 	return false;
875*5113495bSYour Name }
876*5113495bSYour Name 
877*5113495bSYour Name bool
sap_chan_bond_dfs_sub_chan(struct sap_context * sap_context,qdf_freq_t channel_freq,ePhyChanBondState bond_state)878*5113495bSYour Name sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context,
879*5113495bSYour Name 			   qdf_freq_t channel_freq,
880*5113495bSYour Name 			   ePhyChanBondState bond_state)
881*5113495bSYour Name {
882*5113495bSYour Name 	int i;
883*5113495bSYour Name 	struct mac_context *mac_ctx;
884*5113495bSYour Name 	qdf_freq_t freq_list[MAX_BONDED_CHANNELS];
885*5113495bSYour Name 	uint8_t num_freq;
886*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
887*5113495bSYour Name 
888*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
889*5113495bSYour Name 	if (!mac_ctx) {
890*5113495bSYour Name 		sap_err("Invalid MAC context");
891*5113495bSYour Name 		return false;
892*5113495bSYour Name 	}
893*5113495bSYour Name 
894*5113495bSYour Name 	pdev = mac_ctx->pdev;
895*5113495bSYour Name 	if (!pdev) {
896*5113495bSYour Name 		sap_err("null pdev");
897*5113495bSYour Name 		return false;
898*5113495bSYour Name 	}
899*5113495bSYour Name 
900*5113495bSYour Name 	if (wlan_reg_chan_has_dfs_attribute_for_freq(pdev, channel_freq))
901*5113495bSYour Name 		return true;
902*5113495bSYour Name 
903*5113495bSYour Name 	/* get the bonded channels */
904*5113495bSYour Name 	if (channel_freq == sap_context->chan_freq &&
905*5113495bSYour Name 	    bond_state >= PHY_CHANNEL_BONDING_STATE_MAX)
906*5113495bSYour Name 		num_freq = sap_ch_params_to_bonding_channels(
907*5113495bSYour Name 					&sap_context->ch_params, freq_list);
908*5113495bSYour Name 	else
909*5113495bSYour Name 		num_freq = sap_get_bonding_channels(
910*5113495bSYour Name 					sap_context, channel_freq, freq_list,
911*5113495bSYour Name 					MAX_BONDED_CHANNELS, bond_state);
912*5113495bSYour Name 
913*5113495bSYour Name 	for (i = 0; i < num_freq; i++) {
914*5113495bSYour Name 		if (wlan_reg_chan_has_dfs_attribute_for_freq(pdev, freq_list[i])) {
915*5113495bSYour Name 			sap_debug("sub ch freq=%d is dfs in %d",
916*5113495bSYour Name 				  freq_list[i], channel_freq);
917*5113495bSYour Name 			return true;
918*5113495bSYour Name 		}
919*5113495bSYour Name 	}
920*5113495bSYour Name 
921*5113495bSYour Name 	return false;
922*5113495bSYour Name }
923*5113495bSYour Name 
sap_select_default_oper_chan(struct mac_context * mac_ctx,struct sap_acs_cfg * acs_cfg)924*5113495bSYour Name uint32_t sap_select_default_oper_chan(struct mac_context *mac_ctx,
925*5113495bSYour Name 				      struct sap_acs_cfg *acs_cfg)
926*5113495bSYour Name {
927*5113495bSYour Name 	uint16_t i;
928*5113495bSYour Name 	uint32_t freq0 = 0, freq1 = 0, freq2 = 0, default_freq;
929*5113495bSYour Name 
930*5113495bSYour Name 	if (!acs_cfg)
931*5113495bSYour Name 		return 0;
932*5113495bSYour Name 
933*5113495bSYour Name 	if (!acs_cfg->ch_list_count || !acs_cfg->freq_list) {
934*5113495bSYour Name 		if (mac_ctx->mlme_cfg->acs.force_sap_start) {
935*5113495bSYour Name 			sap_debug("SAP forced, freq selected %d",
936*5113495bSYour Name 				  acs_cfg->master_freq_list[0]);
937*5113495bSYour Name 			return acs_cfg->master_freq_list[0];
938*5113495bSYour Name 		} else {
939*5113495bSYour Name 			sap_debug("No channel left for operation");
940*5113495bSYour Name 			return 0;
941*5113495bSYour Name 		}
942*5113495bSYour Name 	}
943*5113495bSYour Name 	/*
944*5113495bSYour Name 	 * There could be both 2.4Ghz and 5ghz channels present in the list
945*5113495bSYour Name 	 * based upon the Hw mode received from hostapd, it is always better
946*5113495bSYour Name 	 * to chose a default 5ghz operating channel than 2.4ghz, as it can
947*5113495bSYour Name 	 * provide a better throughput, latency than 2.4ghz. Also 40 Mhz is
948*5113495bSYour Name 	 * rare in 2.4ghz band, so 5ghz should be preferred. If we get a 5Ghz
949*5113495bSYour Name 	 * chan in the acs cfg ch list , we should go for that first else the
950*5113495bSYour Name 	 * default channel can be 2.4ghz.
951*5113495bSYour Name 	 * Add check regulatory channel state before select the channel.
952*5113495bSYour Name 	 */
953*5113495bSYour Name 
954*5113495bSYour Name 	for (i = 0; i < acs_cfg->ch_list_count; i++) {
955*5113495bSYour Name 		enum channel_state state =
956*5113495bSYour Name 			wlan_reg_get_channel_state_for_pwrmode(
957*5113495bSYour Name 					mac_ctx->pdev, acs_cfg->freq_list[i],
958*5113495bSYour Name 					REG_CURRENT_PWR_MODE);
959*5113495bSYour Name 		if (!freq0 && state == CHANNEL_STATE_ENABLE &&
960*5113495bSYour Name 		    WLAN_REG_IS_5GHZ_CH_FREQ(acs_cfg->freq_list[i])) {
961*5113495bSYour Name 			freq0 = acs_cfg->freq_list[i];
962*5113495bSYour Name 			break;
963*5113495bSYour Name 		} else if (!freq1 && state == CHANNEL_STATE_DFS &&
964*5113495bSYour Name 			   WLAN_REG_IS_5GHZ_CH_FREQ(acs_cfg->freq_list[i])) {
965*5113495bSYour Name 			freq1 = acs_cfg->freq_list[i];
966*5113495bSYour Name 		} else if (!freq2 && state == CHANNEL_STATE_ENABLE) {
967*5113495bSYour Name 			freq2 = acs_cfg->freq_list[i];
968*5113495bSYour Name 		}
969*5113495bSYour Name 	}
970*5113495bSYour Name 	default_freq = freq0;
971*5113495bSYour Name 	if (!default_freq)
972*5113495bSYour Name 		default_freq = freq1;
973*5113495bSYour Name 	if (!default_freq)
974*5113495bSYour Name 		default_freq = freq2;
975*5113495bSYour Name 	if (!default_freq)
976*5113495bSYour Name 		default_freq = acs_cfg->freq_list[0];
977*5113495bSYour Name 
978*5113495bSYour Name 	sap_debug("default freq %d chosen from %d %d %d %d", default_freq,
979*5113495bSYour Name 		  freq0, freq1, freq2, acs_cfg->freq_list[0]);
980*5113495bSYour Name 
981*5113495bSYour Name 	return default_freq;
982*5113495bSYour Name }
983*5113495bSYour Name 
is_mcc_preferred(struct sap_context * sap_context,uint32_t con_ch_freq)984*5113495bSYour Name static bool is_mcc_preferred(struct sap_context *sap_context,
985*5113495bSYour Name 			     uint32_t con_ch_freq)
986*5113495bSYour Name {
987*5113495bSYour Name 	/*
988*5113495bSYour Name 	 * If SAP ACS channel list is 1-11 and STA is on non-preferred
989*5113495bSYour Name 	 * channel i.e. 12, 13, 14 then MCC is unavoidable. This is because
990*5113495bSYour Name 	 * if SAP is started on 12,13,14 some clients may not be able to
991*5113495bSYour Name 	 * join dependending on their regulatory country.
992*5113495bSYour Name 	 */
993*5113495bSYour Name 	if ((con_ch_freq >= 2467) && (con_ch_freq <= 2484) &&
994*5113495bSYour Name 	    (sap_context->acs_cfg->start_ch_freq >= 2412 &&
995*5113495bSYour Name 	     sap_context->acs_cfg->end_ch_freq <= 2462)) {
996*5113495bSYour Name 		sap_debug("conc ch freq %d & sap acs ch list is 1-11, prefer mcc",
997*5113495bSYour Name 			  con_ch_freq);
998*5113495bSYour Name 		return true;
999*5113495bSYour Name 	}
1000*5113495bSYour Name 
1001*5113495bSYour Name 	return false;
1002*5113495bSYour Name }
1003*5113495bSYour Name 
1004*5113495bSYour Name /**
1005*5113495bSYour Name  * sap_process_force_scc_with_go_start() - Check GO force SCC or not
1006*5113495bSYour Name  * @psoc: psoc object
1007*5113495bSYour Name  * @sap_context: sap_context
1008*5113495bSYour Name  *
1009*5113495bSYour Name  * This function checks the current SAP MCC or not with the GO's home channel.
1010*5113495bSYour Name  * If it is, skip the GO's force SCC. The SAP will do force SCC after
1011*5113495bSYour Name  * GO's started.
1012*5113495bSYour Name  *
1013*5113495bSYour Name  * Return: true if skip GO's force SCC
1014*5113495bSYour Name  */
1015*5113495bSYour Name static bool
sap_process_force_scc_with_go_start(struct wlan_objmgr_psoc * psoc,struct sap_context * sap_context)1016*5113495bSYour Name sap_process_force_scc_with_go_start(struct wlan_objmgr_psoc *psoc,
1017*5113495bSYour Name 				    struct sap_context *sap_context)
1018*5113495bSYour Name {
1019*5113495bSYour Name 	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
1020*5113495bSYour Name 	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
1021*5113495bSYour Name 	uint32_t con_freq;
1022*5113495bSYour Name 	enum phy_ch_width ch_width;
1023*5113495bSYour Name 
1024*5113495bSYour Name 	if (sap_context->cc_switch_mode ==
1025*5113495bSYour Name 			QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)
1026*5113495bSYour Name 		return false;
1027*5113495bSYour Name 
1028*5113495bSYour Name 	existing_vdev_id =
1029*5113495bSYour Name 		policy_mgr_fetch_existing_con_info(psoc,
1030*5113495bSYour Name 						   sap_context->sessionId,
1031*5113495bSYour Name 						   sap_context->chan_freq,
1032*5113495bSYour Name 						   &existing_vdev_mode,
1033*5113495bSYour Name 						   &con_freq, &ch_width);
1034*5113495bSYour Name 	if (existing_vdev_id < WLAN_UMAC_VDEV_ID_MAX &&
1035*5113495bSYour Name 	    existing_vdev_mode == PM_SAP_MODE) {
1036*5113495bSYour Name 		sap_debug("concurrent sap vdev: %d on freq %d, skip GO force scc",
1037*5113495bSYour Name 			  existing_vdev_id, con_freq);
1038*5113495bSYour Name 		return true;
1039*5113495bSYour Name 	}
1040*5113495bSYour Name 
1041*5113495bSYour Name 	return false;
1042*5113495bSYour Name }
1043*5113495bSYour Name 
1044*5113495bSYour Name #ifdef WLAN_FEATURE_P2P_P2P_STA
1045*5113495bSYour Name /**
1046*5113495bSYour Name  * sap_set_forcescc_required() - set force scc flag for provided p2p go vdev
1047*5113495bSYour Name  *
1048*5113495bSYour Name  * @vdev_id: vdev_id for which flag needs to be set
1049*5113495bSYour Name  *
1050*5113495bSYour Name  * Return: None
1051*5113495bSYour Name  */
sap_set_forcescc_required(uint8_t vdev_id)1052*5113495bSYour Name static void sap_set_forcescc_required(uint8_t vdev_id)
1053*5113495bSYour Name {
1054*5113495bSYour Name 	struct mac_context *mac_ctx;
1055*5113495bSYour Name 	struct sap_context *sap_ctx;
1056*5113495bSYour Name 	uint8_t i = 0;
1057*5113495bSYour Name 
1058*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
1059*5113495bSYour Name 	if (!mac_ctx) {
1060*5113495bSYour Name 		sap_err("Invalid MAC context");
1061*5113495bSYour Name 		return;
1062*5113495bSYour Name 	}
1063*5113495bSYour Name 
1064*5113495bSYour Name 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
1065*5113495bSYour Name 		sap_ctx = mac_ctx->sap.sapCtxList[i].sap_context;
1066*5113495bSYour Name 		if (QDF_P2P_GO_MODE == mac_ctx->sap.sapCtxList[i].sapPersona &&
1067*5113495bSYour Name 		    sap_ctx->sessionId == vdev_id) {
1068*5113495bSYour Name 			sap_debug("update forcescc restart for vdev %d",
1069*5113495bSYour Name 				  vdev_id);
1070*5113495bSYour Name 			sap_ctx->is_forcescc_restart_required = true;
1071*5113495bSYour Name 		}
1072*5113495bSYour Name 	}
1073*5113495bSYour Name }
1074*5113495bSYour Name 
1075*5113495bSYour Name /**
1076*5113495bSYour Name  * sap_process_liberal_scc_for_go() - based on existing connections this
1077*5113495bSYour Name  * function decides current go should start on provided channel or not and
1078*5113495bSYour Name  * sets force scc required bit for existing GO.
1079*5113495bSYour Name  *
1080*5113495bSYour Name  * @sap_context: sap_context
1081*5113495bSYour Name  *
1082*5113495bSYour Name  * Return: bool
1083*5113495bSYour Name  */
sap_process_liberal_scc_for_go(struct sap_context * sap_context)1084*5113495bSYour Name static bool sap_process_liberal_scc_for_go(struct sap_context *sap_context)
1085*5113495bSYour Name {
1086*5113495bSYour Name 	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
1087*5113495bSYour Name 	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
1088*5113495bSYour Name 	uint32_t con_freq;
1089*5113495bSYour Name 	enum phy_ch_width ch_width;
1090*5113495bSYour Name 	struct mac_context *mac_ctx;
1091*5113495bSYour Name 	mac_handle_t mac_handle;
1092*5113495bSYour Name 
1093*5113495bSYour Name 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
1094*5113495bSYour Name 	mac_ctx = MAC_CONTEXT(mac_handle);
1095*5113495bSYour Name 	if (!mac_ctx) {
1096*5113495bSYour Name 		sap_alert("invalid MAC handle");
1097*5113495bSYour Name 		return true;
1098*5113495bSYour Name 	}
1099*5113495bSYour Name 
1100*5113495bSYour Name 	existing_vdev_id =
1101*5113495bSYour Name 		policy_mgr_fetch_existing_con_info(
1102*5113495bSYour Name 				mac_ctx->psoc,
1103*5113495bSYour Name 				sap_context->sessionId,
1104*5113495bSYour Name 				sap_context->chan_freq,
1105*5113495bSYour Name 				&existing_vdev_mode,
1106*5113495bSYour Name 				&con_freq, &ch_width);
1107*5113495bSYour Name 
1108*5113495bSYour Name 	if (existing_vdev_id <
1109*5113495bSYour Name 			WLAN_UMAC_VDEV_ID_MAX &&
1110*5113495bSYour Name 			existing_vdev_mode == PM_P2P_GO_MODE) {
1111*5113495bSYour Name 		sap_debug("set forcescc flag for go vdev: %d",
1112*5113495bSYour Name 			  existing_vdev_id);
1113*5113495bSYour Name 		sap_set_forcescc_required(
1114*5113495bSYour Name 				existing_vdev_id);
1115*5113495bSYour Name 		return true;
1116*5113495bSYour Name 	}
1117*5113495bSYour Name 	if (existing_vdev_id < WLAN_UMAC_VDEV_ID_MAX &&
1118*5113495bSYour Name 	    (existing_vdev_mode == PM_STA_MODE ||
1119*5113495bSYour Name 	    existing_vdev_mode == PM_P2P_CLIENT_MODE)) {
1120*5113495bSYour Name 		sap_debug("don't override channel, start go on %d",
1121*5113495bSYour Name 			  sap_context->chan_freq);
1122*5113495bSYour Name 		return true;
1123*5113495bSYour Name 	}
1124*5113495bSYour Name 
1125*5113495bSYour Name 	return false;
1126*5113495bSYour Name }
1127*5113495bSYour Name #else
sap_process_liberal_scc_for_go(struct sap_context * sap_context)1128*5113495bSYour Name static bool sap_process_liberal_scc_for_go(struct sap_context *sap_context)
1129*5113495bSYour Name {
1130*5113495bSYour Name 	return false;
1131*5113495bSYour Name }
1132*5113495bSYour Name #endif
1133*5113495bSYour Name 
1134*5113495bSYour Name QDF_STATUS
sap_validate_chan(struct sap_context * sap_context,bool pre_start_bss,bool check_for_connection_update)1135*5113495bSYour Name sap_validate_chan(struct sap_context *sap_context,
1136*5113495bSYour Name 		  bool pre_start_bss,
1137*5113495bSYour Name 		  bool check_for_connection_update)
1138*5113495bSYour Name {
1139*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1140*5113495bSYour Name 	struct mac_context *mac_ctx;
1141*5113495bSYour Name 	mac_handle_t mac_handle;
1142*5113495bSYour Name 	uint32_t con_ch_freq;
1143*5113495bSYour Name 	bool sta_sap_scc_on_dfs_chan;
1144*5113495bSYour Name 	uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK;
1145*5113495bSYour Name 	uint32_t sta_sap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK;
1146*5113495bSYour Name 	uint32_t concurrent_state;
1147*5113495bSYour Name 	bool go_force_scc;
1148*5113495bSYour Name 	struct ch_params ch_params = {0};
1149*5113495bSYour Name 	bool is_go_scc_strict = false;
1150*5113495bSYour Name 	bool start_sap_on_provided_freq = false;
1151*5113495bSYour Name 	enum QDF_OPMODE opmode = QDF_SAP_MODE;
1152*5113495bSYour Name 
1153*5113495bSYour Name 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
1154*5113495bSYour Name 	mac_ctx = MAC_CONTEXT(mac_handle);
1155*5113495bSYour Name 	if (!mac_ctx) {
1156*5113495bSYour Name 		/* we have a serious problem */
1157*5113495bSYour Name 		sap_alert("invalid MAC handle");
1158*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
1159*5113495bSYour Name 	}
1160*5113495bSYour Name 
1161*5113495bSYour Name 	if (!sap_context->chan_freq) {
1162*5113495bSYour Name 		sap_err("Invalid channel");
1163*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1164*5113495bSYour Name 	}
1165*5113495bSYour Name 
1166*5113495bSYour Name 	if (policy_mgr_is_vdev_ll_lt_sap(mac_ctx->psoc, sap_context->vdev_id)) {
1167*5113495bSYour Name 		sap_context->chan_freq = wlan_ll_lt_sap_override_freq(
1168*5113495bSYour Name 							mac_ctx->psoc,
1169*5113495bSYour Name 							sap_context->vdev_id,
1170*5113495bSYour Name 							sap_context->chan_freq);
1171*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1172*5113495bSYour Name 	}
1173*5113495bSYour Name 
1174*5113495bSYour Name 	if (sap_context->vdev)
1175*5113495bSYour Name 		opmode = wlan_vdev_mlme_get_opmode(sap_context->vdev);
1176*5113495bSYour Name 
1177*5113495bSYour Name 	if (opmode == QDF_P2P_GO_MODE) {
1178*5113495bSYour Name 	       /*
1179*5113495bSYour Name 		* check whether go_force_scc is enabled or not.
1180*5113495bSYour Name 		* If it not enabled then don't any force scc on existing go and
1181*5113495bSYour Name 		* new p2p go vdevs.
1182*5113495bSYour Name 		* Otherwise, if it is enabled then check whether it's in strict
1183*5113495bSYour Name 		* mode or liberal mode.
1184*5113495bSYour Name 		* For strict mode, do force scc on newly p2p go to existing vdev
1185*5113495bSYour Name 		* channel.
1186*5113495bSYour Name 		* For liberal first form new p2p go on requested channel and
1187*5113495bSYour Name 		* follow below rules:
1188*5113495bSYour Name 		* a.) If Existing vdev mode is P2P GO Once set key is done, do
1189*5113495bSYour Name 		* force scc for existing p2p go and move that go to new p2p
1190*5113495bSYour Name 		* go's channel.
1191*5113495bSYour Name 		*
1192*5113495bSYour Name 		* b.) If Existing vdev mode is P2P CLI/STA Once set key is
1193*5113495bSYour Name 		* done, do force scc for p2p go and move go to cli/sta channel.
1194*5113495bSYour Name 		*/
1195*5113495bSYour Name 		go_force_scc = policy_mgr_go_scc_enforced(mac_ctx->psoc);
1196*5113495bSYour Name 		sap_debug("go force scc enabled %d", go_force_scc);
1197*5113495bSYour Name 
1198*5113495bSYour Name 		if (sap_process_force_scc_with_go_start(mac_ctx->psoc,
1199*5113495bSYour Name 							sap_context))
1200*5113495bSYour Name 			goto validation_done;
1201*5113495bSYour Name 
1202*5113495bSYour Name 		if (go_force_scc) {
1203*5113495bSYour Name 			is_go_scc_strict =
1204*5113495bSYour Name 				policy_mgr_is_go_scc_strict(mac_ctx->psoc);
1205*5113495bSYour Name 			if (!is_go_scc_strict) {
1206*5113495bSYour Name 				sap_debug("liberal mode is enabled");
1207*5113495bSYour Name 				start_sap_on_provided_freq =
1208*5113495bSYour Name 				sap_process_liberal_scc_for_go(sap_context);
1209*5113495bSYour Name 				if (start_sap_on_provided_freq)
1210*5113495bSYour Name 					goto validation_done;
1211*5113495bSYour Name 			}
1212*5113495bSYour Name 		} else {
1213*5113495bSYour Name 			goto validation_done;
1214*5113495bSYour Name 		}
1215*5113495bSYour Name 	}
1216*5113495bSYour Name 
1217*5113495bSYour Name 	concurrent_state = policy_mgr_get_concurrency_mode(mac_ctx->psoc);
1218*5113495bSYour Name 	if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) ||
1219*5113495bSYour Name 	    ((concurrent_state & sta_sap_bit_mask) == sta_sap_bit_mask) ||
1220*5113495bSYour Name 	    ((concurrent_state & sta_go_bit_mask) == sta_go_bit_mask)) {
1221*5113495bSYour Name #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
1222*5113495bSYour Name 		if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
1223*5113495bSYour Name 					     sap_context->chan_freq)) {
1224*5113495bSYour Name 			sap_warn("DFS not supported in STA_AP Mode");
1225*5113495bSYour Name 			return QDF_STATUS_E_ABORTED;
1226*5113495bSYour Name 		}
1227*5113495bSYour Name #endif
1228*5113495bSYour Name #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
1229*5113495bSYour Name 		if (sap_context->cc_switch_mode !=
1230*5113495bSYour Name 					QDF_MCC_TO_SCC_SWITCH_DISABLE) {
1231*5113495bSYour Name 			con_ch_freq = sme_check_concurrent_channel_overlap(
1232*5113495bSYour Name 					mac_handle,
1233*5113495bSYour Name 					sap_context->chan_freq,
1234*5113495bSYour Name 					sap_context->phyMode,
1235*5113495bSYour Name 					sap_context->cc_switch_mode,
1236*5113495bSYour Name 					sap_context->sessionId);
1237*5113495bSYour Name 			sap_debug("After check overlap: sap freq %d con freq:%d",
1238*5113495bSYour Name 				  sap_context->chan_freq, con_ch_freq);
1239*5113495bSYour Name 			/*
1240*5113495bSYour Name 			 * For non-DBS platform, a 2.4Ghz can become a 5Ghz freq
1241*5113495bSYour Name 			 * so lets used max BW in that case, if it remain 2.4Ghz
1242*5113495bSYour Name 			 * then BW will be limited to 20 anyway
1243*5113495bSYour Name 			 */
1244*5113495bSYour Name 			if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_context->chan_freq))
1245*5113495bSYour Name 				ch_params.ch_width = CH_WIDTH_MAX;
1246*5113495bSYour Name 			else
1247*5113495bSYour Name 				ch_params = sap_context->ch_params;
1248*5113495bSYour Name 
1249*5113495bSYour Name 			if (sap_context->cc_switch_mode !=
1250*5113495bSYour Name 		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) {
1251*5113495bSYour Name 				if (QDF_IS_STATUS_ERROR(
1252*5113495bSYour Name 					policy_mgr_valid_sap_conc_channel_check(
1253*5113495bSYour Name 						mac_ctx->psoc, &con_ch_freq,
1254*5113495bSYour Name 						sap_context->chan_freq,
1255*5113495bSYour Name 						sap_context->sessionId,
1256*5113495bSYour Name 						&ch_params))) {
1257*5113495bSYour Name 					sap_warn("SAP can't start (no MCC)");
1258*5113495bSYour Name 					return QDF_STATUS_E_ABORTED;
1259*5113495bSYour Name 				}
1260*5113495bSYour Name 			}
1261*5113495bSYour Name 			/* if CH width didn't change fallback to original */
1262*5113495bSYour Name 			if (ch_params.ch_width == CH_WIDTH_MAX)
1263*5113495bSYour Name 				ch_params = sap_context->ch_params;
1264*5113495bSYour Name 
1265*5113495bSYour Name 			sap_debug("After check concurrency: con freq:%d",
1266*5113495bSYour Name 				  con_ch_freq);
1267*5113495bSYour Name 			sta_sap_scc_on_dfs_chan =
1268*5113495bSYour Name 				policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
1269*5113495bSYour Name 						mac_ctx->psoc);
1270*5113495bSYour Name 			if (con_ch_freq &&
1271*5113495bSYour Name 			    (policy_mgr_sta_sap_scc_on_lte_coex_chan(
1272*5113495bSYour Name 						mac_ctx->psoc) ||
1273*5113495bSYour Name 			     policy_mgr_is_safe_channel(
1274*5113495bSYour Name 						mac_ctx->psoc, con_ch_freq)) &&
1275*5113495bSYour Name 			    (!wlan_mlme_check_chan_param_has_dfs(
1276*5113495bSYour Name 					mac_ctx->pdev, &ch_params,
1277*5113495bSYour Name 					con_ch_freq) ||
1278*5113495bSYour Name 			    sta_sap_scc_on_dfs_chan)) {
1279*5113495bSYour Name 				if (is_mcc_preferred(sap_context, con_ch_freq))
1280*5113495bSYour Name 					goto validation_done;
1281*5113495bSYour Name 
1282*5113495bSYour Name 				sap_debug("Override ch freq %d (bw %d) to %d (bw %d) due to CC Intf",
1283*5113495bSYour Name 					  sap_context->chan_freq,
1284*5113495bSYour Name 					  sap_context->ch_params.ch_width,
1285*5113495bSYour Name 					  con_ch_freq, ch_params.ch_width);
1286*5113495bSYour Name 				sap_context->chan_freq = con_ch_freq;
1287*5113495bSYour Name 				sap_context->ch_params = ch_params;
1288*5113495bSYour Name 			}
1289*5113495bSYour Name 		}
1290*5113495bSYour Name #endif
1291*5113495bSYour Name 	}
1292*5113495bSYour Name validation_done:
1293*5113495bSYour Name 	sap_debug("for configured channel, Ch_freq = %d",
1294*5113495bSYour Name 		  sap_context->chan_freq);
1295*5113495bSYour Name 
1296*5113495bSYour Name 	/*
1297*5113495bSYour Name 	 * Don't check if the frequency is allowed or not if SAP is started
1298*5113495bSYour Name 	 * in fixed channel, or WLAN CH AVOID EXT feature explicit restrict
1299*5113495bSYour Name 	 * SAP start on unsafe channel.
1300*5113495bSYour Name 	 */
1301*5113495bSYour Name 
1302*5113495bSYour Name 	if ((sap_context->acs_cfg->acs_mode ||
1303*5113495bSYour Name 	     policy_mgr_restrict_sap_on_unsafe_chan(mac_ctx->psoc)) &&
1304*5113495bSYour Name 	    !policy_mgr_is_sap_freq_allowed(mac_ctx->psoc, opmode,
1305*5113495bSYour Name 					    sap_context->chan_freq)) {
1306*5113495bSYour Name 		sap_warn("Abort SAP start due to unsafe channel");
1307*5113495bSYour Name 		return QDF_STATUS_E_ABORTED;
1308*5113495bSYour Name 	}
1309*5113495bSYour Name 
1310*5113495bSYour Name 	if (check_for_connection_update) {
1311*5113495bSYour Name 		/* This wait happens in the hostapd context. The event
1312*5113495bSYour Name 		 * is set in the MC thread context.
1313*5113495bSYour Name 		 */
1314*5113495bSYour Name 		qdf_status =
1315*5113495bSYour Name 		policy_mgr_update_and_wait_for_connection_update(
1316*5113495bSYour Name 			mac_ctx->psoc, sap_context->sessionId,
1317*5113495bSYour Name 			sap_context->chan_freq,
1318*5113495bSYour Name 			POLICY_MGR_UPDATE_REASON_START_AP);
1319*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(qdf_status))
1320*5113495bSYour Name 			return qdf_status;
1321*5113495bSYour Name 	}
1322*5113495bSYour Name 
1323*5113495bSYour Name 	if (pre_start_bss) {
1324*5113495bSYour Name 		sap_info("ACS end due to Ch override. Sel Ch freq = %d",
1325*5113495bSYour Name 			  sap_context->chan_freq);
1326*5113495bSYour Name 		sap_context->acs_cfg->pri_ch_freq = sap_context->chan_freq;
1327*5113495bSYour Name 		sap_context->acs_cfg->ch_width =
1328*5113495bSYour Name 					 sap_context->ch_width_orig;
1329*5113495bSYour Name 		sap_config_acs_result(mac_handle, sap_context, 0);
1330*5113495bSYour Name 		return QDF_STATUS_E_CANCELED;
1331*5113495bSYour Name 	}
1332*5113495bSYour Name 
1333*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1334*5113495bSYour Name }
1335*5113495bSYour Name 
1336*5113495bSYour Name #ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE
1337*5113495bSYour Name 
sap_sort_freq_list(struct chan_list * list,uint8_t num_ch)1338*5113495bSYour Name static void sap_sort_freq_list(struct chan_list *list,
1339*5113495bSYour Name 			       uint8_t num_ch)
1340*5113495bSYour Name {
1341*5113495bSYour Name 	int i, j, temp;
1342*5113495bSYour Name 
1343*5113495bSYour Name 	for (i = 0; i < num_ch - 1; i++) {
1344*5113495bSYour Name 		for (j = 0 ; j < num_ch - i - 1; j++) {
1345*5113495bSYour Name 			if (list->chan[j].freq < list->chan[j + 1].freq) {
1346*5113495bSYour Name 				temp = list->chan[j].freq;
1347*5113495bSYour Name 				list->chan[j].freq = list->chan[j + 1].freq;
1348*5113495bSYour Name 				list->chan[j + 1].freq = temp;
1349*5113495bSYour Name 			}
1350*5113495bSYour Name 		}
1351*5113495bSYour Name 	}
1352*5113495bSYour Name }
1353*5113495bSYour Name 
1354*5113495bSYour Name /**
1355*5113495bSYour Name  * sap_acs_scan_freq_list_optimize() - optimize the ACS scan freq list based
1356*5113495bSYour Name  * on when last scan was performed on particular frequency. If last scan
1357*5113495bSYour Name  * performed on particular frequency is less than configured last_scan_ageout
1358*5113495bSYour Name  * time, then skip that frequency from ACS scan freq list.
1359*5113495bSYour Name  *
1360*5113495bSYour Name  * @sap_ctx: sap context
1361*5113495bSYour Name  * @list: ACS scan frequency list
1362*5113495bSYour Name  * @ch_count: number of frequency in list
1363*5113495bSYour Name  *
1364*5113495bSYour Name  * Return: None
1365*5113495bSYour Name  */
sap_acs_scan_freq_list_optimize(struct sap_context * sap_ctx,struct chan_list * list,uint8_t * ch_count)1366*5113495bSYour Name static void sap_acs_scan_freq_list_optimize(struct sap_context *sap_ctx,
1367*5113495bSYour Name 					    struct chan_list *list,
1368*5113495bSYour Name 					    uint8_t *ch_count)
1369*5113495bSYour Name {
1370*5113495bSYour Name 	int loop_count = 0, j = 0;
1371*5113495bSYour Name 	uint32_t ts_last_scan;
1372*5113495bSYour Name 
1373*5113495bSYour Name 	sap_ctx->partial_acs_scan = false;
1374*5113495bSYour Name 
1375*5113495bSYour Name 	while (loop_count < *ch_count) {
1376*5113495bSYour Name 		ts_last_scan = scm_get_last_scan_time_per_channel(
1377*5113495bSYour Name 				sap_ctx->vdev, list->chan[loop_count].freq);
1378*5113495bSYour Name 
1379*5113495bSYour Name 		if (qdf_system_time_before(
1380*5113495bSYour Name 		    qdf_get_time_of_the_day_ms(),
1381*5113495bSYour Name 		    ts_last_scan + sap_ctx->acs_cfg->last_scan_ageout_time)) {
1382*5113495bSYour Name 			sap_info("ACS chan %d skipped from scan as last scan ts %lu\n",
1383*5113495bSYour Name 				 list->chan[loop_count].freq,
1384*5113495bSYour Name 				 qdf_get_time_of_the_day_ms() - ts_last_scan);
1385*5113495bSYour Name 
1386*5113495bSYour Name 			for (j = loop_count; j < *ch_count - 1; j++)
1387*5113495bSYour Name 				list->chan[j].freq = list->chan[j + 1].freq;
1388*5113495bSYour Name 
1389*5113495bSYour Name 			(*ch_count)--;
1390*5113495bSYour Name 			sap_ctx->partial_acs_scan = true;
1391*5113495bSYour Name 			continue;
1392*5113495bSYour Name 		}
1393*5113495bSYour Name 		loop_count++;
1394*5113495bSYour Name 	}
1395*5113495bSYour Name 	if (*ch_count == 0)
1396*5113495bSYour Name 		sap_info("All ACS freq channels are scanned recently, skip ACS scan\n");
1397*5113495bSYour Name 	else
1398*5113495bSYour Name 		sap_sort_freq_list(list, *ch_count);
1399*5113495bSYour Name }
1400*5113495bSYour Name #else
sap_acs_scan_freq_list_optimize(struct sap_context * sap_ctx,struct chan_list * list,uint8_t * ch_count)1401*5113495bSYour Name static void sap_acs_scan_freq_list_optimize(struct sap_context *sap_ctx,
1402*5113495bSYour Name 					    struct chan_list *list,
1403*5113495bSYour Name 					    uint8_t *ch_count)
1404*5113495bSYour Name {
1405*5113495bSYour Name }
1406*5113495bSYour Name #endif
1407*5113495bSYour Name 
1408*5113495bSYour Name #ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE
1409*5113495bSYour Name /**
1410*5113495bSYour Name  * sap_reset_clean_freq_array() - clear freq array that contains info
1411*5113495bSYour Name  * channel is free or not
1412*5113495bSYour Name  * @sap_context: sap context
1413*5113495bSYour Name  *
1414*5113495bSYour Name  * Return: void
1415*5113495bSYour Name  */
1416*5113495bSYour Name static
sap_reset_clean_freq_array(struct sap_context * sap_context)1417*5113495bSYour Name void sap_reset_clean_freq_array(struct sap_context *sap_context)
1418*5113495bSYour Name {
1419*5113495bSYour Name 	memset(sap_context->clean_channel_array, 0, NUM_CHANNELS);
1420*5113495bSYour Name }
1421*5113495bSYour Name #else
1422*5113495bSYour Name static inline
sap_reset_clean_freq_array(struct sap_context * sap_context)1423*5113495bSYour Name void sap_reset_clean_freq_array(struct sap_context *sap_context)
1424*5113495bSYour Name {}
1425*5113495bSYour Name #endif
1426*5113495bSYour Name 
1427*5113495bSYour Name /**
1428*5113495bSYour Name  * wlansap_set_aux_scan_ctrl_ext_flag() - update aux scan policy
1429*5113495bSYour Name  * @req: pointer to scan request
1430*5113495bSYour Name  *
1431*5113495bSYour Name  * Set aux scan bits in scan_ctrl_ext_flag value depending on scan type
1432*5113495bSYour Name  *
1433*5113495bSYour Name  * Return: None
1434*5113495bSYour Name  */
wlansap_set_aux_scan_ctrl_ext_flag(struct scan_start_request * req)1435*5113495bSYour Name static void wlansap_set_aux_scan_ctrl_ext_flag(struct scan_start_request *req)
1436*5113495bSYour Name {
1437*5113495bSYour Name 	sap_debug("Set Reliable Scan Flag");
1438*5113495bSYour Name 	req->scan_req.scan_ctrl_flags_ext |=
1439*5113495bSYour Name 			SCAN_FLAG_EXT_AUX_RELIABLE_SCAN;
1440*5113495bSYour Name }
1441*5113495bSYour Name 
sap_channel_sel(struct sap_context * sap_context)1442*5113495bSYour Name QDF_STATUS sap_channel_sel(struct sap_context *sap_context)
1443*5113495bSYour Name {
1444*5113495bSYour Name 	QDF_STATUS qdf_ret_status;
1445*5113495bSYour Name 	struct mac_context *mac_ctx;
1446*5113495bSYour Name 	struct scan_start_request *req;
1447*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev = NULL;
1448*5113495bSYour Name 	uint8_t i, j;
1449*5113495bSYour Name 	uint32_t *freq_list = NULL;
1450*5113495bSYour Name 	uint8_t num_of_channels = 0;
1451*5113495bSYour Name 	mac_handle_t mac_handle;
1452*5113495bSYour Name 	uint32_t con_ch_freq;
1453*5113495bSYour Name 	uint8_t vdev_id;
1454*5113495bSYour Name 	uint32_t scan_id;
1455*5113495bSYour Name 	uint32_t default_op_freq;
1456*5113495bSYour Name 
1457*5113495bSYour Name 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
1458*5113495bSYour Name 	if (!mac_handle)
1459*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
1460*5113495bSYour Name 
1461*5113495bSYour Name 	mac_ctx = MAC_CONTEXT(mac_handle);
1462*5113495bSYour Name 	if (!mac_ctx) {
1463*5113495bSYour Name 		sap_err("Invalid MAC context");
1464*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1465*5113495bSYour Name 	}
1466*5113495bSYour Name 	if (sap_context->fsm_state != SAP_STARTED && sap_context->chan_freq)
1467*5113495bSYour Name 		return sap_validate_chan(sap_context, true, false);
1468*5113495bSYour Name 
1469*5113495bSYour Name 	if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc) ||
1470*5113495bSYour Name 	    ((sap_context->cc_switch_mode ==
1471*5113495bSYour Name 	      QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
1472*5113495bSYour Name 	     (policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
1473*5113495bSYour Name 							PM_SAP_MODE, NULL) ||
1474*5113495bSYour Name 	     policy_mgr_mode_specific_connection_count(mac_ctx->psoc,
1475*5113495bSYour Name 						       PM_P2P_GO_MODE,
1476*5113495bSYour Name 						       NULL)))) {
1477*5113495bSYour Name 		con_ch_freq = sme_get_beaconing_concurrent_operation_channel(
1478*5113495bSYour Name 					mac_handle, sap_context->sessionId);
1479*5113495bSYour Name #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
1480*5113495bSYour Name 		if (con_ch_freq)
1481*5113495bSYour Name 			sap_context->dfs_ch_disable = true;
1482*5113495bSYour Name #endif
1483*5113495bSYour Name 	}
1484*5113495bSYour Name 
1485*5113495bSYour Name 	if ((policy_mgr_get_concurrency_mode(mac_ctx->psoc) ==
1486*5113495bSYour Name 		(QDF_STA_MASK | QDF_SAP_MASK)) ||
1487*5113495bSYour Name 		((sap_context->cc_switch_mode ==
1488*5113495bSYour Name 		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
1489*5113495bSYour Name 		(policy_mgr_get_concurrency_mode(mac_ctx->psoc) ==
1490*5113495bSYour Name 		(QDF_STA_MASK | QDF_P2P_GO_MASK)))) {
1491*5113495bSYour Name #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
1492*5113495bSYour Name 		sap_context->dfs_ch_disable = true;
1493*5113495bSYour Name #endif
1494*5113495bSYour Name 	}
1495*5113495bSYour Name #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1496*5113495bSYour Name 	sap_debug("skip_acs_status = %d",
1497*5113495bSYour Name 		  sap_context->acs_cfg->skip_scan_status);
1498*5113495bSYour Name 	if (sap_context->acs_cfg->skip_scan_status !=
1499*5113495bSYour Name 					eSAP_SKIP_ACS_SCAN) {
1500*5113495bSYour Name #endif
1501*5113495bSYour Name 
1502*5113495bSYour Name 		if (sap_context->freq_list) {
1503*5113495bSYour Name 			qdf_mem_free(sap_context->freq_list);
1504*5113495bSYour Name 			sap_context->freq_list = NULL;
1505*5113495bSYour Name 			sap_context->num_of_channel = 0;
1506*5113495bSYour Name 		}
1507*5113495bSYour Name 
1508*5113495bSYour Name 		sap_get_freq_list(sap_context, &freq_list, &num_of_channels);
1509*5113495bSYour Name 		if (!num_of_channels || !freq_list) {
1510*5113495bSYour Name 			sap_err("No freq sutiable for SAP in current list, SAP failed");
1511*5113495bSYour Name 			return QDF_STATUS_E_FAILURE;
1512*5113495bSYour Name 		}
1513*5113495bSYour Name 
1514*5113495bSYour Name 		req = qdf_mem_malloc(sizeof(*req));
1515*5113495bSYour Name 		if (!req) {
1516*5113495bSYour Name 			qdf_mem_free(freq_list);
1517*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
1518*5113495bSYour Name 		}
1519*5113495bSYour Name 
1520*5113495bSYour Name 		vdev_id = sap_context->sessionId;
1521*5113495bSYour Name 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
1522*5113495bSYour Name 							    vdev_id,
1523*5113495bSYour Name 							    WLAN_LEGACY_SME_ID);
1524*5113495bSYour Name 		if (!vdev) {
1525*5113495bSYour Name 			sap_err("Invalid vdev objmgr");
1526*5113495bSYour Name 			qdf_mem_free(freq_list);
1527*5113495bSYour Name 			qdf_mem_free(req);
1528*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
1529*5113495bSYour Name 		}
1530*5113495bSYour Name 
1531*5113495bSYour Name 		/* Initiate a SCAN request */
1532*5113495bSYour Name 		wlan_scan_init_default_params(vdev, req);
1533*5113495bSYour Name 		scan_id = wlan_scan_get_scan_id(mac_ctx->psoc);
1534*5113495bSYour Name 		req->scan_req.scan_id = scan_id;
1535*5113495bSYour Name 		req->scan_req.vdev_id = vdev_id;
1536*5113495bSYour Name 		req->scan_req.scan_f_passive = false;
1537*5113495bSYour Name 		req->scan_req.scan_req_id = sap_context->req_id;
1538*5113495bSYour Name 		req->scan_req.scan_priority = SCAN_PRIORITY_HIGH;
1539*5113495bSYour Name 		req->scan_req.scan_f_bcast_probe = true;
1540*5113495bSYour Name 		for (i = 0, j = 0; i < num_of_channels; i++) {
1541*5113495bSYour Name 			if (wlan_reg_is_6ghz_chan_freq(freq_list[i]) &&
1542*5113495bSYour Name 			    !wlan_reg_is_6ghz_psc_chan_freq(freq_list[i]))
1543*5113495bSYour Name 				continue;
1544*5113495bSYour Name 			req->scan_req.chan_list.chan[j++].freq = freq_list[i];
1545*5113495bSYour Name 		}
1546*5113495bSYour Name 		req->scan_req.chan_list.num_chan = j;
1547*5113495bSYour Name 		sap_context->freq_list = freq_list;
1548*5113495bSYour Name 		sap_context->num_of_channel = num_of_channels;
1549*5113495bSYour Name 		sap_context->optimize_acs_chan_selected = false;
1550*5113495bSYour Name 		sap_reset_clean_freq_array(sap_context);
1551*5113495bSYour Name 		/* Set requestType to Full scan */
1552*5113495bSYour Name 
1553*5113495bSYour Name 		/*
1554*5113495bSYour Name 		 * send partial channels to be scanned in SCAN request if
1555*5113495bSYour Name 		 * vendor command included last scan ageout time to be used to
1556*5113495bSYour Name 		 * optimize the SAP bring up time
1557*5113495bSYour Name 		 */
1558*5113495bSYour Name 		if (sap_context->acs_cfg->last_scan_ageout_time)
1559*5113495bSYour Name 			sap_acs_scan_freq_list_optimize(
1560*5113495bSYour Name 					sap_context, &req->scan_req.chan_list,
1561*5113495bSYour Name 					&req->scan_req.chan_list.num_chan);
1562*5113495bSYour Name 
1563*5113495bSYour Name 		if (!req->scan_req.chan_list.num_chan) {
1564*5113495bSYour Name 			sap_info("## SKIPPED ACS SCAN");
1565*5113495bSYour Name 			sap_context->acs_cfg->skip_acs_scan = true;
1566*5113495bSYour Name 			wlansap_pre_start_bss_acs_scan_callback(
1567*5113495bSYour Name 				mac_handle, sap_context, sap_context->sessionId,
1568*5113495bSYour Name 				0, eCSR_SCAN_SUCCESS);
1569*5113495bSYour Name 			qdf_mem_free(req);
1570*5113495bSYour Name 			qdf_ret_status = QDF_STATUS_SUCCESS;
1571*5113495bSYour Name 			goto release_vdev_ref;
1572*5113495bSYour Name 		}
1573*5113495bSYour Name 
1574*5113495bSYour Name 		sap_context->acs_req_timestamp = qdf_get_time_of_the_day_ms();
1575*5113495bSYour Name 
1576*5113495bSYour Name 		if (wlan_scan_get_aux_support(mac_ctx->psoc))
1577*5113495bSYour Name 			wlansap_set_aux_scan_ctrl_ext_flag(req);
1578*5113495bSYour Name 		qdf_ret_status = wlan_scan_start(req);
1579*5113495bSYour Name 		if (qdf_ret_status != QDF_STATUS_SUCCESS) {
1580*5113495bSYour Name 			sap_err("scan request  fail %d!!!", qdf_ret_status);
1581*5113495bSYour Name 			sap_info("SAP Configuring default ch, Ch_freq=%d",
1582*5113495bSYour Name 				  sap_context->chan_freq);
1583*5113495bSYour Name 			default_op_freq = sap_select_default_oper_chan(
1584*5113495bSYour Name 						mac_ctx, sap_context->acs_cfg);
1585*5113495bSYour Name 			wlansap_set_acs_ch_freq(sap_context, default_op_freq);
1586*5113495bSYour Name 
1587*5113495bSYour Name 			if (sap_context->freq_list) {
1588*5113495bSYour Name 				wlansap_set_acs_ch_freq(
1589*5113495bSYour Name 					sap_context, sap_context->freq_list[0]);
1590*5113495bSYour Name 				qdf_mem_free(sap_context->freq_list);
1591*5113495bSYour Name 				sap_context->freq_list = NULL;
1592*5113495bSYour Name 				sap_context->num_of_channel = 0;
1593*5113495bSYour Name 			}
1594*5113495bSYour Name 			/*
1595*5113495bSYour Name 			* In case of ACS req before start Bss,
1596*5113495bSYour Name 			* return failure so that the calling
1597*5113495bSYour Name 			* function can use the default channel.
1598*5113495bSYour Name 			*/
1599*5113495bSYour Name 			qdf_ret_status = QDF_STATUS_E_FAILURE;
1600*5113495bSYour Name 			goto release_vdev_ref;
1601*5113495bSYour Name 		} else {
1602*5113495bSYour Name 			wlansap_dump_acs_ch_freq(sap_context);
1603*5113495bSYour Name 			host_log_acs_scan_start(scan_id, vdev_id);
1604*5113495bSYour Name 		}
1605*5113495bSYour Name 
1606*5113495bSYour Name #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1607*5113495bSYour Name 	} else {
1608*5113495bSYour Name 		sap_context->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN;
1609*5113495bSYour Name 	}
1610*5113495bSYour Name 
1611*5113495bSYour Name 	if (sap_context->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) {
1612*5113495bSYour Name 		sap_err("## SKIPPED ACS SCAN");
1613*5113495bSYour Name 		wlansap_pre_start_bss_acs_scan_callback(mac_handle,
1614*5113495bSYour Name 				sap_context, sap_context->sessionId, 0,
1615*5113495bSYour Name 				eCSR_SCAN_SUCCESS);
1616*5113495bSYour Name 	}
1617*5113495bSYour Name #endif
1618*5113495bSYour Name 
1619*5113495bSYour Name 	wlansap_dump_acs_ch_freq(sap_context);
1620*5113495bSYour Name 
1621*5113495bSYour Name 	qdf_ret_status = QDF_STATUS_SUCCESS;
1622*5113495bSYour Name 
1623*5113495bSYour Name release_vdev_ref:
1624*5113495bSYour Name 	if (vdev)
1625*5113495bSYour Name 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
1626*5113495bSYour Name 	return qdf_ret_status;
1627*5113495bSYour Name }
1628*5113495bSYour Name 
1629*5113495bSYour Name /**
1630*5113495bSYour Name  * sap_find_valid_concurrent_session() - to find valid concurrent session
1631*5113495bSYour Name  * @mac_handle: Opaque handle to the global MAC context
1632*5113495bSYour Name  *
1633*5113495bSYour Name  * This API will check if any valid concurrent SAP session is present
1634*5113495bSYour Name  *
1635*5113495bSYour Name  * Return: pointer to sap context of valid concurrent session
1636*5113495bSYour Name  */
1637*5113495bSYour Name static struct sap_context *
sap_find_valid_concurrent_session(mac_handle_t mac_handle)1638*5113495bSYour Name sap_find_valid_concurrent_session(mac_handle_t mac_handle)
1639*5113495bSYour Name {
1640*5113495bSYour Name 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
1641*5113495bSYour Name 	uint8_t intf = 0;
1642*5113495bSYour Name 	struct sap_context *sap_ctx;
1643*5113495bSYour Name 
1644*5113495bSYour Name 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
1645*5113495bSYour Name 		if (((QDF_SAP_MODE ==
1646*5113495bSYour Name 				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
1647*5113495bSYour Name 		     (QDF_P2P_GO_MODE ==
1648*5113495bSYour Name 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
1649*5113495bSYour Name 		    mac_ctx->sap.sapCtxList[intf].sap_context) {
1650*5113495bSYour Name 			sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context;
1651*5113495bSYour Name 			if (sap_ctx->fsm_state != SAP_INIT)
1652*5113495bSYour Name 				return sap_ctx;
1653*5113495bSYour Name 		}
1654*5113495bSYour Name 	}
1655*5113495bSYour Name 
1656*5113495bSYour Name 	return NULL;
1657*5113495bSYour Name }
1658*5113495bSYour Name 
sap_clear_global_dfs_param(mac_handle_t mac_handle,struct sap_context * sap_ctx)1659*5113495bSYour Name QDF_STATUS sap_clear_global_dfs_param(mac_handle_t mac_handle,
1660*5113495bSYour Name 				      struct sap_context *sap_ctx)
1661*5113495bSYour Name {
1662*5113495bSYour Name 	struct sap_context *con_sap_ctx;
1663*5113495bSYour Name 
1664*5113495bSYour Name 	con_sap_ctx = sap_find_valid_concurrent_session(mac_handle);
1665*5113495bSYour Name 	if (con_sap_ctx && WLAN_REG_IS_5GHZ_CH_FREQ(con_sap_ctx->chan_freq)) {
1666*5113495bSYour Name 		sap_debug("conc session exists, no need to clear dfs struct");
1667*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1668*5113495bSYour Name 	}
1669*5113495bSYour Name 	/*
1670*5113495bSYour Name 	 * CAC timer will be initiated and started only when SAP starts
1671*5113495bSYour Name 	 * on DFS channel and it will be stopped and destroyed
1672*5113495bSYour Name 	 * immediately once the radar detected or timedout. So
1673*5113495bSYour Name 	 * as per design CAC timer should be destroyed after stop
1674*5113495bSYour Name 	 */
1675*5113495bSYour Name 	wlansap_cleanup_cac_timer(sap_ctx);
1676*5113495bSYour Name 	sap_cac_reset_notify(mac_handle);
1677*5113495bSYour Name 
1678*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1679*5113495bSYour Name }
1680*5113495bSYour Name 
sap_acquire_vdev_ref(struct wlan_objmgr_psoc * psoc,struct sap_context * sap_ctx,uint8_t session_id)1681*5113495bSYour Name QDF_STATUS sap_acquire_vdev_ref(struct wlan_objmgr_psoc *psoc,
1682*5113495bSYour Name 				struct sap_context *sap_ctx,
1683*5113495bSYour Name 				uint8_t session_id)
1684*5113495bSYour Name {
1685*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
1686*5113495bSYour Name 
1687*5113495bSYour Name 	if (sap_ctx->vdev) {
1688*5113495bSYour Name 		sap_err("Invalid vdev obj in sap context");
1689*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
1690*5113495bSYour Name 	}
1691*5113495bSYour Name 
1692*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id,
1693*5113495bSYour Name 						    WLAN_LEGACY_SAP_ID);
1694*5113495bSYour Name 	if (!vdev) {
1695*5113495bSYour Name 		sap_err("vdev is NULL for vdev_id: %u", session_id);
1696*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1697*5113495bSYour Name 	}
1698*5113495bSYour Name 
1699*5113495bSYour Name 	sap_ctx->vdev = vdev;
1700*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1701*5113495bSYour Name }
1702*5113495bSYour Name 
sap_release_vdev_ref(struct sap_context * sap_ctx)1703*5113495bSYour Name void sap_release_vdev_ref(struct sap_context *sap_ctx)
1704*5113495bSYour Name {
1705*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
1706*5113495bSYour Name 
1707*5113495bSYour Name 	if (!sap_ctx) {
1708*5113495bSYour Name 		sap_debug("Invalid SAP pointer");
1709*5113495bSYour Name 		return;
1710*5113495bSYour Name 	}
1711*5113495bSYour Name 
1712*5113495bSYour Name 	vdev = sap_ctx->vdev;
1713*5113495bSYour Name 	if (vdev) {
1714*5113495bSYour Name 		sap_ctx->vdev = NULL;
1715*5113495bSYour Name 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SAP_ID);
1716*5113495bSYour Name 	}
1717*5113495bSYour Name }
1718*5113495bSYour Name 
sap_set_session_param(mac_handle_t mac_handle,struct sap_context * sapctx,uint32_t session_id)1719*5113495bSYour Name QDF_STATUS sap_set_session_param(mac_handle_t mac_handle,
1720*5113495bSYour Name 				 struct sap_context *sapctx,
1721*5113495bSYour Name 				 uint32_t session_id)
1722*5113495bSYour Name {
1723*5113495bSYour Name 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
1724*5113495bSYour Name 	int i;
1725*5113495bSYour Name 
1726*5113495bSYour Name 	sapctx->sessionId = session_id;
1727*5113495bSYour Name 	wlan_pre_cac_set_status(sapctx->vdev, false);
1728*5113495bSYour Name 	wlan_pre_cac_complete_set(sapctx->vdev, false);
1729*5113495bSYour Name 	wlan_pre_cac_set_freq_before_pre_cac(sapctx->vdev, 0);
1730*5113495bSYour Name 
1731*5113495bSYour Name 	/* When SSR, SAP will restart, clear the old context,sessionId */
1732*5113495bSYour Name 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
1733*5113495bSYour Name 		if (mac_ctx->sap.sapCtxList[i].sap_context == sapctx)
1734*5113495bSYour Name 			mac_ctx->sap.sapCtxList[i].sap_context = NULL;
1735*5113495bSYour Name 	}
1736*5113495bSYour Name 
1737*5113495bSYour Name 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = sapctx;
1738*5113495bSYour Name 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona =
1739*5113495bSYour Name 			wlan_get_opmode_from_vdev_id(mac_ctx->pdev, session_id);
1740*5113495bSYour Name 	sap_debug("Initializing sap_ctx = %pK with session = %d",
1741*5113495bSYour Name 		   sapctx, session_id);
1742*5113495bSYour Name 
1743*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1744*5113495bSYour Name }
1745*5113495bSYour Name 
sap_clear_session_param(mac_handle_t mac_handle,struct sap_context * sapctx,uint32_t session_id)1746*5113495bSYour Name QDF_STATUS sap_clear_session_param(mac_handle_t mac_handle,
1747*5113495bSYour Name 				   struct sap_context *sapctx,
1748*5113495bSYour Name 				   uint32_t session_id)
1749*5113495bSYour Name {
1750*5113495bSYour Name 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
1751*5113495bSYour Name 
1752*5113495bSYour Name 	if (sapctx->sessionId >= SAP_MAX_NUM_SESSION)
1753*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1754*5113495bSYour Name 
1755*5113495bSYour Name 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = NULL;
1756*5113495bSYour Name 	mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona =
1757*5113495bSYour Name 		QDF_MAX_NO_OF_MODE;
1758*5113495bSYour Name 	sap_clear_global_dfs_param(mac_handle, sapctx);
1759*5113495bSYour Name 
1760*5113495bSYour Name 	sap_err("Set sapCtxList null for session %d", sapctx->sessionId);
1761*5113495bSYour Name 	qdf_mem_zero(sapctx, sizeof(*sapctx));
1762*5113495bSYour Name 	sapctx->sessionId = WLAN_UMAC_VDEV_ID_MAX;
1763*5113495bSYour Name 
1764*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1765*5113495bSYour Name }
1766*5113495bSYour Name 
1767*5113495bSYour Name #ifdef WLAN_FEATURE_11AX
he_mcs_12_13_support(void)1768*5113495bSYour Name static uint16_t he_mcs_12_13_support(void)
1769*5113495bSYour Name {
1770*5113495bSYour Name 	struct mac_context *mac_ctx;
1771*5113495bSYour Name 
1772*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
1773*5113495bSYour Name 	if (!mac_ctx) {
1774*5113495bSYour Name 		sap_err("Invalid MAC context");
1775*5113495bSYour Name 		return 0;
1776*5113495bSYour Name 	}
1777*5113495bSYour Name 
1778*5113495bSYour Name 	return mac_ctx->mlme_cfg->he_caps.he_mcs_12_13_supp_5g;
1779*5113495bSYour Name }
1780*5113495bSYour Name #else
he_mcs_12_13_support(void)1781*5113495bSYour Name static inline uint16_t he_mcs_12_13_support(void)
1782*5113495bSYour Name {
1783*5113495bSYour Name 	return 0;
1784*5113495bSYour Name }
1785*5113495bSYour Name #endif
1786*5113495bSYour Name 
is_mcs13_ch_width(enum phy_ch_width ch_width)1787*5113495bSYour Name static bool is_mcs13_ch_width(enum phy_ch_width ch_width)
1788*5113495bSYour Name {
1789*5113495bSYour Name 	if ((ch_width == CH_WIDTH_320MHZ) ||
1790*5113495bSYour Name 	    (ch_width == CH_WIDTH_160MHZ) ||
1791*5113495bSYour Name 	    (ch_width == CH_WIDTH_80P80MHZ))
1792*5113495bSYour Name 		return true;
1793*5113495bSYour Name 
1794*5113495bSYour Name 	return false;
1795*5113495bSYour Name }
1796*5113495bSYour Name 
1797*5113495bSYour Name /**
1798*5113495bSYour Name  * sap_update_mcs_rate() - Update SAP MCS rate
1799*5113495bSYour Name  * @sap_ctx: pointer to sap Context
1800*5113495bSYour Name  * @is_start: Start or stop SAP
1801*5113495bSYour Name  *
1802*5113495bSYour Name  * Return: QDF_STATUS
1803*5113495bSYour Name  */
1804*5113495bSYour Name static QDF_STATUS
sap_update_mcs_rate(struct sap_context * sap_ctx,bool is_start)1805*5113495bSYour Name sap_update_mcs_rate(struct sap_context *sap_ctx, bool is_start)
1806*5113495bSYour Name {
1807*5113495bSYour Name 	uint32_t default_mcs[] = {26, 0x3fff};
1808*5113495bSYour Name 	uint32_t fixed_mcs[] = {26, 0x1fff};
1809*5113495bSYour Name 	bool disable_mcs13_support = false;
1810*5113495bSYour Name 	uint16_t he_mcs_12_13_supp;
1811*5113495bSYour Name 	struct mac_context *mac_ctx;
1812*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1813*5113495bSYour Name 
1814*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
1815*5113495bSYour Name 	if (!mac_ctx) {
1816*5113495bSYour Name 		sap_err("Invalid MAC context");
1817*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1818*5113495bSYour Name 	}
1819*5113495bSYour Name 
1820*5113495bSYour Name 	he_mcs_12_13_supp = he_mcs_12_13_support();
1821*5113495bSYour Name 	disable_mcs13_support = cfg_get(mac_ctx->psoc,
1822*5113495bSYour Name 					CFG_DISABLE_MCS13_SUPPORT);
1823*5113495bSYour Name 	sap_debug("session id %d, disable mcs13 support %d, he_mcs_12_13 %d, start %d, disabled_mcs13 %d, ch width %d",
1824*5113495bSYour Name 		  sap_ctx->sessionId, disable_mcs13_support,
1825*5113495bSYour Name 		  he_mcs_12_13_supp,
1826*5113495bSYour Name 		  is_start, sap_ctx->disabled_mcs13,
1827*5113495bSYour Name 		  sap_ctx->ch_params.ch_width);
1828*5113495bSYour Name 
1829*5113495bSYour Name 	if (!disable_mcs13_support ||
1830*5113495bSYour Name 	    !he_mcs_12_13_supp)
1831*5113495bSYour Name 		return status;
1832*5113495bSYour Name 
1833*5113495bSYour Name 	if (!is_start && !sap_ctx->disabled_mcs13)
1834*5113495bSYour Name 		return status;
1835*5113495bSYour Name 
1836*5113495bSYour Name 	if (!is_mcs13_ch_width(sap_ctx->ch_params.ch_width))
1837*5113495bSYour Name 		return status;
1838*5113495bSYour Name 
1839*5113495bSYour Name 	if (is_start) {
1840*5113495bSYour Name 		status = sme_send_unit_test_cmd(sap_ctx->sessionId,
1841*5113495bSYour Name 						10, 2, fixed_mcs);
1842*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
1843*5113495bSYour Name 			sap_err("Set fixed mcs rate failed, session %d",
1844*5113495bSYour Name 				sap_ctx->sessionId);
1845*5113495bSYour Name 		} else {
1846*5113495bSYour Name 			sap_ctx->disabled_mcs13 = true;
1847*5113495bSYour Name 		}
1848*5113495bSYour Name 	} else {
1849*5113495bSYour Name 		status = sme_send_unit_test_cmd(sap_ctx->sessionId,
1850*5113495bSYour Name 						10, 2, default_mcs);
1851*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
1852*5113495bSYour Name 			sap_err("Set default mcs rate failed, session %d",
1853*5113495bSYour Name 				sap_ctx->sessionId);
1854*5113495bSYour Name 		} else {
1855*5113495bSYour Name 			sap_ctx->disabled_mcs13 = false;
1856*5113495bSYour Name 		}
1857*5113495bSYour Name 	}
1858*5113495bSYour Name 
1859*5113495bSYour Name 	return status;
1860*5113495bSYour Name }
1861*5113495bSYour Name 
1862*5113495bSYour Name /**
1863*5113495bSYour Name  * sap_goto_stopping() - Processing of SAP FSM stopping state
1864*5113495bSYour Name  * @sap_ctx: pointer to sap Context
1865*5113495bSYour Name  *
1866*5113495bSYour Name  * Return: QDF_STATUS code associated with performing the operation
1867*5113495bSYour Name  */
sap_goto_stopping(struct sap_context * sap_ctx)1868*5113495bSYour Name static QDF_STATUS sap_goto_stopping(struct sap_context *sap_ctx)
1869*5113495bSYour Name {
1870*5113495bSYour Name 	QDF_STATUS status;
1871*5113495bSYour Name 	struct mac_context *mac_ctx;
1872*5113495bSYour Name 
1873*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
1874*5113495bSYour Name 	if (!mac_ctx) {
1875*5113495bSYour Name 		/* we have a serious problem */
1876*5113495bSYour Name 		sap_err("Invalid MAC context");
1877*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
1878*5113495bSYour Name 	}
1879*5113495bSYour Name 
1880*5113495bSYour Name 	sap_update_mcs_rate(sap_ctx, false);
1881*5113495bSYour Name 	qdf_mem_zero(&sap_ctx->sap_bss_cfg, sizeof(sap_ctx->sap_bss_cfg));
1882*5113495bSYour Name 
1883*5113495bSYour Name 	status = sme_roam_stop_bss(MAC_HANDLE(mac_ctx), sap_ctx->sessionId);
1884*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
1885*5113495bSYour Name 		sap_err("Calling sme_roam_stop_bss status = %d", status);
1886*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1887*5113495bSYour Name 	}
1888*5113495bSYour Name 
1889*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1890*5113495bSYour Name }
1891*5113495bSYour Name 
1892*5113495bSYour Name /**
1893*5113495bSYour Name  * sap_goto_init() - Function for setting the SAP FSM to init state
1894*5113495bSYour Name  * @sap_ctx: pointer to sap context
1895*5113495bSYour Name  *
1896*5113495bSYour Name  * Return: QDF_STATUS code associated with performing the operation
1897*5113495bSYour Name  */
sap_goto_init(struct sap_context * sap_ctx)1898*5113495bSYour Name static QDF_STATUS sap_goto_init(struct sap_context *sap_ctx)
1899*5113495bSYour Name {
1900*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
1901*5113495bSYour Name 	struct sap_sm_event sap_event;
1902*5113495bSYour Name 	/* Processing has to be coded */
1903*5113495bSYour Name 
1904*5113495bSYour Name 	/*
1905*5113495bSYour Name 	 * Clean up stations from TL etc as AP BSS is shut down
1906*5113495bSYour Name 	 * then set event
1907*5113495bSYour Name 	 */
1908*5113495bSYour Name 
1909*5113495bSYour Name 	/* hardcoded event */
1910*5113495bSYour Name 	sap_event.event = eSAP_MAC_READY_FOR_CONNECTIONS;
1911*5113495bSYour Name 	sap_event.params = 0;
1912*5113495bSYour Name 	sap_event.u1 = 0;
1913*5113495bSYour Name 	sap_event.u2 = 0;
1914*5113495bSYour Name 	/* Handle event */
1915*5113495bSYour Name 	qdf_status = sap_fsm(sap_ctx, &sap_event);
1916*5113495bSYour Name 
1917*5113495bSYour Name 	return qdf_status;
1918*5113495bSYour Name }
1919*5113495bSYour Name 
1920*5113495bSYour Name #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1921*5113495bSYour Name /**
1922*5113495bSYour Name  * sap_handle_acs_scan_event() - handle acs scan event for SAP
1923*5113495bSYour Name  * @sap_context: ptSapContext
1924*5113495bSYour Name  * @sap_event: struct sap_event
1925*5113495bSYour Name  * @status: status of acs scan
1926*5113495bSYour Name  *
1927*5113495bSYour Name  * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event.
1928*5113495bSYour Name  *
1929*5113495bSYour Name  * Return: void
1930*5113495bSYour Name  */
sap_handle_acs_scan_event(struct sap_context * sap_context,struct sap_event * sap_event,eSapStatus status)1931*5113495bSYour Name static void sap_handle_acs_scan_event(struct sap_context *sap_context,
1932*5113495bSYour Name 		struct sap_event *sap_event, eSapStatus status)
1933*5113495bSYour Name {
1934*5113495bSYour Name 	sap_event->sapHddEventCode = eSAP_ACS_SCAN_SUCCESS_EVENT;
1935*5113495bSYour Name 	sap_event->sapevt.sap_acs_scan_comp.status = status;
1936*5113495bSYour Name 	sap_event->sapevt.sap_acs_scan_comp.num_of_channels =
1937*5113495bSYour Name 			sap_context->num_of_channel;
1938*5113495bSYour Name 	sap_event->sapevt.sap_acs_scan_comp.freq_list =
1939*5113495bSYour Name 			sap_context->freq_list;
1940*5113495bSYour Name }
1941*5113495bSYour Name #else
sap_handle_acs_scan_event(struct sap_context * sap_context,struct sap_event * sap_event,eSapStatus status)1942*5113495bSYour Name static void sap_handle_acs_scan_event(struct sap_context *sap_context,
1943*5113495bSYour Name 		struct sap_event *sap_event, eSapStatus status)
1944*5113495bSYour Name {
1945*5113495bSYour Name }
1946*5113495bSYour Name #endif
1947*5113495bSYour Name 
1948*5113495bSYour Name #define DH_OUI_TYPE      "\x20"
1949*5113495bSYour Name #define DH_OUI_TYPE_SIZE (1)
1950*5113495bSYour Name /**
1951*5113495bSYour Name  * sap_fill_owe_ie_in_assoc_ind() - Fill OWE IE in assoc indication
1952*5113495bSYour Name  * Function to fill OWE IE in assoc indication
1953*5113495bSYour Name  * @assoc_ind: SAP STA association indication
1954*5113495bSYour Name  * @sme_assoc_ind: SME association indication
1955*5113495bSYour Name  * @reassoc: True if it is reassoc frame
1956*5113495bSYour Name  *
1957*5113495bSYour Name  * This function is to get OWE IEs (RSN IE, DH IE etc) from assoc request
1958*5113495bSYour Name  * and fill them in association indication.
1959*5113495bSYour Name  *
1960*5113495bSYour Name  * Return: true for success and false for failure
1961*5113495bSYour Name  */
sap_fill_owe_ie_in_assoc_ind(tSap_StationAssocIndication * assoc_ind,struct assoc_ind * sme_assoc_ind,bool reassoc)1962*5113495bSYour Name static bool sap_fill_owe_ie_in_assoc_ind(tSap_StationAssocIndication *assoc_ind,
1963*5113495bSYour Name 					 struct assoc_ind *sme_assoc_ind,
1964*5113495bSYour Name 					 bool reassoc)
1965*5113495bSYour Name {
1966*5113495bSYour Name 	uint32_t owe_ie_len, rsn_ie_len, dh_ie_len;
1967*5113495bSYour Name 	const uint8_t *rsn_ie, *dh_ie;
1968*5113495bSYour Name 	uint8_t *assoc_req_ie;
1969*5113495bSYour Name 	uint16_t assoc_req_ie_len;
1970*5113495bSYour Name 
1971*5113495bSYour Name 	if (reassoc) {
1972*5113495bSYour Name 		if (assoc_ind->assocReqLength < WLAN_REASSOC_REQ_IES_OFFSET) {
1973*5113495bSYour Name 			sap_err("Invalid reassoc req");
1974*5113495bSYour Name 			return false;
1975*5113495bSYour Name 		}
1976*5113495bSYour Name 
1977*5113495bSYour Name 		assoc_req_ie = assoc_ind->assocReqPtr +
1978*5113495bSYour Name 			       WLAN_REASSOC_REQ_IES_OFFSET;
1979*5113495bSYour Name 		assoc_req_ie_len = assoc_ind->assocReqLength -
1980*5113495bSYour Name 				   WLAN_REASSOC_REQ_IES_OFFSET;
1981*5113495bSYour Name 	} else {
1982*5113495bSYour Name 		if (assoc_ind->assocReqLength < WLAN_ASSOC_REQ_IES_OFFSET) {
1983*5113495bSYour Name 			sap_err("Invalid assoc req");
1984*5113495bSYour Name 			return false;
1985*5113495bSYour Name 		}
1986*5113495bSYour Name 
1987*5113495bSYour Name 		assoc_req_ie = assoc_ind->assocReqPtr +
1988*5113495bSYour Name 			       WLAN_ASSOC_REQ_IES_OFFSET;
1989*5113495bSYour Name 		assoc_req_ie_len = assoc_ind->assocReqLength -
1990*5113495bSYour Name 				   WLAN_ASSOC_REQ_IES_OFFSET;
1991*5113495bSYour Name 	}
1992*5113495bSYour Name 	rsn_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_RSN,
1993*5113495bSYour Name 					  assoc_req_ie, assoc_req_ie_len);
1994*5113495bSYour Name 	if (!rsn_ie) {
1995*5113495bSYour Name 		sap_err("RSN IE is not present");
1996*5113495bSYour Name 		return false;
1997*5113495bSYour Name 	}
1998*5113495bSYour Name 	rsn_ie_len = rsn_ie[1] + 2;
1999*5113495bSYour Name 	if (rsn_ie_len < DOT11F_IE_RSN_MIN_LEN ||
2000*5113495bSYour Name 	    rsn_ie_len > DOT11F_IE_RSN_MAX_LEN) {
2001*5113495bSYour Name 		sap_err("Invalid RSN IE len %d", rsn_ie_len);
2002*5113495bSYour Name 		return false;
2003*5113495bSYour Name 	}
2004*5113495bSYour Name 
2005*5113495bSYour Name 	dh_ie = wlan_get_ext_ie_ptr_from_ext_id(DH_OUI_TYPE, DH_OUI_TYPE_SIZE,
2006*5113495bSYour Name 						assoc_req_ie, assoc_req_ie_len);
2007*5113495bSYour Name 	if (!dh_ie) {
2008*5113495bSYour Name 		sap_err("DH IE is not present");
2009*5113495bSYour Name 		return false;
2010*5113495bSYour Name 	}
2011*5113495bSYour Name 	dh_ie_len = dh_ie[1] + 2;
2012*5113495bSYour Name 	if (dh_ie_len < DOT11F_IE_DH_PARAMETER_ELEMENT_MIN_LEN ||
2013*5113495bSYour Name 	    dh_ie_len > DOT11F_IE_DH_PARAMETER_ELEMENT_MAX_LEN) {
2014*5113495bSYour Name 		sap_err("Invalid DH IE len %d", dh_ie_len);
2015*5113495bSYour Name 		return false;
2016*5113495bSYour Name 	}
2017*5113495bSYour Name 
2018*5113495bSYour Name 	sap_debug("rsn_ie_len = %d, dh_ie_len = %d", rsn_ie_len, dh_ie_len);
2019*5113495bSYour Name 
2020*5113495bSYour Name 	owe_ie_len = rsn_ie_len + dh_ie_len;
2021*5113495bSYour Name 	assoc_ind->owe_ie = qdf_mem_malloc(owe_ie_len);
2022*5113495bSYour Name 	if (!assoc_ind->owe_ie)
2023*5113495bSYour Name 		return false;
2024*5113495bSYour Name 
2025*5113495bSYour Name 	qdf_mem_copy(assoc_ind->owe_ie, rsn_ie, rsn_ie_len);
2026*5113495bSYour Name 	qdf_mem_copy(assoc_ind->owe_ie + rsn_ie_len, dh_ie, dh_ie_len);
2027*5113495bSYour Name 	assoc_ind->owe_ie_len = owe_ie_len;
2028*5113495bSYour Name 
2029*5113495bSYour Name 	return true;
2030*5113495bSYour Name }
2031*5113495bSYour Name 
2032*5113495bSYour Name /**
2033*5113495bSYour Name  * sap_save_owe_pending_assoc_ind() - Save pending assoc indication
2034*5113495bSYour Name  * Function to save pending assoc indication in SAP context
2035*5113495bSYour Name  * @sap_ctx: SAP context
2036*5113495bSYour Name  * @sme_assoc_ind: SME association indication
2037*5113495bSYour Name  *
2038*5113495bSYour Name  * This function is to save pending assoc indication in linked list
2039*5113495bSYour Name  * in SAP context.
2040*5113495bSYour Name  *
2041*5113495bSYour Name  * Return: true for success and false for failure
2042*5113495bSYour Name  */
sap_save_owe_pending_assoc_ind(struct sap_context * sap_ctx,struct assoc_ind * sme_assoc_ind)2043*5113495bSYour Name static bool sap_save_owe_pending_assoc_ind(struct sap_context *sap_ctx,
2044*5113495bSYour Name 				       struct assoc_ind *sme_assoc_ind)
2045*5113495bSYour Name {
2046*5113495bSYour Name 	struct owe_assoc_ind *assoc_ind;
2047*5113495bSYour Name 	QDF_STATUS status;
2048*5113495bSYour Name 
2049*5113495bSYour Name 	assoc_ind = qdf_mem_malloc(sizeof(*assoc_ind));
2050*5113495bSYour Name 	if (!assoc_ind)
2051*5113495bSYour Name 		return false;
2052*5113495bSYour Name 	assoc_ind->assoc_ind = sme_assoc_ind;
2053*5113495bSYour Name 	status = qdf_list_insert_back(&sap_ctx->owe_pending_assoc_ind_list,
2054*5113495bSYour Name 				      &assoc_ind->node);
2055*5113495bSYour Name 	if (QDF_STATUS_SUCCESS != status) {
2056*5113495bSYour Name 		qdf_mem_free(assoc_ind);
2057*5113495bSYour Name 		return false;
2058*5113495bSYour Name 	}
2059*5113495bSYour Name 
2060*5113495bSYour Name 	return true;
2061*5113495bSYour Name }
2062*5113495bSYour Name 
sap_save_ft_pending_assoc_ind(struct sap_context * sap_ctx,struct assoc_ind * sme_assoc_ind)2063*5113495bSYour Name static bool sap_save_ft_pending_assoc_ind(struct sap_context *sap_ctx,
2064*5113495bSYour Name 					  struct assoc_ind *sme_assoc_ind)
2065*5113495bSYour Name {
2066*5113495bSYour Name 	struct ft_assoc_ind *assoc_ind;
2067*5113495bSYour Name 	QDF_STATUS status;
2068*5113495bSYour Name 
2069*5113495bSYour Name 	assoc_ind = qdf_mem_malloc(sizeof(*assoc_ind));
2070*5113495bSYour Name 	if (!assoc_ind)
2071*5113495bSYour Name 		return false;
2072*5113495bSYour Name 	assoc_ind->assoc_ind = sme_assoc_ind;
2073*5113495bSYour Name 	status = qdf_list_insert_back(&sap_ctx->ft_pending_assoc_ind_list,
2074*5113495bSYour Name 				      &assoc_ind->node);
2075*5113495bSYour Name 	if (QDF_STATUS_SUCCESS != status) {
2076*5113495bSYour Name 		qdf_mem_free(assoc_ind);
2077*5113495bSYour Name 		return false;
2078*5113495bSYour Name 	}
2079*5113495bSYour Name 	qdf_event_set(&sap_ctx->ft_pending_event);
2080*5113495bSYour Name 
2081*5113495bSYour Name 	return true;
2082*5113495bSYour Name }
2083*5113495bSYour Name 
2084*5113495bSYour Name #ifdef FEATURE_RADAR_HISTORY
2085*5113495bSYour Name /* Last cac result */
2086*5113495bSYour Name static struct prev_cac_result prev_cac_history;
2087*5113495bSYour Name 
2088*5113495bSYour Name /**
2089*5113495bSYour Name  * sap_update_cac_history() - record SAP Radar found result in last
2090*5113495bSYour Name  * "active" or CAC period
2091*5113495bSYour Name  * @mac_ctx: mac context
2092*5113495bSYour Name  * @sap_ctx: sap context
2093*5113495bSYour Name  * @event_id: sap event
2094*5113495bSYour Name  *
2095*5113495bSYour Name  *  The function is to save the dfs channel information
2096*5113495bSYour Name  *  If SAP has been "active" or "CAC" on DFS channel for 60s and
2097*5113495bSYour Name  *  no found radar event.
2098*5113495bSYour Name  *
2099*5113495bSYour Name  * Return: void
2100*5113495bSYour Name  */
2101*5113495bSYour Name static void
sap_update_cac_history(struct mac_context * mac_ctx,struct sap_context * sap_ctx,eSapHddEvent event_id)2102*5113495bSYour Name sap_update_cac_history(struct mac_context *mac_ctx,
2103*5113495bSYour Name 		       struct sap_context *sap_ctx,
2104*5113495bSYour Name 		       eSapHddEvent event_id)
2105*5113495bSYour Name {
2106*5113495bSYour Name 	struct prev_cac_result *cac_result = &sap_ctx->cac_result;
2107*5113495bSYour Name 
2108*5113495bSYour Name 	switch (event_id) {
2109*5113495bSYour Name 	case eSAP_START_BSS_EVENT:
2110*5113495bSYour Name 	case eSAP_CHANNEL_CHANGE_RESP:
2111*5113495bSYour Name 	case eSAP_DFS_CAC_START:
2112*5113495bSYour Name 		if (sap_operating_on_dfs(mac_ctx, sap_ctx)) {
2113*5113495bSYour Name 			qdf_mem_zero(cac_result,
2114*5113495bSYour Name 				     sizeof(struct prev_cac_result));
2115*5113495bSYour Name 			if (!sap_ctx->ch_params.mhz_freq_seg0) {
2116*5113495bSYour Name 				sap_debug("invalid seq0");
2117*5113495bSYour Name 				return;
2118*5113495bSYour Name 			}
2119*5113495bSYour Name 			cac_result->ap_start_time =
2120*5113495bSYour Name 				qdf_get_monotonic_boottime();
2121*5113495bSYour Name 			cac_result->cac_ch_param = sap_ctx->ch_params;
2122*5113495bSYour Name 			sap_debug("ap start(CAC) (%d, %d) bw %d",
2123*5113495bSYour Name 				  cac_result->cac_ch_param.mhz_freq_seg0,
2124*5113495bSYour Name 				  cac_result->cac_ch_param.mhz_freq_seg1,
2125*5113495bSYour Name 				  cac_result->cac_ch_param.ch_width);
2126*5113495bSYour Name 		}
2127*5113495bSYour Name 		break;
2128*5113495bSYour Name 	case eSAP_DFS_RADAR_DETECT:
2129*5113495bSYour Name 		qdf_mem_zero(cac_result,
2130*5113495bSYour Name 			     sizeof(struct prev_cac_result));
2131*5113495bSYour Name 		break;
2132*5113495bSYour Name 	case eSAP_DFS_CAC_END:
2133*5113495bSYour Name 	case eSAP_STOP_BSS_EVENT:
2134*5113495bSYour Name 		if (cac_result->ap_start_time) {
2135*5113495bSYour Name 			uint64_t diff_ms;
2136*5113495bSYour Name 
2137*5113495bSYour Name 			cac_result->ap_end_time =
2138*5113495bSYour Name 				qdf_get_monotonic_boottime();
2139*5113495bSYour Name 			diff_ms = qdf_do_div(cac_result->ap_end_time -
2140*5113495bSYour Name 				     cac_result->ap_start_time, 1000);
2141*5113495bSYour Name 			if (diff_ms < DEFAULT_CAC_TIMEOUT - 5000) {
2142*5113495bSYour Name 				if (event_id == eSAP_STOP_BSS_EVENT)
2143*5113495bSYour Name 					qdf_mem_zero(
2144*5113495bSYour Name 					cac_result,
2145*5113495bSYour Name 					sizeof(struct prev_cac_result));
2146*5113495bSYour Name 				sap_debug("ap cac dur %llu ms", diff_ms);
2147*5113495bSYour Name 				break;
2148*5113495bSYour Name 			}
2149*5113495bSYour Name 			cac_result->cac_complete = true;
2150*5113495bSYour Name 			qdf_mem_copy(&prev_cac_history, cac_result,
2151*5113495bSYour Name 				     sizeof(struct prev_cac_result));
2152*5113495bSYour Name 			sap_debug("ap cac saved %llu ms %llu (%d, %d) bw %d",
2153*5113495bSYour Name 				  diff_ms,
2154*5113495bSYour Name 				  cac_result->ap_end_time,
2155*5113495bSYour Name 				  cac_result->cac_ch_param.mhz_freq_seg0,
2156*5113495bSYour Name 				  cac_result->cac_ch_param.mhz_freq_seg1,
2157*5113495bSYour Name 				  cac_result->cac_ch_param.ch_width);
2158*5113495bSYour Name 			if (event_id == eSAP_STOP_BSS_EVENT)
2159*5113495bSYour Name 				qdf_mem_zero(cac_result,
2160*5113495bSYour Name 					     sizeof(struct prev_cac_result));
2161*5113495bSYour Name 		}
2162*5113495bSYour Name 		break;
2163*5113495bSYour Name 	default:
2164*5113495bSYour Name 		break;
2165*5113495bSYour Name 	}
2166*5113495bSYour Name }
2167*5113495bSYour Name 
2168*5113495bSYour Name /**
2169*5113495bSYour Name  * find_ch_freq_in_radar_hist() - check channel frequency existing
2170*5113495bSYour Name  * in radar history buffer
2171*5113495bSYour Name  * @radar_result: radar history buffer
2172*5113495bSYour Name  * @count: radar history element number
2173*5113495bSYour Name  * @ch_freq: channel frequency
2174*5113495bSYour Name  *
2175*5113495bSYour Name  * Return: bool
2176*5113495bSYour Name  */
2177*5113495bSYour Name static
find_ch_freq_in_radar_hist(struct dfs_radar_history * radar_result,uint32_t count,uint16_t ch_freq)2178*5113495bSYour Name bool find_ch_freq_in_radar_hist(struct dfs_radar_history *radar_result,
2179*5113495bSYour Name 				uint32_t count, uint16_t ch_freq)
2180*5113495bSYour Name {
2181*5113495bSYour Name 	while (count) {
2182*5113495bSYour Name 		if (radar_result->ch_freq == ch_freq)
2183*5113495bSYour Name 			return true;
2184*5113495bSYour Name 		radar_result++;
2185*5113495bSYour Name 		count--;
2186*5113495bSYour Name 	}
2187*5113495bSYour Name 
2188*5113495bSYour Name 	return false;
2189*5113495bSYour Name }
2190*5113495bSYour Name 
2191*5113495bSYour Name /**
2192*5113495bSYour Name  * sap_append_cac_history() - Add CAC history to list
2193*5113495bSYour Name  * @mac_ctx: pointer to mac context
2194*5113495bSYour Name  * @radar_result: radar history buffer
2195*5113495bSYour Name  * @idx: current radar history element number
2196*5113495bSYour Name  * @max_elems: max elements number of radar history buffer.
2197*5113495bSYour Name  *
2198*5113495bSYour Name  * This function is to add the CAC history to radar history list.
2199*5113495bSYour Name  *
2200*5113495bSYour Name  * Return: void
2201*5113495bSYour Name  */
2202*5113495bSYour Name static
sap_append_cac_history(struct mac_context * mac_ctx,struct dfs_radar_history * radar_result,uint32_t * idx,uint32_t max_elems)2203*5113495bSYour Name void sap_append_cac_history(struct mac_context *mac_ctx,
2204*5113495bSYour Name 			    struct dfs_radar_history *radar_result,
2205*5113495bSYour Name 			    uint32_t *idx, uint32_t max_elems)
2206*5113495bSYour Name {
2207*5113495bSYour Name 	struct prev_cac_result *cac_result = &prev_cac_history;
2208*5113495bSYour Name 	struct ch_params ch_param = cac_result->cac_ch_param;
2209*5113495bSYour Name 	uint32_t count = *idx;
2210*5113495bSYour Name 
2211*5113495bSYour Name 	if (!cac_result->cac_complete || !cac_result->ap_end_time) {
2212*5113495bSYour Name 		sap_debug("cac hist empty");
2213*5113495bSYour Name 		return;
2214*5113495bSYour Name 	}
2215*5113495bSYour Name 
2216*5113495bSYour Name 	if (ch_param.ch_width <= CH_WIDTH_20MHZ) {
2217*5113495bSYour Name 		if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
2218*5113495bSYour Name 					     ch_param.mhz_freq_seg0) &&
2219*5113495bSYour Name 		    !find_ch_freq_in_radar_hist(radar_result, count,
2220*5113495bSYour Name 						ch_param.mhz_freq_seg0) &&
2221*5113495bSYour Name 		    *idx < max_elems) {
2222*5113495bSYour Name 			radar_result[*idx].ch_freq = ch_param.mhz_freq_seg0;
2223*5113495bSYour Name 			radar_result[*idx].time = cac_result->ap_end_time;
2224*5113495bSYour Name 			radar_result[*idx].radar_found = false;
2225*5113495bSYour Name 			sap_debug("radar hist[%d] freq %d time %llu no radar",
2226*5113495bSYour Name 				  *idx, ch_param.mhz_freq_seg0,
2227*5113495bSYour Name 				  cac_result->ap_end_time);
2228*5113495bSYour Name 			(*idx)++;
2229*5113495bSYour Name 		}
2230*5113495bSYour Name 	} else {
2231*5113495bSYour Name 		uint16_t chan_cfreq;
2232*5113495bSYour Name 		enum channel_state state;
2233*5113495bSYour Name 		const struct bonded_channel_freq *bonded_chan_ptr = NULL;
2234*5113495bSYour Name 
2235*5113495bSYour Name 		state = wlan_reg_get_5g_bonded_channel_and_state_for_pwrmode
2236*5113495bSYour Name 			(mac_ctx->pdev, ch_param.mhz_freq_seg0,
2237*5113495bSYour Name 			 ch_param.ch_width, &bonded_chan_ptr,
2238*5113495bSYour Name 			 REG_CURRENT_PWR_MODE, NO_SCHANS_PUNC);
2239*5113495bSYour Name 		if (!bonded_chan_ptr || state == CHANNEL_STATE_INVALID) {
2240*5113495bSYour Name 			sap_debug("invalid freq %d", ch_param.mhz_freq_seg0);
2241*5113495bSYour Name 			return;
2242*5113495bSYour Name 		}
2243*5113495bSYour Name 
2244*5113495bSYour Name 		chan_cfreq = bonded_chan_ptr->start_freq;
2245*5113495bSYour Name 		while (chan_cfreq <= bonded_chan_ptr->end_freq) {
2246*5113495bSYour Name 			state = wlan_reg_get_channel_state_for_pwrmode(
2247*5113495bSYour Name 					mac_ctx->pdev, chan_cfreq,
2248*5113495bSYour Name 					REG_CURRENT_PWR_MODE);
2249*5113495bSYour Name 			if (state == CHANNEL_STATE_INVALID) {
2250*5113495bSYour Name 				sap_debug("invalid ch freq %d",
2251*5113495bSYour Name 					  chan_cfreq);
2252*5113495bSYour Name 				chan_cfreq = chan_cfreq + 20;
2253*5113495bSYour Name 				continue;
2254*5113495bSYour Name 			}
2255*5113495bSYour Name 			if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
2256*5113495bSYour Name 						     chan_cfreq) &&
2257*5113495bSYour Name 			    !find_ch_freq_in_radar_hist(radar_result, count,
2258*5113495bSYour Name 							chan_cfreq) &&
2259*5113495bSYour Name 			    *idx < max_elems) {
2260*5113495bSYour Name 				radar_result[*idx].ch_freq = chan_cfreq;
2261*5113495bSYour Name 				radar_result[*idx].time =
2262*5113495bSYour Name 						cac_result->ap_end_time;
2263*5113495bSYour Name 				radar_result[*idx].radar_found = false;
2264*5113495bSYour Name 				sap_debug("radar hist[%d] freq %d time %llu no radar",
2265*5113495bSYour Name 					  *idx, chan_cfreq,
2266*5113495bSYour Name 					  cac_result->ap_end_time);
2267*5113495bSYour Name 				(*idx)++;
2268*5113495bSYour Name 			}
2269*5113495bSYour Name 			chan_cfreq = chan_cfreq + 20;
2270*5113495bSYour Name 		}
2271*5113495bSYour Name 	}
2272*5113495bSYour Name }
2273*5113495bSYour Name 
2274*5113495bSYour Name QDF_STATUS
wlansap_query_radar_history(mac_handle_t mac_handle,struct dfs_radar_history ** radar_history,uint32_t * count)2275*5113495bSYour Name wlansap_query_radar_history(mac_handle_t mac_handle,
2276*5113495bSYour Name 			    struct dfs_radar_history **radar_history,
2277*5113495bSYour Name 			    uint32_t *count)
2278*5113495bSYour Name {
2279*5113495bSYour Name 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
2280*5113495bSYour Name 	struct dfsreq_nolinfo *nol_info;
2281*5113495bSYour Name 	uint32_t i;
2282*5113495bSYour Name 	uint32_t hist_count;
2283*5113495bSYour Name 	struct dfs_radar_history *radar_result;
2284*5113495bSYour Name 
2285*5113495bSYour Name 	nol_info = qdf_mem_malloc(sizeof(struct dfsreq_nolinfo));
2286*5113495bSYour Name 	if (!nol_info)
2287*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2288*5113495bSYour Name 
2289*5113495bSYour Name 	ucfg_dfs_getnol(mac_ctx->pdev, nol_info);
2290*5113495bSYour Name 
2291*5113495bSYour Name 	hist_count = nol_info->dfs_ch_nchans + MAX_NUM_OF_CAC_HISTORY;
2292*5113495bSYour Name 	radar_result = qdf_mem_malloc(sizeof(struct dfs_radar_history) *
2293*5113495bSYour Name 					hist_count);
2294*5113495bSYour Name 	if (!radar_result) {
2295*5113495bSYour Name 		qdf_mem_free(nol_info);
2296*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2297*5113495bSYour Name 	}
2298*5113495bSYour Name 
2299*5113495bSYour Name 	for (i = 0; i < nol_info->dfs_ch_nchans && i < DFS_CHAN_MAX; i++) {
2300*5113495bSYour Name 		radar_result[i].ch_freq = nol_info->dfs_nol[i].nol_freq;
2301*5113495bSYour Name 		radar_result[i].time = nol_info->dfs_nol[i].nol_start_us;
2302*5113495bSYour Name 		radar_result[i].radar_found = true;
2303*5113495bSYour Name 		sap_debug("radar hist[%d] freq %d time %llu radar",
2304*5113495bSYour Name 			  i, nol_info->dfs_nol[i].nol_freq,
2305*5113495bSYour Name 			  nol_info->dfs_nol[i].nol_start_us);
2306*5113495bSYour Name 	}
2307*5113495bSYour Name 
2308*5113495bSYour Name 	sap_append_cac_history(mac_ctx, radar_result, &i, hist_count);
2309*5113495bSYour Name 	sap_debug("hist count %d cur %llu", i, qdf_get_monotonic_boottime());
2310*5113495bSYour Name 
2311*5113495bSYour Name 	*radar_history = radar_result;
2312*5113495bSYour Name 	*count = i;
2313*5113495bSYour Name 	qdf_mem_free(nol_info);
2314*5113495bSYour Name 
2315*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2316*5113495bSYour Name }
2317*5113495bSYour Name #else
2318*5113495bSYour Name static inline void
sap_update_cac_history(struct mac_context * mac_ctx,struct sap_context * sap_ctx,eSapHddEvent event_id)2319*5113495bSYour Name sap_update_cac_history(struct mac_context *mac_ctx,
2320*5113495bSYour Name 		       struct sap_context *sap_ctx,
2321*5113495bSYour Name 		       eSapHddEvent event_id)
2322*5113495bSYour Name {
2323*5113495bSYour Name }
2324*5113495bSYour Name #endif
2325*5113495bSYour Name 
2326*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
2327*5113495bSYour Name static inline
sap_check_peer_for_peer_null_mldaddr(struct wlan_objmgr_peer * peer)2328*5113495bSYour Name bool sap_check_peer_for_peer_null_mldaddr(struct wlan_objmgr_peer *peer)
2329*5113495bSYour Name {
2330*5113495bSYour Name 	if (qdf_is_macaddr_zero((struct qdf_mac_addr *)peer->mldaddr))
2331*5113495bSYour Name 		return true;
2332*5113495bSYour Name 	else
2333*5113495bSYour Name 		return false;
2334*5113495bSYour Name }
2335*5113495bSYour Name #else
2336*5113495bSYour Name static inline
sap_check_peer_for_peer_null_mldaddr(struct wlan_objmgr_peer * peer)2337*5113495bSYour Name bool sap_check_peer_for_peer_null_mldaddr(struct wlan_objmgr_peer *peer)
2338*5113495bSYour Name {
2339*5113495bSYour Name 	return true;
2340*5113495bSYour Name }
2341*5113495bSYour Name #endif
2342*5113495bSYour Name 
2343*5113495bSYour Name static
sap_populate_peer_assoc_info(struct mac_context * mac_ctx,struct csr_roam_info * csr_roaminfo,struct sap_event * sap_ap_event)2344*5113495bSYour Name QDF_STATUS sap_populate_peer_assoc_info(struct mac_context *mac_ctx,
2345*5113495bSYour Name 					struct csr_roam_info *csr_roaminfo,
2346*5113495bSYour Name 					struct sap_event *sap_ap_event)
2347*5113495bSYour Name {
2348*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
2349*5113495bSYour Name 	tSap_StationAssocReassocCompleteEvent *reassoc_complete;
2350*5113495bSYour Name 
2351*5113495bSYour Name 	reassoc_complete =
2352*5113495bSYour Name 		&sap_ap_event->sapevt.sapStationAssocReassocCompleteEvent;
2353*5113495bSYour Name 
2354*5113495bSYour Name 	peer = wlan_objmgr_get_peer_by_mac(mac_ctx->psoc,
2355*5113495bSYour Name 					   csr_roaminfo->peerMac.bytes,
2356*5113495bSYour Name 					   WLAN_LEGACY_MAC_ID);
2357*5113495bSYour Name 	if (!peer) {
2358*5113495bSYour Name 		sap_err("Peer object not found");
2359*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2360*5113495bSYour Name 	}
2361*5113495bSYour Name 
2362*5113495bSYour Name 	sap_debug("mlo peer assoc:%d", wlan_peer_mlme_is_assoc_peer(peer));
2363*5113495bSYour Name 
2364*5113495bSYour Name 	if (sap_check_peer_for_peer_null_mldaddr(peer) ||
2365*5113495bSYour Name 	    wlan_peer_mlme_is_assoc_peer(peer)) {
2366*5113495bSYour Name 		if (csr_roaminfo->assocReqLength < ASSOC_REQ_IE_OFFSET) {
2367*5113495bSYour Name 			sap_err("Invalid assoc request length:%d",
2368*5113495bSYour Name 				csr_roaminfo->assocReqLength);
2369*5113495bSYour Name 			wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
2370*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2371*5113495bSYour Name 		}
2372*5113495bSYour Name 		reassoc_complete->ies_len = (csr_roaminfo->assocReqLength -
2373*5113495bSYour Name 					    ASSOC_REQ_IE_OFFSET);
2374*5113495bSYour Name 		reassoc_complete->ies = (csr_roaminfo->assocReqPtr +
2375*5113495bSYour Name 					 ASSOC_REQ_IE_OFFSET);
2376*5113495bSYour Name 		/* skip current AP address in reassoc frame */
2377*5113495bSYour Name 		if (csr_roaminfo->fReassocReq) {
2378*5113495bSYour Name 			reassoc_complete->ies_len -= QDF_MAC_ADDR_SIZE;
2379*5113495bSYour Name 			reassoc_complete->ies += QDF_MAC_ADDR_SIZE;
2380*5113495bSYour Name 		}
2381*5113495bSYour Name 	}
2382*5113495bSYour Name 
2383*5113495bSYour Name 	if (csr_roaminfo->addIELen) {
2384*5113495bSYour Name 		if (wlan_get_vendor_ie_ptr_from_oui(
2385*5113495bSYour Name 		    SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE,
2386*5113495bSYour Name 		    csr_roaminfo->paddIE, csr_roaminfo->addIELen)) {
2387*5113495bSYour Name 			reassoc_complete->staType = eSTA_TYPE_P2P_CLI;
2388*5113495bSYour Name 		} else {
2389*5113495bSYour Name 			reassoc_complete->staType = eSTA_TYPE_INFRA;
2390*5113495bSYour Name 		}
2391*5113495bSYour Name 	}
2392*5113495bSYour Name 
2393*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
2394*5113495bSYour Name 
2395*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2396*5113495bSYour Name }
2397*5113495bSYour Name 
2398*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
2399*5113495bSYour Name static void
sap_reassoc_mld_copy(struct csr_roam_info * csr_roaminfo,tSap_StationAssocReassocCompleteEvent * reassoc_complete)2400*5113495bSYour Name sap_reassoc_mld_copy(struct csr_roam_info *csr_roaminfo,
2401*5113495bSYour Name 		     tSap_StationAssocReassocCompleteEvent *reassoc_complete)
2402*5113495bSYour Name {
2403*5113495bSYour Name 	qdf_copy_macaddr(&reassoc_complete->sta_mld,
2404*5113495bSYour Name 			 &csr_roaminfo->peer_mld);
2405*5113495bSYour Name 	sap_debug("reassoc_complete->staMld: " QDF_MAC_ADDR_FMT,
2406*5113495bSYour Name 		  QDF_MAC_ADDR_REF(reassoc_complete->sta_mld.bytes));
2407*5113495bSYour Name }
2408*5113495bSYour Name #else /* WLAN_FEATURE_11BE_MLO */
2409*5113495bSYour Name static inline void
sap_reassoc_mld_copy(struct csr_roam_info * csr_roaminfo,tSap_StationAssocReassocCompleteEvent * reassoc_complete)2410*5113495bSYour Name sap_reassoc_mld_copy(struct csr_roam_info *csr_roaminfo,
2411*5113495bSYour Name 		     tSap_StationAssocReassocCompleteEvent *reassoc_complete)
2412*5113495bSYour Name {
2413*5113495bSYour Name }
2414*5113495bSYour Name #endif /* WLAN_FEATURE_11BE_MLO */
2415*5113495bSYour Name 
2416*5113495bSYour Name /**
2417*5113495bSYour Name  * sap_signal_hdd_event() - send event notification
2418*5113495bSYour Name  * @sap_ctx: Sap Context
2419*5113495bSYour Name  * @csr_roaminfo: Pointer to CSR roam information
2420*5113495bSYour Name  * @sap_hddevent: SAP HDD event
2421*5113495bSYour Name  * @context: to pass the element for future support
2422*5113495bSYour Name  *
2423*5113495bSYour Name  * Function for HDD to send the event notification using callback
2424*5113495bSYour Name  *
2425*5113495bSYour Name  * Return: QDF_STATUS
2426*5113495bSYour Name  */
sap_signal_hdd_event(struct sap_context * sap_ctx,struct csr_roam_info * csr_roaminfo,eSapHddEvent sap_hddevent,void * context)2427*5113495bSYour Name QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx,
2428*5113495bSYour Name 		struct csr_roam_info *csr_roaminfo, eSapHddEvent sap_hddevent,
2429*5113495bSYour Name 		void *context)
2430*5113495bSYour Name {
2431*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
2432*5113495bSYour Name 	struct sap_event *sap_ap_event;
2433*5113495bSYour Name 	struct mac_context *mac_ctx;
2434*5113495bSYour Name 	struct oem_channel_info *chaninfo;
2435*5113495bSYour Name 	tSap_StationAssocIndication *assoc_ind;
2436*5113495bSYour Name 	tSap_StartBssCompleteEvent *bss_complete;
2437*5113495bSYour Name 	struct sap_ch_selected_s *acs_selected;
2438*5113495bSYour Name 	tSap_StationAssocReassocCompleteEvent *reassoc_complete;
2439*5113495bSYour Name 	tSap_StationDisassocCompleteEvent *disassoc_comp;
2440*5113495bSYour Name 	tSap_StationSetKeyCompleteEvent *key_complete;
2441*5113495bSYour Name 	tSap_StationMICFailureEvent *mic_failure;
2442*5113495bSYour Name 
2443*5113495bSYour Name 	/* Format the Start BSS Complete event to return... */
2444*5113495bSYour Name 	if (!sap_ctx->sap_event_cb)
2445*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2446*5113495bSYour Name 
2447*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
2448*5113495bSYour Name 	if (!mac_ctx) {
2449*5113495bSYour Name 		sap_err("Invalid MAC context");
2450*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2451*5113495bSYour Name 	}
2452*5113495bSYour Name 
2453*5113495bSYour Name 	sap_ap_event = qdf_mem_malloc(sizeof(*sap_ap_event));
2454*5113495bSYour Name 	if (!sap_ap_event)
2455*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2456*5113495bSYour Name 
2457*5113495bSYour Name 	sap_debug("SAP event callback event = %s",
2458*5113495bSYour Name 		  sap_hdd_event_to_string(sap_hddevent));
2459*5113495bSYour Name 
2460*5113495bSYour Name 	switch (sap_hddevent) {
2461*5113495bSYour Name 	case eSAP_STA_ASSOC_IND:
2462*5113495bSYour Name 		if (!csr_roaminfo) {
2463*5113495bSYour Name 			sap_debug("Invalid CSR Roam Info");
2464*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2465*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2466*5113495bSYour Name 		}
2467*5113495bSYour Name 		/*  TODO - Indicate the assoc request indication to OS */
2468*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_STA_ASSOC_IND;
2469*5113495bSYour Name 		assoc_ind = &sap_ap_event->sapevt.sapAssocIndication;
2470*5113495bSYour Name 
2471*5113495bSYour Name 		qdf_copy_macaddr(&assoc_ind->staMac, &csr_roaminfo->peerMac);
2472*5113495bSYour Name 		assoc_ind->staId = csr_roaminfo->staId;
2473*5113495bSYour Name 		assoc_ind->status = 0;
2474*5113495bSYour Name 		/* Required for indicating the frames to upper layer */
2475*5113495bSYour Name 		assoc_ind->assocReqLength = csr_roaminfo->assocReqLength;
2476*5113495bSYour Name 		assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr;
2477*5113495bSYour Name 		assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta;
2478*5113495bSYour Name 		assoc_ind->ecsa_capable = csr_roaminfo->ecsa_capable;
2479*5113495bSYour Name 		if (csr_roaminfo->owe_pending_assoc_ind) {
2480*5113495bSYour Name 			if (!sap_fill_owe_ie_in_assoc_ind(assoc_ind,
2481*5113495bSYour Name 					 csr_roaminfo->owe_pending_assoc_ind,
2482*5113495bSYour Name 					 csr_roaminfo->fReassocReq)) {
2483*5113495bSYour Name 				sap_err("Failed to fill OWE IE");
2484*5113495bSYour Name 				qdf_mem_free(csr_roaminfo->
2485*5113495bSYour Name 					     owe_pending_assoc_ind);
2486*5113495bSYour Name 				csr_roaminfo->owe_pending_assoc_ind = NULL;
2487*5113495bSYour Name 				qdf_mem_free(sap_ap_event);
2488*5113495bSYour Name 				return QDF_STATUS_E_INVAL;
2489*5113495bSYour Name 			}
2490*5113495bSYour Name 			if (!sap_save_owe_pending_assoc_ind(sap_ctx,
2491*5113495bSYour Name 					 csr_roaminfo->owe_pending_assoc_ind)) {
2492*5113495bSYour Name 				sap_err("Failed to save assoc ind");
2493*5113495bSYour Name 				qdf_mem_free(csr_roaminfo->
2494*5113495bSYour Name 					     owe_pending_assoc_ind);
2495*5113495bSYour Name 				csr_roaminfo->owe_pending_assoc_ind = NULL;
2496*5113495bSYour Name 				qdf_mem_free(sap_ap_event);
2497*5113495bSYour Name 				return QDF_STATUS_E_INVAL;
2498*5113495bSYour Name 			}
2499*5113495bSYour Name 			csr_roaminfo->owe_pending_assoc_ind = NULL;
2500*5113495bSYour Name 		}
2501*5113495bSYour Name 
2502*5113495bSYour Name 		if (csr_roaminfo->ft_pending_assoc_ind) {
2503*5113495bSYour Name 			if (!sap_save_ft_pending_assoc_ind(sap_ctx,
2504*5113495bSYour Name 			    csr_roaminfo->ft_pending_assoc_ind)) {
2505*5113495bSYour Name 				sap_err("Failed to save ft assoc ind");
2506*5113495bSYour Name 				qdf_mem_free(csr_roaminfo->ft_pending_assoc_ind);
2507*5113495bSYour Name 				csr_roaminfo->ft_pending_assoc_ind = NULL;
2508*5113495bSYour Name 				qdf_mem_free(sap_ap_event);
2509*5113495bSYour Name 				return QDF_STATUS_E_INVAL;
2510*5113495bSYour Name 			}
2511*5113495bSYour Name 			csr_roaminfo->ft_pending_assoc_ind = NULL;
2512*5113495bSYour Name 		}
2513*5113495bSYour Name 		break;
2514*5113495bSYour Name 	case eSAP_START_BSS_EVENT:
2515*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_START_BSS_EVENT;
2516*5113495bSYour Name 		bss_complete = &sap_ap_event->sapevt.sapStartBssCompleteEvent;
2517*5113495bSYour Name 
2518*5113495bSYour Name 		bss_complete->sessionId = sap_ctx->sessionId;
2519*5113495bSYour Name 		if (bss_complete->sessionId == WLAN_UMAC_VDEV_ID_MAX) {
2520*5113495bSYour Name 			sap_err("Invalid sessionId");
2521*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2522*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2523*5113495bSYour Name 		}
2524*5113495bSYour Name 
2525*5113495bSYour Name 		bss_complete->status = (eSapStatus) context;
2526*5113495bSYour Name 		bss_complete->staId = sap_ctx->sap_sta_id;
2527*5113495bSYour Name 
2528*5113495bSYour Name 		sap_debug("(eSAP_START_BSS_EVENT): staId = %d",
2529*5113495bSYour Name 			  bss_complete->staId);
2530*5113495bSYour Name 
2531*5113495bSYour Name 		bss_complete->operating_chan_freq = sap_ctx->chan_freq;
2532*5113495bSYour Name 		bss_complete->ch_width = sap_ctx->ch_params.ch_width;
2533*5113495bSYour Name 		if (QDF_IS_STATUS_SUCCESS(bss_complete->status)) {
2534*5113495bSYour Name 			sap_update_cac_history(mac_ctx, sap_ctx,
2535*5113495bSYour Name 					       sap_hddevent);
2536*5113495bSYour Name 			sap_update_mcs_rate(sap_ctx, true);
2537*5113495bSYour Name 		}
2538*5113495bSYour Name 		break;
2539*5113495bSYour Name 	case eSAP_DFS_CAC_START:
2540*5113495bSYour Name 	case eSAP_DFS_CAC_INTERRUPTED:
2541*5113495bSYour Name 	case eSAP_DFS_CAC_END:
2542*5113495bSYour Name 	case eSAP_DFS_RADAR_DETECT:
2543*5113495bSYour Name 	case eSAP_DFS_NO_AVAILABLE_CHANNEL:
2544*5113495bSYour Name 		sap_ap_event->sapHddEventCode = sap_hddevent;
2545*5113495bSYour Name 		sap_ap_event->sapevt.sapStopBssCompleteEvent.status =
2546*5113495bSYour Name 			(eSapStatus) context;
2547*5113495bSYour Name 		sap_update_cac_history(mac_ctx, sap_ctx,
2548*5113495bSYour Name 				       sap_hddevent);
2549*5113495bSYour Name 		break;
2550*5113495bSYour Name 	case eSAP_ACS_SCAN_SUCCESS_EVENT:
2551*5113495bSYour Name 		sap_handle_acs_scan_event(sap_ctx, sap_ap_event,
2552*5113495bSYour Name 					  (eSapStatus)context);
2553*5113495bSYour Name 		break;
2554*5113495bSYour Name 	case eSAP_ACS_CHANNEL_SELECTED:
2555*5113495bSYour Name 		sap_ap_event->sapHddEventCode = sap_hddevent;
2556*5113495bSYour Name 		acs_selected = &sap_ap_event->sapevt.sap_ch_selected;
2557*5113495bSYour Name 		if (eSAP_STATUS_SUCCESS == (eSapStatus)context) {
2558*5113495bSYour Name 			acs_selected->pri_ch_freq =
2559*5113495bSYour Name 						sap_ctx->acs_cfg->pri_ch_freq;
2560*5113495bSYour Name 			acs_selected->ht_sec_ch_freq =
2561*5113495bSYour Name 					sap_ctx->acs_cfg->ht_sec_ch_freq;
2562*5113495bSYour Name 			acs_selected->ch_width = sap_ctx->acs_cfg->ch_width;
2563*5113495bSYour Name 			acs_selected->vht_seg0_center_ch_freq =
2564*5113495bSYour Name 				sap_ctx->acs_cfg->vht_seg0_center_ch_freq;
2565*5113495bSYour Name 			acs_selected->vht_seg1_center_ch_freq =
2566*5113495bSYour Name 				sap_ctx->acs_cfg->vht_seg1_center_ch_freq;
2567*5113495bSYour Name 		} else if (eSAP_STATUS_FAILURE == (eSapStatus)context) {
2568*5113495bSYour Name 			acs_selected->pri_ch_freq = 0;
2569*5113495bSYour Name 		}
2570*5113495bSYour Name 		break;
2571*5113495bSYour Name 
2572*5113495bSYour Name 	case eSAP_STOP_BSS_EVENT:
2573*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_STOP_BSS_EVENT;
2574*5113495bSYour Name 		sap_ap_event->sapevt.sapStopBssCompleteEvent.status =
2575*5113495bSYour Name 			(eSapStatus) context;
2576*5113495bSYour Name 		break;
2577*5113495bSYour Name 
2578*5113495bSYour Name 	case eSAP_STA_ASSOC_EVENT:
2579*5113495bSYour Name 	case eSAP_STA_REASSOC_EVENT:
2580*5113495bSYour Name 
2581*5113495bSYour Name 		if (!csr_roaminfo) {
2582*5113495bSYour Name 			sap_err("Invalid CSR Roam Info");
2583*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2584*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2585*5113495bSYour Name 		}
2586*5113495bSYour Name 		if (sap_ctx->fsm_state == SAP_STOPPING) {
2587*5113495bSYour Name 			sap_err("SAP is stopping, not able to handle any incoming (re)assoc req");
2588*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2589*5113495bSYour Name 			return QDF_STATUS_E_ABORTED;
2590*5113495bSYour Name 		}
2591*5113495bSYour Name 
2592*5113495bSYour Name 		qdf_status = sap_populate_peer_assoc_info(mac_ctx, csr_roaminfo,
2593*5113495bSYour Name 							  sap_ap_event);
2594*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
2595*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2596*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2597*5113495bSYour Name 		}
2598*5113495bSYour Name 
2599*5113495bSYour Name 		reassoc_complete =
2600*5113495bSYour Name 		    &sap_ap_event->sapevt.sapStationAssocReassocCompleteEvent;
2601*5113495bSYour Name 
2602*5113495bSYour Name 		if (csr_roaminfo->fReassocReq)
2603*5113495bSYour Name 			sap_ap_event->sapHddEventCode = eSAP_STA_REASSOC_EVENT;
2604*5113495bSYour Name 		else
2605*5113495bSYour Name 			sap_ap_event->sapHddEventCode = eSAP_STA_ASSOC_EVENT;
2606*5113495bSYour Name 
2607*5113495bSYour Name 		qdf_copy_macaddr(&reassoc_complete->staMac,
2608*5113495bSYour Name 				 &csr_roaminfo->peerMac);
2609*5113495bSYour Name 		sap_reassoc_mld_copy(csr_roaminfo, reassoc_complete);
2610*5113495bSYour Name 		reassoc_complete->staId = csr_roaminfo->staId;
2611*5113495bSYour Name 		reassoc_complete->status_code = csr_roaminfo->status_code;
2612*5113495bSYour Name 
2613*5113495bSYour Name 		/* also fill up the channel info from the csr_roamInfo */
2614*5113495bSYour Name 		chaninfo = &reassoc_complete->chan_info;
2615*5113495bSYour Name 
2616*5113495bSYour Name 		chaninfo->mhz = csr_roaminfo->chan_info.mhz;
2617*5113495bSYour Name 		chaninfo->info = csr_roaminfo->chan_info.info;
2618*5113495bSYour Name 		chaninfo->band_center_freq1 =
2619*5113495bSYour Name 			csr_roaminfo->chan_info.band_center_freq1;
2620*5113495bSYour Name 		chaninfo->band_center_freq2 =
2621*5113495bSYour Name 			csr_roaminfo->chan_info.band_center_freq2;
2622*5113495bSYour Name 		chaninfo->reg_info_1 =
2623*5113495bSYour Name 			csr_roaminfo->chan_info.reg_info_1;
2624*5113495bSYour Name 		chaninfo->reg_info_2 =
2625*5113495bSYour Name 			csr_roaminfo->chan_info.reg_info_2;
2626*5113495bSYour Name 		chaninfo->nss = csr_roaminfo->chan_info.nss;
2627*5113495bSYour Name 		chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags;
2628*5113495bSYour Name 
2629*5113495bSYour Name 		reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta;
2630*5113495bSYour Name 		reassoc_complete->status = (eSapStatus) context;
2631*5113495bSYour Name 		reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap;
2632*5113495bSYour Name 		reassoc_complete->ampdu = csr_roaminfo->ampdu;
2633*5113495bSYour Name 		reassoc_complete->sgi_enable = csr_roaminfo->sgi_enable;
2634*5113495bSYour Name 		reassoc_complete->tx_stbc = csr_roaminfo->tx_stbc;
2635*5113495bSYour Name 		reassoc_complete->rx_stbc = csr_roaminfo->rx_stbc;
2636*5113495bSYour Name 		reassoc_complete->ch_width = csr_roaminfo->ch_width;
2637*5113495bSYour Name 		reassoc_complete->mode = csr_roaminfo->mode;
2638*5113495bSYour Name 		reassoc_complete->max_supp_idx = csr_roaminfo->max_supp_idx;
2639*5113495bSYour Name 		reassoc_complete->max_ext_idx = csr_roaminfo->max_ext_idx;
2640*5113495bSYour Name 		reassoc_complete->max_mcs_idx = csr_roaminfo->max_mcs_idx;
2641*5113495bSYour Name 		reassoc_complete->max_real_mcs_idx =
2642*5113495bSYour Name 						csr_roaminfo->max_real_mcs_idx;
2643*5113495bSYour Name 		reassoc_complete->rx_mcs_map = csr_roaminfo->rx_mcs_map;
2644*5113495bSYour Name 		reassoc_complete->tx_mcs_map = csr_roaminfo->tx_mcs_map;
2645*5113495bSYour Name 		reassoc_complete->ecsa_capable = csr_roaminfo->ecsa_capable;
2646*5113495bSYour Name 		reassoc_complete->ext_cap = csr_roaminfo->ext_cap;
2647*5113495bSYour Name 		reassoc_complete->supported_band = csr_roaminfo->supported_band;
2648*5113495bSYour Name 		if (csr_roaminfo->ht_caps.present)
2649*5113495bSYour Name 			reassoc_complete->ht_caps = csr_roaminfo->ht_caps;
2650*5113495bSYour Name 		if (csr_roaminfo->vht_caps.present)
2651*5113495bSYour Name 			reassoc_complete->vht_caps = csr_roaminfo->vht_caps;
2652*5113495bSYour Name 		reassoc_complete->he_caps_present =
2653*5113495bSYour Name 						csr_roaminfo->he_caps_present;
2654*5113495bSYour Name 		reassoc_complete->eht_caps_present =
2655*5113495bSYour Name 						csr_roaminfo->eht_caps_present;
2656*5113495bSYour Name 		reassoc_complete->capability_info =
2657*5113495bSYour Name 						csr_roaminfo->capability_info;
2658*5113495bSYour Name 
2659*5113495bSYour Name 		break;
2660*5113495bSYour Name 
2661*5113495bSYour Name 	case eSAP_STA_DISASSOC_EVENT:
2662*5113495bSYour Name 		if (!csr_roaminfo) {
2663*5113495bSYour Name 			sap_debug("Invalid CSR Roam Info");
2664*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2665*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2666*5113495bSYour Name 		}
2667*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
2668*5113495bSYour Name 		disassoc_comp =
2669*5113495bSYour Name 			&sap_ap_event->sapevt.sapStationDisassocCompleteEvent;
2670*5113495bSYour Name 
2671*5113495bSYour Name 		qdf_copy_macaddr(&disassoc_comp->staMac,
2672*5113495bSYour Name 				 &csr_roaminfo->peerMac);
2673*5113495bSYour Name 		disassoc_comp->staId = csr_roaminfo->staId;
2674*5113495bSYour Name 		if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED)
2675*5113495bSYour Name 			disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC;
2676*5113495bSYour Name 		else
2677*5113495bSYour Name 			disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC;
2678*5113495bSYour Name 
2679*5113495bSYour Name 		disassoc_comp->status_code = csr_roaminfo->status_code;
2680*5113495bSYour Name 		disassoc_comp->status = (eSapStatus) context;
2681*5113495bSYour Name 		disassoc_comp->rssi = csr_roaminfo->rssi;
2682*5113495bSYour Name 		disassoc_comp->rx_rate = csr_roaminfo->rx_rate;
2683*5113495bSYour Name 		disassoc_comp->tx_rate = csr_roaminfo->tx_rate;
2684*5113495bSYour Name 		disassoc_comp->rx_mc_bc_cnt = csr_roaminfo->rx_mc_bc_cnt;
2685*5113495bSYour Name 		disassoc_comp->rx_retry_cnt = csr_roaminfo->rx_retry_cnt;
2686*5113495bSYour Name 		disassoc_comp->reason_code = csr_roaminfo->disassoc_reason;
2687*5113495bSYour Name 		break;
2688*5113495bSYour Name 
2689*5113495bSYour Name 	case eSAP_STA_SET_KEY_EVENT:
2690*5113495bSYour Name 
2691*5113495bSYour Name 		if (!csr_roaminfo) {
2692*5113495bSYour Name 			sap_debug("Invalid CSR Roam Info");
2693*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2694*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2695*5113495bSYour Name 		}
2696*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_STA_SET_KEY_EVENT;
2697*5113495bSYour Name 		key_complete =
2698*5113495bSYour Name 			&sap_ap_event->sapevt.sapStationSetKeyCompleteEvent;
2699*5113495bSYour Name 		key_complete->status = (eSapStatus) context;
2700*5113495bSYour Name 		qdf_copy_macaddr(&key_complete->peerMacAddr,
2701*5113495bSYour Name 				 &csr_roaminfo->peerMac);
2702*5113495bSYour Name 		break;
2703*5113495bSYour Name 
2704*5113495bSYour Name 	case eSAP_STA_MIC_FAILURE_EVENT:
2705*5113495bSYour Name 
2706*5113495bSYour Name 		if (!csr_roaminfo) {
2707*5113495bSYour Name 			sap_debug("Invalid CSR Roam Info");
2708*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2709*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2710*5113495bSYour Name 		}
2711*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT;
2712*5113495bSYour Name 		mic_failure = &sap_ap_event->sapevt.sapStationMICFailureEvent;
2713*5113495bSYour Name 
2714*5113495bSYour Name 		qdf_mem_copy(&mic_failure->srcMacAddr,
2715*5113495bSYour Name 			     csr_roaminfo->u.pMICFailureInfo->srcMacAddr,
2716*5113495bSYour Name 			     sizeof(tSirMacAddr));
2717*5113495bSYour Name 		qdf_mem_copy(&mic_failure->staMac.bytes,
2718*5113495bSYour Name 			     csr_roaminfo->u.pMICFailureInfo->taMacAddr,
2719*5113495bSYour Name 			     sizeof(tSirMacAddr));
2720*5113495bSYour Name 		qdf_mem_copy(&mic_failure->dstMacAddr.bytes,
2721*5113495bSYour Name 			     csr_roaminfo->u.pMICFailureInfo->dstMacAddr,
2722*5113495bSYour Name 			     sizeof(tSirMacAddr));
2723*5113495bSYour Name 		mic_failure->multicast =
2724*5113495bSYour Name 			csr_roaminfo->u.pMICFailureInfo->multicast;
2725*5113495bSYour Name 		mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1;
2726*5113495bSYour Name 		mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId;
2727*5113495bSYour Name 		qdf_mem_copy(mic_failure->TSC,
2728*5113495bSYour Name 			     csr_roaminfo->u.pMICFailureInfo->TSC,
2729*5113495bSYour Name 			     SIR_CIPHER_SEQ_CTR_SIZE);
2730*5113495bSYour Name 		break;
2731*5113495bSYour Name 
2732*5113495bSYour Name 	case eSAP_WPS_PBC_PROBE_REQ_EVENT:
2733*5113495bSYour Name 
2734*5113495bSYour Name 		if (!csr_roaminfo) {
2735*5113495bSYour Name 			sap_debug("Invalid CSR Roam Info");
2736*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2737*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2738*5113495bSYour Name 		}
2739*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT;
2740*5113495bSYour Name 
2741*5113495bSYour Name 		qdf_mem_copy(&sap_ap_event->sapevt.sapPBCProbeReqEvent.
2742*5113495bSYour Name 			     WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq,
2743*5113495bSYour Name 			     sizeof(tSirWPSPBCProbeReq));
2744*5113495bSYour Name 		break;
2745*5113495bSYour Name 
2746*5113495bSYour Name 	case eSAP_DISCONNECT_ALL_P2P_CLIENT:
2747*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT;
2748*5113495bSYour Name 		sap_ap_event->sapevt.sapActionCnf.actionSendSuccess =
2749*5113495bSYour Name 			(eSapStatus) context;
2750*5113495bSYour Name 		break;
2751*5113495bSYour Name 
2752*5113495bSYour Name 	case eSAP_MAC_TRIG_STOP_BSS_EVENT:
2753*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT;
2754*5113495bSYour Name 		sap_ap_event->sapevt.sapActionCnf.actionSendSuccess =
2755*5113495bSYour Name 			(eSapStatus) context;
2756*5113495bSYour Name 		break;
2757*5113495bSYour Name 
2758*5113495bSYour Name 	case eSAP_UNKNOWN_STA_JOIN:
2759*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_UNKNOWN_STA_JOIN;
2760*5113495bSYour Name 		qdf_mem_copy((void *)sap_ap_event->sapevt.sapUnknownSTAJoin.
2761*5113495bSYour Name 			     macaddr.bytes, (void *) context,
2762*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
2763*5113495bSYour Name 		break;
2764*5113495bSYour Name 
2765*5113495bSYour Name 	case eSAP_MAX_ASSOC_EXCEEDED:
2766*5113495bSYour Name 
2767*5113495bSYour Name 		if (!csr_roaminfo) {
2768*5113495bSYour Name 			sap_debug("Invalid CSR Roam Info");
2769*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2770*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2771*5113495bSYour Name 		}
2772*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED;
2773*5113495bSYour Name 		qdf_copy_macaddr(&sap_ap_event->sapevt.
2774*5113495bSYour Name 				 sapMaxAssocExceeded.macaddr,
2775*5113495bSYour Name 				 &csr_roaminfo->peerMac);
2776*5113495bSYour Name 		break;
2777*5113495bSYour Name 
2778*5113495bSYour Name 	case eSAP_CHANNEL_CHANGE_EVENT:
2779*5113495bSYour Name 		/*
2780*5113495bSYour Name 		 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS
2781*5113495bSYour Name 		 * follows pri AP
2782*5113495bSYour Name 		 */
2783*5113495bSYour Name 		sap_ctx->acs_cfg->pri_ch_freq = sap_ctx->chan_freq;
2784*5113495bSYour Name 		sap_ctx->acs_cfg->ch_width =
2785*5113495bSYour Name 					sap_ctx->ch_params.ch_width;
2786*5113495bSYour Name 		sap_config_acs_result(MAC_HANDLE(mac_ctx), sap_ctx,
2787*5113495bSYour Name 				      sap_ctx->sec_ch_freq);
2788*5113495bSYour Name 
2789*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT;
2790*5113495bSYour Name 
2791*5113495bSYour Name 		acs_selected = &sap_ap_event->sapevt.sap_ch_selected;
2792*5113495bSYour Name 		acs_selected->pri_ch_freq = sap_ctx->chan_freq;
2793*5113495bSYour Name 		acs_selected->ht_sec_ch_freq = sap_ctx->sec_ch_freq;
2794*5113495bSYour Name 		acs_selected->ch_width =
2795*5113495bSYour Name 			sap_ctx->acs_cfg->ch_width;
2796*5113495bSYour Name 		acs_selected->vht_seg0_center_ch_freq =
2797*5113495bSYour Name 			sap_ctx->acs_cfg->vht_seg0_center_ch_freq;
2798*5113495bSYour Name 		acs_selected->vht_seg1_center_ch_freq =
2799*5113495bSYour Name 			sap_ctx->acs_cfg->vht_seg1_center_ch_freq;
2800*5113495bSYour Name 		break;
2801*5113495bSYour Name 
2802*5113495bSYour Name 	case eSAP_ECSA_CHANGE_CHAN_IND:
2803*5113495bSYour Name 
2804*5113495bSYour Name 		if (!csr_roaminfo) {
2805*5113495bSYour Name 			sap_debug("Invalid CSR Roam Info");
2806*5113495bSYour Name 			qdf_mem_free(sap_ap_event);
2807*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2808*5113495bSYour Name 		}
2809*5113495bSYour Name 		sap_debug("SAP event callback event = %s",
2810*5113495bSYour Name 			  "eSAP_ECSA_CHANGE_CHAN_IND");
2811*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND;
2812*5113495bSYour Name 		sap_ap_event->sapevt.sap_chan_cng_ind.new_chan_freq =
2813*5113495bSYour Name 					   csr_roaminfo->target_chan_freq;
2814*5113495bSYour Name 		break;
2815*5113495bSYour Name 	case eSAP_DFS_NEXT_CHANNEL_REQ:
2816*5113495bSYour Name 		sap_debug("SAP event callback event = %s",
2817*5113495bSYour Name 			  "eSAP_DFS_NEXT_CHANNEL_REQ");
2818*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_DFS_NEXT_CHANNEL_REQ;
2819*5113495bSYour Name 		break;
2820*5113495bSYour Name 	case eSAP_STOP_BSS_DUE_TO_NO_CHNL:
2821*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_STOP_BSS_DUE_TO_NO_CHNL;
2822*5113495bSYour Name 		sap_debug("stopping session_id:%d, bssid:"QDF_MAC_ADDR_FMT", chan_freq:%d",
2823*5113495bSYour Name 			   sap_ctx->sessionId,
2824*5113495bSYour Name 			   QDF_MAC_ADDR_REF(sap_ctx->self_mac_addr),
2825*5113495bSYour Name 			   sap_ctx->chan_freq);
2826*5113495bSYour Name 		break;
2827*5113495bSYour Name 
2828*5113495bSYour Name 	case eSAP_CHANNEL_CHANGE_RESP:
2829*5113495bSYour Name 		sap_ap_event->sapHddEventCode = eSAP_CHANNEL_CHANGE_RESP;
2830*5113495bSYour Name 		sap_ap_event->sapevt.sap_chan_cng_rsp.ch_change_rsp_status =
2831*5113495bSYour Name 					(eSapStatus)context;
2832*5113495bSYour Name 		acs_selected =
2833*5113495bSYour Name 			&sap_ap_event->sapevt.sap_chan_cng_rsp.sap_ch_selected;
2834*5113495bSYour Name 		acs_selected->pri_ch_freq = sap_ctx->chan_freq;
2835*5113495bSYour Name 		acs_selected->ht_sec_ch_freq = sap_ctx->sec_ch_freq;
2836*5113495bSYour Name 		acs_selected->ch_width =
2837*5113495bSYour Name 				sap_ctx->ch_params.ch_width;
2838*5113495bSYour Name 		acs_selected->vht_seg0_center_ch_freq =
2839*5113495bSYour Name 				sap_ctx->ch_params.mhz_freq_seg0;
2840*5113495bSYour Name 		acs_selected->vht_seg1_center_ch_freq =
2841*5113495bSYour Name 				sap_ctx->ch_params.mhz_freq_seg1;
2842*5113495bSYour Name 		sap_update_cac_history(mac_ctx, sap_ctx,
2843*5113495bSYour Name 				       sap_hddevent);
2844*5113495bSYour Name 		sap_debug("SAP event callback event = %s",
2845*5113495bSYour Name 			  "eSAP_CHANNEL_CHANGE_RESP");
2846*5113495bSYour Name 		break;
2847*5113495bSYour Name 
2848*5113495bSYour Name 	default:
2849*5113495bSYour Name 		sap_err("SAP Unknown callback event = %d", sap_hddevent);
2850*5113495bSYour Name 		break;
2851*5113495bSYour Name 	}
2852*5113495bSYour Name 	qdf_status = (*sap_ctx->sap_event_cb)
2853*5113495bSYour Name 			(sap_ap_event, sap_ctx->user_context);
2854*5113495bSYour Name 
2855*5113495bSYour Name 	qdf_mem_free(sap_ap_event);
2856*5113495bSYour Name 
2857*5113495bSYour Name 	return qdf_status;
2858*5113495bSYour Name }
2859*5113495bSYour Name 
sap_is_dfs_cac_wait_state(struct sap_context * sap_ctx)2860*5113495bSYour Name bool sap_is_dfs_cac_wait_state(struct sap_context *sap_ctx)
2861*5113495bSYour Name {
2862*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
2863*5113495bSYour Name 	QDF_STATUS status;
2864*5113495bSYour Name 	struct mac_context *mac_ctx;
2865*5113495bSYour Name 	mac_handle_t mac_handle;
2866*5113495bSYour Name 
2867*5113495bSYour Name 	if (!sap_ctx) {
2868*5113495bSYour Name 		sap_err("Invalid sap context");
2869*5113495bSYour Name 		return false;
2870*5113495bSYour Name 	}
2871*5113495bSYour Name 
2872*5113495bSYour Name 	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
2873*5113495bSYour Name 	if (!mac_handle)
2874*5113495bSYour Name 		return false;
2875*5113495bSYour Name 
2876*5113495bSYour Name 	mac_ctx = MAC_CONTEXT(mac_handle);
2877*5113495bSYour Name 	if (!mac_ctx) {
2878*5113495bSYour Name 		sap_err("Invalid MAC context");
2879*5113495bSYour Name 		return false;
2880*5113495bSYour Name 	}
2881*5113495bSYour Name 
2882*5113495bSYour Name 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
2883*5113495bSYour Name 						    sap_ctx->sessionId,
2884*5113495bSYour Name 						    WLAN_DFS_ID);
2885*5113495bSYour Name 	if (!vdev) {
2886*5113495bSYour Name 		sap_err("vdev is NULL for vdev_id: %u", sap_ctx->sessionId);
2887*5113495bSYour Name 		return false;
2888*5113495bSYour Name 	}
2889*5113495bSYour Name 
2890*5113495bSYour Name 	status = wlan_vdev_is_dfs_cac_wait(vdev);
2891*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
2892*5113495bSYour Name 
2893*5113495bSYour Name 	return QDF_IS_STATUS_SUCCESS(status);
2894*5113495bSYour Name }
2895*5113495bSYour Name 
2896*5113495bSYour Name /**
2897*5113495bSYour Name  * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state
2898*5113495bSYour Name  * @handle: Global MAC handle
2899*5113495bSYour Name  *
2900*5113495bSYour Name  * Finds and gets the context of a SAP session in CAC wait state.
2901*5113495bSYour Name  *
2902*5113495bSYour Name  * Return: Valid SAP context on success, else NULL
2903*5113495bSYour Name  */
sap_find_cac_wait_session(mac_handle_t handle)2904*5113495bSYour Name static struct sap_context *sap_find_cac_wait_session(mac_handle_t handle)
2905*5113495bSYour Name {
2906*5113495bSYour Name 	struct mac_context *mac = MAC_CONTEXT(handle);
2907*5113495bSYour Name 	uint8_t i = 0;
2908*5113495bSYour Name 	struct sap_context *sap_ctx;
2909*5113495bSYour Name 
2910*5113495bSYour Name 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
2911*5113495bSYour Name 		sap_ctx = mac->sap.sapCtxList[i].sap_context;
2912*5113495bSYour Name 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona)
2913*5113495bSYour Name 		    ||
2914*5113495bSYour Name 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) &&
2915*5113495bSYour Name 		    (sap_is_dfs_cac_wait_state(sap_ctx))) {
2916*5113495bSYour Name 			sap_debug("found SAP in cac wait state");
2917*5113495bSYour Name 			return sap_ctx;
2918*5113495bSYour Name 		}
2919*5113495bSYour Name 		if (sap_ctx) {
2920*5113495bSYour Name 			sap_debug("sapdfs: mode:%d intf:%d state:%d",
2921*5113495bSYour Name 				  mac->sap.sapCtxList[i].sapPersona, i,
2922*5113495bSYour Name 				  sap_ctx->fsm_state);
2923*5113495bSYour Name 		}
2924*5113495bSYour Name 	}
2925*5113495bSYour Name 
2926*5113495bSYour Name 	return NULL;
2927*5113495bSYour Name }
2928*5113495bSYour Name 
sap_cac_reset_notify(mac_handle_t mac_handle)2929*5113495bSYour Name void sap_cac_reset_notify(mac_handle_t mac_handle)
2930*5113495bSYour Name {
2931*5113495bSYour Name 	uint8_t intf = 0;
2932*5113495bSYour Name 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
2933*5113495bSYour Name 
2934*5113495bSYour Name 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2935*5113495bSYour Name 		struct sap_context *sap_context =
2936*5113495bSYour Name 			mac->sap.sapCtxList[intf].sap_context;
2937*5113495bSYour Name 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona)
2938*5113495bSYour Name 		    ||
2939*5113495bSYour Name 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona))
2940*5113495bSYour Name 		    && mac->sap.sapCtxList[intf].sap_context) {
2941*5113495bSYour Name 			sap_context->isCacStartNotified = false;
2942*5113495bSYour Name 			sap_context->isCacEndNotified = false;
2943*5113495bSYour Name 		}
2944*5113495bSYour Name 	}
2945*5113495bSYour Name }
2946*5113495bSYour Name 
2947*5113495bSYour Name /**
2948*5113495bSYour Name  * sap_cac_start_notify() - Notify CAC start to HDD
2949*5113495bSYour Name  * @mac_handle: Opaque handle to the global MAC context
2950*5113495bSYour Name  *
2951*5113495bSYour Name  * Function will be called to notify eSAP_DFS_CAC_START event to HDD
2952*5113495bSYour Name  *
2953*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS if the notification was sent, otherwise
2954*5113495bSYour Name  *         an appropriate QDF_STATUS error
2955*5113495bSYour Name  */
sap_cac_start_notify(mac_handle_t mac_handle)2956*5113495bSYour Name static QDF_STATUS sap_cac_start_notify(mac_handle_t mac_handle)
2957*5113495bSYour Name {
2958*5113495bSYour Name 	uint8_t intf = 0;
2959*5113495bSYour Name 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
2960*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2961*5113495bSYour Name 
2962*5113495bSYour Name 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2963*5113495bSYour Name 		struct sap_context *sap_context =
2964*5113495bSYour Name 			mac->sap.sapCtxList[intf].sap_context;
2965*5113495bSYour Name 
2966*5113495bSYour Name 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona)
2967*5113495bSYour Name 		    ||
2968*5113495bSYour Name 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona))
2969*5113495bSYour Name 		    && mac->sap.sapCtxList[intf].sap_context &&
2970*5113495bSYour Name 		    (false == sap_context->isCacStartNotified)) {
2971*5113495bSYour Name 			/* Don't start CAC for non-dfs channel, its violation */
2972*5113495bSYour Name 			if (!sap_operating_on_dfs(
2973*5113495bSYour Name 					mac,
2974*5113495bSYour Name 					mac->sap.sapCtxList[intf].sap_context))
2975*5113495bSYour Name 				continue;
2976*5113495bSYour Name 			sap_debug("sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%pK]",
2977*5113495bSYour Name 				  sap_context);
2978*5113495bSYour Name 
2979*5113495bSYour Name 			qdf_status = sap_signal_hdd_event(sap_context, NULL,
2980*5113495bSYour Name 							  eSAP_DFS_CAC_START,
2981*5113495bSYour Name 							  (void *)
2982*5113495bSYour Name 							  eSAP_STATUS_SUCCESS);
2983*5113495bSYour Name 			if (QDF_STATUS_SUCCESS != qdf_status) {
2984*5113495bSYour Name 				sap_err("Failed setting isCacStartNotified on interface[%d]",
2985*5113495bSYour Name 					 intf);
2986*5113495bSYour Name 				return qdf_status;
2987*5113495bSYour Name 			}
2988*5113495bSYour Name 			sap_context->isCacStartNotified = true;
2989*5113495bSYour Name 		}
2990*5113495bSYour Name 	}
2991*5113495bSYour Name 	return qdf_status;
2992*5113495bSYour Name }
2993*5113495bSYour Name 
2994*5113495bSYour Name #ifdef PRE_CAC_SUPPORT
2995*5113495bSYour Name /**
2996*5113495bSYour Name  * wlansap_pre_cac_end_notify() - Update pre cac end to upper layer
2997*5113495bSYour Name  * @sap_context: SAP context
2998*5113495bSYour Name  * @mac: Global MAC structure
2999*5113495bSYour Name  * @intf: Interface number
3000*5113495bSYour Name  *
3001*5113495bSYour Name  * Notifies pre cac end to upper layer
3002*5113495bSYour Name  *
3003*5113495bSYour Name  * Return: None
3004*5113495bSYour Name  */
wlansap_pre_cac_end_notify(struct sap_context * sap_context,struct mac_context * mac,uint8_t intf)3005*5113495bSYour Name static void wlansap_pre_cac_end_notify(struct sap_context *sap_context,
3006*5113495bSYour Name 				       struct mac_context *mac,
3007*5113495bSYour Name 				       uint8_t intf)
3008*5113495bSYour Name {
3009*5113495bSYour Name 	sap_context->isCacEndNotified = true;
3010*5113495bSYour Name 	sap_context->sap_radar_found_status = false;
3011*5113495bSYour Name 	sap_context->fsm_state = SAP_STARTED;
3012*5113495bSYour Name 	sap_warn("sap_fsm: vdev %d => SAP_STARTED, pre cac end notify on %d",
3013*5113495bSYour Name 		 sap_context->vdev_id, intf);
3014*5113495bSYour Name 	wlan_pre_cac_handle_cac_end(sap_context->vdev);
3015*5113495bSYour Name }
3016*5113495bSYour Name #endif
3017*5113495bSYour Name 
sap_cac_end_notify(mac_handle_t mac_handle,struct csr_roam_info * roamInfo)3018*5113495bSYour Name QDF_STATUS sap_cac_end_notify(mac_handle_t mac_handle,
3019*5113495bSYour Name 			      struct csr_roam_info *roamInfo)
3020*5113495bSYour Name {
3021*5113495bSYour Name 	uint8_t intf;
3022*5113495bSYour Name 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
3023*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3024*5113495bSYour Name 	bool is_acs;
3025*5113495bSYour Name 
3026*5113495bSYour Name 	/*
3027*5113495bSYour Name 	 * eSAP_DFS_CHANNEL_CAC_END:
3028*5113495bSYour Name 	 * CAC Period elapsed and there was no radar
3029*5113495bSYour Name 	 * found so, SAP can continue beaconing.
3030*5113495bSYour Name 	 * sap_radar_found_status is set to 0
3031*5113495bSYour Name 	 */
3032*5113495bSYour Name 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3033*5113495bSYour Name 		struct sap_context *sap_context =
3034*5113495bSYour Name 			mac->sap.sapCtxList[intf].sap_context;
3035*5113495bSYour Name 
3036*5113495bSYour Name 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona)
3037*5113495bSYour Name 		    ||
3038*5113495bSYour Name 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona))
3039*5113495bSYour Name 		    && mac->sap.sapCtxList[intf].sap_context &&
3040*5113495bSYour Name 		    (false == sap_context->isCacEndNotified) &&
3041*5113495bSYour Name 		    sap_is_dfs_cac_wait_state(sap_context)) {
3042*5113495bSYour Name 			sap_context = mac->sap.sapCtxList[intf].sap_context;
3043*5113495bSYour Name 			/* Don't check CAC for non-dfs channel */
3044*5113495bSYour Name 			if (!sap_operating_on_dfs(
3045*5113495bSYour Name 					mac,
3046*5113495bSYour Name 					mac->sap.sapCtxList[intf].sap_context))
3047*5113495bSYour Name 				continue;
3048*5113495bSYour Name 
3049*5113495bSYour Name 			/* If this is an end notification of a pre cac, the
3050*5113495bSYour Name 			 * SAP must not start beaconing and must delete the
3051*5113495bSYour Name 			 * temporary interface created for pre cac and switch
3052*5113495bSYour Name 			 * the original SAP to the pre CAC channel.
3053*5113495bSYour Name 			 */
3054*5113495bSYour Name 			if (wlan_pre_cac_get_status(mac->psoc)) {
3055*5113495bSYour Name 				wlansap_pre_cac_end_notify(sap_context,
3056*5113495bSYour Name 							   mac, intf);
3057*5113495bSYour Name 				/* pre CAC is not allowed with any concurrency.
3058*5113495bSYour Name 				 * So, we can break from here.
3059*5113495bSYour Name 				 */
3060*5113495bSYour Name 				break;
3061*5113495bSYour Name 			}
3062*5113495bSYour Name 
3063*5113495bSYour Name 			qdf_status = sap_signal_hdd_event(sap_context, NULL,
3064*5113495bSYour Name 							  eSAP_DFS_CAC_END,
3065*5113495bSYour Name 							  (void *)
3066*5113495bSYour Name 							  eSAP_STATUS_SUCCESS);
3067*5113495bSYour Name 			if (QDF_STATUS_SUCCESS != qdf_status) {
3068*5113495bSYour Name 				sap_err("failed setting isCacEndNotified on interface[%d]",
3069*5113495bSYour Name 					 intf);
3070*5113495bSYour Name 				return qdf_status;
3071*5113495bSYour Name 			}
3072*5113495bSYour Name 			sap_context->isCacEndNotified = true;
3073*5113495bSYour Name 			sap_context->sap_radar_found_status = false;
3074*5113495bSYour Name 			sap_debug("sapdfs: Start beacon request on sapctx[%pK]",
3075*5113495bSYour Name 				  sap_context);
3076*5113495bSYour Name 
3077*5113495bSYour Name 			/* Start beaconing on the new channel */
3078*5113495bSYour Name 			wlansap_start_beacon_req(sap_context);
3079*5113495bSYour Name 
3080*5113495bSYour Name 			/* Transition from SAP_STARTING to SAP_STARTED
3081*5113495bSYour Name 			 * (both without substates)
3082*5113495bSYour Name 			 */
3083*5113495bSYour Name 			sap_context->fsm_state = SAP_STARTED;
3084*5113495bSYour Name 			sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STARTED, freq %d",
3085*5113495bSYour Name 				  sap_context->vdev_id, sap_context->chan_freq);
3086*5113495bSYour Name 
3087*5113495bSYour Name 			/*Action code for transition */
3088*5113495bSYour Name 			qdf_status = sap_signal_hdd_event(sap_context, roamInfo,
3089*5113495bSYour Name 							  eSAP_START_BSS_EVENT,
3090*5113495bSYour Name 							  (void *)
3091*5113495bSYour Name 							  eSAP_STATUS_SUCCESS);
3092*5113495bSYour Name 			if (QDF_STATUS_SUCCESS != qdf_status) {
3093*5113495bSYour Name 				sap_err("Failed setting isCacEndNotified on interface[%d]",
3094*5113495bSYour Name 					 intf);
3095*5113495bSYour Name 				return qdf_status;
3096*5113495bSYour Name 			}
3097*5113495bSYour Name 
3098*5113495bSYour Name 			/*
3099*5113495bSYour Name 			 * CAC wait prevent SAP restart, check if need
3100*5113495bSYour Name 			 * restart SAP after CAC end
3101*5113495bSYour Name 			 */
3102*5113495bSYour Name 			is_acs = sap_context->acs_cfg &&
3103*5113495bSYour Name 				 sap_context->acs_cfg->acs_mode;
3104*5113495bSYour Name 			policy_mgr_check_concurrent_intf_and_restart_sap(mac->psoc,
3105*5113495bSYour Name 									 is_acs);
3106*5113495bSYour Name 		}
3107*5113495bSYour Name 	}
3108*5113495bSYour Name 
3109*5113495bSYour Name 	return qdf_status;
3110*5113495bSYour Name }
3111*5113495bSYour Name 
3112*5113495bSYour Name /**
3113*5113495bSYour Name  * sap_validate_dfs_nol() - Validate SAP channel with NOL list
3114*5113495bSYour Name  * @sap_ctx: SAP context
3115*5113495bSYour Name  * @mac_ctx: pointer to mac context
3116*5113495bSYour Name  *
3117*5113495bSYour Name  * Function will be called to validate SAP channel and bonded sub channels
3118*5113495bSYour Name  * included in DFS NOL or not.
3119*5113495bSYour Name  *
3120*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS for NOT in NOL
3121*5113495bSYour Name  */
sap_validate_dfs_nol(struct sap_context * sap_ctx,struct mac_context * mac_ctx)3122*5113495bSYour Name static QDF_STATUS sap_validate_dfs_nol(struct sap_context *sap_ctx,
3123*5113495bSYour Name 				       struct mac_context *mac_ctx)
3124*5113495bSYour Name {
3125*5113495bSYour Name 	bool b_leak_chan = false;
3126*5113495bSYour Name 	uint16_t temp_freq;
3127*5113495bSYour Name 	uint16_t sap_freq;
3128*5113495bSYour Name 	enum channel_state ch_state;
3129*5113495bSYour Name 	bool is_chan_nol = false;
3130*5113495bSYour Name 
3131*5113495bSYour Name 	sap_freq = sap_ctx->chan_freq;
3132*5113495bSYour Name 	temp_freq = sap_freq;
3133*5113495bSYour Name 	utils_dfs_mark_leaking_chan_for_freq(mac_ctx->pdev,
3134*5113495bSYour Name 					     sap_ctx->ch_params.ch_width, 1,
3135*5113495bSYour Name 					     &temp_freq);
3136*5113495bSYour Name 
3137*5113495bSYour Name 	/*
3138*5113495bSYour Name 	 * if selelcted channel has leakage to channels
3139*5113495bSYour Name 	 * in NOL, the temp_freq will be reset
3140*5113495bSYour Name 	 */
3141*5113495bSYour Name 	b_leak_chan = (temp_freq != sap_freq);
3142*5113495bSYour Name 	/*
3143*5113495bSYour Name 	 * check if channel is in DFS_NOL or if the channel
3144*5113495bSYour Name 	 * has leakage to the channels in NOL
3145*5113495bSYour Name 	 */
3146*5113495bSYour Name 
3147*5113495bSYour Name 	if (sap_phymode_is_eht(sap_ctx->phyMode)) {
3148*5113495bSYour Name 		ch_state =
3149*5113495bSYour Name 			wlan_reg_get_channel_state_from_secondary_list_for_freq(
3150*5113495bSYour Name 						mac_ctx->pdev, sap_freq);
3151*5113495bSYour Name 		if (CHANNEL_STATE_ENABLE != ch_state &&
3152*5113495bSYour Name 		    CHANNEL_STATE_DFS != ch_state) {
3153*5113495bSYour Name 			sap_err_rl("Invalid sap freq = %d, ch state=%d",
3154*5113495bSYour Name 				   sap_freq, ch_state);
3155*5113495bSYour Name 			is_chan_nol = true;
3156*5113495bSYour Name 		}
3157*5113495bSYour Name 	} else {
3158*5113495bSYour Name 		is_chan_nol = sap_dfs_is_channel_in_nol_list(
3159*5113495bSYour Name 					sap_ctx, sap_ctx->chan_freq,
3160*5113495bSYour Name 					PHY_CHANNEL_BONDING_STATE_MAX);
3161*5113495bSYour Name 	}
3162*5113495bSYour Name 
3163*5113495bSYour Name 	if (is_chan_nol || b_leak_chan) {
3164*5113495bSYour Name 		qdf_freq_t chan_freq;
3165*5113495bSYour Name 
3166*5113495bSYour Name 		/* find a new available channel */
3167*5113495bSYour Name 		chan_freq = sap_random_channel_sel(sap_ctx);
3168*5113495bSYour Name 		if (!chan_freq) {
3169*5113495bSYour Name 			/* No available channel found */
3170*5113495bSYour Name 			sap_err("No available channel found!!!");
3171*5113495bSYour Name 			sap_signal_hdd_event(sap_ctx, NULL,
3172*5113495bSYour Name 					     eSAP_DFS_NO_AVAILABLE_CHANNEL,
3173*5113495bSYour Name 					     (void *)eSAP_STATUS_SUCCESS);
3174*5113495bSYour Name 			return QDF_STATUS_E_FAULT;
3175*5113495bSYour Name 		}
3176*5113495bSYour Name 
3177*5113495bSYour Name 		sap_debug("ch_freq %d is in NOL, start bss on new freq %d",
3178*5113495bSYour Name 			  sap_ctx->chan_freq, chan_freq);
3179*5113495bSYour Name 
3180*5113495bSYour Name 		sap_ctx->chan_freq = chan_freq;
3181*5113495bSYour Name 		if (sap_phymode_is_eht(sap_ctx->phyMode))
3182*5113495bSYour Name 			wlan_reg_set_create_punc_bitmap(&sap_ctx->ch_params,
3183*5113495bSYour Name 							true);
3184*5113495bSYour Name 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
3185*5113495bSYour Name 							sap_ctx->chan_freq,
3186*5113495bSYour Name 							sap_ctx->sec_ch_freq,
3187*5113495bSYour Name 							&sap_ctx->ch_params,
3188*5113495bSYour Name 							REG_CURRENT_PWR_MODE);
3189*5113495bSYour Name 	}
3190*5113495bSYour Name 
3191*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3192*5113495bSYour Name }
3193*5113495bSYour Name 
sap_validate_chanmode_and_chwidth(struct mac_context * mac_ctx,struct sap_context * sap_ctx)3194*5113495bSYour Name static void sap_validate_chanmode_and_chwidth(struct mac_context *mac_ctx,
3195*5113495bSYour Name 					      struct sap_context *sap_ctx)
3196*5113495bSYour Name {
3197*5113495bSYour Name 	uint32_t orig_phymode;
3198*5113495bSYour Name 	enum phy_ch_width orig_ch_width;
3199*5113495bSYour Name 
3200*5113495bSYour Name 	orig_ch_width = sap_ctx->ch_params.ch_width;
3201*5113495bSYour Name 	orig_phymode = sap_ctx->phyMode;
3202*5113495bSYour Name 
3203*5113495bSYour Name 	if (WLAN_REG_IS_5GHZ_CH_FREQ(sap_ctx->chan_freq) &&
3204*5113495bSYour Name 	    (sap_ctx->phyMode == eCSR_DOT11_MODE_11g ||
3205*5113495bSYour Name 	     sap_ctx->phyMode == eCSR_DOT11_MODE_11g_ONLY)) {
3206*5113495bSYour Name 		sap_ctx->phyMode = eCSR_DOT11_MODE_11a;
3207*5113495bSYour Name 	} else if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_ctx->chan_freq) &&
3208*5113495bSYour Name 		   (sap_ctx->phyMode == eCSR_DOT11_MODE_11a)) {
3209*5113495bSYour Name 		sap_ctx->phyMode = eCSR_DOT11_MODE_11g;
3210*5113495bSYour Name 	}
3211*5113495bSYour Name 
3212*5113495bSYour Name 	if (sap_ctx->ch_params.ch_width > CH_WIDTH_20MHZ &&
3213*5113495bSYour Name 	    (sap_ctx->phyMode == eCSR_DOT11_MODE_abg ||
3214*5113495bSYour Name 	     sap_ctx->phyMode == eCSR_DOT11_MODE_11a ||
3215*5113495bSYour Name 	     sap_ctx->phyMode == eCSR_DOT11_MODE_11g ||
3216*5113495bSYour Name 	     sap_ctx->phyMode == eCSR_DOT11_MODE_11b)) {
3217*5113495bSYour Name 		sap_ctx->ch_params.ch_width = CH_WIDTH_20MHZ;
3218*5113495bSYour Name 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
3219*5113495bSYour Name 					       sap_ctx->chan_freq,
3220*5113495bSYour Name 					       sap_ctx->ch_params.sec_ch_offset,
3221*5113495bSYour Name 					       &sap_ctx->ch_params,
3222*5113495bSYour Name 					       REG_CURRENT_PWR_MODE);
3223*5113495bSYour Name 	} else if (sap_ctx->ch_params.ch_width > CH_WIDTH_40MHZ &&
3224*5113495bSYour Name 		   sap_ctx->phyMode == eCSR_DOT11_MODE_11n) {
3225*5113495bSYour Name 		sap_ctx->ch_params.ch_width = CH_WIDTH_40MHZ;
3226*5113495bSYour Name 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
3227*5113495bSYour Name 					       sap_ctx->chan_freq,
3228*5113495bSYour Name 					       sap_ctx->ch_params.sec_ch_offset,
3229*5113495bSYour Name 					       &sap_ctx->ch_params,
3230*5113495bSYour Name 					       REG_CURRENT_PWR_MODE);
3231*5113495bSYour Name 	}
3232*5113495bSYour Name 
3233*5113495bSYour Name 	if (orig_ch_width != sap_ctx->ch_params.ch_width ||
3234*5113495bSYour Name 	    orig_phymode != sap_ctx->phyMode)
3235*5113495bSYour Name 		sap_info("Freq %d Updated BW %d -> %d , phymode %d -> %d",
3236*5113495bSYour Name 			 sap_ctx->chan_freq, orig_ch_width,
3237*5113495bSYour Name 			 sap_ctx->ch_params.ch_width,
3238*5113495bSYour Name 			 orig_phymode, sap_ctx->phyMode);
3239*5113495bSYour Name }
3240*5113495bSYour Name 
3241*5113495bSYour Name static bool
wlansap_is_power_change_required(struct mac_context * mac_ctx,qdf_freq_t sap_freq)3242*5113495bSYour Name wlansap_is_power_change_required(struct mac_context *mac_ctx,
3243*5113495bSYour Name 				 qdf_freq_t sap_freq)
3244*5113495bSYour Name {
3245*5113495bSYour Name 	struct wlan_objmgr_vdev *sta_vdev;
3246*5113495bSYour Name 	uint8_t sta_vdev_id;
3247*5113495bSYour Name 	enum hw_mode_bandwidth ch_wd;
3248*5113495bSYour Name 	uint8_t country[CDS_COUNTRY_CODE_LEN + 1];
3249*5113495bSYour Name 	enum channel_state state;
3250*5113495bSYour Name 	uint32_t ap_pwr_type_6g = 0;
3251*5113495bSYour Name 	bool indoor_ch_support = false;
3252*5113495bSYour Name 
3253*5113495bSYour Name 	if (!mac_ctx || !mac_ctx->psoc || !mac_ctx->pdev)
3254*5113495bSYour Name 		return false;
3255*5113495bSYour Name 
3256*5113495bSYour Name 	if (!policy_mgr_is_sta_present_on_freq(mac_ctx->psoc, &sta_vdev_id,
3257*5113495bSYour Name 					       sap_freq, &ch_wd)) {
3258*5113495bSYour Name 		return false;
3259*5113495bSYour Name 	}
3260*5113495bSYour Name 
3261*5113495bSYour Name 	sta_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc,
3262*5113495bSYour Name 							sta_vdev_id,
3263*5113495bSYour Name 							WLAN_LEGACY_SAP_ID);
3264*5113495bSYour Name 	if (!sta_vdev)
3265*5113495bSYour Name 		return false;
3266*5113495bSYour Name 
3267*5113495bSYour Name 	ap_pwr_type_6g = wlan_mlme_get_6g_ap_power_type(sta_vdev);
3268*5113495bSYour Name 
3269*5113495bSYour Name 	wlan_objmgr_vdev_release_ref(sta_vdev, WLAN_LEGACY_SAP_ID);
3270*5113495bSYour Name 
3271*5113495bSYour Name 	if (ap_pwr_type_6g == REG_VERY_LOW_POWER_AP)
3272*5113495bSYour Name 		return false;
3273*5113495bSYour Name 	ucfg_mlme_get_indoor_channel_support(mac_ctx->psoc, &indoor_ch_support);
3274*5113495bSYour Name 
3275*5113495bSYour Name 	if (ap_pwr_type_6g == REG_INDOOR_AP && indoor_ch_support) {
3276*5113495bSYour Name 		sap_debug("STA is connected to Indoor AP and indoor concurrency is supported");
3277*5113495bSYour Name 		return false;
3278*5113495bSYour Name 	}
3279*5113495bSYour Name 
3280*5113495bSYour Name 	wlan_reg_read_current_country(mac_ctx->psoc, country);
3281*5113495bSYour Name 	if (!wlan_reg_ctry_support_vlp(country)) {
3282*5113495bSYour Name 		sap_debug("Device country doesn't support VLP");
3283*5113495bSYour Name 		return false;
3284*5113495bSYour Name 	}
3285*5113495bSYour Name 
3286*5113495bSYour Name 	state = wlan_reg_get_channel_state_for_pwrmode(mac_ctx->pdev,
3287*5113495bSYour Name 						       sap_freq, REG_AP_VLP);
3288*5113495bSYour Name 
3289*5113495bSYour Name 	return state & CHANNEL_STATE_ENABLE;
3290*5113495bSYour Name }
3291*5113495bSYour Name 
3292*5113495bSYour Name /**
3293*5113495bSYour Name  * sap_goto_starting() - Trigger softap start
3294*5113495bSYour Name  * @sap_ctx: SAP context
3295*5113495bSYour Name  * @sap_event: SAP event buffer
3296*5113495bSYour Name  * @mac_ctx: global MAC context
3297*5113495bSYour Name  * @mac_handle: Opaque handle to the global MAC context
3298*5113495bSYour Name  *
3299*5113495bSYour Name  * This function triggers start of softap. Before starting, it can select
3300*5113495bSYour Name  * new channel if given channel has leakage or if given channel in DFS_NOL.
3301*5113495bSYour Name  *
3302*5113495bSYour Name  * Return: QDF_STATUS
3303*5113495bSYour Name  */
sap_goto_starting(struct sap_context * sap_ctx,struct sap_sm_event * sap_event,struct mac_context * mac_ctx,mac_handle_t mac_handle)3304*5113495bSYour Name static QDF_STATUS sap_goto_starting(struct sap_context *sap_ctx,
3305*5113495bSYour Name 				    struct sap_sm_event *sap_event,
3306*5113495bSYour Name 				    struct mac_context *mac_ctx,
3307*5113495bSYour Name 				    mac_handle_t mac_handle)
3308*5113495bSYour Name {
3309*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3310*5113495bSYour Name 	struct bss_dot11_config dot11_cfg = {0};
3311*5113495bSYour Name 	tSirMacRateSet *opr_rates = &sap_ctx->sap_bss_cfg.operationalRateSet;
3312*5113495bSYour Name 	tSirMacRateSet *ext_rates = &sap_ctx->sap_bss_cfg.extendedRateSet;
3313*5113495bSYour Name 	uint8_t h2e;
3314*5113495bSYour Name 
3315*5113495bSYour Name 	/*
3316*5113495bSYour Name 	 * check if channel is in DFS_NOL or if the channel
3317*5113495bSYour Name 	 * has leakage to the channels in NOL.
3318*5113495bSYour Name 	 */
3319*5113495bSYour Name 	if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq)) {
3320*5113495bSYour Name 		qdf_status = sap_validate_dfs_nol(sap_ctx, mac_ctx);
3321*5113495bSYour Name 		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
3322*5113495bSYour Name 			return qdf_status;
3323*5113495bSYour Name 	} else if (!policy_mgr_get_ap_6ghz_capable(mac_ctx->psoc,
3324*5113495bSYour Name 						   sap_ctx->sessionId, NULL)) {
3325*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3326*5113495bSYour Name 	} else if (wlansap_is_power_change_required(mac_ctx,
3327*5113495bSYour Name 						    sap_ctx->chan_freq)) {
3328*5113495bSYour Name 		wlan_set_tpc_update_required_for_sta(sap_ctx->vdev, true);
3329*5113495bSYour Name 	}
3330*5113495bSYour Name 
3331*5113495bSYour Name 	/*
3332*5113495bSYour Name 	 * when AP2 is started while AP1 is performing ACS, we may not
3333*5113495bSYour Name 	 * have the AP1 channel yet.So here after the completion of AP2
3334*5113495bSYour Name 	 * ACS check if AP1 ACS resulting channel is DFS and if yes
3335*5113495bSYour Name 	 * override AP2 ACS scan result with AP1 DFS channel
3336*5113495bSYour Name 	 */
3337*5113495bSYour Name 	if (policy_mgr_concurrent_beaconing_sessions_running(mac_ctx->psoc)) {
3338*5113495bSYour Name 		uint32_t con_ch_freq;
3339*5113495bSYour Name 		uint16_t con_ch;
3340*5113495bSYour Name 
3341*5113495bSYour Name 		con_ch_freq = sme_get_beaconing_concurrent_operation_channel(
3342*5113495bSYour Name 				mac_handle, sap_ctx->sessionId);
3343*5113495bSYour Name 		con_ch = wlan_reg_freq_to_chan(mac_ctx->pdev, con_ch_freq);
3344*5113495bSYour Name 		/* Overwrite second AP's channel with first only when:
3345*5113495bSYour Name 		 * 1. If operating mode is single mac
3346*5113495bSYour Name 		 * 2. or if 2nd AP is coming up on 5G band channel
3347*5113495bSYour Name 		 */
3348*5113495bSYour Name 		if ((!policy_mgr_is_hw_dbs_capable(mac_ctx->psoc) ||
3349*5113495bSYour Name 		     WLAN_REG_IS_5GHZ_CH_FREQ(sap_ctx->chan_freq)) &&
3350*5113495bSYour Name 		     con_ch &&
3351*5113495bSYour Name 		     wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
3352*5113495bSYour Name 					      con_ch_freq)) {
3353*5113495bSYour Name 			sap_ctx->chan_freq = con_ch_freq;
3354*5113495bSYour Name 			if (sap_phymode_is_eht(sap_ctx->phyMode))
3355*5113495bSYour Name 				wlan_reg_set_create_punc_bitmap(
3356*5113495bSYour Name 					&sap_ctx->ch_params, true);
3357*5113495bSYour Name 			wlan_reg_set_channel_params_for_pwrmode(
3358*5113495bSYour Name 						    mac_ctx->pdev,
3359*5113495bSYour Name 						    con_ch_freq, 0,
3360*5113495bSYour Name 						    &sap_ctx->ch_params,
3361*5113495bSYour Name 						    REG_CURRENT_PWR_MODE);
3362*5113495bSYour Name 		}
3363*5113495bSYour Name 	}
3364*5113495bSYour Name 
3365*5113495bSYour Name 	sap_validate_chanmode_and_chwidth(mac_ctx, sap_ctx);
3366*5113495bSYour Name 	/* Channel selected. Now can sap_goto_starting */
3367*5113495bSYour Name 	sap_ctx->fsm_state = SAP_STARTING;
3368*5113495bSYour Name 	sap_debug("sap_fsm: vdev %d: SAP_INIT => SAP_STARTING, phyMode %d bw %d",
3369*5113495bSYour Name 		  sap_ctx->vdev_id, sap_ctx->phyMode,
3370*5113495bSYour Name 		  sap_ctx->ch_params.ch_width);
3371*5113495bSYour Name 	/* Specify the channel */
3372*5113495bSYour Name 	sap_get_cac_dur_dfs_region(sap_ctx,
3373*5113495bSYour Name 				   &sap_ctx->sap_bss_cfg.cac_duration_ms,
3374*5113495bSYour Name 				   &sap_ctx->sap_bss_cfg.dfs_regdomain,
3375*5113495bSYour Name 				   sap_ctx->chan_freq,
3376*5113495bSYour Name 				   &sap_ctx->ch_params);
3377*5113495bSYour Name 	mlme_set_cac_required(sap_ctx->vdev,
3378*5113495bSYour Name 			      !!sap_ctx->sap_bss_cfg.cac_duration_ms);
3379*5113495bSYour Name 
3380*5113495bSYour Name 	sap_ctx->sap_bss_cfg.oper_ch_freq = sap_ctx->chan_freq;
3381*5113495bSYour Name 	sap_ctx->sap_bss_cfg.vht_channel_width = sap_ctx->ch_params.ch_width;
3382*5113495bSYour Name 	sap_ctx->sap_bss_cfg.center_freq_seg0 =
3383*5113495bSYour Name 					sap_ctx->ch_params.center_freq_seg0;
3384*5113495bSYour Name 	sap_ctx->sap_bss_cfg.center_freq_seg1 =
3385*5113495bSYour Name 					sap_ctx->ch_params.center_freq_seg1;
3386*5113495bSYour Name 	sap_ctx->sap_bss_cfg.sec_ch_offset = sap_ctx->ch_params.sec_ch_offset;
3387*5113495bSYour Name 
3388*5113495bSYour Name 	dot11_cfg.vdev_id = sap_ctx->sessionId;
3389*5113495bSYour Name 	dot11_cfg.bss_op_ch_freq = sap_ctx->chan_freq;
3390*5113495bSYour Name 	dot11_cfg.phy_mode = sap_ctx->phyMode;
3391*5113495bSYour Name 	dot11_cfg.privacy = sap_ctx->sap_bss_cfg.privacy;
3392*5113495bSYour Name 
3393*5113495bSYour Name 	qdf_mem_copy(dot11_cfg.opr_rates.rate,
3394*5113495bSYour Name 		     opr_rates->rate, opr_rates->numRates);
3395*5113495bSYour Name 	dot11_cfg.opr_rates.numRates = opr_rates->numRates;
3396*5113495bSYour Name 
3397*5113495bSYour Name 	qdf_mem_copy(dot11_cfg.ext_rates.rate,
3398*5113495bSYour Name 		     ext_rates->rate, ext_rates->numRates);
3399*5113495bSYour Name 	dot11_cfg.ext_rates.numRates = ext_rates->numRates;
3400*5113495bSYour Name 
3401*5113495bSYour Name 	sme_get_network_params(mac_ctx, &dot11_cfg);
3402*5113495bSYour Name 
3403*5113495bSYour Name 	sap_ctx->sap_bss_cfg.nwType = dot11_cfg.nw_type;
3404*5113495bSYour Name 	sap_ctx->sap_bss_cfg.dot11mode = dot11_cfg.dot11_mode;
3405*5113495bSYour Name 
3406*5113495bSYour Name 	if (dot11_cfg.opr_rates.numRates) {
3407*5113495bSYour Name 		qdf_mem_copy(opr_rates->rate,
3408*5113495bSYour Name 			     dot11_cfg.opr_rates.rate,
3409*5113495bSYour Name 			     dot11_cfg.opr_rates.numRates);
3410*5113495bSYour Name 		opr_rates->numRates = dot11_cfg.opr_rates.numRates;
3411*5113495bSYour Name 	} else {
3412*5113495bSYour Name 		qdf_mem_zero(opr_rates, sizeof(tSirMacRateSet));
3413*5113495bSYour Name 	}
3414*5113495bSYour Name 
3415*5113495bSYour Name 	if (dot11_cfg.ext_rates.numRates) {
3416*5113495bSYour Name 		qdf_mem_copy(ext_rates->rate,
3417*5113495bSYour Name 			     dot11_cfg.ext_rates.rate,
3418*5113495bSYour Name 			     dot11_cfg.ext_rates.numRates);
3419*5113495bSYour Name 		ext_rates->numRates = dot11_cfg.ext_rates.numRates;
3420*5113495bSYour Name 	} else {
3421*5113495bSYour Name 		qdf_mem_zero(ext_rates, sizeof(tSirMacRateSet));
3422*5113495bSYour Name 	}
3423*5113495bSYour Name 
3424*5113495bSYour Name 	if (sap_ctx->require_h2e) {
3425*5113495bSYour Name 		h2e = WLAN_BASIC_RATE_MASK |
3426*5113495bSYour Name 			WLAN_BSS_MEMBERSHIP_SELECTOR_SAE_H2E;
3427*5113495bSYour Name 		if (ext_rates->numRates < SIR_MAC_MAX_NUMBER_OF_RATES) {
3428*5113495bSYour Name 			ext_rates->rate[ext_rates->numRates] = h2e;
3429*5113495bSYour Name 			ext_rates->numRates++;
3430*5113495bSYour Name 			sap_debug("H2E bss membership add to ext support rate");
3431*5113495bSYour Name 		} else if (opr_rates->numRates < SIR_MAC_MAX_NUMBER_OF_RATES) {
3432*5113495bSYour Name 			opr_rates->rate[opr_rates->numRates] = h2e;
3433*5113495bSYour Name 			opr_rates->numRates++;
3434*5113495bSYour Name 			sap_debug("H2E bss membership add to support rate");
3435*5113495bSYour Name 		} else {
3436*5113495bSYour Name 			sap_err("rates full, can not add H2E bss membership");
3437*5113495bSYour Name 		}
3438*5113495bSYour Name 	}
3439*5113495bSYour Name 	sap_dfs_set_current_channel(sap_ctx);
3440*5113495bSYour Name 	/* Reset radar found flag before start sap, the flag will
3441*5113495bSYour Name 	 * be set when radar found in CAC wait.
3442*5113495bSYour Name 	 */
3443*5113495bSYour Name 	sap_ctx->sap_radar_found_status = false;
3444*5113495bSYour Name 
3445*5113495bSYour Name 	sap_debug("session: %d", sap_ctx->sessionId);
3446*5113495bSYour Name 
3447*5113495bSYour Name 	qdf_status = sme_start_bss(mac_handle, sap_ctx->sessionId,
3448*5113495bSYour Name 				   &sap_ctx->sap_bss_cfg);
3449*5113495bSYour Name 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
3450*5113495bSYour Name 		sap_err("Failed to issue sme_roam_connect");
3451*5113495bSYour Name 
3452*5113495bSYour Name 	return qdf_status;
3453*5113495bSYour Name }
3454*5113495bSYour Name 
3455*5113495bSYour Name /**
3456*5113495bSYour Name  * sap_fsm_cac_start() - start cac wait timer
3457*5113495bSYour Name  * @sap_ctx: SAP context
3458*5113495bSYour Name  * @mac_ctx: global MAC context
3459*5113495bSYour Name  * @mac_handle: Opaque handle to the global MAC context
3460*5113495bSYour Name  *
3461*5113495bSYour Name  * Return: QDF_STATUS
3462*5113495bSYour Name  */
sap_fsm_cac_start(struct sap_context * sap_ctx,struct mac_context * mac_ctx,mac_handle_t mac_handle)3463*5113495bSYour Name static QDF_STATUS sap_fsm_cac_start(struct sap_context *sap_ctx,
3464*5113495bSYour Name 				    struct mac_context *mac_ctx,
3465*5113495bSYour Name 				    mac_handle_t mac_handle)
3466*5113495bSYour Name {
3467*5113495bSYour Name 	if (!mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
3468*5113495bSYour Name 		sap_debug("sapdfs: starting dfs cac timer on sapctx[%pK]",
3469*5113495bSYour Name 			  sap_ctx);
3470*5113495bSYour Name 		sap_start_dfs_cac_timer(sap_ctx);
3471*5113495bSYour Name 	}
3472*5113495bSYour Name 
3473*5113495bSYour Name 	return sap_cac_start_notify(mac_handle);
3474*5113495bSYour Name }
3475*5113495bSYour Name 
3476*5113495bSYour Name /**
3477*5113495bSYour Name  * sap_fsm_state_init() - utility function called from sap fsm
3478*5113495bSYour Name  * @sap_ctx: SAP context
3479*5113495bSYour Name  * @sap_event: SAP event buffer
3480*5113495bSYour Name  * @mac_ctx: global MAC context
3481*5113495bSYour Name  * @mac_handle: Opaque handle to the global MAC context
3482*5113495bSYour Name  *
3483*5113495bSYour Name  * This function is called for state transition from "SAP_INIT"
3484*5113495bSYour Name  *
3485*5113495bSYour Name  * Return: QDF_STATUS
3486*5113495bSYour Name  */
sap_fsm_state_init(struct sap_context * sap_ctx,struct sap_sm_event * sap_event,struct mac_context * mac_ctx,mac_handle_t mac_handle)3487*5113495bSYour Name static QDF_STATUS sap_fsm_state_init(struct sap_context *sap_ctx,
3488*5113495bSYour Name 				     struct sap_sm_event *sap_event,
3489*5113495bSYour Name 				     struct mac_context *mac_ctx,
3490*5113495bSYour Name 				     mac_handle_t mac_handle)
3491*5113495bSYour Name {
3492*5113495bSYour Name 	uint32_t msg = sap_event->event;
3493*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3494*5113495bSYour Name 
3495*5113495bSYour Name 	if (msg == eSAP_HDD_START_INFRA_BSS) {
3496*5113495bSYour Name 		/* init dfs channel nol */
3497*5113495bSYour Name 		sap_init_dfs_channel_nol_list(sap_ctx);
3498*5113495bSYour Name 
3499*5113495bSYour Name 		/*
3500*5113495bSYour Name 		 * Perform sme_ScanRequest. This scan request is post start bss
3501*5113495bSYour Name 		 * request so, set the third to false.
3502*5113495bSYour Name 		 */
3503*5113495bSYour Name 		qdf_status = sap_validate_chan(sap_ctx, false, true);
3504*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
3505*5113495bSYour Name 			sap_err("vdev %d: channel is not valid!",
3506*5113495bSYour Name 				sap_ctx->vdev_id);
3507*5113495bSYour Name 			goto exit;
3508*5113495bSYour Name 		}
3509*5113495bSYour Name 
3510*5113495bSYour Name 		qdf_status = sap_goto_starting(sap_ctx, sap_event,
3511*5113495bSYour Name 					       mac_ctx, mac_handle);
3512*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(qdf_status))
3513*5113495bSYour Name 			sap_err("vdev %d: sap_goto_starting failed",
3514*5113495bSYour Name 				sap_ctx->vdev_id);
3515*5113495bSYour Name 	} else {
3516*5113495bSYour Name 		sap_err("sap_fsm: vdev %d: SAP_INIT, invalid event %d",
3517*5113495bSYour Name 			sap_ctx->vdev_id, msg);
3518*5113495bSYour Name 	}
3519*5113495bSYour Name 
3520*5113495bSYour Name exit:
3521*5113495bSYour Name 	return qdf_status;
3522*5113495bSYour Name }
3523*5113495bSYour Name 
3524*5113495bSYour Name /**
3525*5113495bSYour Name  * sap_fsm_handle_radar_during_cac() - uhandle radar event during cac
3526*5113495bSYour Name  * @sap_ctx: SAP context
3527*5113495bSYour Name  * @mac_ctx: global MAC context
3528*5113495bSYour Name  *
3529*5113495bSYour Name  * Return: QDF_STATUS
3530*5113495bSYour Name  */
sap_fsm_handle_radar_during_cac(struct sap_context * sap_ctx,struct mac_context * mac_ctx)3531*5113495bSYour Name static QDF_STATUS sap_fsm_handle_radar_during_cac(struct sap_context *sap_ctx,
3532*5113495bSYour Name 						  struct mac_context *mac_ctx)
3533*5113495bSYour Name {
3534*5113495bSYour Name 	uint8_t intf;
3535*5113495bSYour Name 
3536*5113495bSYour Name 	if (mac_ctx->sap.SapDfsInfo.target_chan_freq) {
3537*5113495bSYour Name 		if (sap_phymode_is_eht(sap_ctx->phyMode))
3538*5113495bSYour Name 			wlan_reg_set_create_punc_bitmap(&sap_ctx->ch_params,
3539*5113495bSYour Name 							true);
3540*5113495bSYour Name 		wlan_reg_set_channel_params_for_pwrmode(mac_ctx->pdev,
3541*5113495bSYour Name 				    mac_ctx->sap.SapDfsInfo.target_chan_freq, 0,
3542*5113495bSYour Name 				    &sap_ctx->ch_params, REG_CURRENT_PWR_MODE);
3543*5113495bSYour Name 	} else {
3544*5113495bSYour Name 		sap_err("Invalid target channel freq %d",
3545*5113495bSYour Name 			 mac_ctx->sap.SapDfsInfo.target_chan_freq);
3546*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3547*5113495bSYour Name 	}
3548*5113495bSYour Name 
3549*5113495bSYour Name 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3550*5113495bSYour Name 		struct sap_context *t_sap_ctx;
3551*5113495bSYour Name 
3552*5113495bSYour Name 		t_sap_ctx = mac_ctx->sap.sapCtxList[intf].sap_context;
3553*5113495bSYour Name 		if (((QDF_SAP_MODE ==
3554*5113495bSYour Name 		      mac_ctx->sap.sapCtxList[intf].sapPersona) ||
3555*5113495bSYour Name 		     (QDF_P2P_GO_MODE ==
3556*5113495bSYour Name 		      mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
3557*5113495bSYour Name 		    t_sap_ctx && t_sap_ctx->fsm_state != SAP_INIT) {
3558*5113495bSYour Name 			if (!sap_operating_on_dfs(mac_ctx, t_sap_ctx))
3559*5113495bSYour Name 				continue;
3560*5113495bSYour Name 			t_sap_ctx->is_chan_change_inprogress = true;
3561*5113495bSYour Name 			/*
3562*5113495bSYour Name 			 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
3563*5113495bSYour Name 			 * A Radar is found on current DFS Channel
3564*5113495bSYour Name 			 * while in CAC WAIT period So, do a channel
3565*5113495bSYour Name 			 * switch to randomly selected	target channel.
3566*5113495bSYour Name 			 * Send the Channel change message to SME/PE.
3567*5113495bSYour Name 			 * sap_radar_found_status is set to 1
3568*5113495bSYour Name 			 */
3569*5113495bSYour Name 			wlansap_channel_change_request(t_sap_ctx,
3570*5113495bSYour Name 				mac_ctx->sap.SapDfsInfo.target_chan_freq);
3571*5113495bSYour Name 		}
3572*5113495bSYour Name 	}
3573*5113495bSYour Name 
3574*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3575*5113495bSYour Name }
3576*5113495bSYour Name 
3577*5113495bSYour Name /**
3578*5113495bSYour Name  * sap_fsm_handle_start_failure() - handle sap start failure
3579*5113495bSYour Name  * @sap_ctx: SAP context
3580*5113495bSYour Name  * @msg: event msg
3581*5113495bSYour Name  * @mac_handle: Opaque handle to the global MAC context
3582*5113495bSYour Name  *
3583*5113495bSYour Name  * Return: QDF_STATUS
3584*5113495bSYour Name  */
sap_fsm_handle_start_failure(struct sap_context * sap_ctx,uint32_t msg,mac_handle_t mac_handle)3585*5113495bSYour Name static QDF_STATUS sap_fsm_handle_start_failure(struct sap_context *sap_ctx,
3586*5113495bSYour Name 					       uint32_t msg,
3587*5113495bSYour Name 					       mac_handle_t mac_handle)
3588*5113495bSYour Name {
3589*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3590*5113495bSYour Name 
3591*5113495bSYour Name 	if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3592*5113495bSYour Name 		/*
3593*5113495bSYour Name 		 * Stop the CAC timer only in following conditions
3594*5113495bSYour Name 		 * single AP: if there is a single AP then stop timer
3595*5113495bSYour Name 		 * multiple APs: incase of multiple APs, make sure that
3596*5113495bSYour Name 		 * all APs are down.
3597*5113495bSYour Name 		 */
3598*5113495bSYour Name 		if (!sap_find_valid_concurrent_session(mac_handle)) {
3599*5113495bSYour Name 			sap_debug("sapdfs: no sessions are valid, stopping timer");
3600*5113495bSYour Name 			sap_stop_dfs_cac_timer(sap_ctx);
3601*5113495bSYour Name 		}
3602*5113495bSYour Name 		/* Transition from SAP_STARTING to SAP_STOPPING */
3603*5113495bSYour Name 		sap_ctx->fsm_state = SAP_STOPPING;
3604*5113495bSYour Name 		sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STOPPING, start is in progress",
3605*5113495bSYour Name 			  sap_ctx->vdev_id);
3606*5113495bSYour Name 		qdf_status = sap_goto_stopping(sap_ctx);
3607*5113495bSYour Name 	} else {
3608*5113495bSYour Name 		/*
3609*5113495bSYour Name 		 * Transition from SAP_STARTING to SAP_INIT
3610*5113495bSYour Name 		 * (both without substates)
3611*5113495bSYour Name 		 */
3612*5113495bSYour Name 		sap_ctx->fsm_state = SAP_INIT;
3613*5113495bSYour Name 		sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_INIT",
3614*5113495bSYour Name 			  sap_ctx->vdev_id);
3615*5113495bSYour Name 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3616*5113495bSYour Name 						  eSAP_START_BSS_EVENT,
3617*5113495bSYour Name 						  (void *)
3618*5113495bSYour Name 						  eSAP_STATUS_FAILURE);
3619*5113495bSYour Name 		qdf_status = sap_goto_init(sap_ctx);
3620*5113495bSYour Name 	}
3621*5113495bSYour Name 
3622*5113495bSYour Name 	return qdf_status;
3623*5113495bSYour Name }
3624*5113495bSYour Name 
3625*5113495bSYour Name /**
3626*5113495bSYour Name  * sap_propagate_cac_events() - Indicate CAC START/END event
3627*5113495bSYour Name  * @sap_ctx: SAP context
3628*5113495bSYour Name  *
3629*5113495bSYour Name  * This function is to indicate CAC START/END event if CAC process
3630*5113495bSYour Name  * is skipped.
3631*5113495bSYour Name  *
3632*5113495bSYour Name  * Return: void
3633*5113495bSYour Name  */
sap_propagate_cac_events(struct sap_context * sap_ctx)3634*5113495bSYour Name static void sap_propagate_cac_events(struct sap_context *sap_ctx)
3635*5113495bSYour Name {
3636*5113495bSYour Name 	QDF_STATUS qdf_status;
3637*5113495bSYour Name 
3638*5113495bSYour Name 	qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3639*5113495bSYour Name 					  eSAP_DFS_CAC_START,
3640*5113495bSYour Name 					  (void *)
3641*5113495bSYour Name 					  eSAP_STATUS_SUCCESS);
3642*5113495bSYour Name 	if (qdf_status != QDF_STATUS_SUCCESS) {
3643*5113495bSYour Name 		sap_err("Failed to indicate CAC START vdev %d",
3644*5113495bSYour Name 			sap_ctx->sessionId);
3645*5113495bSYour Name 		return;
3646*5113495bSYour Name 	}
3647*5113495bSYour Name 
3648*5113495bSYour Name 	qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3649*5113495bSYour Name 					  eSAP_DFS_CAC_END,
3650*5113495bSYour Name 					  (void *)
3651*5113495bSYour Name 					  eSAP_STATUS_SUCCESS);
3652*5113495bSYour Name 	if (qdf_status != QDF_STATUS_SUCCESS) {
3653*5113495bSYour Name 		sap_debug("Failed to indicate CAC End vdev %d",
3654*5113495bSYour Name 			  sap_ctx->sessionId);
3655*5113495bSYour Name 	}
3656*5113495bSYour Name }
3657*5113495bSYour Name 
sap_check_and_update_vdev_ch_params(struct sap_context * sap_ctx)3658*5113495bSYour Name static void sap_check_and_update_vdev_ch_params(struct sap_context *sap_ctx)
3659*5113495bSYour Name {
3660*5113495bSYour Name 	struct wlan_channel *chan;
3661*5113495bSYour Name 	enum phy_ch_width orig_ch_width;
3662*5113495bSYour Name 
3663*5113495bSYour Name 	chan = wlan_vdev_get_active_channel(sap_ctx->vdev);
3664*5113495bSYour Name 	if (!chan) {
3665*5113495bSYour Name 		sap_debug("Couldn't get vdev active channel");
3666*5113495bSYour Name 		return;
3667*5113495bSYour Name 	}
3668*5113495bSYour Name 	if (sap_ctx->ch_params.ch_width == chan->ch_width)
3669*5113495bSYour Name 		return;
3670*5113495bSYour Name 
3671*5113495bSYour Name 	orig_ch_width = sap_ctx->ch_params.ch_width;
3672*5113495bSYour Name 
3673*5113495bSYour Name 	sap_ctx->ch_params.ch_width = chan->ch_width;
3674*5113495bSYour Name 	sap_ctx->ch_params.center_freq_seg0 = chan->ch_freq_seg1;
3675*5113495bSYour Name 	sap_ctx->ch_params.center_freq_seg1 = chan->ch_freq_seg2;
3676*5113495bSYour Name 	sap_ctx->ch_params.mhz_freq_seg0 = chan->ch_cfreq1;
3677*5113495bSYour Name 	sap_ctx->ch_params.mhz_freq_seg1 = chan->ch_cfreq2;
3678*5113495bSYour Name 
3679*5113495bSYour Name 	if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_ctx->chan_freq) &&
3680*5113495bSYour Name 	    (chan->ch_width == CH_WIDTH_40MHZ)) {
3681*5113495bSYour Name 		if (sap_ctx->chan_freq < chan->ch_freq_seg1)
3682*5113495bSYour Name 			sap_ctx->ch_params.sec_ch_offset = LOW_PRIMARY_CH;
3683*5113495bSYour Name 		else
3684*5113495bSYour Name 			sap_ctx->ch_params.sec_ch_offset = HIGH_PRIMARY_CH;
3685*5113495bSYour Name 	}
3686*5113495bSYour Name 	sap_debug("updated BW %d -> %d", orig_ch_width,
3687*5113495bSYour Name 		  sap_ctx->ch_params.ch_width);
3688*5113495bSYour Name }
3689*5113495bSYour Name 
3690*5113495bSYour Name /**
3691*5113495bSYour Name  * sap_fsm_send_csa_restart_req() - send csa start event
3692*5113495bSYour Name  * @mac_ctx: mac ctx
3693*5113495bSYour Name  * @sap_ctx: SAP context
3694*5113495bSYour Name  *
3695*5113495bSYour Name  * Return: QDF_STATUS
3696*5113495bSYour Name  */
3697*5113495bSYour Name static inline QDF_STATUS
sap_fsm_send_csa_restart_req(struct mac_context * mac_ctx,struct sap_context * sap_ctx)3698*5113495bSYour Name sap_fsm_send_csa_restart_req(struct mac_context *mac_ctx,
3699*5113495bSYour Name 			     struct sap_context *sap_ctx)
3700*5113495bSYour Name {
3701*5113495bSYour Name 	QDF_STATUS status;
3702*5113495bSYour Name 
3703*5113495bSYour Name 	status = policy_mgr_check_and_set_hw_mode_for_channel_switch(
3704*5113495bSYour Name 				mac_ctx->psoc, sap_ctx->sessionId,
3705*5113495bSYour Name 				mac_ctx->sap.SapDfsInfo.target_chan_freq,
3706*5113495bSYour Name 				POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_SAP);
3707*5113495bSYour Name 
3708*5113495bSYour Name 	/*
3709*5113495bSYour Name 	 * If hw_mode_status is QDF_STATUS_E_FAILURE, mean HW
3710*5113495bSYour Name 	 * mode change was required but driver failed to set HW
3711*5113495bSYour Name 	 * mode so ignore CSA for the channel.
3712*5113495bSYour Name 	 */
3713*5113495bSYour Name 	if (status == QDF_STATUS_E_FAILURE) {
3714*5113495bSYour Name 		sap_err("HW change required but failed to set hw mode");
3715*5113495bSYour Name 		return status;
3716*5113495bSYour Name 	}
3717*5113495bSYour Name 
3718*5113495bSYour Name 	/*
3719*5113495bSYour Name 	 * If hw_mode_status is QDF_STATUS_SUCCESS mean HW mode
3720*5113495bSYour Name 	 * change was required and was successfully requested so
3721*5113495bSYour Name 	 * the channel switch will continue after HW mode change
3722*5113495bSYour Name 	 * completion.
3723*5113495bSYour Name 	 */
3724*5113495bSYour Name 	if (QDF_IS_STATUS_SUCCESS(status)) {
3725*5113495bSYour Name 		sap_info("Channel change will continue after HW mode change");
3726*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
3727*5113495bSYour Name 	}
3728*5113495bSYour Name 
3729*5113495bSYour Name 	return sme_csa_restart(mac_ctx, sap_ctx->sessionId);
3730*5113495bSYour Name }
3731*5113495bSYour Name 
wlansap_validate_channel_post_csa(mac_handle_t mac_handle,struct sap_context * sap_ctx)3732*5113495bSYour Name bool wlansap_validate_channel_post_csa(mac_handle_t mac_handle,
3733*5113495bSYour Name 				       struct sap_context *sap_ctx)
3734*5113495bSYour Name {
3735*5113495bSYour Name 	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
3736*5113495bSYour Name 
3737*5113495bSYour Name 	if (((!sap_ctx->acs_cfg || !sap_ctx->acs_cfg->acs_mode) &&
3738*5113495bSYour Name 	     (!policy_mgr_restrict_sap_on_unsafe_chan(mac_ctx->psoc) ||
3739*5113495bSYour Name 	      target_psoc_get_sap_coex_fixed_chan_cap(
3740*5113495bSYour Name 		      wlan_psoc_get_tgt_if_handle(mac_ctx->psoc)))) ||
3741*5113495bSYour Name 	    (policy_mgr_is_sap_freq_allowed(mac_ctx->psoc,
3742*5113495bSYour Name 				wlan_vdev_mlme_get_opmode(sap_ctx->vdev),
3743*5113495bSYour Name 				sap_ctx->chan_freq) &&
3744*5113495bSYour Name 	     !wlan_reg_is_disable_for_pwrmode(mac_ctx->pdev, sap_ctx->chan_freq,
3745*5113495bSYour Name 					      REG_CURRENT_PWR_MODE)))
3746*5113495bSYour Name 		return true;
3747*5113495bSYour Name 	sap_debug("sap vdev %d on unsafe ch freq %d",
3748*5113495bSYour Name 		  sap_ctx->sessionId, sap_ctx->chan_freq);
3749*5113495bSYour Name 
3750*5113495bSYour Name 	return false;
3751*5113495bSYour Name }
3752*5113495bSYour Name 
3753*5113495bSYour Name /**
3754*5113495bSYour Name  * sap_fsm_state_starting() - utility function called from sap fsm
3755*5113495bSYour Name  * @sap_ctx: SAP context
3756*5113495bSYour Name  * @sap_event: SAP event buffer
3757*5113495bSYour Name  * @mac_ctx: global MAC context
3758*5113495bSYour Name  * @mac_handle: Opaque handle to the global MAC context
3759*5113495bSYour Name  *
3760*5113495bSYour Name  * This function is called for state transition from "SAP_STARTING"
3761*5113495bSYour Name  *
3762*5113495bSYour Name  * Return: QDF_STATUS
3763*5113495bSYour Name  */
sap_fsm_state_starting(struct sap_context * sap_ctx,struct sap_sm_event * sap_event,struct mac_context * mac_ctx,mac_handle_t mac_handle)3764*5113495bSYour Name static QDF_STATUS sap_fsm_state_starting(struct sap_context *sap_ctx,
3765*5113495bSYour Name 					 struct sap_sm_event *sap_event,
3766*5113495bSYour Name 					 struct mac_context *mac_ctx,
3767*5113495bSYour Name 					 mac_handle_t mac_handle)
3768*5113495bSYour Name {
3769*5113495bSYour Name 	uint32_t msg = sap_event->event;
3770*5113495bSYour Name 	struct csr_roam_info *roam_info =
3771*5113495bSYour Name 		(struct csr_roam_info *) (sap_event->params);
3772*5113495bSYour Name 	tSapDfsInfo *sap_dfs_info;
3773*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3774*5113495bSYour Name 	uint8_t is_dfs = false;
3775*5113495bSYour Name 	uint32_t sap_chan_freq;
3776*5113495bSYour Name 	uint32_t ch_cfreq1 = 0;
3777*5113495bSYour Name 	enum reg_wifi_band band;
3778*5113495bSYour Name 	eSapDfsCACState_t cac_state = eSAP_DFS_DO_NOT_SKIP_CAC;
3779*5113495bSYour Name 
3780*5113495bSYour Name 	if (msg == eSAP_MAC_START_BSS_SUCCESS) {
3781*5113495bSYour Name 		/*
3782*5113495bSYour Name 		 * Update sap_ctx->ch_params from vdev to make up with any BW
3783*5113495bSYour Name 		 * change in lower layer
3784*5113495bSYour Name 		 */
3785*5113495bSYour Name 		sap_check_and_update_vdev_ch_params(sap_ctx);
3786*5113495bSYour Name 
3787*5113495bSYour Name 		/*
3788*5113495bSYour Name 		 * Transition from SAP_STARTING to SAP_STARTED
3789*5113495bSYour Name 		 * (both without substates)
3790*5113495bSYour Name 		 */
3791*5113495bSYour Name 		sap_ctx->fsm_state = SAP_STARTED;
3792*5113495bSYour Name 		sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STARTED, freq %d ch_width %d",
3793*5113495bSYour Name 			  sap_ctx->vdev_id, sap_ctx->chan_freq,
3794*5113495bSYour Name 			  sap_ctx->ch_params.ch_width);
3795*5113495bSYour Name 
3796*5113495bSYour Name 		if (sap_ctx->is_chan_change_inprogress) {
3797*5113495bSYour Name 			/* SAP channel change request processing is completed */
3798*5113495bSYour Name 			qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
3799*5113495bSYour Name 						eSAP_CHANNEL_CHANGE_EVENT,
3800*5113495bSYour Name 						(void *)eSAP_STATUS_SUCCESS);
3801*5113495bSYour Name 			sap_ctx->is_chan_change_inprogress = false;
3802*5113495bSYour Name 		} else {
3803*5113495bSYour Name 			sap_debug("vdev %d notify hostapd about chan freq selection: %d",
3804*5113495bSYour Name 				  sap_ctx->vdev_id, sap_ctx->chan_freq);
3805*5113495bSYour Name 			qdf_status =
3806*5113495bSYour Name 				sap_signal_hdd_event(sap_ctx, roam_info,
3807*5113495bSYour Name 						     eSAP_CHANNEL_CHANGE_EVENT,
3808*5113495bSYour Name 						     (void *)eSAP_STATUS_SUCCESS);
3809*5113495bSYour Name 			/* Action code for transition */
3810*5113495bSYour Name 			qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
3811*5113495bSYour Name 					eSAP_START_BSS_EVENT,
3812*5113495bSYour Name 					(void *) eSAP_STATUS_SUCCESS);
3813*5113495bSYour Name 		}
3814*5113495bSYour Name 		sap_chan_freq = sap_ctx->chan_freq;
3815*5113495bSYour Name 		band = wlan_reg_freq_to_band(sap_ctx->chan_freq);
3816*5113495bSYour Name 		if (sap_ctx->ch_params.center_freq_seg1)
3817*5113495bSYour Name 			ch_cfreq1 = wlan_reg_chan_band_to_freq(
3818*5113495bSYour Name 					mac_ctx->pdev,
3819*5113495bSYour Name 					sap_ctx->ch_params.center_freq_seg1,
3820*5113495bSYour Name 					BIT(band));
3821*5113495bSYour Name 
3822*5113495bSYour Name 		/*
3823*5113495bSYour Name 		 * The upper layers have been informed that AP is up and
3824*5113495bSYour Name 		 * running, however, the AP is still not beaconing, until
3825*5113495bSYour Name 		 * CAC is done if the operating channel is DFS
3826*5113495bSYour Name 		 */
3827*5113495bSYour Name 		if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) {
3828*5113495bSYour Name 			struct ch_params ch_params = {0};
3829*5113495bSYour Name 
3830*5113495bSYour Name 			wlan_reg_set_create_punc_bitmap(&ch_params, true);
3831*5113495bSYour Name 			ch_params.ch_width = CH_WIDTH_160MHZ;
3832*5113495bSYour Name 			is_dfs =
3833*5113495bSYour Name 			wlan_reg_get_5g_bonded_channel_state_for_pwrmode(mac_ctx->pdev,
3834*5113495bSYour Name 									 sap_chan_freq,
3835*5113495bSYour Name 									 &ch_params,
3836*5113495bSYour Name 									 REG_CURRENT_PWR_MODE) ==
3837*5113495bSYour Name 			CHANNEL_STATE_DFS;
3838*5113495bSYour Name 		} else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) {
3839*5113495bSYour Name 			if (wlan_reg_get_channel_state_for_pwrmode(
3840*5113495bSYour Name 							mac_ctx->pdev,
3841*5113495bSYour Name 							sap_chan_freq,
3842*5113495bSYour Name 							REG_CURRENT_PWR_MODE) ==
3843*5113495bSYour Name 			    CHANNEL_STATE_DFS ||
3844*5113495bSYour Name 			    wlan_reg_get_channel_state_for_pwrmode(
3845*5113495bSYour Name 							mac_ctx->pdev,
3846*5113495bSYour Name 							ch_cfreq1,
3847*5113495bSYour Name 							REG_CURRENT_PWR_MODE) ==
3848*5113495bSYour Name 					CHANNEL_STATE_DFS)
3849*5113495bSYour Name 				is_dfs = true;
3850*5113495bSYour Name 		} else {
3851*5113495bSYour Name 			/* Indoor channels are also marked DFS, therefore
3852*5113495bSYour Name 			 * check if the channel has REGULATORY_CHAN_RADAR
3853*5113495bSYour Name 			 * channel flag to identify if the channel is DFS
3854*5113495bSYour Name 			 */
3855*5113495bSYour Name 			if (wlan_reg_is_dfs_for_freq(mac_ctx->pdev,
3856*5113495bSYour Name 						     sap_chan_freq))
3857*5113495bSYour Name 				is_dfs = true;
3858*5113495bSYour Name 		}
3859*5113495bSYour Name 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ctx->chan_freq))
3860*5113495bSYour Name 			is_dfs = false;
3861*5113495bSYour Name 
3862*5113495bSYour Name 		sap_debug("vdev %d freq %d, is_dfs %d", sap_ctx->vdev_id,
3863*5113495bSYour Name 			  sap_ctx->chan_freq, is_dfs);
3864*5113495bSYour Name 		if (is_dfs) {
3865*5113495bSYour Name 			sap_dfs_info = &mac_ctx->sap.SapDfsInfo;
3866*5113495bSYour Name 			if (sap_plus_sap_cac_skip(mac_ctx, sap_ctx,
3867*5113495bSYour Name 						  sap_chan_freq))
3868*5113495bSYour Name 				cac_state = eSAP_DFS_SKIP_CAC;
3869*5113495bSYour Name 			if ((false == sap_dfs_info->ignore_cac) &&
3870*5113495bSYour Name 			    (cac_state == eSAP_DFS_DO_NOT_SKIP_CAC) &&
3871*5113495bSYour Name 			    !wlan_pre_cac_complete_get(sap_ctx->vdev) &&
3872*5113495bSYour Name 			    policy_mgr_get_dfs_master_dynamic_enabled(
3873*5113495bSYour Name 					mac_ctx->psoc,
3874*5113495bSYour Name 					sap_ctx->sessionId)) {
3875*5113495bSYour Name 				sap_ctx->fsm_state = SAP_STARTING;
3876*5113495bSYour Name 				sap_debug("sap_fsm: vdev %d: SAP_STARTED => SAP_STARTING to start cac timer",
3877*5113495bSYour Name 					  sap_ctx->vdev_id);
3878*5113495bSYour Name 				qdf_status = sap_fsm_cac_start(sap_ctx, mac_ctx,
3879*5113495bSYour Name 							       mac_handle);
3880*5113495bSYour Name 			} else {
3881*5113495bSYour Name 				sap_debug("vdev %d skip cac timer",
3882*5113495bSYour Name 					  sap_ctx->vdev_id);
3883*5113495bSYour Name 				sap_ctx->sap_radar_found_status = false;
3884*5113495bSYour Name 				/*
3885*5113495bSYour Name 				 * If hostapd starts AP on dfs channel,
3886*5113495bSYour Name 				 * hostapd will wait for CAC START/CAC END
3887*5113495bSYour Name 				 * event and finish AP start process.
3888*5113495bSYour Name 				 * If we skip CAC timer, we will need to
3889*5113495bSYour Name 				 * indicate the CAC event even though driver
3890*5113495bSYour Name 				 * doesn't perform CAC.
3891*5113495bSYour Name 				 */
3892*5113495bSYour Name 				sap_propagate_cac_events(sap_ctx);
3893*5113495bSYour Name 
3894*5113495bSYour Name 				wlansap_start_beacon_req(sap_ctx);
3895*5113495bSYour Name 			}
3896*5113495bSYour Name 		}
3897*5113495bSYour Name 	} else if (msg == eSAP_MAC_START_FAILS ||
3898*5113495bSYour Name 		 msg == eSAP_HDD_STOP_INFRA_BSS) {
3899*5113495bSYour Name 			qdf_status = sap_fsm_handle_start_failure(sap_ctx, msg,
3900*5113495bSYour Name 								  mac_handle);
3901*5113495bSYour Name 	} else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) {
3902*5113495bSYour Name 		/* The operating channel has changed, update hostapd */
3903*5113495bSYour Name 		sap_ctx->chan_freq = mac_ctx->sap.SapDfsInfo.target_chan_freq;
3904*5113495bSYour Name 
3905*5113495bSYour Name 		sap_ctx->fsm_state = SAP_STARTED;
3906*5113495bSYour Name 		sap_debug("sap_fsm: vdev %d: SAP_STARTING => SAP_STARTED",
3907*5113495bSYour Name 			  sap_ctx->vdev_id);
3908*5113495bSYour Name 
3909*5113495bSYour Name 		/* Indicate change in the state to upper layers */
3910*5113495bSYour Name 		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
3911*5113495bSYour Name 				  eSAP_START_BSS_EVENT,
3912*5113495bSYour Name 				  (void *)eSAP_STATUS_SUCCESS);
3913*5113495bSYour Name 	} else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) {
3914*5113495bSYour Name 		qdf_status = sap_fsm_handle_radar_during_cac(sap_ctx, mac_ctx);
3915*5113495bSYour Name 	} else if (msg == eSAP_DFS_CHANNEL_CAC_END) {
3916*5113495bSYour Name 		if (sap_ctx->vdev &&
3917*5113495bSYour Name 		    wlan_util_vdev_mgr_get_cac_timeout_for_vdev(sap_ctx->vdev)) {
3918*5113495bSYour Name 			qdf_status = sap_cac_end_notify(mac_handle, roam_info);
3919*5113495bSYour Name 		} else {
3920*5113495bSYour Name 			sap_debug("vdev %d cac duration is zero",
3921*5113495bSYour Name 				  sap_ctx->vdev_id);
3922*5113495bSYour Name 			qdf_status = QDF_STATUS_SUCCESS;
3923*5113495bSYour Name 		}
3924*5113495bSYour Name 	} else if (msg == eSAP_DFS_CHANNEL_CAC_START) {
3925*5113495bSYour Name 		if (sap_ctx->is_chan_change_inprogress) {
3926*5113495bSYour Name 			sap_signal_hdd_event(sap_ctx,
3927*5113495bSYour Name 					     NULL,
3928*5113495bSYour Name 					     eSAP_CHANNEL_CHANGE_EVENT,
3929*5113495bSYour Name 					     (void *)eSAP_STATUS_SUCCESS);
3930*5113495bSYour Name 			sap_ctx->is_chan_change_inprogress = false;
3931*5113495bSYour Name 		}
3932*5113495bSYour Name 		qdf_status = sap_fsm_cac_start(sap_ctx, mac_ctx, mac_handle);
3933*5113495bSYour Name 	} else {
3934*5113495bSYour Name 		sap_err("sap_fsm: vdev %d: SAP_STARTING, invalid event %d",
3935*5113495bSYour Name 			sap_ctx->vdev_id, msg);
3936*5113495bSYour Name 	}
3937*5113495bSYour Name 
3938*5113495bSYour Name 	return qdf_status;
3939*5113495bSYour Name }
3940*5113495bSYour Name 
3941*5113495bSYour Name /**
3942*5113495bSYour Name  * sap_fsm_state_started() - utility function called from sap fsm
3943*5113495bSYour Name  * @sap_ctx: SAP context
3944*5113495bSYour Name  * @sap_event: SAP event buffer
3945*5113495bSYour Name  * @mac_ctx: global MAC context
3946*5113495bSYour Name  *
3947*5113495bSYour Name  * This function is called for state transition from "SAP_STARTED"
3948*5113495bSYour Name  *
3949*5113495bSYour Name  * Return: QDF_STATUS
3950*5113495bSYour Name  */
sap_fsm_state_started(struct sap_context * sap_ctx,struct sap_sm_event * sap_event,struct mac_context * mac_ctx)3951*5113495bSYour Name static QDF_STATUS sap_fsm_state_started(struct sap_context *sap_ctx,
3952*5113495bSYour Name 					struct sap_sm_event *sap_event,
3953*5113495bSYour Name 					struct mac_context *mac_ctx)
3954*5113495bSYour Name {
3955*5113495bSYour Name 	uint32_t msg = sap_event->event;
3956*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3957*5113495bSYour Name 
3958*5113495bSYour Name 	if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3959*5113495bSYour Name 		/*
3960*5113495bSYour Name 		 * Transition from SAP_STARTED to SAP_STOPPING
3961*5113495bSYour Name 		 * (both without substates)
3962*5113495bSYour Name 		 */
3963*5113495bSYour Name 		sap_ctx->fsm_state = SAP_STOPPING;
3964*5113495bSYour Name 		sap_debug("sap_fsm: vdev %d: SAP_STARTED => SAP_STOPPING",
3965*5113495bSYour Name 			  sap_ctx->vdev_id);
3966*5113495bSYour Name 		qdf_status = sap_goto_stopping(sap_ctx);
3967*5113495bSYour Name 	} else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) {
3968*5113495bSYour Name 		uint8_t intf;
3969*5113495bSYour Name 		if (!mac_ctx->sap.SapDfsInfo.target_chan_freq) {
3970*5113495bSYour Name 			sap_err("Invalid target channel freq %d",
3971*5113495bSYour Name 				mac_ctx->sap.SapDfsInfo.target_chan_freq);
3972*5113495bSYour Name 			return qdf_status;
3973*5113495bSYour Name 		}
3974*5113495bSYour Name 
3975*5113495bSYour Name 		/*
3976*5113495bSYour Name 		 * Radar is seen on the current operating channel
3977*5113495bSYour Name 		 * send CSA IE for all associated stations
3978*5113495bSYour Name 		 * Request for CSA IE transmission
3979*5113495bSYour Name 		 */
3980*5113495bSYour Name 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3981*5113495bSYour Name 			struct sap_context *temp_sap_ctx;
3982*5113495bSYour Name 
3983*5113495bSYour Name 			if (((QDF_SAP_MODE ==
3984*5113495bSYour Name 				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
3985*5113495bSYour Name 			    (QDF_P2P_GO_MODE ==
3986*5113495bSYour Name 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
3987*5113495bSYour Name 			    mac_ctx->sap.sapCtxList[intf].sap_context) {
3988*5113495bSYour Name 				temp_sap_ctx =
3989*5113495bSYour Name 				    mac_ctx->sap.sapCtxList[intf].sap_context;
3990*5113495bSYour Name 				/*
3991*5113495bSYour Name 				 * Radar won't come on non-dfs channel, so
3992*5113495bSYour Name 				 * no need to move them
3993*5113495bSYour Name 				 */
3994*5113495bSYour Name 				if (!sap_operating_on_dfs(
3995*5113495bSYour Name 						mac_ctx, temp_sap_ctx)) {
3996*5113495bSYour Name 					sap_debug("vdev %d freq %d (state %d) is not DFS or disabled so continue",
3997*5113495bSYour Name 						  temp_sap_ctx->sessionId,
3998*5113495bSYour Name 						  temp_sap_ctx->chan_freq,
3999*5113495bSYour Name 						  wlan_reg_get_channel_state_for_pwrmode(
4000*5113495bSYour Name 						  mac_ctx->pdev,
4001*5113495bSYour Name 						  temp_sap_ctx->chan_freq,
4002*5113495bSYour Name 						  REG_CURRENT_PWR_MODE));
4003*5113495bSYour Name 					continue;
4004*5113495bSYour Name 				}
4005*5113495bSYour Name 				sap_debug("vdev %d switch freq %d -> %d",
4006*5113495bSYour Name 					  temp_sap_ctx->sessionId,
4007*5113495bSYour Name 					  temp_sap_ctx->chan_freq,
4008*5113495bSYour Name 					  mac_ctx->sap.SapDfsInfo.target_chan_freq);
4009*5113495bSYour Name 				qdf_status =
4010*5113495bSYour Name 				   sap_fsm_send_csa_restart_req(mac_ctx,
4011*5113495bSYour Name 								temp_sap_ctx);
4012*5113495bSYour Name 			}
4013*5113495bSYour Name 		}
4014*5113495bSYour Name 	} else {
4015*5113495bSYour Name 		sap_err("sap_fsm: vdev %d: SAP_STARTED, invalid event %d",
4016*5113495bSYour Name 			sap_ctx->vdev_id, msg);
4017*5113495bSYour Name 	}
4018*5113495bSYour Name 
4019*5113495bSYour Name 	return qdf_status;
4020*5113495bSYour Name }
4021*5113495bSYour Name 
4022*5113495bSYour Name /**
4023*5113495bSYour Name  * sap_fsm_state_stopping() - utility function called from sap fsm
4024*5113495bSYour Name  * @sap_ctx: SAP context
4025*5113495bSYour Name  * @sap_event: SAP event buffer
4026*5113495bSYour Name  * @mac_ctx: global MAC context
4027*5113495bSYour Name  * @mac_handle: Opaque handle to the global MAC context
4028*5113495bSYour Name  *
4029*5113495bSYour Name  * This function is called for state transition from "SAP_STOPPING"
4030*5113495bSYour Name  *
4031*5113495bSYour Name  * Return: QDF_STATUS
4032*5113495bSYour Name  */
4033*5113495bSYour Name static QDF_STATUS
sap_fsm_state_stopping(struct sap_context * sap_ctx,struct sap_sm_event * sap_event,struct mac_context * mac_ctx,mac_handle_t mac_handle)4034*5113495bSYour Name sap_fsm_state_stopping(struct sap_context *sap_ctx,
4035*5113495bSYour Name 		       struct sap_sm_event *sap_event,
4036*5113495bSYour Name 		       struct mac_context *mac_ctx,
4037*5113495bSYour Name 		       mac_handle_t mac_handle)
4038*5113495bSYour Name {
4039*5113495bSYour Name 	uint32_t msg = sap_event->event;
4040*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
4041*5113495bSYour Name 
4042*5113495bSYour Name 	if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) {
4043*5113495bSYour Name 		/*
4044*5113495bSYour Name 		 * Transition from SAP_STOPPING to SAP_INIT
4045*5113495bSYour Name 		 * (both without substates)
4046*5113495bSYour Name 		 */
4047*5113495bSYour Name 		sap_ctx->fsm_state = SAP_INIT;
4048*5113495bSYour Name 		sap_debug("sap_fsm: vdev %d: SAP_STOPPING => SAP_INIT",
4049*5113495bSYour Name 			  sap_ctx->vdev_id);
4050*5113495bSYour Name 
4051*5113495bSYour Name 		/* Close the SME session */
4052*5113495bSYour Name 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
4053*5113495bSYour Name 					eSAP_STOP_BSS_EVENT,
4054*5113495bSYour Name 					(void *)eSAP_STATUS_SUCCESS);
4055*5113495bSYour Name 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
4056*5113495bSYour Name 		/*
4057*5113495bSYour Name 		 * In case the SAP is already in stopping case and
4058*5113495bSYour Name 		 * we get a STOP request, return success.
4059*5113495bSYour Name 		 */
4060*5113495bSYour Name 		sap_debug("vdev %d SAP already in Stopping state",
4061*5113495bSYour Name 			  sap_ctx->vdev_id);
4062*5113495bSYour Name 		qdf_status = QDF_STATUS_SUCCESS;
4063*5113495bSYour Name 	} else {
4064*5113495bSYour Name 		sap_err("sap_fsm: vdev %d: SAP_STOPPING, invalid event %d",
4065*5113495bSYour Name 			sap_ctx->vdev_id, msg);
4066*5113495bSYour Name 	}
4067*5113495bSYour Name 
4068*5113495bSYour Name 	return qdf_status;
4069*5113495bSYour Name }
4070*5113495bSYour Name 
4071*5113495bSYour Name /**
4072*5113495bSYour Name  * sap_fsm() - SAP statem machine entry function
4073*5113495bSYour Name  * @sap_ctx: SAP context
4074*5113495bSYour Name  * @sap_event: SAP event
4075*5113495bSYour Name  *
4076*5113495bSYour Name  * SAP state machine entry function
4077*5113495bSYour Name  *
4078*5113495bSYour Name  * Return: QDF_STATUS
4079*5113495bSYour Name  */
sap_fsm(struct sap_context * sap_ctx,struct sap_sm_event * sap_event)4080*5113495bSYour Name QDF_STATUS sap_fsm(struct sap_context *sap_ctx, struct sap_sm_event *sap_event)
4081*5113495bSYour Name {
4082*5113495bSYour Name 	/*
4083*5113495bSYour Name 	 * Retrieve the phy link state machine structure
4084*5113495bSYour Name 	 * from the sap_ctx value
4085*5113495bSYour Name 	 * state var that keeps track of state machine
4086*5113495bSYour Name 	 */
4087*5113495bSYour Name 	enum sap_fsm_state state_var = sap_ctx->fsm_state;
4088*5113495bSYour Name 	uint32_t msg = sap_event->event; /* State machine input event message */
4089*5113495bSYour Name 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
4090*5113495bSYour Name 	struct mac_context *mac_ctx;
4091*5113495bSYour Name 	mac_handle_t mac_handle;
4092*5113495bSYour Name 
4093*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
4094*5113495bSYour Name 	if (!mac_ctx) {
4095*5113495bSYour Name 		sap_err("Invalid MAC context");
4096*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4097*5113495bSYour Name 	}
4098*5113495bSYour Name 	mac_handle = MAC_HANDLE(mac_ctx);
4099*5113495bSYour Name 
4100*5113495bSYour Name 	sap_debug("vdev %d: state %d event %d", sap_ctx->vdev_id, state_var,
4101*5113495bSYour Name 		  msg);
4102*5113495bSYour Name 
4103*5113495bSYour Name 	switch (state_var) {
4104*5113495bSYour Name 	case SAP_INIT:
4105*5113495bSYour Name 		qdf_status = sap_fsm_state_init(sap_ctx, sap_event,
4106*5113495bSYour Name 						mac_ctx, mac_handle);
4107*5113495bSYour Name 		break;
4108*5113495bSYour Name 
4109*5113495bSYour Name 	case SAP_STARTING:
4110*5113495bSYour Name 		qdf_status = sap_fsm_state_starting(sap_ctx, sap_event,
4111*5113495bSYour Name 						    mac_ctx, mac_handle);
4112*5113495bSYour Name 		break;
4113*5113495bSYour Name 
4114*5113495bSYour Name 	case SAP_STARTED:
4115*5113495bSYour Name 		qdf_status = sap_fsm_state_started(sap_ctx, sap_event,
4116*5113495bSYour Name 						   mac_ctx);
4117*5113495bSYour Name 		break;
4118*5113495bSYour Name 
4119*5113495bSYour Name 	case SAP_STOPPING:
4120*5113495bSYour Name 		qdf_status = sap_fsm_state_stopping(sap_ctx, sap_event,
4121*5113495bSYour Name 						    mac_ctx, mac_handle);
4122*5113495bSYour Name 		break;
4123*5113495bSYour Name 	}
4124*5113495bSYour Name 	return qdf_status;
4125*5113495bSYour Name }
4126*5113495bSYour Name 
sap_sort_mac_list(struct qdf_mac_addr * macList,uint16_t size)4127*5113495bSYour Name void sap_sort_mac_list(struct qdf_mac_addr *macList, uint16_t size)
4128*5113495bSYour Name {
4129*5113495bSYour Name 	uint16_t outer, inner;
4130*5113495bSYour Name 	struct qdf_mac_addr temp;
4131*5113495bSYour Name 	int32_t nRes = -1;
4132*5113495bSYour Name 
4133*5113495bSYour Name 	if ((!macList) || (size > MAX_ACL_MAC_ADDRESS)) {
4134*5113495bSYour Name 		sap_err("either buffer is NULL or size = %d is more", size);
4135*5113495bSYour Name 		return;
4136*5113495bSYour Name 	}
4137*5113495bSYour Name 
4138*5113495bSYour Name 	for (outer = 0; outer < size; outer++) {
4139*5113495bSYour Name 		for (inner = 0; inner < size - 1; inner++) {
4140*5113495bSYour Name 			nRes =
4141*5113495bSYour Name 				qdf_mem_cmp((macList + inner)->bytes,
4142*5113495bSYour Name 						 (macList + inner + 1)->bytes,
4143*5113495bSYour Name 						 QDF_MAC_ADDR_SIZE);
4144*5113495bSYour Name 			if (nRes > 0) {
4145*5113495bSYour Name 				qdf_mem_copy(temp.bytes,
4146*5113495bSYour Name 					     (macList + inner + 1)->bytes,
4147*5113495bSYour Name 					     QDF_MAC_ADDR_SIZE);
4148*5113495bSYour Name 				qdf_mem_copy((macList + inner + 1)->bytes,
4149*5113495bSYour Name 					     (macList + inner)->bytes,
4150*5113495bSYour Name 					     QDF_MAC_ADDR_SIZE);
4151*5113495bSYour Name 				qdf_mem_copy((macList + inner)->bytes,
4152*5113495bSYour Name 					     temp.bytes, QDF_MAC_ADDR_SIZE);
4153*5113495bSYour Name 			}
4154*5113495bSYour Name 		}
4155*5113495bSYour Name 	}
4156*5113495bSYour Name }
4157*5113495bSYour Name 
4158*5113495bSYour Name bool
sap_search_mac_list(struct qdf_mac_addr * macList,uint16_t num_mac,uint8_t * peerMac,uint16_t * index)4159*5113495bSYour Name sap_search_mac_list(struct qdf_mac_addr *macList,
4160*5113495bSYour Name 		    uint16_t num_mac, uint8_t *peerMac,
4161*5113495bSYour Name 		    uint16_t *index)
4162*5113495bSYour Name {
4163*5113495bSYour Name 	int32_t nRes = -1, nStart = 0, nEnd, nMiddle;
4164*5113495bSYour Name 
4165*5113495bSYour Name 	nEnd = num_mac - 1;
4166*5113495bSYour Name 
4167*5113495bSYour Name 	if ((!macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) {
4168*5113495bSYour Name 		sap_err("either buffer is NULL or size = %d is more", num_mac);
4169*5113495bSYour Name 		return false;
4170*5113495bSYour Name 	}
4171*5113495bSYour Name 
4172*5113495bSYour Name 	while (nStart <= nEnd) {
4173*5113495bSYour Name 		nMiddle = (nStart + nEnd) / 2;
4174*5113495bSYour Name 		nRes =
4175*5113495bSYour Name 			qdf_mem_cmp(&macList[nMiddle], peerMac,
4176*5113495bSYour Name 					 QDF_MAC_ADDR_SIZE);
4177*5113495bSYour Name 
4178*5113495bSYour Name 		if (0 == nRes) {
4179*5113495bSYour Name 			sap_debug("search SUCC");
4180*5113495bSYour Name 			/* "index equals NULL" means the caller does not need the */
4181*5113495bSYour Name 			/* index value of the peerMac being searched */
4182*5113495bSYour Name 			if (index) {
4183*5113495bSYour Name 				*index = (uint16_t)nMiddle;
4184*5113495bSYour Name 				sap_debug("index %d", *index);
4185*5113495bSYour Name 			}
4186*5113495bSYour Name 			return true;
4187*5113495bSYour Name 		}
4188*5113495bSYour Name 		if (nRes < 0)
4189*5113495bSYour Name 			nStart = nMiddle + 1;
4190*5113495bSYour Name 		else
4191*5113495bSYour Name 			nEnd = nMiddle - 1;
4192*5113495bSYour Name 	}
4193*5113495bSYour Name 
4194*5113495bSYour Name 	sap_debug("search not succ");
4195*5113495bSYour Name 	return false;
4196*5113495bSYour Name }
4197*5113495bSYour Name 
sap_add_mac_to_acl(struct qdf_mac_addr * macList,uint16_t * size,uint8_t * peerMac)4198*5113495bSYour Name void sap_add_mac_to_acl(struct qdf_mac_addr *macList,
4199*5113495bSYour Name 			uint16_t *size, uint8_t *peerMac)
4200*5113495bSYour Name {
4201*5113495bSYour Name 	int32_t nRes = -1;
4202*5113495bSYour Name 	int i;
4203*5113495bSYour Name 
4204*5113495bSYour Name 	sap_debug("add acl entered");
4205*5113495bSYour Name 
4206*5113495bSYour Name 	if (!macList || *size > MAX_ACL_MAC_ADDRESS) {
4207*5113495bSYour Name 		sap_debug("either buffer is NULL or size = %d is incorrect",
4208*5113495bSYour Name 			  *size);
4209*5113495bSYour Name 		return;
4210*5113495bSYour Name 	}
4211*5113495bSYour Name 
4212*5113495bSYour Name 	for (i = ((*size) - 1); i >= 0; i--) {
4213*5113495bSYour Name 		nRes =
4214*5113495bSYour Name 			qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE);
4215*5113495bSYour Name 		if (nRes > 0) {
4216*5113495bSYour Name 			/* Move alphabetically greater mac addresses one index down to allow for insertion
4217*5113495bSYour Name 			   of new mac in sorted order */
4218*5113495bSYour Name 			qdf_mem_copy((macList + i + 1)->bytes,
4219*5113495bSYour Name 				     (macList + i)->bytes, QDF_MAC_ADDR_SIZE);
4220*5113495bSYour Name 		} else {
4221*5113495bSYour Name 			break;
4222*5113495bSYour Name 		}
4223*5113495bSYour Name 	}
4224*5113495bSYour Name 	/* This should also take care of if the element is the first to be added in the list */
4225*5113495bSYour Name 	qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE);
4226*5113495bSYour Name 	/* increment the list size */
4227*5113495bSYour Name 	(*size)++;
4228*5113495bSYour Name }
4229*5113495bSYour Name 
sap_remove_mac_from_acl(struct qdf_mac_addr * macList,uint16_t * size,uint16_t index)4230*5113495bSYour Name void sap_remove_mac_from_acl(struct qdf_mac_addr *macList,
4231*5113495bSYour Name 			     uint16_t *size, uint16_t index)
4232*5113495bSYour Name {
4233*5113495bSYour Name 	int i;
4234*5113495bSYour Name 
4235*5113495bSYour Name 	sap_debug("remove acl entered");
4236*5113495bSYour Name 	/*
4237*5113495bSYour Name 	 * Return if the list passed is empty. Ideally this should never happen
4238*5113495bSYour Name 	 * since this funcn is always called after sap_search_mac_list to get
4239*5113495bSYour Name 	 * the index of the mac addr to be removed and this will only get
4240*5113495bSYour Name 	 * called if the search is successful. Still no harm in having the check
4241*5113495bSYour Name 	 */
4242*5113495bSYour Name 	if ((!macList) || (*size == 0) ||
4243*5113495bSYour Name 					(*size > MAX_ACL_MAC_ADDRESS)) {
4244*5113495bSYour Name 		sap_err("either buffer is NULL or size %d is incorrect",
4245*5113495bSYour Name 			 *size);
4246*5113495bSYour Name 		return;
4247*5113495bSYour Name 	}
4248*5113495bSYour Name 	for (i = index; i < ((*size) - 1); i++) {
4249*5113495bSYour Name 		/* Move mac addresses starting from "index" passed one index up to delete the void
4250*5113495bSYour Name 		   created by deletion of a mac address in ACL */
4251*5113495bSYour Name 		qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes,
4252*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
4253*5113495bSYour Name 	}
4254*5113495bSYour Name 	/* The last space should be made empty since all mac addresses moved one step up */
4255*5113495bSYour Name 	qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE);
4256*5113495bSYour Name 	/* reduce the list size by 1 */
4257*5113495bSYour Name 	(*size)--;
4258*5113495bSYour Name }
4259*5113495bSYour Name 
sap_print_acl(struct qdf_mac_addr * macList,uint16_t size)4260*5113495bSYour Name void sap_print_acl(struct qdf_mac_addr *macList, uint16_t size)
4261*5113495bSYour Name {
4262*5113495bSYour Name 	uint16_t i;
4263*5113495bSYour Name 	uint8_t *macArray;
4264*5113495bSYour Name 
4265*5113495bSYour Name 	sap_debug("print acl entered");
4266*5113495bSYour Name 
4267*5113495bSYour Name 	if ((!macList) || (size == 0) || (size > MAX_ACL_MAC_ADDRESS)) {
4268*5113495bSYour Name 		sap_err("Either buffer is NULL or size %d is incorrect", size);
4269*5113495bSYour Name 		return;
4270*5113495bSYour Name 	}
4271*5113495bSYour Name 
4272*5113495bSYour Name 	for (i = 0; i < size; i++) {
4273*5113495bSYour Name 		macArray = (macList + i)->bytes;
4274*5113495bSYour Name 		sap_debug("** ACL entry %i - " QDF_MAC_ADDR_FMT, i,
4275*5113495bSYour Name 			  QDF_MAC_ADDR_REF(macArray));
4276*5113495bSYour Name 	}
4277*5113495bSYour Name 	return;
4278*5113495bSYour Name }
4279*5113495bSYour Name 
sap_is_peer_mac_allowed(struct sap_context * sap_ctx,uint8_t * peerMac)4280*5113495bSYour Name QDF_STATUS sap_is_peer_mac_allowed(struct sap_context *sap_ctx,
4281*5113495bSYour Name 				   uint8_t *peerMac)
4282*5113495bSYour Name {
4283*5113495bSYour Name 	if (eSAP_ALLOW_ALL == sap_ctx->eSapMacAddrAclMode)
4284*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
4285*5113495bSYour Name 
4286*5113495bSYour Name 	if (sap_search_mac_list
4287*5113495bSYour Name 		    (sap_ctx->acceptMacList, sap_ctx->nAcceptMac, peerMac, NULL))
4288*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
4289*5113495bSYour Name 
4290*5113495bSYour Name 	if (sap_search_mac_list
4291*5113495bSYour Name 		    (sap_ctx->denyMacList, sap_ctx->nDenyMac, peerMac, NULL)) {
4292*5113495bSYour Name 		sap_err("Peer " QDF_MAC_ADDR_FMT " in deny list",
4293*5113495bSYour Name 			 QDF_MAC_ADDR_REF(peerMac));
4294*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4295*5113495bSYour Name 	}
4296*5113495bSYour Name 	/* A new station CAN associate, unless in deny list. Less stringent mode */
4297*5113495bSYour Name 	if (eSAP_ACCEPT_UNLESS_DENIED == sap_ctx->eSapMacAddrAclMode)
4298*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
4299*5113495bSYour Name 
4300*5113495bSYour Name 	/* A new station CANNOT associate, unless in accept list. More stringent mode */
4301*5113495bSYour Name 	if (eSAP_DENY_UNLESS_ACCEPTED == sap_ctx->eSapMacAddrAclMode) {
4302*5113495bSYour Name 		sap_debug("Peer " QDF_MAC_ADDR_FMT
4303*5113495bSYour Name 			  " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED",
4304*5113495bSYour Name 			  QDF_MAC_ADDR_REF(peerMac));
4305*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4306*5113495bSYour Name 	}
4307*5113495bSYour Name 
4308*5113495bSYour Name 	/* The new STA is neither in accept list nor in deny list. In this case, deny the association
4309*5113495bSYour Name 	 * but send a wifi event notification indicating the mac address being denied
4310*5113495bSYour Name 	 */
4311*5113495bSYour Name 	if (eSAP_SUPPORT_ACCEPT_AND_DENY == sap_ctx->eSapMacAddrAclMode) {
4312*5113495bSYour Name 		sap_signal_hdd_event(sap_ctx, NULL, eSAP_UNKNOWN_STA_JOIN,
4313*5113495bSYour Name 				     (void *) peerMac);
4314*5113495bSYour Name 		sap_debug("Peer " QDF_MAC_ADDR_FMT
4315*5113495bSYour Name 			  " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY",
4316*5113495bSYour Name 			  QDF_MAC_ADDR_REF(peerMac));
4317*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4318*5113495bSYour Name 	}
4319*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4320*5113495bSYour Name }
4321*5113495bSYour Name 
sap_dump_acs_channel(struct sap_acs_cfg * acs_cfg)4322*5113495bSYour Name void sap_dump_acs_channel(struct sap_acs_cfg *acs_cfg)
4323*5113495bSYour Name {
4324*5113495bSYour Name 	uint32_t buf_len = 0, len = 0, i;
4325*5113495bSYour Name 	uint8_t *chan_buff = NULL;
4326*5113495bSYour Name 
4327*5113495bSYour Name 	/*
4328*5113495bSYour Name 	 * Buffer of (num channel * 5) + 1  to consider the 4 char freq
4329*5113495bSYour Name 	 * and 1 space after it for each channel and 1 to end the string
4330*5113495bSYour Name 	 * with NULL.
4331*5113495bSYour Name 	 */
4332*5113495bSYour Name 	buf_len = (acs_cfg->ch_list_count * 5) + 1;
4333*5113495bSYour Name 	chan_buff = qdf_mem_malloc(buf_len);
4334*5113495bSYour Name 	if (!chan_buff)
4335*5113495bSYour Name 		return;
4336*5113495bSYour Name 
4337*5113495bSYour Name 	for (i = 0; i < acs_cfg->ch_list_count; i++)
4338*5113495bSYour Name 		len += qdf_scnprintf(chan_buff + len, buf_len - len,
4339*5113495bSYour Name 				     " %d", acs_cfg->freq_list[i]);
4340*5113495bSYour Name 
4341*5113495bSYour Name 	sap_nofl_debug("ACS freq list[%d]:%s",
4342*5113495bSYour Name 		       acs_cfg->ch_list_count, chan_buff);
4343*5113495bSYour Name 	qdf_mem_free(chan_buff);
4344*5113495bSYour Name }
4345*5113495bSYour Name 
4346*5113495bSYour Name #ifdef SOFTAP_CHANNEL_RANGE
4347*5113495bSYour Name /**
4348*5113495bSYour Name  * sap_get_freq_list() - get the list of channel frequency
4349*5113495bSYour Name  * @sap_ctx: sap context
4350*5113495bSYour Name  * @freq_list: pointer to channel list array
4351*5113495bSYour Name  * @num_ch: pointer to number of channels.
4352*5113495bSYour Name  *
4353*5113495bSYour Name  * This function populates the list of channel frequency for scanning.
4354*5113495bSYour Name  *
4355*5113495bSYour Name  * Return: QDF_STATUS
4356*5113495bSYour Name  */
sap_get_freq_list(struct sap_context * sap_ctx,uint32_t ** freq_list,uint8_t * num_ch)4357*5113495bSYour Name static QDF_STATUS sap_get_freq_list(struct sap_context *sap_ctx,
4358*5113495bSYour Name 				    uint32_t **freq_list,
4359*5113495bSYour Name 				    uint8_t *num_ch)
4360*5113495bSYour Name {
4361*5113495bSYour Name 	uint8_t loop_count;
4362*5113495bSYour Name 	uint32_t *list;
4363*5113495bSYour Name 	uint8_t ch_count;
4364*5113495bSYour Name 	uint8_t dfs_master_enable;
4365*5113495bSYour Name 	uint32_t start_ch_freq, band_start_ch;
4366*5113495bSYour Name 	uint32_t end_ch_freq, band_end_ch;
4367*5113495bSYour Name 	uint32_t en_lte_coex;
4368*5113495bSYour Name 	struct mac_context *mac_ctx;
4369*5113495bSYour Name 	uint16_t ch_width;
4370*5113495bSYour Name 	uint8_t normalize_factor = 100;
4371*5113495bSYour Name 	uint32_t chan_freq;
4372*5113495bSYour Name 	struct acs_weight *weight_list;
4373*5113495bSYour Name 	struct acs_weight_range *range_list;
4374*5113495bSYour Name 	bool freq_present_in_list = false;
4375*5113495bSYour Name 	uint8_t i;
4376*5113495bSYour Name 	bool srd_chan_enabled;
4377*5113495bSYour Name 	enum QDF_OPMODE vdev_opmode;
4378*5113495bSYour Name 
4379*5113495bSYour Name 	mac_ctx = sap_get_mac_context();
4380*5113495bSYour Name 	if (!mac_ctx) {
4381*5113495bSYour Name 		sap_err("Invalid MAC context");
4382*5113495bSYour Name 		*num_ch = 0;
4383*5113495bSYour Name 		*freq_list = NULL;
4384*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
4385*5113495bSYour Name 	}
4386*5113495bSYour Name 
4387*5113495bSYour Name 	weight_list = mac_ctx->mlme_cfg->acs.normalize_weight_chan;
4388*5113495bSYour Name 	range_list = mac_ctx->mlme_cfg->acs.normalize_weight_range;
4389*5113495bSYour Name 
4390*5113495bSYour Name 	dfs_master_enable = mac_ctx->mlme_cfg->dfs_cfg.dfs_master_capable;
4391*5113495bSYour Name 	if (sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE)
4392*5113495bSYour Name 		dfs_master_enable = false;
4393*5113495bSYour Name 
4394*5113495bSYour Name 	start_ch_freq = sap_ctx->acs_cfg->start_ch_freq;
4395*5113495bSYour Name 	end_ch_freq = sap_ctx->acs_cfg->end_ch_freq;
4396*5113495bSYour Name 	ch_width = sap_ctx->acs_cfg->ch_width;
4397*5113495bSYour Name 
4398*5113495bSYour Name 	sap_debug("startChannel %d, EndChannel %d, ch_width %d, HW:%d",
4399*5113495bSYour Name 		  start_ch_freq, end_ch_freq, ch_width,
4400*5113495bSYour Name 		  sap_ctx->acs_cfg->hw_mode);
4401*5113495bSYour Name 
4402*5113495bSYour Name 	wlansap_extend_to_acs_range(MAC_HANDLE(mac_ctx),
4403*5113495bSYour Name 				    &start_ch_freq, &end_ch_freq,
4404*5113495bSYour Name 				    &band_start_ch, &band_end_ch);
4405*5113495bSYour Name 
4406*5113495bSYour Name 	sap_debug("expanded startChannel %d,EndChannel %d band_start_ch %d, band_end_ch %d",
4407*5113495bSYour Name 		  start_ch_freq, end_ch_freq, band_start_ch, band_end_ch);
4408*5113495bSYour Name 
4409*5113495bSYour Name 	en_lte_coex = mac_ctx->mlme_cfg->sap_cfg.enable_lte_coex;
4410*5113495bSYour Name 
4411*5113495bSYour Name 	/* Check if LTE coex is enabled and 2.4GHz is selected */
4412*5113495bSYour Name 	if (en_lte_coex && (band_start_ch == CHAN_ENUM_2412) &&
4413*5113495bSYour Name 	    (band_end_ch == CHAN_ENUM_2484)) {
4414*5113495bSYour Name 		/* Set 2.4GHz upper limit to channel 9 for LTE COEX */
4415*5113495bSYour Name 		band_end_ch = CHAN_ENUM_2452;
4416*5113495bSYour Name 	}
4417*5113495bSYour Name 
4418*5113495bSYour Name 	/* Allocate the max number of channel supported */
4419*5113495bSYour Name 	list = qdf_mem_malloc((NUM_CHANNELS) * sizeof(uint32_t));
4420*5113495bSYour Name 	if (!list) {
4421*5113495bSYour Name 		*num_ch = 0;
4422*5113495bSYour Name 		*freq_list = NULL;
4423*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4424*5113495bSYour Name 	}
4425*5113495bSYour Name 
4426*5113495bSYour Name 	/* Search for the Active channels in the given range */
4427*5113495bSYour Name 	ch_count = 0;
4428*5113495bSYour Name 	for (loop_count = band_start_ch; loop_count <= band_end_ch;
4429*5113495bSYour Name 	     loop_count++) {
4430*5113495bSYour Name 		chan_freq = WLAN_REG_CH_TO_FREQ(loop_count);
4431*5113495bSYour Name 
4432*5113495bSYour Name 		/* go to next channel if rf_channel is out of range */
4433*5113495bSYour Name 		if (start_ch_freq > WLAN_REG_CH_TO_FREQ(loop_count) ||
4434*5113495bSYour Name 		    end_ch_freq < WLAN_REG_CH_TO_FREQ(loop_count))
4435*5113495bSYour Name 			continue;
4436*5113495bSYour Name 		/*
4437*5113495bSYour Name 		 * go to next channel if none of these condition pass
4438*5113495bSYour Name 		 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE
4439*5113495bSYour Name 		 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE
4440*5113495bSYour Name 		 */
4441*5113495bSYour Name 		if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) &&
4442*5113495bSYour Name 		      wlan_reg_get_channel_state_from_secondary_list_for_freq(
4443*5113495bSYour Name 			mac_ctx->pdev, WLAN_REG_CH_TO_FREQ(loop_count)))
4444*5113495bSYour Name 		      ||
4445*5113495bSYour Name 		    ((false == mac_ctx->scan.fEnableDFSChnlScan) &&
4446*5113495bSYour Name 		     (CHANNEL_STATE_ENABLE ==
4447*5113495bSYour Name 		      wlan_reg_get_channel_state_from_secondary_list_for_freq(
4448*5113495bSYour Name 			mac_ctx->pdev, WLAN_REG_CH_TO_FREQ(loop_count)))
4449*5113495bSYour Name 		     )))
4450*5113495bSYour Name 			continue;
4451*5113495bSYour Name 
4452*5113495bSYour Name 		/* check if the channel is in NOL denylist */
4453*5113495bSYour Name 		if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(WLAN_REG_CH_TO_FREQ(
4454*5113495bSYour Name 					loop_count))) {
4455*5113495bSYour Name 			if (sap_dfs_is_channel_in_nol_list(
4456*5113495bSYour Name 					sap_ctx,
4457*5113495bSYour Name 					chan_freq,
4458*5113495bSYour Name 					PHY_SINGLE_CHANNEL_CENTERED)) {
4459*5113495bSYour Name 				sap_debug("Ch freq %d in NOL list", chan_freq);
4460*5113495bSYour Name 				continue;
4461*5113495bSYour Name 			}
4462*5113495bSYour Name 		}
4463*5113495bSYour Name 		/* Skip DSRC channels */
4464*5113495bSYour Name 		if (wlan_reg_is_dsrc_freq(WLAN_REG_CH_TO_FREQ(loop_count)))
4465*5113495bSYour Name 			continue;
4466*5113495bSYour Name 
4467*5113495bSYour Name 		/*
4468*5113495bSYour Name 		 * Skip the channels which are not in ACS config from user
4469*5113495bSYour Name 		 * space
4470*5113495bSYour Name 		 */
4471*5113495bSYour Name 		if (!wlansap_is_channel_present_in_acs_list(
4472*5113495bSYour Name 					chan_freq,
4473*5113495bSYour Name 					sap_ctx->acs_cfg->freq_list,
4474*5113495bSYour Name 					sap_ctx->acs_cfg->ch_list_count))
4475*5113495bSYour Name 			continue;
4476*5113495bSYour Name 		/* Dont scan DFS channels in case of MCC disallowed
4477*5113495bSYour Name 		 * As it can result in SAP starting on DFS channel
4478*5113495bSYour Name 		 * resulting  MCC on DFS channel
4479*5113495bSYour Name 		 */
4480*5113495bSYour Name 		if (wlan_reg_is_dfs_in_secondary_list_for_freq(
4481*5113495bSYour Name 					mac_ctx->pdev,
4482*5113495bSYour Name 					WLAN_REG_CH_TO_FREQ(loop_count))) {
4483*5113495bSYour Name 			if (!dfs_master_enable)
4484*5113495bSYour Name 				continue;
4485*5113495bSYour Name 			if (wlansap_dcs_is_wlan_interference_mitigation_enabled(
4486*5113495bSYour Name 								sap_ctx))
4487*5113495bSYour Name 				sap_debug("dfs chan_freq %d added when dcs enabled",
4488*5113495bSYour Name 					  WLAN_REG_CH_TO_FREQ(loop_count));
4489*5113495bSYour Name 			else if (policy_mgr_disallow_mcc(
4490*5113495bSYour Name 					mac_ctx->psoc,
4491*5113495bSYour Name 					WLAN_REG_CH_TO_FREQ(loop_count)))
4492*5113495bSYour Name 				continue;
4493*5113495bSYour Name 			normalize_factor =
4494*5113495bSYour Name 				MLME_GET_DFS_CHAN_WEIGHT(
4495*5113495bSYour Name 				mac_ctx->mlme_cfg->acs.np_chan_weightage);
4496*5113495bSYour Name 			freq_present_in_list = true;
4497*5113495bSYour Name 		}
4498*5113495bSYour Name 
4499*5113495bSYour Name 		vdev_opmode = wlan_vdev_mlme_get_opmode(sap_ctx->vdev);
4500*5113495bSYour Name 		wlan_mlme_get_srd_master_mode_for_vdev(mac_ctx->psoc,
4501*5113495bSYour Name 						       vdev_opmode,
4502*5113495bSYour Name 						       &srd_chan_enabled);
4503*5113495bSYour Name 
4504*5113495bSYour Name 		if (!srd_chan_enabled &&
4505*5113495bSYour Name 		    wlan_reg_is_etsi_srd_chan_for_freq(
4506*5113495bSYour Name 					mac_ctx->pdev,
4507*5113495bSYour Name 					WLAN_REG_CH_TO_FREQ(loop_count))) {
4508*5113495bSYour Name 			sap_debug("vdev opmode %d not allowed on SRD freq %d",
4509*5113495bSYour Name 				  vdev_opmode, WLAN_REG_CH_TO_FREQ(loop_count));
4510*5113495bSYour Name 			continue;
4511*5113495bSYour Name 		}
4512*5113495bSYour Name 
4513*5113495bSYour Name 		/* Check if the freq is present in range list */
4514*5113495bSYour Name 		for (i = 0; i < mac_ctx->mlme_cfg->acs.num_weight_range; i++) {
4515*5113495bSYour Name 			if (chan_freq >= range_list[i].start_freq &&
4516*5113495bSYour Name 			    chan_freq <= range_list[i].end_freq) {
4517*5113495bSYour Name 				normalize_factor =
4518*5113495bSYour Name 					range_list[i].normalize_weight;
4519*5113495bSYour Name 				sap_debug("Range list, freq %d normalize weight factor %d",
4520*5113495bSYour Name 					  chan_freq, normalize_factor);
4521*5113495bSYour Name 				freq_present_in_list = true;
4522*5113495bSYour Name 			}
4523*5113495bSYour Name 		}
4524*5113495bSYour Name 
4525*5113495bSYour Name 		for (i = 0;
4526*5113495bSYour Name 		     i < mac_ctx->mlme_cfg->acs.normalize_weight_num_chan;
4527*5113495bSYour Name 		     i++) {
4528*5113495bSYour Name 			if (chan_freq == weight_list[i].chan_freq) {
4529*5113495bSYour Name 				normalize_factor =
4530*5113495bSYour Name 					weight_list[i].normalize_weight;
4531*5113495bSYour Name 				sap_debug("freq %d normalize weight factor %d",
4532*5113495bSYour Name 					  chan_freq, normalize_factor);
4533*5113495bSYour Name 				freq_present_in_list = true;
4534*5113495bSYour Name 			}
4535*5113495bSYour Name 		}
4536*5113495bSYour Name 
4537*5113495bSYour Name 		/* This would mean that the user does not want this freq */
4538*5113495bSYour Name 		if (freq_present_in_list && !normalize_factor) {
4539*5113495bSYour Name 			sap_debug("chan_freq %d ecluded normalize weight 0",
4540*5113495bSYour Name 				  chan_freq);
4541*5113495bSYour Name 			freq_present_in_list = false;
4542*5113495bSYour Name 			continue;
4543*5113495bSYour Name 		}
4544*5113495bSYour Name #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
4545*5113495bSYour Name 		if (sap_ctx->acs_cfg->skip_scan_status ==
4546*5113495bSYour Name 			eSAP_DO_PAR_ACS_SCAN) {
4547*5113495bSYour Name 			uint32_t ch_freq;
4548*5113495bSYour Name 
4549*5113495bSYour Name 			ch_freq = WLAN_REG_CH_TO_FREQ(loop_count);
4550*5113495bSYour Name 			if ((ch_freq >=
4551*5113495bSYour Name 				sap_ctx->acs_cfg->skip_scan_range1_stch &&
4552*5113495bSYour Name 			      ch_freq <=
4553*5113495bSYour Name 				sap_ctx->acs_cfg->skip_scan_range1_endch) ||
4554*5113495bSYour Name 			     (ch_freq >=
4555*5113495bSYour Name 				sap_ctx->acs_cfg->skip_scan_range2_stch &&
4556*5113495bSYour Name 			      ch_freq <=
4557*5113495bSYour Name 				sap_ctx->acs_cfg->skip_scan_range2_endch)) {
4558*5113495bSYour Name 				list[ch_count] =
4559*5113495bSYour Name 					WLAN_REG_CH_TO_FREQ(loop_count);
4560*5113495bSYour Name 				ch_count++;
4561*5113495bSYour Name 				sap_debug("%d %d added to ACS ch range",
4562*5113495bSYour Name 					  ch_count, ch_freq);
4563*5113495bSYour Name 			} else {
4564*5113495bSYour Name 				sap_debug("%d %d skipped from ACS ch range",
4565*5113495bSYour Name 					  ch_count, ch_freq);
4566*5113495bSYour Name 			}
4567*5113495bSYour Name 		} else {
4568*5113495bSYour Name 			list[ch_count] = WLAN_REG_CH_TO_FREQ(loop_count);
4569*5113495bSYour Name 			ch_count++;
4570*5113495bSYour Name 			sap_debug("%d added to ACS ch range", ch_count);
4571*5113495bSYour Name 		}
4572*5113495bSYour Name #else
4573*5113495bSYour Name 		list[ch_count] = WLAN_REG_CH_TO_FREQ(loop_count);
4574*5113495bSYour Name 		ch_count++;
4575*5113495bSYour Name #endif
4576*5113495bSYour Name 	}
4577*5113495bSYour Name 	if (!ch_count) {
4578*5113495bSYour Name 		sap_info("No active channels present for the current region");
4579*5113495bSYour Name 		/*
4580*5113495bSYour Name 		 * LTE COEX: channel range outside the restricted 2.4GHz
4581*5113495bSYour Name 		 * band limits
4582*5113495bSYour Name 		 */
4583*5113495bSYour Name 		if (en_lte_coex &&
4584*5113495bSYour Name 		    start_ch_freq > WLAN_REG_CH_TO_FREQ(band_end_ch))
4585*5113495bSYour Name 			sap_info("SAP can't be started as due to LTE COEX");
4586*5113495bSYour Name 	}
4587*5113495bSYour Name 
4588*5113495bSYour Name 	/* return the channel list and number of channels to scan */
4589*5113495bSYour Name 	*num_ch = ch_count;
4590*5113495bSYour Name 	if (ch_count != 0) {
4591*5113495bSYour Name 		*freq_list = list;
4592*5113495bSYour Name 	} else {
4593*5113495bSYour Name 		*freq_list = NULL;
4594*5113495bSYour Name 		qdf_mem_free(list);
4595*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
4596*5113495bSYour Name 	}
4597*5113495bSYour Name 
4598*5113495bSYour Name 	for (loop_count = 0; loop_count < ch_count; loop_count++) {
4599*5113495bSYour Name 		sap_ctx->acs_cfg->freq_list[loop_count] = list[loop_count];
4600*5113495bSYour Name 	}
4601*5113495bSYour Name 	sap_ctx->acs_cfg->ch_list_count = ch_count;
4602*5113495bSYour Name 	sap_dump_acs_channel(sap_ctx->acs_cfg);
4603*5113495bSYour Name 
4604*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4605*5113495bSYour Name }
4606*5113495bSYour Name #endif
4607*5113495bSYour Name 
4608*5113495bSYour Name #ifdef DFS_COMPONENT_ENABLE
sap_indicate_radar(struct sap_context * sap_ctx)4609*5113495bSYour Name qdf_freq_t sap_indicate_radar(struct sap_context *sap_ctx)
4610*5113495bSYour Name {
4611*5113495bSYour Name 	qdf_freq_t chan_freq = 0;
4612*5113495bSYour Name 	struct mac_context *mac;
4613*5113495bSYour Name 
4614*5113495bSYour Name 	if (!sap_ctx) {
4615*5113495bSYour Name 		sap_err("null sap_ctx");
4616*5113495bSYour Name 		return 0;
4617*5113495bSYour Name 	}
4618*5113495bSYour Name 
4619*5113495bSYour Name 	mac = sap_get_mac_context();
4620*5113495bSYour Name 	if (!mac) {
4621*5113495bSYour Name 		sap_err("Invalid MAC context");
4622*5113495bSYour Name 		return 0;
4623*5113495bSYour Name 	}
4624*5113495bSYour Name 
4625*5113495bSYour Name 	/*
4626*5113495bSYour Name 	 * SAP needs to generate Channel Switch IE
4627*5113495bSYour Name 	 * if the radar is found in the STARTED state
4628*5113495bSYour Name 	 */
4629*5113495bSYour Name 	if (sap_ctx->fsm_state == SAP_STARTED)
4630*5113495bSYour Name 		mac->sap.SapDfsInfo.csaIERequired = true;
4631*5113495bSYour Name 
4632*5113495bSYour Name 	if (mac->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) {
4633*5113495bSYour Name 		mac->sap.SapDfsInfo.new_chanWidth =
4634*5113495bSYour Name 					sap_ctx->ch_params.ch_width;
4635*5113495bSYour Name 		sap_debug("DFS channel switch disabled, CSA to same ch %d wd %d",
4636*5113495bSYour Name 			  sap_ctx->chan_freq, sap_ctx->ch_params.ch_width);
4637*5113495bSYour Name 		return sap_ctx->chan_freq;
4638*5113495bSYour Name 	}
4639*5113495bSYour Name 
4640*5113495bSYour Name 	/* set the Radar Found flag in SapDfsInfo */
4641*5113495bSYour Name 	sap_ctx->sap_radar_found_status = true;
4642*5113495bSYour Name 
4643*5113495bSYour Name 	chan_freq = wlan_pre_cac_get_freq_before_pre_cac(sap_ctx->vdev);
4644*5113495bSYour Name 	if (chan_freq) {
4645*5113495bSYour Name 		sap_info("sapdfs: set chan freq before pre cac %d as target chan",
4646*5113495bSYour Name 			 chan_freq);
4647*5113495bSYour Name 		return chan_freq;
4648*5113495bSYour Name 	}
4649*5113495bSYour Name 
4650*5113495bSYour Name 	if (sap_ctx->vendor_acs_dfs_lte_enabled && (QDF_STATUS_SUCCESS ==
4651*5113495bSYour Name 	    sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_NEXT_CHANNEL_REQ,
4652*5113495bSYour Name 	    (void *) eSAP_STATUS_SUCCESS)))
4653*5113495bSYour Name 		return 0;
4654*5113495bSYour Name 
4655*5113495bSYour Name 	if (!sap_is_chan_change_needed(sap_ctx))
4656*5113495bSYour Name 		return sap_ctx->chan_freq;
4657*5113495bSYour Name 
4658*5113495bSYour Name 	chan_freq = sap_random_channel_sel(sap_ctx);
4659*5113495bSYour Name 	if (!chan_freq)
4660*5113495bSYour Name 		sap_signal_hdd_event(sap_ctx, NULL,
4661*5113495bSYour Name 		eSAP_DFS_NO_AVAILABLE_CHANNEL, (void *) eSAP_STATUS_SUCCESS);
4662*5113495bSYour Name 
4663*5113495bSYour Name 	sap_warn("sapdfs: New selected target freq is [%d]", chan_freq);
4664*5113495bSYour Name 
4665*5113495bSYour Name 	return chan_freq;
4666*5113495bSYour Name }
4667*5113495bSYour Name #endif
4668*5113495bSYour Name 
4669*5113495bSYour Name /*
4670*5113495bSYour Name  * CAC timer callback function.
4671*5113495bSYour Name  * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm().
4672*5113495bSYour Name  */
sap_dfs_cac_timer_callback(void * data)4673*5113495bSYour Name void sap_dfs_cac_timer_callback(void *data)
4674*5113495bSYour Name {
4675*5113495bSYour Name 	struct sap_context *sap_ctx;
4676*5113495bSYour Name 	struct sap_sm_event sap_event;
4677*5113495bSYour Name 	mac_handle_t mac_handle = data;
4678*5113495bSYour Name 	struct mac_context *mac;
4679*5113495bSYour Name 
4680*5113495bSYour Name 	if (!mac_handle) {
4681*5113495bSYour Name 		sap_err("Invalid mac_handle");
4682*5113495bSYour Name 		return;
4683*5113495bSYour Name 	}
4684*5113495bSYour Name 	mac = MAC_CONTEXT(mac_handle);
4685*5113495bSYour Name 	sap_ctx = sap_find_cac_wait_session(mac_handle);
4686*5113495bSYour Name 	if (!sap_ctx) {
4687*5113495bSYour Name 		sap_err("no SAP contexts in wait state");
4688*5113495bSYour Name 		return;
4689*5113495bSYour Name 	}
4690*5113495bSYour Name 
4691*5113495bSYour Name 	if (mac->sap.SapDfsInfo.vdev_id != sap_ctx->vdev_id) {
4692*5113495bSYour Name 		sap_err("vdev mismatch sap_ctx->vdev_id %d mac->sap.SapDfsInfo.vdev_id %d",
4693*5113495bSYour Name 			sap_ctx->vdev_id, mac->sap.SapDfsInfo.vdev_id);
4694*5113495bSYour Name 		return;
4695*5113495bSYour Name 	}
4696*5113495bSYour Name 
4697*5113495bSYour Name 	/*
4698*5113495bSYour Name 	 * SAP may not be in CAC wait state, when the timer runs out.
4699*5113495bSYour Name 	 * if following flag is set, then timer is in initialized state,
4700*5113495bSYour Name 	 * destroy timer here.
4701*5113495bSYour Name 	 */
4702*5113495bSYour Name 	if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) {
4703*5113495bSYour Name 		if (!sap_ctx->dfs_cac_offload)
4704*5113495bSYour Name 			qdf_mc_timer_destroy(
4705*5113495bSYour Name 				&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
4706*5113495bSYour Name 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
4707*5113495bSYour Name 		mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
4708*5113495bSYour Name 	}
4709*5113495bSYour Name 
4710*5113495bSYour Name 	/*
4711*5113495bSYour Name 	 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm
4712*5113495bSYour Name 	 */
4713*5113495bSYour Name 	sap_debug("sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_chan_freq = %d on sapctx[%pK]",
4714*5113495bSYour Name 		  sap_ctx->chan_freq, sap_ctx);
4715*5113495bSYour Name 
4716*5113495bSYour Name 	sap_event.event = eSAP_DFS_CHANNEL_CAC_END;
4717*5113495bSYour Name 	sap_event.params = 0;
4718*5113495bSYour Name 	sap_event.u1 = 0;
4719*5113495bSYour Name 	sap_event.u2 = 0;
4720*5113495bSYour Name 
4721*5113495bSYour Name 	sap_fsm(sap_ctx, &sap_event);
4722*5113495bSYour Name }
4723*5113495bSYour Name 
4724*5113495bSYour Name /*
4725*5113495bSYour Name  * Function to stop the DFS CAC Timer
4726*5113495bSYour Name  */
sap_stop_dfs_cac_timer(struct sap_context * sap_ctx)4727*5113495bSYour Name static int sap_stop_dfs_cac_timer(struct sap_context *sap_ctx)
4728*5113495bSYour Name {
4729*5113495bSYour Name 	struct mac_context *mac;
4730*5113495bSYour Name 
4731*5113495bSYour Name 	if (!sap_ctx)
4732*5113495bSYour Name 		return 0;
4733*5113495bSYour Name 
4734*5113495bSYour Name 	mac = sap_get_mac_context();
4735*5113495bSYour Name 	if (!mac) {
4736*5113495bSYour Name 		sap_err("Invalid MAC context");
4737*5113495bSYour Name 		return 0;
4738*5113495bSYour Name 	}
4739*5113495bSYour Name 
4740*5113495bSYour Name 	if (mac->sap.SapDfsInfo.vdev_id != sap_ctx->vdev_id) {
4741*5113495bSYour Name 		sap_err("Invalid vdev Id sap_ctx_vdev_id %d mac_ctx vdev id %d",
4742*5113495bSYour Name 			sap_ctx->vdev_id, mac->sap.SapDfsInfo.vdev_id);
4743*5113495bSYour Name 		return 0;
4744*5113495bSYour Name 	}
4745*5113495bSYour Name 
4746*5113495bSYour Name 	if (sap_ctx->dfs_cac_offload) {
4747*5113495bSYour Name 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
4748*5113495bSYour Name 		mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
4749*5113495bSYour Name 		return 0;
4750*5113495bSYour Name 	}
4751*5113495bSYour Name 
4752*5113495bSYour Name 	if (QDF_TIMER_STATE_RUNNING !=
4753*5113495bSYour Name 	    qdf_mc_timer_get_current_state(&mac->sap.SapDfsInfo.
4754*5113495bSYour Name 					   sap_dfs_cac_timer)) {
4755*5113495bSYour Name 		return 0;
4756*5113495bSYour Name 	}
4757*5113495bSYour Name 
4758*5113495bSYour Name 	qdf_mc_timer_stop(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
4759*5113495bSYour Name 	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
4760*5113495bSYour Name 	mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
4761*5113495bSYour Name 	qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
4762*5113495bSYour Name 
4763*5113495bSYour Name 	return 0;
4764*5113495bSYour Name }
4765*5113495bSYour Name 
4766*5113495bSYour Name /*
4767*5113495bSYour Name  * Function to start the DFS CAC Timer
4768*5113495bSYour Name  * when SAP is started on a DFS channel
4769*5113495bSYour Name  */
sap_start_dfs_cac_timer(struct sap_context * sap_ctx)4770*5113495bSYour Name static int sap_start_dfs_cac_timer(struct sap_context *sap_ctx)
4771*5113495bSYour Name {
4772*5113495bSYour Name 	QDF_STATUS status;
4773*5113495bSYour Name 	uint32_t cac_dur;
4774*5113495bSYour Name 	struct mac_context *mac;
4775*5113495bSYour Name 	enum dfs_reg dfs_region;
4776*5113495bSYour Name 
4777*5113495bSYour Name 	if (!sap_ctx) {
4778*5113495bSYour Name 		sap_err("null sap_ctx");
4779*5113495bSYour Name 		return 0;
4780*5113495bSYour Name 	}
4781*5113495bSYour Name 
4782*5113495bSYour Name 	mac = sap_get_mac_context();
4783*5113495bSYour Name 	if (!mac) {
4784*5113495bSYour Name 		sap_err("Invalid MAC context");
4785*5113495bSYour Name 		return 0;
4786*5113495bSYour Name 	}
4787*5113495bSYour Name 	/* start time only when is_dfs_cac_timer_running is not running */
4788*5113495bSYour Name 	if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
4789*5113495bSYour Name 		sap_err("Invalid state is_dfs_cac_timer_running");
4790*5113495bSYour Name 		return 0;
4791*5113495bSYour Name 	}
4792*5113495bSYour Name 
4793*5113495bSYour Name 	if (sap_ctx->dfs_cac_offload) {
4794*5113495bSYour Name 		sap_debug("cac timer offloaded to firmware");
4795*5113495bSYour Name 		mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
4796*5113495bSYour Name 		mac->sap.SapDfsInfo.vdev_id = sap_ctx->vdev_id;
4797*5113495bSYour Name 		return 1;
4798*5113495bSYour Name 	}
4799*5113495bSYour Name 
4800*5113495bSYour Name 	sap_get_cac_dur_dfs_region(sap_ctx, &cac_dur, &dfs_region,
4801*5113495bSYour Name 				   sap_ctx->chan_freq, &sap_ctx->ch_params);
4802*5113495bSYour Name 	if (0 == cac_dur)
4803*5113495bSYour Name 		return 0;
4804*5113495bSYour Name 
4805*5113495bSYour Name #ifdef QCA_WIFI_EMULATION
4806*5113495bSYour Name 	cac_dur = cac_dur / 100;
4807*5113495bSYour Name #endif
4808*5113495bSYour Name 	sap_debug("sapdfs: SAP_DFS_CHANNEL_CAC_START on CH freq %d, CAC_DUR-%d sec",
4809*5113495bSYour Name 		  sap_ctx->chan_freq, cac_dur / 1000);
4810*5113495bSYour Name 
4811*5113495bSYour Name 	qdf_mc_timer_init(&mac->sap.SapDfsInfo.sap_dfs_cac_timer,
4812*5113495bSYour Name 			  QDF_TIMER_TYPE_SW,
4813*5113495bSYour Name 			  sap_dfs_cac_timer_callback, MAC_HANDLE(mac));
4814*5113495bSYour Name 
4815*5113495bSYour Name 	/* Start the CAC timer */
4816*5113495bSYour Name 	status = qdf_mc_timer_start(&mac->sap.SapDfsInfo.sap_dfs_cac_timer,
4817*5113495bSYour Name 			cac_dur);
4818*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
4819*5113495bSYour Name 		sap_err("failed to start cac timer");
4820*5113495bSYour Name 		goto destroy_timer;
4821*5113495bSYour Name 	}
4822*5113495bSYour Name 
4823*5113495bSYour Name 	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
4824*5113495bSYour Name 	mac->sap.SapDfsInfo.vdev_id = sap_ctx->vdev_id;
4825*5113495bSYour Name 
4826*5113495bSYour Name 	return 0;
4827*5113495bSYour Name 
4828*5113495bSYour Name destroy_timer:
4829*5113495bSYour Name 	mac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
4830*5113495bSYour Name 	mac->sap.SapDfsInfo.vdev_id = WLAN_INVALID_VDEV_ID;
4831*5113495bSYour Name 	qdf_mc_timer_destroy(&mac->sap.SapDfsInfo.sap_dfs_cac_timer);
4832*5113495bSYour Name 
4833*5113495bSYour Name 	return 1;
4834*5113495bSYour Name }
4835*5113495bSYour Name 
4836*5113495bSYour Name /*
4837*5113495bSYour Name  * This function initializes the NOL list
4838*5113495bSYour Name  * parameters required to track the radar
4839*5113495bSYour Name  * found DFS channels in the current Reg. Domain .
4840*5113495bSYour Name  */
sap_init_dfs_channel_nol_list(struct sap_context * sap_ctx)4841*5113495bSYour Name QDF_STATUS sap_init_dfs_channel_nol_list(struct sap_context *sap_ctx)
4842*5113495bSYour Name {
4843*5113495bSYour Name 	struct mac_context *mac;
4844*5113495bSYour Name 
4845*5113495bSYour Name 	if (!sap_ctx) {
4846*5113495bSYour Name 		sap_err("Invalid SAP context");
4847*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
4848*5113495bSYour Name 	}
4849*5113495bSYour Name 
4850*5113495bSYour Name 	mac = sap_get_mac_context();
4851*5113495bSYour Name 	if (!mac) {
4852*5113495bSYour Name 		sap_err("Invalid MAC context");
4853*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
4854*5113495bSYour Name 	}
4855*5113495bSYour Name 
4856*5113495bSYour Name 	utils_dfs_init_nol(mac->pdev);
4857*5113495bSYour Name 
4858*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4859*5113495bSYour Name }
4860*5113495bSYour Name 
4861*5113495bSYour Name /**
4862*5113495bSYour Name  * sap_is_active() - Check SAP active or not by sap_context object
4863*5113495bSYour Name  * @sap_ctx: Pointer to the SAP context
4864*5113495bSYour Name  *
4865*5113495bSYour Name  * Return: true if SAP is active
4866*5113495bSYour Name  */
sap_is_active(struct sap_context * sap_ctx)4867*5113495bSYour Name static bool sap_is_active(struct sap_context *sap_ctx)
4868*5113495bSYour Name {
4869*5113495bSYour Name 	return sap_ctx->fsm_state != SAP_INIT;
4870*5113495bSYour Name }
4871*5113495bSYour Name 
4872*5113495bSYour Name /*
4873*5113495bSYour Name  * This function will calculate how many interfaces
4874*5113495bSYour Name  * have sap persona and returns total number of sap persona.
4875*5113495bSYour Name  */
sap_get_total_number_sap_intf(mac_handle_t mac_handle)4876*5113495bSYour Name uint8_t sap_get_total_number_sap_intf(mac_handle_t mac_handle)
4877*5113495bSYour Name {
4878*5113495bSYour Name 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4879*5113495bSYour Name 	uint8_t intf = 0;
4880*5113495bSYour Name 	uint8_t intf_count = 0;
4881*5113495bSYour Name 	struct sap_context *sap_context;
4882*5113495bSYour Name 
4883*5113495bSYour Name 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
4884*5113495bSYour Name 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona)
4885*5113495bSYour Name 		    ||
4886*5113495bSYour Name 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona))
4887*5113495bSYour Name 		    && mac->sap.sapCtxList[intf].sap_context) {
4888*5113495bSYour Name 			sap_context =
4889*5113495bSYour Name 				mac->sap.sapCtxList[intf].sap_context;
4890*5113495bSYour Name 			if (!sap_is_active(sap_context))
4891*5113495bSYour Name 				continue;
4892*5113495bSYour Name 			intf_count++;
4893*5113495bSYour Name 		}
4894*5113495bSYour Name 	}
4895*5113495bSYour Name 	return intf_count;
4896*5113495bSYour Name }
4897*5113495bSYour Name 
4898*5113495bSYour Name /**
4899*5113495bSYour Name  * is_concurrent_sap_ready_for_channel_change() - to check all saps are ready
4900*5113495bSYour Name  *						  for channel change
4901*5113495bSYour Name  * @mac_handle: Opaque handle to the global MAC context
4902*5113495bSYour Name  * @sap_ctx: sap context for which this function has been called
4903*5113495bSYour Name  *
4904*5113495bSYour Name  * This function will find the concurrent sap context apart from
4905*5113495bSYour Name  * passed sap context and return its channel change ready status
4906*5113495bSYour Name  *
4907*5113495bSYour Name  *
4908*5113495bSYour Name  * Return: true if other SAP personas are ready to channel switch else false
4909*5113495bSYour Name  */
is_concurrent_sap_ready_for_channel_change(mac_handle_t mac_handle,struct sap_context * sap_ctx)4910*5113495bSYour Name bool is_concurrent_sap_ready_for_channel_change(mac_handle_t mac_handle,
4911*5113495bSYour Name 						struct sap_context *sap_ctx)
4912*5113495bSYour Name {
4913*5113495bSYour Name 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4914*5113495bSYour Name 	struct sap_context *sap_context;
4915*5113495bSYour Name 	uint8_t intf = 0;
4916*5113495bSYour Name 
4917*5113495bSYour Name 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
4918*5113495bSYour Name 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[intf].sapPersona)
4919*5113495bSYour Name 		    ||
4920*5113495bSYour Name 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[intf].sapPersona))
4921*5113495bSYour Name 		    && mac->sap.sapCtxList[intf].sap_context) {
4922*5113495bSYour Name 			sap_context =
4923*5113495bSYour Name 				mac->sap.sapCtxList[intf].sap_context;
4924*5113495bSYour Name 			if (!sap_is_active(sap_context))
4925*5113495bSYour Name 				continue;
4926*5113495bSYour Name 			if (sap_context == sap_ctx) {
4927*5113495bSYour Name 				sap_err("sapCtx matched [%pK]", sap_ctx);
4928*5113495bSYour Name 				continue;
4929*5113495bSYour Name 			} else {
4930*5113495bSYour Name 				sap_err("concurrent sapCtx[%pK] didn't matche with [%pK]",
4931*5113495bSYour Name 					 sap_context, sap_ctx);
4932*5113495bSYour Name 				return sap_context->is_sap_ready_for_chnl_chng;
4933*5113495bSYour Name 			}
4934*5113495bSYour Name 		}
4935*5113495bSYour Name 	}
4936*5113495bSYour Name 	return false;
4937*5113495bSYour Name }
4938*5113495bSYour Name 
4939*5113495bSYour Name /**
4940*5113495bSYour Name  * sap_is_conc_sap_doing_scc_dfs() - check if conc SAPs are doing SCC DFS
4941*5113495bSYour Name  * @mac_handle: Opaque handle to the global MAC context
4942*5113495bSYour Name  * @given_sapctx: current SAP persona's channel
4943*5113495bSYour Name  *
4944*5113495bSYour Name  * If provided SAP's channel is DFS then Loop through each SAP or GO persona and
4945*5113495bSYour Name  * check if other beaconing entity's channel is same DFS channel. If they are
4946*5113495bSYour Name  * same then concurrent sap is doing SCC DFS.
4947*5113495bSYour Name  *
4948*5113495bSYour Name  * Return: true if two or more beaconing entities doing SCC DFS else false
4949*5113495bSYour Name  */
sap_is_conc_sap_doing_scc_dfs(mac_handle_t mac_handle,struct sap_context * given_sapctx)4950*5113495bSYour Name bool sap_is_conc_sap_doing_scc_dfs(mac_handle_t mac_handle,
4951*5113495bSYour Name 				   struct sap_context *given_sapctx)
4952*5113495bSYour Name {
4953*5113495bSYour Name 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
4954*5113495bSYour Name 	struct sap_context *sap_ctx;
4955*5113495bSYour Name 	uint8_t intf = 0, scc_dfs_counter = 0;
4956*5113495bSYour Name 	qdf_freq_t ch_freq;
4957*5113495bSYour Name 
4958*5113495bSYour Name 	ch_freq = given_sapctx->chan_freq;
4959*5113495bSYour Name 	/*
4960*5113495bSYour Name 	 * current SAP persona's channel itself is not DFS, so no need to check
4961*5113495bSYour Name 	 * what other persona's channel is
4962*5113495bSYour Name 	 */
4963*5113495bSYour Name 	if (!wlan_reg_is_dfs_for_freq(mac->pdev,
4964*5113495bSYour Name 				      ch_freq)) {
4965*5113495bSYour Name 		sap_debug("skip this loop as provided channel is non-dfs");
4966*5113495bSYour Name 		return false;
4967*5113495bSYour Name 	}
4968*5113495bSYour Name 
4969*5113495bSYour Name 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
4970*5113495bSYour Name 		if ((QDF_SAP_MODE != mac->sap.sapCtxList[intf].sapPersona) &&
4971*5113495bSYour Name 		    (QDF_P2P_GO_MODE != mac->sap.sapCtxList[intf].sapPersona))
4972*5113495bSYour Name 			continue;
4973*5113495bSYour Name 		if (!mac->sap.sapCtxList[intf].sap_context)
4974*5113495bSYour Name 			continue;
4975*5113495bSYour Name 		sap_ctx = mac->sap.sapCtxList[intf].sap_context;
4976*5113495bSYour Name 		if (!sap_is_active(sap_ctx))
4977*5113495bSYour Name 			continue;
4978*5113495bSYour Name 		/* if same SAP contexts then skip to next context */
4979*5113495bSYour Name 		if (sap_ctx == given_sapctx)
4980*5113495bSYour Name 			continue;
4981*5113495bSYour Name 		if (given_sapctx->chan_freq == sap_ctx->chan_freq)
4982*5113495bSYour Name 			scc_dfs_counter++;
4983*5113495bSYour Name 	}
4984*5113495bSYour Name 
4985*5113495bSYour Name 	/* Found atleast two of the beaconing entities doing SCC DFS */
4986*5113495bSYour Name 	if (scc_dfs_counter)
4987*5113495bSYour Name 		return true;
4988*5113495bSYour Name 
4989*5113495bSYour Name 	return false;
4990*5113495bSYour Name }
4991*5113495bSYour Name 
4992*5113495bSYour Name /**
4993*5113495bSYour Name  * sap_build_start_bss_config() - Fill the start bss request for SAP
4994*5113495bSYour Name  * @sap_bss_cfg: start bss config
4995*5113495bSYour Name  * @config: sap config
4996*5113495bSYour Name  *
4997*5113495bSYour Name  * This function fills the start bss request for SAP
4998*5113495bSYour Name  *
4999*5113495bSYour Name  * Return: None
5000*5113495bSYour Name  */
5001*5113495bSYour Name void
sap_build_start_bss_config(struct start_bss_config * sap_bss_cfg,struct sap_config * config)5002*5113495bSYour Name sap_build_start_bss_config(struct start_bss_config *sap_bss_cfg,
5003*5113495bSYour Name 			   struct sap_config *config)
5004*5113495bSYour Name {
5005*5113495bSYour Name 	qdf_mem_zero(&sap_bss_cfg->ssId.ssId, sizeof(sap_bss_cfg->ssId.ssId));
5006*5113495bSYour Name 	sap_bss_cfg->ssId.length = config->SSIDinfo.ssid.length;
5007*5113495bSYour Name 	qdf_mem_copy(&sap_bss_cfg->ssId.ssId, config->SSIDinfo.ssid.ssId,
5008*5113495bSYour Name 		     config->SSIDinfo.ssid.length);
5009*5113495bSYour Name 
5010*5113495bSYour Name 	if (config->authType == eSAP_SHARED_KEY)
5011*5113495bSYour Name 		sap_bss_cfg->authType = eSIR_SHARED_KEY;
5012*5113495bSYour Name 	else if (config->authType == eSAP_OPEN_SYSTEM)
5013*5113495bSYour Name 		sap_bss_cfg->authType = eSIR_OPEN_SYSTEM;
5014*5113495bSYour Name 	else
5015*5113495bSYour Name 		sap_bss_cfg->authType = eSIR_AUTO_SWITCH;
5016*5113495bSYour Name 
5017*5113495bSYour Name 	sap_bss_cfg->beaconInterval = (uint16_t)config->beacon_int;
5018*5113495bSYour Name 	sap_bss_cfg->privacy = config->privacy;
5019*5113495bSYour Name 	sap_bss_cfg->ssidHidden = config->SSIDinfo.ssidHidden;
5020*5113495bSYour Name 	sap_bss_cfg->dtimPeriod = config->dtim_period;
5021*5113495bSYour Name 	sap_bss_cfg->wps_state = config->wps_state;
5022*5113495bSYour Name 	sap_bss_cfg->beacon_tx_rate = config->beacon_tx_rate;
5023*5113495bSYour Name 
5024*5113495bSYour Name 	/* RSNIE */
5025*5113495bSYour Name 	sap_bss_cfg->rsnIE.length = config->RSNWPAReqIELength;
5026*5113495bSYour Name 	if (config->RSNWPAReqIELength)
5027*5113495bSYour Name 		qdf_mem_copy(sap_bss_cfg->rsnIE.rsnIEdata,
5028*5113495bSYour Name 			     config->RSNWPAReqIE, config->RSNWPAReqIELength);
5029*5113495bSYour Name 
5030*5113495bSYour Name 	/* Probe response IE */
5031*5113495bSYour Name 	if (config->probeRespIEsBufferLen > 0 &&
5032*5113495bSYour Name 	    config->pProbeRespIEsBuffer) {
5033*5113495bSYour Name 		sap_bss_cfg->add_ie_params.probeRespDataLen =
5034*5113495bSYour Name 						config->probeRespIEsBufferLen;
5035*5113495bSYour Name 		sap_bss_cfg->add_ie_params.probeRespData_buff =
5036*5113495bSYour Name 						config->pProbeRespIEsBuffer;
5037*5113495bSYour Name 	} else {
5038*5113495bSYour Name 		sap_bss_cfg->add_ie_params.probeRespDataLen = 0;
5039*5113495bSYour Name 		sap_bss_cfg->add_ie_params.probeRespData_buff = NULL;
5040*5113495bSYour Name 	}
5041*5113495bSYour Name 
5042*5113495bSYour Name 	/*assoc resp IE */
5043*5113495bSYour Name 	if (config->assocRespIEsLen > 0 && config->pAssocRespIEsBuffer) {
5044*5113495bSYour Name 		sap_bss_cfg->add_ie_params.assocRespDataLen =
5045*5113495bSYour Name 						config->assocRespIEsLen;
5046*5113495bSYour Name 		sap_bss_cfg->add_ie_params.assocRespData_buff =
5047*5113495bSYour Name 						config->pAssocRespIEsBuffer;
5048*5113495bSYour Name 	} else {
5049*5113495bSYour Name 		sap_bss_cfg->add_ie_params.assocRespDataLen = 0;
5050*5113495bSYour Name 		sap_bss_cfg->add_ie_params.assocRespData_buff = NULL;
5051*5113495bSYour Name 	}
5052*5113495bSYour Name 
5053*5113495bSYour Name 	if (config->probeRespBcnIEsLen > 0 &&
5054*5113495bSYour Name 	    config->pProbeRespBcnIEsBuffer) {
5055*5113495bSYour Name 		sap_bss_cfg->add_ie_params.probeRespBCNDataLen =
5056*5113495bSYour Name 						config->probeRespBcnIEsLen;
5057*5113495bSYour Name 		sap_bss_cfg->add_ie_params.probeRespBCNData_buff =
5058*5113495bSYour Name 						config->pProbeRespBcnIEsBuffer;
5059*5113495bSYour Name 	} else {
5060*5113495bSYour Name 		sap_bss_cfg->add_ie_params.probeRespBCNDataLen = 0;
5061*5113495bSYour Name 		sap_bss_cfg->add_ie_params.probeRespBCNData_buff = NULL;
5062*5113495bSYour Name 	}
5063*5113495bSYour Name 
5064*5113495bSYour Name 	if (config->supported_rates.numRates) {
5065*5113495bSYour Name 		qdf_mem_copy(sap_bss_cfg->operationalRateSet.rate,
5066*5113495bSYour Name 			     config->supported_rates.rate,
5067*5113495bSYour Name 			     config->supported_rates.numRates);
5068*5113495bSYour Name 		sap_bss_cfg->operationalRateSet.numRates =
5069*5113495bSYour Name 					config->supported_rates.numRates;
5070*5113495bSYour Name 	}
5071*5113495bSYour Name 
5072*5113495bSYour Name 	if (config->extended_rates.numRates) {
5073*5113495bSYour Name 		qdf_mem_copy(sap_bss_cfg->extendedRateSet.rate,
5074*5113495bSYour Name 			     config->extended_rates.rate,
5075*5113495bSYour Name 			     config->extended_rates.numRates);
5076*5113495bSYour Name 		sap_bss_cfg->extendedRateSet.numRates =
5077*5113495bSYour Name 				config->extended_rates.numRates;
5078*5113495bSYour Name 	}
5079*5113495bSYour Name 
5080*5113495bSYour Name 	return;
5081*5113495bSYour Name }
5082