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