blob: 1d93e445d2368b23e203daaeb0304b8321a3772f [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Dustin Browndb2a8be2017-12-20 11:49:56 -08002 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019/**
20 * DOC: wlan_hdd_hostapd.c
21 *
22 * WLAN Host Device Driver implementation
23 */
24
25/* Include Files */
26
27#include <linux/version.h>
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/init.h>
31#include <linux/wireless.h>
32#include <linux/semaphore.h>
33#include <linux/compat.h>
Venkata Sharath Chandra Manchala83985632017-02-28 14:16:22 -080034#include <cdp_txrx_cmn.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080035#include <cds_api.h>
36#include <cds_sched.h>
37#include <linux/etherdevice.h>
38#include <wlan_hdd_includes.h>
39#include <qc_sap_ioctl.h>
40#include <wlan_hdd_hostapd.h>
Rachit Kankane0dc3e852018-05-07 17:33:42 +053041#include <wlan_hdd_hostapd_wext.h>
Jeff Johnson8bb61112018-03-31 13:33:54 -070042#include <wlan_hdd_green_ap.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080043#include <sap_api.h>
44#include <sap_internal.h>
45#include <wlan_hdd_softap_tx_rx.h>
46#include <wlan_hdd_main.h>
47#include <wlan_hdd_ioctl.h>
48#include <wlan_hdd_stats.h>
49#include <linux/netdevice.h>
50#include <linux/rtnetlink.h>
51#include <linux/mmc/sdio_func.h>
52#include "wlan_hdd_p2p.h"
53#include <wlan_hdd_ipa.h>
54#include "cfg_api.h"
55#include "wni_cfg.h"
56#include "wlan_hdd_misc.h"
57#include <cds_utils.h>
Yuanyuan Liu13738502016-04-06 17:41:37 -070058#include "pld_common.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059
60#include "wma.h"
Srinivas Girigowda6147c582016-10-18 12:26:15 -070061#ifdef WLAN_DEBUG
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062#include "wma_api.h"
63#endif
64#include "wlan_hdd_trace.h"
Dustin Brownd4241942018-02-26 12:51:37 -080065#include "qdf_str.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053066#include "qdf_types.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053067#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080068#include "wlan_hdd_cfg.h"
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080069#include "wlan_policy_mgr_api.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -070070#include "wlan_hdd_tsf.h"
Dhanashri Atrea8f82f22017-01-23 12:58:24 -080071#include <cdp_txrx_misc.h>
Rajeev Kumar699debf2017-01-06 14:17:00 -080072#include "wlan_hdd_object_manager.h"
Sandeep Puligillafdd201e2017-02-02 18:43:46 -080073#include <qca_vendor.h>
Venkata Sharath Chandra Manchala83985632017-02-28 14:16:22 -080074#include <cds_api.h>
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -080075#include "wlan_hdd_he.h"
Arif Hussaincd151632017-02-11 16:57:19 -080076#include "wlan_dfs_tgt_api.h"
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -070077#include <wlan_reg_ucfg_api.h>
Naveen Rawat08db88f2017-09-08 15:07:48 -070078#include "wlan_utility.h"
Wu Gaoc02785d2017-09-07 18:17:13 +080079#include <wlan_p2p_ucfg_api.h>
Naveen Rawatd8feac12017-09-08 15:08:39 -070080#include "sir_api.h"
Mukul Sharmaecf8e092017-12-19 22:36:31 +053081#include "sme_api.h"
82#include "wlan_hdd_regulatory.h"
Sravan Kumar Kairam271fab22018-03-07 18:57:41 +053083#include <wlan_ipa_ucfg_api.h>
Yu Wangc0b46f82018-03-09 16:04:15 +080084#include <wlan_cp_stats_mc_ucfg_api.h>
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -080085
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080086#define ACS_SCAN_EXPIRY_TIMEOUT_S 4
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080087
Will Huang496b36c2017-07-11 16:38:50 +080088/*
89 * 11B, 11G Rate table include Basic rate and Extended rate
90 * The IDX field is the rate index
91 * The HI field is the rate when RSSI is strong or being ignored
92 * (in this case we report actual rate)
93 * The MID field is the rate when RSSI is moderate
94 * (in this case we cap 11b rates at 5.5 and 11g rates at 24)
95 * The LO field is the rate when RSSI is low
96 * (in this case we don't report rates, actual current rate used)
97 */
98static const struct index_data_rate_type supported_data_rate[] = {
99 /* IDX HI HM LM LO (RSSI-based index */
100 {2, { 10, 10, 10, 0} },
101 {4, { 20, 20, 10, 0} },
102 {11, { 55, 20, 10, 0} },
103 {12, { 60, 55, 20, 0} },
104 {18, { 90, 55, 20, 0} },
105 {22, {110, 55, 20, 0} },
106 {24, {120, 90, 60, 0} },
107 {36, {180, 120, 60, 0} },
108 {44, {220, 180, 60, 0} },
109 {48, {240, 180, 90, 0} },
110 {66, {330, 180, 90, 0} },
111 {72, {360, 240, 90, 0} },
112 {96, {480, 240, 120, 0} },
113 {108, {540, 240, 120, 0} }
114};
115
116/* MCS Based rate table */
117/* HT MCS parameters with Nss = 1 */
118static const struct index_data_rate_type supported_mcs_rate_nss1[] = {
119 /* MCS L20 L40 S20 S40 */
120 {0, { 65, 135, 72, 150} },
121 {1, { 130, 270, 144, 300} },
122 {2, { 195, 405, 217, 450} },
123 {3, { 260, 540, 289, 600} },
124 {4, { 390, 810, 433, 900} },
125 {5, { 520, 1080, 578, 1200} },
126 {6, { 585, 1215, 650, 1350} },
127 {7, { 650, 1350, 722, 1500} }
128};
129
130/* HT MCS parameters with Nss = 2 */
131static const struct index_data_rate_type supported_mcs_rate_nss2[] = {
132 /* MCS L20 L40 S20 S40 */
133 {0, {130, 270, 144, 300} },
134 {1, {260, 540, 289, 600} },
135 {2, {390, 810, 433, 900} },
136 {3, {520, 1080, 578, 1200} },
137 {4, {780, 1620, 867, 1800} },
138 {5, {1040, 2160, 1156, 2400} },
139 {6, {1170, 2430, 1300, 2700} },
140 {7, {1300, 2700, 1444, 3000} }
141};
142
143/* MCS Based VHT rate table */
144/* MCS parameters with Nss = 1*/
145static const struct index_vht_data_rate_type supported_vht_mcs_rate_nss1[] = {
146 /* MCS L80 S80 L40 S40 L20 S40*/
147 {0, {293, 325}, {135, 150}, {65, 72} },
148 {1, {585, 650}, {270, 300}, {130, 144} },
149 {2, {878, 975}, {405, 450}, {195, 217} },
150 {3, {1170, 1300}, {540, 600}, {260, 289} },
151 {4, {1755, 1950}, {810, 900}, {390, 433} },
152 {5, {2340, 2600}, {1080, 1200}, {520, 578} },
153 {6, {2633, 2925}, {1215, 1350}, {585, 650} },
154 {7, {2925, 3250}, {1350, 1500}, {650, 722} },
155 {8, {3510, 3900}, {1620, 1800}, {780, 867} },
156 {9, {3900, 4333}, {1800, 2000}, {780, 867} }
157};
158
159/*MCS parameters with Nss = 2*/
160static const struct index_vht_data_rate_type supported_vht_mcs_rate_nss2[] = {
161 /* MCS L80 S80 L40 S40 L20 S40*/
162 {0, {585, 650}, {270, 300}, {130, 144} },
163 {1, {1170, 1300}, {540, 600}, {260, 289} },
164 {2, {1755, 1950}, {810, 900}, {390, 433} },
165 {3, {2340, 2600}, {1080, 1200}, {520, 578} },
166 {4, {3510, 3900}, {1620, 1800}, {780, 867} },
167 {5, {4680, 5200}, {2160, 2400}, {1040, 1156} },
168 {6, {5265, 5850}, {2430, 2700}, {1170, 1300} },
169 {7, {5850, 6500}, {2700, 3000}, {1300, 1444} },
170 {8, {7020, 7800}, {3240, 3600}, {1560, 1733} },
171 {9, {7800, 8667}, {3600, 4000}, {1560, 1733} }
172};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800173
174/* Function definitions */
175
176/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700177 * hdd_sap_context_init() - Initialize SAP context.
178 * @hdd_ctx: HDD context.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800179 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700180 * Initialize SAP context.
181 *
182 * Return: 0 on success.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800183 */
Jeff Johnsonc54bbf92017-08-28 11:59:35 -0700184int hdd_sap_context_init(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800185{
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700186 qdf_wake_lock_create(&hdd_ctx->sap_dfs_wakelock, "sap_dfs_wakelock");
187 atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0);
188
189 mutex_init(&hdd_ctx->sap_lock);
190 qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock");
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +0530191 qdf_spinlock_create(&hdd_ctx->sap_update_info_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700192
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700193 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800194}
195
Krunal Sonib51eec72017-11-20 21:53:01 -0800196/**
197 * hdd_hostapd_init_sap_session() - To init the sap session completely
198 * @adapter: SAP/GO adapter
199 *
200 * This API will do
201 * 1) sap_init_ctx()
202 *
203 * Return: 0 if success else non-zero value.
204 */
205static struct sap_context *
206hdd_hostapd_init_sap_session(struct hdd_adapter *adapter)
Krunal Soni4a020c72017-10-30 20:58:40 -0700207{
208 struct sap_context *sap_ctx;
Krunal Soni4a020c72017-10-30 20:58:40 -0700209 QDF_STATUS status;
210
211 if (!adapter) {
212 hdd_err("invalid adapter");
213 return NULL;
214 }
Krunal Soni4a020c72017-10-30 20:58:40 -0700215
Krunal Sonib51eec72017-11-20 21:53:01 -0800216 sap_ctx = adapter->session.ap.sap_context;
Krunal Soni4a020c72017-10-30 20:58:40 -0700217
218 if (!sap_ctx) {
219 hdd_err("can't allocate the sap_ctx");
220 return NULL;
221 }
Krunal Soni59437652017-11-21 13:42:14 -0800222 status = sap_init_ctx(sap_ctx, adapter->device_mode,
Jeff Johnson1e851a12017-10-28 14:36:12 -0700223 adapter->mac_addr.bytes,
Jeff Johnson1b780e42017-10-31 14:11:45 -0700224 adapter->session_id);
Krunal Soni4a020c72017-10-30 20:58:40 -0700225 if (QDF_IS_STATUS_ERROR(status)) {
226 hdd_err("wlansap_start failed!! status: %d", status);
Jeff Johnsonb9424862017-10-30 08:49:35 -0700227 adapter->session.ap.sap_context = NULL;
Krunal Soni4a020c72017-10-30 20:58:40 -0700228 goto error;
229 }
Krunal Soni4a020c72017-10-30 20:58:40 -0700230 return sap_ctx;
231error:
232 wlansap_context_put(sap_ctx);
233 hdd_err("releasing the sap context for session-id:%d",
Jeff Johnson1b780e42017-10-31 14:11:45 -0700234 adapter->session_id);
Krunal Soni4a020c72017-10-30 20:58:40 -0700235
236 return NULL;
237}
238
Krunal Sonib51eec72017-11-20 21:53:01 -0800239/**
240 * hdd_hostapd_deinit_sap_session() - To de-init the sap session completely
241 * @adapter: SAP/GO adapter
242 *
243 * This API will do
244 * 1) sap_init_ctx()
245 * 2) sap_destroy_ctx()
246 *
247 * Return: 0 if success else non-zero value.
248 */
249static int hdd_hostapd_deinit_sap_session(struct hdd_adapter *adapter)
Krunal Soni4a020c72017-10-30 20:58:40 -0700250{
251 struct sap_context *sap_ctx;
252 int status = 0;
253
254 if (!adapter) {
255 hdd_err("invalid adapter");
256 return -EINVAL;
257 }
258
259 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
260 if (!sap_ctx) {
261 hdd_debug("sap context already released, nothing to be done");
262 return 0;
263 }
264
Krunal Soni59437652017-11-21 13:42:14 -0800265 if (!QDF_IS_STATUS_SUCCESS(sap_deinit_ctx(sap_ctx))) {
Krunal Soni4a020c72017-10-30 20:58:40 -0700266 hdd_err("Error stopping the sap session");
267 status = -EINVAL;
268 }
Krunal Sonib51eec72017-11-20 21:53:01 -0800269
Krunal Soni59437652017-11-21 13:42:14 -0800270 if (!QDF_IS_STATUS_SUCCESS(sap_destroy_ctx(sap_ctx))) {
Krunal Soni4a020c72017-10-30 20:58:40 -0700271 hdd_err("Error closing the sap session");
272 status = -EINVAL;
273 }
Jeff Johnsonb9424862017-10-30 08:49:35 -0700274 adapter->session.ap.sap_context = NULL;
Krunal Soni4a020c72017-10-30 20:58:40 -0700275
Krunal Soni4a020c72017-10-30 20:58:40 -0700276 if (!QDF_IS_STATUS_SUCCESS(status))
277 hdd_debug("sap has issue closing the session");
278 else
279 hdd_debug("sap has been closed successfully");
280
281
282 return status;
283}
284
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800285/**
286 * hdd_hostapd_channel_allow_suspend() - allow suspend in a channel.
287 * Called when, 1. bss stopped, 2. channel switch
288 *
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700289 * @adapter: pointer to hdd adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800290 * @channel: current channel
291 *
292 * Return: None
293 */
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700294static void hdd_hostapd_channel_allow_suspend(struct hdd_adapter *adapter,
Jeff Johnsone4090f72016-10-05 16:00:23 -0700295 uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800296{
297
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700298 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson5c19ade2017-10-04 09:52:12 -0700299 struct hdd_hostapd_state *hostapd_state =
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700300 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800301
Jeff Johnson0f9f87b2017-10-28 09:21:06 -0700302 hdd_debug("bss_state: %d, channel: %d, dfs_ref_cnt: %d",
303 hostapd_state->bss_state, channel,
Jeff Johnson23c3b842017-09-03 09:05:29 -0700304 atomic_read(&hdd_ctx->sap_dfs_ref_cnt));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800305
306 /* Return if BSS is already stopped */
Jeff Johnson0f9f87b2017-10-28 09:21:06 -0700307 if (hostapd_state->bss_state == BSS_STOP)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800308 return;
309
Jeff Johnson23c3b842017-09-03 09:05:29 -0700310 if (CHANNEL_STATE_DFS != wlan_reg_get_channel_state(hdd_ctx->hdd_pdev,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700311 channel))
Komal Seelam81cb1662016-09-29 12:39:08 +0530312 return;
313
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800314 /* Release wakelock when no more DFS channels are used */
Jeff Johnson23c3b842017-09-03 09:05:29 -0700315 if (atomic_dec_and_test(&hdd_ctx->sap_dfs_ref_cnt)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -0800316 hdd_err("DFS: allowing suspend (chan: %d)", channel);
Jeff Johnson23c3b842017-09-03 09:05:29 -0700317 qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock,
Komal Seelam81cb1662016-09-29 12:39:08 +0530318 WIFI_POWER_EVENT_WAKELOCK_DFS);
Jeff Johnson23c3b842017-09-03 09:05:29 -0700319 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.dfs);
Komal Seelam81cb1662016-09-29 12:39:08 +0530320
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800321 }
322}
323
324/**
325 * hdd_hostapd_channel_prevent_suspend() - prevent suspend in a channel.
326 * Called when, 1. bss started, 2. channel switch
327 *
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700328 * @adapter: pointer to hdd adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800329 * @channel: current channel
330 *
331 * Return - None
332 */
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700333static void hdd_hostapd_channel_prevent_suspend(struct hdd_adapter *adapter,
Jeff Johnsone4090f72016-10-05 16:00:23 -0700334 uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800335{
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700336 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson5c19ade2017-10-04 09:52:12 -0700337 struct hdd_hostapd_state *hostapd_state =
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700338 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800339
Jeff Johnson0f9f87b2017-10-28 09:21:06 -0700340 hdd_debug("bss_state: %d, channel: %d, dfs_ref_cnt: %d",
341 hostapd_state->bss_state, channel,
Jeff Johnson23c3b842017-09-03 09:05:29 -0700342 atomic_read(&hdd_ctx->sap_dfs_ref_cnt));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800343
344 /* Return if BSS is already started && wakelock is acquired */
Jeff Johnson0f9f87b2017-10-28 09:21:06 -0700345 if ((hostapd_state->bss_state == BSS_START) &&
Jeff Johnson23c3b842017-09-03 09:05:29 -0700346 (atomic_read(&hdd_ctx->sap_dfs_ref_cnt) >= 1))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800347 return;
348
Jeff Johnson23c3b842017-09-03 09:05:29 -0700349 if (CHANNEL_STATE_DFS != wlan_reg_get_channel_state(hdd_ctx->hdd_pdev,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700350 channel))
Komal Seelam81cb1662016-09-29 12:39:08 +0530351 return;
352
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800353 /* Acquire wakelock if we have at least one DFS channel in use */
Jeff Johnson23c3b842017-09-03 09:05:29 -0700354 if (atomic_inc_return(&hdd_ctx->sap_dfs_ref_cnt) == 1) {
Srinivas Girigowda55756882017-03-06 16:45:27 -0800355 hdd_err("DFS: preventing suspend (chan: %d)", channel);
Jeff Johnson23c3b842017-09-03 09:05:29 -0700356 qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.dfs);
357 qdf_wake_lock_acquire(&hdd_ctx->sap_dfs_wakelock,
Komal Seelam81cb1662016-09-29 12:39:08 +0530358 WIFI_POWER_EVENT_WAKELOCK_DFS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800359 }
360}
361
362/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700363 * hdd_sap_context_destroy() - Destroy SAP context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800364 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700365 * @hdd_ctx: HDD context.
366 *
367 * Destroy SAP context.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800368 *
369 * Return: None
370 */
Jeff Johnsonc54bbf92017-08-28 11:59:35 -0700371void hdd_sap_context_destroy(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800372{
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700373 if (atomic_read(&hdd_ctx->sap_dfs_ref_cnt)) {
374 qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800375 WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT);
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700376
377 atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0);
Srinivas Girigowda55756882017-03-06 16:45:27 -0800378 hdd_debug("DFS: Allowing suspend");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379 }
380
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700381 qdf_wake_lock_destroy(&hdd_ctx->sap_dfs_wakelock);
382
383 mutex_destroy(&hdd_ctx->sap_lock);
384 qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock);
385
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +0530386 qdf_spinlock_destroy(&hdd_ctx->sap_update_info_lock);
387
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800388}
389
390/**
391 * __hdd_hostapd_open() - hdd open function for hostapd interface
392 * This is called in response to ifconfig up
393 * @dev: pointer to net_device structure
394 *
395 * Return - 0 for success non-zero for failure
396 */
397static int __hdd_hostapd_open(struct net_device *dev)
398{
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700399 struct hdd_adapter *adapter = netdev_priv(dev);
400 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Arunk Khandavalli702e1702016-12-06 18:01:55 +0530401 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800402
Dustin Brownfdf17c12018-03-14 12:55:34 -0700403 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530405 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800406 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
Krunal Soni4a020c72017-10-30 20:58:40 -0700407 /* Nothing to be done if device is unloading */
408 if (cds_is_driver_unloading()) {
409 hdd_err("Driver is unloading can not open the hdd");
410 return -EBUSY;
411 }
412
413 if (cds_is_driver_recovering()) {
414 hdd_err("WLAN is currently recovering; Please try again.");
415 return -EBUSY;
416 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800417
Arunk Khandavalli702e1702016-12-06 18:01:55 +0530418 ret = wlan_hdd_validate_context(hdd_ctx);
419 if (ret)
420 return ret;
421 /*
422 * Check statemachine state and also stop iface change timer if running
423 */
Dustin Browne7e71d32018-05-11 16:00:08 -0700424 ret = hdd_wlan_start_modules(hdd_ctx, false);
Arunk Khandavalli702e1702016-12-06 18:01:55 +0530425
426 if (ret) {
427 hdd_err("Failed to start WLAN modules return");
428 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800429 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800430
Krunal Soni4a020c72017-10-30 20:58:40 -0700431 ret = hdd_start_adapter(adapter);
432 if (ret) {
433 hdd_err("Error Initializing the AP mode: %d", ret);
434 return ret;
435 }
436
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700437 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Krunal Soni4a020c72017-10-30 20:58:40 -0700438
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800439 /* Enable all Tx queues */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700440 hdd_debug("Enabling queues");
Jeff Johnsonfd33cce2017-10-02 13:28:39 -0700441 wlan_hdd_netif_queue_control(adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800442 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
443 WLAN_CONTROL_PATH);
Dustin Browne74003f2018-03-14 12:51:58 -0700444 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800445 return 0;
446}
447
448/**
449 * hdd_hostapd_open() - SSR wrapper for __hdd_hostapd_open
450 * @dev: pointer to net device
451 *
452 * Return: 0 on success, error number otherwise
453 */
454static int hdd_hostapd_open(struct net_device *dev)
455{
456 int ret;
457
458 cds_ssr_protect(__func__);
459 ret = __hdd_hostapd_open(dev);
460 cds_ssr_unprotect(__func__);
461
462 return ret;
463}
464
465/**
466 * __hdd_hostapd_stop() - hdd stop function for hostapd interface
467 * This is called in response to ifconfig down
468 *
469 * @dev: pointer to net_device structure
470 *
471 * Return - 0 for success non-zero for failure
472 */
473static int __hdd_hostapd_stop(struct net_device *dev)
474{
Jeff Johnson866aca82017-09-10 15:27:20 -0700475 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsonc54bbf92017-08-28 11:59:35 -0700476 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manikandan Mohanfa7b7fe2017-02-15 14:53:31 -0800477 int ret;
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800478
Dustin Brownfdf17c12018-03-14 12:55:34 -0700479 hdd_enter_dev(dev);
Manikandan Mohanfa7b7fe2017-02-15 14:53:31 -0800480 ret = wlan_hdd_validate_context(hdd_ctx);
481 if (ret)
482 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800483
Krunal Soni4a020c72017-10-30 20:58:40 -0700484 /*
Krunal Soni4a020c72017-10-30 20:58:40 -0700485 * Some tests requires to do "ifconfig down" only to bring
486 * down the SAP/GO without killing hostapd/wpa_supplicant.
487 * In such case, user will do "ifconfig up" to bring-back
488 * the SAP/GO session. to fulfill this requirement, driver
489 * needs to de-init the sap session here and re-init when
490 * __hdd_hostapd_open() API
491 */
Dustin Browndb2a8be2017-12-20 11:49:56 -0800492 hdd_stop_adapter(hdd_ctx, adapter);
Krunal Soni4a020c72017-10-30 20:58:40 -0700493 hdd_deinit_adapter(hdd_ctx, adapter, true);
Arun Khandavalli97f28382016-09-09 17:36:50 +0530494 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Hanumanth Reddy Pothula3862ca92018-01-12 16:44:10 +0530495
496 if (!hdd_is_cli_iface_up(hdd_ctx))
Jeff Johnson89a0c742018-06-12 18:17:46 -0700497 sme_scan_flush_result(hdd_ctx->mac_handle);
Hanumanth Reddy Pothula3862ca92018-01-12 16:44:10 +0530498
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800499 /* Stop all tx queues */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700500 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +0530501 wlan_hdd_netif_queue_control(adapter,
502 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
503 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800504
Dustin Browne74003f2018-03-14 12:51:58 -0700505 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800506 return 0;
507}
508
509/**
510 * hdd_hostapd_stop() - SSR wrapper for__hdd_hostapd_stop
511 * @dev: pointer to net_device
512 *
513 * This is called in response to ifconfig down
514 *
515 * Return: 0 on success, error number otherwise
516 */
517int hdd_hostapd_stop(struct net_device *dev)
518{
519 int ret;
520
521 cds_ssr_protect(__func__);
522 ret = __hdd_hostapd_stop(dev);
523 cds_ssr_unprotect(__func__);
524
525 return ret;
526}
527
528/**
529 * __hdd_hostapd_uninit() - hdd uninit function
530 * This is called during the netdev unregister to uninitialize all data
531 * associated with the device.
532 *
533 * @dev: pointer to net_device structure
534 *
535 * Return: None
536 */
537static void __hdd_hostapd_uninit(struct net_device *dev)
538{
Jeff Johnson866aca82017-09-10 15:27:20 -0700539 struct hdd_adapter *adapter = netdev_priv(dev);
Jeff Johnsonc54bbf92017-08-28 11:59:35 -0700540 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800541
Dustin Brownfdf17c12018-03-14 12:55:34 -0700542 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800543
544 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700545 hdd_err("Invalid magic");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800546 return;
547 }
548
549 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
550 if (NULL == hdd_ctx) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700551 hdd_err("NULL hdd_ctx");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800552 return;
553 }
554
555 hdd_deinit_adapter(hdd_ctx, adapter, true);
556
557 /* after uninit our adapter structure will no longer be valid */
558 adapter->dev = NULL;
559 adapter->magic = 0;
560
Dustin Browne74003f2018-03-14 12:51:58 -0700561 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800562}
563
564/**
565 * hdd_hostapd_uninit() - SSR wrapper for __hdd_hostapd_uninit
566 * @dev: pointer to net_device
567 *
568 * Return: 0 on success, error number otherwise
569 */
570static void hdd_hostapd_uninit(struct net_device *dev)
571{
572 cds_ssr_protect(__func__);
573 __hdd_hostapd_uninit(dev);
574 cds_ssr_unprotect(__func__);
575}
576
577/**
578 * __hdd_hostapd_change_mtu() - change mtu
579 * @dev: pointer to net_device
580 * @new_mtu: new mtu
581 *
582 * Return: 0 on success, error number otherwise
583 */
584static int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
585{
Dustin Brownfdf17c12018-03-14 12:55:34 -0700586 hdd_enter_dev(dev);
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800587
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800588 return 0;
589}
590
591/**
592 * hdd_hostapd_change_mtu() - SSR wrapper for __hdd_hostapd_change_mtu
593 * @dev: pointer to net_device
594 * @new_mtu: new mtu
595 *
596 * Return: 0 on success, error number otherwise
597 */
598static int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
599{
600 int ret;
601
602 cds_ssr_protect(__func__);
603 ret = __hdd_hostapd_change_mtu(dev, new_mtu);
604 cds_ssr_unprotect(__func__);
605
606 return ret;
607}
608
609#ifdef QCA_HT_2040_COEX
Jeff Johnson9c4f93d2017-10-04 08:56:22 -0700610QDF_STATUS hdd_set_sap_ht2040_mode(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611 uint8_t channel_type)
612{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530613 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
Jeff Johnson89a0c742018-06-12 18:17:46 -0700614 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800615
Srinivas Girigowda55756882017-03-06 16:45:27 -0800616 hdd_debug("change HT20/40 mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800617
Jeff Johnson9c4f93d2017-10-04 08:56:22 -0700618 if (QDF_SAP_MODE == adapter->device_mode) {
Jeff Johnson89a0c742018-06-12 18:17:46 -0700619 mac_handle = adapter->hdd_ctx->mac_handle;
620 if (!mac_handle) {
621 hdd_err("mac handle is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530622 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800623 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530624 qdf_ret_status =
Jeff Johnson89a0c742018-06-12 18:17:46 -0700625 sme_set_ht2040_mode(mac_handle, adapter->session_id,
626 channel_type, true);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530627 if (qdf_ret_status == QDF_STATUS_E_FAILURE) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700628 hdd_err("Failed to change HT20/40 mode");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530629 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630 }
631 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530632 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800633}
634#endif
635
636/**
637 * __hdd_hostapd_set_mac_address() -
638 * This function sets the user specified mac address using
639 * the command ifconfig wlanX hw ether <mac address>.
640 *
641 * @dev: pointer to the net device.
642 * @addr: pointer to the sockaddr.
643 *
644 * Return: 0 for success, non zero for failure
645 */
646static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
647{
648 struct sockaddr *psta_mac_addr = addr;
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +0530649 struct hdd_adapter *adapter, *adapter_temp;
Jeff Johnsonc54bbf92017-08-28 11:59:35 -0700650 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800651 int ret = 0;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +0530652 struct qdf_mac_addr mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800653
Dustin Brownfdf17c12018-03-14 12:55:34 -0700654 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655
656 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
657 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
658 ret = wlan_hdd_validate_context(hdd_ctx);
659 if (0 != ret)
660 return ret;
661
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +0530662 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +0530663 adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
664 if (adapter_temp) {
665 if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
666 return 0;
667 hdd_err("%s adapter exist with same address " MAC_ADDRESS_STR,
668 adapter_temp->dev->name,
Ashish Kumar Dhanotiyaf974f332018-04-19 16:03:15 +0530669 MAC_ADDR_ARRAY(mac_addr.bytes));
670 return -EINVAL;
671 }
672
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +0530673 if (qdf_is_macaddr_zero(&mac_addr)) {
674 hdd_err("MAC is all zero");
675 return -EINVAL;
676 }
677
678 if (qdf_is_macaddr_broadcast(&mac_addr)) {
679 hdd_err("MAC is Broadcast");
680 return -EINVAL;
681 }
682
683 if (ETHER_IS_MULTICAST(psta_mac_addr->sa_data)) {
684 hdd_err("MAC is Multicast");
685 return -EINVAL;
686 }
687
Ashish Kumar Dhanotiya8bfef122018-04-18 16:48:27 +0530688 hdd_info("Changing MAC to " MAC_ADDRESS_STR " of interface %s ",
689 MAC_ADDR_ARRAY(mac_addr.bytes),
690 dev->name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800691 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
Dustin Browne74003f2018-03-14 12:51:58 -0700692 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693 return 0;
694}
695
696/**
697 * hdd_hostapd_set_mac_address() - set mac address
698 * @dev: pointer to net_device
699 * @addr: mac address
700 *
701 * Return: 0 on success, error number otherwise
702 */
703static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
704{
705 int ret;
706
707 cds_ssr_protect(__func__);
708 ret = __hdd_hostapd_set_mac_address(dev, addr);
709 cds_ssr_unprotect(__func__);
710
711 return ret;
712}
713
Jeff Johnsone4b24872017-10-27 08:37:12 -0700714static void hdd_clear_sta(struct hdd_adapter *adapter, uint8_t sta_id)
715{
716 struct hdd_ap_ctx *ap_ctx;
717 struct hdd_station_info *sta_info;
Jeff Johnsone6bf7192017-11-07 15:16:09 -0800718 struct csr_del_sta_params del_sta_params;
Jeff Johnsone4b24872017-10-27 08:37:12 -0700719
720 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
721
722 if (sta_id == ap_ctx->broadcast_sta_id)
723 return;
724
725 sta_info = &adapter->sta_info[sta_id];
726 if (!sta_info->in_use)
727 return;
728
729 wlansap_populate_del_sta_params(sta_info->sta_mac.bytes,
730 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
731 (SIR_MAC_MGMT_DISASSOC >> 4),
732 &del_sta_params);
733
734 hdd_softap_sta_disassoc(adapter, &del_sta_params);
735}
736
Jeff Johnsonb55bf512017-10-26 13:38:18 -0700737static void hdd_clear_all_sta(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800738{
Jeff Johnsone4b24872017-10-27 08:37:12 -0700739 uint8_t sta_id;
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -0700740
Dustin Brownfdf17c12018-03-14 12:55:34 -0700741 hdd_enter_dev(adapter->dev);
Jeff Johnsone4b24872017-10-27 08:37:12 -0700742 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++)
743 hdd_clear_sta(adapter, sta_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800744}
745
Jeff Johnson0604a362018-03-24 17:36:59 -0700746static int hdd_stop_bss_link(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747{
Jeff Johnson0604a362018-03-24 17:36:59 -0700748 struct hdd_context *hdd_ctx;
749 int errno;
750 QDF_STATUS status;
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -0700751
Dustin Brown491d54b2018-03-14 12:39:11 -0700752 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800753
Jeff Johnson9c4f93d2017-10-04 08:56:22 -0700754 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson0604a362018-03-24 17:36:59 -0700755 errno = wlan_hdd_validate_context(hdd_ctx);
756 if (errno)
757 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800758
Jeff Johnson9c4f93d2017-10-04 08:56:22 -0700759 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Dustin Brown5118e8e2016-09-13 15:54:23 -0700760 status = wlansap_stop_bss(
Jeff Johnson9c4f93d2017-10-04 08:56:22 -0700761 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530762 if (QDF_IS_STATUS_SUCCESS(status))
Srinivas Girigowda55756882017-03-06 16:45:27 -0800763 hdd_debug("Deleting SAP/P2P link!!!!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800764
Jeff Johnson9c4f93d2017-10-04 08:56:22 -0700765 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Jeff Johnson23c3b842017-09-03 09:05:29 -0700766 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -0700767 adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -0700768 adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -0700769 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +0530770 false);
Jeff Johnson0604a362018-03-24 17:36:59 -0700771 errno = (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800772 }
Dustin Browne74003f2018-03-14 12:51:58 -0700773 hdd_exit();
Jeff Johnson0604a362018-03-24 17:36:59 -0700774 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800775}
776
777/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 * hdd_chan_change_notify() - Function to notify hostapd about channel change
bings58ce8622017-07-10 15:55:36 +0800779 * @hostapd_adapter: hostapd adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800780 * @dev: Net device structure
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +0530781 * @chan_change: New channel change parameters
bings58ce8622017-07-10 15:55:36 +0800782 * @legacy_phymode: is the phymode legacy
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800783 *
784 * This function is used to notify hostapd about the channel change
785 *
786 * Return: Success on intimating userspace
787 *
788 */
Jeff Johnson866aca82017-09-10 15:27:20 -0700789QDF_STATUS hdd_chan_change_notify(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800790 struct net_device *dev,
bings58ce8622017-07-10 15:55:36 +0800791 struct hdd_chan_change_params chan_change,
792 bool legacy_phymode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800793{
794 struct ieee80211_channel *chan;
795 struct cfg80211_chan_def chandef;
796 enum nl80211_channel_type channel_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800797 uint32_t freq;
Jeff Johnson89a0c742018-06-12 18:17:46 -0700798 mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799
Jeff Johnson89a0c742018-06-12 18:17:46 -0700800 if (!mac_handle) {
801 hdd_err("mac_handle is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530802 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803 }
804
Srinivas Girigowda55756882017-03-06 16:45:27 -0800805 hdd_debug("chan:%d width:%d sec_ch_offset:%d seg0:%d seg1:%d",
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +0530806 chan_change.chan, chan_change.chan_params.ch_width,
807 chan_change.chan_params.sec_ch_offset,
808 chan_change.chan_params.center_freq_seg0,
809 chan_change.chan_params.center_freq_seg1);
810
811 freq = cds_chan_to_freq(chan_change.chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800812
Dustin Brown2eb1e452017-08-15 12:40:34 -0700813 chan = ieee80211_get_channel(adapter->wdev.wiphy, freq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800814
815 if (!chan) {
816 hdd_err("Invalid input frequency for channel conversion");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530817 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800818 }
819
bings58ce8622017-07-10 15:55:36 +0800820 if (legacy_phymode) {
821 channel_type = NL80211_CHAN_NO_HT;
822 } else {
bingsbd6bc472017-06-23 10:14:40 +0800823 switch (chan_change.chan_params.sec_ch_offset) {
824 case PHY_SINGLE_CHANNEL_CENTERED:
825 channel_type = NL80211_CHAN_HT20;
826 break;
827 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
828 channel_type = NL80211_CHAN_HT40MINUS;
829 break;
830 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
831 channel_type = NL80211_CHAN_HT40PLUS;
832 break;
833 default:
834 channel_type = NL80211_CHAN_NO_HT;
835 break;
836 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800837 }
838
839 cfg80211_chandef_create(&chandef, chan, channel_type);
840
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +0530841 /* cfg80211_chandef_create() does update of width and center_freq1
842 * only for NL80211_CHAN_NO_HT, NL80211_CHAN_HT20, NL80211_CHAN_HT40PLUS
843 * and NL80211_CHAN_HT40MINUS.
844 */
845 if (chan_change.chan_params.ch_width == CH_WIDTH_80MHZ)
846 chandef.width = NL80211_CHAN_WIDTH_80;
847 else if (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ)
848 chandef.width = NL80211_CHAN_WIDTH_80P80;
849 else if (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ)
850 chandef.width = NL80211_CHAN_WIDTH_160;
851
852 if ((chan_change.chan_params.ch_width == CH_WIDTH_80MHZ) ||
853 (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ) ||
854 (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ)) {
855 if (chan_change.chan_params.center_freq_seg0)
856 chandef.center_freq1 = cds_chan_to_freq(
857 chan_change.chan_params.center_freq_seg0);
858
859 if (chan_change.chan_params.center_freq_seg1)
860 chandef.center_freq2 = cds_chan_to_freq(
861 chan_change.chan_params.center_freq_seg1);
862 }
863
Srinivas Girigowda55756882017-03-06 16:45:27 -0800864 hdd_debug("notify: chan:%d width:%d freq1:%d freq2:%d",
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +0530865 chandef.chan->center_freq, chandef.width, chandef.center_freq1,
866 chandef.center_freq2);
Wu Gao2c3a8002016-01-22 10:56:07 +0800867
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800868 cfg80211_ch_switch_notify(dev, &chandef);
869
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530870 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800871}
872
873/**
874 * hdd_send_radar_event() - Function to send radar events to user space
875 * @hdd_context: HDD context
876 * @event: Type of radar event
877 * @dfs_info: Structure containing DFS channel and country
878 * @wdev: Wireless device structure
879 *
880 * This function is used to send radar events such as CAC start, CAC
881 * end etc., to userspace
882 *
883 * Return: Success on sending notifying userspace
884 *
885 */
Jeff Johnsonc54bbf92017-08-28 11:59:35 -0700886static QDF_STATUS hdd_send_radar_event(struct hdd_context *hdd_context,
Jeff Johnsone4090f72016-10-05 16:00:23 -0700887 eSapHddEvent event,
888 struct wlan_dfs_info dfs_info,
889 struct wireless_dev *wdev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800890{
891
892 struct sk_buff *vendor_event;
893 enum qca_nl80211_vendor_subcmds_index index;
894 uint32_t freq, ret;
895 uint32_t data_size;
896
897 if (!hdd_context) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700898 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530899 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800900 }
901
902 freq = cds_chan_to_freq(dfs_info.channel);
903
904 switch (event) {
905 case eSAP_DFS_CAC_START:
906 index =
907 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX;
908 data_size = sizeof(uint32_t);
909 break;
910 case eSAP_DFS_CAC_END:
911 index =
912 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX;
913 data_size = sizeof(uint32_t);
914 break;
915 case eSAP_DFS_RADAR_DETECT:
916 index =
917 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX;
918 data_size = sizeof(uint32_t);
919 break;
920 default:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530921 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800922 }
923
924 vendor_event = cfg80211_vendor_event_alloc(hdd_context->wiphy,
925 wdev,
926 data_size + NLMSG_HDRLEN,
927 index,
928 GFP_KERNEL);
929 if (!vendor_event) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700930 hdd_err("cfg80211_vendor_event_alloc failed for %d", index);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530931 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800932 }
933
934 ret = nla_put_u32(vendor_event, NL80211_ATTR_WIPHY_FREQ, freq);
935
936 if (ret) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700937 hdd_err("NL80211_ATTR_WIPHY_FREQ put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800938 kfree_skb(vendor_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530939 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800940 }
941
942 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530943 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944}
945
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +0530946/**
947 * hdd_send_conditional_chan_switch_status() - Send conditional channel switch
948 * status
949 * @hdd_ctx: HDD context
950 * @wdev: Wireless device structure
951 * @status: Status of conditional channel switch
952 * (0: Success, Non-zero: Failure)
953 *
954 * Sends the status of conditional channel switch to user space. This is named
955 * conditional channel switch because the SAP will move to the provided channel
956 * after some condition (pre-cac) is met.
957 *
958 * Return: None
959 */
Jeff Johnsonc54bbf92017-08-28 11:59:35 -0700960static void hdd_send_conditional_chan_switch_status(struct hdd_context *hdd_ctx,
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +0530961 struct wireless_dev *wdev,
962 bool status)
963{
964 struct sk_buff *event;
965
Dustin Brownfdf17c12018-03-14 12:55:34 -0700966 hdd_enter_dev(wdev->netdev);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +0530967
968 if (!hdd_ctx) {
969 hdd_err("Invalid HDD context pointer");
970 return;
971 }
972
973 event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
974 wdev, sizeof(uint32_t) + NLMSG_HDRLEN,
975 QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH_INDEX,
976 GFP_KERNEL);
977 if (!event) {
978 hdd_err("cfg80211_vendor_event_alloc failed");
979 return;
980 }
981
982 if (nla_put_u32(event,
983 QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_STATUS,
984 status)) {
985 hdd_err("nla put failed");
986 kfree_skb(event);
987 return;
988 }
989
990 cfg80211_vendor_event(event, GFP_KERNEL);
991}
992
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +0530993/**
994 * wlan_hdd_set_pre_cac_complete_status() - Set pre cac complete status
995 * @ap_adapter: AP adapter
996 * @status: Status which can be true or false
997 *
998 * Sets the status of pre cac i.e., whether it is complete or not
999 *
1000 * Return: Zero on success, non-zero on failure
1001 */
Jeff Johnson866aca82017-09-10 15:27:20 -07001002static int wlan_hdd_set_pre_cac_complete_status(struct hdd_adapter *ap_adapter,
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301003 bool status)
1004{
1005 QDF_STATUS ret;
1006
1007 ret = wlan_sap_set_pre_cac_complete_status(
1008 WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), status);
1009 if (QDF_IS_STATUS_ERROR(ret))
1010 return -EINVAL;
1011
1012 return 0;
1013}
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301014
1015/**
Liangwei Dongad89c762018-06-01 01:56:23 -04001016 * hdd_check_adapter() - check adapter existing or not
1017 * @adapter: adapter
1018 *
1019 * Check adapter in the hdd global list or not
1020 *
1021 * Return: true if adapter exists.
1022 */
1023static bool hdd_check_adapter(struct hdd_adapter *adapter)
1024{
1025 struct hdd_adapter *temp;
1026 struct hdd_context *hdd_ctx;
1027
1028 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
1029 if (!hdd_ctx) {
1030 hdd_err("HDD context is null");
1031 return false;
1032 }
1033 hdd_for_each_adapter(hdd_ctx, temp) {
1034 if (temp == adapter)
1035 return true;
1036 }
1037
1038 return false;
1039}
1040
1041/**
Manikandan Mohan7ef504e2017-03-17 14:55:17 -07001042 * __wlan_hdd_sap_pre_cac_failure() - Process the pre cac failure
1043 * @data: AP adapter
1044 *
1045 * Deletes the pre cac adapter
1046 *
1047 * Return: None
1048 */
1049static void __wlan_hdd_sap_pre_cac_failure(void *data)
1050{
Jeff Johnson866aca82017-09-10 15:27:20 -07001051 struct hdd_adapter *adapter;
Jeff Johnsonc54bbf92017-08-28 11:59:35 -07001052 struct hdd_context *hdd_ctx;
Manikandan Mohan7ef504e2017-03-17 14:55:17 -07001053
Dustin Brown491d54b2018-03-14 12:39:11 -07001054 hdd_enter();
Manikandan Mohan7ef504e2017-03-17 14:55:17 -07001055
Jeff Johnson866aca82017-09-10 15:27:20 -07001056 adapter = (struct hdd_adapter *) data;
Liangwei Dongad89c762018-06-01 01:56:23 -04001057 if (!adapter || !hdd_check_adapter(adapter) ||
Manikandan Mohan7ef504e2017-03-17 14:55:17 -07001058 adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
1059 hdd_err("SAP Pre CAC adapter invalid");
1060 return;
1061 }
1062
Jeff Johnson399c6272017-08-30 10:51:00 -07001063 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manikandan Mohan7ef504e2017-03-17 14:55:17 -07001064 if (wlan_hdd_validate_context(hdd_ctx)) {
1065 hdd_err("HDD context is null");
1066 return;
1067 }
1068
1069 wlan_hdd_release_intf_addr(hdd_ctx,
Jeff Johnson1e851a12017-10-28 14:36:12 -07001070 adapter->mac_addr.bytes);
Liangwei Dongad89c762018-06-01 01:56:23 -04001071 hdd_stop_adapter_ext(hdd_ctx, adapter, HDD_IN_CAC_WORK_TH_CONTEXT);
Manikandan Mohan7ef504e2017-03-17 14:55:17 -07001072 hdd_close_adapter(hdd_ctx, adapter, false);
1073}
1074
1075/**
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301076 * wlan_hdd_sap_pre_cac_failure() - Process the pre cac failure
1077 * @data: AP adapter
1078 *
1079 * Deletes the pre cac adapter
1080 *
1081 * Return: None
1082 */
1083void wlan_hdd_sap_pre_cac_failure(void *data)
1084{
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301085 cds_ssr_protect(__func__);
Manikandan Mohan7ef504e2017-03-17 14:55:17 -07001086 __wlan_hdd_sap_pre_cac_failure(data);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301087 cds_ssr_unprotect(__func__);
1088}
1089
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301090/**
1091 * wlan_hdd_sap_pre_cac_success() - Process the pre cac result
1092 * @data: AP adapter
1093 *
1094 * Deletes the pre cac adapter and moves the existing SAP to the pre cac
1095 * channel
1096 *
1097 * Return: None
1098 */
1099static void wlan_hdd_sap_pre_cac_success(void *data)
1100{
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001101 struct hdd_adapter *adapter, *ap_adapter;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301102 int i;
Jeff Johnsonc54bbf92017-08-28 11:59:35 -07001103 struct hdd_context *hdd_ctx;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301104
Dustin Brown491d54b2018-03-14 12:39:11 -07001105 hdd_enter();
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301106
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001107 adapter = (struct hdd_adapter *) data;
Liangwei Dongad89c762018-06-01 01:56:23 -04001108 if (!adapter || !hdd_check_adapter(adapter) ||
1109 adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
1110 hdd_err("SAP Pre CAC adapter invalid");
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301111 return;
1112 }
1113
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001114 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301115 if (!hdd_ctx) {
1116 hdd_err("HDD context is null");
1117 return;
1118 }
1119
1120 cds_ssr_protect(__func__);
Krunal Soni38152c92017-01-06 11:05:43 -08001121 wlan_hdd_release_intf_addr(hdd_ctx,
Jeff Johnson1e851a12017-10-28 14:36:12 -07001122 adapter->mac_addr.bytes);
Liangwei Dongad89c762018-06-01 01:56:23 -04001123 hdd_stop_adapter_ext(hdd_ctx, adapter, HDD_IN_CAC_WORK_TH_CONTEXT);
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001124 hdd_close_adapter(hdd_ctx, adapter, false);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301125 cds_ssr_unprotect(__func__);
1126
1127 /* Prepare to switch AP from 2.4GHz channel to the pre CAC channel */
1128 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
1129 if (!ap_adapter) {
1130 hdd_err("failed to get SAP adapter, no restart on pre CAC channel");
1131 return;
1132 }
1133
1134 /*
1135 * Setting of the pre cac complete status will ensure that on channel
1136 * switch to the pre CAC DFS channel, there is no CAC again.
1137 */
1138 wlan_hdd_set_pre_cac_complete_status(ap_adapter, true);
1139 i = hdd_softap_set_channel_change(ap_adapter->dev,
1140 ap_adapter->pre_cac_chan,
Min Liu2fef5792018-01-19 17:59:42 +08001141 CH_WIDTH_MAX, false);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301142 if (0 != i) {
1143 hdd_err("failed to change channel");
1144 wlan_hdd_set_pre_cac_complete_status(ap_adapter, false);
1145 }
1146}
1147
Liangwei Dongaef84342016-10-21 05:28:00 -04001148#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1149/**
1150 * hdd_handle_acs_scan_event() - handle acs scan event for SAP
1151 * @sap_event: tpSap_Event
Jeff Johnson866aca82017-09-10 15:27:20 -07001152 * @adapter: struct hdd_adapter for SAP
Liangwei Dongaef84342016-10-21 05:28:00 -04001153 *
1154 * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event.
1155 * It will update scan result to cfg80211 and start a timer to flush the
1156 * cached acs scan result.
1157 *
1158 * Return: QDF_STATUS_SUCCESS on success,
1159 * other value on failure
1160 */
1161static QDF_STATUS hdd_handle_acs_scan_event(tpSap_Event sap_event,
Jeff Johnson866aca82017-09-10 15:27:20 -07001162 struct hdd_adapter *adapter)
Liangwei Dongaef84342016-10-21 05:28:00 -04001163{
Jeff Johnsonc54bbf92017-08-28 11:59:35 -07001164 struct hdd_context *hdd_ctx;
Liangwei Dongaef84342016-10-21 05:28:00 -04001165 struct sap_acs_scan_complete_event *comp_evt;
1166 QDF_STATUS qdf_status;
1167 int chan_list_size;
1168
Jeff Johnson399c6272017-08-30 10:51:00 -07001169 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Liangwei Dongaef84342016-10-21 05:28:00 -04001170 if (!hdd_ctx) {
1171 hdd_err("HDD context is null");
1172 return QDF_STATUS_E_FAILURE;
1173 }
1174 comp_evt = &sap_event->sapevt.sap_acs_scan_comp;
1175 hdd_ctx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN;
1176 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
1177 qdf_mem_free(hdd_ctx->last_acs_channel_list);
1178 hdd_ctx->last_acs_channel_list = NULL;
1179 hdd_ctx->num_of_channels = 0;
1180 /* cache the previous ACS scan channel list .
1181 * If the following OBSS scan chan list is covered by ACS chan list,
1182 * we can skip OBSS Scan to save SAP starting total time.
1183 */
1184 if (comp_evt->num_of_channels && comp_evt->channellist) {
1185 chan_list_size = comp_evt->num_of_channels *
1186 sizeof(comp_evt->channellist[0]);
1187 hdd_ctx->last_acs_channel_list = qdf_mem_malloc(
1188 chan_list_size);
1189 if (hdd_ctx->last_acs_channel_list) {
1190 qdf_mem_copy(hdd_ctx->last_acs_channel_list,
1191 comp_evt->channellist,
1192 chan_list_size);
1193 hdd_ctx->num_of_channels = comp_evt->num_of_channels;
1194 }
1195 }
1196 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Liangwei Dongaef84342016-10-21 05:28:00 -04001197
Srinivas Girigowda55756882017-03-06 16:45:27 -08001198 hdd_debug("Reusing Last ACS scan result for %d sec",
Liangwei Dongaef84342016-10-21 05:28:00 -04001199 ACS_SCAN_EXPIRY_TIMEOUT_S);
1200 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
1201 qdf_status = qdf_mc_timer_start(&hdd_ctx->skip_acs_scan_timer,
1202 ACS_SCAN_EXPIRY_TIMEOUT_S * 1000);
1203 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1204 hdd_err("Failed to start ACS scan expiry timer");
1205 return QDF_STATUS_SUCCESS;
1206}
1207#else
1208static QDF_STATUS hdd_handle_acs_scan_event(tpSap_Event sap_event,
Jeff Johnson866aca82017-09-10 15:27:20 -07001209 struct hdd_adapter *adapter)
Liangwei Dongaef84342016-10-21 05:28:00 -04001210{
1211 return QDF_STATUS_SUCCESS;
1212}
1213#endif
1214
Will Huang496b36c2017-07-11 16:38:50 +08001215/**
1216 * get_max_rate_vht() - calculate max rate for VHT mode
1217 * @nss: num of streams
1218 * @ch_width: channel width
1219 * @sgi: short gi
1220 * @vht_mcs_map: vht mcs map
1221 *
1222 * This function calculate max rate for VHT mode
1223 *
1224 * Return: max rate
1225 */
1226static int get_max_rate_vht(int nss, int ch_width, int sgi, int vht_mcs_map)
1227{
1228 const struct index_vht_data_rate_type *supported_vht_mcs_rate;
1229 enum data_rate_11ac_max_mcs vht_max_mcs;
1230 int maxrate = 0;
1231 int maxidx;
1232
1233 if (nss == 1) {
1234 supported_vht_mcs_rate = supported_vht_mcs_rate_nss1;
1235 } else if (nss == 2) {
1236 supported_vht_mcs_rate = supported_vht_mcs_rate_nss2;
1237 } else {
1238 /* Not Supported */
1239 hdd_err("nss %d not supported", nss);
1240 return maxrate;
1241 }
1242
1243 vht_max_mcs =
1244 (enum data_rate_11ac_max_mcs)
1245 (vht_mcs_map & DATA_RATE_11AC_MCS_MASK);
1246
1247 if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_7) {
1248 maxidx = 7;
1249 } else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_8) {
1250 maxidx = 8;
1251 } else if (vht_max_mcs == DATA_RATE_11AC_MAX_MCS_9) {
1252 if (ch_width == eHT_CHANNEL_WIDTH_20MHZ)
1253 /* MCS9 is not valid for VHT20 when nss=1,2 */
1254 maxidx = 8;
1255 else
1256 maxidx = 9;
1257 } else {
1258 hdd_err("vht mcs map %x not supported",
1259 vht_mcs_map & DATA_RATE_11AC_MCS_MASK);
1260 return maxrate;
1261 }
1262
1263 if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) {
1264 maxrate =
1265 supported_vht_mcs_rate[maxidx].supported_VHT20_rate[sgi];
1266 } else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) {
1267 maxrate =
1268 supported_vht_mcs_rate[maxidx].supported_VHT40_rate[sgi];
1269 } else if (ch_width == eHT_CHANNEL_WIDTH_80MHZ) {
1270 maxrate =
1271 supported_vht_mcs_rate[maxidx].supported_VHT80_rate[sgi];
1272 } else {
1273 hdd_err("ch_width %d not supported", ch_width);
1274 return maxrate;
1275 }
1276
1277 return maxrate;
1278}
1279
1280/**
1281 * calculate_max_phy_rate() - calcuate maximum phy rate (100kbps)
1282 * @mode: phymode: Legacy, 11a/b/g, HT, VHT
1283 * @nss: num of stream (maximum num is 2)
1284 * @ch_width: channel width
1285 * @sgi: short gi enabled or not
1286 * @supp_idx: max supported idx
1287 * @ext_idx: max extended idx
1288 * @ht_mcs_idx: max mcs index for HT
1289 * @vht_mcs_map: mcs map for VHT
1290 *
1291 * return: maximum phy rate in 100kbps
1292 */
1293static int calcuate_max_phy_rate(int mode, int nss, int ch_width,
1294 int sgi, int supp_idx, int ext_idx,
1295 int ht_mcs_idx, int vht_mcs_map)
1296{
1297 const struct index_data_rate_type *supported_mcs_rate;
1298 int maxidx = 12; /*default 6M mode*/
1299 int maxrate = 0, tmprate;
1300 int i;
1301
1302 /* check supported rates */
1303 if (supp_idx != 0xff && maxidx < supp_idx)
1304 maxidx = supp_idx;
1305
1306 /* check extended rates */
1307 if (ext_idx != 0xff && maxidx < ext_idx)
1308 maxidx = ext_idx;
1309
1310 for (i = 0; i < QDF_ARRAY_SIZE(supported_data_rate); i++) {
1311 if (supported_data_rate[i].beacon_rate_index == maxidx)
1312 maxrate = supported_data_rate[i].supported_rate[0];
1313 }
1314
1315 if (mode == SIR_SME_PHY_MODE_HT) {
1316 /* check for HT Mode */
1317 maxidx = ht_mcs_idx;
1318 if (nss == 1) {
1319 supported_mcs_rate = supported_mcs_rate_nss1;
1320 } else if (nss == 2) {
1321 supported_mcs_rate = supported_mcs_rate_nss2;
1322 } else {
1323 /* Not Supported */
1324 hdd_err("nss %d not supported", nss);
1325 return maxrate;
1326 }
1327
1328 if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) {
1329 tmprate = sgi ?
1330 supported_mcs_rate[maxidx].supported_rate[2] :
1331 supported_mcs_rate[maxidx].supported_rate[0];
1332 } else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) {
1333 tmprate = sgi ?
1334 supported_mcs_rate[maxidx].supported_rate[3] :
1335 supported_mcs_rate[maxidx].supported_rate[1];
1336 } else {
1337 hdd_err("invalid mode %d ch_width %d",
1338 mode, ch_width);
1339 return maxrate;
1340 }
1341
1342 if (maxrate < tmprate)
1343 maxrate = tmprate;
1344 }
1345
1346 if (mode == SIR_SME_PHY_MODE_VHT) {
1347 /* check for VHT Mode */
1348 tmprate = get_max_rate_vht(nss, ch_width, sgi, vht_mcs_map);
1349 if (maxrate < tmprate)
1350 maxrate = tmprate;
1351 }
1352
1353 return maxrate;
1354}
1355
1356/**
Ashish Kumar Dhanotiyad523f0d2017-10-26 14:15:48 +05301357 * hdd_convert_dot11mode_from_phymode() - get dot11 mode from phymode
1358 * @phymode: phymode of sta associated to SAP
1359 *
1360 * The function is to convert the phymode to corresponding dot11 mode
1361 *
1362 * Return: dot11mode.
1363 */
1364
1365
1366static int hdd_convert_dot11mode_from_phymode(int phymode)
1367{
1368
1369 switch (phymode) {
1370
1371 case MODE_11A:
1372 return QCA_WLAN_802_11_MODE_11A;
1373
1374 case MODE_11B:
1375 return QCA_WLAN_802_11_MODE_11B;
1376
1377 case MODE_11G:
1378 case MODE_11GONLY:
1379 return QCA_WLAN_802_11_MODE_11G;
1380
1381 case MODE_11NA_HT20:
1382 case MODE_11NG_HT20:
1383 case MODE_11NA_HT40:
1384 case MODE_11NG_HT40:
1385 return QCA_WLAN_802_11_MODE_11N;
1386
1387 case MODE_11AC_VHT20:
1388 case MODE_11AC_VHT40:
1389 case MODE_11AC_VHT80:
1390 case MODE_11AC_VHT20_2G:
1391 case MODE_11AC_VHT40_2G:
1392 case MODE_11AC_VHT80_2G:
1393#ifdef CONFIG_160MHZ_SUPPORT
1394 case MODE_11AC_VHT80_80:
1395 case MODE_11AC_VHT160:
1396#endif
1397 return QCA_WLAN_802_11_MODE_11AC;
1398
1399 default:
1400 return QCA_WLAN_802_11_MODE_INVALID;
1401 }
1402
1403}
1404
1405/**
Will Huang496b36c2017-07-11 16:38:50 +08001406 * hdd_fill_station_info() - fill stainfo once connected
1407 * @stainfo: peer stainfo associate to SAP
1408 * @event: associate/reassociate event received
1409 *
1410 * The function is to update rate stats to stainfo
1411 *
1412 * Return: None.
1413 */
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05301414static void hdd_fill_station_info(struct hdd_adapter *adapter,
Will Huang496b36c2017-07-11 16:38:50 +08001415 tSap_StationAssocReassocCompleteEvent *event)
1416{
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05301417 struct hdd_station_info *stainfo;
1418 uint8_t i = 0;
1419
1420 if (event->staId >= WLAN_MAX_STA_COUNT) {
1421 hdd_err("invalid sta id");
1422 return;
1423 }
1424
1425 stainfo = &adapter->sta_info[event->staId];
1426
1427 if (!stainfo) {
1428 hdd_err("invalid stainfo");
1429 return;
1430 }
1431
1432 stainfo->freq = cds_chan_to_freq(event->chan_info.chan_id);
Jeff Johnsone7cc44c2017-10-21 16:27:41 -07001433 stainfo->sta_type = event->staType;
Ashish Kumar Dhanotiyad523f0d2017-10-26 14:15:48 +05301434 stainfo->dot11_mode =
1435 hdd_convert_dot11mode_from_phymode(event->chan_info.info);
1436
Will Huang496b36c2017-07-11 16:38:50 +08001437 stainfo->nss = event->chan_info.nss;
1438 stainfo->rate_flags = event->chan_info.rate_flags;
1439 stainfo->ampdu = event->ampdu;
1440 stainfo->sgi_enable = event->sgi_enable;
1441 stainfo->tx_stbc = event->tx_stbc;
1442 stainfo->rx_stbc = event->rx_stbc;
1443 stainfo->ch_width = event->ch_width;
1444 stainfo->mode = event->mode;
1445 stainfo->max_supp_idx = event->max_supp_idx;
1446 stainfo->max_ext_idx = event->max_ext_idx;
1447 stainfo->max_mcs_idx = event->max_mcs_idx;
1448 stainfo->rx_mcs_map = event->rx_mcs_map;
1449 stainfo->tx_mcs_map = event->tx_mcs_map;
1450 stainfo->assoc_ts = qdf_system_ticks();
1451 stainfo->max_phy_rate =
1452 calcuate_max_phy_rate(stainfo->mode,
1453 stainfo->nss,
1454 stainfo->ch_width,
1455 stainfo->sgi_enable,
1456 stainfo->max_supp_idx,
1457 stainfo->max_ext_idx,
1458 stainfo->max_mcs_idx,
1459 stainfo->rx_mcs_map);
1460 /* expect max_phy_rate report in kbps */
1461 stainfo->max_phy_rate *= 100;
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05301462
1463 if (event->vht_caps.present) {
1464 stainfo->vht_present = true;
1465 hdd_copy_vht_caps(&stainfo->vht_caps, &event->vht_caps);
1466 }
1467 if (event->ht_caps.present) {
1468 stainfo->ht_present = true;
1469 hdd_copy_ht_caps(&stainfo->ht_caps, &event->ht_caps);
1470 }
1471
Yun Parkc3e35562018-03-08 12:05:52 -08001472 /* Initialize DHCP info */
1473 stainfo->dhcp_phase = DHCP_PHASE_ACK;
1474 stainfo->dhcp_nego_status = DHCP_NEGO_STOP;
1475
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05301476 while (i < WLAN_MAX_STA_COUNT) {
1477 if (!qdf_mem_cmp(adapter->cache_sta_info[i].sta_mac.bytes,
1478 event->staMac.bytes,
1479 QDF_MAC_ADDR_SIZE)) {
1480 qdf_mem_zero(&adapter->cache_sta_info[i],
1481 sizeof(*stainfo));
1482 break;
1483 }
1484 i++;
1485 }
1486 if (i >= WLAN_MAX_STA_COUNT) {
1487 i = 0;
1488 while (i < WLAN_MAX_STA_COUNT) {
1489 if (adapter->cache_sta_info[i].in_use != TRUE)
1490 break;
1491 i++;
1492 }
1493 }
1494 if (i < WLAN_MAX_STA_COUNT)
1495 qdf_mem_copy(&adapter->cache_sta_info[i],
1496 stainfo, sizeof(struct hdd_station_info));
1497 else
1498 hdd_debug("reached max staid, stainfo can't be cached");
1499
Will Huang496b36c2017-07-11 16:38:50 +08001500 hdd_debug("cap %d %d %d %d %d %d %d %d %d %x %d",
1501 stainfo->ampdu,
1502 stainfo->sgi_enable,
1503 stainfo->tx_stbc,
1504 stainfo->rx_stbc,
Jeff Johnson65fda112017-10-21 13:46:10 -07001505 stainfo->is_qos_enabled,
Will Huang496b36c2017-07-11 16:38:50 +08001506 stainfo->ch_width,
1507 stainfo->mode,
1508 event->wmmEnabled,
1509 event->chan_info.nss,
1510 event->chan_info.rate_flags,
1511 stainfo->max_phy_rate);
1512 hdd_debug("rate info %d %d %d %d %d",
1513 stainfo->max_supp_idx,
1514 stainfo->max_ext_idx,
1515 stainfo->max_mcs_idx,
1516 stainfo->rx_mcs_map,
1517 stainfo->tx_mcs_map);
1518}
1519
Krunal Soni22208392017-09-29 18:10:34 -07001520/**
1521 * hdd_stop_sap_due_to_invalid_channel() - to stop sap in case of invalid chnl
1522 * @work: pointer to work structure
1523 *
1524 * Let's say SAP detected RADAR and trying to select the new channel and if no
1525 * valid channel is found due to none of the channels are available or
1526 * regulatory restriction then SAP needs to be stopped. so SAP state-machine
1527 * will create a work to stop the bss
1528 *
1529 * stop bss has to happen through worker thread because radar indication comes
1530 * from FW through mc thread or main host thread and if same thread is used to
1531 * do stopbss then waiting for stopbss to finish operation will halt mc thread
1532 * to freeze which will trigger stopbss timeout. Instead worker thread can do
1533 * the stopbss operation while mc thread waits for stopbss to finish.
1534 *
1535 * Return: none
1536 */
1537static void
1538hdd_stop_sap_due_to_invalid_channel(struct work_struct *work)
1539{
1540 /*
1541 * Extract the adapter from work structure. sap_stop_bss_work
1542 * is part of adapter context.
1543 */
1544 struct hdd_adapter *sap_adapter = container_of(work,
1545 struct hdd_adapter,
1546 sap_stop_bss_work);
Krunal Soni22208392017-09-29 18:10:34 -07001547 cds_ssr_protect(__func__);
1548 if (sap_adapter == NULL) {
Jeff Johnsonb8adae42018-02-27 16:12:00 -08001549 cds_err("sap_adapter is NULL, no work needed");
1550 cds_ssr_unprotect(__func__);
1551 return;
Krunal Soni22208392017-09-29 18:10:34 -07001552 }
Nachiket Kukade65499372017-11-14 16:53:54 +05301553 hdd_debug("work started for sap session[%d]", sap_adapter->session_id);
Krunal Soni22208392017-09-29 18:10:34 -07001554 wlan_hdd_stop_sap(sap_adapter);
Krunal Soni22208392017-09-29 18:10:34 -07001555 wlansap_cleanup_cac_timer(WLAN_HDD_GET_SAP_CTX_PTR(sap_adapter));
1556 hdd_debug("work finished for sap");
1557 cds_ssr_unprotect(__func__);
1558}
1559
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301560QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
Jeff Johnson0604a362018-03-24 17:36:59 -07001561 void *context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001562{
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001563 struct hdd_adapter *adapter;
Jeff Johnson9bf24972017-10-04 09:26:58 -07001564 struct hdd_ap_ctx *ap_ctx;
Jeff Johnson5c19ade2017-10-04 09:52:12 -07001565 struct hdd_hostapd_state *hostapd_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001566 struct net_device *dev;
1567 eSapHddEvent sapEvent;
1568 union iwreq_data wrqu;
1569 uint8_t *we_custom_event_generic = NULL;
1570 int we_event = 0;
1571 int i = 0;
1572 uint8_t staId;
Anurag Chouhance0dc992016-02-16 18:18:03 +05301573 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001574 bool bAuthRequired = true;
1575 tpSap_AssocMacAddr pAssocStasArray = NULL;
1576 char unknownSTAEvent[IW_CUSTOM_MAX + 1];
1577 char maxAssocExceededEvent[IW_CUSTOM_MAX + 1];
1578 uint8_t we_custom_start_event[64];
1579 char *startBssEvent;
Jeff Johnson23c3b842017-09-03 09:05:29 -07001580 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001581 struct iw_michaelmicfailure msg;
1582 uint8_t ignoreCAC = 0;
1583 struct hdd_config *cfg = NULL;
1584 struct wlan_dfs_info dfs_info;
1585 uint8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN;
Jeff Johnson866aca82017-09-10 15:27:20 -07001586 struct hdd_adapter *con_sap_adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301587 QDF_STATUS status = QDF_STATUS_SUCCESS;
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05301588 struct hdd_chan_change_params chan_change;
Will Huang496b36c2017-07-11 16:38:50 +08001589 tSap_StationAssocReassocCompleteEvent *event;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001590 int ret = 0;
bings61d5bec2017-06-27 14:13:40 +08001591 struct ch_params sap_ch_param = {0};
bings58ce8622017-07-10 15:55:36 +08001592 eCsrPhyMode phy_mode;
1593 bool legacy_phymode;
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05301594 tSap_StationDisassocCompleteEvent *disassoc_comp;
1595 struct hdd_station_info *stainfo;
Jeff Johnson89a0c742018-06-12 18:17:46 -07001596 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001597
Jeff Johnson0604a362018-03-24 17:36:59 -07001598 dev = context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001599 if (!dev) {
Jeff Johnson0604a362018-03-24 17:36:59 -07001600 hdd_err("context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301601 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001602 }
1603
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001604 adapter = netdev_priv(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001605
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001606 if ((NULL == adapter) ||
1607 (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001608 hdd_err("invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301609 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001610 }
1611
Jeff Johnson5c19ade2017-10-04 09:52:12 -07001612 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Jeff Johnson9bf24972017-10-04 09:26:58 -07001613 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001614
1615 if (!pSapEvent) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001616 hdd_err("pSapEvent is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301617 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001618 }
1619
1620 sapEvent = pSapEvent->sapHddEventCode;
1621 memset(&wrqu, '\0', sizeof(wrqu));
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001622 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001623
Jeff Johnson23c3b842017-09-03 09:05:29 -07001624 if (!hdd_ctx) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001625 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301626 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627 }
1628
Jeff Johnson23c3b842017-09-03 09:05:29 -07001629 cfg = hdd_ctx->config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001630
1631 if (!cfg) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001632 hdd_err("HDD config is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301633 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001634 }
1635
Jeff Johnson89a0c742018-06-12 18:17:46 -07001636 mac_handle = hdd_ctx->mac_handle;
Jeff Johnson01206862017-10-27 20:55:59 -07001637 dfs_info.channel = ap_ctx->operating_channel;
Jeff Johnson89a0c742018-06-12 18:17:46 -07001638 sme_get_country_code(mac_handle, dfs_info.country_code, &cc_len);
Sourav Mohapatra02fbc092018-01-08 17:11:07 +05301639 staId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001640
1641 switch (sapEvent) {
1642 case eSAP_START_BSS_EVENT:
Srinivas Girigowda55756882017-03-06 16:45:27 -08001643 hdd_debug("BSS status = %s, channel = %u, bc sta Id = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001644 pSapEvent->sapevt.sapStartBssCompleteEvent.
1645 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
1646 pSapEvent->sapevt.sapStartBssCompleteEvent.
1647 operatingChannel,
1648 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
1649
Jeff Johnson1b780e42017-10-31 14:11:45 -07001650 adapter->session_id =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001651 pSapEvent->sapevt.sapStartBssCompleteEvent.sessionId;
1652
Himanshu Agarwalf5c5b102018-05-22 20:13:57 +05301653 adapter->session.ap.sap_config.channel =
1654 pSapEvent->sapevt.sapStartBssCompleteEvent.
1655 operatingChannel;
1656
1657 adapter->session.ap.sap_config.ch_params.ch_width =
1658 pSapEvent->sapevt.sapStartBssCompleteEvent.ch_width;
1659
Jeff Johnson5c19ade2017-10-04 09:52:12 -07001660 hostapd_state->qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001661 pSapEvent->sapevt.sapStartBssCompleteEvent.status;
Arif Hussaine478b4d2017-03-30 13:55:48 -07001662
Min Liu2fef5792018-01-19 17:59:42 +08001663 qdf_atomic_set(&adapter->dfs_radar_found, 0);
Bala Venkatesh7e9c6882018-06-11 15:03:30 +05301664
1665 status = policy_mgr_set_chan_switch_complete_evt(
1666 hdd_ctx->hdd_psoc);
1667 if (!QDF_IS_STATUS_SUCCESS(status)) {
1668 hdd_err("set event failed");
1669 goto stopbss;
1670 }
Jeff Johnson89a0c742018-06-12 18:17:46 -07001671 wlansap_get_dfs_ignore_cac(mac_handle, &ignoreCAC);
Arif Hussaine478b4d2017-03-30 13:55:48 -07001672
1673 /* DFS requirement: DO NOT transmit during CAC. */
1674 if ((CHANNEL_STATE_DFS !=
Jeff Johnson23c3b842017-09-03 09:05:29 -07001675 wlan_reg_get_channel_state(hdd_ctx->hdd_pdev,
Jeff Johnson01206862017-10-27 20:55:59 -07001676 ap_ctx->operating_channel))
Arif Hussaine478b4d2017-03-30 13:55:48 -07001677 || ignoreCAC
Jeff Johnson23c3b842017-09-03 09:05:29 -07001678 || hdd_ctx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE)
Jeff Johnson9bf24972017-10-04 09:26:58 -07001679 ap_ctx->dfs_cac_block_tx = false;
Arif Hussaine478b4d2017-03-30 13:55:48 -07001680 else
Jeff Johnson9bf24972017-10-04 09:26:58 -07001681 ap_ctx->dfs_cac_block_tx = true;
Arif Hussaine478b4d2017-03-30 13:55:48 -07001682
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05301683 ucfg_ipa_set_dfs_cac_tx(hdd_ctx->hdd_pdev,
1684 ap_ctx->dfs_cac_block_tx);
1685
Jeff Johnson36e74c42017-09-18 08:15:42 -07001686 hdd_debug("The value of dfs_cac_block_tx[%d] for ApCtx[%pK]:%d",
Jeff Johnson9bf24972017-10-04 09:26:58 -07001687 ap_ctx->dfs_cac_block_tx, ap_ctx,
Jeff Johnson1b780e42017-10-31 14:11:45 -07001688 adapter->session_id);
Arif Hussaine478b4d2017-03-30 13:55:48 -07001689
Jeff Johnson5c19ade2017-10-04 09:52:12 -07001690 if (hostapd_state->qdf_status) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08001691 hdd_err("startbss event failed!!");
Krunal Soni35fc8ea2016-10-26 18:52:38 -07001692 /*
1693 * Make sure to set the event before proceeding
1694 * for error handling otherwise caller thread will
1695 * wait till 10 secs and no other connection will
1696 * go through before that.
1697 */
Jeff Johnson0f9f87b2017-10-28 09:21:06 -07001698 hostapd_state->bss_state = BSS_STOP;
Jeff Johnson5c19ade2017-10-04 09:52:12 -07001699 qdf_event_set(&hostapd_state->qdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001700 goto stopbss;
1701 } else {
Jeff Johnson89a0c742018-06-12 18:17:46 -07001702 sme_ch_avoid_update_req(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001703
Jeff Johnson42518cf2017-10-26 13:33:29 -07001704 ap_ctx->broadcast_sta_id =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001705 pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
1706
Ajit Pal Singhd6c08f22018-04-25 16:55:26 +05301707 cdp_hl_fc_set_td_limit(
1708 cds_get_context(QDF_MODULE_ID_SOC),
1709 adapter->session_id,
1710 ap_ctx->operating_channel);
1711
1712 hdd_register_tx_flow_control(adapter,
1713 hdd_softap_tx_resume_timer_expired_handler,
1714 hdd_softap_tx_resume_cb,
1715 hdd_tx_flow_control_is_pause);
1716
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717 /* @@@ need wep logic here to set privacy bit */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301718 qdf_status =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001719 hdd_softap_register_bc_sta(adapter,
Jeff Johnsonc8d94a12017-10-27 14:02:53 -07001720 ap_ctx->privacy);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301721 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001722 hdd_warn("Failed to register BC STA %d",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301723 qdf_status);
Jeff Johnson0604a362018-03-24 17:36:59 -07001724 hdd_stop_bss_link(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001725 }
1726 }
1727
Sravan Kumar Kairam5214f652018-03-13 09:52:31 +05301728 if (ucfg_ipa_is_enabled()) {
1729 status = ucfg_ipa_wlan_evt(hdd_ctx->hdd_pdev,
1730 adapter->dev, adapter->device_mode,
Jeff Johnson42518cf2017-10-26 13:33:29 -07001731 ap_ctx->broadcast_sta_id,
Sravan Kumar Kairam5214f652018-03-13 09:52:31 +05301732 adapter->session_id,
1733 WLAN_IPA_AP_CONNECT,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001734 adapter->dev->dev_addr);
Yun Parka9d0c112018-03-07 14:11:27 -08001735 if (status)
1736 hdd_err("WLAN_AP_CONNECT event failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001737 }
1738
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001739#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Jeff Johnson23c3b842017-09-03 09:05:29 -07001740 wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001741#endif
Jeff Johnson01206862017-10-27 20:55:59 -07001742 ap_ctx->operating_channel =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001743 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
1744
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001745 hdd_hostapd_channel_prevent_suspend(adapter,
Jeff Johnson01206862017-10-27 20:55:59 -07001746 ap_ctx->operating_channel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001747
Jeff Johnson0f9f87b2017-10-28 09:21:06 -07001748 hostapd_state->bss_state = BSS_START;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001749
Kondabattini, Ganesh702d90e2016-09-03 01:54:22 +05301750 /* Set default key index */
Dustin Browna2868622018-03-20 11:38:14 -07001751 hdd_debug("default key index %hu", ap_ctx->wep_def_key_idx);
Kondabattini, Ganesh702d90e2016-09-03 01:54:22 +05301752
Jeff Johnson89a0c742018-06-12 18:17:46 -07001753 sme_roam_set_default_key_index(mac_handle,
1754 adapter->session_id,
1755 ap_ctx->wep_def_key_idx);
Kondabattini, Ganesh702d90e2016-09-03 01:54:22 +05301756
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001757 /* Set group key / WEP key every time when BSS is restarted */
Jeff Johnson413c15f2017-10-27 18:56:35 -07001758 if (ap_ctx->group_key.keyLength) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001759 status = wlansap_set_key_sta(
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001760 WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Jeff Johnson413c15f2017-10-27 18:56:35 -07001761 &ap_ctx->group_key);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301762 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001763 hdd_err("wlansap_set_key_sta failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001764 } else {
1765 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
Jeff Johnson3d731362017-10-27 19:06:41 -07001766 if (!ap_ctx->wep_key[i].keyLength)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001767 continue;
1768
1769 status = wlansap_set_key_sta(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001770 WLAN_HDD_GET_SAP_CTX_PTR
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001771 (adapter),
Jeff Johnson3d731362017-10-27 19:06:41 -07001772 &ap_ctx->wep_key[i]);
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07001773 if (!QDF_IS_STATUS_SUCCESS(status))
Srinivas Girigowda55756882017-03-06 16:45:27 -08001774 hdd_err("set_key failed idx: %d", i);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001775 }
1776 }
1777
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07001778 /* Fill the params for sending IWEVCUSTOM Event
1779 * with SOFTAP.enabled
1780 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001781 startBssEvent = "SOFTAP.enabled";
1782 memset(&we_custom_start_event, '\0',
1783 sizeof(we_custom_start_event));
1784 memcpy(&we_custom_start_event, startBssEvent,
1785 strlen(startBssEvent));
1786 memset(&wrqu, 0, sizeof(wrqu));
1787 wrqu.data.length = strlen(startBssEvent);
1788 we_event = IWEVCUSTOM;
1789 we_custom_event_generic = we_custom_start_event;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08001790 hdd_ipa_set_tx_flow_info();
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05301791
Bala Venkateshf13b7282018-04-13 20:48:11 +05301792 hdd_debug("check for SAP restart");
1793 policy_mgr_check_concurrent_intf_and_restart_sap(
1794 hdd_ctx->hdd_psoc);
1795
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08001796 if (policy_mgr_is_hw_mode_change_after_vdev_up(
Jeff Johnson23c3b842017-09-03 09:05:29 -07001797 hdd_ctx->hdd_psoc)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08001798 hdd_debug("check for possible hw mode change");
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08001799 status = policy_mgr_set_hw_mode_on_channel_switch(
Jeff Johnson1b780e42017-10-31 14:11:45 -07001800 hdd_ctx->hdd_psoc, adapter->session_id);
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05301801 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda55756882017-03-06 16:45:27 -08001802 hdd_debug("set hw mode change not done");
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08001803 policy_mgr_set_do_hw_mode_change_flag(
Jeff Johnson23c3b842017-09-03 09:05:29 -07001804 hdd_ctx->hdd_psoc, false);
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05301805 }
Krunal Soni35fc8ea2016-10-26 18:52:38 -07001806 /*
1807 * set this event at the very end because once this events
1808 * get set, caller thread is waiting to do further processing.
1809 * so once this event gets set, current worker thread might get
1810 * pre-empted by caller thread.
1811 */
Jeff Johnson5c19ade2017-10-04 09:52:12 -07001812 qdf_status = qdf_event_set(&hostapd_state->qdf_event);
Krunal Soni35fc8ea2016-10-26 18:52:38 -07001813 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08001814 hdd_err("qdf_event_set failed! status: %d", qdf_status);
Krunal Soni35fc8ea2016-10-26 18:52:38 -07001815 goto stopbss;
1816 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001817 break; /* Event will be sent after Switch-Case stmt */
1818
1819 case eSAP_STOP_BSS_EVENT:
Srinivas Girigowda55756882017-03-06 16:45:27 -08001820 hdd_debug("BSS stop status = %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001821 pSapEvent->sapevt.sapStopBssCompleteEvent.
1822 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1823
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001824 hdd_hostapd_channel_allow_suspend(adapter,
Jeff Johnson01206862017-10-27 20:55:59 -07001825 ap_ctx->operating_channel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001826
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001827 /* Invalidate the channel info. */
Jeff Johnson01206862017-10-27 20:55:59 -07001828 ap_ctx->operating_channel = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001829
1830 /* reset the dfs_cac_status and dfs_cac_block_tx flag only when
1831 * the last BSS is stopped
1832 */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001833 con_sap_adapter = hdd_get_con_sap_adapter(adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001834 if (!con_sap_adapter) {
Jeff Johnson9bf24972017-10-04 09:26:58 -07001835 ap_ctx->dfs_cac_block_tx = true;
Jeff Johnson23c3b842017-09-03 09:05:29 -07001836 hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001837 }
Jeff Johnson9bf24972017-10-04 09:26:58 -07001838 hdd_debug("bss_stop_reason=%d", ap_ctx->bss_stop_reason);
hqu73bccf22017-10-28 15:34:17 +08001839 if ((BSS_STOP_DUE_TO_MCC_SCC_SWITCH !=
1840 ap_ctx->bss_stop_reason) &&
1841 (BSS_STOP_DUE_TO_VENDOR_CONFIG_CHAN !=
1842 ap_ctx->bss_stop_reason)) {
1843 /*
1844 * when MCC to SCC switching or vendor subcmd
1845 * setting sap config channel happens, key storage
wadesong9b819072017-02-07 16:42:09 +08001846 * should not be cleared due to hostapd will not
1847 * repopulate the original keys
1848 */
Jeff Johnson413c15f2017-10-27 18:56:35 -07001849 ap_ctx->group_key.keyLength = 0;
wadesong9b819072017-02-07 16:42:09 +08001850 for (i = 0; i < CSR_MAX_NUM_KEY; i++)
Jeff Johnson3d731362017-10-27 19:06:41 -07001851 ap_ctx->wep_key[i].keyLength = 0;
wadesong9b819072017-02-07 16:42:09 +08001852 }
1853
1854 /* clear the reason code in case BSS is stopped
1855 * in another place
1856 */
Jeff Johnson9bf24972017-10-04 09:26:58 -07001857 ap_ctx->bss_stop_reason = BSS_STOP_REASON_INVALID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001858 goto stopbss;
1859
1860 case eSAP_DFS_CAC_START:
Jeff Johnson23c3b842017-09-03 09:05:29 -07001861 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05301862 WLAN_SVC_DFS_CAC_START_IND,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001863 &dfs_info,
1864 sizeof(struct wlan_dfs_info));
Jeff Johnson23c3b842017-09-03 09:05:29 -07001865 hdd_ctx->dev_dfs_cac_status = DFS_CAC_IN_PROGRESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301866 if (QDF_STATUS_SUCCESS !=
Jeff Johnson23c3b842017-09-03 09:05:29 -07001867 hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_START,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001868 dfs_info, &adapter->wdev)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001869 hdd_err("Unable to indicate CAC start NL event");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001870 } else {
Srinivas Girigowda55756882017-03-06 16:45:27 -08001871 hdd_debug("Sent CAC start to user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001872 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301873
Min Liu2fef5792018-01-19 17:59:42 +08001874 qdf_atomic_set(&adapter->dfs_radar_found, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001875 break;
1876 case eSAP_DFS_CAC_INTERRUPTED:
1877 /*
1878 * The CAC timer did not run completely and a radar was detected
1879 * during the CAC time. This new state will keep the tx path
1880 * blocked since we do not want any transmission on the DFS
1881 * channel. CAC end will only be reported here since the user
1882 * space applications are waiting on CAC end for their state
1883 * management.
1884 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301885 if (QDF_STATUS_SUCCESS !=
Jeff Johnson23c3b842017-09-03 09:05:29 -07001886 hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_END,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001887 dfs_info, &adapter->wdev)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001888 hdd_err("Unable to indicate CAC end (interrupted) event");
1889 } else {
Srinivas Girigowda55756882017-03-06 16:45:27 -08001890 hdd_debug("Sent CAC end (interrupted) to user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001891 }
1892 break;
1893 case eSAP_DFS_CAC_END:
Jeff Johnson23c3b842017-09-03 09:05:29 -07001894 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05301895 WLAN_SVC_DFS_CAC_END_IND,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001896 &dfs_info,
1897 sizeof(struct wlan_dfs_info));
Jeff Johnson9bf24972017-10-04 09:26:58 -07001898 ap_ctx->dfs_cac_block_tx = false;
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05301899 ucfg_ipa_set_dfs_cac_tx(hdd_ctx->hdd_pdev,
1900 ap_ctx->dfs_cac_block_tx);
Jeff Johnson23c3b842017-09-03 09:05:29 -07001901 hdd_ctx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301902 if (QDF_STATUS_SUCCESS !=
Jeff Johnson23c3b842017-09-03 09:05:29 -07001903 hdd_send_radar_event(hdd_ctx, eSAP_DFS_CAC_END,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001904 dfs_info, &adapter->wdev)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001905 hdd_err("Unable to indicate CAC end NL event");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001906 } else {
Srinivas Girigowda55756882017-03-06 16:45:27 -08001907 hdd_debug("Sent CAC end to user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001908 }
1909 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001910 case eSAP_DFS_RADAR_DETECT:
Kapil Guptac1224bf2017-06-22 21:22:40 +05301911 {
1912 int i;
Jeff Johnsone4c11db2018-05-05 23:22:32 -07001913 tsap_config_t *sap_config =
Jeff Johnsonb9424862017-10-30 08:49:35 -07001914 &adapter->session.ap.sap_config;
Kapil Guptac1224bf2017-06-22 21:22:40 +05301915
Jeff Johnson23c3b842017-09-03 09:05:29 -07001916 hdd_dfs_indicate_radar(hdd_ctx);
1917 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05301918 WLAN_SVC_DFS_RADAR_DETECT_IND,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001919 &dfs_info,
1920 sizeof(struct wlan_dfs_info));
Jeff Johnson23c3b842017-09-03 09:05:29 -07001921 hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
Kapil Guptac1224bf2017-06-22 21:22:40 +05301922 for (i = 0; i < sap_config->channel_info_count; i++) {
1923 if (sap_config->channel_info[i].ieee_chan_number
1924 == dfs_info.channel)
1925 sap_config->channel_info[i].flags |=
1926 IEEE80211_CHAN_RADAR_DFS;
1927 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301928 if (QDF_STATUS_SUCCESS !=
Jeff Johnson23c3b842017-09-03 09:05:29 -07001929 hdd_send_radar_event(hdd_ctx, eSAP_DFS_RADAR_DETECT,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001930 dfs_info, &adapter->wdev)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001931 hdd_err("Unable to indicate Radar detect NL event");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001932 } else {
Srinivas Girigowda55756882017-03-06 16:45:27 -08001933 hdd_debug("Sent radar detected to user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001934 }
1935 break;
Kapil Guptac1224bf2017-06-22 21:22:40 +05301936 }
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301937 case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC:
1938 hdd_debug("notification for radar detect during pre cac:%d",
Jeff Johnson1b780e42017-10-31 14:11:45 -07001939 adapter->session_id);
Jeff Johnson23c3b842017-09-03 09:05:29 -07001940 hdd_send_conditional_chan_switch_status(hdd_ctx,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001941 &adapter->wdev, false);
Jeff Johnson23c3b842017-09-03 09:05:29 -07001942 hdd_ctx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
1943 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301944 wlan_hdd_sap_pre_cac_failure,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001945 (void *)adapter);
Jeff Johnson23c3b842017-09-03 09:05:29 -07001946 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301947 break;
1948 case eSAP_DFS_PRE_CAC_END:
1949 hdd_debug("pre cac end notification received:%d",
Jeff Johnson1b780e42017-10-31 14:11:45 -07001950 adapter->session_id);
Jeff Johnson23c3b842017-09-03 09:05:29 -07001951 hdd_send_conditional_chan_switch_status(hdd_ctx,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001952 &adapter->wdev, true);
Jeff Johnson9bf24972017-10-04 09:26:58 -07001953 ap_ctx->dfs_cac_block_tx = false;
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05301954 ucfg_ipa_set_dfs_cac_tx(hdd_ctx->hdd_pdev,
1955 ap_ctx->dfs_cac_block_tx);
Jeff Johnson23c3b842017-09-03 09:05:29 -07001956 hdd_ctx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001957
Jeff Johnson23c3b842017-09-03 09:05:29 -07001958 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301959 wlan_hdd_sap_pre_cac_success,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07001960 (void *)adapter);
Jeff Johnson23c3b842017-09-03 09:05:29 -07001961 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301962 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001963 case eSAP_DFS_NO_AVAILABLE_CHANNEL:
1964 wlan_hdd_send_svc_nlink_msg
Jeff Johnson23c3b842017-09-03 09:05:29 -07001965 (hdd_ctx->radio_index,
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05301966 WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND, &dfs_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001967 sizeof(struct wlan_dfs_info));
1968 break;
1969
1970 case eSAP_STA_SET_KEY_EVENT:
1971 /* TODO:
1972 * forward the message to hostapd once implementation
1973 * is done for now just print
1974 */
Srinivas Girigowda55756882017-03-06 16:45:27 -08001975 hdd_debug("SET Key: configured status = %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001976 pSapEvent->sapevt.sapStationSetKeyCompleteEvent.
1977 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301978 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001979 case eSAP_STA_MIC_FAILURE_EVENT:
1980 {
1981 memset(&msg, '\0', sizeof(msg));
1982 msg.src_addr.sa_family = ARPHRD_ETHER;
1983 memcpy(msg.src_addr.sa_data,
1984 &pSapEvent->sapevt.sapStationMICFailureEvent.
Anurag Chouhan6d760662016-02-20 16:05:43 +05301985 staMac, QDF_MAC_ADDR_SIZE);
Srinivas Girigowda55756882017-03-06 16:45:27 -08001986 hdd_debug("MIC MAC " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001987 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
1988 if (pSapEvent->sapevt.sapStationMICFailureEvent.
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07001989 multicast == true)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001990 msg.flags = IW_MICFAILURE_GROUP;
1991 else
1992 msg.flags = IW_MICFAILURE_PAIRWISE;
1993 memset(&wrqu, 0, sizeof(wrqu));
1994 wrqu.data.length = sizeof(msg);
1995 we_event = IWEVMICHAELMICFAILURE;
1996 we_custom_event_generic = (uint8_t *) &msg;
1997 }
1998 /* inform mic failure to nl80211 */
1999 cfg80211_michael_mic_failure(dev,
2000 pSapEvent->
2001 sapevt.sapStationMICFailureEvent.
2002 staMac.bytes,
2003 ((pSapEvent->sapevt.
2004 sapStationMICFailureEvent.
2005 multicast ==
Srinivas Girigowda74a66d62017-06-21 23:28:25 -07002006 true) ?
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002007 NL80211_KEYTYPE_GROUP :
2008 NL80211_KEYTYPE_PAIRWISE),
2009 pSapEvent->sapevt.
2010 sapStationMICFailureEvent.keyId,
2011 pSapEvent->sapevt.
2012 sapStationMICFailureEvent.TSC,
2013 GFP_KERNEL);
2014 break;
2015
2016 case eSAP_STA_ASSOC_EVENT:
2017 case eSAP_STA_REASSOC_EVENT:
Will Huang496b36c2017-07-11 16:38:50 +08002018 event = &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent;
wadesonga8637bb2018-01-23 15:11:19 +08002019 if (eSAP_STATUS_FAILURE == event->status) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07002020 hdd_info("assoc failure: " MAC_ADDRESS_STR,
2021 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
wadesonga8637bb2018-01-23 15:11:19 +08002022 break;
2023 }
2024
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002025 wrqu.addr.sa_family = ARPHRD_ETHER;
2026 memcpy(wrqu.addr.sa_data,
Will Huang496b36c2017-07-11 16:38:50 +08002027 &event->staMac, QDF_MAC_ADDR_SIZE);
Dustin Brown5e89ef82018-03-14 11:50:23 -07002028 hdd_info("associated " MAC_ADDRESS_STR,
2029 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002030 we_event = IWEVREGISTERED;
2031
Jeff Johnsona8e686b2017-10-27 15:05:18 -07002032 if ((eCSR_ENCRYPT_TYPE_NONE == ap_ctx->encryption_type) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002033 (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
Jeff Johnsona8e686b2017-10-27 15:05:18 -07002034 ap_ctx->encryption_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002035 || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
Jeff Johnsona8e686b2017-10-27 15:05:18 -07002036 ap_ctx->encryption_type)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002037 bAuthRequired = false;
2038 }
2039
Jeff Johnson8b8d03d2017-09-20 13:56:27 -07002040 if (bAuthRequired) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302041 qdf_status = hdd_softap_register_sta(
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002042 adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002043 true,
Jeff Johnsonc8d94a12017-10-27 14:02:53 -07002044 ap_ctx->privacy,
Jeff Johnson3f6c89f2018-03-01 14:27:38 -08002045 event->staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302046 (struct qdf_mac_addr *)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002047 wrqu.addr.sa_data,
Will Huang496b36c2017-07-11 16:38:50 +08002048 event->wmmEnabled);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302049 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda55756882017-03-06 16:45:27 -08002050 hdd_err("Failed to register STA %d "
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002051 MAC_ADDRESS_STR "", qdf_status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002052 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
2053 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302054 qdf_status = hdd_softap_register_sta(
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002055 adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002056 false,
Jeff Johnsonc8d94a12017-10-27 14:02:53 -07002057 ap_ctx->privacy,
Jeff Johnson3f6c89f2018-03-01 14:27:38 -08002058 event->staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302059 (struct qdf_mac_addr *)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002060 wrqu.addr.sa_data,
Will Huang496b36c2017-07-11 16:38:50 +08002061 event->wmmEnabled);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302062 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda55756882017-03-06 16:45:27 -08002063 hdd_err("Failed to register STA %d "
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002064 MAC_ADDRESS_STR "", qdf_status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002065 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
2066 }
2067
Will Huang496b36c2017-07-11 16:38:50 +08002068 staId = event->staId;
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05302069 if (QDF_IS_STATUS_SUCCESS(qdf_status))
2070 hdd_fill_station_info(adapter, event);
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05302071
gaolezd16a2852018-01-10 11:08:20 +08002072 adapter->sta_info[staId].ecsa_capable = event->ecsa_capable;
2073
Sravan Kumar Kairam5214f652018-03-13 09:52:31 +05302074 if (ucfg_ipa_is_enabled()) {
2075 status = ucfg_ipa_wlan_evt(hdd_ctx->hdd_pdev,
2076 adapter->dev,
2077 adapter->device_mode,
2078 event->staId,
2079 adapter->session_id,
2080 WLAN_IPA_CLIENT_CONNECT_EX,
2081 event->staMac.bytes);
Yun Parka9d0c112018-03-07 14:11:27 -08002082 if (status)
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002083 hdd_err("WLAN_CLIENT_CONNECT_EX event failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002084 }
2085
Nirav Shah1da77682016-05-03 20:16:39 +05302086 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
Jeff Johnson1b780e42017-10-31 14:11:45 -07002087 adapter->session_id,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -07002088 QDF_TRACE_DEFAULT_PDEV_ID,
Nirav Shah1da77682016-05-03 20:16:39 +05302089 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002090
2091#ifdef MSM_PLATFORM
2092 /* start timer in sap/p2p_go */
Jeff Johnson136c51b2017-10-27 20:02:41 -07002093 if (ap_ctx->ap_active == false) {
Jeff Johnson23c3b842017-09-03 09:05:29 -07002094 spin_lock_bh(&hdd_ctx->bus_bw_lock);
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002095 adapter->prev_tx_packets =
2096 adapter->stats.tx_packets;
2097 adapter->prev_rx_packets =
2098 adapter->stats.rx_packets;
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08002099
2100 cdp_get_intra_bss_fwd_pkts_count(
2101 cds_get_context(QDF_MODULE_ID_SOC),
Jeff Johnson1b780e42017-10-31 14:11:45 -07002102 adapter->session_id,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002103 &adapter->prev_fwd_tx_packets,
2104 &adapter->prev_fwd_rx_packets);
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08002105
Jeff Johnson23c3b842017-09-03 09:05:29 -07002106 spin_unlock_bh(&hdd_ctx->bus_bw_lock);
2107 hdd_bus_bw_compute_timer_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002108 }
2109#endif
Jeff Johnson136c51b2017-10-27 20:02:41 -07002110 ap_ctx->ap_active = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002111#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Jeff Johnson23c3b842017-09-03 09:05:29 -07002112 wlan_hdd_auto_shutdown_enable(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002113#endif
Jeff Johnson23c3b842017-09-03 09:05:29 -07002114 cds_host_diag_log_work(&hdd_ctx->sap_wake_lock,
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05302115 HDD_SAP_WAKE_LOCK_DURATION,
2116 WIFI_POWER_EVENT_WAKELOCK_SAP);
Jeff Johnson23c3b842017-09-03 09:05:29 -07002117 qdf_wake_lock_timeout_acquire(&hdd_ctx->sap_wake_lock,
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05302118 HDD_SAP_WAKE_LOCK_DURATION);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002119 {
Manjeet Singhd295b1d2016-07-28 15:57:38 +05302120 struct station_info *sta_info;
Will Huang496b36c2017-07-11 16:38:50 +08002121 uint16_t iesLen = event->iesLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002122
Manjeet Singhd295b1d2016-07-28 15:57:38 +05302123 sta_info = qdf_mem_malloc(sizeof(*sta_info));
2124 if (!sta_info) {
2125 hdd_err("Failed to allocate station info");
2126 return QDF_STATUS_E_FAILURE;
2127 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002128 if (iesLen <= MAX_ASSOC_IND_IE_LEN) {
Manjeet Singhd295b1d2016-07-28 15:57:38 +05302129 sta_info->assoc_req_ies =
Will Huang496b36c2017-07-11 16:38:50 +08002130 (const u8 *)&event->ies[0];
Manjeet Singhd295b1d2016-07-28 15:57:38 +05302131 sta_info->assoc_req_ies_len = iesLen;
Ryan Hsue7bc3a72016-01-18 12:08:22 -08002132#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
2133 /*
2134 * After Kernel 4.0, it's no longer need to set
2135 * STATION_INFO_ASSOC_REQ_IES flag, as it
2136 * changed to use assoc_req_ies_len length to
Jeff Johnsond6a8af92018-05-06 16:01:28 -07002137 * check the existence of request IE.
Ryan Hsue7bc3a72016-01-18 12:08:22 -08002138 */
Manjeet Singhd295b1d2016-07-28 15:57:38 +05302139 sta_info->filled |= STATION_INFO_ASSOC_REQ_IES;
Ryan Hsue7bc3a72016-01-18 12:08:22 -08002140#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002141 cfg80211_new_sta(dev,
Will Huang496b36c2017-07-11 16:38:50 +08002142 (const u8 *)&event->staMac.bytes[0],
2143 sta_info, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002144 } else {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002145 hdd_err("Assoc Ie length is too long");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002146 }
Manjeet Singhd295b1d2016-07-28 15:57:38 +05302147 qdf_mem_free(sta_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002148 }
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07002149 /* Lets abort scan to ensure smooth authentication for client */
Sandeep Puligilla5f86d992017-10-29 14:58:53 -07002150 if (ucfg_scan_get_vdev_status(adapter->hdd_vdev) !=
2151 SCAN_NOT_IN_PROGRESS) {
Jeff Johnson23c3b842017-09-03 09:05:29 -07002152 wlan_abort_scan(hdd_ctx->hdd_pdev, INVAL_PDEV_ID,
Jeff Johnson1b780e42017-10-31 14:11:45 -07002153 adapter->session_id, INVALID_SCAN_ID, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002154 }
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002155 if (adapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002156 /* send peer status indication to oem app */
Will Huang496b36c2017-07-11 16:38:50 +08002157 hdd_send_peer_status_ind_to_app(
2158 &event->staMac,
2159 ePeerConnected,
2160 event->timingMeasCap,
Jeff Johnson1b780e42017-10-31 14:11:45 -07002161 adapter->session_id,
Will Huang496b36c2017-07-11 16:38:50 +08002162 &event->chan_info,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002163 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002164 }
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302165
Jeff Johnson8bb61112018-03-31 13:33:54 -07002166 hdd_green_ap_add_sta(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002167 break;
2168
2169 case eSAP_STA_DISASSOC_EVENT:
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05302170 disassoc_comp =
2171 &pSapEvent->sapevt.sapStationDisassocCompleteEvent;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002172 memcpy(wrqu.addr.sa_data,
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05302173 &disassoc_comp->staMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002174
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05302175 stainfo = hdd_get_stainfo(adapter->cache_sta_info,
2176 disassoc_comp->staMac);
Pragaspathi Thilagaraj961a8b82018-05-03 14:16:44 +05302177 if (!stainfo) {
2178 hdd_err("peer " MAC_ADDRESS_STR " not found",
2179 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
2180 return -EINVAL;
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05302181 }
Pragaspathi Thilagaraj961a8b82018-05-03 14:16:44 +05302182 hdd_info(" disassociated " MAC_ADDRESS_STR,
2183 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
2184
2185 stainfo->rssi = disassoc_comp->rssi;
2186 stainfo->tx_rate = disassoc_comp->tx_rate;
2187 stainfo->rx_rate = disassoc_comp->rx_rate;
2188 stainfo->reason_code = disassoc_comp->reason_code;
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05302189
Jeff Johnson5c19ade2017-10-04 09:52:12 -07002190 qdf_status = qdf_event_set(&hostapd_state->qdf_sta_disassoc_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05302191 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Srinivas Girigowda55756882017-03-06 16:45:27 -08002192 hdd_err("Station Deauth event Set failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002193
2194 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason ==
2195 eSAP_USR_INITATED_DISASSOC)
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002196 hdd_debug(" User initiated disassociation");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002197 else
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002198 hdd_debug(" MAC initiated disassociation");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002199 we_event = IWEVEXPIRED;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302200 qdf_status =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002201 hdd_softap_get_sta_id(adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002202 &pSapEvent->sapevt.
2203 sapStationDisassocCompleteEvent.staMac,
2204 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302205 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07002206 hdd_err("Failed to find sta id status: %d", qdf_status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302207 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002208 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002209
Nirav Shah1da77682016-05-03 20:16:39 +05302210 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
Jeff Johnson1b780e42017-10-31 14:11:45 -07002211 adapter->session_id,
Venkata Sharath Chandra Manchala0b9fc632017-05-15 14:35:15 -07002212 QDF_TRACE_DEFAULT_PDEV_ID,
Nirav Shah1da77682016-05-03 20:16:39 +05302213 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC));
2214
Yun Parkc3e35562018-03-08 12:05:52 -08002215 /* Send DHCP STOP indication to FW */
2216 stainfo->dhcp_phase = DHCP_PHASE_ACK;
Yun Park0ac12822018-04-02 11:18:04 -07002217 if (stainfo->dhcp_nego_status ==
2218 DHCP_NEGO_IN_PROGRESS)
Yun Parkc3e35562018-03-08 12:05:52 -08002219 hdd_post_dhcp_ind(adapter, staId,
2220 WMA_DHCP_STOP_IND);
2221 stainfo->dhcp_nego_status = DHCP_NEGO_STOP;
2222
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002223 hdd_softap_deregister_sta(adapter, staId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002224
Jeff Johnson136c51b2017-10-27 20:02:41 -07002225 ap_ctx->ap_active = false;
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07002226 spin_lock_bh(&adapter->sta_info_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002227 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07002228 if (adapter->sta_info[i].in_use
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002229 && i !=
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002230 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->
Jeff Johnson42518cf2017-10-26 13:33:29 -07002231 broadcast_sta_id) {
Jeff Johnson136c51b2017-10-27 20:02:41 -07002232 ap_ctx->ap_active = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002233 break;
2234 }
2235 }
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07002236 spin_unlock_bh(&adapter->sta_info_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002237
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002238#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Jeff Johnson23c3b842017-09-03 09:05:29 -07002239 wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002240#endif
2241
Jeff Johnson23c3b842017-09-03 09:05:29 -07002242 cds_host_diag_log_work(&hdd_ctx->sap_wake_lock,
Rajeev Kumarf98a5cc2017-07-28 08:42:46 -07002243 HDD_SAP_WAKE_LOCK_DURATION,
2244 WIFI_POWER_EVENT_WAKELOCK_SAP);
Jeff Johnson23c3b842017-09-03 09:05:29 -07002245 qdf_wake_lock_timeout_acquire(&hdd_ctx->sap_wake_lock,
Rajeev Kumarf98a5cc2017-07-28 08:42:46 -07002246 HDD_SAP_CLIENT_DISCONNECT_WAKE_LOCK_DURATION);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002247 cfg80211_del_sta(dev,
2248 (const u8 *)&pSapEvent->sapevt.
2249 sapStationDisassocCompleteEvent.staMac.
2250 bytes[0], GFP_KERNEL);
2251
2252 /* Update the beacon Interval if it is P2P GO */
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08002253 qdf_status = policy_mgr_change_mcc_go_beacon_interval(
Jeff Johnson1b780e42017-10-31 14:11:45 -07002254 hdd_ctx->hdd_psoc, adapter->session_id,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002255 adapter->device_mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302256 if (QDF_STATUS_SUCCESS != qdf_status) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08002257 hdd_err("Failed to update Beacon interval status: %d",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302258 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002259 }
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002260 if (adapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002261 /* send peer status indication to oem app */
Naveen Rawat910726a2017-03-06 11:42:51 -08002262 hdd_send_peer_status_ind_to_app(&pSapEvent->sapevt.
Abhishek Singh1c676222016-05-09 14:20:28 +05302263 sapStationDisassocCompleteEvent.
2264 staMac, ePeerDisconnected,
2265 0,
Jeff Johnson1b780e42017-10-31 14:11:45 -07002266 adapter->session_id,
Abhishek Singh1c676222016-05-09 14:20:28 +05302267 NULL,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002268 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002269 }
2270#ifdef MSM_PLATFORM
2271 /*stop timer in sap/p2p_go */
Jeff Johnson136c51b2017-10-27 20:02:41 -07002272 if (ap_ctx->ap_active == false) {
Jeff Johnson23c3b842017-09-03 09:05:29 -07002273 spin_lock_bh(&hdd_ctx->bus_bw_lock);
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002274 adapter->prev_tx_packets = 0;
2275 adapter->prev_rx_packets = 0;
2276 adapter->prev_fwd_tx_packets = 0;
2277 adapter->prev_fwd_rx_packets = 0;
Jeff Johnson23c3b842017-09-03 09:05:29 -07002278 spin_unlock_bh(&hdd_ctx->bus_bw_lock);
2279 hdd_bus_bw_compute_timer_try_stop(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002280 }
2281#endif
Jeff Johnson8bb61112018-03-31 13:33:54 -07002282 hdd_green_ap_del_sta(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002283 break;
2284
2285 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
Jeff Johnsonc98d41d2017-10-27 21:41:53 -07002286 hdd_debug("WPS PBC probe req");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302287 return QDF_STATUS_SUCCESS;
Jeff Johnsonc98d41d2017-10-27 21:41:53 -07002288
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002289 case eSAP_ASSOC_STA_CALLBACK_EVENT:
2290 pAssocStasArray =
2291 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07002292 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002293 for (i = 0;
2294 i <
2295 pSapEvent->sapevt.sapAssocStaListEvent.
2296 noOfAssocSta; i++) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07002297 hdd_info("Associated Sta Num %d:assocId=%d, staId=%d, staMac="
2298 MAC_ADDRESS_STR, i + 1,
2299 pAssocStasArray->assocId,
2300 pAssocStasArray->staId,
2301 MAC_ADDR_ARRAY(pAssocStasArray->staMac.
2302 bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002303 pAssocStasArray++;
2304 }
2305 }
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07002306 qdf_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002307 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302308 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002309 case eSAP_UNKNOWN_STA_JOIN:
2310 snprintf(unknownSTAEvent, IW_CUSTOM_MAX,
2311 "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
2312 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
2313 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
2314 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
2315 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
2316 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
2317 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
2318 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
2319 wrqu.data.pointer = unknownSTAEvent;
2320 wrqu.data.length = strlen(unknownSTAEvent);
2321 we_custom_event_generic = (uint8_t *) unknownSTAEvent;
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002322 hdd_err("%s", unknownSTAEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002323 break;
2324
2325 case eSAP_MAX_ASSOC_EXCEEDED:
2326 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX,
2327 "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
2328 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
2329 " one or more devices to enable the new device connection",
2330 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
2331 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
2332 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
2333 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
2334 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
2335 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.
2336 bytes[5]);
2337 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
2338 wrqu.data.pointer = maxAssocExceededEvent;
2339 wrqu.data.length = strlen(maxAssocExceededEvent);
2340 we_custom_event_generic = (uint8_t *) maxAssocExceededEvent;
Srinivas Girigowda55756882017-03-06 16:45:27 -08002341 hdd_debug("%s", maxAssocExceededEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002342 break;
2343 case eSAP_STA_ASSOC_IND:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302344 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002345
2346 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Jeff Johnsonb55bf512017-10-26 13:38:18 -07002347 hdd_clear_all_sta(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302348 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002349
2350 case eSAP_MAC_TRIG_STOP_BSS_EVENT:
Jeff Johnson0604a362018-03-24 17:36:59 -07002351 ret = hdd_stop_bss_link(adapter);
2352 if (ret)
2353 hdd_warn("hdd_stop_bss_link failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302354 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002355
2356 case eSAP_CHANNEL_CHANGE_EVENT:
Srinivas Girigowda55756882017-03-06 16:45:27 -08002357 hdd_debug("Received eSAP_CHANNEL_CHANGE_EVENT event");
Jeff Johnson0f9f87b2017-10-28 09:21:06 -07002358 if (hostapd_state->bss_state != BSS_STOP) {
Liangwei Dong5047d512016-10-11 00:24:26 -04002359 /* Prevent suspend for new channel */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002360 hdd_hostapd_channel_prevent_suspend(adapter,
Liangwei Dong5047d512016-10-11 00:24:26 -04002361 pSapEvent->sapevt.sap_ch_selected.pri_ch);
2362 /* Allow suspend for old channel */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002363 hdd_hostapd_channel_allow_suspend(adapter,
Jeff Johnson01206862017-10-27 20:55:59 -07002364 ap_ctx->operating_channel);
Liangwei Dong5047d512016-10-11 00:24:26 -04002365 }
Jeff Johnsond3919a92017-01-12 09:47:22 -08002366 /* SME/PE is already updated for new operation
2367 * channel. So update HDD layer also here. This
2368 * resolves issue in AP-AP mode where AP1 channel is
2369 * changed due to RADAR then CAC is going on and
2370 * START_BSS on new channel has not come to HDD. At
2371 * this case if AP2 is started it needs current
2372 * operation channel for MCC DFS restriction
2373 */
Jeff Johnson01206862017-10-27 20:55:59 -07002374 ap_ctx->operating_channel =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002375 pSapEvent->sapevt.sap_ch_selected.pri_ch;
Jeff Johnson91df29d2017-10-27 19:29:50 -07002376 ap_ctx->sap_config.acs_cfg.pri_ch =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002377 pSapEvent->sapevt.sap_ch_selected.pri_ch;
Jeff Johnson91df29d2017-10-27 19:29:50 -07002378 ap_ctx->sap_config.acs_cfg.ht_sec_ch =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002379 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
Jeff Johnson91df29d2017-10-27 19:29:50 -07002380 ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002381 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
Jeff Johnson91df29d2017-10-27 19:29:50 -07002382 ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002383 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
Jeff Johnson91df29d2017-10-27 19:29:50 -07002384 ap_ctx->sap_config.acs_cfg.ch_width =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002385 pSapEvent->sapevt.sap_ch_selected.ch_width;
2386
bings61d5bec2017-06-27 14:13:40 +08002387 sap_ch_param.ch_width =
2388 pSapEvent->sapevt.sap_ch_selected.ch_width;
2389 sap_ch_param.center_freq_seg0 =
2390 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
2391 sap_ch_param.center_freq_seg1 =
2392 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
Jeff Johnson23c3b842017-09-03 09:05:29 -07002393 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev,
bings61d5bec2017-06-27 14:13:40 +08002394 pSapEvent->sapevt.sap_ch_selected.pri_ch,
2395 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch,
2396 &sap_ch_param);
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05302397
Ajit Pal Singhd6c08f22018-04-25 16:55:26 +05302398 cdp_hl_fc_set_td_limit(cds_get_context(QDF_MODULE_ID_SOC),
2399 adapter->session_id,
2400 ap_ctx->operating_channel);
2401
bings58ce8622017-07-10 15:55:36 +08002402 phy_mode = wlan_sap_get_phymode(
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002403 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
bings58ce8622017-07-10 15:55:36 +08002404
2405 switch (phy_mode) {
2406 case eCSR_DOT11_MODE_11n:
2407 case eCSR_DOT11_MODE_11n_ONLY:
2408 case eCSR_DOT11_MODE_11ac:
2409 case eCSR_DOT11_MODE_11ac_ONLY:
2410 legacy_phymode = false;
2411 break;
2412 default:
2413 legacy_phymode = true;
2414 break;
2415 }
2416
Jeff Johnson68755312017-02-10 11:46:55 -08002417 chan_change.chan =
2418 pSapEvent->sapevt.sap_ch_selected.pri_ch;
2419 chan_change.chan_params.ch_width =
2420 pSapEvent->sapevt.sap_ch_selected.ch_width;
2421 chan_change.chan_params.sec_ch_offset =
bings61d5bec2017-06-27 14:13:40 +08002422 sap_ch_param.sec_ch_offset;
Jeff Johnson68755312017-02-10 11:46:55 -08002423 chan_change.chan_params.center_freq_seg0 =
2424 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
2425 chan_change.chan_params.center_freq_seg1 =
2426 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
2427
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002428 return hdd_chan_change_notify(adapter, dev,
bings58ce8622017-07-10 15:55:36 +08002429 chan_change, legacy_phymode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002430 case eSAP_ACS_SCAN_SUCCESS_EVENT:
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002431 return hdd_handle_acs_scan_event(pSapEvent, adapter);
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07002432
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002433 case eSAP_ACS_CHANNEL_SELECTED:
Srinivas Girigowda55756882017-03-06 16:45:27 -08002434 hdd_debug("ACS Completed for wlan%d",
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002435 adapter->dev->ifindex);
2436 clear_bit(ACS_PENDING, &adapter->event_flags);
Jeff Johnson23c3b842017-09-03 09:05:29 -07002437 clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
Jeff Johnson91df29d2017-10-27 19:29:50 -07002438 ap_ctx->sap_config.acs_cfg.pri_ch =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002439 pSapEvent->sapevt.sap_ch_selected.pri_ch;
Jeff Johnson91df29d2017-10-27 19:29:50 -07002440 ap_ctx->sap_config.acs_cfg.ht_sec_ch =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002441 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
Jeff Johnson91df29d2017-10-27 19:29:50 -07002442 ap_ctx->sap_config.acs_cfg.vht_seg0_center_ch =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002443 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
Jeff Johnson91df29d2017-10-27 19:29:50 -07002444 ap_ctx->sap_config.acs_cfg.vht_seg1_center_ch =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002445 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
Jeff Johnson91df29d2017-10-27 19:29:50 -07002446 ap_ctx->sap_config.acs_cfg.ch_width =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002447 pSapEvent->sapevt.sap_ch_selected.ch_width;
Himanshu Agarwalad4c0392018-05-08 16:53:36 +05302448 wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05302449 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302450 return QDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302451 case eSAP_ECSA_CHANGE_CHAN_IND:
Srinivas Girigowda55756882017-03-06 16:45:27 -08002452 hdd_debug("Channel change indication from peer for channel %d",
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302453 pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
2454 if (hdd_softap_set_channel_change(dev,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302455 pSapEvent->sapevt.sap_chan_cng_ind.new_chan,
Min Liu2fef5792018-01-19 17:59:42 +08002456 CH_WIDTH_MAX, false))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302457 return QDF_STATUS_E_FAILURE;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302458 else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302459 return QDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302460
Kapil Gupta8878ad92017-02-13 11:56:04 +05302461 case eSAP_DFS_NEXT_CHANNEL_REQ:
Dustin Brown5e89ef82018-03-14 11:50:23 -07002462 hdd_debug("Sending next channel query to userspace");
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002463 hdd_update_acs_timer_reason(adapter,
Kapil Gupta8878ad92017-02-13 11:56:04 +05302464 QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS);
2465 return QDF_STATUS_SUCCESS;
2466
Krunal Soni22208392017-09-29 18:10:34 -07002467 case eSAP_STOP_BSS_DUE_TO_NO_CHNL:
2468 hdd_debug("Stop sap session[%d]",
Jeff Johnson1b780e42017-10-31 14:11:45 -07002469 adapter->session_id);
Krunal Soni22208392017-09-29 18:10:34 -07002470 INIT_WORK(&adapter->sap_stop_bss_work,
2471 hdd_stop_sap_due_to_invalid_channel);
2472 schedule_work(&adapter->sap_stop_bss_work);
2473 return QDF_STATUS_SUCCESS;
2474
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002475 default:
Srinivas Girigowda55756882017-03-06 16:45:27 -08002476 hdd_debug("SAP message is not handled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002477 goto stopbss;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302478 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002479 }
2480 wireless_send_event(dev, we_event, &wrqu,
2481 (char *)we_custom_event_generic);
Manjeet Singhd295b1d2016-07-28 15:57:38 +05302482
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302483 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002484
2485stopbss:
2486 {
2487 uint8_t we_custom_event[64];
2488 char *stopBssEvent = "STOP-BSS.response"; /* 17 */
2489 int event_len = strlen(stopBssEvent);
2490
Srinivas Girigowda55756882017-03-06 16:45:27 -08002491 hdd_debug("BSS stop status = %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002492 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
2493 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
2494
Jeff Johnsond3919a92017-01-12 09:47:22 -08002495 /* Change the BSS state now since, as we are shutting
2496 * things down, we don't want interfaces to become
2497 * re-enabled
2498 */
Jeff Johnson0f9f87b2017-10-28 09:21:06 -07002499 hostapd_state->bss_state = BSS_STOP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002500
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002501#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Jeff Johnson23c3b842017-09-03 09:05:29 -07002502 wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002503#endif
2504
2505 /* Stop the pkts from n/w stack as we are going to free all of
Jeff Johnsond3919a92017-01-12 09:47:22 -08002506 * the TX WMM queues for all STAID's
2507 */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002508 hdd_debug("Disabling queues");
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002509 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05302510 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
2511 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002512
2513 /* reclaim all resources allocated to the BSS */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002514 qdf_status = hdd_softap_stop_bss(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302515 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002516 hdd_warn("hdd_softap_stop_bss failed %d",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302517 qdf_status);
Sravan Kumar Kairamce792eb2018-06-15 15:07:11 +05302518 if (ucfg_ipa_is_enabled()) {
2519 ucfg_ipa_uc_disconnect_ap(hdd_ctx->hdd_pdev,
2520 adapter->dev);
2521 ucfg_ipa_cleanup_dev_iface(hdd_ctx->hdd_pdev,
2522 adapter->dev);
2523 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002524 }
2525
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002526 /* notify userspace that the BSS has stopped */
2527 memset(&we_custom_event, '\0', sizeof(we_custom_event));
2528 memcpy(&we_custom_event, stopBssEvent, event_len);
2529 memset(&wrqu, 0, sizeof(wrqu));
2530 wrqu.data.length = event_len;
2531 we_event = IWEVCUSTOM;
2532 we_custom_event_generic = we_custom_event;
2533 wireless_send_event(dev, we_event, &wrqu,
2534 (char *)we_custom_event_generic);
Nitesh Shahf5765be2017-02-22 20:36:59 +05302535
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002536 /* once the event is set, structure dev/adapter should
Nitesh Shahf5765be2017-02-22 20:36:59 +05302537 * not be touched since they are now subject to being deleted
2538 * by another thread
2539 */
2540 if (eSAP_STOP_BSS_EVENT == sapEvent)
Jeff Johnson5c19ade2017-10-04 09:52:12 -07002541 qdf_event_set(&hostapd_state->qdf_stop_bss_event);
Nitesh Shahf5765be2017-02-22 20:36:59 +05302542
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08002543 hdd_ipa_set_tx_flow_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002544 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302545 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002546}
2547
Jeff Johnson89a0c742018-06-12 18:17:46 -07002548static int hdd_softap_unpack_ie(mac_handle_t mac_handle,
2549 eCsrEncryptionType *pEncryptType,
2550 eCsrEncryptionType *mcEncryptType,
2551 eCsrAuthType *pAuthType,
2552 bool *pMFPCapable,
2553 bool *pMFPRequired,
2554 uint16_t gen_ie_len, uint8_t *gen_ie)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002555{
Naveen Rawat72475db2017-12-13 18:07:35 -08002556 uint32_t ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002557 uint8_t *pRsnIe;
2558 uint16_t RSNIeLen;
Naveen Rawat72475db2017-12-13 18:07:35 -08002559 tDot11fIERSN dot11RSNIE = {0};
2560 tDot11fIEWPA dot11WPAIE = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002561
Jeff Johnson89a0c742018-06-12 18:17:46 -07002562 if (NULL == mac_handle) {
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002563 hdd_err("Error haHandle returned NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002564 return -EINVAL;
2565 }
2566 /* Validity checks */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302567 if ((gen_ie_len < QDF_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002568 || (gen_ie_len >
Anurag Chouhan6d760662016-02-20 16:05:43 +05302569 QDF_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002570 return -EINVAL;
2571 /* Type check */
2572 if (gen_ie[0] == DOT11F_EID_RSN) {
2573 /* Validity checks */
2574 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
2575 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302576 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002577 }
2578 /* Skip past the EID byte and length byte */
2579 pRsnIe = gen_ie + 2;
2580 RSNIeLen = gen_ie_len - 2;
2581 /* Unpack the RSN IE */
2582 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
Jeff Johnson89a0c742018-06-12 18:17:46 -07002583 ret = sme_unpack_rsn_ie(mac_handle, pRsnIe, RSNIeLen,
Naveen Rawat72475db2017-12-13 18:07:35 -08002584 &dot11RSNIE, false);
2585 if (DOT11F_FAILED(ret)) {
2586 hdd_err("unpack failed, ret: 0x%x", ret);
2587 return -EINVAL;
2588 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002589 /* Copy out the encryption and authentication types */
Srinivas Girigowda55756882017-03-06 16:45:27 -08002590 hdd_debug("pairwise cipher suite count: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002591 dot11RSNIE.pwise_cipher_suite_count);
Srinivas Girigowda55756882017-03-06 16:45:27 -08002592 hdd_debug("authentication suite count: %d",
Abhishek Singh3f13a812018-01-16 14:24:44 +05302593 dot11RSNIE.akm_suite_cnt);
Jeff Johnsond3919a92017-01-12 09:47:22 -08002594 /*
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07002595 * Here we have followed the apple base code,
2596 * but probably I suspect we can do something different
Abhishek Singh3f13a812018-01-16 14:24:44 +05302597 * dot11RSNIE.akm_suite_cnt
Jeff Johnsond3919a92017-01-12 09:47:22 -08002598 * Just translate the FIRST one
2599 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002600 *pAuthType =
Abhishek Singh3f13a812018-01-16 14:24:44 +05302601 hdd_translate_rsn_to_csr_auth_type(dot11RSNIE.akm_suite[0]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002602 /* dot11RSNIE.pwise_cipher_suite_count */
2603 *pEncryptType =
2604 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
2605 pwise_cipher_suites[0]);
2606 /* dot11RSNIE.gp_cipher_suite_count */
2607 *mcEncryptType =
2608 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
2609 gp_cipher_suite);
2610 /* Set the PMKSA ID Cache for this interface */
2611 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
2612 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002613 } else if (gen_ie[0] == DOT11F_EID_WPA) {
2614 /* Validity checks */
2615 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
2616 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302617 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002618 }
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07002619 /* Skip past the EID byte and length byte and 4 byte WiFi OUI */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002620 pRsnIe = gen_ie + 2 + 4;
2621 RSNIeLen = gen_ie_len - (2 + 4);
2622 /* Unpack the WPA IE */
2623 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
Jeff Johnson89a0c742018-06-12 18:17:46 -07002624 ret = dot11f_unpack_ie_wpa((tpAniSirGlobal) mac_handle,
Selvaraj, Sridhar75afbeb2017-04-03 17:08:59 +05302625 pRsnIe, RSNIeLen, &dot11WPAIE, false);
Naveen Rawat72475db2017-12-13 18:07:35 -08002626 if (DOT11F_FAILED(ret)) {
2627 hdd_err("unpack failed, ret: 0x%x", ret);
2628 return -EINVAL;
2629 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002630 /* Copy out the encryption and authentication types */
Srinivas Girigowda55756882017-03-06 16:45:27 -08002631 hdd_debug("WPA unicast cipher suite count: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002632 dot11WPAIE.unicast_cipher_count);
Srinivas Girigowda55756882017-03-06 16:45:27 -08002633 hdd_debug("WPA authentication suite count: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002634 dot11WPAIE.auth_suite_count);
2635 /* dot11WPAIE.auth_suite_count */
2636 /* Just translate the FIRST one */
2637 *pAuthType =
2638 hdd_translate_wpa_to_csr_auth_type(dot11WPAIE.auth_suites[0]);
2639 /* dot11WPAIE.unicast_cipher_count */
2640 *pEncryptType =
2641 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
2642 unicast_ciphers[0]);
2643 /* dot11WPAIE.unicast_cipher_count */
2644 *mcEncryptType =
2645 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
2646 multicast_cipher);
2647 *pMFPCapable = false;
2648 *pMFPRequired = false;
2649 } else {
Srinivas Girigowda55756882017-03-06 16:45:27 -08002650 hdd_err("gen_ie[0]: %d", gen_ie[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302651 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002652 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302653 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002654}
2655
2656/**
2657 * hdd_softap_set_channel_change() -
2658 * This function to support SAP channel change with CSA IE
2659 * set in the beacons.
2660 *
2661 * @dev: pointer to the net device.
2662 * @target_channel: target channel number.
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302663 * @target_bw: Target bandwidth to move.
2664 * If no bandwidth is specified, the value is CH_WIDTH_MAX
Min Liu2fef5792018-01-19 17:59:42 +08002665 * @forced: Force to switch channel, ignore SCC/MCC check
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002666 *
2667 * Return: 0 for success, non zero for failure
2668 */
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302669int hdd_softap_set_channel_change(struct net_device *dev, int target_channel,
Min Liu2fef5792018-01-19 17:59:42 +08002670 enum phy_ch_width target_bw, bool forced)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002671{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302672 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002673 int ret = 0;
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002674 struct hdd_adapter *adapter = (netdev_priv(dev));
Jeff Johnson23c3b842017-09-03 09:05:29 -07002675 struct hdd_context *hdd_ctx = NULL;
Jeff Johnson866aca82017-09-10 15:27:20 -07002676 struct hdd_adapter *sta_adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002677 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002678
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002679 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson23c3b842017-09-03 09:05:29 -07002680 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05302681 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002682 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002683
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002684 ret = hdd_validate_channel_and_bandwidth(adapter,
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +05302685 target_channel, target_bw);
2686 if (ret) {
2687 hdd_err("Invalid CH and BW combo");
2688 return ret;
2689 }
2690
Jeff Johnson23c3b842017-09-03 09:05:29 -07002691 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05302692 /*
2693 * conc_custom_rule1:
2694 * Force SCC for SAP + STA
2695 * if STA is already connected then we shouldn't allow
2696 * channel switch in SAP interface.
2697 */
Jeff Johnson23c3b842017-09-03 09:05:29 -07002698 if (sta_adapter && hdd_ctx->config->conc_custom_rule1) {
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05302699 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
2700 if (hdd_conn_is_connected(sta_ctx)) {
2701 hdd_err("Channel switch not allowed after STA connection with conc_custom_rule1 enabled");
2702 return -EBUSY;
2703 }
2704 }
2705
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002706 /*
2707 * Set the dfs_radar_found flag to mimic channel change
2708 * when a radar is found. This will enable synchronizing
2709 * SAP and HDD states similar to that of radar indication.
2710 * Suspend the netif queues to stop queuing Tx frames
2711 * from upper layers. netif queues will be resumed
2712 * once the channel change is completed and SAP will
2713 * post eSAP_START_BSS_EVENT success event to HDD.
2714 */
Min Liu2fef5792018-01-19 17:59:42 +08002715 if (qdf_atomic_inc_return(&adapter->dfs_radar_found) > 1) {
Arif Hussain2a7c1f32016-07-18 14:24:36 -07002716 hdd_err("Channel switch in progress!!");
2717 return -EBUSY;
2718 }
2719
Bala Venkatesh7e9c6882018-06-11 15:03:30 +05302720 status = policy_mgr_reset_chan_switch_complete_evt(hdd_ctx->hdd_psoc);
2721 if (!QDF_IS_STATUS_SUCCESS(status)) {
2722 hdd_err("clear event failed");
2723 return -EINVAL;
2724 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002725 /*
2726 * Post the Channel Change request to SAP.
2727 */
2728 status = wlansap_set_channel_change_with_csa(
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07002729 WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Dustin Brown5118e8e2016-09-13 15:54:23 -07002730 (uint32_t)target_channel,
Zhu Jianmin72d32de2018-05-11 10:54:10 +08002731 target_bw,
2732 forced && !(hdd_ctx->config->sta_sap_scc_on_lte_coex_chan));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002733
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302734 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08002735 hdd_err("SAP set channel failed for channel: %d, bw: %d",
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302736 target_channel, target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002737 /*
2738 * If channel change command fails then clear the
2739 * radar found flag and also restart the netif
2740 * queues.
2741 */
Min Liu2fef5792018-01-19 17:59:42 +08002742 qdf_atomic_set(&adapter->dfs_radar_found, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002743
2744 ret = -EINVAL;
2745 }
2746
2747 return ret;
2748}
2749
Chandrasekaran Manishekarcde33d72016-04-14 19:03:39 +05302750#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
2751/**
2752 * hdd_sap_restart_with_channel_switch() - SAP channel change with E/CSA
2753 * @ap_adapter: HDD adapter
2754 * @target_channel: Channel to which switch must happen
2755 * @target_bw: Bandwidth of the target channel
Min Liu2fef5792018-01-19 17:59:42 +08002756 * @forced: Force to switch channel, ignore SCC/MCC check
Chandrasekaran Manishekarcde33d72016-04-14 19:03:39 +05302757 *
2758 * Invokes the necessary API to perform channel switch for the SAP or GO
2759 *
2760 * Return: None
2761 */
Jeff Johnson866aca82017-09-10 15:27:20 -07002762void hdd_sap_restart_with_channel_switch(struct hdd_adapter *ap_adapter,
Chandrasekaran Manishekarcde33d72016-04-14 19:03:39 +05302763 uint32_t target_channel,
Min Liu2fef5792018-01-19 17:59:42 +08002764 uint32_t target_bw,
2765 bool forced)
Chandrasekaran Manishekarcde33d72016-04-14 19:03:39 +05302766{
2767 struct net_device *dev = ap_adapter->dev;
2768 int ret;
2769
Dustin Brown491d54b2018-03-14 12:39:11 -07002770 hdd_enter();
Chandrasekaran Manishekarcde33d72016-04-14 19:03:39 +05302771
2772 if (!dev) {
2773 hdd_err("Invalid dev pointer");
2774 return;
2775 }
2776
Min Liu2fef5792018-01-19 17:59:42 +08002777 ret = hdd_softap_set_channel_change(dev, target_channel,
2778 target_bw, forced);
Chandrasekaran Manishekarcde33d72016-04-14 19:03:39 +05302779 if (ret) {
2780 hdd_err("channel switch failed");
2781 return;
2782 }
2783}
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002784
Jeff Johnson23812942017-10-06 11:33:55 -07002785void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc,
2786 uint8_t vdev_id, uint32_t channel,
Min Liu2fef5792018-01-19 17:59:42 +08002787 uint32_t channel_bw,
2788 bool forced)
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002789{
Jeff Johnson23812942017-10-06 11:33:55 -07002790 struct hdd_adapter *ap_adapter =
2791 wlan_hdd_get_adapter_from_vdev(psoc, vdev_id);
2792
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002793 if (!ap_adapter) {
2794 hdd_err("Adapter is NULL");
2795 return;
2796 }
2797 hdd_sap_restart_with_channel_switch(ap_adapter, channel,
Min Liu2fef5792018-01-19 17:59:42 +08002798 channel_bw, forced);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002799}
2800
2801QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
2802 struct wlan_objmgr_psoc *psoc,
2803 uint8_t vdev_id, uint8_t *channel,
Ajit Pal Singh9b0ebdb2017-06-08 11:26:43 +05302804 uint8_t *sec_ch)
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002805{
Jeff Johnson89a0c742018-06-12 18:17:46 -07002806 mac_handle_t mac_handle;
Jeff Johnson87251032017-08-29 13:31:11 -07002807 struct hdd_ap_ctx *hdd_ap_ctx;
Tushnim Bhattacharyya2479ba32017-07-07 11:56:29 -07002808 uint8_t intf_ch = 0;
Jeff Johnsonc54bbf92017-08-28 11:59:35 -07002809 struct hdd_context *hdd_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07002810 struct hdd_station_ctx *hdd_sta_ctx;
Jeff Johnson866aca82017-09-10 15:27:20 -07002811 struct hdd_adapter *sta_adapter;
2812 struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev(
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002813 psoc, vdev_id);
2814 if (!ap_adapter) {
Tushnim Bhattacharyya2df9de72017-08-04 16:59:50 -07002815 hdd_err("ap_adapter is NULL");
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002816 return QDF_STATUS_E_FAILURE;
2817 }
2818
Tushnim Bhattacharyyaed678f92017-06-28 15:09:25 -07002819 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
2820 if (!hdd_ctx) {
2821 hdd_err("hdd_ctx is NULL");
2822 return QDF_STATUS_E_FAILURE;
2823 }
2824
2825 /* TODO: need work for 3 port case with sta+sta */
2826 sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
2827 if (!sta_adapter) {
Tushnim Bhattacharyya2df9de72017-08-04 16:59:50 -07002828 hdd_err("sta_adapter is NULL");
Tushnim Bhattacharyyaed678f92017-06-28 15:09:25 -07002829 return QDF_STATUS_E_FAILURE;
2830 }
2831
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002832 if (NULL == channel || NULL == sec_ch) {
2833 hdd_err("Null parameters");
Tushnim Bhattacharyya2df9de72017-08-04 16:59:50 -07002834 return QDF_STATUS_E_FAILURE;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002835 }
2836
Tushnim Bhattacharyya2df9de72017-08-04 16:59:50 -07002837 if (!test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
2838 hdd_err("SOFTAP_BSS_STARTED not set");
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002839 return QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyya2df9de72017-08-04 16:59:50 -07002840 }
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002841
2842 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
Tushnim Bhattacharyyaed678f92017-06-28 15:09:25 -07002843 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002844
Jeff Johnson89a0c742018-06-12 18:17:46 -07002845 mac_handle = hdd_ctx->mac_handle;
2846 if (!mac_handle) {
2847 hdd_err("mac_handle is NULL");
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002848 return QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyya2df9de72017-08-04 16:59:50 -07002849 }
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002850
Tushnim Bhattacharyyaed678f92017-06-28 15:09:25 -07002851 /*
2852 * Check if STA's channel is DFS or passive or part of LTE avoided
2853 * channel list. In that case move SAP to other band if DBS is
2854 * supported, return from here if DBS is not supported.
2855 * Need to take care of 3 port cases with 2 STA iface in future.
2856 */
Jeff Johnson0bbe66f2017-10-27 19:23:49 -07002857 intf_ch = wlansap_check_cc_intf(hdd_ap_ctx->sap_context);
Tushnim Bhattacharyya2479ba32017-07-07 11:56:29 -07002858 hdd_info("intf_ch: %d", intf_ch);
Jayachandran Sreekumaran9575dec2017-10-11 14:23:23 +05302859 if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION !=
2860 hdd_ctx->config->WlanMccToSccSwitchMode) {
2861 if (QDF_IS_STATUS_ERROR(
2862 policy_mgr_valid_sap_conc_channel_check(
2863 hdd_ctx->hdd_psoc,
2864 &intf_ch,
2865 policy_mgr_mode_specific_get_channel(
2866 hdd_ctx->hdd_psoc, PM_SAP_MODE)))) {
2867 hdd_debug("can't move sap to %d",
2868 hdd_sta_ctx->conn_info.operationChannel);
2869 return QDF_STATUS_E_FAILURE;
2870 }
Tushnim Bhattacharyyaed678f92017-06-28 15:09:25 -07002871 }
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002872
2873 if (intf_ch == 0) {
Tushnim Bhattacharyya2479ba32017-07-07 11:56:29 -07002874 hdd_debug("interface channel is 0");
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002875 return QDF_STATUS_E_FAILURE;
2876 }
2877
2878 hdd_info("SAP restart orig chan: %d, new chan: %d",
Jeff Johnson91df29d2017-10-27 19:29:50 -07002879 hdd_ap_ctx->sap_config.channel, intf_ch);
2880 hdd_ap_ctx->sap_config.channel = intf_ch;
Himanshu Agarwalf5c5b102018-05-22 20:13:57 +05302881 hdd_ap_ctx->sap_config.ch_params.ch_width = CH_WIDTH_MAX;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002882 hdd_ap_ctx->bss_stop_reason = BSS_STOP_DUE_TO_MCC_SCC_SWITCH;
2883
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002884 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev,
Jeff Johnson91df29d2017-10-27 19:29:50 -07002885 hdd_ap_ctx->sap_config.channel,
2886 hdd_ap_ctx->sap_config.sec_ch,
2887 &hdd_ap_ctx->sap_config.ch_params);
2888 *channel = hdd_ap_ctx->sap_config.channel;
2889 *sec_ch = hdd_ap_ctx->sap_config.sec_ch;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002890
Ajit Pal Singh9b0ebdb2017-06-08 11:26:43 +05302891 hdd_info("SAP channel change with CSA/ECSA");
Jeff Johnson23812942017-10-06 11:33:55 -07002892 hdd_sap_restart_chan_switch_cb(psoc, vdev_id,
Jeff Johnson91df29d2017-10-27 19:29:50 -07002893 hdd_ap_ctx->sap_config.channel,
Min Liu2fef5792018-01-19 17:59:42 +08002894 hdd_ap_ctx->sap_config.ch_params.ch_width, false);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002895
2896 return QDF_STATUS_SUCCESS;
2897}
Chandrasekaran Manishekarcde33d72016-04-14 19:03:39 +05302898#endif
2899
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07002900const struct net_device_ops net_ops_struct = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002901 .ndo_open = hdd_hostapd_open,
2902 .ndo_stop = hdd_hostapd_stop,
2903 .ndo_uninit = hdd_hostapd_uninit,
2904 .ndo_start_xmit = hdd_softap_hard_start_xmit,
2905 .ndo_tx_timeout = hdd_softap_tx_timeout,
2906 .ndo_get_stats = hdd_get_stats,
2907 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
2908 .ndo_do_ioctl = hdd_ioctl,
2909 .ndo_change_mtu = hdd_hostapd_change_mtu,
2910 .ndo_select_queue = hdd_hostapd_select_queue,
2911};
2912
Jeff Johnson15712092017-10-28 12:02:53 -07002913void hdd_set_ap_ops(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002914{
Jeff Johnson15712092017-10-28 12:02:53 -07002915 dev->netdev_ops = &net_ops_struct;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002916}
2917
Krunal Soni59437652017-11-21 13:42:14 -08002918bool hdd_sap_create_ctx(struct hdd_adapter *adapter)
2919{
2920 hdd_debug("creating sap context");
2921 adapter->session.ap.sap_context = sap_create_ctx();
2922 if (adapter->session.ap.sap_context)
2923 return true;
2924
2925 return false;
2926}
2927
2928bool hdd_sap_destroy_ctx(struct hdd_adapter *adapter)
2929{
2930 hdd_debug("destroying sap context");
2931 sap_destroy_ctx(adapter->session.ap.sap_context);
2932 adapter->session.ap.sap_context = NULL;
2933
2934 return true;
2935}
2936
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07002937QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002938{
Jeff Johnsonca2530c2017-09-30 18:25:40 -07002939 struct hdd_hostapd_state *phostapdBuf;
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07002940 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Krunal Soni4a020c72017-10-30 20:58:40 -07002941 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Jeff Johnson2bc0b722017-09-25 08:51:43 -07002942 struct sap_context *sapContext = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002943 int ret;
Agrawal Ashish65634612016-08-18 13:24:32 +05302944 enum dfs_mode acs_dfs_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002945
Dustin Brown491d54b2018-03-14 12:39:11 -07002946 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002947
Arun Khandavallicc544b32017-01-30 19:52:16 +05302948 hdd_info("SSR in progress: %d", reinit);
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05302949 qdf_atomic_init(&adapter->session.ap.acs_in_progress);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002950
Krunal Sonib51eec72017-11-20 21:53:01 -08002951 sapContext = hdd_hostapd_init_sap_session(adapter);
Krunal Soni4a020c72017-10-30 20:58:40 -07002952 if (!sapContext) {
2953 hdd_err("Invalid sap_ctx");
Krunal Sonib51eec72017-11-20 21:53:01 -08002954 goto error_release_vdev;
Krunal Soni4a020c72017-10-30 20:58:40 -07002955 }
Krunal Sonib51eec72017-11-20 21:53:01 -08002956
Krunal Soni4a020c72017-10-30 20:58:40 -07002957 if (!reinit) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07002958 adapter->session.ap.sap_config.channel =
Jeff Johnson23c3b842017-09-03 09:05:29 -07002959 hdd_ctx->acs_policy.acs_channel;
2960 acs_dfs_mode = hdd_ctx->acs_policy.acs_dfs_mode;
Jeff Johnsonb9424862017-10-30 08:49:35 -07002961 adapter->session.ap.sap_config.acs_dfs_mode =
Arun Khandavallicc544b32017-01-30 19:52:16 +05302962 wlan_hdd_get_dfs_mode(acs_dfs_mode);
2963 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002964
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002965 /* Allocate the Wireless Extensions state structure */
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07002966 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002967
Jeff Johnson89a0c742018-06-12 18:17:46 -07002968 sme_set_curr_device_mode(hdd_ctx->mac_handle, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002969
2970 /* Zero the memory. This zeros the profile structure. */
Jeff Johnsonca2530c2017-09-30 18:25:40 -07002971 memset(phostapdBuf, 0, sizeof(struct hdd_hostapd_state));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002972
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302973 status = qdf_event_create(&phostapdBuf->qdf_event);
2974 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08002975 hdd_err("Hostapd HDD qdf event init failed!!");
Krunal Sonib51eec72017-11-20 21:53:01 -08002976 goto error_release_sap_session;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002977 }
2978
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302979 status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event);
2980 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08002981 hdd_err("Hostapd HDD stop bss event init failed!!");
Krunal Sonib51eec72017-11-20 21:53:01 -08002982 goto error_release_sap_session;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002983 }
2984
Wei Song2f76f642016-11-18 16:32:53 +08002985 status = qdf_event_create(&phostapdBuf->qdf_sta_disassoc_event);
2986 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08002987 hdd_err("Hostapd HDD sta disassoc event init failed!!");
Krunal Sonib51eec72017-11-20 21:53:01 -08002988 goto error_release_sap_session;
Wei Song2f76f642016-11-18 16:32:53 +08002989 }
2990
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002991 /* Register as a wireless device */
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302992 hdd_register_hostapd_wext(adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002993
2994 /* Initialize the data path module */
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07002995 status = hdd_softap_init_tx_rx(adapter);
Krunal Sonib51eec72017-11-20 21:53:01 -08002996 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08002997 hdd_err("hdd_softap_init_tx_rx failed");
Krunal Sonib51eec72017-11-20 21:53:01 -08002998 goto error_release_sap_session;
2999 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003000
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003001 status = hdd_wmm_adapter_init(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303002 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003003 hdd_err("hdd_wmm_adapter_init() failed code: %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003004 status, status);
Krunal Sonib51eec72017-11-20 21:53:01 -08003005 goto error_release_wmm;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003006 }
3007
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003008 set_bit(WMM_INIT_DONE, &adapter->event_flags);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003009
Jeff Johnson1b780e42017-10-31 14:11:45 -07003010 ret = wma_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003011 WMI_PDEV_PARAM_BURST_ENABLE,
Dundi Raviteja3aa01be2018-05-21 18:58:59 +05303012 HDD_ENABLE_SIFS_BURST_DEFAULT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003013 PDEV_CMD);
3014
Srinivas Girigowda55756882017-03-06 16:45:27 -08003015 if (0 != ret)
3016 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed: %d", ret);
Arun Khandavallicc544b32017-01-30 19:52:16 +05303017
3018 if (!reinit) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07003019 adapter->session.ap.sap_config.acs_cfg.acs_mode = false;
Himanshu Agarwal1b3be702018-02-20 12:16:57 +05303020 wlan_hdd_undo_acs(adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -07003021 qdf_mem_zero(&adapter->session.ap.sap_config.acs_cfg,
Arun Khandavallicc544b32017-01-30 19:52:16 +05303022 sizeof(struct sap_acs_cfg));
3023 }
3024
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05303025 /* rcpi info initialization */
3026 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
3027
Dustin Browne74003f2018-03-14 12:51:58 -07003028 hdd_exit();
Dustin Brownd28772b2017-03-17 14:16:07 -07003029
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003030 return status;
3031
Krunal Sonib51eec72017-11-20 21:53:01 -08003032error_release_wmm:
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003033 hdd_softap_deinit_tx_rx(adapter);
Krunal Sonib51eec72017-11-20 21:53:01 -08003034error_release_sap_session:
Rachit Kankane0dc3e852018-05-07 17:33:42 +05303035 hdd_unregister_wext(adapter->dev);
Krunal Soni4a020c72017-10-30 20:58:40 -07003036 hdd_hostapd_deinit_sap_session(adapter);
Krunal Sonib51eec72017-11-20 21:53:01 -08003037error_release_vdev:
3038 QDF_BUG(!hdd_vdev_destroy(adapter));
Dustin Brownd28772b2017-03-17 14:16:07 -07003039
Dustin Browne74003f2018-03-14 12:51:58 -07003040 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003041 return status;
3042}
3043
Krunal Soni4a020c72017-10-30 20:58:40 -07003044void hdd_deinit_ap_mode(struct hdd_context *hdd_ctx,
3045 struct hdd_adapter *adapter,
3046 bool rtnl_held)
3047{
Dustin Brownfdf17c12018-03-14 12:55:34 -07003048 hdd_enter_dev(adapter->dev);
Krunal Soni4a020c72017-10-30 20:58:40 -07003049
3050 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
3051 hdd_wmm_adapter_close(adapter);
3052 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
3053 }
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05303054 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Krunal Soni4a020c72017-10-30 20:58:40 -07003055 wlan_hdd_undo_acs(adapter);
3056 hdd_softap_deinit_tx_rx(adapter);
3057 /*
3058 * if we are being called during driver unload,
3059 * then the dev has already been invalidated.
3060 * if we are being called at other times, then we can
3061 * detach the wireless device handlers
3062 */
3063 if (adapter->dev) {
3064 if (rtnl_held) {
3065 adapter->dev->wireless_handlers = NULL;
3066 } else {
3067 rtnl_lock();
3068 adapter->dev->wireless_handlers = NULL;
3069 rtnl_unlock();
3070 }
3071 }
3072 if (hdd_hostapd_deinit_sap_session(adapter))
3073 hdd_err("Failed:hdd_hostapd_deinit_sap_session");
Krunal Soni4a020c72017-10-30 20:58:40 -07003074
Dustin Browne74003f2018-03-14 12:51:58 -07003075 hdd_exit();
Krunal Soni4a020c72017-10-30 20:58:40 -07003076}
3077
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003078/**
3079 * hdd_wlan_create_ap_dev() - create an AP-mode device
Jeff Johnson23c3b842017-09-03 09:05:29 -07003080 * @hdd_ctx: Global HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003081 * @macAddr: MAC address to assign to the interface
Ryan Hsu07495ea2016-01-21 15:25:39 -08003082 * @name_assign_type: the name of assign type of the netdev
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003083 * @iface_name: User-visible name of the interface
3084 *
3085 * This function will allocate a Linux net_device and configuration it
3086 * for an AP mode of operation. Note that the device is NOT actually
3087 * registered with the kernel at this time.
3088 *
3089 * Return: A pointer to the private data portion of the net_device if
3090 * the allocation and initialization was successful, NULL otherwise.
3091 */
Jeff Johnson23c3b842017-09-03 09:05:29 -07003092struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003093 tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003094 unsigned char name_assign_type,
3095 uint8_t *iface_name)
3096{
Jeff Johnson15712092017-10-28 12:02:53 -07003097 struct net_device *dev;
3098 struct hdd_adapter *adapter;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303099 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003100
Srinivas Girigowda55756882017-03-06 16:45:27 -08003101 hdd_debug("iface_name = %s", iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003102
Jeff Johnson15712092017-10-28 12:02:53 -07003103 dev = alloc_netdev_mq(sizeof(struct hdd_adapter), iface_name,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
3105 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003106#endif
Ryan Hsu07495ea2016-01-21 15:25:39 -08003107 ether_setup, NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003108
Jeff Johnson15712092017-10-28 12:02:53 -07003109 if (!dev)
3110 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003111
Jeff Johnson15712092017-10-28 12:02:53 -07003112 adapter = netdev_priv(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003113
Jeff Johnson15712092017-10-28 12:02:53 -07003114 /* Init the net_device structure */
3115 ether_setup(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003116
Jeff Johnson15712092017-10-28 12:02:53 -07003117 /* Initialize the adapter context to zeros. */
3118 qdf_mem_zero(adapter, sizeof(struct hdd_adapter));
3119 adapter->dev = dev;
3120 adapter->hdd_ctx = hdd_ctx;
3121 adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003122 adapter->session_id = HDD_SESSION_ID_INVALID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003123
Jeff Johnson15712092017-10-28 12:02:53 -07003124 hdd_debug("dev = %pK, adapter = %pK, concurrency_mode=0x%x",
3125 dev, adapter,
3126 (int)policy_mgr_get_concurrency_mode(hdd_ctx->hdd_psoc));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003127
Jeff Johnson15712092017-10-28 12:02:53 -07003128 /* Init the net_device structure */
3129 strlcpy(dev->name, (const char *)iface_name, IFNAMSIZ);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003130
Jeff Johnson15712092017-10-28 12:02:53 -07003131 hdd_set_ap_ops(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003132
Jeff Johnson15712092017-10-28 12:02:53 -07003133 dev->watchdog_timeo = HDD_TX_TIMEOUT;
3134 dev->mtu = HDD_DEFAULT_MTU;
3135 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
jge3e6f6382016-09-29 13:28:28 +08003136
Jeff Johnson15712092017-10-28 12:02:53 -07003137 if (hdd_ctx->config->enable_ip_tcp_udp_checksum_offload)
3138 dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
3139 dev->features |= NETIF_F_RXCSUM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003140
Jeff Johnson15712092017-10-28 12:02:53 -07003141 qdf_mem_copy(dev->dev_addr, (void *)macAddr,
3142 sizeof(tSirMacAddr));
Jeff Johnson1e851a12017-10-28 14:36:12 -07003143 qdf_mem_copy(adapter->mac_addr.bytes,
Jeff Johnson15712092017-10-28 12:02:53 -07003144 (void *)macAddr, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003145
Jeff Johnson15712092017-10-28 12:02:53 -07003146 adapter->offloads_configured = false;
3147 hdd_dev_setup_destructor(dev);
3148 dev->ieee80211_ptr = &adapter->wdev;
3149 adapter->wdev.wiphy = hdd_ctx->wiphy;
3150 adapter->wdev.netdev = dev;
3151 hdd_set_tso_flags(hdd_ctx, dev);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303152
3153 qdf_status = qdf_event_create(
3154 &adapter->qdf_session_open_event);
3155 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3156 hdd_err("failed to create session open QDF event!");
3157 free_netdev(adapter->dev);
3158 return NULL;
3159 }
3160
3161 qdf_status = qdf_event_create(
3162 &adapter->qdf_session_close_event);
3163 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3164 hdd_err("failed to create session close QDF event!");
3165 free_netdev(adapter->dev);
3166 return NULL;
3167 }
3168
Dustin Brown662f48b2018-06-22 17:21:00 -07003169 init_completion(&adapter->disconnect_comp_var);
3170 init_completion(&adapter->roaming_comp_var);
3171 init_completion(&adapter->linkup_event_var);
Jeff Johnson15712092017-10-28 12:02:53 -07003172 init_completion(&adapter->cancel_rem_on_chan_var);
3173 init_completion(&adapter->rem_on_chan_ready_event);
3174 init_completion(&adapter->sta_authorized_event);
3175 init_completion(&adapter->offchannel_tx_event);
Dustin Brown662f48b2018-06-22 17:21:00 -07003176 init_completion(&adapter->tx_action_cnf_event);
3177 init_completion(&adapter->ibss_peer_info_comp);
3178 init_completion(&adapter->lfr_fw_status.disable_lfr_event);
Jeff Johnson15712092017-10-28 12:02:53 -07003179
3180 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
3181 spin_lock_init(&adapter->pause_map_lock);
3182 adapter->start_time = adapter->last_time = qdf_system_ticks();
3183
Min Liu2fef5792018-01-19 17:59:42 +08003184 qdf_atomic_init(&adapter->dfs_radar_found);
3185
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003186 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003187}
3188
3189/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003190 * wlan_hdd_rate_is_11g() - check if rate is 11g rate or not
3191 * @rate: Rate to be checked
3192 *
3193 * Return: true if rate if 11g else false
3194 */
3195static bool wlan_hdd_rate_is_11g(u8 rate)
3196{
3197 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72,
3198 96, 108}; /* actual rate * 2 */
3199 u8 i;
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07003200
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003201 for (i = 0; i < 8; i++) {
3202 if (rate == gRateArray[i])
3203 return true;
3204 }
3205 return false;
3206}
3207
3208#ifdef QCA_HT_2040_COEX
3209/**
3210 * wlan_hdd_get_sap_obss() - Get SAP OBSS enable config based on HT_CAPAB IE
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003211 * @adapter: Pointer to hostapd adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003212 *
3213 * Return: HT support channel width config value
3214 */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003215static bool wlan_hdd_get_sap_obss(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003216{
Naveen Rawat72475db2017-12-13 18:07:35 -08003217 uint32_t ret;
3218 const uint8_t *ie = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003219 uint8_t ht_cap_ie[DOT11F_IE_HTCAPS_MAX_LEN];
3220 tDot11fIEHTCaps dot11_ht_cap_ie = {0};
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003221 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -07003222 struct hdd_beacon_data *beacon = adapter->session.ap.beacon;
Jeff Johnson89a0c742018-06-12 18:17:46 -07003223 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003224
Jeff Johnson89a0c742018-06-12 18:17:46 -07003225 mac_handle = hdd_ctx->mac_handle;
Naveen Rawat08db88f2017-09-08 15:07:48 -07003226 ie = wlan_get_ie_ptr_from_eid(WLAN_EID_HT_CAPABILITY,
3227 beacon->tail, beacon->tail_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003228 if (ie && ie[1]) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303229 qdf_mem_copy(ht_cap_ie, &ie[2], DOT11F_IE_HTCAPS_MAX_LEN);
Jeff Johnson89a0c742018-06-12 18:17:46 -07003230 ret = dot11f_unpack_ie_ht_caps((tpAniSirGlobal)mac_handle,
Naveen Rawat72475db2017-12-13 18:07:35 -08003231 ht_cap_ie, ie[1],
3232 &dot11_ht_cap_ie, false);
3233 if (DOT11F_FAILED(ret)) {
3234 hdd_err("unpack failed, ret: 0x%x", ret);
3235 return false;
3236 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003237 return dot11_ht_cap_ie.supportedChannelWidthSet;
3238 }
3239
3240 return false;
3241}
3242#else
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003243static bool wlan_hdd_get_sap_obss(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003244{
3245 return false;
3246}
3247#endif
3248/**
3249 * wlan_hdd_set_channel() - set channel in sap mode
3250 * @wiphy: Pointer to wiphy structure
3251 * @dev: Pointer to net_device structure
3252 * @chandef: Pointer to channel definition structure
3253 * @channel_type: Channel type
3254 *
3255 * Return: 0 for success non-zero for failure
3256 */
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05303257int wlan_hdd_set_channel(struct wiphy *wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003258 struct net_device *dev,
3259 struct cfg80211_chan_def *chandef,
3260 enum nl80211_channel_type channel_type)
3261{
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003262 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003263 uint32_t num_ch = 0;
3264 int channel = 0;
3265 int channel_seg2 = 0;
Jeff Johnson23c3b842017-09-03 09:05:29 -07003266 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003267 int status;
Jeff Johnson89a0c742018-06-12 18:17:46 -07003268 mac_handle_t mac_handle;
Manjeet Singhaec78b52016-11-03 15:43:56 +05303269 tSmeConfigParams *sme_config;
Jeff Johnsone4c11db2018-05-05 23:22:32 -07003270 tsap_config_t *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003271
Dustin Brown491d54b2018-03-14 12:39:11 -07003272 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003273
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003274 if (NULL == dev) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003275 hdd_err("Called with dev = NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003276 return -ENODEV;
3277 }
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003278 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003279
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303280 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003281 TRACE_CODE_HDD_CFG80211_SET_CHANNEL,
Jeff Johnson1b780e42017-10-31 14:11:45 -07003282 adapter->session_id, channel_type));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003283
Srinivas Girigowda55756882017-03-06 16:45:27 -08003284 hdd_debug("Device_mode %s(%d) freq = %d",
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003285 hdd_device_mode_to_string(adapter->device_mode),
3286 adapter->device_mode, chandef->chan->center_freq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003287
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003288 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson23c3b842017-09-03 09:05:29 -07003289 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05303290 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003291 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05303292
Jeff Johnson89a0c742018-06-12 18:17:46 -07003293 mac_handle = hdd_ctx->mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003294
3295 /*
3296 * Do freq to chan conversion
3297 * TODO: for 11a
3298 */
3299
3300 channel = ieee80211_frequency_to_channel(chandef->chan->center_freq);
Arif Hussain174c3fc2016-07-28 11:19:42 -07003301
Kiran Kumar Lokeref1f5e992016-06-20 16:48:50 -07003302 if (NL80211_CHAN_WIDTH_80P80 == chandef->width ||
Arif Hussain174c3fc2016-07-28 11:19:42 -07003303 NL80211_CHAN_WIDTH_160 == chandef->width) {
3304 if (chandef->center_freq2)
3305 channel_seg2 = ieee80211_frequency_to_channel(
3306 chandef->center_freq2);
3307 else
3308 hdd_err("Invalid center_freq2");
3309 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003310
3311 /* Check freq range */
3312 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
3313 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003314 hdd_err("Channel: %d is outside valid range from %d to %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003315 channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
3316 WNI_CFG_CURRENT_CHANNEL_STAMAX);
3317 return -EINVAL;
3318 }
3319
3320 /* Check freq range */
3321
3322 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel_seg2) ||
3323 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel_seg2)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003324 hdd_err("Channel: %d is outside valid range from %d to %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003325 channel_seg2, WNI_CFG_CURRENT_CHANNEL_STAMIN,
3326 WNI_CFG_CURRENT_CHANNEL_STAMAX);
3327 return -EINVAL;
3328 }
3329
3330 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
3331
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003332 if ((QDF_SAP_MODE != adapter->device_mode) &&
3333 (QDF_P2P_GO_MODE != adapter->device_mode)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303334 if (QDF_STATUS_SUCCESS !=
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003335 wlan_hdd_validate_operation_channel(adapter, channel)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003336 hdd_err("Invalid Channel: %d", channel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003337 return -EINVAL;
3338 }
Srinivas Girigowda55756882017-03-06 16:45:27 -08003339 hdd_debug("set channel to [%d] for device mode %s(%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003340 channel,
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003341 hdd_device_mode_to_string(adapter->device_mode),
3342 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003343 }
3344
Jeff Johnson2b89f8b2018-03-14 12:37:14 -07003345 if ((adapter->device_mode == QDF_STA_MODE) ||
3346 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
3347 struct csr_roam_profile *roam_profile;
Jeff Johnsond377dce2017-10-04 10:32:42 -07003348 struct hdd_station_ctx *sta_ctx =
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003349 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003350
3351 if (eConnectionState_IbssConnected ==
Jeff Johnsond377dce2017-10-04 10:32:42 -07003352 sta_ctx->conn_info.connState) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003353 /* Link is up then return cant set channel */
Jeff Johnsonecd884e2016-06-30 14:52:25 -07003354 hdd_err("IBSS Associated, can't set the channel");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003355 return -EINVAL;
3356 }
3357
Jeff Johnson2b89f8b2018-03-14 12:37:14 -07003358 roam_profile = hdd_roam_profile(adapter);
Jeff Johnson5b34fce2017-10-13 13:24:51 -07003359 num_ch = roam_profile->ChannelInfo.numOfChannels = 1;
Jeff Johnsond377dce2017-10-04 10:32:42 -07003360 sta_ctx->conn_info.operationChannel = channel;
Jeff Johnson5b34fce2017-10-13 13:24:51 -07003361 roam_profile->ChannelInfo.ChannelList =
Jeff Johnsond377dce2017-10-04 10:32:42 -07003362 &sta_ctx->conn_info.operationChannel;
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003363 } else if ((adapter->device_mode == QDF_SAP_MODE)
3364 || (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003365 ) {
Jeff Johnson91df29d2017-10-27 19:29:50 -07003366 sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(adapter))->sap_config);
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003367 if (QDF_P2P_GO_MODE == adapter->device_mode) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303368 if (QDF_STATUS_SUCCESS !=
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003369 wlan_hdd_validate_operation_channel(adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003370 channel)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003371 hdd_err("Invalid Channel: %d", channel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003372 return -EINVAL;
3373 }
3374 sap_config->channel = channel;
3375 sap_config->ch_params.center_freq_seg1 = channel_seg2;
3376 } else {
3377 /* set channel to what hostapd configured */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303378 if (QDF_STATUS_SUCCESS !=
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003379 wlan_hdd_validate_operation_channel(adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003380 channel)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003381 hdd_err("Invalid Channel: %d", channel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003382 return -EINVAL;
3383 }
3384
3385 sap_config->channel = channel;
3386 sap_config->ch_params.center_freq_seg1 = channel_seg2;
3387
Manjeet Singhaec78b52016-11-03 15:43:56 +05303388 sme_config = qdf_mem_malloc(sizeof(*sme_config));
3389
3390 if (!sme_config) {
3391 hdd_err("Unable to allocate memory for smeconfig!");
3392 return -ENOMEM;
3393 }
Jeff Johnson89a0c742018-06-12 18:17:46 -07003394 sme_get_config_param(mac_handle, sme_config);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003395 switch (channel_type) {
3396 case NL80211_CHAN_HT20:
3397 case NL80211_CHAN_NO_HT:
Manjeet Singhaec78b52016-11-03 15:43:56 +05303398 sme_config->csrConfig.obssEnabled = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003399 sap_config->sec_ch = 0;
3400 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003401 case NL80211_CHAN_HT40MINUS:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003402 sap_config->sec_ch = sap_config->channel - 4;
3403 break;
3404 case NL80211_CHAN_HT40PLUS:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003405 sap_config->sec_ch = sap_config->channel + 4;
3406 break;
3407 default:
Jeff Johnsonecd884e2016-06-30 14:52:25 -07003408 hdd_err("Error!!! Invalid HT20/40 mode !");
Manjeet Singhaec78b52016-11-03 15:43:56 +05303409 qdf_mem_free(sme_config);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003410 return -EINVAL;
3411 }
Manjeet Singhaec78b52016-11-03 15:43:56 +05303412 sme_config->csrConfig.obssEnabled =
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003413 wlan_hdd_get_sap_obss(adapter);
Manjeet Singhaec78b52016-11-03 15:43:56 +05303414
Jeff Johnson89a0c742018-06-12 18:17:46 -07003415 sme_update_config(mac_handle, sme_config);
Manjeet Singhaec78b52016-11-03 15:43:56 +05303416 qdf_mem_free(sme_config);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003417 }
3418 } else {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07003419 hdd_err("Invalid device mode failed to set valid channel");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003420 return -EINVAL;
3421 }
Dustin Browne74003f2018-03-14 12:51:58 -07003422 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003423 return status;
3424}
3425
3426/**
3427 * wlan_hdd_check_11gmode() - check for 11g mode
3428 * @pIe: Pointer to IE
3429 * @require_ht: Pointer to require ht
3430 * @require_vht: Pointer to require vht
3431 * @pCheckRatesfor11g: Pointer to check rates for 11g mode
3432 * @pSapHw_mode: SAP HW mode
3433 *
3434 * Check for 11g rate and set proper 11g only mode
3435 *
3436 * Return: none
3437 */
Naveen Rawat08db88f2017-09-08 15:07:48 -07003438static void wlan_hdd_check_11gmode(const u8 *pIe, u8 *require_ht,
3439 u8 *require_vht, u8 *pCheckRatesfor11g,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003440 eCsrPhyMode *pSapHw_mode)
3441{
3442 u8 i, num_rates = pIe[0];
3443
3444 pIe += 1;
3445 for (i = 0; i < num_rates; i++) {
3446 if (*pCheckRatesfor11g
3447 && (true == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK))) {
3448 /* If rate set have 11g rate than change the mode
3449 * to 11G
3450 */
3451 *pSapHw_mode = eCSR_DOT11_MODE_11g;
3452 if (pIe[i] & BASIC_RATE_MASK) {
3453 /* If we have 11g rate as basic rate, it
3454 * means mode is 11g only mode.
3455 */
3456 *pSapHw_mode = eCSR_DOT11_MODE_11g_ONLY;
3457 *pCheckRatesfor11g = false;
3458 }
3459 } else {
3460 if ((BASIC_RATE_MASK |
3461 WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
3462 *require_ht = true;
3463 else if ((BASIC_RATE_MASK |
3464 WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY) == pIe[i])
3465 *require_vht = true;
3466 }
3467 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003468}
3469
Naveen Rawatd8feac12017-09-08 15:08:39 -07003470#ifdef WLAN_FEATURE_11AX
3471/**
3472 * wlan_hdd_add_extn_ie() - add extension IE
3473 * @adapter: Pointer to hostapd adapter
3474 * @genie: Pointer to ie to be added
3475 * @total_ielen: Pointer to store total ie length
3476 * @oui: Pointer to oui
3477 * @oui_size: Size of oui
3478 *
3479 * Return: 0 for success non-zero for failure
3480 */
3481static int wlan_hdd_add_extn_ie(struct hdd_adapter *adapter, uint8_t *genie,
3482 uint16_t *total_ielen, uint8_t *oui,
3483 uint8_t oui_size)
3484{
3485 const uint8_t *ie;
3486 uint16_t ielen = 0;
Jeff Johnsonb9424862017-10-30 08:49:35 -07003487 struct hdd_beacon_data *beacon = adapter->session.ap.beacon;
Naveen Rawatd8feac12017-09-08 15:08:39 -07003488
3489 ie = wlan_get_ext_ie_ptr_from_ext_id(oui, oui_size,
3490 beacon->tail,
3491 beacon->tail_len);
3492 if (ie) {
3493 ielen = ie[1] + 2;
3494 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
3495 qdf_mem_copy(&genie[*total_ielen], ie, ielen);
3496 } else {
3497 hdd_err("**Ie Length is too big***");
3498 return -EINVAL;
3499 }
3500 *total_ielen += ielen;
3501 }
3502 return 0;
3503}
3504#endif
3505
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003506/**
Abhishek Singh86ea5c72017-09-01 16:08:09 +05303507 * wlan_hdd_add_hostapd_conf_vsie() - configure Vendor IE in sap mode
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003508 * @adapter: Pointer to hostapd adapter
Abhishek Singh86ea5c72017-09-01 16:08:09 +05303509 * @genie: Pointer to Vendor IE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003510 * @total_ielen: Pointer to store total ie length
3511 *
3512 * Return: none
3513 */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003514static void wlan_hdd_add_hostapd_conf_vsie(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003515 uint8_t *genie,
Liangwei Dongec9be932016-10-19 05:59:13 -04003516 uint16_t *total_ielen)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003517{
Jeff Johnsonb9424862017-10-30 08:49:35 -07003518 struct hdd_beacon_data *pBeacon = adapter->session.ap.beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003519 int left = pBeacon->tail_len;
3520 uint8_t *ptr = pBeacon->tail;
3521 uint8_t elem_id, elem_len;
3522 uint16_t ielen = 0;
Abhishek Singh86ea5c72017-09-01 16:08:09 +05303523 bool skip_ie;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003524
3525 if (NULL == ptr || 0 == left)
3526 return;
3527
3528 while (left >= 2) {
3529 elem_id = ptr[0];
3530 elem_len = ptr[1];
3531 left -= 2;
Ashish Kumar Dhanotiya20f09e42017-08-04 17:59:38 +05303532 if (elem_len > left) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003533 hdd_err("**Invalid IEs eid: %d elem_len: %d left: %d**",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003534 elem_id, elem_len, left);
3535 return;
3536 }
Abhishek Singh86ea5c72017-09-01 16:08:09 +05303537 if (IE_EID_VENDOR == elem_id) {
3538 /*
3539 * skipping the Vendor IE's which we don't want to
3540 * include or it will be included by existing code.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003541 */
Abhishek Singh86ea5c72017-09-01 16:08:09 +05303542 if (elem_len >= WPS_OUI_TYPE_SIZE &&
3543 (!qdf_mem_cmp(&ptr[2], WHITELIST_OUI_TYPE,
3544 WPA_OUI_TYPE_SIZE) ||
3545 !qdf_mem_cmp(&ptr[2], BLACKLIST_OUI_TYPE,
3546 WPA_OUI_TYPE_SIZE) ||
3547 !qdf_mem_cmp(&ptr[2], "\x00\x50\xf2\x02",
3548 WPA_OUI_TYPE_SIZE) ||
3549 !qdf_mem_cmp(&ptr[2], WPA_OUI_TYPE,
3550 WPA_OUI_TYPE_SIZE)))
3551 skip_ie = true;
3552 else
3553 skip_ie = false;
3554
3555 if (!skip_ie) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003556 ielen = ptr[1] + 2;
3557 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303558 qdf_mem_copy(&genie[*total_ielen], ptr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003559 ielen);
3560 *total_ielen += ielen;
3561 } else {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003562 hdd_err("IE Length is too big IEs eid: %d elem_len: %d total_ie_lent: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003563 elem_id, elem_len, *total_ielen);
3564 }
3565 }
3566 }
3567
3568 left -= elem_len;
3569 ptr += (elem_len + 2);
3570 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003571}
3572
3573/**
3574 * wlan_hdd_add_extra_ie() - add extra ies in beacon
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003575 * @adapter: Pointer to hostapd adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003576 * @genie: Pointer to extra ie
3577 * @total_ielen: Pointer to store total ie length
3578 * @temp_ie_id: ID of extra ie
3579 *
3580 * Return: none
3581 */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003582static void wlan_hdd_add_extra_ie(struct hdd_adapter *adapter,
Liangwei Dongec9be932016-10-19 05:59:13 -04003583 uint8_t *genie, uint16_t *total_ielen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003584 uint8_t temp_ie_id)
3585{
Jeff Johnsonb9424862017-10-30 08:49:35 -07003586 struct hdd_beacon_data *pBeacon = adapter->session.ap.beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003587 int left = pBeacon->tail_len;
3588 uint8_t *ptr = pBeacon->tail;
3589 uint8_t elem_id, elem_len;
3590 uint16_t ielen = 0;
3591
3592 if (NULL == ptr || 0 == left)
3593 return;
3594
3595 while (left >= 2) {
3596 elem_id = ptr[0];
3597 elem_len = ptr[1];
3598 left -= 2;
3599 if (elem_len > left) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003600 hdd_err("**Invalid IEs eid: %d elem_len: %d left: %d**",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003601 elem_id, elem_len, left);
3602 return;
3603 }
3604
3605 if (temp_ie_id == elem_id) {
3606 ielen = ptr[1] + 2;
3607 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303608 qdf_mem_copy(&genie[*total_ielen], ptr, ielen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003609 *total_ielen += ielen;
3610 } else {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003611 hdd_err("IE Length is too big IEs eid: %d elem_len: %d total_ie_len: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003612 elem_id, elem_len, *total_ielen);
3613 }
3614 }
3615
3616 left -= elem_len;
3617 ptr += (elem_len + 2);
3618 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003619}
3620
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003621/**
3622 * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003623 * @adapter: Pointer to hostapd adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003624 * @ppBeacon: Pointer to pointer to beacon data
3625 * @params: Pointer to beacon parameters
3626 * @dtim_period: DTIM period
3627 *
3628 * Return: 0 for success non-zero for failure
3629 */
Jeff Johnsone4090f72016-10-05 16:00:23 -07003630static int
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07003631wlan_hdd_cfg80211_alloc_new_beacon(struct hdd_adapter *adapter,
Jeff Johnson44e52172017-09-30 16:39:16 -07003632 struct hdd_beacon_data **ppBeacon,
Jeff Johnsone4090f72016-10-05 16:00:23 -07003633 struct cfg80211_beacon_data *params,
3634 int dtim_period)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003635{
3636 int size;
Jeff Johnson44e52172017-09-30 16:39:16 -07003637 struct hdd_beacon_data *beacon = NULL;
3638 struct hdd_beacon_data *old = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003639 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
3640 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
3641
Dustin Brown491d54b2018-03-14 12:39:11 -07003642 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003643 if (params->head && !params->head_len) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07003644 hdd_err("head_len is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003645 return -EINVAL;
3646 }
3647
Jeff Johnsonb9424862017-10-30 08:49:35 -07003648 old = adapter->session.ap.beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003649
3650 if (!params->head && !old) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08003651 hdd_err("session: %d old and new heads points to NULL",
Jeff Johnson1b780e42017-10-31 14:11:45 -07003652 adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003653 return -EINVAL;
3654 }
3655
3656 if (params->head) {
3657 head_len = params->head_len;
3658 head = params->head;
3659 } else {
3660 head_len = old->head_len;
3661 head = old->head;
3662 }
3663
3664 if (params->tail || !old) {
3665 tail_len = params->tail_len;
3666 tail = params->tail;
3667 } else {
3668 tail_len = old->tail_len;
3669 tail = old->tail;
3670 }
3671
3672 if (params->proberesp_ies || !old) {
3673 proberesp_ies_len = params->proberesp_ies_len;
3674 proberesp_ies = params->proberesp_ies;
3675 } else {
3676 proberesp_ies_len = old->proberesp_ies_len;
3677 proberesp_ies = old->proberesp_ies;
3678 }
3679
3680 if (params->assocresp_ies || !old) {
3681 assocresp_ies_len = params->assocresp_ies_len;
3682 assocresp_ies = params->assocresp_ies;
3683 } else {
3684 assocresp_ies_len = old->assocresp_ies_len;
3685 assocresp_ies = old->assocresp_ies;
3686 }
3687
Jeff Johnson44e52172017-09-30 16:39:16 -07003688 size = sizeof(struct hdd_beacon_data) + head_len + tail_len +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003689 proberesp_ies_len + assocresp_ies_len;
3690
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05303691 beacon = qdf_mem_malloc(size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003692
3693 if (beacon == NULL) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07003694 hdd_err("Mem allocation for beacon failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003695 return -ENOMEM;
3696 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003697 if (dtim_period)
3698 beacon->dtim_period = dtim_period;
3699 else if (old)
3700 beacon->dtim_period = old->dtim_period;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003701 /* -----------------------------------------------
3702 * | head | tail | proberesp_ies | assocresp_ies |
3703 * -----------------------------------------------
3704 */
Jeff Johnson44e52172017-09-30 16:39:16 -07003705 beacon->head = ((u8 *) beacon) + sizeof(struct hdd_beacon_data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003706 beacon->tail = beacon->head + head_len;
3707 beacon->proberesp_ies = beacon->tail + tail_len;
3708 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
3709
3710 beacon->head_len = head_len;
3711 beacon->tail_len = tail_len;
3712 beacon->proberesp_ies_len = proberesp_ies_len;
3713 beacon->assocresp_ies_len = assocresp_ies_len;
3714
3715 if (head && head_len)
3716 memcpy(beacon->head, head, head_len);
3717 if (tail && tail_len)
3718 memcpy(beacon->tail, tail, tail_len);
3719 if (proberesp_ies && proberesp_ies_len)
3720 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
3721 if (assocresp_ies && assocresp_ies_len)
3722 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
3723
3724 *ppBeacon = beacon;
3725
Jeff Johnsonb9424862017-10-30 08:49:35 -07003726 adapter->session.ap.beacon = NULL;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05303727 qdf_mem_free(old);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003728
3729 return 0;
3730
3731}
3732
Liangwei Dongec9be932016-10-19 05:59:13 -04003733#ifdef QCA_HT_2040_COEX
3734static void wlan_hdd_add_sap_obss_scan_ie(
Jeff Johnson866aca82017-09-10 15:27:20 -07003735 struct hdd_adapter *hostapd_adapter, uint8_t *ie_buf, uint16_t *ie_len)
Liangwei Dongec9be932016-10-19 05:59:13 -04003736{
3737 if (QDF_SAP_MODE == hostapd_adapter->device_mode) {
3738 if (wlan_hdd_get_sap_obss(hostapd_adapter))
3739 wlan_hdd_add_extra_ie(hostapd_adapter, ie_buf, ie_len,
3740 WLAN_EID_OVERLAP_BSS_SCAN_PARAM);
3741 }
3742}
3743#else
3744static void wlan_hdd_add_sap_obss_scan_ie(
Jeff Johnson866aca82017-09-10 15:27:20 -07003745 struct hdd_adapter *hostapd_adapter, uint8_t *ie_buf, uint16_t *ie_len)
Liangwei Dongec9be932016-10-19 05:59:13 -04003746{
3747}
3748#endif
3749
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003750/**
Naveen Rawatd8feac12017-09-08 15:08:39 -07003751 * wlan_hdd_cfg80211_update_apies() - update ap mode 11ax ies
3752 * @adapter: Pointer to hostapd adapter
3753 * @genie: generic IE buffer
3754 * @total_ielen: out param to update total ielen
3755 *
3756 * Return: 0 for success non-zero for failure
3757 */
3758
3759#ifdef WLAN_FEATURE_11AX
3760static int hdd_update_11ax_apies(struct hdd_adapter *adapter,
3761 uint8_t *genie, uint16_t *total_ielen)
3762{
3763 if (wlan_hdd_add_extn_ie(adapter, genie, total_ielen,
3764 HE_CAP_OUI_TYPE, HE_CAP_OUI_SIZE)) {
3765 hdd_err("Adding HE Cap ie failed");
3766 return -EINVAL;
3767 }
3768
3769 if (wlan_hdd_add_extn_ie(adapter, genie, total_ielen,
3770 HE_OP_OUI_TYPE, HE_OP_OUI_SIZE)) {
3771 hdd_err("Adding HE Op ie failed");
3772 return -EINVAL;
3773 }
3774
3775 return 0;
3776}
3777#else
3778static int hdd_update_11ax_apies(struct hdd_adapter *adapter,
3779 uint8_t *genie, uint16_t *total_ielen)
3780{
3781 return 0;
3782}
3783#endif
3784
3785/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003786 * wlan_hdd_cfg80211_update_apies() - update ap mode ies
3787 * @adapter: Pointer to hostapd adapter
3788 *
3789 * Return: 0 for success non-zero for failure
3790 */
Jeff Johnson866aca82017-09-10 15:27:20 -07003791int wlan_hdd_cfg80211_update_apies(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003792{
3793 uint8_t *genie;
Liangwei Dongec9be932016-10-19 05:59:13 -04003794 uint16_t total_ielen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003795 int ret = 0;
Jeff Johnsone4c11db2018-05-05 23:22:32 -07003796 tsap_config_t *pConfig;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003797 tSirUpdateIE updateIE;
Jeff Johnson44e52172017-09-30 16:39:16 -07003798 struct hdd_beacon_data *beacon = NULL;
Liangwei Dongec9be932016-10-19 05:59:13 -04003799 uint16_t proberesp_ies_len;
3800 uint8_t *proberesp_ies = NULL;
Jeff Johnson89a0c742018-06-12 18:17:46 -07003801 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003802
Jeff Johnsonb9424862017-10-30 08:49:35 -07003803 pConfig = &adapter->session.ap.sap_config;
3804 beacon = adapter->session.ap.beacon;
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08003805 if (!beacon) {
3806 hdd_err("Beacon is NULL !");
3807 return -EINVAL;
3808 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003809
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303810 genie = qdf_mem_malloc(MAX_GENIE_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003811
3812 if (genie == NULL)
3813 return -ENOMEM;
3814
Jeff Johnson89a0c742018-06-12 18:17:46 -07003815 mac_handle = adapter->hdd_ctx->mac_handle;
3816
Edhar, Mahesh Kumar14846232016-06-30 15:03:23 +05303817 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
3818 WLAN_EID_VHT_TX_POWER_ENVELOPE);
3819
Vidyullatha Kanchanapally518c5d72016-09-30 11:04:16 +05303820 /* Extract and add the extended capabilities and interworking IE */
3821 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
3822 WLAN_EID_EXT_CAPABILITY);
3823
3824 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
3825 WLAN_EID_INTERWORKING);
3826
Visweswara Tanukue6b0da52018-04-11 11:41:02 +05303827 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))
3828 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
3829 WLAN_EID_RSN);
3830
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003831#ifdef FEATURE_WLAN_WAPI
Krunal Soni056ea0f2016-03-10 13:07:10 -08003832 if (QDF_SAP_MODE == adapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003833 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
3834 WLAN_EID_WAPI);
3835 }
3836#endif
3837
Abhishek Singh86ea5c72017-09-01 16:08:09 +05303838 wlan_hdd_add_hostapd_conf_vsie(adapter, genie,
3839 &total_ielen);
yeshwanth sriram guntukaf6059f22017-08-04 16:22:55 +05303840
Naveen Rawatd8feac12017-09-08 15:08:39 -07003841 ret = hdd_update_11ax_apies(adapter, genie, &total_ielen);
3842 if (ret)
3843 goto done;
3844
Liangwei Dongec9be932016-10-19 05:59:13 -04003845 wlan_hdd_add_sap_obss_scan_ie(adapter, genie, &total_ielen);
3846
Jeff Johnson1e851a12017-10-28 14:36:12 -07003847 qdf_copy_macaddr(&updateIE.bssid, &adapter->mac_addr);
Jeff Johnson1b780e42017-10-31 14:11:45 -07003848 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003849
3850 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
3851 updateIE.ieBufferlength = total_ielen;
3852 updateIE.pAdditionIEBuffer = genie;
3853 updateIE.append = false;
3854 updateIE.notify = true;
Jeff Johnson89a0c742018-06-12 18:17:46 -07003855 if (sme_update_add_ie(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003856 &updateIE,
3857 eUPDATE_IE_PROBE_BCN) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303858 QDF_STATUS_E_FAILURE) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07003859 hdd_err("Could not pass on Add Ie probe beacon data");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003860 ret = -EINVAL;
3861 goto done;
3862 }
3863 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_BCN);
3864 } else {
3865 wlansap_update_sap_config_add_ie(pConfig,
3866 genie,
3867 total_ielen,
3868 eUPDATE_IE_PROBE_BCN);
3869 }
3870
3871 /* Added for Probe Response IE */
Liangwei Dongec9be932016-10-19 05:59:13 -04003872 proberesp_ies = qdf_mem_malloc(beacon->proberesp_ies_len +
3873 MAX_GENIE_LEN);
3874 if (proberesp_ies == NULL) {
Zhu Jianminded9d2d2017-06-22 09:39:36 +08003875 hdd_err("mem alloc failed for probe resp ies, size: %d",
3876 beacon->proberesp_ies_len + MAX_GENIE_LEN);
Liangwei Dongec9be932016-10-19 05:59:13 -04003877 ret = -EINVAL;
3878 goto done;
3879 }
3880 qdf_mem_copy(proberesp_ies, beacon->proberesp_ies,
3881 beacon->proberesp_ies_len);
3882 proberesp_ies_len = beacon->proberesp_ies_len;
3883
3884 wlan_hdd_add_sap_obss_scan_ie(adapter, proberesp_ies,
3885 &proberesp_ies_len);
3886
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003887 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Liangwei Dongec9be932016-10-19 05:59:13 -04003888 updateIE.ieBufferlength = proberesp_ies_len;
3889 updateIE.pAdditionIEBuffer = proberesp_ies;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003890 updateIE.append = false;
3891 updateIE.notify = false;
Jeff Johnson89a0c742018-06-12 18:17:46 -07003892 if (sme_update_add_ie(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003893 &updateIE,
3894 eUPDATE_IE_PROBE_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303895 QDF_STATUS_E_FAILURE) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07003896 hdd_err("Could not pass on PROBE_RESP add Ie data");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003897 ret = -EINVAL;
3898 goto done;
3899 }
3900 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_RESP);
3901 } else {
3902 wlansap_update_sap_config_add_ie(pConfig,
Liangwei Dongec9be932016-10-19 05:59:13 -04003903 proberesp_ies,
3904 proberesp_ies_len,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003905 eUPDATE_IE_PROBE_RESP);
3906 }
3907
3908 /* Assoc resp Add ie Data */
3909 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
3910 updateIE.ieBufferlength = beacon->assocresp_ies_len;
3911 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->assocresp_ies;
3912 updateIE.append = false;
3913 updateIE.notify = false;
Jeff Johnson89a0c742018-06-12 18:17:46 -07003914 if (sme_update_add_ie(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003915 &updateIE,
3916 eUPDATE_IE_ASSOC_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303917 QDF_STATUS_E_FAILURE) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07003918 hdd_err("Could not pass on Add Ie Assoc Response data");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003919 ret = -EINVAL;
3920 goto done;
3921 }
3922 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ASSOC_RESP);
3923 } else {
3924 wlansap_update_sap_config_add_ie(pConfig,
3925 beacon->assocresp_ies,
3926 beacon->assocresp_ies_len,
3927 eUPDATE_IE_ASSOC_RESP);
3928 }
3929
3930done:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303931 qdf_mem_free(genie);
Liangwei Dongec9be932016-10-19 05:59:13 -04003932 qdf_mem_free(proberesp_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003933 return ret;
3934}
3935
3936/**
3937 * wlan_hdd_set_sap_hwmode() - set sap hw mode
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003938 * @adapter: Pointer to hostapd adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003939 *
3940 * Return: none
3941 */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07003942static void wlan_hdd_set_sap_hwmode(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003943{
Jeff Johnsone4c11db2018-05-05 23:22:32 -07003944 tsap_config_t *pConfig = &adapter->session.ap.sap_config;
Jeff Johnsonb9424862017-10-30 08:49:35 -07003945 struct hdd_beacon_data *pBeacon = adapter->session.ap.beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003946 struct ieee80211_mgmt *pMgmt_frame =
3947 (struct ieee80211_mgmt *)pBeacon->head;
3948 u8 checkRatesfor11g = true;
3949 u8 require_ht = false, require_vht = false;
Naveen Rawat08db88f2017-09-08 15:07:48 -07003950 const u8 *pIe = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003951
3952 pConfig->SapHw_mode = eCSR_DOT11_MODE_11b;
3953
Jiachao Wu45845162018-03-22 13:43:09 +08003954 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_SUPP_RATES,
Naveen Rawat08db88f2017-09-08 15:07:48 -07003955 &pMgmt_frame->u.beacon.variable[0],
3956 pBeacon->head_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003957 if (pIe != NULL) {
3958 pIe += 1;
3959 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
3960 &checkRatesfor11g, &pConfig->SapHw_mode);
3961 }
3962
Naveen Rawat08db88f2017-09-08 15:07:48 -07003963 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_EXT_SUPP_RATES,
3964 pBeacon->tail, pBeacon->tail_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003965 if (pIe != NULL) {
3966 pIe += 1;
3967 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
3968 &checkRatesfor11g, &pConfig->SapHw_mode);
3969 }
3970
3971 if (pConfig->channel > 14)
3972 pConfig->SapHw_mode = eCSR_DOT11_MODE_11a;
3973
Naveen Rawat08db88f2017-09-08 15:07:48 -07003974 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_HT_CAPABILITY,
3975 pBeacon->tail, pBeacon->tail_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003976 if (pIe) {
3977 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
3978 if (require_ht)
3979 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n_ONLY;
3980 }
3981
Naveen Rawat08db88f2017-09-08 15:07:48 -07003982 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_VHT_CAPABILITY,
3983 pBeacon->tail, pBeacon->tail_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003984 if (pIe) {
3985 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac;
3986 if (require_vht)
3987 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac_ONLY;
3988 }
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08003989
3990 wlan_hdd_check_11ax_support(pBeacon, pConfig);
3991
3992 hdd_info("SAP hw_mode: %d", pConfig->SapHw_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003993}
3994
3995/**
3996 * wlan_hdd_config_acs() - config ACS needed parameters
3997 * @hdd_ctx: HDD context
3998 * @adapter: Adapter pointer
3999 *
Jeff Johnson60ed45a2018-05-06 15:28:49 -07004000 * This function get ACS related INI parameters and populated
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004001 * sap config and smeConfig for ACS needed configurations.
4002 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304003 * Return: The QDF_STATUS code associated with performing the operation.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004004 */
Jeff Johnson89a0c742018-06-12 18:17:46 -07004005QDF_STATUS wlan_hdd_config_acs(struct hdd_context *hdd_ctx,
4006 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004007{
Jeff Johnsone4c11db2018-05-05 23:22:32 -07004008 tsap_config_t *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004009 struct hdd_config *ini_config;
Jeff Johnson89a0c742018-06-12 18:17:46 -07004010 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004011
Jeff Johnson89a0c742018-06-12 18:17:46 -07004012 mac_handle = hdd_ctx->mac_handle;
Jeff Johnsonb9424862017-10-30 08:49:35 -07004013 sap_config = &adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004014 ini_config = hdd_ctx->config;
4015
4016 sap_config->enOverLapCh = !!hdd_ctx->config->gEnableOverLapCh;
4017
Dustin Brown5118e8e2016-09-13 15:54:23 -07004018#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Jeff Johnson89a0c742018-06-12 18:17:46 -07004019 hdd_debug("HDD_ACS_SKIP_STATUS = %d", hdd_ctx->skip_acs_scan_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004020 if (hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) {
Jeff Johnson866aca82017-09-10 15:27:20 -07004021 struct hdd_adapter *con_sap_adapter;
Jeff Johnsone4c11db2018-05-05 23:22:32 -07004022 tsap_config_t *con_sap_config = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004023
4024 con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
4025
4026 if (con_sap_adapter)
4027 con_sap_config =
Jeff Johnsonb9424862017-10-30 08:49:35 -07004028 &con_sap_adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004029
4030 sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN;
4031
4032 if (con_sap_config &&
4033 con_sap_config->acs_cfg.acs_mode == true &&
4034 hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN &&
4035 con_sap_config->acs_cfg.hw_mode ==
4036 sap_config->acs_cfg.hw_mode) {
4037 uint8_t con_sap_st_ch, con_sap_end_ch;
4038 uint8_t cur_sap_st_ch, cur_sap_end_ch;
4039 uint8_t bandStartChannel, bandEndChannel;
4040
4041 con_sap_st_ch =
4042 con_sap_config->acs_cfg.start_ch;
4043 con_sap_end_ch =
4044 con_sap_config->acs_cfg.end_ch;
4045 cur_sap_st_ch = sap_config->acs_cfg.start_ch;
4046 cur_sap_end_ch = sap_config->acs_cfg.end_ch;
4047
Jeff Johnson89a0c742018-06-12 18:17:46 -07004048 wlansap_extend_to_acs_range(mac_handle, &cur_sap_st_ch,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07004049 &cur_sap_end_ch, &bandStartChannel,
4050 &bandEndChannel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004051
Jeff Johnson89a0c742018-06-12 18:17:46 -07004052 wlansap_extend_to_acs_range(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004053 &con_sap_st_ch, &con_sap_end_ch,
4054 &bandStartChannel, &bandEndChannel);
4055
4056 if (con_sap_st_ch <= cur_sap_st_ch &&
4057 con_sap_end_ch >= cur_sap_end_ch) {
4058 sap_config->acs_cfg.skip_scan_status =
4059 eSAP_SKIP_ACS_SCAN;
4060
4061 } else if (con_sap_st_ch >= cur_sap_st_ch &&
4062 con_sap_end_ch >= cur_sap_end_ch) {
4063 sap_config->acs_cfg.skip_scan_status =
4064 eSAP_DO_PAR_ACS_SCAN;
4065
4066 sap_config->acs_cfg.skip_scan_range1_stch =
4067 cur_sap_st_ch;
4068 sap_config->acs_cfg.skip_scan_range1_endch =
4069 con_sap_st_ch - 1;
4070 sap_config->acs_cfg.skip_scan_range2_stch =
4071 0;
4072 sap_config->acs_cfg.skip_scan_range2_endch =
4073 0;
4074
4075 } else if (con_sap_st_ch <= cur_sap_st_ch &&
4076 con_sap_end_ch <= cur_sap_end_ch) {
4077 sap_config->acs_cfg.skip_scan_status =
4078 eSAP_DO_PAR_ACS_SCAN;
4079
4080 sap_config->acs_cfg.skip_scan_range1_stch =
4081 con_sap_end_ch + 1;
4082 sap_config->acs_cfg.skip_scan_range1_endch =
4083 cur_sap_end_ch;
4084 sap_config->acs_cfg.skip_scan_range2_stch =
4085 0;
4086 sap_config->acs_cfg.skip_scan_range2_endch =
4087 0;
4088
4089 } else if (con_sap_st_ch >= cur_sap_st_ch &&
4090 con_sap_end_ch <= cur_sap_end_ch) {
4091 sap_config->acs_cfg.skip_scan_status =
4092 eSAP_DO_PAR_ACS_SCAN;
4093
4094 sap_config->acs_cfg.skip_scan_range1_stch =
4095 cur_sap_st_ch;
4096 sap_config->acs_cfg.skip_scan_range1_endch =
4097 con_sap_st_ch - 1;
4098 sap_config->acs_cfg.skip_scan_range2_stch =
4099 con_sap_end_ch;
4100 sap_config->acs_cfg.skip_scan_range2_endch =
4101 cur_sap_end_ch + 1;
4102
4103 } else
4104 sap_config->acs_cfg.skip_scan_status =
4105 eSAP_DO_NEW_ACS_SCAN;
4106
4107
Dustin Brownbacc48f2018-03-14 14:48:44 -07004108 hdd_debug("SecAP ACS Skip=%d, ACS CH RANGE=%d-%d, %d-%d",
4109 sap_config->acs_cfg.skip_scan_status,
4110 sap_config->acs_cfg.skip_scan_range1_stch,
4111 sap_config->acs_cfg.skip_scan_range1_endch,
4112 sap_config->acs_cfg.skip_scan_range2_stch,
4113 sap_config->acs_cfg.skip_scan_range2_endch);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004114 }
4115 }
4116#endif
4117
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304118 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004119}
4120
4121/**
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05304122 * wlan_hdd_sap_p2p_11ac_overrides: API to overwrite 11ac config in case of
4123 * SAP or p2p go
4124 * @ap_adapter: pointer to adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004125 *
4126 * This function overrides SAP / P2P Go configuration based on driver INI
4127 * parameters for 11AC override and ACS. This overrides are done to support
4128 * android legacy configuration method.
4129 *
4130 * NOTE: Non android platform supports concurrency and these overrides shall
4131 * not be used. Also future driver based overrides shall be consolidated in this
4132 * function only. Avoid random overrides in other location based on ini.
4133 *
4134 * Return: 0 for Success or Negative error codes.
4135 */
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05304136static int wlan_hdd_sap_p2p_11ac_overrides(struct hdd_adapter *ap_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004137{
Jeff Johnsone4c11db2018-05-05 23:22:32 -07004138 tsap_config_t *sap_cfg = &ap_adapter->session.ap.sap_config;
Jeff Johnsonc54bbf92017-08-28 11:59:35 -07004139 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004140
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004141 /* Fixed channel 11AC override:
4142 * 11AC override in qcacld is introduced for following reasons:
4143 * 1. P2P GO also follows start_bss and since p2p GO could not be
4144 * configured to setup VHT channel width in wpa_supplicant
4145 * 2. Android UI does not provide advanced configuration options for SAP
4146 *
4147 * Default override enabled (for android). MDM shall disable this in ini
4148 */
Naveen Rawat216605a2017-01-04 16:36:28 -08004149 /*
4150 * sub_20 MHz channel width is incompatible with 11AC rates, hence do
4151 * not allow 11AC rates or more than 20 MHz channel width when
4152 * enable_sub_20_channel_width is non zero
4153 */
4154 if (!hdd_ctx->config->enable_sub_20_channel_width &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004155 (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
4156 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08004157 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY ||
4158 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ax ||
4159 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ax_ONLY) &&
Himanshu Agarwal4ecf6ca2018-05-09 16:48:56 +05304160 ((ap_adapter->device_mode == QDF_SAP_MODE &&
4161 !hdd_ctx->config->sap_force_11n_for_11ac &&
4162 hdd_ctx->config->sap_11ac_override) ||
4163 (ap_adapter->device_mode == QDF_P2P_GO_MODE &&
4164 !hdd_ctx->config->go_force_11n_for_11ac &&
4165 hdd_ctx->config->go_11ac_override))) {
Bala Venkateshb9cf3362017-11-09 15:48:46 +05304166 hdd_debug("** Driver force 11AC override for SAP/Go **");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004167
4168 /* 11n only shall not be overridden since it may be on purpose*/
4169 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n)
4170 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
4171
Abhishek Singh26a7b9f2017-04-06 16:23:05 +05304172 if (sap_cfg->channel >= 36) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004173 sap_cfg->ch_width_orig =
4174 hdd_ctx->config->vhtChannelWidth;
Abhishek Singh26a7b9f2017-04-06 16:23:05 +05304175 } else {
4176 /*
4177 * Allow 40 Mhz in 2.4 Ghz only if indicated by
4178 * supplicant after OBSS scan and if 2.4 Ghz channel
4179 * bonding is set in INI
4180 */
4181 if (sap_cfg->ch_width_orig >= eHT_CHANNEL_WIDTH_40MHZ &&
4182 hdd_ctx->config->nChannelBondingMode24GHz)
4183 sap_cfg->ch_width_orig =
4184 eHT_CHANNEL_WIDTH_40MHZ;
4185 else
4186 sap_cfg->ch_width_orig =
4187 eHT_CHANNEL_WIDTH_20MHZ;
4188 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004189 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004190
4191 return 0;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05304192}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004193
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05304194/**
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05304195 * wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
4196 * @adapter: pointer to adapter struct
4197 *
4198 * This function overrides SAP / P2P Go configuration based on driver INI
4199 * parameters for 11AC override and ACS. These overrides are done to support
4200 * android legacy configuration method.
4201 *
4202 * NOTE: Non android platform supports concurrency and these overrides shall
4203 * not be used. Also future driver based overrides shall be consolidated in this
4204 * function only. Avoid random overrides in other location based on ini.
4205 *
4206 * Return: 0 for Success or Negative error codes.
4207 */
4208static int wlan_hdd_setup_driver_overrides(struct hdd_adapter *ap_adapter)
4209{
4210 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
4211
Himanshu Agarwalad4c0392018-05-08 16:53:36 +05304212 if (!hdd_ctx->config->vendor_acs_support)
4213 return wlan_hdd_sap_p2p_11ac_overrides(ap_adapter);
4214 else
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05304215 return 0;
4216}
4217
4218/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004219 * wlan_hdd_cfg80211_start_bss() - start bss
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004220 * @adapter: Pointer to hostapd adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004221 * @params: Pointer to start bss beacon parameters
4222 * @ssid: Pointer ssid
4223 * @ssid_len: Length of ssid
4224 * @hidden_ssid: Hidden SSID parameter
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05304225 * @check_for_concurrency: Flag to indicate if check for concurrency is needed
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004226 *
4227 * Return: 0 for success non-zero for failure
4228 */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004229int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004230 struct cfg80211_beacon_data *params,
4231 const u8 *ssid, size_t ssid_len,
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05304232 enum nl80211_hidden_ssid hidden_ssid,
Mahesh Kumar Kalikot Veetilc637fc92017-09-27 16:06:21 -07004233 bool check_for_concurrency)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004234{
Jeff Johnsone4c11db2018-05-05 23:22:32 -07004235 tsap_config_t *pConfig;
Jeff Johnson44e52172017-09-30 16:39:16 -07004236 struct hdd_beacon_data *pBeacon = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004237 struct ieee80211_mgmt *pMgmt_frame;
Naveen Rawat08db88f2017-09-08 15:07:48 -07004238 const uint8_t *pIe = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004239 uint16_t capab_info;
4240 eCsrAuthType RSNAuthType;
4241 eCsrEncryptionType RSNEncryptType;
4242 eCsrEncryptionType mcRSNEncryptType;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304243 int status = QDF_STATUS_SUCCESS, ret;
Anurag Chouhance0dc992016-02-16 18:18:03 +05304244 int qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004245 tpWLAN_SAPEventCB pSapEventCallback;
Jeff Johnson5c19ade2017-10-04 09:52:12 -07004246 struct hdd_hostapd_state *hostapd_state;
Jeff Johnson89a0c742018-06-12 18:17:46 -07004247 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004248 struct qc_mac_acl_entry *acl_entry = NULL;
4249 int32_t i;
4250 struct hdd_config *iniConfig;
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004251 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Sridhar Selvaraj48c47092017-07-31 18:18:14 +05304252 tSmeConfigParams *sme_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004253 bool MFPCapable = false;
4254 bool MFPRequired = false;
4255 uint16_t prev_rsn_length = 0;
Agrawal Ashish65634612016-08-18 13:24:32 +05304256 enum dfs_mode mode;
Himanshu Agarwal6c3607a2018-01-12 12:04:19 +05304257 struct hdd_adapter *sta_adapter;
Bala Venkatesh5479cf82018-06-09 20:02:38 +05304258 uint8_t ignore_cac = 0;
Agrawal Ashish65634612016-08-18 13:24:32 +05304259
Dustin Brown491d54b2018-03-14 12:39:11 -07004260 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004261
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004262 hdd_notify_teardown_tdls_links(adapter->hdd_vdev);
Kabilan Kannan1c1c4022017-04-06 22:49:26 -07004263
Jeff Johnson23c3b842017-09-03 09:05:29 -07004264 if (policy_mgr_is_hw_mode_change_in_progress(hdd_ctx->hdd_psoc)) {
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08004265 status = policy_mgr_wait_for_connection_update(
Jeff Johnson23c3b842017-09-03 09:05:29 -07004266 hdd_ctx->hdd_psoc);
Nitesh Shaha3dfea32017-02-09 19:18:57 +05304267 if (!QDF_IS_STATUS_SUCCESS(status)) {
4268 hdd_err("qdf wait for event failed!!");
4269 return -EINVAL;
4270 }
4271 }
4272
Himanshu Agarwal6c3607a2018-01-12 12:04:19 +05304273 /*
4274 * For STA+SAP concurrency support from GUI, first STA connection gets
4275 * triggered and while it is in progress, SAP start also comes up.
4276 * Once STA association is successful, STA connect event is sent to
4277 * kernel which gets queued in kernel workqueue and supplicant won't
4278 * process M1 received from AP and send M2 until this NL80211_CONNECT
4279 * event is received. Workqueue is not scheduled as RTNL lock is already
4280 * taken by hostapd thread which has issued start_bss command to driver.
4281 * Driver cannot complete start_bss as the pending command at the head
4282 * of the SME command pending list is hw_mode_update for STA session
4283 * which cannot be processed as SME is in WAITforKey state for STA
4284 * interface. The start_bss command for SAP interface is queued behind
4285 * the hw_mode_update command and so it cannot be processed until
4286 * hw_mode_update command is processed. This is causing a deadlock so
4287 * disconnect the STA interface first if connection or key exchange is
4288 * in progress and then start SAP interface.
4289 */
4290 sta_adapter = hdd_get_sta_connection_in_progress(hdd_ctx);
4291 if (sta_adapter) {
4292 hdd_debug("Disconnecting STA with session id: %d",
4293 sta_adapter->session_id);
4294 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
4295 }
4296
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +05304297 /*
4298 * Reject start bss if reassoc in progress on any adapter.
4299 * sme_is_any_session_in_middle_of_roaming is for LFR2 and
4300 * hdd_is_roaming_in_progress is for LFR3
4301 */
Jeff Johnson89a0c742018-06-12 18:17:46 -07004302 mac_handle = hdd_ctx->mac_handle;
4303 if (sme_is_any_session_in_middle_of_roaming(mac_handle) ||
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +05304304 hdd_is_roaming_in_progress(hdd_ctx)) {
4305 hdd_info("Reassociation in progress");
4306 return -EINVAL;
4307 }
4308
4309 /* Disable Roaming on all adapters before starting bss */
4310 wlan_hdd_disable_roaming(adapter);
4311
Sridhar Selvaraj48c47092017-07-31 18:18:14 +05304312 sme_config = qdf_mem_malloc(sizeof(*sme_config));
4313 if (!sme_config) {
4314 hdd_err("failed to allocate memory");
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +05304315 ret = -ENOMEM;
4316 goto free;
Sridhar Selvaraj48c47092017-07-31 18:18:14 +05304317 }
4318
Jeff Johnson23c3b842017-09-03 09:05:29 -07004319 iniConfig = hdd_ctx->config;
Jeff Johnson5c19ade2017-10-04 09:52:12 -07004320 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004321
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004322 clear_bit(ACS_PENDING, &adapter->event_flags);
Jeff Johnson23c3b842017-09-03 09:05:29 -07004323 clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004324
Mukul Sharmaecf8e092017-12-19 22:36:31 +05304325 /* Mark the indoor channel (passive) to disable */
4326 if (iniConfig->force_ssc_disable_indoor_channel) {
4327 hdd_update_indoor_channel(hdd_ctx, true);
4328 if (QDF_IS_STATUS_ERROR(
Jeff Johnson89a0c742018-06-12 18:17:46 -07004329 sme_update_channel_list(mac_handle))) {
Mukul Sharmaecf8e092017-12-19 22:36:31 +05304330 hdd_update_indoor_channel(hdd_ctx, false);
4331 hdd_err("Can't start BSS: update channel list failed");
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +05304332 ret = -EINVAL;
4333 goto free;
Mukul Sharmaecf8e092017-12-19 22:36:31 +05304334 }
4335 }
4336
Jeff Johnsonb9424862017-10-30 08:49:35 -07004337 pConfig = &adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004338
Jeff Johnsonb9424862017-10-30 08:49:35 -07004339 pBeacon = adapter->session.ap.beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004340
4341 pMgmt_frame = (struct ieee80211_mgmt *)pBeacon->head;
4342
4343 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
Jeff Johnson23c3b842017-09-03 09:05:29 -07004344 pConfig->dfs_cac_offload = hdd_ctx->dfs_cac_offload;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004345
Himanshu Agarwalc8552272017-10-12 18:16:46 +05304346 pConfig->auto_channel_select_weight =
4347 iniConfig->auto_channel_select_weight;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004348 pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch;
gaoleze2920bd2017-03-21 17:38:42 +08004349 pConfig->sap_chanswitch_beacon_cnt =
4350 iniConfig->sap_chanswitch_beacon_cnt;
gaolez76d2a162017-03-21 19:23:58 +08004351 pConfig->sap_chanswitch_mode = iniConfig->sap_chanswitch_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004352
4353 /* channel is already set in the set_channel Call back */
4354 /* pConfig->channel = pCommitConfig->channel; */
4355
4356 /* Protection parameter to enable or disable */
4357 pConfig->protEnabled = iniConfig->apProtEnabled;
4358
hqu16d6e082017-09-04 10:52:31 +08004359 pConfig->chan_switch_hostapd_rate_enabled =
4360 iniConfig->chan_switch_hostapd_rate_enabled;
4361
Ganesh Kondabattini4a7f5b92017-11-21 14:58:39 +05304362 if (iniConfig->WlanMccToSccSwitchMode !=
4363 QDF_MCC_TO_SCC_SWITCH_DISABLE) {
4364 pConfig->chan_switch_hostapd_rate_enabled = false;
4365 }
4366
Arif Hussain1b21e812016-08-16 16:08:28 -07004367 pConfig->enOverLapCh = iniConfig->gEnableOverLapCh;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004368 pConfig->dtim_period = pBeacon->dtim_period;
lifeng1c16b6b2017-09-25 13:59:55 +08004369 pConfig->dfs_beacon_tx_enhanced = iniConfig->dfs_beacon_tx_enhanced;
lifeng7c607dd2017-02-21 21:16:49 +08004370 pConfig->reduced_beacon_interval =
4371 iniConfig->reduced_beacon_interval;
Srinivas Girigowda55756882017-03-06 16:45:27 -08004372 hdd_debug("acs_mode %d", pConfig->acs_cfg.acs_mode);
Kondabattini, Ganeshc846f3a2016-10-05 15:01:18 +05304373
4374 if (pConfig->acs_cfg.acs_mode == true) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08004375 hdd_debug("acs_channel %d, acs_dfs_mode %d",
Jeff Johnson23c3b842017-09-03 09:05:29 -07004376 hdd_ctx->acs_policy.acs_channel,
4377 hdd_ctx->acs_policy.acs_dfs_mode);
Kondabattini, Ganeshc846f3a2016-10-05 15:01:18 +05304378
Jeff Johnson23c3b842017-09-03 09:05:29 -07004379 if (hdd_ctx->acs_policy.acs_channel)
4380 pConfig->channel = hdd_ctx->acs_policy.acs_channel;
4381 mode = hdd_ctx->acs_policy.acs_dfs_mode;
Kondabattini, Ganeshc846f3a2016-10-05 15:01:18 +05304382 pConfig->acs_dfs_mode = wlan_hdd_get_dfs_mode(mode);
4383 }
4384
Srinivas Girigowda55756882017-03-06 16:45:27 -08004385 hdd_debug("pConfig->channel %d, pConfig->acs_dfs_mode %d",
Kondabattini, Ganeshc846f3a2016-10-05 15:01:18 +05304386 pConfig->channel, pConfig->acs_dfs_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004387
Srinivas Girigowda55756882017-03-06 16:45:27 -08004388 hdd_debug("****pConfig->dtim_period=%d***",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004389 pConfig->dtim_period);
4390
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004391 if (adapter->device_mode == QDF_SAP_MODE) {
Naveen Rawat08db88f2017-09-08 15:07:48 -07004392 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_COUNTRY,
4393 pBeacon->tail, pBeacon->tail_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004394 if (pIe) {
Nachiket Kukadee24c4922017-11-29 15:06:20 +05304395 if (pIe[1] < IEEE80211_COUNTRY_IE_MIN_LEN) {
4396 hdd_err("Invalid Country IE len: %d", pIe[1]);
4397 ret = -EINVAL;
4398 goto error;
4399 }
4400
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004401 pConfig->ieee80211d = 1;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304402 qdf_mem_copy(pConfig->countryCode, &pIe[2], 3);
Jeff Johnson23c3b842017-09-03 09:05:29 -07004403 status = ucfg_reg_set_country(hdd_ctx->hdd_pdev,
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004404 pConfig->countryCode);
4405 if (QDF_IS_STATUS_ERROR(status)) {
4406 hdd_err("Failed to set country");
4407 pConfig->ieee80211d = 0;
4408 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004409 } else {
Jeff Johnson23c3b842017-09-03 09:05:29 -07004410 pConfig->countryCode[0] = hdd_ctx->reg.alpha2[0];
4411 pConfig->countryCode[1] = hdd_ctx->reg.alpha2[1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004412 pConfig->ieee80211d = 0;
4413 }
4414
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004415 ret = wlan_hdd_sap_cfg_dfs_override(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004416 if (ret < 0) {
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304417 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004418 } else {
4419 if (ret == 0) {
Jeff Johnson23c3b842017-09-03 09:05:29 -07004420 if (wlan_reg_is_dfs_ch(hdd_ctx->hdd_pdev,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07004421 pConfig->channel))
Jeff Johnson23c3b842017-09-03 09:05:29 -07004422 hdd_ctx->dev_dfs_cac_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004423 DFS_CAC_NEVER_DONE;
4424 }
4425 }
4426
Rajeev Kumar Sirasanagandlaa0006022016-09-09 16:24:31 +05304427 /*
4428 * If auto channel is configured i.e. channel is 0,
4429 * so skip channel validation.
4430 */
4431 if (AUTO_CHANNEL_SELECT != pConfig->channel) {
4432 if (QDF_STATUS_SUCCESS !=
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004433 wlan_hdd_validate_operation_channel(adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004434 pConfig->channel)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08004435 hdd_err("Invalid Channel: %d", pConfig->channel);
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304436 ret = -EINVAL;
4437 goto error;
Rajeev Kumar Sirasanagandlaa0006022016-09-09 16:24:31 +05304438 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004439
Rajeev Kumar Sirasanagandlaa0006022016-09-09 16:24:31 +05304440 /* reject SAP if DFS channel scan is not allowed */
Jeff Johnson23c3b842017-09-03 09:05:29 -07004441 if (!(hdd_ctx->config->enableDFSChnlScan) &&
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07004442 (CHANNEL_STATE_DFS ==
Jeff Johnson23c3b842017-09-03 09:05:29 -07004443 wlan_reg_get_channel_state(hdd_ctx->hdd_pdev,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07004444 pConfig->channel))) {
Rajeev Kumar Sirasanagandlaa0006022016-09-09 16:24:31 +05304445 hdd_err("No SAP start on DFS channel");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304446 ret = -EOPNOTSUPP;
4447 goto error;
Rajeev Kumar Sirasanagandlaa0006022016-09-09 16:24:31 +05304448 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004449 }
Bala Venkatesh5479cf82018-06-09 20:02:38 +05304450
4451 if (iniConfig->ignoreCAC ||
4452 ((iniConfig->WlanMccToSccSwitchMode !=
4453 QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
4454 iniConfig->sta_sap_scc_on_dfs_chan))
4455 ignore_cac = 1;
4456
4457 wlansap_set_dfs_ignore_cac(mac_handle, ignore_cac);
Jeff Johnson89a0c742018-06-12 18:17:46 -07004458 wlansap_set_dfs_restrict_japan_w53(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004459 iniConfig->gDisableDfsJapanW53);
Jeff Johnson89a0c742018-06-12 18:17:46 -07004460 wlansap_set_dfs_preferred_channel_location(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004461 iniConfig->gSapPreferredChanLocation);
4462#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
Jeff Johnson89a0c742018-06-12 18:17:46 -07004463 wlan_sap_set_channel_avoidance(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004464 iniConfig->sap_channel_avoidance);
4465#endif
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004466 } else if (adapter->device_mode == QDF_P2P_GO_MODE) {
Jeff Johnson23c3b842017-09-03 09:05:29 -07004467 pConfig->countryCode[0] = hdd_ctx->reg.alpha2[0];
4468 pConfig->countryCode[1] = hdd_ctx->reg.alpha2[1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004469 pConfig->ieee80211d = 0;
4470 } else {
4471 pConfig->ieee80211d = 0;
4472 }
4473
Jeff Johnson89a0c742018-06-12 18:17:46 -07004474 wlansap_set_tx_leakage_threshold(mac_handle,
Yingying Tangb4832f72016-10-20 13:44:55 +08004475 iniConfig->sap_tx_leakage_threshold);
4476
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004477 capab_info = pMgmt_frame->u.beacon.capab_info;
4478
4479 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
4480 WLAN_CAPABILITY_PRIVACY) ? true : false;
4481
Jeff Johnsonc8d94a12017-10-27 14:02:53 -07004482 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->privacy = pConfig->privacy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004483
4484 /*Set wps station to configured */
4485 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
4486
4487 if (pIe) {
Hanumanth Reddy Pothula04bad8f2018-06-13 18:32:02 +05304488 /* To acess pIe[15], length needs to be atlest 14 */
4489 if (pIe[1] < 14) {
4490 hdd_err("**Wps Ie Length(%hhu) is too small***",
4491 pIe[1]);
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304492 ret = -EINVAL;
4493 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004494 } else if (memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) ==
4495 0) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08004496 hdd_debug("** WPS IE(len %d) ***", (pIe[1] + 2));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004497 /* Check 15 bit of WPS IE as it contain information for
4498 * wps state
4499 */
4500 if (SAP_WPS_ENABLED_UNCONFIGURED == pIe[15]) {
4501 pConfig->wps_state =
4502 SAP_WPS_ENABLED_UNCONFIGURED;
4503 } else if (SAP_WPS_ENABLED_CONFIGURED == pIe[15]) {
4504 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
4505 }
4506 }
4507 } else {
Srinivas Girigowda55756882017-03-06 16:45:27 -08004508 hdd_debug("WPS disabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004509 pConfig->wps_state = SAP_WPS_DISABLED;
4510 }
4511 /* Forward WPS PBC probe request frame up */
4512 pConfig->fwdWPSPBCProbeReq = 1;
4513
4514 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
4515 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
Jeff Johnsona8e686b2017-10-27 15:05:18 -07004516 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->encryption_type =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004517 eCSR_ENCRYPT_TYPE_NONE;
4518
4519 pConfig->RSNWPAReqIELength = 0;
4520 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Naveen Rawat08db88f2017-09-08 15:07:48 -07004521 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_RSN, pBeacon->tail,
4522 pBeacon->tail_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004523 if (pIe && pIe[1]) {
4524 pConfig->RSNWPAReqIELength = pIe[1] + 2;
4525 if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE))
4526 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
4527 pConfig->RSNWPAReqIELength);
4528 else
Jeff Johnsonecd884e2016-06-30 14:52:25 -07004529 hdd_err("RSNWPA IE MAX Length exceeded; length =%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004530 pConfig->RSNWPAReqIELength);
4531 /* The actual processing may eventually be more extensive than
Jeff Johnsond3919a92017-01-12 09:47:22 -08004532 * this. Right now, just consume any PMKIDs that are sent in
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004533 * by the app.
Jeff Johnsond3919a92017-01-12 09:47:22 -08004534 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004535 status =
4536 hdd_softap_unpack_ie(cds_get_context
Anurag Chouhan6d760662016-02-20 16:05:43 +05304537 (QDF_MODULE_ID_SME),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004538 &RSNEncryptType, &mcRSNEncryptType,
4539 &RSNAuthType, &MFPCapable,
4540 &MFPRequired,
4541 pConfig->RSNWPAReqIE[1] + 2,
4542 pConfig->RSNWPAReqIE);
4543
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304544 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004545 /* Now copy over all the security attributes you have
4546 * parsed out. Use the cipher type in the RSN IE
4547 */
4548 pConfig->RSNEncryptType = RSNEncryptType;
4549 pConfig->mcRSNEncryptType = mcRSNEncryptType;
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004550 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->
Jeff Johnsona8e686b2017-10-27 15:05:18 -07004551 encryption_type = RSNEncryptType;
Srinivas Girigowda55756882017-03-06 16:45:27 -08004552 hdd_debug("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004553 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4554 }
4555 }
4556
Naveen Rawat08db88f2017-09-08 15:07:48 -07004557 pIe = wlan_get_vendor_ie_ptr_from_oui(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004558 pBeacon->tail, pBeacon->tail_len);
4559
4560 if (pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA)) {
4561 if (pConfig->RSNWPAReqIE[0]) {
4562 /*Mixed mode WPA/WPA2 */
4563 prev_rsn_length = pConfig->RSNWPAReqIELength;
4564 pConfig->RSNWPAReqIELength += pIe[1] + 2;
4565 if (pConfig->RSNWPAReqIELength <
4566 sizeof(pConfig->RSNWPAReqIE))
4567 memcpy(&pConfig->RSNWPAReqIE[0] +
4568 prev_rsn_length, pIe, pIe[1] + 2);
4569 else
Srinivas Girigowda55756882017-03-06 16:45:27 -08004570 hdd_err("RSNWPA IE MAX Length exceeded; length: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004571 pConfig->RSNWPAReqIELength);
4572 } else {
4573 pConfig->RSNWPAReqIELength = pIe[1] + 2;
4574 if (pConfig->RSNWPAReqIELength <
4575 sizeof(pConfig->RSNWPAReqIE))
4576 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
4577 pConfig->RSNWPAReqIELength);
4578 else
Srinivas Girigowda55756882017-03-06 16:45:27 -08004579 hdd_err("RSNWPA IE MAX Length exceeded; length: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004580 pConfig->RSNWPAReqIELength);
4581 status = hdd_softap_unpack_ie
Anurag Chouhan6d760662016-02-20 16:05:43 +05304582 (cds_get_context(QDF_MODULE_ID_SME),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004583 &RSNEncryptType,
4584 &mcRSNEncryptType, &RSNAuthType,
4585 &MFPCapable, &MFPRequired,
4586 pConfig->RSNWPAReqIE[1] + 2,
4587 pConfig->RSNWPAReqIE);
4588
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304589 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004590 /* Now copy over all the security attributes
4591 * you have parsed out. Use the cipher type
4592 * in the RSN IE
4593 */
4594 pConfig->RSNEncryptType = RSNEncryptType;
4595 pConfig->mcRSNEncryptType = mcRSNEncryptType;
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004596 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->
Jeff Johnsona8e686b2017-10-27 15:05:18 -07004597 encryption_type = RSNEncryptType;
Srinivas Girigowda55756882017-03-06 16:45:27 -08004598 hdd_debug("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004599 RSNAuthType, RSNEncryptType,
4600 mcRSNEncryptType);
4601 }
4602 }
4603 }
4604
4605 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07004606 hdd_err("**RSNWPAReqIELength is too large***");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304607 ret = -EINVAL;
4608 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004609 }
4610
4611 pConfig->SSIDinfo.ssidHidden = false;
4612
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004613 if (ssid != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304614 qdf_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004615 pConfig->SSIDinfo.ssid.length = ssid_len;
4616
4617 switch (hidden_ssid) {
4618 case NL80211_HIDDEN_SSID_NOT_IN_USE:
Srinivas Girigowda55756882017-03-06 16:45:27 -08004619 hdd_debug("HIDDEN_SSID_NOT_IN_USE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004620 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
4621 break;
4622 case NL80211_HIDDEN_SSID_ZERO_LEN:
Srinivas Girigowda55756882017-03-06 16:45:27 -08004623 hdd_debug("HIDDEN_SSID_ZERO_LEN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004624 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
4625 break;
4626 case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
Srinivas Girigowda55756882017-03-06 16:45:27 -08004627 hdd_debug("HIDDEN_SSID_ZERO_CONTENTS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004628 pConfig->SSIDinfo.ssidHidden =
4629 eHIDDEN_SSID_ZERO_CONTENTS;
4630 break;
4631 default:
Srinivas Girigowda55756882017-03-06 16:45:27 -08004632 hdd_err("Wrong hidden_ssid param: %d", hidden_ssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004633 break;
4634 }
4635 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004636
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304637 qdf_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson1e851a12017-10-28 14:36:12 -07004638 adapter->mac_addr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304639 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004640
4641 /* default value */
4642 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
4643 pConfig->num_accept_mac = 0;
4644 pConfig->num_deny_mac = 0;
4645#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
4646 /*
4647 * We don't want P2PGO to follow STA's channel
4648 * so lets limit the logic for SAP only.
4649 * Later if we decide to make p2pgo follow STA's
4650 * channel then remove this check.
4651 */
Jeff Johnson23c3b842017-09-03 09:05:29 -07004652 if ((0 == hdd_ctx->config->conc_custom_rule1) ||
4653 (hdd_ctx->config->conc_custom_rule1 &&
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004654 QDF_SAP_MODE == adapter->device_mode))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004655 pConfig->cc_switch_mode = iniConfig->WlanMccToSccSwitchMode;
4656#endif
4657
Naveen Rawat08db88f2017-09-08 15:07:48 -07004658 pIe = wlan_get_vendor_ie_ptr_from_oui(BLACKLIST_OUI_TYPE,
4659 WPA_OUI_TYPE_SIZE, pBeacon->tail,
4660 pBeacon->tail_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004661
4662 /* pIe for black list is following form:
4663 * type : 1 byte
4664 * length : 1 byte
4665 * OUI : 4 bytes
4666 * acl type : 1 byte
4667 * no of mac addr in black list: 1 byte
4668 * list of mac_acl_entries: variable, 6 bytes per mac
4669 * address + sizeof(int) for vlan id
4670 */
4671 if ((pIe != NULL) && (pIe[1] != 0)) {
4672 pConfig->SapMacaddr_acl = pIe[6];
4673 pConfig->num_deny_mac = pIe[7];
Srinivas Girigowda55756882017-03-06 16:45:27 -08004674 hdd_debug("acl type = %d no deny mac = %d", pIe[6], pIe[7]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004675 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
4676 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
4677 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
4678 for (i = 0; i < pConfig->num_deny_mac; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304679 qdf_mem_copy(&pConfig->deny_mac[i], acl_entry->addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004680 sizeof(qcmacaddr));
4681 acl_entry++;
4682 }
4683 }
Naveen Rawat08db88f2017-09-08 15:07:48 -07004684 pIe = wlan_get_vendor_ie_ptr_from_oui(WHITELIST_OUI_TYPE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004685 WPA_OUI_TYPE_SIZE, pBeacon->tail,
4686 pBeacon->tail_len);
4687
4688 /* pIe for white list is following form:
4689 * type : 1 byte
4690 * length : 1 byte
4691 * OUI : 4 bytes
4692 * acl type : 1 byte
4693 * no of mac addr in white list: 1 byte
4694 * list of mac_acl_entries: variable, 6 bytes per mac
4695 * address + sizeof(int) for vlan id
4696 */
4697 if ((pIe != NULL) && (pIe[1] != 0)) {
4698 pConfig->SapMacaddr_acl = pIe[6];
4699 pConfig->num_accept_mac = pIe[7];
Srinivas Girigowda55756882017-03-06 16:45:27 -08004700 hdd_debug("acl type = %d no accept mac = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004701 pIe[6], pIe[7]);
4702 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
4703 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
4704 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
4705 for (i = 0; i < pConfig->num_accept_mac; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304706 qdf_mem_copy(&pConfig->accept_mac[i], acl_entry->addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004707 sizeof(qcmacaddr));
4708 acl_entry++;
4709 }
4710 }
Himanshu Agarwalad4c0392018-05-08 16:53:36 +05304711 if (!(ssid && qdf_str_len(PRE_CAC_SSID) == ssid_len &&
Houston Hoffman1942cae2017-08-24 16:59:35 -07004712 (0 == qdf_mem_cmp(ssid, PRE_CAC_SSID, ssid_len)))) {
Naveen Rawat08db88f2017-09-08 15:07:48 -07004713 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_SUPP_RATES,
4714 &pMgmt_frame->u.beacon.variable[0],
4715 pBeacon->head_len);
Agrawal Ashish06e76d22016-08-18 16:44:48 +05304716
4717 if (pIe != NULL) {
4718 pIe++;
4719 pConfig->supported_rates.numRates = pIe[0];
4720 pIe++;
4721 for (i = 0;
4722 i < pConfig->supported_rates.numRates; i++) {
4723 if (pIe[i]) {
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07004724 pConfig->supported_rates.rate[i] = pIe[i];
4725 hdd_debug("Configured Supported rate is %2x",
4726 pConfig->supported_rates.rate[i]);
Agrawal Ashish06e76d22016-08-18 16:44:48 +05304727 }
4728 }
4729 }
Naveen Rawat08db88f2017-09-08 15:07:48 -07004730 pIe = wlan_get_ie_ptr_from_eid(WLAN_EID_EXT_SUPP_RATES,
4731 pBeacon->tail,
4732 pBeacon->tail_len);
Agrawal Ashish06e76d22016-08-18 16:44:48 +05304733 if (pIe != NULL) {
4734 pIe++;
4735 pConfig->extended_rates.numRates = pIe[0];
4736 pIe++;
4737 for (i = 0; i < pConfig->extended_rates.numRates; i++) {
4738 if (pIe[i]) {
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07004739 pConfig->extended_rates.rate[i] = pIe[i];
4740 hdd_debug("Configured ext Supported rate is %2x",
4741 pConfig->extended_rates.rate[i]);
Agrawal Ashish06e76d22016-08-18 16:44:48 +05304742 }
4743 }
4744 }
4745 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004746
Naveen Rawat10b1c152017-01-18 11:16:06 -08004747 if (!cds_is_sub_20_mhz_enabled())
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004748 wlan_hdd_set_sap_hwmode(adapter);
Naveen Rawat10b1c152017-01-18 11:16:06 -08004749
Himanshu Agarwalf5c5b102018-05-22 20:13:57 +05304750 if (IS_24G_CH(pConfig->channel) &&
4751 hdd_ctx->config->enableVhtFor24GHzBand &&
4752 (pConfig->SapHw_mode == eCSR_DOT11_MODE_11n ||
4753 pConfig->SapHw_mode == eCSR_DOT11_MODE_11n_ONLY))
4754 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac;
4755
Bala Venkateshb9cf3362017-11-09 15:48:46 +05304756 if (((adapter->device_mode == QDF_SAP_MODE) &&
4757 (hdd_ctx->config->sap_force_11n_for_11ac)) ||
4758 ((adapter->device_mode == QDF_P2P_GO_MODE) &&
4759 (hdd_ctx->config->go_force_11n_for_11ac))) {
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05304760 if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac ||
4761 pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)
4762 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
4763 }
4764
Sridhar Selvaraj48c47092017-07-31 18:18:14 +05304765 qdf_mem_zero(sme_config, sizeof(*sme_config));
Jeff Johnson89a0c742018-06-12 18:17:46 -07004766 sme_get_config_param(mac_handle, sme_config);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004767 /* Override hostapd.conf wmm_enabled only for 11n and 11AC configs (IOT)
4768 * As per spec 11N/AC STA are QOS STA and may not connect or throughput
4769 * may not be good with non QOS 11N AP
4770 * Default: enable QOS for SAP unless WMM IE not present for 11bga
4771 */
Sridhar Selvaraj48c47092017-07-31 18:18:14 +05304772 sme_config->csrConfig.WMMSupportMode = eCsrRoamWmmAuto;
Naveen Rawat08db88f2017-09-08 15:07:48 -07004773 pIe = wlan_get_vendor_ie_ptr_from_oui(WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004774 pBeacon->tail, pBeacon->tail_len);
4775 if (!pIe && (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a ||
4776 pConfig->SapHw_mode == eCSR_DOT11_MODE_11g ||
4777 pConfig->SapHw_mode == eCSR_DOT11_MODE_11b))
Sridhar Selvaraj48c47092017-07-31 18:18:14 +05304778 sme_config->csrConfig.WMMSupportMode = eCsrRoamWmmNoQos;
Jeff Johnson89a0c742018-06-12 18:17:46 -07004779 sme_update_config(mac_handle, sme_config);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004780
Bala Venkateshb9cf3362017-11-09 15:48:46 +05304781 if (!((adapter->device_mode == QDF_SAP_MODE) &&
4782 (hdd_ctx->config->sap_force_11n_for_11ac)) ||
4783 ((adapter->device_mode == QDF_P2P_GO_MODE) &&
4784 (hdd_ctx->config->go_force_11n_for_11ac))) {
Amar Singhal4f22ccd2016-08-15 15:01:45 -07004785 pConfig->ch_width_orig =
4786 hdd_map_nl_chan_width(pConfig->ch_width_orig);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004787 } else {
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05304788 if (pConfig->ch_width_orig >= NL80211_CHAN_WIDTH_40)
4789 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
4790 else
4791 pConfig->ch_width_orig = CH_WIDTH_20MHZ;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004792 }
4793
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004794 if (wlan_hdd_setup_driver_overrides(adapter)) {
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304795 ret = -EINVAL;
4796 goto error;
4797 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004798
Himanshu Agarwal57b7ee32018-06-11 15:09:52 +05304799 pConfig->ch_params.ch_width = pConfig->ch_width_orig;
4800 wlan_reg_set_channel_params(hdd_ctx->hdd_pdev, pConfig->channel,
4801 pConfig->sec_ch, &pConfig->ch_params);
4802
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07004803 /* ht_capab is not what the name conveys,
4804 * this is used for protection bitmap
Jeff Johnsond3919a92017-01-12 09:47:22 -08004805 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004806 pConfig->ht_capab = iniConfig->apProtection;
4807
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004808 if (0 != wlan_hdd_cfg80211_update_apies(adapter)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07004809 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004810 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304811 ret = -EINVAL;
4812 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004813 }
4814 /* Uapsd Enabled Bit */
4815 pConfig->UapsdEnable = iniConfig->apUapsdEnabled;
4816 /* Enable OBSS protection */
4817 pConfig->obssProtEnabled = iniConfig->apOBSSProtEnabled;
4818
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004819 if (adapter->device_mode == QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004820 pConfig->sap_dot11mc =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004821 (WLAN_HDD_GET_CTX(adapter))->config->sap_dot11mc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004822 else /* for P2P-Go case */
4823 pConfig->sap_dot11mc = 1;
4824
Srinivas Girigowda55756882017-03-06 16:45:27 -08004825 hdd_debug("11MC Support Enabled : %d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004826 pConfig->sap_dot11mc);
4827
4828#ifdef WLAN_FEATURE_11W
4829 pConfig->mfpCapable = MFPCapable;
4830 pConfig->mfpRequired = MFPRequired;
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004831 hdd_debug("Soft AP MFP capable %d, MFP required %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004832 pConfig->mfpCapable, pConfig->mfpRequired);
4833#endif
4834
Srinivas Girigowda55756882017-03-06 16:45:27 -08004835 hdd_debug("SOftAP macaddress : " MAC_ADDRESS_STR,
Jeff Johnson1e851a12017-10-28 14:36:12 -07004836 MAC_ADDR_ARRAY(adapter->mac_addr.bytes));
Srinivas Girigowda55756882017-03-06 16:45:27 -08004837 hdd_debug("ssid =%s, beaconint=%d, channel=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004838 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
4839 (int)pConfig->channel);
Srinivas Girigowda55756882017-03-06 16:45:27 -08004840 hdd_debug("hw_mode=%x, privacy=%d, authType=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004841 pConfig->SapHw_mode, pConfig->privacy, pConfig->authType);
Srinivas Girigowda55756882017-03-06 16:45:27 -08004842 hdd_debug("RSN/WPALen=%d, Uapsd = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004843 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
Srinivas Girigowda55756882017-03-06 16:45:27 -08004844 hdd_debug("ProtEnabled = %d, OBSSProtEnabled = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004845 pConfig->protEnabled, pConfig->obssProtEnabled);
hqu16d6e082017-09-04 10:52:31 +08004846 hdd_debug("ChanSwitchHostapdRateEnabled = %d",
4847 pConfig->chan_switch_hostapd_rate_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004848
Tiger Yub2395d42018-05-15 15:05:44 +08004849 mutex_lock(&hdd_ctx->sap_lock);
4850 if (cds_is_driver_unloading()) {
4851 mutex_unlock(&hdd_ctx->sap_lock);
4852
4853 hdd_err("The driver is unloading, ignore the bss starting");
4854 ret = -EINVAL;
4855 goto error;
4856 }
4857
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004858 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Tiger Yub2395d42018-05-15 15:05:44 +08004859 mutex_unlock(&hdd_ctx->sap_lock);
4860
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004861 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
4862 /* Bss already started. just return. */
4863 /* TODO Probably it should update some beacon params. */
Srinivas Girigowda55756882017-03-06 16:45:27 -08004864 hdd_debug("Bss Already started...Ignore the request");
Dustin Browne74003f2018-03-14 12:51:58 -07004865 hdd_exit();
Sridhar Selvaraj48c47092017-07-31 18:18:14 +05304866 ret = 0;
4867 goto free;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004868 }
4869
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05304870 if (check_for_concurrency) {
Jeff Johnson23c3b842017-09-03 09:05:29 -07004871 if (!policy_mgr_allow_concurrency(hdd_ctx->hdd_psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08004872 policy_mgr_convert_device_mode_to_qdf_type(
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004873 adapter->device_mode),
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05304874 pConfig->channel, HW_MODE_20_MHZ)) {
Tiger Yub2395d42018-05-15 15:05:44 +08004875 mutex_unlock(&hdd_ctx->sap_lock);
4876
Srinivas Girigowda55756882017-03-06 16:45:27 -08004877 hdd_err("This concurrency combination is not allowed");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304878 ret = -EINVAL;
4879 goto error;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05304880 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004881 }
4882
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08004883 if (!hdd_set_connection_in_progress(true)) {
Tiger Yub2395d42018-05-15 15:05:44 +08004884 mutex_unlock(&hdd_ctx->sap_lock);
4885
Jeff Johnsone444c102018-05-06 16:04:21 -07004886 hdd_err("Can't start BSS: set connection in progress failed");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304887 ret = -EINVAL;
4888 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004889 }
4890
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004891 pConfig->persona = adapter->device_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004892
4893 pSapEventCallback = hdd_hostapd_sap_event_cb;
4894
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004895 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->dfs_cac_block_tx = true;
4896 set_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004897
Jeff Johnson5c19ade2017-10-04 09:52:12 -07004898 qdf_event_reset(&hostapd_state->qdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004899 status = wlansap_start_bss(
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004900 WLAN_HDD_GET_SAP_CTX_PTR(adapter),
4901 pSapEventCallback, pConfig, adapter->dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304902 if (!QDF_IS_STATUS_SUCCESS(status)) {
Tiger Yub2395d42018-05-15 15:05:44 +08004903 mutex_unlock(&hdd_ctx->sap_lock);
4904
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004905 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08004906 hdd_set_connection_in_progress(false);
Jeff Johnsonecd884e2016-06-30 14:52:25 -07004907 hdd_err("SAP Start Bss fail");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304908 ret = -EINVAL;
4909 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004910 }
4911
Srinivas Girigowda55756882017-03-06 16:45:27 -08004912 hdd_debug("Waiting for Scan to complete(auto mode) and BSS to start");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004913
Nachiket Kukade0396b732017-11-14 16:35:16 +05304914 qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Naveen Rawatb56880c2016-12-13 17:56:03 -08004915 SME_CMD_TIMEOUT_VALUE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004916
4917 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
4918
Anurag Chouhance0dc992016-02-16 18:18:03 +05304919 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Tiger Yub2395d42018-05-15 15:05:44 +08004920 mutex_unlock(&hdd_ctx->sap_lock);
4921
Srinivas Girigowda55756882017-03-06 16:45:27 -08004922 hdd_err("qdf wait for single_event failed!!");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08004923 hdd_set_connection_in_progress(false);
Jeff Johnson89a0c742018-06-12 18:17:46 -07004924 sme_get_command_q_status(mac_handle);
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004925 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304926 QDF_ASSERT(0);
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304927 ret = -EINVAL;
4928 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004929 }
Jeff Johnson45ecc242018-05-06 17:12:48 -07004930 /* Successfully started Bss update the state bit. */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004931 set_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Tiger Yub2395d42018-05-15 15:05:44 +08004932
4933 mutex_unlock(&hdd_ctx->sap_lock);
4934
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004935 /* Initialize WMM configuation */
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004936 hdd_wmm_init(adapter);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05304937 if (hostapd_state->bss_state == BSS_START) {
Jeff Johnson23c3b842017-09-03 09:05:29 -07004938 policy_mgr_incr_active_session(hdd_ctx->hdd_psoc,
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004939 adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -07004940 adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07004941 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05304942 true);
4943 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004944#ifdef DHCP_SERVER_OFFLOAD
4945 if (iniConfig->enableDHCPServerOffload)
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004946 wlan_hdd_set_dhcp_server_offload(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004947#endif /* DHCP_SERVER_OFFLOAD */
4948
Wu Gaoc02785d2017-09-07 18:17:13 +08004949 ucfg_p2p_status_start_bss(adapter->hdd_vdev);
4950
Ashish Kumar Dhanotiya9298a8e2017-03-24 17:02:44 +05304951 /* Check and restart SAP if it is on unsafe channel */
Jeff Johnson23c3b842017-09-03 09:05:29 -07004952 hdd_unsafe_channel_restart_sap(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004953
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08004954 hdd_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004955
Sridhar Selvaraj48c47092017-07-31 18:18:14 +05304956 ret = 0;
4957 goto free;
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304958
4959error:
Mukul Sharmaecf8e092017-12-19 22:36:31 +05304960 /* Revert the indoor to passive marking if START BSS fails */
4961 if (iniConfig->force_ssc_disable_indoor_channel) {
4962 hdd_update_indoor_channel(hdd_ctx, false);
Jeff Johnson89a0c742018-06-12 18:17:46 -07004963 sme_update_channel_list(mac_handle);
Mukul Sharmaecf8e092017-12-19 22:36:31 +05304964 }
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07004965 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05304966 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Himanshu Agarwal1b3be702018-02-20 12:16:57 +05304967 wlan_hdd_undo_acs(adapter);
Sridhar Selvaraj48c47092017-07-31 18:18:14 +05304968
4969free:
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +05304970 /* Enable Roaming after start bss in case of failure/success */
4971 wlan_hdd_enable_roaming(adapter);
Sridhar Selvaraj48c47092017-07-31 18:18:14 +05304972 qdf_mem_free(sme_config);
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05304973 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004974}
4975
Jeff Johnson866aca82017-09-10 15:27:20 -07004976int hdd_destroy_acs_timer(struct hdd_adapter *adapter)
Kapil Gupta63e75282017-05-18 20:55:10 +05304977{
4978 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
4979
Jeff Johnsonb9424862017-10-30 08:49:35 -07004980 if (!adapter->session.ap.vendor_acs_timer_initialized)
Kapil Gupta63e75282017-05-18 20:55:10 +05304981 return 0;
4982
Jeff Johnsonb9424862017-10-30 08:49:35 -07004983 adapter->session.ap.vendor_acs_timer_initialized = false;
Kapil Gupta63e75282017-05-18 20:55:10 +05304984
4985 if (QDF_TIMER_STATE_RUNNING ==
Jeff Johnsonb9424862017-10-30 08:49:35 -07004986 adapter->session.ap.vendor_acs_timer.state) {
Kapil Gupta63e75282017-05-18 20:55:10 +05304987 qdf_status =
Jeff Johnsonb9424862017-10-30 08:49:35 -07004988 qdf_mc_timer_stop(&adapter->session.ap.
Kapil Gupta63e75282017-05-18 20:55:10 +05304989 vendor_acs_timer);
4990 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
4991 hdd_err("Failed to stop ACS timer");
4992 }
4993
Jeff Johnsonb9424862017-10-30 08:49:35 -07004994 if (adapter->session.ap.vendor_acs_timer.user_data)
4995 qdf_mem_free(adapter->session.ap.vendor_acs_timer.user_data);
Kapil Gupta63e75282017-05-18 20:55:10 +05304996
Jeff Johnsonb9424862017-10-30 08:49:35 -07004997 qdf_mc_timer_destroy(&adapter->session.ap.vendor_acs_timer);
Kapil Gupta63e75282017-05-18 20:55:10 +05304998
4999 return 0;
5000}
5001
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005002/**
5003 * __wlan_hdd_cfg80211_stop_ap() - stop soft ap
5004 * @wiphy: Pointer to wiphy structure
5005 * @dev: Pointer to net_device structure
5006 *
5007 * Return: 0 for success non-zero for failure
5008 */
5009static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
5010 struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005011{
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005012 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathandd9cf622018-02-09 12:08:37 +05305013 struct hdd_adapter *sta_adapter;
Jeff Johnson23c3b842017-09-03 09:05:29 -07005014 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305015 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Anurag Chouhance0dc992016-02-16 18:18:03 +05305016 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005017 tSirUpdateIE updateIE;
Jeff Johnson44e52172017-09-30 16:39:16 -07005018 struct hdd_beacon_data *old;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005019 int ret;
Jeff Johnson89a0c742018-06-12 18:17:46 -07005020 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005021
Dustin Brown491d54b2018-03-14 12:39:11 -07005022 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005023
Anurag Chouhan6d760662016-02-20 16:05:43 +05305024 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07005025 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005026 return -EINVAL;
5027 }
5028
Jeff Johnson23c3b842017-09-03 09:05:29 -07005029 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
Dustin Brown6807c742017-02-01 17:43:03 -08005030 hdd_err("Driver module is closed; dropping request");
5031 return -EINVAL;
5032 }
5033
Jeff Johnson1b780e42017-10-31 14:11:45 -07005034 if (wlan_hdd_validate_session_id(adapter->session_id)) {
5035 hdd_err("Invalid session id: %d", adapter->session_id);
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +05305036 return -EINVAL;
5037 }
5038
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305039 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005040 TRACE_CODE_HDD_CFG80211_STOP_AP,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005041 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005042
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005043 if (!(adapter->device_mode == QDF_SAP_MODE ||
5044 adapter->device_mode == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005045 return -EOPNOTSUPP;
5046 }
Srinivas Girigowda55756882017-03-06 16:45:27 -08005047
Manikandan Mohanf9b2dc12017-02-17 16:49:57 -08005048 /* Clear SOFTAP_INIT_DONE flag to mark stop_ap deinit. So that we do
5049 * not restart SAP after SSR as SAP is already stopped from user space.
5050 * This update is moved to start of this function to resolve stop_ap
5051 * call during SSR case. Adapter gets cleaned up as part of SSR.
5052 */
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005053 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
Srinivas Girigowda55756882017-03-06 16:45:27 -08005054 hdd_debug("Device_mode %s(%d)",
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005055 hdd_device_mode_to_string(adapter->device_mode),
5056 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005057
Jeff Johnson23c3b842017-09-03 09:05:29 -07005058 ret = wlan_hdd_validate_context(hdd_ctx);
Liangwei Dong8baf7c82016-10-11 01:26:59 -04005059 if (0 != ret)
Ganesh Kondabattiniff050662016-08-05 12:21:23 +05305060 return ret;
Ganesh Kondabattiniff050662016-08-05 12:21:23 +05305061
Vignesh Viswanathandd9cf622018-02-09 12:08:37 +05305062 /*
5063 * If a STA connection is in progress in another adapter, disconnect
5064 * the STA and complete the SAP operation. STA will reconnect
5065 * after SAP stop is done.
5066 */
5067 sta_adapter = hdd_get_sta_connection_in_progress(hdd_ctx);
5068 if (sta_adapter) {
5069 hdd_debug("Disconnecting STA with session id: %d",
5070 sta_adapter->session_id);
5071 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
5072 }
5073
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305074 if (adapter->device_mode == QDF_SAP_MODE)
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005075 wlan_hdd_del_station(adapter);
Himanshu Agarwalb229a142017-12-21 10:16:45 +05305076
Krunal Soni22208392017-09-29 18:10:34 -07005077 cds_flush_work(&adapter->sap_stop_bss_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005078 /*
5079 * When ever stop ap adapter gets called, we need to check
5080 * whether any restart AP work is pending. If any restart is pending
5081 * then lets finish it and go ahead from there.
5082 */
Jeff Johnson23c3b842017-09-03 09:05:29 -07005083 if (hdd_ctx->config->conc_custom_rule1 &&
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005084 (QDF_SAP_MODE == adapter->device_mode)) {
Jeff Johnson23c3b842017-09-03 09:05:29 -07005085 cds_flush_work(&hdd_ctx->sap_start_work);
Srinivas Girigowda55756882017-03-06 16:45:27 -08005086 hdd_debug("Canceled the pending restart work");
Jeff Johnson23c3b842017-09-03 09:05:29 -07005087 qdf_spin_lock(&hdd_ctx->sap_update_info_lock);
5088 hdd_ctx->is_sap_restart_required = false;
5089 qdf_spin_unlock(&hdd_ctx->sap_update_info_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005090 }
Jeff Johnsonb9424862017-10-30 08:49:35 -07005091 adapter->session.ap.sap_config.acs_cfg.acs_mode = false;
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05305092 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005093 wlan_hdd_undo_acs(adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -07005094 qdf_mem_zero(&adapter->session.ap.sap_config.acs_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005095 sizeof(struct sap_acs_cfg));
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005096 hdd_debug("Disabling queues");
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005097 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305098 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Arunk Khandavalli0dd8c012017-01-23 20:48:48 +05305099 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005100
Jeff Johnsonb9424862017-10-30 08:49:35 -07005101 old = adapter->session.ap.beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005102 if (!old) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08005103 hdd_err("Session id: %d beacon data points to NULL",
Jeff Johnson1b780e42017-10-31 14:11:45 -07005104 adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005105 return -EINVAL;
5106 }
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005107 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Jeff Johnson23c3b842017-09-03 09:05:29 -07005108 mutex_lock(&hdd_ctx->sap_lock);
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005109 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Jeff Johnson5c19ade2017-10-04 09:52:12 -07005110 struct hdd_hostapd_state *hostapd_state =
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005111 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005112
Vignesh Viswanathan200f5c12018-02-27 14:01:59 +05305113 /* Set the stop_bss_in_progress flag */
5114 wlansap_set_stop_bss_inprogress(
5115 WLAN_HDD_GET_SAP_CTX_PTR(adapter), true);
5116
Jeff Johnson5c19ade2017-10-04 09:52:12 -07005117 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005118 status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305119 if (QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhance0dc992016-02-16 18:18:03 +05305120 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +05305121 qdf_wait_for_event_completion(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -08005122 qdf_stop_bss_event,
5123 SME_CMD_TIMEOUT_VALUE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005124
Anurag Chouhance0dc992016-02-16 18:18:03 +05305125 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08005126 hdd_err("qdf wait for single_event failed!!");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305127 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005128 }
5129 }
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005130 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Vignesh Viswanathan200f5c12018-02-27 14:01:59 +05305131
5132 /* Clear the stop_bss_in_progress flag */
5133 wlansap_set_stop_bss_inprogress(
5134 WLAN_HDD_GET_SAP_CTX_PTR(adapter), false);
5135
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005136 /*BSS stopped, clear the active sessions for this device mode*/
Jeff Johnson23c3b842017-09-03 09:05:29 -07005137 policy_mgr_decr_session_set_pcl(hdd_ctx->hdd_psoc,
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005138 adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005139 adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005140 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305141 false);
Jeff Johnsonb9424862017-10-30 08:49:35 -07005142 adapter->session.ap.beacon = NULL;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305143 qdf_mem_free(old);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005144 }
Jeff Johnson23c3b842017-09-03 09:05:29 -07005145 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005146
Jeff Johnson89a0c742018-06-12 18:17:46 -07005147 mac_handle = hdd_ctx->mac_handle;
5148 if (wlan_sap_is_pre_cac_active(mac_handle))
Jeff Johnson23c3b842017-09-03 09:05:29 -07005149 hdd_clean_up_pre_cac_interface(hdd_ctx);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305150
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305151 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07005152 hdd_err("Stopping the BSS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005153 return -EINVAL;
5154 }
5155
Jeff Johnson1e851a12017-10-28 14:36:12 -07005156 qdf_copy_macaddr(&updateIE.bssid, &adapter->mac_addr);
Jeff Johnson1b780e42017-10-31 14:11:45 -07005157 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005158 updateIE.ieBufferlength = 0;
5159 updateIE.pAdditionIEBuffer = NULL;
5160 updateIE.append = true;
5161 updateIE.notify = true;
Jeff Johnson89a0c742018-06-12 18:17:46 -07005162 if (sme_update_add_ie(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005163 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305164 eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07005165 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005166 }
5167
Jeff Johnson89a0c742018-06-12 18:17:46 -07005168 if (sme_update_add_ie(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005169 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305170 eUPDATE_IE_ASSOC_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07005171 hdd_err("Could not pass on ASSOC_RSP data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005172 }
5173 /* Reset WNI_CFG_PROBE_RSP Flags */
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005174 wlan_hdd_reset_prob_rspies(adapter);
5175 hdd_destroy_acs_timer(adapter);
Wu Gaoc02785d2017-09-07 18:17:13 +08005176
5177 ucfg_p2p_status_stop_bss(adapter->hdd_vdev);
5178
Dustin Browne74003f2018-03-14 12:51:58 -07005179 hdd_exit();
Wu Gao0c45d6a2017-05-23 18:53:36 +08005180
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005181 return ret;
5182}
5183
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005184/**
5185 * wlan_hdd_get_channel_bw() - get channel bandwidth
5186 * @width: input channel width in nl80211_chan_width value
5187 *
5188 * Return: channel width value defined by driver
5189 */
5190static enum hw_mode_bandwidth wlan_hdd_get_channel_bw(
5191 enum nl80211_chan_width width)
5192{
5193 enum hw_mode_bandwidth ch_bw = HW_MODE_20_MHZ;
5194
5195 switch (width) {
5196 case NL80211_CHAN_WIDTH_20_NOHT:
5197 case NL80211_CHAN_WIDTH_20:
5198 ch_bw = HW_MODE_20_MHZ;
5199 break;
5200 case NL80211_CHAN_WIDTH_40:
5201 ch_bw = HW_MODE_40_MHZ;
5202 break;
5203 case NL80211_CHAN_WIDTH_80:
5204 ch_bw = HW_MODE_80_MHZ;
5205 break;
5206 case NL80211_CHAN_WIDTH_80P80:
5207 ch_bw = HW_MODE_80_PLUS_80_MHZ;
5208 break;
5209 case NL80211_CHAN_WIDTH_160:
5210 ch_bw = HW_MODE_160_MHZ;
5211 break;
5212 default:
5213 hdd_err("Invalid width: %d, using default 20MHz", width);
5214 break;
5215 }
5216
5217 return ch_bw;
5218}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005219
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005220/**
5221 * wlan_hdd_cfg80211_stop_ap() - stop sap
5222 * @wiphy: Pointer to wiphy
5223 * @dev: Pointer to netdev
5224 *
5225 * Return: zero for success non-zero for failure
5226 */
5227int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
5228 struct net_device *dev)
5229{
5230 int ret;
5231
5232 cds_ssr_protect(__func__);
5233 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
5234 cds_ssr_unprotect(__func__);
5235
5236 return ret;
5237}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005238
Jiachao Wu712d4fd2017-08-23 16:52:34 +08005239#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) || \
5240 defined(CFG80211_BEACON_TX_RATE_CUSTOM_BACKPORT)
5241/**
5242 * hdd_get_data_rate_from_rate_mask() - convert mask to rate
5243 * @wiphy: Pointer to wiphy
5244 * @band: band
5245 * @bit_rate_mask: pointer to bit_rake_mask
5246 *
5247 * This function takes band and bit_rate_mask as input and
5248 * derives the beacon_tx_rate based on the supported rates
5249 * published as part of wiphy register.
5250 *
5251 * Return: data rate for success or zero for failure
5252 */
5253static uint16_t hdd_get_data_rate_from_rate_mask(struct wiphy *wiphy,
Dustin Brown76b92122017-09-20 17:35:39 -07005254 enum nl80211_band band,
Jiachao Wu712d4fd2017-08-23 16:52:34 +08005255 struct cfg80211_bitrate_mask *bit_rate_mask)
5256{
5257 struct ieee80211_supported_band *sband = wiphy->bands[band];
5258 int sband_n_bitrates;
5259 struct ieee80211_rate *sband_bitrates;
5260 int i;
5261
5262 if (sband) {
5263 sband_bitrates = sband->bitrates;
5264 sband_n_bitrates = sband->n_bitrates;
5265 for (i = 0; i < sband_n_bitrates; i++) {
5266 if (bit_rate_mask->control[band].legacy ==
5267 sband_bitrates[i].hw_value)
5268 return sband_bitrates[i].bitrate;
5269 }
5270 }
5271 return 0;
5272}
5273
5274/**
5275 * hdd_update_beacon_rate() - Update beacon tx rate
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005276 * @adapter: Pointer to hdd_adapter_t
Jiachao Wu712d4fd2017-08-23 16:52:34 +08005277 * @wiphy: Pointer to wiphy
5278 * @params: Pointet to cfg80211_ap_settings
5279 *
5280 * This function updates the beacon tx rate which is provided
Jeff Johnson91df29d2017-10-27 19:29:50 -07005281 * as part of cfg80211_ap_settions in to the sap_config
Jiachao Wu712d4fd2017-08-23 16:52:34 +08005282 * structure
5283 *
5284 * Return: none
5285 */
5286static void hdd_update_beacon_rate(struct hdd_adapter *adapter,
5287 struct wiphy *wiphy,
5288 struct cfg80211_ap_settings *params)
5289{
5290 struct cfg80211_bitrate_mask *beacon_rate_mask;
Dustin Brown76b92122017-09-20 17:35:39 -07005291 enum nl80211_band band;
Jiachao Wu712d4fd2017-08-23 16:52:34 +08005292
5293 band = params->chandef.chan->band;
5294 beacon_rate_mask = &params->beacon_rate;
5295 if (beacon_rate_mask->control[band].legacy) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07005296 adapter->session.ap.sap_config.beacon_tx_rate =
Jiachao Wu712d4fd2017-08-23 16:52:34 +08005297 hdd_get_data_rate_from_rate_mask(wiphy, band,
5298 beacon_rate_mask);
5299 hdd_debug("beacon mask value %u, rate %hu",
5300 params->beacon_rate.control[0].legacy,
Jeff Johnsonb9424862017-10-30 08:49:35 -07005301 adapter->session.ap.sap_config.beacon_tx_rate);
Jiachao Wu712d4fd2017-08-23 16:52:34 +08005302 }
5303}
5304#else
5305static void hdd_update_beacon_rate(struct hdd_adapter *adapter,
5306 struct wiphy *wiphy,
5307 struct cfg80211_ap_settings *params)
5308{
5309}
5310#endif
5311
5312
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005313/**
5314 * __wlan_hdd_cfg80211_start_ap() - start soft ap mode
5315 * @wiphy: Pointer to wiphy structure
5316 * @dev: Pointer to net_device structure
5317 * @params: Pointer to AP settings parameters
5318 *
5319 * Return: 0 for success non-zero for failure
5320 */
5321static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
5322 struct net_device *dev,
5323 struct cfg80211_ap_settings *params)
5324{
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005325 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson23c3b842017-09-03 09:05:29 -07005326 struct hdd_context *hdd_ctx;
Chandrasekaran, Manishekar96c90962015-11-20 16:47:45 +05305327 enum hw_mode_bandwidth channel_width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005328 int status;
Agrawal, Ashish4e5fa1c2016-09-21 19:03:43 +05305329 struct sme_sta_inactivity_timeout *sta_inactivity_timer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005330 uint8_t channel;
Bala Venkatesh5479cf82018-06-09 20:02:38 +05305331 bool sta_sap_scc_on_dfs_chan;
5332 uint16_t sta_cnt;
Dustin Brown491d54b2018-03-14 12:39:11 -07005333
5334 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005335
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005336 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
Anurag Chouhan6d760662016-02-20 16:05:43 +05305337 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07005338 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005339 return -EINVAL;
5340 }
5341
Jeff Johnson1b780e42017-10-31 14:11:45 -07005342 if (wlan_hdd_validate_session_id(adapter->session_id)) {
5343 hdd_err("Invalid session id: %d", adapter->session_id);
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +05305344 return -EINVAL;
5345 }
5346
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305347 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005348 TRACE_CODE_HDD_CFG80211_START_AP, adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005349 params->beacon_interval));
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005350 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07005351 hdd_err("HDD adapter magic is invalid");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005352 return -ENODEV;
5353 }
5354
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005355 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson23c3b842017-09-03 09:05:29 -07005356 status = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305357 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005358 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005359
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005360 hdd_debug("adapter = %pK, Device mode %s(%d) sub20 %d",
5361 adapter, hdd_device_mode_to_string(adapter->device_mode),
5362 adapter->device_mode, cds_is_sub_20_mhz_enabled());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005363
Jeff Johnson23c3b842017-09-03 09:05:29 -07005364 if (policy_mgr_is_hw_mode_change_in_progress(hdd_ctx->hdd_psoc)) {
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005365 status = policy_mgr_wait_for_connection_update(
Jeff Johnson23c3b842017-09-03 09:05:29 -07005366 hdd_ctx->hdd_psoc);
Nitesh Shaha3dfea32017-02-09 19:18:57 +05305367 if (!QDF_IS_STATUS_SUCCESS(status)) {
5368 hdd_err("qdf wait for event failed!!");
5369 return -EINVAL;
5370 }
5371 }
5372
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005373 channel_width = wlan_hdd_get_channel_bw(params->chandef.width);
5374 channel = ieee80211_frequency_to_channel(
5375 params->chandef.chan->center_freq);
Himanshu Agarwal5fb304b2018-02-27 21:14:05 +05305376 adapter->session.ap.sap_config.ch_params.center_freq_seg0 =
5377 cds_freq_to_chan(params->chandef.center_freq1);
5378 adapter->session.ap.sap_config.ch_params.center_freq_seg1 =
5379 cds_freq_to_chan(params->chandef.center_freq2);
Amar Singhal01098f72015-10-08 11:55:32 -07005380
Bala Venkatesh5479cf82018-06-09 20:02:38 +05305381 sta_sap_scc_on_dfs_chan =
5382 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
5383 hdd_ctx->hdd_psoc);
5384 sta_cnt =
5385 policy_mgr_mode_specific_connection_count(
5386 hdd_ctx->hdd_psoc, PM_STA_MODE, NULL);
5387
5388 hdd_debug("sta_sap_scc_on_dfs_chan %u, sta_cnt %u",
5389 sta_sap_scc_on_dfs_chan, sta_cnt);
5390
5391 /* if sta_sap_scc_on_dfs_chan ini is set, DFS master capability is
5392 * assumed disabled in the driver.
5393 */
5394 if (channel && (reg_get_channel_state(hdd_ctx->hdd_pdev, channel) ==
5395 CHANNEL_STATE_DFS) && sta_sap_scc_on_dfs_chan && !sta_cnt) {
5396 hdd_err("SAP not allowed on DFS channel!!");
5397 return -EINVAL;
5398 }
5399
Naveen Rawat64e477e2016-05-20 10:34:56 -07005400 if (cds_is_sub_20_mhz_enabled()) {
5401 enum channel_state ch_state;
5402 enum phy_ch_width sub_20_ch_width = CH_WIDTH_INVALID;
Jeff Johnsone4c11db2018-05-05 23:22:32 -07005403 tsap_config_t *sap_cfg = &adapter->session.ap.sap_config;
Naveen Rawat10b1c152017-01-18 11:16:06 -08005404
Naveen Rawat64e477e2016-05-20 10:34:56 -07005405 /* Avoid ACS/DFS, and overwrite ch wd to 20 */
5406 if (channel == 0) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08005407 hdd_err("Can't start SAP-ACS (channel=0) with sub 20 MHz ch width");
Naveen Rawat64e477e2016-05-20 10:34:56 -07005408 return -EINVAL;
5409 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07005410 if (CHANNEL_STATE_DFS == wlan_reg_get_channel_state(
Jeff Johnson23c3b842017-09-03 09:05:29 -07005411 hdd_ctx->hdd_pdev, channel)) {
Naveen Rawat64e477e2016-05-20 10:34:56 -07005412 hdd_err("Can't start SAP-DFS (channel=%d)with sub 20 MHz ch wd",
5413 channel);
5414 return -EINVAL;
5415 }
5416 if (channel_width != HW_MODE_20_MHZ) {
5417 hdd_err("Hostapd (20+ MHz) conflits with config.ini (sub 20 MHz)");
5418 return -EINVAL;
5419 }
5420 if (cds_is_5_mhz_enabled())
5421 sub_20_ch_width = CH_WIDTH_5MHZ;
5422 if (cds_is_10_mhz_enabled())
5423 sub_20_ch_width = CH_WIDTH_10MHZ;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07005424 if (WLAN_REG_IS_5GHZ_CH(channel))
5425 ch_state = wlan_reg_get_5g_bonded_channel_state(
Jeff Johnson23c3b842017-09-03 09:05:29 -07005426 hdd_ctx->hdd_pdev, channel,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07005427 sub_20_ch_width);
Naveen Rawat64e477e2016-05-20 10:34:56 -07005428 else
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07005429 ch_state = wlan_reg_get_2g_bonded_channel_state(
Jeff Johnson23c3b842017-09-03 09:05:29 -07005430 hdd_ctx->hdd_pdev, channel,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07005431 sub_20_ch_width, 0);
Naveen Rawat64e477e2016-05-20 10:34:56 -07005432 if (CHANNEL_STATE_DISABLE == ch_state) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08005433 hdd_err("Given ch width not supported by reg domain");
Naveen Rawat64e477e2016-05-20 10:34:56 -07005434 return -EINVAL;
5435 }
Naveen Rawat10b1c152017-01-18 11:16:06 -08005436 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_abg;
Naveen Rawat64e477e2016-05-20 10:34:56 -07005437 }
5438
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005439 /* check if concurrency is allowed */
Jeff Johnson23c3b842017-09-03 09:05:29 -07005440 if (!policy_mgr_allow_concurrency(hdd_ctx->hdd_psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005441 policy_mgr_convert_device_mode_to_qdf_type(
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005442 adapter->device_mode),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005443 channel,
5444 channel_width)) {
5445 hdd_err("Connection failed due to concurrency check failure");
5446 return -EINVAL;
5447 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005448
Jeff Johnson23c3b842017-09-03 09:05:29 -07005449 status = policy_mgr_reset_connection_update(hdd_ctx->hdd_psoc);
Krunal Soni3091bcc2016-06-23 12:28:21 -07005450 if (!QDF_IS_STATUS_SUCCESS(status))
5451 hdd_err("ERR: clear event failed");
5452
Himanshu Agarwal55972082018-04-18 14:26:39 +05305453 /*
5454 * Stop opportunistic timer here if running as we are already doing
5455 * hw mode change before vdev start based on the new concurrency
5456 * situation. If timer is not stopped and if it gets triggered before
5457 * VDEV_UP, it will reset the hw mode to some wrong value.
5458 */
5459 status = policy_mgr_stop_opportunistic_timer(hdd_ctx->hdd_psoc);
5460 if (status != QDF_STATUS_SUCCESS) {
5461 hdd_err("Failed to stop DBS opportunistic timer");
5462 return -EINVAL;
5463 }
5464
Jeff Johnson23c3b842017-09-03 09:05:29 -07005465 status = policy_mgr_current_connections_update(hdd_ctx->hdd_psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005466 adapter->session_id, channel,
Tushnim Bhattacharyya3b99f4b2018-03-26 14:19:24 -07005467 POLICY_MGR_UPDATE_REASON_START_AP);
Himanshu Agarwal55972082018-04-18 14:26:39 +05305468 if (status == QDF_STATUS_E_FAILURE) {
Krunal Soni3091bcc2016-06-23 12:28:21 -07005469 hdd_err("ERROR: connections update failed!!");
5470 return -EINVAL;
5471 }
5472
5473 if (QDF_STATUS_SUCCESS == status) {
Jeff Johnson23c3b842017-09-03 09:05:29 -07005474 status = policy_mgr_wait_for_connection_update(hdd_ctx->hdd_psoc);
Krunal Soni3091bcc2016-06-23 12:28:21 -07005475 if (!QDF_IS_STATUS_SUCCESS(status)) {
5476 hdd_err("ERROR: qdf wait for event failed!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005477 return -EINVAL;
5478 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005479 }
bings612b9c42016-11-07 10:52:03 +08005480
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005481 if (adapter->device_mode == QDF_P2P_GO_MODE) {
Jeff Johnson866aca82017-09-10 15:27:20 -07005482 struct hdd_adapter *p2p_adapter;
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07005483
Jeff Johnson23c3b842017-09-03 09:05:29 -07005484 p2p_adapter = hdd_get_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE);
Liangwei Dongb3f26cc2016-10-11 04:37:00 -04005485 if (p2p_adapter) {
Srinivas Girigowdadf88faa2017-03-24 22:05:44 -07005486 hdd_debug("Cancel active p2p device ROC before GO starting");
Liangwei Dongb3f26cc2016-10-11 04:37:00 -04005487 wlan_hdd_cancel_existing_remain_on_channel(
5488 p2p_adapter);
5489 }
5490 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005491
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005492 if ((adapter->device_mode == QDF_SAP_MODE)
5493 || (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005494 ) {
Jeff Johnson44e52172017-09-30 16:39:16 -07005495 struct hdd_beacon_data *old, *new;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005496 enum nl80211_channel_type channel_type;
Jeff Johnsone4c11db2018-05-05 23:22:32 -07005497 tsap_config_t *sap_config =
Jeff Johnson91df29d2017-10-27 19:29:50 -07005498 &((WLAN_HDD_GET_AP_CTX_PTR(adapter))->sap_config);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005499
Jeff Johnsonb9424862017-10-30 08:49:35 -07005500 old = adapter->session.ap.beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005501
5502 if (old)
5503 return -EALREADY;
5504
5505 status =
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005506 wlan_hdd_cfg80211_alloc_new_beacon(adapter, &new,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005507 &params->beacon,
5508 params->dtim_period);
5509
5510 if (status != 0) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07005511 hdd_err("Error!!! Allocating the new beacon");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005512 return -EINVAL;
5513 }
Jeff Johnsonb9424862017-10-30 08:49:35 -07005514 adapter->session.ap.beacon = new;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005515
5516 if (params->chandef.width < NL80211_CHAN_WIDTH_80)
5517 channel_type = cfg80211_get_chandef_type(
5518 &(params->chandef));
5519 else
5520 channel_type = NL80211_CHAN_HT40PLUS;
5521
5522
5523 wlan_hdd_set_channel(wiphy, dev,
5524 &params->chandef,
5525 channel_type);
5526
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005527 hdd_update_beacon_rate(adapter, wiphy, params);
Jiachao Wu712d4fd2017-08-23 16:52:34 +08005528
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005529 /* set authentication type */
5530 switch (params->auth_type) {
5531 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Jeff Johnsonb9424862017-10-30 08:49:35 -07005532 adapter->session.ap.sap_config.authType =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005533 eSAP_OPEN_SYSTEM;
5534 break;
5535 case NL80211_AUTHTYPE_SHARED_KEY:
Jeff Johnsonb9424862017-10-30 08:49:35 -07005536 adapter->session.ap.sap_config.authType =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005537 eSAP_SHARED_KEY;
5538 break;
5539 default:
Jeff Johnsonb9424862017-10-30 08:49:35 -07005540 adapter->session.ap.sap_config.authType =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005541 eSAP_AUTO_SWITCH;
5542 }
Jeff Johnsonb9424862017-10-30 08:49:35 -07005543 adapter->session.ap.sap_config.ch_width_orig =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005544 params->chandef.width;
Himanshu Agarwal5fb304b2018-02-27 21:14:05 +05305545
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005546 status =
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005547 wlan_hdd_cfg80211_start_bss(adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005548 &params->beacon,
5549 params->ssid, params->ssid_len,
Mahesh Kumar Kalikot Veetilc637fc92017-09-27 16:06:21 -07005550 params->hidden_ssid, true);
Arunk Khandavallibbc301f2017-06-21 22:14:31 +05305551
5552 if (status != 0) {
5553 hdd_err("Error Start bss Failed");
5554 goto err_start_bss;
5555 }
5556
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305557 /*
5558 * If Do_Not_Break_Stream enabled send avoid channel list
5559 * to application.
5560 */
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005561 if (policy_mgr_is_dnsc_set(adapter->hdd_vdev) &&
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305562 sap_config->channel) {
Jeff Johnson23c3b842017-09-03 09:05:29 -07005563 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx,
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305564 sap_config->channel);
5565 }
Jeff Johnson23c3b842017-09-03 09:05:29 -07005566 if (hdd_ctx->config->sap_max_inactivity_override) {
Agrawal, Ashish4e5fa1c2016-09-21 19:03:43 +05305567 sta_inactivity_timer = qdf_mem_malloc(
5568 sizeof(*sta_inactivity_timer));
5569 if (!sta_inactivity_timer) {
5570 hdd_err("Failed to allocate Memory");
5571 return QDF_STATUS_E_FAILURE;
5572 }
Jeff Johnson1b780e42017-10-31 14:11:45 -07005573 sta_inactivity_timer->session_id = adapter->session_id;
Agrawal, Ashish4e5fa1c2016-09-21 19:03:43 +05305574 sta_inactivity_timer->sta_inactivity_timeout =
5575 params->inactivity_timeout;
Jeff Johnson89a0c742018-06-12 18:17:46 -07005576 sme_update_sta_inactivity_timeout(hdd_ctx->mac_handle,
5577 sta_inactivity_timer);
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05305578 qdf_mem_free(sta_inactivity_timer);
Agrawal, Ashish4e5fa1c2016-09-21 19:03:43 +05305579 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005580 }
5581
Arunk Khandavallibbc301f2017-06-21 22:14:31 +05305582 goto success;
5583
5584err_start_bss:
Jeff Johnsonb9424862017-10-30 08:49:35 -07005585 if (adapter->session.ap.beacon)
5586 qdf_mem_free(adapter->session.ap.beacon);
5587 adapter->session.ap.beacon = NULL;
Arunk Khandavallibbc301f2017-06-21 22:14:31 +05305588
5589success:
Dustin Browne74003f2018-03-14 12:51:58 -07005590 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005591 return status;
5592}
5593
5594/**
5595 * wlan_hdd_cfg80211_start_ap() - start sap
5596 * @wiphy: Pointer to wiphy
5597 * @dev: Pointer to netdev
5598 * @params: Pointer to start ap configuration parameters
5599 *
5600 * Return: zero for success non-zero for failure
5601 */
5602int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
5603 struct net_device *dev,
5604 struct cfg80211_ap_settings *params)
5605{
5606 int ret;
5607
5608 cds_ssr_protect(__func__);
5609 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
5610 cds_ssr_unprotect(__func__);
5611
5612 return ret;
5613}
5614
5615/**
5616 * __wlan_hdd_cfg80211_change_beacon() - change beacon for sofatap/p2p go
5617 * @wiphy: Pointer to wiphy structure
5618 * @dev: Pointer to net_device structure
5619 * @params: Pointer to change beacon parameters
5620 *
5621 * Return: 0 for success non-zero for failure
5622 */
5623static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
5624 struct net_device *dev,
5625 struct cfg80211_beacon_data *params)
5626{
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005627 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson23c3b842017-09-03 09:05:29 -07005628 struct hdd_context *hdd_ctx;
Jeff Johnson44e52172017-09-30 16:39:16 -07005629 struct hdd_beacon_data *old, *new;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005630 int status;
5631
Dustin Brown491d54b2018-03-14 12:39:11 -07005632 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005633
Anurag Chouhan6d760662016-02-20 16:05:43 +05305634 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07005635 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005636 return -EINVAL;
5637 }
5638
Jeff Johnson1b780e42017-10-31 14:11:45 -07005639 if (wlan_hdd_validate_session_id(adapter->session_id)) {
5640 hdd_err("invalid session id: %d", adapter->session_id);
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +05305641 return -EINVAL;
5642 }
5643
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305644 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005645 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005646 adapter->session_id, adapter->device_mode));
Srinivas Girigowda55756882017-03-06 16:45:27 -08005647 hdd_debug("Device_mode %s(%d)",
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005648 hdd_device_mode_to_string(adapter->device_mode),
5649 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005650
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005651 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson23c3b842017-09-03 09:05:29 -07005652 status = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005653
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305654 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005655 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005656
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005657 if (!(adapter->device_mode == QDF_SAP_MODE ||
5658 adapter->device_mode == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005659 return -EOPNOTSUPP;
5660 }
5661
Jeff Johnsonb9424862017-10-30 08:49:35 -07005662 old = adapter->session.ap.beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005663
5664 if (!old) {
Srinivas Girigowda55756882017-03-06 16:45:27 -08005665 hdd_err("session id: %d beacon data points to NULL",
Jeff Johnson1b780e42017-10-31 14:11:45 -07005666 adapter->session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005667 return -EINVAL;
5668 }
5669
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005670 status = wlan_hdd_cfg80211_alloc_new_beacon(adapter, &new, params, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005671
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305672 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07005673 hdd_err("new beacon alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005674 return -EINVAL;
5675 }
5676
Jeff Johnsonb9424862017-10-30 08:49:35 -07005677 adapter->session.ap.beacon = new;
Archana Ramachandran7498d372017-03-31 11:03:16 -07005678 hdd_debug("update beacon for P2P GO/SAP");
Jeff Johnsonfd33cce2017-10-02 13:28:39 -07005679 status = wlan_hdd_cfg80211_start_bss(adapter, params, NULL,
Mahesh Kumar Kalikot Veetilc637fc92017-09-27 16:06:21 -07005680 0, 0, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005681
Dustin Browne74003f2018-03-14 12:51:58 -07005682 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005683 return status;
5684}
5685
5686/**
5687 * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode
5688 * @wiphy: Pointer to wiphy
5689 * @dev: Pointer to netdev
5690 * @params: Pointer to change beacon parameters
5691 *
5692 * Return: zero for success non-zero for failure
5693 */
5694int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
5695 struct net_device *dev,
5696 struct cfg80211_beacon_data *params)
5697{
5698 int ret;
5699
5700 cds_ssr_protect(__func__);
5701 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
5702 cds_ssr_unprotect(__func__);
5703
5704 return ret;
5705}
Arun Khandavallicc544b32017-01-30 19:52:16 +05305706
5707/**
5708 * hdd_sap_indicate_disconnect_for_sta() - Indicate disconnect indication
5709 * to supplicant, if there any clients connected to SAP interface.
5710 * @adapter: sap adapter context
5711 *
5712 * Return: nothing
5713 */
Jeff Johnson866aca82017-09-10 15:27:20 -07005714void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter)
Arun Khandavallicc544b32017-01-30 19:52:16 +05305715{
5716 tSap_Event sap_event;
5717 int sta_id;
Jeff Johnsonf1cd3c72017-09-14 07:18:06 -07005718 struct sap_context *sap_ctx;
Arun Khandavallicc544b32017-01-30 19:52:16 +05305719
Dustin Brown491d54b2018-03-14 12:39:11 -07005720 hdd_enter();
Arun Khandavallicc544b32017-01-30 19:52:16 +05305721
5722 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
5723 if (!sap_ctx) {
5724 hdd_err("invalid sap context");
5725 return;
5726 }
5727
5728 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07005729 if (adapter->sta_info[sta_id].in_use) {
Jeff Johnsonb105d052017-10-21 12:07:29 -07005730 hdd_debug("sta_id: %d in_use: %d %pK",
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07005731 sta_id, adapter->sta_info[sta_id].in_use,
Arun Khandavallicc544b32017-01-30 19:52:16 +05305732 adapter);
5733
5734 if (qdf_is_macaddr_broadcast(
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07005735 &adapter->sta_info[sta_id].sta_mac))
Arun Khandavallicc544b32017-01-30 19:52:16 +05305736 continue;
5737
5738 sap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
5739 qdf_mem_copy(
5740 &sap_event.sapevt.
5741 sapStationDisassocCompleteEvent.staMac,
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07005742 &adapter->sta_info[sta_id].sta_mac,
Arun Khandavallicc544b32017-01-30 19:52:16 +05305743 sizeof(struct qdf_mac_addr));
5744 sap_event.sapevt.sapStationDisassocCompleteEvent.
5745 reason =
5746 eSAP_MAC_INITATED_DISASSOC;
5747 sap_event.sapevt.sapStationDisassocCompleteEvent.
5748 statusCode =
5749 QDF_STATUS_E_RESOURCES;
5750 hdd_hostapd_sap_event_cb(&sap_event,
5751 sap_ctx->pUsrContext);
5752 }
5753 }
5754
Dustin Browne74003f2018-03-14 12:51:58 -07005755 hdd_exit();
Arun Khandavallicc544b32017-01-30 19:52:16 +05305756}
5757
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05305758bool hdd_is_peer_associated(struct hdd_adapter *adapter,
5759 struct qdf_mac_addr *mac_addr)
5760{
5761 uint32_t cnt;
5762 struct hdd_station_info *sta_info;
5763
5764 if (!adapter || !mac_addr) {
5765 hdd_err("Invalid adapter or mac_addr");
5766 return false;
5767 }
5768
5769 sta_info = adapter->sta_info;
5770 spin_lock_bh(&adapter->sta_info_lock);
5771 for (cnt = 0; cnt < WLAN_MAX_STA_COUNT; cnt++) {
5772 if ((sta_info[cnt].in_use) &&
5773 !qdf_mem_cmp(&(sta_info[cnt].sta_mac), mac_addr,
5774 QDF_MAC_ADDR_SIZE))
5775 break;
5776 }
5777 spin_unlock_bh(&adapter->sta_info_lock);
5778 if (cnt != WLAN_MAX_STA_COUNT)
5779 return true;
5780
5781 return false;
5782}