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